drm/msm/dsi: fuse dsi_pll_* code into dsi_phy_* code
authorDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Wed, 31 Mar 2021 10:57:15 +0000 (13:57 +0300)
committerRob Clark <robdclark@chromium.org>
Wed, 7 Apr 2021 18:05:45 +0000 (11:05 -0700)
Each phy version is tightly coupled with the corresponding PLL code,
there is no need to keep them separate. Fuse source files together in
order to simplify DSI code.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Abhinav Kumar <abhinavk@codeaurora.org>
Tested-by: Stephen Boyd <swboyd@chromium.org> # on sc7180 lazor
Link: https://lore.kernel.org/r/20210331105735.3690009-5-dmitry.baryshkov@linaro.org
Signed-off-by: Rob Clark <robdclark@chromium.org>
15 files changed:
drivers/gpu/drm/msm/Makefile
drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
drivers/gpu/drm/msm/dsi/phy/dsi_pll.c [new file with mode: 0644]
drivers/gpu/drm/msm/dsi/phy/dsi_pll.h [new file with mode: 0644]
drivers/gpu/drm/msm/dsi/pll/dsi_pll.c [deleted file]
drivers/gpu/drm/msm/dsi/pll/dsi_pll.h [deleted file]
drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c [deleted file]
drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c [deleted file]
drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c [deleted file]
drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c [deleted file]
drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c [deleted file]

index 3cc9061..1be6996 100644 (file)
@@ -136,13 +136,6 @@ msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o
 msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/phy/dsi_phy_10nm.o
 msm-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/phy/dsi_phy_7nm.o
 
-ifeq ($(CONFIG_DRM_MSM_DSI_PLL),y)
-msm-y += dsi/pll/dsi_pll.o
-msm-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/pll/dsi_pll_28nm.o
-msm-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/pll/dsi_pll_28nm_8960.o
-msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/pll/dsi_pll_14nm.o
-msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/pll/dsi_pll_10nm.o
-msm-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/pll/dsi_pll_7nm.o
-endif
+msm-$(CONFIG_DRM_MSM_DSI_PLL) += dsi/phy/dsi_pll.o
 
 obj-$(CONFIG_DRM_MSM)  += msm.o
index 655fa17..5da369b 100644 (file)
  * Copyright (c) 2018, The Linux Foundation
  */
 
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/iopoll.h>
 
+#include "dsi_pll.h"
 #include "dsi_phy.h"
 #include "dsi.xml.h"
 
