summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-12-18 14:48:01 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-12-18 14:48:01 -0800
commit2d28ff09533427b3fc0b9651eff8c1d936f2cfb4 (patch)
tree33afe4d672e31712e4d087dc5c5fd5d27581f976
parent4d86efbfe8d21ec46c88477249108fb67b673ce2 (diff)
parent6a21dcc9bf61ffbb511b7d58b2744ee1b8cfddef (diff)
Merge "clk: qcom: add common clock framework support for MDSS PLL"
-rw-r--r--drivers/clk/qcom/Kconfig2
-rw-r--r--drivers/clk/qcom/Makefile2
-rw-r--r--drivers/clk/qcom/mdss/Kconfig3
-rw-r--r--drivers/clk/qcom/mdss/Makefile9
-rw-r--r--drivers/clk/qcom/mdss/mdss-dsi-pll-14nm-util.c (renamed from drivers/clk/qcom/mdss/mdss-dsi-pll-8996-util.c)344
-rw-r--r--drivers/clk/qcom/mdss/mdss-dsi-pll-14nm.c614
-rw-r--r--drivers/clk/qcom/mdss/mdss-dsi-pll-14nm.h (renamed from drivers/clk/qcom/mdss/mdss-dsi-pll-8996.h)54
-rw-r--r--drivers/clk/qcom/mdss/mdss-dsi-pll-8996.c566
-rw-r--r--drivers/clk/qcom/mdss/mdss-dsi-pll.h65
-rw-r--r--drivers/clk/qcom/mdss/mdss-pll-util.c1
-rw-r--r--drivers/clk/qcom/mdss/mdss-pll.c25
-rw-r--r--drivers/clk/qcom/mdss/mdss-pll.h27
-rw-r--r--include/dt-bindings/clock/mdss-pll-clk.h42
13 files changed, 896 insertions, 858 deletions
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 36ab5cf68740..2148dad33e87 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -218,3 +218,5 @@ config QCOM_A53
Support for the A53 clock controller on MSM devices.
Say Y if you want to support CPU frequency scaling on devices
such as MSM8916.
+
+source "drivers/clk/qcom/mdss/Kconfig"
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 595254f69db1..176dc3103cdb 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -37,3 +37,5 @@ obj-$(CONFIG_KRAITCC) += krait-cc.o
obj-$(CONFIG_QCOM_A53) += clk-a53.o
obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
+
+obj-y += mdss/
diff --git a/drivers/clk/qcom/mdss/Kconfig b/drivers/clk/qcom/mdss/Kconfig
index 229780e45bb8..7213e375f1ef 100644
--- a/drivers/clk/qcom/mdss/Kconfig
+++ b/drivers/clk/qcom/mdss/Kconfig
@@ -1,5 +1,6 @@
-config MSM_MDSS_PLL
+config QCOM_MDSS_PLL
bool "MDSS pll programming"
+ depends on COMMON_CLK_QCOM
---help---
It provides support for DSI, eDP and HDMI interface pll programming on MDSS
hardware. It also handles the pll specific resources and turn them on/off when
diff --git a/drivers/clk/qcom/mdss/Makefile b/drivers/clk/qcom/mdss/Makefile
index 75891dc10dda..6a0a1de1e942 100644
--- a/drivers/clk/qcom/mdss/Makefile
+++ b/drivers/clk/qcom/mdss/Makefile
@@ -1,5 +1,4 @@
-obj-$(CONFIG_MSM_MDSS_PLL) += mdss-pll-util.o
-obj-$(CONFIG_MSM_MDSS_PLL) += mdss-pll.o
-obj-$(CONFIG_MSM_MDSS_PLL) += mdss-dsi-pll-8996.o
-obj-$(CONFIG_MSM_MDSS_PLL) += mdss-dsi-pll-8996-util.o
-obj-$(CONFIG_MSM_MDSS_PLL) += mdss-hdmi-pll-8996.o
+obj-$(CONFIG_QCOM_MDSS_PLL) += mdss-pll-util.o
+obj-$(CONFIG_QCOM_MDSS_PLL) += mdss-pll.o
+obj-$(CONFIG_QCOM_MDSS_PLL) += mdss-dsi-pll-14nm.o
+obj-$(CONFIG_QCOM_MDSS_PLL) += mdss-dsi-pll-14nm-util.o
diff --git a/drivers/clk/qcom/mdss/mdss-dsi-pll-8996-util.c b/drivers/clk/qcom/mdss/mdss-dsi-pll-14nm-util.c
index 6d2694d5a2e9..a4044955c68f 100644
--- a/drivers/clk/qcom/mdss/mdss-dsi-pll-8996-util.c
+++ b/drivers/clk/qcom/mdss/mdss-dsi-pll-14nm-util.c
@@ -16,37 +16,18 @@
#include <linux/err.h>
#include <linux/iopoll.h>
#include <linux/delay.h>
-#include <linux/clk/msm-clock-generic.h>
#include "mdss-pll.h"
#include "mdss-dsi-pll.h"
-#include "mdss-dsi-pll-8996.h"
+#include "mdss-dsi-pll-14nm.h"
#define DSI_PLL_POLL_MAX_READS 15
#define DSI_PLL_POLL_TIMEOUT_US 1000
#define MSM8996_DSI_PLL_REVISION_2 2
-#define CEIL(x, y) (((x) + ((y)-1)) / (y))
-
-int set_mdss_byte_mux_sel_8996(struct mux_clk *clk, int sel)
-{
- return 0;
-}
-
-int get_mdss_byte_mux_sel_8996(struct mux_clk *clk)
-{
- return 0;
-}
-
-int set_mdss_pixel_mux_sel_8996(struct mux_clk *clk, int sel)
-{
- return 0;
-}
+#define VCO_REF_CLK_RATE 19200000
-int get_mdss_pixel_mux_sel_8996(struct mux_clk *clk)
-{
- return 0;
-}
+#define CEIL(x, y) (((x) + ((y)-1)) / (y))
static int mdss_pll_read_stored_trim_codes(
struct mdss_pll_resources *dsi_pll_res, s64 vco_clk_rate)
@@ -94,9 +75,9 @@ end_read:
return rc;
}
-int post_n1_div_set_div(struct div_clk *clk, int div)
+int post_n1_div_set_div(void *context, unsigned int reg, unsigned int div)
{
- struct mdss_pll_resources *pll = clk->priv;
+ struct mdss_pll_resources *pll = context;
struct dsi_pll_db *pdb;
struct dsi_pll_output *pout;
int rc;
@@ -108,6 +89,9 @@ int post_n1_div_set_div(struct div_clk *clk, int div)
return rc;
}
+ /* in common clock framework the divider value provided is one less */
+ div++;
+
pdb = (struct dsi_pll_db *)pll->priv;
pout = &pdb->out;
@@ -120,8 +104,6 @@ int post_n1_div_set_div(struct div_clk *clk, int div)
* support bit_clk above 86.67Mhz
*/
- /* this is for vco/bit clock */
- pout->pll_postdiv = 1; /* fixed, divided by 1 */
pout->pll_n1div = div;
n1div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0);
@@ -138,11 +120,15 @@ int post_n1_div_set_div(struct div_clk *clk, int div)
return 0;
}
-int post_n1_div_get_div(struct div_clk *clk)
+int post_n1_div_get_div(void *context, unsigned int reg, unsigned int *div)
{
- u32 div;
int rc;
- struct mdss_pll_resources *pll = clk->priv;
+ struct mdss_pll_resources *pll = context;
+ struct dsi_pll_db *pdb;
+ struct dsi_pll_output *pout;
+
+ pdb = (struct dsi_pll_db *)pll->priv;
+ pout = &pdb->out;
if (is_gdsc_disabled(pll))
return 0;
@@ -159,20 +145,33 @@ int post_n1_div_get_div(struct div_clk *clk)
* fot the time being, assume postdiv = 1
*/
- div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0);
- div &= 0xF;
- pr_debug("n1 div = %d\n", div);
+ *div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0);
+ *div &= 0xF;
+
+ /*
+ * initialize n1div here, it will get updated when
+ * corresponding set_div is called.
+ */
+ pout->pll_n1div = *div;
+
+ /* common clock framework will add one to the divider value sent */
+ if (*div == 0)
+ *div = 1; /* value of zero means div is 2 as per SWI */
+ else
+ *div -= 1;
+
+ pr_debug("post n1 get div = %d\n", *div);
mdss_pll_resource_enable(pll, false);
- return div;
+ return rc;
}
-int n2_div_set_div(struct div_clk *clk, int div)
+int n2_div_set_div(void *context, unsigned int reg, unsigned int div)
{
int rc;
u32 n2div;
- struct mdss_pll_resources *pll = clk->priv;
+ struct mdss_pll_resources *pll = context;
struct dsi_pll_db *pdb;
struct dsi_pll_output *pout;
struct mdss_pll_resources *slave;
@@ -183,6 +182,12 @@ int n2_div_set_div(struct div_clk *clk, int div)
return rc;
}
+ /*
+ * in common clock framework the actual divider value
+ * provided is one less.
+ */
+ div++;
+
pdb = (struct dsi_pll_db *)pll->priv;
pout = &pdb->out;
@@ -208,9 +213,9 @@ int n2_div_set_div(struct div_clk *clk, int div)
return rc;
}
-int shadow_n2_div_set_div(struct div_clk *clk, int div)
+int shadow_n2_div_set_div(void *context, unsigned int reg, unsigned int div)
{
- struct mdss_pll_resources *pll = clk->priv;
+ struct mdss_pll_resources *pll = context;
struct dsi_pll_db *pdb;
struct dsi_pll_output *pout;
u32 data;
@@ -218,6 +223,12 @@ int shadow_n2_div_set_div(struct div_clk *clk, int div)
pdb = pll->priv;
pout = &pdb->out;
+ /*
+ * in common clock framework the actual divider value
+ * provided is one less.
+ */
+ div++;
+
pout->pll_n2div = div;
data = (pout->pll_n1div | (pout->pll_n2div << 4));
@@ -228,15 +239,20 @@ int shadow_n2_div_set_div(struct div_clk *clk, int div)
return 0;
}
-int n2_div_get_div(struct div_clk *clk)
+int n2_div_get_div(void *context, unsigned int reg, unsigned int *div)
{
int rc;
u32 n2div;
- struct mdss_pll_resources *pll = clk->priv;
+ struct mdss_pll_resources *pll = context;
+ struct dsi_pll_db *pdb;
+ struct dsi_pll_output *pout;
if (is_gdsc_disabled(pll))
return 0;
+ pdb = (struct dsi_pll_db *)pll->priv;
+ pout = &pdb->out;
+
rc = mdss_pll_resource_enable(pll, true);
if (rc) {
pr_err("Failed to enable mdss dsi pll=%d resources\n",
@@ -247,15 +263,27 @@ int n2_div_get_div(struct div_clk *clk)
n2div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0);
n2div >>= 4;
n2div &= 0x0f;
-
+ /*
+ * initialize n2div here, it will get updated when
+ * corresponding set_div is called.
+ */
+ pout->pll_n2div = n2div;
mdss_pll_resource_enable(pll, false);
- pr_debug("ndx=%d div=%d\n", pll->index, n2div);
+ *div = n2div;
+
+ /* common clock framework will add one to the divider value sent */
+ if (*div == 0)
+ *div = 1; /* value of zero means div is 2 as per SWI */
+ else
+ *div -= 1;
+
+ pr_debug("ndx=%d div=%d\n", pll->index, *div);
- return n2div;
+ return rc;
}
-static bool pll_is_pll_locked_8996(struct mdss_pll_resources *pll)
+static bool pll_is_pll_locked_14nm(struct mdss_pll_resources *pll)
{
u32 status;
bool pll_locked;
@@ -286,7 +314,7 @@ static bool pll_is_pll_locked_8996(struct mdss_pll_resources *pll)
return pll_locked;
}
-static void dsi_pll_start_8996(void __iomem *pll_base)
+static void dsi_pll_start_14nm(void __iomem *pll_base)
{
pr_debug("start PLL at base=%p\n", pll_base);
@@ -294,14 +322,14 @@ static void dsi_pll_start_8996(void __iomem *pll_base)
MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 1);
}
-static void dsi_pll_stop_8996(void __iomem *pll_base)
+static void dsi_pll_stop_14nm(void __iomem *pll_base)
{
pr_debug("stop PLL at base=%p\n", pll_base);
MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 0);
}
-int dsi_pll_enable_seq_8996(struct mdss_pll_resources *pll)
+int dsi_pll_enable_seq_14nm(struct mdss_pll_resources *pll)
{
int rc = 0;
@@ -310,14 +338,14 @@ int dsi_pll_enable_seq_8996(struct mdss_pll_resources *pll)
return -EINVAL;
}
- dsi_pll_start_8996(pll->pll_base);
+ dsi_pll_start_14nm(pll->pll_base);
/*
* both DSIPHY_PLL_CLKBUFLR_EN and DSIPHY_CMN_GLBL_TEST_CTRL
- * enabled at mdss_dsi_8996_phy_config()
+ * enabled at mdss_dsi_14nm_phy_config()
*/
- if (!pll_is_pll_locked_8996(pll)) {
+ if (!pll_is_pll_locked_14nm(pll)) {
pr_err("DSI PLL ndx=%d lock failed\n", pll->index);
rc = -EINVAL;
goto init_lock_err;
@@ -329,10 +357,10 @@ init_lock_err:
return rc;
}
-static int dsi_pll_enable(struct clk *c)
+static int dsi_pll_enable(struct clk_hw *hw)
{
int i, rc = 0;
- struct dsi_pll_vco_clk *vco = to_vco_clk(c);
+ struct dsi_pll_vco_clk *vco = to_vco_hw(hw);
struct mdss_pll_resources *pll = vco->priv;
/* Try all enable sequences until one succeeds */
@@ -352,9 +380,9 @@ static int dsi_pll_enable(struct clk *c)
return rc;
}
-static void dsi_pll_disable(struct clk *c)
+static void dsi_pll_disable(struct clk_hw *hw)
{
- struct dsi_pll_vco_clk *vco = to_vco_clk(c);
+ struct dsi_pll_vco_clk *vco = to_vco_hw(hw);
struct mdss_pll_resources *pll = vco->priv;
struct mdss_pll_resources *slave;
@@ -367,7 +395,7 @@ static void dsi_pll_disable(struct clk *c)
pll->handoff_resources = false;
slave = pll->slave;
- dsi_pll_stop_8996(pll->pll_base);
+ dsi_pll_stop_14nm(pll->pll_base);
mdss_pll_resource_enable(pll, false);
@@ -376,7 +404,7 @@ static void dsi_pll_disable(struct clk *c)
pr_debug("DSI PLL ndx=%d Disabled\n", pll->index);
}
-static void mdss_dsi_pll_8996_input_init(struct mdss_pll_resources *pll,
+static void mdss_dsi_pll_14nm_input_init(struct mdss_pll_resources *pll,
struct dsi_pll_db *pdb)
{
pdb->in.fref = 19200000; /* 19.2 Mhz*/
@@ -414,9 +442,10 @@ static void mdss_dsi_pll_8996_input_init(struct mdss_pll_resources *pll,
pdb->in.pll_iptat_trim = 7;
pdb->in.pll_c3ctrl = 2; /* 2 */
pdb->in.pll_r3ctrl = 1; /* 1 */
+ pdb->out.pll_postdiv = 1;
}
-static void pll_8996_ssc_calc(struct mdss_pll_resources *pll,
+static void pll_14nm_ssc_calc(struct mdss_pll_resources *pll,
struct dsi_pll_db *pdb)
{
u32 period, ssc_period;
@@ -457,7 +486,7 @@ static void pll_8996_ssc_calc(struct mdss_pll_resources *pll,
pdb->out.ssc_step_size = step_size;
}
-static void pll_8996_dec_frac_calc(struct mdss_pll_resources *pll,
+static void pll_14nm_dec_frac_calc(struct mdss_pll_resources *pll,
struct dsi_pll_db *pdb)
{
struct dsi_pll_input *pin = &pdb->in;
@@ -501,7 +530,7 @@ static void pll_8996_dec_frac_calc(struct mdss_pll_resources *pll,
pout->cmn_ldo_cntrl = 0x1c;
}
-static u32 pll_8996_kvco_slop(u32 vrate)
+static u32 pll_14nm_kvco_slop(u32 vrate)
{
u32 slop = 0;
@@ -515,7 +544,7 @@ static u32 pll_8996_kvco_slop(u32 vrate)
return slop;
}
-static void pll_8996_calc_vco_count(struct dsi_pll_db *pdb,
+static void pll_14nm_calc_vco_count(struct dsi_pll_db *pdb,
s64 vco_clk_rate, s64 fref)
{
struct dsi_pll_input *pin = &pdb->in;
@@ -540,7 +569,7 @@ static void pll_8996_calc_vco_count(struct dsi_pll_db *pdb,
data -= 1;
pout->pll_kvco_div_ref = data;
- cnt = pll_8996_kvco_slop(vco_clk_rate);
+ cnt = pll_14nm_kvco_slop(vco_clk_rate);
cnt *= 2;
do_div(cnt, 100);
cnt *= pin->kvco_measure_time;
@@ -659,7 +688,7 @@ static void pll_db_commit_common(struct mdss_pll_resources *pll,
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_CRCTRL, data);
}
-static void pll_db_commit_8996(struct mdss_pll_resources *pll,
+static void pll_db_commit_14nm(struct mdss_pll_resources *pll,
struct dsi_pll_db *pdb)
{
void __iomem *pll_base = pll->pll_base;
@@ -753,7 +782,7 @@ static void pll_db_commit_8996(struct mdss_pll_resources *pll,
/*
* pll_source_finding:
* Both GLBL_TEST_CTRL and CLKBUFLR_EN are configured
- * at mdss_dsi_8996_phy_config()
+ * at mdss_dsi_14nm_phy_config()
*/
static int pll_source_finding(struct mdss_pll_resources *pll)
{
@@ -820,10 +849,59 @@ static void pll_source_setup(struct mdss_pll_resources *pll)
other->slave = pll;
}
-int pll_vco_set_rate_8996(struct clk *c, unsigned long rate)
+unsigned long pll_vco_recalc_rate_14nm(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct dsi_pll_vco_clk *vco = to_vco_hw(hw);
+ struct mdss_pll_resources *pll = vco->priv;
+ u64 vco_rate, multiplier = BIT(20);
+ s32 div_frac_start;
+ u32 dec_start;
+ u64 ref_clk = vco->ref_clk_rate;
+ int rc;
+
+ if (pll->vco_current_rate)
+ return (unsigned long)pll->vco_current_rate;
+
+ if (is_gdsc_disabled(pll))
+ return 0;
+
+ rc = mdss_pll_resource_enable(pll, true);
+ if (rc) {
+ pr_err("Failed to enable mdss dsi pll=%d\n", pll->index);
+ return rc;
+ }
+
+ dec_start = MDSS_PLL_REG_R(pll->pll_base,
+ DSIPHY_PLL_DEC_START);
+ dec_start &= 0x0ff;
+ pr_debug("dec_start = 0x%x\n", dec_start);
+
+ div_frac_start = (MDSS_PLL_REG_R(pll->pll_base,
+ DSIPHY_PLL_DIV_FRAC_START3) & 0x0f) << 16;
+ div_frac_start |= (MDSS_PLL_REG_R(pll->pll_base,
+ DSIPHY_PLL_DIV_FRAC_START2) & 0x0ff) << 8;
+ div_frac_start |= MDSS_PLL_REG_R(pll->pll_base,
+ DSIPHY_PLL_DIV_FRAC_START1) & 0x0ff;
+ pr_debug("div_frac_start = 0x%x\n", div_frac_start);
+
+ vco_rate = ref_clk * dec_start;
+ vco_rate += ((ref_clk * div_frac_start) / multiplier);
+
+ pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate);
+
+ mdss_pll_resource_enable(pll, false);
+
+ pr_debug("%s: returning vco rate as %lu\n",
+ __func__, (unsigned long)vco_rate);
+ return (unsigned long)vco_rate;
+}
+
+int pll_vco_set_rate_14nm(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
{
int rc;
- struct dsi_pll_vco_clk *vco = to_vco_clk(c);
+ struct dsi_pll_vco_clk *vco = to_vco_hw(hw);
struct mdss_pll_resources *pll = vco->priv;
struct mdss_pll_resources *slave;
struct dsi_pll_db *pdb;
@@ -848,30 +926,30 @@ int pll_vco_set_rate_8996(struct clk *c, unsigned long rate)
pll->vco_current_rate = rate;
pll->vco_ref_clk_rate = vco->ref_clk_rate;
- mdss_dsi_pll_8996_input_init(pll, pdb);
+ mdss_dsi_pll_14nm_input_init(pll, pdb);
- pll_8996_dec_frac_calc(pll, pdb);
+ pll_14nm_dec_frac_calc(pll, pdb);
if (pll->ssc_en)
- pll_8996_ssc_calc(pll, pdb);
+ pll_14nm_ssc_calc(pll, pdb);
- pll_8996_calc_vco_count(pdb, pll->vco_current_rate,
+ pll_14nm_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_8996(slave, pdb);
+ pll_db_commit_14nm(slave, pdb);
/* commit master itself */
- pll_db_commit_8996(pll, pdb);
+ pll_db_commit_14nm(pll, pdb);
mdss_pll_resource_enable(pll, false);
return rc;
}
-static void shadow_pll_dynamic_refresh_8996(struct mdss_pll_resources *pll,
+static void shadow_pll_dynamic_refresh_14nm(struct mdss_pll_resources *pll,
struct dsi_pll_db *pdb)
{
struct dsi_pll_output *pout = &pdb->out;
@@ -931,10 +1009,11 @@ static void shadow_pll_dynamic_refresh_8996(struct mdss_pll_resources *pll,
wmb();
}
-int shadow_pll_vco_set_rate_8996(struct clk *c, unsigned long rate)
+int shadow_pll_vco_set_rate_14nm(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
{
int rc;
- struct dsi_pll_vco_clk *vco = to_vco_clk(c);
+ struct dsi_pll_vco_clk *vco = to_vco_hw(hw);
struct mdss_pll_resources *pll = vco->priv;
struct dsi_pll_db *pdb;
s64 vco_clk_rate = (s64)rate;
@@ -968,14 +1047,14 @@ int shadow_pll_vco_set_rate_8996(struct clk *c, unsigned long rate)
pll->vco_current_rate = rate;
pll->vco_ref_clk_rate = vco->ref_clk_rate;
- mdss_dsi_pll_8996_input_init(pll, pdb);
+ mdss_dsi_pll_14nm_input_init(pll, pdb);
- pll_8996_dec_frac_calc(pll, pdb);
+ pll_14nm_dec_frac_calc(pll, pdb);
- pll_8996_calc_vco_count(pdb, pll->vco_current_rate,
+ pll_14nm_calc_vco_count(pdb, pll->vco_current_rate,
pll->vco_ref_clk_rate);
- shadow_pll_dynamic_refresh_8996(pll, pdb);
+ shadow_pll_dynamic_refresh_14nm(pll, pdb);
rc = mdss_pll_resource_enable(pll, false);
if (rc) {
@@ -986,53 +1065,12 @@ int shadow_pll_vco_set_rate_8996(struct clk *c, unsigned long rate)
return rc;
}
-unsigned long pll_vco_get_rate_8996(struct clk *c)
-{
- u64 vco_rate, multiplier = BIT(20);
- s32 div_frac_start;
- u32 dec_start;
- struct dsi_pll_vco_clk *vco = to_vco_clk(c);
- u64 ref_clk = vco->ref_clk_rate;
- int rc;
- struct mdss_pll_resources *pll = vco->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=%d\n", pll->index);
- return rc;
- }
-
- dec_start = MDSS_PLL_REG_R(pll->pll_base,
- DSIPHY_PLL_DEC_START);
- dec_start &= 0x0ff;
- pr_debug("dec_start = 0x%x\n", dec_start);
-
- div_frac_start = (MDSS_PLL_REG_R(pll->pll_base,
- DSIPHY_PLL_DIV_FRAC_START3) & 0x0f) << 16;
- div_frac_start |= (MDSS_PLL_REG_R(pll->pll_base,
- DSIPHY_PLL_DIV_FRAC_START2) & 0x0ff) << 8;
- div_frac_start |= MDSS_PLL_REG_R(pll->pll_base,
- DSIPHY_PLL_DIV_FRAC_START1) & 0x0ff;
- pr_debug("div_frac_start = 0x%x\n", div_frac_start);
-
- vco_rate = ref_clk * dec_start;
- vco_rate += ((ref_clk * div_frac_start) / multiplier);
-
- pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate);
-
- mdss_pll_resource_enable(pll, false);
-
- return (unsigned long)vco_rate;
-}
-
-long pll_vco_round_rate_8996(struct clk *c, unsigned long rate)
+long pll_vco_round_rate_14nm(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
{
unsigned long rrate = rate;
u32 div;
- struct dsi_pll_vco_clk *vco = to_vco_clk(c);
+ struct dsi_pll_vco_clk *vco = to_vco_hw(hw);
div = vco->min_rate / rate;
if (div > 15) {
@@ -1046,46 +1084,14 @@ long pll_vco_round_rate_8996(struct clk *c, unsigned long rate)
if (rate > vco->max_rate)
rrate = vco->max_rate;
+ *parent_rate = rrate;
return rrate;
}
-enum handoff pll_vco_handoff_8996(struct clk *c)
-{
- int rc;
- enum handoff ret = HANDOFF_DISABLED_CLK;
- struct dsi_pll_vco_clk *vco = to_vco_clk(c);
- struct mdss_pll_resources *pll = vco->priv;
-
- if (is_gdsc_disabled(pll))
- return HANDOFF_DISABLED_CLK;
-
- rc = mdss_pll_resource_enable(pll, true);
- if (rc) {
- pr_err("Failed to enable mdss dsi pll=%d\n", pll->index);
- return ret;
- }
-
- if (pll_is_pll_locked_8996(pll)) {
- pll->handoff_resources = true;
- pll->pll_on = true;
- c->rate = pll_vco_get_rate_8996(c);
- ret = HANDOFF_ENABLED_CLK;
- } else {
- mdss_pll_resource_enable(pll, false);
- }
-
- return ret;
-}
-
-enum handoff shadow_pll_vco_handoff_8996(struct clk *c)
-{
- return HANDOFF_DISABLED_CLK;
-}
-
-int pll_vco_prepare_8996(struct clk *c)
+int pll_vco_prepare_14nm(struct clk_hw *hw)
{
int rc = 0;
- struct dsi_pll_vco_clk *vco = to_vco_clk(c);
+ struct dsi_pll_vco_clk *vco = to_vco_hw(hw);
struct mdss_pll_resources *pll = vco->priv;
if (!pll) {
@@ -1101,8 +1107,9 @@ int pll_vco_prepare_8996(struct clk *c)
}
if ((pll->vco_cached_rate != 0)
- && (pll->vco_cached_rate == c->rate)) {
- rc = c->ops->set_rate(c, pll->vco_cached_rate);
+ && (pll->vco_cached_rate == clk_hw_get_rate(hw))) {
+ rc = hw->init->ops->set_rate(hw, pll->vco_cached_rate,
+ pll->vco_cached_rate);
if (rc) {
pr_err("index=%d vco_set_rate failed. rc=%d\n",
rc, pll->index);
@@ -1111,7 +1118,7 @@ int pll_vco_prepare_8996(struct clk *c)
}
}
- rc = dsi_pll_enable(c);
+ rc = dsi_pll_enable(hw);
if (rc) {
mdss_pll_resource_enable(pll, false);
@@ -1122,9 +1129,9 @@ error:
return rc;
}
-void pll_vco_unprepare_8996(struct clk *c)
+void pll_vco_unprepare_14nm(struct clk_hw *hw)
{
- struct dsi_pll_vco_clk *vco = to_vco_clk(c);
+ struct dsi_pll_vco_clk *vco = to_vco_hw(hw);
struct mdss_pll_resources *pll = vco->priv;
if (!pll) {
@@ -1132,6 +1139,17 @@ void pll_vco_unprepare_8996(struct clk *c)
return;
}
- pll->vco_cached_rate = c->rate;
- dsi_pll_disable(c);
+ pll->vco_cached_rate = clk_hw_get_rate(hw);
+ dsi_pll_disable(hw);
+}
+
+int dsi_mux_set_parent_14nm(void *context, unsigned int reg, unsigned int val)
+{
+ return 0;
+}
+
+int dsi_mux_get_parent_14nm(void *context, unsigned int reg, unsigned int *val)
+{
+ *val = 0;
+ return 0;
}
diff --git a/drivers/clk/qcom/mdss/mdss-dsi-pll-14nm.c b/drivers/clk/qcom/mdss/mdss-dsi-pll-14nm.c
new file mode 100644
index 000000000000..667a1512d54f
--- /dev/null
+++ b/drivers/clk/qcom/mdss/mdss-dsi-pll-14nm.c
@@ -0,0 +1,614 @@
+/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+
+#include "mdss-pll.h"
+#include "mdss-dsi-pll.h"
+#include "mdss-dsi-pll-14nm.h"
+
+#define VCO_DELAY_USEC 1
+
+static struct dsi_pll_db pll_db[DSI_PLL_NUM];
+
+static struct regmap_config dsi_pll_14nm_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x588,
+};
+
+static struct regmap_bus post_n1_div_regmap_bus = {
+ .reg_write = post_n1_div_set_div,
+ .reg_read = post_n1_div_get_div,
+};
+
+static struct regmap_bus n2_div_regmap_bus = {
+ .reg_write = n2_div_set_div,
+ .reg_read = n2_div_get_div,
+};
+
+static struct regmap_bus shadow_n2_div_regmap_bus = {
+ .reg_write = shadow_n2_div_set_div,
+ .reg_read = n2_div_get_div,
+};
+
+static struct regmap_bus dsi_mux_regmap_bus = {
+ .reg_write = dsi_mux_set_parent_14nm,
+ .reg_read = dsi_mux_get_parent_14nm,
+};
+
+/* Op structures */
+static struct clk_ops clk_ops_dsi_vco = {
+ .recalc_rate = pll_vco_recalc_rate_14nm,
+ .set_rate = pll_vco_set_rate_14nm,
+ .round_rate = pll_vco_round_rate_14nm,
+ .prepare = pll_vco_prepare_14nm,
+ .unprepare = pll_vco_unprepare_14nm,
+};
+
+/* Shadow ops for dynamic refresh */
+static struct clk_ops clk_ops_shadow_dsi_vco = {
+ .recalc_rate = pll_vco_recalc_rate_14nm,
+ .set_rate = shadow_pll_vco_set_rate_14nm,
+ .round_rate = pll_vco_round_rate_14nm,
+};
+
+static struct dsi_pll_vco_clk dsi0pll_vco_clk = {
+ .ref_clk_rate = 19200000UL,
+ .min_rate = 1300000000UL,
+ .max_rate = 2600000000UL,
+ .pll_en_seq_cnt = 1,
+ .pll_enable_seqs[0] = dsi_pll_enable_seq_14nm,
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi0pll_vco_clk_14nm",
+ .parent_names = (const char *[]){ "xo_board" },
+ .num_parents = 1,
+ .ops = &clk_ops_dsi_vco,
+ },
+};
+
+static struct dsi_pll_vco_clk dsi0pll_shadow_vco_clk = {
+ .ref_clk_rate = 19200000u,
+ .min_rate = 1300000000u,
+ .max_rate = 2600000000u,
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi0pll_shadow_vco_clk_14nm",
+ .parent_names = (const char *[]){ "xo_board" },
+ .num_parents = 1,
+ .ops = &clk_ops_shadow_dsi_vco,
+ },
+};
+
+static struct dsi_pll_vco_clk dsi1pll_vco_clk = {
+ .ref_clk_rate = 19200000UL,
+ .min_rate = 1300000000UL,
+ .max_rate = 2600000000UL,
+ .pll_en_seq_cnt = 1,
+ .pll_enable_seqs[0] = dsi_pll_enable_seq_14nm,
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi1pll_vco_clk_14nm",
+ .parent_names = (const char *[]){ "xo_board" },
+ .num_parents = 1,
+ .ops = &clk_ops_dsi_vco,
+ },
+};
+
+static struct dsi_pll_vco_clk dsi1pll_shadow_vco_clk = {
+ .ref_clk_rate = 19200000u,
+ .min_rate = 1300000000u,
+ .max_rate = 2600000000u,
+ .pll_en_seq_cnt = 1,
+ .pll_enable_seqs[0] = dsi_pll_enable_seq_14nm,
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi1pll_shadow_vco_clk_14nm",
+ .parent_names = (const char *[]){ "xo_board" },
+ .num_parents = 1,
+ .ops = &clk_ops_shadow_dsi_vco,
+ },
+};
+
+static struct clk_regmap_div dsi0pll_post_n1_div_clk = {
+ .reg = 0x48,
+ .shift = 0,
+ .width = 4,
+
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi0pll_post_n1_div_clk",
+ .parent_names =
+ (const char *[]){ "dsi0pll_vco_clk_14nm" },
+ .num_parents = 1,
+ .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+ .ops = &clk_regmap_div_ops,
+ },
+ },
+};
+
+static struct clk_regmap_div dsi0pll_shadow_post_n1_div_clk = {
+ .reg = 0x48,
+ .shift = 0,
+ .width = 4,
+
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi0pll_shadow_post_n1_div_clk",
+ .parent_names =
+ (const char *[]){"dsi0pll_shadow_vco_clk_14nm"},
+ .num_parents = 1,
+ .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+ .ops = &clk_regmap_div_ops,
+ },
+ },
+};
+
+static struct clk_regmap_div dsi1pll_post_n1_div_clk = {
+ .reg = 0x48,
+ .shift = 0,
+ .width = 4,
+
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi1pll_post_n1_div_clk",
+ .parent_names =
+ (const char *[]){ "dsi1pll_vco_clk_14nm" },
+ .num_parents = 1,
+ .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+ .ops = &clk_regmap_div_ops,
+ },
+ },
+};
+
+static struct clk_regmap_div dsi1pll_shadow_post_n1_div_clk = {
+ .reg = 0x48,
+ .shift = 0,
+ .width = 4,
+
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi1pll_shadow_post_n1_div_clk",
+ .parent_names =
+ (const char *[]){"dsi1pll_shadow_vco_clk_14nm"},
+ .num_parents = 1,
+ .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+ .ops = &clk_regmap_div_ops,
+ },
+ },
+};
+
+static struct clk_regmap_div dsi0pll_n2_div_clk = {
+ .reg = 0x48,
+ .shift = 0,
+ .width = 4,
+
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi0pll_n2_div_clk",
+ .parent_names =
+ (const char *[]){ "dsi0pll_post_n1_div_clk" },
+ .num_parents = 1,
+ .flags = CLK_GET_RATE_NOCACHE,
+ .ops = &clk_regmap_div_ops,
+ },
+ },
+};
+
+static struct clk_regmap_div dsi0pll_shadow_n2_div_clk = {
+ .reg = 0x48,
+ .shift = 0,
+ .width = 4,
+
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi0pll_shadow_n2_div_clk",
+ .parent_names =
+ (const char *[]){ "dsi0pll_shadow_post_n1_div_clk" },
+ .num_parents = 1,
+ .flags = CLK_GET_RATE_NOCACHE,
+ .ops = &clk_regmap_div_ops,
+ },
+ },
+};
+
+static struct clk_regmap_div dsi1pll_n2_div_clk = {
+ .reg = 0x48,
+ .shift = 0,
+ .width = 4,
+
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi1pll_n2_div_clk",
+ .parent_names =
+ (const char *[]){ "dsi1pll_post_n1_div_clk" },
+ .num_parents = 1,
+ .flags = CLK_GET_RATE_NOCACHE,
+ .ops = &clk_regmap_div_ops,
+ },
+ },
+};
+
+static struct clk_regmap_div dsi1pll_shadow_n2_div_clk = {
+ .reg = 0x48,
+ .shift = 0,
+ .width = 4,
+
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi1pll_shadow_n2_div_clk",
+ .parent_names =
+ (const char *[]){ "dsi1pll_shadow_post_n1_div_clk" },
+ .num_parents = 1,
+ .flags = CLK_GET_RATE_NOCACHE,
+ .ops = &clk_regmap_div_ops,
+ },
+ },
+};
+
+static struct clk_fixed_factor dsi0pll_pixel_clk_src = {
+ .div = 2,
+ .mult = 1,
+
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi0pll_pixel_clk_src",
+ .parent_names = (const char *[]){ "dsi0pll_n2_div_clk" },
+ .num_parents = 1,
+ .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+ .ops = &clk_fixed_factor_ops,
+ },
+};
+
+static struct clk_fixed_factor dsi0pll_shadow_pixel_clk_src = {
+ .div = 2,
+ .mult = 1,
+
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi0pll_shadow_pixel_clk_src",
+ .parent_names = (const char *[]){ "dsi0pll_shadow_n2_div_clk" },
+ .num_parents = 1,
+ .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+ .ops = &clk_fixed_factor_ops,
+ },
+};
+
+static struct clk_fixed_factor dsi1pll_pixel_clk_src = {
+ .div = 2,
+ .mult = 1,
+
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi1pll_pixel_clk_src",
+ .parent_names = (const char *[]){ "dsi1pll_n2_div_clk" },
+ .num_parents = 1,
+ .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+ .ops = &clk_fixed_factor_ops,
+ },
+};
+
+static struct clk_fixed_factor dsi1pll_shadow_pixel_clk_src = {
+ .div = 2,
+ .mult = 1,
+
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi1pll_shadow_pixel_clk_src",
+ .parent_names = (const char *[]){ "dsi1pll_shadow_n2_div_clk" },
+ .num_parents = 1,
+ .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+ .ops = &clk_fixed_factor_ops,
+ },
+};
+
+static struct clk_regmap_mux dsi0pll_pixel_clk_mux = {
+ .reg = 0x48,
+ .shift = 0,
+ .width = 1,
+
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi0pll_pixel_clk_mux",
+ .parent_names =
+ (const char *[]){ "dsi0pll_pixel_clk_src",
+ "dsi0pll_shadow_pixel_clk_src"},
+ .num_parents = 2,
+ .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+ .ops = &clk_regmap_mux_closest_ops,
+ },
+ },
+};
+
+static struct clk_regmap_mux dsi1pll_pixel_clk_mux = {
+ .reg = 0x48,
+ .shift = 0,
+ .width = 1,
+
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi1pll_pixel_clk_mux",
+ .parent_names =
+ (const char *[]){ "dsi1pll_pixel_clk_src",
+ "dsi1pll_shadow_pixel_clk_src"},
+ .num_parents = 2,
+ .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+ .ops = &clk_regmap_mux_closest_ops,
+ },
+ },
+};
+
+static struct clk_fixed_factor dsi0pll_byte_clk_src = {
+ .div = 8,
+ .mult = 1,
+
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi0pll_byte_clk_src",
+ .parent_names = (const char *[]){ "dsi0pll_post_n1_div_clk" },
+ .num_parents = 1,
+ .flags = (CLK_SET_RATE_PARENT),
+ .ops = &clk_fixed_factor_ops,
+ },
+};
+
+static struct clk_fixed_factor dsi0pll_shadow_byte_clk_src = {
+ .div = 8,
+ .mult = 1,
+
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi0pll_shadow_byte_clk_src",
+ .parent_names =
+ (const char *[]){ "dsi0pll_shadow_post_n1_div_clk" },
+ .num_parents = 1,
+ .flags = (CLK_SET_RATE_PARENT),
+ .ops = &clk_fixed_factor_ops,
+ },
+};
+
+static struct clk_fixed_factor dsi1pll_byte_clk_src = {
+ .div = 8,
+ .mult = 1,
+
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi1pll_byte_clk_src",
+ .parent_names = (const char *[]){ "dsi1pll_post_n1_div_clk" },
+ .num_parents = 1,
+ .flags = (CLK_SET_RATE_PARENT),
+ .ops = &clk_fixed_factor_ops,
+ },
+};
+
+static struct clk_fixed_factor dsi1pll_shadow_byte_clk_src = {
+ .div = 8,
+ .mult = 1,
+
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi1pll_shadow_byte_clk_src",
+ .parent_names =
+ (const char *[]){ "dsi1pll_shadow_post_n1_div_clk" },
+ .num_parents = 1,
+ .flags = (CLK_SET_RATE_PARENT),
+ .ops = &clk_fixed_factor_ops,
+ },
+};
+
+static struct clk_regmap_mux dsi0pll_byte_clk_mux = {
+ .reg = 0x48,
+ .shift = 0,
+ .width = 1,
+
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi0pll_byte_clk_mux",
+ .parent_names =
+ (const char *[]){"dsi0pll_byte_clk_src",
+ "dsi0pll_shadow_byte_clk_src"},
+ .num_parents = 2,
+ .ops = &clk_regmap_mux_closest_ops,
+ .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+ },
+ },
+};
+
+static struct clk_regmap_mux dsi1pll_byte_clk_mux = {
+ .reg = 0x48,
+ .shift = 0,
+ .width = 1,
+
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "dsi1pll_byte_clk_mux",
+ .parent_names =
+ (const char *[]){"dsi1pll_byte_clk_src",
+ "dsi1pll_shadow_byte_clk_src"},
+ .num_parents = 2,
+ .ops = &clk_regmap_mux_closest_ops,
+ .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
+ },
+ },
+};
+
+static struct clk_hw *mdss_dsi_pllcc_14nm[] = {
+ [BYTE0_MUX_CLK] = &dsi0pll_byte_clk_mux.clkr.hw,
+ [BYTE0_SRC_CLK] = &dsi0pll_byte_clk_src.hw,
+ [PIX0_MUX_CLK] = &dsi0pll_pixel_clk_mux.clkr.hw,
+ [PIX0_SRC_CLK] = &dsi0pll_pixel_clk_src.hw,
+ [N2_DIV_0_CLK] = &dsi0pll_n2_div_clk.clkr.hw,
+ [POST_N1_DIV_0_CLK] = &dsi0pll_post_n1_div_clk.clkr.hw,
+ [VCO_CLK_0_CLK] = &dsi0pll_vco_clk.hw,
+ [SHADOW_BYTE0_SRC_CLK] = &dsi0pll_shadow_byte_clk_src.hw,
+ [SHADOW_PIX0_SRC_CLK] = &dsi0pll_shadow_pixel_clk_src.hw,
+ [SHADOW_N2_DIV_0_CLK] = &dsi0pll_shadow_n2_div_clk.clkr.hw,
+ [SHADOW_POST_N1_DIV_0_CLK] = &dsi0pll_shadow_post_n1_div_clk.clkr.hw,
+ [SHADOW_VCO_CLK_0_CLK] = &dsi0pll_shadow_vco_clk.hw,
+ [BYTE1_MUX_CLK] = &dsi1pll_byte_clk_mux.clkr.hw,
+ [BYTE1_SRC_CLK] = &dsi1pll_byte_clk_src.hw,
+ [PIX1_MUX_CLK] = &dsi1pll_pixel_clk_mux.clkr.hw,
+ [PIX1_SRC_CLK] = &dsi1pll_pixel_clk_src.hw,
+ [N2_DIV_1_CLK] = &dsi1pll_n2_div_clk.clkr.hw,
+ [POST_N1_DIV_1_CLK] = &dsi1pll_post_n1_div_clk.clkr.hw,
+ [VCO_CLK_1_CLK] = &dsi1pll_vco_clk.hw,
+ [SHADOW_BYTE1_SRC_CLK] = &dsi1pll_shadow_byte_clk_src.hw,
+ [SHADOW_PIX1_SRC_CLK] = &dsi1pll_shadow_pixel_clk_src.hw,
+ [SHADOW_N2_DIV_1_CLK] = &dsi1pll_shadow_n2_div_clk.clkr.hw,
+ [SHADOW_POST_N1_DIV_1_CLK] = &dsi1pll_shadow_post_n1_div_clk.clkr.hw,
+ [SHADOW_VCO_CLK_1_CLK] = &dsi1pll_shadow_vco_clk.hw,
+};
+
+int dsi_pll_clock_register_14nm(struct platform_device *pdev,
+ struct mdss_pll_resources *pll_res)
+{
+ int rc = 0, ndx, i;
+ int const ssc_freq_default = 31500; /* default h/w recommended value */
+ int const ssc_ppm_default = 5000; /* default h/w recommended value */
+ struct dsi_pll_db *pdb;
+ struct clk_onecell_data *clk_data;
+ struct clk *clk;
+ struct regmap *regmap;
+ int num_clks = ARRAY_SIZE(mdss_dsi_pllcc_14nm);
+
+ if (!pdev || !pdev->dev.of_node) {
+ pr_err("Invalid input parameters\n");
+ return -EINVAL;
+ }
+
+ if (!pll_res || !pll_res->pll_base) {
+ pr_err("Invalid PLL resources\n");
+ return -EPROBE_DEFER;
+ }
+
+ if (pll_res->index >= DSI_PLL_NUM) {
+ pr_err("pll ndx=%d is NOT supported\n", pll_res->index);
+ return -EINVAL;
+ }
+
+ 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];
+
+ if (pll_res->ssc_en) {
+ if (!pll_res->ssc_freq)
+ pll_res->ssc_freq = ssc_freq_default;
+ if (!pll_res->ssc_ppm)
+ pll_res->ssc_ppm = ssc_ppm_default;
+ }
+
+ clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data),
+ GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ clk_data->clks = devm_kzalloc(&pdev->dev, (num_clks *
+ sizeof(struct clk *)), GFP_KERNEL);
+ if (!clk_data->clks) {
+ devm_kfree(&pdev->dev, clk_data);
+ return -ENOMEM;
+ }
+
+ clk_data->clk_num = num_clks;
+
+ /* Set client data to mux, div and vco clocks. */
+ if (pll_res->index == DSI_PLL_1) {
+ regmap = devm_regmap_init(&pdev->dev, &post_n1_div_regmap_bus,
+ pll_res, &dsi_pll_14nm_config);
+ dsi1pll_post_n1_div_clk.clkr.regmap = regmap;
+ dsi1pll_shadow_post_n1_div_clk.clkr.regmap = regmap;
+
+ regmap = devm_regmap_init(&pdev->dev, &n2_div_regmap_bus,
+ pll_res, &dsi_pll_14nm_config);
+ dsi1pll_n2_div_clk.clkr.regmap = regmap;
+
+ regmap = devm_regmap_init(&pdev->dev, &shadow_n2_div_regmap_bus,
+ pll_res, &dsi_pll_14nm_config);
+ dsi1pll_shadow_n2_div_clk.clkr.regmap = regmap;
+
+ regmap = devm_regmap_init(&pdev->dev, &dsi_mux_regmap_bus,
+ pll_res, &dsi_pll_14nm_config);
+ dsi1pll_byte_clk_mux.clkr.regmap = regmap;
+ dsi1pll_pixel_clk_mux.clkr.regmap = regmap;
+
+ dsi1pll_vco_clk.priv = pll_res;
+ dsi1pll_shadow_vco_clk.priv = pll_res;
+
+ pll_res->vco_delay = VCO_DELAY_USEC;
+
+ for (i = BYTE1_MUX_CLK; i <= SHADOW_VCO_CLK_1_CLK; i++) {
+ pr_debug("register clk: %d index: %d\n",
+ i, pll_res->index);
+ clk = devm_clk_register(&pdev->dev,
+ mdss_dsi_pllcc_14nm[i]);
+ if (IS_ERR(clk)) {
+ pr_err("clk registration failed for DSI: %d\n",
+ pll_res->index);
+ rc = -EINVAL;
+ goto clk_reg_fail;
+ }
+ clk_data->clks[i] = clk;
+ }
+
+ rc = of_clk_add_provider(pdev->dev.of_node,
+ of_clk_src_onecell_get, clk_data);
+ } else {
+ regmap = devm_regmap_init(&pdev->dev, &post_n1_div_regmap_bus,
+ pll_res, &dsi_pll_14nm_config);
+ dsi0pll_post_n1_div_clk.clkr.regmap = regmap;
+ dsi0pll_shadow_post_n1_div_clk.clkr.regmap = regmap;
+
+ regmap = devm_regmap_init(&pdev->dev, &n2_div_regmap_bus,
+ pll_res, &dsi_pll_14nm_config);
+ dsi0pll_n2_div_clk.clkr.regmap = regmap;
+
+ regmap = devm_regmap_init(&pdev->dev, &shadow_n2_div_regmap_bus,
+ pll_res, &dsi_pll_14nm_config);
+ dsi0pll_shadow_n2_div_clk.clkr.regmap = regmap;
+
+ regmap = devm_regmap_init(&pdev->dev, &dsi_mux_regmap_bus,
+ pll_res, &dsi_pll_14nm_config);
+ dsi0pll_byte_clk_mux.clkr.regmap = regmap;
+ dsi0pll_pixel_clk_mux.clkr.regmap = regmap;
+
+ dsi0pll_vco_clk.priv = pll_res;
+ dsi0pll_shadow_vco_clk.priv = pll_res;
+ pll_res->vco_delay = VCO_DELAY_USEC;
+
+ for (i = BYTE0_MUX_CLK; i <= SHADOW_VCO_CLK_0_CLK; i++) {
+ pr_debug("reg clk: %d index: %d\n", i, pll_res->index);
+ clk = devm_clk_register(&pdev->dev,
+ mdss_dsi_pllcc_14nm[i]);
+ if (IS_ERR(clk)) {
+ pr_err("clk registration failed for DSI: %d\n",
+ pll_res->index);
+ rc = -EINVAL;
+ goto clk_reg_fail;
+ }
+ clk_data->clks[i] = clk;
+ }
+
+ rc = of_clk_add_provider(pdev->dev.of_node,
+ of_clk_src_onecell_get, clk_data);
+ }
+
+ if (!rc) {
+ pr_info("Registered DSI PLL ndx=%d clocks successfully\n",
+ pll_res->index);
+ return rc;
+ }
+
+clk_reg_fail:
+ devm_kfree(&pdev->dev, clk_data->clks);
+ devm_kfree(&pdev->dev, clk_data);
+ return rc;
+}
diff --git a/drivers/clk/qcom/mdss/mdss-dsi-pll-8996.h b/drivers/clk/qcom/mdss/mdss-dsi-pll-14nm.h
index 611e79101d4f..c2a3b12d8174 100644
--- a/drivers/clk/qcom/mdss/mdss-dsi-pll-8996.h
+++ b/drivers/clk/qcom/mdss/mdss-dsi-pll-14nm.h
@@ -10,8 +10,8 @@
* GNU General Public License for more details.
*/
-#ifndef MDSS_DSI_PLL_8996_H
-#define MDSS_DSI_PLL_8996_H
+#ifndef MDSS_DSI_PLL_14NM_H
+#define MDSS_DSI_PLL_14NM_H
#define DSIPHY_CMN_CLK_CFG0 0x0010
#define DSIPHY_CMN_CLK_CFG1 0x0014
@@ -197,25 +197,31 @@ enum {
PLL_MASTER
};
-int pll_vco_set_rate_8996(struct clk *c, unsigned long rate);
-long pll_vco_round_rate_8996(struct clk *c, unsigned long rate);
-enum handoff pll_vco_handoff_8996(struct clk *c);
-enum handoff shadow_pll_vco_handoff_8996(struct clk *c);
-int shadow_post_n1_div_set_div(struct div_clk *clk, int div);
-int shadow_post_n1_div_get_div(struct div_clk *clk);
-int shadow_n2_div_set_div(struct div_clk *clk, int div);
-int shadow_n2_div_get_div(struct div_clk *clk);
-int shadow_pll_vco_set_rate_8996(struct clk *c, unsigned long rate);
-int pll_vco_prepare_8996(struct clk *c);
-void pll_vco_unprepare_8996(struct clk *c);
-int set_mdss_byte_mux_sel_8996(struct mux_clk *clk, int sel);
-int get_mdss_byte_mux_sel_8996(struct mux_clk *clk);
-int set_mdss_pixel_mux_sel_8996(struct mux_clk *clk, int sel);
-int get_mdss_pixel_mux_sel_8996(struct mux_clk *clk);
-int post_n1_div_set_div(struct div_clk *clk, int div);
-int post_n1_div_get_div(struct div_clk *clk);
-int n2_div_set_div(struct div_clk *clk, int div);
-int n2_div_get_div(struct div_clk *clk);
-int dsi_pll_enable_seq_8996(struct mdss_pll_resources *pll);
-
-#endif /* MDSS_DSI_PLL_8996_H */
+int pll_vco_set_rate_14nm(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate);
+int shadow_pll_vco_set_rate_14nm(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate);
+long pll_vco_round_rate_14nm(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate);
+unsigned long pll_vco_recalc_rate_14nm(struct clk_hw *hw,
+ unsigned long parent_rate);
+
+int pll_vco_prepare_14nm(struct clk_hw *hw);
+void pll_vco_unprepare_14nm(struct clk_hw *hw);
+
+int shadow_post_n1_div_set_div(void *context,
+ unsigned int reg, unsigned int div);
+int shadow_post_n1_div_get_div(void *context,
+ unsigned int reg, unsigned int *div);
+int shadow_n2_div_set_div(void *context, unsigned int reg, unsigned int div);
+int shadow_n2_div_get_div(void *context, unsigned int reg, unsigned int *div);
+
+int post_n1_div_set_div(void *context, unsigned int reg, unsigned int div);
+int post_n1_div_get_div(void *context, unsigned int reg, unsigned int *div);
+int n2_div_set_div(void *context, unsigned int reg, unsigned int div);
+int n2_div_get_div(void *context, unsigned int reg, unsigned int *div);
+int dsi_pll_enable_seq_14nm(struct mdss_pll_resources *pll);
+int dsi_mux_set_parent_14nm(void *context, unsigned int reg, unsigned int val);
+int dsi_mux_get_parent_14nm(void *context, unsigned int reg, unsigned int *val);
+
+#endif /* MDSS_DSI_PLL_14NM_H */
diff --git a/drivers/clk/qcom/mdss/mdss-dsi-pll-8996.c b/drivers/clk/qcom/mdss/mdss-dsi-pll-8996.c
deleted file mode 100644
index 1de1b997a041..000000000000
--- a/drivers/clk/qcom/mdss/mdss-dsi-pll-8996.c
+++ /dev/null
@@ -1,566 +0,0 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#define pr_fmt(fmt) "%s: " fmt, __func__
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/clk/msm-clk-provider.h>
-#include <linux/clk/msm-clk.h>
-#include <linux/workqueue.h>
-#include <linux/clk/msm-clock-generic.h>
-#include <dt-bindings/clock/msm-clocks-8996.h>
-
-#include "mdss-pll.h"
-#include "mdss-dsi-pll.h"
-#include "mdss-dsi-pll-8996.h"
-
-#define VCO_DELAY_USEC 1
-
-static struct dsi_pll_db pll_db[DSI_PLL_NUM];
-
-static struct clk_ops n2_clk_src_ops;
-static struct clk_ops shadow_n2_clk_src_ops;
-static struct clk_ops byte_clk_src_ops;
-static struct clk_ops post_n1_div_clk_src_ops;
-static struct clk_ops shadow_post_n1_div_clk_src_ops;
-
-static struct clk_ops clk_ops_gen_mux_dsi;
-
-/* Op structures */
-static struct clk_ops clk_ops_dsi_vco = {
- .set_rate = pll_vco_set_rate_8996,
- .round_rate = pll_vco_round_rate_8996,
- .handoff = pll_vco_handoff_8996,
- .prepare = pll_vco_prepare_8996,
- .unprepare = pll_vco_unprepare_8996,
-};
-
-static struct clk_div_ops post_n1_div_ops = {
- .set_div = post_n1_div_set_div,
- .get_div = post_n1_div_get_div,
-};
-
-static struct clk_div_ops n2_div_ops = { /* hr_oclk3 */
- .set_div = n2_div_set_div,
- .get_div = n2_div_get_div,
-};
-
-static struct clk_mux_ops mdss_byte_mux_ops = {
- .set_mux_sel = set_mdss_byte_mux_sel_8996,
- .get_mux_sel = get_mdss_byte_mux_sel_8996,
-};
-
-static struct clk_mux_ops mdss_pixel_mux_ops = {
- .set_mux_sel = set_mdss_pixel_mux_sel_8996,
- .get_mux_sel = get_mdss_pixel_mux_sel_8996,
-};
-
-/* Shadow ops for dynamic refresh */
-static struct clk_ops clk_ops_shadow_dsi_vco = {
- .set_rate = shadow_pll_vco_set_rate_8996,
- .round_rate = pll_vco_round_rate_8996,
- .handoff = shadow_pll_vco_handoff_8996,
-};
-
-static struct clk_div_ops shadow_post_n1_div_ops = {
- .set_div = post_n1_div_set_div,
-};
-
-static struct clk_div_ops shadow_n2_div_ops = {
- .set_div = shadow_n2_div_set_div,
-};
-
-static struct dsi_pll_vco_clk dsi0pll_vco_clk = {
- .ref_clk_rate = 19200000UL,
- .min_rate = 1300000000UL,
- .max_rate = 2600000000UL,
- .pll_en_seq_cnt = 1,
- .pll_enable_seqs[0] = dsi_pll_enable_seq_8996,
- .c = {
- .dbg_name = "dsi0pll_vco_clk_8996",
- .ops = &clk_ops_dsi_vco,
- CLK_INIT(dsi0pll_vco_clk.c),
- },
-};
-
-static struct dsi_pll_vco_clk dsi0pll_shadow_vco_clk = {
- .ref_clk_rate = 19200000u,
- .min_rate = 1300000000u,
- .max_rate = 2600000000u,
- .c = {
- .dbg_name = "dsi0pll_shadow_vco_clk",
- .ops = &clk_ops_shadow_dsi_vco,
- CLK_INIT(dsi0pll_shadow_vco_clk.c),
- },
-};
-
-static struct dsi_pll_vco_clk dsi1pll_vco_clk = {
- .ref_clk_rate = 19200000UL,
- .min_rate = 1300000000UL,
- .max_rate = 2600000000UL,
- .pll_en_seq_cnt = 1,
- .pll_enable_seqs[0] = dsi_pll_enable_seq_8996,
- .c = {
- .dbg_name = "dsi1pll_vco_clk_8996",
- .ops = &clk_ops_dsi_vco,
- CLK_INIT(dsi1pll_vco_clk.c),
- },
-};
-
-static struct dsi_pll_vco_clk dsi1pll_shadow_vco_clk = {
- .ref_clk_rate = 19200000u,
- .min_rate = 1300000000u,
- .max_rate = 2600000000u,
- .pll_en_seq_cnt = 1,
- .pll_enable_seqs[0] = dsi_pll_enable_seq_8996,
- .c = {
- .dbg_name = "dsi1pll_shadow_vco_clk",
- .ops = &clk_ops_shadow_dsi_vco,
- CLK_INIT(dsi1pll_shadow_vco_clk.c),
- },
-};
-
-static struct div_clk dsi0pll_post_n1_div_clk = {
- .data = {
- .max_div = 15,
- .min_div = 1,
- },
- .ops = &post_n1_div_ops,
- .c = {
- .parent = &dsi0pll_vco_clk.c,
- .dbg_name = "dsi0pll_post_n1_div_clk",
- .ops = &post_n1_div_clk_src_ops,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi0pll_post_n1_div_clk.c),
- },
-};
-
-static struct div_clk dsi0pll_shadow_post_n1_div_clk = {
- .data = {
- .max_div = 15,
- .min_div = 1,
- },
- .ops = &shadow_post_n1_div_ops,
- .c = {
- .parent = &dsi0pll_shadow_vco_clk.c,
- .dbg_name = "dsi0pll_shadow_post_n1_div_clk",
- .ops = &shadow_post_n1_div_clk_src_ops,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi0pll_shadow_post_n1_div_clk.c),
- },
-};
-
-static struct div_clk dsi1pll_post_n1_div_clk = {
- .data = {
- .max_div = 15,
- .min_div = 1,
- },
- .ops = &post_n1_div_ops,
- .c = {
- .parent = &dsi1pll_vco_clk.c,
- .dbg_name = "dsi1pll_post_n1_div_clk",
- .ops = &post_n1_div_clk_src_ops,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi1pll_post_n1_div_clk.c),
- },
-};
-
-static struct div_clk dsi1pll_shadow_post_n1_div_clk = {
- .data = {
- .max_div = 15,
- .min_div = 1,
- },
- .ops = &shadow_post_n1_div_ops,
- .c = {
- .parent = &dsi1pll_shadow_vco_clk.c,
- .dbg_name = "dsi1pll_shadow_post_n1_div_clk",
- .ops = &shadow_post_n1_div_clk_src_ops,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi1pll_shadow_post_n1_div_clk.c),
- },
-};
-
-static struct div_clk dsi0pll_n2_div_clk = {
- .data = {
- .max_div = 15,
- .min_div = 1,
- },
- .ops = &n2_div_ops,
- .c = {
- .parent = &dsi0pll_post_n1_div_clk.c,
- .dbg_name = "dsi0pll_n2_div_clk",
- .ops = &n2_clk_src_ops,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi0pll_n2_div_clk.c),
- },
-};
-
-static struct div_clk dsi0pll_shadow_n2_div_clk = {
- .data = {
- .max_div = 15,
- .min_div = 1,
- },
- .ops = &shadow_n2_div_ops,
- .c = {
- .parent = &dsi0pll_shadow_post_n1_div_clk.c,
- .dbg_name = "dsi0pll_shadow_n2_div_clk",
- .ops = &shadow_n2_clk_src_ops,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi0pll_shadow_n2_div_clk.c),
- },
-};
-
-static struct div_clk dsi1pll_n2_div_clk = {
- .data = {
- .max_div = 15,
- .min_div = 1,
- },
- .ops = &n2_div_ops,
- .c = {
- .parent = &dsi1pll_post_n1_div_clk.c,
- .dbg_name = "dsi1pll_n2_div_clk",
- .ops = &n2_clk_src_ops,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi1pll_n2_div_clk.c),
- },
-};
-
-static struct div_clk dsi1pll_shadow_n2_div_clk = {
- .data = {
- .max_div = 15,
- .min_div = 1,
- },
- .ops = &shadow_n2_div_ops,
- .c = {
- .parent = &dsi1pll_shadow_post_n1_div_clk.c,
- .dbg_name = "dsi1pll_shadow_n2_div_clk",
- .ops = &shadow_n2_clk_src_ops,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi1pll_shadow_n2_div_clk.c),
- },
-};
-
-static struct div_clk dsi0pll_pixel_clk_src = {
- .data = {
- .div = 2,
- .min_div = 2,
- .max_div = 2,
- },
- .c = {
- .parent = &dsi0pll_n2_div_clk.c,
- .dbg_name = "dsi0pll_pixel_clk_src",
- .ops = &clk_ops_div,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi0pll_pixel_clk_src.c),
- },
-};
-
-static struct div_clk dsi0pll_shadow_pixel_clk_src = {
- .data = {
- .div = 2,
- .min_div = 2,
- .max_div = 2,
- },
- .c = {
- .parent = &dsi0pll_shadow_n2_div_clk.c,
- .dbg_name = "dsi0pll_shadow_pixel_clk_src",
- .ops = &clk_ops_div,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi0pll_shadow_pixel_clk_src.c),
- },
-};
-
-static struct div_clk dsi1pll_pixel_clk_src = {
- .data = {
- .div = 2,
- .min_div = 2,
- .max_div = 2,
- },
- .c = {
- .parent = &dsi1pll_n2_div_clk.c,
- .dbg_name = "dsi1pll_pixel_clk_src",
- .ops = &clk_ops_div,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi1pll_pixel_clk_src.c),
- },
-};
-
-static struct div_clk dsi1pll_shadow_pixel_clk_src = {
- .data = {
- .div = 2,
- .min_div = 2,
- .max_div = 2,
- },
- .c = {
- .parent = &dsi1pll_shadow_n2_div_clk.c,
- .dbg_name = "dsi1pll_shadow_pixel_clk_src",
- .ops = &clk_ops_div,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi1pll_shadow_pixel_clk_src.c),
- },
-};
-
-static struct mux_clk dsi0pll_pixel_clk_mux = {
- .num_parents = 2,
- .parents = (struct clk_src[]) {
- {&dsi0pll_pixel_clk_src.c, 0},
- {&dsi0pll_shadow_pixel_clk_src.c, 1},
- },
- .ops = &mdss_pixel_mux_ops,
- .c = {
- .parent = &dsi0pll_pixel_clk_src.c,
- .dbg_name = "dsi0pll_pixel_clk_mux",
- .ops = &clk_ops_gen_mux_dsi,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi0pll_pixel_clk_mux.c),
- }
-};
-
-static struct mux_clk dsi1pll_pixel_clk_mux = {
- .num_parents = 2,
- .parents = (struct clk_src[]) {
- {&dsi1pll_pixel_clk_src.c, 0},
- {&dsi1pll_shadow_pixel_clk_src.c, 1},
- },
- .ops = &mdss_pixel_mux_ops,
- .c = {
- .parent = &dsi1pll_pixel_clk_src.c,
- .dbg_name = "dsi1pll_pixel_clk_mux",
- .ops = &clk_ops_gen_mux_dsi,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi1pll_pixel_clk_mux.c),
- }
-};
-
-static struct div_clk dsi0pll_byte_clk_src = {
- .data = {
- .div = 8,
- .min_div = 8,
- .max_div = 8,
- },
- .c = {
- .parent = &dsi0pll_post_n1_div_clk.c,
- .dbg_name = "dsi0pll_byte_clk_src",
- .ops = &clk_ops_div,
- CLK_INIT(dsi0pll_byte_clk_src.c),
- },
-};
-
-static struct div_clk dsi0pll_shadow_byte_clk_src = {
- .data = {
- .div = 8,
- .min_div = 8,
- .max_div = 8,
- },
- .c = {
- .parent = &dsi0pll_shadow_post_n1_div_clk.c,
- .dbg_name = "dsi0pll_shadow_byte_clk_src",
- .ops = &clk_ops_div,
- CLK_INIT(dsi0pll_shadow_byte_clk_src.c),
- },
-};
-
-static struct div_clk dsi1pll_byte_clk_src = {
- .data = {
- .div = 8,
- .min_div = 8,
- .max_div = 8,
- },
- .c = {
- .parent = &dsi1pll_post_n1_div_clk.c,
- .dbg_name = "dsi1pll_byte_clk_src",
- .ops = &clk_ops_div,
- CLK_INIT(dsi1pll_byte_clk_src.c),
- },
-};
-
-static struct div_clk dsi1pll_shadow_byte_clk_src = {
- .data = {
- .div = 8,
- .min_div = 8,
- .max_div = 8,
- },
- .c = {
- .parent = &dsi1pll_shadow_post_n1_div_clk.c,
- .dbg_name = "dsi1pll_shadow_byte_clk_src",
- .ops = &clk_ops_div,
- CLK_INIT(dsi1pll_shadow_byte_clk_src.c),
- },
-};
-
-static struct mux_clk dsi0pll_byte_clk_mux = {
- .num_parents = 2,
- .parents = (struct clk_src[]) {
- {&dsi0pll_byte_clk_src.c, 0},
- {&dsi0pll_shadow_byte_clk_src.c, 1},
- },
- .ops = &mdss_byte_mux_ops,
- .c = {
- .parent = &dsi0pll_byte_clk_src.c,
- .dbg_name = "dsi0pll_byte_clk_mux",
- .ops = &clk_ops_gen_mux_dsi,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi0pll_byte_clk_mux.c),
- }
-};
-static struct mux_clk dsi1pll_byte_clk_mux = {
- .num_parents = 2,
- .parents = (struct clk_src[]) {
- {&dsi1pll_byte_clk_src.c, 0},
- {&dsi1pll_shadow_byte_clk_src.c, 1},
- },
- .ops = &mdss_byte_mux_ops,
- .c = {
- .parent = &dsi1pll_byte_clk_src.c,
- .dbg_name = "dsi1pll_byte_clk_mux",
- .ops = &clk_ops_gen_mux_dsi,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dsi1pll_byte_clk_mux.c),
- }
-};
-
-static struct clk_lookup mdss_dsi_pllcc_8996[] = {
- CLK_LIST(dsi0pll_byte_clk_mux),
- CLK_LIST(dsi0pll_byte_clk_src),
- CLK_LIST(dsi0pll_pixel_clk_mux),
- CLK_LIST(dsi0pll_pixel_clk_src),
- CLK_LIST(dsi0pll_n2_div_clk),
- CLK_LIST(dsi0pll_post_n1_div_clk),
- CLK_LIST(dsi0pll_vco_clk),
- CLK_LIST(dsi0pll_shadow_byte_clk_src),
- CLK_LIST(dsi0pll_shadow_pixel_clk_src),
- CLK_LIST(dsi0pll_shadow_n2_div_clk),
- CLK_LIST(dsi0pll_shadow_post_n1_div_clk),
- CLK_LIST(dsi0pll_shadow_vco_clk),
-};
-
-static struct clk_lookup mdss_dsi_pllcc_8996_1[] = {
- CLK_LIST(dsi1pll_byte_clk_mux),
- CLK_LIST(dsi1pll_byte_clk_src),
- CLK_LIST(dsi1pll_pixel_clk_mux),
- CLK_LIST(dsi1pll_pixel_clk_src),
- CLK_LIST(dsi1pll_n2_div_clk),
- CLK_LIST(dsi1pll_post_n1_div_clk),
- CLK_LIST(dsi1pll_vco_clk),
- CLK_LIST(dsi1pll_shadow_byte_clk_src),
- CLK_LIST(dsi1pll_shadow_pixel_clk_src),
- CLK_LIST(dsi1pll_shadow_n2_div_clk),
- CLK_LIST(dsi1pll_shadow_post_n1_div_clk),
- CLK_LIST(dsi1pll_shadow_vco_clk),
-};
-
-int dsi_pll_clock_register_8996(struct platform_device *pdev,
- struct mdss_pll_resources *pll_res)
-{
- int rc = 0, ndx;
- int const ssc_freq_default = 31500; /* default h/w recommended value */
- int const ssc_ppm_default = 5000; /* default h/w recommended value */
- struct dsi_pll_db *pdb;
-
- if (!pdev || !pdev->dev.of_node) {
- pr_err("Invalid input parameters\n");
- return -EINVAL;
- }
-
- if (!pll_res || !pll_res->pll_base) {
- pr_err("Invalid PLL resources\n");
- return -EPROBE_DEFER;
- }
-
- if (pll_res->index >= DSI_PLL_NUM) {
- pr_err("pll ndx=%d is NOT supported\n", pll_res->index);
- return -EINVAL;
- }
-
- 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 */
-
- /* hr_oclk3, pixel */
- n2_clk_src_ops = clk_ops_slave_div;
- n2_clk_src_ops.prepare = mdss_pll_div_prepare;
-
- shadow_n2_clk_src_ops = clk_ops_slave_div;
-
- /* hr_ockl2, byte, vco pll */
- post_n1_div_clk_src_ops = clk_ops_div;
- post_n1_div_clk_src_ops.prepare = mdss_pll_div_prepare;
-
- shadow_post_n1_div_clk_src_ops = clk_ops_div;
-
- byte_clk_src_ops = clk_ops_div;
- byte_clk_src_ops.prepare = mdss_pll_div_prepare;
-
- clk_ops_gen_mux_dsi = clk_ops_gen_mux;
- clk_ops_gen_mux_dsi.round_rate = parent_round_rate;
- clk_ops_gen_mux_dsi.set_rate = parent_set_rate;
-
- if (pll_res->ssc_en) {
- if (!pll_res->ssc_freq)
- pll_res->ssc_freq = ssc_freq_default;
- if (!pll_res->ssc_ppm)
- pll_res->ssc_ppm = ssc_ppm_default;
- }
-
- /* Set client data to mux, div and vco clocks. */
- if (pll_res->index == DSI_PLL_1) {
- dsi1pll_byte_clk_src.priv = pll_res;
- dsi1pll_pixel_clk_src.priv = pll_res;
- dsi1pll_post_n1_div_clk.priv = pll_res;
- dsi1pll_n2_div_clk.priv = pll_res;
- dsi1pll_vco_clk.priv = pll_res;
-
- dsi1pll_shadow_byte_clk_src.priv = pll_res;
- dsi1pll_shadow_pixel_clk_src.priv = pll_res;
- dsi1pll_shadow_post_n1_div_clk.priv = pll_res;
- dsi1pll_shadow_n2_div_clk.priv = pll_res;
- dsi1pll_shadow_vco_clk.priv = pll_res;
-
- pll_res->vco_delay = VCO_DELAY_USEC;
- rc = of_msm_clock_register(pdev->dev.of_node,
- mdss_dsi_pllcc_8996_1,
- ARRAY_SIZE(mdss_dsi_pllcc_8996_1));
- } else {
- dsi0pll_byte_clk_src.priv = pll_res;
- dsi0pll_pixel_clk_src.priv = pll_res;
- dsi0pll_post_n1_div_clk.priv = pll_res;
- dsi0pll_n2_div_clk.priv = pll_res;
- dsi0pll_vco_clk.priv = pll_res;
-
- dsi0pll_shadow_byte_clk_src.priv = pll_res;
- dsi0pll_shadow_pixel_clk_src.priv = pll_res;
- dsi0pll_shadow_post_n1_div_clk.priv = pll_res;
- dsi0pll_shadow_n2_div_clk.priv = pll_res;
- dsi0pll_shadow_vco_clk.priv = pll_res;
-
- pll_res->vco_delay = VCO_DELAY_USEC;
- rc = of_msm_clock_register(pdev->dev.of_node,
- mdss_dsi_pllcc_8996,
- ARRAY_SIZE(mdss_dsi_pllcc_8996));
- }
-
- if (!rc) {
- pr_info("Registered DSI PLL ndx=%d clocks successfully\n",
- pll_res->index);
- }
-
- return rc;
-}
diff --git a/drivers/clk/qcom/mdss/mdss-dsi-pll.h b/drivers/clk/qcom/mdss/mdss-dsi-pll.h
index 286c99e339c6..822d5181435d 100644
--- a/drivers/clk/qcom/mdss/mdss-dsi-pll.h
+++ b/drivers/clk/qcom/mdss/mdss-dsi-pll.h
@@ -31,6 +31,8 @@ struct lpfr_cfg {
};
struct dsi_pll_vco_clk {
+ struct clk_hw hw;
+
unsigned long ref_clk_rate;
unsigned long min_rate;
unsigned long max_rate;
@@ -39,72 +41,15 @@ struct dsi_pll_vco_clk {
u32 lpfr_lut_size;
void *priv;
- struct clk c;
-
int (*pll_enable_seqs[MAX_DSI_PLL_EN_SEQS])
(struct mdss_pll_resources *dsi_pll_Res);
};
-static inline struct dsi_pll_vco_clk *to_vco_clk(struct clk *clk)
+static inline struct dsi_pll_vco_clk *to_vco_hw(struct clk_hw *hw)
{
- return container_of(clk, struct dsi_pll_vco_clk, c);
+ return container_of(hw, struct dsi_pll_vco_clk, hw);
}
-int dsi_pll_clock_register_hpm(struct platform_device *pdev,
- struct mdss_pll_resources *pll_res);
-int dsi_pll_clock_register_20nm(struct platform_device *pdev,
- struct mdss_pll_resources *pll_res);
-int dsi_pll_clock_register_lpm(struct platform_device *pdev,
- struct mdss_pll_resources *pll_res);
-int dsi_pll_clock_register_8996(struct platform_device *pdev,
+int dsi_pll_clock_register_14nm(struct platform_device *pdev,
struct mdss_pll_resources *pll_res);
-int dsi_pll_clock_register_8998(struct platform_device *pdev,
- struct mdss_pll_resources *pll_res);
-
-int set_byte_mux_sel(struct mux_clk *clk, int sel);
-int get_byte_mux_sel(struct mux_clk *clk);
-int dsi_pll_mux_prepare(struct clk *c);
-int fixed_4div_set_div(struct div_clk *clk, int div);
-int fixed_4div_get_div(struct div_clk *clk);
-int digital_set_div(struct div_clk *clk, int div);
-int digital_get_div(struct div_clk *clk);
-int analog_set_div(struct div_clk *clk, int div);
-int analog_get_div(struct div_clk *clk);
-int dsi_pll_lock_status(struct mdss_pll_resources *dsi_pll_res);
-int vco_set_rate(struct dsi_pll_vco_clk *vco, unsigned long rate);
-unsigned long vco_get_rate(struct clk *c);
-long vco_round_rate(struct clk *c, unsigned long rate);
-enum handoff vco_handoff(struct clk *c);
-int vco_prepare(struct clk *c);
-void vco_unprepare(struct clk *c);
-
-/* APIs for 20nm PHY PLL */
-int pll_20nm_vco_set_rate(struct dsi_pll_vco_clk *vco, unsigned long rate);
-int shadow_pll_20nm_vco_set_rate(struct dsi_pll_vco_clk *vco,
- unsigned long rate);
-long pll_20nm_vco_round_rate(struct clk *c, unsigned long rate);
-enum handoff pll_20nm_vco_handoff(struct clk *c);
-int pll_20nm_vco_prepare(struct clk *c);
-void pll_20nm_vco_unprepare(struct clk *c);
-int pll_20nm_vco_enable_seq(struct mdss_pll_resources *dsi_pll_res);
-
-int set_bypass_lp_div_mux_sel(struct mux_clk *clk, int sel);
-int set_shadow_bypass_lp_div_mux_sel(struct mux_clk *clk, int sel);
-int get_bypass_lp_div_mux_sel(struct mux_clk *clk);
-int fixed_hr_oclk2_set_div(struct div_clk *clk, int div);
-int shadow_fixed_hr_oclk2_set_div(struct div_clk *clk, int div);
-int fixed_hr_oclk2_get_div(struct div_clk *clk);
-int hr_oclk3_set_div(struct div_clk *clk, int div);
-int shadow_hr_oclk3_set_div(struct div_clk *clk, int div);
-int hr_oclk3_get_div(struct div_clk *clk);
-int ndiv_set_div(struct div_clk *clk, int div);
-int shadow_ndiv_set_div(struct div_clk *clk, int div);
-int ndiv_get_div(struct div_clk *clk);
-void __dsi_pll_disable(void __iomem *pll_base);
-
-int set_mdss_pixel_mux_sel(struct mux_clk *clk, int sel);
-int get_mdss_pixel_mux_sel(struct mux_clk *clk);
-int set_mdss_byte_mux_sel(struct mux_clk *clk, int sel);
-int get_mdss_byte_mux_sel(struct mux_clk *clk);
-
#endif
diff --git a/drivers/clk/qcom/mdss/mdss-pll-util.c b/drivers/clk/qcom/mdss/mdss-pll-util.c
index 690c53f30eb7..881c973ec1b6 100644
--- a/drivers/clk/qcom/mdss/mdss-pll-util.c
+++ b/drivers/clk/qcom/mdss/mdss-pll-util.c
@@ -16,7 +16,6 @@
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/string.h>
-#include <linux/clk/msm-clock-generic.h>
#include <linux/of_address.h>
#include <linux/dma-mapping.h>
#include <linux/vmalloc.h>
diff --git a/drivers/clk/qcom/mdss/mdss-pll.c b/drivers/clk/qcom/mdss/mdss-pll.c
index 8264d2e5a3cd..b4b73ea4211a 100644
--- a/drivers/clk/qcom/mdss/mdss-pll.c
+++ b/drivers/clk/qcom/mdss/mdss-pll.c
@@ -19,12 +19,9 @@
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
-#include <linux/clk/msm-clock-generic.h>
#include "mdss-pll.h"
#include "mdss-dsi-pll.h"
-#include "mdss-hdmi-pll.h"
-#include "mdss-dp-pll.h"
int mdss_pll_resource_enable(struct mdss_pll_resources *pll_res, bool enable)
{
@@ -175,27 +172,7 @@ static int mdss_pll_clock_register(struct platform_device *pdev,
switch (pll_res->pll_interface_type) {
case MDSS_DSI_PLL_8996:
- rc = dsi_pll_clock_register_8996(pdev, pll_res);
- break;
- case MDSS_DSI_PLL_8998:
- rc = dsi_pll_clock_register_8998(pdev, pll_res);
- case MDSS_DP_PLL_8998:
- rc = dp_pll_clock_register_8998(pdev, pll_res);
- break;
- case MDSS_HDMI_PLL_8996:
- rc = hdmi_8996_v1_pll_clock_register(pdev, pll_res);
- break;
- case MDSS_HDMI_PLL_8996_V2:
- rc = hdmi_8996_v2_pll_clock_register(pdev, pll_res);
- break;
- case MDSS_HDMI_PLL_8996_V3:
- rc = hdmi_8996_v3_pll_clock_register(pdev, pll_res);
- break;
- case MDSS_HDMI_PLL_8996_V3_1_8:
- rc = hdmi_8996_v3_1p8_pll_clock_register(pdev, pll_res);
- break;
- case MDSS_HDMI_PLL_8998:
- rc = hdmi_8998_pll_clock_register(pdev, pll_res);
+ rc = dsi_pll_clock_register_14nm(pdev, pll_res);
break;
case MDSS_UNKNOWN_PLL:
default:
diff --git a/drivers/clk/qcom/mdss/mdss-pll.h b/drivers/clk/qcom/mdss/mdss-pll.h
index 8fffaf30d4ec..3528dcfd0cb5 100644
--- a/drivers/clk/qcom/mdss/mdss-pll.h
+++ b/drivers/clk/qcom/mdss/mdss-pll.h
@@ -14,8 +14,16 @@
#define __MDSS_PLL_H
#include <linux/mdss_io_util.h>
-#include <linux/clk/msm-clock-generic.h>
+#include <linux/clk-provider.h>
#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/regmap.h>
+
+#include "../clk-regmap.h"
+#include "../clk-regmap-divider.h"
+#include "../clk-regmap-mux.h"
+#include <dt-bindings/clock/mdss-pll-clk.h>
#define MDSS_PLL_REG_W(base, offset, data) \
writel_relaxed((data), (base) + (offset))
@@ -200,21 +208,12 @@ static inline bool is_gdsc_disabled(struct mdss_pll_resources *pll_res)
(!(readl_relaxed(pll_res->gdsc_base) & BIT(0)))) ? false : true;
}
-static inline int mdss_pll_div_prepare(struct clk *c)
+static inline int mdss_pll_div_prepare(struct clk_hw *hw)
{
- struct div_clk *div = to_div_clk(c);
+ struct clk_hw *parent_hw = clk_hw_get_parent(hw);
/* Restore the divider's value */
- return div->ops->set_div(div, div->data.div);
-}
-
-static inline int mdss_set_mux_sel(struct mux_clk *clk, int sel)
-{
- return 0;
-}
-
-static inline int mdss_get_mux_sel(struct mux_clk *clk)
-{
- return 0;
+ return hw->init->ops->set_rate(hw, clk_hw_get_rate(hw),
+ clk_hw_get_rate(parent_hw));
}
int mdss_pll_resource_enable(struct mdss_pll_resources *pll_res, bool enable);
diff --git a/include/dt-bindings/clock/mdss-pll-clk.h b/include/dt-bindings/clock/mdss-pll-clk.h
new file mode 100644
index 000000000000..8cd0b2a9bc98
--- /dev/null
+++ b/include/dt-bindings/clock/mdss-pll-clk.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MDSS_PLL_CLK_H
+#define __MDSS_PLL_CLK_H
+
+/* DSI PLL clocks */
+#define BYTE0_MUX_CLK 0
+#define BYTE0_SRC_CLK 1
+#define PIX0_MUX_CLK 2
+#define PIX0_SRC_CLK 3
+#define N2_DIV_0_CLK 4
+#define POST_N1_DIV_0_CLK 5
+#define VCO_CLK_0_CLK 6
+#define SHADOW_BYTE0_SRC_CLK 7
+#define SHADOW_PIX0_SRC_CLK 8
+#define SHADOW_N2_DIV_0_CLK 9
+#define SHADOW_POST_N1_DIV_0_CLK 10
+#define SHADOW_VCO_CLK_0_CLK 11
+#define BYTE1_MUX_CLK 12
+#define BYTE1_SRC_CLK 13
+#define PIX1_MUX_CLK 14
+#define PIX1_SRC_CLK 15
+#define N2_DIV_1_CLK 16
+#define POST_N1_DIV_1_CLK 17
+#define VCO_CLK_1_CLK 18
+#define SHADOW_BYTE1_SRC_CLK 19
+#define SHADOW_PIX1_SRC_CLK 20
+#define SHADOW_N2_DIV_1_CLK 21
+#define SHADOW_POST_N1_DIV_1_CLK 22
+#define SHADOW_VCO_CLK_1_CLK 23
+
+#endif