1 /* 2 * Copyright (c) 2013 Google, Inc 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <clk.h> 9 #include <dm.h> 10 #include <dt-structs.h> 11 #include <dwmmc.h> 12 #include <errno.h> 13 #include <mapmem.h> 14 #include <pwrseq.h> 15 #include <syscon.h> 16 #include <asm/gpio.h> 17 #include <asm/arch/clock.h> 18 #include <asm/arch/periph.h> 19 #include <linux/err.h> 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 struct rockchip_mmc_plat { 24 #if CONFIG_IS_ENABLED(OF_PLATDATA) 25 struct dtd_rockchip_rk3288_dw_mshc dtplat; 26 #endif 27 struct mmc_config cfg; 28 struct mmc mmc; 29 }; 30 31 struct rockchip_dwmmc_priv { 32 struct clk clk; 33 struct clk sample_clk; 34 struct dwmci_host host; 35 int fifo_depth; 36 bool fifo_mode; 37 u32 minmax[2]; 38 }; 39 40 static uint rockchip_dwmmc_get_mmc_clk(struct dwmci_host *host, uint freq) 41 { 42 struct udevice *dev = host->priv; 43 struct rockchip_dwmmc_priv *priv = dev_get_priv(dev); 44 int ret; 45 46 /* 47 * If DDR52 8bit mode(only emmc work in 8bit mode), 48 * divider must be set 1 49 */ 50 if (mmc_card_ddr52(host->mmc) && host->mmc->bus_width == 8) 51 freq *= 2; 52 53 ret = clk_set_rate(&priv->clk, freq); 54 if (ret < 0) { 55 debug("%s: err=%d\n", __func__, ret); 56 return ret; 57 } 58 59 return freq; 60 } 61 62 static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev) 63 { 64 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 65 struct rockchip_dwmmc_priv *priv = dev_get_priv(dev); 66 struct dwmci_host *host = &priv->host; 67 68 host->name = dev->name; 69 host->ioaddr = dev_read_addr_ptr(dev); 70 host->buswidth = dev_read_u32_default(dev, "bus-width", 4); 71 host->get_mmc_clk = rockchip_dwmmc_get_mmc_clk; 72 host->priv = dev; 73 74 /* use non-removeable as sdcard and emmc as judgement */ 75 if (dev_read_bool(dev, "non-removable")) 76 host->dev_index = 0; 77 else 78 host->dev_index = 1; 79 80 priv->fifo_depth = dev_read_u32_default(dev, "fifo-depth", 0); 81 82 if (priv->fifo_depth < 0) 83 return -EINVAL; 84 priv->fifo_mode = dev_read_bool(dev, "fifo-mode"); 85 86 /* 87 * 'clock-freq-min-max' is deprecated 88 * (see https://github.com/torvalds/linux/commit/b023030f10573de738bbe8df63d43acab64c9f7b) 89 */ 90 if (dev_read_u32_array(dev, "clock-freq-min-max", priv->minmax, 2)) { 91 int val = dev_read_u32_default(dev, "max-frequency", -EINVAL); 92 93 if (val < 0) 94 return val; 95 96 priv->minmax[0] = 400000; /* 400 kHz */ 97 priv->minmax[1] = val; 98 } else { 99 debug("%s: 'clock-freq-min-max' property was deprecated.\n", 100 __func__); 101 } 102 #endif 103 return 0; 104 } 105 106 #define NUM_PHASES 270 107 #define TUNING_ITERATION_TO_PHASE(i) (DIV_ROUND_UP((i) * 270, NUM_PHASES)) 108 109 static int rockchip_dwmmc_execute_tuning(struct dwmci_host *host, u32 opcode) 110 { 111 int ret = 0; 112 int i; 113 bool v, prev_v = 0, first_v; 114 struct range_t { 115 int start; 116 int end; /* inclusive */ 117 }; 118 struct range_t *ranges; 119 unsigned int range_count = 0; 120 int longest_range_len = -1; 121 int longest_range = -1; 122 int middle_phase; 123 struct udevice *dev = host->priv; 124 struct rockchip_dwmmc_priv *priv = dev_get_priv(dev); 125 struct mmc *mmc = host->mmc; 126 127 if (IS_ERR(&priv->sample_clk)) 128 return -EIO; 129 130 ranges = calloc(sizeof(*ranges), NUM_PHASES / 2 + 1); 131 if (!ranges) 132 return -ENOMEM; 133 134 /* Try each phase and extract good ranges */ 135 for (i = 0; i < NUM_PHASES; ) { 136 clk_set_phase(&priv->sample_clk, TUNING_ITERATION_TO_PHASE(i)); 137 138 v = !mmc_send_tuning(mmc, opcode); 139 140 if (i == 0) 141 first_v = v; 142 143 if ((!prev_v) && v) { 144 range_count++; 145 ranges[range_count - 1].start = i; 146 } 147 if (v) { 148 ranges[range_count - 1].end = i; 149 i++; 150 } else if (i == NUM_PHASES - 1) { 151 /* No extra skipping rules if we're at the end */ 152 i++; 153 } else { 154 /* 155 * No need to check too close to an invalid 156 * one since testing bad phases is slow. Skip 157 * 20 degrees. 158 */ 159 i += DIV_ROUND_UP(20 * NUM_PHASES, NUM_PHASES); 160 161 /* Always test the last one */ 162 if (i >= NUM_PHASES) 163 i = NUM_PHASES - 1; 164 } 165 166 prev_v = v; 167 } 168 169 if (range_count == 0) { 170 debug("All phases bad!"); 171 ret = -EIO; 172 goto free; 173 } 174 175 /* wrap around case, merge the end points */ 176 if ((range_count > 1) && first_v && v) { 177 ranges[0].start = ranges[range_count - 1].start; 178 range_count--; 179 } 180 181 if (ranges[0].start == 0 && ranges[0].end == NUM_PHASES - 1) { 182 clk_set_phase(&priv->sample_clk, 183 TUNING_ITERATION_TO_PHASE(NUM_PHASES / 2)); 184 debug("All phases work, using middle phase.\n"); 185 goto free; 186 } 187 188 /* Find the longest range */ 189 for (i = 0; i < range_count; i++) { 190 int len = (ranges[i].end - ranges[i].start + 1); 191 192 if (len < 0) 193 len += NUM_PHASES; 194 195 if (longest_range_len < len) { 196 longest_range_len = len; 197 longest_range = i; 198 } 199 200 debug("Good phase range %d-%d (%d len)\n", 201 TUNING_ITERATION_TO_PHASE(ranges[i].start), 202 TUNING_ITERATION_TO_PHASE(ranges[i].end), len); 203 } 204 205 printf("Best phase range %d-%d (%d len)\n", 206 TUNING_ITERATION_TO_PHASE(ranges[longest_range].start), 207 TUNING_ITERATION_TO_PHASE(ranges[longest_range].end), 208 longest_range_len); 209 210 middle_phase = ranges[longest_range].start + longest_range_len / 2; 211 middle_phase %= NUM_PHASES; 212 debug("Successfully tuned phase to %d\n", 213 TUNING_ITERATION_TO_PHASE(middle_phase)); 214 215 clk_set_phase(&priv->sample_clk, 216 TUNING_ITERATION_TO_PHASE(middle_phase)); 217 218 free: 219 free(ranges); 220 return ret; 221 } 222 223 static int rockchip_dwmmc_probe(struct udevice *dev) 224 { 225 struct rockchip_mmc_plat *plat = dev_get_platdata(dev); 226 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); 227 struct rockchip_dwmmc_priv *priv = dev_get_priv(dev); 228 struct dwmci_host *host = &priv->host; 229 struct udevice *pwr_dev __maybe_unused; 230 int ret; 231 232 #if CONFIG_IS_ENABLED(OF_PLATDATA) 233 struct dtd_rockchip_rk3288_dw_mshc *dtplat = &plat->dtplat; 234 235 host->name = dev->name; 236 host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]); 237 host->buswidth = dtplat->bus_width; 238 host->get_mmc_clk = rockchip_dwmmc_get_mmc_clk; 239 host->execute_tuning = rockchip_dwmmc_execute_tuning; 240 host->priv = dev; 241 host->dev_index = 0; 242 priv->fifo_depth = dtplat->fifo_depth; 243 priv->fifo_mode = 0; 244 priv->minmax[0] = 400000; /* 400 kHz */ 245 priv->minmax[1] = dtplat->max_frequency; 246 247 ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk); 248 if (ret < 0) 249 return ret; 250 #else 251 ret = clk_get_by_index(dev, 0, &priv->clk); 252 if (ret < 0) 253 return ret; 254 clk_get_by_name(dev, "ciu_sample", &priv->sample_clk); 255 host->execute_tuning = rockchip_dwmmc_execute_tuning; 256 #endif 257 host->fifoth_val = MSIZE(0x2) | 258 RX_WMARK(priv->fifo_depth / 2 - 1) | 259 TX_WMARK(priv->fifo_depth / 2); 260 261 host->fifo_mode = priv->fifo_mode; 262 263 #ifdef CONFIG_ROCKCHIP_RK3128 264 host->stride_pio = true; 265 #else 266 host->stride_pio = false; 267 #endif 268 269 #ifdef CONFIG_PWRSEQ 270 /* Enable power if needed */ 271 ret = uclass_get_device_by_phandle(UCLASS_PWRSEQ, dev, "mmc-pwrseq", 272 &pwr_dev); 273 if (!ret) { 274 ret = pwrseq_set_power(pwr_dev, true); 275 if (ret) 276 return ret; 277 } 278 #endif 279 dwmci_setup_cfg(&plat->cfg, host, priv->minmax[1], priv->minmax[0]); 280 plat->cfg.host_caps |= MMC_MODE_DDR_52MHz; 281 host->mmc = &plat->mmc; 282 host->mmc->priv = &priv->host; 283 host->mmc->dev = dev; 284 upriv->mmc = host->mmc; 285 286 return dwmci_probe(dev); 287 } 288 289 static int rockchip_dwmmc_bind(struct udevice *dev) 290 { 291 struct rockchip_mmc_plat *plat = dev_get_platdata(dev); 292 293 return dwmci_bind(dev, &plat->mmc, &plat->cfg); 294 } 295 296 static const struct udevice_id rockchip_dwmmc_ids[] = { 297 { .compatible = "rockchip,rk3288-dw-mshc" }, 298 { .compatible = "rockchip,rk2928-dw-mshc" }, 299 { } 300 }; 301 302 U_BOOT_DRIVER(rockchip_dwmmc_drv) = { 303 .name = "rockchip_rk3288_dw_mshc", 304 .id = UCLASS_MMC, 305 .of_match = rockchip_dwmmc_ids, 306 .ofdata_to_platdata = rockchip_dwmmc_ofdata_to_platdata, 307 .ops = &dm_dwmci_ops, 308 .bind = rockchip_dwmmc_bind, 309 .probe = rockchip_dwmmc_probe, 310 .priv_auto_alloc_size = sizeof(struct rockchip_dwmmc_priv), 311 .platdata_auto_alloc_size = sizeof(struct rockchip_mmc_plat), 312 }; 313 314 #ifdef CONFIG_PWRSEQ 315 static int rockchip_dwmmc_pwrseq_set_power(struct udevice *dev, bool enable) 316 { 317 struct gpio_desc reset; 318 int ret; 319 320 ret = gpio_request_by_name(dev, "reset-gpios", 0, &reset, GPIOD_IS_OUT); 321 if (ret) 322 return ret; 323 dm_gpio_set_value(&reset, 1); 324 udelay(1); 325 dm_gpio_set_value(&reset, 0); 326 udelay(200); 327 328 return 0; 329 } 330 331 static const struct pwrseq_ops rockchip_dwmmc_pwrseq_ops = { 332 .set_power = rockchip_dwmmc_pwrseq_set_power, 333 }; 334 335 static const struct udevice_id rockchip_dwmmc_pwrseq_ids[] = { 336 { .compatible = "mmc-pwrseq-emmc" }, 337 { } 338 }; 339 340 U_BOOT_DRIVER(rockchip_dwmmc_pwrseq_drv) = { 341 .name = "mmc_pwrseq_emmc", 342 .id = UCLASS_PWRSEQ, 343 .of_match = rockchip_dwmmc_pwrseq_ids, 344 .ops = &rockchip_dwmmc_pwrseq_ops, 345 }; 346 #endif 347