1 /* linux/drivers/mmc/host/sdhci-s3c.c 2 * 3 * Copyright 2008 Openmoko Inc. 4 * Copyright 2008 Simtec Electronics 5 * Ben Dooks <ben@simtec.co.uk> 6 * http://armlinux.simtec.co.uk/ 7 * 8 * SDHCI (HSMMC) support for Samsung SoC 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15 #include <linux/delay.h> 16 #include <linux/dma-mapping.h> 17 #include <linux/platform_device.h> 18 #include <linux/slab.h> 19 #include <linux/clk.h> 20 #include <linux/io.h> 21 22 #include <linux/mmc/host.h> 23 24 #include <plat/sdhci.h> 25 #include <plat/regs-sdhci.h> 26 27 #include "sdhci.h" 28 29 #define MAX_BUS_CLK (4) 30 31 /** 32 * struct sdhci_s3c - S3C SDHCI instance 33 * @host: The SDHCI host created 34 * @pdev: The platform device we where created from. 35 * @ioarea: The resource created when we claimed the IO area. 36 * @pdata: The platform data for this controller. 37 * @cur_clk: The index of the current bus clock. 38 * @clk_io: The clock for the internal bus interface. 39 * @clk_bus: The clocks that are available for the SD/MMC bus clock. 40 */ 41 struct sdhci_s3c { 42 struct sdhci_host *host; 43 struct platform_device *pdev; 44 struct resource *ioarea; 45 struct s3c_sdhci_platdata *pdata; 46 unsigned int cur_clk; 47 48 struct clk *clk_io; 49 struct clk *clk_bus[MAX_BUS_CLK]; 50 }; 51 52 static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host) 53 { 54 return sdhci_priv(host); 55 } 56 57 /** 58 * get_curclk - convert ctrl2 register to clock source number 59 * @ctrl2: Control2 register value. 60 */ 61 static u32 get_curclk(u32 ctrl2) 62 { 63 ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK; 64 ctrl2 >>= S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; 65 66 return ctrl2; 67 } 68 69 static void sdhci_s3c_check_sclk(struct sdhci_host *host) 70 { 71 struct sdhci_s3c *ourhost = to_s3c(host); 72 u32 tmp = readl(host->ioaddr + S3C_SDHCI_CONTROL2); 73 74 if (get_curclk(tmp) != ourhost->cur_clk) { 75 dev_dbg(&ourhost->pdev->dev, "restored ctrl2 clock setting\n"); 76 77 tmp &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK; 78 tmp |= ourhost->cur_clk << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; 79 writel(tmp, host->ioaddr + 0x80); 80 } 81 } 82 83 /** 84 * sdhci_s3c_get_max_clk - callback to get maximum clock frequency. 85 * @host: The SDHCI host instance. 86 * 87 * Callback to return the maximum clock rate acheivable by the controller. 88 */ 89 static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host) 90 { 91 struct sdhci_s3c *ourhost = to_s3c(host); 92 struct clk *busclk; 93 unsigned int rate, max; 94 int clk; 95 96 /* note, a reset will reset the clock source */ 97 98 sdhci_s3c_check_sclk(host); 99 100 for (max = 0, clk = 0; clk < MAX_BUS_CLK; clk++) { 101 busclk = ourhost->clk_bus[clk]; 102 if (!busclk) 103 continue; 104 105 rate = clk_get_rate(busclk); 106 if (rate > max) 107 max = rate; 108 } 109 110 return max; 111 } 112 113 static unsigned int sdhci_s3c_get_timeout_clk(struct sdhci_host *host) 114 { 115 return sdhci_s3c_get_max_clk(host) / 1000000; 116 } 117 118 /** 119 * sdhci_s3c_consider_clock - consider one the bus clocks for current setting 120 * @ourhost: Our SDHCI instance. 121 * @src: The source clock index. 122 * @wanted: The clock frequency wanted. 123 */ 124 static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost, 125 unsigned int src, 126 unsigned int wanted) 127 { 128 unsigned long rate; 129 struct clk *clksrc = ourhost->clk_bus[src]; 130 int div; 131 132 if (!clksrc) 133 return UINT_MAX; 134 135 rate = clk_get_rate(clksrc); 136 137 for (div = 1; div < 256; div *= 2) { 138 if ((rate / div) <= wanted) 139 break; 140 } 141 142 dev_dbg(&ourhost->pdev->dev, "clk %d: rate %ld, want %d, got %ld\n", 143 src, rate, wanted, rate / div); 144 145 return (wanted - (rate / div)); 146 } 147 148 /** 149 * sdhci_s3c_set_clock - callback on clock change 150 * @host: The SDHCI host being changed 151 * @clock: The clock rate being requested. 152 * 153 * When the card's clock is going to be changed, look at the new frequency 154 * and find the best clock source to go with it. 155 */ 156 static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock) 157 { 158 struct sdhci_s3c *ourhost = to_s3c(host); 159 unsigned int best = UINT_MAX; 160 unsigned int delta; 161 int best_src = 0; 162 int src; 163 u32 ctrl; 164 165 /* don't bother if the clock is going off. */ 166 if (clock == 0) 167 return; 168 169 for (src = 0; src < MAX_BUS_CLK; src++) { 170 delta = sdhci_s3c_consider_clock(ourhost, src, clock); 171 if (delta < best) { 172 best = delta; 173 best_src = src; 174 } 175 } 176 177 dev_dbg(&ourhost->pdev->dev, 178 "selected source %d, clock %d, delta %d\n", 179 best_src, clock, best); 180 181 /* select the new clock source */ 182 183 if (ourhost->cur_clk != best_src) { 184 struct clk *clk = ourhost->clk_bus[best_src]; 185 186 /* turn clock off to card before changing clock source */ 187 writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); 188 189 ourhost->cur_clk = best_src; 190 host->max_clk = clk_get_rate(clk); 191 host->timeout_clk = sdhci_s3c_get_timeout_clk(host); 192 193 ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2); 194 ctrl &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK; 195 ctrl |= best_src << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; 196 writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2); 197 } 198 199 /* reconfigure the hardware for new clock rate */ 200 201 { 202 struct mmc_ios ios; 203 204 ios.clock = clock; 205 206 if (ourhost->pdata->cfg_card) 207 (ourhost->pdata->cfg_card)(ourhost->pdev, host->ioaddr, 208 &ios, NULL); 209 } 210 } 211 212 static struct sdhci_ops sdhci_s3c_ops = { 213 .get_max_clock = sdhci_s3c_get_max_clk, 214 .get_timeout_clock = sdhci_s3c_get_timeout_clk, 215 .set_clock = sdhci_s3c_set_clock, 216 }; 217 218 static int __devinit sdhci_s3c_probe(struct platform_device *pdev) 219 { 220 struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data; 221 struct device *dev = &pdev->dev; 222 struct sdhci_host *host; 223 struct sdhci_s3c *sc; 224 struct resource *res; 225 int ret, irq, ptr, clks; 226 227 if (!pdata) { 228 dev_err(dev, "no device data specified\n"); 229 return -ENOENT; 230 } 231 232 irq = platform_get_irq(pdev, 0); 233 if (irq < 0) { 234 dev_err(dev, "no irq specified\n"); 235 return irq; 236 } 237 238 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 239 if (!res) { 240 dev_err(dev, "no memory specified\n"); 241 return -ENOENT; 242 } 243 244 host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c)); 245 if (IS_ERR(host)) { 246 dev_err(dev, "sdhci_alloc_host() failed\n"); 247 return PTR_ERR(host); 248 } 249 250 sc = sdhci_priv(host); 251 252 sc->host = host; 253 sc->pdev = pdev; 254 sc->pdata = pdata; 255 256 platform_set_drvdata(pdev, host); 257 258 sc->clk_io = clk_get(dev, "hsmmc"); 259 if (IS_ERR(sc->clk_io)) { 260 dev_err(dev, "failed to get io clock\n"); 261 ret = PTR_ERR(sc->clk_io); 262 goto err_io_clk; 263 } 264 265 /* enable the local io clock and keep it running for the moment. */ 266 clk_enable(sc->clk_io); 267 268 for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { 269 struct clk *clk; 270 char *name = pdata->clocks[ptr]; 271 272 if (name == NULL) 273 continue; 274 275 clk = clk_get(dev, name); 276 if (IS_ERR(clk)) { 277 dev_err(dev, "failed to get clock %s\n", name); 278 continue; 279 } 280 281 clks++; 282 sc->clk_bus[ptr] = clk; 283 clk_enable(clk); 284 285 dev_info(dev, "clock source %d: %s (%ld Hz)\n", 286 ptr, name, clk_get_rate(clk)); 287 } 288 289 if (clks == 0) { 290 dev_err(dev, "failed to find any bus clocks\n"); 291 ret = -ENOENT; 292 goto err_no_busclks; 293 } 294 295 sc->ioarea = request_mem_region(res->start, resource_size(res), 296 mmc_hostname(host->mmc)); 297 if (!sc->ioarea) { 298 dev_err(dev, "failed to reserve register area\n"); 299 ret = -ENXIO; 300 goto err_req_regs; 301 } 302 303 host->ioaddr = ioremap_nocache(res->start, resource_size(res)); 304 if (!host->ioaddr) { 305 dev_err(dev, "failed to map registers\n"); 306 ret = -ENXIO; 307 goto err_req_regs; 308 } 309 310 /* Ensure we have minimal gpio selected CMD/CLK/Detect */ 311 if (pdata->cfg_gpio) 312 pdata->cfg_gpio(pdev, pdata->max_width); 313 314 host->hw_name = "samsung-hsmmc"; 315 host->ops = &sdhci_s3c_ops; 316 host->quirks = 0; 317 host->irq = irq; 318 319 /* Setup quirks for the controller */ 320 host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC; 321 322 #ifndef CONFIG_MMC_SDHCI_S3C_DMA 323 324 /* we currently see overruns on errors, so disable the SDMA 325 * support as well. */ 326 host->quirks |= SDHCI_QUIRK_BROKEN_DMA; 327 328 #endif /* CONFIG_MMC_SDHCI_S3C_DMA */ 329 330 /* It seems we do not get an DATA transfer complete on non-busy 331 * transfers, not sure if this is a problem with this specific 332 * SDHCI block, or a missing configuration that needs to be set. */ 333 host->quirks |= SDHCI_QUIRK_NO_BUSY_IRQ; 334 335 host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR | 336 SDHCI_QUIRK_32BIT_DMA_SIZE); 337 338 ret = sdhci_add_host(host); 339 if (ret) { 340 dev_err(dev, "sdhci_add_host() failed\n"); 341 goto err_add_host; 342 } 343 344 return 0; 345 346 err_add_host: 347 release_resource(sc->ioarea); 348 kfree(sc->ioarea); 349 350 err_req_regs: 351 for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { 352 clk_disable(sc->clk_bus[ptr]); 353 clk_put(sc->clk_bus[ptr]); 354 } 355 356 err_no_busclks: 357 clk_disable(sc->clk_io); 358 clk_put(sc->clk_io); 359 360 err_io_clk: 361 sdhci_free_host(host); 362 363 return ret; 364 } 365 366 static int __devexit sdhci_s3c_remove(struct platform_device *pdev) 367 { 368 struct sdhci_host *host = platform_get_drvdata(pdev); 369 struct sdhci_s3c *sc = sdhci_priv(host); 370 int ptr; 371 372 sdhci_remove_host(host, 1); 373 374 for (ptr = 0; ptr < 3; ptr++) { 375 clk_disable(sc->clk_bus[ptr]); 376 clk_put(sc->clk_bus[ptr]); 377 } 378 clk_disable(sc->clk_io); 379 clk_put(sc->clk_io); 380 381 iounmap(host->ioaddr); 382 release_resource(sc->ioarea); 383 kfree(sc->ioarea); 384 385 sdhci_free_host(host); 386 platform_set_drvdata(pdev, NULL); 387 388 return 0; 389 } 390 391 #ifdef CONFIG_PM 392 393 static int sdhci_s3c_suspend(struct platform_device *dev, pm_message_t pm) 394 { 395 struct sdhci_host *host = platform_get_drvdata(dev); 396 397 sdhci_suspend_host(host, pm); 398 return 0; 399 } 400 401 static int sdhci_s3c_resume(struct platform_device *dev) 402 { 403 struct sdhci_host *host = platform_get_drvdata(dev); 404 405 sdhci_resume_host(host); 406 return 0; 407 } 408 409 #else 410 #define sdhci_s3c_suspend NULL 411 #define sdhci_s3c_resume NULL 412 #endif 413 414 static struct platform_driver sdhci_s3c_driver = { 415 .probe = sdhci_s3c_probe, 416 .remove = __devexit_p(sdhci_s3c_remove), 417 .suspend = sdhci_s3c_suspend, 418 .resume = sdhci_s3c_resume, 419 .driver = { 420 .owner = THIS_MODULE, 421 .name = "s3c-sdhci", 422 }, 423 }; 424 425 static int __init sdhci_s3c_init(void) 426 { 427 return platform_driver_register(&sdhci_s3c_driver); 428 } 429 430 static void __exit sdhci_s3c_exit(void) 431 { 432 platform_driver_unregister(&sdhci_s3c_driver); 433 } 434 435 module_init(sdhci_s3c_init); 436 module_exit(sdhci_s3c_exit); 437 438 MODULE_DESCRIPTION("Samsung SDHCI (HSMMC) glue"); 439 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 440 MODULE_LICENSE("GPL v2"); 441 MODULE_ALIAS("platform:s3c-sdhci"); 442