]> git.sur5r.net Git - u-boot/blob - drivers/mmc/ftsdc010_mci.c
Merge git://git.denx.de/u-boot-dm
[u-boot] / drivers / mmc / ftsdc010_mci.c
1 /*
2  * Faraday MMC/SD Host Controller
3  *
4  * (C) Copyright 2010 Faraday Technology
5  * Dante Su <dantesu@faraday-tech.com>
6  *
7  * Copyright 2018 Andes Technology, Inc.
8  * Author: Rick Chen (rick@andestech.com)
9  *
10  * SPDX-License-Identifier:     GPL-2.0+
11  */
12
13 #include <common.h>
14 #include <clk.h>
15 #include <malloc.h>
16 #include <part.h>
17 #include <mmc.h>
18 #include <linux/io.h>
19 #include <linux/errno.h>
20 #include <asm/byteorder.h>
21 #include <faraday/ftsdc010.h>
22 #include "ftsdc010_mci.h"
23 #include <dm.h>
24 #include <dt-structs.h>
25 #include <errno.h>
26 #include <mapmem.h>
27 #include <pwrseq.h>
28 #include <syscon.h>
29 #include <linux/err.h>
30
31 DECLARE_GLOBAL_DATA_PTR;
32
33 #define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 4) /* 250 ms */
34 #define CFG_RST_TIMEOUT CONFIG_SYS_HZ /* 1 sec reset timeout */
35
36 #if CONFIG_IS_ENABLED(OF_PLATDATA)
37 struct ftsdc010 {
38         fdt32_t         bus_width;
39         bool            cap_mmc_highspeed;
40         bool            cap_sd_highspeed;
41         fdt32_t         clock_freq_min_max[2];
42         struct phandle_2_cell   clocks[4];
43         fdt32_t         fifo_depth;
44         fdt32_t         reg[2];
45 };
46 #endif
47
48 struct ftsdc010_plat {
49 #if CONFIG_IS_ENABLED(OF_PLATDATA)
50         struct ftsdc010 dtplat;
51 #endif
52         struct mmc_config cfg;
53         struct mmc mmc;
54 };
55
56 struct ftsdc_priv {
57         struct clk clk;
58         struct ftsdc010_chip chip;
59         int fifo_depth;
60         bool fifo_mode;
61         u32 minmax[2];
62 };
63
64 static inline int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
65 {
66         struct ftsdc010_chip *chip = mmc->priv;
67         struct ftsdc010_mmc __iomem *regs = chip->regs;
68         int ret = -ETIMEDOUT;
69         uint32_t ts, st;
70         uint32_t cmd   = FTSDC010_CMD_IDX(mmc_cmd->cmdidx);
71         uint32_t arg   = mmc_cmd->cmdarg;
72         uint32_t flags = mmc_cmd->resp_type;
73
74         cmd |= FTSDC010_CMD_CMD_EN;
75
76         if (chip->acmd) {
77                 cmd |= FTSDC010_CMD_APP_CMD;
78                 chip->acmd = 0;
79         }
80
81         if (flags & MMC_RSP_PRESENT)
82                 cmd |= FTSDC010_CMD_NEED_RSP;
83
84         if (flags & MMC_RSP_136)
85                 cmd |= FTSDC010_CMD_LONG_RSP;
86
87         writel(FTSDC010_STATUS_RSP_MASK | FTSDC010_STATUS_CMD_SEND,
88                 &regs->clr);
89         writel(arg, &regs->argu);
90         writel(cmd, &regs->cmd);
91
92         if (!(flags & (MMC_RSP_PRESENT | MMC_RSP_136))) {
93                 for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
94                         if (readl(&regs->status) & FTSDC010_STATUS_CMD_SEND) {
95                                 writel(FTSDC010_STATUS_CMD_SEND, &regs->clr);
96                                 ret = 0;
97                                 break;
98                         }
99                 }
100         } else {
101                 st = 0;
102                 for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
103                         st = readl(&regs->status);
104                         writel(st & FTSDC010_STATUS_RSP_MASK, &regs->clr);
105                         if (st & FTSDC010_STATUS_RSP_MASK)
106                                 break;
107                 }
108                 if (st & FTSDC010_STATUS_RSP_CRC_OK) {
109                         if (flags & MMC_RSP_136) {
110                                 mmc_cmd->response[0] = readl(&regs->rsp3);
111                                 mmc_cmd->response[1] = readl(&regs->rsp2);
112                                 mmc_cmd->response[2] = readl(&regs->rsp1);
113                                 mmc_cmd->response[3] = readl(&regs->rsp0);
114                         } else {
115                                 mmc_cmd->response[0] = readl(&regs->rsp0);
116                         }
117                         ret = 0;
118                 } else {
119                         debug("ftsdc010: rsp err (cmd=%d, st=0x%x)\n",
120                                 mmc_cmd->cmdidx, st);
121                 }
122         }
123
124         if (ret) {
125                 debug("ftsdc010: cmd timeout (op code=%d)\n",
126                         mmc_cmd->cmdidx);
127         } else if (mmc_cmd->cmdidx == MMC_CMD_APP_CMD) {
128                 chip->acmd = 1;
129         }
130
131         return ret;
132 }
133
134 static void ftsdc010_clkset(struct mmc *mmc, uint32_t rate)
135 {
136         struct ftsdc010_chip *chip = mmc->priv;
137         struct ftsdc010_mmc __iomem *regs = chip->regs;
138         uint32_t div;
139
140         for (div = 0; div < 0x7f; ++div) {
141                 if (rate >= chip->sclk / (2 * (div + 1)))
142                         break;
143         }
144         chip->rate = chip->sclk / (2 * (div + 1));
145
146         writel(FTSDC010_CCR_CLK_DIV(div), &regs->ccr);
147
148         if (IS_SD(mmc)) {
149                 setbits_le32(&regs->ccr, FTSDC010_CCR_CLK_SD);
150
151                 if (chip->rate > 25000000)
152                         setbits_le32(&regs->ccr, FTSDC010_CCR_CLK_HISPD);
153                 else
154                         clrbits_le32(&regs->ccr, FTSDC010_CCR_CLK_HISPD);
155         }
156 }
157
158 static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
159 {
160         int ret = -ETIMEDOUT;
161         uint32_t st, timeout = 10000000;
162         while (timeout--) {
163                 st = readl(&regs->status);
164                 if (!(st & mask))
165                         continue;
166                 writel(st & mask, &regs->clr);
167                 ret = 0;
168                 break;
169         }
170
171         if (ret){
172                 debug("ftsdc010: wait st(0x%x) timeout\n", mask);
173         }
174
175         return ret;
176 }
177
178 /*
179  * u-boot mmc api
180  */
181 static int ftsdc010_request(struct udevice *dev, struct mmc_cmd *cmd,
182         struct mmc_data *data)
183 {
184         struct mmc *mmc = mmc_get_mmc_dev(dev);
185         int ret = -EOPNOTSUPP;
186         uint32_t len = 0;
187         struct ftsdc010_chip *chip = mmc->priv;
188         struct ftsdc010_mmc __iomem *regs = chip->regs;
189
190         if (data && (data->flags & MMC_DATA_WRITE) && chip->wprot) {
191                 printf("ftsdc010: the card is write protected!\n");
192                 return ret;
193         }
194
195         if (data) {
196                 uint32_t dcr;
197
198                 len = data->blocksize * data->blocks;
199
200                 /* 1. data disable + fifo reset */
201                 dcr = 0;
202 #ifdef CONFIG_FTSDC010_SDIO
203                 dcr |= FTSDC010_DCR_FIFO_RST;
204 #endif
205                 writel(dcr, &regs->dcr);
206
207                 /* 2. clear status register */
208                 writel(FTSDC010_STATUS_DATA_MASK | FTSDC010_STATUS_FIFO_URUN
209                         | FTSDC010_STATUS_FIFO_ORUN, &regs->clr);
210
211                 /* 3. data timeout (1 sec) */
212                 writel(chip->rate, &regs->dtr);
213
214                 /* 4. data length (bytes) */
215                 writel(len, &regs->dlr);
216
217                 /* 5. data enable */
218                 dcr = (ffs(data->blocksize) - 1) | FTSDC010_DCR_DATA_EN;
219                 if (data->flags & MMC_DATA_WRITE)
220                         dcr |= FTSDC010_DCR_DATA_WRITE;
221                 writel(dcr, &regs->dcr);
222         }
223
224         ret = ftsdc010_send_cmd(mmc, cmd);
225         if (ret) {
226                 printf("ftsdc010: CMD%d failed\n", cmd->cmdidx);
227                 return ret;
228         }
229
230         if (!data)
231                 return ret;
232
233         if (data->flags & MMC_DATA_WRITE) {
234                 const uint8_t *buf = (const uint8_t *)data->src;
235
236                 while (len > 0) {
237                         int wlen;
238
239                         /* wait for tx ready */
240                         ret = ftsdc010_wait(regs, FTSDC010_STATUS_FIFO_URUN);
241                         if (ret)
242                                 break;
243
244                         /* write bytes to ftsdc010 */
245                         for (wlen = 0; wlen < len && wlen < chip->fifo; ) {
246                                 writel(*(uint32_t *)buf, &regs->dwr);
247                                 buf  += 4;
248                                 wlen += 4;
249                         }
250
251                         len -= wlen;
252                 }
253
254         } else {
255                 uint8_t *buf = (uint8_t *)data->dest;
256
257                 while (len > 0) {
258                         int rlen;
259
260                         /* wait for rx ready */
261                         ret = ftsdc010_wait(regs, FTSDC010_STATUS_FIFO_ORUN);
262                         if (ret)
263                                 break;
264
265                         /* fetch bytes from ftsdc010 */
266                         for (rlen = 0; rlen < len && rlen < chip->fifo; ) {
267                                 *(uint32_t *)buf = readl(&regs->dwr);
268                                 buf  += 4;
269                                 rlen += 4;
270                         }
271
272                         len -= rlen;
273                 }
274
275         }
276
277         if (!ret) {
278                 ret = ftsdc010_wait(regs,
279                         FTSDC010_STATUS_DATA_END | FTSDC010_STATUS_DATA_CRC_OK);
280         }
281
282         return ret;
283 }
284
285 static int ftsdc010_set_ios(struct udevice *dev)
286 {
287         struct mmc *mmc = mmc_get_mmc_dev(dev);
288         struct ftsdc010_chip *chip = mmc->priv;
289         struct ftsdc010_mmc __iomem *regs = chip->regs;
290
291         ftsdc010_clkset(mmc, mmc->clock);
292
293         clrbits_le32(&regs->bwr, FTSDC010_BWR_MODE_MASK);
294         switch (mmc->bus_width) {
295         case 4:
296                 setbits_le32(&regs->bwr, FTSDC010_BWR_MODE_4BIT);
297                 break;
298         case 8:
299                 setbits_le32(&regs->bwr, FTSDC010_BWR_MODE_8BIT);
300                 break;
301         default:
302                 setbits_le32(&regs->bwr, FTSDC010_BWR_MODE_1BIT);
303                 break;
304         }
305
306         return 0;
307 }
308
309 static int ftsdc010_get_cd(struct udevice *dev)
310 {
311         struct mmc *mmc = mmc_get_mmc_dev(dev);
312         struct ftsdc010_chip *chip = mmc->priv;
313         struct ftsdc010_mmc __iomem *regs = chip->regs;
314         return !(readl(&regs->status) & FTSDC010_STATUS_CARD_DETECT);
315 }
316
317 static int ftsdc010_get_wp(struct udevice *dev)
318 {
319         struct mmc *mmc = mmc_get_mmc_dev(dev);
320         struct ftsdc010_chip *chip = mmc->priv;
321         struct ftsdc010_mmc __iomem *regs = chip->regs;
322         if (readl(&regs->status) & FTSDC010_STATUS_WRITE_PROT) {
323                 printf("ftsdc010: write protected\n");
324                 chip->wprot = 1;
325         }
326
327         return 0;
328 }
329
330 static int ftsdc010_init(struct mmc *mmc)
331 {
332         struct ftsdc010_chip *chip = mmc->priv;
333         struct ftsdc010_mmc __iomem *regs = chip->regs;
334         uint32_t ts;
335
336         chip->fifo = (readl(&regs->feature) & 0xff) << 2;
337
338         /* 1. chip reset */
339         writel(FTSDC010_CMD_SDC_RST, &regs->cmd);
340         for (ts = get_timer(0); get_timer(ts) < CFG_RST_TIMEOUT; ) {
341                 if (readl(&regs->cmd) & FTSDC010_CMD_SDC_RST)
342                         continue;
343                 break;
344         }
345         if (readl(&regs->cmd) & FTSDC010_CMD_SDC_RST) {
346                 printf("ftsdc010: reset failed\n");
347                 return -EOPNOTSUPP;
348         }
349
350         /* 2. enter low speed mode (400k card detection) */
351         ftsdc010_clkset(mmc, 400000);
352
353         /* 3. interrupt disabled */
354         writel(0, &regs->int_mask);
355
356         return 0;
357 }
358
359 static int ftsdc010_probe(struct udevice *dev)
360 {
361         struct mmc *mmc = mmc_get_mmc_dev(dev);
362         return ftsdc010_init(mmc);
363 }
364
365 const struct dm_mmc_ops dm_ftsdc010_mmc_ops = {
366         .send_cmd       = ftsdc010_request,
367         .set_ios        = ftsdc010_set_ios,
368         .get_cd         = ftsdc010_get_cd,
369         .get_wp         = ftsdc010_get_wp,
370 };
371
372 static void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
373                      uint caps, u32 max_clk, u32 min_clk)
374 {
375         cfg->name = name;
376         cfg->f_min = min_clk;
377         cfg->f_max = max_clk;
378         cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
379         cfg->host_caps = caps;
380         if (buswidth == 8) {
381                 cfg->host_caps |= MMC_MODE_8BIT;
382                 cfg->host_caps &= ~MMC_MODE_4BIT;
383         } else {
384                 cfg->host_caps |= MMC_MODE_4BIT;
385                 cfg->host_caps &= ~MMC_MODE_8BIT;
386         }
387         cfg->part_type = PART_TYPE_DOS;
388         cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
389 }
390
391 static int ftsdc010_mmc_ofdata_to_platdata(struct udevice *dev)
392 {
393 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
394         struct ftsdc_priv *priv = dev_get_priv(dev);
395         struct ftsdc010_chip *chip = &priv->chip;
396         chip->name = dev->name;
397         chip->ioaddr = (void *)devfdt_get_addr(dev);
398         chip->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
399                                         "bus-width", 4);
400         chip->priv = dev;
401         priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
402                                     "fifo-depth", 0);
403         priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
404                                           "fifo-mode");
405         if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
406                          "clock-freq-min-max", priv->minmax, 2)) {
407                 int val = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
408                                   "max-frequency", -EINVAL);
409                 if (val < 0)
410                         return val;
411
412                 priv->minmax[0] = 400000;  /* 400 kHz */
413                 priv->minmax[1] = val;
414         } else {
415                 debug("%s: 'clock-freq-min-max' property was deprecated.\n",
416                 __func__);
417         }
418 #endif
419         chip->sclk = priv->minmax[1];
420         chip->regs = chip->ioaddr;
421         return 0;
422 }
423
424 static int ftsdc010_mmc_probe(struct udevice *dev)
425 {
426         struct ftsdc010_plat *plat = dev_get_platdata(dev);
427         struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
428         struct ftsdc_priv *priv = dev_get_priv(dev);
429         struct ftsdc010_chip *chip = &priv->chip;
430         struct udevice *pwr_dev __maybe_unused;
431
432 #if CONFIG_IS_ENABLED(OF_PLATDATA)
433         int ret;
434         struct ftsdc010 *dtplat = &plat->dtplat;
435         chip->name = dev->name;
436         chip->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
437         chip->buswidth = dtplat->bus_width;
438         chip->priv = dev;
439         chip->dev_index = 1;
440         memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
441         ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
442         if (ret < 0)
443                 return ret;
444 #endif
445
446         if (dev_read_bool(dev, "cap-mmc-highspeed") || \
447                   dev_read_bool(dev, "cap-sd-highspeed"))
448                 chip->caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
449
450         ftsdc_setup_cfg(&plat->cfg, dev->name, chip->buswidth, chip->caps,
451                         priv->minmax[1] , priv->minmax[0]);
452         chip->mmc = &plat->mmc;
453         chip->mmc->priv = &priv->chip;
454         chip->mmc->dev = dev;
455         upriv->mmc = chip->mmc;
456         return ftsdc010_probe(dev);
457 }
458
459 int ftsdc010_mmc_bind(struct udevice *dev)
460 {
461         struct ftsdc010_plat *plat = dev_get_platdata(dev);
462
463         return mmc_bind(dev, &plat->mmc, &plat->cfg);
464 }
465
466 static const struct udevice_id ftsdc010_mmc_ids[] = {
467         { .compatible = "andestech,atsdc010" },
468         { }
469 };
470
471 U_BOOT_DRIVER(ftsdc010_mmc) = {
472         .name           = "ftsdc010_mmc",
473         .id             = UCLASS_MMC,
474         .of_match       = ftsdc010_mmc_ids,
475         .ofdata_to_platdata = ftsdc010_mmc_ofdata_to_platdata,
476         .ops            = &dm_ftsdc010_mmc_ops,
477         .bind           = ftsdc010_mmc_bind,
478         .probe          = ftsdc010_mmc_probe,
479         .priv_auto_alloc_size = sizeof(struct ftsdc_priv),
480         .platdata_auto_alloc_size = sizeof(struct ftsdc010_plat),
481 };