Merge "clk: qcom: mdss: update dsi 12nm clock driver"

This commit is contained in:
qctecmdr 2020-07-09 05:21:28 -07:00 committed by Gerrit - the friendly Code Review server
commit e1182a30ef
4 changed files with 115 additions and 54 deletions

View File

@ -24,17 +24,31 @@
#define DSI_PLL_POLL_MAX_READS 15
#define DSI_PLL_POLL_TIMEOUT_US 1000
static void __mdss_dsi_get_pll_vco_cntrl(u64 target_freq, u32 post_div_mux,
u32 *vco_cntrl, u32 *cpbias_cntrl);
int pixel_div_set_div(void *context, unsigned int reg,
unsigned int div)
{
struct mdss_pll_resources *pll = context;
void __iomem *pll_base = pll->pll_base;
int rc;
char data = 0;
struct dsi_pll_db *pdb;
pdb = (struct dsi_pll_db *)pll->priv;
rc = mdss_pll_resource_enable(pll, true);
if (rc) {
pr_err("Failed to enable mdss dsi pll resources\n");
return rc;
}
/* Programming during vco_prepare. Keep this value */
pdb->param.pixel_divhf = (div - 1);
data = ((div - 1) & 0x7f);
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC9, data);
pdb->param.pixel_divhf = data;
mdss_pll_resource_enable(pll, false);
pr_debug("ndx=%d div=%d divhf=%d\n",
pll->index, div, pdb->param.pixel_divhf);
@ -46,6 +60,7 @@ int pixel_div_get_div(void *context, unsigned int reg,
{
int rc;
struct mdss_pll_resources *pll = context;
u32 val = 0;
if (is_gdsc_disabled(pll))
return 0;
@ -56,8 +71,9 @@ int pixel_div_get_div(void *context, unsigned int reg,
return rc;
}
*div = (MDSS_PLL_REG_R(pll->pll_base, DSIPHY_SSC9) & 0x7F);
pr_debug("pixel_div = %d\n", (*div+1));
val = (MDSS_PLL_REG_R(pll->pll_base, DSIPHY_SSC9) & 0x7F);
*div = val + 1;
pr_debug("pixel_div = %d\n", (*div));
mdss_pll_resource_enable(pll, false);
@ -68,13 +84,30 @@ int set_post_div_mux_sel(void *context, unsigned int reg,
unsigned int sel)
{
struct mdss_pll_resources *pll = context;
void __iomem *pll_base = pll->pll_base;
struct dsi_pll_db *pdb;
u64 target_freq = 0;
u32 vco_cntrl = 0, cpbias_cntrl = 0;
char data = 0;
pdb = (struct dsi_pll_db *)pll->priv;
/* Programming during vco_prepare. Keep this value */
pdb->param.post_div_mux = sel;
target_freq = div_u64(pll->vco_current_rate,
BIT(pdb->param.post_div_mux));
__mdss_dsi_get_pll_vco_cntrl(target_freq, pdb->param.post_div_mux,
&vco_cntrl, &cpbias_cntrl);
data = ((vco_cntrl & 0x3f) | BIT(6));
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_CTRL, data);
pr_debug("%s: vco_cntrl 0x%x\n", __func__, vco_cntrl);
data = ((cpbias_cntrl & 0x1) << 6) | BIT(4);
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CHAR_PUMP_BIAS_CTRL, data);
pr_debug("%s: cpbias_cntrl 0x%x\n", __func__, cpbias_cntrl);
pr_debug("ndx=%d post_div_mux_sel=%d p_div=%d\n",
pll->index, sel, (u32) BIT(sel));
@ -99,6 +132,7 @@ int get_post_div_mux_sel(void *context, unsigned int reg,
vco_cntrl = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_PLL_VCO_CTRL);
vco_cntrl &= 0x30;
pr_debug("%s: vco_cntrl 0x%x\n", __func__, vco_cntrl);
cpbias_cntrl = MDSS_PLL_REG_R(pll->pll_base,
DSIPHY_PLL_CHAR_PUMP_BIAS_CTRL);
@ -121,6 +155,7 @@ int get_post_div_mux_sel(void *context, unsigned int reg,
}
mdss_pll_resource_enable(pll, false);
pr_debug("%s: sel = %d\n", __func__, *sel);
return 0;
}
@ -129,16 +164,24 @@ int set_gp_mux_sel(void *context, unsigned int reg,
unsigned int sel)
{
struct mdss_pll_resources *pll = context;
struct dsi_pll_db *pdb;
void __iomem *pll_base = pll->pll_base;
char data = 0;
int rc;
pdb = (struct dsi_pll_db *)pll->priv;
rc = mdss_pll_resource_enable(pll, true);
if (rc) {
pr_err("Failed to enable mdss dsi pll resources\n");
return rc;
}
/* Programming during vco_prepare. Keep this value */
pdb->param.gp_div_mux = sel;
data = ((sel & 0x7) << 5) | 0x5;
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CTRL, data);
pr_debug("ndx=%d gp_div_mux_sel=%d gp_cntrl=%d\n",
pll->index, sel, (u32) BIT(sel));
mdss_pll_resource_enable(pll, false);
return 0;
}
@ -184,7 +227,9 @@ static bool pll_is_pll_locked_12nm(struct mdss_pll_resources *pll,
pr_err("DSI PLL ndx=%d status=%x failed to Lock\n",
pll->index, status);
pll_locked = false;
pr_debug("%s: not locked\n", __func__);
} else {
pr_debug("%s: locked\n", __func__);
pll_locked = true;
}
@ -551,13 +596,13 @@ static void mdss_dsi_pll_12nm_calc_reg(struct mdss_pll_resources *pll,
{
struct dsi_pll_param *param = &pdb->param;
u64 target_freq = 0;
u32 post_div_mux = 0;
get_post_div_mux_sel(pll, 0, &post_div_mux);
target_freq = div_u64(pll->vco_current_rate,
BIT(pdb->param.post_div_mux));
BIT(post_div_mux));
param->hsfreqrange = __mdss_dsi_get_hsfreqrange(target_freq);
__mdss_dsi_get_pll_vco_cntrl(target_freq, param->post_div_mux,
&param->vco_cntrl, &param->cpbias_cntrl);
param->osc_freq_target = __mdss_dsi_get_osc_freq_target(target_freq);
param->m_div = (u32) __mdss_dsi_pll_get_m_div(pll->vco_current_rate);
param->fsm_ovr_ctrl = __mdss_dsi_get_fsm_ovr_ctrl(target_freq);
@ -716,9 +761,6 @@ static void pll_db_commit_12nm(struct mdss_pll_resources *pll,
data = ((param->hsfreqrange & 0x7f) | BIT(7));
MDSS_PLL_REG_W(pll_base, DSIPHY_HS_FREQ_RAN_SEL, data);
data = ((param->vco_cntrl & 0x3f) | BIT(6));
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_CTRL, data);
data = (param->osc_freq_target & 0x7f);
MDSS_PLL_REG_W(pll_base, DSIPHY_SLEWRATE_DDL_CYC_FRQ_ADJ_0, data);
@ -742,15 +784,6 @@ static void pll_db_commit_12nm(struct mdss_pll_resources *pll,
data = ((param->gmp_cntrl & 0x3) << 4);
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_GMP_CTRL_DIG_TST, data);
data = ((param->cpbias_cntrl & 0x1) << 6) | BIT(4);
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CHAR_PUMP_BIAS_CTRL, data);
data = ((param->gp_div_mux & 0x7) << 5) | 0x5;
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CTRL, data);
data = (param->pixel_divhf & 0x7f);
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC9, data);
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_ANA_PROG_CTRL, 0x03);
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_ANA_TST_LOCK_ST_OVR_CTRL, 0x50);
MDSS_PLL_REG_W(pll_base,
@ -788,6 +821,14 @@ int pll_vco_set_rate_12nm(struct clk_hw *hw, unsigned long rate,
pll->vco_current_rate = rate;
pll->vco_ref_clk_rate = vco->ref_clk_rate;
mdss_dsi_pll_12nm_calc_reg(pll, pdb);
if (pll->ssc_en)
mdss_dsi_pll_12nm_calc_ssc(pll, pdb);
/* commit DSI vco */
pll_db_commit_12nm(pll, pdb);
error:
return rc;
}
@ -800,9 +841,13 @@ static unsigned long pll_vco_get_rate_12nm(struct clk_hw *hw)
u64 ref_clk = vco->ref_clk_rate;
int rc;
struct mdss_pll_resources *pll = vco->priv;
u32 post_div_mux;
u32 cpbias_cntrl = 0;
if (is_gdsc_disabled(pll))
if (is_gdsc_disabled(pll)) {
pr_err("%s:gdsc disabled\n", __func__);
return 0;
}
rc = mdss_pll_resource_enable(pll, true);
if (rc) {
@ -820,6 +865,16 @@ static unsigned long pll_vco_get_rate_12nm(struct clk_hw *hw)
m_div_11_6 &= 0x3f;
pr_debug("m_div_11_6 = 0x%x\n", m_div_11_6);
post_div_mux = MDSS_PLL_REG_R(pll->pll_base,
DSIPHY_PLL_VCO_CTRL);
pr_debug("post_div_mux = 0x%x\n", post_div_mux);
cpbias_cntrl = MDSS_PLL_REG_R(pll->pll_base,
DSIPHY_PLL_CHAR_PUMP_BIAS_CTRL);
cpbias_cntrl = ((cpbias_cntrl >> 6) & 0x1);
pr_debug("cpbias_cntrl = 0x%x\n", cpbias_cntrl);
m_div = ((m_div_11_6 << 6) | (m_div_5_0));
vco_rate = div_u64((ref_clk * m_div), 4);
@ -854,12 +909,22 @@ unsigned long vco_12nm_recalc_rate(struct clk_hw *hw,
struct mdss_pll_resources *pll = vco->priv;
unsigned long rate = 0;
int rc;
struct dsi_pll_db *pdb;
pdb = (struct dsi_pll_db *)pll->priv;
if (!pll && is_gdsc_disabled(pll)) {
pr_err("gdsc disabled\n");
return 0;
}
if (pll->vco_current_rate != 0) {
rate = pll_vco_get_rate_12nm(hw);
pr_debug("%s:returning vco rate = %lld\n", __func__,
pll->vco_current_rate);
return rate;
}
rc = mdss_pll_resource_enable(pll, true);
if (rc) {
pr_err("Failed to enable mdss dsi pll=%d\n", pll->index);
@ -870,6 +935,7 @@ unsigned long vco_12nm_recalc_rate(struct clk_hw *hw,
pll->handoff_resources = true;
pll->pll_on = true;
rate = pll_vco_get_rate_12nm(hw);
pr_debug("%s: pll locked. rate %lu\n", __func__, rate);
} else {
mdss_pll_resource_enable(pll, false);
}
@ -930,15 +996,7 @@ int pll_vco_prepare_12nm(struct clk_hw *hw)
goto end;
}
mdss_dsi_pll_12nm_calc_reg(pll, pdb);
if (pll->ssc_en)
mdss_dsi_pll_12nm_calc_ssc(pll, pdb);
/* commit DSI vco */
pll_db_commit_12nm(pll, pdb);
rc = dsi_pll_enable(hw);
error:
if (rc) {
mdss_pll_resource_enable(pll, false);

View File

@ -37,6 +37,7 @@ static const struct clk_ops clk_ops_vco_12nm = {
.round_rate = pll_vco_round_rate_12nm,
.prepare = pll_vco_prepare_12nm,
.unprepare = pll_vco_unprepare_12nm,
.enable = pll_vco_enable_12nm,
};
static struct regmap_bus pclk_div_regmap_bus = {
@ -216,8 +217,8 @@ static struct clk_fixed_factor dsi0pll_post_div32 = {
static struct clk_regmap_mux dsi0pll_post_div_mux = {
.reg = DSIPHY_PLL_VCO_CTRL,
.shift = 4,
.width = 2,
.shift = 0,
.width = 3,
.clkr = {
.hw.init = &(struct clk_init_data){
.name = "dsi0pll_post_div_mux",
@ -308,8 +309,8 @@ static struct clk_fixed_factor dsi1pll_post_div32 = {
static struct clk_regmap_mux dsi1pll_post_div_mux = {
.reg = DSIPHY_PLL_VCO_CTRL,
.shift = 4,
.width = 2,
.shift = 0,
.width = 3,
.clkr = {
.hw.init = &(struct clk_init_data){
.name = "dsi1pll_post_div_mux",
@ -400,7 +401,7 @@ static struct clk_fixed_factor dsi0pll_gp_div32 = {
static struct clk_regmap_mux dsi0pll_gp_div_mux = {
.reg = DSIPHY_PLL_CTRL,
.shift = 5,
.shift = 0,
.width = 3,
.clkr = {
.hw.init = &(struct clk_init_data){
@ -492,7 +493,7 @@ static struct clk_fixed_factor dsi1pll_gp_div32 = {
static struct clk_regmap_mux dsi1pll_gp_div_mux = {
.reg = DSIPHY_PLL_CTRL,
.shift = 5,
.shift = 0,
.width = 3,
.clkr = {
.hw.init = &(struct clk_init_data){
@ -516,11 +517,12 @@ static struct clk_regmap_div dsi0pll_pclk_src = {
.width = 6,
.clkr = {
.hw.init = &(struct clk_init_data){
.name = "dsi0pll_pclk_src",
.name = "dsi0_phy_pll_out_dsiclk",
.parent_names = (const char *[]){
"dsi0pll_gp_div_mux"},
.num_parents = 1,
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT),
.ops = &clk_regmap_div_ops,
},
},
@ -532,11 +534,12 @@ static struct clk_regmap_div dsi1pll_pclk_src = {
.width = 6,
.clkr = {
.hw.init = &(struct clk_init_data){
.name = "dsi1pll_pclk_src",
.name = "dsi1_phy_pll_out_dsiclk",
.parent_names = (const char *[]){
"dsi1pll_gp_div_mux"},
.num_parents = 1,
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT),
.ops = &clk_regmap_div_ops,
},
},
@ -546,10 +549,11 @@ static struct clk_fixed_factor dsi0pll_byte_clk_src = {
.div = 4,
.mult = 1,
.hw.init = &(struct clk_init_data){
.name = "dsi0pll_byte_clk_src",
.name = "dsi0_phy_pll_out_byteclk",
.parent_names = (const char *[]){"dsi0pll_post_div_mux"},
.num_parents = 1,
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT),
.ops = &clk_fixed_factor_ops,
},
};
@ -558,15 +562,15 @@ static struct clk_fixed_factor dsi1pll_byte_clk_src = {
.div = 4,
.mult = 1,
.hw.init = &(struct clk_init_data){
.name = "dsi1pll_byte_clk_src",
.name = "dsi1_phy_pll_out_byteclk",
.parent_names = (const char *[]){"dsi1pll_post_div_mux"},
.num_parents = 1,
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT |
CLK_SET_RATE_NO_REPARENT),
.ops = &clk_fixed_factor_ops,
},
};
static struct clk_hw *mdss_dsi_pllcc_12nm[] = {
[VCO_CLK_0] = &dsi0pll_vco_clk.hw,
[POST_DIV1_0_CLK] = &dsi0pll_post_div1.hw,
@ -608,14 +612,14 @@ int dsi_pll_clock_register_12nm(struct platform_device *pdev,
struct mdss_pll_resources *pll_res)
{
int rc = 0, ndx, i;
struct clk *clk;
struct clk *clk = NULL;
struct clk_onecell_data *clk_data;
int num_clks = ARRAY_SIZE(mdss_dsi_pllcc_12nm);
struct regmap *rmap;
struct dsi_pll_db *pdb;
if (!pdev || !pdev->dev.of_node ||
!pll_res || !pll_res->pll_base || !pll_res->phy_base) {
!pll_res || !pll_res->pll_base) {
pr_err("Invalid params\n");
return -EINVAL;
}
@ -649,7 +653,7 @@ int dsi_pll_clock_register_12nm(struct platform_device *pdev,
clk_data->clk_num = num_clks;
/* Establish client data */
if (ndx == 0) {
if (pll_res->index == 0) {
rmap = devm_regmap_init(&pdev->dev, &post_div_mux_regmap_bus,
pll_res, &dsi_pll_12nm_config);
dsi0pll_post_div_mux.clkr.regmap = rmap;
@ -712,7 +716,8 @@ int dsi_pll_clock_register_12nm(struct platform_device *pdev,
of_clk_src_onecell_get, clk_data);
}
if (!rc) {
pr_info("Registered DSI PLL ndx=%d, clocks successfully", ndx);
pr_info("Registered DSI PLL ndx=%d, clocks successfully",
pll_res->index);
return rc;
}

View File

@ -136,6 +136,8 @@ static int mdss_pll_resource_parse(struct platform_device *pdev,
pll_res->pll_interface_type = MDSS_DSI_PLL_7NM;
else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_7nm_v2"))
pll_res->pll_interface_type = MDSS_DSI_PLL_7NM_V2;
else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_12nm"))
pll_res->pll_interface_type = MDSS_DSI_PLL_12NM;
else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_28lpm"))
pll_res->pll_interface_type = MDSS_DSI_PLL_28LPM;
else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_14nm"))

View File

@ -219,12 +219,8 @@ static inline bool is_gdsc_disabled(struct mdss_pll_resources *pll_res)
WARN(1, "gdsc_base register is not defined\n");
return true;
}
if (pll_res->target_id == MDSS_PLL_TARGET_SDM660)
ret = ((readl_relaxed(pll_res->gdsc_base + 0x4) & BIT(31)) &&
ret = ((readl_relaxed(pll_res->gdsc_base + 0x4) & BIT(31)) &&
(!(readl_relaxed(pll_res->gdsc_base) & BIT(0)))) ? false : true;
else
ret = readl_relaxed(pll_res->gdsc_base) & BIT(31) ?
false : true;
return ret;
}