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