bcm2835_sdhost.c revision 1.1 1 /* $NetBSD: bcm2835_sdhost.c,v 1.1 2017/07/30 16:54:36 jmcneill Exp $ */
2
3 /*-
4 * Copyright (c) 2017 Jared McNeill <jmcneill (at) invisible.ca>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: bcm2835_sdhost.c,v 1.1 2017/07/30 16:54:36 jmcneill Exp $");
31
32 #include <sys/param.h>
33 #include <sys/bus.h>
34 #include <sys/device.h>
35 #include <sys/intr.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/gpio.h>
39
40 #include <arm/broadcom/bcm2835reg.h>
41 #include <arm/broadcom/bcm_amba.h>
42 #include <arm/broadcom/bcm2835_dmac.h>
43
44 #include <dev/sdmmc/sdmmcvar.h>
45 #include <dev/sdmmc/sdmmcchip.h>
46 #include <dev/sdmmc/sdmmc_ioreg.h>
47
48 #define SDCMD 0x00
49 #define SDCMD_NEW __BIT(15)
50 #define SDCMD_FAIL __BIT(14)
51 #define SDCMD_BUSY __BIT(11)
52 #define SDCMD_NORESP __BIT(10)
53 #define SDCMD_LONGRESP __BIT(9)
54 #define SDCMD_WRITE __BIT(7)
55 #define SDCMD_READ __BIT(6)
56 #define SDARG 0x04
57 #define SDTOUT 0x08
58 #define SDTOUT_DEFAULT 0xf00000
59 #define SDCDIV 0x0c
60 #define SDCDIV_MASK __BITS(10,0)
61 #define SDRSP0 0x10
62 #define SDRSP1 0x14
63 #define SDRSP2 0x18
64 #define SDRSP3 0x1c
65 #define SDHSTS 0x20
66 #define SDHSTS_BUSY __BIT(10)
67 #define SDHSTS_BLOCK __BIT(9)
68 #define SDHSTS_SDIO __BIT(8)
69 #define SDHSTS_REW_TO __BIT(7)
70 #define SDHSTS_CMD_TO __BIT(6)
71 #define SDHSTS_CRC16_E __BIT(5)
72 #define SDHSTS_CRC7_E __BIT(4)
73 #define SDHSTS_FIFO_E __BIT(3)
74 #define SDHSTS_DATA __BIT(0)
75 #define SDVDD 0x30
76 #define SDVDD_POWER __BIT(0)
77 #define SDEDM 0x34
78 #define SDEDM_RD_FIFO __BITS(18,14)
79 #define SDEDM_WR_FIFO __BITS(13,9)
80 #define SDHCFG 0x38
81 #define SDHCFG_BUSY_EN __BIT(10)
82 #define SDHCFG_BLOCK_EN __BIT(8)
83 #define SDHCFG_SDIO_EN __BIT(5)
84 #define SDHCFG_DATA_EN __BIT(4)
85 #define SDHCFG_SLOW __BIT(3)
86 #define SDHCFG_WIDE_EXT __BIT(2)
87 #define SDHCFG_WIDE_INT __BIT(1)
88 #define SDHCFG_REL_CMD __BIT(0)
89 #define SDHBCT 0x3c
90 #define SDDATA 0x40
91 #define SDHBLC 0x50
92
93 struct sdhost_softc;
94
95 static int sdhost_match(device_t, cfdata_t, void *);
96 static void sdhost_attach(device_t, device_t, void *);
97 static void sdhost_attach_i(device_t);
98
99 static int sdhost_intr(void *);
100 static int sdhost_dma_setup(struct sdhost_softc *);
101 static void sdhost_dma_done(uint32_t, uint32_t, void *);
102
103 static int sdhost_host_reset(sdmmc_chipset_handle_t);
104 static uint32_t sdhost_host_ocr(sdmmc_chipset_handle_t);
105 static int sdhost_host_maxblklen(sdmmc_chipset_handle_t);
106 static int sdhost_card_detect(sdmmc_chipset_handle_t);
107 static int sdhost_write_protect(sdmmc_chipset_handle_t);
108 static int sdhost_bus_power(sdmmc_chipset_handle_t, uint32_t);
109 static int sdhost_bus_clock(sdmmc_chipset_handle_t, int, bool);
110 static int sdhost_bus_width(sdmmc_chipset_handle_t, int);
111 static int sdhost_bus_rod(sdmmc_chipset_handle_t, int);
112 static void sdhost_exec_command(sdmmc_chipset_handle_t,
113 struct sdmmc_command *);
114 static void sdhost_card_enable_intr(sdmmc_chipset_handle_t, int);
115 static void sdhost_card_intr_ack(sdmmc_chipset_handle_t);
116
117 void sdhost_dump_regs(void);
118
119 static struct sdmmc_chip_functions sdhost_chip_functions = {
120 .host_reset = sdhost_host_reset,
121 .host_ocr = sdhost_host_ocr,
122 .host_maxblklen = sdhost_host_maxblklen,
123 .card_detect = sdhost_card_detect,
124 .write_protect = sdhost_write_protect,
125 .bus_power = sdhost_bus_power,
126 .bus_clock_ddr = sdhost_bus_clock,
127 .bus_width = sdhost_bus_width,
128 .bus_rod = sdhost_bus_rod,
129 .exec_command = sdhost_exec_command,
130 .card_enable_intr = sdhost_card_enable_intr,
131 .card_intr_ack = sdhost_card_intr_ack,
132 };
133
134 struct sdhost_softc {
135 device_t sc_dev;
136 bus_space_tag_t sc_bst;
137 bus_space_handle_t sc_bsh;
138 bus_dma_tag_t sc_dmat;
139
140 bus_addr_t sc_addr;
141
142 void *sc_ih;
143 kmutex_t sc_intr_lock;
144 kcondvar_t sc_intr_cv;
145 kcondvar_t sc_dma_cv;
146
147 u_int sc_rate;
148
149 int sc_mmc_width;
150 int sc_mmc_present;
151
152 device_t sc_sdmmc_dev;
153
154 struct bcm_dmac_channel *sc_dmac;
155
156 bus_dmamap_t sc_dmamap;
157 bus_dma_segment_t sc_segs[1];
158 struct bcm_dmac_conblk *sc_cblk;
159
160 uint32_t sc_intr_hsts;
161
162 uint32_t sc_dma_status;
163 uint32_t sc_dma_error;
164 };
165
166 CFATTACH_DECL_NEW(bcmsdhost, sizeof(struct sdhost_softc),
167 sdhost_match, sdhost_attach, NULL, NULL);
168
169 #define SDHOST_WRITE(sc, reg, val) \
170 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
171 #define SDHOST_READ(sc, reg) \
172 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
173
174 static int
175 sdhost_match(device_t parent, cfdata_t cf, void *aux)
176 {
177 struct amba_attach_args * const aaa = aux;
178
179 return strcmp(aaa->aaa_name, "sdhost") == 0;
180 }
181
182 static void
183 sdhost_attach(device_t parent, device_t self, void *aux)
184 {
185 struct sdhost_softc * const sc = device_private(self);
186 struct amba_attach_args * const aaa = aux;
187 prop_dictionary_t dict = device_properties(self);
188
189 sc->sc_dev = self;
190 sc->sc_bst = aaa->aaa_iot;
191 sc->sc_dmat = aaa->aaa_dmat;
192 sc->sc_addr = aaa->aaa_addr;
193 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_BIO);
194 cv_init(&sc->sc_intr_cv, "sdhostintr");
195 cv_init(&sc->sc_dma_cv, "sdhostdma");
196
197 if (bus_space_map(sc->sc_bst, aaa->aaa_addr, aaa->aaa_size, 0,
198 &sc->sc_bsh) != 0) {
199 aprint_error(": couldn't map registers\n");
200 return;
201 }
202
203 aprint_naive("\n");
204 aprint_normal(": SD HOST controller\n");
205
206 sdhost_dump_regs();
207
208 prop_dictionary_get_uint32(dict, "frequency", &sc->sc_rate);
209 if (sc->sc_rate == 0) {
210 aprint_error_dev(self, "couldn't get clock frequency\n");
211 return;
212 }
213
214 aprint_normal_dev(self, "ref freq %u Hz\n", sc->sc_rate);
215
216 if (sdhost_dma_setup(sc) != 0) {
217 aprint_error_dev(self, "failed to setup DMA\n");
218 return;
219 }
220
221 sc->sc_ih = intr_establish(aaa->aaa_intr, IPL_SDMMC, IST_LEVEL,
222 sdhost_intr, sc);
223 if (sc->sc_ih == NULL) {
224 aprint_error_dev(self, "failed to establish interrupt %d\n",
225 aaa->aaa_intr);
226 return;
227 }
228 aprint_normal_dev(self, "interrupting on intr %d\n", aaa->aaa_intr);
229
230 config_interrupts(self, sdhost_attach_i);
231 }
232
233 static int
234 sdhost_dma_setup(struct sdhost_softc *sc)
235 {
236 int error, rseg;
237
238 sc->sc_dmac = bcm_dmac_alloc(BCM_DMAC_TYPE_NORMAL, IPL_SDMMC,
239 sdhost_dma_done, sc);
240 if (sc->sc_dmac == NULL)
241 return ENXIO;
242
243 error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE,
244 PAGE_SIZE, sc->sc_segs, 1, &rseg, BUS_DMA_WAITOK);
245 if (error)
246 return error;
247
248 error = bus_dmamem_map(sc->sc_dmat, sc->sc_segs, rseg, PAGE_SIZE,
249 (void **)&sc->sc_cblk, BUS_DMA_WAITOK);
250 if (error)
251 return error;
252
253 memset(sc->sc_cblk, 0, PAGE_SIZE);
254
255 error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0,
256 BUS_DMA_WAITOK, &sc->sc_dmamap);
257 if (error)
258 return error;
259
260 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_cblk,
261 PAGE_SIZE, NULL, BUS_DMA_WAITOK|BUS_DMA_WRITE);
262 if (error)
263 return error;
264
265 return 0;
266 }
267
268 static void
269 sdhost_attach_i(device_t self)
270 {
271 struct sdhost_softc *sc = device_private(self);
272 struct sdmmcbus_attach_args saa;
273
274 sdhost_host_reset(sc);
275 sdhost_bus_width(sc, 1);
276 sdhost_bus_clock(sc, 400, false);
277
278 memset(&saa, 0, sizeof(saa));
279 saa.saa_busname = "sdmmc";
280 saa.saa_sct = &sdhost_chip_functions;
281 saa.saa_sch = sc;
282 saa.saa_dmat = sc->sc_dmat;
283 saa.saa_clkmin = 400;
284 saa.saa_clkmax = 50000;
285 saa.saa_caps = SMC_CAPS_DMA |
286 SMC_CAPS_MULTI_SEG_DMA |
287 SMC_CAPS_SD_HIGHSPEED |
288 SMC_CAPS_MMC_HIGHSPEED |
289 SMC_CAPS_4BIT_MODE;
290
291 sc->sc_sdmmc_dev = config_found(self, &saa, NULL);
292 }
293
294 static int
295 sdhost_intr(void *priv)
296 {
297 struct sdhost_softc * const sc = priv;
298
299 mutex_enter(&sc->sc_intr_lock);
300 const uint32_t hsts = SDHOST_READ(sc, SDHSTS);
301 if (!hsts) {
302 mutex_exit(&sc->sc_intr_lock);
303 return 0;
304 }
305 SDHOST_WRITE(sc, SDHSTS, hsts);
306
307 #ifdef SDHOST_DEBUG
308 device_printf(sc->sc_dev, "mmc intr hsts %#x\n", hsts);
309 #endif
310
311 if (hsts) {
312 sc->sc_intr_hsts |= hsts;
313 cv_broadcast(&sc->sc_intr_cv);
314 }
315
316 mutex_exit(&sc->sc_intr_lock);
317
318 return 1;
319 }
320
321 static int
322 sdhost_dma_transfer(struct sdhost_softc *sc, struct sdmmc_command *cmd)
323 {
324 size_t seg;
325 int error;
326
327 KASSERT(mutex_owned(&sc->sc_intr_lock));
328
329 for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) {
330 sc->sc_cblk[seg].cb_ti =
331 __SHIFTIN(13, DMAC_TI_PERMAP); /* SD HOST */
332 sc->sc_cblk[seg].cb_txfr_len =
333 cmd->c_dmamap->dm_segs[seg].ds_len;
334 /*
335 * All transfers are assumed to be multiples of 32-bits.
336 */
337 KASSERTMSG((sc->sc_cblk[seg].cb_txfr_len & 0x3) == 0,
338 "seg %zu len %d", seg, sc->sc_cblk[seg].cb_txfr_len);
339 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
340 sc->sc_cblk[seg].cb_ti |= DMAC_TI_DEST_INC;
341 /*
342 * Use 128-bit mode if transfer is a multiple of
343 * 16-bytes.
344 */
345 if ((sc->sc_cblk[seg].cb_txfr_len & 0xf) == 0)
346 sc->sc_cblk[seg].cb_ti |= DMAC_TI_DEST_WIDTH;
347 sc->sc_cblk[seg].cb_ti |= DMAC_TI_SRC_DREQ;
348 sc->sc_cblk[seg].cb_source_ad =
349 sc->sc_addr + SDDATA;
350 sc->sc_cblk[seg].cb_dest_ad =
351 cmd->c_dmamap->dm_segs[seg].ds_addr;
352 } else {
353 sc->sc_cblk[seg].cb_ti |= DMAC_TI_SRC_INC;
354 /*
355 * Use 128-bit mode if transfer is a multiple of
356 * 16-bytes.
357 */
358 if ((sc->sc_cblk[seg].cb_txfr_len & 0xf) == 0)
359 sc->sc_cblk[seg].cb_ti |= DMAC_TI_SRC_WIDTH;
360 sc->sc_cblk[seg].cb_ti |= DMAC_TI_DEST_DREQ;
361 sc->sc_cblk[seg].cb_ti |= DMAC_TI_WAIT_RESP;
362 sc->sc_cblk[seg].cb_source_ad =
363 cmd->c_dmamap->dm_segs[seg].ds_addr;
364 sc->sc_cblk[seg].cb_dest_ad =
365 sc->sc_addr + SDDATA;
366 }
367 sc->sc_cblk[seg].cb_stride = 0;
368 if (seg == cmd->c_dmamap->dm_nsegs - 1) {
369 sc->sc_cblk[seg].cb_ti |= DMAC_TI_INTEN;
370 sc->sc_cblk[seg].cb_nextconbk = 0;
371 } else {
372 sc->sc_cblk[seg].cb_nextconbk =
373 sc->sc_dmamap->dm_segs[0].ds_addr +
374 sizeof(struct bcm_dmac_conblk) * (seg+1);
375 }
376 sc->sc_cblk[seg].cb_padding[0] = 0;
377 sc->sc_cblk[seg].cb_padding[1] = 0;
378 }
379
380 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
381 sc->sc_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE);
382
383 error = 0;
384
385 sc->sc_dma_status = 0;
386 sc->sc_dma_error = 0;
387
388 bcm_dmac_set_conblk_addr(sc->sc_dmac,
389 sc->sc_dmamap->dm_segs[0].ds_addr);
390 error = bcm_dmac_transfer(sc->sc_dmac);
391 if (error)
392 return error;
393
394 return 0;
395 }
396
397 static int
398 sdhost_dma_wait(struct sdhost_softc *sc, struct sdmmc_command *cmd)
399 {
400 int error = 0;
401
402 while (sc->sc_dma_status == 0 && sc->sc_dma_error == 0) {
403 error = cv_timedwait(&sc->sc_dma_cv, &sc->sc_intr_lock, hz*5);
404 if (error == EWOULDBLOCK) {
405 device_printf(sc->sc_dev, "transfer timeout!\n");
406 bcm_dmac_halt(sc->sc_dmac);
407 error = ETIMEDOUT;
408 break;
409 }
410 }
411
412 if (sc->sc_dma_status & DMAC_CS_END) {
413 cmd->c_resid = 0;
414 error = 0;
415 } else {
416 error = EIO;
417 }
418
419 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
420 sc->sc_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
421
422 return error;
423 }
424
425 static void
426 sdhost_dma_done(uint32_t status, uint32_t error, void *arg)
427 {
428 struct sdhost_softc * const sc = arg;
429
430 if (status != (DMAC_CS_INT|DMAC_CS_END))
431 device_printf(sc->sc_dev, "dma status %#x error %#x\n",
432 status, error);
433
434 mutex_enter(&sc->sc_intr_lock);
435 sc->sc_dma_status = status;
436 sc->sc_dma_error = error;
437 cv_broadcast(&sc->sc_dma_cv);
438 mutex_exit(&sc->sc_intr_lock);
439 }
440
441 static int
442 sdhost_wait_idle(struct sdhost_softc *sc, int timeout)
443 {
444 int retry;
445
446 KASSERT(mutex_owned(&sc->sc_intr_lock));
447
448 retry = timeout * 1000;
449
450 while (--retry > 0) {
451 const uint32_t cmd = SDHOST_READ(sc, SDCMD);
452 if ((cmd & SDCMD_NEW) == 0)
453 return 0;
454 delay(1);
455 }
456
457 return ETIMEDOUT;
458 }
459
460 static int
461 sdhost_host_reset(sdmmc_chipset_handle_t sch)
462 {
463 struct sdhost_softc * const sc = sch;
464 uint32_t edm;
465
466 SDHOST_WRITE(sc, SDVDD, 0);
467 SDHOST_WRITE(sc, SDCMD, 0);
468 SDHOST_WRITE(sc, SDARG, 0);
469 SDHOST_WRITE(sc, SDTOUT, SDTOUT_DEFAULT);
470 SDHOST_WRITE(sc, SDCDIV, 0);
471 SDHOST_WRITE(sc, SDHSTS, SDHOST_READ(sc, SDHSTS));
472 SDHOST_WRITE(sc, SDHCFG, 0);
473 SDHOST_WRITE(sc, SDHBCT, 0);
474 SDHOST_WRITE(sc, SDHBLC, 0);
475
476 edm = SDHOST_READ(sc, SDEDM);
477 edm &= ~(SDEDM_RD_FIFO|SDEDM_WR_FIFO);
478 edm |= __SHIFTIN(4, SDEDM_RD_FIFO);
479 edm |= __SHIFTIN(4, SDEDM_WR_FIFO);
480 SDHOST_WRITE(sc, SDEDM, edm);
481 delay(20000);
482 SDHOST_WRITE(sc, SDVDD, SDVDD_POWER);
483 delay(20000);
484
485 SDHOST_WRITE(sc, SDHCFG, 0);
486 SDHOST_WRITE(sc, SDCDIV, SDCDIV_MASK);
487
488 return 0;
489 }
490
491 static uint32_t
492 sdhost_host_ocr(sdmmc_chipset_handle_t sch)
493 {
494 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V | MMC_OCR_HCS;
495 }
496
497 static int
498 sdhost_host_maxblklen(sdmmc_chipset_handle_t sch)
499 {
500 return 8192;
501 }
502
503 static int
504 sdhost_card_detect(sdmmc_chipset_handle_t sch)
505 {
506 return 1; /* XXX */
507 }
508
509 static int
510 sdhost_write_protect(sdmmc_chipset_handle_t sch)
511 {
512 return 0; /* no write protect pin, assume rw */
513 }
514
515 static int
516 sdhost_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
517 {
518 return 0;
519 }
520
521 static int
522 sdhost_bus_clock(sdmmc_chipset_handle_t sch, int freq, bool ddr)
523 {
524 struct sdhost_softc * const sc = sch;
525 u_int target_rate = freq * 1000;
526 int div;
527
528 if (freq == 0)
529 div = SDCDIV_MASK;
530 else {
531 div = sc->sc_rate / target_rate;
532 if (div < 2)
533 div = 2;
534 if ((sc->sc_rate / div) > target_rate)
535 div++;
536 div -= 2;
537 if (div > SDCDIV_MASK)
538 div = SDCDIV_MASK;
539 }
540
541 SDHOST_WRITE(sc, SDCDIV, div);
542
543 return 0;
544 }
545
546 static int
547 sdhost_bus_width(sdmmc_chipset_handle_t sch, int width)
548 {
549 struct sdhost_softc * const sc = sch;
550 uint32_t hcfg;
551
552 #ifdef SDHOST_DEBUG
553 aprint_normal_dev(sc->sc_dev, "width = %d\n", width);
554 #endif
555
556 hcfg = SDHOST_READ(sc, SDHCFG);
557 if (width == 4)
558 hcfg |= SDHCFG_WIDE_EXT;
559 else
560 hcfg &= ~SDHCFG_WIDE_EXT;
561 hcfg |= (SDHCFG_WIDE_INT | SDHCFG_SLOW);
562 SDHOST_WRITE(sc, SDHCFG, hcfg);
563
564 return 0;
565 }
566
567 static int
568 sdhost_bus_rod(sdmmc_chipset_handle_t sch, int on)
569 {
570 return -1;
571 }
572
573 static void
574 sdhost_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
575 {
576 struct sdhost_softc * const sc = sch;
577 uint32_t cmdval, hcfg;
578 u_int nblks;
579
580 #ifdef SDHOST_DEBUG
581 aprint_normal_dev(sc->sc_dev,
582 "opcode %d flags 0x%x data %p datalen %d blklen %d\n",
583 cmd->c_opcode, cmd->c_flags, cmd->c_data, cmd->c_datalen,
584 cmd->c_blklen);
585 #endif
586
587 mutex_enter(&sc->sc_intr_lock);
588
589 hcfg = SDHOST_READ(sc, SDHCFG);
590 SDHOST_WRITE(sc, SDHCFG, hcfg | SDHCFG_BUSY_EN);
591
592 sc->sc_intr_hsts = 0;
593
594 cmd->c_error = sdhost_wait_idle(sc, 5000);
595 if (cmd->c_error != 0) {
596 #ifdef SDHOST_DEBUG
597 device_printf(sc->sc_dev, "device is busy\n");
598 #endif
599 goto done;
600 }
601
602 cmdval = SDCMD_NEW;
603 if (!ISSET(cmd->c_flags, SCF_RSP_PRESENT))
604 cmdval |= SDCMD_NORESP;
605 if (ISSET(cmd->c_flags, SCF_RSP_136))
606 cmdval |= SDCMD_LONGRESP;
607 if (ISSET(cmd->c_flags, SCF_RSP_BSY))
608 cmdval |= SDCMD_BUSY;
609
610 if (cmd->c_datalen > 0) {
611 if (ISSET(cmd->c_flags, SCF_CMD_READ))
612 cmdval |= SDCMD_READ;
613 else
614 cmdval |= SDCMD_WRITE;
615
616 nblks = cmd->c_datalen / cmd->c_blklen;
617 if (nblks == 0 || (cmd->c_datalen % cmd->c_blklen) != 0)
618 ++nblks;
619
620 SDHOST_WRITE(sc, SDHBCT, cmd->c_blklen);
621 SDHOST_WRITE(sc, SDHBLC, nblks);
622
623 cmd->c_resid = cmd->c_datalen;
624 cmd->c_error = sdhost_dma_transfer(sc, cmd);
625 if (cmd->c_error != 0) {
626 #ifdef SDHOST_DEBUG
627 device_printf(sc->sc_dev, "dma transfer failed: %d\n",
628 cmd->c_error);
629 #endif
630 goto done;
631 }
632 }
633
634 SDHOST_WRITE(sc, SDARG, cmd->c_arg);
635 SDHOST_WRITE(sc, SDCMD, cmdval | cmd->c_opcode);
636
637 if (cmd->c_datalen > 0) {
638 cmd->c_error = sdhost_dma_wait(sc, cmd);
639 if (cmd->c_error != 0) {
640 #ifdef SDHOST_DEBUG
641 device_printf(sc->sc_dev,
642 "wait dma failed: %d\n", cmd->c_error);
643 #endif
644 goto done;
645 }
646 }
647
648 cmd->c_error = sdhost_wait_idle(sc, 5000);
649 if (cmd->c_error != 0) {
650 #ifdef SDHOST_DEBUG
651 device_printf(sc->sc_dev,
652 "wait cmd idle (%#x) failed: %d\n",
653 SDHOST_READ(sc, SDCMD), cmd->c_error);
654 #endif
655 }
656
657 if ((SDHOST_READ(sc, SDCMD) & SDCMD_FAIL) != 0) {
658 #ifdef SDHOST_DEBUG
659 device_printf(sc->sc_dev, "SDCMD: %#x\n",
660 SDHOST_READ(sc, SDCMD));
661 #endif
662 cmd->c_error = EIO;
663 goto done;
664 }
665
666 if (ISSET(cmd->c_flags, SCF_RSP_PRESENT)) {
667 if (ISSET(cmd->c_flags, SCF_RSP_136)) {
668 cmd->c_resp[0] = SDHOST_READ(sc, SDRSP0);
669 cmd->c_resp[1] = SDHOST_READ(sc, SDRSP1);
670 cmd->c_resp[2] = SDHOST_READ(sc, SDRSP2);
671 cmd->c_resp[3] = SDHOST_READ(sc, SDRSP3);
672 if (ISSET(cmd->c_flags, SCF_RSP_CRC)) {
673 cmd->c_resp[0] = (cmd->c_resp[0] >> 8) |
674 (cmd->c_resp[1] << 24);
675 cmd->c_resp[1] = (cmd->c_resp[1] >> 8) |
676 (cmd->c_resp[2] << 24);
677 cmd->c_resp[2] = (cmd->c_resp[2] >> 8) |
678 (cmd->c_resp[3] << 24);
679 cmd->c_resp[3] = (cmd->c_resp[3] >> 8);
680 }
681 } else {
682 cmd->c_resp[0] = SDHOST_READ(sc, SDRSP0);
683 }
684 }
685
686 done:
687 cmd->c_flags |= SCF_ITSDONE;
688 SDHOST_WRITE(sc, SDHCFG, hcfg);
689 SDHOST_WRITE(sc, SDHSTS, SDHOST_READ(sc, SDHSTS));
690 mutex_exit(&sc->sc_intr_lock);
691
692 #ifdef SDHOST_DEBUG
693 if (cmd->c_error != 0)
694 device_printf(sc->sc_dev, "command failed with error %d\n",
695 cmd->c_error);
696 #endif
697 }
698
699 static void
700 sdhost_card_enable_intr(sdmmc_chipset_handle_t sch, int enable)
701 {
702 }
703
704 static void
705 sdhost_card_intr_ack(sdmmc_chipset_handle_t sch)
706 {
707 }
708
709 void
710 sdhost_dump_regs(void)
711 {
712 device_t dev = device_find_by_driver_unit("sdhost", 0);
713 if (dev == NULL)
714 return;
715 struct sdhost_softc * const sc = device_private(dev);
716
717 device_printf(dev, "SDCMD = %08x\n", SDHOST_READ(sc, SDCMD));
718 device_printf(dev, "SDARG = %08x\n", SDHOST_READ(sc, SDARG));
719 device_printf(dev, "SDTOUT = %08x\n", SDHOST_READ(sc, SDTOUT));
720 device_printf(dev, "SDCDIV = %08x\n", SDHOST_READ(sc, SDCDIV));
721 device_printf(dev, "SDRSP0 = %08x\n", SDHOST_READ(sc, SDRSP0));
722 device_printf(dev, "SDRSP1 = %08x\n", SDHOST_READ(sc, SDRSP1));
723 device_printf(dev, "SDRSP2 = %08x\n", SDHOST_READ(sc, SDRSP2));
724 device_printf(dev, "SDRSP3 = %08x\n", SDHOST_READ(sc, SDRSP3));
725 device_printf(dev, "SDHSTS = %08x\n", SDHOST_READ(sc, SDHSTS));
726 device_printf(dev, "SDVDD = %08x\n", SDHOST_READ(sc, SDVDD));
727 device_printf(dev, "SDEDM = %08x\n", SDHOST_READ(sc, SDEDM));
728 device_printf(dev, "SDHCFG = %08x\n", SDHOST_READ(sc, SDHCFG));
729 device_printf(dev, "SDHBCT = %08x\n", SDHOST_READ(sc, SDHBCT));
730 device_printf(dev, "SDDATA = ........\n");
731 device_printf(dev, "SDHBLC = %08x\n", SDHOST_READ(sc, SDHBLC));
732 }
733