Lines Matching +full:sdhci +full:- +full:caps

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
35 * pin 48-53 - card slot
36 * pin 34-39 - radio module
38 * alt-0 - rubbish SDHCI (0x7e202000) aka sdhost
39 * alt-3 - advanced SDHCI (0x7e300000) aka sdhci/mmc/sdio
95 #include <dev/sdhci/sdhci.h>
183 &bcm2835_sdhost_debug, 0, "bcm2835-sdhost Debug level");
197 {"brcm,bcm2835-sdhost", 1},
237 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, off); in RD4()
246 bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, val); in WR4()
370 sc->sdhci_present_state = SDHCI_CARD_PRESENT | SDHCI_CARD_STABLE | in bcm_sdhost_reset()
386 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) in bcm_sdhost_probe()
404 mtx_init(&sc->mtx, "BCM SDHOST mtx", "bcm_sdhost", in bcm_sdhost_attach()
407 sc->sc_dev = dev; in bcm_sdhost_attach()
408 sc->sc_req = NULL; in bcm_sdhost_attach()
410 sc->cmdbusy = 0; in bcm_sdhost_attach()
411 sc->mmc_app_cmd = 0; in bcm_sdhost_attach()
412 sc->sdhci_int_status = 0; in bcm_sdhost_attach()
413 sc->sdhci_signal_enable = 0; in bcm_sdhost_attach()
414 sc->sdhci_present_state = 0; in bcm_sdhost_attach()
415 sc->sdhci_blocksize = 0; in bcm_sdhost_attach()
416 sc->sdhci_blockcount = 0; in bcm_sdhost_attach()
418 sc->sdcard_rca = 0; in bcm_sdhost_attach()
424 device_printf(dev, "SDHCI frequency: %dMHz\n", default_freq); in bcm_sdhost_attach()
427 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, in bcm_sdhost_attach()
429 if (!sc->sc_mem_res) { in bcm_sdhost_attach()
435 sc->sc_bst = rman_get_bustag(sc->sc_mem_res); in bcm_sdhost_attach()
436 sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); in bcm_sdhost_attach()
438 bcm_sdhost_reset(dev, &sc->sc_slot); in bcm_sdhost_attach()
440 bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 0); in bcm_sdhost_attach()
443 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in bcm_sdhost_attach()
445 if (!sc->sc_irq_res) { in bcm_sdhost_attach()
451 if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, in bcm_sdhost_attach()
452 NULL, bcm_sdhost_intr, sc, &sc->sc_intrhand)) { in bcm_sdhost_attach()
458 sc->sc_slot.caps = 0; in bcm_sdhost_attach()
459 sc->sc_slot.caps |= SDHCI_CAN_VDD_330; in bcm_sdhost_attach()
460 sc->sc_slot.caps |= SDHCI_CAN_DO_HISPD; in bcm_sdhost_attach()
461 sc->sc_slot.caps |= (default_freq << SDHCI_CLOCK_BASE_SHIFT); in bcm_sdhost_attach()
463 sc->sc_slot.quirks = 0; in bcm_sdhost_attach()
464 sc->sc_slot.quirks |= SDHCI_QUIRK_MISSING_CAPS; in bcm_sdhost_attach()
465 sc->sc_slot.quirks |= SDHCI_QUIRK_DONT_SHIFT_RESPONSE; in bcm_sdhost_attach()
467 sc->sc_slot.opt = 0; in bcm_sdhost_attach()
470 sc->slot->timeout_clk = ...; in bcm_sdhost_attach()
473 sdhci_init_slot(dev, &sc->sc_slot, 0); in bcm_sdhost_attach()
478 sdhci_start_slot(&sc->sc_slot); in bcm_sdhost_attach()
483 if (sc->sc_intrhand) in bcm_sdhost_attach()
484 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand); in bcm_sdhost_attach()
485 if (sc->sc_irq_res) in bcm_sdhost_attach()
486 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); in bcm_sdhost_attach()
487 if (sc->sc_mem_res) in bcm_sdhost_attach()
488 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); in bcm_sdhost_attach()
503 * rv 0 --> command finished
504 * rv 1 --> command timed out
511 mtx_assert(&sc->mtx, MA_OWNED); in bcm_sdhost_waitcommand()
513 while ((RD4(sc, HC_COMMAND) & HC_CMD_ENABLE) && --timeout > 0) { in bcm_sdhost_waitcommand()
533 WR4(sc, HC_ARGUMENT, sc->sdcard_rca << 16); in bcm_sdhost_waitcommand_status()
557 struct sdhci_slot *slot = &sc->sc_slot; in bcm_sdhost_intr()
561 mtx_lock(&sc->mtx); in bcm_sdhost_intr()
567 sc->sdhci_present_state |= SDHCI_DATA_AVAILABLE; in bcm_sdhost_intr()
568 sc->sdhci_int_status |= SDHCI_INT_DATA_AVAIL; in bcm_sdhost_intr()
570 sc->sdhci_present_state |= SDHCI_SPACE_AVAILABLE; in bcm_sdhost_intr()
571 sc->sdhci_int_status |= SDHCI_INT_SPACE_AVAIL; in bcm_sdhost_intr()
578 sc->sdhci_present_state &= in bcm_sdhost_intr()
580 sc->sdhci_int_status &= in bcm_sdhost_intr()
586 bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1); in bcm_sdhost_intr()
587 sc->sdhci_int_status |= SDHCI_INT_ERROR; in bcm_sdhost_intr()
589 sc->sdhci_int_status &= ~SDHCI_INT_ERROR; in bcm_sdhost_intr()
593 "sdhci_int_status=%08x\n", __func__, hstst, slot->offset, in bcm_sdhost_intr()
594 sc->sdhci_present_state, sc->sdhci_int_status); in bcm_sdhost_intr()
596 sdhci_generic_intr(&sc->sc_slot); in bcm_sdhost_intr()
598 sc->sdhci_int_status &= in bcm_sdhost_intr()
600 sc->sdhci_present_state &= ~SDHCI_DATA_AVAILABLE; in bcm_sdhost_intr()
603 (sc->sdhci_blocksize * sc->sdhci_blockcount == slot->offset)) { in bcm_sdhost_intr()
605 "sdhci_blockcount=%08x\n", __func__, slot->offset, in bcm_sdhost_intr()
606 sc->sdhci_blocksize, sc->sdhci_blockcount); in bcm_sdhost_intr()
607 sc->sdhci_int_status &= in bcm_sdhost_intr()
609 sc->sdhci_int_status |= SDHCI_INT_DATA_END; in bcm_sdhost_intr()
610 sdhci_generic_intr(&sc->sc_slot); in bcm_sdhost_intr()
611 sc->sdhci_int_status &= ~SDHCI_INT_DATA_END; in bcm_sdhost_intr()
621 bcm_sdhost_print_regs(sc, &sc->sc_slot, in bcm_sdhost_intr()
628 sc->sdhci_int_status |= SDHCI_INT_ERROR; in bcm_sdhost_intr()
631 slot->data_done = 1; in bcm_sdhost_intr()
633 sc->sdhci_int_status |= SDHCI_INT_RESPONSE; in bcm_sdhost_intr()
634 sdhci_generic_intr(&sc->sc_slot); in bcm_sdhost_intr()
635 sc->sdhci_int_status &= ~(SDHCI_INT_RESPONSE|SDHCI_INT_ERROR); in bcm_sdhost_intr()
642 mtx_unlock(&sc->mtx); in bcm_sdhost_intr()
667 struct mmc_data *data = slot->curcmd->data; in bcm_sdhost_command()
672 mtx_assert(&sc->mtx, MA_OWNED); in bcm_sdhost_command()
678 if (sc->cmdbusy == 1) in bcm_sdhost_command()
681 sc->cmdbusy = 1; in bcm_sdhost_command()
689 sc->mmc_app_cmd = 1; in bcm_sdhost_command()
702 sc->sdhci_present_state |= in bcm_sdhost_command()
705 if (data != NULL && data->flags & MMC_DATA_READ) in bcm_sdhost_command()
707 else if (data != NULL && data->flags & MMC_DATA_WRITE) in bcm_sdhost_command()
710 dprintf("%s: SDHCI_COMMAND_FLAGS --> HC_COMMAND %04x --> %04x\n", in bcm_sdhost_command()
719 sc->sdhci_blockcount); in bcm_sdhost_command()
722 WR4(sc, HC_ARGUMENT, sc->sdhci_blockcount); in bcm_sdhost_command()
729 bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1); in bcm_sdhost_command()
731 bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 0); in bcm_sdhost_command()
736 sc->sdcard_rca = (RD4(sc, HC_ARGUMENT) >> 16); in bcm_sdhost_command()
748 slot->data_done = 0; in bcm_sdhost_command()
752 bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1); in bcm_sdhost_command()
758 bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1); in bcm_sdhost_command()
760 slot->data_done = 1; in bcm_sdhost_command()
761 sc->sdhci_present_state &= in bcm_sdhost_command()
767 bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1); in bcm_sdhost_command()
769 slot->data_done = 1; in bcm_sdhost_command()
770 sc->sdhci_present_state &= in bcm_sdhost_command()
774 bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 0); in bcm_sdhost_command()
777 slot->curcmd->error = MMC_ERR_TIMEOUT; in bcm_sdhost_command()
779 slot->curcmd->error = MMC_ERR_FAILED; in bcm_sdhost_command()
781 dprintf("%s: curcmd->flags=%d data_done=%d\n", in bcm_sdhost_command()
782 __func__, slot->curcmd->flags, slot->data_done); in bcm_sdhost_command()
785 slot->curcmd->error = 0; in bcm_sdhost_command()
787 if (sc->mmc_app_cmd == 1 && opcode != MMC_APP_CMD) in bcm_sdhost_command()
788 sc->mmc_app_cmd = 0; in bcm_sdhost_command()
791 bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1); in bcm_sdhost_command()
795 sc->cmdbusy = 0; in bcm_sdhost_command()
798 sc->sdhci_int_status |= SDHCI_INT_RESPONSE; in bcm_sdhost_command()
803 mtx_unlock(&slot->mtx); in bcm_sdhost_command()
805 mtx_lock(&slot->mtx); in bcm_sdhost_command()
806 sc->sdhci_int_status &= ~SDHCI_INT_RESPONSE; in bcm_sdhost_command()
815 mtx_lock(&sc->mtx); in bcm_sdhost_read_1()
823 dprintf("%s: SDHCI_HOST_CONTROL --> HC_HOSTCONFIG val2 %02x\n", in bcm_sdhost_read_1()
829 dprintf("%s: SDHCI_POWER_CONTROL --> HC_POWER val2 %02x\n", in bcm_sdhost_read_1()
858 mtx_unlock(&sc->mtx); in bcm_sdhost_read_1()
869 mtx_lock(&sc->mtx); in bcm_sdhost_read_2()
873 val2 = sc->sdhci_blocksize; in bcm_sdhost_read_2()
874 dprintf("%s: SDHCI_BLOCK_SIZE --> HC_BLOCKSIZE %08x\n", in bcm_sdhost_read_2()
878 val2 = sc->sdhci_blockcount; in bcm_sdhost_read_2()
879 dprintf("%s: SDHCI_BLOCK_COUNT --> HC_BLOCKCOUNT %08x\n", in bcm_sdhost_read_2()
891 dprintf("%s: SDHCI_CLOCK_CONTROL %04x --> %04x\n", in bcm_sdhost_read_2()
916 mtx_unlock(&sc->mtx); in bcm_sdhost_read_2()
927 mtx_lock(&sc->mtx); in bcm_sdhost_read_4()
961 __func__, sc->sdhci_present_state); in bcm_sdhost_read_4()
962 val2 = sc->sdhci_present_state; in bcm_sdhost_read_4()
966 __func__, sc->sdhci_int_status); in bcm_sdhost_read_4()
967 val2 = sc->sdhci_int_status; in bcm_sdhost_read_4()
975 __func__, sc->sdhci_signal_enable); in bcm_sdhost_read_4()
976 val2 = sc->sdhci_signal_enable; in bcm_sdhost_read_4()
999 mtx_unlock(&sc->mtx); in bcm_sdhost_read_4()
1013 mtx_lock(&sc->mtx); in bcm_sdhost_read_multi_4()
1021 avail = count - i; in bcm_sdhost_read_multi_4()
1023 bus_space_read_multi_4(sc->sc_bst, sc->sc_bsh, in bcm_sdhost_read_multi_4()
1029 mtx_unlock(&sc->mtx); in bcm_sdhost_read_multi_4()
1039 mtx_lock(&sc->mtx); in bcm_sdhost_write_1()
1048 dprintf("%s: SDHCI_HOST_CONTROL --> HC_HOSTC %04x --> %04x\n", in bcm_sdhost_write_1()
1054 dprintf("%s: SDHCI_POWER_CONTROL --> HC_POWER %02x --> %02x\n", in bcm_sdhost_write_1()
1080 mtx_unlock(&sc->mtx); in bcm_sdhost_write_1()
1089 mtx_lock(&sc->mtx); in bcm_sdhost_write_2()
1095 sc->sdhci_blocksize = val; in bcm_sdhost_write_2()
1102 sc->sdhci_blockcount = val; in bcm_sdhost_write_2()
1120 dprintf("%s: SDHCI_CLOCK_CONTROL %04x --> SCDIV %04x\n", in bcm_sdhost_write_2()
1146 mtx_unlock(&sc->mtx); in bcm_sdhost_write_2()
1156 mtx_lock(&sc->mtx); in bcm_sdhost_write_4()
1161 dprintf("%s: SDHCI_ARGUMENT --> HC_ARGUMENT val=%08x\n", in bcm_sdhost_write_4()
1168 sc->sdhci_int_status = val; in bcm_sdhost_write_4()
1175 sc->sdhci_signal_enable = val; in bcm_sdhost_write_4()
1183 dprintf("%s: SDHCI_SIGNAL_ENABLE --> HC_HOSTC %08x --> %08x\n" , in bcm_sdhost_write_4()
1209 mtx_unlock(&sc->mtx); in bcm_sdhost_write_4()
1221 mtx_lock(&sc->mtx); in bcm_sdhost_write_multi_4()
1227 space = HC_FIFO_SIZE - ((edm >> 4) & 0x1f); in bcm_sdhost_write_multi_4()
1229 space = count - i; in bcm_sdhost_write_multi_4()
1231 bus_space_write_multi_4(sc->sc_bst, sc->sc_bsh, in bcm_sdhost_write_multi_4()
1241 mtx_unlock(&sc->mtx); in bcm_sdhost_write_multi_4()
1261 /* SDHCI registers accessors */