1 /* 2 * Copyright (c) 2022-2023, Intel Corporation. All rights reserved. 3 * Copyright (c) 2024-2025, Altera Corporation. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #include <assert.h> 9 #include <errno.h> 10 #include <stdbool.h> 11 #include <stddef.h> 12 #include <string.h> 13 14 #include <arch_helpers.h> 15 #include <common/debug.h> 16 #include <drivers/cadence/cdns_sdmmc.h> 17 #include <drivers/delay_timer.h> 18 #include <drivers/mmc.h> 19 #include <lib/mmio.h> 20 #include <lib/utils.h> 21 22 void cdns_init(void); 23 int cdns_send_cmd(struct mmc_cmd *cmd); 24 int cdns_set_ios(unsigned int clk, unsigned int width); 25 int cdns_prepare(int lba, uintptr_t buf, size_t size); 26 int cdns_read(int lba, uintptr_t buf, size_t size); 27 int cdns_write(int lba, uintptr_t buf, size_t size); 28 29 const struct mmc_ops cdns_sdmmc_ops = { 30 .init = cdns_init, 31 .send_cmd = cdns_send_cmd, 32 .set_ios = cdns_set_ios, 33 .prepare = cdns_prepare, 34 .read = cdns_read, 35 .write = cdns_write, 36 }; 37 void sd_host_adma_prepare(struct cdns_idmac_desc *desc_ptr, uintptr_t buf, 38 size_t size); 39 struct cdns_sdmmc_params cdns_params; 40 struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg; 41 struct cdns_sdmmc_sdhc sdmmc_sdhc_reg; 42 struct cdns_idmac_desc cdns_desc[CONFIG_CDNS_DESC_COUNT] __aligned(8); 43 44 bool data_cmd; 45 46 int cdns_wait_ics(uint16_t timeout, uint32_t cdn_srs_res) 47 { 48 /* Clock for sdmclk and sdclk */ 49 uint32_t count = 0; 50 uint32_t data = 0; 51 52 /* Wait status command response ready */ 53 do { 54 data = mmio_read_32(cdn_srs_res); 55 count++; 56 if (count >= timeout) { 57 return -ETIMEDOUT; 58 } 59 } while ((data & (1 << SDMMC_CDN_ICS)) == 0); 60 61 return 0; 62 } 63 64 void cdns_set_sdmmc_var(struct cdns_sdmmc_combo_phy *combo_phy_reg, 65 struct cdns_sdmmc_sdhc *sdhc_reg) 66 { 67 /* Values are taken by the reference of cadence IP documents */ 68 combo_phy_reg->cp_clk_wr_delay = 0; 69 combo_phy_reg->cp_clk_wrdqs_delay = 0; 70 combo_phy_reg->cp_data_select_oe_end = 1; 71 combo_phy_reg->cp_dll_bypass_mode = 1; 72 combo_phy_reg->cp_dll_locked_mode = 0; 73 combo_phy_reg->cp_dll_start_point = 254; 74 combo_phy_reg->cp_gate_cfg_always_on = 1; 75 combo_phy_reg->cp_io_mask_always_on = 0; 76 combo_phy_reg->cp_io_mask_end = 5; 77 combo_phy_reg->cp_io_mask_start = 0; 78 combo_phy_reg->cp_rd_del_sel = 52; 79 combo_phy_reg->cp_read_dqs_cmd_delay = 0; 80 combo_phy_reg->cp_read_dqs_delay = 0; 81 combo_phy_reg->cp_sw_half_cycle_shift = 0; 82 combo_phy_reg->cp_sync_method = 1; 83 combo_phy_reg->cp_underrun_suppress = 1; 84 combo_phy_reg->cp_use_ext_lpbk_dqs = 1; 85 combo_phy_reg->cp_use_lpbk_dqs = 1; 86 combo_phy_reg->cp_use_phony_dqs = 1; 87 combo_phy_reg->cp_use_phony_dqs_cmd = 1; 88 89 sdhc_reg->sdhc_extended_rd_mode = 1; 90 sdhc_reg->sdhc_extended_wr_mode = 1; 91 sdhc_reg->sdhc_hcsdclkadj = 3; 92 sdhc_reg->sdhc_idelay_val = 0; 93 sdhc_reg->sdhc_rdcmd_en = 1; 94 sdhc_reg->sdhc_rddata_en = 1; 95 sdhc_reg->sdhc_rw_compensate = 10; 96 sdhc_reg->sdhc_sdcfsh = 0; 97 sdhc_reg->sdhc_sdcfsl = 0; 98 sdhc_reg->sdhc_wrcmd0_dly = 1; 99 sdhc_reg->sdhc_wrcmd0_sdclk_dly = 0; 100 sdhc_reg->sdhc_wrcmd1_dly = 0; 101 sdhc_reg->sdhc_wrcmd1_sdclk_dly = 0; 102 sdhc_reg->sdhc_wrdata0_dly = 0; 103 sdhc_reg->sdhc_wrdata0_sdclk_dly = 0; 104 sdhc_reg->sdhc_wrdata1_dly = 0; 105 sdhc_reg->sdhc_wrdata1_sdclk_dly = 0; 106 } 107 108 int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg, 109 struct cdns_sdmmc_sdhc *sdhc_reg) 110 { 111 uint32_t value = 0; 112 int ret = 0; 113 uint32_t timeout = 0; 114 115 /* HRS00 - Software Reset */ 116 mmio_write_32((cdns_params.reg_base + SDHC_CDNS_HRS00), SDHC_CDNS_HRS00_SWR); 117 118 /* Waiting for SDHC_CDNS_HRS00_SWR reset */ 119 timeout = TIMEOUT; 120 do { 121 udelay(250); 122 if (--timeout <= 0) { 123 NOTICE(" SDHC Software Reset failed!!!\n"); 124 panic(); 125 } 126 } while (((mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS00) & 127 SDHC_CDNS_HRS00_SWR) == 1)); 128 129 /* Step 1, switch on DLL_RESET */ 130 value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09); 131 value &= ~SDHC_PHY_SW_RESET; 132 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, value); 133 134 /* program PHY_DQS_TIMING_REG */ 135 value = (CP_USE_EXT_LPBK_DQS(combo_phy_reg->cp_use_ext_lpbk_dqs)) | 136 (CP_USE_LPBK_DQS(combo_phy_reg->cp_use_lpbk_dqs)) | 137 (CP_USE_PHONY_DQS(combo_phy_reg->cp_use_phony_dqs)) | 138 (CP_USE_PHONY_DQS_CMD(combo_phy_reg->cp_use_phony_dqs_cmd)); 139 ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04, 140 COMBO_PHY_REG + PHY_DQS_TIMING_REG, 141 cdns_params.reg_base + SDHC_CDNS_HRS05, value); 142 if (ret != 0U) { 143 return ret; 144 } 145 146 /* program PHY_GATE_LPBK_CTRL_REG */ 147 value = (CP_SYNC_METHOD(combo_phy_reg->cp_sync_method)) | 148 (CP_SW_HALF_CYCLE_SHIFT(combo_phy_reg->cp_sw_half_cycle_shift)) | 149 (CP_RD_DEL_SEL(combo_phy_reg->cp_rd_del_sel)) | 150 (CP_UNDERRUN_SUPPRESS(combo_phy_reg->cp_underrun_suppress)) | 151 (CP_GATE_CFG_ALWAYS_ON(combo_phy_reg->cp_gate_cfg_always_on)); 152 ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04, 153 COMBO_PHY_REG + PHY_GATE_LPBK_CTRL_REG, 154 cdns_params.reg_base + SDHC_CDNS_HRS05, value); 155 if (ret != 0U) { 156 return -ret; 157 } 158 159 /* program PHY_DLL_MASTER_CTRL_REG */ 160 value = (CP_DLL_BYPASS_MODE(combo_phy_reg->cp_dll_bypass_mode)) | (2 << 20) | 161 (CP_DLL_START_POINT(combo_phy_reg->cp_dll_start_point)); 162 ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04, 163 COMBO_PHY_REG + PHY_DLL_MASTER_CTRL_REG, 164 cdns_params.reg_base + SDHC_CDNS_HRS05, value); 165 if (ret != 0U) { 166 return ret; 167 } 168 169 /* program PHY_DLL_SLAVE_CTRL_REG */ 170 value = (CP_READ_DQS_CMD_DELAY(combo_phy_reg->cp_read_dqs_cmd_delay)) | 171 (CP_CLK_WRDQS_DELAY(combo_phy_reg->cp_clk_wrdqs_delay)) | 172 (CP_CLK_WR_DELAY(combo_phy_reg->cp_clk_wr_delay)) | 173 (CP_READ_DQS_DELAY(combo_phy_reg->cp_read_dqs_delay)); 174 ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04, 175 COMBO_PHY_REG + PHY_DLL_SLAVE_CTRL_REG, 176 cdns_params.reg_base + SDHC_CDNS_HRS05, value); 177 if (ret != 0U) { 178 return ret; 179 } 180 181 /* program PHY_CTRL_REG */ 182 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS04, COMBO_PHY_REG + PHY_CTRL_REG); 183 value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS05); 184 185 /* phony_dqs_timing=0 */ 186 value &= ~(CP_PHONY_DQS_TIMING_MASK << CP_PHONY_DQS_TIMING_SHIFT); 187 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS05, value); 188 189 /* switch off DLL_RESET */ 190 do { 191 value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09); 192 value |= SDHC_PHY_SW_RESET; 193 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, value); 194 value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09); 195 /* polling PHY_INIT_COMPLETE */ 196 } while ((value & SDHC_PHY_INIT_COMPLETE) != SDHC_PHY_INIT_COMPLETE); 197 198 /* program PHY_DQ_TIMING_REG */ 199 value = (CP_IO_MASK_ALWAYS_ON(combo_phy_reg->cp_io_mask_always_on)) | 200 (CP_IO_MASK_END(combo_phy_reg->cp_io_mask_end)) | 201 (CP_IO_MASK_START(combo_phy_reg->cp_io_mask_start)) | 202 (CP_DATA_SELECT_OE_END(combo_phy_reg->cp_data_select_oe_end)); 203 204 ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04, 205 COMBO_PHY_REG + PHY_DQ_TIMING_REG, 206 cdns_params.reg_base + SDHC_CDNS_HRS05, value); 207 if (ret != 0U) { 208 return ret; 209 } 210 211 value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09); 212 value |= (HRS_09_EXTENDED_RD_MODE | HRS_09_EXTENDED_WR_MODE | 213 HRS_09_RDCMD_EN | HRS_09_RDDATA_EN); 214 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, value); 215 216 value = 0; 217 value = SDHC_HCSDCLKADJ(HRS_10_HCSDCLKADJ_VAL); 218 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS10, value); 219 220 value = 0; 221 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS16, value); 222 223 value = (10 << 16); 224 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS07, value); 225 226 return 0; 227 } 228 229 int cdns_read(int lba, uintptr_t buf, size_t size) 230 { 231 return 0; 232 } 233 234 int cdns_write(int lba, uintptr_t buf, size_t size) 235 { 236 return 0; 237 } 238 239 void cdns_init(void) 240 { 241 /* Dummy function pointer for cdns_init. */ 242 } 243 244 int cdns_prepare(int dma_start_addr, uintptr_t dma_buff, size_t size) 245 { 246 struct cdns_idmac_desc *cdns_desc_data; 247 assert(((dma_buff & CDNSMMC_ADDRESS_MASK) == 0) && 248 (cdns_params.desc_size > 0)); 249 250 cdns_desc_data = (struct cdns_idmac_desc *)cdns_params.desc_base; 251 sd_host_adma_prepare(cdns_desc_data, dma_buff, size); 252 253 return 0; 254 } 255 256 void cdns_host_set_clk(uint32_t clk) 257 { 258 uint32_t ret = 0; 259 uint32_t sdclkfsval = 0; 260 uint32_t dtcvval = 0xE; 261 262 sdclkfsval = (SD_HOST_CLK / 2) / clk; 263 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, 0); 264 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, 265 (dtcvval << SDMMC_CDN_DTCV) | (sdclkfsval << SDMMC_CDN_SDCLKFS) | 266 (1 << SDMMC_CDN_ICE)); 267 268 ret = cdns_wait_ics(5000, cdns_params.reg_base + SDHC_CDNS_SRS11); 269 if (ret != 0) { 270 ERROR("Waiting ICS timeout"); 271 } 272 /* Enable DLL reset */ 273 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, 274 mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) & ~0x00000001); 275 /* Set extended_wr_mode */ 276 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, 277 (mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) & 0xFFFFFFF7) | 278 (1 << EXTENDED_WR_MODE)); 279 /* Release DLL reset */ 280 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, 281 mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) | PHY_SW_RESET_EN); 282 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, 283 mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) | RDCMD_EN); 284 285 do { 286 mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09); 287 } while (~mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) & 288 (PHY_INIT_COMPLETE_BIT)); 289 290 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) | 291 (sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) | 292 (1 << SDMMC_CDN_SDCE)); 293 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS13, 0xFFFFFFFF); 294 } 295 296 int cdns_set_ios(unsigned int clk, unsigned int width) 297 { 298 uint32_t _status = 0; 299 300 _status = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10); 301 switch (width) { 302 case MMC_BUS_WIDTH_1: 303 _status &= ~(BIT4); 304 break; 305 306 case MMC_BUS_WIDTH_4: 307 _status |= BIT4; 308 break; 309 310 case MMC_BUS_WIDTH_8: 311 _status |= BIT8; 312 break; 313 314 default: 315 assert(0); 316 break; 317 } 318 mmio_write_32((cdns_params.reg_base + SDHC_CDNS_SRS10), _status); 319 cdns_host_set_clk(clk); 320 321 return 0; 322 } 323 324 int cdns_sdmmc_write_sd_host_reg(uint32_t addr, uint32_t data) 325 { 326 uint32_t value = 0; 327 328 value = mmio_read_32(addr); 329 value &= ~SDHC_REG_MASK; 330 value |= data; 331 mmio_write_32(addr, value); 332 value = mmio_read_32(addr); 333 334 if (value != data) { 335 ERROR("SD host address is not set properly\n"); 336 return -ENXIO; 337 } 338 339 return 0; 340 } 341 342 343 344 void sd_host_oper_mode(enum sd_opr_modes opr_mode) 345 { 346 347 uint32_t reg = 0; 348 349 switch (opr_mode) { 350 case SD_HOST_OPR_MODE_HV4E_0_SDMA_32: 351 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10); 352 reg &= ~(DMA_SEL_BIT); 353 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg); 354 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15); 355 reg &= ~(HV4E | BIT_AD_64); 356 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg); 357 break; 358 359 case SD_HOST_OPR_MODE_HV4E_1_SDMA_32: 360 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10); 361 reg &= ~(DMA_SEL_BIT); 362 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg); 363 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15); 364 reg &= ~(HV4E | BIT_AD_64); 365 reg |= (HV4E); 366 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg); 367 break; 368 369 case SD_HOST_OPR_MODE_HV4E_1_SDMA_64: 370 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10); 371 reg &= ~(DMA_SEL_BIT); 372 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg); 373 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15); 374 reg |= (HV4E | BIT_AD_64); 375 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg); 376 break; 377 378 case SD_HOST_OPR_MODE_HV4E_0_ADMA_32: 379 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10); 380 reg &= ~(DMA_SEL_BIT); 381 reg |= DMA_SEL_BIT_2; 382 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg); 383 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15); 384 reg &= ~(HV4E | BIT_AD_64); 385 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg); 386 break; 387 388 case SD_HOST_OPR_MODE_HV4E_0_ADMA_64: 389 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10); 390 reg &= ~(DMA_SEL_BIT); 391 reg |= DMA_SEL_BIT_3; 392 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg); 393 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15); 394 reg &= ~(HV4E | BIT_AD_64); 395 reg |= BIT_AD_64; 396 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg); 397 break; 398 399 case SD_HOST_OPR_MODE_HV4E_1_ADMA_32: 400 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10); 401 reg &= ~(DMA_SEL_BIT); 402 reg |= DMA_SEL_BIT_2; 403 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg); 404 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15); 405 reg &= ~(HV4E | BIT_AD_64); 406 reg |= HV4E; 407 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg); 408 break; 409 410 case SD_HOST_OPR_MODE_HV4E_1_ADMA_64: 411 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10); 412 reg &= ~(DMA_SEL_BIT); 413 reg |= DMA_SEL_BIT_2; 414 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg); 415 reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15); 416 reg |= (HV4E | BIT_AD_64); 417 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg); 418 break; 419 } 420 } 421 422 void card_reset(bool power_enable) 423 { 424 uint32_t reg_value = 0; 425 426 /* Reading SRS10 value before writing */ 427 reg_value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10); 428 429 if (power_enable == true) { 430 reg_value &= ~((7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP)); 431 reg_value = ((1 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP)); 432 } else { 433 reg_value &= ~((7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP)); 434 } 435 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg_value); 436 } 437 438 void high_speed_enable(bool mode) 439 { 440 441 uint32_t reg_value = 0; 442 /* Reading SRS10 value before writing */ 443 reg_value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10); 444 445 if (mode == true) { 446 reg_value |= HS_EN; 447 } else { 448 reg_value &= ~HS_EN; 449 } 450 451 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg_value); 452 } 453 454 int cdns_reset(void) 455 { 456 volatile uint32_t data = 0; 457 uint32_t count = 0; 458 459 /* Software reset */ 460 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, SRS11_SRFA); 461 /* Wait status command response ready */ 462 do { 463 data = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS00); 464 count++; 465 if (count >= CDNS_TIMEOUT) { 466 return -ETIMEDOUT; 467 } 468 /* Wait for SRS11 */ 469 } while (((SRS11_SRFA_CHK(data)) & 1) == 1); 470 471 return 0; 472 } 473 474 void sdmmc_host_init(bool uhs2_enable) 475 { 476 uint32_t timeout; 477 478 /* SRS11 - Host Control default value set */ 479 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, 0x0); 480 481 /* Waiting for detect card */ 482 timeout = TIMEOUT; 483 do { 484 udelay(250); 485 if (--timeout <= 0) { 486 NOTICE(" SDHC Card Detecion failed!!!\n"); 487 panic(); 488 } 489 } while (((mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS09) & CHECK_CARD) == 0)); 490 491 /* UHS2 Host setting */ 492 if (uhs2_enable == true) { 493 /** need to implement*/ 494 } 495 496 /* Card reset */ 497 498 card_reset(1); 499 udelay(2500); 500 card_reset(0); 501 udelay(2500); 502 card_reset(1); 503 udelay(2500); 504 505 /* Enable Interrupt Flags*/ 506 mmio_write_32((cdns_params.reg_base + SDHC_CDNS_SRS13), ~0); 507 high_speed_enable(true); 508 } 509 510 int cdns_sd_host_init(struct cdns_sdmmc_combo_phy *mmc_combo_phy_reg, 511 struct cdns_sdmmc_sdhc *mmc_sdhc_reg) 512 { 513 int ret = 0; 514 515 ret = cdns_reset(); 516 if (ret != 0U) { 517 ERROR("Program phy reg init failed"); 518 return ret; 519 } 520 521 ret = cdns_program_phy_reg(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg); 522 if (ret != 0U) { 523 ERROR("Program phy reg init failed"); 524 return ret; 525 } 526 sdmmc_host_init(0); 527 cdns_host_set_clk(100000); 528 529 sd_host_oper_mode(SD_HOST_OPR_MODE_HV4E_0_ADMA_64); 530 531 return 0; 532 } 533 534 int cdns_send_cmd(struct mmc_cmd *cmd) 535 { 536 uint32_t cmd_flags = 0; 537 uint32_t timeout = 0; 538 uint32_t status_check = 0; 539 uint32_t mode = 0; 540 uint32_t status; 541 542 assert(cmd); 543 544 cmd_flags = CDNS_HOST_CMD_INHIBIT | CDNS_HOST_DATA_INHIBIT; 545 546 if ((cmd->cmd_idx == SD_STOP_TRANSMISSION) && (!data_cmd)) { 547 cmd_flags &= ~CDNS_HOST_DATA_INHIBIT; 548 } 549 550 timeout = TIMEOUT; 551 do { 552 udelay(100); 553 if (--timeout <= 0) { 554 udelay(50); 555 NOTICE("Timeout occur data and cmd line %x\n", 556 mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS09)); 557 panic(); 558 } 559 } while ((mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS09) & (cmd_flags))); 560 561 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS12, 0xFFFFFFFF); 562 cmd_flags = 0; 563 cmd_flags = (cmd->cmd_idx) << COM_IDX; 564 565 if ((cmd->resp_type & MMC_RSP_136) != 0) { 566 cmd_flags |= RES_TYPE_SEL_136; 567 } else if (((cmd->resp_type & MMC_RSP_48) != 0) && 568 ((cmd->resp_type & MMC_RSP_BUSY) != 0)) { 569 cmd_flags |= RES_TYPE_SEL_48_B; 570 } else if ((cmd->resp_type & MMC_RSP_48) != 0) { 571 cmd_flags |= RES_TYPE_SEL_48; 572 } else { 573 cmd_flags &= ~RES_TYPE_SEL_NO; 574 } 575 576 if ((cmd->resp_type & MMC_RSP_CRC) != 0) { 577 cmd_flags |= CMD_CHECK_RESP_CRC; 578 } 579 580 if ((cmd->resp_type & MMC_RSP_CMD_IDX) != 0) { 581 cmd_flags |= CMD_IDX_CHK_ENABLE; 582 } 583 584 if ((cmd->cmd_idx == MMC_ACMD(51)) || (cmd->cmd_idx == MMC_CMD(17)) || 585 (cmd->cmd_idx == MMC_CMD(18)) || (cmd->cmd_idx == MMC_CMD(24)) || 586 (cmd->cmd_idx == MMC_CMD(25))) { 587 mmio_write_8((cdns_params.reg_base + DTCV_OFFSET), DTCV_VAL); 588 cmd_flags |= DATA_PRESENT; 589 mode |= BLK_CNT_EN; 590 591 mode |= (DMA_ENABLED); 592 if ((cmd->cmd_idx == SD_WRITE_MULTIPLE_BLOCK) || 593 (cmd->cmd_idx == SD_READ_MULTIPLE_BLOCK)) { 594 mode |= (MULTI_BLK_READ); 595 } else { 596 mode &= ~(MULTI_BLK_READ); 597 } 598 if ((cmd->cmd_idx == SD_WRITE_MULTIPLE_BLOCK) || 599 (cmd->cmd_idx == SD_WRITE_SINGLE_BLOCK)) { 600 mode &= ~CMD_READ; 601 } else { 602 mode |= CMD_READ; 603 } 604 mmio_write_16(cdns_params.reg_base + SDHC_CDNS_SRS03, mode); 605 606 } else { 607 mmio_write_8((cdns_params.reg_base + DTCV_OFFSET), DTCV_VAL); 608 } 609 610 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS02, cmd->cmd_arg); 611 mmio_write_16((cdns_params.reg_base + CICE_OFFSET), 612 SDHCI_MAKE_CMD(cmd->cmd_idx, cmd_flags)); 613 614 timeout = TIMEOUT; 615 616 do { 617 udelay(CDNS_TIMEOUT); 618 status = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS12); 619 } while (((status & (INT_CMD_DONE | ERROR_INT)) == 0) && (timeout-- > 0)); 620 621 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS12, (SRS_12_CC_EN)); 622 status_check = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS12) & 0xffff8000; 623 if (status_check != 0U) { 624 timeout = TIMEOUT; 625 ERROR("SD host controller send command failed, SRS12 = %x", status_check); 626 return -1; 627 } 628 629 if (!((cmd_flags & RES_TYPE_SEL_NO) == 0)) { 630 cmd->resp_data[0] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS04); 631 if ((cmd_flags & RES_TYPE_SEL_NO) == RES_TYPE_SEL_136) { 632 cmd->resp_data[1] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS05); 633 cmd->resp_data[2] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS06); 634 cmd->resp_data[3] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS07); 635 /* 136-bit: RTS=01b, Response field R[127:8] - RESP3[23:0], 636 * RESP2[31:0], RESP1[31:0], RESP0[31:0] 637 * Subsystem expects 128 bits response but cadence SDHC sends 638 * 120 bits response from R[127:8]. Bits manupulation to address 639 * the correct responses for the 136 bit response type. 640 */ 641 cmd->resp_data[3] = ((cmd->resp_data[3] << 8) | 642 ((cmd->resp_data[2] >> 24) & 643 CDNS_CSD_BYTE_MASK)); 644 cmd->resp_data[2] = ((cmd->resp_data[2] << 8) | 645 ((cmd->resp_data[1] >> 24) & 646 CDNS_CSD_BYTE_MASK)); 647 cmd->resp_data[1] = ((cmd->resp_data[1] << 8) | 648 ((cmd->resp_data[0] >> 24) & 649 CDNS_CSD_BYTE_MASK)); 650 cmd->resp_data[0] = (cmd->resp_data[0] << 8); 651 } 652 } 653 654 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS12, (SRS_12_CC_EN)); 655 656 return 0; 657 } 658 659 void sd_host_adma_prepare(struct cdns_idmac_desc *desc_ptr, uint64_t buf, 660 size_t size) 661 { 662 uint32_t full_desc_cnt = 0; 663 uint32_t non_full_desc_cnt = 0; 664 uint64_t desc_address; 665 uint32_t block_count; 666 uint32_t transfer_block_size; 667 668 full_desc_cnt = (size / PAGE_BUFFER_LEN); 669 non_full_desc_cnt = (size % PAGE_BUFFER_LEN); 670 for (int i = 0; i < full_desc_cnt; i++) { 671 desc_ptr->attr = (ADMA_DESC_TRANSFER_DATA | ADMA_DESC_ATTR_VALID); 672 desc_ptr->len = 0; // 0 means 64kb page size it will take 673 desc_ptr->addr_lo = 0; 674 #if CONFIG_DMA_ADDR_T_64BIT == 1 675 desc_ptr->addr_hi = (uint32_t)((buf >> 32) & 0xffffffff); 676 #endif 677 if (non_full_desc_cnt == 0) { 678 desc_ptr->attr |= (ADMA_DESC_ATTR_END); 679 } 680 buf += PAGE_BUFFER_LEN; 681 } 682 683 if (non_full_desc_cnt != 0) { 684 desc_ptr->attr = 685 (ADMA_DESC_TRANSFER_DATA | ADMA_DESC_ATTR_END | ADMA_DESC_ATTR_VALID); 686 desc_ptr->addr_lo = buf & 0xffffffff; 687 desc_ptr->len = size; 688 #if CONFIG_DMA_ADDR_T_64BIT == 1 689 desc_ptr->addr_hi = (uint32_t)((buf >> 32) & 0xffffffff); 690 #endif 691 desc_address = (uint64_t)desc_ptr; 692 if (size > MMC_MAX_BLOCK_LEN) { 693 transfer_block_size = MMC_MAX_BLOCK_LEN; 694 } else { 695 transfer_block_size = size; 696 } 697 698 block_count = (size / transfer_block_size); 699 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS01, 700 ((transfer_block_size << BLOCK_SIZE) | SDMA_BUF | 701 (block_count << BLK_COUNT_CT))); 702 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS22, 703 (uint32_t)desc_address & 0xFFFFFFFF); 704 mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS23, 705 (uint32_t)(desc_address >> 32 & 0xFFFFFFFF)); 706 } 707 } 708 709 int cdns_mmc_init(struct cdns_sdmmc_params *params, 710 struct mmc_device_info *info) 711 { 712 713 int result = 0; 714 715 assert((params != NULL) && 716 ((params->reg_base & MMC_BLOCK_MASK) == 0) && 717 ((params->desc_size & MMC_BLOCK_MASK) == 0) && 718 ((params->reg_pinmux & MMC_BLOCK_MASK) == 0) && 719 ((params->reg_phy & MMC_BLOCK_MASK) == 0) && 720 (params->desc_size > 0) && 721 (params->clk_rate > 0) && 722 ((params->bus_width == MMC_BUS_WIDTH_1) || 723 (params->bus_width == MMC_BUS_WIDTH_4) || 724 (params->bus_width == MMC_BUS_WIDTH_8))); 725 726 memcpy(&cdns_params, params, sizeof(struct cdns_sdmmc_params)); 727 728 cdns_set_sdmmc_var(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg); 729 result = cdns_sd_host_init(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg); 730 if (result < 0) { 731 return result; 732 } 733 734 cdns_params.cdn_sdmmc_dev_type = info->mmc_dev_type; 735 cdns_params.cdn_sdmmc_dev_mode = SD_DS; 736 737 result = mmc_init(&cdns_sdmmc_ops, params->clk_rate, params->bus_width, 738 params->flags, info); 739 740 return result; 741 } 742