xref: /rk3399_rockchip-uboot/drivers/mmc/rockchip_sdhci.c (revision 8dd9db5d1cd5826638c3cdb5f681300ff2f29f3b)
1 /*
2  * (C) Copyright 2016 Fuzhou Rockchip Electronics Co., Ltd
3  *
4  * Rockchip SD Host Controller Interface
5  *
6  * SPDX-License-Identifier:	GPL-2.0+
7  */
8 
9 #include <asm/arch/hardware.h>
10 #include <common.h>
11 #include <dm.h>
12 #include <dt-structs.h>
13 #include <linux/libfdt.h>
14 #include <malloc.h>
15 #include <mapmem.h>
16 #include <sdhci.h>
17 #include <clk.h>
18 #include <syscon.h>
19 #include <dm/ofnode.h>
20 #include <asm/arch/clock.h>
21 
22 DECLARE_GLOBAL_DATA_PTR;
23 /* 400KHz is max freq for card ID etc. Use that as min */
24 #define EMMC_MIN_FREQ	400000
25 
26 struct rockchip_sdhc_plat {
27 #if CONFIG_IS_ENABLED(OF_PLATDATA)
28 	struct dtd_rockchip_rk3399_sdhci_5_1 dtplat;
29 #endif
30 	struct mmc_config cfg;
31 	struct mmc mmc;
32 };
33 
34 struct rockchip_emmc_phy {
35 	u32 emmcphy_con[7];
36 	u32 reserved;
37 	u32 emmcphy_status;
38 };
39 
40 struct rockchip_sdhc {
41 	struct sdhci_host host;
42 	void *base;
43 	struct rockchip_emmc_phy *phy;
44 	struct clk emmc_clk;
45 };
46 
47 #define PHYCTRL_CALDONE_MASK		0x1
48 #define PHYCTRL_CALDONE_SHIFT		0x6
49 #define PHYCTRL_CALDONE_DONE		0x1
50 
51 #define PHYCTRL_DLLRDY_MASK		0x1
52 #define PHYCTRL_DLLRDY_SHIFT		0x5
53 #define PHYCTRL_DLLRDY_DONE		0x1
54 
55 #define PHYCTRL_FREQSEL_200M            0x0
56 #define PHYCTRL_FREQSEL_50M             0x1
57 #define PHYCTRL_FREQSEL_100M            0x2
58 #define PHYCTRL_FREQSEL_150M            0x3
59 
60 #define KHz	(1000)
61 #define MHz	(1000 * KHz)
62 
63 static void rk3399_emmc_phy_power_on(struct rockchip_emmc_phy *phy, u32 clock)
64 {
65 	u32 caldone, dllrdy, freqsel;
66 	uint start;
67 
68 	writel(RK_CLRSETBITS(7 << 4, 0), &phy->emmcphy_con[6]);
69 	writel(RK_CLRSETBITS(1 << 11, 1 << 11), &phy->emmcphy_con[0]);
70 	writel(RK_CLRSETBITS(0xf << 7, 6 << 7), &phy->emmcphy_con[0]);
71 
72 	/*
73 	 * According to the user manual, calpad calibration
74 	 * cycle takes more than 2us without the minimal recommended
75 	 * value, so we may need a little margin here
76 	 */
77 	udelay(3);
78 	writel(RK_CLRSETBITS(1, 1), &phy->emmcphy_con[6]);
79 
80 	/*
81 	 * According to the user manual, it asks driver to
82 	 * wait 5us for calpad busy trimming. But it seems that
83 	 * 5us of caldone isn't enough for all cases.
84 	 */
85 	udelay(500);
86 	caldone = readl(&phy->emmcphy_status);
87 	caldone = (caldone >> PHYCTRL_CALDONE_SHIFT) & PHYCTRL_CALDONE_MASK;
88 	if (caldone != PHYCTRL_CALDONE_DONE) {
89 		printf("%s: caldone timeout.\n", __func__);
90 		return;
91 	}
92 
93 	/* Set the frequency of the DLL operation */
94 	if (clock < 75 * MHz)
95 		freqsel = PHYCTRL_FREQSEL_50M;
96 	else if (clock < 125 * MHz)
97 		freqsel = PHYCTRL_FREQSEL_100M;
98 	else if (clock < 175 * MHz)
99 		freqsel = PHYCTRL_FREQSEL_150M;
100 	else
101 		freqsel = PHYCTRL_FREQSEL_200M;
102 
103 	/* Set the frequency of the DLL operation */
104 	writel(RK_CLRSETBITS(3 << 12, freqsel << 12), &phy->emmcphy_con[0]);
105 	writel(RK_CLRSETBITS(1 << 1, 1 << 1), &phy->emmcphy_con[6]);
106 
107 	start = get_timer(0);
108 
109 	do {
110 		udelay(1);
111 		dllrdy = readl(&phy->emmcphy_status);
112 		dllrdy = (dllrdy >> PHYCTRL_DLLRDY_SHIFT) & PHYCTRL_DLLRDY_MASK;
113 		if (dllrdy == PHYCTRL_DLLRDY_DONE)
114 			break;
115 	} while (get_timer(start) < 50000);
116 
117 	if (dllrdy != PHYCTRL_DLLRDY_DONE)
118 		printf("%s: dllrdy timeout.\n", __func__);
119 }
120 
121 static void rk3399_emmc_phy_power_off(struct rockchip_emmc_phy *phy)
122 {
123 	writel(RK_CLRSETBITS(1, 0), &phy->emmcphy_con[6]);
124 	writel(RK_CLRSETBITS(1 << 1, 0), &phy->emmcphy_con[6]);
125 }
126 
127 static int rk3399_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
128 {
129 	unsigned int div, clk = 0, timeout;
130 	unsigned int input_clk;
131 	struct rockchip_sdhc *priv =
132 			container_of(host, struct rockchip_sdhc, host);
133 
134 	/* Wait max 20 ms */
135 	timeout = 200;
136 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) &
137 			   (SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT)) {
138 		if (timeout == 0) {
139 			printf("%s: Timeout to wait cmd & data inhibit\n",
140 			       __func__);
141 			return -EBUSY;
142 		}
143 
144 		timeout--;
145 		udelay(100);
146 	}
147 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
148 
149 	if (clock == 0)
150 		return 0;
151 
152 	input_clk = clk_set_rate(&priv->emmc_clk, clock);
153 	if (IS_ERR_VALUE(input_clk))
154 		input_clk = host->max_clk;
155 
156 	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
157 		/*
158 		 * Check if the Host Controller supports Programmable Clock
159 		 * Mode.
160 		 */
161 		if (host->clk_mul) {
162 			for (div = 1; div <= 1024; div++) {
163 				if ((input_clk / div) <= clock)
164 					break;
165 			}
166 
167 			/*
168 			 * Set Programmable Clock Mode in the Clock
169 			 * Control register.
170 			 */
171 			clk = SDHCI_PROG_CLOCK_MODE;
172 			div--;
173 		} else {
174 			/* Version 3.00 divisors must be a multiple of 2. */
175 			if (input_clk <= clock) {
176 				div = 1;
177 			} else {
178 				for (div = 2;
179 				     div < SDHCI_MAX_DIV_SPEC_300;
180 				     div += 2) {
181 					if ((input_clk / div) <= clock)
182 						break;
183 				}
184 			}
185 			div >>= 1;
186 		}
187 	} else {
188 		/* Version 2.00 divisors must be a power of 2. */
189 		for (div = 1; div < SDHCI_MAX_DIV_SPEC_200; div *= 2) {
190 			if ((input_clk / div) <= clock)
191 				break;
192 		}
193 		div >>= 1;
194 	}
195 
196 	clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
197 	clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
198 		<< SDHCI_DIVIDER_HI_SHIFT;
199 	clk |= SDHCI_CLOCK_INT_EN;
200 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
201 
202 	/* Wait max 20 ms */
203 	timeout = 20;
204 	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
205 		& SDHCI_CLOCK_INT_STABLE)) {
206 		if (timeout == 0) {
207 			printf("%s: Internal clock never stabilised.\n",
208 			       __func__);
209 			return -EBUSY;
210 		}
211 		timeout--;
212 		udelay(1000);
213 	}
214 	clk |= SDHCI_CLOCK_CARD_EN;
215 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
216 	host->clock = clock;
217 
218 	return 0;
219 }
220 
221 static int arasan_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
222 {
223 	struct rockchip_sdhc *priv =
224 			container_of(host, struct rockchip_sdhc, host);
225 	int cycle_phy = host->clock != clock &&
226 			clock > EMMC_MIN_FREQ;
227 
228 	if (cycle_phy)
229 		rk3399_emmc_phy_power_off(priv->phy);
230 
231 	rk3399_sdhci_set_clock(host, clock);
232 
233 	if (cycle_phy)
234 		rk3399_emmc_phy_power_on(priv->phy, clock);
235 
236 	return 0;
237 }
238 
239 static struct sdhci_ops arasan_sdhci_ops = {
240 	.set_clock	= arasan_sdhci_set_clock,
241 };
242 
243 static int arasan_get_phy(struct udevice *dev)
244 {
245 	struct rockchip_sdhc *priv = dev_get_priv(dev);
246 
247 #if CONFIG_IS_ENABLED(OF_PLATDATA)
248 	priv->phy = (struct rockchip_emmc_phy *)0xff77f780;
249 #else
250 	ofnode phy_node;
251 	void *grf_base;
252 	u32 grf_phy_offset, phandle;
253 
254 	phandle = dev_read_u32_default(dev, "phys", 0);
255 	phy_node = ofnode_get_by_phandle(phandle);
256 	if (!ofnode_valid(phy_node)) {
257 		debug("Not found emmc phy device\n");
258 		return -ENODEV;
259 	}
260 
261 	grf_base = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
262 	if (grf_base < 0)
263 		printf("%s Get syscon grf failed", __func__);
264 	grf_phy_offset = ofnode_read_u32_default(phy_node, "reg", 0);
265 
266 	priv->phy = (struct rockchip_emmc_phy *)(grf_base + grf_phy_offset);
267 #endif
268 	return 0;
269 }
270 
271 static int arasan_sdhci_probe(struct udevice *dev)
272 {
273 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
274 	struct rockchip_sdhc_plat *plat = dev_get_platdata(dev);
275 	struct rockchip_sdhc *prv = dev_get_priv(dev);
276 	struct sdhci_host *host = &prv->host;
277 	int max_frequency, ret;
278 	struct clk clk;
279 
280 #if CONFIG_IS_ENABLED(OF_PLATDATA)
281 	struct dtd_rockchip_rk3399_sdhci_5_1 *dtplat = &plat->dtplat;
282 
283 	host->name = dev->name;
284 	host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
285 	host->host_caps |= MMC_MODE_8BIT;
286 	max_frequency = dtplat->max_frequency;
287 	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &clk);
288 #else
289 	max_frequency = dev_read_u32_default(dev, "max-frequency", 0);
290 	switch (dev_read_u32_default(dev, "bus-width", 4)) {
291 	case 8:
292 		host->host_caps |= MMC_MODE_8BIT;
293 		break;
294 	case 4:
295 		host->host_caps |= MMC_MODE_4BIT;
296 		break;
297 	case 1:
298 		break;
299 	default:
300 		printf("Invalid \"bus-width\" value\n");
301 		return -EINVAL;
302 	}
303 	ret = clk_get_by_index(dev, 0, &clk);
304 #endif
305 	if (!ret) {
306 		ret = clk_set_rate(&clk, max_frequency);
307 		if (IS_ERR_VALUE(ret))
308 			printf("%s clk set rate fail!\n", __func__);
309 	} else {
310 		printf("%s fail to get clk\n", __func__);
311 	}
312 
313 	prv->emmc_clk = clk;
314 	ret = arasan_get_phy(dev);
315 	if (ret)
316 		return ret;
317 
318 	host->ops = &arasan_sdhci_ops;
319 
320 	host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD;
321 	host->max_clk = max_frequency;
322 
323 	if (dev_read_bool(dev, "mmc-hs200-1_8v"))
324 		host->host_caps |= MMC_MODE_HS200;
325 	else if (dev_read_bool(dev, "mmc-hs400-1_8v"))
326 		host->host_caps |= MMC_MODE_HS400;
327 	ret = sdhci_setup_cfg(&plat->cfg, host, 0, EMMC_MIN_FREQ);
328 
329 	host->mmc = &plat->mmc;
330 	if (ret)
331 		return ret;
332 	host->mmc->priv = &prv->host;
333 	host->mmc->dev = dev;
334 	upriv->mmc = host->mmc;
335 
336 	return sdhci_probe(dev);
337 }
338 
339 static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
340 {
341 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
342 	struct sdhci_host *host = dev_get_priv(dev);
343 
344 	host->name = dev->name;
345 	host->ioaddr = dev_read_addr_ptr(dev);
346 #endif
347 
348 	return 0;
349 }
350 
351 static int rockchip_sdhci_bind(struct udevice *dev)
352 {
353 	struct rockchip_sdhc_plat *plat = dev_get_platdata(dev);
354 
355 	return sdhci_bind(dev, &plat->mmc, &plat->cfg);
356 }
357 
358 static const struct udevice_id arasan_sdhci_ids[] = {
359 	{ .compatible = "arasan,sdhci-5.1" },
360 	{ }
361 };
362 
363 U_BOOT_DRIVER(arasan_sdhci_drv) = {
364 	.name		= "rockchip_rk3399_sdhci_5_1",
365 	.id		= UCLASS_MMC,
366 	.of_match	= arasan_sdhci_ids,
367 	.ofdata_to_platdata = arasan_sdhci_ofdata_to_platdata,
368 	.ops		= &sdhci_ops,
369 	.bind		= rockchip_sdhci_bind,
370 	.probe		= arasan_sdhci_probe,
371 	.priv_auto_alloc_size = sizeof(struct rockchip_sdhc),
372 	.platdata_auto_alloc_size = sizeof(struct rockchip_sdhc_plat),
373 };
374