1 /*
2 * Copyright (c) 2013 Google, Inc
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7 #include <common.h>
8 #include <clk.h>
9 #include <dm.h>
10 #include <dt-structs.h>
11 #include <dwmmc.h>
12 #include <errno.h>
13 #include <mapmem.h>
14 #include <pwrseq.h>
15 #include <syscon.h>
16 #include <asm/gpio.h>
17 #include <asm/arch/clock.h>
18 #include <asm/arch/periph.h>
19 #include <linux/err.h>
20
21 DECLARE_GLOBAL_DATA_PTR;
22
23 struct rockchip_mmc_plat {
24 #if CONFIG_IS_ENABLED(OF_PLATDATA)
25 struct dtd_rockchip_rk3288_dw_mshc dtplat;
26 #endif
27 struct mmc_config cfg;
28 struct mmc mmc;
29 };
30
31 struct rockchip_dwmmc_priv {
32 struct clk clk;
33 struct clk sample_clk;
34 struct dwmci_host host;
35 int fifo_depth;
36 bool fifo_mode;
37 u32 minmax[2];
38 };
39
40 #ifdef CONFIG_USING_KERNEL_DTB
board_mmc_dm_reinit(struct udevice * dev)41 int board_mmc_dm_reinit(struct udevice *dev)
42 {
43 struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
44
45 if (!priv)
46 return 0;
47
48 if (!memcmp(dev->name, "dwmmc", strlen("dwmmc")))
49 return clk_get_by_index(dev, 0, &priv->clk);
50 else
51 return 0;
52 }
53 #endif
54
55 #ifdef CONFIG_SPL_BUILD
mmc_gpio_init_direct(void)56 __weak void mmc_gpio_init_direct(void) {}
57 #endif
58
rockchip_dwmmc_get_mmc_clk(struct dwmci_host * host,uint freq)59 static uint rockchip_dwmmc_get_mmc_clk(struct dwmci_host *host, uint freq)
60 {
61 struct udevice *dev = host->priv;
62 struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
63 int ret;
64
65 /*
66 * If DDR52 8bit mode(only emmc work in 8bit mode),
67 * divider must be set 1
68 */
69 if (mmc_card_ddr52(host->mmc) && host->mmc->bus_width == 8)
70 freq *= 2;
71
72 ret = clk_set_rate(&priv->clk, freq);
73 if (ret < 0) {
74 debug("%s: err=%d\n", __func__, ret);
75 return 0;
76 }
77
78 return freq;
79 }
80
rockchip_dwmmc_ofdata_to_platdata(struct udevice * dev)81 static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
82 {
83 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
84 struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
85 struct dwmci_host *host = &priv->host;
86
87 host->name = dev->name;
88 host->ioaddr = dev_read_addr_ptr(dev);
89 host->buswidth = dev_read_u32_default(dev, "bus-width", 4);
90 host->get_mmc_clk = rockchip_dwmmc_get_mmc_clk;
91 host->priv = dev;
92
93 /* use non-removeable as sdcard and emmc as judgement */
94 if (dev_read_bool(dev, "non-removable"))
95 host->dev_index = 0;
96 else
97 host->dev_index = 1;
98
99 priv->fifo_depth = dev_read_u32_default(dev, "fifo-depth", 0);
100
101 if (priv->fifo_depth < 0)
102 return -EINVAL;
103 priv->fifo_mode = dev_read_bool(dev, "fifo-mode");
104
105 /*
106 * 'clock-freq-min-max' is deprecated
107 * (see https://github.com/torvalds/linux/commit/b023030f10573de738bbe8df63d43acab64c9f7b)
108 */
109 if (dev_read_u32_array(dev, "clock-freq-min-max", priv->minmax, 2)) {
110 int val = dev_read_u32_default(dev, "max-frequency", -EINVAL);
111
112 if (val < 0)
113 return val;
114
115 priv->minmax[0] = 400000; /* 400 kHz */
116 priv->minmax[1] = val;
117 } else {
118 debug("%s: 'clock-freq-min-max' property was deprecated.\n",
119 __func__);
120 }
121 #endif
122 return 0;
123 }
124
125 #ifndef CONFIG_MMC_SIMPLE
rockchip_dwmmc_execute_tuning(struct dwmci_host * host,u32 opcode)126 static int rockchip_dwmmc_execute_tuning(struct dwmci_host *host, u32 opcode)
127 {
128 int i = 0;
129 int ret = -1;
130 struct mmc *mmc = host->mmc;
131 struct udevice *dev = host->priv;
132 struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
133
134 if (IS_ERR(&priv->sample_clk))
135 return -EIO;
136
137 if (mmc->default_phase > 0 && mmc->default_phase < 360) {
138 ret = clk_set_phase(&priv->sample_clk, mmc->default_phase);
139 if (ret)
140 printf("set clk phase fail\n");
141 else
142 ret = mmc_send_tuning(mmc, opcode);
143 mmc->default_phase = 0;
144 }
145 /*
146 * If use default_phase to tune successfully, return.
147 * Otherwise, use the othe phase to tune.
148 */
149 if (!ret)
150 return ret;
151
152 for (i = 0; i < 5; i++) {
153 /* mmc->init_retry must be 0, 1, 2, 3 */
154 if (mmc->init_retry == 4)
155 mmc->init_retry = 0;
156
157 ret = clk_set_phase(&priv->sample_clk, 90 * mmc->init_retry);
158 if (ret) {
159 printf("set clk phase fail\n");
160 break;
161 }
162 ret = mmc_send_tuning(mmc, opcode);
163 debug("Tuning phase is %d, ret is %d\n", mmc->init_retry * 90, ret);
164 mmc->init_retry++;
165 if (!ret)
166 break;
167 }
168
169 return ret;
170 }
171 #else
rockchip_dwmmc_execute_tuning(struct dwmci_host * host,u32 opcode)172 static int rockchip_dwmmc_execute_tuning(struct dwmci_host *host, u32 opcode) { return 0; }
173 #endif
174
rockchip_dwmmc_probe(struct udevice * dev)175 static int rockchip_dwmmc_probe(struct udevice *dev)
176 {
177 struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
178 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
179 struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
180 struct dwmci_host *host = &priv->host;
181 struct udevice *pwr_dev __maybe_unused;
182 int ret;
183
184 #ifdef CONFIG_SPL_BUILD
185 mmc_gpio_init_direct();
186 #endif
187 #if CONFIG_IS_ENABLED(OF_PLATDATA)
188 struct dtd_rockchip_rk3288_dw_mshc *dtplat = &plat->dtplat;
189
190 host->name = dev->name;
191 host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
192 host->buswidth = dtplat->bus_width;
193 host->get_mmc_clk = rockchip_dwmmc_get_mmc_clk;
194 host->execute_tuning = rockchip_dwmmc_execute_tuning;
195 host->priv = dev;
196 host->dev_index = 0;
197 priv->fifo_depth = dtplat->fifo_depth;
198 priv->fifo_mode = 0;
199 priv->minmax[0] = 400000; /* 400 kHz */
200 priv->minmax[1] = dtplat->max_frequency;
201
202 ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
203 if (ret < 0)
204 return ret;
205 #else
206 ret = clk_get_by_index(dev, 0, &priv->clk);
207 if (ret < 0)
208 return ret;
209
210 ret = clk_get_by_name(dev, "ciu-sample", &priv->sample_clk);
211 if (ret < 0)
212 debug("MMC: sample clock not found, not support hs200!\n");
213 host->execute_tuning = rockchip_dwmmc_execute_tuning;
214 #endif
215 host->fifoth_val = MSIZE(DWMCI_MSIZE) |
216 RX_WMARK(priv->fifo_depth / 2 - 1) |
217 TX_WMARK(priv->fifo_depth / 2);
218
219 host->fifo_mode = priv->fifo_mode;
220
221 #ifdef CONFIG_ROCKCHIP_RK3128
222 host->stride_pio = true;
223 #else
224 host->stride_pio = false;
225 #endif
226
227 #ifdef CONFIG_PWRSEQ
228 /* Enable power if needed */
229 ret = uclass_get_device_by_phandle(UCLASS_PWRSEQ, dev, "mmc-pwrseq",
230 &pwr_dev);
231 if (!ret) {
232 ret = pwrseq_set_power(pwr_dev, true);
233 if (ret)
234 return ret;
235 }
236 #endif
237 dwmci_setup_cfg(&plat->cfg, host, priv->minmax[1], priv->minmax[0]);
238 if (dev_read_bool(dev, "mmc-hs200-1_8v"))
239 plat->cfg.host_caps |= MMC_MODE_HS200;
240 plat->mmc.default_phase =
241 dev_read_u32_default(dev, "default-sample-phase", 0);
242 #ifdef CONFIG_ROCKCHIP_RV1106
243 if (!(ret < 0) && (&priv->sample_clk)) {
244 ret = clk_set_phase(&priv->sample_clk, plat->mmc.default_phase);
245 if (ret < 0)
246 debug("MMC: can not set default phase!\n");
247 }
248 #endif
249
250 plat->mmc.init_retry = 0;
251 host->mmc = &plat->mmc;
252 host->mmc->priv = &priv->host;
253 host->mmc->dev = dev;
254 upriv->mmc = host->mmc;
255
256 return dwmci_probe(dev);
257 }
258
rockchip_dwmmc_bind(struct udevice * dev)259 static int rockchip_dwmmc_bind(struct udevice *dev)
260 {
261 struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
262
263 return dwmci_bind(dev, &plat->mmc, &plat->cfg);
264 }
265
266 static const struct udevice_id rockchip_dwmmc_ids[] = {
267 { .compatible = "rockchip,rk3288-dw-mshc" },
268 { .compatible = "rockchip,rk2928-dw-mshc" },
269 { }
270 };
271
272 U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
273 .name = "rockchip_rk3288_dw_mshc",
274 .id = UCLASS_MMC,
275 .of_match = rockchip_dwmmc_ids,
276 .ofdata_to_platdata = rockchip_dwmmc_ofdata_to_platdata,
277 .ops = &dm_dwmci_ops,
278 .bind = rockchip_dwmmc_bind,
279 .probe = rockchip_dwmmc_probe,
280 .priv_auto_alloc_size = sizeof(struct rockchip_dwmmc_priv),
281 .platdata_auto_alloc_size = sizeof(struct rockchip_mmc_plat),
282 };
283
284 #ifdef CONFIG_PWRSEQ
rockchip_dwmmc_pwrseq_set_power(struct udevice * dev,bool enable)285 static int rockchip_dwmmc_pwrseq_set_power(struct udevice *dev, bool enable)
286 {
287 struct gpio_desc reset;
288 int ret;
289
290 ret = gpio_request_by_name(dev, "reset-gpios", 0, &reset, GPIOD_IS_OUT);
291 if (ret)
292 return ret;
293 dm_gpio_set_value(&reset, 1);
294 udelay(1);
295 dm_gpio_set_value(&reset, 0);
296 udelay(200);
297
298 return 0;
299 }
300
301 static const struct pwrseq_ops rockchip_dwmmc_pwrseq_ops = {
302 .set_power = rockchip_dwmmc_pwrseq_set_power,
303 };
304
305 static const struct udevice_id rockchip_dwmmc_pwrseq_ids[] = {
306 { .compatible = "mmc-pwrseq-emmc" },
307 { }
308 };
309
310 U_BOOT_DRIVER(rockchip_dwmmc_pwrseq_drv) = {
311 .name = "mmc_pwrseq_emmc",
312 .id = UCLASS_PWRSEQ,
313 .of_match = rockchip_dwmmc_pwrseq_ids,
314 .ops = &rockchip_dwmmc_pwrseq_ops,
315 };
316 #endif
317