xref: /openbmc/u-boot/drivers/mmc/ftsdc010_mci.c (revision 3eceff64)
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 
ftsdc010_send_cmd(struct mmc * mmc,struct mmc_cmd * mmc_cmd)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 
ftsdc010_clkset(struct mmc * mmc,uint32_t rate)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 
ftsdc010_wait(struct ftsdc010_mmc __iomem * regs,uint32_t mask)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  */
ftsdc010_request(struct udevice * dev,struct mmc_cmd * cmd,struct mmc_data * data)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 
ftsdc010_set_ios(struct udevice * dev)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 
ftsdc010_get_cd(struct udevice * dev)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 
ftsdc010_get_wp(struct udevice * dev)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 
ftsdc010_init(struct mmc * mmc)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 
ftsdc010_probe(struct udevice * dev)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 
ftsdc_setup_cfg(struct mmc_config * cfg,const char * name,int buswidth,uint caps,u32 max_clk,u32 min_clk)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 
ftsdc010_mmc_ofdata_to_platdata(struct udevice * dev)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 
ftsdc010_mmc_probe(struct udevice * dev)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 
ftsdc010_mmc_bind(struct udevice * dev)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,atfsdc010" },
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 };
481