Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Index: fsl_sdhc.c
- ===================================================================
- --- fsl_sdhc.c (revision 243277)
- +++ fsl_sdhc.c (working copy)
- @@ -64,8 +64,11 @@
- #include "fsl_sdhc.h"
- +//#undef FSL_SDHC_NO_DMA
- +//#define FSL_SDHC_NO_DMA
- +//#undef FSL_SDHC_NO_DMA
- #define DEBUG
- -#undef DEBUG
- +//#undef DEBUG
- #ifdef DEBUG
- #define DPRINTF(fmt, arg...) printf("DEBUG %s(): " fmt, __FUNCTION__, ##arg)
- #else
- @@ -90,6 +93,10 @@
- static int fsl_sdhc_acquire_host(device_t, device_t);
- static int fsl_sdhc_release_host(device_t, device_t);
- +#ifdef DEBUG
- +static void dump_registers(struct fsl_sdhc_softc *);
- +#endif
- +
- static device_method_t fsl_sdhc_methods[] = {
- /* device_if */
- DEVMETHOD(device_probe, fsl_sdhc_probe),
- @@ -119,14 +126,14 @@
- /* kobj_class definition */
- static driver_t fsl_sdhc_driver = {
- - "sdhci",
- + "sdhci_imx",
- fsl_sdhc_methods,
- sizeof(struct fsl_sdhc_softc)
- };
- static devclass_t fsl_sdhc_devclass;
- -DRIVER_MODULE(sdhci, simplebus, fsl_sdhc_driver, fsl_sdhc_devclass, 0, 0);
- +DRIVER_MODULE(sdhci_imx, simplebus, fsl_sdhc_driver, fsl_sdhc_devclass, 0, 0);
- /*****************************************************************************
- @@ -210,6 +217,7 @@
- self = sc->self;
- node = ofw_bus_get_node(self);
- + clock = 0;
- /* Get sdhci node properties */
- if((OF_getprop(node, "clock-frequency", (void *)&clock,
- @@ -232,7 +240,9 @@
- }
- }
- - DPRINTF("Acquired clock: %d from DTS\n", clock);
- + //clock *= 14; /* XXX: Fix FDT better */
- + clock = 216000000;
- + DPRINTF("Acquired clock: %u from DTS\n", clock);
- return (clock);
- }
- @@ -253,8 +263,14 @@
- return;
- if (clock == 0) {
- - clear_bit(sc, SDHC_SYSCTL, MASK_CLOCK_CONTROL | SYSCTL_PEREN |
- - SYSCTL_HCKEN | SYSCTL_IPGEN);
- + if (sc->mode == FSL_SDHC_MODE_MPC)
- + clear_bit(sc, SDHC_SYSCTL, MASK_CLOCK_CONTROL |
- + SYSCTL_PEREN | SYSCTL_HCKEN | SYSCTL_IPGEN);
- + else if (sc->mode == FSL_SDHC_MODE_IMX)
- + clear_bit(sc, SDHC_SYSCTL, MASK_CLOCK_CONTROL |
- + SYSCTL_SDCLKEN | SYSCTL_PEREN | SYSCTL_HCKEN |
- + SYSCTL_IPGEN);
- + /* else undefined mode */
- return;
- }
- @@ -296,7 +312,12 @@
- * it prevents controller from generating card insertion/removal
- * interrupts correctly.
- */
- - set_bit(sc, SDHC_SYSCTL, SYSCTL_PEREN | SYSCTL_HCKEN | SYSCTL_IPGEN);
- + if (sc->mode == FSL_SDHC_MODE_MPC)
- + set_bit(sc, SDHC_SYSCTL, SYSCTL_PEREN | SYSCTL_HCKEN |
- + SYSCTL_IPGEN);
- + else if (sc->mode == FSL_SDHC_MODE_IMX)
- + set_bit(sc, SDHC_SYSCTL, SYSCTL_SDCLKEN | SYSCTL_PEREN |
- + SYSCTL_HCKEN | SYSCTL_IPGEN);
- sc->slot.clock = clock;
- @@ -388,7 +409,8 @@
- write4(sc, SDHC_DSADDR, sc->dma_phys);
- /* Enable snooping and fix for AHB2MAG bypass. */
- - write4(sc, SDHC_DCR, DCR_SNOOP | DCR_AHB2MAG_BYPASS);
- + if (sc->mode == FSL_SDHC_MODE_MPC)
- + write4(sc, SDHC_DCR, DCR_SNOOP | DCR_AHB2MAG_BYPASS);
- #endif
- /* Set data timeout. */
- set_bit(sc, SDHC_SYSCTL, 0xe << SHIFT_DTOCV);
- @@ -413,13 +435,26 @@
- /* Set operation conditions (voltage). */
- host->host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
- + host->host_ocr |= MMC_OCR_290_300 | MMC_OCR_300_310; //
- +// host->host_ocr |= MMC_OCR_LOW_VOLTAGE; //
- +
- /* Set additional host controller capabilities. */
- host->caps = MMC_CAP_4_BIT_DATA;
- + host->caps |= MMC_CAP_HSPEED; //
- /* Set mode. */
- host->mode = mode_sd;
- }
- +#define GPIO_DATA_REG(_u) (*((volatile uint32_t *)(0xf3f84000 + (0x4000 * (_u)))))
- +#define GPIO_DIR_REG(_u) (*((volatile uint32_t *)(0xf3f84004 + (0x4000 * (_u)))))
- +
- +#define GPIO_GET(_b) (GPIO_DATA_REG((_b) / 32) & (1 << ((_b) % 32)))
- +#define GPIO_SET(_b) GPIO_DATA_REG((_b) / 32) = GPIO_DATA_REG((_b) / 32) | (1 << ((_b) % 32))
- +#define GPIO_CLEAR(_b) GPIO_DATA_REG((_b) / 32) = GPIO_DATA_REG((_b) / 32) & ~(1 << ((_b) % 32))
- +#define GPIO_OUT(_b) GPIO_DIR_REG((_b) / 32) = GPIO_DIR_REG((_b) / 32) | (1 << ((_b) % 32))
- +#define GPIO_IN(_b) GPIO_DIR_REG((_b) / 32) = GPIO_DIR_REG((_b) / 32) & ~(1 << ((_b) % 32))
- +
- static void
- card_detect_task(void *arg, int pending)
- {
- @@ -427,7 +462,11 @@
- int err;
- int insert;
- +#ifdef GPIO_CD
- + insert = GPIO_GET(0)?0:1;
- +#else
- insert = read4(sc, SDHC_PRSSTAT) & PRSSTAT_CINS;
- +#endif
- mtx_lock(&sc->mtx);
- @@ -480,10 +519,40 @@
- }
- static void
- +transfer_timeout_task(void *arg, int pending)
- +{
- + struct fsl_sdhc_softc *sc = (struct fsl_sdhc_softc *)arg;
- +
- + sc->request->cmd->error = MMC_ERR_TIMEOUT;
- + sc->command_done = 1;
- + sc->data_done = 1;
- + dump_registers(sc);
- + set_clock(sc, 0);
- + reset_controller_dat_cmd(sc);
- + set_clock(sc, sc->slot.clock);
- + init_controller(sc);
- + dump_registers(sc);
- +
- + mtx_lock(&sc->mtx);
- + if (callout_active(&sc->transfer_timeout_callout))
- + callout_stop(&sc->transfer_timeout_callout);
- + mtx_unlock(&sc->mtx);
- +}
- +
- +static void
- +transfer_timeout(void *arg)
- +{
- + struct fsl_sdhc_softc *sc = arg;
- +
- + taskqueue_enqueue(taskqueue_swi_giant, &sc->transfer_timeout_task);
- + device_printf(sc->self, "Transfer timeout, reseting controller");
- +}
- +
- +static void
- finalize_request(struct fsl_sdhc_softc *sc)
- {
- - DPRINTF("finishing request %x\n", sc->request);
- + DPRINTF("finishing request %x\n", (uint32_t)sc->request);
- sc->request->done(sc->request);
- sc->request = NULL;
- @@ -623,7 +692,8 @@
- }
- if (cmd->error) {
- - device_printf(sc->self, "Error interrupt occured\n");
- + device_printf(sc->self, "Error interrupt occured, "
- + "irq = 0x%08x\n", irq_stat);
- reset_controller_dat_cmd(sc);
- return;
- }
- @@ -642,8 +712,9 @@
- static inline void
- handle_data_intr(struct fsl_sdhc_softc *sc, uint32_t irq_stat)
- {
- - struct mmc_command *cmd = sc->request->cmd;
- + struct mmc_command *cmd;
- + cmd = sc->request->cmd;
- /* Handle errors. */
- if (irq_stat & IRQ_DTOE) {
- cmd->error = MMC_ERR_TIMEOUT;
- @@ -660,8 +731,10 @@
- return;
- }
- - if (sc->data_done)
- + if (sc->data_done) {
- + printf(" [TC/DINT] w/ data_done] ");
- return;
- + }
- #ifdef FSL_SDHC_NO_DMA
- if (irq_stat & IRQ_BRR) {
- @@ -671,30 +744,11 @@
- if (irq_stat & IRQ_BWR) {
- pio_write_transfer(sc);
- }
- -#else
- - if (irq_stat & IRQ_DINT) {
- - struct mmc_data *data = sc->request->cmd->data;
- -
- - /* Synchronize DMA. */
- - if (data->flags & MMC_DATA_READ) {
- - bus_dmamap_sync(sc->dma_tag, sc->dma_map,
- - BUS_DMASYNC_POSTREAD);
- - memcpy(data->data, sc->dma_mem, data->len);
- - } else {
- - bus_dmamap_sync(sc->dma_tag, sc->dma_map,
- - BUS_DMASYNC_POSTWRITE);
- - }
- -
- - /*
- - * TODO: For multiple block transfers, address of dma memory
- - * in DSADDR register should be set to the beginning of the
- - * segment here. Also offset to data pointer should be handled.
- - */
- - }
- #endif
- - if (irq_stat & IRQ_TC)
- + if (irq_stat & IRQ_TC) {
- sc->data_done = 1;
- + }
- }
- static void
- @@ -737,8 +791,10 @@
- /* Handle request interrupts. */
- if (sc->request) {
- - handle_command_intr(sc, irq_stat);
- - handle_data_intr(sc, irq_stat);
- + if (irq_stat & IRQ_CMD_MASK)
- + handle_command_intr(sc, irq_stat);
- + if (irq_stat & IRQ_DATA_MASK)
- + handle_data_intr(sc, irq_stat);
- /*
- * Finalize request when transfer is done successfully
- @@ -746,6 +802,8 @@
- */
- if ((sc->data_done && sc->command_done) ||
- (sc->request->cmd->error))
- + if (callout_active(&sc->transfer_timeout_callout))
- + callout_stop(&sc->transfer_timeout_callout);
- finalize_request(sc);
- }
- @@ -773,10 +831,11 @@
- device_t self = sc->self;
- int err;
- + /* XXX: fix DMA, now we have panic on block size more than 16384 */
- err = bus_dma_tag_create(bus_get_dma_tag(self),
- FSL_SDHC_DMA_BLOCK_SIZE, 0, BUS_SPACE_MAXADDR_32BIT,
- - BUS_SPACE_MAXADDR, NULL, NULL, FSL_SDHC_DMA_BLOCK_SIZE, 1,
- - FSL_SDHC_DMA_BLOCK_SIZE, BUS_DMA_ALLOCNOW, NULL, NULL,
- + BUS_SPACE_MAXADDR, NULL, NULL, FSL_SDHC_DMA_BLOCK_SIZE*4, 1,
- + FSL_SDHC_DMA_BLOCK_SIZE*4, BUS_DMA_ALLOCNOW, NULL, NULL,
- &sc->dma_tag);
- if (err) {
- @@ -792,7 +851,7 @@
- }
- err = bus_dmamap_load(sc->dma_tag, sc->dma_map, (void *)sc->dma_mem,
- - FSL_SDHC_DMA_BLOCK_SIZE, dma_get_phys_addr, &sc->dma_phys, 0);
- + FSL_SDHC_DMA_BLOCK_SIZE*4, dma_get_phys_addr, &sc->dma_phys, 0);
- if (err) {
- device_printf(self, "Could not load DMA map!\n");
- goto fail2;
- @@ -824,10 +883,19 @@
- /* Set data preset select. */
- if (cmd->data) {
- xfertyp |= XFERTYP_DPSEL;
- + /* Enable Block count */
- + xfertyp |= XFERTYP_BCEN;
- /* Set transfer direction. */
- if (cmd->data->flags & MMC_DATA_READ)
- xfertyp |= XFERTYP_DTDSEL;
- + if (cmd->data->len > 512) {
- + /* Enable Multiblock */
- + xfertyp |= XFERTYP_MSBSEL;
- + /* Enable AC12 (Errata) */
- + xfertyp |= XFERTYP_AC12EN;
- + }
- +
- }
- /* Set command index check. */
- @@ -856,20 +924,6 @@
- return (xfertyp);
- }
- -static uint32_t
- -set_blkattr_register(const struct mmc_data *data)
- -{
- -
- - if (data->len <= FSL_SDHC_MAX_BLOCK_SIZE) {
- - /* One block transfer. */
- - return (BLKATTR_BLOCK_COUNT(1) | ((data->len) &
- - BLKATTR_BLKSZE));
- - }
- -
- - /* TODO: Write code here for multi-block transfers. */
- - return (0);
- -}
- -
- /**
- * Initiate data transfer. Interrupt handler will finalize it.
- * @todo Implement multi-block transfers.
- @@ -879,7 +933,6 @@
- static int
- start_data(struct fsl_sdhc_softc *sc, struct mmc_data *data)
- {
- - uint32_t reg;
- if ((uint32_t)data->data & 0x3) {
- device_printf(sc->self, "32-bit unaligned data pointer in "
- @@ -901,19 +954,13 @@
- bus_dmamap_sync(sc->dma_tag, sc->dma_map,
- BUS_DMASYNC_PREREAD);
- } else {
- - memcpy(sc->dma_mem, data->data, data->len);
- + memcpy(sc->dma_mem, data->data, MIN(data->len, 512));
- bus_dmamap_sync(sc->dma_tag, sc->dma_map,
- BUS_DMASYNC_PREWRITE);
- }
- #endif
- - /* Set block size and count. */
- - reg = set_blkattr_register(data);
- - if (reg == 0) {
- - device_printf(sc->self, "Requested unsupported multi-block "
- - "transfer.\n");
- - return (-1);
- - }
- - write4(sc, SDHC_BLKATTR, reg);
- + write4(sc, SDHC_BLKATTR, BLKATTR_BLOCK_COUNT((data->len + 511) / 512)|
- + MIN(data->len, 512));
- return (0);
- }
- @@ -934,7 +981,6 @@
- cmd->error = MMC_ERR_NONE;
- /* TODO: should we check here for card presence and clock settings? */
- -
- /* Always wait for free CMD line. */
- mask = SDHC_CMD_LINE;
- /* Wait for free DAT if we have data or busy signal. */
- @@ -984,7 +1030,10 @@
- {
- printf("PRSSTAT = 0x%08x\n", read4(sc, SDHC_PRSSTAT));
- printf("PROCTL = 0x%08x\n", read4(sc, SDHC_PROCTL));
- - printf("PMUXCR = 0x%08x\n", ccsr_read4(OCP85XX_PMUXCR));
- +#if 0 /* Where OCP85XX_PMUXCR is defined? */
- + if (sc->mode == FSL_SDHC_MODE_MPC)
- + printf("PMUXCR = 0x%08x\n", ccsr_read4(OCP85XX_PMUXCR));
- +#endif
- printf("HOSTCAPBLT = 0x%08x\n", read4(sc, SDHC_HOSTCAPBLT));
- printf("IRQSTAT = 0x%08x\n", read4(sc, SDHC_IRQSTAT));
- printf("IRQSTATEN = 0x%08x\n", read4(sc, SDHC_IRQSTATEN));
- @@ -992,8 +1041,12 @@
- printf("WML = 0x%08x\n", read4(sc, SDHC_WML));
- printf("DSADDR = 0x%08x\n", read4(sc, SDHC_DSADDR));
- printf("XFERTYP = 0x%08x\n", read4(sc, SDHC_XFERTYP));
- - printf("ECMCR = 0x%08x\n", ccsr_read4(OCP85XX_ECMCR));
- - printf("DCR = 0x%08x\n", read4(sc, SDHC_DCR));
- + if (sc->mode == FSL_SDHC_MODE_MPC) {
- +#if 0 /* Where OCP85XX_ECMCR is defined? */
- + printf("ECMCR = 0x%08x\n", ccsr_read4(OCP85XX_ECMCR));
- +#endif
- + printf("DCR = 0x%08x\n", read4(sc, SDHC_DCR));
- + }
- }
- #endif
- @@ -1006,11 +1059,19 @@
- static int
- fsl_sdhc_probe(device_t self)
- {
- + struct fsl_sdhc_softc *sc;
- +
- static const char *desc =
- "Freescale Enhanced Secure Digital Host Controller";
- - if (!ofw_bus_is_compatible(self, "fsl,p2020-esdhc") &&
- - !ofw_bus_is_compatible(self, "fsl,esdhc"))
- + sc = device_get_softc(self);
- + if (ofw_bus_is_compatible(self, "fsl,p2020-esdhc") ||
- + ofw_bus_is_compatible(self, "fsl,esdhc"))
- + sc->mode = FSL_SDHC_MODE_DEFAULT;
- + else if (ofw_bus_is_compatible(self, "fsl,imx51-esdhc") ||
- + ofw_bus_is_compatible(self, "fsl,imx-esdhc"))
- + sc->mode = FSL_SDHC_MODE_IMX;
- + else
- return (ENXIO);
- device_set_desc(self, desc);
- @@ -1073,6 +1134,9 @@
- TASK_INIT(&sc->card_detect_task, 0, card_detect_task, sc);
- callout_init(&sc->card_detect_callout, 1);
- + TASK_INIT(&sc->transfer_timeout_task, 0, transfer_timeout_task, sc);
- + callout_init(&sc->transfer_timeout_callout, 1);
- +
- reset_controller_all(sc);
- init_controller(sc);
- set_clock(sc, 400000);
- @@ -1259,6 +1323,8 @@
- mtx_lock(&sc->mtx);
- sc->request = req;
- + callout_reset(&sc->transfer_timeout_callout, hz,
- + transfer_timeout, sc);
- err = start_command(sc, req->cmd);
- mtx_unlock(&sc->mtx);
- @@ -1272,7 +1338,11 @@
- struct fsl_sdhc_softc *sc = device_get_softc(self);
- /* Wouldn't it be faster using branching (if {}) ?? */
- +#ifdef GPIO_CD
- + return (GPIO_GET(1)?1:0);
- +#else
- return (((read4(sc, SDHC_PRSSTAT) & PRSSTAT_WPSPL) >> 19) ^ 0x1);
- +#endif
- }
- static int
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement