blob: 4f0dde326c24c675b02cf44f9385253bcc34d003 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Michal Simek293eb332013-04-22 14:56:49 +02002/*
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -07003 * (C) Copyright 2013 - 2022, Xilinx, Inc.
4 * (C) Copyright 2022, Advanced Micro Devices, Inc.
Michal Simek293eb332013-04-22 14:56:49 +02005 *
6 * Xilinx Zynq SD Host Controller Interface
Michal Simek293eb332013-04-22 14:56:49 +02007 */
8
Stefan Herbrechtsmeiere0f4de12017-01-17 16:27:32 +01009#include <clk.h>
Michal Simek293eb332013-04-22 14:56:49 +020010#include <common.h>
Michal Simekd9ae52c2015-11-30 16:13:03 +010011#include <dm.h>
Michal Simek345d3c02014-02-24 11:16:31 +010012#include <fdtdec.h>
Simon Glassc05ed002020-05-10 11:40:11 -060013#include <linux/delay.h>
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +053014#include "mmc_private.h"
Simon Glassf7ae49f2020-05-10 11:40:05 -060015#include <log.h>
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +010016#include <reset.h>
Simon Glass336d4612020-02-03 07:36:16 -070017#include <dm/device_compat.h>
Simon Glass61b29b82020-02-03 07:36:15 -070018#include <linux/err.h>
Masahiro Yamadab08c8c42018-03-05 01:20:11 +090019#include <linux/libfdt.h>
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -070020#include <linux/iopoll.h>
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +010021#include <asm/types.h>
22#include <linux/math64.h>
Ashok Reddy Soma655d69f2021-08-02 23:20:44 -060023#include <asm/cache.h>
Michal Simek293eb332013-04-22 14:56:49 +020024#include <malloc.h>
25#include <sdhci.h>
Ashok Reddy Somad0449822021-08-02 23:20:43 -060026#include <zynqmp_firmware.h>
Michal Simek293eb332013-04-22 14:56:49 +020027
Ashok Reddy Somaee9ae002021-07-09 05:53:41 -060028#define SDHCI_ARASAN_ITAPDLY_REGISTER 0xF0F8
29#define SDHCI_ARASAN_ITAPDLY_SEL_MASK GENMASK(7, 0)
30#define SDHCI_ARASAN_OTAPDLY_REGISTER 0xF0FC
31#define SDHCI_ARASAN_OTAPDLY_SEL_MASK GENMASK(5, 0)
32#define SDHCI_ITAPDLY_CHGWIN BIT(9)
33#define SDHCI_ITAPDLY_ENABLE BIT(8)
34#define SDHCI_OTAPDLY_ENABLE BIT(6)
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -060035
Michal Simek9851f502020-10-23 04:58:59 -060036#define SDHCI_TUNING_LOOP_COUNT 40
Michal Simek80355ae2020-10-23 04:59:00 -060037#define MMC_BANK2 0x2
38
Ashok Reddy Soma655d69f2021-08-02 23:20:44 -060039#define SD_DLL_CTRL 0xFF180358
40#define SD_ITAP_DLY 0xFF180314
41#define SD_OTAP_DLY 0xFF180318
42#define SD0_DLL_RST BIT(2)
43#define SD1_DLL_RST BIT(18)
44#define SD0_ITAPCHGWIN BIT(9)
45#define SD1_ITAPCHGWIN BIT(25)
46#define SD0_ITAPDLYENA BIT(8)
47#define SD1_ITAPDLYENA BIT(24)
48#define SD0_ITAPDLYSEL_MASK GENMASK(7, 0)
49#define SD1_ITAPDLYSEL_MASK GENMASK(23, 16)
50#define SD0_OTAPDLYSEL_MASK GENMASK(5, 0)
51#define SD1_OTAPDLYSEL_MASK GENMASK(21, 16)
52
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -070053#define MIN_PHY_CLK_HZ 50000000
54
55#define PHY_CTRL_REG1 0x270
56#define PHY_CTRL_ITAPDLY_ENA_MASK BIT(0)
57#define PHY_CTRL_ITAPDLY_SEL_MASK GENMASK(5, 1)
58#define PHY_CTRL_ITAPDLY_SEL_SHIFT 1
59#define PHY_CTRL_ITAP_CHG_WIN_MASK BIT(6)
60#define PHY_CTRL_OTAPDLY_ENA_MASK BIT(8)
61#define PHY_CTRL_OTAPDLY_SEL_MASK GENMASK(15, 12)
62#define PHY_CTRL_OTAPDLY_SEL_SHIFT 12
63#define PHY_CTRL_STRB_SEL_MASK GENMASK(23, 16)
64#define PHY_CTRL_STRB_SEL_SHIFT 16
65#define PHY_CTRL_TEST_CTRL_MASK GENMASK(31, 24)
66
67#define PHY_CTRL_REG2 0x274
68#define PHY_CTRL_EN_DLL_MASK BIT(0)
69#define PHY_CTRL_DLL_RDY_MASK BIT(1)
70#define PHY_CTRL_FREQ_SEL_MASK GENMASK(6, 4)
71#define PHY_CTRL_FREQ_SEL_SHIFT 4
72#define PHY_CTRL_SEL_DLY_TX_MASK BIT(16)
73#define PHY_CTRL_SEL_DLY_RX_MASK BIT(17)
74#define FREQSEL_200M_170M 0x0
75#define FREQSEL_170M_140M 0x1
76#define FREQSEL_140M_110M 0x2
77#define FREQSEL_110M_80M 0x3
78#define FREQSEL_80M_50M 0x4
79#define FREQSEL_275M_250M 0x5
80#define FREQSEL_250M_225M 0x6
81#define FREQSEL_225M_200M 0x7
82#define PHY_DLL_TIMEOUT_MS 100
83
84#define VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLY_CHAIN 39
85#define VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLL 146
86#define VERSAL_NET_PHY_CTRL_STRB90_STRB180_VAL 0X77
87
Michal Simek80355ae2020-10-23 04:59:00 -060088struct arasan_sdhci_clk_data {
89 int clk_phase_in[MMC_TIMING_MMC_HS400 + 1];
90 int clk_phase_out[MMC_TIMING_MMC_HS400 + 1];
91};
Michal Simek9851f502020-10-23 04:58:59 -060092
Simon Glass329a4492016-07-05 17:10:15 -060093struct arasan_sdhci_plat {
94 struct mmc_config cfg;
95 struct mmc mmc;
96};
97
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +053098struct arasan_sdhci_priv {
99 struct sdhci_host *host;
Michal Simek80355ae2020-10-23 04:59:00 -0600100 struct arasan_sdhci_clk_data clk_data;
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -0600101 u32 node_id;
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530102 u8 bank;
Ashok Reddy Soma7a49a162020-10-23 04:58:57 -0600103 u8 no_1p8;
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -0700104 bool internal_phy_reg;
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +0100105 struct reset_ctl_bulk resets;
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530106};
107
Ashok Reddy Soma655d69f2021-08-02 23:20:44 -0600108/* For Versal platforms zynqmp_mmio_write() won't be available */
109__weak int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value)
110{
111 return 0;
112}
113
T Karthik Reddya3e3d462021-10-01 16:38:38 +0530114__weak int xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
115 u32 arg3, u32 *ret_payload)
116{
117 return 0;
118}
119
T Karthik Reddy15535322022-04-27 10:27:12 +0200120__weak int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id)
121{
122 return 1;
123}
124
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -0700125#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL_NET)
Michal Simek80355ae2020-10-23 04:59:00 -0600126/* Default settings for ZynqMP Clock Phases */
Michal Simek419b4a82021-07-09 05:53:44 -0600127static const u32 zynqmp_iclk_phases[] = {0, 63, 63, 0, 63, 0,
128 0, 183, 54, 0, 0};
129static const u32 zynqmp_oclk_phases[] = {0, 72, 60, 0, 60, 72,
130 135, 48, 72, 135, 0};
Michal Simek80355ae2020-10-23 04:59:00 -0600131
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600132/* Default settings for Versal Clock Phases */
Michal Simek419b4a82021-07-09 05:53:44 -0600133static const u32 versal_iclk_phases[] = {0, 132, 132, 0, 132,
134 0, 0, 162, 90, 0, 0};
135static const u32 versal_oclk_phases[] = {0, 60, 48, 0, 48, 72,
136 90, 36, 60, 90, 0};
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600137
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -0700138/* Default settings for versal-net eMMC Clock Phases */
139static const u32 versal_net_emmc_iclk_phases[] = {0, 0, 0, 0, 0, 0, 0, 0, 39,
140 0, 0};
141static const u32 versal_net_emmc_oclk_phases[] = {0, 113, 0, 0, 0, 0, 0, 0,
142 113, 79, 45};
143
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530144static const u8 mode2timing[] = {
Ashok Reddy Soma17a42ab2020-10-23 04:58:58 -0600145 [MMC_LEGACY] = MMC_TIMING_LEGACY,
146 [MMC_HS] = MMC_TIMING_MMC_HS,
147 [SD_HS] = MMC_TIMING_SD_HS,
Ashok Reddy Soma71f07732022-06-27 14:22:45 +0530148 [MMC_HS_52] = MMC_TIMING_MMC_HS,
149 [MMC_DDR_52] = MMC_TIMING_MMC_DDR52,
Ashok Reddy Soma17a42ab2020-10-23 04:58:58 -0600150 [UHS_SDR12] = MMC_TIMING_UHS_SDR12,
151 [UHS_SDR25] = MMC_TIMING_UHS_SDR25,
152 [UHS_SDR50] = MMC_TIMING_UHS_SDR50,
153 [UHS_DDR50] = MMC_TIMING_UHS_DDR50,
154 [UHS_SDR104] = MMC_TIMING_UHS_SDR104,
155 [MMC_HS_200] = MMC_TIMING_MMC_HS200,
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530156};
157
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -0700158#if defined(CONFIG_ARCH_VERSAL_NET)
159/**
160 * arasan_phy_set_delaychain - Set eMMC delay chain based Input/Output clock
161 *
162 * @host: Pointer to the sdhci_host structure
163 * @enable: Enable or disable Delay chain based Tx and Rx clock
164 * Return: None
165 *
166 * Enable or disable eMMC delay chain based Input and Output clock in
167 * PHY_CTRL_REG2
168 */
169static void arasan_phy_set_delaychain(struct sdhci_host *host, bool enable)
170{
171 u32 reg;
172
173 reg = sdhci_readw(host, PHY_CTRL_REG2);
174 if (enable)
175 reg |= PHY_CTRL_SEL_DLY_TX_MASK | PHY_CTRL_SEL_DLY_RX_MASK;
176 else
177 reg &= ~(PHY_CTRL_SEL_DLY_TX_MASK | PHY_CTRL_SEL_DLY_RX_MASK);
178
179 sdhci_writew(host, reg, PHY_CTRL_REG2);
180}
181
182/**
183 * arasan_phy_set_dll - Set eMMC DLL clock
184 *
185 * @host: Pointer to the sdhci_host structure
186 * @enable: Enable or disable DLL clock
187 * Return: 0 if success or timeout error
188 *
189 * Enable or disable eMMC DLL clock in PHY_CTRL_REG2. When DLL enable is
190 * set, wait till DLL is locked
191 */
192static int arasan_phy_set_dll(struct sdhci_host *host, bool enable)
193{
194 u32 reg;
195
196 reg = sdhci_readw(host, PHY_CTRL_REG2);
197 if (enable)
198 reg |= PHY_CTRL_EN_DLL_MASK;
199 else
200 reg &= ~PHY_CTRL_EN_DLL_MASK;
201
202 sdhci_writew(host, reg, PHY_CTRL_REG2);
203
204 /* If DLL is disabled return success */
205 if (!enable)
206 return 0;
207
208 /* If DLL is enabled wait till DLL loop is locked, which is
209 * indicated by dll_rdy bit(bit1) in PHY_CTRL_REG2
210 */
211 return readl_relaxed_poll_timeout(host->ioaddr + PHY_CTRL_REG2, reg,
212 (reg & PHY_CTRL_DLL_RDY_MASK),
213 1000 * PHY_DLL_TIMEOUT_MS);
214}
215
216/**
217 * arasan_phy_dll_set_freq - Select frequency range of DLL for eMMC
218 *
219 * @host: Pointer to the sdhci_host structure
220 * @clock: clock value
221 * Return: None
222 *
223 * Set frequency range bits based on the selected clock for eMMC
224 */
225static void arasan_phy_dll_set_freq(struct sdhci_host *host, int clock)
226{
227 u32 reg, freq_sel, freq;
228
229 freq = DIV_ROUND_CLOSEST(clock, 1000000);
230 if (freq <= 200 && freq > 170)
231 freq_sel = FREQSEL_200M_170M;
232 else if (freq <= 170 && freq > 140)
233 freq_sel = FREQSEL_170M_140M;
234 else if (freq <= 140 && freq > 110)
235 freq_sel = FREQSEL_140M_110M;
236 else if (freq <= 110 && freq > 80)
237 freq_sel = FREQSEL_110M_80M;
238 else
239 freq_sel = FREQSEL_80M_50M;
240
241 reg = sdhci_readw(host, PHY_CTRL_REG2);
242 reg &= ~PHY_CTRL_FREQ_SEL_MASK;
243 reg |= (freq_sel << PHY_CTRL_FREQ_SEL_SHIFT);
244 sdhci_writew(host, reg, PHY_CTRL_REG2);
245}
246
247static int arasan_sdhci_config_dll(struct sdhci_host *host, unsigned int clock, bool enable)
248{
249 struct mmc *mmc = (struct mmc *)host->mmc;
250 struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
251
252 if (enable) {
253 if (priv->internal_phy_reg && clock >= MIN_PHY_CLK_HZ && enable)
254 arasan_phy_set_dll(host, 1);
255 return 0;
256 }
257
258 if (priv->internal_phy_reg && clock >= MIN_PHY_CLK_HZ) {
259 sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
260 arasan_phy_set_dll(host, 0);
261 arasan_phy_set_delaychain(host, 0);
262 arasan_phy_dll_set_freq(host, clock);
263 return 0;
264 }
265
266 sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
267 arasan_phy_set_delaychain(host, 1);
268
269 return 0;
270}
271#endif
272
Ashok Reddy Somacbdee4d2022-09-30 03:25:46 -0600273static inline int arasan_zynqmp_set_in_tapdelay(u32 node_id, u32 itap_delay)
Ashok Reddy Soma655d69f2021-08-02 23:20:44 -0600274{
275 int ret;
276
277 if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
278 if (node_id == NODE_SD_0) {
279 ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN,
280 SD0_ITAPCHGWIN);
281 if (ret)
282 return ret;
283
284 ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA,
285 SD0_ITAPDLYENA);
286 if (ret)
287 return ret;
288
289 ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
290 itap_delay);
291 if (ret)
292 return ret;
293
294 ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN, 0);
295 if (ret)
296 return ret;
297 }
298 ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN,
299 SD1_ITAPCHGWIN);
300 if (ret)
301 return ret;
302
303 ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA,
304 SD1_ITAPDLYENA);
305 if (ret)
306 return ret;
307
308 ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
309 (itap_delay << 16));
310 if (ret)
311 return ret;
312
313 ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN, 0);
314 if (ret)
315 return ret;
316 } else {
Ashok Reddy Somacbdee4d2022-09-30 03:25:46 -0600317 return xilinx_pm_request(PM_IOCTL, node_id,
Ashok Reddy Soma655d69f2021-08-02 23:20:44 -0600318 IOCTL_SET_SD_TAPDELAY,
319 PM_TAPDELAY_INPUT, itap_delay, NULL);
320 }
321
322 return 0;
323}
324
Ashok Reddy Somacbdee4d2022-09-30 03:25:46 -0600325static inline int arasan_zynqmp_set_out_tapdelay(u32 node_id, u32 otap_delay)
Ashok Reddy Soma655d69f2021-08-02 23:20:44 -0600326{
327 if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
328 if (node_id == NODE_SD_0)
329 return zynqmp_mmio_write(SD_OTAP_DLY,
330 SD0_OTAPDLYSEL_MASK,
331 otap_delay);
332
333 return zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
334 (otap_delay << 16));
335 } else {
Ashok Reddy Somacbdee4d2022-09-30 03:25:46 -0600336 return xilinx_pm_request(PM_IOCTL, node_id,
Ashok Reddy Soma655d69f2021-08-02 23:20:44 -0600337 IOCTL_SET_SD_TAPDELAY,
338 PM_TAPDELAY_OUTPUT, otap_delay, NULL);
339 }
340}
341
Ashok Reddy Somacbdee4d2022-09-30 03:25:46 -0600342static inline int zynqmp_dll_reset(u32 node_id, u32 type)
Ashok Reddy Soma655d69f2021-08-02 23:20:44 -0600343{
344 if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
345 if (node_id == NODE_SD_0)
346 return zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST,
347 type == PM_DLL_RESET_ASSERT ?
348 SD0_DLL_RST : 0);
349
350 return zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST,
351 type == PM_DLL_RESET_ASSERT ?
352 SD1_DLL_RST : 0);
353 } else {
Ashok Reddy Somacbdee4d2022-09-30 03:25:46 -0600354 return xilinx_pm_request(PM_IOCTL, node_id,
Ashok Reddy Soma655d69f2021-08-02 23:20:44 -0600355 IOCTL_SD_DLL_RESET, type, 0, NULL);
356 }
357}
358
Ashok Reddy Somacbdee4d2022-09-30 03:25:46 -0600359static int arasan_zynqmp_dll_reset(struct sdhci_host *host, u32 node_id)
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530360{
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600361 struct mmc *mmc = (struct mmc *)host->mmc;
362 struct udevice *dev = mmc->dev;
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530363 unsigned long timeout;
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600364 int ret;
365 u16 clk;
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530366
367 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
368 clk &= ~(SDHCI_CLOCK_CARD_EN);
369 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
370
371 /* Issue DLL Reset */
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600372 ret = zynqmp_dll_reset(node_id, PM_DLL_RESET_ASSERT);
373 if (ret) {
374 dev_err(dev, "dll_reset assert failed with err: %d\n", ret);
375 return ret;
376 }
377
378 /* Allow atleast 1ms delay for proper DLL reset */
379 mdelay(1);
380 ret = zynqmp_dll_reset(node_id, PM_DLL_RESET_RELEASE);
381 if (ret) {
382 dev_err(dev, "dll_reset release failed with err: %d\n", ret);
383 return ret;
384 }
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530385
386 /* Wait max 20 ms */
387 timeout = 100;
388 while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
389 & SDHCI_CLOCK_INT_STABLE)) {
390 if (timeout == 0) {
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600391 dev_err(dev, ": Internal clock never stabilised.\n");
392 return -EBUSY;
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530393 }
394 timeout--;
395 udelay(1000);
396 }
397
398 clk |= SDHCI_CLOCK_CARD_EN;
399 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600400
401 return 0;
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530402}
403
404static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
405{
406 struct mmc_cmd cmd;
407 struct mmc_data data;
408 u32 ctrl;
409 struct sdhci_host *host;
410 struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
Algapally Santosh Sagarb387c252023-01-19 22:36:17 -0700411 int tuning_loop_counter = SDHCI_TUNING_LOOP_COUNT;
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530412
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +0100413 dev_dbg(mmc->dev, "%s\n", __func__);
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530414
415 host = priv->host;
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530416
Faiz Abbasd1c0a222019-06-11 00:43:40 +0530417 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530418 ctrl |= SDHCI_CTRL_EXEC_TUNING;
Faiz Abbasd1c0a222019-06-11 00:43:40 +0530419 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530420
421 mdelay(1);
422
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -0600423 arasan_zynqmp_dll_reset(host, priv->node_id);
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530424
425 sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
426 sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
427
428 do {
429 cmd.cmdidx = opcode;
430 cmd.resp_type = MMC_RSP_R1;
431 cmd.cmdarg = 0;
432
433 data.blocksize = 64;
434 data.blocks = 1;
435 data.flags = MMC_DATA_READ;
436
437 if (tuning_loop_counter-- == 0)
438 break;
439
440 if (cmd.cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200 &&
441 mmc->bus_width == 8)
442 data.blocksize = 128;
443
444 sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
445 data.blocksize),
446 SDHCI_BLOCK_SIZE);
447 sdhci_writew(host, data.blocks, SDHCI_BLOCK_COUNT);
448 sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
449
450 mmc_send_cmd(mmc, &cmd, NULL);
Faiz Abbasd1c0a222019-06-11 00:43:40 +0530451 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530452
453 if (cmd.cmdidx == MMC_CMD_SEND_TUNING_BLOCK)
454 udelay(1);
455
456 } while (ctrl & SDHCI_CTRL_EXEC_TUNING);
457
458 if (tuning_loop_counter < 0) {
459 ctrl &= ~SDHCI_CTRL_TUNED_CLK;
Faiz Abbasd1c0a222019-06-11 00:43:40 +0530460 sdhci_writel(host, ctrl, SDHCI_HOST_CONTROL2);
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530461 }
462
463 if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) {
464 printf("%s:Tuning failed\n", __func__);
465 return -1;
466 }
467
468 udelay(1);
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -0600469 arasan_zynqmp_dll_reset(host, priv->node_id);
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530470
471 /* Enable only interrupts served by the SD controller */
472 sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK,
473 SDHCI_INT_ENABLE);
474 /* Mask all sdhci interrupt sources */
475 sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE);
476
477 return 0;
478}
479
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600480/**
481 * sdhci_zynqmp_sdcardclk_set_phase - Set the SD Output Clock Tap Delays
482 *
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600483 * @host: Pointer to the sdhci_host structure.
484 * @degrees: The clock phase shift between 0 - 359.
Ashok Reddy Soma8e34aa02021-07-09 05:53:39 -0600485 * Return: 0
Michal Simekc0436fc2021-07-09 05:53:43 -0600486 *
487 * Set the SD Output Clock Tap Delays for Output path
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600488 */
489static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host,
490 int degrees)
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530491{
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530492 struct mmc *mmc = (struct mmc *)host->mmc;
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600493 struct udevice *dev = mmc->dev;
494 struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600495 u8 tap_delay, tap_max = 0;
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600496 int timing = mode2timing[mmc->selected_mode];
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600497 int ret;
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530498
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600499 /*
500 * This is applicable for SDHCI_SPEC_300 and above
501 * ZynqMP does not set phase for <=25MHz clock.
502 * If degrees is zero, no need to do anything.
503 */
Ashok Reddy Somaaffcba72021-07-09 05:53:40 -0600504 if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300)
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600505 return 0;
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530506
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600507 switch (timing) {
508 case MMC_TIMING_MMC_HS:
509 case MMC_TIMING_SD_HS:
510 case MMC_TIMING_UHS_SDR25:
511 case MMC_TIMING_UHS_DDR50:
512 case MMC_TIMING_MMC_DDR52:
513 /* For 50MHz clock, 30 Taps are available */
514 tap_max = 30;
515 break;
516 case MMC_TIMING_UHS_SDR50:
517 /* For 100MHz clock, 15 Taps are available */
518 tap_max = 15;
519 break;
520 case MMC_TIMING_UHS_SDR104:
521 case MMC_TIMING_MMC_HS200:
522 /* For 200MHz clock, 8 Taps are available */
523 tap_max = 8;
524 default:
525 break;
526 }
527
528 tap_delay = (degrees * tap_max) / 360;
529
Ashok Reddy Somaa70bdaf2021-07-09 05:53:42 -0600530 /* Limit output tap_delay value to 6 bits */
531 tap_delay &= SDHCI_ARASAN_OTAPDLY_SEL_MASK;
532
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600533 /* Set the Clock Phase */
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -0600534 ret = arasan_zynqmp_set_out_tapdelay(priv->node_id, tap_delay);
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600535 if (ret) {
536 dev_err(dev, "Error setting output Tap Delay\n");
537 return ret;
538 }
539
540 /* Release DLL Reset */
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -0600541 ret = zynqmp_dll_reset(priv->node_id, PM_DLL_RESET_RELEASE);
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600542 if (ret) {
543 dev_err(dev, "dll_reset release failed with err: %d\n", ret);
544 return ret;
545 }
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600546
Ashok Reddy Soma8e34aa02021-07-09 05:53:39 -0600547 return 0;
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600548}
549
550/**
551 * sdhci_zynqmp_sampleclk_set_phase - Set the SD Input Clock Tap Delays
552 *
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600553 * @host: Pointer to the sdhci_host structure.
554 * @degrees: The clock phase shift between 0 - 359.
Ashok Reddy Soma8e34aa02021-07-09 05:53:39 -0600555 * Return: 0
Michal Simekc0436fc2021-07-09 05:53:43 -0600556 *
557 * Set the SD Input Clock Tap Delays for Input path
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600558 */
559static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host,
560 int degrees)
561{
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600562 struct mmc *mmc = (struct mmc *)host->mmc;
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600563 struct udevice *dev = mmc->dev;
564 struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600565 u8 tap_delay, tap_max = 0;
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600566 int timing = mode2timing[mmc->selected_mode];
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600567 int ret;
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600568
569 /*
570 * This is applicable for SDHCI_SPEC_300 and above
571 * ZynqMP does not set phase for <=25MHz clock.
572 * If degrees is zero, no need to do anything.
573 */
Ashok Reddy Somaaffcba72021-07-09 05:53:40 -0600574 if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300)
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600575 return 0;
576
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600577 /* Assert DLL Reset */
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -0600578 ret = zynqmp_dll_reset(priv->node_id, PM_DLL_RESET_ASSERT);
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600579 if (ret) {
580 dev_err(dev, "dll_reset assert failed with err: %d\n", ret);
581 return ret;
582 }
583
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600584 switch (timing) {
585 case MMC_TIMING_MMC_HS:
586 case MMC_TIMING_SD_HS:
587 case MMC_TIMING_UHS_SDR25:
588 case MMC_TIMING_UHS_DDR50:
589 case MMC_TIMING_MMC_DDR52:
590 /* For 50MHz clock, 120 Taps are available */
591 tap_max = 120;
592 break;
593 case MMC_TIMING_UHS_SDR50:
594 /* For 100MHz clock, 60 Taps are available */
595 tap_max = 60;
596 break;
597 case MMC_TIMING_UHS_SDR104:
598 case MMC_TIMING_MMC_HS200:
599 /* For 200MHz clock, 30 Taps are available */
600 tap_max = 30;
601 default:
602 break;
603 }
604
605 tap_delay = (degrees * tap_max) / 360;
606
Ashok Reddy Somaa70bdaf2021-07-09 05:53:42 -0600607 /* Limit input tap_delay value to 8 bits */
608 tap_delay &= SDHCI_ARASAN_ITAPDLY_SEL_MASK;
609
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -0600610 ret = arasan_zynqmp_set_in_tapdelay(priv->node_id, tap_delay);
Ashok Reddy Somad0449822021-08-02 23:20:43 -0600611 if (ret) {
612 dev_err(dev, "Error setting Input Tap Delay\n");
613 return ret;
614 }
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600615
Ashok Reddy Soma8e34aa02021-07-09 05:53:39 -0600616 return 0;
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600617}
618
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600619/**
620 * sdhci_versal_sdcardclk_set_phase - Set the SD Output Clock Tap Delays
621 *
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600622 * @host: Pointer to the sdhci_host structure.
Michal Simekc0436fc2021-07-09 05:53:43 -0600623 * @degrees: The clock phase shift between 0 - 359.
Ashok Reddy Soma8e34aa02021-07-09 05:53:39 -0600624 * Return: 0
Michal Simekc0436fc2021-07-09 05:53:43 -0600625 *
626 * Set the SD Output Clock Tap Delays for Output path
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600627 */
628static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host,
629 int degrees)
630{
631 struct mmc *mmc = (struct mmc *)host->mmc;
632 u8 tap_delay, tap_max = 0;
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600633 int timing = mode2timing[mmc->selected_mode];
Ashok Reddy Somaee9ae002021-07-09 05:53:41 -0600634 u32 regval;
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600635
636 /*
637 * This is applicable for SDHCI_SPEC_300 and above
638 * Versal does not set phase for <=25MHz clock.
639 * If degrees is zero, no need to do anything.
640 */
Ashok Reddy Somaaffcba72021-07-09 05:53:40 -0600641 if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300)
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600642 return 0;
643
644 switch (timing) {
645 case MMC_TIMING_MMC_HS:
646 case MMC_TIMING_SD_HS:
647 case MMC_TIMING_UHS_SDR25:
648 case MMC_TIMING_UHS_DDR50:
649 case MMC_TIMING_MMC_DDR52:
650 /* For 50MHz clock, 30 Taps are available */
651 tap_max = 30;
652 break;
653 case MMC_TIMING_UHS_SDR50:
654 /* For 100MHz clock, 15 Taps are available */
655 tap_max = 15;
656 break;
657 case MMC_TIMING_UHS_SDR104:
658 case MMC_TIMING_MMC_HS200:
659 /* For 200MHz clock, 8 Taps are available */
660 tap_max = 8;
661 default:
662 break;
663 }
664
665 tap_delay = (degrees * tap_max) / 360;
666
Ashok Reddy Somaee9ae002021-07-09 05:53:41 -0600667 /* Limit output tap_delay value to 6 bits */
668 tap_delay &= SDHCI_ARASAN_OTAPDLY_SEL_MASK;
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600669
Ashok Reddy Somaee9ae002021-07-09 05:53:41 -0600670 /* Set the Clock Phase */
671 regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER);
672 regval |= SDHCI_OTAPDLY_ENABLE;
673 sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER);
674 regval &= ~SDHCI_ARASAN_OTAPDLY_SEL_MASK;
675 regval |= tap_delay;
676 sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER);
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600677
Ashok Reddy Soma8e34aa02021-07-09 05:53:39 -0600678 return 0;
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600679}
680
681/**
682 * sdhci_versal_sampleclk_set_phase - Set the SD Input Clock Tap Delays
683 *
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600684 * @host: Pointer to the sdhci_host structure.
Michal Simekc0436fc2021-07-09 05:53:43 -0600685 * @degrees: The clock phase shift between 0 - 359.
Ashok Reddy Soma8e34aa02021-07-09 05:53:39 -0600686 * Return: 0
Michal Simekc0436fc2021-07-09 05:53:43 -0600687 *
688 * Set the SD Input Clock Tap Delays for Input path
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600689 */
690static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host,
691 int degrees)
692{
693 struct mmc *mmc = (struct mmc *)host->mmc;
694 u8 tap_delay, tap_max = 0;
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600695 int timing = mode2timing[mmc->selected_mode];
Ashok Reddy Somaee9ae002021-07-09 05:53:41 -0600696 u32 regval;
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600697
698 /*
699 * This is applicable for SDHCI_SPEC_300 and above
700 * Versal does not set phase for <=25MHz clock.
701 * If degrees is zero, no need to do anything.
702 */
Ashok Reddy Somaaffcba72021-07-09 05:53:40 -0600703 if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300)
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600704 return 0;
705
706 switch (timing) {
707 case MMC_TIMING_MMC_HS:
708 case MMC_TIMING_SD_HS:
709 case MMC_TIMING_UHS_SDR25:
710 case MMC_TIMING_UHS_DDR50:
711 case MMC_TIMING_MMC_DDR52:
712 /* For 50MHz clock, 120 Taps are available */
713 tap_max = 120;
714 break;
715 case MMC_TIMING_UHS_SDR50:
716 /* For 100MHz clock, 60 Taps are available */
717 tap_max = 60;
718 break;
719 case MMC_TIMING_UHS_SDR104:
720 case MMC_TIMING_MMC_HS200:
721 /* For 200MHz clock, 30 Taps are available */
722 tap_max = 30;
723 default:
724 break;
725 }
726
727 tap_delay = (degrees * tap_max) / 360;
728
Ashok Reddy Somaee9ae002021-07-09 05:53:41 -0600729 /* Limit input tap_delay value to 8 bits */
730 tap_delay &= SDHCI_ARASAN_ITAPDLY_SEL_MASK;
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600731
Ashok Reddy Somaee9ae002021-07-09 05:53:41 -0600732 /* Set the Clock Phase */
733 regval = sdhci_readl(host, SDHCI_ARASAN_ITAPDLY_REGISTER);
734 regval |= SDHCI_ITAPDLY_CHGWIN;
735 sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
736 regval |= SDHCI_ITAPDLY_ENABLE;
737 sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
738 regval &= ~SDHCI_ARASAN_ITAPDLY_SEL_MASK;
739 regval |= tap_delay;
740 sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
741 regval &= ~SDHCI_ITAPDLY_CHGWIN;
742 sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600743
Ashok Reddy Soma8e34aa02021-07-09 05:53:39 -0600744 return 0;
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600745}
746
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -0700747/**
748 * sdhci_versal_net_emmc_sdcardclk_set_phase - Set eMMC Output Clock Tap Delays
749 *
750 * @host: Pointer to the sdhci_host structure.
751 * @degrees: The clock phase shift between 0 - 359.
752 * Return: 0
753 *
754 * Set eMMC Output Clock Tap Delays for Output path
755 */
756static int sdhci_versal_net_emmc_sdcardclk_set_phase(struct sdhci_host *host, int degrees)
757{
758 struct mmc *mmc = (struct mmc *)host->mmc;
759 int timing = mode2timing[mmc->selected_mode];
760 u8 tap_delay, tap_max = 0;
761 u32 regval;
762
763 switch (timing) {
764 case MMC_TIMING_MMC_HS:
765 case MMC_TIMING_MMC_DDR52:
766 tap_max = 16;
767 break;
768 case MMC_TIMING_MMC_HS200:
769 case MMC_TIMING_MMC_HS400:
770 /* For 200MHz clock, 32 Taps are available */
771 tap_max = 32;
772 break;
773 default:
774 break;
775 }
776
777 tap_delay = (degrees * tap_max) / 360;
778 /* Set the Clock Phase */
779 if (tap_delay) {
780 regval = sdhci_readl(host, PHY_CTRL_REG1);
781 regval |= PHY_CTRL_OTAPDLY_ENA_MASK;
782 sdhci_writel(host, regval, PHY_CTRL_REG1);
783 regval &= ~PHY_CTRL_OTAPDLY_SEL_MASK;
784 regval |= tap_delay << PHY_CTRL_OTAPDLY_SEL_SHIFT;
785 sdhci_writel(host, regval, PHY_CTRL_REG1);
786 }
787
788 return 0;
789}
790
791/**
792 * sdhci_versal_net_emmc_sampleclk_set_phase - Set eMMC Input Clock Tap Delays
793 *
794 * @host: Pointer to the sdhci_host structure.
795 * @degrees: The clock phase shift between 0 - 359.
796 * Return: 0
797 *
798 * Set eMMC Input Clock Tap Delays for Input path. If HS400 is selected,
799 * set strobe90 and strobe180 in PHY_CTRL_REG1.
800 */
801static int sdhci_versal_net_emmc_sampleclk_set_phase(struct sdhci_host *host, int degrees)
802{
803 struct mmc *mmc = (struct mmc *)host->mmc;
804 int timing = mode2timing[mmc->selected_mode];
805 u8 tap_delay, tap_max = 0;
806 u32 regval;
807
808 switch (timing) {
809 case MMC_TIMING_MMC_HS:
810 case MMC_TIMING_MMC_DDR52:
811 tap_max = 32;
812 break;
813 case MMC_TIMING_MMC_HS400:
814 /* Strobe select tap point for strb90 and strb180 */
815 regval = sdhci_readl(host, PHY_CTRL_REG1);
816 regval &= ~PHY_CTRL_STRB_SEL_MASK;
817 regval |= VERSAL_NET_PHY_CTRL_STRB90_STRB180_VAL << PHY_CTRL_STRB_SEL_SHIFT;
818 sdhci_writel(host, regval, PHY_CTRL_REG1);
819 break;
820 default:
821 break;
822 }
823
824 tap_delay = (degrees * tap_max) / 360;
825 /* Set the Clock Phase */
826 if (tap_delay) {
827 regval = sdhci_readl(host, PHY_CTRL_REG1);
828 regval |= PHY_CTRL_ITAP_CHG_WIN_MASK;
829 sdhci_writel(host, regval, PHY_CTRL_REG1);
830 regval |= PHY_CTRL_ITAPDLY_ENA_MASK;
831 sdhci_writel(host, regval, PHY_CTRL_REG1);
832 regval &= ~PHY_CTRL_ITAPDLY_SEL_MASK;
833 regval |= tap_delay << PHY_CTRL_ITAPDLY_SEL_SHIFT;
834 sdhci_writel(host, regval, PHY_CTRL_REG1);
835 regval &= ~PHY_CTRL_ITAP_CHG_WIN_MASK;
836 sdhci_writel(host, regval, PHY_CTRL_REG1);
837 }
838
839 return 0;
840}
841
Ashok Reddy Soma5ab5d9a2021-08-02 23:20:40 -0600842static int arasan_sdhci_set_tapdelay(struct sdhci_host *host)
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600843{
844 struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
845 struct arasan_sdhci_clk_data *clk_data = &priv->clk_data;
846 struct mmc *mmc = (struct mmc *)host->mmc;
847 struct udevice *dev = mmc->dev;
848 u8 timing = mode2timing[mmc->selected_mode];
849 u32 iclk_phase = clk_data->clk_phase_in[timing];
850 u32 oclk_phase = clk_data->clk_phase_out[timing];
Ashok Reddy Soma5ab5d9a2021-08-02 23:20:40 -0600851 int ret;
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600852
853 dev_dbg(dev, "%s, host:%s, mode:%d\n", __func__, host->name, timing);
854
855 if (IS_ENABLED(CONFIG_ARCH_ZYNQMP) &&
856 device_is_compatible(dev, "xlnx,zynqmp-8.9a")) {
Ashok Reddy Soma5ab5d9a2021-08-02 23:20:40 -0600857 ret = sdhci_zynqmp_sampleclk_set_phase(host, iclk_phase);
858 if (ret)
859 return ret;
860
861 ret = sdhci_zynqmp_sdcardclk_set_phase(host, oclk_phase);
862 if (ret)
863 return ret;
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600864 } else if (IS_ENABLED(CONFIG_ARCH_VERSAL) &&
865 device_is_compatible(dev, "xlnx,versal-8.9a")) {
Ashok Reddy Soma5ab5d9a2021-08-02 23:20:40 -0600866 ret = sdhci_versal_sampleclk_set_phase(host, iclk_phase);
867 if (ret)
868 return ret;
869
870 ret = sdhci_versal_sdcardclk_set_phase(host, oclk_phase);
871 if (ret)
872 return ret;
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -0700873 } else if (IS_ENABLED(CONFIG_ARCH_VERSAL_NET) &&
874 device_is_compatible(dev, "xlnx,versal-net-5.1-emmc")) {
875 if (mmc->clock >= MIN_PHY_CLK_HZ)
876 if (iclk_phase == VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLY_CHAIN)
877 iclk_phase = VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLL;
878
879 ret = sdhci_versal_net_emmc_sampleclk_set_phase(host, iclk_phase);
880 if (ret)
881 return ret;
882
883 ret = sdhci_versal_net_emmc_sdcardclk_set_phase(host, oclk_phase);
884 if (ret)
885 return ret;
Ashok Reddy Somaf4b297b2020-10-23 04:59:01 -0600886 }
Ashok Reddy Soma5ab5d9a2021-08-02 23:20:40 -0600887
888 return 0;
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530889}
890
Michal Simek80355ae2020-10-23 04:59:00 -0600891static void arasan_dt_read_clk_phase(struct udevice *dev, unsigned char timing,
892 const char *prop)
893{
894 struct arasan_sdhci_priv *priv = dev_get_priv(dev);
895 struct arasan_sdhci_clk_data *clk_data = &priv->clk_data;
896 u32 clk_phase[2] = {0};
897
898 /*
899 * Read Tap Delay values from DT, if the DT does not contain the
900 * Tap Values then use the pre-defined values
901 */
902 if (dev_read_u32_array(dev, prop, &clk_phase[0], 2)) {
903 dev_dbg(dev, "Using predefined clock phase for %s = %d %d\n",
904 prop, clk_data->clk_phase_in[timing],
905 clk_data->clk_phase_out[timing]);
906 return;
907 }
908
909 /* The values read are Input and Output Clock Delays in order */
910 clk_data->clk_phase_in[timing] = clk_phase[0];
911 clk_data->clk_phase_out[timing] = clk_phase[1];
912}
913
914/**
915 * arasan_dt_parse_clk_phases - Read Tap Delay values from DT
916 *
Michal Simek80355ae2020-10-23 04:59:00 -0600917 * @dev: Pointer to our struct udevice.
Michal Simekc0436fc2021-07-09 05:53:43 -0600918 *
919 * Called at initialization to parse the values of Tap Delays.
Michal Simek80355ae2020-10-23 04:59:00 -0600920 */
921static void arasan_dt_parse_clk_phases(struct udevice *dev)
922{
923 struct arasan_sdhci_priv *priv = dev_get_priv(dev);
924 struct arasan_sdhci_clk_data *clk_data = &priv->clk_data;
925 int i;
926
927 if (IS_ENABLED(CONFIG_ARCH_ZYNQMP) &&
928 device_is_compatible(dev, "xlnx,zynqmp-8.9a")) {
929 for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) {
930 clk_data->clk_phase_in[i] = zynqmp_iclk_phases[i];
931 clk_data->clk_phase_out[i] = zynqmp_oclk_phases[i];
932 }
933
934 if (priv->bank == MMC_BANK2) {
935 clk_data->clk_phase_out[MMC_TIMING_UHS_SDR104] = 90;
936 clk_data->clk_phase_out[MMC_TIMING_MMC_HS200] = 90;
937 }
938 }
939
Ashok Reddy Soma2e819a72020-10-23 04:59:02 -0600940 if (IS_ENABLED(CONFIG_ARCH_VERSAL) &&
941 device_is_compatible(dev, "xlnx,versal-8.9a")) {
942 for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) {
943 clk_data->clk_phase_in[i] = versal_iclk_phases[i];
944 clk_data->clk_phase_out[i] = versal_oclk_phases[i];
945 }
946 }
947
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -0700948 if (IS_ENABLED(CONFIG_ARCH_VERSAL_NET) &&
949 device_is_compatible(dev, "xlnx,versal-net-5.1-emmc")) {
950 for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) {
951 clk_data->clk_phase_in[i] = versal_net_emmc_iclk_phases[i];
952 clk_data->clk_phase_out[i] = versal_net_emmc_oclk_phases[i];
953 }
954 }
955
Michal Simek80355ae2020-10-23 04:59:00 -0600956 arasan_dt_read_clk_phase(dev, MMC_TIMING_LEGACY,
957 "clk-phase-legacy");
958 arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS,
959 "clk-phase-mmc-hs");
960 arasan_dt_read_clk_phase(dev, MMC_TIMING_SD_HS,
961 "clk-phase-sd-hs");
962 arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR12,
963 "clk-phase-uhs-sdr12");
964 arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR25,
965 "clk-phase-uhs-sdr25");
966 arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR50,
967 "clk-phase-uhs-sdr50");
968 arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR104,
969 "clk-phase-uhs-sdr104");
970 arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_DDR50,
971 "clk-phase-uhs-ddr50");
972 arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_DDR52,
973 "clk-phase-mmc-ddr52");
974 arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS200,
975 "clk-phase-mmc-hs200");
976 arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS400,
977 "clk-phase-mmc-hs400");
978}
979
Michal Simek419b4a82021-07-09 05:53:44 -0600980static const struct sdhci_ops arasan_ops = {
981 .platform_execute_tuning = &arasan_sdhci_execute_tuning,
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530982 .set_delay = &arasan_sdhci_set_tapdelay,
Ashok Reddy Soma3ae330c2021-08-02 23:20:46 -0600983 .set_control_reg = &sdhci_set_control_reg,
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -0700984#if defined(CONFIG_ARCH_VERSAL_NET)
985 .config_dll = &arasan_sdhci_config_dll,
986#endif
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +0530987};
988#endif
989
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +0100990#if defined(CONFIG_ARCH_ZYNQMP)
991static int sdhci_zynqmp_set_dynamic_config(struct arasan_sdhci_priv *priv,
992 struct udevice *dev)
Michal Simek293eb332013-04-22 14:56:49 +0200993{
Simon Glass329a4492016-07-05 17:10:15 -0600994 int ret;
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +0100995 struct clk clk;
996 unsigned long clock, mhz;
Michal Simek293eb332013-04-22 14:56:49 +0200997
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -0600998 ret = xilinx_pm_request(PM_REQUEST_NODE, priv->node_id,
999 ZYNQMP_PM_CAPABILITY_ACCESS, ZYNQMP_PM_MAX_QOS,
1000 ZYNQMP_PM_REQUEST_ACK_NO, NULL);
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +01001001 if (ret) {
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -06001002 dev_err(dev, "Request node failed for %d\n", priv->node_id);
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +01001003 return ret;
1004 }
1005
1006 ret = reset_get_bulk(dev, &priv->resets);
1007 if (ret == -ENOTSUPP || ret == -ENOENT) {
1008 dev_err(dev, "Reset not found\n");
1009 return 0;
1010 } else if (ret) {
1011 dev_err(dev, "Reset failed\n");
1012 return ret;
1013 }
1014
1015 ret = reset_assert_bulk(&priv->resets);
1016 if (ret) {
1017 dev_err(dev, "Reset assert failed\n");
1018 return ret;
1019 }
1020
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -06001021 ret = zynqmp_pm_set_sd_config(priv->node_id, SD_CONFIG_FIXED, 0);
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +01001022 if (ret) {
1023 dev_err(dev, "SD_CONFIG_FIXED failed\n");
1024 return ret;
1025 }
1026
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -06001027 ret = zynqmp_pm_set_sd_config(priv->node_id, SD_CONFIG_EMMC_SEL,
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +01001028 dev_read_bool(dev, "non-removable"));
1029 if (ret) {
1030 dev_err(dev, "SD_CONFIG_EMMC_SEL failed\n");
1031 return ret;
1032 }
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +05301033
Stefan Herbrechtsmeiere0f4de12017-01-17 16:27:32 +01001034 ret = clk_get_by_index(dev, 0, &clk);
1035 if (ret < 0) {
1036 dev_err(dev, "failed to get clock\n");
1037 return ret;
1038 }
1039
1040 clock = clk_get_rate(&clk);
1041 if (IS_ERR_VALUE(clock)) {
1042 dev_err(dev, "failed to get rate\n");
1043 return clock;
1044 }
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +05301045
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +01001046 mhz = DIV64_U64_ROUND_UP(clock, 1000000);
1047
Ashok Reddy Soma035d56f2022-03-25 13:11:10 +01001048 if (mhz > 100 && mhz <= 200)
1049 mhz = 200;
1050 else if (mhz > 50 && mhz <= 100)
1051 mhz = 100;
1052 else if (mhz > 25 && mhz <= 50)
1053 mhz = 50;
1054 else
1055 mhz = 25;
1056
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -06001057 ret = zynqmp_pm_set_sd_config(priv->node_id, SD_CONFIG_BASECLK, mhz);
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +01001058 if (ret) {
1059 dev_err(dev, "SD_CONFIG_BASECLK failed\n");
1060 return ret;
1061 }
1062
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -06001063 ret = zynqmp_pm_set_sd_config(priv->node_id, SD_CONFIG_8BIT,
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +01001064 (dev_read_u32_default(dev, "bus-width", 1) == 8));
1065 if (ret) {
1066 dev_err(dev, "SD_CONFIG_8BIT failed\n");
1067 return ret;
1068 }
1069
1070 ret = reset_deassert_bulk(&priv->resets);
1071 if (ret) {
1072 dev_err(dev, "Reset release failed\n");
1073 return ret;
1074 }
1075
1076 return 0;
1077}
1078#endif
1079
1080static int arasan_sdhci_probe(struct udevice *dev)
1081{
1082 struct arasan_sdhci_plat *plat = dev_get_plat(dev);
1083 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
1084 struct arasan_sdhci_priv *priv = dev_get_priv(dev);
1085 struct sdhci_host *host;
1086 struct clk clk;
1087 unsigned long clock;
1088 int ret;
1089
1090 host = priv->host;
1091
1092#if defined(CONFIG_ARCH_ZYNQMP)
1093 if (device_is_compatible(dev, "xlnx,zynqmp-8.9a")) {
1094 ret = zynqmp_pm_is_function_supported(PM_IOCTL,
1095 IOCTL_SET_SD_CONFIG);
1096 if (!ret) {
1097 ret = sdhci_zynqmp_set_dynamic_config(priv, dev);
1098 if (ret)
1099 return ret;
1100 }
1101 }
1102#endif
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -07001103 if (device_is_compatible(dev, "xlnx,versal-net-5.1-emmc"))
1104 priv->internal_phy_reg = true;
Ashok Reddy Soma90ab7fa2022-02-23 15:36:05 +01001105
1106 ret = clk_get_by_index(dev, 0, &clk);
1107 if (ret < 0) {
1108 dev_err(dev, "failed to get clock\n");
1109 return ret;
1110 }
1111
1112 clock = clk_get_rate(&clk);
1113 if (IS_ERR_VALUE(clock)) {
1114 dev_err(dev, "failed to get rate\n");
1115 return clock;
1116 }
1117
1118 dev_dbg(dev, "%s: CLK %ld\n", __func__, clock);
Stefan Herbrechtsmeiere0f4de12017-01-17 16:27:32 +01001119
1120 ret = clk_enable(&clk);
Michal Simek9b7aac72021-02-09 15:28:15 +01001121 if (ret) {
Stefan Herbrechtsmeiere0f4de12017-01-17 16:27:32 +01001122 dev_err(dev, "failed to enable clock\n");
1123 return ret;
1124 }
1125
Siva Durga Prasad Paladugueddabd12014-07-08 15:31:04 +05301126 host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
Siva Durga Prasad Paladuguf9ec45d2014-01-22 09:17:09 +01001127 SDHCI_QUIRK_BROKEN_R1B;
Siva Durga Prasad Paladugub2156142016-01-12 15:12:16 +05301128
1129#ifdef CONFIG_ZYNQ_HISPD_BROKEN
Hannes Schmelzer47819212018-03-07 08:00:57 +01001130 host->quirks |= SDHCI_QUIRK_BROKEN_HISPD_MODE;
Siva Durga Prasad Paladugub2156142016-01-12 15:12:16 +05301131#endif
1132
Ashok Reddy Soma7a49a162020-10-23 04:58:57 -06001133 if (priv->no_1p8)
1134 host->quirks |= SDHCI_QUIRK_NO_1_8_V;
1135
Benedikt Grassl942b5fc2020-04-14 07:32:12 +02001136 plat->cfg.f_max = CONFIG_ZYNQ_SDHCI_MAX_FREQ;
1137
1138 ret = mmc_of_parse(dev, &plat->cfg);
1139 if (ret)
1140 return ret;
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +05301141
Stefan Herbrechtsmeiere0f4de12017-01-17 16:27:32 +01001142 host->max_clk = clock;
Stefan Herbrechtsmeier6d0e34b2017-01-17 15:58:48 +01001143
Matwey V. Kornilov3148a3c2019-08-01 18:00:05 +03001144 host->mmc = &plat->mmc;
1145 host->mmc->dev = dev;
1146 host->mmc->priv = host;
1147
Benedikt Grassl942b5fc2020-04-14 07:32:12 +02001148 ret = sdhci_setup_cfg(&plat->cfg, host, plat->cfg.f_max,
Jaehoon Chung14bed522016-07-26 19:06:24 +09001149 CONFIG_ZYNQ_SDHCI_MIN_FREQ);
Simon Glass329a4492016-07-05 17:10:15 -06001150 if (ret)
1151 return ret;
Simon Glass329a4492016-07-05 17:10:15 -06001152 upriv->mmc = host->mmc;
Michal Simekd9ae52c2015-11-30 16:13:03 +01001153
T Karthik Reddyb6f44082021-08-02 23:20:45 -06001154 /*
1155 * WORKAROUND: Versal platforms have an issue with card detect state.
1156 * Due to this, host controller is switching off voltage to sd card
1157 * causing sd card timeout error. Workaround this by adding a wait for
1158 * 1000msec till the card detect state gets stable.
1159 */
Ashok Reddy Soma980e5552022-02-23 15:13:32 +01001160 if (IS_ENABLED(CONFIG_ARCH_ZYNQMP) || IS_ENABLED(CONFIG_ARCH_VERSAL)) {
Ashok Reddy Soma8d32bca2022-02-23 15:13:31 +01001161 u32 timeout = 1000000;
T Karthik Reddyb6f44082021-08-02 23:20:45 -06001162
1163 while (((sdhci_readl(host, SDHCI_PRESENT_STATE) &
Ashok Reddy Somac252b272022-02-23 15:13:30 +01001164 SDHCI_CARD_STATE_STABLE) == 0) && timeout) {
Ashok Reddy Soma8d32bca2022-02-23 15:13:31 +01001165 udelay(1);
Ashok Reddy Somac252b272022-02-23 15:13:30 +01001166 timeout--;
T Karthik Reddyb6f44082021-08-02 23:20:45 -06001167 }
1168 if (!timeout) {
1169 dev_err(dev, "Sdhci card detect state not stable\n");
1170 return -ETIMEDOUT;
1171 }
1172 }
1173
Simon Glass329a4492016-07-05 17:10:15 -06001174 return sdhci_probe(dev);
Michal Simek293eb332013-04-22 14:56:49 +02001175}
Michal Simekd9ae52c2015-11-30 16:13:03 +01001176
Simon Glassd1998a92020-12-03 16:55:21 -07001177static int arasan_sdhci_of_to_plat(struct udevice *dev)
Michal Simekd9ae52c2015-11-30 16:13:03 +01001178{
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +05301179 struct arasan_sdhci_priv *priv = dev_get_priv(dev);
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -06001180 u32 pm_info[2];
Michal Simekd9ae52c2015-11-30 16:13:03 +01001181
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +05301182 priv->host = calloc(1, sizeof(struct sdhci_host));
1183 if (!priv->host)
1184 return -1;
1185
1186 priv->host->name = dev->name;
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +05301187
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -07001188#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL_NET)
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +05301189 priv->host->ops = &arasan_ops;
Michal Simek80355ae2020-10-23 04:59:00 -06001190 arasan_dt_parse_clk_phases(dev);
Siva Durga Prasad Paladugud1f4e392018-04-19 12:37:09 +05301191#endif
Michal Simekd9ae52c2015-11-30 16:13:03 +01001192
Michal Simek458e8d82018-05-16 10:57:07 +02001193 priv->host->ioaddr = (void *)dev_read_addr(dev);
1194 if (IS_ERR(priv->host->ioaddr))
1195 return PTR_ERR(priv->host->ioaddr);
Stefan Herbrechtsmeier61e745d2017-01-17 16:27:33 +01001196
Michal Simeke8deb222020-07-22 17:46:31 +02001197 priv->bank = dev_read_u32_default(dev, "xlnx,mio-bank", 0);
Ashok Reddy Soma7a49a162020-10-23 04:58:57 -06001198 priv->no_1p8 = dev_read_bool(dev, "no-1-8-v");
Michal Simek458e8d82018-05-16 10:57:07 +02001199
Ashok Reddy Somaaba0e652022-09-30 03:25:47 -06001200 priv->node_id = 0;
1201 if (!dev_read_u32_array(dev, "power-domains", pm_info, ARRAY_SIZE(pm_info)))
1202 priv->node_id = pm_info[1];
1203
Michal Simekd9ae52c2015-11-30 16:13:03 +01001204 return 0;
1205}
1206
Simon Glass329a4492016-07-05 17:10:15 -06001207static int arasan_sdhci_bind(struct udevice *dev)
1208{
Simon Glassc69cda22020-12-03 16:55:20 -07001209 struct arasan_sdhci_plat *plat = dev_get_plat(dev);
Simon Glass329a4492016-07-05 17:10:15 -06001210
Masahiro Yamada24f5aec2016-09-06 22:17:32 +09001211 return sdhci_bind(dev, &plat->mmc, &plat->cfg);
Simon Glass329a4492016-07-05 17:10:15 -06001212}
1213
Michal Simekd9ae52c2015-11-30 16:13:03 +01001214static const struct udevice_id arasan_sdhci_ids[] = {
1215 { .compatible = "arasan,sdhci-8.9a" },
Ashok Reddy Soma14ef4c72023-01-10 04:31:21 -07001216 { .compatible = "xlnx,versal-net-5.1-emmc" },
Michal Simekd9ae52c2015-11-30 16:13:03 +01001217 { }
1218};
1219
1220U_BOOT_DRIVER(arasan_sdhci_drv) = {
1221 .name = "arasan_sdhci",
1222 .id = UCLASS_MMC,
1223 .of_match = arasan_sdhci_ids,
Simon Glassd1998a92020-12-03 16:55:21 -07001224 .of_to_plat = arasan_sdhci_of_to_plat,
Simon Glass329a4492016-07-05 17:10:15 -06001225 .ops = &sdhci_ops,
1226 .bind = arasan_sdhci_bind,
Michal Simekd9ae52c2015-11-30 16:13:03 +01001227 .probe = arasan_sdhci_probe,
Simon Glass41575d82020-12-03 16:55:17 -07001228 .priv_auto = sizeof(struct arasan_sdhci_priv),
Simon Glasscaa4daa2020-12-03 16:55:18 -07001229 .plat_auto = sizeof(struct arasan_sdhci_plat),
Michal Simekd9ae52c2015-11-30 16:13:03 +01001230};