common: Drop linux/delay.h from common header
[oweals/u-boot.git] / drivers / mmc / zynq_sdhci.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2013 - 2015 Xilinx, Inc.
4  *
5  * Xilinx Zynq SD Host Controller Interface
6  */
7
8 #include <clk.h>
9 #include <common.h>
10 #include <dm.h>
11 #include <fdtdec.h>
12 #include <linux/delay.h>
13 #include "mmc_private.h"
14 #include <log.h>
15 #include <dm/device_compat.h>
16 #include <linux/err.h>
17 #include <linux/libfdt.h>
18 #include <malloc.h>
19 #include <sdhci.h>
20 #include <zynqmp_tap_delay.h>
21
22 DECLARE_GLOBAL_DATA_PTR;
23
24 struct arasan_sdhci_plat {
25         struct mmc_config cfg;
26         struct mmc mmc;
27 };
28
29 struct arasan_sdhci_priv {
30         struct sdhci_host *host;
31         u8 deviceid;
32         u8 bank;
33 };
34
35 #if defined(CONFIG_ARCH_ZYNQMP)
36 #define MMC_HS200_BUS_SPEED     5
37
38 static const u8 mode2timing[] = {
39         [MMC_LEGACY] = UHS_SDR12_BUS_SPEED,
40         [MMC_HS] = HIGH_SPEED_BUS_SPEED,
41         [SD_HS] = HIGH_SPEED_BUS_SPEED,
42         [MMC_HS_52] = HIGH_SPEED_BUS_SPEED,
43         [MMC_DDR_52] = HIGH_SPEED_BUS_SPEED,
44         [UHS_SDR12] = UHS_SDR12_BUS_SPEED,
45         [UHS_SDR25] = UHS_SDR25_BUS_SPEED,
46         [UHS_SDR50] = UHS_SDR50_BUS_SPEED,
47         [UHS_DDR50] = UHS_DDR50_BUS_SPEED,
48         [UHS_SDR104] = UHS_SDR104_BUS_SPEED,
49         [MMC_HS_200] = MMC_HS200_BUS_SPEED,
50 };
51
52 #define SDHCI_TUNING_LOOP_COUNT 40
53
54 static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 deviceid)
55 {
56         u16 clk;
57         unsigned long timeout;
58
59         clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
60         clk &= ~(SDHCI_CLOCK_CARD_EN);
61         sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
62
63         /* Issue DLL Reset */
64         zynqmp_dll_reset(deviceid);
65
66         /* Wait max 20 ms */
67         timeout = 100;
68         while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
69                                 & SDHCI_CLOCK_INT_STABLE)) {
70                 if (timeout == 0) {
71                         dev_err(mmc_dev(host->mmc),
72                                 ": Internal clock never stabilised.\n");
73                         return;
74                 }
75                 timeout--;
76                 udelay(1000);
77         }
78
79         clk |= SDHCI_CLOCK_CARD_EN;
80         sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
81 }
82
83 static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
84 {
85         struct mmc_cmd cmd;
86         struct mmc_data data;
87         u32 ctrl;
88         struct sdhci_host *host;
89         struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
90         char tuning_loop_counter = SDHCI_TUNING_LOOP_COUNT;
91         u8 deviceid;
92
93         debug("%s\n", __func__);
94
95         host = priv->host;
96         deviceid = priv->deviceid;
97
98         ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
99         ctrl |= SDHCI_CTRL_EXEC_TUNING;
100         sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
101
102         mdelay(1);
103
104         arasan_zynqmp_dll_reset(host, deviceid);
105
106         sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
107         sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
108
109         do {
110                 cmd.cmdidx = opcode;
111                 cmd.resp_type = MMC_RSP_R1;
112                 cmd.cmdarg = 0;
113
114                 data.blocksize = 64;
115                 data.blocks = 1;
116                 data.flags = MMC_DATA_READ;
117
118                 if (tuning_loop_counter-- == 0)
119                         break;
120
121                 if (cmd.cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200 &&
122                     mmc->bus_width == 8)
123                         data.blocksize = 128;
124
125                 sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
126                                                     data.blocksize),
127                              SDHCI_BLOCK_SIZE);
128                 sdhci_writew(host, data.blocks, SDHCI_BLOCK_COUNT);
129                 sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
130
131                 mmc_send_cmd(mmc, &cmd, NULL);
132                 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
133
134                 if (cmd.cmdidx == MMC_CMD_SEND_TUNING_BLOCK)
135                         udelay(1);
136
137         } while (ctrl & SDHCI_CTRL_EXEC_TUNING);
138
139         if (tuning_loop_counter < 0) {
140                 ctrl &= ~SDHCI_CTRL_TUNED_CLK;
141                 sdhci_writel(host, ctrl, SDHCI_HOST_CONTROL2);
142         }
143
144         if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) {
145                 printf("%s:Tuning failed\n", __func__);
146                 return -1;
147         }
148
149         udelay(1);
150         arasan_zynqmp_dll_reset(host, deviceid);
151
152         /* Enable only interrupts served by the SD controller */
153         sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK,
154                      SDHCI_INT_ENABLE);
155         /* Mask all sdhci interrupt sources */
156         sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE);
157
158         return 0;
159 }
160
161 static void arasan_sdhci_set_tapdelay(struct sdhci_host *host)
162 {
163         struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
164         struct mmc *mmc = (struct mmc *)host->mmc;
165         u8 uhsmode;
166
167         uhsmode = mode2timing[mmc->selected_mode];
168
169         if (uhsmode >= UHS_SDR25_BUS_SPEED)
170                 arasan_zynqmp_set_tapdelay(priv->deviceid, uhsmode,
171                                            priv->bank);
172 }
173
174 static void arasan_sdhci_set_control_reg(struct sdhci_host *host)
175 {
176         struct mmc *mmc = (struct mmc *)host->mmc;
177         u32 reg;
178
179         if (!IS_SD(mmc))
180                 return;
181
182         if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
183                 reg = sdhci_readw(host, SDHCI_HOST_CONTROL2);
184                 reg |= SDHCI_CTRL_VDD_180;
185                 sdhci_writew(host, reg, SDHCI_HOST_CONTROL2);
186         }
187
188         if (mmc->selected_mode > SD_HS &&
189             mmc->selected_mode <= UHS_DDR50)
190                 sdhci_set_uhs_timing(host);
191 }
192 #endif
193
194 #if defined(CONFIG_ARCH_ZYNQMP)
195 const struct sdhci_ops arasan_ops = {
196         .platform_execute_tuning        = &arasan_sdhci_execute_tuning,
197         .set_delay = &arasan_sdhci_set_tapdelay,
198         .set_control_reg = &arasan_sdhci_set_control_reg,
199 };
200 #endif
201
202 static int arasan_sdhci_probe(struct udevice *dev)
203 {
204         struct arasan_sdhci_plat *plat = dev_get_platdata(dev);
205         struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
206         struct arasan_sdhci_priv *priv = dev_get_priv(dev);
207         struct sdhci_host *host;
208         struct clk clk;
209         unsigned long clock;
210         int ret;
211
212         host = priv->host;
213
214         ret = clk_get_by_index(dev, 0, &clk);
215         if (ret < 0) {
216                 dev_err(dev, "failed to get clock\n");
217                 return ret;
218         }
219
220         clock = clk_get_rate(&clk);
221         if (IS_ERR_VALUE(clock)) {
222                 dev_err(dev, "failed to get rate\n");
223                 return clock;
224         }
225
226         debug("%s: CLK %ld\n", __func__, clock);
227
228         ret = clk_enable(&clk);
229         if (ret && ret != -ENOSYS) {
230                 dev_err(dev, "failed to enable clock\n");
231                 return ret;
232         }
233
234         host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
235                        SDHCI_QUIRK_BROKEN_R1B;
236
237 #ifdef CONFIG_ZYNQ_HISPD_BROKEN
238         host->quirks |= SDHCI_QUIRK_BROKEN_HISPD_MODE;
239 #endif
240
241         plat->cfg.f_max = CONFIG_ZYNQ_SDHCI_MAX_FREQ;
242
243         ret = mmc_of_parse(dev, &plat->cfg);
244         if (ret)
245                 return ret;
246
247         host->max_clk = clock;
248
249         host->mmc = &plat->mmc;
250         host->mmc->dev = dev;
251         host->mmc->priv = host;
252
253         ret = sdhci_setup_cfg(&plat->cfg, host, plat->cfg.f_max,
254                               CONFIG_ZYNQ_SDHCI_MIN_FREQ);
255         if (ret)
256                 return ret;
257         upriv->mmc = host->mmc;
258
259         return sdhci_probe(dev);
260 }
261
262 static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
263 {
264         struct arasan_sdhci_priv *priv = dev_get_priv(dev);
265
266         priv->host = calloc(1, sizeof(struct sdhci_host));
267         if (!priv->host)
268                 return -1;
269
270         priv->host->name = dev->name;
271
272 #if defined(CONFIG_ARCH_ZYNQMP)
273         priv->host->ops = &arasan_ops;
274 #endif
275
276         priv->host->ioaddr = (void *)dev_read_addr(dev);
277         if (IS_ERR(priv->host->ioaddr))
278                 return PTR_ERR(priv->host->ioaddr);
279
280         priv->deviceid = dev_read_u32_default(dev, "xlnx,device_id", -1);
281         priv->bank = dev_read_u32_default(dev, "xlnx,mio_bank", -1);
282
283         return 0;
284 }
285
286 static int arasan_sdhci_bind(struct udevice *dev)
287 {
288         struct arasan_sdhci_plat *plat = dev_get_platdata(dev);
289
290         return sdhci_bind(dev, &plat->mmc, &plat->cfg);
291 }
292
293 static const struct udevice_id arasan_sdhci_ids[] = {
294         { .compatible = "arasan,sdhci-8.9a" },
295         { }
296 };
297
298 U_BOOT_DRIVER(arasan_sdhci_drv) = {
299         .name           = "arasan_sdhci",
300         .id             = UCLASS_MMC,
301         .of_match       = arasan_sdhci_ids,
302         .ofdata_to_platdata = arasan_sdhci_ofdata_to_platdata,
303         .ops            = &sdhci_ops,
304         .bind           = arasan_sdhci_bind,
305         .probe          = arasan_sdhci_probe,
306         .priv_auto_alloc_size = sizeof(struct arasan_sdhci_priv),
307         .platdata_auto_alloc_size = sizeof(struct arasan_sdhci_plat),
308 };