sdhci-esdhc-mcf.c (12384B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Freescale eSDHC ColdFire family controller driver, platform bus. 4 * 5 * Copyright (c) 2020 Timesys Corporation 6 * Author: Angelo Dureghello <angelo.dureghello@timesys.it> 7 */ 8 9#include <linux/module.h> 10#include <linux/delay.h> 11#include <linux/platform_data/mmc-esdhc-mcf.h> 12#include <linux/mmc/mmc.h> 13#include "sdhci-pltfm.h" 14#include "sdhci-esdhc.h" 15 16#define ESDHC_PROCTL_D3CD 0x08 17#define ESDHC_SYS_CTRL_DTOCV_MASK 0x0f 18#define ESDHC_DEFAULT_HOST_CONTROL 0x28 19 20/* 21 * Freescale eSDHC has DMA ERR flag at bit 28, not as std spec says, bit 25. 22 */ 23#define ESDHC_INT_VENDOR_SPEC_DMA_ERR BIT(28) 24 25struct pltfm_mcf_data { 26 struct clk *clk_ipg; 27 struct clk *clk_ahb; 28 struct clk *clk_per; 29 int aside; 30 int current_bus_width; 31}; 32 33static inline void esdhc_mcf_buffer_swap32(u32 *buf, int len) 34{ 35 int i; 36 u32 temp; 37 38 len = (len + 3) >> 2; 39 40 for (i = 0; i < len; i++) { 41 temp = swab32(*buf); 42 *buf++ = temp; 43 } 44} 45 46static inline void esdhc_clrset_be(struct sdhci_host *host, 47 u32 mask, u32 val, int reg) 48{ 49 void __iomem *base = host->ioaddr + (reg & ~3); 50 u8 shift = (reg & 3) << 3; 51 52 mask <<= shift; 53 val <<= shift; 54 55 if (reg == SDHCI_HOST_CONTROL) 56 val |= ESDHC_PROCTL_D3CD; 57 58 writel((readl(base) & ~mask) | val, base); 59} 60 61/* 62 * Note: mcf is big-endian, single bytes need to be accessed at big endian 63 * offsets. 64 */ 65static void esdhc_mcf_writeb_be(struct sdhci_host *host, u8 val, int reg) 66{ 67 void __iomem *base = host->ioaddr + (reg & ~3); 68 u8 shift = (reg & 3) << 3; 69 u32 mask = ~(0xff << shift); 70 71 if (reg == SDHCI_HOST_CONTROL) { 72 u32 host_ctrl = ESDHC_DEFAULT_HOST_CONTROL; 73 u8 dma_bits = (val & SDHCI_CTRL_DMA_MASK) >> 3; 74 u8 tmp = readb(host->ioaddr + SDHCI_HOST_CONTROL + 1); 75 76 tmp &= ~0x03; 77 tmp |= dma_bits; 78 79 /* 80 * Recomposition needed, restore always endianness and 81 * keep D3CD and AI, just setting bus width. 82 */ 83 host_ctrl |= val; 84 host_ctrl |= (dma_bits << 8); 85 writel(host_ctrl, host->ioaddr + SDHCI_HOST_CONTROL); 86 87 return; 88 } 89 90 writel((readl(base) & mask) | (val << shift), base); 91} 92 93static void esdhc_mcf_writew_be(struct sdhci_host *host, u16 val, int reg) 94{ 95 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 96 struct pltfm_mcf_data *mcf_data = sdhci_pltfm_priv(pltfm_host); 97 void __iomem *base = host->ioaddr + (reg & ~3); 98 u8 shift = (reg & 3) << 3; 99 u32 mask = ~(0xffff << shift); 100 101 switch (reg) { 102 case SDHCI_TRANSFER_MODE: 103 mcf_data->aside = val; 104 return; 105 case SDHCI_COMMAND: 106 if (host->cmd->opcode == MMC_STOP_TRANSMISSION) 107 val |= SDHCI_CMD_ABORTCMD; 108 109 /* 110 * As for the fsl driver, 111 * we have to set the mode in a single write here. 112 */ 113 writel(val << 16 | mcf_data->aside, 114 host->ioaddr + SDHCI_TRANSFER_MODE); 115 return; 116 } 117 118 writel((readl(base) & mask) | (val << shift), base); 119} 120 121static void esdhc_mcf_writel_be(struct sdhci_host *host, u32 val, int reg) 122{ 123 writel(val, host->ioaddr + reg); 124} 125 126static u8 esdhc_mcf_readb_be(struct sdhci_host *host, int reg) 127{ 128 if (reg == SDHCI_HOST_CONTROL) { 129 u8 __iomem *base = host->ioaddr + (reg & ~3); 130 u16 val = readw(base + 2); 131 u8 dma_bits = (val >> 5) & SDHCI_CTRL_DMA_MASK; 132 u8 host_ctrl = val & 0xff; 133 134 host_ctrl &= ~SDHCI_CTRL_DMA_MASK; 135 host_ctrl |= dma_bits; 136 137 return host_ctrl; 138 } 139 140 return readb(host->ioaddr + (reg ^ 0x3)); 141} 142 143static u16 esdhc_mcf_readw_be(struct sdhci_host *host, int reg) 144{ 145 /* 146 * For SDHCI_HOST_VERSION, sdhci specs defines 0xFE, 147 * a wrong offset for us, we are at 0xFC. 148 */ 149 if (reg == SDHCI_HOST_VERSION) 150 reg -= 2; 151 152 return readw(host->ioaddr + (reg ^ 0x2)); 153} 154 155static u32 esdhc_mcf_readl_be(struct sdhci_host *host, int reg) 156{ 157 u32 val; 158 159 val = readl(host->ioaddr + reg); 160 161 /* 162 * RM (25.3.9) sd pin clock must never exceed 25Mhz. 163 * So forcing legacy mode at 25Mhz. 164 */ 165 if (unlikely(reg == SDHCI_CAPABILITIES)) 166 val &= ~SDHCI_CAN_DO_HISPD; 167 168 if (unlikely(reg == SDHCI_INT_STATUS)) { 169 if (val & ESDHC_INT_VENDOR_SPEC_DMA_ERR) { 170 val &= ~ESDHC_INT_VENDOR_SPEC_DMA_ERR; 171 val |= SDHCI_INT_ADMA_ERROR; 172 } 173 } 174 175 return val; 176} 177 178static unsigned int esdhc_mcf_get_max_timeout_count(struct sdhci_host *host) 179{ 180 return 1 << 27; 181} 182 183static void esdhc_mcf_set_timeout(struct sdhci_host *host, 184 struct mmc_command *cmd) 185{ 186 /* Use maximum timeout counter */ 187 esdhc_clrset_be(host, ESDHC_SYS_CTRL_DTOCV_MASK, 0xE, 188 SDHCI_TIMEOUT_CONTROL); 189} 190 191static void esdhc_mcf_reset(struct sdhci_host *host, u8 mask) 192{ 193 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 194 struct pltfm_mcf_data *mcf_data = sdhci_pltfm_priv(pltfm_host); 195 196 sdhci_reset(host, mask); 197 198 esdhc_clrset_be(host, ESDHC_CTRL_BUSWIDTH_MASK, 199 mcf_data->current_bus_width, SDHCI_HOST_CONTROL); 200 201 sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); 202 sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); 203} 204 205static unsigned int esdhc_mcf_pltfm_get_max_clock(struct sdhci_host *host) 206{ 207 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 208 209 return pltfm_host->clock; 210} 211 212static unsigned int esdhc_mcf_pltfm_get_min_clock(struct sdhci_host *host) 213{ 214 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 215 216 return pltfm_host->clock / 256 / 16; 217} 218 219static void esdhc_mcf_pltfm_set_clock(struct sdhci_host *host, 220 unsigned int clock) 221{ 222 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 223 unsigned long *pll_dr = (unsigned long *)MCF_PLL_DR; 224 u32 fvco, fsys, fesdhc, temp; 225 const int sdclkfs[] = {2, 4, 8, 16, 32, 64, 128, 256}; 226 int delta, old_delta = clock; 227 int i, q, ri, rq; 228 229 if (clock == 0) { 230 host->mmc->actual_clock = 0; 231 return; 232 } 233 234 /* 235 * ColdFire eSDHC clock.s 236 * 237 * pll -+-> / outdiv1 --> fsys 238 * +-> / outdiv3 --> eSDHC clock ---> / SDCCLKFS / DVS 239 * 240 * mcf5441x datasheet says: 241 * (8.1.2) eSDHC should be 40 MHz max 242 * (25.3.9) eSDHC input is, as example, 96 Mhz ... 243 * (25.3.9) sd pin clock must never exceed 25Mhz 244 * 245 * fvco = fsys * outdvi1 + 1 246 * fshdc = fvco / outdiv3 + 1 247 */ 248 temp = readl(pll_dr); 249 fsys = pltfm_host->clock; 250 fvco = fsys * ((temp & 0x1f) + 1); 251 fesdhc = fvco / (((temp >> 10) & 0x1f) + 1); 252 253 for (i = 0; i < 8; ++i) { 254 int result = fesdhc / sdclkfs[i]; 255 256 for (q = 1; q < 17; ++q) { 257 int finale = result / q; 258 259 delta = abs(clock - finale); 260 261 if (delta < old_delta) { 262 old_delta = delta; 263 ri = i; 264 rq = q; 265 } 266 } 267 } 268 269 /* 270 * Apply divisors and re-enable all the clocks 271 */ 272 temp = ((sdclkfs[ri] >> 1) << 8) | ((rq - 1) << 4) | 273 (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN); 274 esdhc_clrset_be(host, 0x0000fff7, temp, SDHCI_CLOCK_CONTROL); 275 276 host->mmc->actual_clock = clock; 277 278 mdelay(1); 279} 280 281static void esdhc_mcf_pltfm_set_bus_width(struct sdhci_host *host, int width) 282{ 283 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 284 struct pltfm_mcf_data *mcf_data = sdhci_pltfm_priv(pltfm_host); 285 286 switch (width) { 287 case MMC_BUS_WIDTH_4: 288 mcf_data->current_bus_width = ESDHC_CTRL_4BITBUS; 289 break; 290 default: 291 mcf_data->current_bus_width = 0; 292 break; 293 } 294 295 esdhc_clrset_be(host, ESDHC_CTRL_BUSWIDTH_MASK, 296 mcf_data->current_bus_width, SDHCI_HOST_CONTROL); 297} 298 299static void esdhc_mcf_request_done(struct sdhci_host *host, 300 struct mmc_request *mrq) 301{ 302 struct scatterlist *sg; 303 u32 *buffer; 304 int i; 305 306 if (!mrq->data || !mrq->data->bytes_xfered) 307 goto exit_done; 308 309 if (mmc_get_dma_dir(mrq->data) != DMA_FROM_DEVICE) 310 goto exit_done; 311 312 /* 313 * On mcf5441x there is no hw sdma option/flag to select the dma 314 * transfer endiannes. A swap after the transfer is needed. 315 */ 316 for_each_sg(mrq->data->sg, sg, mrq->data->sg_len, i) { 317 buffer = (u32 *)sg_virt(sg); 318 esdhc_mcf_buffer_swap32(buffer, sg->length); 319 } 320 321exit_done: 322 mmc_request_done(host->mmc, mrq); 323} 324 325static void esdhc_mcf_copy_to_bounce_buffer(struct sdhci_host *host, 326 struct mmc_data *data, 327 unsigned int length) 328{ 329 sg_copy_to_buffer(data->sg, data->sg_len, 330 host->bounce_buffer, length); 331 332 esdhc_mcf_buffer_swap32((u32 *)host->bounce_buffer, 333 data->blksz * data->blocks); 334} 335 336static struct sdhci_ops sdhci_esdhc_ops = { 337 .reset = esdhc_mcf_reset, 338 .set_clock = esdhc_mcf_pltfm_set_clock, 339 .get_max_clock = esdhc_mcf_pltfm_get_max_clock, 340 .get_min_clock = esdhc_mcf_pltfm_get_min_clock, 341 .set_bus_width = esdhc_mcf_pltfm_set_bus_width, 342 .get_max_timeout_count = esdhc_mcf_get_max_timeout_count, 343 .set_timeout = esdhc_mcf_set_timeout, 344 .write_b = esdhc_mcf_writeb_be, 345 .write_w = esdhc_mcf_writew_be, 346 .write_l = esdhc_mcf_writel_be, 347 .read_b = esdhc_mcf_readb_be, 348 .read_w = esdhc_mcf_readw_be, 349 .read_l = esdhc_mcf_readl_be, 350 .copy_to_bounce_buffer = esdhc_mcf_copy_to_bounce_buffer, 351 .request_done = esdhc_mcf_request_done, 352}; 353 354static const struct sdhci_pltfm_data sdhci_esdhc_mcf_pdata = { 355 .ops = &sdhci_esdhc_ops, 356 .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_FORCE_DMA, 357 /* 358 * Mandatory quirk, 359 * controller does not support cmd23, 360 * without, on > 8G cards cmd23 is used, and 361 * driver times out. 362 */ 363 SDHCI_QUIRK2_HOST_NO_CMD23, 364}; 365 366static int esdhc_mcf_plat_init(struct sdhci_host *host, 367 struct pltfm_mcf_data *mcf_data) 368{ 369 struct mcf_esdhc_platform_data *plat_data; 370 struct device *dev = mmc_dev(host->mmc); 371 372 if (!dev->platform_data) { 373 dev_err(dev, "no platform data!\n"); 374 return -EINVAL; 375 } 376 377 plat_data = (struct mcf_esdhc_platform_data *)dev->platform_data; 378 379 /* Card_detect */ 380 switch (plat_data->cd_type) { 381 default: 382 case ESDHC_CD_CONTROLLER: 383 /* We have a working card_detect back */ 384 host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; 385 break; 386 case ESDHC_CD_PERMANENT: 387 host->mmc->caps |= MMC_CAP_NONREMOVABLE; 388 break; 389 case ESDHC_CD_NONE: 390 break; 391 } 392 393 switch (plat_data->max_bus_width) { 394 case 4: 395 host->mmc->caps |= MMC_CAP_4_BIT_DATA; 396 break; 397 case 1: 398 default: 399 host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; 400 break; 401 } 402 403 return 0; 404} 405 406static int sdhci_esdhc_mcf_probe(struct platform_device *pdev) 407{ 408 struct sdhci_host *host; 409 struct sdhci_pltfm_host *pltfm_host; 410 struct pltfm_mcf_data *mcf_data; 411 int err; 412 413 host = sdhci_pltfm_init(pdev, &sdhci_esdhc_mcf_pdata, 414 sizeof(*mcf_data)); 415 416 if (IS_ERR(host)) 417 return PTR_ERR(host); 418 419 pltfm_host = sdhci_priv(host); 420 mcf_data = sdhci_pltfm_priv(pltfm_host); 421 422 host->sdma_boundary = 0; 423 424 host->flags |= SDHCI_AUTO_CMD12; 425 426 mcf_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); 427 if (IS_ERR(mcf_data->clk_ipg)) { 428 err = PTR_ERR(mcf_data->clk_ipg); 429 goto err_exit; 430 } 431 432 mcf_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); 433 if (IS_ERR(mcf_data->clk_ahb)) { 434 err = PTR_ERR(mcf_data->clk_ahb); 435 goto err_exit; 436 } 437 438 mcf_data->clk_per = devm_clk_get(&pdev->dev, "per"); 439 if (IS_ERR(mcf_data->clk_per)) { 440 err = PTR_ERR(mcf_data->clk_per); 441 goto err_exit; 442 } 443 444 pltfm_host->clk = mcf_data->clk_per; 445 pltfm_host->clock = clk_get_rate(pltfm_host->clk); 446 err = clk_prepare_enable(mcf_data->clk_per); 447 if (err) 448 goto err_exit; 449 450 err = clk_prepare_enable(mcf_data->clk_ipg); 451 if (err) 452 goto unprep_per; 453 454 err = clk_prepare_enable(mcf_data->clk_ahb); 455 if (err) 456 goto unprep_ipg; 457 458 err = esdhc_mcf_plat_init(host, mcf_data); 459 if (err) 460 goto unprep_ahb; 461 462 err = sdhci_setup_host(host); 463 if (err) 464 goto unprep_ahb; 465 466 if (!host->bounce_buffer) { 467 dev_err(&pdev->dev, "bounce buffer not allocated"); 468 err = -ENOMEM; 469 goto cleanup; 470 } 471 472 err = __sdhci_add_host(host); 473 if (err) 474 goto cleanup; 475 476 return 0; 477 478cleanup: 479 sdhci_cleanup_host(host); 480unprep_ahb: 481 clk_disable_unprepare(mcf_data->clk_ahb); 482unprep_ipg: 483 clk_disable_unprepare(mcf_data->clk_ipg); 484unprep_per: 485 clk_disable_unprepare(mcf_data->clk_per); 486err_exit: 487 sdhci_pltfm_free(pdev); 488 489 return err; 490} 491 492static int sdhci_esdhc_mcf_remove(struct platform_device *pdev) 493{ 494 struct sdhci_host *host = platform_get_drvdata(pdev); 495 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 496 struct pltfm_mcf_data *mcf_data = sdhci_pltfm_priv(pltfm_host); 497 498 sdhci_remove_host(host, 0); 499 500 clk_disable_unprepare(mcf_data->clk_ipg); 501 clk_disable_unprepare(mcf_data->clk_ahb); 502 clk_disable_unprepare(mcf_data->clk_per); 503 504 sdhci_pltfm_free(pdev); 505 506 return 0; 507} 508 509static struct platform_driver sdhci_esdhc_mcf_driver = { 510 .driver = { 511 .name = "sdhci-esdhc-mcf", 512 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 513 }, 514 .probe = sdhci_esdhc_mcf_probe, 515 .remove = sdhci_esdhc_mcf_remove, 516}; 517 518module_platform_driver(sdhci_esdhc_mcf_driver); 519 520MODULE_DESCRIPTION("SDHCI driver for Freescale ColdFire eSDHC"); 521MODULE_AUTHOR("Angelo Dureghello <angelo.dureghello@timesys.com>"); 522MODULE_LICENSE("GPL v2");