mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user