1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * SDHCI driver for Black Sesame Technologies C1200 controller 4 * 5 * Copyright (c) 2025 Black Sesame Technologies 6 */ 7 8 #include <linux/bits.h> 9 #include <linux/bitfield.h> 10 #include <linux/delay.h> 11 #include <linux/dma-mapping.h> 12 #include <linux/iopoll.h> 13 #include <linux/module.h> 14 #include <linux/of.h> 15 #include <linux/of_reserved_mem.h> 16 #include <linux/platform_device.h> 17 #include "sdhci.h" 18 #include "sdhci-pltfm.h" 19 20 /* SDHCI register extensions */ 21 #define SDHCI_CLOCK_PLL_EN 0x0008 22 #define SDHCI_VENDOR_PTR_R 0xE8 23 24 /* BST-specific tuning parameters */ 25 #define BST_TUNING_COUNT 0x20 26 27 /* Synopsys vendor specific registers */ 28 #define SDHC_EMMC_CTRL_R_OFFSET 0x2C 29 #define MBIU_CTRL 0x510 30 31 /* MBIU burst control bits */ 32 #define BURST_INCR16_EN BIT(3) 33 #define BURST_INCR8_EN BIT(2) 34 #define BURST_INCR4_EN BIT(1) 35 #define BURST_EN (BURST_INCR16_EN | BURST_INCR8_EN | BURST_INCR4_EN) 36 #define MBIU_BURST_MASK GENMASK(3, 0) 37 38 /* CRM (Clock/Reset/Management) register offsets */ 39 #define SDEMMC_CRM_BCLK_DIV_CTRL 0x08 40 #define SDEMMC_CRM_TIMER_DIV_CTRL 0x0C 41 #define SDEMMC_CRM_RX_CLK_CTRL 0x14 42 #define SDEMMC_CRM_VOL_CTRL 0x1C 43 #define REG_WR_PROTECT 0x88 44 #define DELAY_CHAIN_SEL 0x94 45 46 /* CRM register values and bit definitions */ 47 #define REG_WR_PROTECT_KEY 0x1234abcd 48 #define BST_VOL_STABLE_ON BIT(7) 49 #define BST_TIMER_DIV_MASK GENMASK(7, 0) 50 #define BST_TIMER_DIV_VAL 0x20 51 #define BST_TIMER_LOAD_BIT BIT(8) 52 #define BST_BCLK_EN_BIT BIT(10) 53 #define BST_RX_UPDATE_BIT BIT(11) 54 #define BST_EMMC_CTRL_RST_N BIT(2) /* eMMC card reset control */ 55 56 /* Clock frequency limits */ 57 #define BST_DEFAULT_MAX_FREQ 200000000UL /* 200 MHz */ 58 #define BST_DEFAULT_MIN_FREQ 400000UL /* 400 kHz */ 59 60 /* Clock control bit definitions */ 61 #define BST_CLOCK_DIV_MASK GENMASK(7, 0) 62 #define BST_CLOCK_DIV_SHIFT 8 63 #define BST_BCLK_DIV_MASK GENMASK(9, 0) 64 65 /* Clock frequency thresholds */ 66 #define BST_CLOCK_THRESHOLD_LOW 1500 67 68 /* Clock stability polling parameters */ 69 #define BST_CLK_STABLE_POLL_US 1000 /* Poll interval in microseconds */ 70 #define BST_CLK_STABLE_TIMEOUT_US 20000 /* Timeout for internal clock stabilization (us) */ 71 72 struct sdhci_bst_priv { 73 void __iomem *crm_reg_base; 74 }; 75 76 union sdhci_bst_rx_ctrl { 77 struct { 78 u32 rx_revert:1, 79 rx_clk_sel_sec:1, 80 rx_clk_div:4, 81 rx_clk_phase_inner:2, 82 rx_clk_sel_first:1, 83 rx_clk_phase_out:2, 84 rx_clk_en:1, 85 res0:20; 86 }; 87 u32 reg; 88 }; 89 90 static u32 sdhci_bst_crm_read(struct sdhci_pltfm_host *pltfm_host, u32 offset) 91 { 92 struct sdhci_bst_priv *priv = sdhci_pltfm_priv(pltfm_host); 93 94 return readl(priv->crm_reg_base + offset); 95 } 96 97 static void sdhci_bst_crm_write(struct sdhci_pltfm_host *pltfm_host, u32 offset, u32 value) 98 { 99 struct sdhci_bst_priv *priv = sdhci_pltfm_priv(pltfm_host); 100 101 writel(value, priv->crm_reg_base + offset); 102 } 103 104 static int sdhci_bst_wait_int_clk(struct sdhci_host *host) 105 { 106 u16 clk; 107 108 if (read_poll_timeout(sdhci_readw, clk, (clk & SDHCI_CLOCK_INT_STABLE), 109 BST_CLK_STABLE_POLL_US, BST_CLK_STABLE_TIMEOUT_US, false, 110 host, SDHCI_CLOCK_CONTROL)) 111 return -EBUSY; 112 return 0; 113 } 114 115 static unsigned int sdhci_bst_get_max_clock(struct sdhci_host *host) 116 { 117 return BST_DEFAULT_MAX_FREQ; 118 } 119 120 static unsigned int sdhci_bst_get_min_clock(struct sdhci_host *host) 121 { 122 return BST_DEFAULT_MIN_FREQ; 123 } 124 125 static void sdhci_bst_enable_clk(struct sdhci_host *host, unsigned int clk) 126 { 127 struct sdhci_pltfm_host *pltfm_host; 128 unsigned int div; 129 u32 val; 130 union sdhci_bst_rx_ctrl rx_reg; 131 132 pltfm_host = sdhci_priv(host); 133 134 /* Calculate clock divider based on target frequency */ 135 if (clk == 0) { 136 div = 0; 137 } else if (clk < BST_DEFAULT_MIN_FREQ) { 138 /* Below minimum: use max divider to get closest to min freq */ 139 div = BST_DEFAULT_MAX_FREQ / BST_DEFAULT_MIN_FREQ; 140 } else if (clk <= BST_DEFAULT_MAX_FREQ) { 141 /* Normal range: calculate divider directly */ 142 div = BST_DEFAULT_MAX_FREQ / clk; 143 } else { 144 /* Above maximum: no division needed */ 145 div = 1; 146 } 147 148 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 149 clk &= ~SDHCI_CLOCK_CARD_EN; 150 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 151 152 clk &= ~SDHCI_CLOCK_PLL_EN; 153 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 154 155 val = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_TIMER_DIV_CTRL); 156 val &= ~BST_TIMER_LOAD_BIT; 157 sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_TIMER_DIV_CTRL, val); 158 159 val = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_TIMER_DIV_CTRL); 160 val &= ~BST_TIMER_DIV_MASK; 161 val |= BST_TIMER_DIV_VAL; 162 sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_TIMER_DIV_CTRL, val); 163 164 val = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_TIMER_DIV_CTRL); 165 val |= BST_TIMER_LOAD_BIT; 166 sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_TIMER_DIV_CTRL, val); 167 168 val = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_RX_CLK_CTRL); 169 val &= ~BST_RX_UPDATE_BIT; 170 sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_RX_CLK_CTRL, val); 171 172 rx_reg.reg = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_RX_CLK_CTRL); 173 174 rx_reg.rx_revert = 0; 175 rx_reg.rx_clk_sel_sec = 1; 176 rx_reg.rx_clk_div = 4; 177 rx_reg.rx_clk_phase_inner = 2; 178 rx_reg.rx_clk_sel_first = 0; 179 rx_reg.rx_clk_phase_out = 2; 180 181 sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_RX_CLK_CTRL, rx_reg.reg); 182 183 val = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_RX_CLK_CTRL); 184 val |= BST_RX_UPDATE_BIT; 185 sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_RX_CLK_CTRL, val); 186 187 /* Disable clock first */ 188 val = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_BCLK_DIV_CTRL); 189 val &= ~BST_BCLK_EN_BIT; 190 sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_BCLK_DIV_CTRL, val); 191 192 /* Setup clock divider */ 193 val = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_BCLK_DIV_CTRL); 194 val &= ~BST_BCLK_DIV_MASK; 195 val |= div; 196 sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_BCLK_DIV_CTRL, val); 197 198 /* Enable clock */ 199 val = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_BCLK_DIV_CTRL); 200 val |= BST_BCLK_EN_BIT; 201 sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_BCLK_DIV_CTRL, val); 202 203 /* RMW the clock divider bits to avoid clobbering other fields */ 204 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 205 clk &= ~(BST_CLOCK_DIV_MASK << BST_CLOCK_DIV_SHIFT); 206 clk |= (div & BST_CLOCK_DIV_MASK) << BST_CLOCK_DIV_SHIFT; 207 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 208 209 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 210 clk |= SDHCI_CLOCK_PLL_EN; 211 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 212 213 clk |= SDHCI_CLOCK_CARD_EN; 214 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 215 216 clk |= SDHCI_CLOCK_INT_EN; 217 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 218 } 219 220 static void sdhci_bst_set_clock(struct sdhci_host *host, unsigned int clock) 221 { 222 /* Turn off card/internal/PLL clocks when clock==0 to avoid idle power */ 223 u32 clk_reg = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 224 225 if (!clock) { 226 clk_reg &= ~(SDHCI_CLOCK_CARD_EN | SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_PLL_EN); 227 sdhci_writew(host, clk_reg, SDHCI_CLOCK_CONTROL); 228 return; 229 } 230 sdhci_bst_enable_clk(host, clock); 231 } 232 233 /* 234 * sdhci_bst_reset - Reset the SDHCI host controller with special 235 * handling for eMMC card reset control. 236 */ 237 static void sdhci_bst_reset(struct sdhci_host *host, u8 mask) 238 { 239 u16 vendor_ptr, emmc_ctrl_reg; 240 u32 reg; 241 242 if (host->mmc->caps2 & MMC_CAP2_NO_SD) { 243 vendor_ptr = sdhci_readw(host, SDHCI_VENDOR_PTR_R); 244 emmc_ctrl_reg = vendor_ptr + SDHC_EMMC_CTRL_R_OFFSET; 245 246 reg = sdhci_readw(host, emmc_ctrl_reg); 247 reg &= ~BST_EMMC_CTRL_RST_N; 248 sdhci_writew(host, reg, emmc_ctrl_reg); 249 sdhci_reset(host, mask); 250 usleep_range(10, 20); 251 reg = sdhci_readw(host, emmc_ctrl_reg); 252 reg |= BST_EMMC_CTRL_RST_N; 253 sdhci_writew(host, reg, emmc_ctrl_reg); 254 } else { 255 sdhci_reset(host, mask); 256 } 257 } 258 259 /* Set timeout control register to maximum value (0xE) */ 260 static void sdhci_bst_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) 261 { 262 sdhci_writeb(host, 0xE, SDHCI_TIMEOUT_CONTROL); 263 } 264 265 /* 266 * sdhci_bst_set_power - Set power mode and voltage, also configures 267 * MBIU burst mode control based on power state. 268 */ 269 static void sdhci_bst_set_power(struct sdhci_host *host, unsigned char mode, 270 unsigned short vdd) 271 { 272 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 273 u32 reg; 274 u32 val; 275 276 sdhci_set_power(host, mode, vdd); 277 278 if (mode == MMC_POWER_OFF) { 279 /* Disable MBIU burst mode */ 280 reg = sdhci_readw(host, MBIU_CTRL); 281 reg &= ~BURST_EN; /* Clear all burst enable bits */ 282 sdhci_writew(host, reg, MBIU_CTRL); 283 284 /* Disable CRM BCLK */ 285 val = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_BCLK_DIV_CTRL); 286 val &= ~BST_BCLK_EN_BIT; 287 sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_BCLK_DIV_CTRL, val); 288 289 /* Disable RX clock */ 290 val = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_RX_CLK_CTRL); 291 val &= ~BST_RX_UPDATE_BIT; 292 sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_RX_CLK_CTRL, val); 293 294 /* Turn off voltage stable power */ 295 val = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_VOL_CTRL); 296 val &= ~BST_VOL_STABLE_ON; 297 sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_VOL_CTRL, val); 298 } else { 299 /* Configure burst mode only when powered on */ 300 reg = sdhci_readw(host, MBIU_CTRL); 301 reg &= ~MBIU_BURST_MASK; /* Clear burst related bits */ 302 reg |= BURST_EN; /* Enable burst mode for better bandwidth */ 303 sdhci_writew(host, reg, MBIU_CTRL); 304 } 305 } 306 307 /* 308 * sdhci_bst_execute_tuning - Execute tuning procedure by trying different 309 * delay chain values and selecting the optimal one. 310 */ 311 static int sdhci_bst_execute_tuning(struct sdhci_host *host, u32 opcode) 312 { 313 struct sdhci_pltfm_host *pltfm_host; 314 int ret = 0, error; 315 int first_start = -1, first_end = -1, best = 0; 316 int second_start = -1, second_end = -1, has_failure = 0; 317 int i; 318 319 pltfm_host = sdhci_priv(host); 320 321 for (i = 0; i < BST_TUNING_COUNT; i++) { 322 /* Protected write */ 323 sdhci_bst_crm_write(pltfm_host, REG_WR_PROTECT, REG_WR_PROTECT_KEY); 324 /* Write tuning value */ 325 sdhci_bst_crm_write(pltfm_host, DELAY_CHAIN_SEL, (1ul << i) - 1); 326 327 /* Wait for internal clock stable before tuning */ 328 if (sdhci_bst_wait_int_clk(host)) { 329 dev_err(mmc_dev(host->mmc), "Internal clock never stabilised\n"); 330 return -EBUSY; 331 } 332 333 ret = mmc_send_tuning(host->mmc, opcode, &error); 334 if (ret != 0) { 335 has_failure = 1; 336 } else { 337 if (has_failure == 0) { 338 if (first_start == -1) 339 first_start = i; 340 first_end = i; 341 } else { 342 if (second_start == -1) 343 second_start = i; 344 second_end = i; 345 } 346 } 347 } 348 349 /* Calculate best tuning value */ 350 if (first_end - first_start >= second_end - second_start) 351 best = ((first_end - first_start) >> 1) + first_start; 352 else 353 best = ((second_end - second_start) >> 1) + second_start; 354 355 if (best < 0) 356 best = 0; 357 358 sdhci_bst_crm_write(pltfm_host, DELAY_CHAIN_SEL, (1ul << best) - 1); 359 /* Confirm internal clock stable after setting best tuning value */ 360 if (sdhci_bst_wait_int_clk(host)) { 361 dev_err(mmc_dev(host->mmc), "Internal clock never stabilised\n"); 362 return -EBUSY; 363 } 364 365 return 0; 366 } 367 368 /* Enable voltage stable power for voltage switch */ 369 static void sdhci_bst_voltage_switch(struct sdhci_host *host) 370 { 371 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 372 373 /* Enable voltage stable power */ 374 sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_VOL_CTRL, BST_VOL_STABLE_ON); 375 } 376 377 static const struct sdhci_ops sdhci_bst_ops = { 378 .set_clock = sdhci_bst_set_clock, 379 .set_bus_width = sdhci_set_bus_width, 380 .set_uhs_signaling = sdhci_set_uhs_signaling, 381 .get_min_clock = sdhci_bst_get_min_clock, 382 .get_max_clock = sdhci_bst_get_max_clock, 383 .reset = sdhci_bst_reset, 384 .set_power = sdhci_bst_set_power, 385 .set_timeout = sdhci_bst_set_timeout, 386 .platform_execute_tuning = sdhci_bst_execute_tuning, 387 .voltage_switch = sdhci_bst_voltage_switch, 388 }; 389 390 static const struct sdhci_pltfm_data sdhci_bst_pdata = { 391 .ops = &sdhci_bst_ops, 392 .quirks = SDHCI_QUIRK_BROKEN_ADMA | 393 SDHCI_QUIRK_DELAY_AFTER_POWER | 394 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | 395 SDHCI_QUIRK_INVERTED_WRITE_PROTECT, 396 .quirks2 = SDHCI_QUIRK2_BROKEN_DDR50 | 397 SDHCI_QUIRK2_TUNING_WORK_AROUND | 398 SDHCI_QUIRK2_ACMD23_BROKEN, 399 }; 400 401 static void sdhci_bst_free_bounce_buffer(struct sdhci_host *host) 402 { 403 if (host->bounce_buffer) { 404 dma_free_coherent(mmc_dev(host->mmc), host->bounce_buffer_size, 405 host->bounce_buffer, host->bounce_addr); 406 host->bounce_buffer = NULL; 407 } 408 of_reserved_mem_device_release(mmc_dev(host->mmc)); 409 } 410 411 static int sdhci_bst_alloc_bounce_buffer(struct sdhci_host *host) 412 { 413 struct mmc_host *mmc = host->mmc; 414 unsigned int bounce_size; 415 int ret; 416 417 /* Fixed SRAM bounce size to 32KB: verified config under 32-bit DMA addressing limit */ 418 bounce_size = SZ_32K; 419 420 ret = of_reserved_mem_device_init_by_idx(mmc_dev(mmc), mmc_dev(mmc)->of_node, 0); 421 if (ret) { 422 dev_err(mmc_dev(mmc), "Failed to initialize reserved memory\n"); 423 return ret; 424 } 425 426 host->bounce_buffer = dma_alloc_coherent(mmc_dev(mmc), bounce_size, 427 &host->bounce_addr, GFP_KERNEL); 428 if (!host->bounce_buffer) { 429 of_reserved_mem_device_release(mmc_dev(mmc)); 430 return -ENOMEM; 431 } 432 433 host->bounce_buffer_size = bounce_size; 434 435 return 0; 436 } 437 438 static int sdhci_bst_probe(struct platform_device *pdev) 439 { 440 struct sdhci_pltfm_host *pltfm_host; 441 struct sdhci_host *host; 442 struct sdhci_bst_priv *priv; 443 int err; 444 445 host = sdhci_pltfm_init(pdev, &sdhci_bst_pdata, sizeof(struct sdhci_bst_priv)); 446 if (IS_ERR(host)) 447 return PTR_ERR(host); 448 449 pltfm_host = sdhci_priv(host); 450 priv = sdhci_pltfm_priv(pltfm_host); /* Get platform private data */ 451 452 err = mmc_of_parse(host->mmc); 453 if (err) 454 return err; 455 456 sdhci_get_of_property(pdev); 457 458 /* Get CRM registers from the second reg entry */ 459 priv->crm_reg_base = devm_platform_ioremap_resource(pdev, 1); 460 if (IS_ERR(priv->crm_reg_base)) { 461 err = PTR_ERR(priv->crm_reg_base); 462 return err; 463 } 464 465 /* 466 * Silicon constraints for BST C1200: 467 * - System RAM base is 0x800000000 (above 32-bit addressable range) 468 * - The eMMC controller DMA engine is limited to 32-bit addressing 469 * - SMMU cannot be used on this path due to hardware design flaws 470 * - These are fixed in silicon and cannot be changed in software 471 * 472 * Bus/controller mapping: 473 * - No registers are available to reprogram the address mapping 474 * - The 32-bit DMA limit is a hard constraint of the controller IP 475 * 476 * Given these constraints, an SRAM-based bounce buffer in the 32-bit 477 * address space is required to enable eMMC DMA on this platform. 478 */ 479 err = sdhci_bst_alloc_bounce_buffer(host); 480 if (err) { 481 dev_err(&pdev->dev, "Failed to allocate bounce buffer: %d\n", err); 482 return err; 483 } 484 485 err = sdhci_add_host(host); 486 if (err) 487 goto err_free_bounce_buffer; 488 489 return 0; 490 491 err_free_bounce_buffer: 492 sdhci_bst_free_bounce_buffer(host); 493 494 return err; 495 } 496 497 static void sdhci_bst_remove(struct platform_device *pdev) 498 { 499 struct sdhci_host *host = platform_get_drvdata(pdev); 500 501 sdhci_bst_free_bounce_buffer(host); 502 sdhci_pltfm_remove(pdev); 503 } 504 505 static const struct of_device_id sdhci_bst_ids[] = { 506 { .compatible = "bst,c1200-sdhci" }, 507 {} 508 }; 509 MODULE_DEVICE_TABLE(of, sdhci_bst_ids); 510 511 static struct platform_driver sdhci_bst_driver = { 512 .driver = { 513 .name = "sdhci-bst", 514 .of_match_table = sdhci_bst_ids, 515 }, 516 .probe = sdhci_bst_probe, 517 .remove = sdhci_bst_remove, 518 }; 519 module_platform_driver(sdhci_bst_driver); 520 521 MODULE_DESCRIPTION("Black Sesame Technologies SDHCI driver (BST)"); 522 MODULE_AUTHOR("Black Sesame Technologies Co., Ltd."); 523 MODULE_LICENSE("GPL"); 524