0001
0002
0003
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_7nm.xml.h"
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #define VCO_REF_CLK_RATE 19200000
0040 #define FRAC_BITS 18
0041
0042
0043 #define DSI_PHY_7NM_QUIRK_V4_1 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
0053 u32 decimal_div_start;
0054 u32 frac_div_start;
0055 u32 pll_clock_inverters;
0056 u32 ssc_stepsize;
0057 u32 ssc_div_per;
0058 };
0059
0060 struct pll_7nm_cached_state {
0061 unsigned long vco_rate;
0062 u8 bit_clk_div;
0063 u8 pix_clk_div;
0064 u8 pll_out_div;
0065 u8 pll_mux;
0066 };
0067
0068 struct dsi_pll_7nm {
0069 struct clk_hw clk_hw;
0070
0071 struct msm_dsi_phy *phy;
0072
0073 u64 vco_current_rate;
0074
0075
0076 spinlock_t postdiv_lock;
0077
0078 struct pll_7nm_cached_state cached_state;
0079
0080 struct dsi_pll_7nm *slave;
0081 };
0082
0083 #define to_pll_7nm(x) container_of(x, struct dsi_pll_7nm, clk_hw)
0084
0085
0086
0087
0088
0089 static struct dsi_pll_7nm *pll_7nm_list[DSI_MAX];
0090
0091 static void dsi_pll_setup_config(struct dsi_pll_config *config)
0092 {
0093 config->ssc_freq = 31500;
0094 config->ssc_offset = 4800;
0095 config->ssc_adj_per = 2;
0096
0097
0098 config->enable_ssc = false;
0099 config->ssc_center = 0;
0100 }
0101
0102 static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
0103 {
0104 u64 fref = VCO_REF_CLK_RATE;
0105 u64 pll_freq;
0106 u64 divider;
0107 u64 dec, dec_multiple;
0108 u32 frac;
0109 u64 multiplier;
0110
0111 pll_freq = pll->vco_current_rate;
0112
0113 divider = fref * 2;
0114
0115 multiplier = 1 << FRAC_BITS;
0116 dec_multiple = div_u64(pll_freq * multiplier, divider);
0117 dec = div_u64_rem(dec_multiple, multiplier, &frac);
0118
0119 if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1))
0120 config->pll_clock_inverters = 0x28;
0121 else if (pll_freq <= 1000000000ULL)
0122 config->pll_clock_inverters = 0xa0;
0123 else if (pll_freq <= 2500000000ULL)
0124 config->pll_clock_inverters = 0x20;
0125 else if (pll_freq <= 3020000000ULL)
0126 config->pll_clock_inverters = 0x00;
0127 else
0128 config->pll_clock_inverters = 0x40;
0129
0130 config->decimal_div_start = dec;
0131 config->frac_div_start = frac;
0132 }
0133
0134 #define SSC_CENTER BIT(0)
0135 #define SSC_EN BIT(1)
0136
0137 static void dsi_pll_calc_ssc(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
0138 {
0139 u32 ssc_per;
0140 u32 ssc_mod;
0141 u64 ssc_step_size;
0142 u64 frac;
0143
0144 if (!config->enable_ssc) {
0145 DBG("SSC not enabled\n");
0146 return;
0147 }
0148
0149 ssc_per = DIV_ROUND_CLOSEST(VCO_REF_CLK_RATE, config->ssc_freq) / 2 - 1;
0150 ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1);
0151 ssc_per -= ssc_mod;
0152
0153 frac = config->frac_div_start;
0154 ssc_step_size = config->decimal_div_start;
0155 ssc_step_size *= (1 << FRAC_BITS);
0156 ssc_step_size += frac;
0157 ssc_step_size *= config->ssc_offset;
0158 ssc_step_size *= (config->ssc_adj_per + 1);
0159 ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1));
0160 ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000);
0161
0162 config->ssc_div_per = ssc_per;
0163 config->ssc_stepsize = ssc_step_size;
0164
0165 pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n",
0166 config->decimal_div_start, frac, FRAC_BITS);
0167 pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n",
0168 ssc_per, (u32)ssc_step_size, config->ssc_adj_per);
0169 }
0170
0171 static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
0172 {
0173 void __iomem *base = pll->phy->pll_base;
0174
0175 if (config->enable_ssc) {
0176 pr_debug("SSC is enabled\n");
0177
0178 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_LOW_1,
0179 config->ssc_stepsize & 0xff);
0180 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_HIGH_1,
0181 config->ssc_stepsize >> 8);
0182 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_LOW_1,
0183 config->ssc_div_per & 0xff);
0184 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_HIGH_1,
0185 config->ssc_div_per >> 8);
0186 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_LOW_1,
0187 config->ssc_adj_per & 0xff);
0188 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_HIGH_1,
0189 config->ssc_adj_per >> 8);
0190 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_CONTROL,
0191 SSC_EN | (config->ssc_center ? SSC_CENTER : 0));
0192 }
0193 }
0194
0195 static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll)
0196 {
0197 void __iomem *base = pll->phy->pll_base;
0198 u8 analog_controls_five_1 = 0x01, vco_config_1 = 0x00;
0199
0200 if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
0201 if (pll->vco_current_rate >= 3100000000ULL)
0202 analog_controls_five_1 = 0x03;
0203
0204 if (pll->vco_current_rate < 1520000000ULL)
0205 vco_config_1 = 0x08;
0206 else if (pll->vco_current_rate < 2990000000ULL)
0207 vco_config_1 = 0x01;
0208 }
0209
0210 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1,
0211 analog_controls_five_1);
0212 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_VCO_CONFIG_1, vco_config_1);
0213 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE, 0x01);
0214 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03);
0215 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00);
0216 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_DSM_DIVIDER, 0x00);
0217 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e);
0218 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40);
0219 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE, 0xba);
0220 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c);
0221 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_OUTDIV, 0x00);
0222 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CORE_OVERRIDE, 0x00);
0223 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08);
0224 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x0a);
0225 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_BAND_SEL_RATE_1, 0xc0);
0226 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x84);
0227 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x82);
0228 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x4c);
0229 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80);
0230 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x29);
0231 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x2f);
0232 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT, 0x2a);
0233 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT,
0234 pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1 ? 0x3f : 0x22);
0235
0236 if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
0237 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
0238 if (pll->slave)
0239 dsi_phy_write(pll->slave->phy->pll_base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
0240 }
0241 }
0242
0243 static void dsi_pll_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
0244 {
0245 void __iomem *base = pll->phy->pll_base;
0246
0247 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12);
0248 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1, config->decimal_div_start);
0249 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1,
0250 config->frac_div_start & 0xff);
0251 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1,
0252 (config->frac_div_start & 0xff00) >> 8);
0253 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1,
0254 (config->frac_div_start & 0x30000) >> 16);
0255 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, 0x40);
0256 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06);
0257 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, pll->phy->cphy_mode ? 0x00 : 0x10);
0258 dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, config->pll_clock_inverters);
0259 }
0260
0261 static int dsi_pll_7nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
0262 unsigned long parent_rate)
0263 {
0264 struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
0265 struct dsi_pll_config config;
0266
0267 DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_7nm->phy->id, rate,
0268 parent_rate);
0269
0270 pll_7nm->vco_current_rate = rate;
0271
0272 dsi_pll_setup_config(&config);
0273
0274 dsi_pll_calc_dec_frac(pll_7nm, &config);
0275
0276 dsi_pll_calc_ssc(pll_7nm, &config);
0277
0278 dsi_pll_commit(pll_7nm, &config);
0279
0280 dsi_pll_config_hzindep_reg(pll_7nm);
0281
0282 dsi_pll_ssc_commit(pll_7nm, &config);
0283
0284
0285 wmb();
0286
0287 return 0;
0288 }
0289
0290 static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm *pll)
0291 {
0292 int rc;
0293 u32 status = 0;
0294 u32 const delay_us = 100;
0295 u32 const timeout_us = 5000;
0296
0297 rc = readl_poll_timeout_atomic(pll->phy->pll_base +
0298 REG_DSI_7nm_PHY_PLL_COMMON_STATUS_ONE,
0299 status,
0300 ((status & BIT(0)) > 0),
0301 delay_us,
0302 timeout_us);
0303 if (rc)
0304 pr_err("DSI PLL(%d) lock failed, status=0x%08x\n",
0305 pll->phy->id, status);
0306
0307 return rc;
0308 }
0309
0310 static void dsi_pll_disable_pll_bias(struct dsi_pll_7nm *pll)
0311 {
0312 u32 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);
0313
0314 dsi_phy_write(pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0);
0315 dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0, data & ~BIT(5));
0316 ndelay(250);
0317 }
0318
0319 static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll)
0320 {
0321 u32 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);
0322
0323 dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0, data | BIT(5));
0324 dsi_phy_write(pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0xc0);
0325 ndelay(250);
0326 }
0327
0328 static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll)
0329 {
0330 u32 data;
0331
0332 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
0333 dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data & ~BIT(5));
0334 }
0335
0336 static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll)
0337 {
0338 u32 data;
0339
0340 dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x04);
0341
0342 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
0343 dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1,
0344 data | BIT(5) | BIT(4));
0345 }
0346
0347 static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll)
0348 {
0349
0350
0351
0352
0353
0354 dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0));
0355 wmb();
0356 dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, 0x0);
0357 wmb();
0358 }
0359
0360 static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw)
0361 {
0362 struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
0363 int rc;
0364
0365 dsi_pll_enable_pll_bias(pll_7nm);
0366 if (pll_7nm->slave)
0367 dsi_pll_enable_pll_bias(pll_7nm->slave);
0368
0369
0370 dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x01);
0371
0372
0373
0374
0375
0376 wmb();
0377
0378
0379 rc = dsi_pll_7nm_lock_status(pll_7nm);
0380 if (rc) {
0381 pr_err("PLL(%d) lock failed\n", pll_7nm->phy->id);
0382 goto error;
0383 }
0384
0385 pll_7nm->phy->pll_on = true;
0386
0387
0388
0389
0390
0391
0392 dsi_pll_phy_dig_reset(pll_7nm);
0393 if (pll_7nm->slave)
0394 dsi_pll_phy_dig_reset(pll_7nm->slave);
0395
0396 dsi_pll_enable_global_clk(pll_7nm);
0397 if (pll_7nm->slave)
0398 dsi_pll_enable_global_clk(pll_7nm->slave);
0399
0400 error:
0401 return rc;
0402 }
0403
0404 static void dsi_pll_disable_sub(struct dsi_pll_7nm *pll)
0405 {
0406 dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0);
0407 dsi_pll_disable_pll_bias(pll);
0408 }
0409
0410 static void dsi_pll_7nm_vco_unprepare(struct clk_hw *hw)
0411 {
0412 struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
0413
0414
0415
0416
0417
0418
0419 dsi_pll_disable_global_clk(pll_7nm);
0420 dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0);
0421 dsi_pll_disable_sub(pll_7nm);
0422 if (pll_7nm->slave) {
0423 dsi_pll_disable_global_clk(pll_7nm->slave);
0424 dsi_pll_disable_sub(pll_7nm->slave);
0425 }
0426
0427 wmb();
0428 pll_7nm->phy->pll_on = false;
0429 }
0430
0431 static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw,
0432 unsigned long parent_rate)
0433 {
0434 struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
0435 void __iomem *base = pll_7nm->phy->pll_base;
0436 u64 ref_clk = VCO_REF_CLK_RATE;
0437 u64 vco_rate = 0x0;
0438 u64 multiplier;
0439 u32 frac;
0440 u32 dec;
0441 u64 pll_freq, tmp64;
0442
0443 dec = dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1);
0444 dec &= 0xff;
0445
0446 frac = dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1);
0447 frac |= ((dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1) &
0448 0xff) << 8);
0449 frac |= ((dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1) &
0450 0x3) << 16);
0451
0452
0453
0454
0455
0456 multiplier = 1 << FRAC_BITS;
0457 pll_freq = dec * (ref_clk * 2);
0458 tmp64 = (ref_clk * 2 * frac);
0459 pll_freq += div_u64(tmp64, multiplier);
0460
0461 vco_rate = pll_freq;
0462 pll_7nm->vco_current_rate = vco_rate;
0463
0464 DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x",
0465 pll_7nm->phy->id, (unsigned long)vco_rate, dec, frac);
0466
0467 return (unsigned long)vco_rate;
0468 }
0469
0470 static long dsi_pll_7nm_clk_round_rate(struct clk_hw *hw,
0471 unsigned long rate, unsigned long *parent_rate)
0472 {
0473 struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
0474
0475 if (rate < pll_7nm->phy->cfg->min_pll_rate)
0476 return pll_7nm->phy->cfg->min_pll_rate;
0477 else if (rate > pll_7nm->phy->cfg->max_pll_rate)
0478 return pll_7nm->phy->cfg->max_pll_rate;
0479 else
0480 return rate;
0481 }
0482
0483 static const struct clk_ops clk_ops_dsi_pll_7nm_vco = {
0484 .round_rate = dsi_pll_7nm_clk_round_rate,
0485 .set_rate = dsi_pll_7nm_vco_set_rate,
0486 .recalc_rate = dsi_pll_7nm_vco_recalc_rate,
0487 .prepare = dsi_pll_7nm_vco_prepare,
0488 .unprepare = dsi_pll_7nm_vco_unprepare,
0489 };
0490
0491
0492
0493
0494
0495 static void dsi_7nm_pll_save_state(struct msm_dsi_phy *phy)
0496 {
0497 struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
0498 struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;
0499 void __iomem *phy_base = pll_7nm->phy->base;
0500 u32 cmn_clk_cfg0, cmn_clk_cfg1;
0501
0502 cached->pll_out_div = dsi_phy_read(pll_7nm->phy->pll_base +
0503 REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);
0504 cached->pll_out_div &= 0x3;
0505
0506 cmn_clk_cfg0 = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0);
0507 cached->bit_clk_div = cmn_clk_cfg0 & 0xf;
0508 cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4;
0509
0510 cmn_clk_cfg1 = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
0511 cached->pll_mux = cmn_clk_cfg1 & 0x3;
0512
0513 DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x",
0514 pll_7nm->phy->id, cached->pll_out_div, cached->bit_clk_div,
0515 cached->pix_clk_div, cached->pll_mux);
0516 }
0517
0518 static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy)
0519 {
0520 struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
0521 struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;
0522 void __iomem *phy_base = pll_7nm->phy->base;
0523 u32 val;
0524 int ret;
0525
0526 val = dsi_phy_read(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);
0527 val &= ~0x3;
0528 val |= cached->pll_out_div;
0529 dsi_phy_write(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, val);
0530
0531 dsi_phy_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0,
0532 cached->bit_clk_div | (cached->pix_clk_div << 4));
0533
0534 val = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
0535 val &= ~0x3;
0536 val |= cached->pll_mux;
0537 dsi_phy_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, val);
0538
0539 ret = dsi_pll_7nm_vco_set_rate(phy->vco_hw,
0540 pll_7nm->vco_current_rate,
0541 VCO_REF_CLK_RATE);
0542 if (ret) {
0543 DRM_DEV_ERROR(&pll_7nm->phy->pdev->dev,
0544 "restore vco rate failed. ret=%d\n", ret);
0545 return ret;
0546 }
0547
0548 DBG("DSI PLL%d", pll_7nm->phy->id);
0549
0550 return 0;
0551 }
0552
0553 static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy)
0554 {
0555 struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
0556 void __iomem *base = phy->base;
0557 u32 data = 0x0;
0558
0559 DBG("DSI PLL%d", pll_7nm->phy->id);
0560
0561 switch (phy->usecase) {
0562 case MSM_DSI_PHY_STANDALONE:
0563 break;
0564 case MSM_DSI_PHY_MASTER:
0565 pll_7nm->slave = pll_7nm_list[(pll_7nm->phy->id + 1) % DSI_MAX];
0566 break;
0567 case MSM_DSI_PHY_SLAVE:
0568 data = 0x1;
0569 break;
0570 default:
0571 return -EINVAL;
0572 }
0573
0574
0575 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, (data << 2));
0576
0577 return 0;
0578 }
0579
0580
0581
0582
0583
0584
0585
0586 static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provided_clocks)
0587 {
0588 char clk_name[32], parent[32], vco_name[32];
0589 char parent2[32];
0590 struct clk_init_data vco_init = {
0591 .parent_data = &(const struct clk_parent_data) {
0592 .fw_name = "ref",
0593 },
0594 .num_parents = 1,
0595 .name = vco_name,
0596 .flags = CLK_IGNORE_UNUSED,
0597 .ops = &clk_ops_dsi_pll_7nm_vco,
0598 };
0599 struct device *dev = &pll_7nm->phy->pdev->dev;
0600 struct clk_hw *hw;
0601 int ret;
0602
0603 DBG("DSI%d", pll_7nm->phy->id);
0604
0605 snprintf(vco_name, 32, "dsi%dvco_clk", pll_7nm->phy->id);
0606 pll_7nm->clk_hw.init = &vco_init;
0607
0608 ret = devm_clk_hw_register(dev, &pll_7nm->clk_hw);
0609 if (ret)
0610 return ret;
0611
0612 snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id);
0613 snprintf(parent, 32, "dsi%dvco_clk", pll_7nm->phy->id);
0614
0615 hw = devm_clk_hw_register_divider(dev, clk_name,
0616 parent, CLK_SET_RATE_PARENT,
0617 pll_7nm->phy->pll_base +
0618 REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE,
0619 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
0620 if (IS_ERR(hw)) {
0621 ret = PTR_ERR(hw);
0622 goto fail;
0623 }
0624
0625 snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id);
0626 snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id);
0627
0628
0629 hw = devm_clk_hw_register_divider(dev, clk_name, parent,
0630 CLK_SET_RATE_PARENT,
0631 pll_7nm->phy->base +
0632 REG_DSI_7nm_PHY_CMN_CLK_CFG0,
0633 0, 4, CLK_DIVIDER_ONE_BASED,
0634 &pll_7nm->postdiv_lock);
0635 if (IS_ERR(hw)) {
0636 ret = PTR_ERR(hw);
0637 goto fail;
0638 }
0639
0640 snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_7nm->phy->id);
0641 snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id);
0642
0643
0644 hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent,
0645 CLK_SET_RATE_PARENT, 1,
0646 pll_7nm->phy->cphy_mode ? 7 : 8);
0647 if (IS_ERR(hw)) {
0648 ret = PTR_ERR(hw);
0649 goto fail;
0650 }
0651
0652 provided_clocks[DSI_BYTE_PLL_CLK] = hw;
0653
0654 snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->phy->id);
0655 snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id);
0656
0657 hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent,
0658 0, 1, 2);
0659 if (IS_ERR(hw)) {
0660 ret = PTR_ERR(hw);
0661 goto fail;
0662 }
0663
0664 snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id);
0665 snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id);
0666
0667 if (pll_7nm->phy->cphy_mode)
0668 hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 2, 7);
0669 else
0670 hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 4);
0671 if (IS_ERR(hw)) {
0672 ret = PTR_ERR(hw);
0673 goto fail;
0674 }
0675
0676
0677
0678
0679 if (pll_7nm->phy->cphy_mode) {
0680 u32 data;
0681
0682 data = dsi_phy_read(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
0683 dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data | 3);
0684
0685 snprintf(parent, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id);
0686 } else {
0687 snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_7nm->phy->id);
0688 snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id);
0689 snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->phy->id);
0690
0691 hw = devm_clk_hw_register_mux(dev, clk_name,
0692 ((const char *[]){
0693 parent, parent2,
0694 }), 2, 0, pll_7nm->phy->base +
0695 REG_DSI_7nm_PHY_CMN_CLK_CFG1,
0696 0, 1, 0, NULL);
0697 if (IS_ERR(hw)) {
0698 ret = PTR_ERR(hw);
0699 goto fail;
0700 }
0701
0702 snprintf(parent, 32, "dsi%d_pclk_mux", pll_7nm->phy->id);
0703 }
0704
0705 snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_7nm->phy->id);
0706
0707
0708 hw = devm_clk_hw_register_divider(dev, clk_name, parent,
0709 0, pll_7nm->phy->base +
0710 REG_DSI_7nm_PHY_CMN_CLK_CFG0,
0711 4, 4, CLK_DIVIDER_ONE_BASED,
0712 &pll_7nm->postdiv_lock);
0713 if (IS_ERR(hw)) {
0714 ret = PTR_ERR(hw);
0715 goto fail;
0716 }
0717
0718 provided_clocks[DSI_PIXEL_PLL_CLK] = hw;
0719
0720 return 0;
0721
0722 fail:
0723
0724 return ret;
0725 }
0726
0727 static int dsi_pll_7nm_init(struct msm_dsi_phy *phy)
0728 {
0729 struct platform_device *pdev = phy->pdev;
0730 struct dsi_pll_7nm *pll_7nm;
0731 int ret;
0732
0733 pll_7nm = devm_kzalloc(&pdev->dev, sizeof(*pll_7nm), GFP_KERNEL);
0734 if (!pll_7nm)
0735 return -ENOMEM;
0736
0737 DBG("DSI PLL%d", phy->id);
0738
0739 pll_7nm_list[phy->id] = pll_7nm;
0740
0741 spin_lock_init(&pll_7nm->postdiv_lock);
0742
0743 pll_7nm->phy = phy;
0744
0745 ret = pll_7nm_register(pll_7nm, phy->provided_clocks->hws);
0746 if (ret) {
0747 DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
0748 return ret;
0749 }
0750
0751 phy->vco_hw = &pll_7nm->clk_hw;
0752
0753
0754 msm_dsi_phy_pll_save_state(phy);
0755
0756 return 0;
0757 }
0758
0759 static int dsi_phy_hw_v4_0_is_pll_on(struct msm_dsi_phy *phy)
0760 {
0761 void __iomem *base = phy->base;
0762 u32 data = 0;
0763
0764 data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL);
0765 mb();
0766
0767 return (data & BIT(0));
0768 }
0769
0770 static void dsi_phy_hw_v4_0_config_lpcdrx(struct msm_dsi_phy *phy, bool enable)
0771 {
0772 void __iomem *lane_base = phy->lane_base;
0773 int phy_lane_0 = 0;
0774
0775
0776
0777
0778
0779 if (enable)
0780 dsi_phy_write(lane_base +
0781 REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0x3);
0782 else
0783 dsi_phy_write(lane_base +
0784 REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0);
0785 }
0786
0787 static void dsi_phy_hw_v4_0_lane_settings(struct msm_dsi_phy *phy)
0788 {
0789 int i;
0790 const u8 tx_dctrl_0[] = { 0x00, 0x00, 0x00, 0x04, 0x01 };
0791 const u8 tx_dctrl_1[] = { 0x40, 0x40, 0x40, 0x46, 0x41 };
0792 const u8 *tx_dctrl = tx_dctrl_0;
0793 void __iomem *lane_base = phy->lane_base;
0794
0795 if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1)
0796 tx_dctrl = tx_dctrl_1;
0797
0798
0799 for (i = 0; i < 5; i++) {
0800
0801
0802
0803
0804
0805 dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_LPRX_CTRL(i), 0);
0806 dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_PIN_SWAP(i), 0x0);
0807 }
0808
0809 dsi_phy_hw_v4_0_config_lpcdrx(phy, true);
0810
0811
0812 for (i = 0; i < 5; i++) {
0813 dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG0(i), 0x0);
0814 dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG1(i), 0x0);
0815 dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG2(i), i == 4 ? 0x8a : 0xa);
0816 dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_TX_DCTRL(i), tx_dctrl[i]);
0817 }
0818 }
0819
0820 static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
0821 struct msm_dsi_phy_clk_request *clk_req)
0822 {
0823 int ret;
0824 u32 status;
0825 u32 const delay_us = 5;
0826 u32 const timeout_us = 1000;
0827 struct msm_dsi_dphy_timing *timing = &phy->timing;
0828 void __iomem *base = phy->base;
0829 bool less_than_1500_mhz;
0830 u32 vreg_ctrl_0, vreg_ctrl_1, lane_ctrl0;
0831 u32 glbl_pemph_ctrl_0;
0832 u32 glbl_str_swi_cal_sel_ctrl, glbl_hstx_str_ctrl_0;
0833 u32 glbl_rescode_top_ctrl, glbl_rescode_bot_ctrl;
0834 u32 data;
0835
0836 DBG("");
0837
0838 if (phy->cphy_mode)
0839 ret = msm_dsi_cphy_timing_calc_v4(timing, clk_req);
0840 else
0841 ret = msm_dsi_dphy_timing_calc_v4(timing, clk_req);
0842 if (ret) {
0843 DRM_DEV_ERROR(&phy->pdev->dev,
0844 "%s: PHY timing calculation failed\n", __func__);
0845 return -EINVAL;
0846 }
0847
0848 if (dsi_phy_hw_v4_0_is_pll_on(phy))
0849 pr_warn("PLL turned on before configuring PHY\n");
0850
0851
0852 ret = readl_poll_timeout_atomic(base + REG_DSI_7nm_PHY_CMN_PHY_STATUS,
0853 status, (status & BIT(0)),
0854 delay_us, timeout_us);
0855 if (ret) {
0856 pr_err("Ref gen not ready. Aborting\n");
0857 return -EINVAL;
0858 }
0859
0860
0861
0862
0863 less_than_1500_mhz = (clk_req->bitclk_rate <= 1500000000);
0864
0865 if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
0866 vreg_ctrl_0 = less_than_1500_mhz ? 0x53 : 0x52;
0867 if (phy->cphy_mode) {
0868 glbl_rescode_top_ctrl = 0x00;
0869 glbl_rescode_bot_ctrl = 0x3c;
0870 } else {
0871 glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x00;
0872 glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : 0x3c;
0873 }
0874 glbl_str_swi_cal_sel_ctrl = 0x00;
0875 glbl_hstx_str_ctrl_0 = 0x88;
0876 } else {
0877 vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59;
0878 if (phy->cphy_mode) {
0879 glbl_str_swi_cal_sel_ctrl = 0x03;
0880 glbl_hstx_str_ctrl_0 = 0x66;
0881 } else {
0882 glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00;
0883 glbl_hstx_str_ctrl_0 = less_than_1500_mhz ? 0x66 : 0x88;
0884 }
0885 glbl_rescode_top_ctrl = 0x03;
0886 glbl_rescode_bot_ctrl = 0x3c;
0887 }
0888
0889 if (phy->cphy_mode) {
0890 vreg_ctrl_0 = 0x51;
0891 vreg_ctrl_1 = 0x55;
0892 glbl_pemph_ctrl_0 = 0x11;
0893 lane_ctrl0 = 0x17;
0894 } else {
0895 vreg_ctrl_1 = 0x5c;
0896 glbl_pemph_ctrl_0 = 0x00;
0897 lane_ctrl0 = 0x1f;
0898 }
0899
0900
0901 data = BIT(6) | BIT(5);
0902 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, data);
0903
0904
0905 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x00);
0906
0907
0908 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0x00);
0909
0910
0911 data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_REVISION_ID0);
0912 data = data & (0xf0);
0913 if (data == 0x20)
0914 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_4, 0x04);
0915
0916
0917 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CFG0, 0x21);
0918 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CFG1, 0x84);
0919
0920 if (phy->cphy_mode)
0921 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_CTRL, BIT(6));
0922
0923
0924 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_0, vreg_ctrl_0);
0925 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_1, vreg_ctrl_1);
0926
0927 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x00);
0928 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL,
0929 glbl_str_swi_cal_sel_ctrl);
0930 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_HSTX_STR_CTRL_0,
0931 glbl_hstx_str_ctrl_0);
0932 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_0,
0933 glbl_pemph_ctrl_0);
0934 if (phy->cphy_mode)
0935 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_1, 0x01);
0936 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_TOP_CTRL,
0937 glbl_rescode_top_ctrl);
0938 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_BOT_CTRL,
0939 glbl_rescode_bot_ctrl);
0940 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_LPTX_STR_CTRL, 0x55);
0941
0942
0943 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, 0x7f);
0944
0945 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0, lane_ctrl0);
0946
0947
0948 if (!phy->cphy_mode)
0949 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_2, 0x40);
0950
0951 ret = dsi_7nm_set_usecase(phy);
0952 if (ret) {
0953 DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n",
0954 __func__, ret);
0955 return ret;
0956 }
0957
0958
0959 if (phy->cphy_mode) {
0960 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0, 0x00);
0961 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4, timing->hs_exit);
0962 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5,
0963 timing->shared_timings.clk_pre);
0964 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6, timing->clk_prepare);
0965 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7,
0966 timing->shared_timings.clk_post);
0967 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8, timing->hs_rqst);
0968 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9, 0x02);
0969 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10, 0x04);
0970 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11, 0x00);
0971 } else {
0972 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0, 0x00);
0973 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_1, timing->clk_zero);
0974 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_2, timing->clk_prepare);
0975 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_3, timing->clk_trail);
0976 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4, timing->hs_exit);
0977 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5, timing->hs_zero);
0978 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6, timing->hs_prepare);
0979 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7, timing->hs_trail);
0980 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8, timing->hs_rqst);
0981 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9, 0x02);
0982 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10, 0x04);
0983 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11, 0x00);
0984 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_12,
0985 timing->shared_timings.clk_pre);
0986 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_13,
0987 timing->shared_timings.clk_post);
0988 }
0989
0990
0991 dsi_phy_hw_v4_0_lane_settings(phy);
0992
0993 DBG("DSI%d PHY enabled", phy->id);
0994
0995 return 0;
0996 }
0997
0998 static bool dsi_7nm_set_continuous_clock(struct msm_dsi_phy *phy, bool enable)
0999 {
1000 void __iomem *base = phy->base;
1001 u32 data;
1002
1003 data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1);
1004 if (enable)
1005 data |= BIT(5) | BIT(6);
1006 else
1007 data &= ~(BIT(5) | BIT(6));
1008 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1, data);
1009
1010 return enable;
1011 }
1012
1013 static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)
1014 {
1015 void __iomem *base = phy->base;
1016 u32 data;
1017
1018 DBG("");
1019
1020 if (dsi_phy_hw_v4_0_is_pll_on(phy))
1021 pr_warn("Turning OFF PHY while PLL is on\n");
1022
1023 dsi_phy_hw_v4_0_config_lpcdrx(phy, false);
1024 data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_CTRL_0);
1025
1026
1027 data &= ~0x1F;
1028 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, data);
1029 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0, 0);
1030
1031
1032 dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, 0x00);
1033
1034 wmb();
1035
1036 DBG("DSI%d PHY disabled", phy->id);
1037 }
1038
1039 const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs = {
1040 .has_phy_lane = true,
1041 .reg_cfg = {
1042 .num = 1,
1043 .regs = {
1044 {"vdds", 36000, 32},
1045 },
1046 },
1047 .ops = {
1048 .enable = dsi_7nm_phy_enable,
1049 .disable = dsi_7nm_phy_disable,
1050 .pll_init = dsi_pll_7nm_init,
1051 .save_pll_state = dsi_7nm_pll_save_state,
1052 .restore_pll_state = dsi_7nm_pll_restore_state,
1053 .set_continuous_clock = dsi_7nm_set_continuous_clock,
1054 },
1055 .min_pll_rate = 600000000UL,
1056 #ifdef CONFIG_64BIT
1057 .max_pll_rate = 5000000000UL,
1058 #else
1059 .max_pll_rate = ULONG_MAX,
1060 #endif
1061 .io_start = { 0xae94400, 0xae96400 },
1062 .num_dsi_phy = 2,
1063 .quirks = DSI_PHY_7NM_QUIRK_V4_1,
1064 };
1065
1066 const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs = {
1067 .has_phy_lane = true,
1068 .reg_cfg = {
1069 .num = 1,
1070 .regs = {
1071 {"vdds", 36000, 32},
1072 },
1073 },
1074 .ops = {
1075 .enable = dsi_7nm_phy_enable,
1076 .disable = dsi_7nm_phy_disable,
1077 .pll_init = dsi_pll_7nm_init,
1078 .save_pll_state = dsi_7nm_pll_save_state,
1079 .restore_pll_state = dsi_7nm_pll_restore_state,
1080 .set_continuous_clock = dsi_7nm_set_continuous_clock,
1081 },
1082 .min_pll_rate = 1000000000UL,
1083 .max_pll_rate = 3500000000UL,
1084 .io_start = { 0xae94400, 0xae96400 },
1085 .num_dsi_phy = 2,
1086 };
1087
1088 const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs = {
1089 .has_phy_lane = true,
1090 .reg_cfg = {
1091 .num = 1,
1092 .regs = {
1093 {"vdds", 37550, 0},
1094 },
1095 },
1096 .ops = {
1097 .enable = dsi_7nm_phy_enable,
1098 .disable = dsi_7nm_phy_disable,
1099 .pll_init = dsi_pll_7nm_init,
1100 .save_pll_state = dsi_7nm_pll_save_state,
1101 .restore_pll_state = dsi_7nm_pll_restore_state,
1102 },
1103 .min_pll_rate = 600000000UL,
1104 #ifdef CONFIG_64BIT
1105 .max_pll_rate = 5000000000ULL,
1106 #else
1107 .max_pll_rate = ULONG_MAX,
1108 #endif
1109 .io_start = { 0xae94400 },
1110 .num_dsi_phy = 1,
1111 .quirks = DSI_PHY_7NM_QUIRK_V4_1,
1112 };