diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx-hdmi.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx-hdmi.c index 7ae0510124de..7f39af64397f 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx-hdmi.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx-hdmi.c @@ -917,6 +917,8 @@ static int hdptx_post_enable_lane(struct rockchip_hdptx_phy *hdptx) HDPTX_I_BGR_EN; hdptx_grf_write(hdptx, GRF_HDPTX_CON0, val); + hdptx_write(hdptx, LNTOP_REG0207, 0x0f); + for (i = 0; i < 50; i++) { val = hdptx_grf_read(hdptx, GRF_HDPTX_STATUS); @@ -1395,14 +1397,6 @@ static int hdptx_ropll_tmds_mode_config(struct rockchip_hdptx_phy *hdptx, u32 ra { u32 bit_rate = rate & DATA_RATE_MASK; - if (!(hdptx_grf_read(hdptx, GRF_HDPTX_STATUS) & HDPTX_O_PLL_LOCK_DONE)) { - int ret; - - ret = hdptx_ropll_cmn_config(hdptx, bit_rate); - if (ret) - return ret; - } - hdptx_write(hdptx, SB_REG0114, 0x00); hdptx_write(hdptx, SB_REG0115, 0x00); hdptx_write(hdptx, SB_REG0116, 0x00); @@ -1426,7 +1420,6 @@ static int hdptx_ropll_tmds_mode_config(struct rockchip_hdptx_phy *hdptx, u32 ra } hdptx_write(hdptx, LNTOP_REG0206, 0x07); - hdptx_write(hdptx, LNTOP_REG0207, 0x0f); hdptx_write(hdptx, LANE_REG0303, 0x0c); hdptx_write(hdptx, LANE_REG0307, 0x20); hdptx_write(hdptx, LANE_REG030A, 0x17); @@ -1733,19 +1726,24 @@ static int hdptx_ropll_frl_mode_config(struct rockchip_hdptx_phy *hdptx, u32 rat return hdptx_post_power_up(hdptx); } -static int hdptx_lcpll_frl_mode_config(struct rockchip_hdptx_phy *hdptx, u32 rate) +static int hdptx_lcpll_cmn_config(struct rockchip_hdptx_phy *hdptx, unsigned long rate) { u32 bit_rate = rate & DATA_RATE_MASK; u8 color_depth = (rate & COLOR_DEPTH_MASK) ? 1 : 0; struct lcpll_config *cfg = lcpll_cfg; + dev_info(hdptx->dev, "%s rate:%lu\n", __func__, rate); + + hdptx->rate = bit_rate * 100; for (; cfg->bit_rate != ~0; cfg++) if (bit_rate == cfg->bit_rate) break; - if (cfg->bit_rate == ~0) + if (cfg->bit_rate == ~0) { + dev_err(hdptx->dev, "can't find frl rate, phy pll init failed\n"); return -EINVAL; + } hdptx_pre_power_up(hdptx); @@ -1880,6 +1878,12 @@ static int hdptx_lcpll_frl_mode_config(struct rockchip_hdptx_phy *hdptx, u32 rat hdptx_write(hdptx, CMN_REG0099, 0x00); hdptx_write(hdptx, CMN_REG009A, 0x11); hdptx_write(hdptx, CMN_REG009B, 0x10); + + return hdptx_post_enable_pll(hdptx); +} + +static int hdptx_lcpll_frl_mode_config(struct rockchip_hdptx_phy *hdptx, u32 rate) +{ hdptx_write(hdptx, SB_REG0114, 0x00); hdptx_write(hdptx, SB_REG0115, 0x00); hdptx_write(hdptx, SB_REG0116, 0x00); @@ -1891,7 +1895,6 @@ static int hdptx_lcpll_frl_mode_config(struct rockchip_hdptx_phy *hdptx, u32 rat hdptx_write(hdptx, LNTOP_REG0204, 0xff); hdptx_write(hdptx, LNTOP_REG0205, 0xff); hdptx_write(hdptx, LNTOP_REG0206, 0x05); - hdptx_write(hdptx, LNTOP_REG0207, 0x0f); hdptx_write(hdptx, LANE_REG0303, 0x0c); hdptx_write(hdptx, LANE_REG0307, 0x20); hdptx_write(hdptx, LANE_REG030A, 0x17); @@ -1974,7 +1977,7 @@ static int hdptx_lcpll_frl_mode_config(struct rockchip_hdptx_phy *hdptx, u32 rat if (hdptx->earc_en) hdptx_earc_config(hdptx); - return hdptx_post_power_up(hdptx); + return hdptx_post_enable_lane(hdptx); } static int rockchip_hdptx_phy_power_on(struct phy *phy) @@ -1982,15 +1985,6 @@ static int rockchip_hdptx_phy_power_on(struct phy *phy) struct rockchip_hdptx_phy *hdptx = phy_get_drvdata(phy); int bus_width = phy_get_bus_width(hdptx->phy); int bit_rate = bus_width & DATA_RATE_MASK; - int ret; - - if (!hdptx->count) { - ret = clk_bulk_enable(hdptx->nr_clks, hdptx->clks); - if (ret) { - dev_err(hdptx->dev, "failed to enable clocks\n"); - return ret; - } - } dev_info(hdptx->dev, "bus_width:0x%x,bit_rate:%d\n", bus_width, bit_rate); if (bus_width & HDMI_EARC_MASK) @@ -2011,14 +2005,8 @@ static int rockchip_hdptx_phy_power_off(struct phy *phy) { struct rockchip_hdptx_phy *hdptx = phy_get_drvdata(phy); - if (hdptx->count) - return 0; - - if (!(hdptx_grf_read(hdptx, GRF_HDPTX_STATUS) & HDPTX_O_PLL_LOCK_DONE)) - return 0; - - hdptx_phy_disable(hdptx); - clk_bulk_disable(hdptx->nr_clks, hdptx->clks); + /* disable phy lane output */ + hdptx_write(hdptx, LNTOP_REG0207, 0); return 0; } @@ -2079,9 +2067,10 @@ static int hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate, if (hdptx_grf_read(hdptx, GRF_HDPTX_STATUS) & HDPTX_O_PLL_LOCK_DONE) hdptx_phy_disable(hdptx); - rate = rate / 100; - - return hdptx_ropll_cmn_config(hdptx, rate); + if (rate > HDMI20_MAX_RATE) + return hdptx_lcpll_cmn_config(hdptx, rate / 100); + else + return hdptx_ropll_cmn_config(hdptx, rate / 100); } static int hdptx_phy_clk_enable(struct clk_hw *hw) @@ -2101,7 +2090,10 @@ static int hdptx_phy_clk_enable(struct clk_hw *hw) } if (hdptx->rate) { - ret = hdptx_ropll_cmn_config(hdptx, hdptx->rate / 100); + if (hdptx->rate > HDMI20_MAX_RATE) + ret = hdptx_lcpll_cmn_config(hdptx, hdptx->rate / 100); + else + ret = hdptx_ropll_cmn_config(hdptx, hdptx->rate / 100); if (ret < 0) { dev_err(hdptx->dev, "hdmi phy pll init failed\n"); return ret;