phy: rockchip-samsung-hdptx-hdmi: Add function of enabling PLL independently in FRL mode

The phy pll must be enabled before access hdmi controller registers.
To support config hdmi controller registers before phy output is
enabled, pll must be enabled separately in both TMDS and FRL mode.

Signed-off-by: Algea Cao <algea.cao@rock-chips.com>
Change-Id: I1860c8a333e37db0c3406a0487ec916d5fd94976
This commit is contained in:
Algea Cao
2022-07-13 20:49:30 +08:00
committed by Tao Huang
parent d0eb5198e1
commit 0e95e08982

View File

@@ -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;