+/*
+ * DSI PLL 10nm - clock diagram (eg: DSI0):
+ *
+ *           dsi0_pll_out_div_clk  dsi0_pll_bit_clk
+ *                              |                |
+ *                              |                |
+ *                 +---------+  |  +----------+  |  +----+
+ *  dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk
+ *                 +---------+  |  +----------+  |  +----+
+ *                              |                |
+ *                              |                |         dsi0_pll_by_2_bit_clk
+ *                              |                |          |
+ *                              |                |  +----+  |  |\  dsi0_pclk_mux
+ *                              |                |--| /2 |--o--| \   |
+ *                              |                |  +----+     |  \  |  +---------+
+ *                              |                --------------|  |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk
+ *                              |------------------------------|  /     +---------+
+ *                              |          +-----+             | /
+ *                              -----------| /4? |--o----------|/
+ *                                         +-----+  |           |
+ *                                                  |           |dsiclk_sel
+ *                                                  |
+ *                                                  dsi0_pll_post_out_div_clk
+ */
+
+#define DSI_BYTE_PLL_CLK               0
+#define DSI_PIXEL_PLL_CLK              1
+#define NUM_PROVIDED_CLKS              2
+
+#define VCO_REF_CLK_RATE               19200000
+
+struct dsi_pll_regs {
+       u32 pll_prop_gain_rate;
+       u32 pll_lockdet_rate;
+       u32 decimal_div_start;
+       u32 frac_div_start_low;
+       u32 frac_div_start_mid;
+       u32 frac_div_start_high;
+       u32 pll_clock_inverters;
+       u32 ssc_stepsize_low;
+       u32 ssc_stepsize_high;
+       u32 ssc_div_per_low;
+       u32 ssc_div_per_high;
+       u32 ssc_adjper_low;
+       u32 ssc_adjper_high;
+       u32 ssc_control;
+};
+
+struct dsi_pll_config {
+       u32 ref_freq;
+       bool div_override;
+       u32 output_div;
+       bool ignore_frac;
+       bool disable_prescaler;
+       bool enable_ssc;
+       bool ssc_center;
+       u32 dec_bits;
+       u32 frac_bits;
+       u32 lock_timer;
+       u32 ssc_freq;
+       u32 ssc_offset;
+       u32 ssc_adj_per;
+       u32 thresh_cycles;
+       u32 refclk_cycles;
+};
+
+struct pll_10nm_cached_state {
+       unsigned long vco_rate;
+       u8 bit_clk_div;
+       u8 pix_clk_div;
+       u8 pll_out_div;
+       u8 pll_mux;
+};
+
+struct dsi_pll_10nm {
+       struct msm_dsi_pll base;
+
+       int id;
+       struct platform_device *pdev;
+
+       void __iomem *phy_cmn_mmio;
+       void __iomem *mmio;
+
+       u64 vco_ref_clk_rate;
+       u64 vco_current_rate;
+
+       /* protects REG_DSI_10nm_PHY_CMN_CLK_CFG0 register */
+       spinlock_t postdiv_lock;
+
+       int vco_delay;
+       struct dsi_pll_config pll_configuration;
+       struct dsi_pll_regs reg_setup;
+
+       /* private clocks: */
+       struct clk_hw *out_div_clk_hw;
+       struct clk_hw *bit_clk_hw;
+       struct clk_hw *byte_clk_hw;
+       struct clk_hw *by_2_bit_clk_hw;
+       struct clk_hw *post_out_div_clk_hw;
+       struct clk_hw *pclk_mux_hw;
+       struct clk_hw *out_dsiclk_hw;
+
+       /* clock-provider: */
+       struct clk_hw_onecell_data *hw_data;
+
+       struct pll_10nm_cached_state cached_state;
+
+       enum msm_dsi_phy_usecase uc;
+       struct dsi_pll_10nm *slave;
+};
+
+#define to_pll_10nm(x) container_of(x, struct dsi_pll_10nm, base)
+
+/*
+ * Global list of private DSI PLL struct pointers. We need this for Dual DSI
+ * mode, where the master PLL's clk_ops needs access the slave's private data
+ */
+static struct dsi_pll_10nm *pll_10nm_list[DSI_MAX];
+
+static void dsi_pll_setup_config(struct dsi_pll_10nm *pll)
+{
+       struct dsi_pll_config *config = &pll->pll_configuration;
+
+       config->ref_freq = pll->vco_ref_clk_rate;
+       config->output_div = 1;
+       config->dec_bits = 8;
+       config->frac_bits = 18;
+       config->lock_timer = 64;
+       config->ssc_freq = 31500;
+       config->ssc_offset = 5000;
+       config->ssc_adj_per = 2;
+       config->thresh_cycles = 32;
+       config->refclk_cycles = 256;
+
+       config->div_override = false;
+       config->ignore_frac = false;
+       config->disable_prescaler = false;
+
+       config->enable_ssc = false;
+       config->ssc_center = 0;
+}
+
+static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll)
+{
+       struct dsi_pll_config *config = &pll->pll_configuration;
+       struct dsi_pll_regs *regs = &pll->reg_setup;
+       u64 fref = pll->vco_ref_clk_rate;
+       u64 pll_freq;
+       u64 divider;
+       u64 dec, dec_multiple;
+       u32 frac;
+       u64 multiplier;
+
+       pll_freq = pll->vco_current_rate;
+
+       if (config->disable_prescaler)
+               divider = fref;
+       else
+               divider = fref * 2;
+
+       multiplier = 1 << config->frac_bits;
+       dec_multiple = div_u64(pll_freq * multiplier, divider);
+       dec = div_u64_rem(dec_multiple, multiplier, &frac);
+
+       if (pll_freq <= 1900000000UL)
+               regs->pll_prop_gain_rate = 8;
+       else if (pll_freq <= 3000000000UL)
+               regs->pll_prop_gain_rate = 10;
+       else
+               regs->pll_prop_gain_rate = 12;
+       if (pll_freq < 1100000000UL)
+               regs->pll_clock_inverters = 8;
+       else
+               regs->pll_clock_inverters = 0;
+
+       regs->pll_lockdet_rate = config->lock_timer;
+       regs->decimal_div_start = dec;
+       regs->frac_div_start_low = (frac & 0xff);
+       regs->frac_div_start_mid = (frac & 0xff00) >> 8;
+       regs->frac_div_start_high = (frac & 0x30000) >> 16;
+}
+
+#define SSC_CENTER             BIT(0)
+#define SSC_EN                 BIT(1)
+
+static void dsi_pll_calc_ssc(struct dsi_pll_10nm *pll)
+{
+       struct dsi_pll_config *config = &pll->pll_configuration;
+       struct dsi_pll_regs *regs = &pll->reg_setup;
+       u32 ssc_per;
+       u32 ssc_mod;
+       u64 ssc_step_size;
+       u64 frac;
+
+       if (!config->enable_ssc) {
+               DBG("SSC not enabled\n");
+               return;
+       }
+
+       ssc_per = DIV_ROUND_CLOSEST(config->ref_freq, config->ssc_freq) / 2 - 1;
+       ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1);
+       ssc_per -= ssc_mod;
+
+       frac = regs->frac_div_start_low |
+                       (regs->frac_div_start_mid << 8) |
+                       (regs->frac_div_start_high << 16);
+       ssc_step_size = regs->decimal_div_start;
+       ssc_step_size *= (1 << config->frac_bits);
+       ssc_step_size += frac;
+       ssc_step_size *= config->ssc_offset;
+       ssc_step_size *= (config->ssc_adj_per + 1);
+       ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1));
+       ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000);
+
+       regs->ssc_div_per_low = ssc_per & 0xFF;
+       regs->ssc_div_per_high = (ssc_per & 0xFF00) >> 8;
+       regs->ssc_stepsize_low = (u32)(ssc_step_size & 0xFF);
+       regs->ssc_stepsize_high = (u32)((ssc_step_size & 0xFF00) >> 8);
+       regs->ssc_adjper_low = config->ssc_adj_per & 0xFF;
+       regs->ssc_adjper_high = (config->ssc_adj_per & 0xFF00) >> 8;
+
+       regs->ssc_control = config->ssc_center ? SSC_CENTER : 0;
+
+       pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n",
+                regs->decimal_div_start, frac, config->frac_bits);
+       pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n",
+                ssc_per, (u32)ssc_step_size, config->ssc_adj_per);
+}
+
+static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll)
+{
+       void __iomem *base = pll->mmio;
+       struct dsi_pll_regs *regs = &pll->reg_setup;
+
+       if (pll->pll_configuration.enable_ssc) {
+               pr_debug("SSC is enabled\n");
+
+               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_LOW_1,
+                         regs->ssc_stepsize_low);
+               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_HIGH_1,
+                         regs->ssc_stepsize_high);
+               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_LOW_1,
+                         regs->ssc_div_per_low);
+               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_HIGH_1,
+                         regs->ssc_div_per_high);
+               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_LOW_1,
+                         regs->ssc_adjper_low);
+               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_HIGH_1,
+                         regs->ssc_adjper_high);
+               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_CONTROL,
+                         SSC_EN | regs->ssc_control);
+       }
+}
+
+static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll)
+{
+       void __iomem *base = pll->mmio;
+
+       pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_ONE, 0x80);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_DSM_DIVIDER, 0x00);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE,
+                 0xba);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_OUTDIV, 0x00);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_CORE_OVERRIDE, 0x00);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x08);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_BAND_SET_RATE_1, 0xc0);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0xfa);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1,
+                 0x4c);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_PFILT, 0x29);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_IFILT, 0x3f);
+}
+
+static void dsi_pll_commit(struct dsi_pll_10nm *pll)
+{
+       void __iomem *base = pll->mmio;
+       struct dsi_pll_regs *reg = &pll->reg_setup;
+
+       pll_write(base + REG_DSI_10nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1,
+                 reg->decimal_div_start);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1,
+                 reg->frac_div_start_low);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1,
+                 reg->frac_div_start_mid);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1,
+                 reg->frac_div_start_high);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCKDET_RATE_1,
+                 reg->pll_lockdet_rate);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_DELAY, 0x06);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_CMODE, 0x10);
+       pll_write(base + REG_DSI_10nm_PHY_PLL_CLOCK_INVERTERS,
+                 reg->pll_clock_inverters);
+}
+
+static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
+                                    unsigned long parent_rate)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
+
+       DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_10nm->id, rate,
+           parent_rate);
+
+       pll_10nm->vco_current_rate = rate;
+       pll_10nm->vco_ref_clk_rate = VCO_REF_CLK_RATE;
+
+       dsi_pll_setup_config(pll_10nm);
+
+       dsi_pll_calc_dec_frac(pll_10nm);
+
+       dsi_pll_calc_ssc(pll_10nm);
+
+       dsi_pll_commit(pll_10nm);
+
+       dsi_pll_config_hzindep_reg(pll_10nm);
+
+       dsi_pll_ssc_commit(pll_10nm);
+
+       /* flush, ensure all register writes are done*/
+       wmb();
+
+       return 0;
+}
+
+static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll)
+{
+       struct device *dev = &pll->pdev->dev;
+       int rc;
+       u32 status = 0;
+       u32 const delay_us = 100;
+       u32 const timeout_us = 5000;
+
+       rc = readl_poll_timeout_atomic(pll->mmio +
+                                      REG_DSI_10nm_PHY_PLL_COMMON_STATUS_ONE,
+                                      status,
+                                      ((status & BIT(0)) > 0),
+                                      delay_us,
+                                      timeout_us);
+       if (rc)
+               DRM_DEV_ERROR(dev, "DSI PLL(%d) lock failed, status=0x%08x\n",
+                             pll->id, status);
+
+       return rc;
+}
+
+static void dsi_pll_disable_pll_bias(struct dsi_pll_10nm *pll)
+{
+       u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0);
+
+       pll_write(pll->mmio + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0);
+       pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0,
+                 data & ~BIT(5));
+       ndelay(250);
+}
+
+static void dsi_pll_enable_pll_bias(struct dsi_pll_10nm *pll)
+{
+       u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0);
+
+       pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0,
+                 data | BIT(5));
+       pll_write(pll->mmio + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0xc0);
+       ndelay(250);
+}
+
+static void dsi_pll_disable_global_clk(struct dsi_pll_10nm *pll)
+{
+       u32 data;
+
+       data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
+       pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1,
+                 data & ~BIT(5));
+}
+
+static void dsi_pll_enable_global_clk(struct dsi_pll_10nm *pll)
+{
+       u32 data;
+
+       data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
+       pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1,
+                 data | BIT(5));
+}
+
+static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
+       struct device *dev = &pll_10nm->pdev->dev;
+       int rc;
+
+       dsi_pll_enable_pll_bias(pll_10nm);
+       if (pll_10nm->slave)
+               dsi_pll_enable_pll_bias(pll_10nm->slave);
+
+       rc = dsi_pll_10nm_vco_set_rate(hw,pll_10nm->vco_current_rate, 0);
+       if (rc) {
+               DRM_DEV_ERROR(dev, "vco_set_rate failed, rc=%d\n", rc);
+               return rc;
+       }
+
+       /* Start PLL */
+       pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_PLL_CNTRL,
+                 0x01);
+
+       /*
+        * ensure all PLL configurations are written prior to checking
+        * for PLL lock.
+        */
+       wmb();
+
+       /* Check for PLL lock */
+       rc = dsi_pll_10nm_lock_status(pll_10nm);
+       if (rc) {
+               DRM_DEV_ERROR(dev, "PLL(%d) lock failed\n", pll_10nm->id);
+               goto error;
+       }
+
+       pll->pll_on = true;
+
+       dsi_pll_enable_global_clk(pll_10nm);
+       if (pll_10nm->slave)
+               dsi_pll_enable_global_clk(pll_10nm->slave);
+
+       pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_RBUF_CTRL,
+                 0x01);
+       if (pll_10nm->slave)
+               pll_write(pll_10nm->slave->phy_cmn_mmio +
+                         REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0x01);
+
+error:
+       return rc;
+}
+
+static void dsi_pll_disable_sub(struct dsi_pll_10nm *pll)
+{
+       pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0);
+       dsi_pll_disable_pll_bias(pll);
+}
+
+static void dsi_pll_10nm_vco_unprepare(struct clk_hw *hw)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
+
+       /*
+        * To avoid any stray glitches while abruptly powering down the PLL
+        * make sure to gate the clock using the clock enable bit before
+        * powering down the PLL
+        */
+       dsi_pll_disable_global_clk(pll_10nm);
+       pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0);
+       dsi_pll_disable_sub(pll_10nm);
+       if (pll_10nm->slave) {
+               dsi_pll_disable_global_clk(pll_10nm->slave);
+               dsi_pll_disable_sub(pll_10nm->slave);
+       }
+       /* flush, ensure all register writes are done */
+       wmb();
+       pll->pll_on = false;
+}
+
+static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw,
+                                                 unsigned long parent_rate)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
+       struct dsi_pll_config *config = &pll_10nm->pll_configuration;
+       void __iomem *base = pll_10nm->mmio;
+       u64 ref_clk = pll_10nm->vco_ref_clk_rate;
+       u64 vco_rate = 0x0;
+       u64 multiplier;
+       u32 frac;
+       u32 dec;
+       u64 pll_freq, tmp64;
+
+       dec = pll_read(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1);
+       dec &= 0xff;
+
+       frac = pll_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1);
+       frac |= ((pll_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1) &
+                 0xff) << 8);
+       frac |= ((pll_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1) &
+                 0x3) << 16);
+
+       /*
+        * TODO:
+        *      1. Assumes prescaler is disabled
+        */
+       multiplier = 1 << config->frac_bits;
+       pll_freq = dec * (ref_clk * 2);
+       tmp64 = (ref_clk * 2 * frac);
+       pll_freq += div_u64(tmp64, multiplier);
+
+       vco_rate = pll_freq;
+
+       DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x",
+           pll_10nm->id, (unsigned long)vco_rate, dec, frac);
+
+       return (unsigned long)vco_rate;
+}
+
+static const struct clk_ops clk_ops_dsi_pll_10nm_vco = {
+       .round_rate = msm_dsi_pll_helper_clk_round_rate,
+       .set_rate = dsi_pll_10nm_vco_set_rate,
+       .recalc_rate = dsi_pll_10nm_vco_recalc_rate,
+       .prepare = dsi_pll_10nm_vco_prepare,
+       .unprepare = dsi_pll_10nm_vco_unprepare,
+};
+
+/*
+ * PLL Callbacks
+ */
+
+static void dsi_pll_10nm_save_state(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
+       struct pll_10nm_cached_state *cached = &pll_10nm->cached_state;
+       void __iomem *phy_base = pll_10nm->phy_cmn_mmio;
+       u32 cmn_clk_cfg0, cmn_clk_cfg1;
+
+       cached->pll_out_div = pll_read(pll_10nm->mmio +
+                                      REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE);
+       cached->pll_out_div &= 0x3;
+
+       cmn_clk_cfg0 = pll_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0);
+       cached->bit_clk_div = cmn_clk_cfg0 & 0xf;
+       cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4;
+
+       cmn_clk_cfg1 = pll_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
+       cached->pll_mux = cmn_clk_cfg1 & 0x3;
+
+       DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x",
+           pll_10nm->id, cached->pll_out_div, cached->bit_clk_div,
+           cached->pix_clk_div, cached->pll_mux);
+}
+
+static int dsi_pll_10nm_restore_state(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
+       struct pll_10nm_cached_state *cached = &pll_10nm->cached_state;
+       void __iomem *phy_base = pll_10nm->phy_cmn_mmio;
+       u32 val;
+       int ret;
+
+       val = pll_read(pll_10nm->mmio + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE);
+       val &= ~0x3;
+       val |= cached->pll_out_div;
+       pll_write(pll_10nm->mmio + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, val);
+
+       pll_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0,
+                 cached->bit_clk_div | (cached->pix_clk_div << 4));
+
+       val = pll_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
+       val &= ~0x3;
+       val |= cached->pll_mux;
+       pll_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, val);
+
+       ret = dsi_pll_10nm_vco_set_rate(&pll->clk_hw, pll_10nm->vco_current_rate, pll_10nm->vco_ref_clk_rate);
+       if (ret) {
+               DRM_DEV_ERROR(&pll_10nm->pdev->dev,
+                       "restore vco rate failed. ret=%d\n", ret);
+               return ret;
+       }
+
+       DBG("DSI PLL%d", pll_10nm->id);
+
+       return 0;
+}
+
+static int dsi_pll_10nm_set_usecase(struct msm_dsi_pll *pll,
+                                   enum msm_dsi_phy_usecase uc)
+{
+       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
+       void __iomem *base = pll_10nm->phy_cmn_mmio;
+       u32 data = 0x0; /* internal PLL */
+
+       DBG("DSI PLL%d", pll_10nm->id);
+
+       switch (uc) {
+       case MSM_DSI_PHY_STANDALONE:
+               break;
+       case MSM_DSI_PHY_MASTER:
+               pll_10nm->slave = pll_10nm_list[(pll_10nm->id + 1) % DSI_MAX];
+               break;
+       case MSM_DSI_PHY_SLAVE:
+               data = 0x1; /* external PLL */
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* set PLL src */
+       pll_write(base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, (data << 2));
+
+       pll_10nm->uc = uc;
+
+       return 0;
+}
+
+static int dsi_pll_10nm_get_provider(struct msm_dsi_pll *pll,
+                                    struct clk **byte_clk_provider,
+                                    struct clk **pixel_clk_provider)
+{
+       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
+       struct clk_hw_onecell_data *hw_data = pll_10nm->hw_data;
+
+       DBG("DSI PLL%d", pll_10nm->id);
+
+       if (byte_clk_provider)
+               *byte_clk_provider = hw_data->hws[DSI_BYTE_PLL_CLK]->clk;
+       if (pixel_clk_provider)
+               *pixel_clk_provider = hw_data->hws[DSI_PIXEL_PLL_CLK]->clk;
+
+       return 0;
+}
+
+static void dsi_pll_10nm_destroy(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
+       struct device *dev = &pll_10nm->pdev->dev;
+
+       DBG("DSI PLL%d", pll_10nm->id);
+       of_clk_del_provider(dev->of_node);
+
+       clk_hw_unregister_divider(pll_10nm->out_dsiclk_hw);
+       clk_hw_unregister_mux(pll_10nm->pclk_mux_hw);
+       clk_hw_unregister_fixed_factor(pll_10nm->post_out_div_clk_hw);
+       clk_hw_unregister_fixed_factor(pll_10nm->by_2_bit_clk_hw);
+       clk_hw_unregister_fixed_factor(pll_10nm->byte_clk_hw);
+       clk_hw_unregister_divider(pll_10nm->bit_clk_hw);
+       clk_hw_unregister_divider(pll_10nm->out_div_clk_hw);
+       clk_hw_unregister(&pll_10nm->base.clk_hw);
+}
+
+/*
+ * The post dividers and mux clocks are created using the standard divider and
+ * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux
+ * state to follow the master PLL's divider/mux state. Therefore, we don't
+ * require special clock ops that also configure the slave PLL registers
+ */
+static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
+{
+       char clk_name[32], parent[32], vco_name[32];
+       char parent2[32], parent3[32], parent4[32];
+       struct clk_init_data vco_init = {
+               .parent_names = (const char *[]){ "xo" },
+               .num_parents = 1,
+               .name = vco_name,
+               .flags = CLK_IGNORE_UNUSED,
+               .ops = &clk_ops_dsi_pll_10nm_vco,
+       };
+       struct device *dev = &pll_10nm->pdev->dev;
+       struct clk_hw_onecell_data *hw_data;
+       struct clk_hw *hw;
+       int ret;
+
+       DBG("DSI%d", pll_10nm->id);
+
+       hw_data = devm_kzalloc(dev, sizeof(*hw_data) +
+                              NUM_PROVIDED_CLKS * sizeof(struct clk_hw *),
+                              GFP_KERNEL);
+       if (!hw_data)
+               return -ENOMEM;
+
+       snprintf(vco_name, 32, "dsi%dvco_clk", pll_10nm->id);
+       pll_10nm->base.clk_hw.init = &vco_init;
+
+       ret = clk_hw_register(dev, &pll_10nm->base.clk_hw);
+       if (ret)
+               return ret;
+
+       snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_10nm->id);
+       snprintf(parent, 32, "dsi%dvco_clk", pll_10nm->id);
+
+       hw = clk_hw_register_divider(dev, clk_name,
+                                    parent, CLK_SET_RATE_PARENT,
+                                    pll_10nm->mmio +
+                                    REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE,
+                                    0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_base_clk_hw;
+       }
+
+       pll_10nm->out_div_clk_hw = hw;
+
+       snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_10nm->id);
+       snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id);
+
+       /* BIT CLK: DIV_CTRL_3_0 */
+       hw = clk_hw_register_divider(dev, clk_name, parent,
+                                    CLK_SET_RATE_PARENT,
+                                    pll_10nm->phy_cmn_mmio +
+                                    REG_DSI_10nm_PHY_CMN_CLK_CFG0,
+                                    0, 4, CLK_DIVIDER_ONE_BASED,
+                                    &pll_10nm->postdiv_lock);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_out_div_clk_hw;
+       }
+
+       pll_10nm->bit_clk_hw = hw;
+
+       snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_10nm->id);
+       snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id);
+
+       /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */
+       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
+                                         CLK_SET_RATE_PARENT, 1, 8);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_bit_clk_hw;
+       }
+
+       pll_10nm->byte_clk_hw = hw;
+       hw_data->hws[DSI_BYTE_PLL_CLK] = hw;
+
+       snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->id);
+       snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id);
+
+       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
+                                         0, 1, 2);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_byte_clk_hw;
+       }
+
+       pll_10nm->by_2_bit_clk_hw = hw;
+
+       snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id);
+       snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id);
+
+       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
+                                         0, 1, 4);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_by_2_bit_clk_hw;
+       }
+
+       pll_10nm->post_out_div_clk_hw = hw;
+
+       snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_10nm->id);
+       snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id);
+       snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->id);
+       snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_10nm->id);
+       snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id);
+
+       hw = clk_hw_register_mux(dev, clk_name,
+                                ((const char *[]){
+                                parent, parent2, parent3, parent4
+                                }), 4, 0, pll_10nm->phy_cmn_mmio +
+                                REG_DSI_10nm_PHY_CMN_CLK_CFG1,
+                                0, 2, 0, NULL);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_post_out_div_clk_hw;
+       }
+
+       pll_10nm->pclk_mux_hw = hw;
+
+       snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_10nm->id);
+       snprintf(parent, 32, "dsi%d_pclk_mux", pll_10nm->id);
+
+       /* PIX CLK DIV : DIV_CTRL_7_4*/
+       hw = clk_hw_register_divider(dev, clk_name, parent,
+                                    0, pll_10nm->phy_cmn_mmio +
+                                       REG_DSI_10nm_PHY_CMN_CLK_CFG0,
+                                    4, 4, CLK_DIVIDER_ONE_BASED,
+                                    &pll_10nm->postdiv_lock);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_pclk_mux_hw;
+       }
+
+       pll_10nm->out_dsiclk_hw = hw;
+       hw_data->hws[DSI_PIXEL_PLL_CLK] = hw;
+
+       hw_data->num = NUM_PROVIDED_CLKS;
+       pll_10nm->hw_data = hw_data;
+
+       ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
+                                    pll_10nm->hw_data);
+       if (ret) {
+               DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
+               goto err_dsiclk_hw;
+       }
+
+       return 0;
+
+err_dsiclk_hw:
+       clk_hw_unregister_divider(pll_10nm->out_dsiclk_hw);
+err_pclk_mux_hw:
+       clk_hw_unregister_mux(pll_10nm->pclk_mux_hw);
+err_post_out_div_clk_hw:
+       clk_hw_unregister_fixed_factor(pll_10nm->post_out_div_clk_hw);
+err_by_2_bit_clk_hw:
+       clk_hw_unregister_fixed_factor(pll_10nm->by_2_bit_clk_hw);
+err_byte_clk_hw:
+       clk_hw_unregister_fixed_factor(pll_10nm->byte_clk_hw);
+err_bit_clk_hw:
+       clk_hw_unregister_divider(pll_10nm->bit_clk_hw);
+err_out_div_clk_hw:
+       clk_hw_unregister_divider(pll_10nm->out_div_clk_hw);
+err_base_clk_hw:
+       clk_hw_unregister(&pll_10nm->base.clk_hw);
+
+       return ret;
+}
+
+struct msm_dsi_pll *msm_dsi_pll_10nm_init(struct platform_device *pdev, int id)
+{
+       struct dsi_pll_10nm *pll_10nm;
+       struct msm_dsi_pll *pll;
+       int ret;
+
+       pll_10nm = devm_kzalloc(&pdev->dev, sizeof(*pll_10nm), GFP_KERNEL);
+       if (!pll_10nm)
+               return ERR_PTR(-ENOMEM);
+
+       DBG("DSI PLL%d", id);
+
+       pll_10nm->pdev = pdev;
+       pll_10nm->id = id;
+       pll_10nm_list[id] = pll_10nm;
+
+       pll_10nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY");
+       if (IS_ERR_OR_NULL(pll_10nm->phy_cmn_mmio)) {
+               DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       pll_10nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL");
+       if (IS_ERR_OR_NULL(pll_10nm->mmio)) {
+               DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       spin_lock_init(&pll_10nm->postdiv_lock);
+
+       pll = &pll_10nm->base;
+       pll->min_rate = 1000000000UL;
+       pll->max_rate = 3500000000UL;
+       pll->get_provider = dsi_pll_10nm_get_provider;
+       pll->destroy = dsi_pll_10nm_destroy;
+       pll->save_state = dsi_pll_10nm_save_state;
+       pll->restore_state = dsi_pll_10nm_restore_state;
+       pll->set_usecase = dsi_pll_10nm_set_usecase;
+
+       pll_10nm->vco_delay = 1;
+
+       ret = pll_10nm_register(pll_10nm);
+       if (ret) {
+               DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
+               return ERR_PTR(ret);
+       }
+
+       /* TODO: Remove this when we have proper display handover support */
+       msm_dsi_pll_save_state(pll);
+
+       return pll;
+}
+
 static int dsi_phy_hw_v3_0_is_pll_on(struct msm_dsi_phy *phy)
 {
        void __iomem *base = phy->base;
index 6989730..6a63901 100644 (file)
  * Copyright (c) 2016, The Linux Foundation. All rights reserved.
  */
 
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/delay.h>
 
 #include "dsi_phy.h"
+#include "dsi_pll.h"
 #include "dsi.xml.h"
 
 #define PHY_14NM_CKLN_IDX      4
 
+/*
+ * DSI PLL 14nm - clock diagram (eg: DSI0):
+ *
+ *         dsi0n1_postdiv_clk
+ *                         |
+ *                         |
+ *                 +----+  |  +----+
+ *  dsi0vco_clk ---| n1 |--o--| /8 |-- dsi0pllbyte
+ *                 +----+  |  +----+
+ *                         |           dsi0n1_postdivby2_clk
+ *                         |   +----+  |
+ *                         o---| /2 |--o--|\
+ *                         |   +----+     | \   +----+
+ *                         |              |  |--| n2 |-- dsi0pll
+ *                         o--------------| /   +----+
+ *                                        |/
+ */
+
+#define POLL_MAX_READS                 15
+#define POLL_TIMEOUT_US                        1000
+
+#define NUM_PROVIDED_CLKS              2
+
+#define VCO_REF_CLK_RATE               19200000
+#define VCO_MIN_RATE                   1300000000UL
+#define VCO_MAX_RATE                   2600000000UL
+
+#define DSI_BYTE_PLL_CLK               0
+#define DSI_PIXEL_PLL_CLK              1
+
+#define DSI_PLL_DEFAULT_VCO_POSTDIV    1
+
+struct dsi_pll_input {
+       u32 fref;       /* reference clk */
+       u32 fdata;      /* bit clock rate */
+       u32 dsiclk_sel; /* Mux configuration (see diagram) */
+       u32 ssc_en;     /* SSC enable/disable */
+       u32 ldo_en;
+
+       /* fixed params */
+       u32 refclk_dbler_en;
+       u32 vco_measure_time;
+       u32 kvco_measure_time;
+       u32 bandgap_timer;
+       u32 pll_wakeup_timer;
+       u32 plllock_cnt;
+       u32 plllock_rng;
+       u32 ssc_center;
+       u32 ssc_adj_period;
+       u32 ssc_spread;
+       u32 ssc_freq;
+       u32 pll_ie_trim;
+       u32 pll_ip_trim;
+       u32 pll_iptat_trim;
+       u32 pll_cpcset_cur;
+       u32 pll_cpmset_cur;
+
+       u32 pll_icpmset;
+       u32 pll_icpcset;
+
+       u32 pll_icpmset_p;
+       u32 pll_icpmset_m;
+
+       u32 pll_icpcset_p;
+       u32 pll_icpcset_m;
+
+       u32 pll_lpf_res1;
+       u32 pll_lpf_cap1;
+       u32 pll_lpf_cap2;
+       u32 pll_c3ctrl;
+       u32 pll_r3ctrl;
+};
+
+struct dsi_pll_output {
+       u32 pll_txclk_en;
+       u32 dec_start;
+       u32 div_frac_start;
+       u32 ssc_period;
+       u32 ssc_step_size;
+       u32 plllock_cmp;
+       u32 pll_vco_div_ref;
+       u32 pll_vco_count;
+       u32 pll_kvco_div_ref;
+       u32 pll_kvco_count;
+       u32 pll_misc1;
+       u32 pll_lpf2_postdiv;
+       u32 pll_resetsm_cntrl;
+       u32 pll_resetsm_cntrl2;
+       u32 pll_resetsm_cntrl5;
+       u32 pll_kvco_code;
+
+       u32 cmn_clk_cfg0;
+       u32 cmn_clk_cfg1;
+       u32 cmn_ldo_cntrl;
+
+       u32 pll_postdiv;
+       u32 fcvo;
+};
+
+struct pll_14nm_cached_state {
+       unsigned long vco_rate;
+       u8 n2postdiv;
+       u8 n1postdiv;
+};
+
+struct dsi_pll_14nm {
+       struct msm_dsi_pll base;
+
+       int id;
+       struct platform_device *pdev;
+
+       void __iomem *phy_cmn_mmio;
+       void __iomem *mmio;
+
+       int vco_delay;
+
+       struct dsi_pll_input in;
+       struct dsi_pll_output out;
+
+       /* protects REG_DSI_14nm_PHY_CMN_CLK_CFG0 register */
+       spinlock_t postdiv_lock;
+
+       u64 vco_current_rate;
+       u64 vco_ref_clk_rate;
+
+       /* private clocks: */
+       struct clk_hw *hws[NUM_DSI_CLOCKS_MAX];
+       u32 num_hws;
+
+       /* clock-provider: */
+       struct clk_hw_onecell_data *hw_data;
+
+       struct pll_14nm_cached_state cached_state;
+
+       enum msm_dsi_phy_usecase uc;
+       struct dsi_pll_14nm *slave;
+};
+
+#define to_pll_14nm(x) container_of(x, struct dsi_pll_14nm, base)
+
+/*
+ * Private struct for N1/N2 post-divider clocks. These clocks are similar to
+ * the generic clk_divider class of clocks. The only difference is that it
+ * also sets the slave DSI PLL's post-dividers if in Dual DSI mode
+ */
+struct dsi_pll_14nm_postdiv {
+       struct clk_hw hw;
+
+       /* divider params */
+       u8 shift;
+       u8 width;
+       u8 flags; /* same flags as used by clk_divider struct */
+
+       struct dsi_pll_14nm *pll;
+};
+
+#define to_pll_14nm_postdiv(_hw) container_of(_hw, struct dsi_pll_14nm_postdiv, hw)
+
+/*
+ * Global list of private DSI PLL struct pointers. We need this for Dual DSI
+ * mode, where the master PLL's clk_ops needs access the slave's private data
+ */
+static struct dsi_pll_14nm *pll_14nm_list[DSI_MAX];
+
+static bool pll_14nm_poll_for_ready(struct dsi_pll_14nm *pll_14nm,
+                                   u32 nb_tries, u32 timeout_us)
+{
+       bool pll_locked = false;
+       void __iomem *base = pll_14nm->mmio;
+       u32 tries, val;
+
+       tries = nb_tries;
+       while (tries--) {
+               val = pll_read(base +
+                              REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
+               pll_locked = !!(val & BIT(5));
+
+               if (pll_locked)
+                       break;
+
+               udelay(timeout_us);
+       }
+
+       if (!pll_locked) {
+               tries = nb_tries;
+               while (tries--) {
+                       val = pll_read(base +
+                               REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
+                       pll_locked = !!(val & BIT(0));
+
+                       if (pll_locked)
+                               break;
+
+                       udelay(timeout_us);
+               }
+       }
+
+       DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* ");
+
+       return pll_locked;
+}
+
+static void dsi_pll_14nm_input_init(struct dsi_pll_14nm *pll)
+{
+       pll->in.fref = pll->vco_ref_clk_rate;
+       pll->in.fdata = 0;
+       pll->in.dsiclk_sel = 1; /* Use the /2 path in Mux */
+       pll->in.ldo_en = 0;     /* disabled for now */
+
+       /* fixed input */
+       pll->in.refclk_dbler_en = 0;
+       pll->in.vco_measure_time = 5;
+       pll->in.kvco_measure_time = 5;
+       pll->in.bandgap_timer = 4;
+       pll->in.pll_wakeup_timer = 5;
+       pll->in.plllock_cnt = 1;
+       pll->in.plllock_rng = 0;
+
+       /*
+        * SSC is enabled by default. We might need DT props for configuring
+        * some SSC params like PPM and center/down spread etc.
+        */
+       pll->in.ssc_en = 1;
+       pll->in.ssc_center = 0;         /* down spread by default */
+       pll->in.ssc_spread = 5;         /* PPM / 1000 */
+       pll->in.ssc_freq = 31500;       /* default recommended */
+       pll->in.ssc_adj_period = 37;
+
+       pll->in.pll_ie_trim = 4;
+       pll->in.pll_ip_trim = 4;
+       pll->in.pll_cpcset_cur = 1;
+       pll->in.pll_cpmset_cur = 1;
+       pll->in.pll_icpmset = 4;
+       pll->in.pll_icpcset = 4;
+       pll->in.pll_icpmset_p = 0;
+       pll->in.pll_icpmset_m = 0;
+       pll->in.pll_icpcset_p = 0;
+       pll->in.pll_icpcset_m = 0;
+       pll->in.pll_lpf_res1 = 3;
+       pll->in.pll_lpf_cap1 = 11;
+       pll->in.pll_lpf_cap2 = 1;
+       pll->in.pll_iptat_trim = 7;
+       pll->in.pll_c3ctrl = 2;
+       pll->in.pll_r3ctrl = 1;
+}
+
+#define CEIL(x, y)             (((x) + ((y) - 1)) / (y))
+
+static void pll_14nm_ssc_calc(struct dsi_pll_14nm *pll)
+{
+       u32 period, ssc_period;
+       u32 ref, rem;
+       u64 step_size;
+
+       DBG("vco=%lld ref=%lld", pll->vco_current_rate, pll->vco_ref_clk_rate);
+
+       ssc_period = pll->in.ssc_freq / 500;
+       period = (u32)pll->vco_ref_clk_rate / 1000;
+       ssc_period  = CEIL(period, ssc_period);
+       ssc_period -= 1;
+       pll->out.ssc_period = ssc_period;
+
+       DBG("ssc freq=%d spread=%d period=%d", pll->in.ssc_freq,
+           pll->in.ssc_spread, pll->out.ssc_period);
+
+       step_size = (u32)pll->vco_current_rate;
+       ref = pll->vco_ref_clk_rate;
+       ref /= 1000;
+       step_size = div_u64(step_size, ref);
+       step_size <<= 20;
+       step_size = div_u64(step_size, 1000);
+       step_size *= pll->in.ssc_spread;
+       step_size = div_u64(step_size, 1000);
+       step_size *= (pll->in.ssc_adj_period + 1);
+
+       rem = 0;
+       step_size = div_u64_rem(step_size, ssc_period + 1, &rem);
+       if (rem)
+               step_size++;
+
+       DBG("step_size=%lld", step_size);
+
+       step_size &= 0x0ffff;   /* take lower 16 bits */
+
+       pll->out.ssc_step_size = step_size;
+}
+
+static void pll_14nm_dec_frac_calc(struct dsi_pll_14nm *pll)
+{
+       struct dsi_pll_input *pin = &pll->in;
+       struct dsi_pll_output *pout = &pll->out;
+       u64 multiplier = BIT(20);
+       u64 dec_start_multiple, dec_start, pll_comp_val;
+       u32 duration, div_frac_start;
+       u64 vco_clk_rate = pll->vco_current_rate;
+       u64 fref = pll->vco_ref_clk_rate;
+
+       DBG("vco_clk_rate=%lld ref_clk_rate=%lld", vco_clk_rate, fref);
+
+       dec_start_multiple = div_u64(vco_clk_rate * multiplier, fref);
+       div_u64_rem(dec_start_multiple, multiplier, &div_frac_start);
+
+       dec_start = div_u64(dec_start_multiple, multiplier);
+
+       pout->dec_start = (u32)dec_start;
+       pout->div_frac_start = div_frac_start;
+
+       if (pin->plllock_cnt == 0)
+               duration = 1024;
+       else if (pin->plllock_cnt == 1)
+               duration = 256;
+       else if (pin->plllock_cnt == 2)
+               duration = 128;
+       else
+               duration = 32;
+
+       pll_comp_val = duration * dec_start_multiple;
+       pll_comp_val = div_u64(pll_comp_val, multiplier);
+       do_div(pll_comp_val, 10);
+
+       pout->plllock_cmp = (u32)pll_comp_val;
+
+       pout->pll_txclk_en = 1;
+       pout->cmn_ldo_cntrl = 0x3c;
+}
+
+static u32 pll_14nm_kvco_slop(u32 vrate)
+{
+       u32 slop = 0;
+
+       if (vrate > VCO_MIN_RATE && vrate <= 1800000000UL)
+               slop =  600;
+       else if (vrate > 1800000000UL && vrate < 2300000000UL)
+               slop = 400;
+       else if (vrate > 2300000000UL && vrate < VCO_MAX_RATE)
+               slop = 280;
+
+       return slop;
+}
+
+static void pll_14nm_calc_vco_count(struct dsi_pll_14nm *pll)
+{
+       struct dsi_pll_input *pin = &pll->in;
+       struct dsi_pll_output *pout = &pll->out;
+       u64 vco_clk_rate = pll->vco_current_rate;
+       u64 fref = pll->vco_ref_clk_rate;
+       u64 data;
+       u32 cnt;
+
+       data = fref * pin->vco_measure_time;
+       do_div(data, 1000000);
+       data &= 0x03ff; /* 10 bits */
+       data -= 2;
+       pout->pll_vco_div_ref = data;
+
+       data = div_u64(vco_clk_rate, 1000000);  /* unit is Mhz */
+       data *= pin->vco_measure_time;
+       do_div(data, 10);
+       pout->pll_vco_count = data;
+
+       data = fref * pin->kvco_measure_time;
+       do_div(data, 1000000);
+       data &= 0x03ff; /* 10 bits */
+       data -= 1;
+       pout->pll_kvco_div_ref = data;
+
+       cnt = pll_14nm_kvco_slop(vco_clk_rate);
+       cnt *= 2;
+       cnt /= 100;
+       cnt *= pin->kvco_measure_time;
+       pout->pll_kvco_count = cnt;
+
+       pout->pll_misc1 = 16;
+       pout->pll_resetsm_cntrl = 48;
+       pout->pll_resetsm_cntrl2 = pin->bandgap_timer << 3;
+       pout->pll_resetsm_cntrl5 = pin->pll_wakeup_timer;
+       pout->pll_kvco_code = 0;
+}
+
+static void pll_db_commit_ssc(struct dsi_pll_14nm *pll)
+{
+       void __iomem *base = pll->mmio;
+       struct dsi_pll_input *pin = &pll->in;
+       struct dsi_pll_output *pout = &pll->out;
+       u8 data;
+
+       data = pin->ssc_adj_period;
+       data &= 0x0ff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER1, data);
+       data = (pin->ssc_adj_period >> 8);
+       data &= 0x03;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER2, data);
+
+       data = pout->ssc_period;
+       data &= 0x0ff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER1, data);
+       data = (pout->ssc_period >> 8);
+       data &= 0x0ff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER2, data);
+
+       data = pout->ssc_step_size;
+       data &= 0x0ff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE1, data);
+       data = (pout->ssc_step_size >> 8);
+       data &= 0x0ff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE2, data);
+
+       data = (pin->ssc_center & 0x01);
+       data <<= 1;
+       data |= 0x01; /* enable */
+       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_EN_CENTER, data);
+
+       wmb();  /* make sure register committed */
+}
+
+static void pll_db_commit_common(struct dsi_pll_14nm *pll,
+                                struct dsi_pll_input *pin,
+                                struct dsi_pll_output *pout)
+{
+       void __iomem *base = pll->mmio;
+       u8 data;
+
+       /* confgiure the non frequency dependent pll registers */
+       data = 0;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_SYSCLK_EN_RESET, data);
+
+       data = pout->pll_txclk_en;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_TXCLK_EN, data);
+
+       data = pout->pll_resetsm_cntrl;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL, data);
+       data = pout->pll_resetsm_cntrl2;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL2, data);
+       data = pout->pll_resetsm_cntrl5;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL5, data);
+
+       data = pout->pll_vco_div_ref & 0xff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF1, data);
+       data = (pout->pll_vco_div_ref >> 8) & 0x3;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF2, data);
+
+       data = pout->pll_kvco_div_ref & 0xff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF1, data);
+       data = (pout->pll_kvco_div_ref >> 8) & 0x3;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF2, data);
+
+       data = pout->pll_misc1;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_MISC1, data);
+
+       data = pin->pll_ie_trim;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_IE_TRIM, data);
+
+       data = pin->pll_ip_trim;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_IP_TRIM, data);
+
+       data = pin->pll_cpmset_cur << 3 | pin->pll_cpcset_cur;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_CP_SET_CUR, data);
+
+       data = pin->pll_icpcset_p << 3 | pin->pll_icpcset_m;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPCSET, data);
+
+       data = pin->pll_icpmset_p << 3 | pin->pll_icpcset_m;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPMSET, data);
+
+       data = pin->pll_icpmset << 3 | pin->pll_icpcset;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICP_SET, data);
+
+       data = pin->pll_lpf_cap2 << 4 | pin->pll_lpf_cap1;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF1, data);
+
+       data = pin->pll_iptat_trim;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_IPTAT_TRIM, data);
+
+       data = pin->pll_c3ctrl | pin->pll_r3ctrl << 4;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_CRCTRL, data);
+}
+
+static void pll_14nm_software_reset(struct dsi_pll_14nm *pll_14nm)
+{
+       void __iomem *cmn_base = pll_14nm->phy_cmn_mmio;
+
+       /* de assert pll start and apply pll sw reset */
+
+       /* stop pll */
+       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0);
+
+       /* pll sw reset */
+       pll_write_udelay(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x20, 10);
+       wmb();  /* make sure register committed */
+
+       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0);
+       wmb();  /* make sure register committed */
+}
+
+static void pll_db_commit_14nm(struct dsi_pll_14nm *pll,
+                              struct dsi_pll_input *pin,
+                              struct dsi_pll_output *pout)
+{
+       void __iomem *base = pll->mmio;
+       void __iomem *cmn_base = pll->phy_cmn_mmio;
+       u8 data;
+
+       DBG("DSI%d PLL", pll->id);
+
+       data = pout->cmn_ldo_cntrl;
+       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_LDO_CNTRL, data);
+
+       pll_db_commit_common(pll, pin, pout);
+
+       pll_14nm_software_reset(pll);
+
+       data = pin->dsiclk_sel; /* set dsiclk_sel = 1  */
+       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG1, data);
+
+       data = 0xff; /* data, clk, pll normal operation */
+       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_0, data);
+
+       /* configure the frequency dependent pll registers */
+       data = pout->dec_start;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_DEC_START, data);
+
+       data = pout->div_frac_start & 0xff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1, data);
+       data = (pout->div_frac_start >> 8) & 0xff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2, data);
+       data = (pout->div_frac_start >> 16) & 0xf;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3, data);
+
+       data = pout->plllock_cmp & 0xff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP1, data);
+
+       data = (pout->plllock_cmp >> 8) & 0xff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP2, data);
+
+       data = (pout->plllock_cmp >> 16) & 0x3;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP3, data);
+
+       data = pin->plllock_cnt << 1 | pin->plllock_rng << 3;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP_EN, data);
+
+       data = pout->pll_vco_count & 0xff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT1, data);
+       data = (pout->pll_vco_count >> 8) & 0xff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT2, data);
+
+       data = pout->pll_kvco_count & 0xff;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT1, data);
+       data = (pout->pll_kvco_count >> 8) & 0x3;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT2, data);
+
+       data = (pout->pll_postdiv - 1) << 4 | pin->pll_lpf_res1;
+       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF2_POSTDIV, data);
+
+       if (pin->ssc_en)
+               pll_db_commit_ssc(pll);
+
+       wmb();  /* make sure register committed */
+}
+
+/*
+ * VCO clock Callbacks
+ */
+static int dsi_pll_14nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
+                                    unsigned long parent_rate)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
+       struct dsi_pll_input *pin = &pll_14nm->in;
+       struct dsi_pll_output *pout = &pll_14nm->out;
+
+       DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_14nm->id, rate,
+           parent_rate);
+
+       pll_14nm->vco_current_rate = rate;
+       pll_14nm->vco_ref_clk_rate = VCO_REF_CLK_RATE;
+
+       dsi_pll_14nm_input_init(pll_14nm);
+
+       /*
+        * This configures the post divider internal to the VCO. It's
+        * fixed to divide by 1 for now.
+        *
+        * tx_band = pll_postdiv.
+        * 0: divided by 1
+        * 1: divided by 2
+        * 2: divided by 4
+        * 3: divided by 8
+        */
+       pout->pll_postdiv = DSI_PLL_DEFAULT_VCO_POSTDIV;
+
+       pll_14nm_dec_frac_calc(pll_14nm);
+
+       if (pin->ssc_en)
+               pll_14nm_ssc_calc(pll_14nm);
+
+       pll_14nm_calc_vco_count(pll_14nm);
+
+       /* commit the slave DSI PLL registers if we're master. Note that we
+        * don't lock the slave PLL. We just ensure that the PLL/PHY registers
+        * of the master and slave are identical
+        */
+       if (pll_14nm->uc == MSM_DSI_PHY_MASTER) {
+               struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave;
+
+               pll_db_commit_14nm(pll_14nm_slave, pin, pout);
+       }
+
+       pll_db_commit_14nm(pll_14nm, pin, pout);
+
+       return 0;
+}
+
+static unsigned long dsi_pll_14nm_vco_recalc_rate(struct clk_hw *hw,
+                                                 unsigned long parent_rate)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
+       void __iomem *base = pll_14nm->mmio;
+       u64 vco_rate, multiplier = BIT(20);
+       u32 div_frac_start;
+       u32 dec_start;
+       u64 ref_clk = parent_rate;
+
+       dec_start = pll_read(base + REG_DSI_14nm_PHY_PLL_DEC_START);
+       dec_start &= 0x0ff;
+
+       DBG("dec_start = %x", dec_start);
+
+       div_frac_start = (pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3)
+                               & 0xf) << 16;
+       div_frac_start |= (pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2)
+                               & 0xff) << 8;
+       div_frac_start |= pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1)
+                               & 0xff;
+
+       DBG("div_frac_start = %x", div_frac_start);
+
+       vco_rate = ref_clk * dec_start;
+
+       vco_rate += ((ref_clk * div_frac_start) / multiplier);
+
+       /*
+        * Recalculating the rate from dec_start and frac_start doesn't end up
+        * the rate we originally set. Convert the freq to KHz, round it up and
+        * convert it back to MHz.
+        */
+       vco_rate = DIV_ROUND_UP_ULL(vco_rate, 1000) * 1000;
+
+       DBG("returning vco rate = %lu", (unsigned long)vco_rate);
+
+       return (unsigned long)vco_rate;
+}
+
+static const struct clk_ops clk_ops_dsi_pll_14nm_vco = {
+       .round_rate = msm_dsi_pll_helper_clk_round_rate,
+       .set_rate = dsi_pll_14nm_vco_set_rate,
+       .recalc_rate = dsi_pll_14nm_vco_recalc_rate,
+       .prepare = msm_dsi_pll_helper_clk_prepare,
+       .unprepare = msm_dsi_pll_helper_clk_unprepare,
+};
+
+/*
+ * N1 and N2 post-divider clock callbacks
+ */
+#define div_mask(width)        ((1 << (width)) - 1)
+static unsigned long dsi_pll_14nm_postdiv_recalc_rate(struct clk_hw *hw,
+                                                     unsigned long parent_rate)
+{
+       struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw);
+       struct dsi_pll_14nm *pll_14nm = postdiv->pll;
+       void __iomem *base = pll_14nm->phy_cmn_mmio;
+       u8 shift = postdiv->shift;
+       u8 width = postdiv->width;
+       u32 val;
+
+       DBG("DSI%d PLL parent rate=%lu", pll_14nm->id, parent_rate);
+
+       val = pll_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0) >> shift;
+       val &= div_mask(width);
+
+       return divider_recalc_rate(hw, parent_rate, val, NULL,
+                                  postdiv->flags, width);
+}
+
+static long dsi_pll_14nm_postdiv_round_rate(struct clk_hw *hw,
+                                           unsigned long rate,
+                                           unsigned long *prate)
+{
+       struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw);
+       struct dsi_pll_14nm *pll_14nm = postdiv->pll;
+
+       DBG("DSI%d PLL parent rate=%lu", pll_14nm->id, rate);
+
+       return divider_round_rate(hw, rate, prate, NULL,
+                                 postdiv->width,
+                                 postdiv->flags);
+}
+
+static int dsi_pll_14nm_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
+                                        unsigned long parent_rate)
+{
+       struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw);
+       struct dsi_pll_14nm *pll_14nm = postdiv->pll;
+       void __iomem *base = pll_14nm->phy_cmn_mmio;
+       spinlock_t *lock = &pll_14nm->postdiv_lock;
+       u8 shift = postdiv->shift;
+       u8 width = postdiv->width;
+       unsigned int value;
+       unsigned long flags = 0;
+       u32 val;
+
+       DBG("DSI%d PLL parent rate=%lu parent rate %lu", pll_14nm->id, rate,
+           parent_rate);
+
+       value = divider_get_val(rate, parent_rate, NULL, postdiv->width,
+                               postdiv->flags);
+
+       spin_lock_irqsave(lock, flags);
+
+       val = pll_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0);
+       val &= ~(div_mask(width) << shift);
+
+       val |= value << shift;
+       pll_write(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val);
+
+       /* If we're master in dual DSI mode, then the slave PLL's post-dividers
+        * follow the master's post dividers
+        */
+       if (pll_14nm->uc == MSM_DSI_PHY_MASTER) {
+               struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave;
+               void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio;
+
+               pll_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val);
+       }
+
+       spin_unlock_irqrestore(lock, flags);
+
+       return 0;
+}
+
+static const struct clk_ops clk_ops_dsi_pll_14nm_postdiv = {
+       .recalc_rate = dsi_pll_14nm_postdiv_recalc_rate,
+       .round_rate = dsi_pll_14nm_postdiv_round_rate,
+       .set_rate = dsi_pll_14nm_postdiv_set_rate,
+};
+
+/*
+ * PLL Callbacks
+ */
+
+static int dsi_pll_14nm_enable_seq(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
+       void __iomem *base = pll_14nm->mmio;
+       void __iomem *cmn_base = pll_14nm->phy_cmn_mmio;
+       bool locked;
+
+       DBG("");
+
+       pll_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10);
+       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1);
+
+       locked = pll_14nm_poll_for_ready(pll_14nm, POLL_MAX_READS,
+                                        POLL_TIMEOUT_US);
+
+       if (unlikely(!locked))
+               DRM_DEV_ERROR(&pll_14nm->pdev->dev, "DSI PLL lock failed\n");
+       else
+               DBG("DSI PLL lock success");
+
+       return locked ? 0 : -EINVAL;
+}
+
+static void dsi_pll_14nm_disable_seq(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
+       void __iomem *cmn_base = pll_14nm->phy_cmn_mmio;
+
+       DBG("");
+
+       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0);
+}
+
+static void dsi_pll_14nm_save_state(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
+       struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state;
+       void __iomem *cmn_base = pll_14nm->phy_cmn_mmio;
+       u32 data;
+
+       data = pll_read(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0);
+
+       cached_state->n1postdiv = data & 0xf;
+       cached_state->n2postdiv = (data >> 4) & 0xf;
+
+       DBG("DSI%d PLL save state %x %x", pll_14nm->id,
+           cached_state->n1postdiv, cached_state->n2postdiv);
+
+       cached_state->vco_rate = clk_hw_get_rate(&pll->clk_hw);
+}
+
+static int dsi_pll_14nm_restore_state(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
+       struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state;
+       void __iomem *cmn_base = pll_14nm->phy_cmn_mmio;
+       u32 data;
+       int ret;
+
+       ret = dsi_pll_14nm_vco_set_rate(&pll->clk_hw,
+                                       cached_state->vco_rate, 0);
+       if (ret) {
+               DRM_DEV_ERROR(&pll_14nm->pdev->dev,
+                       "restore vco rate failed. ret=%d\n", ret);
+               return ret;
+       }
+
+       data = cached_state->n1postdiv | (cached_state->n2postdiv << 4);
+
+       DBG("DSI%d PLL restore state %x %x", pll_14nm->id,
+           cached_state->n1postdiv, cached_state->n2postdiv);
+
+       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data);
+
+       /* also restore post-dividers for slave DSI PLL */
+       if (pll_14nm->uc == MSM_DSI_PHY_MASTER) {
+               struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave;
+               void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio;
+
+               pll_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data);
+       }
+
+       return 0;
+}
+
+static int dsi_pll_14nm_set_usecase(struct msm_dsi_pll *pll,
+                                   enum msm_dsi_phy_usecase uc)
+{
+       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
+       void __iomem *base = pll_14nm->mmio;
+       u32 clkbuflr_en, bandgap = 0;
+
+       switch (uc) {
+       case MSM_DSI_PHY_STANDALONE:
+               clkbuflr_en = 0x1;
+               break;
+       case MSM_DSI_PHY_MASTER:
+               clkbuflr_en = 0x3;
+               pll_14nm->slave = pll_14nm_list[(pll_14nm->id + 1) % DSI_MAX];
+               break;
+       case MSM_DSI_PHY_SLAVE:
+               clkbuflr_en = 0x0;
+               bandgap = 0x3;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       pll_write(base + REG_DSI_14nm_PHY_PLL_CLKBUFLR_EN, clkbuflr_en);
+       if (bandgap)
+               pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_BANDGAP, bandgap);
+
+       pll_14nm->uc = uc;
+
+       return 0;
+}
+
+static int dsi_pll_14nm_get_provider(struct msm_dsi_pll *pll,
+                                    struct clk **byte_clk_provider,
+                                    struct clk **pixel_clk_provider)
+{
+       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
+       struct clk_hw_onecell_data *hw_data = pll_14nm->hw_data;
+
+       if (byte_clk_provider)
+               *byte_clk_provider = hw_data->hws[DSI_BYTE_PLL_CLK]->clk;
+       if (pixel_clk_provider)
+               *pixel_clk_provider = hw_data->hws[DSI_PIXEL_PLL_CLK]->clk;
+
+       return 0;
+}
+
+static void dsi_pll_14nm_destroy(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
+       struct platform_device *pdev = pll_14nm->pdev;
+       int num_hws = pll_14nm->num_hws;
+
+       of_clk_del_provider(pdev->dev.of_node);
+
+       while (num_hws--)
+               clk_hw_unregister(pll_14nm->hws[num_hws]);
+}
+
+static struct clk_hw *pll_14nm_postdiv_register(struct dsi_pll_14nm *pll_14nm,
+                                               const char *name,
+                                               const char *parent_name,
+                                               unsigned long flags,
+                                               u8 shift)
+{
+       struct dsi_pll_14nm_postdiv *pll_postdiv;
+       struct device *dev = &pll_14nm->pdev->dev;
+       struct clk_init_data postdiv_init = {
+               .parent_names = (const char *[]) { parent_name },
+               .num_parents = 1,
+               .name = name,
+               .flags = flags,
+               .ops = &clk_ops_dsi_pll_14nm_postdiv,
+       };
+       int ret;
+
+       pll_postdiv = devm_kzalloc(dev, sizeof(*pll_postdiv), GFP_KERNEL);
+       if (!pll_postdiv)
+               return ERR_PTR(-ENOMEM);
+
+       pll_postdiv->pll = pll_14nm;
+       pll_postdiv->shift = shift;
+       /* both N1 and N2 postdividers are 4 bits wide */
+       pll_postdiv->width = 4;
+       /* range of each divider is from 1 to 15 */
+       pll_postdiv->flags = CLK_DIVIDER_ONE_BASED;
+       pll_postdiv->hw.init = &postdiv_init;
+
+       ret = clk_hw_register(dev, &pll_postdiv->hw);
+       if (ret)
+               return ERR_PTR(ret);
+
+       return &pll_postdiv->hw;
+}
+
+static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm)
+{
+       char clk_name[32], parent[32], vco_name[32];
+       struct clk_init_data vco_init = {
+               .parent_names = (const char *[]){ "xo" },
+               .num_parents = 1,
+               .name = vco_name,
+               .flags = CLK_IGNORE_UNUSED,
+               .ops = &clk_ops_dsi_pll_14nm_vco,
+       };
+       struct device *dev = &pll_14nm->pdev->dev;
+       struct clk_hw **hws = pll_14nm->hws;
+       struct clk_hw_onecell_data *hw_data;
+       struct clk_hw *hw;
+       int num = 0;
+       int ret;
+
+       DBG("DSI%d", pll_14nm->id);
+
+       hw_data = devm_kzalloc(dev, sizeof(*hw_data) +
+                              NUM_PROVIDED_CLKS * sizeof(struct clk_hw *),
+                              GFP_KERNEL);
+       if (!hw_data)
+               return -ENOMEM;
+
+       snprintf(vco_name, 32, "dsi%dvco_clk", pll_14nm->id);
+       pll_14nm->base.clk_hw.init = &vco_init;
+
+       ret = clk_hw_register(dev, &pll_14nm->base.clk_hw);
+       if (ret)
+               return ret;
+
+       hws[num++] = &pll_14nm->base.clk_hw;
+
+       snprintf(clk_name, 32, "dsi%dn1_postdiv_clk", pll_14nm->id);
+       snprintf(parent, 32, "dsi%dvco_clk", pll_14nm->id);
+
+       /* N1 postdiv, bits 0-3 in REG_DSI_14nm_PHY_CMN_CLK_CFG0 */
+       hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent,
+                                      CLK_SET_RATE_PARENT, 0);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+
+       hws[num++] = hw;
+
+       snprintf(clk_name, 32, "dsi%dpllbyte", pll_14nm->id);
+       snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->id);
+
+       /* DSI Byte clock = VCO_CLK / N1 / 8 */
+       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
+                                         CLK_SET_RATE_PARENT, 1, 8);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+
+       hws[num++] = hw;
+       hw_data->hws[DSI_BYTE_PLL_CLK] = hw;
+
+       snprintf(clk_name, 32, "dsi%dn1_postdivby2_clk", pll_14nm->id);
+       snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->id);
+
+       /*
+        * Skip the mux for now, force DSICLK_SEL to 1, Add a /2 divider
+        * on the way. Don't let it set parent.
+        */
+       hw = clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 2);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+
+       hws[num++] = hw;
+
+       snprintf(clk_name, 32, "dsi%dpll", pll_14nm->id);
+       snprintf(parent, 32, "dsi%dn1_postdivby2_clk", pll_14nm->id);
+
+       /* DSI pixel clock = VCO_CLK / N1 / 2 / N2
+        * This is the output of N2 post-divider, bits 4-7 in
+        * REG_DSI_14nm_PHY_CMN_CLK_CFG0. Don't let it set parent.
+        */
+       hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent, 0, 4);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+
+       hws[num++] = hw;
+       hw_data->hws[DSI_PIXEL_PLL_CLK] = hw;
+
+       pll_14nm->num_hws = num;
+
+       hw_data->num = NUM_PROVIDED_CLKS;
+       pll_14nm->hw_data = hw_data;
+
+       ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
+                                    pll_14nm->hw_data);
+       if (ret) {
+               DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+struct msm_dsi_pll *msm_dsi_pll_14nm_init(struct platform_device *pdev, int id)
+{
+       struct dsi_pll_14nm *pll_14nm;
+       struct msm_dsi_pll *pll;
+       int ret;
+
+       if (!pdev)
+               return ERR_PTR(-ENODEV);
+
+       pll_14nm = devm_kzalloc(&pdev->dev, sizeof(*pll_14nm), GFP_KERNEL);
+       if (!pll_14nm)
+               return ERR_PTR(-ENOMEM);
+
+       DBG("PLL%d", id);
+
+       pll_14nm->pdev = pdev;
+       pll_14nm->id = id;
+       pll_14nm_list[id] = pll_14nm;
+
+       pll_14nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY");
+       if (IS_ERR_OR_NULL(pll_14nm->phy_cmn_mmio)) {
+               DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       pll_14nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL");
+       if (IS_ERR_OR_NULL(pll_14nm->mmio)) {
+               DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       spin_lock_init(&pll_14nm->postdiv_lock);
+
+       pll = &pll_14nm->base;
+       pll->min_rate = VCO_MIN_RATE;
+       pll->max_rate = VCO_MAX_RATE;
+       pll->get_provider = dsi_pll_14nm_get_provider;
+       pll->destroy = dsi_pll_14nm_destroy;
+       pll->disable_seq = dsi_pll_14nm_disable_seq;
+       pll->save_state = dsi_pll_14nm_save_state;
+       pll->restore_state = dsi_pll_14nm_restore_state;
+       pll->set_usecase = dsi_pll_14nm_set_usecase;
+
+       pll_14nm->vco_delay = 1;
+
+       pll->en_seq_cnt = 1;
+       pll->enable_seqs[0] = dsi_pll_14nm_enable_seq;
+
+       ret = pll_14nm_register(pll_14nm);
+       if (ret) {
+               DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
+               return ERR_PTR(ret);
+       }
+
+       return pll;
+}
+
 static void dsi_14nm_dphy_set_timing(struct msm_dsi_phy *phy,
                                     struct msm_dsi_dphy_timing *timing,
                                     int lane_idx)
index 5bf79de..2f502ef 100644 (file)
@@ -3,9 +3,646 @@
  * Copyright (c) 2015, The Linux Foundation. All rights reserved.
  */
 
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+
 #include "dsi_phy.h"
+#include "dsi_pll.h"
 #include "dsi.xml.h"
 
+/*
+ * DSI PLL 28nm - clock diagram (eg: DSI0):
+ *
+ *         dsi0analog_postdiv_clk
+ *                             |         dsi0indirect_path_div2_clk
+ *                             |          |
+ *                   +------+  |  +----+  |  |\   dsi0byte_mux
+ *  dsi0vco_clk --o--| DIV1 |--o--| /2 |--o--| \   |
+ *                |  +------+     +----+     | m|  |  +----+
+ *                |                          | u|--o--| /4 |-- dsi0pllbyte
+ *                |                          | x|     +----+
+ *                o--------------------------| /
+ *                |                          |/
+ *                |          +------+
+ *                o----------| DIV3 |------------------------- dsi0pll
+ *                           +------+
+ */
+
+#define POLL_MAX_READS                 10
+#define POLL_TIMEOUT_US                50
+
+#define NUM_PROVIDED_CLKS              2
+
+#define VCO_REF_CLK_RATE               19200000
+#define VCO_MIN_RATE                   350000000
+#define VCO_MAX_RATE                   750000000
+
+#define DSI_BYTE_PLL_CLK               0
+#define DSI_PIXEL_PLL_CLK              1
+
+#define LPFR_LUT_SIZE                  10
+struct lpfr_cfg {
+       unsigned long vco_rate;
+       u32 resistance;
+};
+
+/* Loop filter resistance: */
+static const struct lpfr_cfg lpfr_lut[LPFR_LUT_SIZE] = {
+       { 479500000,  8 },
+       { 480000000, 11 },
+       { 575500000,  8 },
+       { 576000000, 12 },
+       { 610500000,  8 },
+       { 659500000,  9 },
+       { 671500000, 10 },
+       { 672000000, 14 },
+       { 708500000, 10 },
+       { 750000000, 11 },
+};
+
+struct pll_28nm_cached_state {
+       unsigned long vco_rate;
+       u8 postdiv3;
+       u8 postdiv1;
+       u8 byte_mux;
+};
+
+struct dsi_pll_28nm {
+       struct msm_dsi_pll base;
+
+       int id;
+       struct platform_device *pdev;
+       void __iomem *mmio;
+
+       int vco_delay;
+
+       /* private clocks: */
+       struct clk *clks[NUM_DSI_CLOCKS_MAX];
+       u32 num_clks;
+
+       /* clock-provider: */
+       struct clk *provided_clks[NUM_PROVIDED_CLKS];
+       struct clk_onecell_data clk_data;
+
+       struct pll_28nm_cached_state cached_state;
+};
+
+#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, base)
+
+static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm,
+                               u32 nb_tries, u32 timeout_us)
+{
+       bool pll_locked = false;
+       u32 val;
+
+       while (nb_tries--) {
+               val = pll_read(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_STATUS);
+               pll_locked = !!(val & DSI_28nm_PHY_PLL_STATUS_PLL_RDY);
+
+               if (pll_locked)
+                       break;
+
+               udelay(timeout_us);
+       }
+       DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* ");
+
+       return pll_locked;
+}
+
+static void pll_28nm_software_reset(struct dsi_pll_28nm *pll_28nm)
+{
+       void __iomem *base = pll_28nm->mmio;
+
+       /*
+        * Add HW recommended delays after toggling the software
+        * reset bit off and back on.
+        */
+       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG,
+                       DSI_28nm_PHY_PLL_TEST_CFG_PLL_SW_RESET, 1);
+       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG, 0x00, 1);
+}
+
+/*
+ * Clock Callbacks
+ */
+static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+       struct device *dev = &pll_28nm->pdev->dev;
+       void __iomem *base = pll_28nm->mmio;
+       unsigned long div_fbx1000, gen_vco_clk;
+       u32 refclk_cfg, frac_n_mode, frac_n_value;
+       u32 sdm_cfg0, sdm_cfg1, sdm_cfg2, sdm_cfg3;
+       u32 cal_cfg10, cal_cfg11;
+       u32 rem;
+       int i;
+
+       VERB("rate=%lu, parent's=%lu", rate, parent_rate);
+
+       /* Force postdiv2 to be div-4 */
+       pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV2_CFG, 3);
+
+       /* Configure the Loop filter resistance */
+       for (i = 0; i < LPFR_LUT_SIZE; i++)
+               if (rate <= lpfr_lut[i].vco_rate)
+                       break;
+       if (i == LPFR_LUT_SIZE) {
+               DRM_DEV_ERROR(dev, "unable to get loop filter resistance. vco=%lu\n",
+                               rate);
+               return -EINVAL;
+       }
+       pll_write(base + REG_DSI_28nm_PHY_PLL_LPFR_CFG, lpfr_lut[i].resistance);
+
+       /* Loop filter capacitance values : c1 and c2 */
+       pll_write(base + REG_DSI_28nm_PHY_PLL_LPFC1_CFG, 0x70);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_LPFC2_CFG, 0x15);
+
+       rem = rate % VCO_REF_CLK_RATE;
+       if (rem) {
+               refclk_cfg = DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR;
+               frac_n_mode = 1;
+               div_fbx1000 = rate / (VCO_REF_CLK_RATE / 500);
+               gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 500);
+       } else {
+               refclk_cfg = 0x0;
+               frac_n_mode = 0;
+               div_fbx1000 = rate / (VCO_REF_CLK_RATE / 1000);
+               gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 1000);
+       }
+
+       DBG("refclk_cfg = %d", refclk_cfg);
+
+       rem = div_fbx1000 % 1000;
+       frac_n_value = (rem << 16) / 1000;
+
+       DBG("div_fb = %lu", div_fbx1000);
+       DBG("frac_n_value = %d", frac_n_value);
+
+       DBG("Generated VCO Clock: %lu", gen_vco_clk);
+       rem = 0;
+       sdm_cfg1 = pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1);
+       sdm_cfg1 &= ~DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET__MASK;
+       if (frac_n_mode) {
+               sdm_cfg0 = 0x0;
+               sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(0);
+               sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(
+                               (u32)(((div_fbx1000 / 1000) & 0x3f) - 1));
+               sdm_cfg3 = frac_n_value >> 8;
+               sdm_cfg2 = frac_n_value & 0xff;
+       } else {
+               sdm_cfg0 = DSI_28nm_PHY_PLL_SDM_CFG0_BYP;
+               sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(
+                               (u32)(((div_fbx1000 / 1000) & 0x3f) - 1));
+               sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(0);
+               sdm_cfg2 = 0;
+               sdm_cfg3 = 0;
+       }
+
+       DBG("sdm_cfg0=%d", sdm_cfg0);
+       DBG("sdm_cfg1=%d", sdm_cfg1);
+       DBG("sdm_cfg2=%d", sdm_cfg2);
+       DBG("sdm_cfg3=%d", sdm_cfg3);
+
+       cal_cfg11 = (u32)(gen_vco_clk / (256 * 1000000));
+       cal_cfg10 = (u32)((gen_vco_clk % (256 * 1000000)) / 1000000);
+       DBG("cal_cfg10=%d, cal_cfg11=%d", cal_cfg10, cal_cfg11);
+
+       pll_write(base + REG_DSI_28nm_PHY_PLL_CHGPUMP_CFG, 0x02);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG3,    0x2b);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG4,    0x06);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2,  0x0d);
+
+       pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1, sdm_cfg1);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2,
+               DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0(sdm_cfg2));
+       pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3,
+               DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8(sdm_cfg3));
+       pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG4, 0x00);
+
+       /* Add hardware recommended delay for correct PLL configuration */
+       if (pll_28nm->vco_delay)
+               udelay(pll_28nm->vco_delay);
+
+       pll_write(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG, refclk_cfg);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG, 0x00);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_VCOLPF_CFG, 0x31);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0,   sdm_cfg0);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG0,   0x12);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG6,   0x30);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG7,   0x00);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG8,   0x60);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG9,   0x00);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG10,  cal_cfg10 & 0xff);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG11,  cal_cfg11 & 0xff);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_EFUSE_CFG,  0x20);
+
+       return 0;
+}
+
+static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+
+       return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS,
+                                       POLL_TIMEOUT_US);
+}
+
+static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+       void __iomem *base = pll_28nm->mmio;
+       u32 sdm0, doubler, sdm_byp_div;
+       u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3;
+       u32 ref_clk = VCO_REF_CLK_RATE;
+       unsigned long vco_rate;
+
+       VERB("parent_rate=%lu", parent_rate);
+
+       /* Check to see if the ref clk doubler is enabled */
+       doubler = pll_read(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG) &
+                       DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR;
+       ref_clk += (doubler * VCO_REF_CLK_RATE);
+
+       /* see if it is integer mode or sdm mode */
+       sdm0 = pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0);
+       if (sdm0 & DSI_28nm_PHY_PLL_SDM_CFG0_BYP) {
+               /* integer mode */
+               sdm_byp_div = FIELD(
+                               pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0),
+                               DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV) + 1;
+               vco_rate = ref_clk * sdm_byp_div;
+       } else {
+               /* sdm mode */
+               sdm_dc_off = FIELD(
+                               pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1),
+                               DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET);
+               DBG("sdm_dc_off = %d", sdm_dc_off);
+               sdm2 = FIELD(pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2),
+                               DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0);
+               sdm3 = FIELD(pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3),
+                               DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8);
+               sdm_freq_seed = (sdm3 << 8) | sdm2;
+               DBG("sdm_freq_seed = %d", sdm_freq_seed);
+
+               vco_rate = (ref_clk * (sdm_dc_off + 1)) +
+                       mult_frac(ref_clk, sdm_freq_seed, BIT(16));
+               DBG("vco rate = %lu", vco_rate);
+       }
+
+       DBG("returning vco rate = %lu", vco_rate);
+
+       return vco_rate;
+}
+
+static const struct clk_ops clk_ops_dsi_pll_28nm_vco = {
+       .round_rate = msm_dsi_pll_helper_clk_round_rate,
+       .set_rate = dsi_pll_28nm_clk_set_rate,
+       .recalc_rate = dsi_pll_28nm_clk_recalc_rate,
+       .prepare = msm_dsi_pll_helper_clk_prepare,
+       .unprepare = msm_dsi_pll_helper_clk_unprepare,
+       .is_enabled = dsi_pll_28nm_clk_is_enabled,
+};
+
+/*
+ * PLL Callbacks
+ */
+static int dsi_pll_28nm_enable_seq_hpm(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+       struct device *dev = &pll_28nm->pdev->dev;
+       void __iomem *base = pll_28nm->mmio;
+       u32 max_reads = 5, timeout_us = 100;
+       bool locked;
+       u32 val;
+       int i;
+
+       DBG("id=%d", pll_28nm->id);
+
+       pll_28nm_software_reset(pll_28nm);
+
+       /*
+        * PLL power up sequence.
+        * Add necessary delays recommended by hardware.
+        */
+       val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
+       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1);
+
+       val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
+       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
+
+       val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
+       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
+
+       val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
+       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600);
+
+       for (i = 0; i < 2; i++) {
+               /* DSI Uniphy lock detect setting */
+               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2,
+                               0x0c, 100);
+               pll_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d);
+
+               /* poll for PLL ready status */
+               locked = pll_28nm_poll_for_ready(pll_28nm,
+                                               max_reads, timeout_us);
+               if (locked)
+                       break;
+
+               pll_28nm_software_reset(pll_28nm);
+
+               /*
+                * PLL power up sequence.
+                * Add necessary delays recommended by hardware.
+                */
+               val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
+               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1);
+
+               val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
+               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
+
+               val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
+               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 250);
+
+               val &= ~DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
+               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
+
+               val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
+               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
+
+               val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
+               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600);
+       }
+
+       if (unlikely(!locked))
+               DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
+       else
+               DBG("DSI PLL Lock success");
+
+       return locked ? 0 : -EINVAL;
+}
+
+static int dsi_pll_28nm_enable_seq_lp(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+       struct device *dev = &pll_28nm->pdev->dev;
+       void __iomem *base = pll_28nm->mmio;
+       bool locked;
+       u32 max_reads = 10, timeout_us = 50;
+       u32 val;
+
+       DBG("id=%d", pll_28nm->id);
+
+       pll_28nm_software_reset(pll_28nm);
+
+       /*
+        * PLL power up sequence.
+        * Add necessary delays recommended by hardware.
+        */
+       pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_CAL_CFG1, 0x34, 500);
+
+       val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
+       pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
+
+       val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
+       pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
+
+       val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B |
+               DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
+       pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
+
+       /* DSI PLL toggle lock detect setting */
+       pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x04, 500);
+       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x05, 512);
+
+       locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us);
+
+       if (unlikely(!locked))
+               DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
+       else
+               DBG("DSI PLL lock success");
+
+       return locked ? 0 : -EINVAL;
+}
+
+static void dsi_pll_28nm_disable_seq(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+
+       DBG("id=%d", pll_28nm->id);
+       pll_write(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_GLB_CFG, 0x00);
+}
+
+static void dsi_pll_28nm_save_state(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+       struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
+       void __iomem *base = pll_28nm->mmio;
+
+       cached_state->postdiv3 =
+                       pll_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG);
+       cached_state->postdiv1 =
+                       pll_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG);
+       cached_state->byte_mux = pll_read(base + REG_DSI_28nm_PHY_PLL_VREG_CFG);
+       if (dsi_pll_28nm_clk_is_enabled(&pll->clk_hw))
+               cached_state->vco_rate = clk_hw_get_rate(&pll->clk_hw);
+       else
+               cached_state->vco_rate = 0;
+}
+
+static int dsi_pll_28nm_restore_state(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+       struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
+       void __iomem *base = pll_28nm->mmio;
+       int ret;
+
+       ret = dsi_pll_28nm_clk_set_rate(&pll->clk_hw,
+                                       cached_state->vco_rate, 0);
+       if (ret) {
+               DRM_DEV_ERROR(&pll_28nm->pdev->dev,
+                       "restore vco rate failed. ret=%d\n", ret);
+               return ret;
+       }
+
+       pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG,
+                       cached_state->postdiv3);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG,
+                       cached_state->postdiv1);
+       pll_write(base + REG_DSI_28nm_PHY_PLL_VREG_CFG,
+                       cached_state->byte_mux);
+
+       return 0;
+}
+
+static int dsi_pll_28nm_get_provider(struct msm_dsi_pll *pll,
+                               struct clk **byte_clk_provider,
+                               struct clk **pixel_clk_provider)
+{
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+
+       if (byte_clk_provider)
+               *byte_clk_provider = pll_28nm->provided_clks[DSI_BYTE_PLL_CLK];
+       if (pixel_clk_provider)
+               *pixel_clk_provider =
+                               pll_28nm->provided_clks[DSI_PIXEL_PLL_CLK];
+
+       return 0;
+}
+
+static void dsi_pll_28nm_destroy(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+       int i;
+
+       msm_dsi_pll_helper_unregister_clks(pll_28nm->pdev,
+                                       pll_28nm->clks, pll_28nm->num_clks);
+
+       for (i = 0; i < NUM_PROVIDED_CLKS; i++)
+               pll_28nm->provided_clks[i] = NULL;
+
+       pll_28nm->num_clks = 0;
+       pll_28nm->clk_data.clks = NULL;
+       pll_28nm->clk_data.clk_num = 0;
+}
+
+static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm)
+{
+       char clk_name[32], parent1[32], parent2[32], vco_name[32];
+       struct clk_init_data vco_init = {
+               .parent_names = (const char *[]){ "xo" },
+               .num_parents = 1,
+               .name = vco_name,
+               .flags = CLK_IGNORE_UNUSED,
+               .ops = &clk_ops_dsi_pll_28nm_vco,
+       };
+       struct device *dev = &pll_28nm->pdev->dev;
+       struct clk **clks = pll_28nm->clks;
+       struct clk **provided_clks = pll_28nm->provided_clks;
+       int num = 0;
+       int ret;
+
+       DBG("%d", pll_28nm->id);
+
+       snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id);
+       pll_28nm->base.clk_hw.init = &vco_init;
+       clks[num++] = clk_register(dev, &pll_28nm->base.clk_hw);
+
+       snprintf(clk_name, 32, "dsi%danalog_postdiv_clk", pll_28nm->id);
+       snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id);
+       clks[num++] = clk_register_divider(dev, clk_name,
+                       parent1, CLK_SET_RATE_PARENT,
+                       pll_28nm->mmio +
+                       REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG,
+                       0, 4, 0, NULL);
+
+       snprintf(clk_name, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id);
+       snprintf(parent1, 32, "dsi%danalog_postdiv_clk", pll_28nm->id);
+       clks[num++] = clk_register_fixed_factor(dev, clk_name,
+                       parent1, CLK_SET_RATE_PARENT,
+                       1, 2);
+
+       snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id);
+       snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id);
+       clks[num++] = provided_clks[DSI_PIXEL_PLL_CLK] =
+                       clk_register_divider(dev, clk_name,
+                               parent1, 0, pll_28nm->mmio +
+                               REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG,
+                               0, 8, 0, NULL);
+
+       snprintf(clk_name, 32, "dsi%dbyte_mux", pll_28nm->id);
+       snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id);
+       snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id);
+       clks[num++] = clk_register_mux(dev, clk_name,
+                       ((const char *[]){
+                               parent1, parent2
+                       }), 2, CLK_SET_RATE_PARENT, pll_28nm->mmio +
+                       REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL);
+
+       snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id);
+       snprintf(parent1, 32, "dsi%dbyte_mux", pll_28nm->id);
+       clks[num++] = provided_clks[DSI_BYTE_PLL_CLK] =
+                       clk_register_fixed_factor(dev, clk_name,
+                               parent1, CLK_SET_RATE_PARENT, 1, 4);
+
+       pll_28nm->num_clks = num;
+
+       pll_28nm->clk_data.clk_num = NUM_PROVIDED_CLKS;
+       pll_28nm->clk_data.clks = provided_clks;
+
+       ret = of_clk_add_provider(dev->of_node,
+                       of_clk_src_onecell_get, &pll_28nm->clk_data);
+       if (ret) {
+               DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+struct msm_dsi_pll *msm_dsi_pll_28nm_init(struct platform_device *pdev,
+                                       enum msm_dsi_phy_type type, int id)
+{
+       struct dsi_pll_28nm *pll_28nm;
+       struct msm_dsi_pll *pll;
+       int ret;
+
+       if (!pdev)
+               return ERR_PTR(-ENODEV);
+
+       pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL);
+       if (!pll_28nm)
+               return ERR_PTR(-ENOMEM);
+
+       pll_28nm->pdev = pdev;
+       pll_28nm->id = id;
+
+       pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL");
+       if (IS_ERR_OR_NULL(pll_28nm->mmio)) {
+               DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       pll = &pll_28nm->base;
+       pll->min_rate = VCO_MIN_RATE;
+       pll->max_rate = VCO_MAX_RATE;
+       pll->get_provider = dsi_pll_28nm_get_provider;
+       pll->destroy = dsi_pll_28nm_destroy;
+       pll->disable_seq = dsi_pll_28nm_disable_seq;
+       pll->save_state = dsi_pll_28nm_save_state;
+       pll->restore_state = dsi_pll_28nm_restore_state;
+
+       if (type == MSM_DSI_PHY_28NM_HPM) {
+               pll_28nm->vco_delay = 1;
+
+               pll->en_seq_cnt = 3;
+               pll->enable_seqs[0] = dsi_pll_28nm_enable_seq_hpm;
+               pll->enable_seqs[1] = dsi_pll_28nm_enable_seq_hpm;
+               pll->enable_seqs[2] = dsi_pll_28nm_enable_seq_hpm;
+       } else if (type == MSM_DSI_PHY_28NM_LP) {
+               pll_28nm->vco_delay = 1000;
+
+               pll->en_seq_cnt = 1;
+               pll->enable_seqs[0] = dsi_pll_28nm_enable_seq_lp;
+       } else {
+               DRM_DEV_ERROR(&pdev->dev, "phy type (%d) is not 28nm\n", type);
+               return ERR_PTR(-EINVAL);
+       }
+
+       ret = pll_28nm_register(pll_28nm);
+       if (ret) {
+               DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
+               return ERR_PTR(ret);
+       }
+
+       return pll;
+}
+
+
 static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy,
                struct msm_dsi_dphy_timing *timing)
 {
index 5d33de2..4a40513 100644 (file)
  * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
  */
 
+#include <linux/clk-provider.h>
 #include <linux/delay.h>
 
 #include "dsi_phy.h"
+#include "dsi_pll.h"
 #include "dsi.xml.h"
 
+/*
+ * DSI PLL 28nm (8960/A family) - clock diagram (eg: DSI1):
+ *
+ *
+ *                        +------+
+ *  dsi1vco_clk ----o-----| DIV1 |---dsi1pllbit (not exposed as clock)
+ *  F * byte_clk    |     +------+
+ *                  | bit clock divider (F / 8)
+ *                  |
+ *                  |     +------+
+ *                  o-----| DIV2 |---dsi0pllbyte---o---> To byte RCG
+ *                  |     +------+                 | (sets parent rate)
+ *                  | byte clock divider (F)       |
+ *                  |                              |
+ *                  |                              o---> To esc RCG
+ *                  |                                (doesn't set parent rate)
+ *                  |
+ *                  |     +------+
+ *                  o-----| DIV3 |----dsi0pll------o---> To dsi RCG
+ *                        +------+                 | (sets parent rate)
+ *                  dsi clock divider (F * magic)  |
+ *                                                 |
+ *                                                 o---> To pixel rcg
+ *                                                  (doesn't set parent rate)
+ */
+
+#define POLL_MAX_READS         8000
+#define POLL_TIMEOUT_US                1
+
+#define NUM_PROVIDED_CLKS      2
+
+#define VCO_REF_CLK_RATE       27000000
+#define VCO_MIN_RATE           600000000
+#define VCO_MAX_RATE           1200000000
+
+#define DSI_BYTE_PLL_CLK       0
+#define DSI_PIXEL_PLL_CLK      1
+
+#define VCO_PREF_DIV_RATIO     27
+
+struct pll_28nm_cached_state {
+       unsigned long vco_rate;
+       u8 postdiv3;
+       u8 postdiv2;
+       u8 postdiv1;
+};
+
+struct clk_bytediv {
+       struct clk_hw hw;
+       void __iomem *reg;
+};
+
+struct dsi_pll_28nm {
+       struct msm_dsi_pll base;
+
+       int id;
+       struct platform_device *pdev;
+       void __iomem *mmio;
+
+       /* custom byte clock divider */
+       struct clk_bytediv *bytediv;
+
+       /* private clocks: */
+       struct clk *clks[NUM_DSI_CLOCKS_MAX];
+       u32 num_clks;
+
+       /* clock-provider: */
+       struct clk *provided_clks[NUM_PROVIDED_CLKS];
+       struct clk_onecell_data clk_data;
+
+       struct pll_28nm_cached_state cached_state;
+};
+
+#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, base)
+
+static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm,
+                                   int nb_tries, int timeout_us)
+{
+       bool pll_locked = false;
+       u32 val;
+
+       while (nb_tries--) {
+               val = pll_read(pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_RDY);
+               pll_locked = !!(val & DSI_28nm_8960_PHY_PLL_RDY_PLL_RDY);
+
+               if (pll_locked)
+                       break;
+
+               udelay(timeout_us);
+       }
+       DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* ");
+
+       return pll_locked;
+}
+
+/*
+ * Clock Callbacks
+ */
+static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                                    unsigned long parent_rate)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+       void __iomem *base = pll_28nm->mmio;
+       u32 val, temp, fb_divider;
+
+       DBG("rate=%lu, parent's=%lu", rate, parent_rate);
+
+       temp = rate / 10;
+       val = VCO_REF_CLK_RATE / 10;
+       fb_divider = (temp * VCO_PREF_DIV_RATIO) / val;
+       fb_divider = fb_divider / 2 - 1;
+       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1,
+                       fb_divider & 0xff);
+
+       val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2);
+
+       val |= (fb_divider >> 8) & 0x07;
+
+       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2,
+                       val);
+
+       val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3);
+
+       val |= (VCO_PREF_DIV_RATIO - 1) & 0x3f;
+
+       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3,
+                       val);
+
+       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_6,
+                       0xf);
+
+       val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8);
+       val |= 0x7 << 4;
+       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8,
+                       val);
+
+       return 0;
+}
+
+static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+
+       return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS,
+                                       POLL_TIMEOUT_US);
+}
+
+static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw,
+                                                 unsigned long parent_rate)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+       void __iomem *base = pll_28nm->mmio;
+       unsigned long vco_rate;
+       u32 status, fb_divider, temp, ref_divider;
+
+       VERB("parent_rate=%lu", parent_rate);
+
+       status = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0);
+
+       if (status & DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE) {
+               fb_divider = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1);
+               fb_divider &= 0xff;
+               temp = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2) & 0x07;
+               fb_divider = (temp << 8) | fb_divider;
+               fb_divider += 1;
+
+               ref_divider = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3);
+               ref_divider &= 0x3f;
+               ref_divider += 1;
+
+               /* multiply by 2 */
+               vco_rate = (parent_rate / ref_divider) * fb_divider * 2;
+       } else {
+               vco_rate = 0;
+       }
+
+       DBG("returning vco rate = %lu", vco_rate);
+
+       return vco_rate;
+}
+
+static const struct clk_ops clk_ops_dsi_pll_28nm_vco = {
+       .round_rate = msm_dsi_pll_helper_clk_round_rate,
+       .set_rate = dsi_pll_28nm_clk_set_rate,
+       .recalc_rate = dsi_pll_28nm_clk_recalc_rate,
+       .prepare = msm_dsi_pll_helper_clk_prepare,
+       .unprepare = msm_dsi_pll_helper_clk_unprepare,
+       .is_enabled = dsi_pll_28nm_clk_is_enabled,
+};
+
+/*
+ * Custom byte clock divier clk_ops
+ *
+ * This clock is the entry point to configuring the PLL. The user (dsi host)
+ * will set this clock's rate to the desired byte clock rate. The VCO lock
+ * frequency is a multiple of the byte clock rate. The multiplication factor
+ * (shown as F in the diagram above) is a function of the byte clock rate.
+ *
+ * This custom divider clock ensures that its parent (VCO) is set to the
+ * desired rate, and that the byte clock postdivider (POSTDIV2) is configured
+ * accordingly
+ */
+#define to_clk_bytediv(_hw) container_of(_hw, struct clk_bytediv, hw)
+
+static unsigned long clk_bytediv_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_bytediv *bytediv = to_clk_bytediv(hw);
+       unsigned int div;
+
+       div = pll_read(bytediv->reg) & 0xff;
+
+       return parent_rate / (div + 1);
+}
+
+/* find multiplication factor(wrt byte clock) at which the VCO should be set */
+static unsigned int get_vco_mul_factor(unsigned long byte_clk_rate)
+{
+       unsigned long bit_mhz;
+
+       /* convert to bit clock in Mhz */
+       bit_mhz = (byte_clk_rate * 8) / 1000000;
+
+       if (bit_mhz < 125)
+               return 64;
+       else if (bit_mhz < 250)
+               return 32;
+       else if (bit_mhz < 600)
+               return 16;
+       else
+               return 8;
+}
+
+static long clk_bytediv_round_rate(struct clk_hw *hw, unsigned long rate,
+                                  unsigned long *prate)
+{
+       unsigned long best_parent;
+       unsigned int factor;
+
+       factor = get_vco_mul_factor(rate);
+
+       best_parent = rate * factor;
+       *prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent);
+
+       return *prate / factor;
+}
+
+static int clk_bytediv_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct clk_bytediv *bytediv = to_clk_bytediv(hw);
+       u32 val;
+       unsigned int factor;
+
+       factor = get_vco_mul_factor(rate);
+
+       val = pll_read(bytediv->reg);
+       val |= (factor - 1) & 0xff;
+       pll_write(bytediv->reg, val);
+
+       return 0;
+}
+
+/* Our special byte clock divider ops */
+static const struct clk_ops clk_bytediv_ops = {
+       .round_rate = clk_bytediv_round_rate,
+       .set_rate = clk_bytediv_set_rate,
+       .recalc_rate = clk_bytediv_recalc_rate,
+};
+
+/*
+ * PLL Callbacks
+ */
+static int dsi_pll_28nm_enable_seq(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+       struct device *dev = &pll_28nm->pdev->dev;
+       void __iomem *base = pll_28nm->mmio;
+       bool locked;
+       unsigned int bit_div, byte_div;
+       int max_reads = 1000, timeout_us = 100;
+       u32 val;
+
+       DBG("id=%d", pll_28nm->id);
+
+       /*
+        * before enabling the PLL, configure the bit clock divider since we
+        * don't expose it as a clock to the outside world
+        * 1: read back the byte clock divider that should already be set
+        * 2: divide by 8 to get bit clock divider
+        * 3: write it to POSTDIV1
+        */
+       val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9);
+       byte_div = val + 1;
+       bit_div = byte_div / 8;
+
+       val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8);
+       val &= ~0xf;
+       val |= (bit_div - 1);
+       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, val);
+
+       /* enable the PLL */
+       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0,
+                       DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE);
+
+       locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us);
+
+       if (unlikely(!locked))
+               DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
+       else
+               DBG("DSI PLL lock success");
+
+       return locked ? 0 : -EINVAL;
+}
+
+static void dsi_pll_28nm_disable_seq(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+
+       DBG("id=%d", pll_28nm->id);
+       pll_write(pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, 0x00);
+}
+
+static void dsi_pll_28nm_save_state(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+       struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
+       void __iomem *base = pll_28nm->mmio;
+
+       cached_state->postdiv3 =
+                       pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10);
+       cached_state->postdiv2 =
+                       pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9);
+       cached_state->postdiv1 =
+                       pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8);
+
+       cached_state->vco_rate = clk_hw_get_rate(&pll->clk_hw);
+}
+
+static int dsi_pll_28nm_restore_state(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+       struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
+       void __iomem *base = pll_28nm->mmio;
+       int ret;
+
+       ret = dsi_pll_28nm_clk_set_rate(&pll->clk_hw,
+                                       cached_state->vco_rate, 0);
+       if (ret) {
+               DRM_DEV_ERROR(&pll_28nm->pdev->dev,
+                       "restore vco rate failed. ret=%d\n", ret);
+               return ret;
+       }
+
+       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10,
+                       cached_state->postdiv3);
+       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9,
+                       cached_state->postdiv2);
+       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8,
+                       cached_state->postdiv1);
+
+       return 0;
+}
+
+static int dsi_pll_28nm_get_provider(struct msm_dsi_pll *pll,
+                               struct clk **byte_clk_provider,
+                               struct clk **pixel_clk_provider)
+{
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+
+       if (byte_clk_provider)
+               *byte_clk_provider = pll_28nm->provided_clks[DSI_BYTE_PLL_CLK];
+       if (pixel_clk_provider)
+               *pixel_clk_provider =
+                               pll_28nm->provided_clks[DSI_PIXEL_PLL_CLK];
+
+       return 0;
+}
+
+static void dsi_pll_28nm_destroy(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
+
+       msm_dsi_pll_helper_unregister_clks(pll_28nm->pdev,
+                                       pll_28nm->clks, pll_28nm->num_clks);
+}
+
+static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm)
+{
+       char *clk_name, *parent_name, *vco_name;
+       struct clk_init_data vco_init = {
+               .parent_names = (const char *[]){ "pxo" },
+               .num_parents = 1,
+               .flags = CLK_IGNORE_UNUSED,
+               .ops = &clk_ops_dsi_pll_28nm_vco,
+       };
+       struct device *dev = &pll_28nm->pdev->dev;
+       struct clk **clks = pll_28nm->clks;
+       struct clk **provided_clks = pll_28nm->provided_clks;
+       struct clk_bytediv *bytediv;
+       struct clk_init_data bytediv_init = { };
+       int ret, num = 0;
+
+       DBG("%d", pll_28nm->id);
+
+       bytediv = devm_kzalloc(dev, sizeof(*bytediv), GFP_KERNEL);
+       if (!bytediv)
+               return -ENOMEM;
+
+       vco_name = devm_kzalloc(dev, 32, GFP_KERNEL);
+       if (!vco_name)
+               return -ENOMEM;
+
+       parent_name = devm_kzalloc(dev, 32, GFP_KERNEL);
+       if (!parent_name)
+               return -ENOMEM;
+
+       clk_name = devm_kzalloc(dev, 32, GFP_KERNEL);
+       if (!clk_name)
+               return -ENOMEM;
+
+       pll_28nm->bytediv = bytediv;
+
+       snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id);
+       vco_init.name = vco_name;
+
+       pll_28nm->base.clk_hw.init = &vco_init;
+
+       clks[num++] = clk_register(dev, &pll_28nm->base.clk_hw);
+
+       /* prepare and register bytediv */
+       bytediv->hw.init = &bytediv_init;
+       bytediv->reg = pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_CTRL_9;
+
+       snprintf(parent_name, 32, "dsi%dvco_clk", pll_28nm->id);
+       snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id);
+
+       bytediv_init.name = clk_name;
+       bytediv_init.ops = &clk_bytediv_ops;
+       bytediv_init.flags = CLK_SET_RATE_PARENT;
+       bytediv_init.parent_names = (const char * const *) &parent_name;
+       bytediv_init.num_parents = 1;
+
+       /* DIV2 */
+       clks[num++] = provided_clks[DSI_BYTE_PLL_CLK] =
+                       clk_register(dev, &bytediv->hw);
+
+       snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id);
+       /* DIV3 */
+       clks[num++] = provided_clks[DSI_PIXEL_PLL_CLK] =
+                       clk_register_divider(dev, clk_name,
+                               parent_name, 0, pll_28nm->mmio +
+                               REG_DSI_28nm_8960_PHY_PLL_CTRL_10,
+                               0, 8, 0, NULL);
+
+       pll_28nm->num_clks = num;
+
+       pll_28nm->clk_data.clk_num = NUM_PROVIDED_CLKS;
+       pll_28nm->clk_data.clks = provided_clks;
+
+       ret = of_clk_add_provider(dev->of_node,
+                       of_clk_src_onecell_get, &pll_28nm->clk_data);
+       if (ret) {
+               DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+struct msm_dsi_pll *msm_dsi_pll_28nm_8960_init(struct platform_device *pdev,
+                                              int id)
+{
+       struct dsi_pll_28nm *pll_28nm;
+       struct msm_dsi_pll *pll;
+       int ret;
+
+       if (!pdev)
+               return ERR_PTR(-ENODEV);
+
+       pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL);
+       if (!pll_28nm)
+               return ERR_PTR(-ENOMEM);
+
+       pll_28nm->pdev = pdev;
+       pll_28nm->id = id + 1;
+
+       pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL");
+       if (IS_ERR_OR_NULL(pll_28nm->mmio)) {
+               DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       pll = &pll_28nm->base;
+       pll->min_rate = VCO_MIN_RATE;
+       pll->max_rate = VCO_MAX_RATE;
+       pll->get_provider = dsi_pll_28nm_get_provider;
+       pll->destroy = dsi_pll_28nm_destroy;
+       pll->disable_seq = dsi_pll_28nm_disable_seq;
+       pll->save_state = dsi_pll_28nm_save_state;
+       pll->restore_state = dsi_pll_28nm_restore_state;
+
+       pll->en_seq_cnt = 1;
+       pll->enable_seqs[0] = dsi_pll_28nm_enable_seq;
+
+       ret = pll_28nm_register(pll_28nm);
+       if (ret) {
+               DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
+               return ERR_PTR(ret);
+       }
+
+       return pll;
+}
+
 static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy,
                struct msm_dsi_dphy_timing *timing)
 {
index cbfeec8..f9af9d7 100644 (file)
  * Copyright (c) 2018, The Linux Foundation
  */
 
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/iopoll.h>
 
+#include "dsi_pll.h"
 #include "dsi_phy.h"
 #include "dsi.xml.h"
 
+/*
+ * DSI PLL 7nm - clock diagram (eg: DSI0): TODO: updated CPHY diagram
+ *
+ *           dsi0_pll_out_div_clk  dsi0_pll_bit_clk
+ *                              |                |
+ *                              |                |
+ *                 +---------+  |  +----------+  |  +----+
+ *  dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk
+ *                 +---------+  |  +----------+  |  +----+
+ *                              |                |
+ *                              |                |         dsi0_pll_by_2_bit_clk
+ *                              |                |          |
+ *                              |                |  +----+  |  |\  dsi0_pclk_mux
+ *                              |                |--| /2 |--o--| \   |
+ *                              |                |  +----+     |  \  |  +---------+
+ *                              |                --------------|  |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk
+ *                              |------------------------------|  /     +---------+
+ *                              |          +-----+             | /
+ *                              -----------| /4? |--o----------|/
+ *                                         +-----+  |           |
+ *                                                  |           |dsiclk_sel
+ *                                                  |
+ *                                                  dsi0_pll_post_out_div_clk
+ */
+
+#define DSI_BYTE_PLL_CLK               0
+#define DSI_PIXEL_PLL_CLK              1
+#define NUM_PROVIDED_CLKS              2
+
+#define VCO_REF_CLK_RATE               19200000
+
+struct dsi_pll_regs {
+       u32 pll_prop_gain_rate;
+       u32 pll_lockdet_rate;
+       u32 decimal_div_start;
+       u32 frac_div_start_low;
+       u32 frac_div_start_mid;
+       u32 frac_div_start_high;
+       u32 pll_clock_inverters;
+       u32 ssc_stepsize_low;
+       u32 ssc_stepsize_high;
+       u32 ssc_div_per_low;
+       u32 ssc_div_per_high;
+       u32 ssc_adjper_low;
+       u32 ssc_adjper_high;
+       u32 ssc_control;
+};
+
+struct dsi_pll_config {
+       u32 ref_freq;
+       bool div_override;
+       u32 output_div;
+       bool ignore_frac;
+       bool disable_prescaler;
+       bool enable_ssc;
+       bool ssc_center;
+       u32 dec_bits;
+       u32 frac_bits;
+       u32 lock_timer;
+       u32 ssc_freq;
+       u32 ssc_offset;
+       u32 ssc_adj_per;
+       u32 thresh_cycles;
+       u32 refclk_cycles;
+};
+
+struct pll_7nm_cached_state {
+       unsigned long vco_rate;
+       u8 bit_clk_div;
+       u8 pix_clk_div;
+       u8 pll_out_div;
+       u8 pll_mux;
+};
+
+struct dsi_pll_7nm {
+       struct msm_dsi_pll base;
+
+       int id;
+       struct platform_device *pdev;
+
+       void __iomem *phy_cmn_mmio;
+       void __iomem *mmio;
+
+       u64 vco_ref_clk_rate;
+       u64 vco_current_rate;
+
+       /* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */
+       spinlock_t postdiv_lock;
+
+       int vco_delay;
+       struct dsi_pll_config pll_configuration;
+       struct dsi_pll_regs reg_setup;
+
+       /* private clocks: */
+       struct clk_hw *out_div_clk_hw;
+       struct clk_hw *bit_clk_hw;
+       struct clk_hw *byte_clk_hw;
+       struct clk_hw *by_2_bit_clk_hw;
+       struct clk_hw *post_out_div_clk_hw;
+       struct clk_hw *pclk_mux_hw;
+       struct clk_hw *out_dsiclk_hw;
+
+       /* clock-provider: */
+       struct clk_hw_onecell_data *hw_data;
+
+       struct pll_7nm_cached_state cached_state;
+
+       enum msm_dsi_phy_usecase uc;
+       struct dsi_pll_7nm *slave;
+};
+
+#define to_pll_7nm(x)  container_of(x, struct dsi_pll_7nm, base)
+
+/*
+ * Global list of private DSI PLL struct pointers. We need this for Dual DSI
+ * mode, where the master PLL's clk_ops needs access the slave's private data
+ */
+static struct dsi_pll_7nm *pll_7nm_list[DSI_MAX];
+
+static void dsi_pll_setup_config(struct dsi_pll_7nm *pll)
+{
+       struct dsi_pll_config *config = &pll->pll_configuration;
+
+       config->ref_freq = pll->vco_ref_clk_rate;
+       config->output_div = 1;
+       config->dec_bits = 8;
+       config->frac_bits = 18;
+       config->lock_timer = 64;
+       config->ssc_freq = 31500;
+       config->ssc_offset = 4800;
+       config->ssc_adj_per = 2;
+       config->thresh_cycles = 32;
+       config->refclk_cycles = 256;
+
+       config->div_override = false;
+       config->ignore_frac = false;
+       config->disable_prescaler = false;
+
+       /* TODO: ssc enable */
+       config->enable_ssc = false;
+       config->ssc_center = 0;
+}
+
+static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll)
+{
+       struct dsi_pll_config *config = &pll->pll_configuration;
+       struct dsi_pll_regs *regs = &pll->reg_setup;
+       u64 fref = pll->vco_ref_clk_rate;
+       u64 pll_freq;
+       u64 divider;
+       u64 dec, dec_multiple;
+       u32 frac;
+       u64 multiplier;
+
+       pll_freq = pll->vco_current_rate;
+
+       if (config->disable_prescaler)
+               divider = fref;
+       else
+               divider = fref * 2;
+
+       multiplier = 1 << config->frac_bits;
+       dec_multiple = div_u64(pll_freq * multiplier, divider);
+       div_u64_rem(dec_multiple, multiplier, &frac);
+
+       dec = div_u64(dec_multiple, multiplier);
+
+       if (pll->base.type != MSM_DSI_PHY_7NM_V4_1)
+               regs->pll_clock_inverters = 0x28;
+       else if (pll_freq <= 1000000000ULL)
+               regs->pll_clock_inverters = 0xa0;
+       else if (pll_freq <= 2500000000ULL)
+               regs->pll_clock_inverters = 0x20;
+       else if (pll_freq <= 3020000000ULL)
+               regs->pll_clock_inverters = 0x00;
+       else
+               regs->pll_clock_inverters = 0x40;
+
+       regs->pll_lockdet_rate = config->lock_timer;
+       regs->decimal_div_start = dec;
+       regs->frac_div_start_low = (frac & 0xff);
+       regs->frac_div_start_mid = (frac & 0xff00) >> 8;
+       regs->frac_div_start_high = (frac & 0x30000) >> 16;
+}
+
+#define SSC_CENTER             BIT(0)
+#define SSC_EN                 BIT(1)
+
+static void dsi_pll_calc_ssc(struct dsi_pll_7nm *pll)
+{
+       struct dsi_pll_config *config = &pll->pll_configuration;
+       struct dsi_pll_regs *regs = &pll->reg_setup;
+       u32 ssc_per;
+       u32 ssc_mod;
+       u64 ssc_step_size;
+       u64 frac;
+
+       if (!config->enable_ssc) {
+               DBG("SSC not enabled\n");
+               return;
+       }
+
+       ssc_per = DIV_ROUND_CLOSEST(config->ref_freq, config->ssc_freq) / 2 - 1;
+       ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1);
+       ssc_per -= ssc_mod;
+
+       frac = regs->frac_div_start_low |
+                       (regs->frac_div_start_mid << 8) |
+                       (regs->frac_div_start_high << 16);
+       ssc_step_size = regs->decimal_div_start;
+       ssc_step_size *= (1 << config->frac_bits);
+       ssc_step_size += frac;
+       ssc_step_size *= config->ssc_offset;
+       ssc_step_size *= (config->ssc_adj_per + 1);
+       ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1));
+       ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000);
+
+       regs->ssc_div_per_low = ssc_per & 0xFF;
+       regs->ssc_div_per_high = (ssc_per & 0xFF00) >> 8;
+       regs->ssc_stepsize_low = (u32)(ssc_step_size & 0xFF);
+       regs->ssc_stepsize_high = (u32)((ssc_step_size & 0xFF00) >> 8);
+       regs->ssc_adjper_low = config->ssc_adj_per & 0xFF;
+       regs->ssc_adjper_high = (config->ssc_adj_per & 0xFF00) >> 8;
+
+       regs->ssc_control = config->ssc_center ? SSC_CENTER : 0;
+
+       pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n",
+                regs->decimal_div_start, frac, config->frac_bits);
+       pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n",
+                ssc_per, (u32)ssc_step_size, config->ssc_adj_per);
+}
+
+static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll)
+{
+       void __iomem *base = pll->mmio;
+       struct dsi_pll_regs *regs = &pll->reg_setup;
+
+       if (pll->pll_configuration.enable_ssc) {
+               pr_debug("SSC is enabled\n");
+
+               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_LOW_1,
+                         regs->ssc_stepsize_low);
+               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_HIGH_1,
+                         regs->ssc_stepsize_high);
+               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_LOW_1,
+                         regs->ssc_div_per_low);
+               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_HIGH_1,
+                         regs->ssc_div_per_high);
+               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_LOW_1,
+                         regs->ssc_adjper_low);
+               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_HIGH_1,
+                         regs->ssc_adjper_high);
+               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_CONTROL,
+                         SSC_EN | regs->ssc_control);
+       }
+}
+
+static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll)
+{
+       void __iomem *base = pll->mmio;
+       u8 analog_controls_five_1 = 0x01, vco_config_1 = 0x00;
+
+       if (pll->base.type == MSM_DSI_PHY_7NM_V4_1) {
+               if (pll->vco_current_rate >= 3100000000ULL)
+                       analog_controls_five_1 = 0x03;
+
+               if (pll->vco_current_rate < 1520000000ULL)
+                       vco_config_1 = 0x08;
+               else if (pll->vco_current_rate < 2990000000ULL)
+                       vco_config_1 = 0x01;
+       }
+
+       pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1,
+                 analog_controls_five_1);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_VCO_CONFIG_1, vco_config_1);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE, 0x01);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_DSM_DIVIDER, 0x00);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE, 0xba);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_OUTDIV, 0x00);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_CORE_OVERRIDE, 0x00);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x0a);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_BAND_SEL_RATE_1, 0xc0);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x84);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x82);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x4c);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x29);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x2f);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_IFILT, 0x2a);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_IFILT,
+                 pll->base.type == MSM_DSI_PHY_7NM_V4_1 ? 0x3f : 0x22);
+
+       if (pll->base.type == MSM_DSI_PHY_7NM_V4_1) {
+               pll_write(base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
+               if (pll->slave)
+                       pll_write(pll->slave->mmio + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
+       }
+}
+
+static void dsi_pll_commit(struct dsi_pll_7nm *pll)
+{
+       void __iomem *base = pll->mmio;
+       struct dsi_pll_regs *reg = &pll->reg_setup;
+
+       pll_write(base + REG_DSI_7nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1, reg->decimal_div_start);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1, reg->frac_div_start_low);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1, reg->frac_div_start_mid);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1, reg->frac_div_start_high);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, reg->pll_lockdet_rate);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06);
+       pll_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, 0x10); /* TODO: 0x00 for CPHY */
+       pll_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, reg->pll_clock_inverters);
+}
+
+static int dsi_pll_7nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
+                                    unsigned long parent_rate)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
+
+       DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_7nm->id, rate,
+           parent_rate);
+
+       pll_7nm->vco_current_rate = rate;
+       pll_7nm->vco_ref_clk_rate = VCO_REF_CLK_RATE;
+
+       dsi_pll_setup_config(pll_7nm);
+
+       dsi_pll_calc_dec_frac(pll_7nm);
+
+       dsi_pll_calc_ssc(pll_7nm);
+
+       dsi_pll_commit(pll_7nm);
+
+       dsi_pll_config_hzindep_reg(pll_7nm);
+
+       dsi_pll_ssc_commit(pll_7nm);
+
+       /* flush, ensure all register writes are done*/
+       wmb();
+
+       return 0;
+}
+
+static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm *pll)
+{
+       int rc;
+       u32 status = 0;
+       u32 const delay_us = 100;
+       u32 const timeout_us = 5000;
+
+       rc = readl_poll_timeout_atomic(pll->mmio +
+                                      REG_DSI_7nm_PHY_PLL_COMMON_STATUS_ONE,
+                                      status,
+                                      ((status & BIT(0)) > 0),
+                                      delay_us,
+                                      timeout_us);
+       if (rc)
+               pr_err("DSI PLL(%d) lock failed, status=0x%08x\n",
+                      pll->id, status);
+
+       return rc;
+}
+
+static void dsi_pll_disable_pll_bias(struct dsi_pll_7nm *pll)
+{
+       u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0);
+
+       pll_write(pll->mmio + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0);
+       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0, data & ~BIT(5));
+       ndelay(250);
+}
+
+static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll)
+{
+       u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0);
+
+       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0, data | BIT(5));
+       pll_write(pll->mmio + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0xc0);
+       ndelay(250);
+}
+
+static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll)
+{
+       u32 data;
+
+       data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
+       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data & ~BIT(5));
+}
+
+static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll)
+{
+       u32 data;
+
+       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x04);
+
+       data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
+       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1,
+                 data | BIT(5) | BIT(4));
+}
+
+static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll)
+{
+       /*
+        * Reset the PHY digital domain. This would be needed when
+        * coming out of a CX or analog rail power collapse while
+        * ensuring that the pads maintain LP00 or LP11 state
+        */
+       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0));
+       wmb(); /* Ensure that the reset is deasserted */
+       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, 0x0);
+       wmb(); /* Ensure that the reset is deasserted */
+}
+
+static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
+       int rc;
+
+       dsi_pll_enable_pll_bias(pll_7nm);
+       if (pll_7nm->slave)
+               dsi_pll_enable_pll_bias(pll_7nm->slave);
+
+       /* Start PLL */
+       pll_write(pll_7nm->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x01);
+
+       /*
+        * ensure all PLL configurations are written prior to checking
+        * for PLL lock.
+        */
+       wmb();
+
+       /* Check for PLL lock */
+       rc = dsi_pll_7nm_lock_status(pll_7nm);
+       if (rc) {
+               pr_err("PLL(%d) lock failed\n", pll_7nm->id);
+               goto error;
+       }
+
+       pll->pll_on = true;
+
+       /*
+        * assert power on reset for PHY digital in case the PLL is
+        * enabled after CX of analog domain power collapse. This needs
+        * to be done before enabling the global clk.
+        */
+       dsi_pll_phy_dig_reset(pll_7nm);
+       if (pll_7nm->slave)
+               dsi_pll_phy_dig_reset(pll_7nm->slave);
+
+       dsi_pll_enable_global_clk(pll_7nm);
+       if (pll_7nm->slave)
+               dsi_pll_enable_global_clk(pll_7nm->slave);
+
+error:
+       return rc;
+}
+
+static void dsi_pll_disable_sub(struct dsi_pll_7nm *pll)
+{
+       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0);
+       dsi_pll_disable_pll_bias(pll);
+}
+
+static void dsi_pll_7nm_vco_unprepare(struct clk_hw *hw)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
+
+       /*
+        * To avoid any stray glitches while abruptly powering down the PLL
+        * make sure to gate the clock using the clock enable bit before
+        * powering down the PLL
+        */
+       dsi_pll_disable_global_clk(pll_7nm);
+       pll_write(pll_7nm->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0);
+       dsi_pll_disable_sub(pll_7nm);
+       if (pll_7nm->slave) {
+               dsi_pll_disable_global_clk(pll_7nm->slave);
+               dsi_pll_disable_sub(pll_7nm->slave);
+       }
+       /* flush, ensure all register writes are done */
+       wmb();
+       pll->pll_on = false;
+}
+
+static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw,
+                                                 unsigned long parent_rate)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
+       struct dsi_pll_config *config = &pll_7nm->pll_configuration;
+       void __iomem *base = pll_7nm->mmio;
+       u64 ref_clk = pll_7nm->vco_ref_clk_rate;
+       u64 vco_rate = 0x0;
+       u64 multiplier;
+       u32 frac;
+       u32 dec;
+       u64 pll_freq, tmp64;
+
+       dec = pll_read(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1);
+       dec &= 0xff;
+
+       frac = pll_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1);
+       frac |= ((pll_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1) &
+                 0xff) << 8);
+       frac |= ((pll_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1) &
+                 0x3) << 16);
+
+       /*
+        * TODO:
+        *      1. Assumes prescaler is disabled
+        */
+       multiplier = 1 << config->frac_bits;
+       pll_freq = dec * (ref_clk * 2);
+       tmp64 = (ref_clk * 2 * frac);
+       pll_freq += div_u64(tmp64, multiplier);
+
+       vco_rate = pll_freq;
+
+       DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x",
+           pll_7nm->id, (unsigned long)vco_rate, dec, frac);
+
+       return (unsigned long)vco_rate;
+}
+
+static const struct clk_ops clk_ops_dsi_pll_7nm_vco = {
+       .round_rate = msm_dsi_pll_helper_clk_round_rate,
+       .set_rate = dsi_pll_7nm_vco_set_rate,
+       .recalc_rate = dsi_pll_7nm_vco_recalc_rate,
+       .prepare = dsi_pll_7nm_vco_prepare,
+       .unprepare = dsi_pll_7nm_vco_unprepare,
+};
+
+/*
+ * PLL Callbacks
+ */
+
+static void dsi_pll_7nm_save_state(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
+       struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;
+       void __iomem *phy_base = pll_7nm->phy_cmn_mmio;
+       u32 cmn_clk_cfg0, cmn_clk_cfg1;
+
+       cached->pll_out_div = pll_read(pll_7nm->mmio +
+                                      REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);
+       cached->pll_out_div &= 0x3;
+
+       cmn_clk_cfg0 = pll_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0);
+       cached->bit_clk_div = cmn_clk_cfg0 & 0xf;
+       cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4;
+
+       cmn_clk_cfg1 = pll_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
+       cached->pll_mux = cmn_clk_cfg1 & 0x3;
+
+       DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x",
+           pll_7nm->id, cached->pll_out_div, cached->bit_clk_div,
+           cached->pix_clk_div, cached->pll_mux);
+}
+
+static int dsi_pll_7nm_restore_state(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
+       struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;
+       void __iomem *phy_base = pll_7nm->phy_cmn_mmio;
+       u32 val;
+       int ret;
+
+       val = pll_read(pll_7nm->mmio + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);
+       val &= ~0x3;
+       val |= cached->pll_out_div;
+       pll_write(pll_7nm->mmio + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, val);
+
+       pll_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0,
+                 cached->bit_clk_div | (cached->pix_clk_div << 4));
+
+       val = pll_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
+       val &= ~0x3;
+       val |= cached->pll_mux;
+       pll_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, val);
+
+       ret = dsi_pll_7nm_vco_set_rate(&pll->clk_hw, pll_7nm->vco_current_rate, pll_7nm->vco_ref_clk_rate);
+       if (ret) {
+               DRM_DEV_ERROR(&pll_7nm->pdev->dev,
+                       "restore vco rate failed. ret=%d\n", ret);
+               return ret;
+       }
+
+       DBG("DSI PLL%d", pll_7nm->id);
+
+       return 0;
+}
+
+static int dsi_pll_7nm_set_usecase(struct msm_dsi_pll *pll,
+                                   enum msm_dsi_phy_usecase uc)
+{
+       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
+       void __iomem *base = pll_7nm->phy_cmn_mmio;
+       u32 data = 0x0; /* internal PLL */
+
+       DBG("DSI PLL%d", pll_7nm->id);
+
+       switch (uc) {
+       case MSM_DSI_PHY_STANDALONE:
+               break;
+       case MSM_DSI_PHY_MASTER:
+               pll_7nm->slave = pll_7nm_list[(pll_7nm->id + 1) % DSI_MAX];
+               break;
+       case MSM_DSI_PHY_SLAVE:
+               data = 0x1; /* external PLL */
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* set PLL src */
+       pll_write(base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, (data << 2));
+
+       pll_7nm->uc = uc;
+
+       return 0;
+}
+
+static int dsi_pll_7nm_get_provider(struct msm_dsi_pll *pll,
+                                    struct clk **byte_clk_provider,
+                                    struct clk **pixel_clk_provider)
+{
+       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
+       struct clk_hw_onecell_data *hw_data = pll_7nm->hw_data;
+
+       DBG("DSI PLL%d", pll_7nm->id);
+
+       if (byte_clk_provider)
+               *byte_clk_provider = hw_data->hws[DSI_BYTE_PLL_CLK]->clk;
+       if (pixel_clk_provider)
+               *pixel_clk_provider = hw_data->hws[DSI_PIXEL_PLL_CLK]->clk;
+
+       return 0;
+}
+
+static void dsi_pll_7nm_destroy(struct msm_dsi_pll *pll)
+{
+       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
+       struct device *dev = &pll_7nm->pdev->dev;
+
+       DBG("DSI PLL%d", pll_7nm->id);
+       of_clk_del_provider(dev->of_node);
+
+       clk_hw_unregister_divider(pll_7nm->out_dsiclk_hw);
+       clk_hw_unregister_mux(pll_7nm->pclk_mux_hw);
+       clk_hw_unregister_fixed_factor(pll_7nm->post_out_div_clk_hw);
+       clk_hw_unregister_fixed_factor(pll_7nm->by_2_bit_clk_hw);
+       clk_hw_unregister_fixed_factor(pll_7nm->byte_clk_hw);
+       clk_hw_unregister_divider(pll_7nm->bit_clk_hw);
+       clk_hw_unregister_divider(pll_7nm->out_div_clk_hw);
+       clk_hw_unregister(&pll_7nm->base.clk_hw);
+}
+
+/*
+ * The post dividers and mux clocks are created using the standard divider and
+ * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux
+ * state to follow the master PLL's divider/mux state. Therefore, we don't
+ * require special clock ops that also configure the slave PLL registers
+ */
+static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm)
+{
+       char clk_name[32], parent[32], vco_name[32];
+       char parent2[32], parent3[32], parent4[32];
+       struct clk_init_data vco_init = {
+               .parent_names = (const char *[]){ "bi_tcxo" },
+               .num_parents = 1,
+               .name = vco_name,
+               .flags = CLK_IGNORE_UNUSED,
+               .ops = &clk_ops_dsi_pll_7nm_vco,
+       };
+       struct device *dev = &pll_7nm->pdev->dev;
+       struct clk_hw_onecell_data *hw_data;
+       struct clk_hw *hw;
+       int ret;
+
+       DBG("DSI%d", pll_7nm->id);
+
+       hw_data = devm_kzalloc(dev, sizeof(*hw_data) +
+                              NUM_PROVIDED_CLKS * sizeof(struct clk_hw *),
+                              GFP_KERNEL);
+       if (!hw_data)
+               return -ENOMEM;
+
+       snprintf(vco_name, 32, "dsi%dvco_clk", pll_7nm->id);
+       pll_7nm->base.clk_hw.init = &vco_init;
+
+       ret = clk_hw_register(dev, &pll_7nm->base.clk_hw);
+       if (ret)
+               return ret;
+
+       snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_7nm->id);
+       snprintf(parent, 32, "dsi%dvco_clk", pll_7nm->id);
+
+       hw = clk_hw_register_divider(dev, clk_name,
+                                    parent, CLK_SET_RATE_PARENT,
+                                    pll_7nm->mmio +
+                                    REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE,
+                                    0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_base_clk_hw;
+       }
+
+       pll_7nm->out_div_clk_hw = hw;
+
+       snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_7nm->id);
+       snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->id);
+
+       /* BIT CLK: DIV_CTRL_3_0 */
+       hw = clk_hw_register_divider(dev, clk_name, parent,
+                                    CLK_SET_RATE_PARENT,
+                                    pll_7nm->phy_cmn_mmio +
+                                    REG_DSI_7nm_PHY_CMN_CLK_CFG0,
+                                    0, 4, CLK_DIVIDER_ONE_BASED,
+                                    &pll_7nm->postdiv_lock);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_out_div_clk_hw;
+       }
+
+       pll_7nm->bit_clk_hw = hw;
+
+       snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_7nm->id);
+       snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id);
+
+       /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */
+       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
+                                         CLK_SET_RATE_PARENT, 1, 8);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_bit_clk_hw;
+       }
+
+       pll_7nm->byte_clk_hw = hw;
+       hw_data->hws[DSI_BYTE_PLL_CLK] = hw;
+
+       snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->id);
+       snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id);
+
+       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
+                                         0, 1, 2);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_byte_clk_hw;
+       }
+
+       pll_7nm->by_2_bit_clk_hw = hw;
+
+       snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->id);
+       snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->id);
+
+       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
+                                         0, 1, 4);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_by_2_bit_clk_hw;
+       }
+
+       pll_7nm->post_out_div_clk_hw = hw;
+
+       snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_7nm->id);
+       snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id);
+       snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->id);
+       snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_7nm->id);
+       snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->id);
+
+       hw = clk_hw_register_mux(dev, clk_name,
+                                ((const char *[]){
+                                parent, parent2, parent3, parent4
+                                }), 4, 0, pll_7nm->phy_cmn_mmio +
+                                REG_DSI_7nm_PHY_CMN_CLK_CFG1,
+                                0, 2, 0, NULL);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_post_out_div_clk_hw;
+       }
+
+       pll_7nm->pclk_mux_hw = hw;
+
+       snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_7nm->id);
+       snprintf(parent, 32, "dsi%d_pclk_mux", pll_7nm->id);
+
+       /* PIX CLK DIV : DIV_CTRL_7_4*/
+       hw = clk_hw_register_divider(dev, clk_name, parent,
+                                    0, pll_7nm->phy_cmn_mmio +
+                                       REG_DSI_7nm_PHY_CMN_CLK_CFG0,
+                                    4, 4, CLK_DIVIDER_ONE_BASED,
+                                    &pll_7nm->postdiv_lock);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto err_pclk_mux_hw;
+       }
+
+       pll_7nm->out_dsiclk_hw = hw;
+       hw_data->hws[DSI_PIXEL_PLL_CLK] = hw;
+
+       hw_data->num = NUM_PROVIDED_CLKS;
+       pll_7nm->hw_data = hw_data;
+
+       ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
+                                    pll_7nm->hw_data);
+       if (ret) {
+               DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
+               goto err_dsiclk_hw;
+       }
+
+       return 0;
+
+err_dsiclk_hw:
+       clk_hw_unregister_divider(pll_7nm->out_dsiclk_hw);
+err_pclk_mux_hw:
+       clk_hw_unregister_mux(pll_7nm->pclk_mux_hw);
+err_post_out_div_clk_hw:
+       clk_hw_unregister_fixed_factor(pll_7nm->post_out_div_clk_hw);
+err_by_2_bit_clk_hw:
+       clk_hw_unregister_fixed_factor(pll_7nm->by_2_bit_clk_hw);
+err_byte_clk_hw:
+       clk_hw_unregister_fixed_factor(pll_7nm->byte_clk_hw);
+err_bit_clk_hw:
+       clk_hw_unregister_divider(pll_7nm->bit_clk_hw);
+err_out_div_clk_hw:
+       clk_hw_unregister_divider(pll_7nm->out_div_clk_hw);
+err_base_clk_hw:
+       clk_hw_unregister(&pll_7nm->base.clk_hw);
+
+       return ret;
+}
+
+struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev,
+                                       enum msm_dsi_phy_type type, int id)
+{
+       struct dsi_pll_7nm *pll_7nm;
+       struct msm_dsi_pll *pll;
+       int ret;
+
+       pll_7nm = devm_kzalloc(&pdev->dev, sizeof(*pll_7nm), GFP_KERNEL);
+       if (!pll_7nm)
+               return ERR_PTR(-ENOMEM);
+
+       DBG("DSI PLL%d", id);
+
+       pll_7nm->pdev = pdev;
+       pll_7nm->id = id;
+       pll_7nm_list[id] = pll_7nm;
+
+       pll_7nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY");
+       if (IS_ERR_OR_NULL(pll_7nm->phy_cmn_mmio)) {
+               DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       pll_7nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL");
+       if (IS_ERR_OR_NULL(pll_7nm->mmio)) {
+               DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       spin_lock_init(&pll_7nm->postdiv_lock);
+
+       pll = &pll_7nm->base;
+       pll->min_rate = 1000000000UL;
+       pll->max_rate = 3500000000UL;
+       if (type == MSM_DSI_PHY_7NM_V4_1) {
+               pll->min_rate = 600000000UL;
+               pll->max_rate = (unsigned long)5000000000ULL;
+               /* workaround for max rate overflowing on 32-bit builds: */
+               pll->max_rate = max(pll->max_rate, 0xffffffffUL);
+       }
+       pll->get_provider = dsi_pll_7nm_get_provider;
+       pll->destroy = dsi_pll_7nm_destroy;
+       pll->save_state = dsi_pll_7nm_save_state;
+       pll->restore_state = dsi_pll_7nm_restore_state;
+       pll->set_usecase = dsi_pll_7nm_set_usecase;
+
+       pll_7nm->vco_delay = 1;
+
+       ret = pll_7nm_register(pll_7nm);
+       if (ret) {
+               DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
+               return ERR_PTR(ret);
+       }
+
+       /* TODO: Remove this when we have proper display handover support */
+       msm_dsi_pll_save_state(pll);
+
+       return pll;
+}
+
 static int dsi_phy_hw_v4_0_is_pll_on(struct msm_dsi_phy *phy)
 {
        void __iomem *base = phy->base;
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_pll.c b/drivers/gpu/drm/msm/dsi/phy/dsi_pll.c
new file mode 100644 (file)
index 0000000..3dc6587
--- /dev/null
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ */
+
+#include "dsi_pll.h"
+
+static int dsi_pll_enable(struct msm_dsi_pll *pll)
+{
+       int i, ret = 0;
+
+       /*
+        * Certain PLLs do not allow VCO rate update when it is on.
+        * Keep track of their status to turn on/off after set rate success.
+        */
+       if (unlikely(pll->pll_on))
+               return 0;
+
+       /* Try all enable sequences until one succeeds */
+       for (i = 0; i < pll->en_seq_cnt; i++) {
+               ret = pll->enable_seqs[i](pll);
+               DBG("DSI PLL %s after sequence #%d",
+                       ret ? "unlocked" : "locked", i + 1);
+               if (!ret)
+                       break;
+       }
+
+       if (ret) {
+               DRM_ERROR("DSI PLL failed to lock\n");
+               return ret;
+       }
+
+       pll->pll_on = true;
+
+       return 0;
+}
+
+static void dsi_pll_disable(struct msm_dsi_pll *pll)
+{
+       if (unlikely(!pll->pll_on))
+               return;
+
+       pll->disable_seq(pll);
+
+       pll->pll_on = false;
+}
+
+/*
+ * DSI PLL Helper functions
+ */
+long msm_dsi_pll_helper_clk_round_rate(struct clk_hw *hw,
+               unsigned long rate, unsigned long *parent_rate)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+
+       if      (rate < pll->min_rate)
+               return  pll->min_rate;
+       else if (rate > pll->max_rate)
+               return  pll->max_rate;
+       else
+               return rate;
+}
+
+int msm_dsi_pll_helper_clk_prepare(struct clk_hw *hw)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+
+       return dsi_pll_enable(pll);
+}
+
+void msm_dsi_pll_helper_clk_unprepare(struct clk_hw *hw)
+{
+       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
+
+       dsi_pll_disable(pll);
+}
+
+void msm_dsi_pll_helper_unregister_clks(struct platform_device *pdev,
+                                       struct clk **clks, u32 num_clks)
+{
+       of_clk_del_provider(pdev->dev.of_node);
+
+       if (!num_clks || !clks)
+               return;
+
+       do {
+               clk_unregister(clks[--num_clks]);
+               clks[num_clks] = NULL;
+       } while (num_clks);
+}
+
+/*
+ * DSI PLL API
+ */
+int msm_dsi_pll_get_clk_provider(struct msm_dsi_pll *pll,
+       struct clk **byte_clk_provider, struct clk **pixel_clk_provider)
+{
+       if (pll->get_provider)
+               return pll->get_provider(pll,
+                                       byte_clk_provider,
+                                       pixel_clk_provider);
+
+       return -EINVAL;
+}
+
+void msm_dsi_pll_destroy(struct msm_dsi_pll *pll)
+{
+       if (pll->destroy)
+               pll->destroy(pll);
+}
+
+void msm_dsi_pll_save_state(struct msm_dsi_pll *pll)
+{
+       if (pll->save_state) {
+               pll->save_state(pll);
+               pll->state_saved = true;
+       }
+}
+
+int msm_dsi_pll_restore_state(struct msm_dsi_pll *pll)
+{
+       int ret;
+
+       if (pll->restore_state && pll->state_saved) {
+               ret = pll->restore_state(pll);
+               if (ret)
+                       return ret;
+
+               pll->state_saved = false;
+       }
+
+       return 0;
+}
+
+int msm_dsi_pll_set_usecase(struct msm_dsi_pll *pll,
+                           enum msm_dsi_phy_usecase uc)
+{
+       if (pll->set_usecase)
+               return pll->set_usecase(pll, uc);
+
+       return 0;
+}
+
+struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev,
+                       enum msm_dsi_phy_type type, int id)
+{
+       struct device *dev = &pdev->dev;
+       struct msm_dsi_pll *pll;
+
+       switch (type) {
+       case MSM_DSI_PHY_28NM_HPM:
+       case MSM_DSI_PHY_28NM_LP:
+               pll = msm_dsi_pll_28nm_init(pdev, type, id);
+               break;
+       case MSM_DSI_PHY_28NM_8960:
+               pll = msm_dsi_pll_28nm_8960_init(pdev, id);
+               break;
+       case MSM_DSI_PHY_14NM:
+               pll = msm_dsi_pll_14nm_init(pdev, id);
+               break;
+       case MSM_DSI_PHY_10NM:
+               pll = msm_dsi_pll_10nm_init(pdev, id);
+               break;
+       case MSM_DSI_PHY_7NM:
+       case MSM_DSI_PHY_7NM_V4_1:
+               pll = msm_dsi_pll_7nm_init(pdev, type, id);
+               break;
+       default:
+               pll = ERR_PTR(-ENXIO);
+               break;
+       }
+
+       if (IS_ERR(pll)) {
+               DRM_DEV_ERROR(dev, "%s: failed to init DSI PLL\n", __func__);
+               return pll;
+       }
+
+       pll->type = type;
+
+       DBG("DSI:%d PLL registered", id);
+
+       return pll;
+}
+
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_pll.h b/drivers/gpu/drm/msm/dsi/phy/dsi_pll.h
new file mode 100644 (file)
index 0000000..bbecb1d
--- /dev/null
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __DSI_PLL_H__
+#define __DSI_PLL_H__
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+
+#include "dsi.h"
+
+#define NUM_DSI_CLOCKS_MAX     6
+#define MAX_DSI_PLL_EN_SEQS    10
+
+struct msm_dsi_pll {
+       enum msm_dsi_phy_type type;
+
+       struct clk_hw   clk_hw;
+       bool            pll_on;
+       bool            state_saved;
+
+       unsigned long   min_rate;
+       unsigned long   max_rate;
+       u32             en_seq_cnt;
+
+       int (*enable_seqs[MAX_DSI_PLL_EN_SEQS])(struct msm_dsi_pll *pll);
+       void (*disable_seq)(struct msm_dsi_pll *pll);
+       int (*get_provider)(struct msm_dsi_pll *pll,
+                       struct clk **byte_clk_provider,
+                       struct clk **pixel_clk_provider);
+       void (*destroy)(struct msm_dsi_pll *pll);
+       void (*save_state)(struct msm_dsi_pll *pll);
+       int (*restore_state)(struct msm_dsi_pll *pll);
+       int (*set_usecase)(struct msm_dsi_pll *pll,
+                          enum msm_dsi_phy_usecase uc);
+};
+
+#define hw_clk_to_pll(x) container_of(x, struct msm_dsi_pll, clk_hw)
+
+static inline void pll_write(void __iomem *reg, u32 data)
+{
+       msm_writel(data, reg);
+}
+
+static inline u32 pll_read(const void __iomem *reg)
+{
+       return msm_readl(reg);
+}
+
+static inline void pll_write_udelay(void __iomem *reg, u32 data, u32 delay_us)
+{
+       pll_write(reg, data);
+       udelay(delay_us);
+}
+
+static inline void pll_write_ndelay(void __iomem *reg, u32 data, u32 delay_ns)
+{
+       pll_write((reg), data);
+       ndelay(delay_ns);
+}
+
+/*
+ * DSI PLL Helper functions
+ */
+
+/* clock callbacks */
+long msm_dsi_pll_helper_clk_round_rate(struct clk_hw *hw,
+               unsigned long rate, unsigned long *parent_rate);
+int msm_dsi_pll_helper_clk_prepare(struct clk_hw *hw);
+void msm_dsi_pll_helper_clk_unprepare(struct clk_hw *hw);
+/* misc */
+void msm_dsi_pll_helper_unregister_clks(struct platform_device *pdev,
+                                       struct clk **clks, u32 num_clks);
+
+/*
+ * Initialization for Each PLL Type
+ */
+#ifdef CONFIG_DRM_MSM_DSI_28NM_PHY
+struct msm_dsi_pll *msm_dsi_pll_28nm_init(struct platform_device *pdev,
+                                       enum msm_dsi_phy_type type, int id);
+#else
+static inline struct msm_dsi_pll *msm_dsi_pll_28nm_init(
+       struct platform_device *pdev, enum msm_dsi_phy_type type, int id)
+{
+       return ERR_PTR(-ENODEV);
+}
+#endif
+#ifdef CONFIG_DRM_MSM_DSI_28NM_8960_PHY
+struct msm_dsi_pll *msm_dsi_pll_28nm_8960_init(struct platform_device *pdev,
+                                              int id);
+#else
+static inline struct msm_dsi_pll *msm_dsi_pll_28nm_8960_init(
+       struct platform_device *pdev, int id)
+{
+       return ERR_PTR(-ENODEV);
+}
+#endif
+
+#ifdef CONFIG_DRM_MSM_DSI_14NM_PHY
+struct msm_dsi_pll *msm_dsi_pll_14nm_init(struct platform_device *pdev, int id);
+#else
+static inline struct msm_dsi_pll *
+msm_dsi_pll_14nm_init(struct platform_device *pdev, int id)
+{
+       return ERR_PTR(-ENODEV);
+}
+#endif
+#ifdef CONFIG_DRM_MSM_DSI_10NM_PHY
+struct msm_dsi_pll *msm_dsi_pll_10nm_init(struct platform_device *pdev, int id);
+#else
+static inline struct msm_dsi_pll *
+msm_dsi_pll_10nm_init(struct platform_device *pdev, int id)
+{
+       return ERR_PTR(-ENODEV);
+}
+#endif
+#ifdef CONFIG_DRM_MSM_DSI_7NM_PHY
+struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev,
+                                       enum msm_dsi_phy_type type, int id);
+#else
+static inline struct msm_dsi_pll *
+msm_dsi_pll_7nm_init(struct platform_device *pdev,
+                                       enum msm_dsi_phy_type type, int id)
+{
+       return ERR_PTR(-ENODEV);
+}
+#endif
+
+#endif /* __DSI_PLL_H__ */
+
diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c
deleted file mode 100644 (file)
index 3dc6587..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
- */
-
-#include "dsi_pll.h"
-
-static int dsi_pll_enable(struct msm_dsi_pll *pll)
-{
-       int i, ret = 0;
-
-       /*
-        * Certain PLLs do not allow VCO rate update when it is on.
-        * Keep track of their status to turn on/off after set rate success.
-        */
-       if (unlikely(pll->pll_on))
-               return 0;
-
-       /* Try all enable sequences until one succeeds */
-       for (i = 0; i < pll->en_seq_cnt; i++) {
-               ret = pll->enable_seqs[i](pll);
-               DBG("DSI PLL %s after sequence #%d",
-                       ret ? "unlocked" : "locked", i + 1);
-               if (!ret)
-                       break;
-       }
-
-       if (ret) {
-               DRM_ERROR("DSI PLL failed to lock\n");
-               return ret;
-       }
-
-       pll->pll_on = true;
-
-       return 0;
-}
-
-static void dsi_pll_disable(struct msm_dsi_pll *pll)
-{
-       if (unlikely(!pll->pll_on))
-               return;
-
-       pll->disable_seq(pll);
-
-       pll->pll_on = false;
-}
-
-/*
- * DSI PLL Helper functions
- */
-long msm_dsi_pll_helper_clk_round_rate(struct clk_hw *hw,
-               unsigned long rate, unsigned long *parent_rate)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-
-       if      (rate < pll->min_rate)
-               return  pll->min_rate;
-       else if (rate > pll->max_rate)
-               return  pll->max_rate;
-       else
-               return rate;
-}
-
-int msm_dsi_pll_helper_clk_prepare(struct clk_hw *hw)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-
-       return dsi_pll_enable(pll);
-}
-
-void msm_dsi_pll_helper_clk_unprepare(struct clk_hw *hw)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-
-       dsi_pll_disable(pll);
-}
-
-void msm_dsi_pll_helper_unregister_clks(struct platform_device *pdev,
-                                       struct clk **clks, u32 num_clks)
-{
-       of_clk_del_provider(pdev->dev.of_node);
-
-       if (!num_clks || !clks)
-               return;
-
-       do {
-               clk_unregister(clks[--num_clks]);
-               clks[num_clks] = NULL;
-       } while (num_clks);
-}
-
-/*
- * DSI PLL API
- */
-int msm_dsi_pll_get_clk_provider(struct msm_dsi_pll *pll,
-       struct clk **byte_clk_provider, struct clk **pixel_clk_provider)
-{
-       if (pll->get_provider)
-               return pll->get_provider(pll,
-                                       byte_clk_provider,
-                                       pixel_clk_provider);
-
-       return -EINVAL;
-}
-
-void msm_dsi_pll_destroy(struct msm_dsi_pll *pll)
-{
-       if (pll->destroy)
-               pll->destroy(pll);
-}
-
-void msm_dsi_pll_save_state(struct msm_dsi_pll *pll)
-{
-       if (pll->save_state) {
-               pll->save_state(pll);
-               pll->state_saved = true;
-       }
-}
-
-int msm_dsi_pll_restore_state(struct msm_dsi_pll *pll)
-{
-       int ret;
-
-       if (pll->restore_state && pll->state_saved) {
-               ret = pll->restore_state(pll);
-               if (ret)
-                       return ret;
-
-               pll->state_saved = false;
-       }
-
-       return 0;
-}
-
-int msm_dsi_pll_set_usecase(struct msm_dsi_pll *pll,
-                           enum msm_dsi_phy_usecase uc)
-{
-       if (pll->set_usecase)
-               return pll->set_usecase(pll, uc);
-
-       return 0;
-}
-
-struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev,
-                       enum msm_dsi_phy_type type, int id)
-{
-       struct device *dev = &pdev->dev;
-       struct msm_dsi_pll *pll;
-
-       switch (type) {
-       case MSM_DSI_PHY_28NM_HPM:
-       case MSM_DSI_PHY_28NM_LP:
-               pll = msm_dsi_pll_28nm_init(pdev, type, id);
-               break;
-       case MSM_DSI_PHY_28NM_8960:
-               pll = msm_dsi_pll_28nm_8960_init(pdev, id);
-               break;
-       case MSM_DSI_PHY_14NM:
-               pll = msm_dsi_pll_14nm_init(pdev, id);
-               break;
-       case MSM_DSI_PHY_10NM:
-               pll = msm_dsi_pll_10nm_init(pdev, id);
-               break;
-       case MSM_DSI_PHY_7NM:
-       case MSM_DSI_PHY_7NM_V4_1:
-               pll = msm_dsi_pll_7nm_init(pdev, type, id);
-               break;
-       default:
-               pll = ERR_PTR(-ENXIO);
-               break;
-       }
-
-       if (IS_ERR(pll)) {
-               DRM_DEV_ERROR(dev, "%s: failed to init DSI PLL\n", __func__);
-               return pll;
-       }
-
-       pll->type = type;
-
-       DBG("DSI:%d PLL registered", id);
-
-       return pll;
-}
-
diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h
deleted file mode 100644 (file)
index bbecb1d..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
- */
-
-#ifndef __DSI_PLL_H__
-#define __DSI_PLL_H__
-
-#include <linux/clk-provider.h>
-#include <linux/delay.h>
-
-#include "dsi.h"
-
-#define NUM_DSI_CLOCKS_MAX     6
-#define MAX_DSI_PLL_EN_SEQS    10
-
-struct msm_dsi_pll {
-       enum msm_dsi_phy_type type;
-
-       struct clk_hw   clk_hw;
-       bool            pll_on;
-       bool            state_saved;
-
-       unsigned long   min_rate;
-       unsigned long   max_rate;
-       u32             en_seq_cnt;
-
-       int (*enable_seqs[MAX_DSI_PLL_EN_SEQS])(struct msm_dsi_pll *pll);
-       void (*disable_seq)(struct msm_dsi_pll *pll);
-       int (*get_provider)(struct msm_dsi_pll *pll,
-                       struct clk **byte_clk_provider,
-                       struct clk **pixel_clk_provider);
-       void (*destroy)(struct msm_dsi_pll *pll);
-       void (*save_state)(struct msm_dsi_pll *pll);
-       int (*restore_state)(struct msm_dsi_pll *pll);
-       int (*set_usecase)(struct msm_dsi_pll *pll,
-                          enum msm_dsi_phy_usecase uc);
-};
-
-#define hw_clk_to_pll(x) container_of(x, struct msm_dsi_pll, clk_hw)
-
-static inline void pll_write(void __iomem *reg, u32 data)
-{
-       msm_writel(data, reg);
-}
-
-static inline u32 pll_read(const void __iomem *reg)
-{
-       return msm_readl(reg);
-}
-
-static inline void pll_write_udelay(void __iomem *reg, u32 data, u32 delay_us)
-{
-       pll_write(reg, data);
-       udelay(delay_us);
-}
-
-static inline void pll_write_ndelay(void __iomem *reg, u32 data, u32 delay_ns)
-{
-       pll_write((reg), data);
-       ndelay(delay_ns);
-}
-
-/*
- * DSI PLL Helper functions
- */
-
-/* clock callbacks */
-long msm_dsi_pll_helper_clk_round_rate(struct clk_hw *hw,
-               unsigned long rate, unsigned long *parent_rate);
-int msm_dsi_pll_helper_clk_prepare(struct clk_hw *hw);
-void msm_dsi_pll_helper_clk_unprepare(struct clk_hw *hw);
-/* misc */
-void msm_dsi_pll_helper_unregister_clks(struct platform_device *pdev,
-                                       struct clk **clks, u32 num_clks);
-
-/*
- * Initialization for Each PLL Type
- */
-#ifdef CONFIG_DRM_MSM_DSI_28NM_PHY
-struct msm_dsi_pll *msm_dsi_pll_28nm_init(struct platform_device *pdev,
-                                       enum msm_dsi_phy_type type, int id);
-#else
-static inline struct msm_dsi_pll *msm_dsi_pll_28nm_init(
-       struct platform_device *pdev, enum msm_dsi_phy_type type, int id)
-{
-       return ERR_PTR(-ENODEV);
-}
-#endif
-#ifdef CONFIG_DRM_MSM_DSI_28NM_8960_PHY
-struct msm_dsi_pll *msm_dsi_pll_28nm_8960_init(struct platform_device *pdev,
-                                              int id);
-#else
-static inline struct msm_dsi_pll *msm_dsi_pll_28nm_8960_init(
-       struct platform_device *pdev, int id)
-{
-       return ERR_PTR(-ENODEV);
-}
-#endif
-
-#ifdef CONFIG_DRM_MSM_DSI_14NM_PHY
-struct msm_dsi_pll *msm_dsi_pll_14nm_init(struct platform_device *pdev, int id);
-#else
-static inline struct msm_dsi_pll *
-msm_dsi_pll_14nm_init(struct platform_device *pdev, int id)
-{
-       return ERR_PTR(-ENODEV);
-}
-#endif
-#ifdef CONFIG_DRM_MSM_DSI_10NM_PHY
-struct msm_dsi_pll *msm_dsi_pll_10nm_init(struct platform_device *pdev, int id);
-#else
-static inline struct msm_dsi_pll *
-msm_dsi_pll_10nm_init(struct platform_device *pdev, int id)
-{
-       return ERR_PTR(-ENODEV);
-}
-#endif
-#ifdef CONFIG_DRM_MSM_DSI_7NM_PHY
-struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev,
-                                       enum msm_dsi_phy_type type, int id);
-#else
-static inline struct msm_dsi_pll *
-msm_dsi_pll_7nm_init(struct platform_device *pdev,
-                                       enum msm_dsi_phy_type type, int id)
-{
-       return ERR_PTR(-ENODEV);
-}
-#endif
-
-#endif /* __DSI_PLL_H__ */
-
diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
deleted file mode 100644 (file)
index de3b802..0000000
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * SPDX-License-Identifier: GPL-2.0
- * Copyright (c) 2018, The Linux Foundation
- */
-
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-#include <linux/iopoll.h>
-
-#include "dsi_pll.h"
-#include "dsi.xml.h"
-
-/*
- * DSI PLL 10nm - clock diagram (eg: DSI0):
- *
- *           dsi0_pll_out_div_clk  dsi0_pll_bit_clk
- *                              |                |
- *                              |                |
- *                 +---------+  |  +----------+  |  +----+
- *  dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk
- *                 +---------+  |  +----------+  |  +----+
- *                              |                |
- *                              |                |         dsi0_pll_by_2_bit_clk
- *                              |                |          |
- *                              |                |  +----+  |  |\  dsi0_pclk_mux
- *                              |                |--| /2 |--o--| \   |
- *                              |                |  +----+     |  \  |  +---------+
- *                              |                --------------|  |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk
- *                              |------------------------------|  /     +---------+
- *                              |          +-----+             | /
- *                              -----------| /4? |--o----------|/
- *                                         +-----+  |           |
- *                                                  |           |dsiclk_sel
- *                                                  |
- *                                                  dsi0_pll_post_out_div_clk
- */
-
-#define DSI_BYTE_PLL_CLK               0
-#define DSI_PIXEL_PLL_CLK              1
-#define NUM_PROVIDED_CLKS              2
-
-#define VCO_REF_CLK_RATE               19200000
-
-struct dsi_pll_regs {
-       u32 pll_prop_gain_rate;
-       u32 pll_lockdet_rate;
-       u32 decimal_div_start;
-       u32 frac_div_start_low;
-       u32 frac_div_start_mid;
-       u32 frac_div_start_high;
-       u32 pll_clock_inverters;
-       u32 ssc_stepsize_low;
-       u32 ssc_stepsize_high;
-       u32 ssc_div_per_low;
-       u32 ssc_div_per_high;
-       u32 ssc_adjper_low;
-       u32 ssc_adjper_high;
-       u32 ssc_control;
-};
-
-struct dsi_pll_config {
-       u32 ref_freq;
-       bool div_override;
-       u32 output_div;
-       bool ignore_frac;
-       bool disable_prescaler;
-       bool enable_ssc;
-       bool ssc_center;
-       u32 dec_bits;
-       u32 frac_bits;
-       u32 lock_timer;
-       u32 ssc_freq;
-       u32 ssc_offset;
-       u32 ssc_adj_per;
-       u32 thresh_cycles;
-       u32 refclk_cycles;
-};
-
-struct pll_10nm_cached_state {
-       unsigned long vco_rate;
-       u8 bit_clk_div;
-       u8 pix_clk_div;
-       u8 pll_out_div;
-       u8 pll_mux;
-};
-
-struct dsi_pll_10nm {
-       struct msm_dsi_pll base;
-
-       int id;
-       struct platform_device *pdev;
-
-       void __iomem *phy_cmn_mmio;
-       void __iomem *mmio;
-
-       u64 vco_ref_clk_rate;
-       u64 vco_current_rate;
-
-       /* protects REG_DSI_10nm_PHY_CMN_CLK_CFG0 register */
-       spinlock_t postdiv_lock;
-
-       int vco_delay;
-       struct dsi_pll_config pll_configuration;
-       struct dsi_pll_regs reg_setup;
-
-       /* private clocks: */
-       struct clk_hw *out_div_clk_hw;
-       struct clk_hw *bit_clk_hw;
-       struct clk_hw *byte_clk_hw;
-       struct clk_hw *by_2_bit_clk_hw;
-       struct clk_hw *post_out_div_clk_hw;
-       struct clk_hw *pclk_mux_hw;
-       struct clk_hw *out_dsiclk_hw;
-
-       /* clock-provider: */
-       struct clk_hw_onecell_data *hw_data;
-
-       struct pll_10nm_cached_state cached_state;
-
-       enum msm_dsi_phy_usecase uc;
-       struct dsi_pll_10nm *slave;
-};
-
-#define to_pll_10nm(x) container_of(x, struct dsi_pll_10nm, base)
-
-/*
- * Global list of private DSI PLL struct pointers. We need this for Dual DSI
- * mode, where the master PLL's clk_ops needs access the slave's private data
- */
-static struct dsi_pll_10nm *pll_10nm_list[DSI_MAX];
-
-static void dsi_pll_setup_config(struct dsi_pll_10nm *pll)
-{
-       struct dsi_pll_config *config = &pll->pll_configuration;
-
-       config->ref_freq = pll->vco_ref_clk_rate;
-       config->output_div = 1;
-       config->dec_bits = 8;
-       config->frac_bits = 18;
-       config->lock_timer = 64;
-       config->ssc_freq = 31500;
-       config->ssc_offset = 5000;
-       config->ssc_adj_per = 2;
-       config->thresh_cycles = 32;
-       config->refclk_cycles = 256;
-
-       config->div_override = false;
-       config->ignore_frac = false;
-       config->disable_prescaler = false;
-
-       config->enable_ssc = false;
-       config->ssc_center = 0;
-}
-
-static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll)
-{
-       struct dsi_pll_config *config = &pll->pll_configuration;
-       struct dsi_pll_regs *regs = &pll->reg_setup;
-       u64 fref = pll->vco_ref_clk_rate;
-       u64 pll_freq;
-       u64 divider;
-       u64 dec, dec_multiple;
-       u32 frac;
-       u64 multiplier;
-
-       pll_freq = pll->vco_current_rate;
-
-       if (config->disable_prescaler)
-               divider = fref;
-       else
-               divider = fref * 2;
-
-       multiplier = 1 << config->frac_bits;
-       dec_multiple = div_u64(pll_freq * multiplier, divider);
-       dec = div_u64_rem(dec_multiple, multiplier, &frac);
-
-       if (pll_freq <= 1900000000UL)
-               regs->pll_prop_gain_rate = 8;
-       else if (pll_freq <= 3000000000UL)
-               regs->pll_prop_gain_rate = 10;
-       else
-               regs->pll_prop_gain_rate = 12;
-       if (pll_freq < 1100000000UL)
-               regs->pll_clock_inverters = 8;
-       else
-               regs->pll_clock_inverters = 0;
-
-       regs->pll_lockdet_rate = config->lock_timer;
-       regs->decimal_div_start = dec;
-       regs->frac_div_start_low = (frac & 0xff);
-       regs->frac_div_start_mid = (frac & 0xff00) >> 8;
-       regs->frac_div_start_high = (frac & 0x30000) >> 16;
-}
-
-#define SSC_CENTER             BIT(0)
-#define SSC_EN                 BIT(1)
-
-static void dsi_pll_calc_ssc(struct dsi_pll_10nm *pll)
-{
-       struct dsi_pll_config *config = &pll->pll_configuration;
-       struct dsi_pll_regs *regs = &pll->reg_setup;
-       u32 ssc_per;
-       u32 ssc_mod;
-       u64 ssc_step_size;
-       u64 frac;
-
-       if (!config->enable_ssc) {
-               DBG("SSC not enabled\n");
-               return;
-       }
-
-       ssc_per = DIV_ROUND_CLOSEST(config->ref_freq, config->ssc_freq) / 2 - 1;
-       ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1);
-       ssc_per -= ssc_mod;
-
-       frac = regs->frac_div_start_low |
-                       (regs->frac_div_start_mid << 8) |
-                       (regs->frac_div_start_high << 16);
-       ssc_step_size = regs->decimal_div_start;
-       ssc_step_size *= (1 << config->frac_bits);
-       ssc_step_size += frac;
-       ssc_step_size *= config->ssc_offset;
-       ssc_step_size *= (config->ssc_adj_per + 1);
-       ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1));
-       ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000);
-
-       regs->ssc_div_per_low = ssc_per & 0xFF;
-       regs->ssc_div_per_high = (ssc_per & 0xFF00) >> 8;
-       regs->ssc_stepsize_low = (u32)(ssc_step_size & 0xFF);
-       regs->ssc_stepsize_high = (u32)((ssc_step_size & 0xFF00) >> 8);
-       regs->ssc_adjper_low = config->ssc_adj_per & 0xFF;
-       regs->ssc_adjper_high = (config->ssc_adj_per & 0xFF00) >> 8;
-
-       regs->ssc_control = config->ssc_center ? SSC_CENTER : 0;
-
-       pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n",
-                regs->decimal_div_start, frac, config->frac_bits);
-       pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n",
-                ssc_per, (u32)ssc_step_size, config->ssc_adj_per);
-}
-
-static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll)
-{
-       void __iomem *base = pll->mmio;
-       struct dsi_pll_regs *regs = &pll->reg_setup;
-
-       if (pll->pll_configuration.enable_ssc) {
-               pr_debug("SSC is enabled\n");
-
-               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_LOW_1,
-                         regs->ssc_stepsize_low);
-               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_HIGH_1,
-                         regs->ssc_stepsize_high);
-               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_LOW_1,
-                         regs->ssc_div_per_low);
-               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_HIGH_1,
-                         regs->ssc_div_per_high);
-               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_LOW_1,
-                         regs->ssc_adjper_low);
-               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_HIGH_1,
-                         regs->ssc_adjper_high);
-               pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_CONTROL,
-                         SSC_EN | regs->ssc_control);
-       }
-}
-
-static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll)
-{
-       void __iomem *base = pll->mmio;
-
-       pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_ONE, 0x80);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_DSM_DIVIDER, 0x00);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE,
-                 0xba);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_OUTDIV, 0x00);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_CORE_OVERRIDE, 0x00);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x08);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_BAND_SET_RATE_1, 0xc0);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0xfa);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1,
-                 0x4c);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_PFILT, 0x29);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_IFILT, 0x3f);
-}
-
-static void dsi_pll_commit(struct dsi_pll_10nm *pll)
-{
-       void __iomem *base = pll->mmio;
-       struct dsi_pll_regs *reg = &pll->reg_setup;
-
-       pll_write(base + REG_DSI_10nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1,
-                 reg->decimal_div_start);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1,
-                 reg->frac_div_start_low);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1,
-                 reg->frac_div_start_mid);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1,
-                 reg->frac_div_start_high);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCKDET_RATE_1,
-                 reg->pll_lockdet_rate);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_DELAY, 0x06);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_CMODE, 0x10);
-       pll_write(base + REG_DSI_10nm_PHY_PLL_CLOCK_INVERTERS,
-                 reg->pll_clock_inverters);
-}
-
-static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
-                                    unsigned long parent_rate)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
-
-       DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_10nm->id, rate,
-           parent_rate);
-
-       pll_10nm->vco_current_rate = rate;
-       pll_10nm->vco_ref_clk_rate = VCO_REF_CLK_RATE;
-
-       dsi_pll_setup_config(pll_10nm);
-
-       dsi_pll_calc_dec_frac(pll_10nm);
-
-       dsi_pll_calc_ssc(pll_10nm);
-
-       dsi_pll_commit(pll_10nm);
-
-       dsi_pll_config_hzindep_reg(pll_10nm);
-
-       dsi_pll_ssc_commit(pll_10nm);
-
-       /* flush, ensure all register writes are done*/
-       wmb();
-
-       return 0;
-}
-
-static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll)
-{
-       struct device *dev = &pll->pdev->dev;
-       int rc;
-       u32 status = 0;
-       u32 const delay_us = 100;
-       u32 const timeout_us = 5000;
-
-       rc = readl_poll_timeout_atomic(pll->mmio +
-                                      REG_DSI_10nm_PHY_PLL_COMMON_STATUS_ONE,
-                                      status,
-                                      ((status & BIT(0)) > 0),
-                                      delay_us,
-                                      timeout_us);
-       if (rc)
-               DRM_DEV_ERROR(dev, "DSI PLL(%d) lock failed, status=0x%08x\n",
-                             pll->id, status);
-
-       return rc;
-}
-
-static void dsi_pll_disable_pll_bias(struct dsi_pll_10nm *pll)
-{
-       u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0);
-
-       pll_write(pll->mmio + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0);
-       pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0,
-                 data & ~BIT(5));
-       ndelay(250);
-}
-
-static void dsi_pll_enable_pll_bias(struct dsi_pll_10nm *pll)
-{
-       u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0);
-
-       pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0,
-                 data | BIT(5));
-       pll_write(pll->mmio + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0xc0);
-       ndelay(250);
-}
-
-static void dsi_pll_disable_global_clk(struct dsi_pll_10nm *pll)
-{
-       u32 data;
-
-       data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
-       pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1,
-                 data & ~BIT(5));
-}
-
-static void dsi_pll_enable_global_clk(struct dsi_pll_10nm *pll)
-{
-       u32 data;
-
-       data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
-       pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1,
-                 data | BIT(5));
-}
-
-static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
-       struct device *dev = &pll_10nm->pdev->dev;
-       int rc;
-
-       dsi_pll_enable_pll_bias(pll_10nm);
-       if (pll_10nm->slave)
-               dsi_pll_enable_pll_bias(pll_10nm->slave);
-
-       rc = dsi_pll_10nm_vco_set_rate(hw,pll_10nm->vco_current_rate, 0);
-       if (rc) {
-               DRM_DEV_ERROR(dev, "vco_set_rate failed, rc=%d\n", rc);
-               return rc;
-       }
-
-       /* Start PLL */
-       pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_PLL_CNTRL,
-                 0x01);
-
-       /*
-        * ensure all PLL configurations are written prior to checking
-        * for PLL lock.
-        */
-       wmb();
-
-       /* Check for PLL lock */
-       rc = dsi_pll_10nm_lock_status(pll_10nm);
-       if (rc) {
-               DRM_DEV_ERROR(dev, "PLL(%d) lock failed\n", pll_10nm->id);
-               goto error;
-       }
-
-       pll->pll_on = true;
-
-       dsi_pll_enable_global_clk(pll_10nm);
-       if (pll_10nm->slave)
-               dsi_pll_enable_global_clk(pll_10nm->slave);
-
-       pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_RBUF_CTRL,
-                 0x01);
-       if (pll_10nm->slave)
-               pll_write(pll_10nm->slave->phy_cmn_mmio +
-                         REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0x01);
-
-error:
-       return rc;
-}
-
-static void dsi_pll_disable_sub(struct dsi_pll_10nm *pll)
-{
-       pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0);
-       dsi_pll_disable_pll_bias(pll);
-}
-
-static void dsi_pll_10nm_vco_unprepare(struct clk_hw *hw)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
-
-       /*
-        * To avoid any stray glitches while abruptly powering down the PLL
-        * make sure to gate the clock using the clock enable bit before
-        * powering down the PLL
-        */
-       dsi_pll_disable_global_clk(pll_10nm);
-       pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0);
-       dsi_pll_disable_sub(pll_10nm);
-       if (pll_10nm->slave) {
-               dsi_pll_disable_global_clk(pll_10nm->slave);
-               dsi_pll_disable_sub(pll_10nm->slave);
-       }
-       /* flush, ensure all register writes are done */
-       wmb();
-       pll->pll_on = false;
-}
-
-static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw,
-                                                 unsigned long parent_rate)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
-       struct dsi_pll_config *config = &pll_10nm->pll_configuration;
-       void __iomem *base = pll_10nm->mmio;
-       u64 ref_clk = pll_10nm->vco_ref_clk_rate;
-       u64 vco_rate = 0x0;
-       u64 multiplier;
-       u32 frac;
-       u32 dec;
-       u64 pll_freq, tmp64;
-
-       dec = pll_read(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1);
-       dec &= 0xff;
-
-       frac = pll_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1);
-       frac |= ((pll_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1) &
-                 0xff) << 8);
-       frac |= ((pll_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1) &
-                 0x3) << 16);
-
-       /*
-        * TODO:
-        *      1. Assumes prescaler is disabled
-        */
-       multiplier = 1 << config->frac_bits;
-       pll_freq = dec * (ref_clk * 2);
-       tmp64 = (ref_clk * 2 * frac);
-       pll_freq += div_u64(tmp64, multiplier);
-
-       vco_rate = pll_freq;
-
-       DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x",
-           pll_10nm->id, (unsigned long)vco_rate, dec, frac);
-
-       return (unsigned long)vco_rate;
-}
-
-static const struct clk_ops clk_ops_dsi_pll_10nm_vco = {
-       .round_rate = msm_dsi_pll_helper_clk_round_rate,
-       .set_rate = dsi_pll_10nm_vco_set_rate,
-       .recalc_rate = dsi_pll_10nm_vco_recalc_rate,
-       .prepare = dsi_pll_10nm_vco_prepare,
-       .unprepare = dsi_pll_10nm_vco_unprepare,
-};
-
-/*
- * PLL Callbacks
- */
-
-static void dsi_pll_10nm_save_state(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
-       struct pll_10nm_cached_state *cached = &pll_10nm->cached_state;
-       void __iomem *phy_base = pll_10nm->phy_cmn_mmio;
-       u32 cmn_clk_cfg0, cmn_clk_cfg1;
-
-       cached->pll_out_div = pll_read(pll_10nm->mmio +
-                                      REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE);
-       cached->pll_out_div &= 0x3;
-
-       cmn_clk_cfg0 = pll_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0);
-       cached->bit_clk_div = cmn_clk_cfg0 & 0xf;
-       cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4;
-
-       cmn_clk_cfg1 = pll_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
-       cached->pll_mux = cmn_clk_cfg1 & 0x3;
-
-       DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x",
-           pll_10nm->id, cached->pll_out_div, cached->bit_clk_div,
-           cached->pix_clk_div, cached->pll_mux);
-}
-
-static int dsi_pll_10nm_restore_state(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
-       struct pll_10nm_cached_state *cached = &pll_10nm->cached_state;
-       void __iomem *phy_base = pll_10nm->phy_cmn_mmio;
-       u32 val;
-       int ret;
-
-       val = pll_read(pll_10nm->mmio + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE);
-       val &= ~0x3;
-       val |= cached->pll_out_div;
-       pll_write(pll_10nm->mmio + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, val);
-
-       pll_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0,
-                 cached->bit_clk_div | (cached->pix_clk_div << 4));
-
-       val = pll_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
-       val &= ~0x3;
-       val |= cached->pll_mux;
-       pll_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, val);
-
-       ret = dsi_pll_10nm_vco_set_rate(&pll->clk_hw, pll_10nm->vco_current_rate, pll_10nm->vco_ref_clk_rate);
-       if (ret) {
-               DRM_DEV_ERROR(&pll_10nm->pdev->dev,
-                       "restore vco rate failed. ret=%d\n", ret);
-               return ret;
-       }
-
-       DBG("DSI PLL%d", pll_10nm->id);
-
-       return 0;
-}
-
-static int dsi_pll_10nm_set_usecase(struct msm_dsi_pll *pll,
-                                   enum msm_dsi_phy_usecase uc)
-{
-       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
-       void __iomem *base = pll_10nm->phy_cmn_mmio;
-       u32 data = 0x0; /* internal PLL */
-
-       DBG("DSI PLL%d", pll_10nm->id);
-
-       switch (uc) {
-       case MSM_DSI_PHY_STANDALONE:
-               break;
-       case MSM_DSI_PHY_MASTER:
-               pll_10nm->slave = pll_10nm_list[(pll_10nm->id + 1) % DSI_MAX];
-               break;
-       case MSM_DSI_PHY_SLAVE:
-               data = 0x1; /* external PLL */
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* set PLL src */
-       pll_write(base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, (data << 2));
-
-       pll_10nm->uc = uc;
-
-       return 0;
-}
-
-static int dsi_pll_10nm_get_provider(struct msm_dsi_pll *pll,
-                                    struct clk **byte_clk_provider,
-                                    struct clk **pixel_clk_provider)
-{
-       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
-       struct clk_hw_onecell_data *hw_data = pll_10nm->hw_data;
-
-       DBG("DSI PLL%d", pll_10nm->id);
-
-       if (byte_clk_provider)
-               *byte_clk_provider = hw_data->hws[DSI_BYTE_PLL_CLK]->clk;
-       if (pixel_clk_provider)
-               *pixel_clk_provider = hw_data->hws[DSI_PIXEL_PLL_CLK]->clk;
-
-       return 0;
-}
-
-static void dsi_pll_10nm_destroy(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
-       struct device *dev = &pll_10nm->pdev->dev;
-
-       DBG("DSI PLL%d", pll_10nm->id);
-       of_clk_del_provider(dev->of_node);
-
-       clk_hw_unregister_divider(pll_10nm->out_dsiclk_hw);
-       clk_hw_unregister_mux(pll_10nm->pclk_mux_hw);
-       clk_hw_unregister_fixed_factor(pll_10nm->post_out_div_clk_hw);
-       clk_hw_unregister_fixed_factor(pll_10nm->by_2_bit_clk_hw);
-       clk_hw_unregister_fixed_factor(pll_10nm->byte_clk_hw);
-       clk_hw_unregister_divider(pll_10nm->bit_clk_hw);
-       clk_hw_unregister_divider(pll_10nm->out_div_clk_hw);
-       clk_hw_unregister(&pll_10nm->base.clk_hw);
-}
-
-/*
- * The post dividers and mux clocks are created using the standard divider and
- * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux
- * state to follow the master PLL's divider/mux state. Therefore, we don't
- * require special clock ops that also configure the slave PLL registers
- */
-static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
-{
-       char clk_name[32], parent[32], vco_name[32];
-       char parent2[32], parent3[32], parent4[32];
-       struct clk_init_data vco_init = {
-               .parent_names = (const char *[]){ "xo" },
-               .num_parents = 1,
-               .name = vco_name,
-               .flags = CLK_IGNORE_UNUSED,
-               .ops = &clk_ops_dsi_pll_10nm_vco,
-       };
-       struct device *dev = &pll_10nm->pdev->dev;
-       struct clk_hw_onecell_data *hw_data;
-       struct clk_hw *hw;
-       int ret;
-
-       DBG("DSI%d", pll_10nm->id);
-
-       hw_data = devm_kzalloc(dev, sizeof(*hw_data) +
-                              NUM_PROVIDED_CLKS * sizeof(struct clk_hw *),
-                              GFP_KERNEL);
-       if (!hw_data)
-               return -ENOMEM;
-
-       snprintf(vco_name, 32, "dsi%dvco_clk", pll_10nm->id);
-       pll_10nm->base.clk_hw.init = &vco_init;
-
-       ret = clk_hw_register(dev, &pll_10nm->base.clk_hw);
-       if (ret)
-               return ret;
-
-       snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_10nm->id);
-       snprintf(parent, 32, "dsi%dvco_clk", pll_10nm->id);
-
-       hw = clk_hw_register_divider(dev, clk_name,
-                                    parent, CLK_SET_RATE_PARENT,
-                                    pll_10nm->mmio +
-                                    REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE,
-                                    0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_base_clk_hw;
-       }
-
-       pll_10nm->out_div_clk_hw = hw;
-
-       snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_10nm->id);
-       snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id);
-
-       /* BIT CLK: DIV_CTRL_3_0 */
-       hw = clk_hw_register_divider(dev, clk_name, parent,
-                                    CLK_SET_RATE_PARENT,
-                                    pll_10nm->phy_cmn_mmio +
-                                    REG_DSI_10nm_PHY_CMN_CLK_CFG0,
-                                    0, 4, CLK_DIVIDER_ONE_BASED,
-                                    &pll_10nm->postdiv_lock);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_out_div_clk_hw;
-       }
-
-       pll_10nm->bit_clk_hw = hw;
-
-       snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_10nm->id);
-       snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id);
-
-       /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */
-       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
-                                         CLK_SET_RATE_PARENT, 1, 8);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_bit_clk_hw;
-       }
-
-       pll_10nm->byte_clk_hw = hw;
-       hw_data->hws[DSI_BYTE_PLL_CLK] = hw;
-
-       snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->id);
-       snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id);
-
-       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
-                                         0, 1, 2);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_byte_clk_hw;
-       }
-
-       pll_10nm->by_2_bit_clk_hw = hw;
-
-       snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id);
-       snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id);
-
-       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
-                                         0, 1, 4);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_by_2_bit_clk_hw;
-       }
-
-       pll_10nm->post_out_div_clk_hw = hw;
-
-       snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_10nm->id);
-       snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id);
-       snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->id);
-       snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_10nm->id);
-       snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id);
-
-       hw = clk_hw_register_mux(dev, clk_name,
-                                ((const char *[]){
-                                parent, parent2, parent3, parent4
-                                }), 4, 0, pll_10nm->phy_cmn_mmio +
-                                REG_DSI_10nm_PHY_CMN_CLK_CFG1,
-                                0, 2, 0, NULL);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_post_out_div_clk_hw;
-       }
-
-       pll_10nm->pclk_mux_hw = hw;
-
-       snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_10nm->id);
-       snprintf(parent, 32, "dsi%d_pclk_mux", pll_10nm->id);
-
-       /* PIX CLK DIV : DIV_CTRL_7_4*/
-       hw = clk_hw_register_divider(dev, clk_name, parent,
-                                    0, pll_10nm->phy_cmn_mmio +
-                                       REG_DSI_10nm_PHY_CMN_CLK_CFG0,
-                                    4, 4, CLK_DIVIDER_ONE_BASED,
-                                    &pll_10nm->postdiv_lock);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_pclk_mux_hw;
-       }
-
-       pll_10nm->out_dsiclk_hw = hw;
-       hw_data->hws[DSI_PIXEL_PLL_CLK] = hw;
-
-       hw_data->num = NUM_PROVIDED_CLKS;
-       pll_10nm->hw_data = hw_data;
-
-       ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
-                                    pll_10nm->hw_data);
-       if (ret) {
-               DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
-               goto err_dsiclk_hw;
-       }
-
-       return 0;
-
-err_dsiclk_hw:
-       clk_hw_unregister_divider(pll_10nm->out_dsiclk_hw);
-err_pclk_mux_hw:
-       clk_hw_unregister_mux(pll_10nm->pclk_mux_hw);
-err_post_out_div_clk_hw:
-       clk_hw_unregister_fixed_factor(pll_10nm->post_out_div_clk_hw);
-err_by_2_bit_clk_hw:
-       clk_hw_unregister_fixed_factor(pll_10nm->by_2_bit_clk_hw);
-err_byte_clk_hw:
-       clk_hw_unregister_fixed_factor(pll_10nm->byte_clk_hw);
-err_bit_clk_hw:
-       clk_hw_unregister_divider(pll_10nm->bit_clk_hw);
-err_out_div_clk_hw:
-       clk_hw_unregister_divider(pll_10nm->out_div_clk_hw);
-err_base_clk_hw:
-       clk_hw_unregister(&pll_10nm->base.clk_hw);
-
-       return ret;
-}
-
-struct msm_dsi_pll *msm_dsi_pll_10nm_init(struct platform_device *pdev, int id)
-{
-       struct dsi_pll_10nm *pll_10nm;
-       struct msm_dsi_pll *pll;
-       int ret;
-
-       pll_10nm = devm_kzalloc(&pdev->dev, sizeof(*pll_10nm), GFP_KERNEL);
-       if (!pll_10nm)
-               return ERR_PTR(-ENOMEM);
-
-       DBG("DSI PLL%d", id);
-
-       pll_10nm->pdev = pdev;
-       pll_10nm->id = id;
-       pll_10nm_list[id] = pll_10nm;
-
-       pll_10nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY");
-       if (IS_ERR_OR_NULL(pll_10nm->phy_cmn_mmio)) {
-               DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n");
-               return ERR_PTR(-ENOMEM);
-       }
-
-       pll_10nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL");
-       if (IS_ERR_OR_NULL(pll_10nm->mmio)) {
-               DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n");
-               return ERR_PTR(-ENOMEM);
-       }
-
-       spin_lock_init(&pll_10nm->postdiv_lock);
-
-       pll = &pll_10nm->base;
-       pll->min_rate = 1000000000UL;
-       pll->max_rate = 3500000000UL;
-       pll->get_provider = dsi_pll_10nm_get_provider;
-       pll->destroy = dsi_pll_10nm_destroy;
-       pll->save_state = dsi_pll_10nm_save_state;
-       pll->restore_state = dsi_pll_10nm_restore_state;
-       pll->set_usecase = dsi_pll_10nm_set_usecase;
-
-       pll_10nm->vco_delay = 1;
-
-       ret = pll_10nm_register(pll_10nm);
-       if (ret) {
-               DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
-               return ERR_PTR(ret);
-       }
-
-       /* TODO: Remove this when we have proper display handover support */
-       msm_dsi_pll_save_state(pll);
-
-       return pll;
-}
diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c
deleted file mode 100644 (file)
index f847376..0000000
+++ /dev/null
@@ -1,1096 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
- */
-
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-
-#include "dsi_pll.h"
-#include "dsi.xml.h"
-
-/*
- * DSI PLL 14nm - clock diagram (eg: DSI0):
- *
- *         dsi0n1_postdiv_clk
- *                         |
- *                         |
- *                 +----+  |  +----+
- *  dsi0vco_clk ---| n1 |--o--| /8 |-- dsi0pllbyte
- *                 +----+  |  +----+
- *                         |           dsi0n1_postdivby2_clk
- *                         |   +----+  |
- *                         o---| /2 |--o--|\
- *                         |   +----+     | \   +----+
- *                         |              |  |--| n2 |-- dsi0pll
- *                         o--------------| /   +----+
- *                                        |/
- */
-
-#define POLL_MAX_READS                 15
-#define POLL_TIMEOUT_US                        1000
-
-#define NUM_PROVIDED_CLKS              2
-
-#define VCO_REF_CLK_RATE               19200000
-#define VCO_MIN_RATE                   1300000000UL
-#define VCO_MAX_RATE                   2600000000UL
-
-#define DSI_BYTE_PLL_CLK               0
-#define DSI_PIXEL_PLL_CLK              1
-
-#define DSI_PLL_DEFAULT_VCO_POSTDIV    1
-
-struct dsi_pll_input {
-       u32 fref;       /* reference clk */
-       u32 fdata;      /* bit clock rate */
-       u32 dsiclk_sel; /* Mux configuration (see diagram) */
-       u32 ssc_en;     /* SSC enable/disable */
-       u32 ldo_en;
-
-       /* fixed params */
-       u32 refclk_dbler_en;
-       u32 vco_measure_time;
-       u32 kvco_measure_time;
-       u32 bandgap_timer;
-       u32 pll_wakeup_timer;
-       u32 plllock_cnt;
-       u32 plllock_rng;
-       u32 ssc_center;
-       u32 ssc_adj_period;
-       u32 ssc_spread;
-       u32 ssc_freq;
-       u32 pll_ie_trim;
-       u32 pll_ip_trim;
-       u32 pll_iptat_trim;
-       u32 pll_cpcset_cur;
-       u32 pll_cpmset_cur;
-
-       u32 pll_icpmset;
-       u32 pll_icpcset;
-
-       u32 pll_icpmset_p;
-       u32 pll_icpmset_m;
-
-       u32 pll_icpcset_p;
-       u32 pll_icpcset_m;
-
-       u32 pll_lpf_res1;
-       u32 pll_lpf_cap1;
-       u32 pll_lpf_cap2;
-       u32 pll_c3ctrl;
-       u32 pll_r3ctrl;
-};
-
-struct dsi_pll_output {
-       u32 pll_txclk_en;
-       u32 dec_start;
-       u32 div_frac_start;
-       u32 ssc_period;
-       u32 ssc_step_size;
-       u32 plllock_cmp;
-       u32 pll_vco_div_ref;
-       u32 pll_vco_count;
-       u32 pll_kvco_div_ref;
-       u32 pll_kvco_count;
-       u32 pll_misc1;
-       u32 pll_lpf2_postdiv;
-       u32 pll_resetsm_cntrl;
-       u32 pll_resetsm_cntrl2;
-       u32 pll_resetsm_cntrl5;
-       u32 pll_kvco_code;
-
-       u32 cmn_clk_cfg0;
-       u32 cmn_clk_cfg1;
-       u32 cmn_ldo_cntrl;
-
-       u32 pll_postdiv;
-       u32 fcvo;
-};
-
-struct pll_14nm_cached_state {
-       unsigned long vco_rate;
-       u8 n2postdiv;
-       u8 n1postdiv;
-};
-
-struct dsi_pll_14nm {
-       struct msm_dsi_pll base;
-
-       int id;
-       struct platform_device *pdev;
-
-       void __iomem *phy_cmn_mmio;
-       void __iomem *mmio;
-
-       int vco_delay;
-
-       struct dsi_pll_input in;
-       struct dsi_pll_output out;
-
-       /* protects REG_DSI_14nm_PHY_CMN_CLK_CFG0 register */
-       spinlock_t postdiv_lock;
-
-       u64 vco_current_rate;
-       u64 vco_ref_clk_rate;
-
-       /* private clocks: */
-       struct clk_hw *hws[NUM_DSI_CLOCKS_MAX];
-       u32 num_hws;
-
-       /* clock-provider: */
-       struct clk_hw_onecell_data *hw_data;
-
-       struct pll_14nm_cached_state cached_state;
-
-       enum msm_dsi_phy_usecase uc;
-       struct dsi_pll_14nm *slave;
-};
-
-#define to_pll_14nm(x) container_of(x, struct dsi_pll_14nm, base)
-
-/*
- * Private struct for N1/N2 post-divider clocks. These clocks are similar to
- * the generic clk_divider class of clocks. The only difference is that it
- * also sets the slave DSI PLL's post-dividers if in Dual DSI mode
- */
-struct dsi_pll_14nm_postdiv {
-       struct clk_hw hw;
-
-       /* divider params */
-       u8 shift;
-       u8 width;
-       u8 flags; /* same flags as used by clk_divider struct */
-
-       struct dsi_pll_14nm *pll;
-};
-
-#define to_pll_14nm_postdiv(_hw) container_of(_hw, struct dsi_pll_14nm_postdiv, hw)
-
-/*
- * Global list of private DSI PLL struct pointers. We need this for Dual DSI
- * mode, where the master PLL's clk_ops needs access the slave's private data
- */
-static struct dsi_pll_14nm *pll_14nm_list[DSI_MAX];
-
-static bool pll_14nm_poll_for_ready(struct dsi_pll_14nm *pll_14nm,
-                                   u32 nb_tries, u32 timeout_us)
-{
-       bool pll_locked = false;
-       void __iomem *base = pll_14nm->mmio;
-       u32 tries, val;
-
-       tries = nb_tries;
-       while (tries--) {
-               val = pll_read(base +
-                              REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
-               pll_locked = !!(val & BIT(5));
-
-               if (pll_locked)
-                       break;
-
-               udelay(timeout_us);
-       }
-
-       if (!pll_locked) {
-               tries = nb_tries;
-               while (tries--) {
-                       val = pll_read(base +
-                               REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
-                       pll_locked = !!(val & BIT(0));
-
-                       if (pll_locked)
-                               break;
-
-                       udelay(timeout_us);
-               }
-       }
-
-       DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* ");
-
-       return pll_locked;
-}
-
-static void dsi_pll_14nm_input_init(struct dsi_pll_14nm *pll)
-{
-       pll->in.fref = pll->vco_ref_clk_rate;
-       pll->in.fdata = 0;
-       pll->in.dsiclk_sel = 1; /* Use the /2 path in Mux */
-       pll->in.ldo_en = 0;     /* disabled for now */
-
-       /* fixed input */
-       pll->in.refclk_dbler_en = 0;
-       pll->in.vco_measure_time = 5;
-       pll->in.kvco_measure_time = 5;
-       pll->in.bandgap_timer = 4;
-       pll->in.pll_wakeup_timer = 5;
-       pll->in.plllock_cnt = 1;
-       pll->in.plllock_rng = 0;
-
-       /*
-        * SSC is enabled by default. We might need DT props for configuring
-        * some SSC params like PPM and center/down spread etc.
-        */
-       pll->in.ssc_en = 1;
-       pll->in.ssc_center = 0;         /* down spread by default */
-       pll->in.ssc_spread = 5;         /* PPM / 1000 */
-       pll->in.ssc_freq = 31500;       /* default recommended */
-       pll->in.ssc_adj_period = 37;
-
-       pll->in.pll_ie_trim = 4;
-       pll->in.pll_ip_trim = 4;
-       pll->in.pll_cpcset_cur = 1;
-       pll->in.pll_cpmset_cur = 1;
-       pll->in.pll_icpmset = 4;
-       pll->in.pll_icpcset = 4;
-       pll->in.pll_icpmset_p = 0;
-       pll->in.pll_icpmset_m = 0;
-       pll->in.pll_icpcset_p = 0;
-       pll->in.pll_icpcset_m = 0;
-       pll->in.pll_lpf_res1 = 3;
-       pll->in.pll_lpf_cap1 = 11;
-       pll->in.pll_lpf_cap2 = 1;
-       pll->in.pll_iptat_trim = 7;
-       pll->in.pll_c3ctrl = 2;
-       pll->in.pll_r3ctrl = 1;
-}
-
-#define CEIL(x, y)             (((x) + ((y) - 1)) / (y))
-
-static void pll_14nm_ssc_calc(struct dsi_pll_14nm *pll)
-{
-       u32 period, ssc_period;
-       u32 ref, rem;
-       u64 step_size;
-
-       DBG("vco=%lld ref=%lld", pll->vco_current_rate, pll->vco_ref_clk_rate);
-
-       ssc_period = pll->in.ssc_freq / 500;
-       period = (u32)pll->vco_ref_clk_rate / 1000;
-       ssc_period  = CEIL(period, ssc_period);
-       ssc_period -= 1;
-       pll->out.ssc_period = ssc_period;
-
-       DBG("ssc freq=%d spread=%d period=%d", pll->in.ssc_freq,
-           pll->in.ssc_spread, pll->out.ssc_period);
-
-       step_size = (u32)pll->vco_current_rate;
-       ref = pll->vco_ref_clk_rate;
-       ref /= 1000;
-       step_size = div_u64(step_size, ref);
-       step_size <<= 20;
-       step_size = div_u64(step_size, 1000);
-       step_size *= pll->in.ssc_spread;
-       step_size = div_u64(step_size, 1000);
-       step_size *= (pll->in.ssc_adj_period + 1);
-
-       rem = 0;
-       step_size = div_u64_rem(step_size, ssc_period + 1, &rem);
-       if (rem)
-               step_size++;
-
-       DBG("step_size=%lld", step_size);
-
-       step_size &= 0x0ffff;   /* take lower 16 bits */
-
-       pll->out.ssc_step_size = step_size;
-}
-
-static void pll_14nm_dec_frac_calc(struct dsi_pll_14nm *pll)
-{
-       struct dsi_pll_input *pin = &pll->in;
-       struct dsi_pll_output *pout = &pll->out;
-       u64 multiplier = BIT(20);
-       u64 dec_start_multiple, dec_start, pll_comp_val;
-       u32 duration, div_frac_start;
-       u64 vco_clk_rate = pll->vco_current_rate;
-       u64 fref = pll->vco_ref_clk_rate;
-
-       DBG("vco_clk_rate=%lld ref_clk_rate=%lld", vco_clk_rate, fref);
-
-       dec_start_multiple = div_u64(vco_clk_rate * multiplier, fref);
-       div_u64_rem(dec_start_multiple, multiplier, &div_frac_start);
-
-       dec_start = div_u64(dec_start_multiple, multiplier);
-
-       pout->dec_start = (u32)dec_start;
-       pout->div_frac_start = div_frac_start;
-
-       if (pin->plllock_cnt == 0)
-               duration = 1024;
-       else if (pin->plllock_cnt == 1)
-               duration = 256;
-       else if (pin->plllock_cnt == 2)
-               duration = 128;
-       else
-               duration = 32;
-
-       pll_comp_val = duration * dec_start_multiple;
-       pll_comp_val = div_u64(pll_comp_val, multiplier);
-       do_div(pll_comp_val, 10);
-
-       pout->plllock_cmp = (u32)pll_comp_val;
-
-       pout->pll_txclk_en = 1;
-       pout->cmn_ldo_cntrl = 0x3c;
-}
-
-static u32 pll_14nm_kvco_slop(u32 vrate)
-{
-       u32 slop = 0;
-
-       if (vrate > VCO_MIN_RATE && vrate <= 1800000000UL)
-               slop =  600;
-       else if (vrate > 1800000000UL && vrate < 2300000000UL)
-               slop = 400;
-       else if (vrate > 2300000000UL && vrate < VCO_MAX_RATE)
-               slop = 280;
-
-       return slop;
-}
-
-static void pll_14nm_calc_vco_count(struct dsi_pll_14nm *pll)
-{
-       struct dsi_pll_input *pin = &pll->in;
-       struct dsi_pll_output *pout = &pll->out;
-       u64 vco_clk_rate = pll->vco_current_rate;
-       u64 fref = pll->vco_ref_clk_rate;
-       u64 data;
-       u32 cnt;
-
-       data = fref * pin->vco_measure_time;
-       do_div(data, 1000000);
-       data &= 0x03ff; /* 10 bits */
-       data -= 2;
-       pout->pll_vco_div_ref = data;
-
-       data = div_u64(vco_clk_rate, 1000000);  /* unit is Mhz */
-       data *= pin->vco_measure_time;
-       do_div(data, 10);
-       pout->pll_vco_count = data;
-
-       data = fref * pin->kvco_measure_time;
-       do_div(data, 1000000);
-       data &= 0x03ff; /* 10 bits */
-       data -= 1;
-       pout->pll_kvco_div_ref = data;
-
-       cnt = pll_14nm_kvco_slop(vco_clk_rate);
-       cnt *= 2;
-       cnt /= 100;
-       cnt *= pin->kvco_measure_time;
-       pout->pll_kvco_count = cnt;
-
-       pout->pll_misc1 = 16;
-       pout->pll_resetsm_cntrl = 48;
-       pout->pll_resetsm_cntrl2 = pin->bandgap_timer << 3;
-       pout->pll_resetsm_cntrl5 = pin->pll_wakeup_timer;
-       pout->pll_kvco_code = 0;
-}
-
-static void pll_db_commit_ssc(struct dsi_pll_14nm *pll)
-{
-       void __iomem *base = pll->mmio;
-       struct dsi_pll_input *pin = &pll->in;
-       struct dsi_pll_output *pout = &pll->out;
-       u8 data;
-
-       data = pin->ssc_adj_period;
-       data &= 0x0ff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER1, data);
-       data = (pin->ssc_adj_period >> 8);
-       data &= 0x03;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER2, data);
-
-       data = pout->ssc_period;
-       data &= 0x0ff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER1, data);
-       data = (pout->ssc_period >> 8);
-       data &= 0x0ff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER2, data);
-
-       data = pout->ssc_step_size;
-       data &= 0x0ff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE1, data);
-       data = (pout->ssc_step_size >> 8);
-       data &= 0x0ff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE2, data);
-
-       data = (pin->ssc_center & 0x01);
-       data <<= 1;
-       data |= 0x01; /* enable */
-       pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_EN_CENTER, data);
-
-       wmb();  /* make sure register committed */
-}
-
-static void pll_db_commit_common(struct dsi_pll_14nm *pll,
-                                struct dsi_pll_input *pin,
-                                struct dsi_pll_output *pout)
-{
-       void __iomem *base = pll->mmio;
-       u8 data;
-
-       /* confgiure the non frequency dependent pll registers */
-       data = 0;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_SYSCLK_EN_RESET, data);
-
-       data = pout->pll_txclk_en;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_TXCLK_EN, data);
-
-       data = pout->pll_resetsm_cntrl;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL, data);
-       data = pout->pll_resetsm_cntrl2;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL2, data);
-       data = pout->pll_resetsm_cntrl5;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL5, data);
-
-       data = pout->pll_vco_div_ref & 0xff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF1, data);
-       data = (pout->pll_vco_div_ref >> 8) & 0x3;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF2, data);
-
-       data = pout->pll_kvco_div_ref & 0xff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF1, data);
-       data = (pout->pll_kvco_div_ref >> 8) & 0x3;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF2, data);
-
-       data = pout->pll_misc1;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_MISC1, data);
-
-       data = pin->pll_ie_trim;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_IE_TRIM, data);
-
-       data = pin->pll_ip_trim;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_IP_TRIM, data);
-
-       data = pin->pll_cpmset_cur << 3 | pin->pll_cpcset_cur;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_CP_SET_CUR, data);
-
-       data = pin->pll_icpcset_p << 3 | pin->pll_icpcset_m;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPCSET, data);
-
-       data = pin->pll_icpmset_p << 3 | pin->pll_icpcset_m;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPMSET, data);
-
-       data = pin->pll_icpmset << 3 | pin->pll_icpcset;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICP_SET, data);
-
-       data = pin->pll_lpf_cap2 << 4 | pin->pll_lpf_cap1;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF1, data);
-
-       data = pin->pll_iptat_trim;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_IPTAT_TRIM, data);
-
-       data = pin->pll_c3ctrl | pin->pll_r3ctrl << 4;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_CRCTRL, data);
-}
-
-static void pll_14nm_software_reset(struct dsi_pll_14nm *pll_14nm)
-{
-       void __iomem *cmn_base = pll_14nm->phy_cmn_mmio;
-
-       /* de assert pll start and apply pll sw reset */
-
-       /* stop pll */
-       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0);
-
-       /* pll sw reset */
-       pll_write_udelay(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x20, 10);
-       wmb();  /* make sure register committed */
-
-       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0);
-       wmb();  /* make sure register committed */
-}
-
-static void pll_db_commit_14nm(struct dsi_pll_14nm *pll,
-                              struct dsi_pll_input *pin,
-                              struct dsi_pll_output *pout)
-{
-       void __iomem *base = pll->mmio;
-       void __iomem *cmn_base = pll->phy_cmn_mmio;
-       u8 data;
-
-       DBG("DSI%d PLL", pll->id);
-
-       data = pout->cmn_ldo_cntrl;
-       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_LDO_CNTRL, data);
-
-       pll_db_commit_common(pll, pin, pout);
-
-       pll_14nm_software_reset(pll);
-
-       data = pin->dsiclk_sel; /* set dsiclk_sel = 1  */
-       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG1, data);
-
-       data = 0xff; /* data, clk, pll normal operation */
-       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_0, data);
-
-       /* configure the frequency dependent pll registers */
-       data = pout->dec_start;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_DEC_START, data);
-
-       data = pout->div_frac_start & 0xff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1, data);
-       data = (pout->div_frac_start >> 8) & 0xff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2, data);
-       data = (pout->div_frac_start >> 16) & 0xf;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3, data);
-
-       data = pout->plllock_cmp & 0xff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP1, data);
-
-       data = (pout->plllock_cmp >> 8) & 0xff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP2, data);
-
-       data = (pout->plllock_cmp >> 16) & 0x3;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP3, data);
-
-       data = pin->plllock_cnt << 1 | pin->plllock_rng << 3;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP_EN, data);
-
-       data = pout->pll_vco_count & 0xff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT1, data);
-       data = (pout->pll_vco_count >> 8) & 0xff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT2, data);
-
-       data = pout->pll_kvco_count & 0xff;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT1, data);
-       data = (pout->pll_kvco_count >> 8) & 0x3;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT2, data);
-
-       data = (pout->pll_postdiv - 1) << 4 | pin->pll_lpf_res1;
-       pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF2_POSTDIV, data);
-
-       if (pin->ssc_en)
-               pll_db_commit_ssc(pll);
-
-       wmb();  /* make sure register committed */
-}
-
-/*
- * VCO clock Callbacks
- */
-static int dsi_pll_14nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
-                                    unsigned long parent_rate)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
-       struct dsi_pll_input *pin = &pll_14nm->in;
-       struct dsi_pll_output *pout = &pll_14nm->out;
-
-       DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_14nm->id, rate,
-           parent_rate);
-
-       pll_14nm->vco_current_rate = rate;
-       pll_14nm->vco_ref_clk_rate = VCO_REF_CLK_RATE;
-
-       dsi_pll_14nm_input_init(pll_14nm);
-
-       /*
-        * This configures the post divider internal to the VCO. It's
-        * fixed to divide by 1 for now.
-        *
-        * tx_band = pll_postdiv.
-        * 0: divided by 1
-        * 1: divided by 2
-        * 2: divided by 4
-        * 3: divided by 8
-        */
-       pout->pll_postdiv = DSI_PLL_DEFAULT_VCO_POSTDIV;
-
-       pll_14nm_dec_frac_calc(pll_14nm);
-
-       if (pin->ssc_en)
-               pll_14nm_ssc_calc(pll_14nm);
-
-       pll_14nm_calc_vco_count(pll_14nm);
-
-       /* commit the slave DSI PLL registers if we're master. Note that we
-        * don't lock the slave PLL. We just ensure that the PLL/PHY registers
-        * of the master and slave are identical
-        */
-       if (pll_14nm->uc == MSM_DSI_PHY_MASTER) {
-               struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave;
-
-               pll_db_commit_14nm(pll_14nm_slave, pin, pout);
-       }
-
-       pll_db_commit_14nm(pll_14nm, pin, pout);
-
-       return 0;
-}
-
-static unsigned long dsi_pll_14nm_vco_recalc_rate(struct clk_hw *hw,
-                                                 unsigned long parent_rate)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
-       void __iomem *base = pll_14nm->mmio;
-       u64 vco_rate, multiplier = BIT(20);
-       u32 div_frac_start;
-       u32 dec_start;
-       u64 ref_clk = parent_rate;
-
-       dec_start = pll_read(base + REG_DSI_14nm_PHY_PLL_DEC_START);
-       dec_start &= 0x0ff;
-
-       DBG("dec_start = %x", dec_start);
-
-       div_frac_start = (pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3)
-                               & 0xf) << 16;
-       div_frac_start |= (pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2)
-                               & 0xff) << 8;
-       div_frac_start |= pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1)
-                               & 0xff;
-
-       DBG("div_frac_start = %x", div_frac_start);
-
-       vco_rate = ref_clk * dec_start;
-
-       vco_rate += ((ref_clk * div_frac_start) / multiplier);
-
-       /*
-        * Recalculating the rate from dec_start and frac_start doesn't end up
-        * the rate we originally set. Convert the freq to KHz, round it up and
-        * convert it back to MHz.
-        */
-       vco_rate = DIV_ROUND_UP_ULL(vco_rate, 1000) * 1000;
-
-       DBG("returning vco rate = %lu", (unsigned long)vco_rate);
-
-       return (unsigned long)vco_rate;
-}
-
-static const struct clk_ops clk_ops_dsi_pll_14nm_vco = {
-       .round_rate = msm_dsi_pll_helper_clk_round_rate,
-       .set_rate = dsi_pll_14nm_vco_set_rate,
-       .recalc_rate = dsi_pll_14nm_vco_recalc_rate,
-       .prepare = msm_dsi_pll_helper_clk_prepare,
-       .unprepare = msm_dsi_pll_helper_clk_unprepare,
-};
-
-/*
- * N1 and N2 post-divider clock callbacks
- */
-#define div_mask(width)        ((1 << (width)) - 1)
-static unsigned long dsi_pll_14nm_postdiv_recalc_rate(struct clk_hw *hw,
-                                                     unsigned long parent_rate)
-{
-       struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw);
-       struct dsi_pll_14nm *pll_14nm = postdiv->pll;
-       void __iomem *base = pll_14nm->phy_cmn_mmio;
-       u8 shift = postdiv->shift;
-       u8 width = postdiv->width;
-       u32 val;
-
-       DBG("DSI%d PLL parent rate=%lu", pll_14nm->id, parent_rate);
-
-       val = pll_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0) >> shift;
-       val &= div_mask(width);
-
-       return divider_recalc_rate(hw, parent_rate, val, NULL,
-                                  postdiv->flags, width);
-}
-
-static long dsi_pll_14nm_postdiv_round_rate(struct clk_hw *hw,
-                                           unsigned long rate,
-                                           unsigned long *prate)
-{
-       struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw);
-       struct dsi_pll_14nm *pll_14nm = postdiv->pll;
-
-       DBG("DSI%d PLL parent rate=%lu", pll_14nm->id, rate);
-
-       return divider_round_rate(hw, rate, prate, NULL,
-                                 postdiv->width,
-                                 postdiv->flags);
-}
-
-static int dsi_pll_14nm_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
-                                        unsigned long parent_rate)
-{
-       struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw);
-       struct dsi_pll_14nm *pll_14nm = postdiv->pll;
-       void __iomem *base = pll_14nm->phy_cmn_mmio;
-       spinlock_t *lock = &pll_14nm->postdiv_lock;
-       u8 shift = postdiv->shift;
-       u8 width = postdiv->width;
-       unsigned int value;
-       unsigned long flags = 0;
-       u32 val;
-
-       DBG("DSI%d PLL parent rate=%lu parent rate %lu", pll_14nm->id, rate,
-           parent_rate);
-
-       value = divider_get_val(rate, parent_rate, NULL, postdiv->width,
-                               postdiv->flags);
-
-       spin_lock_irqsave(lock, flags);
-
-       val = pll_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0);
-       val &= ~(div_mask(width) << shift);
-
-       val |= value << shift;
-       pll_write(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val);
-
-       /* If we're master in dual DSI mode, then the slave PLL's post-dividers
-        * follow the master's post dividers
-        */
-       if (pll_14nm->uc == MSM_DSI_PHY_MASTER) {
-               struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave;
-               void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio;
-
-               pll_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val);
-       }
-
-       spin_unlock_irqrestore(lock, flags);
-
-       return 0;
-}
-
-static const struct clk_ops clk_ops_dsi_pll_14nm_postdiv = {
-       .recalc_rate = dsi_pll_14nm_postdiv_recalc_rate,
-       .round_rate = dsi_pll_14nm_postdiv_round_rate,
-       .set_rate = dsi_pll_14nm_postdiv_set_rate,
-};
-
-/*
- * PLL Callbacks
- */
-
-static int dsi_pll_14nm_enable_seq(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
-       void __iomem *base = pll_14nm->mmio;
-       void __iomem *cmn_base = pll_14nm->phy_cmn_mmio;
-       bool locked;
-
-       DBG("");
-
-       pll_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10);
-       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1);
-
-       locked = pll_14nm_poll_for_ready(pll_14nm, POLL_MAX_READS,
-                                        POLL_TIMEOUT_US);
-
-       if (unlikely(!locked))
-               DRM_DEV_ERROR(&pll_14nm->pdev->dev, "DSI PLL lock failed\n");
-       else
-               DBG("DSI PLL lock success");
-
-       return locked ? 0 : -EINVAL;
-}
-
-static void dsi_pll_14nm_disable_seq(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
-       void __iomem *cmn_base = pll_14nm->phy_cmn_mmio;
-
-       DBG("");
-
-       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0);
-}
-
-static void dsi_pll_14nm_save_state(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
-       struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state;
-       void __iomem *cmn_base = pll_14nm->phy_cmn_mmio;
-       u32 data;
-
-       data = pll_read(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0);
-
-       cached_state->n1postdiv = data & 0xf;
-       cached_state->n2postdiv = (data >> 4) & 0xf;
-
-       DBG("DSI%d PLL save state %x %x", pll_14nm->id,
-           cached_state->n1postdiv, cached_state->n2postdiv);
-
-       cached_state->vco_rate = clk_hw_get_rate(&pll->clk_hw);
-}
-
-static int dsi_pll_14nm_restore_state(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
-       struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state;
-       void __iomem *cmn_base = pll_14nm->phy_cmn_mmio;
-       u32 data;
-       int ret;
-
-       ret = dsi_pll_14nm_vco_set_rate(&pll->clk_hw,
-                                       cached_state->vco_rate, 0);
-       if (ret) {
-               DRM_DEV_ERROR(&pll_14nm->pdev->dev,
-                       "restore vco rate failed. ret=%d\n", ret);
-               return ret;
-       }
-
-       data = cached_state->n1postdiv | (cached_state->n2postdiv << 4);
-
-       DBG("DSI%d PLL restore state %x %x", pll_14nm->id,
-           cached_state->n1postdiv, cached_state->n2postdiv);
-
-       pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data);
-
-       /* also restore post-dividers for slave DSI PLL */
-       if (pll_14nm->uc == MSM_DSI_PHY_MASTER) {
-               struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave;
-               void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio;
-
-               pll_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data);
-       }
-
-       return 0;
-}
-
-static int dsi_pll_14nm_set_usecase(struct msm_dsi_pll *pll,
-                                   enum msm_dsi_phy_usecase uc)
-{
-       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
-       void __iomem *base = pll_14nm->mmio;
-       u32 clkbuflr_en, bandgap = 0;
-
-       switch (uc) {
-       case MSM_DSI_PHY_STANDALONE:
-               clkbuflr_en = 0x1;
-               break;
-       case MSM_DSI_PHY_MASTER:
-               clkbuflr_en = 0x3;
-               pll_14nm->slave = pll_14nm_list[(pll_14nm->id + 1) % DSI_MAX];
-               break;
-       case MSM_DSI_PHY_SLAVE:
-               clkbuflr_en = 0x0;
-               bandgap = 0x3;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       pll_write(base + REG_DSI_14nm_PHY_PLL_CLKBUFLR_EN, clkbuflr_en);
-       if (bandgap)
-               pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_BANDGAP, bandgap);
-
-       pll_14nm->uc = uc;
-
-       return 0;
-}
-
-static int dsi_pll_14nm_get_provider(struct msm_dsi_pll *pll,
-                                    struct clk **byte_clk_provider,
-                                    struct clk **pixel_clk_provider)
-{
-       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
-       struct clk_hw_onecell_data *hw_data = pll_14nm->hw_data;
-
-       if (byte_clk_provider)
-               *byte_clk_provider = hw_data->hws[DSI_BYTE_PLL_CLK]->clk;
-       if (pixel_clk_provider)
-               *pixel_clk_provider = hw_data->hws[DSI_PIXEL_PLL_CLK]->clk;
-
-       return 0;
-}
-
-static void dsi_pll_14nm_destroy(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll);
-       struct platform_device *pdev = pll_14nm->pdev;
-       int num_hws = pll_14nm->num_hws;
-
-       of_clk_del_provider(pdev->dev.of_node);
-
-       while (num_hws--)
-               clk_hw_unregister(pll_14nm->hws[num_hws]);
-}
-
-static struct clk_hw *pll_14nm_postdiv_register(struct dsi_pll_14nm *pll_14nm,
-                                               const char *name,
-                                               const char *parent_name,
-                                               unsigned long flags,
-                                               u8 shift)
-{
-       struct dsi_pll_14nm_postdiv *pll_postdiv;
-       struct device *dev = &pll_14nm->pdev->dev;
-       struct clk_init_data postdiv_init = {
-               .parent_names = (const char *[]) { parent_name },
-               .num_parents = 1,
-               .name = name,
-               .flags = flags,
-               .ops = &clk_ops_dsi_pll_14nm_postdiv,
-       };
-       int ret;
-
-       pll_postdiv = devm_kzalloc(dev, sizeof(*pll_postdiv), GFP_KERNEL);
-       if (!pll_postdiv)
-               return ERR_PTR(-ENOMEM);
-
-       pll_postdiv->pll = pll_14nm;
-       pll_postdiv->shift = shift;
-       /* both N1 and N2 postdividers are 4 bits wide */
-       pll_postdiv->width = 4;
-       /* range of each divider is from 1 to 15 */
-       pll_postdiv->flags = CLK_DIVIDER_ONE_BASED;
-       pll_postdiv->hw.init = &postdiv_init;
-
-       ret = clk_hw_register(dev, &pll_postdiv->hw);
-       if (ret)
-               return ERR_PTR(ret);
-
-       return &pll_postdiv->hw;
-}
-
-static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm)
-{
-       char clk_name[32], parent[32], vco_name[32];
-       struct clk_init_data vco_init = {
-               .parent_names = (const char *[]){ "xo" },
-               .num_parents = 1,
-               .name = vco_name,
-               .flags = CLK_IGNORE_UNUSED,
-               .ops = &clk_ops_dsi_pll_14nm_vco,
-       };
-       struct device *dev = &pll_14nm->pdev->dev;
-       struct clk_hw **hws = pll_14nm->hws;
-       struct clk_hw_onecell_data *hw_data;
-       struct clk_hw *hw;
-       int num = 0;
-       int ret;
-
-       DBG("DSI%d", pll_14nm->id);
-
-       hw_data = devm_kzalloc(dev, sizeof(*hw_data) +
-                              NUM_PROVIDED_CLKS * sizeof(struct clk_hw *),
-                              GFP_KERNEL);
-       if (!hw_data)
-               return -ENOMEM;
-
-       snprintf(vco_name, 32, "dsi%dvco_clk", pll_14nm->id);
-       pll_14nm->base.clk_hw.init = &vco_init;
-
-       ret = clk_hw_register(dev, &pll_14nm->base.clk_hw);
-       if (ret)
-               return ret;
-
-       hws[num++] = &pll_14nm->base.clk_hw;
-
-       snprintf(clk_name, 32, "dsi%dn1_postdiv_clk", pll_14nm->id);
-       snprintf(parent, 32, "dsi%dvco_clk", pll_14nm->id);
-
-       /* N1 postdiv, bits 0-3 in REG_DSI_14nm_PHY_CMN_CLK_CFG0 */
-       hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent,
-                                      CLK_SET_RATE_PARENT, 0);
-       if (IS_ERR(hw))
-               return PTR_ERR(hw);
-
-       hws[num++] = hw;
-
-       snprintf(clk_name, 32, "dsi%dpllbyte", pll_14nm->id);
-       snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->id);
-
-       /* DSI Byte clock = VCO_CLK / N1 / 8 */
-       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
-                                         CLK_SET_RATE_PARENT, 1, 8);
-       if (IS_ERR(hw))
-               return PTR_ERR(hw);
-
-       hws[num++] = hw;
-       hw_data->hws[DSI_BYTE_PLL_CLK] = hw;
-
-       snprintf(clk_name, 32, "dsi%dn1_postdivby2_clk", pll_14nm->id);
-       snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->id);
-
-       /*
-        * Skip the mux for now, force DSICLK_SEL to 1, Add a /2 divider
-        * on the way. Don't let it set parent.
-        */
-       hw = clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 2);
-       if (IS_ERR(hw))
-               return PTR_ERR(hw);
-
-       hws[num++] = hw;
-
-       snprintf(clk_name, 32, "dsi%dpll", pll_14nm->id);
-       snprintf(parent, 32, "dsi%dn1_postdivby2_clk", pll_14nm->id);
-
-       /* DSI pixel clock = VCO_CLK / N1 / 2 / N2
-        * This is the output of N2 post-divider, bits 4-7 in
-        * REG_DSI_14nm_PHY_CMN_CLK_CFG0. Don't let it set parent.
-        */
-       hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent, 0, 4);
-       if (IS_ERR(hw))
-               return PTR_ERR(hw);
-
-       hws[num++] = hw;
-       hw_data->hws[DSI_PIXEL_PLL_CLK] = hw;
-
-       pll_14nm->num_hws = num;
-
-       hw_data->num = NUM_PROVIDED_CLKS;
-       pll_14nm->hw_data = hw_data;
-
-       ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
-                                    pll_14nm->hw_data);
-       if (ret) {
-               DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-struct msm_dsi_pll *msm_dsi_pll_14nm_init(struct platform_device *pdev, int id)
-{
-       struct dsi_pll_14nm *pll_14nm;
-       struct msm_dsi_pll *pll;
-       int ret;
-
-       if (!pdev)
-               return ERR_PTR(-ENODEV);
-
-       pll_14nm = devm_kzalloc(&pdev->dev, sizeof(*pll_14nm), GFP_KERNEL);
-       if (!pll_14nm)
-               return ERR_PTR(-ENOMEM);
-
-       DBG("PLL%d", id);
-
-       pll_14nm->pdev = pdev;
-       pll_14nm->id = id;
-       pll_14nm_list[id] = pll_14nm;
-
-       pll_14nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY");
-       if (IS_ERR_OR_NULL(pll_14nm->phy_cmn_mmio)) {
-               DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n");
-               return ERR_PTR(-ENOMEM);
-       }
-
-       pll_14nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL");
-       if (IS_ERR_OR_NULL(pll_14nm->mmio)) {
-               DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n");
-               return ERR_PTR(-ENOMEM);
-       }
-
-       spin_lock_init(&pll_14nm->postdiv_lock);
-
-       pll = &pll_14nm->base;
-       pll->min_rate = VCO_MIN_RATE;
-       pll->max_rate = VCO_MAX_RATE;
-       pll->get_provider = dsi_pll_14nm_get_provider;
-       pll->destroy = dsi_pll_14nm_destroy;
-       pll->disable_seq = dsi_pll_14nm_disable_seq;
-       pll->save_state = dsi_pll_14nm_save_state;
-       pll->restore_state = dsi_pll_14nm_restore_state;
-       pll->set_usecase = dsi_pll_14nm_set_usecase;
-
-       pll_14nm->vco_delay = 1;
-
-       pll->en_seq_cnt = 1;
-       pll->enable_seqs[0] = dsi_pll_14nm_enable_seq;
-
-       ret = pll_14nm_register(pll_14nm);
-       if (ret) {
-               DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
-               return ERR_PTR(ret);
-       }
-
-       return pll;
-}
diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c
deleted file mode 100644 (file)
index 37a1f99..0000000
+++ /dev/null
@@ -1,643 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
- */
-
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-
-#include "dsi_pll.h"
-#include "dsi.xml.h"
-
-/*
- * DSI PLL 28nm - clock diagram (eg: DSI0):
- *
- *         dsi0analog_postdiv_clk
- *                             |         dsi0indirect_path_div2_clk
- *                             |          |
- *                   +------+  |  +----+  |  |\   dsi0byte_mux
- *  dsi0vco_clk --o--| DIV1 |--o--| /2 |--o--| \   |
- *                |  +------+     +----+     | m|  |  +----+
- *                |                          | u|--o--| /4 |-- dsi0pllbyte
- *                |                          | x|     +----+
- *                o--------------------------| /
- *                |                          |/
- *                |          +------+
- *                o----------| DIV3 |------------------------- dsi0pll
- *                           +------+
- */
-
-#define POLL_MAX_READS                 10
-#define POLL_TIMEOUT_US                50
-
-#define NUM_PROVIDED_CLKS              2
-
-#define VCO_REF_CLK_RATE               19200000
-#define VCO_MIN_RATE                   350000000
-#define VCO_MAX_RATE                   750000000
-
-#define DSI_BYTE_PLL_CLK               0
-#define DSI_PIXEL_PLL_CLK              1
-
-#define LPFR_LUT_SIZE                  10
-struct lpfr_cfg {
-       unsigned long vco_rate;
-       u32 resistance;
-};
-
-/* Loop filter resistance: */
-static const struct lpfr_cfg lpfr_lut[LPFR_LUT_SIZE] = {
-       { 479500000,  8 },
-       { 480000000, 11 },
-       { 575500000,  8 },
-       { 576000000, 12 },
-       { 610500000,  8 },
-       { 659500000,  9 },
-       { 671500000, 10 },
-       { 672000000, 14 },
-       { 708500000, 10 },
-       { 750000000, 11 },
-};
-
-struct pll_28nm_cached_state {
-       unsigned long vco_rate;
-       u8 postdiv3;
-       u8 postdiv1;
-       u8 byte_mux;
-};
-
-struct dsi_pll_28nm {
-       struct msm_dsi_pll base;
-
-       int id;
-       struct platform_device *pdev;
-       void __iomem *mmio;
-
-       int vco_delay;
-
-       /* private clocks: */
-       struct clk *clks[NUM_DSI_CLOCKS_MAX];
-       u32 num_clks;
-
-       /* clock-provider: */
-       struct clk *provided_clks[NUM_PROVIDED_CLKS];
-       struct clk_onecell_data clk_data;
-
-       struct pll_28nm_cached_state cached_state;
-};
-
-#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, base)
-
-static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm,
-                               u32 nb_tries, u32 timeout_us)
-{
-       bool pll_locked = false;
-       u32 val;
-
-       while (nb_tries--) {
-               val = pll_read(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_STATUS);
-               pll_locked = !!(val & DSI_28nm_PHY_PLL_STATUS_PLL_RDY);
-
-               if (pll_locked)
-                       break;
-
-               udelay(timeout_us);
-       }
-       DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* ");
-
-       return pll_locked;
-}
-
-static void pll_28nm_software_reset(struct dsi_pll_28nm *pll_28nm)
-{
-       void __iomem *base = pll_28nm->mmio;
-
-       /*
-        * Add HW recommended delays after toggling the software
-        * reset bit off and back on.
-        */
-       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG,
-                       DSI_28nm_PHY_PLL_TEST_CFG_PLL_SW_RESET, 1);
-       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG, 0x00, 1);
-}
-
-/*
- * Clock Callbacks
- */
-static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-       struct device *dev = &pll_28nm->pdev->dev;
-       void __iomem *base = pll_28nm->mmio;
-       unsigned long div_fbx1000, gen_vco_clk;
-       u32 refclk_cfg, frac_n_mode, frac_n_value;
-       u32 sdm_cfg0, sdm_cfg1, sdm_cfg2, sdm_cfg3;
-       u32 cal_cfg10, cal_cfg11;
-       u32 rem;
-       int i;
-
-       VERB("rate=%lu, parent's=%lu", rate, parent_rate);
-
-       /* Force postdiv2 to be div-4 */
-       pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV2_CFG, 3);
-
-       /* Configure the Loop filter resistance */
-       for (i = 0; i < LPFR_LUT_SIZE; i++)
-               if (rate <= lpfr_lut[i].vco_rate)
-                       break;
-       if (i == LPFR_LUT_SIZE) {
-               DRM_DEV_ERROR(dev, "unable to get loop filter resistance. vco=%lu\n",
-                               rate);
-               return -EINVAL;
-       }
-       pll_write(base + REG_DSI_28nm_PHY_PLL_LPFR_CFG, lpfr_lut[i].resistance);
-
-       /* Loop filter capacitance values : c1 and c2 */
-       pll_write(base + REG_DSI_28nm_PHY_PLL_LPFC1_CFG, 0x70);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_LPFC2_CFG, 0x15);
-
-       rem = rate % VCO_REF_CLK_RATE;
-       if (rem) {
-               refclk_cfg = DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR;
-               frac_n_mode = 1;
-               div_fbx1000 = rate / (VCO_REF_CLK_RATE / 500);
-               gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 500);
-       } else {
-               refclk_cfg = 0x0;
-               frac_n_mode = 0;
-               div_fbx1000 = rate / (VCO_REF_CLK_RATE / 1000);
-               gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 1000);
-       }
-
-       DBG("refclk_cfg = %d", refclk_cfg);
-
-       rem = div_fbx1000 % 1000;
-       frac_n_value = (rem << 16) / 1000;
-
-       DBG("div_fb = %lu", div_fbx1000);
-       DBG("frac_n_value = %d", frac_n_value);
-
-       DBG("Generated VCO Clock: %lu", gen_vco_clk);
-       rem = 0;
-       sdm_cfg1 = pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1);
-       sdm_cfg1 &= ~DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET__MASK;
-       if (frac_n_mode) {
-               sdm_cfg0 = 0x0;
-               sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(0);
-               sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(
-                               (u32)(((div_fbx1000 / 1000) & 0x3f) - 1));
-               sdm_cfg3 = frac_n_value >> 8;
-               sdm_cfg2 = frac_n_value & 0xff;
-       } else {
-               sdm_cfg0 = DSI_28nm_PHY_PLL_SDM_CFG0_BYP;
-               sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(
-                               (u32)(((div_fbx1000 / 1000) & 0x3f) - 1));
-               sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(0);
-               sdm_cfg2 = 0;
-               sdm_cfg3 = 0;
-       }
-
-       DBG("sdm_cfg0=%d", sdm_cfg0);
-       DBG("sdm_cfg1=%d", sdm_cfg1);
-       DBG("sdm_cfg2=%d", sdm_cfg2);
-       DBG("sdm_cfg3=%d", sdm_cfg3);
-
-       cal_cfg11 = (u32)(gen_vco_clk / (256 * 1000000));
-       cal_cfg10 = (u32)((gen_vco_clk % (256 * 1000000)) / 1000000);
-       DBG("cal_cfg10=%d, cal_cfg11=%d", cal_cfg10, cal_cfg11);
-
-       pll_write(base + REG_DSI_28nm_PHY_PLL_CHGPUMP_CFG, 0x02);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG3,    0x2b);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG4,    0x06);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2,  0x0d);
-
-       pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1, sdm_cfg1);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2,
-               DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0(sdm_cfg2));
-       pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3,
-               DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8(sdm_cfg3));
-       pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG4, 0x00);
-
-       /* Add hardware recommended delay for correct PLL configuration */
-       if (pll_28nm->vco_delay)
-               udelay(pll_28nm->vco_delay);
-
-       pll_write(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG, refclk_cfg);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG, 0x00);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_VCOLPF_CFG, 0x31);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0,   sdm_cfg0);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG0,   0x12);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG6,   0x30);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG7,   0x00);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG8,   0x60);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG9,   0x00);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG10,  cal_cfg10 & 0xff);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG11,  cal_cfg11 & 0xff);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_EFUSE_CFG,  0x20);
-
-       return 0;
-}
-
-static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-
-       return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS,
-                                       POLL_TIMEOUT_US);
-}
-
-static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-       void __iomem *base = pll_28nm->mmio;
-       u32 sdm0, doubler, sdm_byp_div;
-       u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3;
-       u32 ref_clk = VCO_REF_CLK_RATE;
-       unsigned long vco_rate;
-
-       VERB("parent_rate=%lu", parent_rate);
-
-       /* Check to see if the ref clk doubler is enabled */
-       doubler = pll_read(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG) &
-                       DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR;
-       ref_clk += (doubler * VCO_REF_CLK_RATE);
-
-       /* see if it is integer mode or sdm mode */
-       sdm0 = pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0);
-       if (sdm0 & DSI_28nm_PHY_PLL_SDM_CFG0_BYP) {
-               /* integer mode */
-               sdm_byp_div = FIELD(
-                               pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0),
-                               DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV) + 1;
-               vco_rate = ref_clk * sdm_byp_div;
-       } else {
-               /* sdm mode */
-               sdm_dc_off = FIELD(
-                               pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1),
-                               DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET);
-               DBG("sdm_dc_off = %d", sdm_dc_off);
-               sdm2 = FIELD(pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2),
-                               DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0);
-               sdm3 = FIELD(pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3),
-                               DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8);
-               sdm_freq_seed = (sdm3 << 8) | sdm2;
-               DBG("sdm_freq_seed = %d", sdm_freq_seed);
-
-               vco_rate = (ref_clk * (sdm_dc_off + 1)) +
-                       mult_frac(ref_clk, sdm_freq_seed, BIT(16));
-               DBG("vco rate = %lu", vco_rate);
-       }
-
-       DBG("returning vco rate = %lu", vco_rate);
-
-       return vco_rate;
-}
-
-static const struct clk_ops clk_ops_dsi_pll_28nm_vco = {
-       .round_rate = msm_dsi_pll_helper_clk_round_rate,
-       .set_rate = dsi_pll_28nm_clk_set_rate,
-       .recalc_rate = dsi_pll_28nm_clk_recalc_rate,
-       .prepare = msm_dsi_pll_helper_clk_prepare,
-       .unprepare = msm_dsi_pll_helper_clk_unprepare,
-       .is_enabled = dsi_pll_28nm_clk_is_enabled,
-};
-
-/*
- * PLL Callbacks
- */
-static int dsi_pll_28nm_enable_seq_hpm(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-       struct device *dev = &pll_28nm->pdev->dev;
-       void __iomem *base = pll_28nm->mmio;
-       u32 max_reads = 5, timeout_us = 100;
-       bool locked;
-       u32 val;
-       int i;
-
-       DBG("id=%d", pll_28nm->id);
-
-       pll_28nm_software_reset(pll_28nm);
-
-       /*
-        * PLL power up sequence.
-        * Add necessary delays recommended by hardware.
-        */
-       val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
-       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1);
-
-       val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
-       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
-
-       val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
-       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
-
-       val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
-       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600);
-
-       for (i = 0; i < 2; i++) {
-               /* DSI Uniphy lock detect setting */
-               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2,
-                               0x0c, 100);
-               pll_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d);
-
-               /* poll for PLL ready status */
-               locked = pll_28nm_poll_for_ready(pll_28nm,
-                                               max_reads, timeout_us);
-               if (locked)
-                       break;
-
-               pll_28nm_software_reset(pll_28nm);
-
-               /*
-                * PLL power up sequence.
-                * Add necessary delays recommended by hardware.
-                */
-               val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
-               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1);
-
-               val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
-               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
-
-               val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
-               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 250);
-
-               val &= ~DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
-               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
-
-               val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
-               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
-
-               val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
-               pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600);
-       }
-
-       if (unlikely(!locked))
-               DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
-       else
-               DBG("DSI PLL Lock success");
-
-       return locked ? 0 : -EINVAL;
-}
-
-static int dsi_pll_28nm_enable_seq_lp(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-       struct device *dev = &pll_28nm->pdev->dev;
-       void __iomem *base = pll_28nm->mmio;
-       bool locked;
-       u32 max_reads = 10, timeout_us = 50;
-       u32 val;
-
-       DBG("id=%d", pll_28nm->id);
-
-       pll_28nm_software_reset(pll_28nm);
-
-       /*
-        * PLL power up sequence.
-        * Add necessary delays recommended by hardware.
-        */
-       pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_CAL_CFG1, 0x34, 500);
-
-       val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
-       pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
-
-       val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
-       pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
-
-       val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B |
-               DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
-       pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
-
-       /* DSI PLL toggle lock detect setting */
-       pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x04, 500);
-       pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x05, 512);
-
-       locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us);
-
-       if (unlikely(!locked))
-               DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
-       else
-               DBG("DSI PLL lock success");
-
-       return locked ? 0 : -EINVAL;
-}
-
-static void dsi_pll_28nm_disable_seq(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-
-       DBG("id=%d", pll_28nm->id);
-       pll_write(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_GLB_CFG, 0x00);
-}
-
-static void dsi_pll_28nm_save_state(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-       struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
-       void __iomem *base = pll_28nm->mmio;
-
-       cached_state->postdiv3 =
-                       pll_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG);
-       cached_state->postdiv1 =
-                       pll_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG);
-       cached_state->byte_mux = pll_read(base + REG_DSI_28nm_PHY_PLL_VREG_CFG);
-       if (dsi_pll_28nm_clk_is_enabled(&pll->clk_hw))
-               cached_state->vco_rate = clk_hw_get_rate(&pll->clk_hw);
-       else
-               cached_state->vco_rate = 0;
-}
-
-static int dsi_pll_28nm_restore_state(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-       struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
-       void __iomem *base = pll_28nm->mmio;
-       int ret;
-
-       ret = dsi_pll_28nm_clk_set_rate(&pll->clk_hw,
-                                       cached_state->vco_rate, 0);
-       if (ret) {
-               DRM_DEV_ERROR(&pll_28nm->pdev->dev,
-                       "restore vco rate failed. ret=%d\n", ret);
-               return ret;
-       }
-
-       pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG,
-                       cached_state->postdiv3);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG,
-                       cached_state->postdiv1);
-       pll_write(base + REG_DSI_28nm_PHY_PLL_VREG_CFG,
-                       cached_state->byte_mux);
-
-       return 0;
-}
-
-static int dsi_pll_28nm_get_provider(struct msm_dsi_pll *pll,
-                               struct clk **byte_clk_provider,
-                               struct clk **pixel_clk_provider)
-{
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-
-       if (byte_clk_provider)
-               *byte_clk_provider = pll_28nm->provided_clks[DSI_BYTE_PLL_CLK];
-       if (pixel_clk_provider)
-               *pixel_clk_provider =
-                               pll_28nm->provided_clks[DSI_PIXEL_PLL_CLK];
-
-       return 0;
-}
-
-static void dsi_pll_28nm_destroy(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-       int i;
-
-       msm_dsi_pll_helper_unregister_clks(pll_28nm->pdev,
-                                       pll_28nm->clks, pll_28nm->num_clks);
-
-       for (i = 0; i < NUM_PROVIDED_CLKS; i++)
-               pll_28nm->provided_clks[i] = NULL;
-
-       pll_28nm->num_clks = 0;
-       pll_28nm->clk_data.clks = NULL;
-       pll_28nm->clk_data.clk_num = 0;
-}
-
-static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm)
-{
-       char clk_name[32], parent1[32], parent2[32], vco_name[32];
-       struct clk_init_data vco_init = {
-               .parent_names = (const char *[]){ "xo" },
-               .num_parents = 1,
-               .name = vco_name,
-               .flags = CLK_IGNORE_UNUSED,
-               .ops = &clk_ops_dsi_pll_28nm_vco,
-       };
-       struct device *dev = &pll_28nm->pdev->dev;
-       struct clk **clks = pll_28nm->clks;
-       struct clk **provided_clks = pll_28nm->provided_clks;
-       int num = 0;
-       int ret;
-
-       DBG("%d", pll_28nm->id);
-
-       snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id);
-       pll_28nm->base.clk_hw.init = &vco_init;
-       clks[num++] = clk_register(dev, &pll_28nm->base.clk_hw);
-
-       snprintf(clk_name, 32, "dsi%danalog_postdiv_clk", pll_28nm->id);
-       snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id);
-       clks[num++] = clk_register_divider(dev, clk_name,
-                       parent1, CLK_SET_RATE_PARENT,
-                       pll_28nm->mmio +
-                       REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG,
-                       0, 4, 0, NULL);
-
-       snprintf(clk_name, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id);
-       snprintf(parent1, 32, "dsi%danalog_postdiv_clk", pll_28nm->id);
-       clks[num++] = clk_register_fixed_factor(dev, clk_name,
-                       parent1, CLK_SET_RATE_PARENT,
-                       1, 2);
-
-       snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id);
-       snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id);
-       clks[num++] = provided_clks[DSI_PIXEL_PLL_CLK] =
-                       clk_register_divider(dev, clk_name,
-                               parent1, 0, pll_28nm->mmio +
-                               REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG,
-                               0, 8, 0, NULL);
-
-       snprintf(clk_name, 32, "dsi%dbyte_mux", pll_28nm->id);
-       snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id);
-       snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id);
-       clks[num++] = clk_register_mux(dev, clk_name,
-                       ((const char *[]){
-                               parent1, parent2
-                       }), 2, CLK_SET_RATE_PARENT, pll_28nm->mmio +
-                       REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL);
-
-       snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id);
-       snprintf(parent1, 32, "dsi%dbyte_mux", pll_28nm->id);
-       clks[num++] = provided_clks[DSI_BYTE_PLL_CLK] =
-                       clk_register_fixed_factor(dev, clk_name,
-                               parent1, CLK_SET_RATE_PARENT, 1, 4);
-
-       pll_28nm->num_clks = num;
-
-       pll_28nm->clk_data.clk_num = NUM_PROVIDED_CLKS;
-       pll_28nm->clk_data.clks = provided_clks;
-
-       ret = of_clk_add_provider(dev->of_node,
-                       of_clk_src_onecell_get, &pll_28nm->clk_data);
-       if (ret) {
-               DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-struct msm_dsi_pll *msm_dsi_pll_28nm_init(struct platform_device *pdev,
-                                       enum msm_dsi_phy_type type, int id)
-{
-       struct dsi_pll_28nm *pll_28nm;
-       struct msm_dsi_pll *pll;
-       int ret;
-
-       if (!pdev)
-               return ERR_PTR(-ENODEV);
-
-       pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL);
-       if (!pll_28nm)
-               return ERR_PTR(-ENOMEM);
-
-       pll_28nm->pdev = pdev;
-       pll_28nm->id = id;
-
-       pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL");
-       if (IS_ERR_OR_NULL(pll_28nm->mmio)) {
-               DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__);
-               return ERR_PTR(-ENOMEM);
-       }
-
-       pll = &pll_28nm->base;
-       pll->min_rate = VCO_MIN_RATE;
-       pll->max_rate = VCO_MAX_RATE;
-       pll->get_provider = dsi_pll_28nm_get_provider;
-       pll->destroy = dsi_pll_28nm_destroy;
-       pll->disable_seq = dsi_pll_28nm_disable_seq;
-       pll->save_state = dsi_pll_28nm_save_state;
-       pll->restore_state = dsi_pll_28nm_restore_state;
-
-       if (type == MSM_DSI_PHY_28NM_HPM) {
-               pll_28nm->vco_delay = 1;
-
-               pll->en_seq_cnt = 3;
-               pll->enable_seqs[0] = dsi_pll_28nm_enable_seq_hpm;
-               pll->enable_seqs[1] = dsi_pll_28nm_enable_seq_hpm;
-               pll->enable_seqs[2] = dsi_pll_28nm_enable_seq_hpm;
-       } else if (type == MSM_DSI_PHY_28NM_LP) {
-               pll_28nm->vco_delay = 1000;
-
-               pll->en_seq_cnt = 1;
-               pll->enable_seqs[0] = dsi_pll_28nm_enable_seq_lp;
-       } else {
-               DRM_DEV_ERROR(&pdev->dev, "phy type (%d) is not 28nm\n", type);
-               return ERR_PTR(-EINVAL);
-       }
-
-       ret = pll_28nm_register(pll_28nm);
-       if (ret) {
-               DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
-               return ERR_PTR(ret);
-       }
-
-       return pll;
-}
-
diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c
deleted file mode 100644 (file)
index a6e7a25..0000000
+++ /dev/null
@@ -1,526 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
- */
-
-#include <linux/clk-provider.h>
-
-#include "dsi_pll.h"
-#include "dsi.xml.h"
-
-/*
- * DSI PLL 28nm (8960/A family) - clock diagram (eg: DSI1):
- *
- *
- *                        +------+
- *  dsi1vco_clk ----o-----| DIV1 |---dsi1pllbit (not exposed as clock)
- *  F * byte_clk    |     +------+
- *                  | bit clock divider (F / 8)
- *                  |
- *                  |     +------+
- *                  o-----| DIV2 |---dsi0pllbyte---o---> To byte RCG
- *                  |     +------+                 | (sets parent rate)
- *                  | byte clock divider (F)       |
- *                  |                              |
- *                  |                              o---> To esc RCG
- *                  |                                (doesn't set parent rate)
- *                  |
- *                  |     +------+
- *                  o-----| DIV3 |----dsi0pll------o---> To dsi RCG
- *                        +------+                 | (sets parent rate)
- *                  dsi clock divider (F * magic)  |
- *                                                 |
- *                                                 o---> To pixel rcg
- *                                                  (doesn't set parent rate)
- */
-
-#define POLL_MAX_READS         8000
-#define POLL_TIMEOUT_US                1
-
-#define NUM_PROVIDED_CLKS      2
-
-#define VCO_REF_CLK_RATE       27000000
-#define VCO_MIN_RATE           600000000
-#define VCO_MAX_RATE           1200000000
-
-#define DSI_BYTE_PLL_CLK       0
-#define DSI_PIXEL_PLL_CLK      1
-
-#define VCO_PREF_DIV_RATIO     27
-
-struct pll_28nm_cached_state {
-       unsigned long vco_rate;
-       u8 postdiv3;
-       u8 postdiv2;
-       u8 postdiv1;
-};
-
-struct clk_bytediv {
-       struct clk_hw hw;
-       void __iomem *reg;
-};
-
-struct dsi_pll_28nm {
-       struct msm_dsi_pll base;
-
-       int id;
-       struct platform_device *pdev;
-       void __iomem *mmio;
-
-       /* custom byte clock divider */
-       struct clk_bytediv *bytediv;
-
-       /* private clocks: */
-       struct clk *clks[NUM_DSI_CLOCKS_MAX];
-       u32 num_clks;
-
-       /* clock-provider: */
-       struct clk *provided_clks[NUM_PROVIDED_CLKS];
-       struct clk_onecell_data clk_data;
-
-       struct pll_28nm_cached_state cached_state;
-};
-
-#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, base)
-
-static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm,
-                                   int nb_tries, int timeout_us)
-{
-       bool pll_locked = false;
-       u32 val;
-
-       while (nb_tries--) {
-               val = pll_read(pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_RDY);
-               pll_locked = !!(val & DSI_28nm_8960_PHY_PLL_RDY_PLL_RDY);
-
-               if (pll_locked)
-                       break;
-
-               udelay(timeout_us);
-       }
-       DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* ");
-
-       return pll_locked;
-}
-
-/*
- * Clock Callbacks
- */
-static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate,
-                                    unsigned long parent_rate)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-       void __iomem *base = pll_28nm->mmio;
-       u32 val, temp, fb_divider;
-
-       DBG("rate=%lu, parent's=%lu", rate, parent_rate);
-
-       temp = rate / 10;
-       val = VCO_REF_CLK_RATE / 10;
-       fb_divider = (temp * VCO_PREF_DIV_RATIO) / val;
-       fb_divider = fb_divider / 2 - 1;
-       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1,
-                       fb_divider & 0xff);
-
-       val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2);
-
-       val |= (fb_divider >> 8) & 0x07;
-
-       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2,
-                       val);
-
-       val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3);
-
-       val |= (VCO_PREF_DIV_RATIO - 1) & 0x3f;
-
-       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3,
-                       val);
-
-       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_6,
-                       0xf);
-
-       val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8);
-       val |= 0x7 << 4;
-       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8,
-                       val);
-
-       return 0;
-}
-
-static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-
-       return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS,
-                                       POLL_TIMEOUT_US);
-}
-
-static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw,
-                                                 unsigned long parent_rate)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-       void __iomem *base = pll_28nm->mmio;
-       unsigned long vco_rate;
-       u32 status, fb_divider, temp, ref_divider;
-
-       VERB("parent_rate=%lu", parent_rate);
-
-       status = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0);
-
-       if (status & DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE) {
-               fb_divider = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1);
-               fb_divider &= 0xff;
-               temp = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2) & 0x07;
-               fb_divider = (temp << 8) | fb_divider;
-               fb_divider += 1;
-
-               ref_divider = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3);
-               ref_divider &= 0x3f;
-               ref_divider += 1;
-
-               /* multiply by 2 */
-               vco_rate = (parent_rate / ref_divider) * fb_divider * 2;
-       } else {
-               vco_rate = 0;
-       }
-
-       DBG("returning vco rate = %lu", vco_rate);
-
-       return vco_rate;
-}
-
-static const struct clk_ops clk_ops_dsi_pll_28nm_vco = {
-       .round_rate = msm_dsi_pll_helper_clk_round_rate,
-       .set_rate = dsi_pll_28nm_clk_set_rate,
-       .recalc_rate = dsi_pll_28nm_clk_recalc_rate,
-       .prepare = msm_dsi_pll_helper_clk_prepare,
-       .unprepare = msm_dsi_pll_helper_clk_unprepare,
-       .is_enabled = dsi_pll_28nm_clk_is_enabled,
-};
-
-/*
- * Custom byte clock divier clk_ops
- *
- * This clock is the entry point to configuring the PLL. The user (dsi host)
- * will set this clock's rate to the desired byte clock rate. The VCO lock
- * frequency is a multiple of the byte clock rate. The multiplication factor
- * (shown as F in the diagram above) is a function of the byte clock rate.
- *
- * This custom divider clock ensures that its parent (VCO) is set to the
- * desired rate, and that the byte clock postdivider (POSTDIV2) is configured
- * accordingly
- */
-#define to_clk_bytediv(_hw) container_of(_hw, struct clk_bytediv, hw)
-
-static unsigned long clk_bytediv_recalc_rate(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       struct clk_bytediv *bytediv = to_clk_bytediv(hw);
-       unsigned int div;
-
-       div = pll_read(bytediv->reg) & 0xff;
-
-       return parent_rate / (div + 1);
-}
-
-/* find multiplication factor(wrt byte clock) at which the VCO should be set */
-static unsigned int get_vco_mul_factor(unsigned long byte_clk_rate)
-{
-       unsigned long bit_mhz;
-
-       /* convert to bit clock in Mhz */
-       bit_mhz = (byte_clk_rate * 8) / 1000000;
-
-       if (bit_mhz < 125)
-               return 64;
-       else if (bit_mhz < 250)
-               return 32;
-       else if (bit_mhz < 600)
-               return 16;
-       else
-               return 8;
-}
-
-static long clk_bytediv_round_rate(struct clk_hw *hw, unsigned long rate,
-                                  unsigned long *prate)
-{
-       unsigned long best_parent;
-       unsigned int factor;
-
-       factor = get_vco_mul_factor(rate);
-
-       best_parent = rate * factor;
-       *prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent);
-
-       return *prate / factor;
-}
-
-static int clk_bytediv_set_rate(struct clk_hw *hw, unsigned long rate,
-                               unsigned long parent_rate)
-{
-       struct clk_bytediv *bytediv = to_clk_bytediv(hw);
-       u32 val;
-       unsigned int factor;
-
-       factor = get_vco_mul_factor(rate);
-
-       val = pll_read(bytediv->reg);
-       val |= (factor - 1) & 0xff;
-       pll_write(bytediv->reg, val);
-
-       return 0;
-}
-
-/* Our special byte clock divider ops */
-static const struct clk_ops clk_bytediv_ops = {
-       .round_rate = clk_bytediv_round_rate,
-       .set_rate = clk_bytediv_set_rate,
-       .recalc_rate = clk_bytediv_recalc_rate,
-};
-
-/*
- * PLL Callbacks
- */
-static int dsi_pll_28nm_enable_seq(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-       struct device *dev = &pll_28nm->pdev->dev;
-       void __iomem *base = pll_28nm->mmio;
-       bool locked;
-       unsigned int bit_div, byte_div;
-       int max_reads = 1000, timeout_us = 100;
-       u32 val;
-
-       DBG("id=%d", pll_28nm->id);
-
-       /*
-        * before enabling the PLL, configure the bit clock divider since we
-        * don't expose it as a clock to the outside world
-        * 1: read back the byte clock divider that should already be set
-        * 2: divide by 8 to get bit clock divider
-        * 3: write it to POSTDIV1
-        */
-       val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9);
-       byte_div = val + 1;
-       bit_div = byte_div / 8;
-
-       val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8);
-       val &= ~0xf;
-       val |= (bit_div - 1);
-       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, val);
-
-       /* enable the PLL */
-       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0,
-                       DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE);
-
-       locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us);
-
-       if (unlikely(!locked))
-               DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
-       else
-               DBG("DSI PLL lock success");
-
-       return locked ? 0 : -EINVAL;
-}
-
-static void dsi_pll_28nm_disable_seq(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-
-       DBG("id=%d", pll_28nm->id);
-       pll_write(pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, 0x00);
-}
-
-static void dsi_pll_28nm_save_state(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-       struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
-       void __iomem *base = pll_28nm->mmio;
-
-       cached_state->postdiv3 =
-                       pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10);
-       cached_state->postdiv2 =
-                       pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9);
-       cached_state->postdiv1 =
-                       pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8);
-
-       cached_state->vco_rate = clk_hw_get_rate(&pll->clk_hw);
-}
-
-static int dsi_pll_28nm_restore_state(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-       struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
-       void __iomem *base = pll_28nm->mmio;
-       int ret;
-
-       ret = dsi_pll_28nm_clk_set_rate(&pll->clk_hw,
-                                       cached_state->vco_rate, 0);
-       if (ret) {
-               DRM_DEV_ERROR(&pll_28nm->pdev->dev,
-                       "restore vco rate failed. ret=%d\n", ret);
-               return ret;
-       }
-
-       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10,
-                       cached_state->postdiv3);
-       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9,
-                       cached_state->postdiv2);
-       pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8,
-                       cached_state->postdiv1);
-
-       return 0;
-}
-
-static int dsi_pll_28nm_get_provider(struct msm_dsi_pll *pll,
-                               struct clk **byte_clk_provider,
-                               struct clk **pixel_clk_provider)
-{
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-
-       if (byte_clk_provider)
-               *byte_clk_provider = pll_28nm->provided_clks[DSI_BYTE_PLL_CLK];
-       if (pixel_clk_provider)
-               *pixel_clk_provider =
-                               pll_28nm->provided_clks[DSI_PIXEL_PLL_CLK];
-
-       return 0;
-}
-
-static void dsi_pll_28nm_destroy(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll);
-
-       msm_dsi_pll_helper_unregister_clks(pll_28nm->pdev,
-                                       pll_28nm->clks, pll_28nm->num_clks);
-}
-
-static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm)
-{
-       char *clk_name, *parent_name, *vco_name;
-       struct clk_init_data vco_init = {
-               .parent_names = (const char *[]){ "pxo" },
-               .num_parents = 1,
-               .flags = CLK_IGNORE_UNUSED,
-               .ops = &clk_ops_dsi_pll_28nm_vco,
-       };
-       struct device *dev = &pll_28nm->pdev->dev;
-       struct clk **clks = pll_28nm->clks;
-       struct clk **provided_clks = pll_28nm->provided_clks;
-       struct clk_bytediv *bytediv;
-       struct clk_init_data bytediv_init = { };
-       int ret, num = 0;
-
-       DBG("%d", pll_28nm->id);
-
-       bytediv = devm_kzalloc(dev, sizeof(*bytediv), GFP_KERNEL);
-       if (!bytediv)
-               return -ENOMEM;
-
-       vco_name = devm_kzalloc(dev, 32, GFP_KERNEL);
-       if (!vco_name)
-               return -ENOMEM;
-
-       parent_name = devm_kzalloc(dev, 32, GFP_KERNEL);
-       if (!parent_name)
-               return -ENOMEM;
-
-       clk_name = devm_kzalloc(dev, 32, GFP_KERNEL);
-       if (!clk_name)
-               return -ENOMEM;
-
-       pll_28nm->bytediv = bytediv;
-
-       snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id);
-       vco_init.name = vco_name;
-
-       pll_28nm->base.clk_hw.init = &vco_init;
-
-       clks[num++] = clk_register(dev, &pll_28nm->base.clk_hw);
-
-       /* prepare and register bytediv */
-       bytediv->hw.init = &bytediv_init;
-       bytediv->reg = pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_CTRL_9;
-
-       snprintf(parent_name, 32, "dsi%dvco_clk", pll_28nm->id);
-       snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id);
-
-       bytediv_init.name = clk_name;
-       bytediv_init.ops = &clk_bytediv_ops;
-       bytediv_init.flags = CLK_SET_RATE_PARENT;
-       bytediv_init.parent_names = (const char * const *) &parent_name;
-       bytediv_init.num_parents = 1;
-
-       /* DIV2 */
-       clks[num++] = provided_clks[DSI_BYTE_PLL_CLK] =
-                       clk_register(dev, &bytediv->hw);
-
-       snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id);
-       /* DIV3 */
-       clks[num++] = provided_clks[DSI_PIXEL_PLL_CLK] =
-                       clk_register_divider(dev, clk_name,
-                               parent_name, 0, pll_28nm->mmio +
-                               REG_DSI_28nm_8960_PHY_PLL_CTRL_10,
-                               0, 8, 0, NULL);
-
-       pll_28nm->num_clks = num;
-
-       pll_28nm->clk_data.clk_num = NUM_PROVIDED_CLKS;
-       pll_28nm->clk_data.clks = provided_clks;
-
-       ret = of_clk_add_provider(dev->of_node,
-                       of_clk_src_onecell_get, &pll_28nm->clk_data);
-       if (ret) {
-               DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-struct msm_dsi_pll *msm_dsi_pll_28nm_8960_init(struct platform_device *pdev,
-                                              int id)
-{
-       struct dsi_pll_28nm *pll_28nm;
-       struct msm_dsi_pll *pll;
-       int ret;
-
-       if (!pdev)
-               return ERR_PTR(-ENODEV);
-
-       pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL);
-       if (!pll_28nm)
-               return ERR_PTR(-ENOMEM);
-
-       pll_28nm->pdev = pdev;
-       pll_28nm->id = id + 1;
-
-       pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL");
-       if (IS_ERR_OR_NULL(pll_28nm->mmio)) {
-               DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__);
-               return ERR_PTR(-ENOMEM);
-       }
-
-       pll = &pll_28nm->base;
-       pll->min_rate = VCO_MIN_RATE;
-       pll->max_rate = VCO_MAX_RATE;
-       pll->get_provider = dsi_pll_28nm_get_provider;
-       pll->destroy = dsi_pll_28nm_destroy;
-       pll->disable_seq = dsi_pll_28nm_disable_seq;
-       pll->save_state = dsi_pll_28nm_save_state;
-       pll->restore_state = dsi_pll_28nm_restore_state;
-
-       pll->en_seq_cnt = 1;
-       pll->enable_seqs[0] = dsi_pll_28nm_enable_seq;
-
-       ret = pll_28nm_register(pll_28nm);
-       if (ret) {
-               DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
-               return ERR_PTR(ret);
-       }
-
-       return pll;
-}
diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c
deleted file mode 100644 (file)
index e29b3bf..0000000
+++ /dev/null
@@ -1,913 +0,0 @@
-/*
- * SPDX-License-Identifier: GPL-2.0
- * Copyright (c) 2018, The Linux Foundation
- */
-
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-#include <linux/iopoll.h>
-
-#include "dsi_pll.h"
-#include "dsi.xml.h"
-
-/*
- * DSI PLL 7nm - clock diagram (eg: DSI0): TODO: updated CPHY diagram
- *
- *           dsi0_pll_out_div_clk  dsi0_pll_bit_clk
- *                              |                |
- *                              |                |
- *                 +---------+  |  +----------+  |  +----+
- *  dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk
- *                 +---------+  |  +----------+  |  +----+
- *                              |                |
- *                              |                |         dsi0_pll_by_2_bit_clk
- *                              |                |          |
- *                              |                |  +----+  |  |\  dsi0_pclk_mux
- *                              |                |--| /2 |--o--| \   |
- *                              |                |  +----+     |  \  |  +---------+
- *                              |                --------------|  |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk
- *                              |------------------------------|  /     +---------+
- *                              |          +-----+             | /
- *                              -----------| /4? |--o----------|/
- *                                         +-----+  |           |
- *                                                  |           |dsiclk_sel
- *                                                  |
- *                                                  dsi0_pll_post_out_div_clk
- */
-
-#define DSI_BYTE_PLL_CLK               0
-#define DSI_PIXEL_PLL_CLK              1
-#define NUM_PROVIDED_CLKS              2
-
-#define VCO_REF_CLK_RATE               19200000
-
-struct dsi_pll_regs {
-       u32 pll_prop_gain_rate;
-       u32 pll_lockdet_rate;
-       u32 decimal_div_start;
-       u32 frac_div_start_low;
-       u32 frac_div_start_mid;
-       u32 frac_div_start_high;
-       u32 pll_clock_inverters;
-       u32 ssc_stepsize_low;
-       u32 ssc_stepsize_high;
-       u32 ssc_div_per_low;
-       u32 ssc_div_per_high;
-       u32 ssc_adjper_low;
-       u32 ssc_adjper_high;
-       u32 ssc_control;
-};
-
-struct dsi_pll_config {
-       u32 ref_freq;
-       bool div_override;
-       u32 output_div;
-       bool ignore_frac;
-       bool disable_prescaler;
-       bool enable_ssc;
-       bool ssc_center;
-       u32 dec_bits;
-       u32 frac_bits;
-       u32 lock_timer;
-       u32 ssc_freq;
-       u32 ssc_offset;
-       u32 ssc_adj_per;
-       u32 thresh_cycles;
-       u32 refclk_cycles;
-};
-
-struct pll_7nm_cached_state {
-       unsigned long vco_rate;
-       u8 bit_clk_div;
-       u8 pix_clk_div;
-       u8 pll_out_div;
-       u8 pll_mux;
-};
-
-struct dsi_pll_7nm {
-       struct msm_dsi_pll base;
-
-       int id;
-       struct platform_device *pdev;
-
-       void __iomem *phy_cmn_mmio;
-       void __iomem *mmio;
-
-       u64 vco_ref_clk_rate;
-       u64 vco_current_rate;
-
-       /* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */
-       spinlock_t postdiv_lock;
-
-       int vco_delay;
-       struct dsi_pll_config pll_configuration;
-       struct dsi_pll_regs reg_setup;
-
-       /* private clocks: */
-       struct clk_hw *out_div_clk_hw;
-       struct clk_hw *bit_clk_hw;
-       struct clk_hw *byte_clk_hw;
-       struct clk_hw *by_2_bit_clk_hw;
-       struct clk_hw *post_out_div_clk_hw;
-       struct clk_hw *pclk_mux_hw;
-       struct clk_hw *out_dsiclk_hw;
-
-       /* clock-provider: */
-       struct clk_hw_onecell_data *hw_data;
-
-       struct pll_7nm_cached_state cached_state;
-
-       enum msm_dsi_phy_usecase uc;
-       struct dsi_pll_7nm *slave;
-};
-
-#define to_pll_7nm(x)  container_of(x, struct dsi_pll_7nm, base)
-
-/*
- * Global list of private DSI PLL struct pointers. We need this for Dual DSI
- * mode, where the master PLL's clk_ops needs access the slave's private data
- */
-static struct dsi_pll_7nm *pll_7nm_list[DSI_MAX];
-
-static void dsi_pll_setup_config(struct dsi_pll_7nm *pll)
-{
-       struct dsi_pll_config *config = &pll->pll_configuration;
-
-       config->ref_freq = pll->vco_ref_clk_rate;
-       config->output_div = 1;
-       config->dec_bits = 8;
-       config->frac_bits = 18;
-       config->lock_timer = 64;
-       config->ssc_freq = 31500;
-       config->ssc_offset = 4800;
-       config->ssc_adj_per = 2;
-       config->thresh_cycles = 32;
-       config->refclk_cycles = 256;
-
-       config->div_override = false;
-       config->ignore_frac = false;
-       config->disable_prescaler = false;
-
-       /* TODO: ssc enable */
-       config->enable_ssc = false;
-       config->ssc_center = 0;
-}
-
-static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll)
-{
-       struct dsi_pll_config *config = &pll->pll_configuration;
-       struct dsi_pll_regs *regs = &pll->reg_setup;
-       u64 fref = pll->vco_ref_clk_rate;
-       u64 pll_freq;
-       u64 divider;
-       u64 dec, dec_multiple;
-       u32 frac;
-       u64 multiplier;
-
-       pll_freq = pll->vco_current_rate;
-
-       if (config->disable_prescaler)
-               divider = fref;
-       else
-               divider = fref * 2;
-
-       multiplier = 1 << config->frac_bits;
-       dec_multiple = div_u64(pll_freq * multiplier, divider);
-       div_u64_rem(dec_multiple, multiplier, &frac);
-
-       dec = div_u64(dec_multiple, multiplier);
-
-       if (pll->base.type != MSM_DSI_PHY_7NM_V4_1)
-               regs->pll_clock_inverters = 0x28;
-       else if (pll_freq <= 1000000000ULL)
-               regs->pll_clock_inverters = 0xa0;
-       else if (pll_freq <= 2500000000ULL)
-               regs->pll_clock_inverters = 0x20;
-       else if (pll_freq <= 3020000000ULL)
-               regs->pll_clock_inverters = 0x00;
-       else
-               regs->pll_clock_inverters = 0x40;
-
-       regs->pll_lockdet_rate = config->lock_timer;
-       regs->decimal_div_start = dec;
-       regs->frac_div_start_low = (frac & 0xff);
-       regs->frac_div_start_mid = (frac & 0xff00) >> 8;
-       regs->frac_div_start_high = (frac & 0x30000) >> 16;
-}
-
-#define SSC_CENTER             BIT(0)
-#define SSC_EN                 BIT(1)
-
-static void dsi_pll_calc_ssc(struct dsi_pll_7nm *pll)
-{
-       struct dsi_pll_config *config = &pll->pll_configuration;
-       struct dsi_pll_regs *regs = &pll->reg_setup;
-       u32 ssc_per;
-       u32 ssc_mod;
-       u64 ssc_step_size;
-       u64 frac;
-
-       if (!config->enable_ssc) {
-               DBG("SSC not enabled\n");
-               return;
-       }
-
-       ssc_per = DIV_ROUND_CLOSEST(config->ref_freq, config->ssc_freq) / 2 - 1;
-       ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1);
-       ssc_per -= ssc_mod;
-
-       frac = regs->frac_div_start_low |
-                       (regs->frac_div_start_mid << 8) |
-                       (regs->frac_div_start_high << 16);
-       ssc_step_size = regs->decimal_div_start;
-       ssc_step_size *= (1 << config->frac_bits);
-       ssc_step_size += frac;
-       ssc_step_size *= config->ssc_offset;
-       ssc_step_size *= (config->ssc_adj_per + 1);
-       ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1));
-       ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000);
-
-       regs->ssc_div_per_low = ssc_per & 0xFF;
-       regs->ssc_div_per_high = (ssc_per & 0xFF00) >> 8;
-       regs->ssc_stepsize_low = (u32)(ssc_step_size & 0xFF);
-       regs->ssc_stepsize_high = (u32)((ssc_step_size & 0xFF00) >> 8);
-       regs->ssc_adjper_low = config->ssc_adj_per & 0xFF;
-       regs->ssc_adjper_high = (config->ssc_adj_per & 0xFF00) >> 8;
-
-       regs->ssc_control = config->ssc_center ? SSC_CENTER : 0;
-
-       pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n",
-                regs->decimal_div_start, frac, config->frac_bits);
-       pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n",
-                ssc_per, (u32)ssc_step_size, config->ssc_adj_per);
-}
-
-static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll)
-{
-       void __iomem *base = pll->mmio;
-       struct dsi_pll_regs *regs = &pll->reg_setup;
-
-       if (pll->pll_configuration.enable_ssc) {
-               pr_debug("SSC is enabled\n");
-
-               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_LOW_1,
-                         regs->ssc_stepsize_low);
-               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_HIGH_1,
-                         regs->ssc_stepsize_high);
-               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_LOW_1,
-                         regs->ssc_div_per_low);
-               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_HIGH_1,
-                         regs->ssc_div_per_high);
-               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_LOW_1,
-                         regs->ssc_adjper_low);
-               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_HIGH_1,
-                         regs->ssc_adjper_high);
-               pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_CONTROL,
-                         SSC_EN | regs->ssc_control);
-       }
-}
-
-static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll)
-{
-       void __iomem *base = pll->mmio;
-       u8 analog_controls_five_1 = 0x01, vco_config_1 = 0x00;
-
-       if (pll->base.type == MSM_DSI_PHY_7NM_V4_1) {
-               if (pll->vco_current_rate >= 3100000000ULL)
-                       analog_controls_five_1 = 0x03;
-
-               if (pll->vco_current_rate < 1520000000ULL)
-                       vco_config_1 = 0x08;
-               else if (pll->vco_current_rate < 2990000000ULL)
-                       vco_config_1 = 0x01;
-       }
-
-       pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1,
-                 analog_controls_five_1);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_VCO_CONFIG_1, vco_config_1);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE, 0x01);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_DSM_DIVIDER, 0x00);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE, 0xba);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_OUTDIV, 0x00);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_CORE_OVERRIDE, 0x00);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x0a);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_BAND_SEL_RATE_1, 0xc0);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x84);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x82);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x4c);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x29);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x2f);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_IFILT, 0x2a);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_IFILT,
-                 pll->base.type == MSM_DSI_PHY_7NM_V4_1 ? 0x3f : 0x22);
-
-       if (pll->base.type == MSM_DSI_PHY_7NM_V4_1) {
-               pll_write(base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
-               if (pll->slave)
-                       pll_write(pll->slave->mmio + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
-       }
-}
-
-static void dsi_pll_commit(struct dsi_pll_7nm *pll)
-{
-       void __iomem *base = pll->mmio;
-       struct dsi_pll_regs *reg = &pll->reg_setup;
-
-       pll_write(base + REG_DSI_7nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1, reg->decimal_div_start);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1, reg->frac_div_start_low);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1, reg->frac_div_start_mid);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1, reg->frac_div_start_high);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, reg->pll_lockdet_rate);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06);
-       pll_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, 0x10); /* TODO: 0x00 for CPHY */
-       pll_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, reg->pll_clock_inverters);
-}
-
-static int dsi_pll_7nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
-                                    unsigned long parent_rate)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
-
-       DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_7nm->id, rate,
-           parent_rate);
-
-       pll_7nm->vco_current_rate = rate;
-       pll_7nm->vco_ref_clk_rate = VCO_REF_CLK_RATE;
-
-       dsi_pll_setup_config(pll_7nm);
-
-       dsi_pll_calc_dec_frac(pll_7nm);
-
-       dsi_pll_calc_ssc(pll_7nm);
-
-       dsi_pll_commit(pll_7nm);
-
-       dsi_pll_config_hzindep_reg(pll_7nm);
-
-       dsi_pll_ssc_commit(pll_7nm);
-
-       /* flush, ensure all register writes are done*/
-       wmb();
-
-       return 0;
-}
-
-static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm *pll)
-{
-       int rc;
-       u32 status = 0;
-       u32 const delay_us = 100;
-       u32 const timeout_us = 5000;
-
-       rc = readl_poll_timeout_atomic(pll->mmio +
-                                      REG_DSI_7nm_PHY_PLL_COMMON_STATUS_ONE,
-                                      status,
-                                      ((status & BIT(0)) > 0),
-                                      delay_us,
-                                      timeout_us);
-       if (rc)
-               pr_err("DSI PLL(%d) lock failed, status=0x%08x\n",
-                      pll->id, status);
-
-       return rc;
-}
-
-static void dsi_pll_disable_pll_bias(struct dsi_pll_7nm *pll)
-{
-       u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0);
-
-       pll_write(pll->mmio + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0);
-       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0, data & ~BIT(5));
-       ndelay(250);
-}
-
-static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll)
-{
-       u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0);
-
-       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0, data | BIT(5));
-       pll_write(pll->mmio + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0xc0);
-       ndelay(250);
-}
-
-static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll)
-{
-       u32 data;
-
-       data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
-       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data & ~BIT(5));
-}
-
-static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll)
-{
-       u32 data;
-
-       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x04);
-
-       data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
-       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1,
-                 data | BIT(5) | BIT(4));
-}
-
-static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll)
-{
-       /*
-        * Reset the PHY digital domain. This would be needed when
-        * coming out of a CX or analog rail power collapse while
-        * ensuring that the pads maintain LP00 or LP11 state
-        */
-       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0));
-       wmb(); /* Ensure that the reset is deasserted */
-       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, 0x0);
-       wmb(); /* Ensure that the reset is deasserted */
-}
-
-static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
-       int rc;
-
-       dsi_pll_enable_pll_bias(pll_7nm);
-       if (pll_7nm->slave)
-               dsi_pll_enable_pll_bias(pll_7nm->slave);
-
-       /* Start PLL */
-       pll_write(pll_7nm->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x01);
-
-       /*
-        * ensure all PLL configurations are written prior to checking
-        * for PLL lock.
-        */
-       wmb();
-
-       /* Check for PLL lock */
-       rc = dsi_pll_7nm_lock_status(pll_7nm);
-       if (rc) {
-               pr_err("PLL(%d) lock failed\n", pll_7nm->id);
-               goto error;
-       }
-
-       pll->pll_on = true;
-
-       /*
-        * assert power on reset for PHY digital in case the PLL is
-        * enabled after CX of analog domain power collapse. This needs
-        * to be done before enabling the global clk.
-        */
-       dsi_pll_phy_dig_reset(pll_7nm);
-       if (pll_7nm->slave)
-               dsi_pll_phy_dig_reset(pll_7nm->slave);
-
-       dsi_pll_enable_global_clk(pll_7nm);
-       if (pll_7nm->slave)
-               dsi_pll_enable_global_clk(pll_7nm->slave);
-
-error:
-       return rc;
-}
-
-static void dsi_pll_disable_sub(struct dsi_pll_7nm *pll)
-{
-       pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0);
-       dsi_pll_disable_pll_bias(pll);
-}
-
-static void dsi_pll_7nm_vco_unprepare(struct clk_hw *hw)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
-
-       /*
-        * To avoid any stray glitches while abruptly powering down the PLL
-        * make sure to gate the clock using the clock enable bit before
-        * powering down the PLL
-        */
-       dsi_pll_disable_global_clk(pll_7nm);
-       pll_write(pll_7nm->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0);
-       dsi_pll_disable_sub(pll_7nm);
-       if (pll_7nm->slave) {
-               dsi_pll_disable_global_clk(pll_7nm->slave);
-               dsi_pll_disable_sub(pll_7nm->slave);
-       }
-       /* flush, ensure all register writes are done */
-       wmb();
-       pll->pll_on = false;
-}
-
-static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw,
-                                                 unsigned long parent_rate)
-{
-       struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
-       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
-       struct dsi_pll_config *config = &pll_7nm->pll_configuration;
-       void __iomem *base = pll_7nm->mmio;
-       u64 ref_clk = pll_7nm->vco_ref_clk_rate;
-       u64 vco_rate = 0x0;
-       u64 multiplier;
-       u32 frac;
-       u32 dec;
-       u64 pll_freq, tmp64;
-
-       dec = pll_read(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1);
-       dec &= 0xff;
-
-       frac = pll_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1);
-       frac |= ((pll_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1) &
-                 0xff) << 8);
-       frac |= ((pll_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1) &
-                 0x3) << 16);
-
-       /*
-        * TODO:
-        *      1. Assumes prescaler is disabled
-        */
-       multiplier = 1 << config->frac_bits;
-       pll_freq = dec * (ref_clk * 2);
-       tmp64 = (ref_clk * 2 * frac);
-       pll_freq += div_u64(tmp64, multiplier);
-
-       vco_rate = pll_freq;
-
-       DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x",
-           pll_7nm->id, (unsigned long)vco_rate, dec, frac);
-
-       return (unsigned long)vco_rate;
-}
-
-static const struct clk_ops clk_ops_dsi_pll_7nm_vco = {
-       .round_rate = msm_dsi_pll_helper_clk_round_rate,
-       .set_rate = dsi_pll_7nm_vco_set_rate,
-       .recalc_rate = dsi_pll_7nm_vco_recalc_rate,
-       .prepare = dsi_pll_7nm_vco_prepare,
-       .unprepare = dsi_pll_7nm_vco_unprepare,
-};
-
-/*
- * PLL Callbacks
- */
-
-static void dsi_pll_7nm_save_state(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
-       struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;
-       void __iomem *phy_base = pll_7nm->phy_cmn_mmio;
-       u32 cmn_clk_cfg0, cmn_clk_cfg1;
-
-       cached->pll_out_div = pll_read(pll_7nm->mmio +
-                                      REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);
-       cached->pll_out_div &= 0x3;
-
-       cmn_clk_cfg0 = pll_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0);
-       cached->bit_clk_div = cmn_clk_cfg0 & 0xf;
-       cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4;
-
-       cmn_clk_cfg1 = pll_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
-       cached->pll_mux = cmn_clk_cfg1 & 0x3;
-
-       DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x",
-           pll_7nm->id, cached->pll_out_div, cached->bit_clk_div,
-           cached->pix_clk_div, cached->pll_mux);
-}
-
-static int dsi_pll_7nm_restore_state(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
-       struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;
-       void __iomem *phy_base = pll_7nm->phy_cmn_mmio;
-       u32 val;
-       int ret;
-
-       val = pll_read(pll_7nm->mmio + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);
-       val &= ~0x3;
-       val |= cached->pll_out_div;
-       pll_write(pll_7nm->mmio + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, val);
-
-       pll_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0,
-                 cached->bit_clk_div | (cached->pix_clk_div << 4));
-
-       val = pll_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
-       val &= ~0x3;
-       val |= cached->pll_mux;
-       pll_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, val);
-
-       ret = dsi_pll_7nm_vco_set_rate(&pll->clk_hw, pll_7nm->vco_current_rate, pll_7nm->vco_ref_clk_rate);
-       if (ret) {
-               DRM_DEV_ERROR(&pll_7nm->pdev->dev,
-                       "restore vco rate failed. ret=%d\n", ret);
-               return ret;
-       }
-
-       DBG("DSI PLL%d", pll_7nm->id);
-
-       return 0;
-}
-
-static int dsi_pll_7nm_set_usecase(struct msm_dsi_pll *pll,
-                                   enum msm_dsi_phy_usecase uc)
-{
-       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
-       void __iomem *base = pll_7nm->phy_cmn_mmio;
-       u32 data = 0x0; /* internal PLL */
-
-       DBG("DSI PLL%d", pll_7nm->id);
-
-       switch (uc) {
-       case MSM_DSI_PHY_STANDALONE:
-               break;
-       case MSM_DSI_PHY_MASTER:
-               pll_7nm->slave = pll_7nm_list[(pll_7nm->id + 1) % DSI_MAX];
-               break;
-       case MSM_DSI_PHY_SLAVE:
-               data = 0x1; /* external PLL */
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* set PLL src */
-       pll_write(base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, (data << 2));
-
-       pll_7nm->uc = uc;
-
-       return 0;
-}
-
-static int dsi_pll_7nm_get_provider(struct msm_dsi_pll *pll,
-                                    struct clk **byte_clk_provider,
-                                    struct clk **pixel_clk_provider)
-{
-       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
-       struct clk_hw_onecell_data *hw_data = pll_7nm->hw_data;
-
-       DBG("DSI PLL%d", pll_7nm->id);
-
-       if (byte_clk_provider)
-               *byte_clk_provider = hw_data->hws[DSI_BYTE_PLL_CLK]->clk;
-       if (pixel_clk_provider)
-               *pixel_clk_provider = hw_data->hws[DSI_PIXEL_PLL_CLK]->clk;
-
-       return 0;
-}
-
-static void dsi_pll_7nm_destroy(struct msm_dsi_pll *pll)
-{
-       struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
-       struct device *dev = &pll_7nm->pdev->dev;
-
-       DBG("DSI PLL%d", pll_7nm->id);
-       of_clk_del_provider(dev->of_node);
-
-       clk_hw_unregister_divider(pll_7nm->out_dsiclk_hw);
-       clk_hw_unregister_mux(pll_7nm->pclk_mux_hw);
-       clk_hw_unregister_fixed_factor(pll_7nm->post_out_div_clk_hw);
-       clk_hw_unregister_fixed_factor(pll_7nm->by_2_bit_clk_hw);
-       clk_hw_unregister_fixed_factor(pll_7nm->byte_clk_hw);
-       clk_hw_unregister_divider(pll_7nm->bit_clk_hw);
-       clk_hw_unregister_divider(pll_7nm->out_div_clk_hw);
-       clk_hw_unregister(&pll_7nm->base.clk_hw);
-}
-
-/*
- * The post dividers and mux clocks are created using the standard divider and
- * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux
- * state to follow the master PLL's divider/mux state. Therefore, we don't
- * require special clock ops that also configure the slave PLL registers
- */
-static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm)
-{
-       char clk_name[32], parent[32], vco_name[32];
-       char parent2[32], parent3[32], parent4[32];
-       struct clk_init_data vco_init = {
-               .parent_names = (const char *[]){ "bi_tcxo" },
-               .num_parents = 1,
-               .name = vco_name,
-               .flags = CLK_IGNORE_UNUSED,
-               .ops = &clk_ops_dsi_pll_7nm_vco,
-       };
-       struct device *dev = &pll_7nm->pdev->dev;
-       struct clk_hw_onecell_data *hw_data;
-       struct clk_hw *hw;
-       int ret;
-
-       DBG("DSI%d", pll_7nm->id);
-
-       hw_data = devm_kzalloc(dev, sizeof(*hw_data) +
-                              NUM_PROVIDED_CLKS * sizeof(struct clk_hw *),
-                              GFP_KERNEL);
-       if (!hw_data)
-               return -ENOMEM;
-
-       snprintf(vco_name, 32, "dsi%dvco_clk", pll_7nm->id);
-       pll_7nm->base.clk_hw.init = &vco_init;
-
-       ret = clk_hw_register(dev, &pll_7nm->base.clk_hw);
-       if (ret)
-               return ret;
-
-       snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_7nm->id);
-       snprintf(parent, 32, "dsi%dvco_clk", pll_7nm->id);
-
-       hw = clk_hw_register_divider(dev, clk_name,
-                                    parent, CLK_SET_RATE_PARENT,
-                                    pll_7nm->mmio +
-                                    REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE,
-                                    0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_base_clk_hw;
-       }
-
-       pll_7nm->out_div_clk_hw = hw;
-
-       snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_7nm->id);
-       snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->id);
-
-       /* BIT CLK: DIV_CTRL_3_0 */
-       hw = clk_hw_register_divider(dev, clk_name, parent,
-                                    CLK_SET_RATE_PARENT,
-                                    pll_7nm->phy_cmn_mmio +
-                                    REG_DSI_7nm_PHY_CMN_CLK_CFG0,
-                                    0, 4, CLK_DIVIDER_ONE_BASED,
-                                    &pll_7nm->postdiv_lock);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_out_div_clk_hw;
-       }
-
-       pll_7nm->bit_clk_hw = hw;
-
-       snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_7nm->id);
-       snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id);
-
-       /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */
-       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
-                                         CLK_SET_RATE_PARENT, 1, 8);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_bit_clk_hw;
-       }
-
-       pll_7nm->byte_clk_hw = hw;
-       hw_data->hws[DSI_BYTE_PLL_CLK] = hw;
-
-       snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->id);
-       snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id);
-
-       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
-                                         0, 1, 2);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_byte_clk_hw;
-       }
-
-       pll_7nm->by_2_bit_clk_hw = hw;
-
-       snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->id);
-       snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->id);
-
-       hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
-                                         0, 1, 4);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_by_2_bit_clk_hw;
-       }
-
-       pll_7nm->post_out_div_clk_hw = hw;
-
-       snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_7nm->id);
-       snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id);
-       snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->id);
-       snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_7nm->id);
-       snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->id);
-
-       hw = clk_hw_register_mux(dev, clk_name,
-                                ((const char *[]){
-                                parent, parent2, parent3, parent4
-                                }), 4, 0, pll_7nm->phy_cmn_mmio +
-                                REG_DSI_7nm_PHY_CMN_CLK_CFG1,
-                                0, 2, 0, NULL);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_post_out_div_clk_hw;
-       }
-
-       pll_7nm->pclk_mux_hw = hw;
-
-       snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_7nm->id);
-       snprintf(parent, 32, "dsi%d_pclk_mux", pll_7nm->id);
-
-       /* PIX CLK DIV : DIV_CTRL_7_4*/
-       hw = clk_hw_register_divider(dev, clk_name, parent,
-                                    0, pll_7nm->phy_cmn_mmio +
-                                       REG_DSI_7nm_PHY_CMN_CLK_CFG0,
-                                    4, 4, CLK_DIVIDER_ONE_BASED,
-                                    &pll_7nm->postdiv_lock);
-       if (IS_ERR(hw)) {
-               ret = PTR_ERR(hw);
-               goto err_pclk_mux_hw;
-       }
-
-       pll_7nm->out_dsiclk_hw = hw;
-       hw_data->hws[DSI_PIXEL_PLL_CLK] = hw;
-
-       hw_data->num = NUM_PROVIDED_CLKS;
-       pll_7nm->hw_data = hw_data;
-
-       ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
-                                    pll_7nm->hw_data);
-       if (ret) {
-               DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
-               goto err_dsiclk_hw;
-       }
-
-       return 0;
-
-err_dsiclk_hw:
-       clk_hw_unregister_divider(pll_7nm->out_dsiclk_hw);
-err_pclk_mux_hw:
-       clk_hw_unregister_mux(pll_7nm->pclk_mux_hw);
-err_post_out_div_clk_hw:
-       clk_hw_unregister_fixed_factor(pll_7nm->post_out_div_clk_hw);
-err_by_2_bit_clk_hw:
-       clk_hw_unregister_fixed_factor(pll_7nm->by_2_bit_clk_hw);
-err_byte_clk_hw:
-       clk_hw_unregister_fixed_factor(pll_7nm->byte_clk_hw);
-err_bit_clk_hw:
-       clk_hw_unregister_divider(pll_7nm->bit_clk_hw);
-err_out_div_clk_hw:
-       clk_hw_unregister_divider(pll_7nm->out_div_clk_hw);
-err_base_clk_hw:
-       clk_hw_unregister(&pll_7nm->base.clk_hw);
-
-       return ret;
-}
-
-struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev,
-                                       enum msm_dsi_phy_type type, int id)
-{
-       struct dsi_pll_7nm *pll_7nm;
-       struct msm_dsi_pll *pll;
-       int ret;
-
-       pll_7nm = devm_kzalloc(&pdev->dev, sizeof(*pll_7nm), GFP_KERNEL);
-       if (!pll_7nm)
-               return ERR_PTR(-ENOMEM);
-
-       DBG("DSI PLL%d", id);
-
-       pll_7nm->pdev = pdev;
-       pll_7nm->id = id;
-       pll_7nm_list[id] = pll_7nm;
-
-       pll_7nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY");
-       if (IS_ERR_OR_NULL(pll_7nm->phy_cmn_mmio)) {
-               DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n");
-               return ERR_PTR(-ENOMEM);
-       }
-
-       pll_7nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL");
-       if (IS_ERR_OR_NULL(pll_7nm->mmio)) {
-               DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n");
-               return ERR_PTR(-ENOMEM);
-       }
-
-       spin_lock_init(&pll_7nm->postdiv_lock);
-
-       pll = &pll_7nm->base;
-       pll->min_rate = 1000000000UL;
-       pll->max_rate = 3500000000UL;
-       if (type == MSM_DSI_PHY_7NM_V4_1) {
-               pll->min_rate = 600000000UL;
-               pll->max_rate = (unsigned long)5000000000ULL;
-               /* workaround for max rate overflowing on 32-bit builds: */
-               pll->max_rate = max(pll->max_rate, 0xffffffffUL);
-       }
-       pll->get_provider = dsi_pll_7nm_get_provider;
-       pll->destroy = dsi_pll_7nm_destroy;
-       pll->save_state = dsi_pll_7nm_save_state;
-       pll->restore_state = dsi_pll_7nm_restore_state;
-       pll->set_usecase = dsi_pll_7nm_set_usecase;
-
-       pll_7nm->vco_delay = 1;
-
-       ret = pll_7nm_register(pll_7nm);
-       if (ret) {
-               DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
-               return ERR_PTR(ret);
-       }
-
-       /* TODO: Remove this when we have proper display handover support */
-       msm_dsi_pll_save_state(pll);
-
-       return pll;
-}