]> git.sur5r.net Git - u-boot/blob - drivers/mmc/sunxi_mmc.c
dm: mmc: sunxi: Drop mmc_clk_io_on()
[u-boot] / drivers / mmc / sunxi_mmc.c
1 /*
2  * (C) Copyright 2007-2011
3  * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
4  * Aaron <leafy.myeh@allwinnertech.com>
5  *
6  * MMC driver for allwinner sunxi platform.
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <common.h>
12 #include <errno.h>
13 #include <malloc.h>
14 #include <mmc.h>
15 #include <asm/io.h>
16 #include <asm/arch/clock.h>
17 #include <asm/arch/cpu.h>
18 #include <asm/arch/gpio.h>
19 #include <asm/arch/mmc.h>
20 #include <asm-generic/gpio.h>
21
22 struct sunxi_mmc_priv {
23         unsigned mmc_no;
24         uint32_t *mclkreg;
25         unsigned fatal_err;
26         struct sunxi_mmc *reg;
27         struct mmc_config cfg;
28 };
29
30 /* support 4 mmc hosts */
31 struct sunxi_mmc_priv mmc_host[4];
32
33 static int sunxi_mmc_getcd_gpio(int sdc_no)
34 {
35         switch (sdc_no) {
36         case 0: return sunxi_name_to_gpio(CONFIG_MMC0_CD_PIN);
37         case 1: return sunxi_name_to_gpio(CONFIG_MMC1_CD_PIN);
38         case 2: return sunxi_name_to_gpio(CONFIG_MMC2_CD_PIN);
39         case 3: return sunxi_name_to_gpio(CONFIG_MMC3_CD_PIN);
40         }
41         return -EINVAL;
42 }
43
44 static int mmc_resource_init(int sdc_no)
45 {
46         struct sunxi_mmc_priv *priv = &mmc_host[sdc_no];
47         struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
48         int cd_pin, ret = 0;
49
50         debug("init mmc %d resource\n", sdc_no);
51
52         switch (sdc_no) {
53         case 0:
54                 priv->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE;
55                 priv->mclkreg = &ccm->sd0_clk_cfg;
56                 break;
57         case 1:
58                 priv->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE;
59                 priv->mclkreg = &ccm->sd1_clk_cfg;
60                 break;
61         case 2:
62                 priv->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE;
63                 priv->mclkreg = &ccm->sd2_clk_cfg;
64                 break;
65         case 3:
66                 priv->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE;
67                 priv->mclkreg = &ccm->sd3_clk_cfg;
68                 break;
69         default:
70                 printf("Wrong mmc number %d\n", sdc_no);
71                 return -1;
72         }
73         priv->mmc_no = sdc_no;
74
75         cd_pin = sunxi_mmc_getcd_gpio(sdc_no);
76         if (cd_pin >= 0) {
77                 ret = gpio_request(cd_pin, "mmc_cd");
78                 if (!ret) {
79                         sunxi_gpio_set_pull(cd_pin, SUNXI_GPIO_PULL_UP);
80                         ret = gpio_direction_input(cd_pin);
81                 }
82         }
83
84         return ret;
85 }
86
87 static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
88 {
89         unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly;
90
91         if (hz <= 24000000) {
92                 pll = CCM_MMC_CTRL_OSCM24;
93                 pll_hz = 24000000;
94         } else {
95 #ifdef CONFIG_MACH_SUN9I
96                 pll = CCM_MMC_CTRL_PLL_PERIPH0;
97                 pll_hz = clock_get_pll4_periph0();
98 #else
99                 pll = CCM_MMC_CTRL_PLL6;
100                 pll_hz = clock_get_pll6();
101 #endif
102         }
103
104         div = pll_hz / hz;
105         if (pll_hz % hz)
106                 div++;
107
108         n = 0;
109         while (div > 16) {
110                 n++;
111                 div = (div + 1) / 2;
112         }
113
114         if (n > 3) {
115                 printf("mmc %u error cannot set clock to %u\n", priv->mmc_no,
116                        hz);
117                 return -1;
118         }
119
120         /* determine delays */
121         if (hz <= 400000) {
122                 oclk_dly = 0;
123                 sclk_dly = 0;
124         } else if (hz <= 25000000) {
125                 oclk_dly = 0;
126                 sclk_dly = 5;
127 #ifdef CONFIG_MACH_SUN9I
128         } else if (hz <= 50000000) {
129                 oclk_dly = 5;
130                 sclk_dly = 4;
131         } else {
132                 /* hz > 50000000 */
133                 oclk_dly = 2;
134                 sclk_dly = 4;
135 #else
136         } else if (hz <= 50000000) {
137                 oclk_dly = 3;
138                 sclk_dly = 4;
139         } else {
140                 /* hz > 50000000 */
141                 oclk_dly = 1;
142                 sclk_dly = 4;
143 #endif
144         }
145
146         writel(CCM_MMC_CTRL_ENABLE | pll | CCM_MMC_CTRL_SCLK_DLY(sclk_dly) |
147                CCM_MMC_CTRL_N(n) | CCM_MMC_CTRL_OCLK_DLY(oclk_dly) |
148                CCM_MMC_CTRL_M(div), priv->mclkreg);
149
150         debug("mmc %u set mod-clk req %u parent %u n %u m %u rate %u\n",
151               priv->mmc_no, hz, pll_hz, 1u << n, div, pll_hz / (1u << n) / div);
152
153         return 0;
154 }
155
156 static int mmc_update_clk(struct sunxi_mmc_priv *priv)
157 {
158         unsigned int cmd;
159         unsigned timeout_msecs = 2000;
160
161         cmd = SUNXI_MMC_CMD_START |
162               SUNXI_MMC_CMD_UPCLK_ONLY |
163               SUNXI_MMC_CMD_WAIT_PRE_OVER;
164         writel(cmd, &priv->reg->cmd);
165         while (readl(&priv->reg->cmd) & SUNXI_MMC_CMD_START) {
166                 if (!timeout_msecs--)
167                         return -1;
168                 udelay(1000);
169         }
170
171         /* clock update sets various irq status bits, clear these */
172         writel(readl(&priv->reg->rint), &priv->reg->rint);
173
174         return 0;
175 }
176
177 static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc)
178 {
179         unsigned rval = readl(&priv->reg->clkcr);
180
181         /* Disable Clock */
182         rval &= ~SUNXI_MMC_CLK_ENABLE;
183         writel(rval, &priv->reg->clkcr);
184         if (mmc_update_clk(priv))
185                 return -1;
186
187         /* Set mod_clk to new rate */
188         if (mmc_set_mod_clk(priv, mmc->clock))
189                 return -1;
190
191         /* Clear internal divider */
192         rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK;
193         writel(rval, &priv->reg->clkcr);
194
195         /* Re-enable Clock */
196         rval |= SUNXI_MMC_CLK_ENABLE;
197         writel(rval, &priv->reg->clkcr);
198         if (mmc_update_clk(priv))
199                 return -1;
200
201         return 0;
202 }
203
204 static int sunxi_mmc_set_ios_common(struct sunxi_mmc_priv *priv,
205                                     struct mmc *mmc)
206 {
207         debug("set ios: bus_width: %x, clock: %d\n",
208               mmc->bus_width, mmc->clock);
209
210         /* Change clock first */
211         if (mmc->clock && mmc_config_clock(priv, mmc) != 0) {
212                 priv->fatal_err = 1;
213                 return -EINVAL;
214         }
215
216         /* Change bus width */
217         if (mmc->bus_width == 8)
218                 writel(0x2, &priv->reg->width);
219         else if (mmc->bus_width == 4)
220                 writel(0x1, &priv->reg->width);
221         else
222                 writel(0x0, &priv->reg->width);
223
224         return 0;
225 }
226
227 static int sunxi_mmc_core_init(struct mmc *mmc)
228 {
229         struct sunxi_mmc_priv *priv = mmc->priv;
230
231         /* Reset controller */
232         writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
233         udelay(1000);
234
235         return 0;
236 }
237
238 static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc,
239                                  struct mmc_data *data)
240 {
241         const int reading = !!(data->flags & MMC_DATA_READ);
242         const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY :
243                                               SUNXI_MMC_STATUS_FIFO_FULL;
244         unsigned i;
245         unsigned *buff = (unsigned int *)(reading ? data->dest : data->src);
246         unsigned byte_cnt = data->blocksize * data->blocks;
247         unsigned timeout_usecs = (byte_cnt >> 8) * 1000;
248         if (timeout_usecs < 2000000)
249                 timeout_usecs = 2000000;
250
251         /* Always read / write data through the CPU */
252         setbits_le32(&priv->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB);
253
254         for (i = 0; i < (byte_cnt >> 2); i++) {
255                 while (readl(&priv->reg->status) & status_bit) {
256                         if (!timeout_usecs--)
257                                 return -1;
258                         udelay(1);
259                 }
260
261                 if (reading)
262                         buff[i] = readl(&priv->reg->fifo);
263                 else
264                         writel(buff[i], &priv->reg->fifo);
265         }
266
267         return 0;
268 }
269
270 static int mmc_rint_wait(struct sunxi_mmc_priv *priv, struct mmc *mmc,
271                          uint timeout_msecs, uint done_bit, const char *what)
272 {
273         unsigned int status;
274
275         do {
276                 status = readl(&priv->reg->rint);
277                 if (!timeout_msecs-- ||
278                     (status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT)) {
279                         debug("%s timeout %x\n", what,
280                               status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT);
281                         return -ETIMEDOUT;
282                 }
283                 udelay(1000);
284         } while (!(status & done_bit));
285
286         return 0;
287 }
288
289 static int sunxi_mmc_send_cmd_common(struct sunxi_mmc_priv *priv,
290                                      struct mmc *mmc, struct mmc_cmd *cmd,
291                                      struct mmc_data *data)
292 {
293         unsigned int cmdval = SUNXI_MMC_CMD_START;
294         unsigned int timeout_msecs;
295         int error = 0;
296         unsigned int status = 0;
297         unsigned int bytecnt = 0;
298
299         if (priv->fatal_err)
300                 return -1;
301         if (cmd->resp_type & MMC_RSP_BUSY)
302                 debug("mmc cmd %d check rsp busy\n", cmd->cmdidx);
303         if (cmd->cmdidx == 12)
304                 return 0;
305
306         if (!cmd->cmdidx)
307                 cmdval |= SUNXI_MMC_CMD_SEND_INIT_SEQ;
308         if (cmd->resp_type & MMC_RSP_PRESENT)
309                 cmdval |= SUNXI_MMC_CMD_RESP_EXPIRE;
310         if (cmd->resp_type & MMC_RSP_136)
311                 cmdval |= SUNXI_MMC_CMD_LONG_RESPONSE;
312         if (cmd->resp_type & MMC_RSP_CRC)
313                 cmdval |= SUNXI_MMC_CMD_CHK_RESPONSE_CRC;
314
315         if (data) {
316                 if ((u32)(long)data->dest & 0x3) {
317                         error = -1;
318                         goto out;
319                 }
320
321                 cmdval |= SUNXI_MMC_CMD_DATA_EXPIRE|SUNXI_MMC_CMD_WAIT_PRE_OVER;
322                 if (data->flags & MMC_DATA_WRITE)
323                         cmdval |= SUNXI_MMC_CMD_WRITE;
324                 if (data->blocks > 1)
325                         cmdval |= SUNXI_MMC_CMD_AUTO_STOP;
326                 writel(data->blocksize, &priv->reg->blksz);
327                 writel(data->blocks * data->blocksize, &priv->reg->bytecnt);
328         }
329
330         debug("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", priv->mmc_no,
331               cmd->cmdidx, cmdval | cmd->cmdidx, cmd->cmdarg);
332         writel(cmd->cmdarg, &priv->reg->arg);
333
334         if (!data)
335                 writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
336
337         /*
338          * transfer data and check status
339          * STATREG[2] : FIFO empty
340          * STATREG[3] : FIFO full
341          */
342         if (data) {
343                 int ret = 0;
344
345                 bytecnt = data->blocksize * data->blocks;
346                 debug("trans data %d bytes\n", bytecnt);
347                 writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
348                 ret = mmc_trans_data_by_cpu(priv, mmc, data);
349                 if (ret) {
350                         error = readl(&priv->reg->rint) &
351                                 SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT;
352                         error = -ETIMEDOUT;
353                         goto out;
354                 }
355         }
356
357         error = mmc_rint_wait(priv, mmc, 1000, SUNXI_MMC_RINT_COMMAND_DONE,
358                               "cmd");
359         if (error)
360                 goto out;
361
362         if (data) {
363                 timeout_msecs = 120;
364                 debug("cacl timeout %x msec\n", timeout_msecs);
365                 error = mmc_rint_wait(priv, mmc, timeout_msecs,
366                                       data->blocks > 1 ?
367                                       SUNXI_MMC_RINT_AUTO_COMMAND_DONE :
368                                       SUNXI_MMC_RINT_DATA_OVER,
369                                       "data");
370                 if (error)
371                         goto out;
372         }
373
374         if (cmd->resp_type & MMC_RSP_BUSY) {
375                 timeout_msecs = 2000;
376                 do {
377                         status = readl(&priv->reg->status);
378                         if (!timeout_msecs--) {
379                                 debug("busy timeout\n");
380                                 error = -ETIMEDOUT;
381                                 goto out;
382                         }
383                         udelay(1000);
384                 } while (status & SUNXI_MMC_STATUS_CARD_DATA_BUSY);
385         }
386
387         if (cmd->resp_type & MMC_RSP_136) {
388                 cmd->response[0] = readl(&priv->reg->resp3);
389                 cmd->response[1] = readl(&priv->reg->resp2);
390                 cmd->response[2] = readl(&priv->reg->resp1);
391                 cmd->response[3] = readl(&priv->reg->resp0);
392                 debug("mmc resp 0x%08x 0x%08x 0x%08x 0x%08x\n",
393                       cmd->response[3], cmd->response[2],
394                       cmd->response[1], cmd->response[0]);
395         } else {
396                 cmd->response[0] = readl(&priv->reg->resp0);
397                 debug("mmc resp 0x%08x\n", cmd->response[0]);
398         }
399 out:
400         if (error < 0) {
401                 writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
402                 mmc_update_clk(priv);
403         }
404         writel(0xffffffff, &priv->reg->rint);
405         writel(readl(&priv->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET,
406                &priv->reg->gctrl);
407
408         return error;
409 }
410
411 static int sunxi_mmc_set_ios_legacy(struct mmc *mmc)
412 {
413         struct sunxi_mmc_priv *priv = mmc->priv;
414
415         return sunxi_mmc_set_ios_common(priv, mmc);
416 }
417
418 static int sunxi_mmc_send_cmd_legacy(struct mmc *mmc, struct mmc_cmd *cmd,
419                                      struct mmc_data *data)
420 {
421         struct sunxi_mmc_priv *priv = mmc->priv;
422
423         return sunxi_mmc_send_cmd_common(priv, mmc, cmd, data);
424 }
425
426 static int sunxi_mmc_getcd_legacy(struct mmc *mmc)
427 {
428         struct sunxi_mmc_priv *priv = mmc->priv;
429         int cd_pin;
430
431         cd_pin = sunxi_mmc_getcd_gpio(priv->mmc_no);
432         if (cd_pin < 0)
433                 return 1;
434
435         return !gpio_get_value(cd_pin);
436 }
437
438 static const struct mmc_ops sunxi_mmc_ops = {
439         .send_cmd       = sunxi_mmc_send_cmd_legacy,
440         .set_ios        = sunxi_mmc_set_ios_legacy,
441         .init           = sunxi_mmc_core_init,
442         .getcd          = sunxi_mmc_getcd_legacy,
443 };
444
445 struct mmc *sunxi_mmc_init(int sdc_no)
446 {
447         struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
448         struct sunxi_mmc_priv *priv = &mmc_host[sdc_no];
449         struct mmc_config *cfg = &priv->cfg;
450         int ret;
451
452         memset(priv, '\0', sizeof(struct sunxi_mmc_priv));
453
454         cfg->name = "SUNXI SD/MMC";
455         cfg->ops  = &sunxi_mmc_ops;
456
457         cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
458         cfg->host_caps = MMC_MODE_4BIT;
459 #if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN8I)
460         if (sdc_no == 2)
461                 cfg->host_caps = MMC_MODE_8BIT;
462 #endif
463         cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
464         cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
465
466         cfg->f_min = 400000;
467         cfg->f_max = 52000000;
468
469         if (mmc_resource_init(sdc_no) != 0)
470                 return NULL;
471
472         /* config ahb clock */
473         debug("init mmc %d clock and io\n", sdc_no);
474         setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
475
476 #ifdef CONFIG_SUNXI_GEN_SUN6I
477         /* unassert reset */
478         setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no));
479 #endif
480 #if defined(CONFIG_MACH_SUN9I)
481         /* sun9i has a mmc-common module, also set the gate and reset there */
482         writel(SUNXI_MMC_COMMON_CLK_GATE | SUNXI_MMC_COMMON_RESET,
483                SUNXI_MMC_COMMON_BASE + 4 * sdc_no);
484 #endif
485         ret = mmc_set_mod_clk(priv, 24000000);
486         if (ret)
487                 return NULL;
488
489         return mmc_create(cfg, mmc_host);
490 }