/* * Copyright (C) 2010 Marek Vasut * * Loosely based on the old code and Linux's PXA MMC driver * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #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 = (struct pxa_mmc_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 = (struct pxa_mmc_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 = (struct pxa_mmc_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 = (struct pxa_mmc_priv *)mmc->priv; struct pxa_mmc_regs *regs = priv->regs; uint32_t 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 = (struct pxa_mmc_priv *)mmc->priv; struct pxa_mmc_regs *regs = priv->regs; uint32_t len; uint32_t *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, 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 = (struct pxa_mmc_priv *)mmc->priv; struct pxa_mmc_regs *regs = priv->regs; uint32_t len; uint32_t *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, PXAMMC_FIFO_SIZE); len -= size; size /= 4; while (size--) writel(*buf++, ®s->txfifo); if (min(len, 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_request(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv; struct pxa_mmc_regs *regs = priv->regs; uint32_t 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 void pxa_mmc_set_ios(struct mmc *mmc) { struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv; struct pxa_mmc_regs *regs = priv->regs; uint32_t tmp; uint32_t pxa_mmc_clock; if (!mmc->clock) { pxa_mmc_stop_clock(mmc); return; } /* PXA3xx can do 26MHz with special settings. */ if (mmc->clock == 26000000) { writel(0x7, ®s->clkrt); return; } /* Set clock to the card the usual way. */ pxa_mmc_clock = 0; tmp = mmc->f_max / mmc->clock; tmp += tmp % 2; while (tmp > 1) { pxa_mmc_clock++; tmp >>= 1; } writel(pxa_mmc_clock, ®s->clkrt); } static int pxa_mmc_init(struct mmc *mmc) { struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv; 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; } int pxa_mmc_register(int card_index) { struct mmc *mmc; struct pxa_mmc_priv *priv; uint32_t reg; int ret = -ENOMEM; mmc = malloc(sizeof(struct mmc)); if (!mmc) goto err0; priv = malloc(sizeof(struct pxa_mmc_priv)); if (!priv) goto err1; 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: printf("PXA MMC: Invalid MMC controller ID (card_index = %d)\n", card_index); goto err2; } mmc->priv = priv; sprintf(mmc->name, "PXA MMC"); mmc->send_cmd = pxa_mmc_request; mmc->set_ios = pxa_mmc_set_ios; mmc->init = pxa_mmc_init; mmc->getcd = NULL; mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->f_max = PXAMMC_MAX_SPEED; mmc->f_min = PXAMMC_MIN_SPEED; mmc->host_caps = PXAMMC_HOST_CAPS; mmc->b_max = 0; #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_register(mmc); return 0; err2: free(priv); err1: free(mmc); err0: return ret; }