Lines Matching +full:re +full:- +full:tuning

1 // SPDX-License-Identifier: GPL-2.0-or-later
11 #include <linux/mmc/slot-gpio.h>
16 #include "dw_mmc-pltfm.h"
41 * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
46 unsigned long rate = clk_get_rate(host->ciu_clk); in rockchip_mmc_get_internal_phase()
78 struct dw_mci_rockchip_priv_data *priv = host->priv; in rockchip_mmc_get_phase()
79 struct clk *clock = sample ? priv->sample_clk : priv->drv_clk; in rockchip_mmc_get_phase()
81 if (priv->internal_phase) in rockchip_mmc_get_phase()
89 unsigned long rate = clk_get_rate(host->ciu_clk); in rockchip_mmc_set_internal_phase()
105 * for people to debug unstable mmc tuning results. in rockchip_mmc_set_internal_phase()
108 dev_err(host->dev, "%s: invalid clk rate\n", __func__); in rockchip_mmc_set_internal_phase()
109 return -EINVAL; in rockchip_mmc_set_internal_phase()
117 * actually go non-monotonic. We don't go _too_ monotonic in rockchip_mmc_set_internal_phase()
130 * degrees off from what we think we're making. That's OK in rockchip_mmc_set_internal_phase()
136 * don't overflow 32-bit / 64-bit numbers. in rockchip_mmc_set_internal_phase()
155 dev_dbg(host->dev, "set %s_phase(%d) delay_nums=%u actual_degrees=%d\n", in rockchip_mmc_set_internal_phase()
165 struct dw_mci_rockchip_priv_data *priv = host->priv; in rockchip_mmc_set_phase()
166 struct clk *clock = sample ? priv->sample_clk : priv->drv_clk; in rockchip_mmc_set_phase()
168 if (priv->internal_phase) in rockchip_mmc_set_phase()
176 struct dw_mci_rockchip_priv_data *priv = host->priv; in dw_mci_rk3288_set_ios()
181 if (ios->clock == 0) in dw_mci_rk3288_set_ios()
188 * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div)) in dw_mci_rk3288_set_ios()
191 * DDR52 8-bit mode. in dw_mci_rk3288_set_ios()
193 if (ios->bus_width == MMC_BUS_WIDTH_8 && in dw_mci_rk3288_set_ios()
194 ios->timing == MMC_TIMING_MMC_DDR52) in dw_mci_rk3288_set_ios()
195 cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV; in dw_mci_rk3288_set_ios()
197 cclkin = ios->clock * RK3288_CLKGEN_DIV; in dw_mci_rk3288_set_ios()
199 ret = clk_set_rate(host->ciu_clk, cclkin); in dw_mci_rk3288_set_ios()
201 dev_warn(host->dev, "failed to set rate %uHz err: %d\n", cclkin, ret); in dw_mci_rk3288_set_ios()
203 bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV; in dw_mci_rk3288_set_ios()
204 if (bus_hz != host->bus_hz) { in dw_mci_rk3288_set_ios()
205 host->bus_hz = bus_hz; in dw_mci_rk3288_set_ios()
207 host->current_speed = 0; in dw_mci_rk3288_set_ios()
211 if (!IS_ERR(priv->sample_clk) && ios->timing <= MMC_TIMING_SD_HS) in dw_mci_rk3288_set_ios()
212 rockchip_mmc_set_phase(host, true, priv->default_sample_phase); in dw_mci_rk3288_set_ios()
240 if (!IS_ERR(priv->drv_clk)) { in dw_mci_rk3288_set_ios()
251 switch (ios->timing) { in dw_mci_rk3288_set_ios()
258 if (ios->bus_width == MMC_BUS_WIDTH_8) in dw_mci_rk3288_set_ios()
284 struct dw_mci *host = slot->host; in dw_mci_rk3288_execute_tuning()
285 struct dw_mci_rockchip_priv_data *priv = host->priv; in dw_mci_rk3288_execute_tuning()
286 struct mmc_host *mmc = slot->mmc; in dw_mci_rk3288_execute_tuning()
296 int longest_range_len = -1; in dw_mci_rk3288_execute_tuning()
297 int longest_range = -1; in dw_mci_rk3288_execute_tuning()
301 if (IS_ERR(priv->sample_clk)) { in dw_mci_rk3288_execute_tuning()
302 dev_err(host->dev, "Tuning clock (sample_clk) not defined.\n"); in dw_mci_rk3288_execute_tuning()
303 return -EIO; in dw_mci_rk3288_execute_tuning()
306 ranges = kmalloc_array(priv->num_phases / 2 + 1, in dw_mci_rk3288_execute_tuning()
309 return -ENOMEM; in dw_mci_rk3288_execute_tuning()
312 for (i = 0; i < priv->num_phases; ) { in dw_mci_rk3288_execute_tuning()
316 priv->num_phases)); in dw_mci_rk3288_execute_tuning()
325 ranges[range_count-1].start = i; in dw_mci_rk3288_execute_tuning()
328 ranges[range_count-1].end = i; in dw_mci_rk3288_execute_tuning()
330 } else if (i == priv->num_phases - 1) { in dw_mci_rk3288_execute_tuning()
331 /* No extra skipping rules if we're at the end */ in dw_mci_rk3288_execute_tuning()
339 i += DIV_ROUND_UP(20 * priv->num_phases, 360); in dw_mci_rk3288_execute_tuning()
342 if (i >= priv->num_phases) in dw_mci_rk3288_execute_tuning()
343 i = priv->num_phases - 1; in dw_mci_rk3288_execute_tuning()
350 dev_warn(host->dev, "All phases bad!"); in dw_mci_rk3288_execute_tuning()
351 ret = -EIO; in dw_mci_rk3288_execute_tuning()
357 ranges[0].start = ranges[range_count-1].start; in dw_mci_rk3288_execute_tuning()
358 range_count--; in dw_mci_rk3288_execute_tuning()
361 if (ranges[0].start == 0 && ranges[0].end == priv->num_phases - 1) { in dw_mci_rk3288_execute_tuning()
362 rockchip_mmc_set_phase(host, true, priv->default_sample_phase); in dw_mci_rk3288_execute_tuning()
364 dev_info(host->dev, "All phases work, using default phase %d.", in dw_mci_rk3288_execute_tuning()
365 priv->default_sample_phase); in dw_mci_rk3288_execute_tuning()
371 int len = (ranges[i].end - ranges[i].start + 1); in dw_mci_rk3288_execute_tuning()
374 len += priv->num_phases; in dw_mci_rk3288_execute_tuning()
381 dev_dbg(host->dev, "Good phase range %d-%d (%d len)\n", in dw_mci_rk3288_execute_tuning()
383 priv->num_phases), in dw_mci_rk3288_execute_tuning()
385 priv->num_phases), in dw_mci_rk3288_execute_tuning()
390 dev_dbg(host->dev, "Best phase range %d-%d (%d len)\n", in dw_mci_rk3288_execute_tuning()
392 priv->num_phases), in dw_mci_rk3288_execute_tuning()
394 priv->num_phases), in dw_mci_rk3288_execute_tuning()
399 middle_phase %= priv->num_phases; in dw_mci_rk3288_execute_tuning()
400 phase = TUNING_ITERATION_TO_PHASE(middle_phase, priv->num_phases); in dw_mci_rk3288_execute_tuning()
401 dev_info(host->dev, "Successfully tuned phase to %d\n", phase); in dw_mci_rk3288_execute_tuning()
412 struct device_node *np = host->dev->of_node; in dw_mci_common_parse_dt()
415 priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL); in dw_mci_common_parse_dt()
417 return -ENOMEM; in dw_mci_common_parse_dt()
419 if (of_property_read_u32(np, "rockchip,desired-num-phases", in dw_mci_common_parse_dt()
420 &priv->num_phases)) in dw_mci_common_parse_dt()
421 priv->num_phases = 360; in dw_mci_common_parse_dt()
423 if (of_property_read_u32(np, "rockchip,default-sample-phase", in dw_mci_common_parse_dt()
424 &priv->default_sample_phase)) in dw_mci_common_parse_dt()
425 priv->default_sample_phase = 0; in dw_mci_common_parse_dt()
427 host->priv = priv; in dw_mci_common_parse_dt()
441 priv = host->priv; in dw_mci_rk3288_parse_dt()
443 priv->drv_clk = devm_clk_get(host->dev, "ciu-drive"); in dw_mci_rk3288_parse_dt()
444 if (IS_ERR(priv->drv_clk)) in dw_mci_rk3288_parse_dt()
445 dev_dbg(host->dev, "ciu-drive not available\n"); in dw_mci_rk3288_parse_dt()
447 priv->sample_clk = devm_clk_get(host->dev, "ciu-sample"); in dw_mci_rk3288_parse_dt()
448 if (IS_ERR(priv->sample_clk)) in dw_mci_rk3288_parse_dt()
449 dev_dbg(host->dev, "ciu-sample not available\n"); in dw_mci_rk3288_parse_dt()
451 priv->internal_phase = false; in dw_mci_rk3288_parse_dt()
463 priv = host->priv; in dw_mci_rk3576_parse_dt()
465 priv->internal_phase = true; in dw_mci_rk3576_parse_dt()
475 host->sdio_id0 = 8; in dw_mci_rockchip_init()
477 if (of_device_is_compatible(host->dev->of_node, "rockchip,rk3288-dw-mshc")) { in dw_mci_rockchip_init()
478 host->bus_hz /= RK3288_CLKGEN_DIV; in dw_mci_rockchip_init()
486 ret = clk_round_rate(host->ciu_clk, freqs[i] * RK3288_CLKGEN_DIV); in dw_mci_rockchip_init()
488 host->minimum_speed = ret / RK3288_CLKGEN_DIV; in dw_mci_rockchip_init()
493 dev_warn(host->dev, "no valid minimum freq: %d\n", ret); in dw_mci_rockchip_init()
520 { .compatible = "rockchip,rk2928-dw-mshc",
522 { .compatible = "rockchip,rk3288-dw-mshc",
524 { .compatible = "rockchip,rk3576-dw-mshc",
536 if (!pdev->dev.of_node) in dw_mci_rockchip_probe()
537 return -ENODEV; in dw_mci_rockchip_probe()
539 match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node); in dw_mci_rockchip_probe()
540 drv_data = match->data; in dw_mci_rockchip_probe()
542 pm_runtime_get_noresume(&pdev->dev); in dw_mci_rockchip_probe()
543 pm_runtime_set_active(&pdev->dev); in dw_mci_rockchip_probe()
544 pm_runtime_enable(&pdev->dev); in dw_mci_rockchip_probe()
545 pm_runtime_set_autosuspend_delay(&pdev->dev, 50); in dw_mci_rockchip_probe()
546 pm_runtime_use_autosuspend(&pdev->dev); in dw_mci_rockchip_probe()
550 pm_runtime_disable(&pdev->dev); in dw_mci_rockchip_probe()
551 pm_runtime_set_suspended(&pdev->dev); in dw_mci_rockchip_probe()
552 pm_runtime_put_noidle(&pdev->dev); in dw_mci_rockchip_probe()
556 pm_runtime_put_autosuspend(&pdev->dev); in dw_mci_rockchip_probe()
563 pm_runtime_get_sync(&pdev->dev); in dw_mci_rockchip_remove()
564 pm_runtime_disable(&pdev->dev); in dw_mci_rockchip_remove()
565 pm_runtime_put_noidle(&pdev->dev); in dw_mci_rockchip_remove()
591 MODULE_AUTHOR("Addy Ke <addy.ke@rock-chips.com>");
592 MODULE_DESCRIPTION("Rockchip Specific DW-MSHC Driver Extension");