diff options
-rw-r--r-- | Documentation/devicetree/bindings/fb/mdss-pll.txt | 3 | ||||
-rw-r--r-- | drivers/clk/msm/mdss/mdss-dsi-pll-8996-util.c | 76 | ||||
-rw-r--r-- | drivers/clk/msm/mdss/mdss-dsi-pll-8996.c | 27 | ||||
-rw-r--r-- | drivers/clk/msm/mdss/mdss-dsi-pll-8996.h | 22 | ||||
-rw-r--r-- | drivers/clk/msm/mdss/mdss-pll.c | 3 | ||||
-rw-r--r-- | drivers/clk/msm/mdss/mdss-pll.h | 2 |
6 files changed, 105 insertions, 28 deletions
diff --git a/Documentation/devicetree/bindings/fb/mdss-pll.txt b/Documentation/devicetree/bindings/fb/mdss-pll.txt index 50de9553c202..adc948ad9902 100644 --- a/Documentation/devicetree/bindings/fb/mdss-pll.txt +++ b/Documentation/devicetree/bindings/fb/mdss-pll.txt @@ -27,9 +27,6 @@ Optional properties: - label: A string used to describe the driver used. - vcca-supply: Phandle for vcca regulator device node. -- qcom,dsi-pll-slave: indicates it is pll slave at split display case. Otherwise - it is pll master. - - qcom,platform-supply-entries: A node that lists the elements of the supply. There can be more than one instance of this binding, in which case the entry would be appended with diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-8996-util.c b/drivers/clk/msm/mdss/mdss-dsi-pll-8996-util.c index 0c954e487065..10aa2bd16928 100644 --- a/drivers/clk/msm/mdss/mdss-dsi-pll-8996-util.c +++ b/drivers/clk/msm/mdss/mdss-dsi-pll-8996-util.c @@ -593,6 +593,76 @@ static void pll_db_commit_8996(void __iomem *pll_base, wmb(); /* make sure register committed */ } +/* + * pll_source_finding: + * Both GLBL_TEST_CTRL and CLKBUFLR_EN are configured + * at mdss_dsi_8996_phy_config() + */ +static int pll_source_finding(struct mdss_pll_resources *pll) +{ + u32 clk_buf_en; + u32 glbl_test_ctrl; + + glbl_test_ctrl = MDSS_PLL_REG_R(pll->pll_base, + DSIPHY_CMN_GLBL_TEST_CTRL); + clk_buf_en = MDSS_PLL_REG_R(pll->pll_base, + DSIPHY_PLL_CLKBUFLR_EN); + + glbl_test_ctrl &= BIT(2); + glbl_test_ctrl >>= 2; + + pr_debug("%s: pll=%d clk_buf_en=%x glbl_test_ctrl=%x\n", + __func__, pll->index, clk_buf_en, glbl_test_ctrl); + + clk_buf_en &= (PLL_OUTPUT_RIGHT | PLL_OUTPUT_LEFT); + + if ((glbl_test_ctrl == PLL_SOURCE_FROM_LEFT) && + (clk_buf_en == PLL_OUTPUT_BOTH)) + return PLL_MASTER; + + if ((glbl_test_ctrl == PLL_SOURCE_FROM_RIGHT) && + (clk_buf_en == PLL_OUTPUT_NONE)) + return PLL_SLAVE; + + if ((glbl_test_ctrl == PLL_SOURCE_FROM_LEFT) && + (clk_buf_en == PLL_OUTPUT_RIGHT)) + return PLL_STANDALONE; + + pr_debug("%s: Error pll setup, clk_buf_en=%x glbl_test_ctrl=%x\n", + __func__, clk_buf_en, glbl_test_ctrl); + + return PLL_UNKNOWN; +} + +static void pll_source_setup(struct mdss_pll_resources *pll) +{ + int status; + struct dsi_pll_db *pdb = (struct dsi_pll_db *)pll->priv; + struct mdss_pll_resources *other; + + if (pdb->source_setup_done) + return; + + pdb->source_setup_done++; + + status = pll_source_finding(pll); + + if (status == PLL_STANDALONE || status == PLL_UNKNOWN) + return; + + other = pdb->next->pll; + if (!other) + return; + + pr_debug("%s: status=%d pll=%d other=%d\n", __func__, + status, pll->index, other->index); + + if (status == PLL_MASTER) + pll->slave = other; + else + other->slave = pll; +} + int pll_vco_set_rate_8996(struct clk *c, unsigned long rate) { int rc; @@ -613,8 +683,10 @@ int pll_vco_set_rate_8996(struct clk *c, unsigned long rate) return rc; } - pr_debug("%s: ndx=%d base=%p rate=%lu\n", __func__, - pll->index, pll->pll_base, rate); + pll_source_setup(pll); + + pr_debug("%s: ndx=%d base=%p rate=%lu slave=%p\n", __func__, + pll->index, pll->pll_base, rate, pll->slave); pll->vco_current_rate = rate; pll->vco_ref_clk_rate = vco->ref_clk_rate; diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-8996.c b/drivers/clk/msm/mdss/mdss-dsi-pll-8996.c index 9056ec634ecc..a8faf0813378 100644 --- a/drivers/clk/msm/mdss/mdss-dsi-pll-8996.c +++ b/drivers/clk/msm/mdss/mdss-dsi-pll-8996.c @@ -287,8 +287,8 @@ static struct clk_lookup mdss_dsi_pllcc_8996_1[] = { int dsi_pll_clock_register_8996(struct platform_device *pdev, struct mdss_pll_resources *pll_res) { - int rc; - static struct mdss_pll_resources *master_pll; + int rc, ndx; + struct dsi_pll_db *pdb; if (!pdev || !pdev->dev.of_node) { pr_err("Invalid input parameters\n"); @@ -300,27 +300,18 @@ int dsi_pll_clock_register_8996(struct platform_device *pdev, return -EPROBE_DEFER; } - pr_err("ndx=%d is_slave=%d\n", pll_res->index, pll_res->is_slave); - if (pll_res->index >= DSI_PLL_NUM) { pr_err("pll ndx=%d is NOT supported\n", pll_res->index); return -EINVAL; } - if (!pll_res->is_slave) { - /* master at split display or stand alone */ - pll_res->priv = &pll_db[pll_res->index]; - 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 */ - } + ndx = pll_res->index; + pdb = &pll_db[ndx]; + pll_res->priv = pdb; + pdb->pll = pll_res; + ndx++; + ndx %= DSI_PLL_NUM; + pdb->next = &pll_db[ndx]; /* Set clock source operations */ diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-8996.h b/drivers/clk/msm/mdss/mdss-dsi-pll-8996.h index 5193eec641bc..94c50acfb771 100644 --- a/drivers/clk/msm/mdss/mdss-dsi-pll-8996.h +++ b/drivers/clk/msm/mdss/mdss-dsi-pll-8996.h @@ -146,8 +146,30 @@ enum { }; struct dsi_pll_db { + struct dsi_pll_db *next; + struct mdss_pll_resources *pll; struct dsi_pll_input in; struct dsi_pll_output out; + int source_setup_done; +}; + +enum { + PLL_OUTPUT_NONE, + PLL_OUTPUT_RIGHT, + PLL_OUTPUT_LEFT, + PLL_OUTPUT_BOTH +}; + +enum { + PLL_SOURCE_FROM_LEFT, + PLL_SOURCE_FROM_RIGHT +}; + +enum { + PLL_UNKNOWN, + PLL_STANDALONE, + PLL_SLAVE, + PLL_MASTER }; int pll_vco_set_rate_8996(struct clk *c, unsigned long rate); diff --git a/drivers/clk/msm/mdss/mdss-pll.c b/drivers/clk/msm/mdss/mdss-pll.c index 1593ffab14e0..bf118be406cb 100644 --- a/drivers/clk/msm/mdss/mdss-pll.c +++ b/drivers/clk/msm/mdss/mdss-pll.c @@ -222,9 +222,6 @@ 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 c93cda3784d5..365c21d3f0ca 100644 --- a/drivers/clk/msm/mdss/mdss-pll.h +++ b/drivers/clk/msm/mdss/mdss-pll.h @@ -124,8 +124,6 @@ struct mdss_pll_resources { */ uint32_t index; - bool is_slave; /* share pll with master */ - struct mdss_pll_resources *slave; /* |