Lines Matching +full:pxa +full:- +full:mmc

1 // SPDX-License-Identifier: GPL-2.0+
5 * Loosely based on the old code and Linux's PXA MMC driver
10 #include <asm/arch/regs-mmc.h>
14 #include <mmc.h>
34 #error "This CPU isn't supported by PXA MMC!"
50 static int pxa_mmc_wait(struct mmc *mmc, uint32_t mask) in pxa_mmc_wait() argument
52 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_wait()
53 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_wait()
57 while (--timeout) { in pxa_mmc_wait()
58 if (readl(&regs->stat) & mask) in pxa_mmc_wait()
64 return -ETIMEDOUT; in pxa_mmc_wait()
69 static int pxa_mmc_stop_clock(struct mmc *mmc) in pxa_mmc_stop_clock() argument
71 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_stop_clock()
72 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_stop_clock()
76 if (!(readl(&regs->stat) & MMC_STAT_CLK_EN)) in pxa_mmc_stop_clock()
80 writel(MMC_STRPCL_STOP_CLK, &regs->strpcl); in pxa_mmc_stop_clock()
83 while (--timeout) { in pxa_mmc_stop_clock()
84 if (!(readl(&regs->stat) & MMC_STAT_CLK_EN)) in pxa_mmc_stop_clock()
91 return -ETIMEDOUT; in pxa_mmc_stop_clock()
97 static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd, in pxa_mmc_start_cmd() argument
100 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_start_cmd()
101 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_start_cmd()
105 if (cmd->resp_type & MMC_RSP_BUSY) in pxa_mmc_start_cmd()
109 switch (cmd->resp_type) { in pxa_mmc_start_cmd()
125 writel(cmd->cmdidx, &regs->cmd); in pxa_mmc_start_cmd()
126 writel(cmd->cmdarg >> 16, &regs->argh); in pxa_mmc_start_cmd()
127 writel(cmd->cmdarg & 0xffff, &regs->argl); in pxa_mmc_start_cmd()
128 writel(cmdat, &regs->cmdat); in pxa_mmc_start_cmd()
131 writel(MMC_STRPCL_START_CLK, &regs->strpcl); in pxa_mmc_start_cmd()
133 ret = pxa_mmc_wait(mmc, MMC_STAT_CLK_EN); in pxa_mmc_start_cmd()
141 static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) in pxa_mmc_cmd_done() argument
143 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_cmd_done()
144 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_cmd_done()
150 stat = readl(&regs->stat); in pxa_mmc_cmd_done()
155 * discard the upper 8 bits of the first 16-bit word. in pxa_mmc_cmd_done()
157 a = readl(&regs->res) & 0xffff; in pxa_mmc_cmd_done()
159 b = readl(&regs->res) & 0xffff; in pxa_mmc_cmd_done()
160 c = readl(&regs->res) & 0xffff; in pxa_mmc_cmd_done()
161 cmd->response[i] = (a << 24) | (b << 8) | (c >> 8); in pxa_mmc_cmd_done()
167 return -ETIMEDOUT; in pxa_mmc_cmd_done()
169 && cmd->resp_type & MMC_RSP_CRC) { in pxa_mmc_cmd_done()
171 if (cmd->resp_type & MMC_RSP_136 in pxa_mmc_cmd_done()
172 && cmd->response[0] & (1 << 31)) in pxa_mmc_cmd_done()
176 return -EILSEQ; in pxa_mmc_cmd_done()
183 static int pxa_mmc_do_read_xfer(struct mmc *mmc, struct mmc_data *data) in pxa_mmc_do_read_xfer() argument
185 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_do_read_xfer()
186 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_do_read_xfer()
188 uint32_t *buf = (uint32_t *)data->dest; in pxa_mmc_do_read_xfer()
192 len = data->blocks * data->blocksize; in pxa_mmc_do_read_xfer()
196 if (readl(&regs->i_reg) & MMC_I_REG_RXFIFO_RD_REQ) { in pxa_mmc_do_read_xfer()
198 len -= size; in pxa_mmc_do_read_xfer()
202 while (size--) in pxa_mmc_do_read_xfer()
203 *buf++ = readl(&regs->rxfifo); in pxa_mmc_do_read_xfer()
207 if (readl(&regs->stat) & MMC_STAT_ERRORS) in pxa_mmc_do_read_xfer()
208 return -EIO; in pxa_mmc_do_read_xfer()
211 /* Wait for the transmission-done interrupt */ in pxa_mmc_do_read_xfer()
212 ret = pxa_mmc_wait(mmc, MMC_STAT_DATA_TRAN_DONE); in pxa_mmc_do_read_xfer()
219 static int pxa_mmc_do_write_xfer(struct mmc *mmc, struct mmc_data *data) in pxa_mmc_do_write_xfer() argument
221 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_do_write_xfer()
222 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_do_write_xfer()
224 uint32_t *buf = (uint32_t *)data->src; in pxa_mmc_do_write_xfer()
228 len = data->blocks * data->blocksize; in pxa_mmc_do_write_xfer()
232 if (readl(&regs->i_reg) & MMC_I_REG_TXFIFO_WR_REQ) { in pxa_mmc_do_write_xfer()
234 len -= size; in pxa_mmc_do_write_xfer()
237 while (size--) in pxa_mmc_do_write_xfer()
238 writel(*buf++, &regs->txfifo); in pxa_mmc_do_write_xfer()
241 writel(MMC_PRTBUF_BUF_PART_FULL, &regs->prtbuf); in pxa_mmc_do_write_xfer()
244 if (readl(&regs->stat) & MMC_STAT_ERRORS) in pxa_mmc_do_write_xfer()
245 return -EIO; in pxa_mmc_do_write_xfer()
248 /* Wait for the transmission-done interrupt */ in pxa_mmc_do_write_xfer()
249 ret = pxa_mmc_wait(mmc, MMC_STAT_DATA_TRAN_DONE); in pxa_mmc_do_write_xfer()
254 ret = pxa_mmc_wait(mmc, MMC_STAT_PRG_DONE); in pxa_mmc_do_write_xfer()
261 static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, in pxa_mmc_request() argument
264 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_request()
265 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_request()
270 ret = pxa_mmc_stop_clock(mmc); in pxa_mmc_request()
276 writel(data->blocks, &regs->nob); in pxa_mmc_request()
277 writel(data->blocksize, &regs->blklen); in pxa_mmc_request()
279 writel(0xffff, &regs->rdto); in pxa_mmc_request()
281 if (data->flags & MMC_DATA_WRITE) in pxa_mmc_request()
286 if (mmc->bus_width == 4) in pxa_mmc_request()
290 ret = pxa_mmc_start_cmd(mmc, cmd, cmdat); in pxa_mmc_request()
295 ret = pxa_mmc_wait(mmc, MMC_STAT_END_CMD_RES); in pxa_mmc_request()
300 ret = pxa_mmc_cmd_done(mmc, cmd); in pxa_mmc_request()
306 if (data->flags & MMC_DATA_WRITE) in pxa_mmc_request()
307 pxa_mmc_do_write_xfer(mmc, data); in pxa_mmc_request()
309 pxa_mmc_do_read_xfer(mmc, data); in pxa_mmc_request()
315 static int pxa_mmc_set_ios(struct mmc *mmc) in pxa_mmc_set_ios() argument
317 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_set_ios()
318 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_set_ios()
322 if (!mmc->clock) { in pxa_mmc_set_ios()
323 pxa_mmc_stop_clock(mmc); in pxa_mmc_set_ios()
328 if (mmc->clock == 26000000) { in pxa_mmc_set_ios()
329 writel(0x7, &regs->clkrt); in pxa_mmc_set_ios()
335 tmp = mmc->cfg->f_max / mmc->clock; in pxa_mmc_set_ios()
343 writel(pxa_mmc_clock, &regs->clkrt); in pxa_mmc_set_ios()
348 static int pxa_mmc_init(struct mmc *mmc) in pxa_mmc_init() argument
350 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_init()
351 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_init()
354 pxa_mmc_stop_clock(mmc); in pxa_mmc_init()
357 writel(0, &regs->spi); in pxa_mmc_init()
360 writel(MMC_RES_TO_MAX_MASK, &regs->resto); in pxa_mmc_init()
364 &regs->i_mask); in pxa_mmc_init()
375 .name = "PXA MMC",
386 struct mmc *mmc; in pxa_mmc_register() local
389 int ret = -ENOMEM; in pxa_mmc_register()
399 priv->regs = (struct pxa_mmc_regs *)MMC0_BASE; in pxa_mmc_register()
402 priv->regs = (struct pxa_mmc_regs *)MMC1_BASE; in pxa_mmc_register()
405 ret = -EINVAL; in pxa_mmc_register()
406 printf("PXA MMC: Invalid MMC controller ID (card_index = %d)\n", in pxa_mmc_register()
421 mmc = mmc_create(&pxa_mmc_cfg, priv); in pxa_mmc_register()
422 if (mmc == NULL) in pxa_mmc_register()