brintos

brintos / linux-shallow public Read only

0
0
Text · 38.5 KiB · 031446c Raw
1317 lines · c
1/*2 * SPDX-License-Identifier: GPL-2.03 * Copyright (c) 2018, The Linux Foundation4 */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 diagram16 *17 *           dsi0_pll_out_div_clk  dsi0_pll_bit_clk18 *                              |                |19 *                              |                |20 *                 +---------+  |  +----------+  |  +----+21 *  dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk22 *                 +---------+  |  +----------+  |  +----+23 *                              |                |24 *                              |                |         dsi0_pll_by_2_bit_clk25 *                              |                |          |26 *                              |                |  +----+  |  |\  dsi0_pclk_mux27 *                              |                |--| /2 |--o--| \   |28 *                              |                |  +----+     |  \  |  +---------+29 *                              |                --------------|  |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk30 *                              |------------------------------|  /     +---------+31 *                              |          +-----+             | /32 *                              -----------| /4? |--o----------|/33 *                                         +-----+  |           |34 *                                                  |           |dsiclk_sel35 *                                                  |36 *                                                  dsi0_pll_post_out_div_clk37 */38 39#define VCO_REF_CLK_RATE		1920000040#define FRAC_BITS 1841 42/* Hardware is pre V4.1 */43#define DSI_PHY_7NM_QUIRK_PRE_V4_1	BIT(0)44/* Hardware is V4.1 */45#define DSI_PHY_7NM_QUIRK_V4_1		BIT(1)46/* Hardware is V4.2 */47#define DSI_PHY_7NM_QUIRK_V4_2		BIT(2)48/* Hardware is V4.3 */49#define DSI_PHY_7NM_QUIRK_V4_3		BIT(3)50/* Hardware is V5.2 */51#define DSI_PHY_7NM_QUIRK_V5_2		BIT(4)52 53struct dsi_pll_config {54	bool enable_ssc;55	bool ssc_center;56	u32 ssc_freq;57	u32 ssc_offset;58	u32 ssc_adj_per;59 60	/* out */61	u32 decimal_div_start;62	u32 frac_div_start;63	u32 pll_clock_inverters;64	u32 ssc_stepsize;65	u32 ssc_div_per;66};67 68struct pll_7nm_cached_state {69	unsigned long vco_rate;70	u8 bit_clk_div;71	u8 pix_clk_div;72	u8 pll_out_div;73	u8 pll_mux;74};75 76struct dsi_pll_7nm {77	struct clk_hw clk_hw;78 79	struct msm_dsi_phy *phy;80 81	u64 vco_current_rate;82 83	/* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */84	spinlock_t postdiv_lock;85 86	struct pll_7nm_cached_state cached_state;87 88	struct dsi_pll_7nm *slave;89};90 91#define to_pll_7nm(x)	container_of(x, struct dsi_pll_7nm, clk_hw)92 93/*94 * Global list of private DSI PLL struct pointers. We need this for bonded DSI95 * mode, where the master PLL's clk_ops needs access the slave's private data96 */97static struct dsi_pll_7nm *pll_7nm_list[DSI_MAX];98 99static void dsi_pll_setup_config(struct dsi_pll_config *config)100{101	config->ssc_freq = 31500;102	config->ssc_offset = 4800;103	config->ssc_adj_per = 2;104 105	/* TODO: ssc enable */106	config->enable_ssc = false;107	config->ssc_center = 0;108}109 110static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)111{112	u64 fref = VCO_REF_CLK_RATE;113	u64 pll_freq;114	u64 divider;115	u64 dec, dec_multiple;116	u32 frac;117	u64 multiplier;118 119	pll_freq = pll->vco_current_rate;120 121	divider = fref * 2;122 123	multiplier = 1 << FRAC_BITS;124	dec_multiple = div_u64(pll_freq * multiplier, divider);125	dec = div_u64_rem(dec_multiple, multiplier, &frac);126 127	if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1)128		config->pll_clock_inverters = 0x28;129	else if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {130		if (pll_freq <= 1300000000ULL)131			config->pll_clock_inverters = 0xa0;132		else if (pll_freq <= 2500000000ULL)133			config->pll_clock_inverters = 0x20;134		else if (pll_freq <= 4000000000ULL)135			config->pll_clock_inverters = 0x00;136		else137			config->pll_clock_inverters = 0x40;138	} else if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {139		if (pll_freq <= 1000000000ULL)140			config->pll_clock_inverters = 0xa0;141		else if (pll_freq <= 2500000000ULL)142			config->pll_clock_inverters = 0x20;143		else if (pll_freq <= 3020000000ULL)144			config->pll_clock_inverters = 0x00;145		else146			config->pll_clock_inverters = 0x40;147	} else {148		/* 4.2, 4.3 */149		if (pll_freq <= 1000000000ULL)150			config->pll_clock_inverters = 0xa0;151		else if (pll_freq <= 2500000000ULL)152			config->pll_clock_inverters = 0x20;153		else if (pll_freq <= 3500000000ULL)154			config->pll_clock_inverters = 0x00;155		else156			config->pll_clock_inverters = 0x40;157	}158 159	config->decimal_div_start = dec;160	config->frac_div_start = frac;161}162 163#define SSC_CENTER		BIT(0)164#define SSC_EN			BIT(1)165 166static void dsi_pll_calc_ssc(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)167{168	u32 ssc_per;169	u32 ssc_mod;170	u64 ssc_step_size;171	u64 frac;172 173	if (!config->enable_ssc) {174		DBG("SSC not enabled\n");175		return;176	}177 178	ssc_per = DIV_ROUND_CLOSEST(VCO_REF_CLK_RATE, config->ssc_freq) / 2 - 1;179	ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1);180	ssc_per -= ssc_mod;181 182	frac = config->frac_div_start;183	ssc_step_size = config->decimal_div_start;184	ssc_step_size *= (1 << FRAC_BITS);185	ssc_step_size += frac;186	ssc_step_size *= config->ssc_offset;187	ssc_step_size *= (config->ssc_adj_per + 1);188	ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1));189	ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000);190 191	config->ssc_div_per = ssc_per;192	config->ssc_stepsize = ssc_step_size;193 194	pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n",195		 config->decimal_div_start, frac, FRAC_BITS);196	pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n",197		 ssc_per, (u32)ssc_step_size, config->ssc_adj_per);198}199 200static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)201{202	void __iomem *base = pll->phy->pll_base;203 204	if (config->enable_ssc) {205		pr_debug("SSC is enabled\n");206 207		writel(config->ssc_stepsize & 0xff,208		       base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_LOW_1);209		writel(config->ssc_stepsize >> 8,210		       base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_HIGH_1);211		writel(config->ssc_div_per & 0xff,212		       base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_LOW_1);213		writel(config->ssc_div_per >> 8,214		       base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_HIGH_1);215		writel(config->ssc_adj_per & 0xff,216		       base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_LOW_1);217		writel(config->ssc_adj_per >> 8,218		       base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_HIGH_1);219		writel(SSC_EN | (config->ssc_center ? SSC_CENTER : 0),220		       base + REG_DSI_7nm_PHY_PLL_SSC_CONTROL);221	}222}223 224static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll)225{226	void __iomem *base = pll->phy->pll_base;227	u8 analog_controls_five_1 = 0x01, vco_config_1 = 0x00;228 229	if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1))230		if (pll->vco_current_rate >= 3100000000ULL)231			analog_controls_five_1 = 0x03;232 233	if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {234		if (pll->vco_current_rate < 1520000000ULL)235			vco_config_1 = 0x08;236		else if (pll->vco_current_rate < 2990000000ULL)237			vco_config_1 = 0x01;238	}239 240	if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_2) ||241	    (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3)) {242		if (pll->vco_current_rate < 1520000000ULL)243			vco_config_1 = 0x08;244		else if (pll->vco_current_rate >= 2990000000ULL)245			vco_config_1 = 0x01;246	}247 248	if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {249		if (pll->vco_current_rate < 1557000000ULL)250			vco_config_1 = 0x08;251		else252			vco_config_1 = 0x01;253	}254 255	writel(analog_controls_five_1, base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1);256	writel(vco_config_1, base + REG_DSI_7nm_PHY_PLL_VCO_CONFIG_1);257	writel(0x01, base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE);258	writel(0x03, base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_TWO);259	writel(0x00, base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_THREE);260	writel(0x00, base + REG_DSI_7nm_PHY_PLL_DSM_DIVIDER);261	writel(0x4e, base + REG_DSI_7nm_PHY_PLL_FEEDBACK_DIVIDER);262	writel(0x40, base + REG_DSI_7nm_PHY_PLL_CALIBRATION_SETTINGS);263	writel(0xba, base + REG_DSI_7nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE);264	writel(0x0c, base + REG_DSI_7nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE);265	writel(0x00, base + REG_DSI_7nm_PHY_PLL_OUTDIV);266	writel(0x00, base + REG_DSI_7nm_PHY_PLL_CORE_OVERRIDE);267	writel(0x08, base + REG_DSI_7nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO);268	writel(0x0a, base + REG_DSI_7nm_PHY_PLL_PLL_PROP_GAIN_RATE_1);269	writel(0xc0, base + REG_DSI_7nm_PHY_PLL_PLL_BAND_SEL_RATE_1);270	writel(0x84, base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1);271	writel(0x82, base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1);272	writel(0x4c, base + REG_DSI_7nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1);273	writel(0x80, base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_OVERRIDE);274	writel(0x29, base + REG_DSI_7nm_PHY_PLL_PFILT);275	writel(0x2f, base + REG_DSI_7nm_PHY_PLL_PFILT);276	writel(0x2a, base + REG_DSI_7nm_PHY_PLL_IFILT);277	writel(!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1) ? 0x3f : 0x22,278	       base + REG_DSI_7nm_PHY_PLL_IFILT);279 280	if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1)) {281		writel(0x22, base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE);282		if (pll->slave)283			writel(0x22, pll->slave->phy->pll_base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE);284	}285}286 287static void dsi_pll_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)288{289	void __iomem *base = pll->phy->pll_base;290 291	writel(0x12, base + REG_DSI_7nm_PHY_PLL_CORE_INPUT_OVERRIDE);292	writel(config->decimal_div_start,293	       base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1);294	writel(config->frac_div_start & 0xff,295	       base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1);296	writel((config->frac_div_start & 0xff00) >> 8,297	       base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1);298	writel((config->frac_div_start & 0x30000) >> 16,299	       base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1);300	writel(0x40, base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1);301	writel(0x06, base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY);302	writel(pll->phy->cphy_mode ? 0x00 : 0x10,303	       base + REG_DSI_7nm_PHY_PLL_CMODE_1);304	writel(config->pll_clock_inverters,305	       base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS);306}307 308static int dsi_pll_7nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,309				     unsigned long parent_rate)310{311	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);312	struct dsi_pll_config config;313 314	DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_7nm->phy->id, rate,315	    parent_rate);316 317	pll_7nm->vco_current_rate = rate;318 319	dsi_pll_setup_config(&config);320 321	dsi_pll_calc_dec_frac(pll_7nm, &config);322 323	dsi_pll_calc_ssc(pll_7nm, &config);324 325	dsi_pll_commit(pll_7nm, &config);326 327	dsi_pll_config_hzindep_reg(pll_7nm);328 329	dsi_pll_ssc_commit(pll_7nm, &config);330 331	/* flush, ensure all register writes are done*/332	wmb();333 334	return 0;335}336 337static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm *pll)338{339	int rc;340	u32 status = 0;341	u32 const delay_us = 100;342	u32 const timeout_us = 5000;343 344	rc = readl_poll_timeout_atomic(pll->phy->pll_base +345				       REG_DSI_7nm_PHY_PLL_COMMON_STATUS_ONE,346				       status,347				       ((status & BIT(0)) > 0),348				       delay_us,349				       timeout_us);350	if (rc)351		pr_err("DSI PLL(%d) lock failed, status=0x%08x\n",352		       pll->phy->id, status);353 354	return rc;355}356 357static void dsi_pll_disable_pll_bias(struct dsi_pll_7nm *pll)358{359	u32 data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);360 361	writel(0, pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES);362	writel(data & ~BIT(5), pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);363	ndelay(250);364}365 366static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll)367{368	u32 data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);369 370	writel(data | BIT(5), pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);371	writel(0xc0, pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES);372	ndelay(250);373}374 375static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll)376{377	u32 data;378 379	data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);380	writel(data & ~BIT(5), pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);381}382 383static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll)384{385	u32 data;386 387	writel(0x04, pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_3);388 389	data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);390	writel(data | BIT(5) | BIT(4), pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);391}392 393static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll)394{395	/*396	 * Reset the PHY digital domain. This would be needed when397	 * coming out of a CX or analog rail power collapse while398	 * ensuring that the pads maintain LP00 or LP11 state399	 */400	writel(BIT(0), pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4);401	wmb(); /* Ensure that the reset is deasserted */402	writel(0, pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4);403	wmb(); /* Ensure that the reset is deasserted */404}405 406static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw)407{408	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);409	int rc;410 411	dsi_pll_enable_pll_bias(pll_7nm);412	if (pll_7nm->slave)413		dsi_pll_enable_pll_bias(pll_7nm->slave);414 415	/* Start PLL */416	writel(BIT(0), pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL);417 418	/*419	 * ensure all PLL configurations are written prior to checking420	 * for PLL lock.421	 */422	wmb();423 424	/* Check for PLL lock */425	rc = dsi_pll_7nm_lock_status(pll_7nm);426	if (rc) {427		pr_err("PLL(%d) lock failed\n", pll_7nm->phy->id);428		goto error;429	}430 431	pll_7nm->phy->pll_on = true;432 433	/*434	 * assert power on reset for PHY digital in case the PLL is435	 * enabled after CX of analog domain power collapse. This needs436	 * to be done before enabling the global clk.437	 */438	dsi_pll_phy_dig_reset(pll_7nm);439	if (pll_7nm->slave)440		dsi_pll_phy_dig_reset(pll_7nm->slave);441 442	dsi_pll_enable_global_clk(pll_7nm);443	if (pll_7nm->slave)444		dsi_pll_enable_global_clk(pll_7nm->slave);445 446error:447	return rc;448}449 450static void dsi_pll_disable_sub(struct dsi_pll_7nm *pll)451{452	writel(0, pll->phy->base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL);453	dsi_pll_disable_pll_bias(pll);454}455 456static void dsi_pll_7nm_vco_unprepare(struct clk_hw *hw)457{458	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);459 460	/*461	 * To avoid any stray glitches while abruptly powering down the PLL462	 * make sure to gate the clock using the clock enable bit before463	 * powering down the PLL464	 */465	dsi_pll_disable_global_clk(pll_7nm);466	writel(0, pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL);467	dsi_pll_disable_sub(pll_7nm);468	if (pll_7nm->slave) {469		dsi_pll_disable_global_clk(pll_7nm->slave);470		dsi_pll_disable_sub(pll_7nm->slave);471	}472	/* flush, ensure all register writes are done */473	wmb();474	pll_7nm->phy->pll_on = false;475}476 477static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw,478						  unsigned long parent_rate)479{480	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);481	void __iomem *base = pll_7nm->phy->pll_base;482	u64 ref_clk = VCO_REF_CLK_RATE;483	u64 vco_rate = 0x0;484	u64 multiplier;485	u32 frac;486	u32 dec;487	u64 pll_freq, tmp64;488 489	dec = readl(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1);490	dec &= 0xff;491 492	frac = readl(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1);493	frac |= ((readl(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1) &494		  0xff) << 8);495	frac |= ((readl(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1) &496		  0x3) << 16);497 498	/*499	 * TODO:500	 *	1. Assumes prescaler is disabled501	 */502	multiplier = 1 << FRAC_BITS;503	pll_freq = dec * (ref_clk * 2);504	tmp64 = (ref_clk * 2 * frac);505	pll_freq += div_u64(tmp64, multiplier);506 507	vco_rate = pll_freq;508	pll_7nm->vco_current_rate = vco_rate;509 510	DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x",511	    pll_7nm->phy->id, (unsigned long)vco_rate, dec, frac);512 513	return (unsigned long)vco_rate;514}515 516static long dsi_pll_7nm_clk_round_rate(struct clk_hw *hw,517		unsigned long rate, unsigned long *parent_rate)518{519	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);520 521	if      (rate < pll_7nm->phy->cfg->min_pll_rate)522		return  pll_7nm->phy->cfg->min_pll_rate;523	else if (rate > pll_7nm->phy->cfg->max_pll_rate)524		return  pll_7nm->phy->cfg->max_pll_rate;525	else526		return rate;527}528 529static const struct clk_ops clk_ops_dsi_pll_7nm_vco = {530	.round_rate = dsi_pll_7nm_clk_round_rate,531	.set_rate = dsi_pll_7nm_vco_set_rate,532	.recalc_rate = dsi_pll_7nm_vco_recalc_rate,533	.prepare = dsi_pll_7nm_vco_prepare,534	.unprepare = dsi_pll_7nm_vco_unprepare,535};536 537/*538 * PLL Callbacks539 */540 541static void dsi_7nm_pll_save_state(struct msm_dsi_phy *phy)542{543	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);544	struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;545	void __iomem *phy_base = pll_7nm->phy->base;546	u32 cmn_clk_cfg0, cmn_clk_cfg1;547 548	cached->pll_out_div = readl(pll_7nm->phy->pll_base +549			REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);550	cached->pll_out_div &= 0x3;551 552	cmn_clk_cfg0 = readl(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0);553	cached->bit_clk_div = cmn_clk_cfg0 & 0xf;554	cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4;555 556	cmn_clk_cfg1 = readl(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);557	cached->pll_mux = cmn_clk_cfg1 & 0x3;558 559	DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x",560	    pll_7nm->phy->id, cached->pll_out_div, cached->bit_clk_div,561	    cached->pix_clk_div, cached->pll_mux);562}563 564static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy)565{566	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);567	struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;568	void __iomem *phy_base = pll_7nm->phy->base;569	u32 val;570	int ret;571 572	val = readl(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);573	val &= ~0x3;574	val |= cached->pll_out_div;575	writel(val, pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);576 577	writel(cached->bit_clk_div | (cached->pix_clk_div << 4),578	       phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0);579 580	val = readl(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);581	val &= ~0x3;582	val |= cached->pll_mux;583	writel(val, phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);584 585	ret = dsi_pll_7nm_vco_set_rate(phy->vco_hw,586			pll_7nm->vco_current_rate,587			VCO_REF_CLK_RATE);588	if (ret) {589		DRM_DEV_ERROR(&pll_7nm->phy->pdev->dev,590			"restore vco rate failed. ret=%d\n", ret);591		return ret;592	}593 594	DBG("DSI PLL%d", pll_7nm->phy->id);595 596	return 0;597}598 599static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy)600{601	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);602	void __iomem *base = phy->base;603	u32 data = 0x0;	/* internal PLL */604 605	DBG("DSI PLL%d", pll_7nm->phy->id);606 607	switch (phy->usecase) {608	case MSM_DSI_PHY_STANDALONE:609		break;610	case MSM_DSI_PHY_MASTER:611		pll_7nm->slave = pll_7nm_list[(pll_7nm->phy->id + 1) % DSI_MAX];612		break;613	case MSM_DSI_PHY_SLAVE:614		data = 0x1; /* external PLL */615		break;616	default:617		return -EINVAL;618	}619 620	/* set PLL src */621	writel(data << 2, base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);622 623	return 0;624}625 626/*627 * The post dividers and mux clocks are created using the standard divider and628 * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux629 * state to follow the master PLL's divider/mux state. Therefore, we don't630 * require special clock ops that also configure the slave PLL registers631 */632static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provided_clocks)633{634	char clk_name[32];635	struct clk_init_data vco_init = {636		.parent_data = &(const struct clk_parent_data) {637			.fw_name = "ref",638		},639		.num_parents = 1,640		.name = clk_name,641		.flags = CLK_IGNORE_UNUSED,642		.ops = &clk_ops_dsi_pll_7nm_vco,643	};644	struct device *dev = &pll_7nm->phy->pdev->dev;645	struct clk_hw *hw, *pll_out_div, *pll_bit, *pll_by_2_bit;646	struct clk_hw *pll_post_out_div, *phy_pll_out_dsi_parent;647	int ret;648 649	DBG("DSI%d", pll_7nm->phy->id);650 651	snprintf(clk_name, sizeof(clk_name), "dsi%dvco_clk", pll_7nm->phy->id);652	pll_7nm->clk_hw.init = &vco_init;653 654	ret = devm_clk_hw_register(dev, &pll_7nm->clk_hw);655	if (ret)656		return ret;657 658	snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_out_div_clk", pll_7nm->phy->id);659 660	pll_out_div = devm_clk_hw_register_divider_parent_hw(dev, clk_name,661			&pll_7nm->clk_hw, CLK_SET_RATE_PARENT,662			pll_7nm->phy->pll_base +663				REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE,664			0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);665	if (IS_ERR(pll_out_div)) {666		ret = PTR_ERR(pll_out_div);667		goto fail;668	}669 670	snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_bit_clk", pll_7nm->phy->id);671 672	/* BIT CLK: DIV_CTRL_3_0 */673	pll_bit = devm_clk_hw_register_divider_parent_hw(dev, clk_name,674			pll_out_div, CLK_SET_RATE_PARENT,675			pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG0,676			0, 4, CLK_DIVIDER_ONE_BASED, &pll_7nm->postdiv_lock);677	if (IS_ERR(pll_bit)) {678		ret = PTR_ERR(pll_bit);679		goto fail;680	}681 682	snprintf(clk_name, sizeof(clk_name), "dsi%d_phy_pll_out_byteclk", pll_7nm->phy->id);683 684	/* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */685	hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk_name,686			pll_bit, CLK_SET_RATE_PARENT, 1,687			pll_7nm->phy->cphy_mode ? 7 : 8);688	if (IS_ERR(hw)) {689		ret = PTR_ERR(hw);690		goto fail;691	}692 693	provided_clocks[DSI_BYTE_PLL_CLK] = hw;694 695	snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_by_2_bit_clk", pll_7nm->phy->id);696 697	pll_by_2_bit = devm_clk_hw_register_fixed_factor_parent_hw(dev,698			clk_name, pll_bit, 0, 1, 2);699	if (IS_ERR(pll_by_2_bit)) {700		ret = PTR_ERR(pll_by_2_bit);701		goto fail;702	}703 704	snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id);705 706	if (pll_7nm->phy->cphy_mode)707		pll_post_out_div = devm_clk_hw_register_fixed_factor_parent_hw(708				dev, clk_name, pll_out_div, 0, 2, 7);709	else710		pll_post_out_div = devm_clk_hw_register_fixed_factor_parent_hw(711				dev, clk_name, pll_out_div, 0, 1, 4);712	if (IS_ERR(pll_post_out_div)) {713		ret = PTR_ERR(pll_post_out_div);714		goto fail;715	}716 717	/* in CPHY mode, pclk_mux will always have post_out_div as parent718	 * don't register a pclk_mux clock and just use post_out_div instead719	 */720	if (pll_7nm->phy->cphy_mode) {721		u32 data;722 723		data = readl(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);724		writel(data | 3, pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);725 726		phy_pll_out_dsi_parent = pll_post_out_div;727	} else {728		snprintf(clk_name, sizeof(clk_name), "dsi%d_pclk_mux", pll_7nm->phy->id);729 730		hw = devm_clk_hw_register_mux_parent_hws(dev, clk_name,731				((const struct clk_hw *[]){732					pll_bit,733					pll_by_2_bit,734				}), 2, 0, pll_7nm->phy->base +735					REG_DSI_7nm_PHY_CMN_CLK_CFG1,736				0, 1, 0, NULL);737		if (IS_ERR(hw)) {738			ret = PTR_ERR(hw);739			goto fail;740		}741 742		phy_pll_out_dsi_parent = hw;743	}744 745	snprintf(clk_name, sizeof(clk_name), "dsi%d_phy_pll_out_dsiclk", pll_7nm->phy->id);746 747	/* PIX CLK DIV : DIV_CTRL_7_4*/748	hw = devm_clk_hw_register_divider_parent_hw(dev, clk_name,749			phy_pll_out_dsi_parent, 0,750			pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG0,751			4, 4, CLK_DIVIDER_ONE_BASED, &pll_7nm->postdiv_lock);752	if (IS_ERR(hw)) {753		ret = PTR_ERR(hw);754		goto fail;755	}756 757	provided_clocks[DSI_PIXEL_PLL_CLK] = hw;758 759	return 0;760 761fail:762 763	return ret;764}765 766static int dsi_pll_7nm_init(struct msm_dsi_phy *phy)767{768	struct platform_device *pdev = phy->pdev;769	struct dsi_pll_7nm *pll_7nm;770	int ret;771 772	pll_7nm = devm_kzalloc(&pdev->dev, sizeof(*pll_7nm), GFP_KERNEL);773	if (!pll_7nm)774		return -ENOMEM;775 776	DBG("DSI PLL%d", phy->id);777 778	pll_7nm_list[phy->id] = pll_7nm;779 780	spin_lock_init(&pll_7nm->postdiv_lock);781 782	pll_7nm->phy = phy;783 784	ret = pll_7nm_register(pll_7nm, phy->provided_clocks->hws);785	if (ret) {786		DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);787		return ret;788	}789 790	phy->vco_hw = &pll_7nm->clk_hw;791 792	/* TODO: Remove this when we have proper display handover support */793	msm_dsi_phy_pll_save_state(phy);794 795	return 0;796}797 798static int dsi_phy_hw_v4_0_is_pll_on(struct msm_dsi_phy *phy)799{800	void __iomem *base = phy->base;801	u32 data = 0;802 803	data = readl(base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL);804	mb(); /* make sure read happened */805 806	return (data & BIT(0));807}808 809static void dsi_phy_hw_v4_0_config_lpcdrx(struct msm_dsi_phy *phy, bool enable)810{811	void __iomem *lane_base = phy->lane_base;812	int phy_lane_0 = 0;	/* TODO: Support all lane swap configs */813 814	/*815	 * LPRX and CDRX need to enabled only for physical data lane816	 * corresponding to the logical data lane 0817	 */818	if (enable)819		writel(0x3, lane_base + REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0));820	else821		writel(0, lane_base + REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0));822}823 824static void dsi_phy_hw_v4_0_lane_settings(struct msm_dsi_phy *phy)825{826	int i;827	const u8 tx_dctrl_0[] = { 0x00, 0x00, 0x00, 0x04, 0x01 };828	const u8 tx_dctrl_1[] = { 0x40, 0x40, 0x40, 0x46, 0x41 };829	const u8 *tx_dctrl = tx_dctrl_0;830	void __iomem *lane_base = phy->lane_base;831 832	if (!(phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1))833		tx_dctrl = tx_dctrl_1;834 835	/* Strength ctrl settings */836	for (i = 0; i < 5; i++) {837		/*838		 * Disable LPRX and CDRX for all lanes. And later on, it will839		 * be only enabled for the physical data lane corresponding840		 * to the logical data lane 0841		 */842		writel(0, lane_base + REG_DSI_7nm_PHY_LN_LPRX_CTRL(i));843		writel(0x0, lane_base + REG_DSI_7nm_PHY_LN_PIN_SWAP(i));844	}845 846	dsi_phy_hw_v4_0_config_lpcdrx(phy, true);847 848	/* other settings */849	for (i = 0; i < 5; i++) {850		writel(0x0, lane_base + REG_DSI_7nm_PHY_LN_CFG0(i));851		writel(0x0, lane_base + REG_DSI_7nm_PHY_LN_CFG1(i));852		writel(i == 4 ? 0x8a : 0xa, lane_base + REG_DSI_7nm_PHY_LN_CFG2(i));853		writel(tx_dctrl[i], lane_base + REG_DSI_7nm_PHY_LN_TX_DCTRL(i));854	}855}856 857static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,858			      struct msm_dsi_phy_clk_request *clk_req)859{860	int ret;861	u32 status;862	u32 const delay_us = 5;863	u32 const timeout_us = 1000;864	struct msm_dsi_dphy_timing *timing = &phy->timing;865	void __iomem *base = phy->base;866	bool less_than_1500_mhz;867	u32 vreg_ctrl_0, vreg_ctrl_1, lane_ctrl0;868	u32 glbl_pemph_ctrl_0;869	u32 glbl_str_swi_cal_sel_ctrl, glbl_hstx_str_ctrl_0;870	u32 glbl_rescode_top_ctrl, glbl_rescode_bot_ctrl;871	u32 data;872 873	DBG("");874 875	if (phy->cphy_mode)876		ret = msm_dsi_cphy_timing_calc_v4(timing, clk_req);877	else878		ret = msm_dsi_dphy_timing_calc_v4(timing, clk_req);879	if (ret) {880		DRM_DEV_ERROR(&phy->pdev->dev,881			      "%s: PHY timing calculation failed\n", __func__);882		return -EINVAL;883	}884 885	if (dsi_phy_hw_v4_0_is_pll_on(phy))886		pr_warn("PLL turned on before configuring PHY\n");887 888	/* Request for REFGEN READY */889	if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3) ||890	    (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {891		writel(0x1, phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10);892		udelay(500);893	}894 895	/* wait for REFGEN READY */896	ret = readl_poll_timeout_atomic(base + REG_DSI_7nm_PHY_CMN_PHY_STATUS,897					status, (status & BIT(0)),898					delay_us, timeout_us);899	if (ret) {900		pr_err("Ref gen not ready. Aborting\n");901		return -EINVAL;902	}903 904	/* TODO: CPHY enable path (this is for DPHY only) */905 906	/* Alter PHY configurations if data rate less than 1.5GHZ*/907	less_than_1500_mhz = (clk_req->bitclk_rate <= 1500000000);908 909	glbl_str_swi_cal_sel_ctrl = 0x00;910	if (phy->cphy_mode) {911		vreg_ctrl_0 = 0x51;912		vreg_ctrl_1 = 0x55;913		glbl_hstx_str_ctrl_0 = 0x00;914		glbl_pemph_ctrl_0 = 0x11;915		lane_ctrl0 = 0x17;916	} else {917		vreg_ctrl_0 = less_than_1500_mhz ? 0x53 : 0x52;918		vreg_ctrl_1 = 0x5c;919		glbl_hstx_str_ctrl_0 = 0x88;920		glbl_pemph_ctrl_0 = 0x00;921		lane_ctrl0 = 0x1f;922	}923 924	if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {925		if (phy->cphy_mode) {926			vreg_ctrl_0 = 0x45;927			vreg_ctrl_1 = 0x41;928			glbl_rescode_top_ctrl = 0x00;929			glbl_rescode_bot_ctrl = 0x00;930		} else {931			vreg_ctrl_0 = 0x44;932			vreg_ctrl_1 = 0x19;933			glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3c :  0x03;934			glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 :  0x3c;935		}936	} else if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3)) {937		if (phy->cphy_mode) {938			glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d :  0x01;939			glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 :  0x3b;940		} else {941			glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d :  0x01;942			glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 :  0x39;943		}944	} else if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_2) {945		if (phy->cphy_mode) {946			glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d :  0x01;947			glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 :  0x3b;948		} else {949			glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3c :  0x00;950			glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 :  0x39;951		}952	} else if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {953		if (phy->cphy_mode) {954			glbl_hstx_str_ctrl_0 = 0x88;955			glbl_rescode_top_ctrl = 0x00;956			glbl_rescode_bot_ctrl = 0x3c;957		} else {958			glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d :  0x00;959			glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 :  0x3c;960		}961	} else {962		if (phy->cphy_mode) {963			glbl_str_swi_cal_sel_ctrl = 0x03;964			glbl_hstx_str_ctrl_0 = 0x66;965		} else {966			vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59;967			glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00;968			glbl_hstx_str_ctrl_0 = less_than_1500_mhz ? 0x66 : 0x88;969		}970		glbl_rescode_top_ctrl = 0x03;971		glbl_rescode_bot_ctrl = 0x3c;972	}973 974	/* de-assert digital and pll power down */975	data = BIT(6) | BIT(5);976	writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0);977 978	/* Assert PLL core reset */979	writel(0x00, base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL);980 981	/* turn off resync FIFO */982	writel(0x00, base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL);983 984	/* program CMN_CTRL_4 for minor_ver 2 chipsets*/985	if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2) ||986	    (readl(base + REG_DSI_7nm_PHY_CMN_REVISION_ID0) & (0xf0)) == 0x20)987		writel(0x04, base + REG_DSI_7nm_PHY_CMN_CTRL_4);988 989	/* Configure PHY lane swap (TODO: we need to calculate this) */990	writel(0x21, base + REG_DSI_7nm_PHY_CMN_LANE_CFG0);991	writel(0x84, base + REG_DSI_7nm_PHY_CMN_LANE_CFG1);992 993	if (phy->cphy_mode)994		writel(BIT(6), base + REG_DSI_7nm_PHY_CMN_GLBL_CTRL);995 996	/* Enable LDO */997	writel(vreg_ctrl_0, base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_0);998	writel(vreg_ctrl_1, base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_1);999 1000	writel(0x00, base + REG_DSI_7nm_PHY_CMN_CTRL_3);1001	writel(glbl_str_swi_cal_sel_ctrl,1002	       base + REG_DSI_7nm_PHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL);1003	writel(glbl_hstx_str_ctrl_0,1004	       base + REG_DSI_7nm_PHY_CMN_GLBL_HSTX_STR_CTRL_0);1005	writel(glbl_pemph_ctrl_0,1006	       base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_0);1007	if (phy->cphy_mode)1008		writel(0x01, base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_1);1009	writel(glbl_rescode_top_ctrl,1010	       base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_TOP_CTRL);1011	writel(glbl_rescode_bot_ctrl,1012	       base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_BOT_CTRL);1013	writel(0x55, base + REG_DSI_7nm_PHY_CMN_GLBL_LPTX_STR_CTRL);1014 1015	/* Remove power down from all blocks */1016	writel(0x7f, base + REG_DSI_7nm_PHY_CMN_CTRL_0);1017 1018	writel(lane_ctrl0, base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0);1019 1020	/* Select full-rate mode */1021	if (!phy->cphy_mode)1022		writel(0x40, base + REG_DSI_7nm_PHY_CMN_CTRL_2);1023 1024	ret = dsi_7nm_set_usecase(phy);1025	if (ret) {1026		DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n",1027			__func__, ret);1028		return ret;1029	}1030 1031	/* DSI PHY timings */1032	if (phy->cphy_mode) {1033		writel(0x00, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0);1034		writel(timing->hs_exit, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4);1035		writel(timing->shared_timings.clk_pre,1036		       base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5);1037		writel(timing->clk_prepare, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6);1038		writel(timing->shared_timings.clk_post,1039		       base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7);1040		writel(timing->hs_rqst, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8);1041		writel(0x02, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9);1042		writel(0x04, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10);1043		writel(0x00, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11);1044	} else {1045		writel(0x00, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0);1046		writel(timing->clk_zero, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_1);1047		writel(timing->clk_prepare, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_2);1048		writel(timing->clk_trail, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_3);1049		writel(timing->hs_exit, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4);1050		writel(timing->hs_zero, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5);1051		writel(timing->hs_prepare, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6);1052		writel(timing->hs_trail, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7);1053		writel(timing->hs_rqst, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8);1054		writel(0x02, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9);1055		writel(0x04, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10);1056		writel(0x00, base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11);1057		writel(timing->shared_timings.clk_pre,1058		       base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_12);1059		writel(timing->shared_timings.clk_post,1060		       base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_13);1061	}1062 1063	/* DSI lane settings */1064	dsi_phy_hw_v4_0_lane_settings(phy);1065 1066	DBG("DSI%d PHY enabled", phy->id);1067 1068	return 0;1069}1070 1071static bool dsi_7nm_set_continuous_clock(struct msm_dsi_phy *phy, bool enable)1072{1073	void __iomem *base = phy->base;1074	u32 data;1075 1076	data = readl(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1);1077	if (enable)1078		data |= BIT(5) | BIT(6);1079	else1080		data &= ~(BIT(5) | BIT(6));1081	writel(data, base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1);1082 1083	return enable;1084}1085 1086static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)1087{1088	void __iomem *base = phy->base;1089	u32 data;1090 1091	DBG("");1092 1093	if (dsi_phy_hw_v4_0_is_pll_on(phy))1094		pr_warn("Turning OFF PHY while PLL is on\n");1095 1096	dsi_phy_hw_v4_0_config_lpcdrx(phy, false);1097 1098	/* Turn off REFGEN Vote */1099	if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3) ||1100	    (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {1101		writel(0x0, base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10);1102		wmb();1103		/* Delay to ensure HW removes vote before PHY shut down */1104		udelay(2);1105	}1106 1107	data = readl(base + REG_DSI_7nm_PHY_CMN_CTRL_0);1108 1109	/* disable all lanes */1110	data &= ~0x1F;1111	writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0);1112	writel(0, base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0);1113 1114	/* Turn off all PHY blocks */1115	writel(0x00, base + REG_DSI_7nm_PHY_CMN_CTRL_0);1116	/* make sure phy is turned off */1117	wmb();1118 1119	DBG("DSI%d PHY disabled", phy->id);1120}1121 1122static const struct regulator_bulk_data dsi_phy_7nm_36mA_regulators[] = {1123	{ .supply = "vdds", .init_load_uA = 36000 },1124};1125 1126static const struct regulator_bulk_data dsi_phy_7nm_37750uA_regulators[] = {1127	{ .supply = "vdds", .init_load_uA = 37550 },1128};1129 1130static const struct regulator_bulk_data dsi_phy_7nm_98000uA_regulators[] = {1131	{ .supply = "vdds", .init_load_uA = 98000 },1132};1133 1134static const struct regulator_bulk_data dsi_phy_7nm_97800uA_regulators[] = {1135	{ .supply = "vdds", .init_load_uA = 97800 },1136};1137 1138static const struct regulator_bulk_data dsi_phy_7nm_98400uA_regulators[] = {1139	{ .supply = "vdds", .init_load_uA = 98400 },1140};1141 1142const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs = {1143	.has_phy_lane = true,1144	.regulator_data = dsi_phy_7nm_36mA_regulators,1145	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_36mA_regulators),1146	.ops = {1147		.enable = dsi_7nm_phy_enable,1148		.disable = dsi_7nm_phy_disable,1149		.pll_init = dsi_pll_7nm_init,1150		.save_pll_state = dsi_7nm_pll_save_state,1151		.restore_pll_state = dsi_7nm_pll_restore_state,1152		.set_continuous_clock = dsi_7nm_set_continuous_clock,1153	},1154	.min_pll_rate = 600000000UL,1155#ifdef CONFIG_64BIT1156	.max_pll_rate = 5000000000UL,1157#else1158	.max_pll_rate = ULONG_MAX,1159#endif1160	.io_start = { 0xae94400, 0xae96400 },1161	.num_dsi_phy = 2,1162	.quirks = DSI_PHY_7NM_QUIRK_V4_1,1163};1164 1165const struct msm_dsi_phy_cfg dsi_phy_7nm_6375_cfgs = {1166	.has_phy_lane = true,1167	.ops = {1168		.enable = dsi_7nm_phy_enable,1169		.disable = dsi_7nm_phy_disable,1170		.pll_init = dsi_pll_7nm_init,1171		.save_pll_state = dsi_7nm_pll_save_state,1172		.restore_pll_state = dsi_7nm_pll_restore_state,1173	},1174	.min_pll_rate = 600000000UL,1175#ifdef CONFIG_64BIT1176	.max_pll_rate = 5000000000ULL,1177#else1178	.max_pll_rate = ULONG_MAX,1179#endif1180	.io_start = { 0x5e94400 },1181	.num_dsi_phy = 1,1182	.quirks = DSI_PHY_7NM_QUIRK_V4_1,1183};1184 1185const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs = {1186	.has_phy_lane = true,1187	.regulator_data = dsi_phy_7nm_36mA_regulators,1188	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_36mA_regulators),1189	.ops = {1190		.enable = dsi_7nm_phy_enable,1191		.disable = dsi_7nm_phy_disable,1192		.pll_init = dsi_pll_7nm_init,1193		.save_pll_state = dsi_7nm_pll_save_state,1194		.restore_pll_state = dsi_7nm_pll_restore_state,1195		.set_continuous_clock = dsi_7nm_set_continuous_clock,1196	},1197	.min_pll_rate = 1000000000UL,1198	.max_pll_rate = 3500000000UL,1199	.io_start = { 0xae94400, 0xae96400 },1200	.num_dsi_phy = 2,1201	.quirks = DSI_PHY_7NM_QUIRK_PRE_V4_1,1202};1203 1204const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs = {1205	.has_phy_lane = true,1206	.regulator_data = dsi_phy_7nm_37750uA_regulators,1207	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_37750uA_regulators),1208	.ops = {1209		.enable = dsi_7nm_phy_enable,1210		.disable = dsi_7nm_phy_disable,1211		.pll_init = dsi_pll_7nm_init,1212		.save_pll_state = dsi_7nm_pll_save_state,1213		.restore_pll_state = dsi_7nm_pll_restore_state,1214	},1215	.min_pll_rate = 600000000UL,1216#ifdef CONFIG_64BIT1217	.max_pll_rate = 5000000000ULL,1218#else1219	.max_pll_rate = ULONG_MAX,1220#endif1221	.io_start = { 0xae94400 },1222	.num_dsi_phy = 1,1223	.quirks = DSI_PHY_7NM_QUIRK_V4_1,1224};1225 1226const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs = {1227	.has_phy_lane = true,1228	.regulator_data = dsi_phy_7nm_37750uA_regulators,1229	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_37750uA_regulators),1230	.ops = {1231		.enable = dsi_7nm_phy_enable,1232		.disable = dsi_7nm_phy_disable,1233		.pll_init = dsi_pll_7nm_init,1234		.save_pll_state = dsi_7nm_pll_save_state,1235		.restore_pll_state = dsi_7nm_pll_restore_state,1236		.set_continuous_clock = dsi_7nm_set_continuous_clock,1237	},1238	.min_pll_rate = 600000000UL,1239#ifdef CONFIG_64BIT1240	.max_pll_rate = 5000000000UL,1241#else1242	.max_pll_rate = ULONG_MAX,1243#endif1244	.io_start = { 0xae94400, 0xae96400 },1245	.num_dsi_phy = 2,1246	.quirks = DSI_PHY_7NM_QUIRK_V4_2,1247};1248 1249const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs = {1250	.has_phy_lane = true,1251	.regulator_data = dsi_phy_7nm_97800uA_regulators,1252	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_97800uA_regulators),1253	.ops = {1254		.enable = dsi_7nm_phy_enable,1255		.disable = dsi_7nm_phy_disable,1256		.pll_init = dsi_pll_7nm_init,1257		.save_pll_state = dsi_7nm_pll_save_state,1258		.restore_pll_state = dsi_7nm_pll_restore_state,1259		.set_continuous_clock = dsi_7nm_set_continuous_clock,1260	},1261	.min_pll_rate = 600000000UL,1262#ifdef CONFIG_64BIT1263	.max_pll_rate = 5000000000UL,1264#else1265	.max_pll_rate = ULONG_MAX,1266#endif1267	.io_start = { 0xae94400, 0xae96400 },1268	.num_dsi_phy = 2,1269	.quirks = DSI_PHY_7NM_QUIRK_V4_3,1270};1271 1272const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs = {1273	.has_phy_lane = true,1274	.regulator_data = dsi_phy_7nm_98400uA_regulators,1275	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_98400uA_regulators),1276	.ops = {1277		.enable = dsi_7nm_phy_enable,1278		.disable = dsi_7nm_phy_disable,1279		.pll_init = dsi_pll_7nm_init,1280		.save_pll_state = dsi_7nm_pll_save_state,1281		.restore_pll_state = dsi_7nm_pll_restore_state,1282		.set_continuous_clock = dsi_7nm_set_continuous_clock,1283	},1284	.min_pll_rate = 600000000UL,1285#ifdef CONFIG_64BIT1286	.max_pll_rate = 5000000000UL,1287#else1288	.max_pll_rate = ULONG_MAX,1289#endif1290	.io_start = { 0xae95000, 0xae97000 },1291	.num_dsi_phy = 2,1292	.quirks = DSI_PHY_7NM_QUIRK_V5_2,1293};1294 1295const struct msm_dsi_phy_cfg dsi_phy_4nm_8650_cfgs = {1296	.has_phy_lane = true,1297	.regulator_data = dsi_phy_7nm_98000uA_regulators,1298	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_98000uA_regulators),1299	.ops = {1300		.enable = dsi_7nm_phy_enable,1301		.disable = dsi_7nm_phy_disable,1302		.pll_init = dsi_pll_7nm_init,1303		.save_pll_state = dsi_7nm_pll_save_state,1304		.restore_pll_state = dsi_7nm_pll_restore_state,1305		.set_continuous_clock = dsi_7nm_set_continuous_clock,1306	},1307	.min_pll_rate = 600000000UL,1308#ifdef CONFIG_64BIT1309	.max_pll_rate = 5000000000UL,1310#else1311	.max_pll_rate = ULONG_MAX,1312#endif1313	.io_start = { 0xae95000, 0xae97000 },1314	.num_dsi_phy = 2,1315	.quirks = DSI_PHY_7NM_QUIRK_V5_2,1316};1317