summaryrefslogtreecommitdiff
path: root/drivers/clk
diff options
context:
space:
mode:
authorKuogee Hsieh <khsieh@codeaurora.org>2015-02-04 14:26:07 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:41:41 -0700
commitbd4cf9d7a034bb48f7a102e1320669bed94baaa7 (patch)
tree68f11775267a764c95316f2daddad203abe360af /drivers/clk
parentec1642743f3de745552fd666f93b45095702645d (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.c37
-rw-r--r--drivers/clk/msm/mdss/mdss-dsi-pll-thulium.c19
-rw-r--r--drivers/clk/msm/mdss/mdss-dsi-pll-thulium.h7
-rw-r--r--drivers/clk/msm/mdss/mdss-pll.c3
-rw-r--r--drivers/clk/msm/mdss/mdss-pll.h4
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;
};