blob: d2cd4d6a54b0efe951987e479c9825d1bd2d709d [file] [log] [blame]
Jit Loon Lima7f54942023-05-17 12:26:11 +08001/*
2 * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <errno.h>
9#include <stdbool.h>
10#include <stddef.h>
11#include <string.h>
12
13#include <arch_helpers.h>
14#include <common/debug.h>
15#include <drivers/cadence/cdns_sdmmc.h>
16#include <drivers/delay_timer.h>
17#include <drivers/mmc.h>
18#include <lib/mmio.h>
19#include <lib/utils.h>
20
21/* Card busy and present */
22#define CARD_BUSY 1
23#define CARD_NOT_BUSY 0
24
25/* 500 ms delay to read the RINST register */
26#define DELAY_MS_SRS_READ 500
27#define DELAY_RES 10
28
29/* SRS12 error mask */
30#define SRS12_ERR_MASK 0xFFFF8000
31
32/* Check DV dfi_init val=0 */
33#define IO_MASK_END_DATA 0x0
34
35/* Check DV dfi_init val=2; DDR Mode */
36#define IO_MASK_END_DATA_DDR 0x2
37#define IO_MASK_START_DATA 0x0
38#define DATA_SELECT_OE_END_DATA 0x1
39
40#define TIMEOUT 100000
41
42/* General define */
43#define SDHC_REG_MASK UINT_MAX
44#define SD_HOST_BLOCK_SIZE 0x200
45#define DTCVVAL_DEFAULT_VAL 0xE
46#define CDMMC_DMA_MAX_BUFFER_SIZE 64*1024
47#define CDNSMMC_ADDRESS_MASK U(0x0f)
48#define CONFIG_CDNS_DESC_COUNT 8
49
50void cdns_init(void);
51int cdns_send_cmd(struct mmc_cmd *cmd);
52int cdns_set_ios(unsigned int clk, unsigned int width);
53int cdns_prepare(int lba, uintptr_t buf, size_t size);
54int cdns_read(int lba, uintptr_t buf, size_t size);
55int cdns_write(int lba, uintptr_t buf, size_t size);
56
57const struct mmc_ops cdns_sdmmc_ops = {
58 .init = cdns_init,
59 .send_cmd = cdns_send_cmd,
60 .set_ios = cdns_set_ios,
61 .prepare = cdns_prepare,
62 .read = cdns_read,
63 .write = cdns_write,
64};
65
66struct cdns_sdmmc_params cdns_params;
67struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg;
68struct cdns_sdmmc_sdhc sdmmc_sdhc_reg;
69#ifdef CONFIG_DMA_ADDR_T_64BIT
70struct cdns_idmac_desc cdns_desc[CONFIG_CDNS_DESC_COUNT];
71#else
72struct cdns_idmac_desc cdns_desc[CONFIG_CDNS_DESC_COUNT] __aligned(32);
73#endif
74
75bool data_cmd;
76
77int cdns_wait_ics(uint16_t timeout, uint32_t cdn_srs_res)
78{
79 /* Clock for sdmclk and sdclk */
80 uint32_t count = 0;
81 uint32_t data = 0;
82
83 /* Wait status command response ready */
84 do {
85 data = mmio_read_32(cdn_srs_res);
86 count++;
87 if (count >= timeout) {
88 return -ETIMEDOUT;
89 }
90 } while ((data & (1 << SDMMC_CDN_ICS)) == 0);
91
92 return 0;
93}
94
95int cdns_busy(void)
96{
97 unsigned int data;
98
99 data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS09);
100 return (data & STATUS_DATA_BUSY) ? CARD_BUSY : CARD_NOT_BUSY;
101}
102
103int cdns_vol_reset(void)
104{
105 /* Reset embedded card */
106 mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
107 udelay(250);
108 mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (0 << SDMMC_CDN_BP));
109 udelay(500);
110
111 /* Turn on supply voltage */
112 /* BVS = 7, BP = 1, BP2 only in UHS2 mode */
113 mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
114 udelay(250);
115 return 0;
116}
117
118void cdns_set_sdmmc_var(struct cdns_sdmmc_combo_phy *combo_phy_reg,
119 struct cdns_sdmmc_sdhc *sdhc_reg)
120{
121 /* Values are taken by the reference of cadence IP documents */
122 combo_phy_reg->cp_clk_wr_delay = 0;
123 combo_phy_reg->cp_clk_wrdqs_delay = 0;
124 combo_phy_reg->cp_data_select_oe_end = 0;
125 combo_phy_reg->cp_dll_bypass_mode = 1;
126 combo_phy_reg->cp_dll_locked_mode = 0;
127 combo_phy_reg->cp_dll_start_point = 0;
128 combo_phy_reg->cp_gate_cfg_always_on = 1;
129 combo_phy_reg->cp_io_mask_always_on = 0;
130 combo_phy_reg->cp_io_mask_end = 0;
131 combo_phy_reg->cp_io_mask_start = 0;
132 combo_phy_reg->cp_rd_del_sel = 52;
133 combo_phy_reg->cp_read_dqs_cmd_delay = 0;
134 combo_phy_reg->cp_read_dqs_delay = 0;
135 combo_phy_reg->cp_sw_half_cycle_shift = 0;
136 combo_phy_reg->cp_sync_method = 1;
137 combo_phy_reg->cp_underrun_suppress = 1;
138 combo_phy_reg->cp_use_ext_lpbk_dqs = 1;
139 combo_phy_reg->cp_use_lpbk_dqs = 1;
140 combo_phy_reg->cp_use_phony_dqs = 1;
141 combo_phy_reg->cp_use_phony_dqs_cmd = 1;
142
143 sdhc_reg->sdhc_extended_rd_mode = 1;
144 sdhc_reg->sdhc_extended_wr_mode = 1;
145 sdhc_reg->sdhc_hcsdclkadj = 0;
146 sdhc_reg->sdhc_idelay_val = 0;
147 sdhc_reg->sdhc_rdcmd_en = 1;
148 sdhc_reg->sdhc_rddata_en = 1;
149 sdhc_reg->sdhc_rw_compensate = 9;
150 sdhc_reg->sdhc_sdcfsh = 0;
151 sdhc_reg->sdhc_sdcfsl = 1;
152 sdhc_reg->sdhc_wrcmd0_dly = 1;
153 sdhc_reg->sdhc_wrcmd0_sdclk_dly = 0;
154 sdhc_reg->sdhc_wrcmd1_dly = 0;
155 sdhc_reg->sdhc_wrcmd1_sdclk_dly = 0;
156 sdhc_reg->sdhc_wrdata0_dly = 1;
157 sdhc_reg->sdhc_wrdata0_sdclk_dly = 0;
158 sdhc_reg->sdhc_wrdata1_dly = 0;
159 sdhc_reg->sdhc_wrdata1_sdclk_dly = 0;
160}
161
162static int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg,
163 struct cdns_sdmmc_sdhc *sdhc_reg)
164{
165 uint32_t value = 0;
166 int ret = 0;
167
168 /* program PHY_DQS_TIMING_REG */
169 value = (CP_USE_EXT_LPBK_DQS(combo_phy_reg->cp_use_ext_lpbk_dqs)) |
170 (CP_USE_LPBK_DQS(combo_phy_reg->cp_use_lpbk_dqs)) |
171 (CP_USE_PHONY_DQS(combo_phy_reg->cp_use_phony_dqs)) |
172 (CP_USE_PHONY_DQS_CMD(combo_phy_reg->cp_use_phony_dqs_cmd));
173 ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
174 COMBO_PHY_REG + PHY_DQS_TIMING_REG, MMC_REG_BASE +
175 SDHC_CDNS_HRS05, value);
176 if (ret != 0) {
177 return ret;
178 }
179
180 /* program PHY_GATE_LPBK_CTRL_REG */
181 value = (CP_SYNC_METHOD(combo_phy_reg->cp_sync_method)) |
182 (CP_SW_HALF_CYCLE_SHIFT(combo_phy_reg->cp_sw_half_cycle_shift)) |
183 (CP_RD_DEL_SEL(combo_phy_reg->cp_rd_del_sel)) |
184 (CP_UNDERRUN_SUPPRESS(combo_phy_reg->cp_underrun_suppress)) |
185 (CP_GATE_CFG_ALWAYS_ON(combo_phy_reg->cp_gate_cfg_always_on));
186 ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
187 COMBO_PHY_REG + PHY_GATE_LPBK_CTRL_REG, MMC_REG_BASE +
188 SDHC_CDNS_HRS05, value);
189 if (ret != 0) {
190 return ret;
191 }
192
193 /* program PHY_DLL_MASTER_CTRL_REG */
194 value = (CP_DLL_BYPASS_MODE(combo_phy_reg->cp_dll_bypass_mode))
195 | (CP_DLL_START_POINT(combo_phy_reg->cp_dll_start_point));
196 ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
197 COMBO_PHY_REG + PHY_DLL_MASTER_CTRL_REG, MMC_REG_BASE
198 + SDHC_CDNS_HRS05, value);
199 if (ret != 0) {
200 return ret;
201 }
202
203 /* program PHY_DLL_SLAVE_CTRL_REG */
204 value = (CP_READ_DQS_CMD_DELAY(combo_phy_reg->cp_read_dqs_cmd_delay))
205 | (CP_CLK_WRDQS_DELAY(combo_phy_reg->cp_clk_wrdqs_delay))
206 | (CP_CLK_WR_DELAY(combo_phy_reg->cp_clk_wr_delay))
207 | (CP_READ_DQS_DELAY(combo_phy_reg->cp_read_dqs_delay));
208 ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
209 COMBO_PHY_REG + PHY_DLL_SLAVE_CTRL_REG, MMC_REG_BASE
210 + SDHC_CDNS_HRS05, value);
211 if (ret != 0) {
212 return ret;
213 }
214
215 /* program PHY_CTRL_REG */
216 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS04, COMBO_PHY_REG
217 + PHY_CTRL_REG);
218 value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS05);
219
220 /* phony_dqs_timing=0 */
221 value &= ~(CP_PHONY_DQS_TIMING_MASK << CP_PHONY_DQS_TIMING_SHIFT);
222 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS05, value);
223
224 /* switch off DLL_RESET */
225 do {
226 value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
227 value |= SDHC_PHY_SW_RESET;
228 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
229 value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
230 /* polling PHY_INIT_COMPLETE */
231 } while ((value & SDHC_PHY_INIT_COMPLETE) != SDHC_PHY_INIT_COMPLETE);
232
233 /* program PHY_DQ_TIMING_REG */
234 combo_phy_reg->cp_io_mask_end = 0U;
235 value = (CP_IO_MASK_ALWAYS_ON(combo_phy_reg->cp_io_mask_always_on))
236 | (CP_IO_MASK_END(combo_phy_reg->cp_io_mask_end))
237 | (CP_IO_MASK_START(combo_phy_reg->cp_io_mask_start))
238 | (CP_DATA_SELECT_OE_END(combo_phy_reg->cp_data_select_oe_end));
239
240 ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
241 COMBO_PHY_REG + PHY_DQ_TIMING_REG, MMC_REG_BASE
242 + SDHC_CDNS_HRS05, value);
243 if (ret != 0) {
244 return ret;
245 }
246 return 0;
247}
248
249int cdns_read(int lba, uintptr_t buf, size_t size)
250{
251 inv_dcache_range(buf, size);
252
253 return 0;
254}
255
256void cdns_init(void)
257{
258 /* Dummy function pointer for cdns_init. */
259}
260
261int cdns_prepare(int dma_start_addr, uintptr_t dma_buff, size_t size)
262{
263 data_cmd = true;
264 struct cdns_idmac_desc *desc;
265 uint32_t desc_cnt, i;
266 uint64_t desc_base;
267
268 assert(((dma_buff & CDNSMMC_ADDRESS_MASK) == 0) &&
269 (cdns_params.desc_size > 0) &&
270 ((MMC_REG_BASE & MMC_BLOCK_MASK) == 0) &&
271 ((cdns_params.desc_base & MMC_BLOCK_MASK) == 0) &&
272 ((cdns_params.desc_size & MMC_BLOCK_MASK) == 0));
273
274 flush_dcache_range(dma_buff, size);
275
276 desc_cnt = (size + (CDMMC_DMA_MAX_BUFFER_SIZE) - 1) / (CDMMC_DMA_MAX_BUFFER_SIZE);
277 assert(desc_cnt * sizeof(struct cdns_idmac_desc) < cdns_params.desc_size);
278
279 if (desc_cnt > CONFIG_CDNS_DESC_COUNT) {
280 ERROR("Requested data transfer length %ld is greater than configured length %d",
281 size, (CONFIG_CDNS_DESC_COUNT * CDMMC_DMA_MAX_BUFFER_SIZE));
282 return -EINVAL;
283 }
284
285 desc = (struct cdns_idmac_desc *)cdns_params.desc_base;
286 desc_base = (uint64_t)desc;
287 i = 0;
288
289 while ((i + 1) < desc_cnt) {
290 desc->attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA;
291 desc->reserved = 0;
292 desc->len = MAX_64KB_PAGE;
293 desc->addr_lo = (dma_buff & UINT_MAX) + (CDMMC_DMA_MAX_BUFFER_SIZE * i);
294#if CONFIG_DMA_ADDR_T_64BIT == 1
295 desc->addr_hi = (dma_buff >> 32) & 0xffffffff;
296#endif
297 size -= CDMMC_DMA_MAX_BUFFER_SIZE;
298 desc++;
299 i++;
300 }
301
302 desc->attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA |
303 ADMA_DESC_ATTR_END;
304 desc->reserved = 0;
305 desc->len = size;
306#if CONFIG_DMA_ADDR_T_64BIT == 1
307 desc->addr_lo = (dma_buff & UINT_MAX) + (CDMMC_DMA_MAX_BUFFER_SIZE * i);
308 desc->addr_hi = (dma_buff >> 32) & UINT_MAX;
309#else
310 desc->addr_lo = (dma_buff & UINT_MAX);
311#endif
312
313 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS22, (uint32_t)desc_base);
314 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS23, (uint32_t)(desc_base >> 32));
315 flush_dcache_range(cdns_params.desc_base,
316 desc_cnt * CDMMC_DMA_MAX_BUFFER_SIZE);
317
318 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS01,
319 ((512 << BLOCK_SIZE) | ((size/512) << BLK_COUNT_CT) | SDMA_BUF));
320 return 0;
321}
322
323static void cdns_host_set_clk(int clk)
324{
325 uint32_t ret = 0;
326 uint32_t sdclkfsval = 0;
327 uint32_t dtcvval = DTCVVAL_DEFAULT_VAL;
328
329 sdclkfsval = (cdns_params.clk_rate / 2000) / clk;
330 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, 0);
331 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
332 (sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE));
333
334 ret = cdns_wait_ics(5000, MMC_REG_BASE + SDHC_CDNS_SRS11);
335 if (ret != 0U) {
336 ERROR("Waiting SDMMC_CDN_ICS timeout");
337 }
338
339 /* Enable DLL reset */
340 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) &
341 ~SDHC_DLL_RESET_MASK);
342 /* Set extended_wr_mode */
343 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, (mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09)
344 & SDHC_EXTENDED_WR_MODE_MASK) | (1 << EXTENDED_WR_MODE));
345 /* Release DLL reset */
346 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
347 + SDHC_CDNS_HRS09) | 1);
348 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
349 + SDHC_CDNS_HRS09) | (3 << RDCMD_EN));
350
351 do {
352 mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
353 } while (~mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & (1 << 1));
354
355 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
356 (sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) | (1 << SDMMC_CDN_SDCE));
357 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS13, UINT_MAX);
358}
359
360int cdns_set_ios(unsigned int clk, unsigned int width)
361{
362
363 switch (width) {
364 case MMC_BUS_WIDTH_1:
365 mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), LEDC_OFF);
366 break;
367 case MMC_BUS_WIDTH_4:
368 mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), DTW_4BIT);
369 break;
370 case MMC_BUS_WIDTH_8:
371 mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), EDTW_8BIT);
372 break;
373 default:
374 assert(0);
375 break;
376 }
377 cdns_host_set_clk(clk);
378
379 return 0;
380}
381
382int cdns_sdmmc_write_sd_host_reg(uint32_t addr, uint32_t data)
383{
384 uint32_t value = 0;
385
386 value = mmio_read_32(addr);
387 value &= ~SDHC_REG_MASK;
388 value |= data;
389 mmio_write_32(addr, value);
390 value = mmio_read_32(addr);
391 if (value != data) {
392 ERROR("SD host address is not set properly\n");
393 return -ENXIO;
394 }
395
396 return 0;
397}
398
399int cdns_write(int lba, uintptr_t buf, size_t size)
400{
401 return 0;
402}
403
404static int cdns_init_hrs_io(struct cdns_sdmmc_combo_phy *combo_phy_reg,
405 struct cdns_sdmmc_sdhc *sdhc_reg)
406{
407 uint32_t value = 0;
408 int ret = 0;
409
410 /* program HRS09, register 42 */
411 value = (SDHC_RDDATA_EN(sdhc_reg->sdhc_rddata_en))
412 | (SDHC_RDCMD_EN(sdhc_reg->sdhc_rdcmd_en))
413 | (SDHC_EXTENDED_WR_MODE(sdhc_reg->sdhc_extended_wr_mode))
414 | (SDHC_EXTENDED_RD_MODE(sdhc_reg->sdhc_extended_rd_mode));
415 ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
416 if (ret != 0) {
417 ERROR("Program HRS09 failed");
418 return ret;
419 }
420
421 /* program HRS10, register 43 */
422 value = (SDHC_HCSDCLKADJ(sdhc_reg->sdhc_hcsdclkadj));
423 ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS10, value);
424 if (ret != 0) {
425 ERROR("Program HRS10 failed");
426 return ret;
427 }
428
429 /* program HRS16, register 48 */
430 value = (SDHC_WRDATA1_SDCLK_DLY(sdhc_reg->sdhc_wrdata1_sdclk_dly))
431 | (SDHC_WRDATA0_SDCLK_DLY(sdhc_reg->sdhc_wrdata0_sdclk_dly))
432 | (SDHC_WRCMD1_SDCLK_DLY(sdhc_reg->sdhc_wrcmd1_sdclk_dly))
433 | (SDHC_WRCMD0_SDCLK_DLY(sdhc_reg->sdhc_wrcmd0_sdclk_dly))
434 | (SDHC_WRDATA1_DLY(sdhc_reg->sdhc_wrdata1_dly))
435 | (SDHC_WRDATA0_DLY(sdhc_reg->sdhc_wrdata0_dly))
436 | (SDHC_WRCMD1_DLY(sdhc_reg->sdhc_wrcmd1_dly))
437 | (SDHC_WRCMD0_DLY(sdhc_reg->sdhc_wrcmd0_dly));
438 ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS16, value);
439 if (ret != 0) {
440 ERROR("Program HRS16 failed");
441 return ret;
442 }
443
444 /* program HRS07, register 40 */
445 value = (SDHC_RW_COMPENSATE(sdhc_reg->sdhc_rw_compensate))
446 | (SDHC_IDELAY_VAL(sdhc_reg->sdhc_idelay_val));
447 ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS07, value);
448 if (ret != 0) {
449 ERROR("Program HRS07 failed");
450 return ret;
451 }
452
453 return ret;
454}
455
456static int cdns_hc_set_clk(struct cdns_sdmmc_params *cdn_sdmmc_dev_mode_params)
457{
458 uint32_t ret = 0;
459 uint32_t dtcvval, sdclkfsval;
460
461 dtcvval = DTC_VAL;
462 sdclkfsval = 0;
463
464 if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_DS) ||
465 (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR12) ||
466 (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_SDR_BC)) {
467 sdclkfsval = 4;
468 } else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_HS) ||
469 (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR25) ||
470 (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_DDR50) ||
471 (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_SDR)) {
472 sdclkfsval = 2;
473 } else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR50) ||
474 (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_DDR) ||
475 (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS400) ||
476 (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS400es)) {
477 sdclkfsval = 1;
478 } else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR104) ||
479 (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS200)) {
480 sdclkfsval = 0;
481 }
482
483 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, 0);
484 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
485 (sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE));
486 ret = cdns_wait_ics(5000, MMC_REG_BASE + SDHC_CDNS_SRS11);
487 if (ret != 0U) {
488 ERROR("Waiting SDMMC_CDN_ICS timeout");
489 return ret;
490 }
491
492 /* Enable DLL reset */
493 mmio_write_32((MMC_REG_BASE + SDHC_CDNS_HRS09), mmio_read_32(MMC_REG_BASE
494 + SDHC_CDNS_HRS09) & ~SDHC_DLL_RESET_MASK);
495 /* Set extended_wr_mode */
496 mmio_write_32((MMC_REG_BASE + SDHC_CDNS_HRS09),
497 (mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & SDHC_EXTENDED_WR_MODE_MASK) |
498 (1 << EXTENDED_WR_MODE));
499 /* Release DLL reset */
500 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
501 + SDHC_CDNS_HRS09) | 1);
502 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
503 + SDHC_CDNS_HRS09) | (3 << RDCMD_EN));
504 do {
505 mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
506 } while (~mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & (1 << 1));
507
508 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
509 (sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) | (1 << SDMMC_CDN_SDCE));
510
511 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS13, UINT_MAX);
512 return 0;
513}
514
515int cdns_reset(void)
516{
517 uint32_t data = 0;
518 uint32_t count = 0;
519 uint32_t value = 0;
520
521 value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS11);
522 value &= ~(0xFFFF);
523 value |= 0x0;
524 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, value);
525 udelay(500);
526
527 /* Software reset */
528 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS00, 1);
529 /* Wait status command response ready */
530 do {
531 data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS00);
532 count++;
533 if (count >= 5000) {
534 return -ETIMEDOUT;
535 }
536 /* Wait for HRS00.SWR */
537 } while ((data & 1) == 1);
538
539 /* Step 1, switch on DLL_RESET */
540 value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
541 value &= ~SDHC_PHY_SW_RESET;
542 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
543
544 return 0;
545}
546
547int cdns_sd_host_init(struct cdns_sdmmc_combo_phy *mmc_combo_phy_reg,
548struct cdns_sdmmc_sdhc *mmc_sdhc_reg)
549{
550 int ret = 0;
551
552 ret = cdns_reset();
553 if (ret != 0) {
554 ERROR("Program phy reg init failed");
555 return ret;
556 }
557
558 ret = cdns_program_phy_reg(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
559 if (ret != 0) {
560 ERROR("Program phy reg init failed");
561 return ret;
562 }
563
564 ret = cdns_init_hrs_io(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
565 if (ret != 0) {
566 ERROR("Program init for HRS reg is failed");
567 return ret;
568 }
569
570 ret = cdns_sd_card_detect();
571 if (ret != 0) {
572 ERROR("SD card does not detect");
573 return ret;
574 }
575
576 ret = cdns_vol_reset();
577 if (ret != 0) {
578 ERROR("eMMC card reset failed");
579 return ret;
580 }
581
582 ret = cdns_hc_set_clk(&cdns_params);
583 if (ret != 0) {
584 ERROR("hc set clk failed");
585 return ret;
586 }
587
588 return 0;
589}
590
591void cdns_srs10_value_toggle(uint8_t write_val, uint8_t prev_val)
592{
593 uint32_t data_op = 0U;
594
595 data_op = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS10);
596 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS10, (data_op & (prev_val << 0)));
597 mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS10);
598 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS10, data_op | (write_val << 0));
599}
600
601void cdns_srs11_srs15_config(uint32_t srs11_val, uint32_t srs15_val)
602{
603 uint32_t data = 0U;
604
605 data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS11);
606 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (data | srs11_val));
607 data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS15);
608 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS15, (data | srs15_val));
609}
610
611int cdns_send_cmd(struct mmc_cmd *cmd)
612{
613 uint32_t op = 0, ret = 0;
614 uint8_t write_value = 0, prev_val = 0;
615 uint32_t value;
616 int32_t timeout;
617 uint32_t cmd_indx;
618 uint32_t status = 0, srs15_val = 0, srs11_val = 0;
619 uint32_t status_check = 0;
620
621 assert(cmd);
622 cmd_indx = (cmd->cmd_idx) << COM_IDX;
623
624 if (data_cmd) {
625 switch (cmd->cmd_idx) {
626 case SD_SWITCH:
627 op = DATA_PRESENT;
628 write_value = ADMA2_32 | DT_WIDTH;
629 prev_val = ADMA2_32 | DT_WIDTH;
630 cdns_srs10_value_toggle(write_value, prev_val);
631 srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
632 srs15_val = BIT_AD_64 | HV4E | V18SE;
633 cdns_srs11_srs15_config(srs11_val, srs15_val);
634 break;
635
636 case SD_WRITE_SINGLE_BLOCK:
637 case SD_READ_SINGLE_BLOCK:
638 op = DATA_PRESENT;
639 write_value = ADMA2_32 | HS_EN | DT_WIDTH | LEDC;
640 prev_val = ADMA2_32 | HS_EN | DT_WIDTH;
641 cdns_srs10_value_toggle(write_value, prev_val);
642 srs15_val = PVE | BIT_AD_64 | HV4E | SDR104_MODE | V18SE;
643 srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
644 cdns_srs11_srs15_config(srs11_val, srs15_val);
645 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS00, SAAR);
646 break;
647
648 case SD_WRITE_MULTIPLE_BLOCK:
649 case SD_READ_MULTIPLE_BLOCK:
650 op = DATA_PRESENT | AUTO_CMD_EN | MULTI_BLK_READ;
651 write_value = ADMA2_32 | HS_EN | DT_WIDTH | LEDC;
652 prev_val = ADMA2_32 | HS_EN | DT_WIDTH;
653 cdns_srs10_value_toggle(write_value, prev_val);
654 srs15_val = PVE | BIT_AD_64 | HV4E | SDR104_MODE | V18SE;
655 srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
656 cdns_srs11_srs15_config(srs11_val, srs15_val);
657 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS00, SAAR);
658 break;
659
660 case SD_APP_SEND_SCR:
661 op = DATA_PRESENT;
662 write_value = ADMA2_32 | LEDC;
663 prev_val = LEDC;
664 cdns_srs10_value_toggle(write_value, prev_val);
665 srs15_val = BIT_AD_64 | HV4E | V18SE;
666 srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
667 cdns_srs11_srs15_config(srs11_val, srs15_val);
668 break;
669
670 case SD_SEND_IF_COND:
671 op = DATA_PRESENT | CMD_IDX_CHK_ENABLE;
672 write_value = LEDC;
673 prev_val = 0x0;
674 cdns_srs10_value_toggle(write_value, prev_val);
675 srs15_val = HV4E;
676 srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
677 cdns_srs11_srs15_config(srs11_val, srs15_val);
678 break;
679
680 default:
681 write_value = LEDC;
682 prev_val = 0x0;
683 cdns_srs10_value_toggle(write_value, prev_val);
684 op = 0;
685 break;
686 }
687 } else {
688 switch (cmd->cmd_idx) {
689 case SD_GO_IDLE_STATE:
690 write_value = LEDC;
691 prev_val = 0x0;
692 cdns_srs10_value_toggle(write_value, prev_val);
693 srs15_val = HV4E;
694 srs11_val = SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
695 cdns_srs11_srs15_config(srs11_val, srs15_val);
696 break;
697
698 case SD_ALL_SEND_CID:
699 write_value = LEDC;
700 prev_val = 0x0;
701 cdns_srs10_value_toggle(write_value, prev_val);
702 srs15_val = HV4E | V18SE;
703 srs11_val = SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
704 cdns_srs11_srs15_config(srs11_val, srs15_val);
705 break;
706
707 case SD_SEND_IF_COND:
708 op = CMD_IDX_CHK_ENABLE;
709 write_value = LEDC;
710 prev_val = 0x0;
711 cdns_srs10_value_toggle(write_value, prev_val);
712 srs15_val = HV4E;
713 srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
714 cdns_srs11_srs15_config(srs11_val, srs15_val);
715 break;
716
717 case SD_STOP_TRANSMISSION:
718 op = CMD_STOP_ABORT_CMD;
719 break;
720
721 case SD_SEND_STATUS:
722 break;
723
724 case 1:
725 cmd->cmd_arg = 0;
726 break;
727
728 case SD_SELECT_CARD:
729 op = MULTI_BLK_READ;
730 break;
731
732 case SD_APP_CMD:
733 default:
734 write_value = LEDC;
735 prev_val = 0x0;
736 cdns_srs10_value_toggle(write_value, prev_val);
737 op = 0;
738 break;
739 }
740 }
741
742 switch (cmd->resp_type) {
743 case MMC_RESPONSE_NONE:
744 op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN;
745 break;
746
747 case MMC_RESPONSE_R2:
748 op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN |
749 RES_TYPE_SEL_136 | CMD_CHECK_RESP_CRC;
750 break;
751
752 case MMC_RESPONSE_R3:
753 op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN |
754 RES_TYPE_SEL_48;
755 break;
756
757 case MMC_RESPONSE_R1:
758 if ((cmd->cmd_idx == SD_WRITE_SINGLE_BLOCK) || (cmd->cmd_idx
759 == SD_WRITE_MULTIPLE_BLOCK)) {
760 op |= DMA_ENABLED | BLK_CNT_EN | RES_TYPE_SEL_48
761 | CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
762 } else {
763 op |= DMA_ENABLED | BLK_CNT_EN | CMD_READ | RES_TYPE_SEL_48
764 | CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
765 }
766 break;
767
768 default:
769 op |= DMA_ENABLED | BLK_CNT_EN | CMD_READ | MULTI_BLK_READ |
770 RES_TYPE_SEL_48 | CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
771 break;
772 }
773
774 timeout = TIMEOUT;
775 do {
776 udelay(100);
777 ret = cdns_busy();
778 if (--timeout <= 0) {
779 udelay(50);
780 panic();
781 }
782 } while (ret);
783
784 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS12, UINT_MAX);
785
786 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS02, cmd->cmd_arg);
787 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS14, 0x00000000);
788 if (cmd_indx == 1)
789 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS03, SDHC_CDNS_SRS03_VALUE);
790 else
791 mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS03, op | cmd_indx);
792
793 timeout = TIMEOUT;
794 do {
795 udelay(500);
796 value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS12);
797 } while (((value & (INT_CMD_DONE | ERROR_INT)) == 0) && (timeout-- > 0));
798
799 timeout = TIMEOUT;
800
801 if (data_cmd) {
802 data_cmd = false;
803 do {
804 udelay(250);
805 } while (((value & TRAN_COMP) == 0) && (timeout-- > 0));
806 }
807
808 status_check = value & SRS12_ERR_MASK;
809 if (status_check != 0U) {
810 ERROR("SD host controller send command failed, SRS12 = %x", status);
811 return -1;
812 }
813
814 if ((op & RES_TYPE_SEL_48) || (op & RES_TYPE_SEL_136)) {
815 cmd->resp_data[0] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS04);
816 if (op & RES_TYPE_SEL_136) {
817 cmd->resp_data[1] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS05);
818 cmd->resp_data[2] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS06);
819 cmd->resp_data[3] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS07);
820 }
821 }
822
823 return 0;
824}