Lines Matching +full:combo +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0
5 * Author: Wyon Bi <bivvy.bi@rock-chips.com>
11 #include <linux/clk-provider.h>
18 #include <linux/phy/phy.h>
19 #include <linux/phy/phy-mipi-dphy.h>
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()
494 static int inno_dsidphy_power_on(struct phy *phy) in inno_dsidphy_power_on() argument
496 struct inno_dsidphy *inno = phy_get_drvdata(phy); in inno_dsidphy_power_on()
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()
523 static int inno_dsidphy_power_off(struct phy *phy) in inno_dsidphy_power_off() argument
525 struct inno_dsidphy *inno = phy_get_drvdata(phy); in inno_dsidphy_power_off()
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()
551 static int inno_dsidphy_set_mode(struct phy *phy, enum phy_mode mode, in inno_dsidphy_set_mode() argument
554 struct inno_dsidphy *inno = phy_get_drvdata(phy); in inno_dsidphy_set_mode()
559 inno->mode = mode; in inno_dsidphy_set_mode()
562 return -EINVAL; in inno_dsidphy_set_mode()
568 static int inno_dsidphy_configure(struct phy *phy, in inno_dsidphy_configure() argument
571 struct inno_dsidphy *inno = phy_get_drvdata(phy); in inno_dsidphy_configure()
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()
599 struct phy *phy; in inno_dsidphy_probe() local
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()
623 dev_err(dev, "failed to get phy pclk: %d\n", ret); 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()
634 phy = devm_phy_create(dev, NULL, &inno_dsidphy_ops); in inno_dsidphy_probe()
635 if (IS_ERR(phy)) { in inno_dsidphy_probe()
636 ret = PTR_ERR(phy); in inno_dsidphy_probe()
637 dev_err(dev, "failed to create phy: %d\n", ret); in inno_dsidphy_probe()
641 phy_set_drvdata(phy, inno); in inno_dsidphy_probe()
646 dev_err(dev, "failed to register phy provider: %d\n", ret); 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>");
683 MODULE_DESCRIPTION("Innosilicon MIPI/LVDS/TTL Video Combo PHY driver");