1 /* 2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. 3 * Copyright 2025 NXP 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #include <assert.h> 9 #include <errno.h> 10 #include <string.h> 11 12 #include <arch.h> 13 #include <arch_helpers.h> 14 #include <common/debug.h> 15 #include <drivers/delay_timer.h> 16 #include <drivers/mmc.h> 17 #include <lib/mmio.h> 18 #include <lib/xlat_tables/xlat_tables_v2.h> 19 20 #include <imx_usdhc.h> 21 22 /* These masks represent the commands which involve a data transfer. */ 23 #define ADTC_MASK_SD (BIT_32(6U) | BIT_32(17U) | BIT_32(18U) |\ 24 BIT_32(24U) | BIT_32(25U)) 25 #define ADTC_MASK_ACMD (BIT_64(51U)) 26 27 struct imx_usdhc_device_data { 28 uint32_t addr; 29 uint32_t blk_size; 30 uint32_t blks; 31 bool valid; 32 }; 33 34 static void imx_usdhc_initialize(void); 35 static int imx_usdhc_send_cmd(struct mmc_cmd *cmd); 36 static int imx_usdhc_set_ios(unsigned int clk, unsigned int width); 37 static int imx_usdhc_prepare(int lba, uintptr_t buf, size_t size); 38 static int imx_usdhc_read(int lba, uintptr_t buf, size_t size); 39 static int imx_usdhc_write(int lba, uintptr_t buf, size_t size); 40 41 static const struct mmc_ops imx_usdhc_ops = { 42 .init = imx_usdhc_initialize, 43 .send_cmd = imx_usdhc_send_cmd, 44 .set_ios = imx_usdhc_set_ios, 45 .prepare = imx_usdhc_prepare, 46 .read = imx_usdhc_read, 47 .write = imx_usdhc_write, 48 }; 49 50 static imx_usdhc_params_t imx_usdhc_params; 51 static struct imx_usdhc_device_data imx_usdhc_data; 52 53 static bool imx_usdhc_is_buf_valid(void) 54 { 55 return imx_usdhc_data.valid; 56 } 57 58 static bool imx_usdhc_is_buf_multiblk(void) 59 { 60 return imx_usdhc_data.blks > 1U; 61 } 62 63 static void imx_usdhc_inval_buf_data(void) 64 { 65 imx_usdhc_data.valid = false; 66 } 67 68 static int imx_usdhc_save_buf_data(uintptr_t buf, size_t size) 69 { 70 uint32_t block_size; 71 uint64_t blks; 72 73 if (size <= MMC_BLOCK_SIZE) { 74 block_size = (uint32_t)size; 75 } else { 76 block_size = MMC_BLOCK_SIZE; 77 } 78 79 if (buf > UINT32_MAX) { 80 return -EOVERFLOW; 81 } 82 83 imx_usdhc_data.addr = (uint32_t)buf; 84 imx_usdhc_data.blk_size = block_size; 85 blks = size / block_size; 86 imx_usdhc_data.blks = (uint32_t)blks; 87 88 imx_usdhc_data.valid = true; 89 90 return 0; 91 } 92 93 static void imx_usdhc_write_buf_data(void) 94 { 95 uintptr_t reg_base = imx_usdhc_params.reg_base; 96 uint32_t addr, blks, blk_size; 97 98 addr = imx_usdhc_data.addr; 99 blks = imx_usdhc_data.blks; 100 blk_size = imx_usdhc_data.blk_size; 101 102 mmio_write_32(reg_base + DSADDR, addr); 103 mmio_write_32(reg_base + BLKATT, BLKATT_BLKCNT(blks) | 104 BLKATT_BLKSIZE(blk_size)); 105 } 106 107 #define IMX7_MMC_SRC_CLK_RATE (200 * 1000 * 1000) 108 static void imx_usdhc_set_clk(unsigned int clk) 109 { 110 unsigned int sdhc_clk = IMX7_MMC_SRC_CLK_RATE; 111 uintptr_t reg_base = imx_usdhc_params.reg_base; 112 unsigned int pre_div = 1U, div = 1U; 113 114 assert(clk > 0); 115 116 while (sdhc_clk / (16 * pre_div) > clk && pre_div < 256) 117 pre_div *= 2; 118 119 while (((sdhc_clk / (div * pre_div)) > clk) && (div < 16U)) { 120 div++; 121 } 122 123 pre_div >>= 1; 124 div -= 1; 125 clk = (pre_div << 8) | (div << 4); 126 127 while ((mmio_read_32(reg_base + PSTATE) & PSTATE_SDSTB) == 0U) { 128 } 129 130 mmio_clrbits32(reg_base + VENDSPEC, VENDSPEC_CARD_CLKEN); 131 mmio_clrsetbits32(reg_base + SYSCTRL, SYSCTRL_CLOCK_MASK, clk); 132 udelay(10000); 133 134 mmio_setbits32(reg_base + VENDSPEC, VENDSPEC_PER_CLKEN | VENDSPEC_CARD_CLKEN); 135 } 136 137 static void imx_usdhc_initialize(void) 138 { 139 unsigned int timeout = 10000; 140 uintptr_t reg_base = imx_usdhc_params.reg_base; 141 142 assert((imx_usdhc_params.reg_base & MMC_BLOCK_MASK) == 0); 143 144 /* reset the controller */ 145 mmio_setbits32(reg_base + SYSCTRL, SYSCTRL_RSTA); 146 147 /* wait for reset done */ 148 while ((mmio_read_32(reg_base + SYSCTRL) & SYSCTRL_RSTA)) { 149 if (!timeout) 150 ERROR("IMX MMC reset timeout.\n"); 151 timeout--; 152 } 153 154 mmio_write_32(reg_base + MMCBOOT, 0); 155 mmio_write_32(reg_base + MIXCTRL, 0); 156 mmio_write_32(reg_base + CLKTUNECTRLSTS, 0); 157 158 mmio_write_32(reg_base + VENDSPEC, VENDSPEC_INIT); 159 mmio_write_32(reg_base + DLLCTRL, 0); 160 mmio_setbits32(reg_base + VENDSPEC, VENDSPEC_IPG_CLKEN | VENDSPEC_PER_CLKEN); 161 162 /* Set the initial boot clock rate */ 163 imx_usdhc_set_clk(MMC_BOOT_CLK_RATE); 164 udelay(100); 165 166 /* Clear read/write ready status */ 167 mmio_clrbits32(reg_base + INTSTATEN, INTSTATEN_BRR | INTSTATEN_BWR); 168 169 /* configure as little endian */ 170 mmio_write_32(reg_base + PROTCTRL, PROTCTRL_LE); 171 172 /* Set timeout to the maximum value */ 173 mmio_clrsetbits32(reg_base + SYSCTRL, SYSCTRL_TIMEOUT_MASK, 174 SYSCTRL_TIMEOUT(15)); 175 176 /* set wartermark level as 16 for safe for MMC */ 177 mmio_clrsetbits32(reg_base + WATERMARKLEV, WMKLV_MASK, 16 | (16 << 16)); 178 } 179 180 #define FSL_CMD_RETRIES 1000 181 182 static bool is_data_transfer_to_card(const struct mmc_cmd *cmd) 183 { 184 unsigned int cmd_idx = cmd->cmd_idx; 185 186 return (cmd_idx == MMC_CMD(24)) || (cmd_idx == MMC_CMD(25)); 187 } 188 189 static bool is_data_transfer_cmd(const struct mmc_cmd *cmd) 190 { 191 uintptr_t reg_base = imx_usdhc_params.reg_base; 192 unsigned int cmd_idx = cmd->cmd_idx; 193 uint32_t xfer_type; 194 195 xfer_type = mmio_read_32(reg_base + XFERTYPE); 196 197 if (XFERTYPE_GET_CMD(xfer_type) == MMC_CMD(55)) { 198 return (ADTC_MASK_ACMD & BIT_64(cmd_idx)) != 0ULL; 199 } 200 201 if ((ADTC_MASK_SD & BIT_32(cmd->cmd_idx)) != 0U) { 202 return true; 203 } 204 205 return false; 206 } 207 208 static int get_xfr_type(const struct mmc_cmd *cmd, bool data, uint32_t *xfertype) 209 { 210 *xfertype = XFERTYPE_CMD(cmd->cmd_idx); 211 212 switch (cmd->resp_type) { 213 case MMC_RESPONSE_R2: 214 *xfertype |= XFERTYPE_RSPTYP_136; 215 *xfertype |= XFERTYPE_CCCEN; 216 break; 217 case MMC_RESPONSE_R4: 218 *xfertype |= XFERTYPE_RSPTYP_48; 219 break; 220 case MMC_RESPONSE_R6: 221 *xfertype |= XFERTYPE_RSPTYP_48; 222 *xfertype |= XFERTYPE_CICEN; 223 *xfertype |= XFERTYPE_CCCEN; 224 break; 225 case MMC_RESPONSE_R1B: 226 *xfertype |= XFERTYPE_RSPTYP_48_BUSY; 227 *xfertype |= XFERTYPE_CICEN; 228 *xfertype |= XFERTYPE_CCCEN; 229 break; 230 case MMC_RESPONSE_NONE: 231 break; 232 default: 233 ERROR("Invalid CMD response: %u\n", cmd->resp_type); 234 return -EINVAL; 235 } 236 237 if (data) { 238 *xfertype |= XFERTYPE_DPSEL; 239 } 240 241 return 0; 242 } 243 244 static int imx_usdhc_send_cmd(struct mmc_cmd *cmd) 245 { 246 uintptr_t reg_base = imx_usdhc_params.reg_base; 247 unsigned int state, flags = INTSTATEN_CC | INTSTATEN_CTOE; 248 unsigned int mixctl = 0; 249 unsigned int cmd_retries = 0; 250 uint32_t xfertype; 251 bool data; 252 int err = 0; 253 254 assert(cmd); 255 256 data = is_data_transfer_cmd(cmd); 257 258 err = get_xfr_type(cmd, data, &xfertype); 259 if (err != 0) { 260 return err; 261 } 262 263 /* clear all irq status */ 264 mmio_write_32(reg_base + INTSTAT, 0xffffffff); 265 266 /* Wait for the bus to be idle */ 267 do { 268 state = mmio_read_32(reg_base + PSTATE); 269 } while (state & (PSTATE_CDIHB | PSTATE_CIHB)); 270 271 while (mmio_read_32(reg_base + PSTATE) & PSTATE_DLA) 272 ; 273 274 mmio_write_32(reg_base + INTSIGEN, 0); 275 276 if (data) { 277 mixctl |= MIXCTRL_DMAEN; 278 } 279 280 if (!is_data_transfer_to_card(cmd)) { 281 mixctl |= MIXCTRL_DTDSEL; 282 } 283 284 if ((cmd->cmd_idx != MMC_CMD(55)) && imx_usdhc_is_buf_valid()) { 285 if (imx_usdhc_is_buf_multiblk()) { 286 mixctl |= MIXCTRL_MSBSEL | MIXCTRL_BCEN; 287 } 288 289 imx_usdhc_write_buf_data(); 290 imx_usdhc_inval_buf_data(); 291 } 292 293 /* Send the command */ 294 mmio_write_32(reg_base + CMDARG, cmd->cmd_arg); 295 mmio_clrsetbits32(reg_base + MIXCTRL, MIXCTRL_DATMASK, mixctl); 296 mmio_write_32(reg_base + XFERTYPE, xfertype); 297 298 /* Wait for the command done */ 299 do { 300 state = mmio_read_32(reg_base + INTSTAT); 301 if (cmd_retries) 302 udelay(1); 303 } while ((!(state & flags)) && ++cmd_retries < FSL_CMD_RETRIES); 304 305 if ((state & (INTSTATEN_CTOE | CMD_ERR)) || cmd_retries == FSL_CMD_RETRIES) { 306 if (cmd_retries == FSL_CMD_RETRIES) 307 err = -ETIMEDOUT; 308 else 309 err = -EIO; 310 ERROR("imx_usdhc mmc cmd %d state 0x%x errno=%d\n", 311 cmd->cmd_idx, state, err); 312 goto out; 313 } 314 315 /* Copy the response to the response buffer */ 316 if (cmd->resp_type & MMC_RSP_136) { 317 unsigned int cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0; 318 319 cmdrsp3 = mmio_read_32(reg_base + CMDRSP3); 320 cmdrsp2 = mmio_read_32(reg_base + CMDRSP2); 321 cmdrsp1 = mmio_read_32(reg_base + CMDRSP1); 322 cmdrsp0 = mmio_read_32(reg_base + CMDRSP0); 323 cmd->resp_data[3] = (cmdrsp3 << 8) | (cmdrsp2 >> 24); 324 cmd->resp_data[2] = (cmdrsp2 << 8) | (cmdrsp1 >> 24); 325 cmd->resp_data[1] = (cmdrsp1 << 8) | (cmdrsp0 >> 24); 326 cmd->resp_data[0] = (cmdrsp0 << 8); 327 } else { 328 cmd->resp_data[0] = mmio_read_32(reg_base + CMDRSP0); 329 } 330 331 /* Wait until all of the blocks are transferred */ 332 if (data) { 333 flags = DATA_COMPLETE; 334 do { 335 state = mmio_read_32(reg_base + INTSTAT); 336 337 if (state & (INTSTATEN_DTOE | DATA_ERR)) { 338 err = -EIO; 339 ERROR("imx_usdhc mmc data state 0x%x\n", state); 340 goto out; 341 } 342 } while ((state & flags) != flags); 343 } 344 345 out: 346 /* Reset CMD and DATA on error */ 347 if (err) { 348 mmio_setbits32(reg_base + SYSCTRL, SYSCTRL_RSTC); 349 while (mmio_read_32(reg_base + SYSCTRL) & SYSCTRL_RSTC) 350 ; 351 352 if (data) { 353 mmio_setbits32(reg_base + SYSCTRL, SYSCTRL_RSTD); 354 while (mmio_read_32(reg_base + SYSCTRL) & SYSCTRL_RSTD) 355 ; 356 } 357 } 358 359 /* clear all irq status */ 360 mmio_write_32(reg_base + INTSTAT, 0xffffffff); 361 362 return err; 363 } 364 365 static int imx_usdhc_set_ios(unsigned int clk, unsigned int width) 366 { 367 uintptr_t reg_base = imx_usdhc_params.reg_base; 368 369 imx_usdhc_set_clk(clk); 370 371 if (width == MMC_BUS_WIDTH_4) 372 mmio_clrsetbits32(reg_base + PROTCTRL, PROTCTRL_WIDTH_MASK, 373 PROTCTRL_WIDTH_4); 374 else if (width == MMC_BUS_WIDTH_8) 375 mmio_clrsetbits32(reg_base + PROTCTRL, PROTCTRL_WIDTH_MASK, 376 PROTCTRL_WIDTH_8); 377 378 return 0; 379 } 380 381 static int imx_usdhc_prepare(int lba, uintptr_t buf, size_t size) 382 { 383 flush_dcache_range(buf, size); 384 return imx_usdhc_save_buf_data(buf, size); 385 } 386 387 static int imx_usdhc_read(int lba, uintptr_t buf, size_t size) 388 { 389 inv_dcache_range(buf, size); 390 return 0; 391 } 392 393 static int imx_usdhc_write(int lba, uintptr_t buf, size_t size) 394 { 395 return 0; 396 } 397 398 void imx_usdhc_init(imx_usdhc_params_t *params, 399 struct mmc_device_info *mmc_dev_info) 400 { 401 int ret __maybe_unused; 402 403 assert((params != 0) && 404 ((params->reg_base & MMC_BLOCK_MASK) == 0) && 405 ((params->bus_width == MMC_BUS_WIDTH_1) || 406 (params->bus_width == MMC_BUS_WIDTH_4) || 407 (params->bus_width == MMC_BUS_WIDTH_8))); 408 409 #if PLAT_XLAT_TABLES_DYNAMIC 410 ret = mmap_add_dynamic_region(params->reg_base, params->reg_base, 411 PAGE_SIZE, 412 MT_DEVICE | MT_RW | MT_SECURE); 413 if (ret != 0) { 414 ERROR("Failed to map the uSDHC registers\n"); 415 panic(); 416 } 417 #endif 418 419 memcpy(&imx_usdhc_params, params, sizeof(imx_usdhc_params_t)); 420 mmc_init(&imx_usdhc_ops, params->clk_rate, params->bus_width, 421 params->flags, mmc_dev_info); 422 } 423