// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2010 Marek Vasut * * Modified to add driver model (DM) support * Copyright (C) 2019 Marcel Ziswiler * * Loosely based on the old code and Linux's PXA MMC driver */ #include #include #include #include #include #include #include #include #include #include /* PXAMMC Generic default config for various CPUs */ #if defined(CONFIG_CPU_PXA25X) #define PXAMMC_FIFO_SIZE 1 #define PXAMMC_MIN_SPEED 312500 #define PXAMMC_MAX_SPEED 20000000 #define PXAMMC_HOST_CAPS (0) #elif defined(CONFIG_CPU_PXA27X) #define PXAMMC_CRC_SKIP #define PXAMMC_FIFO_SIZE 32 #define PXAMMC_MIN_SPEED 304000 #define PXAMMC_MAX_SPEED 19500000 #define PXAMMC_HOST_CAPS (MMC_MODE_4BIT) #elif defined(CONFIG_CPU_MONAHANS) #define PXAMMC_FIFO_SIZE 32 #define PXAMMC_MIN_SPEED 304000 #define PXAMMC_MAX_SPEED 26000000 #define PXAMMC_HOST_CAPS (MMC_MODE_4BIT | MMC_MODE_HS) #else #error "This CPU isn't supported by PXA MMC!" #endif #define MMC_STAT_ERRORS \ (MMC_STAT_RES_CRC_ERROR | MMC_STAT_SPI_READ_ERROR_TOKEN | \ MMC_STAT_CRC_READ_ERROR | MMC_STAT_TIME_OUT_RESPONSE | \ MMC_STAT_READ_TIME_OUT | MMC_STAT_CRC_WRITE_ERROR) /* 1 millisecond (in wait cycles below it's 100 x 10uS waits) */ #define PXA_MMC_TIMEOUT 100 struct pxa_mmc_priv { struct pxa_mmc_regs *regs; }; /* Wait for bit to be set */ static int pxa_mmc_wait(struct mmc *mmc, uint32_t mask) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; unsigned int timeout = PXA_MMC_TIMEOUT; /* Wait for bit to be set */ while (--timeout) { if (readl(®s->stat) & mask) break; udelay(10); } if (!timeout) return -ETIMEDOUT; return 0; } static int pxa_mmc_stop_clock(struct mmc *mmc) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; unsigned int timeout = PXA_MMC_TIMEOUT; /* If the clock aren't running, exit */ if (!(readl(®s->stat) & MMC_STAT_CLK_EN)) return 0; /* Tell the controller to turn off the clock */ writel(MMC_STRPCL_STOP_CLK, ®s->strpcl); /* Wait until the clock are off */ while (--timeout) { if (!(readl(®s->stat) & MMC_STAT_CLK_EN)) break; udelay(10); } /* The clock refused to stop, scream and die a painful death */ if (!timeout) return -ETIMEDOUT; /* The clock stopped correctly */ return 0; } static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd, uint32_t cmdat) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; int ret; /* The card can send a "busy" response */ if (cmd->resp_type & MMC_RSP_BUSY) cmdat |= MMC_CMDAT_BUSY; /* Inform the controller about response type */ switch (cmd->resp_type) { case MMC_RSP_R1: case MMC_RSP_R1b: cmdat |= MMC_CMDAT_R1; break; case MMC_RSP_R2: cmdat |= MMC_CMDAT_R2; break; case MMC_RSP_R3: cmdat |= MMC_CMDAT_R3; break; default: break; } /* Load command and it's arguments into the controller */ writel(cmd->cmdidx, ®s->cmd); writel(cmd->cmdarg >> 16, ®s->argh); writel(cmd->cmdarg & 0xffff, ®s->argl); writel(cmdat, ®s->cmdat); /* Start the controller clock and wait until they are started */ writel(MMC_STRPCL_START_CLK, ®s->strpcl); ret = pxa_mmc_wait(mmc, MMC_STAT_CLK_EN); if (ret) return ret; /* Correct and happy end */ return 0; } static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; u32 a, b, c; int i; int stat; /* Read the controller status */ stat = readl(®s->stat); /* * Linux says: * Did I mention this is Sick. We always need to * discard the upper 8 bits of the first 16-bit word. */ a = readl(®s->res) & 0xffff; for (i = 0; i < 4; i++) { b = readl(®s->res) & 0xffff; c = readl(®s->res) & 0xffff; cmd->response[i] = (a << 24) | (b << 8) | (c >> 8); a = c; } /* The command response didn't arrive */ if (stat & MMC_STAT_TIME_OUT_RESPONSE) { return -ETIMEDOUT; } else if (stat & MMC_STAT_RES_CRC_ERROR && cmd->resp_type & MMC_RSP_CRC) { #ifdef PXAMMC_CRC_SKIP if (cmd->resp_type & MMC_RSP_136 && cmd->response[0] & (1 << 31)) printf("Ignoring CRC, this may be dangerous!\n"); else #endif return -EILSEQ; } /* The command response was successfully read */ return 0; } static int pxa_mmc_do_read_xfer(struct mmc *mmc, struct mmc_data *data) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; u32 len; u32 *buf = (uint32_t *)data->dest; int size; int ret; len = data->blocks * data->blocksize; while (len) { /* The controller has data ready */ if (readl(®s->i_reg) & MMC_I_REG_RXFIFO_RD_REQ) { size = min(len, (uint32_t)PXAMMC_FIFO_SIZE); len -= size; size /= 4; /* Read data into the buffer */ while (size--) *buf++ = readl(®s->rxfifo); } if (readl(®s->stat) & MMC_STAT_ERRORS) return -EIO; } /* Wait for the transmission-done interrupt */ ret = pxa_mmc_wait(mmc, MMC_STAT_DATA_TRAN_DONE); if (ret) return ret; return 0; } static int pxa_mmc_do_write_xfer(struct mmc *mmc, struct mmc_data *data) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; u32 len; u32 *buf = (uint32_t *)data->src; int size; int ret; len = data->blocks * data->blocksize; while (len) { /* The controller is ready to receive data */ if (readl(®s->i_reg) & MMC_I_REG_TXFIFO_WR_REQ) { size = min(len, (uint32_t)PXAMMC_FIFO_SIZE); len -= size; size /= 4; while (size--) writel(*buf++, ®s->txfifo); if (min(len, (uint32_t)PXAMMC_FIFO_SIZE) < 32) writel(MMC_PRTBUF_BUF_PART_FULL, ®s->prtbuf); } if (readl(®s->stat) & MMC_STAT_ERRORS) return -EIO; } /* Wait for the transmission-done interrupt */ ret = pxa_mmc_wait(mmc, MMC_STAT_DATA_TRAN_DONE); if (ret) return ret; /* Wait until the data are really written to the card */ ret = pxa_mmc_wait(mmc, MMC_STAT_PRG_DONE); if (ret) return ret; return 0; } static int pxa_mmc_send_cmd_common(struct pxa_mmc_priv *priv, struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { struct pxa_mmc_regs *regs = priv->regs; u32 cmdat = 0; int ret; /* Stop the controller */ ret = pxa_mmc_stop_clock(mmc); if (ret) return ret; /* If we're doing data transfer, configure the controller accordingly */ if (data) { writel(data->blocks, ®s->nob); writel(data->blocksize, ®s->blklen); /* This delay can be optimized, but stick with max value */ writel(0xffff, ®s->rdto); cmdat |= MMC_CMDAT_DATA_EN; if (data->flags & MMC_DATA_WRITE) cmdat |= MMC_CMDAT_WRITE; } /* Run in 4bit mode if the card can do it */ if (mmc->bus_width == 4) cmdat |= MMC_CMDAT_SD_4DAT; /* Execute the command */ ret = pxa_mmc_start_cmd(mmc, cmd, cmdat); if (ret) return ret; /* Wait until the command completes */ ret = pxa_mmc_wait(mmc, MMC_STAT_END_CMD_RES); if (ret) return ret; /* Read back the result */ ret = pxa_mmc_cmd_done(mmc, cmd); if (ret) return ret; /* In case there was a data transfer scheduled, do it */ if (data) { if (data->flags & MMC_DATA_WRITE) pxa_mmc_do_write_xfer(mmc, data); else pxa_mmc_do_read_xfer(mmc, data); } return 0; } static int pxa_mmc_set_ios_common(struct pxa_mmc_priv *priv, struct mmc *mmc) { struct pxa_mmc_regs *regs = priv->regs; u32 tmp; u32 pxa_mmc_clock; if (!mmc->clock) { pxa_mmc_stop_clock(mmc); return 0; } /* PXA3xx can do 26MHz with special settings. */ if (mmc->clock == 26000000) { writel(0x7, ®s->clkrt); return 0; } /* Set clock to the card the usual way. */ pxa_mmc_clock = 0; tmp = mmc->cfg->f_max / mmc->clock; tmp += tmp % 2; while (tmp > 1) { pxa_mmc_clock++; tmp >>= 1; } writel(pxa_mmc_clock, ®s->clkrt); return 0; } static int pxa_mmc_init_common(struct pxa_mmc_priv *priv, struct mmc *mmc) { struct pxa_mmc_regs *regs = priv->regs; /* Make sure the clock are stopped */ pxa_mmc_stop_clock(mmc); /* Turn off SPI mode */ writel(0, ®s->spi); /* Set up maximum timeout to wait for command response */ writel(MMC_RES_TO_MAX_MASK, ®s->resto); /* Mask all interrupts */ writel(~(MMC_I_MASK_TXFIFO_WR_REQ | MMC_I_MASK_RXFIFO_RD_REQ), ®s->i_mask); return 0; } #if !CONFIG_IS_ENABLED(DM_MMC) static int pxa_mmc_init(struct mmc *mmc) { struct pxa_mmc_priv *priv = mmc->priv; return pxa_mmc_init_common(priv, mmc); } static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { struct pxa_mmc_priv *priv = mmc->priv; return pxa_mmc_send_cmd_common(priv, mmc, cmd, data); } static int pxa_mmc_set_ios(struct mmc *mmc) { struct pxa_mmc_priv *priv = mmc->priv; return pxa_mmc_set_ios_common(priv, mmc); } static const struct mmc_ops pxa_mmc_ops = { .send_cmd = pxa_mmc_request, .set_ios = pxa_mmc_set_ios, .init = pxa_mmc_init, }; static struct mmc_config pxa_mmc_cfg = { .name = "PXA MMC", .ops = &pxa_mmc_ops, .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, .f_max = PXAMMC_MAX_SPEED, .f_min = PXAMMC_MIN_SPEED, .host_caps = PXAMMC_HOST_CAPS, .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, }; int pxa_mmc_register(int card_index) { struct mmc *mmc; struct pxa_mmc_priv *priv; u32 reg; int ret = -ENOMEM; priv = malloc(sizeof(struct pxa_mmc_priv)); if (!priv) goto err0; memset(priv, 0, sizeof(*priv)); switch (card_index) { case 0: priv->regs = (struct pxa_mmc_regs *)MMC0_BASE; break; case 1: priv->regs = (struct pxa_mmc_regs *)MMC1_BASE; break; default: ret = -EINVAL; printf("PXA MMC: Invalid MMC controller ID (card_index = %d)\n", card_index); goto err1; } #ifndef CONFIG_CPU_MONAHANS /* PXA2xx */ reg = readl(CKEN); reg |= CKEN12_MMC; writel(reg, CKEN); #else /* PXA3xx */ reg = readl(CKENA); reg |= CKENA_12_MMC0 | CKENA_13_MMC1; writel(reg, CKENA); #endif mmc = mmc_create(&pxa_mmc_cfg, priv); if (!mmc) goto err1; return 0; err1: free(priv); err0: return ret; } #else /* !CONFIG_IS_ENABLED(DM_MMC) */ static int pxa_mmc_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct pxa_mmc_plat *plat = dev_get_platdata(dev); struct mmc_config *cfg = &plat->cfg; struct mmc *mmc = &plat->mmc; struct pxa_mmc_priv *priv = dev_get_priv(dev); u32 reg; upriv->mmc = mmc; cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; cfg->f_max = PXAMMC_MAX_SPEED; cfg->f_min = PXAMMC_MIN_SPEED; cfg->host_caps = PXAMMC_HOST_CAPS; cfg->name = dev->name; cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->priv = priv; priv->regs = plat->base; #ifndef CONFIG_CPU_MONAHANS /* PXA2xx */ reg = readl(CKEN); reg |= CKEN12_MMC; writel(reg, CKEN); #else /* PXA3xx */ reg = readl(CKENA); reg |= CKENA_12_MMC0 | CKENA_13_MMC1; writel(reg, CKENA); #endif return pxa_mmc_init_common(priv, mmc); } static int pxa_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) { struct pxa_mmc_plat *plat = dev_get_platdata(dev); struct pxa_mmc_priv *priv = dev_get_priv(dev); return pxa_mmc_send_cmd_common(priv, &plat->mmc, cmd, data); } static int pxa_mmc_set_ios(struct udevice *dev) { struct pxa_mmc_plat *plat = dev_get_platdata(dev); struct pxa_mmc_priv *priv = dev_get_priv(dev); return pxa_mmc_set_ios_common(priv, &plat->mmc); } static const struct dm_mmc_ops pxa_mmc_ops = { .get_cd = NULL, .send_cmd = pxa_mmc_send_cmd, .set_ios = pxa_mmc_set_ios, }; #if CONFIG_IS_ENABLED(BLK) static int pxa_mmc_bind(struct udevice *dev) { struct pxa_mmc_plat *plat = dev_get_platdata(dev); return mmc_bind(dev, &plat->mmc, &plat->cfg); } #endif U_BOOT_DRIVER(pxa_mmc) = { #if CONFIG_IS_ENABLED(BLK) .bind = pxa_mmc_bind, #endif .id = UCLASS_MMC, .name = "pxa_mmc", .ops = &pxa_mmc_ops, .priv_auto_alloc_size = sizeof(struct pxa_mmc_priv), .probe = pxa_mmc_probe, }; #endif /* !CONFIG_IS_ENABLED(DM_MMC) */