1 /* 2 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 */ 9 10 #include <linux/module.h> 11 #include <linux/platform_device.h> 12 #include <linux/clk.h> 13 #include <linux/mmc/host.h> 14 #include <linux/mmc/dw_mmc.h> 15 #include <linux/of_address.h> 16 #include <linux/slab.h> 17 18 #include "dw_mmc.h" 19 #include "dw_mmc-pltfm.h" 20 21 #define RK3288_CLKGEN_DIV 2 22 23 struct dw_mci_rockchip_priv_data { 24 struct clk *drv_clk; 25 struct clk *sample_clk; 26 int default_sample_phase; 27 }; 28 29 static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) 30 { 31 struct dw_mci_rockchip_priv_data *priv = host->priv; 32 int ret; 33 unsigned int cclkin; 34 u32 bus_hz; 35 36 if (ios->clock == 0) 37 return; 38 39 /* 40 * cclkin: source clock of mmc controller 41 * bus_hz: card interface clock generated by CLKGEN 42 * bus_hz = cclkin / RK3288_CLKGEN_DIV 43 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div)) 44 * 45 * Note: div can only be 0 or 1 46 * if DDR50 8bit mode(only emmc work in 8bit mode), 47 * div must be set 1 48 */ 49 if (ios->bus_width == MMC_BUS_WIDTH_8 && 50 ios->timing == MMC_TIMING_MMC_DDR52) 51 cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV; 52 else 53 cclkin = ios->clock * RK3288_CLKGEN_DIV; 54 55 ret = clk_set_rate(host->ciu_clk, cclkin); 56 if (ret) 57 dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock); 58 59 bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV; 60 if (bus_hz != host->bus_hz) { 61 host->bus_hz = bus_hz; 62 /* force dw_mci_setup_bus() */ 63 host->current_speed = 0; 64 } 65 66 /* Make sure we use phases which we can enumerate with */ 67 if (!IS_ERR(priv->sample_clk)) 68 clk_set_phase(priv->sample_clk, priv->default_sample_phase); 69 } 70 71 #define NUM_PHASES 360 72 #define TUNING_ITERATION_TO_PHASE(i) (DIV_ROUND_UP((i) * 360, NUM_PHASES)) 73 74 static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode) 75 { 76 struct dw_mci *host = slot->host; 77 struct dw_mci_rockchip_priv_data *priv = host->priv; 78 struct mmc_host *mmc = slot->mmc; 79 int ret = 0; 80 int i; 81 bool v, prev_v = 0, first_v; 82 struct range_t { 83 int start; 84 int end; /* inclusive */ 85 }; 86 struct range_t *ranges; 87 unsigned int range_count = 0; 88 int longest_range_len = -1; 89 int longest_range = -1; 90 int middle_phase; 91 92 if (IS_ERR(priv->sample_clk)) { 93 dev_err(host->dev, "Tuning clock (sample_clk) not defined.\n"); 94 return -EIO; 95 } 96 97 ranges = kmalloc_array(NUM_PHASES / 2 + 1, sizeof(*ranges), GFP_KERNEL); 98 if (!ranges) 99 return -ENOMEM; 100 101 /* Try each phase and extract good ranges */ 102 for (i = 0; i < NUM_PHASES; ) { 103 clk_set_phase(priv->sample_clk, TUNING_ITERATION_TO_PHASE(i)); 104 105 v = !mmc_send_tuning(mmc, opcode, NULL); 106 107 if (i == 0) 108 first_v = v; 109 110 if ((!prev_v) && v) { 111 range_count++; 112 ranges[range_count-1].start = i; 113 } 114 if (v) { 115 ranges[range_count-1].end = i; 116 i++; 117 } else if (i == NUM_PHASES - 1) { 118 /* No extra skipping rules if we're at the end */ 119 i++; 120 } else { 121 /* 122 * No need to check too close to an invalid 123 * one since testing bad phases is slow. Skip 124 * 20 degrees. 125 */ 126 i += DIV_ROUND_UP(20 * NUM_PHASES, 360); 127 128 /* Always test the last one */ 129 if (i >= NUM_PHASES) 130 i = NUM_PHASES - 1; 131 } 132 133 prev_v = v; 134 } 135 136 if (range_count == 0) { 137 dev_warn(host->dev, "All phases bad!"); 138 ret = -EIO; 139 goto free; 140 } 141 142 /* wrap around case, merge the end points */ 143 if ((range_count > 1) && first_v && v) { 144 ranges[0].start = ranges[range_count-1].start; 145 range_count--; 146 } 147 148 if (ranges[0].start == 0 && ranges[0].end == NUM_PHASES - 1) { 149 clk_set_phase(priv->sample_clk, priv->default_sample_phase); 150 dev_info(host->dev, "All phases work, using default phase %d.", 151 priv->default_sample_phase); 152 goto free; 153 } 154 155 /* Find the longest range */ 156 for (i = 0; i < range_count; i++) { 157 int len = (ranges[i].end - ranges[i].start + 1); 158 159 if (len < 0) 160 len += NUM_PHASES; 161 162 if (longest_range_len < len) { 163 longest_range_len = len; 164 longest_range = i; 165 } 166 167 dev_dbg(host->dev, "Good phase range %d-%d (%d len)\n", 168 TUNING_ITERATION_TO_PHASE(ranges[i].start), 169 TUNING_ITERATION_TO_PHASE(ranges[i].end), 170 len 171 ); 172 } 173 174 dev_dbg(host->dev, "Best phase range %d-%d (%d len)\n", 175 TUNING_ITERATION_TO_PHASE(ranges[longest_range].start), 176 TUNING_ITERATION_TO_PHASE(ranges[longest_range].end), 177 longest_range_len 178 ); 179 180 middle_phase = ranges[longest_range].start + longest_range_len / 2; 181 middle_phase %= NUM_PHASES; 182 dev_info(host->dev, "Successfully tuned phase to %d\n", 183 TUNING_ITERATION_TO_PHASE(middle_phase)); 184 185 clk_set_phase(priv->sample_clk, 186 TUNING_ITERATION_TO_PHASE(middle_phase)); 187 188 free: 189 kfree(ranges); 190 return ret; 191 } 192 193 static int dw_mci_rk3288_parse_dt(struct dw_mci *host) 194 { 195 struct device_node *np = host->dev->of_node; 196 struct dw_mci_rockchip_priv_data *priv; 197 198 priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL); 199 if (!priv) 200 return -ENOMEM; 201 202 if (of_property_read_u32(np, "rockchip,default-sample-phase", 203 &priv->default_sample_phase)) 204 priv->default_sample_phase = 0; 205 206 priv->drv_clk = devm_clk_get(host->dev, "ciu-drive"); 207 if (IS_ERR(priv->drv_clk)) 208 dev_dbg(host->dev, "ciu_drv not available\n"); 209 210 priv->sample_clk = devm_clk_get(host->dev, "ciu-sample"); 211 if (IS_ERR(priv->sample_clk)) 212 dev_dbg(host->dev, "ciu_sample not available\n"); 213 214 host->priv = priv; 215 216 return 0; 217 } 218 219 static int dw_mci_rockchip_init(struct dw_mci *host) 220 { 221 /* It is slot 8 on Rockchip SoCs */ 222 host->sdio_id0 = 8; 223 224 /* It needs this quirk on all Rockchip SoCs */ 225 host->pdata->quirks |= DW_MCI_QUIRK_BROKEN_DTO; 226 227 if (of_device_is_compatible(host->dev->of_node, 228 "rockchip,rk3288-dw-mshc")) 229 host->bus_hz /= RK3288_CLKGEN_DIV; 230 231 return 0; 232 } 233 234 /* Common capabilities of RK3288 SoC */ 235 static unsigned long dw_mci_rk3288_dwmmc_caps[4] = { 236 MMC_CAP_ERASE, 237 MMC_CAP_ERASE, 238 MMC_CAP_ERASE, 239 MMC_CAP_ERASE, 240 }; 241 242 static const struct dw_mci_drv_data rk2928_drv_data = { 243 .init = dw_mci_rockchip_init, 244 }; 245 246 static const struct dw_mci_drv_data rk3288_drv_data = { 247 .caps = dw_mci_rk3288_dwmmc_caps, 248 .set_ios = dw_mci_rk3288_set_ios, 249 .execute_tuning = dw_mci_rk3288_execute_tuning, 250 .parse_dt = dw_mci_rk3288_parse_dt, 251 .init = dw_mci_rockchip_init, 252 }; 253 254 static const struct of_device_id dw_mci_rockchip_match[] = { 255 { .compatible = "rockchip,rk2928-dw-mshc", 256 .data = &rk2928_drv_data }, 257 { .compatible = "rockchip,rk3288-dw-mshc", 258 .data = &rk3288_drv_data }, 259 {}, 260 }; 261 MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match); 262 263 static int dw_mci_rockchip_probe(struct platform_device *pdev) 264 { 265 const struct dw_mci_drv_data *drv_data; 266 const struct of_device_id *match; 267 268 if (!pdev->dev.of_node) 269 return -ENODEV; 270 271 match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node); 272 drv_data = match->data; 273 274 return dw_mci_pltfm_register(pdev, drv_data); 275 } 276 277 static struct platform_driver dw_mci_rockchip_pltfm_driver = { 278 .probe = dw_mci_rockchip_probe, 279 .remove = dw_mci_pltfm_remove, 280 .driver = { 281 .name = "dwmmc_rockchip", 282 .of_match_table = dw_mci_rockchip_match, 283 .pm = &dw_mci_pltfm_pmops, 284 }, 285 }; 286 287 module_platform_driver(dw_mci_rockchip_pltfm_driver); 288 289 MODULE_AUTHOR("Addy Ke <addy.ke@rock-chips.com>"); 290 MODULE_DESCRIPTION("Rockchip Specific DW-MSHC Driver Extension"); 291 MODULE_ALIAS("platform:dwmmc_rockchip"); 292 MODULE_LICENSE("GPL v2"); 293