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