From fa08fede1e85ec9777f086c89f1f8d6c5166c4d7 Mon Sep 17 00:00:00 2001 From: bushing Date: Mon, 26 Oct 2009 14:41:40 -0700 Subject: [PATCH] removed more useless SD code --- sdhc.c | 337 ++++++++++++++++++-------------------------------------- sdhc.h | 14 --- sdmmc.c | 152 +++++++++++-------------- sdmmc.h | 7 +- 4 files changed, 175 insertions(+), 335 deletions(-) diff --git a/sdhc.c b/sdhc.c index a103971..cdaeaac 100644 --- a/sdhc.c +++ b/sdhc.c @@ -36,12 +36,13 @@ #include "ipc.h" #endif +struct sdhc_host sc_host; + //#define SDHC_DEBUG #define SDHC_COMMAND_TIMEOUT 500 #define SDHC_TRANSFER_TIMEOUT 5000 -#define sdmmc_delay(t) udelay(t) #define sdhc_wait_intr(a,b,c) sdhc_wait_intr_debug(__func__, __LINE__, a, b, c) static inline u32 bus_space_read_4(bus_space_handle_t ioh, u32 reg) @@ -142,11 +143,8 @@ void sdhc_dump_regs(struct sdhc_host *); * host controller standard register set. (1.3) */ int -sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot, - bus_space_handle_t ioh, int usedma) +sdhc_host_found(bus_space_tag_t iot, bus_space_handle_t ioh, int usedma) { - struct sdmmcbus_attach_args saa; - struct sdhc_host *hp; u_int32_t caps; int error = 1; @@ -166,46 +164,38 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot, } #endif - /* Allocate one more host structure. */ - if (sc->sc_nhosts < SDHC_MAX_HOSTS) { - sc->sc_nhosts++; - hp = &sc->sc_host[sc->sc_nhosts - 1]; - memset(hp, 0, sizeof(*hp)); - } - else - return -EINVAL; + memset(&sc_host, 0, sizeof(sc_host)); /* Fill in the new host structure. */ - hp->sc = sc; - hp->iot = iot; - hp->ioh = ioh; - hp->data_command = 0; + sc_host.iot = iot; + sc_host.ioh = ioh; + sc_host.data_command = 0; /* * Reset the host controller and enable interrupts. */ - (void)sdhc_host_reset(hp); + (void)sdhc_host_reset(&sc_host); /* Determine host capabilities. */ - caps = HREAD4(hp, SDHC_CAPABILITIES); + caps = HREAD4(&sc_host, SDHC_CAPABILITIES); /* Use DMA if the host system and the controller support it. */ if (usedma && ISSET(caps, SDHC_DMA_SUPPORT)) - SET(hp->flags, SHF_USE_DMA); + SET(sc_host.flags, SHF_USE_DMA); /* * Determine the base clock frequency. (2.2.24) */ if (SDHC_BASE_FREQ_KHZ(caps) != 0) - hp->clkbase = SDHC_BASE_FREQ_KHZ(caps); - if (hp->clkbase == 0) { + sc_host.clkbase = SDHC_BASE_FREQ_KHZ(caps); + if (sc_host.clkbase == 0) { /* The attachment driver must tell us. */ gecko_printf("sdhc: base clock frequency unknown\n"); goto err; - } else if (hp->clkbase < 10000 || hp->clkbase > 63000) { + } else if (sc_host.clkbase < 10000 || sc_host.clkbase > 63000) { /* SDHC 1.0 supports only 10-63 MHz. */ gecko_printf("sdhc: base clock frequency out of range: %u MHz\n", - hp->clkbase / 1000); + sc_host.clkbase / 1000); goto err; } @@ -214,41 +204,17 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot, * capabilities. (2.2.15) */ - SET(hp->ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V); - - /* - * Determine the maximum block length supported by the host - * controller. (2.2.24) - */ - switch((caps >> SDHC_MAX_BLK_LEN_SHIFT) & SDHC_MAX_BLK_LEN_MASK) { - case SDHC_MAX_BLK_LEN_512: - hp->maxblklen = 512; - break; - case SDHC_MAX_BLK_LEN_1024: - hp->maxblklen = 1024; - break; - case SDHC_MAX_BLK_LEN_2048: - hp->maxblklen = 2048; - break; - default: - hp->maxblklen = 1; - break; - } + SET(sc_host.ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V); /* * Attach the generic SD/MMC bus driver. (The bus driver must * not invoke any chipset functions before it is attached.) */ - bzero(&saa, sizeof(saa)); - saa.saa_busname = "sdmmc"; - saa.sch = hp; - - sdmmc_attach(hp, "sdhc", ioh); + sdmmc_attach(&sc_host); return 0; err: - sc->sc_nhosts--; return (error); } @@ -257,17 +223,10 @@ err: * Shutdown hook established by or called from attachment driver. */ void -sdhc_shutdown(void *arg) +sdhc_shutdown(void) { - struct sdhc_softc *sc = arg; - struct sdhc_host *hp; - int i; - /* XXX chip locks up if we don't disable it before reboot. */ - for (i = 0; i < sc->sc_nhosts; i++) { - hp = &sc->sc_host[i]; - (void)sdhc_host_reset(hp); - } + (void)sdhc_host_reset(&sc_host); } #endif @@ -276,9 +235,8 @@ sdhc_shutdown(void *arg) * cards are removed, upon resume, and during error recovery. */ int -sdhc_host_reset(sdmmc_chipset_handle_t sch) +sdhc_host_reset(struct sdhc_host *hp) { - struct sdhc_host *hp = sch; u_int16_t imask; int error; @@ -313,27 +271,12 @@ sdhc_host_reset(sdmmc_chipset_handle_t sch) return 0; } -u_int32_t -sdhc_host_ocr(sdmmc_chipset_handle_t sch) -{ - struct sdhc_host *hp = sch; - return hp->ocr; -} - -int -sdhc_host_maxblklen(sdmmc_chipset_handle_t sch) -{ - struct sdhc_host *hp = sch; - return hp->maxblklen; -} - /* * Return non-zero if the card is currently inserted. */ int -sdhc_card_detect(sdmmc_chipset_handle_t sch) +sdhc_card_detect(struct sdhc_host *hp) { - struct sdhc_host *hp = sch; return ISSET(HREAD4(hp, SDHC_PRESENT_STATE), SDHC_CARD_INSERTED) ? 1 : 0; } @@ -343,10 +286,8 @@ sdhc_card_detect(sdmmc_chipset_handle_t sch) * Return zero on success. */ int -sdhc_bus_power(sdmmc_chipset_handle_t sch, u_int32_t ocr) +sdhc_bus_power(struct sdhc_host *hp, u_int32_t ocr) { - struct sdhc_host *hp = sch; - gecko_printf("sdhc_bus_power(%u)\n", ocr); /* Disable bus power before voltage change. */ HWRITE1(hp, SDHC_POWER_CTL, 0); @@ -363,7 +304,7 @@ sdhc_bus_power(sdmmc_chipset_handle_t sch, u_int32_t ocr) */ HWRITE1(hp, SDHC_POWER_CTL, (SDHC_VOLTAGE_3_3V << SDHC_VOLTAGE_SHIFT) | SDHC_BUS_POWER); - sdmmc_delay(10000); + udelay(10000); /* * The host system may not power the bus due to battery low, @@ -399,12 +340,10 @@ sdhc_clock_divisor(struct sdhc_host *hp, u_int freq) * Return zero on success. */ int -sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq) +sdhc_bus_clock(struct sdhc_host *hp, int freq) { - struct sdhc_host *hp = sch; int div; int timo; - int error = 0; gecko_printf("%s(%d)\n", __FUNCTION__, freq); #ifdef DIAGNOSTIC @@ -414,52 +353,39 @@ sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq) gecko_printf("sdhc_sdclk_frequency_select: command in progress\n"); #endif - /* - * Stop SD clock before changing the frequency. - */ + /* Stop SD clock before changing the frequency. */ HWRITE2(hp, SDHC_CLOCK_CTL, 0); if (freq == SDMMC_SDCLK_OFF) - goto ret; + return 0; - /* - * Set the minimum base clock frequency divisor. - */ + /* Set the minimum base clock frequency divisor. */ if ((div = sdhc_clock_divisor(hp, freq)) < 0) { /* Invalid base clock frequency or `freq' value. */ - error = EINVAL; - goto ret; + return EINVAL; } HWRITE2(hp, SDHC_CLOCK_CTL, div << SDHC_SDCLK_DIV_SHIFT); - /* - * Start internal clock. Wait 10ms for stabilization. - */ + /* Start internal clock. Wait 10ms for stabilization. */ HSET2(hp, SDHC_CLOCK_CTL, SDHC_INTCLK_ENABLE); for (timo = 1000; timo > 0; timo--) { if (ISSET(HREAD2(hp, SDHC_CLOCK_CTL), SDHC_INTCLK_STABLE)) break; - sdmmc_delay(10); + udelay(10); } if (timo == 0) { gecko_printf("sdhc: internal clock never stabilized\n"); - error = ETIMEDOUT; - goto ret; + return ETIMEDOUT; } - /* - * Enable SD clock. - */ + /* Enable SD clock. */ HSET2(hp, SDHC_CLOCK_CTL, SDHC_SDCLK_ENABLE); -ret: - return error; + return 0; } void -sdhc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable) +sdhc_card_intr_mask(struct sdhc_host *hp, int enable) { - struct sdhc_host *hp = sch; - if (enable) { HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT); HSET2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_CARD_INTERRUPT); @@ -470,10 +396,8 @@ sdhc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable) } void -sdhc_card_intr_ack(sdmmc_chipset_handle_t sch) +sdhc_card_intr_ack(struct sdhc_host *hp) { - struct sdhc_host *hp = sch; - HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT); } @@ -487,16 +411,15 @@ sdhc_wait_state(struct sdhc_host *hp, u_int32_t mask, u_int32_t value) if (((state = HREAD4(hp, SDHC_PRESENT_STATE)) & mask) == value) return 0; - sdmmc_delay(10000); + udelay(10000); } DPRINTF(0,("sdhc: timeout waiting for %x (state=%d)\n", value, state)); return ETIMEDOUT; } void -sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) +sdhc_exec_command(struct sdhc_host *hp, struct sdmmc_command *cmd) { - struct sdhc_host *hp = sch; int error; if (cmd->c_datalen > 0) @@ -509,8 +432,7 @@ sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) cmd->c_timeout = SDHC_COMMAND_TIMEOUT; } - - sdhc_reset_intr_status(hp); + hp->intr_status = 0; /* * Start the MMC command, or mark `cmd' as failed and return. @@ -563,9 +485,6 @@ sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) if (cmd->c_error == 0 && cmd->c_datalen > 0) sdhc_transfer_data(hp, cmd); - /* Turn off the LED. */ - HCLR1(hp, SDHC_HOST_CTL, SDHC_LED_ON); - DPRINTF(1,("sdhc: cmd %u done (flags=%#x error=%d prev state=%d)\n", cmd->c_opcode, cmd->c_flags, cmd->c_error, (cmd->c_resp[0] >> 9) & 15)); SET(cmd->c_flags, SCF_ITSDONE); @@ -581,7 +500,7 @@ sdhc_start_command(struct sdhc_host *hp, struct sdmmc_command *cmd) u_int16_t command; int error; - DPRINTF(1,("sdhc: start cmd %u arg=%#x data=%p dlen=%d flags=%#x\n", + DPRINTF(1,("sdhc: start cmd %u arg=%#x data=%p dlen=%d flags=%#x\n", cmd->c_opcode, cmd->c_arg, cmd->c_data, cmd->c_datalen, cmd->c_flags)); /* @@ -647,9 +566,6 @@ sdhc_start_command(struct sdhc_host *hp, struct sdmmc_command *cmd) if ((error = sdhc_wait_state(hp, SDHC_CMD_INHIBIT_MASK, 0)) != 0) return error; - /* Alert the user not to remove the card. */ - HSET1(hp, SDHC_HOST_CTL, SDHC_LED_ON); - if (ISSET(hp->flags, SHF_USE_DMA) && cmd->c_datalen > 0) { cmd->c_resid = blkcount; cmd->c_buf = cmd->c_data; @@ -751,7 +667,7 @@ sdhc_soft_reset(struct sdhc_host *hp, int mask) for (timo = 10; timo > 0; timo--) { if (!ISSET(HREAD1(hp, SDHC_SOFTWARE_RESET), mask)) break; - sdmmc_delay(10000); + udelay(10000); HWRITE1(hp, SDHC_SOFTWARE_RESET, 0); } if (timo == 0) { @@ -762,12 +678,6 @@ sdhc_soft_reset(struct sdhc_host *hp, int mask) return (0); } - -void sdhc_reset_intr_status(struct sdhc_host *hp) -{ - hp->intr_status = 0; -} - int sdhc_wait_intr_debug(const char *funcname, int line, struct sdhc_host *hp, int mask, int timo) { @@ -778,7 +688,6 @@ sdhc_wait_intr_debug(const char *funcname, int line, struct sdhc_host *hp, int m status = hp->intr_status & mask; - for (; timo > 0; timo--) { #ifndef CAN_HAZ_IRQ sdhc_irq(); // seems backwards but ok @@ -795,14 +704,14 @@ sdhc_wait_intr_debug(const char *funcname, int line, struct sdhc_host *hp, int m } hp->intr_status &= ~status; - DPRINTF(2,("sdhc: funcname=%s, line=%d, timo=%d status=%#x intr status=%#x error %#x\n", + DPRINTF(2,("sdhc: funcname=%s, line=%d, timo=%d status=%#x intr status=%#x error %#x\n", funcname, line, timo, status, hp->intr_status, hp->intr_error_status)); - + /* Command timeout has higher priority than command complete. */ if (ISSET(status, SDHC_ERROR_INTERRUPT)) { gecko_printf("resetting due to error interrupt\n"); sdhc_dump_regs(hp); - + hp->intr_error_status = 0; (void)sdhc_soft_reset(hp, SDHC_RESET_DAT|SDHC_RESET_CMD); status = 0; @@ -812,7 +721,7 @@ sdhc_wait_intr_debug(const char *funcname, int line, struct sdhc_host *hp, int m if (ISSET(status, SDHC_ERROR_TIMEOUT)) { gecko_printf("not resetting due to timeout\n"); sdhc_dump_regs(hp); - + hp->intr_error_status = 0; // (void)sdhc_soft_reset(hp, SDHC_RESET_DAT|SDHC_RESET_CMD); status = 0; @@ -825,98 +734,77 @@ sdhc_wait_intr_debug(const char *funcname, int line, struct sdhc_host *hp, int m * Established by attachment driver at interrupt priority IPL_SDMMC. */ int -sdhc_intr(void *arg) +sdhc_intr(void) { - struct sdhc_softc *sc = arg; - int host; - int done = 0; + u_int16_t status; - /* We got an interrupt, but we don't know from which slot. */ - for (host = 0; host < sc->sc_nhosts; host++) { - struct sdhc_host *hp = &sc->sc_host[host]; - u_int16_t status; + DPRINTF(1,("shdc_intr():\n")); + sdhc_dump_regs(&sc_host); + + /* Find out which interrupts are pending. */ + status = HREAD2(&sc_host, SDHC_NINTR_STATUS); + if (!ISSET(status, SDHC_NINTR_STATUS_MASK)) { + DPRINTF(1, ("unknown interrupt\n")); + return 0; + } + + /* Acknowledge the interrupts we are about to handle. */ + HWRITE2(&sc_host, SDHC_NINTR_STATUS, status); + DPRINTF(2,("sdhc: interrupt status=%d\n", status)); - if (hp == NULL) - continue; + /* Service error interrupts. */ + if (ISSET(status, SDHC_ERROR_INTERRUPT)) { + u_int16_t error; + u_int16_t signal; - DPRINTF(1,("shdc_intr(%d):\n", host)); - sdhc_dump_regs(hp); + /* Acknowledge error interrupts. */ + error = HREAD2(&sc_host, SDHC_EINTR_STATUS); + signal = HREAD2(&sc_host, SDHC_EINTR_SIGNAL_EN); + HWRITE2(&sc_host, SDHC_EINTR_SIGNAL_EN, 0); + (void)sdhc_soft_reset(&sc_host, SDHC_RESET_DAT|SDHC_RESET_CMD); + if (sc_host.data_command == 1) { + sc_host.data_command = 0; - /* Find out which interrupts are pending. */ - status = HREAD2(hp, SDHC_NINTR_STATUS); - if (!ISSET(status, SDHC_NINTR_STATUS_MASK)) - continue; /* no interrupt for us */ - - /* Acknowledge the interrupts we are about to handle. */ - HWRITE2(hp, SDHC_NINTR_STATUS, status); - DPRINTF(2,("sdhc: interrupt status=%d\n", status)); - - - /* Claim this interrupt. */ - done = 1; - - /* - * Service error interrupts. - */ - if (ISSET(status, SDHC_ERROR_INTERRUPT)) { - u_int16_t error; - u_int16_t signal; - - /* Acknowledge error interrupts. */ - error = HREAD2(hp, SDHC_EINTR_STATUS); - signal = HREAD2(hp, SDHC_EINTR_SIGNAL_EN); - HWRITE2(hp, SDHC_EINTR_SIGNAL_EN, 0); - (void)sdhc_soft_reset(hp, SDHC_RESET_DAT|SDHC_RESET_CMD); - if (hp->data_command == 1) { - hp->data_command = 0; - - // TODO: add a way to send commands from irq - // context and uncomment this -// sdmmc_abort(); - } - HWRITE2(hp, SDHC_EINTR_STATUS, error); - HWRITE2(hp, SDHC_EINTR_SIGNAL_EN, signal); - - DPRINTF(2,("sdhc: error interrupt, status=%d\n", error)); - - if (ISSET(error, SDHC_CMD_TIMEOUT_ERROR| - SDHC_DATA_TIMEOUT_ERROR)) { - hp->intr_error_status |= error; - hp->intr_status |= status; - } + // TODO: add a way to send commands from irq + // context and uncomment this +// sdmmc_abort(); } + HWRITE2(&sc_host, SDHC_EINTR_STATUS, error); + HWRITE2(&sc_host, SDHC_EINTR_SIGNAL_EN, signal); -#ifdef CAN_HAZ_IPC - /* - * Wake up the sdmmc event thread to scan for cards. - */ - if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) { - // this pushes a request to the slow queue so that we - // don't block other IRQs. - ipc_enqueue_slow(IPC_DEV_SDHC, IPC_SDHC_DISCOVER, 0); - } -#endif + DPRINTF(2,("sdhc: error interrupt, status=%d\n", error)); - /* - * Wake up the blocking process to service command - * related interrupt(s). - */ - if (ISSET(status, SDHC_BUFFER_READ_READY| - SDHC_BUFFER_WRITE_READY|SDHC_COMMAND_COMPLETE| - SDHC_TRANSFER_COMPLETE|SDHC_DMA_INTERRUPT)) { - hp->intr_status |= status; - } - - /* - * Service SD card interrupts. - */ - if (ISSET(status, SDHC_CARD_INTERRUPT)) { -// DPRINTF(0,("%s: card interrupt\n", HDEVNAME(hp))); - HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT); -// sdmmc_card_intr(hp->sdmmc); + if (ISSET(error, SDHC_CMD_TIMEOUT_ERROR| + SDHC_DATA_TIMEOUT_ERROR)) { + sc_host.intr_error_status |= error; + sc_host.intr_status |= status; } } - return done; + +#ifdef CAN_HAZ_IPC + /* Wake up the sdmmc event thread to scan for cards. */ + if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) { + // this pushes a request to the slow queue so that we + // don't block other IRQs. + ipc_enqueue_slow(IPC_DEV_SDHC, IPC_SDHC_DISCOVER, 0); + } +#endif + /* + * Wake up the blocking process to service command + * related interrupt(s). + */ + if (ISSET(status, SDHC_BUFFER_READ_READY| + SDHC_BUFFER_WRITE_READY|SDHC_COMMAND_COMPLETE| + SDHC_TRANSFER_COMPLETE|SDHC_DMA_INTERRUPT)) { + sc_host.intr_status |= status; + } + + /* Service SD card interrupts. */ + if (ISSET(status, SDHC_CARD_INTERRUPT)) { + DPRINTF(0,("sdhc: card interrupt\n")); + HCLR2(&sc_host, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT); + } + return 1; } #ifdef SDHC_DEBUG @@ -947,15 +835,10 @@ sdhc_dump_regs(struct sdhc_host *hp) #endif #include "hollywood.h" -#ifdef LOADER -static struct sdhc_softc __softc; -#else -static struct sdhc_softc __softc MEM2_BSS; -#endif void sdhc_irq(void) { - sdhc_intr(&__softc); + sdhc_intr(); } void sdhc_init(void) @@ -963,18 +846,15 @@ void sdhc_init(void) #ifdef CAN_HAZ_IRQ irq_enable(IRQ_SDHC); #endif - memset(&__softc, 0, sizeof(__softc)); - sdhc_host_found(&__softc, 0, SDHC_REG_BASE, 1); -// sdhc_host_found(&__softc, 0, SDHC_REG_BASE + 0x100, 1); -// sdhc_host_found(&__softc, 0, 0x0d080000, 1); + sdhc_host_found(0, SDHC_REG_BASE, 1); } void sdhc_exit(void) { #ifdef CAN_HAZ_IRQ - irq_disable(IRQ_SDHC); + irq_disable(IRQ_SDHC); #endif - sdhc_shutdown(); + sdhc_shutdown(); } #ifdef CAN_HAZ_IPC @@ -987,6 +867,7 @@ void sdhc_ipc(volatile ipc_request *req) case IPC_SDHC_EXIT: sdhc_exit(); ipc_post(req->code, req->tag, 0); + break; } } #endif diff --git a/sdhc.h b/sdhc.h index d44c344..a7a9097 100644 --- a/sdhc.h +++ b/sdhc.h @@ -25,16 +25,10 @@ #include "ipc.h" #endif #include "sdmmc.h" - -#define SDHC_MAX_HOSTS 4 - struct sdhc_host { - struct sdhc_softc *sc; /* host controller device */ - struct device *sdmmc; /* generic SD/MMC device */ bus_space_tag_t iot; /* host register set tag */ bus_space_handle_t ioh; /* host register set handle */ u_int clkbase; /* base clock frequency in KHz */ - int maxblklen; /* maximum block length */ int flags; /* flags for this host */ u_int32_t ocr; /* OCR value from capabilities */ u_int8_t regs[14]; /* host controller state */ @@ -174,11 +168,6 @@ void sdhc_ipc(volatile ipc_request *req); #define SDHC_VOLTAGE_SUPP_3_3V (1<<24) #define SDHC_DMA_SUPPORT (1<<22) #define SDHC_HIGH_SPEED_SUPP (1<<21) -#define SDHC_MAX_BLK_LEN_512 0 -#define SDHC_MAX_BLK_LEN_1024 1 -#define SDHC_MAX_BLK_LEN_2048 2 -#define SDHC_MAX_BLK_LEN_SHIFT 16 -#define SDHC_MAX_BLK_LEN_MASK 0x3 #define SDHC_BASE_FREQ_SHIFT 8 #define SDHC_BASE_FREQ_MASK 0x3f #define SDHC_TIMEOUT_FREQ_UNIT (1<<7) /* 0=KHz, 1=MHz */ @@ -208,12 +197,9 @@ void sdhc_ipc(volatile ipc_request *req); #define SDHC_VENDOR_VERSION(hcv) \ (((hcv) >> SDHC_VENDOR_VERS_SHIFT) & SDHC_VENDOR_VERS_MASK) -//typedef void *sdmmc_chipset_handle_t; struct sdmmc_command; int sdhc_host_reset(struct sdhc_host *hp); -u_int32_t sdhc_host_ocr(struct sdhc_host *hp); -int sdhc_host_maxblklen(struct sdhc_host *hp); int sdhc_card_detect(struct sdhc_host *hp); int sdhc_bus_power(struct sdhc_host *hp, u_int32_t); int sdhc_bus_clock(struct sdhc_host *hp, int); diff --git a/sdmmc.c b/sdmmc.c index b2d0eeb..f6934bf 100644 --- a/sdmmc.c +++ b/sdmmc.c @@ -25,10 +25,7 @@ static int sdmmcdebug = 0; #endif struct sdmmc_card { - struct sdmmc_chip_functions *functions; sdmmc_chipset_handle_t handle; - char name[30]; - int no; int inserted; int sdhc_blockmode; int selected; @@ -41,35 +38,22 @@ struct sdmmc_card { }; #ifdef LOADER -static struct sdmmc_card cards[SDHC_MAX_HOSTS]; +static struct sdmmc_card card; #else -static struct sdmmc_card cards[SDHC_MAX_HOSTS] MEM2_BSS; +static struct sdmmc_card card MEM2_BSS; #endif -static int n_cards = 0; - -void sdmmc_attach(sdmmc_chipset_handle_t handle, const char *name, int no) +void sdmmc_attach(sdmmc_chipset_handle_t handle) { - struct sdmmc_card *c; + memset(&card, 0, sizeof(card)); - if (n_cards >= SDHC_MAX_HOSTS) { - gecko_printf("n_cards(%d) >= %d!\n", n_cards, SDHC_MAX_HOSTS); - gecko_printf("starlet is soo going to crash very soon...\n"); - } + card.handle = handle; - c = &cards[n_cards++]; - memset(c, 0, sizeof(*c)); + DPRINTF(0, ("sdmmc: attached new SD/MMC card\n")); - c->handle = handle; - c->no = no; - strlcpy(c->name, name, sizeof(c->name)); + sdhc_host_reset(card.handle); - DPRINTF(0, ("sdmmc: attached new SD/MMC card %d for host [%s:%d]\n", - n_cards-1, c->name, c->no)); - - sdhc_host_reset(c->handle); - - if (sdhc_card_detect(c->handle)) { + if (sdhc_card_detect(card.handle)) { DPRINTF(1, ("card is inserted. starting init sequence.\n")); sdmmc_needs_discover(); } @@ -83,33 +67,32 @@ void sdmmc_abort(void) { cmd.c_opcode = MMC_STOP_TRANSMISSION; cmd.c_arg = 0; cmd.c_flags = SCF_RSP_R1B; - sdhc_exec_command(&cards[0].handle, &cmd); + sdhc_exec_command(card.handle, &cmd); } void sdmmc_needs_discover(void) { - struct sdmmc_card *c = &cards[0]; struct sdmmc_command cmd; u32 ocr; DPRINTF(0, ("sdmmc: card needs discovery.\n")); - sdhc_host_reset(c->handle); - c->new_card = 1; + sdhc_host_reset(card.handle); + card.new_card = 1; - if (!sdhc_card_detect(c->handle)) { + if (!sdhc_card_detect(card.handle)) { DPRINTF(1, ("sdmmc: card (no longer?) inserted.\n")); - c->inserted = 0; + card.inserted = 0; return; } DPRINTF(1, ("sdmmc: enabling power\n")); - if (sdhc_bus_power(c->handle, 1) != 0) { + if (sdhc_bus_power(card.handle, 1) != 0) { gecko_printf("sdmmc: powerup failed for card\n"); goto out; } DPRINTF(1, ("sdmmc: enabling clock\n")); - if (sdhc_bus_clock(c->handle, SDMMC_DEFAULT_CLOCK) != 0) { + if (sdhc_bus_clock(card.handle, SDMMC_DEFAULT_CLOCK) != 0) { gecko_printf("sdmmc: could not enable clock for card\n"); goto out_power; } @@ -119,7 +102,7 @@ void sdmmc_needs_discover(void) memset(&cmd, 0, sizeof(cmd)); cmd.c_opcode = MMC_GO_IDLE_STATE; cmd.c_flags = SCF_RSP_R0; - sdhc_exec_command(c->handle, &cmd); + sdhc_exec_command(card.handle, &cmd); if (cmd.c_error) { gecko_printf("sdmmc: GO_IDLE_STATE failed with %d\n", cmd.c_error); @@ -134,9 +117,9 @@ void sdmmc_needs_discover(void) cmd.c_arg = 0x1aa; cmd.c_flags = SCF_RSP_R7; cmd.c_timeout = 100; - sdhc_exec_command(c->handle, &cmd); + sdhc_exec_command(card.handle, &cmd); - ocr = sdhc_host_ocr(c->handle); + ocr = card.handle->ocr; if (cmd.c_error || (cmd.c_resp[0] & 0xff) != 0xaa) ocr &= ~SD_OCR_SDHC_CAP; else @@ -151,7 +134,7 @@ void sdmmc_needs_discover(void) cmd.c_opcode = MMC_APP_CMD; cmd.c_arg = 0; cmd.c_flags = SCF_RSP_R1; - sdhc_exec_command(c->handle, &cmd); + sdhc_exec_command(card.handle, &cmd); if (cmd.c_error) continue; @@ -160,7 +143,7 @@ void sdmmc_needs_discover(void) cmd.c_opcode = SD_APP_OP_COND; cmd.c_arg = ocr; cmd.c_flags = SCF_RSP_R3; - sdhc_exec_command(c->handle, &cmd); + sdhc_exec_command(card.handle, &cmd); if (cmd.c_error) continue; @@ -175,10 +158,10 @@ void sdmmc_needs_discover(void) } if (ISSET(MMC_R1(cmd.c_resp), SD_OCR_SDHC_CAP)) - c->sdhc_blockmode = 1; + card.sdhc_blockmode = 1; else - c->sdhc_blockmode = 0; - DPRINTF(2, ("sdmmc: SDHC: %d\n", c->sdhc_blockmode)); + card.sdhc_blockmode = 0; + DPRINTF(2, ("sdmmc: SDHC: %d\n", card.sdhc_blockmode)); u8 *resp; DPRINTF(2, ("sdmmc: MMC_ALL_SEND_CID\n")); @@ -186,13 +169,13 @@ void sdmmc_needs_discover(void) cmd.c_opcode = MMC_ALL_SEND_CID; cmd.c_arg = 0; cmd.c_flags = SCF_RSP_R2; - sdhc_exec_command(c->handle, &cmd); + sdhc_exec_command(card.handle, &cmd); if (cmd.c_error) { gecko_printf("sdmmc: MMC_ALL_SEND_CID failed with %d\n", cmd.c_error); goto out_clock; } - c->cid = MMC_R1(cmd.c_resp); + card.cid = MMC_R1(cmd.c_resp); resp = (u8 *)cmd.c_resp; gecko_printf("CID: mid=%02x name='%c%c%c%c%c%c%c' prv=%d.%d psn=%02x%02x%02x%02x mdt=%d/%d\n", resp[14], resp[13],resp[12],resp[11],resp[10],resp[9],resp[8],resp[7], resp[6], resp[5] >> 4, resp[5] & 0xf, @@ -203,23 +186,23 @@ void sdmmc_needs_discover(void) cmd.c_opcode = SD_SEND_RELATIVE_ADDR; cmd.c_arg = 0; cmd.c_flags = SCF_RSP_R6; - sdhc_exec_command(c->handle, &cmd); + sdhc_exec_command(card.handle, &cmd); if (cmd.c_error) { gecko_printf("sdmmc: SD_SEND_RCA failed with %d\n", cmd.c_error); goto out_clock; } - c->rca = MMC_R1(cmd.c_resp)>>16; - DPRINTF(2, ("sdmmc: rca: %08x\n", c->rca)); + card.rca = MMC_R1(cmd.c_resp)>>16; + DPRINTF(2, ("sdmmc: rca: %08x\n", card.rca)); - c->selected = 0; - c->inserted = 1; + card.selected = 0; + card.inserted = 1; memset(&cmd, 0, sizeof(cmd)); cmd.c_opcode = MMC_SEND_CSD; - cmd.c_arg = ((u32)c->rca)<<16; + cmd.c_arg = ((u32)card.rca)<<16; cmd.c_flags = SCF_RSP_R2; - sdhc_exec_command(c->handle, &cmd); + sdhc_exec_command(card.handle, &cmd); if (cmd.c_error) { gecko_printf("sdmmc: MMC_SEND_CSD failed with %d\n", cmd.c_error); goto out_power; @@ -235,8 +218,8 @@ void sdmmc_needs_discover(void) if (resp[13] == 0xe) { // sdhc unsigned int c_size = resp[7] << 16 | resp[6] << 8 | resp[5]; gecko_printf("sdmmc: sdhc mode, c_size=%u, card size = %uk\n", c_size, (c_size + 1)* 512); - c->timeout = 250 * 1000000; // spec says read timeout is 100ms and write/erase timeout is 250ms - c->num_sectors = (c_size + 1) * 1024; // number of 512-byte sectors + card.timeout = 250 * 1000000; // spec says read timeout is 100ms and write/erase timeout is 250ms + card.num_sectors = (c_size + 1) * 1024; // number of 512-byte sectors } else { unsigned int taac, nsac, read_bl_len, c_size, c_size_mult; @@ -253,9 +236,9 @@ void sdmmc_needs_discover(void) taac, nsac, read_bl_len, c_size, c_size_mult, (c_size + 1) * (4 << c_size_mult) * (1 << read_bl_len)); static const unsigned int time_unit[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000}; static const unsigned int time_value[] = {1, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80}; // must div by 10 - c->timeout = time_unit[taac & 7] * time_value[(taac >> 3) & 0xf] / 10; - gecko_printf("calculated timeout = %uns\n", c->timeout); - c->num_sectors = (c_size + 1) * (4 << c_size_mult) * (1 << read_bl_len) / 512; + card.timeout = time_unit[taac & 7] * time_value[(taac >> 3) & 0xf] / 10; + gecko_printf("calculated timeout = %uns\n", card.timeout); + card.num_sectors = (c_size + 1) * (4 << c_size_mult) * (1 << read_bl_len) / 512; } sdmmc_select(); @@ -264,19 +247,19 @@ void sdmmc_needs_discover(void) cmd.c_opcode = MMC_SET_BLOCKLEN; cmd.c_arg = SDMMC_DEFAULT_BLOCKLEN; cmd.c_flags = SCF_RSP_R1; - sdhc_exec_command(c->handle, &cmd); + sdhc_exec_command(card.handle, &cmd); if (cmd.c_error) { gecko_printf("sdmmc: MMC_SET_BLOCKLEN failed with %d\n", cmd.c_error); - c->inserted = c->selected = 0; + card.inserted = card.selected = 0; goto out_clock; } return; out_clock: - sdhc_bus_clock(c->handle, SDMMC_SDCLK_OFF); + sdhc_bus_clock(card.handle, SDMMC_SDCLK_OFF); out_power: - sdhc_bus_power(c->handle, 0); + sdhc_bus_power(card.handle, 0); out: return; } @@ -284,36 +267,33 @@ out: int sdmmc_select(void) { - struct sdmmc_card *c = &cards[0]; struct sdmmc_command cmd; DPRINTF(2, ("sdmmc: MMC_SELECT_CARD\n")); memset(&cmd, 0, sizeof(cmd)); cmd.c_opcode = MMC_SELECT_CARD; - cmd.c_arg = ((u32)c->rca)<<16; + cmd.c_arg = ((u32)card.rca)<<16; cmd.c_flags = SCF_RSP_R1B; - sdhc_exec_command(c->handle, &cmd); + sdhc_exec_command(card.handle, &cmd); gecko_printf("%s: resp=%x\n", __FUNCTION__, MMC_R1(cmd.c_resp)); - sdhc_dump_regs(c->handle); - + sdhc_dump_regs(card.handle); + // gecko_printf("present state = %x\n", HREAD4(hp, SDHC_PRESENT_STATE)); if (cmd.c_error) { gecko_printf("sdmmc: MMC_SELECT card failed with %d.\n", cmd.c_error); return -1; } - c->selected = 1; + card.selected = 1; return 0; } int sdmmc_check_card(void) { - struct sdmmc_card *c = &cards[0]; - - if (c->inserted == 0) + if (card.inserted == 0) return SDMMC_NO_CARD; - if (c->new_card == 1) + if (card.new_card == 1) return SDMMC_NEW_CARD; return SDMMC_INSERTED; @@ -321,10 +301,8 @@ int sdmmc_check_card(void) int sdmmc_ack_card(void) { - struct sdmmc_card *c = &cards[0]; - - if (c->new_card == 1) { - c->new_card = 0; + if (card.new_card == 1) { + card.new_card = 0; return 0; } @@ -333,23 +311,22 @@ int sdmmc_ack_card(void) int sdmmc_read(u32 blk_start, u32 blk_count, void *data) { - struct sdmmc_card *c = &cards[0]; struct sdmmc_command cmd; gecko_printf("%s(%u, %u, %p)\n", __FUNCTION__, blk_start, blk_count, data); - if (c->inserted == 0) { + if (card.inserted == 0) { gecko_printf("sdmmc: READ: no card inserted.\n"); return -1; } - if (c->selected == 0) { + if (card.selected == 0) { if (sdmmc_select() < 0) { gecko_printf("sdmmc: READ: cannot select card.\n"); return -1; } } - if (c->new_card == 1) { + if (card.new_card == 1) { gecko_printf("sdmmc: new card inserted but not acknowledged yet.\n"); return -1; } @@ -357,7 +334,7 @@ int sdmmc_read(u32 blk_start, u32 blk_count, void *data) DPRINTF(2, ("sdmmc: MMC_READ_BLOCK_MULTIPLE\n")); memset(&cmd, 0, sizeof(cmd)); cmd.c_opcode = MMC_READ_BLOCK_MULTIPLE; - if (c->sdhc_blockmode) + if (card.sdhc_blockmode) cmd.c_arg = blk_start; else cmd.c_arg = blk_start * SDMMC_DEFAULT_BLOCKLEN; @@ -365,7 +342,7 @@ int sdmmc_read(u32 blk_start, u32 blk_count, void *data) cmd.c_datalen = blk_count * SDMMC_DEFAULT_BLOCKLEN; cmd.c_blklen = SDMMC_DEFAULT_BLOCKLEN; cmd.c_flags = SCF_RSP_R1 | SCF_CMD_READ; - sdhc_exec_command(c->handle, &cmd); + sdhc_exec_command(card.handle, &cmd); if (cmd.c_error) { gecko_printf("sdmmc: MMC_READ_BLOCK_MULTIPLE failed with %d\n", cmd.c_error); @@ -379,22 +356,21 @@ int sdmmc_read(u32 blk_start, u32 blk_count, void *data) #ifndef LOADER int sdmmc_write(u32 blk_start, u32 blk_count, void *data) { - struct sdmmc_card *c = &cards[0]; struct sdmmc_command cmd; - if (c->inserted == 0) { + if (card.inserted == 0) { gecko_printf("sdmmc: READ: no card inserted.\n"); return -1; } - if (c->selected == 0) { + if (card.selected == 0) { if (sdmmc_select() < 0) { gecko_printf("sdmmc: READ: cannot select card.\n"); return -1; } } - if (c->new_card == 1) { + if (card.new_card == 1) { gecko_printf("sdmmc: new card inserted but not acknowledged yet.\n"); return -1; } @@ -402,7 +378,7 @@ int sdmmc_write(u32 blk_start, u32 blk_count, void *data) DPRINTF(2, ("sdmmc: MMC_WRITE_BLOCK_MULTIPLE\n")); memset(&cmd, 0, sizeof(cmd)); cmd.c_opcode = MMC_WRITE_BLOCK_MULTIPLE; - if (c->sdhc_blockmode) + if (card.sdhc_blockmode) cmd.c_arg = blk_start; else cmd.c_arg = blk_start * SDMMC_DEFAULT_BLOCKLEN; @@ -410,7 +386,7 @@ int sdmmc_write(u32 blk_start, u32 blk_count, void *data) cmd.c_datalen = blk_count * SDMMC_DEFAULT_BLOCKLEN; cmd.c_blklen = SDMMC_DEFAULT_BLOCKLEN; cmd.c_flags = SCF_RSP_R1; - sdhc_exec_command(c->handle, &cmd); + sdhc_exec_command(card.handle, &cmd); if (cmd.c_error) { gecko_printf("sdmmc: MMC_READ_BLOCK_MULTIPLE failed with %d\n", cmd.c_error); @@ -423,21 +399,19 @@ int sdmmc_write(u32 blk_start, u32 blk_count, void *data) int sdmmc_get_sectors(void) { - struct sdmmc_card *c = &cards[0]; - - if (c->inserted == 0) { + if (card.inserted == 0) { gecko_printf("sdmmc: READ: no card inserted.\n"); return -1; } - if (c->new_card == 1) { + if (card.new_card == 1) { gecko_printf("sdmmc: new card inserted but not acknowledged yet.\n"); return -1; } // sdhc_error(sdhci->reg_base, "num sectors = %u", sdhci->num_sectors); - return c->num_sectors; + return card.num_sectors; } #endif diff --git a/sdmmc.h b/sdmmc.h index fbac277..b61a546 100644 --- a/sdmmc.h +++ b/sdmmc.h @@ -15,8 +15,7 @@ Copyright (C) 2008, 2009 Sven Peter struct sdmmc_command; -typedef struct sdmmc_chip_functions *sdmmc_chipset_tag_t; -typedef void *sdmmc_chipset_handle_t; +typedef struct sdhc_host * sdmmc_chipset_handle_t; /* clock frequencies for sdmmc_chip_bus_clock() */ #define SDMMC_SDCLK_OFF 0 @@ -157,7 +156,7 @@ struct sdmmc_function { #define SDMMC_NEW_CARD 2 #define SDMMC_INSERTED 3 -void sdmmc_attach(sdmmc_chipset_handle_t handle, const char *name, int no); +void sdmmc_attach(sdmmc_chipset_handle_t handle); void sdmmc_needs_discover(void); int sdmmc_select(void); int sdmmc_check_card(void); @@ -304,7 +303,7 @@ void sdmmc_ipc(volatile ipc_request *req); #define SD_CSD_CAPACITY(resp) ((SD_CSD_C_SIZE((resp))+1) << \ (SD_CSD_C_SIZE_MULT((resp))+2)) #define SD_CSD_V2_C_SIZE(resp) MMC_RSP_BITS((resp), 48, 22) -#define SD_CSD_V2_CAPACITY(resp) ((SD_CSD_V2_C_SIZE((resp))+1) << 10) +#define SD_CSD_V2_CAPACITY(resp) ((SD_CSD_V2_C_SIZE((resp))+1) << 10) #define SD_CSD_V2_BL_LEN 0x9 /* 512 */ #define SD_CSD_VDD_R_CURR_MIN(resp) MMC_RSP_BITS((resp), 59, 3) #define SD_CSD_VDD_R_CURR_MAX(resp) MMC_RSP_BITS((resp), 56, 3)