Loading drivers/clk/qcom/mdss/mdss-dsi-20nm-pll-util.c +59 −10 Original line number Diff line number Diff line Loading @@ -167,6 +167,10 @@ static void pll_20nm_cache_trim_codes(struct mdss_pll_resources *dsi_pll_res) MDSS_PLL_REG_R(dsi_pll_res->pll_base, MMSS_DSI_PHY_PLL_CORE_VCO_TUNE); pr_debug("core_kvco_code=0x%x core_vco_turn=0x%x\n", dsi_pll_res->cache_pll_trim_codes[0], dsi_pll_res->cache_pll_trim_codes[1]); mdss_pll_resource_enable(dsi_pll_res, false); dsi_pll_res->reg_upd = true; Loading Loading @@ -852,8 +856,15 @@ enum handoff pll_20nm_vco_handoff(struct clk *c) dsi_pll_res->pll_on = true; c->rate = pll_20nm_vco_get_rate(c); ret = HANDOFF_ENABLED_CLK; dsi_pll_res->vco_locking_rate = c->rate; dsi_pll_res->is_init_locked = true; pll_20nm_cache_trim_codes(dsi_pll_res); pr_debug("handoff vco_locking_rate=%llu\n", dsi_pll_res->vco_locking_rate); } else { mdss_pll_resource_enable(dsi_pll_res, false); dsi_pll_res->vco_locking_rate = 0; dsi_pll_res->is_init_locked = false; } return ret; Loading Loading @@ -913,28 +924,41 @@ static void pll_20nm_config_vco_start(void __iomem *pll_base) MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, 0x03); } static int pll_20nm_vco_init_lock(struct mdss_pll_resources *dsi_pll_res) static void pll_20nm_config_bypass_cal(void __iomem *pll_base) { MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL, 0xac); MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN, 0x28); } static int pll_20nm_vco_relock(struct mdss_pll_resources *dsi_pll_res) { int rc = 0; struct mdss_pll_vco_calc vco_calc; pll_20nm_config_common_block(dsi_pll_res->pll_base); pll_20nm_config_loop_bw(dsi_pll_res->pll_base); pll_20nm_override_trim_codes(dsi_pll_res); pll_20nm_config_bypass_cal(dsi_pll_res->pll_base); pll_20nm_config_vco_start(dsi_pll_res->pll_base); pll_20nm_vco_rate_calc(&vco_calc, dsi_pll_res->vco_current_rate, dsi_pll_res->vco_ref_clk_rate); pll_20nm_config_vco_rate(dsi_pll_res->pll_base, &vco_calc); if (!pll_20nm_is_pll_locked(dsi_pll_res)) { pr_err("DSI PLL re-lock failed\n"); rc = -EINVAL; } return rc; } static int pll_20nm_vco_init_lock(struct mdss_pll_resources *dsi_pll_res) { int rc = 0; pll_20nm_config_resetsm(dsi_pll_res->pll_base); pll_20nm_config_vco_start(dsi_pll_res->pll_base); if (!pll_20nm_is_pll_locked(dsi_pll_res)) { pr_err("DSI PLL lock failed\n"); pr_err("DSI PLL init lock failed\n"); rc = -EINVAL; goto init_lock_err; } pr_debug("DSI PLL Lock success\n"); pll_20nm_cache_trim_codes(dsi_pll_res); init_lock_err: Loading @@ -944,13 +968,38 @@ static int pll_20nm_vco_init_lock(struct mdss_pll_resources *dsi_pll_res) int pll_20nm_vco_enable_seq(struct mdss_pll_resources *dsi_pll_res) { int rc = 0; struct mdss_pll_vco_calc vco_calc; if (!dsi_pll_res) { pr_err("Invalid PLL resources\n"); return -EINVAL; } pll_20nm_config_common_block(dsi_pll_res->pll_base); pll_20nm_config_loop_bw(dsi_pll_res->pll_base); pll_20nm_vco_rate_calc(&vco_calc, dsi_pll_res->vco_current_rate, dsi_pll_res->vco_ref_clk_rate); pll_20nm_config_vco_rate(dsi_pll_res->pll_base, &vco_calc); pr_debug("init lock=%d prev vco_rate=%llu, new vco_rate=%llu\n", dsi_pll_res->is_init_locked, dsi_pll_res->vco_locking_rate, dsi_pll_res->vco_current_rate); /* * Run auto-lock sequence if it is either bootup initial * locking or when the vco rate is changed. Otherwise, just * use stored codes and bypass caliberation. */ if (!dsi_pll_res->is_init_locked || (dsi_pll_res->vco_locking_rate != dsi_pll_res->vco_current_rate)) { rc = pll_20nm_vco_init_lock(dsi_pll_res); dsi_pll_res->is_init_locked = (rc) ? false : true; } else { rc = pll_20nm_vco_relock(dsi_pll_res); } dsi_pll_res->vco_locking_rate = (rc) ? 0 : dsi_pll_res->vco_current_rate; return rc; } drivers/clk/qcom/mdss/mdss-pll.h +2 −0 Original line number Diff line number Diff line Loading @@ -62,7 +62,9 @@ struct mdss_pll_resources { void __iomem *gdsc_base; void __iomem *dyn_pll_base; bool is_init_locked; s64 vco_current_rate; s64 vco_locking_rate; s64 vco_ref_clk_rate; /* Loading Loading
drivers/clk/qcom/mdss/mdss-dsi-20nm-pll-util.c +59 −10 Original line number Diff line number Diff line Loading @@ -167,6 +167,10 @@ static void pll_20nm_cache_trim_codes(struct mdss_pll_resources *dsi_pll_res) MDSS_PLL_REG_R(dsi_pll_res->pll_base, MMSS_DSI_PHY_PLL_CORE_VCO_TUNE); pr_debug("core_kvco_code=0x%x core_vco_turn=0x%x\n", dsi_pll_res->cache_pll_trim_codes[0], dsi_pll_res->cache_pll_trim_codes[1]); mdss_pll_resource_enable(dsi_pll_res, false); dsi_pll_res->reg_upd = true; Loading Loading @@ -852,8 +856,15 @@ enum handoff pll_20nm_vco_handoff(struct clk *c) dsi_pll_res->pll_on = true; c->rate = pll_20nm_vco_get_rate(c); ret = HANDOFF_ENABLED_CLK; dsi_pll_res->vco_locking_rate = c->rate; dsi_pll_res->is_init_locked = true; pll_20nm_cache_trim_codes(dsi_pll_res); pr_debug("handoff vco_locking_rate=%llu\n", dsi_pll_res->vco_locking_rate); } else { mdss_pll_resource_enable(dsi_pll_res, false); dsi_pll_res->vco_locking_rate = 0; dsi_pll_res->is_init_locked = false; } return ret; Loading Loading @@ -913,28 +924,41 @@ static void pll_20nm_config_vco_start(void __iomem *pll_base) MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, 0x03); } static int pll_20nm_vco_init_lock(struct mdss_pll_resources *dsi_pll_res) static void pll_20nm_config_bypass_cal(void __iomem *pll_base) { MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL, 0xac); MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN, 0x28); } static int pll_20nm_vco_relock(struct mdss_pll_resources *dsi_pll_res) { int rc = 0; struct mdss_pll_vco_calc vco_calc; pll_20nm_config_common_block(dsi_pll_res->pll_base); pll_20nm_config_loop_bw(dsi_pll_res->pll_base); pll_20nm_override_trim_codes(dsi_pll_res); pll_20nm_config_bypass_cal(dsi_pll_res->pll_base); pll_20nm_config_vco_start(dsi_pll_res->pll_base); pll_20nm_vco_rate_calc(&vco_calc, dsi_pll_res->vco_current_rate, dsi_pll_res->vco_ref_clk_rate); pll_20nm_config_vco_rate(dsi_pll_res->pll_base, &vco_calc); if (!pll_20nm_is_pll_locked(dsi_pll_res)) { pr_err("DSI PLL re-lock failed\n"); rc = -EINVAL; } return rc; } static int pll_20nm_vco_init_lock(struct mdss_pll_resources *dsi_pll_res) { int rc = 0; pll_20nm_config_resetsm(dsi_pll_res->pll_base); pll_20nm_config_vco_start(dsi_pll_res->pll_base); if (!pll_20nm_is_pll_locked(dsi_pll_res)) { pr_err("DSI PLL lock failed\n"); pr_err("DSI PLL init lock failed\n"); rc = -EINVAL; goto init_lock_err; } pr_debug("DSI PLL Lock success\n"); pll_20nm_cache_trim_codes(dsi_pll_res); init_lock_err: Loading @@ -944,13 +968,38 @@ static int pll_20nm_vco_init_lock(struct mdss_pll_resources *dsi_pll_res) int pll_20nm_vco_enable_seq(struct mdss_pll_resources *dsi_pll_res) { int rc = 0; struct mdss_pll_vco_calc vco_calc; if (!dsi_pll_res) { pr_err("Invalid PLL resources\n"); return -EINVAL; } pll_20nm_config_common_block(dsi_pll_res->pll_base); pll_20nm_config_loop_bw(dsi_pll_res->pll_base); pll_20nm_vco_rate_calc(&vco_calc, dsi_pll_res->vco_current_rate, dsi_pll_res->vco_ref_clk_rate); pll_20nm_config_vco_rate(dsi_pll_res->pll_base, &vco_calc); pr_debug("init lock=%d prev vco_rate=%llu, new vco_rate=%llu\n", dsi_pll_res->is_init_locked, dsi_pll_res->vco_locking_rate, dsi_pll_res->vco_current_rate); /* * Run auto-lock sequence if it is either bootup initial * locking or when the vco rate is changed. Otherwise, just * use stored codes and bypass caliberation. */ if (!dsi_pll_res->is_init_locked || (dsi_pll_res->vco_locking_rate != dsi_pll_res->vco_current_rate)) { rc = pll_20nm_vco_init_lock(dsi_pll_res); dsi_pll_res->is_init_locked = (rc) ? false : true; } else { rc = pll_20nm_vco_relock(dsi_pll_res); } dsi_pll_res->vco_locking_rate = (rc) ? 0 : dsi_pll_res->vco_current_rate; return rc; }
drivers/clk/qcom/mdss/mdss-pll.h +2 −0 Original line number Diff line number Diff line Loading @@ -62,7 +62,9 @@ struct mdss_pll_resources { void __iomem *gdsc_base; void __iomem *dyn_pll_base; bool is_init_locked; s64 vco_current_rate; s64 vco_locking_rate; s64 vco_ref_clk_rate; /* Loading