blob: 0f34056b98552576843b46f7252508e561498f36 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
2 * Driver for simulating ssp as spi device for asr1802s
3 *
4 * (C) Copyright 2018
5 * ASR Microelectronics (Shanghai) Co., Ltd.
6 *
7 * Licensed under the GPL-2 or later.
8 */
9
10
11#include <common.h>
12#include <malloc.h>
13#include <spi.h>
14#include <watchdog.h>
15#include <asm/io.h>
16#include <asm/arch/asr_spi.h>
17#include <asm/gpio.h>
18#include <asm/arch/pxa_dma.h>
19#include <asm/arch/cpu.h>
20
21#define to_asr_spi_slave(s) container_of(s, struct asr_spi_slave, slave)
22
23int cs_continuous;
24
25#ifndef CONFIG_PXA_SPI_ENABLE_AUTO_CS
26void spi_cs_activate(struct spi_slave *slave)
27{
28 struct asr_spi_slave *slv = to_asr_spi_slave(slave);
29 gpio_set_value(slave->cs, slv->gpio_cs_inverted);
30}
31
32void spi_cs_deactivate(struct spi_slave *slave)
33{
34 struct asr_spi_slave *slv = to_asr_spi_slave(slave);
35 gpio_set_value(slave->cs, !slv->gpio_cs_inverted);
36}
37#endif
38
39static int spi_pxa_write(struct asr_spi_slave *slv, unsigned int bitlen)
40{
41 int wait_timeout = SSP_FLUSH_NUM;
42 int bytes = bitlen / slv->slave.wordlen;
43
44 while (--wait_timeout && !(readl(&slv->spi_reg->sssr) & SSSR_TNF))
45 ;
46 if (!wait_timeout) {
47 debug("%s: timeout error\n", __func__);
48 return -1;
49 }
50
51 while (bytes--) {
52 if (slv->tx != NULL) {
53 if (slv->slave.wordlen > 16) {
54 writel(*(u32 *)slv->tx, &slv->spi_reg->ssdr);
55 slv->tx += 4;
56 } else if (slv->slave.wordlen > 8) {
57 writel(*(u16 *)slv->tx, &slv->spi_reg->ssdr);
58 slv->tx += 2;
59 } else {
60 writel(*(u8 *)slv->tx, &slv->spi_reg->ssdr);
61 ++slv->tx;
62 }
63 } else
64 writel(0, &slv->spi_reg->ssdr);
65
66 while (((readl(&slv->spi_reg->sssr)&0xFC1) != 0x40) && wait_timeout--) {
67 nop();
68 nop();
69 }
70 if (!wait_timeout) {
71 debug("%s: timeout error\n", __func__);
72 return -1;
73 }
74 }
75
76 return 0;
77}
78
79static int spi_pxa_read(struct asr_spi_slave *slv, unsigned int bitlen)
80{
81 int wait_timeout = SSP_FLUSH_NUM;
82 int bytes = bitlen / slv->slave.wordlen;
83
84 while (--wait_timeout && !(readl(&slv->spi_reg->sssr) & SSSR_TNF))
85 ;
86 if (!wait_timeout) {
87 debug("%s: timeout error\n", __func__);
88 return -1;
89 }
90
91 while (bytes--) {
92 wait_timeout = SSP_FLUSH_NUM;
93 writel(0xff, &slv->spi_reg->ssdr);
94 while (((readl(&slv->spi_reg->sssr)&0xFC1) != 0x40) && wait_timeout--) {
95 nop();
96 nop();
97 }
98 if (!wait_timeout) {
99 printf("%s: timeout error, sssr:0x%x. byte:0x%x.\n",
100 __func__, readl(&slv->spi_reg->sssr), bytes);
101 return -1;
102 }
103
104 wait_timeout = SSP_FLUSH_NUM;
105 while (--wait_timeout && !(readl(&slv->spi_reg->sssr) & SSSR_RNE))
106 ;
107 if (!wait_timeout) {
108 printf("%s: timeout error sssr:0x%x.\n", __func__,
109 readl(&slv->spi_reg->sssr));
110 return -1;
111 }
112
113 if (slv->rx != NULL) {
114 if (slv->slave.wordlen > 16) {
115 *(u32 *)slv->rx = readl(&slv->spi_reg->ssdr);
116 slv->rx += 4;
117 } else if (slv->slave.wordlen > 8) {
118 *(u16 *)slv->rx = readl(&slv->spi_reg->ssdr);
119 slv->rx += 2;
120 } else {
121 *(u8 *)slv->rx = readl(&slv->spi_reg->ssdr);
122 ++slv->rx;
123 }
124 } else
125 readl(&slv->spi_reg->ssdr);
126 }
127
128 return 0;
129}
130
131static int spi_pxa_flush(struct asr_spi_slave *slv)
132{
133 unsigned long limit = SSP_FLUSH_NUM;
134
135 do {
136 while (readl(&slv->spi_reg->sssr) & SSSR_RNE)
137 readl(&slv->spi_reg->ssdr);
138 } while ((readl(&slv->spi_reg->sssr) & SSSR_BSY) && limit--);
139
140 writel(SSSR_ROR, &slv->spi_reg->sssr);
141
142 return limit;
143}
144
145struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
146 unsigned int max_hz, unsigned int mode)
147{
148 struct asr_spi_slave *slv;
149
150 slv = spi_alloc_slave(struct asr_spi_slave, bus, cs);
151 if (!slv)
152 return NULL;
153
154 slv->slave.bus = bus;
155#ifndef CONFIG_PXA_SPI_ENABLE_AUTO_CS
156 slv->slave.cs = cs;
157#endif
158 slv->spi_reg = (struct ssp_reg *)CONFIG_SYS_SSP_BASE;
159 slv->tcr = SSTCR_TTE | SSTCR_TTELP | SSTCR_MOTO |
160 SSTCR_DSS(DEFAULT_WORD_LEN) | SSTCR_SSE;
161 slv->tcr &= ~(SSTCR_SPO | SSTCR_SPH);
162 slv->tcr |= (((mode & SPI_CPHA) != 0) ? SSTCR_SPH : 0)
163 | (((mode & SPI_CPOL) != 0) ? SSTCR_SPO : 0);
164
165 slv->fcr = (SSFCR_RXTRESH(RX_THRESH_DEF) & SSFCR_RFT) |
166 (SSFCR_TXTRESH(TX_THRESH_DEF) & SSFCR_TFT);
167
168 slv->ier = SSIER_TIE | SSIER_RIE | SSIER_TINTE;
169 slv->clear_sr = SSSR_ROR | SSSR_TINT;
170
171 if (cs) {
172 //In case that device nHold and nWP is connected to 1802s
173 gpio_direction_output(CONFIG_SPINAND_nHOLD, 1);
174 gpio_direction_output(CONFIG_SPINAND_nWP, 1);
175
176#ifndef CONFIG_PXA_SPI_ENABLE_AUTO_CS
177 gpio_direction_output(cs, !slv->gpio_cs_inverted);
178 slv->gpio_cs_inverted = mode & SPI_CS_HIGH;
179 gpio_set_value(cs, !slv->gpio_cs_inverted);
180#endif
181 }
182 cs_continuous = 0;
183
184 return &slv->slave;
185}
186
187void spi_free_slave(struct spi_slave *slave)
188{
189 struct asr_spi_slave *slv = to_asr_spi_slave(slave);
190 free(slv);
191}
192#ifdef CONFIG_PXA_DMA
193__attribute__ ((aligned(32))) unsigned int dummy[0x400];
194#endif
195void spi_init(void)
196{
197 unsigned int reg;
198 int clk = SSP_26M; // default 26M
199 if (CONFIG_SYS_SSP_BASE == SSP0_BASE)
200 reg = APBC_SSP0_CLK_RST;
201 else if (CONFIG_SYS_SSP_BASE == SSP1_BASE)
202 reg = APBC_SSP1_CLK_RST;
203 else if (CONFIG_SYS_SSP_BASE == SSP2_BASE)
204 reg = APBC_SSP2_CLK_RST;
205 else {
206 printf("Fatal error: unsupportted ssp base: 0x%x.\n", CONFIG_SYS_SSP_BASE);
207 return;
208 }
209
210#ifdef CONFIG_SPI_52M_ENABLE
211 clk = SSP_52M;
212#else
213 #ifdef CONFIG_SPI_26M_ENABLE
214 clk = SSP_26M;
215 #else
216 #ifdef CONFIG_SPI_13M_ENABLE
217 clk = SSP_13M;
218 #else
219 #ifdef CONFIG_SPI_6P5M_ENABLE
220 clk = SSP_6P5M;
221 #endif
222 #endif
223 #endif
224#endif
225
226 __raw_writel(APBC_SSP_BCLKEN | APBC_SSP_FNCLKEN |
227 (clk << APBC_SSP_FNCLKSEL_SHIFT), reg);
228
229#ifdef CONFIG_PXA_DMA
230 memset(dummy, 0x0, 0x400*4);
231#endif
232 /* Load default SSP configuration */
233 writel(0, CONFIG_SYS_SSP_BASE + SSTCR);
234 writel(SSFCR_RXTRESH(RX_THRESH_DEF) |
235 SSFCR_TXTRESH(TX_THRESH_DEF), CONFIG_SYS_SSP_BASE + SSFCR);
236 writel(SSTCR_MOTO | SSTCR_DSS(DEFAULT_WORD_LEN)
237 , CONFIG_SYS_SSP_BASE + SSTCR);
238 writel(0, CONFIG_SYS_SSP_BASE + SSTO);
239
240 __raw_writel(DMA_CLK_AXICLK_EN | DMA_CLK_AXI_RST,
241 PMUA_DMA_CLK_RES_CTRL); /* enable DMA clock */
242}
243
244int spi_claim_bus(struct spi_slave *slave)
245{
246 struct asr_spi_slave *slv = to_asr_spi_slave(slave);
247 slave->wordlen = 8; /* set default wordlen */
248
249 if (spi_pxa_flush(slv) == 0)
250 return -1;
251
252 return 0;
253}
254
255void spi_release_bus(struct spi_slave *slave)
256{
257}
258
259int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
260 void *din, unsigned long flags)
261{
262 struct asr_spi_slave *slv = to_asr_spi_slave(slave);
263 int ret = 0;
264
265 if (slave->wordlen < 4 || slave->wordlen > 32) {
266 printf("pxa2xx_spi: invalid wordlen %d\n", slave->wordlen);
267 return -1;
268 }
269
270 if (bitlen % slave->wordlen)
271 return -1;
272
273 slv->rx = din;
274 slv->tx = dout;
275
276 writel(0, &slv->spi_reg->sstcr);
277 slv->tcr &= ~(SSTCR_DSS_MASK);
278 slv->tcr |= SSTCR_DSS(slave->wordlen);
279
280 writel(slv->fcr, &slv->spi_reg->ssfcr);
281 writel(slv->ier, &slv->spi_reg->ssier);
282 writel(TIMEOUT_DEF, &slv->spi_reg->ssto);
283 writel(slv->tcr, &slv->spi_reg->sstcr);
284
285 if (flags & SPI_XFER_BEGIN) {
286#ifndef CONFIG_PXA_SPI_ENABLE_AUTO_CS
287 if (!cs_continuous)
288 spi_cs_activate(slave);
289#endif
290 }
291
292 if (dout != NULL && din != NULL) {
293 ret = spi_pxa_write(slv, bitlen - slave->wordlen);
294 if(ret)
295 return -1;
296
297 ret = spi_pxa_read(slv, slave->wordlen);
298 if(ret)
299 return -1;
300 } else if (dout != NULL) {
301 ret = spi_pxa_write(slv, bitlen);
302 if(ret)
303 return -1;
304 } else if (din != NULL) {
305 ret = spi_pxa_read(slv, bitlen);
306 if(ret)
307 return -1;
308 }
309
310 if (flags & SPI_XFER_END) {
311 writel(slv->clear_sr, &slv->spi_reg->sssr);
312 writel(0, &slv->spi_reg->ssto);
313 writel(0, &slv->spi_reg->sstcr);
314#ifndef CONFIG_PXA_SPI_ENABLE_AUTO_CS
315 if (!cs_continuous)
316 spi_cs_deactivate(slave);
317#endif
318 }
319 return ret;
320}
321#ifdef CONFIG_PXA_DMA
322static int spi_dma_read(void *din, unsigned int len)
323{
324 int i, init = 0;
325 if (!init) {
326 dmac_map_device_to_channel(DMAC_SSP2_RX,
327 SSP_RX_CHANNEL);
328 dmac_map_device_to_channel(DMAC_SSP2_TX,
329 SSP_TX_CHANNEL);
330
331 dmac_user_aligment(SSP_RX_CHANNEL);
332 dmac_user_aligment(SSP_TX_CHANNEL);
333 init = 1;
334 }
335
336 pxa_dma_read((unsigned int)din, SSP_SSDR, len, SSP_RX_CHANNEL);
337 pxa_dma_write(SSP_SSDR, (unsigned int)dummy, len, SSP_TX_CHANNEL);
338
339 dmac_start_transfer(SSP_RX_CHANNEL);
340 dmac_start_transfer(SSP_TX_CHANNEL);
341
342 do {
343 for (i = 0; i < 500; i++)
344 nop();
345 if (dmac_read_dcsr(SSP_TX_CHANNEL) & DCSR_STOPSTATE)
346 break;
347
348 } while (1);
349
350 do {
351 if (dmac_read_dcsr(SSP_RX_CHANNEL) & DCSR_STOPSTATE)
352 break;
353 } while (1);
354
355
356 for (i = 0; i < len; i += 4)
357 swab32s(din+i);
358
359 if (!(dmac_read_dcsr(SSP_TX_CHANNEL) & DCSR_STOPSTATE)) {
360 printf("Error:DMA write operate timeout.\n");
361 return 1;
362 }
363 if (!(dmac_read_dcsr(SSP_RX_CHANNEL) & DCSR_STOPSTATE)) {
364 printf("Error:DMA read operate timeout.\n");
365 return 1;
366 }
367
368 return 0;
369}
370
371static int spi_dma_write(void *dout, unsigned int len)
372{
373 int i, init = 0;
374
375 for (i = 0; i < len; i += 4)
376 swab32s(dout+i);
377
378 flush_dcache_all();
379 if (!init) {
380 dmac_map_device_to_channel(DMAC_SSP2_TX,
381 SSP_TX_CHANNEL);
382
383 dmac_user_aligment(SSP_TX_CHANNEL);
384 init = 1;
385 }
386
387 pxa_dma_write(SSP_SSDR, (unsigned int)dout, len, SSP_TX_CHANNEL);
388 dmac_start_transfer(SSP_TX_CHANNEL);
389
390 do {
391 for (i = 0; i < 500; i++)
392 nop();
393 if (dmac_read_dcsr(SSP_TX_CHANNEL) & DCSR_STOPSTATE)
394 break;
395 } while (1);
396
397 if (!(dmac_read_dcsr(SSP_TX_CHANNEL) & DCSR_STOPSTATE)) {
398 printf("Error:DMA write operate timeout.\n");
399 return 1;
400 }
401
402 return 0;
403}
404
405int spi_dma_xfer(struct spi_slave *slave, const u8 *cmd, size_t cmd_len,
406 const void *dout, const void *din, size_t data_len)
407{
408 struct asr_spi_slave *slv = to_asr_spi_slave(slave);
409 int ret = 0;
410
411#ifndef CONFIG_PXA_SPI_ENABLE_AUTO_CS
412 spi_cs_activate(slave);
413#endif
414
415 if (cmd) {
416 cs_continuous = 1;
417 spi_xfer(slave, cmd_len*8, cmd, NULL,
418 SPI_XFER_BEGIN | SPI_XFER_END);
419 }
420
421 if (dout || din) {
422 writel(TIMEOUT_DEF, &slv->spi_reg->ssto);
423 writel(SSFCR_RXTRESH(0x5) | SSFCR_TSRE | SSFCR_RSRE |
424 SSFCR_TXTRESH(0x4), &slv->spi_reg->ssfcr);
425
426 writel(SSTCR_TTELP | SSTCR_TTE | SSTCR_SSE |SSTCR_TRAIL |
427 SSTCR_DSS(32), &slv->spi_reg->sstcr);
428 }
429
430 if (dout)
431 ret = spi_dma_write((void *)dout, data_len);
432 if (din)
433 ret = spi_dma_read((void *)din, data_len);
434
435 while ( (readl(&slv->spi_reg->sssr) & 0xFC1) != 0x40 )
436 ;
437 if (dout || din) {
438 writel(slv->clear_sr, &slv->spi_reg->sssr);
439 clrbits_le32(&slv->spi_reg->ssier, slv->ier);
440 writel(0, &slv->spi_reg->sstcr);
441#ifndef CONFIG_PXA_SPI_ENABLE_AUTO_CS
442 spi_cs_deactivate(slave);
443#endif
444 }
445 cs_continuous = 0;
446 return ret;
447}
448#endif