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