mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
phy: rockchip-samsung-hdptx-hdmi: Fix get phy pll freq failed in frl mode
Get phy pll freq failed in frl mode should read lcpll regs.
Fixes: fff8ec3ee9 ("phy: rockchip-samsung-hdptx-hdmi: Fix phy pll is incorrectly configured when logo is enabled.")
Change-Id: I64e973f85acd74ee251b4ab6c0a141394c116d92
Signed-off-by: Algea Cao <algea.cao@rock-chips.com>
This commit is contained in:
@@ -729,7 +729,7 @@ struct rockchip_hdptx_phy {
|
||||
int count;
|
||||
};
|
||||
|
||||
struct lcpll_config lcpll_cfg[] = {
|
||||
static struct lcpll_config lcpll_cfg[] = {
|
||||
{ 48000000, 1, 0, 0, 0x7d, 0x7d, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2,
|
||||
0, 0x13, 0x18, 1, 0, 0x20, 0x0c, 1, 0,
|
||||
},
|
||||
@@ -745,27 +745,9 @@ struct lcpll_config lcpll_cfg[] = {
|
||||
{ 9000000, 1, 0, 0, 0x7d, 0x7d, 1, 1, 3, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2,
|
||||
0, 0x13, 0x18, 1, 0, 0x20, 0x0c, 1, 0,
|
||||
},
|
||||
{ ~0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
};
|
||||
|
||||
struct ropll_config ropll_frl_cfg[] = {
|
||||
{ 24000000, 0x19, 0x19, 1, 1, 0, 1, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0,
|
||||
0, 0x20, 0x0c, 1, 0x0e, 0, 0,
|
||||
},
|
||||
{ 18000000, 0x7d, 0x7d, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0,
|
||||
0, 0x20, 0x0c, 1, 0x0e, 0, 0,
|
||||
},
|
||||
{ 9000000, 0x7d, 0x7d, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0,
|
||||
0, 0x20, 0x0c, 1, 0x0e, 0, 0,
|
||||
},
|
||||
{ ~0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
},
|
||||
};
|
||||
|
||||
struct ropll_config ropll_tmds_cfg[] = {
|
||||
static struct ropll_config ropll_tmds_cfg[] = {
|
||||
{ 5940000, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0,
|
||||
1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0,
|
||||
},
|
||||
@@ -826,9 +808,6 @@ struct ropll_config ropll_tmds_cfg[] = {
|
||||
{ 251750, 84, 84, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 168, 1, 16, 4, 1,
|
||||
1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0,
|
||||
},
|
||||
{ ~0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
},
|
||||
};
|
||||
|
||||
static bool rockchip_hdptx_phy_is_accissible_reg(struct device *dev,
|
||||
@@ -1166,8 +1145,9 @@ static int hdptx_ropll_cmn_config(struct rockchip_hdptx_phy *hdptx, unsigned lon
|
||||
{
|
||||
int bus_width = phy_get_bus_width(hdptx->phy);
|
||||
u8 color_depth = (bus_width & COLOR_DEPTH_MASK) ? 1 : 0;
|
||||
struct ropll_config *cfg = ropll_tmds_cfg;
|
||||
struct ropll_config *cfg;
|
||||
struct ropll_config rc = {0};
|
||||
u8 i;
|
||||
|
||||
dev_info(hdptx->dev, "%s bus_width:%x rate:%lu\n", __func__, bus_width, bit_rate);
|
||||
hdptx->rate = bit_rate * 100;
|
||||
@@ -1175,17 +1155,19 @@ static int hdptx_ropll_cmn_config(struct rockchip_hdptx_phy *hdptx, unsigned lon
|
||||
if (color_depth)
|
||||
bit_rate = bit_rate * 10 / 8;
|
||||
|
||||
for (; cfg->bit_rate != ~0; cfg++)
|
||||
if (bit_rate == cfg->bit_rate)
|
||||
for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
|
||||
if (bit_rate == ropll_tmds_cfg[i].bit_rate)
|
||||
break;
|
||||
|
||||
if (cfg->bit_rate == ~0) {
|
||||
if (i == ARRAY_SIZE(ropll_tmds_cfg)) {
|
||||
if (hdptx_phy_clk_pll_calc(bit_rate, &rc)) {
|
||||
cfg = &rc;
|
||||
} else {
|
||||
dev_err(hdptx->dev, "%s can't find pll cfg\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
cfg = &ropll_tmds_cfg[i];
|
||||
}
|
||||
|
||||
dev_dbg(hdptx->dev, "mdiv=%u, sdiv=%u\n",
|
||||
@@ -1610,21 +1592,24 @@ static int hdptx_lcpll_cmn_config(struct rockchip_hdptx_phy *hdptx, unsigned lon
|
||||
{
|
||||
u32 bit_rate = rate & DATA_RATE_MASK;
|
||||
u8 color_depth = (rate & COLOR_DEPTH_MASK) ? 1 : 0;
|
||||
struct lcpll_config *cfg = lcpll_cfg;
|
||||
struct lcpll_config *cfg;
|
||||
u8 i;
|
||||
|
||||
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)
|
||||
for (i = 0; i < ARRAY_SIZE(lcpll_cfg); i++)
|
||||
if (bit_rate == lcpll_cfg[i].bit_rate)
|
||||
break;
|
||||
|
||||
if (cfg->bit_rate == ~0) {
|
||||
if (i == ARRAY_SIZE(lcpll_cfg)) {
|
||||
dev_err(hdptx->dev, "can't find frl rate, phy pll init failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cfg = &lcpll_cfg[i];
|
||||
|
||||
hdptx_pre_power_up(hdptx);
|
||||
|
||||
hdptx_grf_write(hdptx, GRF_HDPTX_CON0, LC_REF_CLK_SEL << 16);
|
||||
@@ -2029,11 +2014,53 @@ static void rockchip_hdptx_phy_runtime_disable(void *data)
|
||||
|
||||
#define PLL_REF_CLK 24000000ULL
|
||||
|
||||
/*
|
||||
* pll frequency in frl mode is calculated differently from that in tmds
|
||||
* mode and is different from the actual frl frequency. So use register
|
||||
* configuration to confirm the current frl frequency.
|
||||
*/
|
||||
static bool hdptx_frl_pll_cfg_equal(struct rockchip_hdptx_phy *hdptx, struct lcpll_config *cfg)
|
||||
{
|
||||
u8 mdiv, sdiv, sdm_num, sdm_deno, sdc_n;
|
||||
bool sdm_num_sign;
|
||||
|
||||
mdiv = hdptx_read(hdptx, CMN_REG0020);
|
||||
sdiv = hdptx_read(hdptx, CMN_REG0023) & 0xf;
|
||||
sdm_num_sign = hdptx_read(hdptx, CMN_REG002B);
|
||||
sdm_num = hdptx_read(hdptx, CMN_REG002C);
|
||||
sdm_deno = hdptx_read(hdptx, CMN_REG002A);
|
||||
sdc_n = (hdptx_read(hdptx, CMN_REG002D) & LCPLL_SDC_N_MASK) >> 1;
|
||||
|
||||
if (cfg->pms_mdiv == mdiv && cfg->pms_sdiv == sdiv && cfg->sdm_num_sign == sdm_num_sign &&
|
||||
cfg->sdm_num == sdm_num && cfg->sdm_deno == sdm_deno && cfg->sdc_n == sdc_n)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static unsigned long hdptx_cal_current_rate(struct rockchip_hdptx_phy *hdptx)
|
||||
{
|
||||
u8 mdiv, sdiv, sdm_num, sdm_deno, sdc_n, sdc_num, sdc_deno;
|
||||
u64 fout, sdm;
|
||||
bool sdm_en, sdm_num_sign;
|
||||
struct lcpll_config *cfg;
|
||||
u8 i;
|
||||
|
||||
/* frl mode phy pll clk will not be used */
|
||||
if (hdptx_read(hdptx, CMN_REG0008) & LCPLL_LCVCO_MODE_EN_MASK) {
|
||||
for (i = 0; i < ARRAY_SIZE(lcpll_cfg); i++) {
|
||||
cfg = &lcpll_cfg[i];
|
||||
if (hdptx_frl_pll_cfg_equal(hdptx, cfg))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(lcpll_cfg)) {
|
||||
dev_err(hdptx->dev, "can't find frl rate, phy pll init failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return cfg->bit_rate * 100;
|
||||
}
|
||||
|
||||
mdiv = hdptx_read(hdptx, CMN_REG0051);
|
||||
sdm_en = hdptx_read(hdptx, CMN_REG005E) & ROPLL_SDM_EN_MASK;
|
||||
@@ -2080,17 +2107,17 @@ static unsigned long hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
|
||||
static long hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct ropll_config *cfg = ropll_tmds_cfg;
|
||||
u32 bit_rate = rate / 100;
|
||||
u8 i;
|
||||
|
||||
if (rate > HDMI20_MAX_RATE)
|
||||
return rate;
|
||||
|
||||
for (; cfg->bit_rate != ~0; cfg++)
|
||||
if (bit_rate == cfg->bit_rate)
|
||||
for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
|
||||
if (bit_rate == ropll_tmds_cfg[i].bit_rate)
|
||||
break;
|
||||
|
||||
if (cfg->bit_rate == ~0 && !hdptx_phy_clk_pll_calc(bit_rate, NULL))
|
||||
if (i == ARRAY_SIZE(ropll_tmds_cfg) && !hdptx_phy_clk_pll_calc(bit_rate, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
return rate;
|
||||
|
||||
Reference in New Issue
Block a user