cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dsi_phy_7nm.c (33325B)


      1/*
      2 * SPDX-License-Identifier: GPL-2.0
      3 * Copyright (c) 2018, The Linux Foundation
      4 */
      5
      6#include <linux/clk.h>
      7#include <linux/clk-provider.h>
      8#include <linux/iopoll.h>
      9
     10#include "dsi_phy.h"
     11#include "dsi.xml.h"
     12#include "dsi_phy_7nm.xml.h"
     13
     14/*
     15 * DSI PLL 7nm - clock diagram (eg: DSI0): TODO: updated CPHY diagram
     16 *
     17 *           dsi0_pll_out_div_clk  dsi0_pll_bit_clk
     18 *                              |                |
     19 *                              |                |
     20 *                 +---------+  |  +----------+  |  +----+
     21 *  dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk
     22 *                 +---------+  |  +----------+  |  +----+
     23 *                              |                |
     24 *                              |                |         dsi0_pll_by_2_bit_clk
     25 *                              |                |          |
     26 *                              |                |  +----+  |  |\  dsi0_pclk_mux
     27 *                              |                |--| /2 |--o--| \   |
     28 *                              |                |  +----+     |  \  |  +---------+
     29 *                              |                --------------|  |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk
     30 *                              |------------------------------|  /     +---------+
     31 *                              |          +-----+             | /
     32 *                              -----------| /4? |--o----------|/
     33 *                                         +-----+  |           |
     34 *                                                  |           |dsiclk_sel
     35 *                                                  |
     36 *                                                  dsi0_pll_post_out_div_clk
     37 */
     38
     39#define VCO_REF_CLK_RATE		19200000
     40#define FRAC_BITS 18
     41
     42/* Hardware is V4.1 */
     43#define DSI_PHY_7NM_QUIRK_V4_1		BIT(0)
     44
     45struct dsi_pll_config {
     46	bool enable_ssc;
     47	bool ssc_center;
     48	u32 ssc_freq;
     49	u32 ssc_offset;
     50	u32 ssc_adj_per;
     51
     52	/* out */
     53	u32 decimal_div_start;
     54	u32 frac_div_start;
     55	u32 pll_clock_inverters;
     56	u32 ssc_stepsize;
     57	u32 ssc_div_per;
     58};
     59
     60struct pll_7nm_cached_state {
     61	unsigned long vco_rate;
     62	u8 bit_clk_div;
     63	u8 pix_clk_div;
     64	u8 pll_out_div;
     65	u8 pll_mux;
     66};
     67
     68struct dsi_pll_7nm {
     69	struct clk_hw clk_hw;
     70
     71	struct msm_dsi_phy *phy;
     72
     73	u64 vco_current_rate;
     74
     75	/* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */
     76	spinlock_t postdiv_lock;
     77
     78	struct pll_7nm_cached_state cached_state;
     79
     80	struct dsi_pll_7nm *slave;
     81};
     82
     83#define to_pll_7nm(x)	container_of(x, struct dsi_pll_7nm, clk_hw)
     84
     85/*
     86 * Global list of private DSI PLL struct pointers. We need this for bonded DSI
     87 * mode, where the master PLL's clk_ops needs access the slave's private data
     88 */
     89static struct dsi_pll_7nm *pll_7nm_list[DSI_MAX];
     90
     91static void dsi_pll_setup_config(struct dsi_pll_config *config)
     92{
     93	config->ssc_freq = 31500;
     94	config->ssc_offset = 4800;
     95	config->ssc_adj_per = 2;
     96
     97	/* TODO: ssc enable */
     98	config->enable_ssc = false;
     99	config->ssc_center = 0;
    100}
    101
    102static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
    103{
    104	u64 fref = VCO_REF_CLK_RATE;
    105	u64 pll_freq;
    106	u64 divider;
    107	u64 dec, dec_multiple;
    108	u32 frac;
    109	u64 multiplier;
    110
    111	pll_freq = pll->vco_current_rate;
    112
    113	divider = fref * 2;
    114
    115	multiplier = 1 << FRAC_BITS;
    116	dec_multiple = div_u64(pll_freq * multiplier, divider);
    117	dec = div_u64_rem(dec_multiple, multiplier, &frac);
    118
    119	if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1))
    120		config->pll_clock_inverters = 0x28;
    121	else if (pll_freq <= 1000000000ULL)
    122		config->pll_clock_inverters = 0xa0;
    123	else if (pll_freq <= 2500000000ULL)
    124		config->pll_clock_inverters = 0x20;
    125	else if (pll_freq <= 3020000000ULL)
    126		config->pll_clock_inverters = 0x00;
    127	else
    128		config->pll_clock_inverters = 0x40;
    129
    130	config->decimal_div_start = dec;
    131	config->frac_div_start = frac;
    132}
    133
    134#define SSC_CENTER		BIT(0)
    135#define SSC_EN			BIT(1)
    136
    137static void dsi_pll_calc_ssc(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
    138{
    139	u32 ssc_per;
    140	u32 ssc_mod;
    141	u64 ssc_step_size;
    142	u64 frac;
    143
    144	if (!config->enable_ssc) {
    145		DBG("SSC not enabled\n");
    146		return;
    147	}
    148
    149	ssc_per = DIV_ROUND_CLOSEST(VCO_REF_CLK_RATE, config->ssc_freq) / 2 - 1;
    150	ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1);
    151	ssc_per -= ssc_mod;
    152
    153	frac = config->frac_div_start;
    154	ssc_step_size = config->decimal_div_start;
    155	ssc_step_size *= (1 << FRAC_BITS);
    156	ssc_step_size += frac;
    157	ssc_step_size *= config->ssc_offset;
    158	ssc_step_size *= (config->ssc_adj_per + 1);
    159	ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1));
    160	ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000);
    161
    162	config->ssc_div_per = ssc_per;
    163	config->ssc_stepsize = ssc_step_size;
    164
    165	pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n",
    166		 config->decimal_div_start, frac, FRAC_BITS);
    167	pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n",
    168		 ssc_per, (u32)ssc_step_size, config->ssc_adj_per);
    169}
    170
    171static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
    172{
    173	void __iomem *base = pll->phy->pll_base;
    174
    175	if (config->enable_ssc) {
    176		pr_debug("SSC is enabled\n");
    177
    178		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_LOW_1,
    179			  config->ssc_stepsize & 0xff);
    180		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_HIGH_1,
    181			  config->ssc_stepsize >> 8);
    182		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_LOW_1,
    183			  config->ssc_div_per & 0xff);
    184		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_HIGH_1,
    185			  config->ssc_div_per >> 8);
    186		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_LOW_1,
    187			  config->ssc_adj_per & 0xff);
    188		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_HIGH_1,
    189			  config->ssc_adj_per >> 8);
    190		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_CONTROL,
    191			  SSC_EN | (config->ssc_center ? SSC_CENTER : 0));
    192	}
    193}
    194
    195static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll)
    196{
    197	void __iomem *base = pll->phy->pll_base;
    198	u8 analog_controls_five_1 = 0x01, vco_config_1 = 0x00;
    199
    200	if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
    201		if (pll->vco_current_rate >= 3100000000ULL)
    202			analog_controls_five_1 = 0x03;
    203
    204		if (pll->vco_current_rate < 1520000000ULL)
    205			vco_config_1 = 0x08;
    206		else if (pll->vco_current_rate < 2990000000ULL)
    207			vco_config_1 = 0x01;
    208	}
    209
    210	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1,
    211		  analog_controls_five_1);
    212	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_VCO_CONFIG_1, vco_config_1);
    213	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE, 0x01);
    214	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03);
    215	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00);
    216	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_DSM_DIVIDER, 0x00);
    217	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e);
    218	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40);
    219	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE, 0xba);
    220	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c);
    221	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_OUTDIV, 0x00);
    222	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CORE_OVERRIDE, 0x00);
    223	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08);
    224	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x0a);
    225	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_BAND_SEL_RATE_1, 0xc0);
    226	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x84);
    227	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x82);
    228	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x4c);
    229	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80);
    230	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x29);
    231	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x2f);
    232	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT, 0x2a);
    233	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT,
    234		  pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1 ? 0x3f : 0x22);
    235
    236	if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
    237		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
    238		if (pll->slave)
    239			dsi_phy_write(pll->slave->phy->pll_base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
    240	}
    241}
    242
    243static void dsi_pll_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
    244{
    245	void __iomem *base = pll->phy->pll_base;
    246
    247	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12);
    248	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1, config->decimal_div_start);
    249	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1,
    250		  config->frac_div_start & 0xff);
    251	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1,
    252		  (config->frac_div_start & 0xff00) >> 8);
    253	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1,
    254		  (config->frac_div_start & 0x30000) >> 16);
    255	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, 0x40);
    256	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06);
    257	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, pll->phy->cphy_mode ? 0x00 : 0x10);
    258	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, config->pll_clock_inverters);
    259}
    260
    261static int dsi_pll_7nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
    262				     unsigned long parent_rate)
    263{
    264	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
    265	struct dsi_pll_config config;
    266
    267	DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_7nm->phy->id, rate,
    268	    parent_rate);
    269
    270	pll_7nm->vco_current_rate = rate;
    271
    272	dsi_pll_setup_config(&config);
    273
    274	dsi_pll_calc_dec_frac(pll_7nm, &config);
    275
    276	dsi_pll_calc_ssc(pll_7nm, &config);
    277
    278	dsi_pll_commit(pll_7nm, &config);
    279
    280	dsi_pll_config_hzindep_reg(pll_7nm);
    281
    282	dsi_pll_ssc_commit(pll_7nm, &config);
    283
    284	/* flush, ensure all register writes are done*/
    285	wmb();
    286
    287	return 0;
    288}
    289
    290static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm *pll)
    291{
    292	int rc;
    293	u32 status = 0;
    294	u32 const delay_us = 100;
    295	u32 const timeout_us = 5000;
    296
    297	rc = readl_poll_timeout_atomic(pll->phy->pll_base +
    298				       REG_DSI_7nm_PHY_PLL_COMMON_STATUS_ONE,
    299				       status,
    300				       ((status & BIT(0)) > 0),
    301				       delay_us,
    302				       timeout_us);
    303	if (rc)
    304		pr_err("DSI PLL(%d) lock failed, status=0x%08x\n",
    305		       pll->phy->id, status);
    306
    307	return rc;
    308}
    309
    310static void dsi_pll_disable_pll_bias(struct dsi_pll_7nm *pll)
    311{
    312	u32 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);
    313
    314	dsi_phy_write(pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0);
    315	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0, data & ~BIT(5));
    316	ndelay(250);
    317}
    318
    319static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll)
    320{
    321	u32 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);
    322
    323	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0, data | BIT(5));
    324	dsi_phy_write(pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0xc0);
    325	ndelay(250);
    326}
    327
    328static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll)
    329{
    330	u32 data;
    331
    332	data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
    333	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data & ~BIT(5));
    334}
    335
    336static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll)
    337{
    338	u32 data;
    339
    340	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x04);
    341
    342	data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
    343	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1,
    344		  data | BIT(5) | BIT(4));
    345}
    346
    347static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll)
    348{
    349	/*
    350	 * Reset the PHY digital domain. This would be needed when
    351	 * coming out of a CX or analog rail power collapse while
    352	 * ensuring that the pads maintain LP00 or LP11 state
    353	 */
    354	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0));
    355	wmb(); /* Ensure that the reset is deasserted */
    356	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, 0x0);
    357	wmb(); /* Ensure that the reset is deasserted */
    358}
    359
    360static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw)
    361{
    362	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
    363	int rc;
    364
    365	dsi_pll_enable_pll_bias(pll_7nm);
    366	if (pll_7nm->slave)
    367		dsi_pll_enable_pll_bias(pll_7nm->slave);
    368
    369	/* Start PLL */
    370	dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x01);
    371
    372	/*
    373	 * ensure all PLL configurations are written prior to checking
    374	 * for PLL lock.
    375	 */
    376	wmb();
    377
    378	/* Check for PLL lock */
    379	rc = dsi_pll_7nm_lock_status(pll_7nm);
    380	if (rc) {
    381		pr_err("PLL(%d) lock failed\n", pll_7nm->phy->id);
    382		goto error;
    383	}
    384
    385	pll_7nm->phy->pll_on = true;
    386
    387	/*
    388	 * assert power on reset for PHY digital in case the PLL is
    389	 * enabled after CX of analog domain power collapse. This needs
    390	 * to be done before enabling the global clk.
    391	 */
    392	dsi_pll_phy_dig_reset(pll_7nm);
    393	if (pll_7nm->slave)
    394		dsi_pll_phy_dig_reset(pll_7nm->slave);
    395
    396	dsi_pll_enable_global_clk(pll_7nm);
    397	if (pll_7nm->slave)
    398		dsi_pll_enable_global_clk(pll_7nm->slave);
    399
    400error:
    401	return rc;
    402}
    403
    404static void dsi_pll_disable_sub(struct dsi_pll_7nm *pll)
    405{
    406	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0);
    407	dsi_pll_disable_pll_bias(pll);
    408}
    409
    410static void dsi_pll_7nm_vco_unprepare(struct clk_hw *hw)
    411{
    412	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
    413
    414	/*
    415	 * To avoid any stray glitches while abruptly powering down the PLL
    416	 * make sure to gate the clock using the clock enable bit before
    417	 * powering down the PLL
    418	 */
    419	dsi_pll_disable_global_clk(pll_7nm);
    420	dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0);
    421	dsi_pll_disable_sub(pll_7nm);
    422	if (pll_7nm->slave) {
    423		dsi_pll_disable_global_clk(pll_7nm->slave);
    424		dsi_pll_disable_sub(pll_7nm->slave);
    425	}
    426	/* flush, ensure all register writes are done */
    427	wmb();
    428	pll_7nm->phy->pll_on = false;
    429}
    430
    431static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw,
    432						  unsigned long parent_rate)
    433{
    434	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
    435	void __iomem *base = pll_7nm->phy->pll_base;
    436	u64 ref_clk = VCO_REF_CLK_RATE;
    437	u64 vco_rate = 0x0;
    438	u64 multiplier;
    439	u32 frac;
    440	u32 dec;
    441	u64 pll_freq, tmp64;
    442
    443	dec = dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1);
    444	dec &= 0xff;
    445
    446	frac = dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1);
    447	frac |= ((dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1) &
    448		  0xff) << 8);
    449	frac |= ((dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1) &
    450		  0x3) << 16);
    451
    452	/*
    453	 * TODO:
    454	 *	1. Assumes prescaler is disabled
    455	 */
    456	multiplier = 1 << FRAC_BITS;
    457	pll_freq = dec * (ref_clk * 2);
    458	tmp64 = (ref_clk * 2 * frac);
    459	pll_freq += div_u64(tmp64, multiplier);
    460
    461	vco_rate = pll_freq;
    462	pll_7nm->vco_current_rate = vco_rate;
    463
    464	DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x",
    465	    pll_7nm->phy->id, (unsigned long)vco_rate, dec, frac);
    466
    467	return (unsigned long)vco_rate;
    468}
    469
    470static long dsi_pll_7nm_clk_round_rate(struct clk_hw *hw,
    471		unsigned long rate, unsigned long *parent_rate)
    472{
    473	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
    474
    475	if      (rate < pll_7nm->phy->cfg->min_pll_rate)
    476		return  pll_7nm->phy->cfg->min_pll_rate;
    477	else if (rate > pll_7nm->phy->cfg->max_pll_rate)
    478		return  pll_7nm->phy->cfg->max_pll_rate;
    479	else
    480		return rate;
    481}
    482
    483static const struct clk_ops clk_ops_dsi_pll_7nm_vco = {
    484	.round_rate = dsi_pll_7nm_clk_round_rate,
    485	.set_rate = dsi_pll_7nm_vco_set_rate,
    486	.recalc_rate = dsi_pll_7nm_vco_recalc_rate,
    487	.prepare = dsi_pll_7nm_vco_prepare,
    488	.unprepare = dsi_pll_7nm_vco_unprepare,
    489};
    490
    491/*
    492 * PLL Callbacks
    493 */
    494
    495static void dsi_7nm_pll_save_state(struct msm_dsi_phy *phy)
    496{
    497	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
    498	struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;
    499	void __iomem *phy_base = pll_7nm->phy->base;
    500	u32 cmn_clk_cfg0, cmn_clk_cfg1;
    501
    502	cached->pll_out_div = dsi_phy_read(pll_7nm->phy->pll_base +
    503				       REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);
    504	cached->pll_out_div &= 0x3;
    505
    506	cmn_clk_cfg0 = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0);
    507	cached->bit_clk_div = cmn_clk_cfg0 & 0xf;
    508	cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4;
    509
    510	cmn_clk_cfg1 = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
    511	cached->pll_mux = cmn_clk_cfg1 & 0x3;
    512
    513	DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x",
    514	    pll_7nm->phy->id, cached->pll_out_div, cached->bit_clk_div,
    515	    cached->pix_clk_div, cached->pll_mux);
    516}
    517
    518static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy)
    519{
    520	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
    521	struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;
    522	void __iomem *phy_base = pll_7nm->phy->base;
    523	u32 val;
    524	int ret;
    525
    526	val = dsi_phy_read(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);
    527	val &= ~0x3;
    528	val |= cached->pll_out_div;
    529	dsi_phy_write(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, val);
    530
    531	dsi_phy_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0,
    532		  cached->bit_clk_div | (cached->pix_clk_div << 4));
    533
    534	val = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
    535	val &= ~0x3;
    536	val |= cached->pll_mux;
    537	dsi_phy_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, val);
    538
    539	ret = dsi_pll_7nm_vco_set_rate(phy->vco_hw,
    540			pll_7nm->vco_current_rate,
    541			VCO_REF_CLK_RATE);
    542	if (ret) {
    543		DRM_DEV_ERROR(&pll_7nm->phy->pdev->dev,
    544			"restore vco rate failed. ret=%d\n", ret);
    545		return ret;
    546	}
    547
    548	DBG("DSI PLL%d", pll_7nm->phy->id);
    549
    550	return 0;
    551}
    552
    553static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy)
    554{
    555	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
    556	void __iomem *base = phy->base;
    557	u32 data = 0x0;	/* internal PLL */
    558
    559	DBG("DSI PLL%d", pll_7nm->phy->id);
    560
    561	switch (phy->usecase) {
    562	case MSM_DSI_PHY_STANDALONE:
    563		break;
    564	case MSM_DSI_PHY_MASTER:
    565		pll_7nm->slave = pll_7nm_list[(pll_7nm->phy->id + 1) % DSI_MAX];
    566		break;
    567	case MSM_DSI_PHY_SLAVE:
    568		data = 0x1; /* external PLL */
    569		break;
    570	default:
    571		return -EINVAL;
    572	}
    573
    574	/* set PLL src */
    575	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, (data << 2));
    576
    577	return 0;
    578}
    579
    580/*
    581 * The post dividers and mux clocks are created using the standard divider and
    582 * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux
    583 * state to follow the master PLL's divider/mux state. Therefore, we don't
    584 * require special clock ops that also configure the slave PLL registers
    585 */
    586static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provided_clocks)
    587{
    588	char clk_name[32], parent[32], vco_name[32];
    589	char parent2[32];
    590	struct clk_init_data vco_init = {
    591		.parent_data = &(const struct clk_parent_data) {
    592			.fw_name = "ref",
    593		},
    594		.num_parents = 1,
    595		.name = vco_name,
    596		.flags = CLK_IGNORE_UNUSED,
    597		.ops = &clk_ops_dsi_pll_7nm_vco,
    598	};
    599	struct device *dev = &pll_7nm->phy->pdev->dev;
    600	struct clk_hw *hw;
    601	int ret;
    602
    603	DBG("DSI%d", pll_7nm->phy->id);
    604
    605	snprintf(vco_name, 32, "dsi%dvco_clk", pll_7nm->phy->id);
    606	pll_7nm->clk_hw.init = &vco_init;
    607
    608	ret = devm_clk_hw_register(dev, &pll_7nm->clk_hw);
    609	if (ret)
    610		return ret;
    611
    612	snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id);
    613	snprintf(parent, 32, "dsi%dvco_clk", pll_7nm->phy->id);
    614
    615	hw = devm_clk_hw_register_divider(dev, clk_name,
    616				     parent, CLK_SET_RATE_PARENT,
    617				     pll_7nm->phy->pll_base +
    618				     REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE,
    619				     0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
    620	if (IS_ERR(hw)) {
    621		ret = PTR_ERR(hw);
    622		goto fail;
    623	}
    624
    625	snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id);
    626	snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id);
    627
    628	/* BIT CLK: DIV_CTRL_3_0 */
    629	hw = devm_clk_hw_register_divider(dev, clk_name, parent,
    630				     CLK_SET_RATE_PARENT,
    631				     pll_7nm->phy->base +
    632				     REG_DSI_7nm_PHY_CMN_CLK_CFG0,
    633				     0, 4, CLK_DIVIDER_ONE_BASED,
    634				     &pll_7nm->postdiv_lock);
    635	if (IS_ERR(hw)) {
    636		ret = PTR_ERR(hw);
    637		goto fail;
    638	}
    639
    640	snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_7nm->phy->id);
    641	snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id);
    642
    643	/* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */
    644	hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent,
    645					  CLK_SET_RATE_PARENT, 1,
    646					  pll_7nm->phy->cphy_mode ? 7 : 8);
    647	if (IS_ERR(hw)) {
    648		ret = PTR_ERR(hw);
    649		goto fail;
    650	}
    651
    652	provided_clocks[DSI_BYTE_PLL_CLK] = hw;
    653
    654	snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->phy->id);
    655	snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id);
    656
    657	hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent,
    658					  0, 1, 2);
    659	if (IS_ERR(hw)) {
    660		ret = PTR_ERR(hw);
    661		goto fail;
    662	}
    663
    664	snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id);
    665	snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id);
    666
    667	if (pll_7nm->phy->cphy_mode)
    668		hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 2, 7);
    669	else
    670		hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 4);
    671	if (IS_ERR(hw)) {
    672		ret = PTR_ERR(hw);
    673		goto fail;
    674	}
    675
    676	/* in CPHY mode, pclk_mux will always have post_out_div as parent
    677	 * don't register a pclk_mux clock and just use post_out_div instead
    678	 */
    679	if (pll_7nm->phy->cphy_mode) {
    680		u32 data;
    681
    682		data = dsi_phy_read(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
    683		dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data | 3);
    684
    685		snprintf(parent, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id);
    686	} else {
    687		snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_7nm->phy->id);
    688		snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id);
    689		snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->phy->id);
    690
    691		hw = devm_clk_hw_register_mux(dev, clk_name,
    692					((const char *[]){
    693					parent, parent2,
    694					}), 2, 0, pll_7nm->phy->base +
    695					REG_DSI_7nm_PHY_CMN_CLK_CFG1,
    696					0, 1, 0, NULL);
    697		if (IS_ERR(hw)) {
    698			ret = PTR_ERR(hw);
    699			goto fail;
    700		}
    701
    702		snprintf(parent, 32, "dsi%d_pclk_mux", pll_7nm->phy->id);
    703	}
    704
    705	snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_7nm->phy->id);
    706
    707	/* PIX CLK DIV : DIV_CTRL_7_4*/
    708	hw = devm_clk_hw_register_divider(dev, clk_name, parent,
    709				     0, pll_7nm->phy->base +
    710					REG_DSI_7nm_PHY_CMN_CLK_CFG0,
    711				     4, 4, CLK_DIVIDER_ONE_BASED,
    712				     &pll_7nm->postdiv_lock);
    713	if (IS_ERR(hw)) {
    714		ret = PTR_ERR(hw);
    715		goto fail;
    716	}
    717
    718	provided_clocks[DSI_PIXEL_PLL_CLK] = hw;
    719
    720	return 0;
    721
    722fail:
    723
    724	return ret;
    725}
    726
    727static int dsi_pll_7nm_init(struct msm_dsi_phy *phy)
    728{
    729	struct platform_device *pdev = phy->pdev;
    730	struct dsi_pll_7nm *pll_7nm;
    731	int ret;
    732
    733	pll_7nm = devm_kzalloc(&pdev->dev, sizeof(*pll_7nm), GFP_KERNEL);
    734	if (!pll_7nm)
    735		return -ENOMEM;
    736
    737	DBG("DSI PLL%d", phy->id);
    738
    739	pll_7nm_list[phy->id] = pll_7nm;
    740
    741	spin_lock_init(&pll_7nm->postdiv_lock);
    742
    743	pll_7nm->phy = phy;
    744
    745	ret = pll_7nm_register(pll_7nm, phy->provided_clocks->hws);
    746	if (ret) {
    747		DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
    748		return ret;
    749	}
    750
    751	phy->vco_hw = &pll_7nm->clk_hw;
    752
    753	/* TODO: Remove this when we have proper display handover support */
    754	msm_dsi_phy_pll_save_state(phy);
    755
    756	return 0;
    757}
    758
    759static int dsi_phy_hw_v4_0_is_pll_on(struct msm_dsi_phy *phy)
    760{
    761	void __iomem *base = phy->base;
    762	u32 data = 0;
    763
    764	data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL);
    765	mb(); /* make sure read happened */
    766
    767	return (data & BIT(0));
    768}
    769
    770static void dsi_phy_hw_v4_0_config_lpcdrx(struct msm_dsi_phy *phy, bool enable)
    771{
    772	void __iomem *lane_base = phy->lane_base;
    773	int phy_lane_0 = 0;	/* TODO: Support all lane swap configs */
    774
    775	/*
    776	 * LPRX and CDRX need to enabled only for physical data lane
    777	 * corresponding to the logical data lane 0
    778	 */
    779	if (enable)
    780		dsi_phy_write(lane_base +
    781			      REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0x3);
    782	else
    783		dsi_phy_write(lane_base +
    784			      REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0);
    785}
    786
    787static void dsi_phy_hw_v4_0_lane_settings(struct msm_dsi_phy *phy)
    788{
    789	int i;
    790	const u8 tx_dctrl_0[] = { 0x00, 0x00, 0x00, 0x04, 0x01 };
    791	const u8 tx_dctrl_1[] = { 0x40, 0x40, 0x40, 0x46, 0x41 };
    792	const u8 *tx_dctrl = tx_dctrl_0;
    793	void __iomem *lane_base = phy->lane_base;
    794
    795	if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1)
    796		tx_dctrl = tx_dctrl_1;
    797
    798	/* Strength ctrl settings */
    799	for (i = 0; i < 5; i++) {
    800		/*
    801		 * Disable LPRX and CDRX for all lanes. And later on, it will
    802		 * be only enabled for the physical data lane corresponding
    803		 * to the logical data lane 0
    804		 */
    805		dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_LPRX_CTRL(i), 0);
    806		dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_PIN_SWAP(i), 0x0);
    807	}
    808
    809	dsi_phy_hw_v4_0_config_lpcdrx(phy, true);
    810
    811	/* other settings */
    812	for (i = 0; i < 5; i++) {
    813		dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG0(i), 0x0);
    814		dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG1(i), 0x0);
    815		dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG2(i), i == 4 ? 0x8a : 0xa);
    816		dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_TX_DCTRL(i), tx_dctrl[i]);
    817	}
    818}
    819
    820static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
    821			      struct msm_dsi_phy_clk_request *clk_req)
    822{
    823	int ret;
    824	u32 status;
    825	u32 const delay_us = 5;
    826	u32 const timeout_us = 1000;
    827	struct msm_dsi_dphy_timing *timing = &phy->timing;
    828	void __iomem *base = phy->base;
    829	bool less_than_1500_mhz;
    830	u32 vreg_ctrl_0, vreg_ctrl_1, lane_ctrl0;
    831	u32 glbl_pemph_ctrl_0;
    832	u32 glbl_str_swi_cal_sel_ctrl, glbl_hstx_str_ctrl_0;
    833	u32 glbl_rescode_top_ctrl, glbl_rescode_bot_ctrl;
    834	u32 data;
    835
    836	DBG("");
    837
    838	if (phy->cphy_mode)
    839		ret = msm_dsi_cphy_timing_calc_v4(timing, clk_req);
    840	else
    841		ret = msm_dsi_dphy_timing_calc_v4(timing, clk_req);
    842	if (ret) {
    843		DRM_DEV_ERROR(&phy->pdev->dev,
    844			"%s: PHY timing calculation failed\n", __func__);
    845		return -EINVAL;
    846	}
    847
    848	if (dsi_phy_hw_v4_0_is_pll_on(phy))
    849		pr_warn("PLL turned on before configuring PHY\n");
    850
    851	/* wait for REFGEN READY */
    852	ret = readl_poll_timeout_atomic(base + REG_DSI_7nm_PHY_CMN_PHY_STATUS,
    853					status, (status & BIT(0)),
    854					delay_us, timeout_us);
    855	if (ret) {
    856		pr_err("Ref gen not ready. Aborting\n");
    857		return -EINVAL;
    858	}
    859
    860	/* TODO: CPHY enable path (this is for DPHY only) */
    861
    862	/* Alter PHY configurations if data rate less than 1.5GHZ*/
    863	less_than_1500_mhz = (clk_req->bitclk_rate <= 1500000000);
    864
    865	if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
    866		vreg_ctrl_0 = less_than_1500_mhz ? 0x53 : 0x52;
    867		if (phy->cphy_mode) {
    868			glbl_rescode_top_ctrl = 0x00;
    869			glbl_rescode_bot_ctrl = 0x3c;
    870		} else {
    871			glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d :  0x00;
    872			glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 :  0x3c;
    873		}
    874		glbl_str_swi_cal_sel_ctrl = 0x00;
    875		glbl_hstx_str_ctrl_0 = 0x88;
    876	} else {
    877		vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59;
    878		if (phy->cphy_mode) {
    879			glbl_str_swi_cal_sel_ctrl = 0x03;
    880			glbl_hstx_str_ctrl_0 = 0x66;
    881		} else {
    882			glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00;
    883			glbl_hstx_str_ctrl_0 = less_than_1500_mhz ? 0x66 : 0x88;
    884		}
    885		glbl_rescode_top_ctrl = 0x03;
    886		glbl_rescode_bot_ctrl = 0x3c;
    887	}
    888
    889	if (phy->cphy_mode) {
    890		vreg_ctrl_0 = 0x51;
    891		vreg_ctrl_1 = 0x55;
    892		glbl_pemph_ctrl_0 = 0x11;
    893		lane_ctrl0 = 0x17;
    894	} else {
    895		vreg_ctrl_1 = 0x5c;
    896		glbl_pemph_ctrl_0 = 0x00;
    897		lane_ctrl0 = 0x1f;
    898	}
    899
    900	/* de-assert digital and pll power down */
    901	data = BIT(6) | BIT(5);
    902	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, data);
    903
    904	/* Assert PLL core reset */
    905	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x00);
    906
    907	/* turn off resync FIFO */
    908	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0x00);
    909
    910	/* program CMN_CTRL_4 for minor_ver 2 chipsets*/
    911	data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_REVISION_ID0);
    912	data = data & (0xf0);
    913	if (data == 0x20)
    914		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_4, 0x04);
    915
    916	/* Configure PHY lane swap (TODO: we need to calculate this) */
    917	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CFG0, 0x21);
    918	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CFG1, 0x84);
    919
    920	if (phy->cphy_mode)
    921		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_CTRL, BIT(6));
    922
    923	/* Enable LDO */
    924	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_0, vreg_ctrl_0);
    925	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_1, vreg_ctrl_1);
    926
    927	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x00);
    928	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL,
    929		      glbl_str_swi_cal_sel_ctrl);
    930	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_HSTX_STR_CTRL_0,
    931		      glbl_hstx_str_ctrl_0);
    932	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_0,
    933		      glbl_pemph_ctrl_0);
    934	if (phy->cphy_mode)
    935		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_1, 0x01);
    936	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_TOP_CTRL,
    937		      glbl_rescode_top_ctrl);
    938	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_BOT_CTRL,
    939		      glbl_rescode_bot_ctrl);
    940	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_LPTX_STR_CTRL, 0x55);
    941
    942	/* Remove power down from all blocks */
    943	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, 0x7f);
    944
    945	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0, lane_ctrl0);
    946
    947	/* Select full-rate mode */
    948	if (!phy->cphy_mode)
    949		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_2, 0x40);
    950
    951	ret = dsi_7nm_set_usecase(phy);
    952	if (ret) {
    953		DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n",
    954			__func__, ret);
    955		return ret;
    956	}
    957
    958	/* DSI PHY timings */
    959	if (phy->cphy_mode) {
    960		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0, 0x00);
    961		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4, timing->hs_exit);
    962		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5,
    963			timing->shared_timings.clk_pre);
    964		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6, timing->clk_prepare);
    965		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7,
    966			timing->shared_timings.clk_post);
    967		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8, timing->hs_rqst);
    968		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9, 0x02);
    969		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10, 0x04);
    970		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11, 0x00);
    971	} else {
    972		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0, 0x00);
    973		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_1, timing->clk_zero);
    974		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_2, timing->clk_prepare);
    975		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_3, timing->clk_trail);
    976		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4, timing->hs_exit);
    977		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5, timing->hs_zero);
    978		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6, timing->hs_prepare);
    979		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7, timing->hs_trail);
    980		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8, timing->hs_rqst);
    981		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9, 0x02);
    982		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10, 0x04);
    983		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11, 0x00);
    984		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_12,
    985			timing->shared_timings.clk_pre);
    986		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_13,
    987			timing->shared_timings.clk_post);
    988	}
    989
    990	/* DSI lane settings */
    991	dsi_phy_hw_v4_0_lane_settings(phy);
    992
    993	DBG("DSI%d PHY enabled", phy->id);
    994
    995	return 0;
    996}
    997
    998static bool dsi_7nm_set_continuous_clock(struct msm_dsi_phy *phy, bool enable)
    999{
   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
   1013static 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	/* disable all lanes */
   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	/* Turn off all PHY blocks */
   1032	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, 0x00);
   1033	/* make sure phy is turned off */
   1034	wmb();
   1035
   1036	DBG("DSI%d PHY disabled", phy->id);
   1037}
   1038
   1039const 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
   1066const 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
   1088const 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};