xref: /openbmc/u-boot/drivers/mmc/renesas-sdhi.c (revision 48f8e159)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
4  */
5 
6 #include <common.h>
7 #include <clk.h>
8 #include <fdtdec.h>
9 #include <mmc.h>
10 #include <dm.h>
11 #include <linux/compat.h>
12 #include <linux/dma-direction.h>
13 #include <linux/io.h>
14 #include <linux/sizes.h>
15 #include <power/regulator.h>
16 #include <asm/unaligned.h>
17 
18 #include "tmio-common.h"
19 
20 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
21 
22 /* SCC registers */
23 #define RENESAS_SDHI_SCC_DTCNTL			0x800
24 #define   RENESAS_SDHI_SCC_DTCNTL_TAPEN		BIT(0)
25 #define   RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT	16
26 #define   RENESAS_SDHI_SCC_DTCNTL_TAPNUM_MASK		0xff
27 #define RENESAS_SDHI_SCC_TAPSET			0x804
28 #define RENESAS_SDHI_SCC_DT2FF			0x808
29 #define RENESAS_SDHI_SCC_CKSEL			0x80c
30 #define   RENESAS_SDHI_SCC_CKSEL_DTSEL		BIT(0)
31 #define RENESAS_SDHI_SCC_RVSCNTL			0x810
32 #define   RENESAS_SDHI_SCC_RVSCNTL_RVSEN		BIT(0)
33 #define RENESAS_SDHI_SCC_RVSREQ			0x814
34 #define   RENESAS_SDHI_SCC_RVSREQ_RVSERR		BIT(2)
35 #define RENESAS_SDHI_SCC_SMPCMP			0x818
36 #define RENESAS_SDHI_SCC_TMPPORT2			0x81c
37 #define   RENESAS_SDHI_SCC_TMPPORT2_HS400EN		BIT(31)
38 #define   RENESAS_SDHI_SCC_TMPPORT2_HS400OSEL		BIT(4)
39 
40 #define RENESAS_SDHI_MAX_TAP 3
41 
42 static unsigned int renesas_sdhi_init_tuning(struct tmio_sd_priv *priv)
43 {
44 	u32 reg;
45 
46 	/* Initialize SCC */
47 	tmio_sd_writel(priv, 0, TMIO_SD_INFO1);
48 
49 	reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL);
50 	reg &= ~TMIO_SD_CLKCTL_SCLKEN;
51 	tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL);
52 
53 	/* Set sampling clock selection range */
54 	tmio_sd_writel(priv, (0x8 << RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT) |
55 			     RENESAS_SDHI_SCC_DTCNTL_TAPEN,
56 			     RENESAS_SDHI_SCC_DTCNTL);
57 
58 	reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL);
59 	reg |= RENESAS_SDHI_SCC_CKSEL_DTSEL;
60 	tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL);
61 
62 	reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL);
63 	reg &= ~RENESAS_SDHI_SCC_RVSCNTL_RVSEN;
64 	tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL);
65 
66 	tmio_sd_writel(priv, 0x300 /* scc_tappos */,
67 			   RENESAS_SDHI_SCC_DT2FF);
68 
69 	reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL);
70 	reg |= TMIO_SD_CLKCTL_SCLKEN;
71 	tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL);
72 
73 	/* Read TAPNUM */
74 	return (tmio_sd_readl(priv, RENESAS_SDHI_SCC_DTCNTL) >>
75 		RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT) &
76 		RENESAS_SDHI_SCC_DTCNTL_TAPNUM_MASK;
77 }
78 
79 static void renesas_sdhi_reset_tuning(struct tmio_sd_priv *priv)
80 {
81 	u32 reg;
82 
83 	/* Reset SCC */
84 	reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL);
85 	reg &= ~TMIO_SD_CLKCTL_SCLKEN;
86 	tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL);
87 
88 	reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL);
89 	reg &= ~RENESAS_SDHI_SCC_CKSEL_DTSEL;
90 	tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL);
91 
92 	reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_TMPPORT2);
93 	reg &= ~(RENESAS_SDHI_SCC_TMPPORT2_HS400EN |
94 		 RENESAS_SDHI_SCC_TMPPORT2_HS400OSEL);
95 	tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_TMPPORT2);
96 
97 	reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL);
98 	reg |= TMIO_SD_CLKCTL_SCLKEN;
99 	tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL);
100 
101 	reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL);
102 	reg &= ~RENESAS_SDHI_SCC_RVSCNTL_RVSEN;
103 	tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL);
104 
105 	reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL);
106 	reg &= ~RENESAS_SDHI_SCC_RVSCNTL_RVSEN;
107 	tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL);
108 }
109 
110 static void renesas_sdhi_prepare_tuning(struct tmio_sd_priv *priv,
111 				       unsigned long tap)
112 {
113 	/* Set sampling clock position */
114 	tmio_sd_writel(priv, tap, RENESAS_SDHI_SCC_TAPSET);
115 }
116 
117 static unsigned int renesas_sdhi_compare_scc_data(struct tmio_sd_priv *priv)
118 {
119 	/* Get comparison of sampling data */
120 	return tmio_sd_readl(priv, RENESAS_SDHI_SCC_SMPCMP);
121 }
122 
123 static int renesas_sdhi_select_tuning(struct tmio_sd_priv *priv,
124 				     unsigned int tap_num, unsigned int taps,
125 				     unsigned int smpcmp)
126 {
127 	unsigned long tap_cnt;  /* counter of tuning success */
128 	unsigned long tap_set;  /* tap position */
129 	unsigned long tap_start;/* start position of tuning success */
130 	unsigned long tap_end;  /* end position of tuning success */
131 	unsigned long ntap;     /* temporary counter of tuning success */
132 	unsigned long match_cnt;/* counter of matching data */
133 	unsigned long i;
134 	bool select = false;
135 	u32 reg;
136 
137 	/* Clear SCC_RVSREQ */
138 	tmio_sd_writel(priv, 0, RENESAS_SDHI_SCC_RVSREQ);
139 
140 	/* Merge the results */
141 	for (i = 0; i < tap_num * 2; i++) {
142 		if (!(taps & BIT(i))) {
143 			taps &= ~BIT(i % tap_num);
144 			taps &= ~BIT((i % tap_num) + tap_num);
145 		}
146 		if (!(smpcmp & BIT(i))) {
147 			smpcmp &= ~BIT(i % tap_num);
148 			smpcmp &= ~BIT((i % tap_num) + tap_num);
149 		}
150 	}
151 
152 	/*
153 	 * Find the longest consecutive run of successful probes.  If that
154 	 * is more than RENESAS_SDHI_MAX_TAP probes long then use the
155 	 * center index as the tap.
156 	 */
157 	tap_cnt = 0;
158 	ntap = 0;
159 	tap_start = 0;
160 	tap_end = 0;
161 	for (i = 0; i < tap_num * 2; i++) {
162 		if (taps & BIT(i))
163 			ntap++;
164 		else {
165 			if (ntap > tap_cnt) {
166 				tap_start = i - ntap;
167 				tap_end = i - 1;
168 				tap_cnt = ntap;
169 			}
170 			ntap = 0;
171 		}
172 	}
173 
174 	if (ntap > tap_cnt) {
175 		tap_start = i - ntap;
176 		tap_end = i - 1;
177 		tap_cnt = ntap;
178 	}
179 
180 	/*
181 	 * If all of the TAP is OK, the sampling clock position is selected by
182 	 * identifying the change point of data.
183 	 */
184 	if (tap_cnt == tap_num * 2) {
185 		match_cnt = 0;
186 		ntap = 0;
187 		tap_start = 0;
188 		tap_end = 0;
189 		for (i = 0; i < tap_num * 2; i++) {
190 			if (smpcmp & BIT(i))
191 				ntap++;
192 			else {
193 				if (ntap > match_cnt) {
194 					tap_start = i - ntap;
195 					tap_end = i - 1;
196 					match_cnt = ntap;
197 				}
198 				ntap = 0;
199 			}
200 		}
201 		if (ntap > match_cnt) {
202 			tap_start = i - ntap;
203 			tap_end = i - 1;
204 			match_cnt = ntap;
205 		}
206 		if (match_cnt)
207 			select = true;
208 	} else if (tap_cnt >= RENESAS_SDHI_MAX_TAP)
209 		select = true;
210 
211 	if (select)
212 		tap_set = ((tap_start + tap_end) / 2) % tap_num;
213 	else
214 		return -EIO;
215 
216 	/* Set SCC */
217 	tmio_sd_writel(priv, tap_set, RENESAS_SDHI_SCC_TAPSET);
218 
219 	/* Enable auto re-tuning */
220 	reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL);
221 	reg |= RENESAS_SDHI_SCC_RVSCNTL_RVSEN;
222 	tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL);
223 
224 	return 0;
225 }
226 
227 int renesas_sdhi_execute_tuning(struct udevice *dev, uint opcode)
228 {
229 	struct tmio_sd_priv *priv = dev_get_priv(dev);
230 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
231 	struct mmc *mmc = upriv->mmc;
232 	unsigned int tap_num;
233 	unsigned int taps = 0, smpcmp = 0;
234 	int i, ret = 0;
235 	u32 caps;
236 
237 	/* Only supported on Renesas RCar */
238 	if (!(priv->caps & TMIO_SD_CAP_RCAR_UHS))
239 		return -EINVAL;
240 
241 	/* clock tuning is not needed for upto 52MHz */
242 	if (!((mmc->selected_mode == MMC_HS_200) ||
243 	      (mmc->selected_mode == UHS_SDR104) ||
244 	      (mmc->selected_mode == UHS_SDR50)))
245 		return 0;
246 
247 	tap_num = renesas_sdhi_init_tuning(priv);
248 	if (!tap_num)
249 		/* Tuning is not supported */
250 		goto out;
251 
252 	if (tap_num * 2 >= sizeof(taps) * 8) {
253 		dev_err(dev,
254 			"Too many taps, skipping tuning. Please consider updating size of taps field of tmio_mmc_host\n");
255 		goto out;
256 	}
257 
258 	/* Issue CMD19 twice for each tap */
259 	for (i = 0; i < 2 * tap_num; i++) {
260 		renesas_sdhi_prepare_tuning(priv, i % tap_num);
261 
262 		/* Force PIO for the tuning */
263 		caps = priv->caps;
264 		priv->caps &= ~TMIO_SD_CAP_DMA_INTERNAL;
265 
266 		ret = mmc_send_tuning(mmc, opcode, NULL);
267 
268 		priv->caps = caps;
269 
270 		if (ret == 0)
271 			taps |= BIT(i);
272 
273 		ret = renesas_sdhi_compare_scc_data(priv);
274 		if (ret == 0)
275 			smpcmp |= BIT(i);
276 
277 		mdelay(1);
278 	}
279 
280 	ret = renesas_sdhi_select_tuning(priv, tap_num, taps, smpcmp);
281 
282 out:
283 	if (ret < 0) {
284 		dev_warn(dev, "Tuning procedure failed\n");
285 		renesas_sdhi_reset_tuning(priv);
286 	}
287 
288 	return ret;
289 }
290 #endif
291 
292 static int renesas_sdhi_set_ios(struct udevice *dev)
293 {
294 	int ret = tmio_sd_set_ios(dev);
295 
296 	mdelay(10);
297 
298 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
299 	struct tmio_sd_priv *priv = dev_get_priv(dev);
300 
301 	if (priv->caps & TMIO_SD_CAP_RCAR_UHS)
302 		renesas_sdhi_reset_tuning(priv);
303 #endif
304 
305 	return ret;
306 }
307 
308 #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
309 static int renesas_sdhi_wait_dat0(struct udevice *dev, int state, int timeout)
310 {
311 	int ret = -ETIMEDOUT;
312 	bool dat0_high;
313 	bool target_dat0_high = !!state;
314 	struct tmio_sd_priv *priv = dev_get_priv(dev);
315 
316 	timeout = DIV_ROUND_UP(timeout, 10); /* check every 10 us. */
317 	while (timeout--) {
318 		dat0_high = !!(tmio_sd_readl(priv, TMIO_SD_INFO2) & TMIO_SD_INFO2_DAT0);
319 		if (dat0_high == target_dat0_high) {
320 			ret = 0;
321 			break;
322 		}
323 		udelay(10);
324 	}
325 
326 	return ret;
327 }
328 #endif
329 
330 static const struct dm_mmc_ops renesas_sdhi_ops = {
331 	.send_cmd = tmio_sd_send_cmd,
332 	.set_ios = renesas_sdhi_set_ios,
333 	.get_cd = tmio_sd_get_cd,
334 #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
335 	.execute_tuning = renesas_sdhi_execute_tuning,
336 #endif
337 #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
338 	.wait_dat0 = renesas_sdhi_wait_dat0,
339 #endif
340 };
341 
342 #define RENESAS_GEN2_QUIRKS	TMIO_SD_CAP_RCAR_GEN2
343 #define RENESAS_GEN3_QUIRKS				\
344 	TMIO_SD_CAP_64BIT | TMIO_SD_CAP_RCAR_GEN3 | TMIO_SD_CAP_RCAR_UHS
345 
346 static const struct udevice_id renesas_sdhi_match[] = {
347 	{ .compatible = "renesas,sdhi-r8a7790", .data = RENESAS_GEN2_QUIRKS },
348 	{ .compatible = "renesas,sdhi-r8a7791", .data = RENESAS_GEN2_QUIRKS },
349 	{ .compatible = "renesas,sdhi-r8a7792", .data = RENESAS_GEN2_QUIRKS },
350 	{ .compatible = "renesas,sdhi-r8a7793", .data = RENESAS_GEN2_QUIRKS },
351 	{ .compatible = "renesas,sdhi-r8a7794", .data = RENESAS_GEN2_QUIRKS },
352 	{ .compatible = "renesas,sdhi-r8a7795", .data = RENESAS_GEN3_QUIRKS },
353 	{ .compatible = "renesas,sdhi-r8a7796", .data = RENESAS_GEN3_QUIRKS },
354 	{ .compatible = "renesas,sdhi-r8a77965", .data = RENESAS_GEN3_QUIRKS },
355 	{ .compatible = "renesas,sdhi-r8a77970", .data = RENESAS_GEN3_QUIRKS },
356 	{ .compatible = "renesas,sdhi-r8a77990", .data = RENESAS_GEN3_QUIRKS },
357 	{ .compatible = "renesas,sdhi-r8a77995", .data = RENESAS_GEN3_QUIRKS },
358 	{ /* sentinel */ }
359 };
360 
361 static int renesas_sdhi_probe(struct udevice *dev)
362 {
363 	struct tmio_sd_priv *priv = dev_get_priv(dev);
364 	u32 quirks = dev_get_driver_data(dev);
365 	struct fdt_resource reg_res;
366 	struct clk clk;
367 	DECLARE_GLOBAL_DATA_PTR;
368 	int ret;
369 
370 	if (quirks == RENESAS_GEN2_QUIRKS) {
371 		ret = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev),
372 				       "reg", 0, &reg_res);
373 		if (ret < 0) {
374 			dev_err(dev, "\"reg\" resource not found, ret=%i\n",
375 				ret);
376 			return ret;
377 		}
378 
379 		if (fdt_resource_size(&reg_res) == 0x100)
380 			quirks |= TMIO_SD_CAP_16BIT;
381 	}
382 
383 	ret = clk_get_by_index(dev, 0, &clk);
384 	if (ret < 0) {
385 		dev_err(dev, "failed to get host clock\n");
386 		return ret;
387 	}
388 
389 	/* set to max rate */
390 	priv->mclk = clk_set_rate(&clk, ULONG_MAX);
391 	if (IS_ERR_VALUE(priv->mclk)) {
392 		dev_err(dev, "failed to set rate for host clock\n");
393 		clk_free(&clk);
394 		return priv->mclk;
395 	}
396 
397 	ret = clk_enable(&clk);
398 	clk_free(&clk);
399 	if (ret) {
400 		dev_err(dev, "failed to enable host clock\n");
401 		return ret;
402 	}
403 
404 	ret = tmio_sd_probe(dev, quirks);
405 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
406 	if (!ret && (priv->caps & TMIO_SD_CAP_RCAR_UHS))
407 		renesas_sdhi_reset_tuning(priv);
408 #endif
409 	return ret;
410 }
411 
412 U_BOOT_DRIVER(renesas_sdhi) = {
413 	.name = "renesas-sdhi",
414 	.id = UCLASS_MMC,
415 	.of_match = renesas_sdhi_match,
416 	.bind = tmio_sd_bind,
417 	.probe = renesas_sdhi_probe,
418 	.priv_auto_alloc_size = sizeof(struct tmio_sd_priv),
419 	.platdata_auto_alloc_size = sizeof(struct tmio_sd_plat),
420 	.ops = &renesas_sdhi_ops,
421 };
422