1/* 2 * SDHCI support for SiRF primaII and marco SoCs 3 * 4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. 5 * 6 * Licensed under GPLv2 or later. 7 */ 8 9#include <linux/delay.h> 10#include <linux/device.h> 11#include <linux/mmc/host.h> 12#include <linux/module.h> 13#include <linux/of.h> 14#include <linux/of_gpio.h> 15#include <linux/mmc/slot-gpio.h> 16#include "sdhci-pltfm.h" 17 18#define SDHCI_CLK_DELAY_SETTING 0x4C 19#define SDHCI_SIRF_8BITBUS BIT(3) 20#define SIRF_TUNING_COUNT 16384 21 22struct sdhci_sirf_priv { 23 int gpio_cd; 24}; 25 26static void sdhci_sirf_set_bus_width(struct sdhci_host *host, int width) 27{ 28 u8 ctrl; 29 30 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 31 ctrl &= ~(SDHCI_CTRL_4BITBUS | SDHCI_SIRF_8BITBUS); 32 33 /* 34 * CSR atlas7 and prima2 SD host version is not 3.0 35 * 8bit-width enable bit of CSR SD hosts is 3, 36 * while stardard hosts use bit 5 37 */ 38 if (width == MMC_BUS_WIDTH_8) 39 ctrl |= SDHCI_SIRF_8BITBUS; 40 else if (width == MMC_BUS_WIDTH_4) 41 ctrl |= SDHCI_CTRL_4BITBUS; 42 43 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 44} 45 46static u32 sdhci_sirf_readl_le(struct sdhci_host *host, int reg) 47{ 48 u32 val = readl(host->ioaddr + reg); 49 50 if (unlikely((reg == SDHCI_CAPABILITIES_1) && 51 (host->mmc->caps & MMC_CAP_UHS_SDR50))) { 52 /* fake CAP_1 register */ 53 val = SDHCI_SUPPORT_DDR50 | 54 SDHCI_SUPPORT_SDR50 | SDHCI_USE_SDR50_TUNING; 55 } 56 57 if (unlikely(reg == SDHCI_SLOT_INT_STATUS)) { 58 u32 prss = val; 59 /* fake chips as V3.0 host conreoller */ 60 prss &= ~(0xFF << 16); 61 val = prss | (SDHCI_SPEC_300 << 16); 62 } 63 return val; 64} 65 66static u16 sdhci_sirf_readw_le(struct sdhci_host *host, int reg) 67{ 68 u16 ret = 0; 69 70 ret = readw(host->ioaddr + reg); 71 72 if (unlikely(reg == SDHCI_HOST_VERSION)) { 73 ret = readw(host->ioaddr + SDHCI_HOST_VERSION); 74 ret |= SDHCI_SPEC_300; 75 } 76 77 return ret; 78} 79 80static int sdhci_sirf_execute_tuning(struct sdhci_host *host, u32 opcode) 81{ 82 int tuning_seq_cnt = 3; 83 int phase; 84 u8 tuned_phase_cnt = 0; 85 int rc = 0, longest_range = 0; 86 int start = -1, end = 0, tuning_value = -1, range = 0; 87 u16 clock_setting; 88 struct mmc_host *mmc = host->mmc; 89 90 clock_setting = sdhci_readw(host, SDHCI_CLK_DELAY_SETTING); 91 clock_setting &= ~0x3fff; 92 93retry: 94 phase = 0; 95 tuned_phase_cnt = 0; 96 do { 97 sdhci_writel(host, 98 clock_setting | phase, 99 SDHCI_CLK_DELAY_SETTING); 100 101 if (!mmc_send_tuning(mmc, opcode, NULL)) { 102 /* Tuning is successful at this tuning point */ 103 tuned_phase_cnt++; 104 dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n", 105 mmc_hostname(mmc), phase); 106 if (start == -1) 107 start = phase; 108 end = phase; 109 range++; 110 if (phase == (SIRF_TUNING_COUNT - 1) 111 && range > longest_range) 112 tuning_value = (start + end) / 2; 113 } else { 114 dev_dbg(mmc_dev(mmc), "%s: Found bad phase = %d\n", 115 mmc_hostname(mmc), phase); 116 if (range > longest_range) { 117 tuning_value = (start + end) / 2; 118 longest_range = range; 119 } 120 start = -1; 121 end = range = 0; 122 } 123 } while (++phase < SIRF_TUNING_COUNT); 124 125 if (tuned_phase_cnt && tuning_value > 0) { 126 /* 127 * Finally set the selected phase in delay 128 * line hw block. 129 */ 130 phase = tuning_value; 131 sdhci_writel(host, 132 clock_setting | phase, 133 SDHCI_CLK_DELAY_SETTING); 134 135 dev_dbg(mmc_dev(mmc), "%s: Setting the tuning phase to %d\n", 136 mmc_hostname(mmc), phase); 137 } else { 138 if (--tuning_seq_cnt) 139 goto retry; 140 /* Tuning failed */ 141 dev_dbg(mmc_dev(mmc), "%s: No tuning point found\n", 142 mmc_hostname(mmc)); 143 rc = -EIO; 144 } 145 146 return rc; 147} 148 149static struct sdhci_ops sdhci_sirf_ops = { 150 .read_l = sdhci_sirf_readl_le, 151 .read_w = sdhci_sirf_readw_le, 152 .platform_execute_tuning = sdhci_sirf_execute_tuning, 153 .set_clock = sdhci_set_clock, 154 .get_max_clock = sdhci_pltfm_clk_get_max_clock, 155 .set_bus_width = sdhci_sirf_set_bus_width, 156 .reset = sdhci_reset, 157 .set_uhs_signaling = sdhci_set_uhs_signaling, 158}; 159 160static struct sdhci_pltfm_data sdhci_sirf_pdata = { 161 .ops = &sdhci_sirf_ops, 162 .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | 163 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | 164 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | 165 SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS, 166 .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, 167}; 168 169static int sdhci_sirf_probe(struct platform_device *pdev) 170{ 171 struct sdhci_host *host; 172 struct sdhci_pltfm_host *pltfm_host; 173 struct sdhci_sirf_priv *priv; 174 struct clk *clk; 175 int gpio_cd; 176 int ret; 177 178 clk = devm_clk_get(&pdev->dev, NULL); 179 if (IS_ERR(clk)) { 180 dev_err(&pdev->dev, "unable to get clock"); 181 return PTR_ERR(clk); 182 } 183 184 if (pdev->dev.of_node) 185 gpio_cd = of_get_named_gpio(pdev->dev.of_node, "cd-gpios", 0); 186 else 187 gpio_cd = -EINVAL; 188 189 host = sdhci_pltfm_init(pdev, &sdhci_sirf_pdata, sizeof(struct sdhci_sirf_priv)); 190 if (IS_ERR(host)) 191 return PTR_ERR(host); 192 193 pltfm_host = sdhci_priv(host); 194 pltfm_host->clk = clk; 195 priv = sdhci_pltfm_priv(pltfm_host); 196 priv->gpio_cd = gpio_cd; 197 198 sdhci_get_of_property(pdev); 199 200 ret = clk_prepare_enable(pltfm_host->clk); 201 if (ret) 202 goto err_clk_prepare; 203 204 ret = sdhci_add_host(host); 205 if (ret) 206 goto err_sdhci_add; 207 208 /* 209 * We must request the IRQ after sdhci_add_host(), as the tasklet only 210 * gets setup in sdhci_add_host() and we oops. 211 */ 212 if (gpio_is_valid(priv->gpio_cd)) { 213 ret = mmc_gpio_request_cd(host->mmc, priv->gpio_cd, 0); 214 if (ret) { 215 dev_err(&pdev->dev, "card detect irq request failed: %d\n", 216 ret); 217 goto err_request_cd; 218 } 219 mmc_gpiod_request_cd_irq(host->mmc); 220 } 221 222 return 0; 223 224err_request_cd: 225 sdhci_remove_host(host, 0); 226err_sdhci_add: 227 clk_disable_unprepare(pltfm_host->clk); 228err_clk_prepare: 229 sdhci_pltfm_free(pdev); 230 return ret; 231} 232 233#ifdef CONFIG_PM_SLEEP 234static int sdhci_sirf_suspend(struct device *dev) 235{ 236 struct sdhci_host *host = dev_get_drvdata(dev); 237 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 238 int ret; 239 240 ret = sdhci_suspend_host(host); 241 if (ret) 242 return ret; 243 244 clk_disable(pltfm_host->clk); 245 246 return 0; 247} 248 249static int sdhci_sirf_resume(struct device *dev) 250{ 251 struct sdhci_host *host = dev_get_drvdata(dev); 252 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 253 int ret; 254 255 ret = clk_enable(pltfm_host->clk); 256 if (ret) { 257 dev_dbg(dev, "Resume: Error enabling clock\n"); 258 return ret; 259 } 260 261 return sdhci_resume_host(host); 262} 263 264static SIMPLE_DEV_PM_OPS(sdhci_sirf_pm_ops, sdhci_sirf_suspend, sdhci_sirf_resume); 265#endif 266 267static const struct of_device_id sdhci_sirf_of_match[] = { 268 { .compatible = "sirf,prima2-sdhc" }, 269 { } 270}; 271MODULE_DEVICE_TABLE(of, sdhci_sirf_of_match); 272 273static struct platform_driver sdhci_sirf_driver = { 274 .driver = { 275 .name = "sdhci-sirf", 276 .of_match_table = sdhci_sirf_of_match, 277#ifdef CONFIG_PM_SLEEP 278 .pm = &sdhci_sirf_pm_ops, 279#endif 280 }, 281 .probe = sdhci_sirf_probe, 282 .remove = sdhci_pltfm_unregister, 283}; 284 285module_platform_driver(sdhci_sirf_driver); 286 287MODULE_DESCRIPTION("SDHCI driver for SiRFprimaII/SiRFmarco"); 288MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); 289MODULE_LICENSE("GPL v2"); 290