Lines Matching +full:4 +full:- +full:lane
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>
30 * when you configure the registers, you must set both of them. The Clock Lane
31 * and Data Lane use the same registers with the same second address, but the
46 #define LANE_EN_2 BIT(4)
65 #define REG_PREDIV_MASK GENMASK(4, 0)
66 #define REG_PREDIV(x) UPDATE(x, 4, 0)
71 #define SAMPLE_CLOCK_PHASE_MASK GENMASK(6, 4)
72 #define SAMPLE_CLOCK_PHASE(x) UPDATE(x, 6, 4)
76 #define DATA_LANE_3_SKEW_PHASE_MASK GENMASK(6, 4)
77 #define DATA_LANE_3_SKEW_PHASE(x) UPDATE(x, 6, 4)
81 #define DATA_LANE_1_SKEW_PHASE_MASK GENMASK(6, 4)
82 #define DATA_LANE_1_SKEW_PHASE(x) UPDATE(x, 6, 4)
86 #define SAMPLE_CLOCK_DIRECTION_MASK BIT(4)
87 #define SAMPLE_CLOCK_DIRECTION_REVERSE BIT(4)
100 /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg05 */
103 /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg06 */
106 /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg07 */
109 /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg08 */
112 /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg09 */
113 #define T_HS_EXIT_CNT_MASK GENMASK(4, 0)
114 #define T_HS_EXIT_CNT(x) UPDATE(x, 4, 0)
115 /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0a */
118 /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0c */
124 /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0d */
127 /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0e */
130 /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg10 */
133 /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg11 */
136 /* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg12 */
157 #define LVDS_DATA_LANE3_EN BIT(4)
213 orig = readl(inno->phy_base + reg); in phy_update_bits()
216 writel(tmp, inno->phy_base + reg); in phy_update_bits()
222 unsigned long prate = clk_get_rate(inno->ref_clk); in inno_dsidphy_pll_calc_rate()
233 * PLL_Output_Frequency: it is equal to DDR-Clock-Frequency * 2 in inno_dsidphy_pll_calc_rate()
266 delta = abs(fout - tmp); in inno_dsidphy_pll_calc_rate()
281 inno->pll.prediv = best_prediv; in inno_dsidphy_pll_calc_rate()
282 inno->pll.fbdiv = best_fbdiv; in inno_dsidphy_pll_calc_rate()
283 inno->pll.rate = best_freq; in inno_dsidphy_pll_calc_rate()
291 struct phy_configure_opts_mipi_dphy *cfg = &inno->dphy_cfg; in inno_dsidphy_mipi_mode_enable()
317 inno_dsidphy_pll_calc_rate(inno, cfg->hs_clk_rate); in inno_dsidphy_mipi_mode_enable()
324 REG_PREDIV_MASK, REG_PREDIV(inno->pll.prediv)); in inno_dsidphy_mipi_mode_enable()
326 REG_FBDIV_HI_MASK, REG_FBDIV_HI(inno->pll.fbdiv)); in inno_dsidphy_mipi_mode_enable()
328 REG_FBDIV_LO_MASK, REG_FBDIV_LO(inno->pll.fbdiv)); in inno_dsidphy_mipi_mode_enable()
346 txbyteclkhs = inno->pll.rate / 8; in inno_dsidphy_mipi_mode_enable()
354 * The value of counter for HS Ths-exit in inno_dsidphy_mipi_mode_enable()
355 * Ths-exit = Tpin_txbyteclkhs * value in inno_dsidphy_mipi_mode_enable()
357 hs_exit = DIV_ROUND_UP(cfg->hs_exit, t_txbyteclkhs); in inno_dsidphy_mipi_mode_enable()
359 * The value of counter for HS Tclk-post in inno_dsidphy_mipi_mode_enable()
360 * Tclk-post = Tpin_txbyteclkhs * value in inno_dsidphy_mipi_mode_enable()
362 clk_post = DIV_ROUND_UP(cfg->clk_post, t_txbyteclkhs); in inno_dsidphy_mipi_mode_enable()
364 * The value of counter for HS Tclk-pre in inno_dsidphy_mipi_mode_enable()
365 * Tclk-pre = Tpin_txbyteclkhs * value in inno_dsidphy_mipi_mode_enable()
367 clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs); in inno_dsidphy_mipi_mode_enable()
373 lpx = DIV_ROUND_UP(cfg->lpx, t_txbyteclkhs); in inno_dsidphy_mipi_mode_enable()
375 lpx -= 2; in inno_dsidphy_mipi_mode_enable()
378 * The value of counter for HS Tta-go in inno_dsidphy_mipi_mode_enable()
379 * Tta-go for turnaround in inno_dsidphy_mipi_mode_enable()
380 * Tta-go = Ttxclkesc * value in inno_dsidphy_mipi_mode_enable()
382 ta_go = DIV_ROUND_UP(cfg->ta_go, t_txclkesc); in inno_dsidphy_mipi_mode_enable()
384 * The value of counter for HS Tta-sure in inno_dsidphy_mipi_mode_enable()
385 * Tta-sure for turnaround in inno_dsidphy_mipi_mode_enable()
386 * Tta-sure = Ttxclkesc * value in inno_dsidphy_mipi_mode_enable()
388 ta_sure = DIV_ROUND_UP(cfg->ta_sure, t_txclkesc); in inno_dsidphy_mipi_mode_enable()
390 * The value of counter for HS Tta-wait in inno_dsidphy_mipi_mode_enable()
391 * Tta-wait for turnaround in inno_dsidphy_mipi_mode_enable()
392 * Tta-wait = Ttxclkesc * value in inno_dsidphy_mipi_mode_enable()
394 ta_wait = DIV_ROUND_UP(cfg->ta_get, t_txclkesc); in inno_dsidphy_mipi_mode_enable()
397 if (inno->pll.rate <= timings[i].rate) in inno_dsidphy_mipi_mode_enable()
401 --i; in inno_dsidphy_mipi_mode_enable()
498 clk_prepare_enable(inno->pclk_phy); in inno_dsidphy_power_on()
499 clk_prepare_enable(inno->ref_clk); in inno_dsidphy_power_on()
500 pm_runtime_get_sync(inno->dev); in inno_dsidphy_power_on()
509 switch (inno->mode) { in inno_dsidphy_power_on()
517 return -EINVAL; in inno_dsidphy_power_on()
544 pm_runtime_put(inno->dev); in inno_dsidphy_power_off()
545 clk_disable_unprepare(inno->ref_clk); in inno_dsidphy_power_off()
546 clk_disable_unprepare(inno->pclk_phy); in inno_dsidphy_power_off()
559 inno->mode = mode; in inno_dsidphy_set_mode()
562 return -EINVAL; in inno_dsidphy_set_mode()
574 if (inno->mode != PHY_MODE_MIPI_DPHY) in inno_dsidphy_configure()
575 return -EINVAL; in inno_dsidphy_configure()
577 ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy); in inno_dsidphy_configure()
581 memcpy(&inno->dphy_cfg, &opts->mipi_dphy, sizeof(inno->dphy_cfg)); in inno_dsidphy_configure()
596 struct device *dev = &pdev->dev; in inno_dsidphy_probe()
604 return -ENOMEM; in inno_dsidphy_probe()
606 inno->dev = dev; in inno_dsidphy_probe()
609 inno->phy_base = devm_platform_ioremap_resource(pdev, 0); in inno_dsidphy_probe()
610 if (IS_ERR(inno->phy_base)) in inno_dsidphy_probe()
611 return PTR_ERR(inno->phy_base); in inno_dsidphy_probe()
613 inno->ref_clk = devm_clk_get(dev, "ref"); in inno_dsidphy_probe()
614 if (IS_ERR(inno->ref_clk)) { in inno_dsidphy_probe()
615 ret = PTR_ERR(inno->ref_clk); in inno_dsidphy_probe()
620 inno->pclk_phy = devm_clk_get(dev, "pclk"); in inno_dsidphy_probe()
621 if (IS_ERR(inno->pclk_phy)) { in inno_dsidphy_probe()
622 ret = PTR_ERR(inno->pclk_phy); in inno_dsidphy_probe()
627 inno->rst = devm_reset_control_get(dev, "apb"); in inno_dsidphy_probe()
628 if (IS_ERR(inno->rst)) { in inno_dsidphy_probe()
629 ret = PTR_ERR(inno->rst); in inno_dsidphy_probe()
659 pm_runtime_disable(inno->dev); in inno_dsidphy_remove()
665 { .compatible = "rockchip,px30-dsi-dphy", },
666 { .compatible = "rockchip,rk3128-dsi-dphy", },
667 { .compatible = "rockchip,rk3368-dsi-dphy", },
674 .name = "inno-dsidphy",
682 MODULE_AUTHOR("Wyon Bi <bivvy.bi@rock-chips.com>");