xref: /openbmc/u-boot/drivers/mmc/ftsdc010_mci.c (revision 3102274d)
1 /*
2  * Faraday MMC/SD Host Controller
3  *
4  * (C) Copyright 2010 Faraday Technology
5  * Dante Su <dantesu@faraday-tech.com>
6  *
7  * SPDX-License-Identifier:	GPL-2.0+
8  */
9 
10 #include <common.h>
11 #include <malloc.h>
12 #include <part.h>
13 #include <mmc.h>
14 
15 #include <asm/io.h>
16 #include <asm/errno.h>
17 #include <asm/byteorder.h>
18 #include <faraday/ftsdc010.h>
19 
20 #define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 4) /* 250 ms */
21 #define CFG_RST_TIMEOUT CONFIG_SYS_HZ /* 1 sec reset timeout */
22 
23 struct ftsdc010_chip {
24 	void __iomem *regs;
25 	uint32_t wprot;   /* write protected (locked) */
26 	uint32_t rate;    /* actual SD clock in Hz */
27 	uint32_t sclk;    /* FTSDC010 source clock in Hz */
28 	uint32_t fifo;    /* fifo depth in bytes */
29 	uint32_t acmd;
30 };
31 
32 static inline int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
33 {
34 	struct ftsdc010_chip *chip = mmc->priv;
35 	struct ftsdc010_mmc __iomem *regs = chip->regs;
36 	int ret = TIMEOUT;
37 	uint32_t ts, st;
38 	uint32_t cmd   = FTSDC010_CMD_IDX(mmc_cmd->cmdidx);
39 	uint32_t arg   = mmc_cmd->cmdarg;
40 	uint32_t flags = mmc_cmd->resp_type;
41 
42 	cmd |= FTSDC010_CMD_CMD_EN;
43 
44 	if (chip->acmd) {
45 		cmd |= FTSDC010_CMD_APP_CMD;
46 		chip->acmd = 0;
47 	}
48 
49 	if (flags & MMC_RSP_PRESENT)
50 		cmd |= FTSDC010_CMD_NEED_RSP;
51 
52 	if (flags & MMC_RSP_136)
53 		cmd |= FTSDC010_CMD_LONG_RSP;
54 
55 	writel(FTSDC010_STATUS_RSP_MASK | FTSDC010_STATUS_CMD_SEND,
56 		&regs->clr);
57 	writel(arg, &regs->argu);
58 	writel(cmd, &regs->cmd);
59 
60 	if (!(flags & (MMC_RSP_PRESENT | MMC_RSP_136))) {
61 		for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
62 			if (readl(&regs->status) & FTSDC010_STATUS_CMD_SEND) {
63 				writel(FTSDC010_STATUS_CMD_SEND, &regs->clr);
64 				ret = 0;
65 				break;
66 			}
67 		}
68 	} else {
69 		st = 0;
70 		for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
71 			st = readl(&regs->status);
72 			writel(st & FTSDC010_STATUS_RSP_MASK, &regs->clr);
73 			if (st & FTSDC010_STATUS_RSP_MASK)
74 				break;
75 		}
76 		if (st & FTSDC010_STATUS_RSP_CRC_OK) {
77 			if (flags & MMC_RSP_136) {
78 				mmc_cmd->response[0] = readl(&regs->rsp3);
79 				mmc_cmd->response[1] = readl(&regs->rsp2);
80 				mmc_cmd->response[2] = readl(&regs->rsp1);
81 				mmc_cmd->response[3] = readl(&regs->rsp0);
82 			} else {
83 				mmc_cmd->response[0] = readl(&regs->rsp0);
84 			}
85 			ret = 0;
86 		} else {
87 			debug("ftsdc010: rsp err (cmd=%d, st=0x%x)\n",
88 				mmc_cmd->cmdidx, st);
89 		}
90 	}
91 
92 	if (ret) {
93 		debug("ftsdc010: cmd timeout (op code=%d)\n",
94 			mmc_cmd->cmdidx);
95 	} else if (mmc_cmd->cmdidx == MMC_CMD_APP_CMD) {
96 		chip->acmd = 1;
97 	}
98 
99 	return ret;
100 }
101 
102 static void ftsdc010_clkset(struct mmc *mmc, uint32_t rate)
103 {
104 	struct ftsdc010_chip *chip = mmc->priv;
105 	struct ftsdc010_mmc __iomem *regs = chip->regs;
106 	uint32_t div;
107 
108 	for (div = 0; div < 0x7f; ++div) {
109 		if (rate >= chip->sclk / (2 * (div + 1)))
110 			break;
111 	}
112 	chip->rate = chip->sclk / (2 * (div + 1));
113 
114 	writel(FTSDC010_CCR_CLK_DIV(div), &regs->ccr);
115 
116 	if (IS_SD(mmc)) {
117 		setbits_le32(&regs->ccr, FTSDC010_CCR_CLK_SD);
118 
119 		if (chip->rate > 25000000)
120 			setbits_le32(&regs->ccr, FTSDC010_CCR_CLK_HISPD);
121 		else
122 			clrbits_le32(&regs->ccr, FTSDC010_CCR_CLK_HISPD);
123 	}
124 }
125 
126 static inline int ftsdc010_is_ro(struct mmc *mmc)
127 {
128 	struct ftsdc010_chip *chip = mmc->priv;
129 	const uint8_t *csd = (const uint8_t *)mmc->csd;
130 
131 	return chip->wprot || (csd[1] & 0x30);
132 }
133 
134 static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
135 {
136 	int ret = TIMEOUT;
137 	uint32_t st, ts;
138 
139 	for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
140 		st = readl(&regs->status);
141 		if (!(st & mask))
142 			continue;
143 		writel(st & mask, &regs->clr);
144 		ret = 0;
145 		break;
146 	}
147 
148 	if (ret)
149 		debug("ftsdc010: wait st(0x%x) timeout\n", mask);
150 
151 	return ret;
152 }
153 
154 /*
155  * u-boot mmc api
156  */
157 
158 static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
159 	struct mmc_data *data)
160 {
161 	int ret = UNUSABLE_ERR;
162 	uint32_t len = 0;
163 	struct ftsdc010_chip *chip = mmc->priv;
164 	struct ftsdc010_mmc __iomem *regs = chip->regs;
165 
166 	if (data && (data->flags & MMC_DATA_WRITE) && chip->wprot) {
167 		printf("ftsdc010: the card is write protected!\n");
168 		return ret;
169 	}
170 
171 	if (data) {
172 		uint32_t dcr;
173 
174 		len = data->blocksize * data->blocks;
175 
176 		/* 1. data disable + fifo reset */
177 		dcr = 0;
178 #ifdef CONFIG_FTSDC010_SDIO
179 		dcr |= FTSDC010_DCR_FIFO_RST;
180 #endif
181 		writel(dcr, &regs->dcr);
182 
183 		/* 2. clear status register */
184 		writel(FTSDC010_STATUS_DATA_MASK | FTSDC010_STATUS_FIFO_URUN
185 			| FTSDC010_STATUS_FIFO_ORUN, &regs->clr);
186 
187 		/* 3. data timeout (1 sec) */
188 		writel(chip->rate, &regs->dtr);
189 
190 		/* 4. data length (bytes) */
191 		writel(len, &regs->dlr);
192 
193 		/* 5. data enable */
194 		dcr = (ffs(data->blocksize) - 1) | FTSDC010_DCR_DATA_EN;
195 		if (data->flags & MMC_DATA_WRITE)
196 			dcr |= FTSDC010_DCR_DATA_WRITE;
197 		writel(dcr, &regs->dcr);
198 	}
199 
200 	ret = ftsdc010_send_cmd(mmc, cmd);
201 	if (ret) {
202 		printf("ftsdc010: CMD%d failed\n", cmd->cmdidx);
203 		return ret;
204 	}
205 
206 	if (!data)
207 		return ret;
208 
209 	if (data->flags & MMC_DATA_WRITE) {
210 		const uint8_t *buf = (const uint8_t *)data->src;
211 
212 		while (len > 0) {
213 			int wlen;
214 
215 			/* wait for tx ready */
216 			ret = ftsdc010_wait(regs, FTSDC010_STATUS_FIFO_URUN);
217 			if (ret)
218 				break;
219 
220 			/* write bytes to ftsdc010 */
221 			for (wlen = 0; wlen < len && wlen < chip->fifo; ) {
222 				writel(*(uint32_t *)buf, &regs->dwr);
223 				buf  += 4;
224 				wlen += 4;
225 			}
226 
227 			len -= wlen;
228 		}
229 
230 	} else {
231 		uint8_t *buf = (uint8_t *)data->dest;
232 
233 		while (len > 0) {
234 			int rlen;
235 
236 			/* wait for rx ready */
237 			ret = ftsdc010_wait(regs, FTSDC010_STATUS_FIFO_ORUN);
238 			if (ret)
239 				break;
240 
241 			/* fetch bytes from ftsdc010 */
242 			for (rlen = 0; rlen < len && rlen < chip->fifo; ) {
243 				*(uint32_t *)buf = readl(&regs->dwr);
244 				buf  += 4;
245 				rlen += 4;
246 			}
247 
248 			len -= rlen;
249 		}
250 
251 	}
252 
253 	if (!ret) {
254 		ret = ftsdc010_wait(regs,
255 			FTSDC010_STATUS_DATA_END | FTSDC010_STATUS_DATA_ERROR);
256 	}
257 
258 	return ret;
259 }
260 
261 static void ftsdc010_set_ios(struct mmc *mmc)
262 {
263 	struct ftsdc010_chip *chip = mmc->priv;
264 	struct ftsdc010_mmc __iomem *regs = chip->regs;
265 
266 	ftsdc010_clkset(mmc, mmc->clock);
267 
268 	clrbits_le32(&regs->bwr, FTSDC010_BWR_MODE_MASK);
269 	switch (mmc->bus_width) {
270 	case 4:
271 		setbits_le32(&regs->bwr, FTSDC010_BWR_MODE_4BIT);
272 		break;
273 	case 8:
274 		setbits_le32(&regs->bwr, FTSDC010_BWR_MODE_8BIT);
275 		break;
276 	default:
277 		setbits_le32(&regs->bwr, FTSDC010_BWR_MODE_1BIT);
278 		break;
279 	}
280 }
281 
282 static int ftsdc010_init(struct mmc *mmc)
283 {
284 	struct ftsdc010_chip *chip = mmc->priv;
285 	struct ftsdc010_mmc __iomem *regs = chip->regs;
286 	uint32_t ts;
287 
288 	if (readl(&regs->status) & FTSDC010_STATUS_CARD_DETECT)
289 		return NO_CARD_ERR;
290 
291 	if (readl(&regs->status) & FTSDC010_STATUS_WRITE_PROT) {
292 		printf("ftsdc010: write protected\n");
293 		chip->wprot = 1;
294 	}
295 
296 	chip->fifo = (readl(&regs->feature) & 0xff) << 2;
297 
298 	/* 1. chip reset */
299 	writel(FTSDC010_CMD_SDC_RST, &regs->cmd);
300 	for (ts = get_timer(0); get_timer(ts) < CFG_RST_TIMEOUT; ) {
301 		if (readl(&regs->cmd) & FTSDC010_CMD_SDC_RST)
302 			continue;
303 		break;
304 	}
305 	if (readl(&regs->cmd) & FTSDC010_CMD_SDC_RST) {
306 		printf("ftsdc010: reset failed\n");
307 		return UNUSABLE_ERR;
308 	}
309 
310 	/* 2. enter low speed mode (400k card detection) */
311 	ftsdc010_clkset(mmc, 400000);
312 
313 	/* 3. interrupt disabled */
314 	writel(0, &regs->int_mask);
315 
316 	return 0;
317 }
318 
319 int ftsdc010_mmc_init(int devid)
320 {
321 	struct mmc *mmc;
322 	struct ftsdc010_chip *chip;
323 	struct ftsdc010_mmc __iomem *regs;
324 #ifdef CONFIG_FTSDC010_BASE_LIST
325 	uint32_t base_list[] = CONFIG_FTSDC010_BASE_LIST;
326 
327 	if (devid < 0 || devid >= ARRAY_SIZE(base_list))
328 		return -1;
329 	regs = (void __iomem *)base_list[devid];
330 #else
331 	regs = (void __iomem *)(CONFIG_FTSDC010_BASE + (devid << 20));
332 #endif
333 
334 	mmc = malloc(sizeof(struct mmc));
335 	if (!mmc)
336 		return -ENOMEM;
337 	memset(mmc, 0, sizeof(struct mmc));
338 
339 	chip = malloc(sizeof(struct ftsdc010_chip));
340 	if (!chip) {
341 		free(mmc);
342 		return -ENOMEM;
343 	}
344 	memset(chip, 0, sizeof(struct ftsdc010_chip));
345 
346 	chip->regs = regs;
347 	mmc->priv  = chip;
348 
349 	sprintf(mmc->name, "ftsdc010");
350 	mmc->send_cmd  = ftsdc010_request;
351 	mmc->set_ios   = ftsdc010_set_ios;
352 	mmc->init      = ftsdc010_init;
353 
354 	mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz;
355 	switch (readl(&regs->bwr) & FTSDC010_BWR_CAPS_MASK) {
356 	case FTSDC010_BWR_CAPS_4BIT:
357 		mmc->host_caps |= MMC_MODE_4BIT;
358 		break;
359 	case FTSDC010_BWR_CAPS_8BIT:
360 		mmc->host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
361 		break;
362 	default:
363 		break;
364 	}
365 
366 #ifdef CONFIG_SYS_CLK_FREQ
367 	chip->sclk = CONFIG_SYS_CLK_FREQ;
368 #else
369 	chip->sclk = clk_get_rate("SDC");
370 #endif
371 
372 	mmc->voltages  = MMC_VDD_32_33 | MMC_VDD_33_34;
373 	mmc->f_max     = chip->sclk / 2;
374 	mmc->f_min     = chip->sclk / 0x100;
375 	mmc->block_dev.part_type = PART_TYPE_DOS;
376 
377 	mmc_register(mmc);
378 
379 	return 0;
380 }
381