diff options
author | Kuogee Hsieh <khsieh@codeaurora.org> | 2015-02-04 14:26:07 -0800 |
---|---|---|
committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:41:41 -0700 |
commit | bd4cf9d7a034bb48f7a102e1320669bed94baaa7 (patch) | |
tree | 68f11775267a764c95316f2daddad203abe360af /drivers/clk | |
parent | ec1642743f3de745552fd666f93b45095702645d (diff) |
msm: mdss: add configuration for dsi pll-1's clock dividers
During split display case, pll-1 share vco output of pll-0.
Therefore pll-1's related clock dividers need to be
configured along with pll-0.
Change-Id: I98744ec0b8a5bea952f41754788ba44d824d3373
Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/msm/mdss/mdss-dsi-pll-thulium-util.c | 37 | ||||
-rw-r--r-- | drivers/clk/msm/mdss/mdss-dsi-pll-thulium.c | 19 | ||||
-rw-r--r-- | drivers/clk/msm/mdss/mdss-dsi-pll-thulium.h | 7 | ||||
-rw-r--r-- | drivers/clk/msm/mdss/mdss-pll.c | 3 | ||||
-rw-r--r-- | drivers/clk/msm/mdss/mdss-pll.h | 4 |
5 files changed, 53 insertions, 17 deletions
diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-thulium-util.c b/drivers/clk/msm/mdss/mdss-dsi-pll-thulium-util.c index 23226f1060b2..3a2603246558 100644 --- a/drivers/clk/msm/mdss/mdss-dsi-pll-thulium-util.c +++ b/drivers/clk/msm/mdss/mdss-dsi-pll-thulium-util.c @@ -55,9 +55,12 @@ int post_n1_div_set_div(struct div_clk *clk, int div) pout = &pdb->out; /* - * postdiv = 1/2/4/8 - * n1div = 1 - 15 - * fot the time being, assume postdiv = 1 + * vco rate = bit_clk * postdiv * n1div + * vco range from 1300 to 2600 Mhz + * postdiv = 1 + * n1div = 1 to 15 + * n1div = roundup(1300Mhz / bit_clk) + * support bit_clk above 86.67Mhz */ /* this is for vco/bit clock */ @@ -103,6 +106,7 @@ int n2_div_set_div(struct div_clk *clk, int div) struct mdss_pll_resources *pll = clk->priv; struct dsi_pll_db *pdb; struct dsi_pll_output *pout; + struct mdss_pll_resources *slave; rc = mdss_pll_resource_enable(pll, true); if (rc) { @@ -119,6 +123,11 @@ int n2_div_set_div(struct div_clk *clk, int div) n2div |= (div << 4); MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_CLK_CFG0, n2div); + /* commit slave if split display is enabled */ + slave = pll->slave; + if (slave) + MDSS_PLL_REG_W(slave->pll_base, DSIPHY_CMN_CLK_CFG0, n2div); + pout->pll_n2div = div; /* set dsiclk_sel=1 so that n2div *= 2 */ @@ -136,6 +145,9 @@ int n2_div_get_div(struct div_clk *clk) u32 n2div; struct mdss_pll_resources *pll = clk->priv; + if (is_gdsc_disabled(pll)) + return 0; + rc = mdss_pll_resource_enable(pll, true); if (rc) { pr_err("Failed to enable mdss dsi pll resources\n"); @@ -336,7 +348,7 @@ static void pll_thulium_dec_frac_calc(struct dsi_pll_db *pdb, vco_clk_rate, fref); dec_start_multiple = div_s64(vco_clk_rate * multiplier, fref); - div_s64_rem(dec_start_multiple, multiplier, &div_frac_start); + div_s64_rem(vco_clk_rate * multiplier, fref, &div_frac_start); dec_start = div_s64(dec_start_multiple, multiplier); @@ -359,7 +371,6 @@ static void pll_thulium_dec_frac_calc(struct dsi_pll_db *pdb, pout->plllock_cmp = (u32)pll_comp_val; pout->pll_txclk_en = 1; - pout->pll_clkbuflr_en = 1; /* right output */ pout->cmn_ldo_cntrl = 0x1c; } @@ -455,10 +466,10 @@ static void pll_db_commit_common(void __iomem *pll_base, data = pout->pll_misc1; MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_MISC1, data); - data = pout->pll_ie_trim; + data = pin->pll_ie_trim; MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IE_TRIM, data); - data = pout->pll_ip_trim; + data = pin->pll_ip_trim; MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IP_TRIM, data); data = ((pin->pll_cpmset_cur << 3) | pin->pll_cpcset_cur); @@ -476,7 +487,7 @@ static void pll_db_commit_common(void __iomem *pll_base, data = ((pdb->in.pll_lpf_cap2 << 4) | pdb->in.pll_lpf_cap1); MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_LPF1, data); - data = pout->pll_iptat_trim; + data = pin->pll_iptat_trim; MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IPTAT_TRIM, data); data = (pdb->in.pll_c3ctrl | (pdb->in.pll_r3ctrl << 4)); @@ -518,10 +529,13 @@ static void pll_db_commit_thulium(void __iomem *pll_base, MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DEC_START, data); data = pout->div_frac_start; + data &= 0x0ff; MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START1, data); data = (pout->div_frac_start >> 8); + data &= 0x0ff; MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START2, data); data = (pout->div_frac_start >> 16); + data &= 0x0ff; MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START3, data); data = pout->plllock_cmp; @@ -572,6 +586,7 @@ int pll_vco_set_rate_thulium(struct clk *c, unsigned long rate) int rc; struct dsi_pll_vco_clk *vco = to_vco_clk(c); struct mdss_pll_resources *pll = vco->priv; + struct mdss_pll_resources *slave; struct dsi_pll_db *pdb; pdb = (struct dsi_pll_db *)pll->priv; @@ -599,6 +614,12 @@ int pll_vco_set_rate_thulium(struct clk *c, unsigned long rate) pll_thulium_calc_vco_count(pdb, pll->vco_current_rate, pll->vco_ref_clk_rate); + /* commit slave if split display is enabled */ + slave = pll->slave; + if (slave) + pll_db_commit_thulium(slave->pll_base, pdb); + + /* commit master itself */ pll_db_commit_thulium(pll->pll_base, pdb); mdss_pll_resource_enable(pll, false); diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-thulium.c b/drivers/clk/msm/mdss/mdss-dsi-pll-thulium.c index 6bb4e678916f..66c3884f027b 100644 --- a/drivers/clk/msm/mdss/mdss-dsi-pll-thulium.c +++ b/drivers/clk/msm/mdss/mdss-dsi-pll-thulium.c @@ -179,6 +179,7 @@ int dsi_pll_clock_register_thulium(struct platform_device *pdev, struct mdss_pll_resources *pll_res) { int rc; + static struct mdss_pll_resources *master_pll; if (!pdev || !pdev->dev.of_node) { pr_err("Invalid input parameters\n"); @@ -190,8 +191,22 @@ int dsi_pll_clock_register_thulium(struct platform_device *pdev, return -EPROBE_DEFER; } - pll_res->priv = &pll_db; - + pr_debug("ndx=%d is_slave=%d\n", pll_res->index, pll_res->is_slave); + + if (!pll_res->is_slave) { + /* master at split display or stand alone */ + pll_res->priv = &pll_db; + master_pll = pll_res; /* keep master pll */ + } else { + /* slave pll */ + if (!master_pll) { + pr_err("No match PLL master found for ndx=%d\n", + pll_res->index); + return -EINVAL; + } + master_pll->slave = pll_res; + return 0; /* done for slave */ + } /* * Set client data to mux, div and vco clocks. * This needs to be done only for PLL0 since, that is the one in diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-thulium.h b/drivers/clk/msm/mdss/mdss-dsi-pll-thulium.h index cdd49752d8cf..381e16d87bdb 100644 --- a/drivers/clk/msm/mdss/mdss-dsi-pll-thulium.h +++ b/drivers/clk/msm/mdss/mdss-dsi-pll-thulium.h @@ -112,7 +112,6 @@ struct dsi_pll_input { }; struct dsi_pll_output { - u32 clkbuflr_en; /* reg: 0x041c, unknown */ u32 pll_txclk_en; /* reg: 0x04c0 */ u32 dec_start; /* reg: 0x0490 */ u32 div_frac_start; /* reg: 0x04b4, 0x4b8, 0x04bc */ @@ -130,12 +129,6 @@ struct dsi_pll_output { u32 pll_resetsm_cntrl5; /* reg: 0x043c */ u32 pll_kvco_code; /* reg: 0x0458 */ - u32 pll_ie_trim; /* reg: 0x0400 */ - u32 pll_ip_trim; /* reg: 0x0404 */ - u32 pll_iptat_trim; /* reg: 0x0410 */ - - u32 pll_clkbuflr_en; /* reg: 0x001c */ - u32 cmn_clk_cfg0; /* reg: 0x0010 */ u32 cmn_clk_cfg1; /* reg: 0x0014 */ u32 cmn_ldo_cntrl; /* reg: 0x004c */ diff --git a/drivers/clk/msm/mdss/mdss-pll.c b/drivers/clk/msm/mdss/mdss-pll.c index a707062170d6..861f94a92550 100644 --- a/drivers/clk/msm/mdss/mdss-pll.c +++ b/drivers/clk/msm/mdss/mdss-pll.c @@ -254,6 +254,9 @@ static int mdss_pll_probe(struct platform_device *pdev) pll_res->index = 0; } + pll_res->is_slave = of_property_read_bool(pdev->dev.of_node, + "qcom,dsi-pll-slave"); + pll_base_reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_base"); if (!pll_base_reg) { diff --git a/drivers/clk/msm/mdss/mdss-pll.h b/drivers/clk/msm/mdss/mdss-pll.h index e9cbe49b5a78..de78d2f43e8b 100644 --- a/drivers/clk/msm/mdss/mdss-pll.h +++ b/drivers/clk/msm/mdss/mdss-pll.h @@ -136,6 +136,10 @@ struct mdss_pll_resources { */ uint32_t index; + bool is_slave; /* share pll with master */ + + struct mdss_pll_resources *slave; + void *priv; }; |