2 * This file is part of the coreboot project.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <device/mmio.h>
17 #include <console/console.h>
20 #include <spi-generic.h>
24 #define EXYNOS_SPI_MAX_TRANSFER_BYTES (65535)
26 #if defined(CONFIG_DEBUG_SPI) && CONFIG_DEBUG_SPI
27 # define DEBUG_SPI(x,...) printk(BIOS_DEBUG, "EXYNOS_SPI: " x)
29 # define DEBUG_SPI(x,...)
32 struct exynos_spi_slave
{
33 struct spi_slave slave
;
34 struct exynos_spi
*regs
;
38 /* TODO(hungte) Move the SPI param list to per-board configuration, probably
39 * Kconfig or mainboard.c */
40 static struct exynos_spi_slave exynos_spi_slaves
[3] = {
43 .slave
= { .bus
= 0, },
44 .regs
= (void *)EXYNOS5_SPI0_BASE
,
48 .slave
= { .bus
= 1, },
49 .regs
= (void *)EXYNOS5_SPI1_BASE
,
53 .slave
= { .bus
= 2, },
54 .regs
= (void *)EXYNOS5_SPI2_BASE
,
58 static inline struct exynos_spi_slave
*to_exynos_spi(const struct spi_slave
*slave
)
60 return &exynos_spi_slaves
[slave
->bus
];
63 static void spi_sw_reset(struct exynos_spi
*regs
, int word
)
65 const uint32_t orig_mode_cfg
= read32(®s
->mode_cfg
);
66 uint32_t mode_cfg
= orig_mode_cfg
;
67 const uint32_t orig_swap_cfg
= read32(®s
->swap_cfg
);
68 uint32_t swap_cfg
= orig_swap_cfg
;
70 mode_cfg
&= ~(SPI_MODE_CH_WIDTH_MASK
| SPI_MODE_BUS_WIDTH_MASK
);
72 mode_cfg
|= SPI_MODE_CH_WIDTH_WORD
| SPI_MODE_BUS_WIDTH_WORD
;
73 swap_cfg
|= SPI_RX_SWAP_EN
|
80 mode_cfg
|= SPI_MODE_CH_WIDTH_BYTE
| SPI_MODE_BUS_WIDTH_BYTE
;
84 if (mode_cfg
!= orig_mode_cfg
)
85 write32(®s
->mode_cfg
, mode_cfg
);
86 if (swap_cfg
!= orig_swap_cfg
)
87 write32(®s
->swap_cfg
, swap_cfg
);
89 clrbits32(®s
->ch_cfg
, SPI_RX_CH_ON
| SPI_TX_CH_ON
);
90 setbits32(®s
->ch_cfg
, SPI_CH_RST
);
91 clrbits32(®s
->ch_cfg
, SPI_CH_RST
);
92 setbits32(®s
->ch_cfg
, SPI_RX_CH_ON
| SPI_TX_CH_ON
);
95 static void exynos_spi_init(struct exynos_spi
*regs
)
98 write32(®s
->fb_clk
, SPI_FB_DELAY_180
);
100 clrbits32(®s
->ch_cfg
, SPI_CH_CPOL_L
);
102 // Clear rx and tx channel if set previously.
103 clrbits32(®s
->ch_cfg
, SPI_RX_CH_ON
| SPI_TX_CH_ON
);
105 setbits32(®s
->swap_cfg
,
106 SPI_RX_SWAP_EN
| SPI_RX_BYTE_SWAP
| SPI_RX_HWORD_SWAP
);
107 clrbits32(®s
->ch_cfg
, SPI_CH_HS_EN
);
109 // Do a soft reset, which will also enable both channels.
110 spi_sw_reset(regs
, 1);
113 static int spi_ctrlr_claim_bus(const struct spi_slave
*slave
)
115 struct exynos_spi
*regs
= to_exynos_spi(slave
)->regs
;
116 // TODO(hungte) Add some delay if too many transactions happen at once.
117 clrbits32(®s
->cs_reg
, SPI_SLAVE_SIG_INACT
);
121 static void spi_transfer(struct exynos_spi
*regs
, void *in
, const void *out
,
125 const u8
*outb
= out
;
127 size_t width
= (size
% 4) ? 1 : 4;
130 size_t packets
= size
/ width
;
131 // The packet count field is 16 bits wide.
132 packets
= MIN(packets
, (1 << 16) - 1);
134 size_t out_bytes
, in_bytes
;
135 out_bytes
= in_bytes
= packets
* width
;
137 spi_sw_reset(regs
, width
== 4);
138 write32(®s
->pkt_cnt
, packets
| SPI_PACKET_CNT_EN
);
140 while (out_bytes
|| in_bytes
) {
141 uint32_t spi_sts
= read32(®s
->spi_sts
);
142 int rx_lvl
= ((spi_sts
>> 15) & 0x1ff);
143 int tx_lvl
= ((spi_sts
>> 6) & 0x1ff);
145 if (tx_lvl
< 32 && tx_lvl
< out_bytes
) {
146 uint32_t data
= 0xffffffff;
149 memcpy(&data
, outb
, width
);
152 write32(®s
->tx_data
, data
);
157 if (rx_lvl
>= width
) {
158 uint32_t data
= read32(®s
->rx_data
);
161 memcpy(inb
, &data
, width
);
169 size
-= packets
* width
;
173 static int spi_ctrlr_xfer(const struct spi_slave
*slave
, const void *dout
, size_t bytes_out
,
174 void *din
, size_t bytes_in
)
176 struct exynos_spi
*regs
= to_exynos_spi(slave
)->regs
;
178 if (bytes_out
&& bytes_in
) {
179 size_t min_size
= MIN(bytes_out
, bytes_in
);
181 spi_transfer(regs
, din
, dout
, min_size
);
183 bytes_out
-= min_size
;
184 bytes_in
-= min_size
;
186 din
= (uint8_t *)din
+ min_size
;
187 dout
= (const uint8_t *)dout
+ min_size
;
191 spi_transfer(regs
, din
, NULL
, bytes_in
);
193 spi_transfer(regs
, NULL
, dout
, bytes_out
);
198 static void spi_ctrlr_release_bus(const struct spi_slave
*slave
)
200 struct exynos_spi
*regs
= to_exynos_spi(slave
)->regs
;
201 setbits32(®s
->cs_reg
, SPI_SLAVE_SIG_INACT
);
204 static int spi_ctrlr_setup(const struct spi_slave
*slave
)
206 ASSERT(slave
->bus
< 3);
207 struct exynos_spi_slave
*eslave
;
209 eslave
= to_exynos_spi(slave
);
210 if (!eslave
->initialized
) {
211 exynos_spi_init(eslave
->regs
);
212 eslave
->initialized
= 1;
217 static const struct spi_ctrlr spi_ctrlr
= {
218 .setup
= spi_ctrlr_setup
,
219 .claim_bus
= spi_ctrlr_claim_bus
,
220 .release_bus
= spi_ctrlr_release_bus
,
221 .xfer
= spi_ctrlr_xfer
,
222 .max_xfer_size
= SPI_CTRLR_DEFAULT_MAX_XFER_SIZE
,
225 const struct spi_ctrlr_buses spi_ctrlr_bus_map
[] = {
233 const size_t spi_ctrlr_bus_map_count
= ARRAY_SIZE(spi_ctrlr_bus_map
);
235 static int exynos_spi_read(struct spi_slave
*slave
, void *dest
, uint32_t len
,
238 struct exynos_spi
*regs
= to_exynos_spi(slave
)->regs
;
240 spi_claim_bus(slave
);
243 ASSERT(off
< (1 << 24));
244 command
= htonl(SF_READ_DATA_CMD
<< 24 | off
);
245 spi_transfer(regs
, NULL
, &command
, sizeof(command
));
248 spi_transfer(regs
, dest
, NULL
, len
);
249 spi_release_bus(slave
);
254 static struct exynos_spi_slave
*boot_slave
;
256 static ssize_t
exynos_spi_readat(const struct region_device
*rdev
, void *dest
,
257 size_t offset
, size_t count
)
259 DEBUG_SPI("exynos_spi_cbfs_read(%u)\n", count
);
260 return exynos_spi_read(&boot_slave
->slave
, dest
, count
, offset
);
263 static void *exynos_spi_map(const struct region_device
*rdev
,
264 size_t offset
, size_t count
)
266 DEBUG_SPI("exynos_spi_cbfs_map\n");
267 // exynos: spi_rx_tx may work in 4 byte-width-transmission mode and
268 // requires buffer memory address to be aligned.
270 count
+= 4 - (count
% 4);
271 return mmap_helper_rdev_mmap(rdev
, offset
, count
);
274 static const struct region_device_ops exynos_spi_ops
= {
275 .mmap
= exynos_spi_map
,
276 .munmap
= mmap_helper_rdev_munmap
,
277 .readat
= exynos_spi_readat
,
280 static struct mmap_helper_region_device mdev
=
281 MMAP_HELPER_REGION_INIT(&exynos_spi_ops
, 0, CONFIG_ROM_SIZE
);
283 void exynos_init_spi_boot_device(void)
285 boot_slave
= &exynos_spi_slaves
[1];
287 mmap_helper_device_init(&mdev
, _cbfs_cache
, REGION_SIZE(cbfs_cache
));
290 const struct region_device
*exynos_spi_boot_device(void)