Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * SPDX-License-Identifier: GPL-2.0
0003  * Copyright (c) 2018, The Linux Foundation
0004  */
0005 
0006 #include <linux/clk.h>
0007 #include <linux/clk-provider.h>
0008 #include <linux/iopoll.h>
0009 
0010 #include "dsi_phy.h"
0011 #include "dsi.xml.h"
0012 #include "dsi_phy_10nm.xml.h"
0013 
0014 /*
0015  * DSI PLL 10nm - clock diagram (eg: DSI0):
0016  *
0017  *           dsi0_pll_out_div_clk  dsi0_pll_bit_clk
0018  *                              |                |
0019  *                              |                |
0020  *                 +---------+  |  +----------+  |  +----+
0021  *  dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk
0022  *                 +---------+  |  +----------+  |  +----+
0023  *                              |                |
0024  *                              |                |         dsi0_pll_by_2_bit_clk
0025  *                              |                |          |
0026  *                              |                |  +----+  |  |\  dsi0_pclk_mux
0027  *                              |                |--| /2 |--o--| \   |
0028  *                              |                |  +----+     |  \  |  +---------+
0029  *                              |                --------------|  |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk
0030  *                              |------------------------------|  /     +---------+
0031  *                              |          +-----+             | /
0032  *                              -----------| /4? |--o----------|/
0033  *                                         +-----+  |           |
0034  *                                                  |           |dsiclk_sel
0035  *                                                  |
0036  *                                                  dsi0_pll_post_out_div_clk
0037  */
0038 
0039 #define VCO_REF_CLK_RATE        19200000
0040 #define FRAC_BITS 18
0041 
0042 /* v3.0.0 10nm implementation that requires the old timings settings */
0043 #define DSI_PHY_10NM_QUIRK_OLD_TIMINGS  BIT(0)
0044 
0045 struct dsi_pll_config {
0046     bool enable_ssc;
0047     bool ssc_center;
0048     u32 ssc_freq;
0049     u32 ssc_offset;
0050     u32 ssc_adj_per;
0051 
0052     /* out */
0053     u32 pll_prop_gain_rate;
0054     u32 decimal_div_start;
0055     u32 frac_div_start;
0056     u32 pll_clock_inverters;
0057     u32 ssc_stepsize;
0058     u32 ssc_div_per;
0059 };
0060 
0061 struct pll_10nm_cached_state {
0062     unsigned long vco_rate;
0063     u8 bit_clk_div;
0064     u8 pix_clk_div;
0065     u8 pll_out_div;
0066     u8 pll_mux;
0067 };
0068 
0069 struct dsi_pll_10nm {
0070     struct clk_hw clk_hw;
0071 
0072     struct msm_dsi_phy *phy;
0073 
0074     u64 vco_current_rate;
0075 
0076     /* protects REG_DSI_10nm_PHY_CMN_CLK_CFG0 register */
0077     spinlock_t postdiv_lock;
0078 
0079     struct pll_10nm_cached_state cached_state;
0080 
0081     struct dsi_pll_10nm *slave;
0082 };
0083 
0084 #define to_pll_10nm(x)  container_of(x, struct dsi_pll_10nm, clk_hw)
0085 
0086 /**
0087  * struct dsi_phy_10nm_tuning_cfg - Holds 10nm PHY tuning config parameters.
0088  * @rescode_offset_top: Offset for pull-up legs rescode.
0089  * @rescode_offset_bot: Offset for pull-down legs rescode.
0090  * @vreg_ctrl: vreg ctrl to drive LDO level
0091  */
0092 struct dsi_phy_10nm_tuning_cfg {
0093     u8 rescode_offset_top[DSI_LANE_MAX];
0094     u8 rescode_offset_bot[DSI_LANE_MAX];
0095     u8 vreg_ctrl;
0096 };
0097 
0098 /*
0099  * Global list of private DSI PLL struct pointers. We need this for bonded DSI
0100  * mode, where the master PLL's clk_ops needs access the slave's private data
0101  */
0102 static struct dsi_pll_10nm *pll_10nm_list[DSI_MAX];
0103 
0104 static void dsi_pll_setup_config(struct dsi_pll_config *config)
0105 {
0106     config->ssc_freq = 31500;
0107     config->ssc_offset = 5000;
0108     config->ssc_adj_per = 2;
0109 
0110     config->enable_ssc = false;
0111     config->ssc_center = false;
0112 }
0113 
0114 static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll, struct dsi_pll_config *config)
0115 {
0116     u64 fref = VCO_REF_CLK_RATE;
0117     u64 pll_freq;
0118     u64 divider;
0119     u64 dec, dec_multiple;
0120     u32 frac;
0121     u64 multiplier;
0122 
0123     pll_freq = pll->vco_current_rate;
0124 
0125     divider = fref * 2;
0126 
0127     multiplier = 1 << FRAC_BITS;
0128     dec_multiple = div_u64(pll_freq * multiplier, divider);
0129     dec = div_u64_rem(dec_multiple, multiplier, &frac);
0130 
0131     if (pll_freq <= 1900000000UL)
0132         config->pll_prop_gain_rate = 8;
0133     else if (pll_freq <= 3000000000UL)
0134         config->pll_prop_gain_rate = 10;
0135     else
0136         config->pll_prop_gain_rate = 12;
0137     if (pll_freq < 1100000000UL)
0138         config->pll_clock_inverters = 8;
0139     else
0140         config->pll_clock_inverters = 0;
0141 
0142     config->decimal_div_start = dec;
0143     config->frac_div_start = frac;
0144 }
0145 
0146 #define SSC_CENTER      BIT(0)
0147 #define SSC_EN          BIT(1)
0148 
0149 static void dsi_pll_calc_ssc(struct dsi_pll_10nm *pll, struct dsi_pll_config *config)
0150 {
0151     u32 ssc_per;
0152     u32 ssc_mod;
0153     u64 ssc_step_size;
0154     u64 frac;
0155 
0156     if (!config->enable_ssc) {
0157         DBG("SSC not enabled\n");
0158         return;
0159     }
0160 
0161     ssc_per = DIV_ROUND_CLOSEST(VCO_REF_CLK_RATE, config->ssc_freq) / 2 - 1;
0162     ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1);
0163     ssc_per -= ssc_mod;
0164 
0165     frac = config->frac_div_start;
0166     ssc_step_size = config->decimal_div_start;
0167     ssc_step_size *= (1 << FRAC_BITS);
0168     ssc_step_size += frac;
0169     ssc_step_size *= config->ssc_offset;
0170     ssc_step_size *= (config->ssc_adj_per + 1);
0171     ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1));
0172     ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000);
0173 
0174     config->ssc_div_per = ssc_per;
0175     config->ssc_stepsize = ssc_step_size;
0176 
0177     pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n",
0178          config->decimal_div_start, frac, FRAC_BITS);
0179     pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n",
0180          ssc_per, (u32)ssc_step_size, config->ssc_adj_per);
0181 }
0182 
0183 static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll, struct dsi_pll_config *config)
0184 {
0185     void __iomem *base = pll->phy->pll_base;
0186 
0187     if (config->enable_ssc) {
0188         pr_debug("SSC is enabled\n");
0189 
0190         dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_LOW_1,
0191               config->ssc_stepsize & 0xff);
0192         dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_HIGH_1,
0193               config->ssc_stepsize >> 8);
0194         dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_LOW_1,
0195               config->ssc_div_per & 0xff);
0196         dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_HIGH_1,
0197               config->ssc_div_per >> 8);
0198         dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_LOW_1,
0199               config->ssc_adj_per & 0xff);
0200         dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_HIGH_1,
0201               config->ssc_adj_per >> 8);
0202         dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_CONTROL,
0203               SSC_EN | (config->ssc_center ? SSC_CENTER : 0));
0204     }
0205 }
0206 
0207 static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll)
0208 {
0209     void __iomem *base = pll->phy->pll_base;
0210 
0211     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_ONE, 0x80);
0212     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03);
0213     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00);
0214     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_DSM_DIVIDER, 0x00);
0215     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e);
0216     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40);
0217     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE,
0218           0xba);
0219     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c);
0220     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_OUTDIV, 0x00);
0221     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CORE_OVERRIDE, 0x00);
0222     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08);
0223     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x08);
0224     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_BAND_SET_RATE_1, 0xc0);
0225     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0xfa);
0226     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1,
0227           0x4c);
0228     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80);
0229     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PFILT, 0x29);
0230     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_IFILT, 0x3f);
0231 }
0232 
0233 static void dsi_pll_commit(struct dsi_pll_10nm *pll, struct dsi_pll_config *config)
0234 {
0235     void __iomem *base = pll->phy->pll_base;
0236 
0237     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12);
0238     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1,
0239           config->decimal_div_start);
0240     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1,
0241           config->frac_div_start & 0xff);
0242     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1,
0243           (config->frac_div_start & 0xff00) >> 8);
0244     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1,
0245           (config->frac_div_start & 0x30000) >> 16);
0246     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCKDET_RATE_1, 64);
0247     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_DELAY, 0x06);
0248     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CMODE, 0x10);
0249     dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CLOCK_INVERTERS,
0250           config->pll_clock_inverters);
0251 }
0252 
0253 static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
0254                      unsigned long parent_rate)
0255 {
0256     struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
0257     struct dsi_pll_config config;
0258 
0259     DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_10nm->phy->id, rate,
0260         parent_rate);
0261 
0262     pll_10nm->vco_current_rate = rate;
0263 
0264     dsi_pll_setup_config(&config);
0265 
0266     dsi_pll_calc_dec_frac(pll_10nm, &config);
0267 
0268     dsi_pll_calc_ssc(pll_10nm, &config);
0269 
0270     dsi_pll_commit(pll_10nm, &config);
0271 
0272     dsi_pll_config_hzindep_reg(pll_10nm);
0273 
0274     dsi_pll_ssc_commit(pll_10nm, &config);
0275 
0276     /* flush, ensure all register writes are done*/
0277     wmb();
0278 
0279     return 0;
0280 }
0281 
0282 static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll)
0283 {
0284     struct device *dev = &pll->phy->pdev->dev;
0285     int rc;
0286     u32 status = 0;
0287     u32 const delay_us = 100;
0288     u32 const timeout_us = 5000;
0289 
0290     rc = readl_poll_timeout_atomic(pll->phy->pll_base +
0291                        REG_DSI_10nm_PHY_PLL_COMMON_STATUS_ONE,
0292                        status,
0293                        ((status & BIT(0)) > 0),
0294                        delay_us,
0295                        timeout_us);
0296     if (rc)
0297         DRM_DEV_ERROR(dev, "DSI PLL(%d) lock failed, status=0x%08x\n",
0298                   pll->phy->id, status);
0299 
0300     return rc;
0301 }
0302 
0303 static void dsi_pll_disable_pll_bias(struct dsi_pll_10nm *pll)
0304 {
0305     u32 data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0);
0306 
0307     dsi_phy_write(pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0);
0308     dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0,
0309           data & ~BIT(5));
0310     ndelay(250);
0311 }
0312 
0313 static void dsi_pll_enable_pll_bias(struct dsi_pll_10nm *pll)
0314 {
0315     u32 data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0);
0316 
0317     dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0,
0318           data | BIT(5));
0319     dsi_phy_write(pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0xc0);
0320     ndelay(250);
0321 }
0322 
0323 static void dsi_pll_disable_global_clk(struct dsi_pll_10nm *pll)
0324 {
0325     u32 data;
0326 
0327     data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
0328     dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1,
0329           data & ~BIT(5));
0330 }
0331 
0332 static void dsi_pll_enable_global_clk(struct dsi_pll_10nm *pll)
0333 {
0334     u32 data;
0335 
0336     data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
0337     dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1,
0338           data | BIT(5));
0339 }
0340 
0341 static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw)
0342 {
0343     struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
0344     struct device *dev = &pll_10nm->phy->pdev->dev;
0345     int rc;
0346 
0347     dsi_pll_enable_pll_bias(pll_10nm);
0348     if (pll_10nm->slave)
0349         dsi_pll_enable_pll_bias(pll_10nm->slave);
0350 
0351     rc = dsi_pll_10nm_vco_set_rate(hw,pll_10nm->vco_current_rate, 0);
0352     if (rc) {
0353         DRM_DEV_ERROR(dev, "vco_set_rate failed, rc=%d\n", rc);
0354         return rc;
0355     }
0356 
0357     /* Start PLL */
0358     dsi_phy_write(pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL,
0359           0x01);
0360 
0361     /*
0362      * ensure all PLL configurations are written prior to checking
0363      * for PLL lock.
0364      */
0365     wmb();
0366 
0367     /* Check for PLL lock */
0368     rc = dsi_pll_10nm_lock_status(pll_10nm);
0369     if (rc) {
0370         DRM_DEV_ERROR(dev, "PLL(%d) lock failed\n", pll_10nm->phy->id);
0371         goto error;
0372     }
0373 
0374     pll_10nm->phy->pll_on = true;
0375 
0376     dsi_pll_enable_global_clk(pll_10nm);
0377     if (pll_10nm->slave)
0378         dsi_pll_enable_global_clk(pll_10nm->slave);
0379 
0380     dsi_phy_write(pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL,
0381           0x01);
0382     if (pll_10nm->slave)
0383         dsi_phy_write(pll_10nm->slave->phy->base +
0384               REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0x01);
0385 
0386 error:
0387     return rc;
0388 }
0389 
0390 static void dsi_pll_disable_sub(struct dsi_pll_10nm *pll)
0391 {
0392     dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0);
0393     dsi_pll_disable_pll_bias(pll);
0394 }
0395 
0396 static void dsi_pll_10nm_vco_unprepare(struct clk_hw *hw)
0397 {
0398     struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
0399 
0400     /*
0401      * To avoid any stray glitches while abruptly powering down the PLL
0402      * make sure to gate the clock using the clock enable bit before
0403      * powering down the PLL
0404      */
0405     dsi_pll_disable_global_clk(pll_10nm);
0406     dsi_phy_write(pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0);
0407     dsi_pll_disable_sub(pll_10nm);
0408     if (pll_10nm->slave) {
0409         dsi_pll_disable_global_clk(pll_10nm->slave);
0410         dsi_pll_disable_sub(pll_10nm->slave);
0411     }
0412     /* flush, ensure all register writes are done */
0413     wmb();
0414     pll_10nm->phy->pll_on = false;
0415 }
0416 
0417 static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw,
0418                           unsigned long parent_rate)
0419 {
0420     struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
0421     void __iomem *base = pll_10nm->phy->pll_base;
0422     u64 ref_clk = VCO_REF_CLK_RATE;
0423     u64 vco_rate = 0x0;
0424     u64 multiplier;
0425     u32 frac;
0426     u32 dec;
0427     u64 pll_freq, tmp64;
0428 
0429     dec = dsi_phy_read(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1);
0430     dec &= 0xff;
0431 
0432     frac = dsi_phy_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1);
0433     frac |= ((dsi_phy_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1) &
0434           0xff) << 8);
0435     frac |= ((dsi_phy_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1) &
0436           0x3) << 16);
0437 
0438     /*
0439      * TODO:
0440      *  1. Assumes prescaler is disabled
0441      */
0442     multiplier = 1 << FRAC_BITS;
0443     pll_freq = dec * (ref_clk * 2);
0444     tmp64 = (ref_clk * 2 * frac);
0445     pll_freq += div_u64(tmp64, multiplier);
0446 
0447     vco_rate = pll_freq;
0448     pll_10nm->vco_current_rate = vco_rate;
0449 
0450     DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x",
0451         pll_10nm->phy->id, (unsigned long)vco_rate, dec, frac);
0452 
0453     return (unsigned long)vco_rate;
0454 }
0455 
0456 static long dsi_pll_10nm_clk_round_rate(struct clk_hw *hw,
0457         unsigned long rate, unsigned long *parent_rate)
0458 {
0459     struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
0460 
0461     if      (rate < pll_10nm->phy->cfg->min_pll_rate)
0462         return  pll_10nm->phy->cfg->min_pll_rate;
0463     else if (rate > pll_10nm->phy->cfg->max_pll_rate)
0464         return  pll_10nm->phy->cfg->max_pll_rate;
0465     else
0466         return rate;
0467 }
0468 
0469 static const struct clk_ops clk_ops_dsi_pll_10nm_vco = {
0470     .round_rate = dsi_pll_10nm_clk_round_rate,
0471     .set_rate = dsi_pll_10nm_vco_set_rate,
0472     .recalc_rate = dsi_pll_10nm_vco_recalc_rate,
0473     .prepare = dsi_pll_10nm_vco_prepare,
0474     .unprepare = dsi_pll_10nm_vco_unprepare,
0475 };
0476 
0477 /*
0478  * PLL Callbacks
0479  */
0480 
0481 static void dsi_10nm_pll_save_state(struct msm_dsi_phy *phy)
0482 {
0483     struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw);
0484     struct pll_10nm_cached_state *cached = &pll_10nm->cached_state;
0485     void __iomem *phy_base = pll_10nm->phy->base;
0486     u32 cmn_clk_cfg0, cmn_clk_cfg1;
0487 
0488     cached->pll_out_div = dsi_phy_read(pll_10nm->phy->pll_base +
0489                        REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE);
0490     cached->pll_out_div &= 0x3;
0491 
0492     cmn_clk_cfg0 = dsi_phy_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0);
0493     cached->bit_clk_div = cmn_clk_cfg0 & 0xf;
0494     cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4;
0495 
0496     cmn_clk_cfg1 = dsi_phy_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
0497     cached->pll_mux = cmn_clk_cfg1 & 0x3;
0498 
0499     DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x",
0500         pll_10nm->phy->id, cached->pll_out_div, cached->bit_clk_div,
0501         cached->pix_clk_div, cached->pll_mux);
0502 }
0503 
0504 static int dsi_10nm_pll_restore_state(struct msm_dsi_phy *phy)
0505 {
0506     struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw);
0507     struct pll_10nm_cached_state *cached = &pll_10nm->cached_state;
0508     void __iomem *phy_base = pll_10nm->phy->base;
0509     u32 val;
0510     int ret;
0511 
0512     val = dsi_phy_read(pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE);
0513     val &= ~0x3;
0514     val |= cached->pll_out_div;
0515     dsi_phy_write(pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, val);
0516 
0517     dsi_phy_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0,
0518           cached->bit_clk_div | (cached->pix_clk_div << 4));
0519 
0520     val = dsi_phy_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
0521     val &= ~0x3;
0522     val |= cached->pll_mux;
0523     dsi_phy_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, val);
0524 
0525     ret = dsi_pll_10nm_vco_set_rate(phy->vco_hw,
0526             pll_10nm->vco_current_rate,
0527             VCO_REF_CLK_RATE);
0528     if (ret) {
0529         DRM_DEV_ERROR(&pll_10nm->phy->pdev->dev,
0530             "restore vco rate failed. ret=%d\n", ret);
0531         return ret;
0532     }
0533 
0534     DBG("DSI PLL%d", pll_10nm->phy->id);
0535 
0536     return 0;
0537 }
0538 
0539 static int dsi_10nm_set_usecase(struct msm_dsi_phy *phy)
0540 {
0541     struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw);
0542     void __iomem *base = phy->base;
0543     u32 data = 0x0; /* internal PLL */
0544 
0545     DBG("DSI PLL%d", pll_10nm->phy->id);
0546 
0547     switch (phy->usecase) {
0548     case MSM_DSI_PHY_STANDALONE:
0549         break;
0550     case MSM_DSI_PHY_MASTER:
0551         pll_10nm->slave = pll_10nm_list[(pll_10nm->phy->id + 1) % DSI_MAX];
0552         break;
0553     case MSM_DSI_PHY_SLAVE:
0554         data = 0x1; /* external PLL */
0555         break;
0556     default:
0557         return -EINVAL;
0558     }
0559 
0560     /* set PLL src */
0561     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, (data << 2));
0562 
0563     return 0;
0564 }
0565 
0566 /*
0567  * The post dividers and mux clocks are created using the standard divider and
0568  * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux
0569  * state to follow the master PLL's divider/mux state. Therefore, we don't
0570  * require special clock ops that also configure the slave PLL registers
0571  */
0572 static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **provided_clocks)
0573 {
0574     char clk_name[32], parent[32], vco_name[32];
0575     char parent2[32], parent3[32], parent4[32];
0576     struct clk_init_data vco_init = {
0577         .parent_data = &(const struct clk_parent_data) {
0578             .fw_name = "ref",
0579         },
0580         .num_parents = 1,
0581         .name = vco_name,
0582         .flags = CLK_IGNORE_UNUSED,
0583         .ops = &clk_ops_dsi_pll_10nm_vco,
0584     };
0585     struct device *dev = &pll_10nm->phy->pdev->dev;
0586     struct clk_hw *hw;
0587     int ret;
0588 
0589     DBG("DSI%d", pll_10nm->phy->id);
0590 
0591     snprintf(vco_name, 32, "dsi%dvco_clk", pll_10nm->phy->id);
0592     pll_10nm->clk_hw.init = &vco_init;
0593 
0594     ret = devm_clk_hw_register(dev, &pll_10nm->clk_hw);
0595     if (ret)
0596         return ret;
0597 
0598     snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_10nm->phy->id);
0599     snprintf(parent, 32, "dsi%dvco_clk", pll_10nm->phy->id);
0600 
0601     hw = devm_clk_hw_register_divider(dev, clk_name,
0602                      parent, CLK_SET_RATE_PARENT,
0603                      pll_10nm->phy->pll_base +
0604                      REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE,
0605                      0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
0606     if (IS_ERR(hw)) {
0607         ret = PTR_ERR(hw);
0608         goto fail;
0609     }
0610 
0611     snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_10nm->phy->id);
0612     snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->phy->id);
0613 
0614     /* BIT CLK: DIV_CTRL_3_0 */
0615     hw = devm_clk_hw_register_divider(dev, clk_name, parent,
0616                      CLK_SET_RATE_PARENT,
0617                      pll_10nm->phy->base +
0618                      REG_DSI_10nm_PHY_CMN_CLK_CFG0,
0619                      0, 4, CLK_DIVIDER_ONE_BASED,
0620                      &pll_10nm->postdiv_lock);
0621     if (IS_ERR(hw)) {
0622         ret = PTR_ERR(hw);
0623         goto fail;
0624     }
0625 
0626     snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_10nm->phy->id);
0627     snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->phy->id);
0628 
0629     /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */
0630     hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent,
0631                       CLK_SET_RATE_PARENT, 1, 8);
0632     if (IS_ERR(hw)) {
0633         ret = PTR_ERR(hw);
0634         goto fail;
0635     }
0636 
0637     provided_clocks[DSI_BYTE_PLL_CLK] = hw;
0638 
0639     snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->phy->id);
0640     snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->phy->id);
0641 
0642     hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent,
0643                       0, 1, 2);
0644     if (IS_ERR(hw)) {
0645         ret = PTR_ERR(hw);
0646         goto fail;
0647     }
0648 
0649     snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->phy->id);
0650     snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->phy->id);
0651 
0652     hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent,
0653                       0, 1, 4);
0654     if (IS_ERR(hw)) {
0655         ret = PTR_ERR(hw);
0656         goto fail;
0657     }
0658 
0659     snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_10nm->phy->id);
0660     snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->phy->id);
0661     snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->phy->id);
0662     snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_10nm->phy->id);
0663     snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->phy->id);
0664 
0665     hw = devm_clk_hw_register_mux(dev, clk_name,
0666                  ((const char *[]){
0667                  parent, parent2, parent3, parent4
0668                  }), 4, 0, pll_10nm->phy->base +
0669                  REG_DSI_10nm_PHY_CMN_CLK_CFG1,
0670                  0, 2, 0, NULL);
0671     if (IS_ERR(hw)) {
0672         ret = PTR_ERR(hw);
0673         goto fail;
0674     }
0675 
0676     snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_10nm->phy->id);
0677     snprintf(parent, 32, "dsi%d_pclk_mux", pll_10nm->phy->id);
0678 
0679     /* PIX CLK DIV : DIV_CTRL_7_4*/
0680     hw = devm_clk_hw_register_divider(dev, clk_name, parent,
0681                      0, pll_10nm->phy->base +
0682                     REG_DSI_10nm_PHY_CMN_CLK_CFG0,
0683                      4, 4, CLK_DIVIDER_ONE_BASED,
0684                      &pll_10nm->postdiv_lock);
0685     if (IS_ERR(hw)) {
0686         ret = PTR_ERR(hw);
0687         goto fail;
0688     }
0689 
0690     provided_clocks[DSI_PIXEL_PLL_CLK] = hw;
0691 
0692     return 0;
0693 
0694 fail:
0695 
0696     return ret;
0697 }
0698 
0699 static int dsi_pll_10nm_init(struct msm_dsi_phy *phy)
0700 {
0701     struct platform_device *pdev = phy->pdev;
0702     struct dsi_pll_10nm *pll_10nm;
0703     int ret;
0704 
0705     pll_10nm = devm_kzalloc(&pdev->dev, sizeof(*pll_10nm), GFP_KERNEL);
0706     if (!pll_10nm)
0707         return -ENOMEM;
0708 
0709     DBG("DSI PLL%d", phy->id);
0710 
0711     pll_10nm_list[phy->id] = pll_10nm;
0712 
0713     spin_lock_init(&pll_10nm->postdiv_lock);
0714 
0715     pll_10nm->phy = phy;
0716 
0717     ret = pll_10nm_register(pll_10nm, phy->provided_clocks->hws);
0718     if (ret) {
0719         DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
0720         return ret;
0721     }
0722 
0723     phy->vco_hw = &pll_10nm->clk_hw;
0724 
0725     /* TODO: Remove this when we have proper display handover support */
0726     msm_dsi_phy_pll_save_state(phy);
0727 
0728     return 0;
0729 }
0730 
0731 static int dsi_phy_hw_v3_0_is_pll_on(struct msm_dsi_phy *phy)
0732 {
0733     void __iomem *base = phy->base;
0734     u32 data = 0;
0735 
0736     data = dsi_phy_read(base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL);
0737     mb(); /* make sure read happened */
0738 
0739     return (data & BIT(0));
0740 }
0741 
0742 static void dsi_phy_hw_v3_0_config_lpcdrx(struct msm_dsi_phy *phy, bool enable)
0743 {
0744     void __iomem *lane_base = phy->lane_base;
0745     int phy_lane_0 = 0; /* TODO: Support all lane swap configs */
0746 
0747     /*
0748      * LPRX and CDRX need to enabled only for physical data lane
0749      * corresponding to the logical data lane 0
0750      */
0751     if (enable)
0752         dsi_phy_write(lane_base +
0753                   REG_DSI_10nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0x3);
0754     else
0755         dsi_phy_write(lane_base +
0756                   REG_DSI_10nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0);
0757 }
0758 
0759 static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy)
0760 {
0761     int i;
0762     u8 tx_dctrl[] = { 0x00, 0x00, 0x00, 0x04, 0x01 };
0763     void __iomem *lane_base = phy->lane_base;
0764     struct dsi_phy_10nm_tuning_cfg *tuning_cfg = phy->tuning_cfg;
0765 
0766     if (phy->cfg->quirks & DSI_PHY_10NM_QUIRK_OLD_TIMINGS)
0767         tx_dctrl[3] = 0x02;
0768 
0769     /* Strength ctrl settings */
0770     for (i = 0; i < 5; i++) {
0771         dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_LPTX_STR_CTRL(i),
0772                   0x55);
0773         /*
0774          * Disable LPRX and CDRX for all lanes. And later on, it will
0775          * be only enabled for the physical data lane corresponding
0776          * to the logical data lane 0
0777          */
0778         dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_LPRX_CTRL(i), 0);
0779         dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_PIN_SWAP(i), 0x0);
0780         dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_HSTX_STR_CTRL(i),
0781                   0x88);
0782     }
0783 
0784     dsi_phy_hw_v3_0_config_lpcdrx(phy, true);
0785 
0786     /* other settings */
0787     for (i = 0; i < 5; i++) {
0788         dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG0(i), 0x0);
0789         dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG1(i), 0x0);
0790         dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG2(i), 0x0);
0791         dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG3(i),
0792                   i == 4 ? 0x80 : 0x0);
0793 
0794         /* platform specific dsi phy drive strength adjustment */
0795         dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_TOP_CTRL(i),
0796                 tuning_cfg->rescode_offset_top[i]);
0797         dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_BOT_CTRL(i),
0798                 tuning_cfg->rescode_offset_bot[i]);
0799 
0800         dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(i),
0801                   tx_dctrl[i]);
0802     }
0803 
0804     if (!(phy->cfg->quirks & DSI_PHY_10NM_QUIRK_OLD_TIMINGS)) {
0805         /* Toggle BIT 0 to release freeze I/0 */
0806         dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3), 0x05);
0807         dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3), 0x04);
0808     }
0809 }
0810 
0811 static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy,
0812                    struct msm_dsi_phy_clk_request *clk_req)
0813 {
0814     int ret;
0815     u32 status;
0816     u32 const delay_us = 5;
0817     u32 const timeout_us = 1000;
0818     struct msm_dsi_dphy_timing *timing = &phy->timing;
0819     void __iomem *base = phy->base;
0820     struct dsi_phy_10nm_tuning_cfg *tuning_cfg = phy->tuning_cfg;
0821     u32 data;
0822 
0823     DBG("");
0824 
0825     if (msm_dsi_dphy_timing_calc_v3(timing, clk_req)) {
0826         DRM_DEV_ERROR(&phy->pdev->dev,
0827             "%s: D-PHY timing calculation failed\n", __func__);
0828         return -EINVAL;
0829     }
0830 
0831     if (dsi_phy_hw_v3_0_is_pll_on(phy))
0832         pr_warn("PLL turned on before configuring PHY\n");
0833 
0834     /* wait for REFGEN READY */
0835     ret = readl_poll_timeout_atomic(base + REG_DSI_10nm_PHY_CMN_PHY_STATUS,
0836                     status, (status & BIT(0)),
0837                     delay_us, timeout_us);
0838     if (ret) {
0839         pr_err("Ref gen not ready. Aborting\n");
0840         return -EINVAL;
0841     }
0842 
0843     /* de-assert digital and pll power down */
0844     data = BIT(6) | BIT(5);
0845     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, data);
0846 
0847     /* Assert PLL core reset */
0848     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0x00);
0849 
0850     /* turn off resync FIFO */
0851     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0x00);
0852 
0853     /* Select MS1 byte-clk */
0854     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_GLBL_CTRL, 0x10);
0855 
0856     /* Enable LDO with platform specific drive level/amplitude adjustment */
0857     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_VREG_CTRL,
0858               tuning_cfg->vreg_ctrl);
0859 
0860     /* Configure PHY lane swap (TODO: we need to calculate this) */
0861     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CFG0, 0x21);
0862     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CFG1, 0x84);
0863 
0864     /* DSI PHY timings */
0865     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_0,
0866               timing->hs_halfbyte_en);
0867     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_1,
0868               timing->clk_zero);
0869     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_2,
0870               timing->clk_prepare);
0871     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_3,
0872               timing->clk_trail);
0873     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_4,
0874               timing->hs_exit);
0875     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_5,
0876               timing->hs_zero);
0877     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_6,
0878               timing->hs_prepare);
0879     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_7,
0880               timing->hs_trail);
0881     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_8,
0882               timing->hs_rqst);
0883     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_9,
0884               timing->ta_go | (timing->ta_sure << 3));
0885     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_10,
0886               timing->ta_get);
0887     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_11,
0888               0x00);
0889 
0890     /* Remove power down from all blocks */
0891     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, 0x7f);
0892 
0893     /* power up lanes */
0894     data = dsi_phy_read(base + REG_DSI_10nm_PHY_CMN_CTRL_0);
0895 
0896     /* TODO: only power up lanes that are used */
0897     data |= 0x1F;
0898     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, data);
0899     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CTRL0, 0x1F);
0900 
0901     /* Select full-rate mode */
0902     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_2, 0x40);
0903 
0904     ret = dsi_10nm_set_usecase(phy);
0905     if (ret) {
0906         DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n",
0907             __func__, ret);
0908         return ret;
0909     }
0910 
0911     /* DSI lane settings */
0912     dsi_phy_hw_v3_0_lane_settings(phy);
0913 
0914     DBG("DSI%d PHY enabled", phy->id);
0915 
0916     return 0;
0917 }
0918 
0919 static void dsi_10nm_phy_disable(struct msm_dsi_phy *phy)
0920 {
0921     void __iomem *base = phy->base;
0922     u32 data;
0923 
0924     DBG("");
0925 
0926     if (dsi_phy_hw_v3_0_is_pll_on(phy))
0927         pr_warn("Turning OFF PHY while PLL is on\n");
0928 
0929     dsi_phy_hw_v3_0_config_lpcdrx(phy, false);
0930     data = dsi_phy_read(base + REG_DSI_10nm_PHY_CMN_CTRL_0);
0931 
0932     /* disable all lanes */
0933     data &= ~0x1F;
0934     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, data);
0935     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CTRL0, 0);
0936 
0937     /* Turn off all PHY blocks */
0938     dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, 0x00);
0939     /* make sure phy is turned off */
0940     wmb();
0941 
0942     DBG("DSI%d PHY disabled", phy->id);
0943 }
0944 
0945 static int dsi_10nm_phy_parse_dt(struct msm_dsi_phy *phy)
0946 {
0947     struct device *dev = &phy->pdev->dev;
0948     struct dsi_phy_10nm_tuning_cfg *tuning_cfg;
0949     s8 offset_top[DSI_LANE_MAX] = { 0 }; /* No offset */
0950     s8 offset_bot[DSI_LANE_MAX] = { 0 }; /* No offset */
0951     u32 ldo_level = 400; /* 400mV */
0952     u8 level;
0953     int ret, i;
0954 
0955     tuning_cfg = devm_kzalloc(dev, sizeof(*tuning_cfg), GFP_KERNEL);
0956     if (!tuning_cfg)
0957         return -ENOMEM;
0958 
0959     /* Drive strength adjustment parameters */
0960     ret = of_property_read_u8_array(dev->of_node, "qcom,phy-rescode-offset-top",
0961                     offset_top, DSI_LANE_MAX);
0962     if (ret && ret != -EINVAL) {
0963         DRM_DEV_ERROR(dev, "failed to parse qcom,phy-rescode-offset-top, %d\n", ret);
0964         return ret;
0965     }
0966 
0967     for (i = 0; i < DSI_LANE_MAX; i++) {
0968         if (offset_top[i] < -32 || offset_top[i] > 31) {
0969             DRM_DEV_ERROR(dev,
0970                 "qcom,phy-rescode-offset-top value %d is not in range [-32..31]\n",
0971                 offset_top[i]);
0972             return -EINVAL;
0973         }
0974         tuning_cfg->rescode_offset_top[i] = 0x3f & offset_top[i];
0975     }
0976 
0977     ret = of_property_read_u8_array(dev->of_node, "qcom,phy-rescode-offset-bot",
0978                     offset_bot, DSI_LANE_MAX);
0979     if (ret && ret != -EINVAL) {
0980         DRM_DEV_ERROR(dev, "failed to parse qcom,phy-rescode-offset-bot, %d\n", ret);
0981         return ret;
0982     }
0983 
0984     for (i = 0; i < DSI_LANE_MAX; i++) {
0985         if (offset_bot[i] < -32 || offset_bot[i] > 31) {
0986             DRM_DEV_ERROR(dev,
0987                 "qcom,phy-rescode-offset-bot value %d is not in range [-32..31]\n",
0988                 offset_bot[i]);
0989             return -EINVAL;
0990         }
0991         tuning_cfg->rescode_offset_bot[i] = 0x3f & offset_bot[i];
0992     }
0993 
0994     /* Drive level/amplitude adjustment parameters */
0995     ret = of_property_read_u32(dev->of_node, "qcom,phy-drive-ldo-level", &ldo_level);
0996     if (ret && ret != -EINVAL) {
0997         DRM_DEV_ERROR(dev, "failed to parse qcom,phy-drive-ldo-level, %d\n", ret);
0998         return ret;
0999     }
1000 
1001     switch (ldo_level) {
1002     case 375:
1003         level = 0;
1004         break;
1005     case 400:
1006         level = 1;
1007         break;
1008     case 425:
1009         level = 2;
1010         break;
1011     case 450:
1012         level = 3;
1013         break;
1014     case 475:
1015         level = 4;
1016         break;
1017     case 500:
1018         level = 5;
1019         break;
1020     default:
1021         DRM_DEV_ERROR(dev, "qcom,phy-drive-ldo-level %d is not supported\n", ldo_level);
1022         return -EINVAL;
1023     }
1024     tuning_cfg->vreg_ctrl = 0x58 | (0x7 & level);
1025 
1026     phy->tuning_cfg = tuning_cfg;
1027 
1028     return 0;
1029 }
1030 
1031 const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = {
1032     .has_phy_lane = true,
1033     .reg_cfg = {
1034         .num = 1,
1035         .regs = {
1036             {"vdds", 36000, 32},
1037         },
1038     },
1039     .ops = {
1040         .enable = dsi_10nm_phy_enable,
1041         .disable = dsi_10nm_phy_disable,
1042         .pll_init = dsi_pll_10nm_init,
1043         .save_pll_state = dsi_10nm_pll_save_state,
1044         .restore_pll_state = dsi_10nm_pll_restore_state,
1045         .parse_dt_properties = dsi_10nm_phy_parse_dt,
1046     },
1047     .min_pll_rate = 1000000000UL,
1048     .max_pll_rate = 3500000000UL,
1049     .io_start = { 0xae94400, 0xae96400 },
1050     .num_dsi_phy = 2,
1051 };
1052 
1053 const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs = {
1054     .has_phy_lane = true,
1055     .reg_cfg = {
1056         .num = 1,
1057         .regs = {
1058             {"vdds", 36000, 32},
1059         },
1060     },
1061     .ops = {
1062         .enable = dsi_10nm_phy_enable,
1063         .disable = dsi_10nm_phy_disable,
1064         .pll_init = dsi_pll_10nm_init,
1065         .save_pll_state = dsi_10nm_pll_save_state,
1066         .restore_pll_state = dsi_10nm_pll_restore_state,
1067         .parse_dt_properties = dsi_10nm_phy_parse_dt,
1068     },
1069     .min_pll_rate = 1000000000UL,
1070     .max_pll_rate = 3500000000UL,
1071     .io_start = { 0xc994400, 0xc996400 },
1072     .num_dsi_phy = 2,
1073     .quirks = DSI_PHY_10NM_QUIRK_OLD_TIMINGS,
1074 };