1 /* $Id: imx23_ssp.c,v 1.8 2021/10/21 13:21:54 andvar Exp $ */
2
3 /*
4 * Copyright (c) 2012 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Petri Laakso.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/bus.h>
35 #include <sys/cdefs.h>
36 #include <sys/condvar.h>
37 #include <sys/device.h>
38 #include <sys/errno.h>
39 #include <sys/mutex.h>
40 #include <sys/systm.h>
41
42 #include <arm/pic/picvar.h>
43
44 #include <arm/imx/imx23_apbdmavar.h>
45 #include <arm/imx/imx23_icollreg.h>
46 #include <arm/imx/imx23_sspreg.h>
47 #include <arm/imx/imx23var.h>
48
49 #include <dev/sdmmc/sdmmcchip.h>
50 #include <dev/sdmmc/sdmmcreg.h>
51 #include <dev/sdmmc/sdmmcvar.h>
52
53 /*
54 * SD/MMC host controller driver for i.MX23.
55 *
56 * TODO:
57 *
58 * - Add support for SMC_CAPS_AUTO_STOP.
59 * - Uset GPIO for SD card detection.
60 */
61
62 #define DMA_MAXNSEGS ((MAXPHYS / PAGE_SIZE) + 1)
63
64 typedef struct issp_softc {
65 device_t sc_dev;
66 apbdma_softc_t sc_dmac;
67 bus_dma_tag_t sc_dmat;
68 bus_dmamap_t sc_dmamp;
69 bus_size_t sc_chnsiz;
70 bus_dma_segment_t sc_ds[1];
71 int sc_rseg;
72 bus_space_handle_t sc_hdl;
73 bus_space_tag_t sc_iot;
74 device_t sc_sdmmc;
75 kmutex_t sc_lock;
76 struct kcondvar sc_intr_cv;
77 unsigned int dma_channel;
78 uint32_t sc_dma_error;
79 uint32_t sc_irq_error;
80 uint8_t sc_state;
81 uint8_t sc_bus_width;
82 } *issp_softc_t;
83
84 static int issp_match(device_t, cfdata_t, void *);
85 static void issp_attach(device_t, device_t, void *);
86 static int issp_activate(device_t, enum devact);
87
88 static void issp_reset(struct issp_softc *);
89 static void issp_init(struct issp_softc *);
90 static uint32_t issp_set_sck(struct issp_softc *, uint32_t);
91 static int issp_dma_intr(void *);
92 static int issp_error_intr(void *);
93 static void issp_ack_intr(struct issp_softc *);
94 static void issp_create_dma_cmd_list_multi(issp_softc_t, void *,
95 struct sdmmc_command *);
96 static void issp_create_dma_cmd_list_single(issp_softc_t, void *,
97 struct sdmmc_command *);
98 static void issp_create_dma_cmd_list(issp_softc_t, void *,
99 struct sdmmc_command *);
100
101 /* sdmmc(4) driver chip function prototypes. */
102 static int issp_host_reset(sdmmc_chipset_handle_t);
103 static uint32_t issp_host_ocr(sdmmc_chipset_handle_t);
104 static int issp_host_maxblklen(sdmmc_chipset_handle_t);
105 static int issp_card_detect(sdmmc_chipset_handle_t);
106 static int issp_write_protect(sdmmc_chipset_handle_t);
107 static int issp_bus_power(sdmmc_chipset_handle_t, uint32_t);
108 static int issp_bus_clock(sdmmc_chipset_handle_t, int);
109 static int issp_bus_width(sdmmc_chipset_handle_t, int);
110 static int issp_bus_rod(sdmmc_chipset_handle_t, int);
111 static void issp_exec_command(sdmmc_chipset_handle_t,
112 struct sdmmc_command *);
113 static void issp_card_enable_intr(sdmmc_chipset_handle_t, int);
114 static void issp_card_intr_ack(sdmmc_chipset_handle_t);
115
116 static struct sdmmc_chip_functions issp_functions = {
117 .host_reset = issp_host_reset,
118 .host_ocr = issp_host_ocr,
119 .host_maxblklen = issp_host_maxblklen,
120 .card_detect = issp_card_detect,
121 .write_protect = issp_write_protect,
122 .bus_power = issp_bus_power,
123 .bus_clock = issp_bus_clock,
124 .bus_width = issp_bus_width,
125 .bus_rod = issp_bus_rod,
126 .exec_command = issp_exec_command,
127 .card_enable_intr = issp_card_enable_intr,
128 .card_intr_ack = issp_card_intr_ack
129 };
130
131 CFATTACH_DECL3_NEW(ssp,
132 sizeof(struct issp_softc),
133 issp_match,
134 issp_attach,
135 NULL,
136 issp_activate,
137 NULL,
138 NULL,
139 0
140 );
141
142 #define SSP_SOFT_RST_LOOP 455 /* At least 1 us ... */
143
144 #define SSP_RD(sc, reg) \
145 bus_space_read_4(sc->sc_iot, sc->sc_hdl, (reg))
146 #define SSP_WR(sc, reg, val) \
147 bus_space_write_4(sc->sc_iot, sc->sc_hdl, (reg), (val))
148
149 #define SSP_CLK 160000000 /* CLK_SSP from PLL in Hz */
150 #define SSP_CLK_MIN 400 /* 400 kHz */
151 #define SSP_CLK_MAX 48000 /* 48 MHz */
152
153 /* DATA_TIMEOUT is calculated as: * (1 / SSP_CLK) * (DATA_TIMEOUT * 4096) */
154 #define DATA_TIMEOUT 0x4240
155
156 #define BUS_WIDTH_1_BIT 0x0
157 #define BUS_WIDTH_4_BIT 0x1
158 #define BUS_WIDTH_8_BIT 0x2
159
160 #define SSP1_ATTACHED 1
161 #define SSP2_ATTACHED 2
162
163 /* Flags for sc_state. */
164 #define SSP_STATE_IDLE 0
165 #define SSP_STATE_DMA 1
166
167 #define PIO_WORD_CTRL0 0
168 #define PIO_WORD_CMD0 1
169 #define PIO_WORD_CMD1 2
170
171 #define HW_SSP_CTRL1_IRQ_MASK ( \
172 HW_SSP_CTRL1_SDIO_IRQ | \
173 HW_SSP_CTRL1_RESP_ERR_IRQ | \
174 HW_SSP_CTRL1_RESP_TIMEOUT_IRQ | \
175 HW_SSP_CTRL1_DATA_TIMEOUT_IRQ | \
176 HW_SSP_CTRL1_DATA_CRC_IRQ | \
177 HW_SSP_CTRL1_FIFO_UNDERRUN_IRQ | \
178 HW_SSP_CTRL1_RECV_TIMEOUT_IRQ | \
179 HW_SSP_CTRL1_FIFO_OVERRUN_IRQ)
180
181 /* SSP does not support over 64k transfer size. */
182 #define MAX_TRANSFER_SIZE 65536
183
184 static int
issp_match(device_t parent,cfdata_t match,void * aux)185 issp_match(device_t parent, cfdata_t match, void *aux)
186 {
187 struct apb_attach_args *aa = aux;
188
189 if ((aa->aa_addr == HW_SSP1_BASE) && (aa->aa_size == HW_SSP1_SIZE))
190 return 1;
191
192 if ((aa->aa_addr == HW_SSP2_BASE) && (aa->aa_size == HW_SSP2_SIZE))
193 return 1;
194
195 return 0;
196 }
197
198 static void
issp_attach(device_t parent,device_t self,void * aux)199 issp_attach(device_t parent, device_t self, void *aux)
200 {
201 struct issp_softc *sc = device_private(self);
202 struct apb_softc *sc_parent = device_private(parent);
203 struct apb_attach_args *aa = aux;
204 struct sdmmcbus_attach_args saa;
205 static int ssp_attached = 0;
206 int error;
207 void *intr;
208
209 sc->sc_dev = self;
210 sc->sc_iot = aa->aa_iot;
211 sc->sc_dmat = aa->aa_dmat;
212
213 /* Test if device instance is already attached. */
214 if (aa->aa_addr == HW_SSP1_BASE && ISSET(ssp_attached, SSP1_ATTACHED)) {
215 aprint_error_dev(sc->sc_dev, "SSP1 already attached\n");
216 return;
217 }
218 if (aa->aa_addr == HW_SSP2_BASE && ISSET(ssp_attached, SSP2_ATTACHED)) {
219 aprint_error_dev(sc->sc_dev, "SSP2 already attached\n");
220 return;
221 }
222
223 if (aa->aa_addr == HW_SSP1_BASE) {
224 sc->dma_channel = APBH_DMA_CHANNEL_SSP1;
225 }
226 if (aa->aa_addr == HW_SSP2_BASE) {
227 sc->dma_channel = APBH_DMA_CHANNEL_SSP2;
228 }
229
230 /* This driver requires DMA functionality from the bus.
231 * Parent bus passes handle to the DMA controller instance. */
232 if (sc_parent->dmac == NULL) {
233 aprint_error_dev(sc->sc_dev, "DMA functionality missing\n");
234 return;
235 }
236 sc->sc_dmac = device_private(sc_parent->dmac);
237
238 /* Initialize lock. */
239 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SDMMC);
240
241 /* Condvar to wait interrupt complete. */
242 cv_init(&sc->sc_intr_cv, "ssp_intr");
243
244 /* Establish interrupt handlers for SSP errors and SSP DMA. */
245 if (aa->aa_addr == HW_SSP1_BASE) {
246 intr = intr_establish(IRQ_SSP1_DMA, IPL_SDMMC, IST_LEVEL,
247 issp_dma_intr, sc);
248 if (intr == NULL) {
249 aprint_error_dev(sc->sc_dev, "Unable to establish "
250 "interrupt for SSP1 DMA\n");
251 return;
252 }
253 intr = intr_establish(IRQ_SSP1_ERROR, IPL_SDMMC, IST_LEVEL,
254 issp_error_intr, sc);
255 if (intr == NULL) {
256 aprint_error_dev(sc->sc_dev, "Unable to establish "
257 "interrupt for SSP1 ERROR\n");
258 return;
259 }
260 }
261
262 if (aa->aa_addr == HW_SSP2_BASE) {
263 intr = intr_establish(IRQ_SSP2_DMA, IPL_SDMMC, IST_LEVEL,
264 issp_dma_intr, sc);
265 if (intr == NULL) {
266 aprint_error_dev(sc->sc_dev, "Unable to establish "
267 "interrupt for SSP2 DMA\n");
268 return;
269 }
270 intr = intr_establish(IRQ_SSP2_ERROR, IPL_SDMMC, IST_LEVEL,
271 issp_error_intr, sc);
272 if (intr == NULL) {
273 aprint_error_dev(sc->sc_dev, "Unable to establish "
274 "interrupt for SSP2 ERROR\n");
275 return;
276 }
277 }
278
279 /* Allocate DMA handle. */
280 error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, 1, MAXPHYS,
281 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &sc->sc_dmamp);
282 if (error) {
283 aprint_error_dev(sc->sc_dev,
284 "Unable to allocate DMA handle\n");
285 return;
286 }
287
288 /* Allocate memory for DMA command chain. */
289 sc->sc_chnsiz = sizeof(struct apbdma_command) *
290 (MAX_TRANSFER_SIZE / SDMMC_SECTOR_SIZE);
291
292 error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_chnsiz, PAGE_SIZE, 0,
293 sc->sc_ds, 1, &sc->sc_rseg, BUS_DMA_NOWAIT);
294 if (error) {
295 aprint_error_dev(sc->sc_dev,
296 "Unable to allocate DMA memory\n");
297 return;
298 }
299
300 /* Initialize DMA channel. */
301 apbdma_chan_init(sc->sc_dmac, sc->dma_channel);
302
303 /* Map SSP bus space. */
304 if (bus_space_map(sc->sc_iot, aa->aa_addr, aa->aa_size, 0,
305 &sc->sc_hdl)) {
306 aprint_error_dev(sc->sc_dev, "Unable to map SSP bus space\n");
307 return;
308 }
309
310 issp_reset(sc);
311 issp_init(sc);
312
313 uint32_t issp_vers = SSP_RD(sc, HW_SSP_VERSION);
314 aprint_normal(": SSP Block v%" __PRIuBIT ".%" __PRIuBIT "\n",
315 __SHIFTOUT(issp_vers, HW_SSP_VERSION_MAJOR),
316 __SHIFTOUT(issp_vers, HW_SSP_VERSION_MINOR));
317
318 /* Attach sdmmc to ssp bus. */
319 saa.saa_busname = "sdmmc";
320 saa.saa_sct = &issp_functions;
321 saa.saa_spi_sct = NULL;
322 saa.saa_sch = sc;
323 saa.saa_dmat = aa->aa_dmat;
324 saa.saa_clkmin = SSP_CLK_MIN;
325 saa.saa_clkmax = SSP_CLK_MAX;
326 saa.saa_caps = SMC_CAPS_DMA | SMC_CAPS_4BIT_MODE |
327 SMC_CAPS_MULTI_SEG_DMA;
328
329 sc->sc_sdmmc = config_found(sc->sc_dev, &saa, NULL, CFARGS_NONE);
330 if (sc->sc_sdmmc == NULL) {
331 aprint_error_dev(sc->sc_dev, "unable to attach sdmmc\n");
332 return;
333 }
334
335 /* Device instance was successfully attached. */
336 if (aa->aa_addr == HW_SSP1_BASE)
337 ssp_attached |= SSP1_ATTACHED;
338 if (aa->aa_addr == HW_SSP2_BASE)
339 ssp_attached |= SSP2_ATTACHED;
340
341 return;
342 }
343
344 static int
issp_activate(device_t self,enum devact act)345 issp_activate(device_t self, enum devact act)
346 {
347 return EOPNOTSUPP;
348 }
349
350 /*
351 * sdmmc chip functions.
352 */
353 static int
issp_host_reset(sdmmc_chipset_handle_t sch)354 issp_host_reset(sdmmc_chipset_handle_t sch)
355 {
356 struct issp_softc *sc = sch;
357 issp_reset(sc);
358 return 0;
359 }
360
361 static uint32_t
issp_host_ocr(sdmmc_chipset_handle_t sch)362 issp_host_ocr(sdmmc_chipset_handle_t sch)
363 {
364 /* SSP supports at least 3.2 - 3.3v */
365 return MMC_OCR_3_2V_3_3V;
366 }
367
368 static int
issp_host_maxblklen(sdmmc_chipset_handle_t sch)369 issp_host_maxblklen(sdmmc_chipset_handle_t sch)
370 {
371 return 512;
372 }
373
374 /*
375 * Called at the beginning of sdmmc_task_thread to detect the presence
376 * of the SD card.
377 */
378 static int
issp_card_detect(sdmmc_chipset_handle_t sch)379 issp_card_detect(sdmmc_chipset_handle_t sch)
380 {
381 return 1;
382 }
383
384 static int
issp_write_protect(sdmmc_chipset_handle_t sch)385 issp_write_protect(sdmmc_chipset_handle_t sch)
386 {
387 /* The device is not write protected. */
388 return 0;
389 }
390
391 static int
issp_bus_power(sdmmc_chipset_handle_t sch,uint32_t ocr)392 issp_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
393 {
394 /* i.MX23 SSP does not support setting bus power. */
395 return 0;
396 }
397
398 static int
issp_bus_clock(sdmmc_chipset_handle_t sch,int clock)399 issp_bus_clock(sdmmc_chipset_handle_t sch, int clock)
400 {
401 struct issp_softc *sc = sch;
402 uint32_t sck;
403
404 if (clock < SSP_CLK_MIN)
405 sck = issp_set_sck(sc, SSP_CLK_MIN * 1000);
406 else
407 sck = issp_set_sck(sc, clock * 1000);
408
409 /* Notify user if we didn't get the exact clock rate from SSP that was
410 * requested from the SDMMC subsystem. */
411 if (sck != clock * 1000) {
412 sck = sck / 1000;
413 if (((sck) / 1000) != 0)
414 aprint_normal_dev(sc->sc_dev, "bus clock @ %u.%03u "
415 "MHz\n", sck / 1000, sck % 1000);
416 else
417 aprint_normal_dev(sc->sc_dev, "bus clock @ %u KHz\n",
418 sck % 1000);
419 }
420
421 return 0;
422 }
423
424 static int
issp_bus_width(sdmmc_chipset_handle_t sch,int width)425 issp_bus_width(sdmmc_chipset_handle_t sch, int width)
426 {
427 struct issp_softc *sc = sch;
428
429 switch(width) {
430 case(1):
431 sc->sc_bus_width = BUS_WIDTH_1_BIT;
432 break;
433 case(4):
434 sc->sc_bus_width = BUS_WIDTH_4_BIT;
435 break;
436 case(8):
437 sc->sc_bus_width = BUS_WIDTH_8_BIT;
438 break;
439 default:
440 return 1;
441 }
442
443 return 0;
444 }
445
446 static int
issp_bus_rod(sdmmc_chipset_handle_t sch,int rod)447 issp_bus_rod(sdmmc_chipset_handle_t sch, int rod)
448 {
449 /* Go to data transfer mode. */
450 return 0;
451 }
452
453 static void
issp_exec_command(sdmmc_chipset_handle_t sch,struct sdmmc_command * cmd)454 issp_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
455 {
456 issp_softc_t sc = sch;
457 void *dma_chain;
458 int error;
459
460 /* SSP does not support over 64k transfer size. */
461 if (cmd->c_data != NULL && cmd->c_datalen > MAX_TRANSFER_SIZE) {
462 aprint_error_dev(sc->sc_dev, "transfer size over %d: %d\n",
463 MAX_TRANSFER_SIZE, cmd->c_datalen);
464 cmd->c_error = ENODEV;
465 return;
466 }
467
468 /* Map dma_chain to point allocated previously allocated DMA chain. */
469 error = bus_dmamem_map(sc->sc_dmat, sc->sc_ds, 1, sc->sc_chnsiz,
470 &dma_chain, BUS_DMA_NOWAIT);
471 if (error) {
472 aprint_error_dev(sc->sc_dev, "bus_dmamem_map: %d\n", error);
473 cmd->c_error = error;
474 goto out;
475 }
476
477 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamp, dma_chain,
478 sc->sc_chnsiz, NULL, BUS_DMA_NOWAIT|BUS_DMA_WRITE);
479 if (error) {
480 aprint_error_dev(sc->sc_dev, "bus_dmamap_load: %d\n", error);
481 cmd->c_error = error;
482 goto dmamem_unmap;
483 }
484
485 memset(dma_chain, 0, sc->sc_chnsiz);
486
487 /* Setup DMA command chain.*/
488 if (cmd->c_data != NULL && (cmd->c_datalen / cmd->c_blklen) > 1) {
489 /* Multi block transfer. */
490 issp_create_dma_cmd_list_multi(sc, dma_chain, cmd);
491 } else if (cmd->c_data != NULL && cmd->c_datalen) {
492 /* Single block transfer. */
493 issp_create_dma_cmd_list_single(sc, dma_chain, cmd);
494 } else {
495 /* Only command, no data. */
496 issp_create_dma_cmd_list(sc, dma_chain, cmd);
497 }
498
499 /* Tell DMA controller where it can find just initialized DMA chain. */
500 apbdma_chan_set_chain(sc->sc_dmac, sc->dma_channel, sc->sc_dmamp);
501
502 /* Synchronize command chain before DMA controller accesses it. */
503 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamp, 0, sc->sc_chnsiz,
504 BUS_DMASYNC_PREWRITE);
505
506 sc->sc_state = SSP_STATE_DMA;
507 sc->sc_irq_error = 0;
508 sc->sc_dma_error = 0;
509 cmd->c_error = 0;
510
511 mutex_enter(&sc->sc_lock);
512
513 /* Run DMA command chain. */
514 apbdma_run(sc->sc_dmac, sc->dma_channel);
515
516 /* Wait DMA to complete. */
517 while (sc->sc_state == SSP_STATE_DMA)
518 cv_wait(&sc->sc_intr_cv, &sc->sc_lock);
519
520 mutex_exit(&sc->sc_lock);
521
522 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamp, 0, sc->sc_chnsiz,
523 BUS_DMASYNC_POSTWRITE);
524
525 if (sc->sc_dma_error) {
526 if (sc->sc_dma_error == DMA_IRQ_TERM) {
527 apbdma_chan_reset(sc->sc_dmac, sc->dma_channel);
528 cmd->c_error = sc->sc_dma_error;
529 }
530 else if (sc->sc_dma_error == DMA_IRQ_BUS_ERROR) {
531 aprint_error_dev(sc->sc_dev, "DMA_IRQ_BUS_ERROR: %d\n",
532 sc->sc_irq_error);
533 cmd->c_error = sc->sc_dma_error;
534 }
535 }
536
537 if (sc->sc_irq_error) {
538 /* Do not log RESP_TIMEOUT_IRQ error if bus width is 0 as it is
539 * expected during SD card initialization phase. */
540 if (sc->sc_bus_width) {
541 aprint_error_dev(sc->sc_dev, "SSP_ERROR_IRQ: %d\n",
542 sc->sc_irq_error);
543 }
544 else if(!(sc->sc_irq_error & HW_SSP_CTRL1_RESP_TIMEOUT_IRQ)) {
545 aprint_error_dev(sc->sc_dev, "SSP_ERROR_IRQ: %d\n",
546 sc->sc_irq_error);
547 }
548
549 /* Shift unsigned error code so it fits nicely to signed int. */
550 cmd->c_error = sc->sc_irq_error >> 8;
551 }
552
553 /* Check response from the card if such was requested. */
554 if (ISSET(cmd->c_flags, SCF_RSP_PRESENT)) {
555 cmd->c_resp[0] = SSP_RD(sc, HW_SSP_SDRESP0);
556 if (ISSET(cmd->c_flags, SCF_RSP_136)) {
557 cmd->c_resp[1] = SSP_RD(sc, HW_SSP_SDRESP1);
558 cmd->c_resp[2] = SSP_RD(sc, HW_SSP_SDRESP2);
559 cmd->c_resp[3] = SSP_RD(sc, HW_SSP_SDRESP3);
560 /*
561 * Remove CRC7 + LSB by rotating all bits right by 8 to
562 * make sdmmc __bitfield() happy.
563 */
564 cmd->c_resp[0] >>= 8; /* Remove CRC7 + LSB. */
565 cmd->c_resp[0] |= (0x000000FF & cmd->c_resp[1]) << 24;
566 cmd->c_resp[1] >>= 8;
567 cmd->c_resp[1] |= (0x000000FF & cmd->c_resp[2]) << 24;
568 cmd->c_resp[2] >>= 8;
569 cmd->c_resp[2] |= (0x000000FF & cmd->c_resp[3]) << 24;
570 cmd->c_resp[3] >>= 8;
571 }
572 }
573
574 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamp);
575 dmamem_unmap:
576 bus_dmamem_unmap(sc->sc_dmat, dma_chain, sc->sc_chnsiz);
577 out:
578
579 return;
580 }
581
582 static void
issp_card_enable_intr(sdmmc_chipset_handle_t sch,int irq)583 issp_card_enable_intr(sdmmc_chipset_handle_t sch, int irq)
584 {
585 struct issp_softc *sc = sch;
586 aprint_error_dev(sc->sc_dev, "issp_card_enable_intr not implemented\n");
587 return;
588 }
589
590 static void
issp_card_intr_ack(sdmmc_chipset_handle_t sch)591 issp_card_intr_ack(sdmmc_chipset_handle_t sch)
592 {
593 struct issp_softc *sc = sch;
594 aprint_error_dev(sc->sc_dev, "issp_card_intr_ack not implemented\n");
595 return;
596 }
597
598 /*
599 * Reset the SSP block.
600 *
601 * Inspired by i.MX23 RM "39.3.10 Correct Way to Soft Reset a Block"
602 */
603 static void
issp_reset(struct issp_softc * sc)604 issp_reset(struct issp_softc *sc)
605 {
606 unsigned int loop;
607
608 /* Prepare for soft-reset by making sure that SFTRST is not currently
609 * asserted. Also clear CLKGATE so we can wait for its assertion below.
610 */
611 SSP_WR(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_SFTRST);
612
613 /* Wait at least a microsecond for SFTRST to deassert. */
614 loop = 0;
615 while ((SSP_RD(sc, HW_SSP_CTRL0) & HW_SSP_CTRL0_SFTRST) ||
616 (loop < SSP_SOFT_RST_LOOP))
617 loop++;
618
619 /* Clear CLKGATE so we can wait for its assertion below. */
620 SSP_WR(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_CLKGATE);
621
622 /* Soft-reset the block. */
623 SSP_WR(sc, HW_SSP_CTRL0_SET, HW_SSP_CTRL0_SFTRST);
624
625 /* Wait until clock is in the gated state. */
626 while (!(SSP_RD(sc, HW_SSP_CTRL0) & HW_SSP_CTRL0_CLKGATE));
627
628 /* Bring block out of reset. */
629 SSP_WR(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_SFTRST);
630
631 loop = 0;
632 while ((SSP_RD(sc, HW_SSP_CTRL0) & HW_SSP_CTRL0_SFTRST) ||
633 (loop < SSP_SOFT_RST_LOOP))
634 loop++;
635
636 SSP_WR(sc, HW_SSP_CTRL0_CLR, HW_SSP_CTRL0_CLKGATE);
637
638 /* Wait until clock is in the NON-gated state. */
639 while (SSP_RD(sc, HW_SSP_CTRL0) & HW_SSP_CTRL0_CLKGATE);
640
641 return;
642 }
643
644 /*
645 * Initialize SSP controller to SD/MMC mode.
646 */
647 static void
issp_init(struct issp_softc * sc)648 issp_init(struct issp_softc *sc)
649 {
650 uint32_t reg;
651
652 reg = SSP_RD(sc, HW_SSP_CTRL0);
653 reg |= HW_SSP_CTRL0_ENABLE;
654
655 /* Initial data bus width is 1-bit. */
656 reg &= ~(HW_SSP_CTRL0_BUS_WIDTH);
657 reg |= __SHIFTIN(BUS_WIDTH_1_BIT, HW_SSP_CTRL0_BUS_WIDTH) |
658 HW_SSP_CTRL0_WAIT_FOR_IRQ | HW_SSP_CTRL0_ENABLE;
659 SSP_WR(sc, HW_SSP_CTRL0, reg);
660 sc->sc_bus_width = BUS_WIDTH_1_BIT;
661
662 /* Set data timeout. */
663 reg = SSP_RD(sc, HW_SSP_TIMING);
664 reg &= ~(HW_SSP_TIMING_TIMEOUT);
665 reg |= __SHIFTIN(DATA_TIMEOUT, HW_SSP_TIMING_TIMEOUT);
666 SSP_WR(sc, HW_SSP_TIMING, reg);
667
668 /* Set initial clock rate to minimum. */
669 issp_set_sck(sc, SSP_CLK_MIN * 1000);
670
671 reg = SSP_RD(sc, HW_SSP_CTRL1);
672 /* Enable all but SDIO IRQ's. */
673 reg |= HW_SSP_CTRL1_RESP_ERR_IRQ_EN |
674 HW_SSP_CTRL1_RESP_TIMEOUT_IRQ_EN |
675 HW_SSP_CTRL1_DATA_TIMEOUT_IRQ_EN |
676 HW_SSP_CTRL1_DATA_CRC_IRQ_EN |
677 HW_SSP_CTRL1_FIFO_UNDERRUN_EN |
678 HW_SSP_CTRL1_RECV_TIMEOUT_IRQ_EN |
679 HW_SSP_CTRL1_FIFO_OVERRUN_IRQ_EN;
680 reg |= HW_SSP_CTRL1_DMA_ENABLE;
681 reg |= HW_SSP_CTRL1_POLARITY;
682 /* Set SD/MMC mode and use use 8-bits per word. */
683 reg &= ~(HW_SSP_CTRL1_WORD_LENGTH | HW_SSP_CTRL1_SSP_MODE);
684 reg |= __SHIFTIN(0x7, HW_SSP_CTRL1_WORD_LENGTH) |
685 __SHIFTIN(0x3, HW_SSP_CTRL1_SSP_MODE);
686 SSP_WR(sc, HW_SSP_CTRL1, reg);
687
688 return;
689 }
690
691 /*
692 * Set SSP_SCK clock rate to the value specified in target.
693 *
694 * SSP_SCK is calculated as: SSP_CLK / (CLOCK_DIVIDE * (1 + CLOCK_RATE))
695 *
696 * issp_set_sck finds the most suitable CLOCK_DIVIDE and CLOCK_RATE register
697 * values for the target clock rate by iterating through all possible register
698 * values.
699 */
700 static uint32_t
issp_set_sck(struct issp_softc * sc,uint32_t target)701 issp_set_sck(struct issp_softc *sc, uint32_t target)
702 {
703 uint32_t newclk, found, reg;
704 uint8_t div, rate, d, r;
705
706 found = div = rate = 0;
707
708 for (d = 2; d < 254; d++) {
709 for (r = 0; r < 255; r++) {
710 newclk = SSP_CLK / (d * (1 + r));
711 if (newclk == target) {
712 found = newclk;
713 div = d;
714 rate = r;
715 goto out;
716 }
717 if (newclk < target && newclk > found) {
718 found = newclk;
719 div = d;
720 rate = r;
721 }
722 }
723 }
724 out:
725 reg = SSP_RD(sc, HW_SSP_TIMING);
726 reg &= ~(HW_SSP_TIMING_CLOCK_DIVIDE | HW_SSP_TIMING_CLOCK_RATE);
727 reg |= __SHIFTIN(div, HW_SSP_TIMING_CLOCK_DIVIDE) |
728 __SHIFTIN(rate, HW_SSP_TIMING_CLOCK_RATE);
729 SSP_WR(sc, HW_SSP_TIMING, reg);
730
731 return SSP_CLK / (div * (1 + rate));
732 }
733
734 /*
735 * IRQ from DMA.
736 */
737 static int
issp_dma_intr(void * arg)738 issp_dma_intr(void *arg)
739 {
740 issp_softc_t sc = arg;
741 unsigned int dma_err;
742
743 dma_err = apbdma_intr_status(sc->sc_dmac, sc->dma_channel);
744
745 if (dma_err) {
746 apbdma_ack_error_intr(sc->sc_dmac, sc->dma_channel);
747 } else {
748 apbdma_ack_intr(sc->sc_dmac, sc->dma_channel);
749 }
750
751 mutex_enter(&sc->sc_lock);
752
753 sc->sc_dma_error = dma_err;
754 sc->sc_state = SSP_STATE_IDLE;
755
756 /* Signal thread that interrupt was handled. */
757 cv_signal(&sc->sc_intr_cv);
758
759 mutex_exit(&sc->sc_lock);
760
761 /* Return 1 to acknowledge IRQ. */
762 return 1;
763 }
764
765 /*
766 * IRQ from SSP block.
767 *
768 * When SSP receives IRQ it terminates ongoing DMA transfer by issuing DMATERM
769 * signal to DMA block.
770 */
771 static int
issp_error_intr(void * arg)772 issp_error_intr(void *arg)
773 {
774 issp_softc_t sc = arg;
775
776 mutex_enter(&sc->sc_lock);
777
778 sc->sc_irq_error =
779 SSP_RD(sc, HW_SSP_CTRL1) & HW_SSP_CTRL1_IRQ_MASK;
780
781 issp_ack_intr(sc);
782
783 mutex_exit(&sc->sc_lock);
784
785 /* Return 1 to acknowledge IRQ. */
786 return 1;
787 }
788
789 /*
790 * Acknowledge SSP error IRQ.
791 */
792 static void
issp_ack_intr(struct issp_softc * sc)793 issp_ack_intr(struct issp_softc *sc)
794 {
795
796 /* Acknowledge all IRQ's. */
797 SSP_WR(sc, HW_SSP_CTRL1_CLR, HW_SSP_CTRL1_IRQ_MASK);
798
799 return;
800 }
801
802 /*
803 * Set up multi block DMA transfer.
804 */
805 static void
issp_create_dma_cmd_list_multi(issp_softc_t sc,void * dma_chain,struct sdmmc_command * cmd)806 issp_create_dma_cmd_list_multi(issp_softc_t sc, void *dma_chain,
807 struct sdmmc_command *cmd)
808 {
809 apbdma_command_t dma_cmd;
810 int blocks;
811 int nblk;
812
813 blocks = cmd->c_datalen / cmd->c_blklen;
814 nblk = 0;
815 dma_cmd = dma_chain;
816
817 /* HEAD */
818 apbdma_cmd_buf(&dma_cmd[nblk], cmd->c_blklen * nblk, cmd->c_dmamap);
819 apbdma_cmd_chain(&dma_cmd[nblk], &dma_cmd[nblk+1], dma_chain,
820 sc->sc_dmamp);
821
822 dma_cmd[nblk].control =
823 __SHIFTIN(cmd->c_blklen, APBDMA_CMD_XFER_COUNT) |
824 __SHIFTIN(3, APBDMA_CMD_CMDPIOWORDS) | APBDMA_CMD_HALTONTERMINATE |
825 APBDMA_CMD_CHAIN;
826
827 if (!ISSET(cmd->c_flags, SCF_RSP_CRC)) {
828 dma_cmd[nblk].pio_words[PIO_WORD_CTRL0] |=
829 HW_SSP_CTRL0_IGNORE_CRC;
830 }
831
832 dma_cmd[nblk].pio_words[PIO_WORD_CTRL0] |= HW_SSP_CTRL0_DATA_XFER |
833 __SHIFTIN(sc->sc_bus_width, HW_SSP_CTRL0_BUS_WIDTH) |
834 HW_SSP_CTRL0_WAIT_FOR_IRQ |
835 __SHIFTIN(cmd->c_datalen, HW_SSP_CTRL0_XFER_COUNT);
836
837 if (ISSET(cmd->c_flags, SCF_RSP_PRESENT)) {
838 dma_cmd[nblk].pio_words[PIO_WORD_CTRL0] |=
839 HW_SSP_CTRL0_GET_RESP;
840 if (ISSET(cmd->c_flags, SCF_RSP_136)) {
841 dma_cmd[nblk].pio_words[PIO_WORD_CTRL0] |=
842 HW_SSP_CTRL0_LONG_RESP;
843 }
844 }
845
846 dma_cmd[nblk].pio_words[PIO_WORD_CTRL0] |= HW_SSP_CTRL0_ENABLE;
847
848 dma_cmd[nblk].pio_words[PIO_WORD_CMD0] =
849 __SHIFTIN(ffs(cmd->c_blklen) - 1, HW_SSP_CMD0_BLOCK_SIZE) |
850 __SHIFTIN(blocks - 1, HW_SSP_CMD0_BLOCK_COUNT) |
851 __SHIFTIN(cmd->c_opcode, HW_SSP_CMD0_CMD);
852
853 dma_cmd[nblk].pio_words[PIO_WORD_CMD1] = cmd->c_arg;
854
855 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
856 dma_cmd[nblk].control |=
857 __SHIFTIN(APBDMA_CMD_DMA_WRITE, APBDMA_CMD_COMMAND);
858 dma_cmd[nblk].pio_words[PIO_WORD_CTRL0] |= HW_SSP_CTRL0_READ;
859 } else {
860 dma_cmd[nblk].control |=
861 __SHIFTIN(APBDMA_CMD_DMA_READ, APBDMA_CMD_COMMAND);
862 }
863
864 nblk++;
865
866 /* BODY: Build commands for blocks between head and tail, if any. */
867 for (; nblk < blocks - 1; nblk++) {
868
869 apbdma_cmd_buf(&dma_cmd[nblk], cmd->c_blklen * nblk,
870 cmd->c_dmamap);
871
872 apbdma_cmd_chain(&dma_cmd[nblk], &dma_cmd[nblk+1], dma_chain,
873 sc->sc_dmamp);
874
875 dma_cmd[nblk].control =
876 __SHIFTIN(cmd->c_blklen, APBDMA_CMD_XFER_COUNT) |
877 APBDMA_CMD_HALTONTERMINATE | APBDMA_CMD_CHAIN;
878
879 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
880 dma_cmd[nblk].control |=
881 __SHIFTIN(APBDMA_CMD_DMA_WRITE,
882 APBDMA_CMD_COMMAND);
883 } else {
884 dma_cmd[nblk].control |=
885 __SHIFTIN(APBDMA_CMD_DMA_READ, APBDMA_CMD_COMMAND);
886 }
887 }
888
889 /* TAIL
890 *
891 * TODO: Send CMD12/STOP with last DMA command to support
892 * SMC_CAPS_AUTO_STOP.
893 */
894 apbdma_cmd_buf(&dma_cmd[nblk], cmd->c_blklen * nblk, cmd->c_dmamap);
895 /* next = NULL */
896 dma_cmd[nblk].control =
897 __SHIFTIN(cmd->c_blklen, APBDMA_CMD_XFER_COUNT) |
898 APBDMA_CMD_HALTONTERMINATE | APBDMA_CMD_WAIT4ENDCMD |
899 APBDMA_CMD_SEMAPHORE | APBDMA_CMD_IRQONCMPLT;
900
901 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
902 dma_cmd[nblk].control |= __SHIFTIN(APBDMA_CMD_DMA_WRITE,
903 APBDMA_CMD_COMMAND);
904 } else {
905 dma_cmd[nblk].control |= __SHIFTIN(APBDMA_CMD_DMA_READ,
906 APBDMA_CMD_COMMAND);
907 }
908
909 return;
910 }
911
912 /*
913 * Set up single block DMA transfer.
914 */
915 static void
issp_create_dma_cmd_list_single(issp_softc_t sc,void * dma_chain,struct sdmmc_command * cmd)916 issp_create_dma_cmd_list_single(issp_softc_t sc, void *dma_chain,
917 struct sdmmc_command *cmd)
918 {
919 apbdma_command_t dma_cmd;
920
921 dma_cmd = dma_chain;
922
923 dma_cmd[0].control = __SHIFTIN(cmd->c_datalen, APBDMA_CMD_XFER_COUNT) |
924 __SHIFTIN(3, APBDMA_CMD_CMDPIOWORDS) |
925 APBDMA_CMD_HALTONTERMINATE | APBDMA_CMD_WAIT4ENDCMD |
926 APBDMA_CMD_SEMAPHORE | APBDMA_CMD_IRQONCMPLT;
927
928 /* Transfer single block to the beginning of the DMA buffer. */
929 apbdma_cmd_buf(&dma_cmd[0], 0, cmd->c_dmamap);
930
931 if (!ISSET(cmd->c_flags, SCF_RSP_CRC)) {
932 dma_cmd[0].pio_words[PIO_WORD_CTRL0] |=
933 HW_SSP_CTRL0_IGNORE_CRC;
934 }
935
936 dma_cmd[0].pio_words[PIO_WORD_CTRL0] |=
937 HW_SSP_CTRL0_DATA_XFER |
938 __SHIFTIN(sc->sc_bus_width, HW_SSP_CTRL0_BUS_WIDTH) |
939 HW_SSP_CTRL0_WAIT_FOR_IRQ |
940 __SHIFTIN(cmd->c_datalen, HW_SSP_CTRL0_XFER_COUNT);
941
942 if (ISSET(cmd->c_flags, SCF_RSP_PRESENT)) {
943 dma_cmd[0].pio_words[PIO_WORD_CTRL0] |= HW_SSP_CTRL0_GET_RESP;
944 if (ISSET(cmd->c_flags, SCF_RSP_136)) {
945 dma_cmd[0].pio_words[PIO_WORD_CTRL0] |=
946 HW_SSP_CTRL0_LONG_RESP;
947 }
948 }
949
950 dma_cmd[0].pio_words[PIO_WORD_CTRL0] |= HW_SSP_CTRL0_ENABLE;
951
952 dma_cmd[0].pio_words[PIO_WORD_CMD0] =
953 HW_SSP_CMD0_APPEND_8CYC |
954 __SHIFTIN(cmd->c_opcode, HW_SSP_CMD0_CMD);
955 dma_cmd[0].pio_words[PIO_WORD_CMD1] = cmd->c_arg;
956
957 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
958 dma_cmd[0].control |=
959 __SHIFTIN(APBDMA_CMD_DMA_WRITE, APBDMA_CMD_COMMAND);
960 dma_cmd[0].pio_words[PIO_WORD_CTRL0] |= HW_SSP_CTRL0_READ;
961 } else {
962 dma_cmd[0].control |=
963 __SHIFTIN(APBDMA_CMD_DMA_READ, APBDMA_CMD_COMMAND);
964 }
965
966 return;
967 }
968
969 /*
970 * Do DMA PIO (issue CMD). No block transfers.
971 */
972 static void
issp_create_dma_cmd_list(issp_softc_t sc,void * dma_chain,struct sdmmc_command * cmd)973 issp_create_dma_cmd_list(issp_softc_t sc, void *dma_chain,
974 struct sdmmc_command *cmd)
975 {
976 apbdma_command_t dma_cmd;
977
978 dma_cmd = dma_chain;
979
980 dma_cmd[0].control = __SHIFTIN(3, APBDMA_CMD_CMDPIOWORDS) |
981 APBDMA_CMD_HALTONTERMINATE | APBDMA_CMD_WAIT4ENDCMD |
982 APBDMA_CMD_SEMAPHORE | APBDMA_CMD_IRQONCMPLT |
983 __SHIFTIN(APBDMA_CMD_NO_DMA_XFER, APBDMA_CMD_COMMAND);
984
985 if (!ISSET(cmd->c_flags, SCF_RSP_CRC)) {
986 dma_cmd[0].pio_words[PIO_WORD_CTRL0] |=
987 HW_SSP_CTRL0_IGNORE_CRC;
988 }
989
990 dma_cmd[0].pio_words[PIO_WORD_CTRL0] |=
991 __SHIFTIN(sc->sc_bus_width, HW_SSP_CTRL0_BUS_WIDTH) |
992 HW_SSP_CTRL0_WAIT_FOR_IRQ;
993
994 if (ISSET(cmd->c_flags, SCF_RSP_PRESENT)) {
995 dma_cmd[0].pio_words[PIO_WORD_CTRL0] |= HW_SSP_CTRL0_GET_RESP;
996 if (ISSET(cmd->c_flags, SCF_RSP_136)) {
997 dma_cmd[0].pio_words[PIO_WORD_CTRL0] |=
998 HW_SSP_CTRL0_LONG_RESP;
999 }
1000 }
1001
1002 dma_cmd[0].pio_words[PIO_WORD_CTRL0] |= HW_SSP_CTRL0_ENABLE;
1003
1004 dma_cmd[0].pio_words[PIO_WORD_CMD0] =
1005 __SHIFTIN(cmd->c_opcode, HW_SSP_CMD0_CMD);
1006 dma_cmd[0].pio_words[PIO_WORD_CMD1] = cmd->c_arg;
1007
1008 return;
1009 }
1010