1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com> 4 */ 5 6 #include <common.h> 7 #include <clk.h> 8 #include <fdtdec.h> 9 #include <mmc.h> 10 #include <dm.h> 11 #include <linux/compat.h> 12 #include <linux/dma-direction.h> 13 #include <linux/io.h> 14 #include <linux/sizes.h> 15 #include <power/regulator.h> 16 #include <asm/unaligned.h> 17 18 #include "tmio-common.h" 19 20 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) 21 22 /* SCC registers */ 23 #define RENESAS_SDHI_SCC_DTCNTL 0x800 24 #define RENESAS_SDHI_SCC_DTCNTL_TAPEN BIT(0) 25 #define RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT 16 26 #define RENESAS_SDHI_SCC_DTCNTL_TAPNUM_MASK 0xff 27 #define RENESAS_SDHI_SCC_TAPSET 0x804 28 #define RENESAS_SDHI_SCC_DT2FF 0x808 29 #define RENESAS_SDHI_SCC_CKSEL 0x80c 30 #define RENESAS_SDHI_SCC_CKSEL_DTSEL BIT(0) 31 #define RENESAS_SDHI_SCC_RVSCNTL 0x810 32 #define RENESAS_SDHI_SCC_RVSCNTL_RVSEN BIT(0) 33 #define RENESAS_SDHI_SCC_RVSREQ 0x814 34 #define RENESAS_SDHI_SCC_RVSREQ_RVSERR BIT(2) 35 #define RENESAS_SDHI_SCC_SMPCMP 0x818 36 #define RENESAS_SDHI_SCC_TMPPORT2 0x81c 37 38 #define RENESAS_SDHI_MAX_TAP 3 39 40 static unsigned int renesas_sdhi_init_tuning(struct tmio_sd_priv *priv) 41 { 42 u32 reg; 43 44 /* Initialize SCC */ 45 tmio_sd_writel(priv, 0, TMIO_SD_INFO1); 46 47 reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); 48 reg &= ~TMIO_SD_CLKCTL_SCLKEN; 49 tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); 50 51 /* Set sampling clock selection range */ 52 tmio_sd_writel(priv, 0x8 << RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT, 53 RENESAS_SDHI_SCC_DTCNTL); 54 55 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_DTCNTL); 56 reg |= RENESAS_SDHI_SCC_DTCNTL_TAPEN; 57 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_DTCNTL); 58 59 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL); 60 reg |= RENESAS_SDHI_SCC_CKSEL_DTSEL; 61 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL); 62 63 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); 64 reg &= ~RENESAS_SDHI_SCC_RVSCNTL_RVSEN; 65 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); 66 67 tmio_sd_writel(priv, 0x300 /* scc_tappos */, 68 RENESAS_SDHI_SCC_DT2FF); 69 70 reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); 71 reg |= TMIO_SD_CLKCTL_SCLKEN; 72 tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); 73 74 /* Read TAPNUM */ 75 return (tmio_sd_readl(priv, RENESAS_SDHI_SCC_DTCNTL) >> 76 RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT) & 77 RENESAS_SDHI_SCC_DTCNTL_TAPNUM_MASK; 78 } 79 80 static void renesas_sdhi_reset_tuning(struct tmio_sd_priv *priv) 81 { 82 u32 reg; 83 84 /* Reset SCC */ 85 reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); 86 reg &= ~TMIO_SD_CLKCTL_SCLKEN; 87 tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); 88 89 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL); 90 reg &= ~RENESAS_SDHI_SCC_CKSEL_DTSEL; 91 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL); 92 93 reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); 94 reg |= TMIO_SD_CLKCTL_SCLKEN; 95 tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); 96 97 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); 98 reg &= ~RENESAS_SDHI_SCC_RVSCNTL_RVSEN; 99 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); 100 101 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); 102 reg &= ~RENESAS_SDHI_SCC_RVSCNTL_RVSEN; 103 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); 104 } 105 106 static void renesas_sdhi_prepare_tuning(struct tmio_sd_priv *priv, 107 unsigned long tap) 108 { 109 /* Set sampling clock position */ 110 tmio_sd_writel(priv, tap, RENESAS_SDHI_SCC_TAPSET); 111 } 112 113 static unsigned int renesas_sdhi_compare_scc_data(struct tmio_sd_priv *priv) 114 { 115 /* Get comparison of sampling data */ 116 return tmio_sd_readl(priv, RENESAS_SDHI_SCC_SMPCMP); 117 } 118 119 static int renesas_sdhi_select_tuning(struct tmio_sd_priv *priv, 120 unsigned int tap_num, unsigned int taps, 121 unsigned int smpcmp) 122 { 123 unsigned long tap_cnt; /* counter of tuning success */ 124 unsigned long tap_set; /* tap position */ 125 unsigned long tap_start;/* start position of tuning success */ 126 unsigned long tap_end; /* end position of tuning success */ 127 unsigned long ntap; /* temporary counter of tuning success */ 128 unsigned long match_cnt;/* counter of matching data */ 129 unsigned long i; 130 bool select = false; 131 u32 reg; 132 133 /* Clear SCC_RVSREQ */ 134 tmio_sd_writel(priv, 0, RENESAS_SDHI_SCC_RVSREQ); 135 136 /* Merge the results */ 137 for (i = 0; i < tap_num * 2; i++) { 138 if (!(taps & BIT(i))) { 139 taps &= ~BIT(i % tap_num); 140 taps &= ~BIT((i % tap_num) + tap_num); 141 } 142 if (!(smpcmp & BIT(i))) { 143 smpcmp &= ~BIT(i % tap_num); 144 smpcmp &= ~BIT((i % tap_num) + tap_num); 145 } 146 } 147 148 /* 149 * Find the longest consecutive run of successful probes. If that 150 * is more than RENESAS_SDHI_MAX_TAP probes long then use the 151 * center index as the tap. 152 */ 153 tap_cnt = 0; 154 ntap = 0; 155 tap_start = 0; 156 tap_end = 0; 157 for (i = 0; i < tap_num * 2; i++) { 158 if (taps & BIT(i)) 159 ntap++; 160 else { 161 if (ntap > tap_cnt) { 162 tap_start = i - ntap; 163 tap_end = i - 1; 164 tap_cnt = ntap; 165 } 166 ntap = 0; 167 } 168 } 169 170 if (ntap > tap_cnt) { 171 tap_start = i - ntap; 172 tap_end = i - 1; 173 tap_cnt = ntap; 174 } 175 176 /* 177 * If all of the TAP is OK, the sampling clock position is selected by 178 * identifying the change point of data. 179 */ 180 if (tap_cnt == tap_num * 2) { 181 match_cnt = 0; 182 ntap = 0; 183 tap_start = 0; 184 tap_end = 0; 185 for (i = 0; i < tap_num * 2; i++) { 186 if (smpcmp & BIT(i)) 187 ntap++; 188 else { 189 if (ntap > match_cnt) { 190 tap_start = i - ntap; 191 tap_end = i - 1; 192 match_cnt = ntap; 193 } 194 ntap = 0; 195 } 196 } 197 if (ntap > match_cnt) { 198 tap_start = i - ntap; 199 tap_end = i - 1; 200 match_cnt = ntap; 201 } 202 if (match_cnt) 203 select = true; 204 } else if (tap_cnt >= RENESAS_SDHI_MAX_TAP) 205 select = true; 206 207 if (select) 208 tap_set = ((tap_start + tap_end) / 2) % tap_num; 209 else 210 return -EIO; 211 212 /* Set SCC */ 213 tmio_sd_writel(priv, tap_set, RENESAS_SDHI_SCC_TAPSET); 214 215 /* Enable auto re-tuning */ 216 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); 217 reg |= RENESAS_SDHI_SCC_RVSCNTL_RVSEN; 218 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); 219 220 return 0; 221 } 222 223 int renesas_sdhi_execute_tuning(struct udevice *dev, uint opcode) 224 { 225 struct tmio_sd_priv *priv = dev_get_priv(dev); 226 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); 227 struct mmc *mmc = upriv->mmc; 228 unsigned int tap_num; 229 unsigned int taps = 0, smpcmp = 0; 230 int i, ret = 0; 231 u32 caps; 232 233 /* Only supported on Renesas RCar */ 234 if (!(priv->caps & TMIO_SD_CAP_RCAR_UHS)) 235 return -EINVAL; 236 237 /* clock tuning is not needed for upto 52MHz */ 238 if (!((mmc->selected_mode == MMC_HS_200) || 239 (mmc->selected_mode == UHS_SDR104) || 240 (mmc->selected_mode == UHS_SDR50))) 241 return 0; 242 243 tap_num = renesas_sdhi_init_tuning(priv); 244 if (!tap_num) 245 /* Tuning is not supported */ 246 goto out; 247 248 if (tap_num * 2 >= sizeof(taps) * 8) { 249 dev_err(dev, 250 "Too many taps, skipping tuning. Please consider updating size of taps field of tmio_mmc_host\n"); 251 goto out; 252 } 253 254 /* Issue CMD19 twice for each tap */ 255 for (i = 0; i < 2 * tap_num; i++) { 256 renesas_sdhi_prepare_tuning(priv, i % tap_num); 257 258 /* Force PIO for the tuning */ 259 caps = priv->caps; 260 priv->caps &= ~TMIO_SD_CAP_DMA_INTERNAL; 261 262 ret = mmc_send_tuning(mmc, opcode, NULL); 263 264 priv->caps = caps; 265 266 if (ret == 0) 267 taps |= BIT(i); 268 269 ret = renesas_sdhi_compare_scc_data(priv); 270 if (ret == 0) 271 smpcmp |= BIT(i); 272 273 mdelay(1); 274 } 275 276 ret = renesas_sdhi_select_tuning(priv, tap_num, taps, smpcmp); 277 278 out: 279 if (ret < 0) { 280 dev_warn(dev, "Tuning procedure failed\n"); 281 renesas_sdhi_reset_tuning(priv); 282 } 283 284 return ret; 285 } 286 #endif 287 288 static int renesas_sdhi_set_ios(struct udevice *dev) 289 { 290 int ret = tmio_sd_set_ios(dev); 291 292 mdelay(10); 293 294 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) 295 struct tmio_sd_priv *priv = dev_get_priv(dev); 296 297 renesas_sdhi_reset_tuning(priv); 298 #endif 299 300 return ret; 301 } 302 303 static const struct dm_mmc_ops renesas_sdhi_ops = { 304 .send_cmd = tmio_sd_send_cmd, 305 .set_ios = renesas_sdhi_set_ios, 306 .get_cd = tmio_sd_get_cd, 307 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) 308 .execute_tuning = renesas_sdhi_execute_tuning, 309 #endif 310 }; 311 312 #define RENESAS_GEN2_QUIRKS TMIO_SD_CAP_RCAR_GEN2 313 #define RENESAS_GEN3_QUIRKS \ 314 TMIO_SD_CAP_64BIT | TMIO_SD_CAP_RCAR_GEN3 | TMIO_SD_CAP_RCAR_UHS 315 316 static const struct udevice_id renesas_sdhi_match[] = { 317 { .compatible = "renesas,sdhi-r8a7790", .data = RENESAS_GEN2_QUIRKS }, 318 { .compatible = "renesas,sdhi-r8a7791", .data = RENESAS_GEN2_QUIRKS }, 319 { .compatible = "renesas,sdhi-r8a7792", .data = RENESAS_GEN2_QUIRKS }, 320 { .compatible = "renesas,sdhi-r8a7793", .data = RENESAS_GEN2_QUIRKS }, 321 { .compatible = "renesas,sdhi-r8a7794", .data = RENESAS_GEN2_QUIRKS }, 322 { .compatible = "renesas,sdhi-r8a7795", .data = RENESAS_GEN3_QUIRKS }, 323 { .compatible = "renesas,sdhi-r8a7796", .data = RENESAS_GEN3_QUIRKS }, 324 { .compatible = "renesas,sdhi-r8a77965", .data = RENESAS_GEN3_QUIRKS }, 325 { .compatible = "renesas,sdhi-r8a77970", .data = RENESAS_GEN3_QUIRKS }, 326 { .compatible = "renesas,sdhi-r8a77995", .data = RENESAS_GEN3_QUIRKS }, 327 { /* sentinel */ } 328 }; 329 330 static int renesas_sdhi_probe(struct udevice *dev) 331 { 332 struct tmio_sd_priv *priv = dev_get_priv(dev); 333 u32 quirks = dev_get_driver_data(dev); 334 struct fdt_resource reg_res; 335 struct clk clk; 336 DECLARE_GLOBAL_DATA_PTR; 337 int ret; 338 339 if (quirks == RENESAS_GEN2_QUIRKS) { 340 ret = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev), 341 "reg", 0, ®_res); 342 if (ret < 0) { 343 dev_err(dev, "\"reg\" resource not found, ret=%i\n", 344 ret); 345 return ret; 346 } 347 348 if (fdt_resource_size(®_res) == 0x100) 349 quirks |= TMIO_SD_CAP_16BIT; 350 } 351 352 ret = clk_get_by_index(dev, 0, &clk); 353 if (ret < 0) { 354 dev_err(dev, "failed to get host clock\n"); 355 return ret; 356 } 357 358 /* set to max rate */ 359 priv->mclk = clk_set_rate(&clk, ULONG_MAX); 360 if (IS_ERR_VALUE(priv->mclk)) { 361 dev_err(dev, "failed to set rate for host clock\n"); 362 clk_free(&clk); 363 return priv->mclk; 364 } 365 366 ret = clk_enable(&clk); 367 clk_free(&clk); 368 if (ret) { 369 dev_err(dev, "failed to enable host clock\n"); 370 return ret; 371 } 372 373 ret = tmio_sd_probe(dev, quirks); 374 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) 375 if (!ret) 376 renesas_sdhi_reset_tuning(dev_get_priv(dev)); 377 #endif 378 return ret; 379 } 380 381 U_BOOT_DRIVER(renesas_sdhi) = { 382 .name = "renesas-sdhi", 383 .id = UCLASS_MMC, 384 .of_match = renesas_sdhi_match, 385 .bind = tmio_sd_bind, 386 .probe = renesas_sdhi_probe, 387 .priv_auto_alloc_size = sizeof(struct tmio_sd_priv), 388 .platdata_auto_alloc_size = sizeof(struct tmio_sd_plat), 389 .ops = &renesas_sdhi_ops, 390 }; 391