Lines Matching +full:px30 +full:- +full:dsi +full:- +full:dphy
1 // SPDX-License-Identifier: GPL-2.0
5 * Author: Wyon Bi <bivvy.bi@rock-chips.com>
11 #include <linux/clk-provider.h>
19 #include <linux/phy/phy-mipi-dphy.h>
201 PX30, enumerator
312 orig = readl(inno->phy_base + reg); in phy_update_bits()
315 writel(tmp, inno->phy_base + reg); in phy_update_bits()
323 orig = readl(inno->host_base + reg); in host_update_bits()
326 writel(tmp, inno->host_base + reg); in host_update_bits()
332 unsigned long prate = clk_get_rate(inno->ref_clk); in inno_dsidphy_pll_calc_rate()
343 * PLL_Output_Frequency: it is equal to DDR-Clock-Frequency * 2 in inno_dsidphy_pll_calc_rate()
376 delta = abs(fout - tmp); in inno_dsidphy_pll_calc_rate()
391 inno->pll.prediv = best_prediv; in inno_dsidphy_pll_calc_rate()
392 inno->pll.fbdiv = best_fbdiv; in inno_dsidphy_pll_calc_rate()
393 inno->pll.rate = best_freq; in inno_dsidphy_pll_calc_rate()
404 unsigned int lane_mbps = inno->pll.rate / USEC_PER_SEC; in inno_mipi_dphy_get_timing()
407 timings = inno->pdata->inno_mipi_dphy_timing_table; in inno_mipi_dphy_get_timing()
408 num_timings = inno->pdata->num_timings; in inno_mipi_dphy_get_timing()
415 --i; in inno_mipi_dphy_get_timing()
424 REG_PREDIV_MASK, REG_PREDIV(inno->pll.prediv)); in inno_mipi_dphy_max_2_5GHz_pll_enable()
426 REG_FBDIV_HI_MASK, REG_FBDIV_HI(inno->pll.fbdiv)); in inno_mipi_dphy_max_2_5GHz_pll_enable()
428 REG_FBDIV_LO_MASK, REG_FBDIV_LO(inno->pll.fbdiv)); in inno_mipi_dphy_max_2_5GHz_pll_enable()
443 REG_PREDIV_MASK, REG_PREDIV(inno->pll.prediv)); in inno_mipi_dphy_max_1GHz_pll_enable()
445 REG_FBDIV_HI_MASK, REG_FBDIV_HI(inno->pll.fbdiv)); in inno_mipi_dphy_max_1GHz_pll_enable()
447 REG_FBDIV_LO_MASK, REG_FBDIV_LO(inno->pll.fbdiv)); in inno_mipi_dphy_max_1GHz_pll_enable()
472 struct phy_configure_opts_mipi_dphy *cfg = &inno->dphy_cfg; in inno_mipi_dphy_timing_init()
480 txbyteclkhs = inno->pll.rate / 8; in inno_mipi_dphy_timing_init()
488 * The value of counter for HS Ths-exit in inno_mipi_dphy_timing_init()
489 * Ths-exit = Tpin_txbyteclkhs * value in inno_mipi_dphy_timing_init()
491 hs_exit = DIV_ROUND_UP(cfg->hs_exit, t_txbyteclkhs); in inno_mipi_dphy_timing_init()
493 * The value of counter for HS Tclk-post in inno_mipi_dphy_timing_init()
494 * Tclk-post = Tpin_txbyteclkhs * value in inno_mipi_dphy_timing_init()
496 clk_post = DIV_ROUND_UP(cfg->clk_post, t_txbyteclkhs); in inno_mipi_dphy_timing_init()
498 * The value of counter for HS Tclk-pre in inno_mipi_dphy_timing_init()
499 * Tclk-pre = Tpin_txbyteclkhs * value in inno_mipi_dphy_timing_init()
501 clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs); in inno_mipi_dphy_timing_init()
503 * The value of counter for HS Tta-go in inno_mipi_dphy_timing_init()
504 * Tta-go for turnaround in inno_mipi_dphy_timing_init()
505 * Tta-go = Ttxclkesc * value in inno_mipi_dphy_timing_init()
507 ta_go = DIV_ROUND_UP(cfg->ta_go, t_txclkesc); in inno_mipi_dphy_timing_init()
509 * The value of counter for HS Tta-sure in inno_mipi_dphy_timing_init()
510 * Tta-sure for turnaround in inno_mipi_dphy_timing_init()
511 * Tta-sure = Ttxclkesc * value in inno_mipi_dphy_timing_init()
513 ta_sure = DIV_ROUND_UP(cfg->ta_sure, t_txclkesc); in inno_mipi_dphy_timing_init()
515 * The value of counter for HS Tta-wait in inno_mipi_dphy_timing_init()
516 * Tta-wait for turnaround in inno_mipi_dphy_timing_init()
517 * Tta-wait = Ttxclkesc * value in inno_mipi_dphy_timing_init()
519 ta_wait = DIV_ROUND_UP(cfg->ta_get, t_txclkesc); in inno_mipi_dphy_timing_init()
526 if (inno->pdata->max_rate == MAX_1GHZ) { in inno_mipi_dphy_timing_init()
527 lpx = DIV_ROUND_UP(cfg->lpx, t_txbyteclkhs); in inno_mipi_dphy_timing_init()
529 lpx -= 2; in inno_mipi_dphy_timing_init()
531 lpx = timing->lpx; in inno_mipi_dphy_timing_init()
533 hs_prepare = timing->hs_prepare; in inno_mipi_dphy_timing_init()
534 hs_trail = timing->hs_trail; in inno_mipi_dphy_timing_init()
535 clk_lane_hs_zero = timing->clk_lane_hs_zero; in inno_mipi_dphy_timing_init()
536 data_lane_hs_zero = timing->data_lane_hs_zero; in inno_mipi_dphy_timing_init()
550 if (inno->pdata->max_rate == MAX_2_5GHZ) in inno_mipi_dphy_timing_init()
559 if (inno->pdata->max_rate == MAX_2_5GHZ) in inno_mipi_dphy_timing_init()
566 if (inno->pdata->max_rate == MAX_2_5GHZ) in inno_mipi_dphy_timing_init()
591 switch (inno->lanes) { in inno_mipi_dphy_lane_enable()
617 if (inno->pdata->soc_type == PX30S) in inno_dsidphy_mipi_mode_enable()
621 if (inno->pdata->max_rate == MAX_2_5GHZ) in inno_dsidphy_mipi_mode_enable()
718 clk_prepare_enable(inno->pclk_phy); in inno_dsidphy_power_on()
719 clk_prepare_enable(inno->ref_clk); in inno_dsidphy_power_on()
720 pm_runtime_get_sync(inno->dev); in inno_dsidphy_power_on()
764 pm_runtime_put(inno->dev); in inno_dsidphy_power_off()
765 clk_disable_unprepare(inno->ref_clk); in inno_dsidphy_power_off()
766 clk_disable_unprepare(inno->pclk_phy); in inno_dsidphy_power_off()
781 struct phy_configure_opts_mipi_dphy *cfg = &inno->dphy_cfg; in inno_dsidphy_configure()
786 return -EINVAL; in inno_dsidphy_configure()
788 ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy); in inno_dsidphy_configure()
792 memcpy(&inno->dphy_cfg, &opts->mipi_dphy, sizeof(inno->dphy_cfg)); in inno_dsidphy_configure()
794 inno_dsidphy_pll_calc_rate(inno, cfg->hs_clk_rate); in inno_dsidphy_configure()
795 cfg->hs_clk_rate = inno->pll.rate; in inno_dsidphy_configure()
796 opts->mipi_dphy.hs_clk_rate = inno->pll.rate; in inno_dsidphy_configure()
805 clk_prepare_enable(inno->pclk_phy); in inno_dsidphy_init()
806 clk_prepare_enable(inno->ref_clk); in inno_dsidphy_init()
807 pm_runtime_get_sync(inno->dev); in inno_dsidphy_init()
816 pm_runtime_put(inno->dev); in inno_dsidphy_exit()
817 clk_disable_unprepare(inno->ref_clk); in inno_dsidphy_exit()
818 clk_disable_unprepare(inno->pclk_phy); in inno_dsidphy_exit()
834 .soc_type = PX30,
884 struct device *dev = &pdev->dev; in inno_dsidphy_probe()
893 return -ENOMEM; in inno_dsidphy_probe()
895 inno->dev = dev; in inno_dsidphy_probe()
896 inno->pdata = of_device_get_match_data(inno->dev); in inno_dsidphy_probe()
898 inno->pdata = &px30s_video_phy_plat_data; in inno_dsidphy_probe()
902 inno->phy_base = devm_platform_ioremap_resource_byname(pdev, "phy"); in inno_dsidphy_probe()
903 if (IS_ERR(inno->phy_base)) in inno_dsidphy_probe()
904 return PTR_ERR(inno->phy_base); in inno_dsidphy_probe()
909 return -EINVAL; in inno_dsidphy_probe()
912 inno->host_base = devm_ioremap(dev, res->start, resource_size(res)); in inno_dsidphy_probe()
913 if (IS_ERR(inno->host_base)) in inno_dsidphy_probe()
914 return PTR_ERR(inno->host_base); in inno_dsidphy_probe()
916 inno->ref_clk = devm_clk_get(dev, "ref"); in inno_dsidphy_probe()
917 if (IS_ERR(inno->ref_clk)) { in inno_dsidphy_probe()
918 ret = PTR_ERR(inno->ref_clk); in inno_dsidphy_probe()
923 inno->pclk_phy = devm_clk_get(dev, "pclk"); in inno_dsidphy_probe()
924 if (IS_ERR(inno->pclk_phy)) { in inno_dsidphy_probe()
925 ret = PTR_ERR(inno->pclk_phy); in inno_dsidphy_probe()
930 inno->pclk_host = devm_clk_get(dev, "pclk_host"); in inno_dsidphy_probe()
931 if (IS_ERR(inno->pclk_host)) { in inno_dsidphy_probe()
932 ret = PTR_ERR(inno->pclk_host); in inno_dsidphy_probe()
937 inno->rst = devm_reset_control_get(dev, "apb"); in inno_dsidphy_probe()
938 if (IS_ERR(inno->rst)) { in inno_dsidphy_probe()
939 ret = PTR_ERR(inno->rst); in inno_dsidphy_probe()
951 if (of_property_read_u32(dev->of_node, "inno,lanes", &inno->lanes)) in inno_dsidphy_probe()
952 inno->lanes = 4; in inno_dsidphy_probe()
972 pm_runtime_disable(inno->dev); in inno_dsidphy_remove()
979 .compatible = "rockchip,px30-dsi-dphy",
982 .compatible = "rockchip,px30s-dsi-dphy",
985 .compatible = "rockchip,rk3128-dsi-dphy",
988 .compatible = "rockchip,rk3368-dsi-dphy",
991 .compatible = "rockchip,rk3562-dsi-dphy",
994 .compatible = "rockchip,rk3568-dsi-dphy",
997 .compatible = "rockchip,rv1126-mipi-dphy",
1006 .name = "inno-dsidphy",
1014 MODULE_AUTHOR("Wyon Bi <bivvy.bi@rock-chips.com>");