Lines Matching +full:mmc +full:-
4 * Loosely based on the old code and Linux's PXA MMC driver
6 * SPDX-License-Identifier: GPL-2.0+
11 #include <asm/arch/regs-mmc.h>
15 #include <mmc.h>
35 #error "This CPU isn't supported by PXA MMC!"
51 static int pxa_mmc_wait(struct mmc *mmc, uint32_t mask) in pxa_mmc_wait() argument
53 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_wait()
54 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_wait()
58 while (--timeout) { in pxa_mmc_wait()
59 if (readl(®s->stat) & mask) in pxa_mmc_wait()
65 return -ETIMEDOUT; in pxa_mmc_wait()
70 static int pxa_mmc_stop_clock(struct mmc *mmc) in pxa_mmc_stop_clock() argument
72 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_stop_clock()
73 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_stop_clock()
77 if (!(readl(®s->stat) & MMC_STAT_CLK_EN)) in pxa_mmc_stop_clock()
81 writel(MMC_STRPCL_STOP_CLK, ®s->strpcl); in pxa_mmc_stop_clock()
84 while (--timeout) { in pxa_mmc_stop_clock()
85 if (!(readl(®s->stat) & MMC_STAT_CLK_EN)) in pxa_mmc_stop_clock()
92 return -ETIMEDOUT; in pxa_mmc_stop_clock()
98 static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd, in pxa_mmc_start_cmd() argument
101 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_start_cmd()
102 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_start_cmd()
106 if (cmd->resp_type & MMC_RSP_BUSY) in pxa_mmc_start_cmd()
110 switch (cmd->resp_type) { in pxa_mmc_start_cmd()
126 writel(cmd->cmdidx, ®s->cmd); in pxa_mmc_start_cmd()
127 writel(cmd->cmdarg >> 16, ®s->argh); in pxa_mmc_start_cmd()
128 writel(cmd->cmdarg & 0xffff, ®s->argl); in pxa_mmc_start_cmd()
129 writel(cmdat, ®s->cmdat); in pxa_mmc_start_cmd()
132 writel(MMC_STRPCL_START_CLK, ®s->strpcl); in pxa_mmc_start_cmd()
134 ret = pxa_mmc_wait(mmc, MMC_STAT_CLK_EN); in pxa_mmc_start_cmd()
142 static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) in pxa_mmc_cmd_done() argument
144 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_cmd_done()
145 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_cmd_done()
151 stat = readl(®s->stat); in pxa_mmc_cmd_done()
156 * discard the upper 8 bits of the first 16-bit word. in pxa_mmc_cmd_done()
158 a = readl(®s->res) & 0xffff; in pxa_mmc_cmd_done()
160 b = readl(®s->res) & 0xffff; in pxa_mmc_cmd_done()
161 c = readl(®s->res) & 0xffff; in pxa_mmc_cmd_done()
162 cmd->response[i] = (a << 24) | (b << 8) | (c >> 8); in pxa_mmc_cmd_done()
168 return -ETIMEDOUT; in pxa_mmc_cmd_done()
170 && cmd->resp_type & MMC_RSP_CRC) { in pxa_mmc_cmd_done()
172 if (cmd->resp_type & MMC_RSP_136 in pxa_mmc_cmd_done()
173 && cmd->response[0] & (1 << 31)) in pxa_mmc_cmd_done()
177 return -EILSEQ; in pxa_mmc_cmd_done()
184 static int pxa_mmc_do_read_xfer(struct mmc *mmc, struct mmc_data *data) in pxa_mmc_do_read_xfer() argument
186 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_do_read_xfer()
187 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_do_read_xfer()
189 uint32_t *buf = (uint32_t *)data->dest; in pxa_mmc_do_read_xfer()
193 len = data->blocks * data->blocksize; in pxa_mmc_do_read_xfer()
197 if (readl(®s->i_reg) & MMC_I_REG_RXFIFO_RD_REQ) { in pxa_mmc_do_read_xfer()
199 len -= size; in pxa_mmc_do_read_xfer()
203 while (size--) in pxa_mmc_do_read_xfer()
204 *buf++ = readl(®s->rxfifo); in pxa_mmc_do_read_xfer()
208 if (readl(®s->stat) & MMC_STAT_ERRORS) in pxa_mmc_do_read_xfer()
209 return -EIO; in pxa_mmc_do_read_xfer()
212 /* Wait for the transmission-done interrupt */ in pxa_mmc_do_read_xfer()
213 ret = pxa_mmc_wait(mmc, MMC_STAT_DATA_TRAN_DONE); in pxa_mmc_do_read_xfer()
220 static int pxa_mmc_do_write_xfer(struct mmc *mmc, struct mmc_data *data) in pxa_mmc_do_write_xfer() argument
222 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_do_write_xfer()
223 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_do_write_xfer()
225 uint32_t *buf = (uint32_t *)data->src; in pxa_mmc_do_write_xfer()
229 len = data->blocks * data->blocksize; in pxa_mmc_do_write_xfer()
233 if (readl(®s->i_reg) & MMC_I_REG_TXFIFO_WR_REQ) { in pxa_mmc_do_write_xfer()
235 len -= size; in pxa_mmc_do_write_xfer()
238 while (size--) in pxa_mmc_do_write_xfer()
239 writel(*buf++, ®s->txfifo); in pxa_mmc_do_write_xfer()
242 writel(MMC_PRTBUF_BUF_PART_FULL, ®s->prtbuf); in pxa_mmc_do_write_xfer()
245 if (readl(®s->stat) & MMC_STAT_ERRORS) in pxa_mmc_do_write_xfer()
246 return -EIO; in pxa_mmc_do_write_xfer()
249 /* Wait for the transmission-done interrupt */ in pxa_mmc_do_write_xfer()
250 ret = pxa_mmc_wait(mmc, MMC_STAT_DATA_TRAN_DONE); in pxa_mmc_do_write_xfer()
255 ret = pxa_mmc_wait(mmc, MMC_STAT_PRG_DONE); in pxa_mmc_do_write_xfer()
262 static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, in pxa_mmc_request() argument
265 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_request()
266 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_request()
271 ret = pxa_mmc_stop_clock(mmc); in pxa_mmc_request()
277 writel(data->blocks, ®s->nob); in pxa_mmc_request()
278 writel(data->blocksize, ®s->blklen); in pxa_mmc_request()
280 writel(0xffff, ®s->rdto); in pxa_mmc_request()
282 if (data->flags & MMC_DATA_WRITE) in pxa_mmc_request()
287 if (mmc->bus_width == 4) in pxa_mmc_request()
291 ret = pxa_mmc_start_cmd(mmc, cmd, cmdat); in pxa_mmc_request()
296 ret = pxa_mmc_wait(mmc, MMC_STAT_END_CMD_RES); in pxa_mmc_request()
301 ret = pxa_mmc_cmd_done(mmc, cmd); in pxa_mmc_request()
307 if (data->flags & MMC_DATA_WRITE) in pxa_mmc_request()
308 pxa_mmc_do_write_xfer(mmc, data); in pxa_mmc_request()
310 pxa_mmc_do_read_xfer(mmc, data); in pxa_mmc_request()
316 static int pxa_mmc_set_ios(struct mmc *mmc) in pxa_mmc_set_ios() argument
318 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_set_ios()
319 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_set_ios()
323 if (!mmc->clock) { in pxa_mmc_set_ios()
324 pxa_mmc_stop_clock(mmc); in pxa_mmc_set_ios()
329 if (mmc->clock == 26000000) { in pxa_mmc_set_ios()
330 writel(0x7, ®s->clkrt); in pxa_mmc_set_ios()
336 tmp = mmc->cfg->f_max / mmc->clock; in pxa_mmc_set_ios()
344 writel(pxa_mmc_clock, ®s->clkrt); in pxa_mmc_set_ios()
349 static int pxa_mmc_init(struct mmc *mmc) in pxa_mmc_init() argument
351 struct pxa_mmc_priv *priv = mmc->priv; in pxa_mmc_init()
352 struct pxa_mmc_regs *regs = priv->regs; in pxa_mmc_init()
355 pxa_mmc_stop_clock(mmc); in pxa_mmc_init()
358 writel(0, ®s->spi); in pxa_mmc_init()
361 writel(MMC_RES_TO_MAX_MASK, ®s->resto); in pxa_mmc_init()
365 ®s->i_mask); in pxa_mmc_init()
376 .name = "PXA MMC",
387 struct mmc *mmc; in pxa_mmc_register() local
390 int ret = -ENOMEM; in pxa_mmc_register()
400 priv->regs = (struct pxa_mmc_regs *)MMC0_BASE; in pxa_mmc_register()
403 priv->regs = (struct pxa_mmc_regs *)MMC1_BASE; in pxa_mmc_register()
406 ret = -EINVAL; in pxa_mmc_register()
407 printf("PXA MMC: Invalid MMC controller ID (card_index = %d)\n", in pxa_mmc_register()
422 mmc = mmc_create(&pxa_mmc_cfg, priv); in pxa_mmc_register()
423 if (mmc == NULL) in pxa_mmc_register()