brintos

brintos / linux-shallow public Read only

0
0
Text · 77.5 KiB · be9bee6 Raw
2759 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved.4 * Copyright (c) 2021, 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.5 */6 7#include <linux/kernel.h>8#include <linux/export.h>9#include <linux/clk-provider.h>10#include <linux/regmap.h>11#include <linux/delay.h>12 13#include "clk-alpha-pll.h"14#include "common.h"15 16#define PLL_MODE(p)		((p)->offset + 0x0)17# define PLL_OUTCTRL		BIT(0)18# define PLL_BYPASSNL		BIT(1)19# define PLL_RESET_N		BIT(2)20# define PLL_OFFLINE_REQ	BIT(7)21# define PLL_LOCK_COUNT_SHIFT	822# define PLL_LOCK_COUNT_MASK	0x3f23# define PLL_BIAS_COUNT_SHIFT	1424# define PLL_BIAS_COUNT_MASK	0x3f25# define PLL_VOTE_FSM_ENA	BIT(20)26# define PLL_FSM_ENA		BIT(20)27# define PLL_VOTE_FSM_RESET	BIT(21)28# define PLL_UPDATE		BIT(22)29# define PLL_UPDATE_BYPASS	BIT(23)30# define PLL_FSM_LEGACY_MODE	BIT(24)31# define PLL_OFFLINE_ACK	BIT(28)32# define ALPHA_PLL_ACK_LATCH	BIT(29)33# define PLL_ACTIVE_FLAG	BIT(30)34# define PLL_LOCK_DET		BIT(31)35 36#define PLL_L_VAL(p)		((p)->offset + (p)->regs[PLL_OFF_L_VAL])37#define PLL_CAL_L_VAL(p)	((p)->offset + (p)->regs[PLL_OFF_CAL_L_VAL])38#define PLL_ALPHA_VAL(p)	((p)->offset + (p)->regs[PLL_OFF_ALPHA_VAL])39#define PLL_ALPHA_VAL_U(p)	((p)->offset + (p)->regs[PLL_OFF_ALPHA_VAL_U])40 41#define PLL_USER_CTL(p)		((p)->offset + (p)->regs[PLL_OFF_USER_CTL])42# define PLL_POST_DIV_SHIFT	843# define PLL_POST_DIV_MASK(p)	GENMASK((p)->width ? (p)->width - 1 : 3, 0)44# define PLL_ALPHA_MSB		BIT(15)45# define PLL_ALPHA_EN		BIT(24)46# define PLL_ALPHA_MODE		BIT(25)47# define PLL_VCO_SHIFT		2048# define PLL_VCO_MASK		0x349 50#define PLL_USER_CTL_U(p)	((p)->offset + (p)->regs[PLL_OFF_USER_CTL_U])51#define PLL_USER_CTL_U1(p)	((p)->offset + (p)->regs[PLL_OFF_USER_CTL_U1])52 53#define PLL_CONFIG_CTL(p)	((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL])54#define PLL_CONFIG_CTL_U(p)	((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U])55#define PLL_CONFIG_CTL_U1(p)	((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U1])56#define PLL_CONFIG_CTL_U2(p)	((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U2])57#define PLL_TEST_CTL(p)		((p)->offset + (p)->regs[PLL_OFF_TEST_CTL])58#define PLL_TEST_CTL_U(p)	((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U])59#define PLL_TEST_CTL_U1(p)     ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U1])60#define PLL_TEST_CTL_U2(p)     ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U2])61#define PLL_STATUS(p)		((p)->offset + (p)->regs[PLL_OFF_STATUS])62#define PLL_OPMODE(p)		((p)->offset + (p)->regs[PLL_OFF_OPMODE])63#define PLL_FRAC(p)		((p)->offset + (p)->regs[PLL_OFF_FRAC])64 65const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {66	[CLK_ALPHA_PLL_TYPE_DEFAULT] =  {67		[PLL_OFF_L_VAL] = 0x04,68		[PLL_OFF_ALPHA_VAL] = 0x08,69		[PLL_OFF_ALPHA_VAL_U] = 0x0c,70		[PLL_OFF_USER_CTL] = 0x10,71		[PLL_OFF_USER_CTL_U] = 0x14,72		[PLL_OFF_CONFIG_CTL] = 0x18,73		[PLL_OFF_TEST_CTL] = 0x1c,74		[PLL_OFF_TEST_CTL_U] = 0x20,75		[PLL_OFF_STATUS] = 0x24,76	},77	[CLK_ALPHA_PLL_TYPE_HUAYRA] =  {78		[PLL_OFF_L_VAL] = 0x04,79		[PLL_OFF_ALPHA_VAL] = 0x08,80		[PLL_OFF_USER_CTL] = 0x10,81		[PLL_OFF_CONFIG_CTL] = 0x14,82		[PLL_OFF_CONFIG_CTL_U] = 0x18,83		[PLL_OFF_TEST_CTL] = 0x1c,84		[PLL_OFF_TEST_CTL_U] = 0x20,85		[PLL_OFF_STATUS] = 0x24,86	},87	[CLK_ALPHA_PLL_TYPE_HUAYRA_APSS] =  {88		[PLL_OFF_L_VAL] = 0x08,89		[PLL_OFF_ALPHA_VAL] = 0x10,90		[PLL_OFF_USER_CTL] = 0x18,91		[PLL_OFF_CONFIG_CTL] = 0x20,92		[PLL_OFF_CONFIG_CTL_U] = 0x24,93		[PLL_OFF_STATUS] = 0x28,94		[PLL_OFF_TEST_CTL] = 0x30,95		[PLL_OFF_TEST_CTL_U] = 0x34,96	},97	[CLK_ALPHA_PLL_TYPE_HUAYRA_2290] =  {98		[PLL_OFF_L_VAL] = 0x04,99		[PLL_OFF_ALPHA_VAL] = 0x08,100		[PLL_OFF_USER_CTL] = 0x0c,101		[PLL_OFF_CONFIG_CTL] = 0x10,102		[PLL_OFF_CONFIG_CTL_U] = 0x14,103		[PLL_OFF_CONFIG_CTL_U1] = 0x18,104		[PLL_OFF_TEST_CTL] = 0x1c,105		[PLL_OFF_TEST_CTL_U] = 0x20,106		[PLL_OFF_TEST_CTL_U1] = 0x24,107		[PLL_OFF_OPMODE] = 0x28,108		[PLL_OFF_STATUS] = 0x38,109	},110	[CLK_ALPHA_PLL_TYPE_BRAMMO] =  {111		[PLL_OFF_L_VAL] = 0x04,112		[PLL_OFF_ALPHA_VAL] = 0x08,113		[PLL_OFF_ALPHA_VAL_U] = 0x0c,114		[PLL_OFF_USER_CTL] = 0x10,115		[PLL_OFF_CONFIG_CTL] = 0x18,116		[PLL_OFF_TEST_CTL] = 0x1c,117		[PLL_OFF_STATUS] = 0x24,118	},119	[CLK_ALPHA_PLL_TYPE_FABIA] =  {120		[PLL_OFF_L_VAL] = 0x04,121		[PLL_OFF_USER_CTL] = 0x0c,122		[PLL_OFF_USER_CTL_U] = 0x10,123		[PLL_OFF_CONFIG_CTL] = 0x14,124		[PLL_OFF_CONFIG_CTL_U] = 0x18,125		[PLL_OFF_TEST_CTL] = 0x1c,126		[PLL_OFF_TEST_CTL_U] = 0x20,127		[PLL_OFF_STATUS] = 0x24,128		[PLL_OFF_OPMODE] = 0x2c,129		[PLL_OFF_FRAC] = 0x38,130	},131	[CLK_ALPHA_PLL_TYPE_TRION] = {132		[PLL_OFF_L_VAL] = 0x04,133		[PLL_OFF_CAL_L_VAL] = 0x08,134		[PLL_OFF_USER_CTL] = 0x0c,135		[PLL_OFF_USER_CTL_U] = 0x10,136		[PLL_OFF_USER_CTL_U1] = 0x14,137		[PLL_OFF_CONFIG_CTL] = 0x18,138		[PLL_OFF_CONFIG_CTL_U] = 0x1c,139		[PLL_OFF_CONFIG_CTL_U1] = 0x20,140		[PLL_OFF_TEST_CTL] = 0x24,141		[PLL_OFF_TEST_CTL_U] = 0x28,142		[PLL_OFF_TEST_CTL_U1] = 0x2c,143		[PLL_OFF_STATUS] = 0x30,144		[PLL_OFF_OPMODE] = 0x38,145		[PLL_OFF_ALPHA_VAL] = 0x40,146	},147	[CLK_ALPHA_PLL_TYPE_AGERA] =  {148		[PLL_OFF_L_VAL] = 0x04,149		[PLL_OFF_ALPHA_VAL] = 0x08,150		[PLL_OFF_USER_CTL] = 0x0c,151		[PLL_OFF_CONFIG_CTL] = 0x10,152		[PLL_OFF_CONFIG_CTL_U] = 0x14,153		[PLL_OFF_TEST_CTL] = 0x18,154		[PLL_OFF_TEST_CTL_U] = 0x1c,155		[PLL_OFF_STATUS] = 0x2c,156	},157	[CLK_ALPHA_PLL_TYPE_ZONDA] =  {158		[PLL_OFF_L_VAL] = 0x04,159		[PLL_OFF_ALPHA_VAL] = 0x08,160		[PLL_OFF_USER_CTL] = 0x0c,161		[PLL_OFF_CONFIG_CTL] = 0x10,162		[PLL_OFF_CONFIG_CTL_U] = 0x14,163		[PLL_OFF_CONFIG_CTL_U1] = 0x18,164		[PLL_OFF_TEST_CTL] = 0x1c,165		[PLL_OFF_TEST_CTL_U] = 0x20,166		[PLL_OFF_TEST_CTL_U1] = 0x24,167		[PLL_OFF_OPMODE] = 0x28,168		[PLL_OFF_STATUS] = 0x38,169	},170	[CLK_ALPHA_PLL_TYPE_LUCID_EVO] = {171		[PLL_OFF_OPMODE] = 0x04,172		[PLL_OFF_STATUS] = 0x0c,173		[PLL_OFF_L_VAL] = 0x10,174		[PLL_OFF_ALPHA_VAL] = 0x14,175		[PLL_OFF_USER_CTL] = 0x18,176		[PLL_OFF_USER_CTL_U] = 0x1c,177		[PLL_OFF_CONFIG_CTL] = 0x20,178		[PLL_OFF_CONFIG_CTL_U] = 0x24,179		[PLL_OFF_CONFIG_CTL_U1] = 0x28,180		[PLL_OFF_TEST_CTL] = 0x2c,181		[PLL_OFF_TEST_CTL_U] = 0x30,182		[PLL_OFF_TEST_CTL_U1] = 0x34,183	},184	[CLK_ALPHA_PLL_TYPE_LUCID_OLE] = {185		[PLL_OFF_OPMODE] = 0x04,186		[PLL_OFF_STATE] = 0x08,187		[PLL_OFF_STATUS] = 0x0c,188		[PLL_OFF_L_VAL] = 0x10,189		[PLL_OFF_ALPHA_VAL] = 0x14,190		[PLL_OFF_USER_CTL] = 0x18,191		[PLL_OFF_USER_CTL_U] = 0x1c,192		[PLL_OFF_CONFIG_CTL] = 0x20,193		[PLL_OFF_CONFIG_CTL_U] = 0x24,194		[PLL_OFF_CONFIG_CTL_U1] = 0x28,195		[PLL_OFF_TEST_CTL] = 0x2c,196		[PLL_OFF_TEST_CTL_U] = 0x30,197		[PLL_OFF_TEST_CTL_U1] = 0x34,198		[PLL_OFF_TEST_CTL_U2] = 0x38,199	},200	[CLK_ALPHA_PLL_TYPE_RIVIAN_EVO] = {201		[PLL_OFF_OPMODE] = 0x04,202		[PLL_OFF_STATUS] = 0x0c,203		[PLL_OFF_L_VAL] = 0x10,204		[PLL_OFF_USER_CTL] = 0x14,205		[PLL_OFF_USER_CTL_U] = 0x18,206		[PLL_OFF_CONFIG_CTL] = 0x1c,207		[PLL_OFF_CONFIG_CTL_U] = 0x20,208		[PLL_OFF_CONFIG_CTL_U1] = 0x24,209		[PLL_OFF_TEST_CTL] = 0x28,210		[PLL_OFF_TEST_CTL_U] = 0x2c,211	},212	[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO] =  {213		[PLL_OFF_L_VAL] = 0x04,214		[PLL_OFF_ALPHA_VAL] = 0x08,215		[PLL_OFF_ALPHA_VAL_U] = 0x0c,216		[PLL_OFF_TEST_CTL] = 0x10,217		[PLL_OFF_TEST_CTL_U] = 0x14,218		[PLL_OFF_USER_CTL] = 0x18,219		[PLL_OFF_USER_CTL_U] = 0x1c,220		[PLL_OFF_CONFIG_CTL] = 0x20,221		[PLL_OFF_STATUS] = 0x24,222	},223	[CLK_ALPHA_PLL_TYPE_BRAMMO_EVO] =  {224		[PLL_OFF_L_VAL] = 0x04,225		[PLL_OFF_ALPHA_VAL] = 0x08,226		[PLL_OFF_ALPHA_VAL_U] = 0x0c,227		[PLL_OFF_TEST_CTL] = 0x10,228		[PLL_OFF_TEST_CTL_U] = 0x14,229		[PLL_OFF_USER_CTL] = 0x18,230		[PLL_OFF_CONFIG_CTL] = 0x1C,231		[PLL_OFF_STATUS] = 0x20,232	},233	[CLK_ALPHA_PLL_TYPE_STROMER] = {234		[PLL_OFF_L_VAL] = 0x08,235		[PLL_OFF_ALPHA_VAL] = 0x10,236		[PLL_OFF_ALPHA_VAL_U] = 0x14,237		[PLL_OFF_USER_CTL] = 0x18,238		[PLL_OFF_USER_CTL_U] = 0x1c,239		[PLL_OFF_CONFIG_CTL] = 0x20,240		[PLL_OFF_STATUS] = 0x28,241		[PLL_OFF_TEST_CTL] = 0x30,242		[PLL_OFF_TEST_CTL_U] = 0x34,243	},244	[CLK_ALPHA_PLL_TYPE_STROMER_PLUS] =  {245		[PLL_OFF_L_VAL] = 0x04,246		[PLL_OFF_USER_CTL] = 0x08,247		[PLL_OFF_USER_CTL_U] = 0x0c,248		[PLL_OFF_CONFIG_CTL] = 0x10,249		[PLL_OFF_TEST_CTL] = 0x14,250		[PLL_OFF_TEST_CTL_U] = 0x18,251		[PLL_OFF_STATUS] = 0x1c,252		[PLL_OFF_ALPHA_VAL] = 0x24,253		[PLL_OFF_ALPHA_VAL_U] = 0x28,254	},255	[CLK_ALPHA_PLL_TYPE_ZONDA_OLE] =  {256		[PLL_OFF_L_VAL] = 0x04,257		[PLL_OFF_ALPHA_VAL] = 0x08,258		[PLL_OFF_USER_CTL] = 0x0c,259		[PLL_OFF_USER_CTL_U] = 0x10,260		[PLL_OFF_CONFIG_CTL] = 0x14,261		[PLL_OFF_CONFIG_CTL_U] = 0x18,262		[PLL_OFF_CONFIG_CTL_U1] = 0x1c,263		[PLL_OFF_CONFIG_CTL_U2] = 0x20,264		[PLL_OFF_TEST_CTL] = 0x24,265		[PLL_OFF_TEST_CTL_U] = 0x28,266		[PLL_OFF_TEST_CTL_U1] = 0x2c,267		[PLL_OFF_OPMODE] = 0x30,268		[PLL_OFF_STATUS] = 0x3c,269	},270};271EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);272 273/*274 * Even though 40 bits are present, use only 32 for ease of calculation.275 */276#define ALPHA_REG_BITWIDTH	40277#define ALPHA_REG_16BIT_WIDTH	16278#define ALPHA_BITWIDTH		32U279#define ALPHA_SHIFT(w)		min(w, ALPHA_BITWIDTH)280 281#define	ALPHA_PLL_STATUS_REG_SHIFT	8282 283#define PLL_HUAYRA_M_WIDTH		8284#define PLL_HUAYRA_M_SHIFT		8285#define PLL_HUAYRA_M_MASK		0xff286#define PLL_HUAYRA_N_SHIFT		0287#define PLL_HUAYRA_N_MASK		0xff288#define PLL_HUAYRA_ALPHA_WIDTH		16289 290#define PLL_STANDBY		0x0291#define PLL_RUN			0x1292#define PLL_OUT_MASK		0x7293#define PLL_RATE_MARGIN		500294 295/* TRION PLL specific settings and offsets */296#define TRION_PLL_CAL_VAL	0x44297#define TRION_PCAL_DONE		BIT(26)298 299/* LUCID PLL specific settings and offsets */300#define LUCID_PCAL_DONE		BIT(27)301 302/* LUCID 5LPE PLL specific settings and offsets */303#define LUCID_5LPE_PCAL_DONE		BIT(11)304#define LUCID_5LPE_ALPHA_PLL_ACK_LATCH	BIT(13)305#define LUCID_5LPE_PLL_LATCH_INPUT	BIT(14)306#define LUCID_5LPE_ENABLE_VOTE_RUN	BIT(21)307 308/* LUCID EVO PLL specific settings and offsets */309#define LUCID_EVO_PCAL_NOT_DONE		BIT(8)310#define LUCID_EVO_ENABLE_VOTE_RUN       BIT(25)311#define LUCID_EVO_PLL_L_VAL_MASK        GENMASK(15, 0)312#define LUCID_EVO_PLL_CAL_L_VAL_SHIFT	16313#define LUCID_OLE_PLL_RINGOSC_CAL_L_VAL_SHIFT	24314 315/* ZONDA PLL specific */316#define ZONDA_PLL_OUT_MASK	0xf317#define ZONDA_STAY_IN_CFA	BIT(16)318#define ZONDA_PLL_FREQ_LOCK_DET	BIT(29)319 320#define pll_alpha_width(p)					\321		((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ?	\322				 ALPHA_REG_BITWIDTH : ALPHA_REG_16BIT_WIDTH)323 324#define pll_has_64bit_config(p)	((PLL_CONFIG_CTL_U(p) - PLL_CONFIG_CTL(p)) == 4)325 326#define to_clk_alpha_pll(_hw) container_of(to_clk_regmap(_hw), \327					   struct clk_alpha_pll, clkr)328 329#define to_clk_alpha_pll_postdiv(_hw) container_of(to_clk_regmap(_hw), \330					   struct clk_alpha_pll_postdiv, clkr)331 332static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,333			const char *action)334{335	u32 val;336	int count;337	int ret;338	const char *name = clk_hw_get_name(&pll->clkr.hw);339 340	ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);341	if (ret)342		return ret;343 344	for (count = 200; count > 0; count--) {345		ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);346		if (ret)347			return ret;348		if (inverse && !(val & mask))349			return 0;350		else if ((val & mask) == mask)351			return 0;352 353		udelay(1);354	}355 356	WARN(1, "%s failed to %s!\n", name, action);357	return -ETIMEDOUT;358}359 360#define wait_for_pll_enable_active(pll) \361	wait_for_pll(pll, PLL_ACTIVE_FLAG, 0, "enable")362 363#define wait_for_pll_enable_lock(pll) \364	wait_for_pll(pll, PLL_LOCK_DET, 0, "enable")365 366#define wait_for_zonda_pll_freq_lock(pll) \367	wait_for_pll(pll, ZONDA_PLL_FREQ_LOCK_DET, 0, "freq enable")368 369#define wait_for_pll_disable(pll) \370	wait_for_pll(pll, PLL_ACTIVE_FLAG, 1, "disable")371 372#define wait_for_pll_offline(pll) \373	wait_for_pll(pll, PLL_OFFLINE_ACK, 0, "offline")374 375#define wait_for_pll_update(pll) \376	wait_for_pll(pll, PLL_UPDATE, 1, "update")377 378#define wait_for_pll_update_ack_set(pll) \379	wait_for_pll(pll, ALPHA_PLL_ACK_LATCH, 0, "update_ack_set")380 381#define wait_for_pll_update_ack_clear(pll) \382	wait_for_pll(pll, ALPHA_PLL_ACK_LATCH, 1, "update_ack_clear")383 384static void clk_alpha_pll_write_config(struct regmap *regmap, unsigned int reg,385					unsigned int val)386{387	if (val)388		regmap_write(regmap, reg, val);389}390 391void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,392			     const struct alpha_pll_config *config)393{394	u32 val, mask;395 396	regmap_write(regmap, PLL_L_VAL(pll), config->l);397	regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha);398	regmap_write(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);399 400	if (pll_has_64bit_config(pll))401		regmap_write(regmap, PLL_CONFIG_CTL_U(pll),402			     config->config_ctl_hi_val);403 404	if (pll_alpha_width(pll) > 32)405		regmap_write(regmap, PLL_ALPHA_VAL_U(pll), config->alpha_hi);406 407	val = config->main_output_mask;408	val |= config->aux_output_mask;409	val |= config->aux2_output_mask;410	val |= config->early_output_mask;411	val |= config->pre_div_val;412	val |= config->post_div_val;413	val |= config->vco_val;414	val |= config->alpha_en_mask;415	val |= config->alpha_mode_mask;416 417	mask = config->main_output_mask;418	mask |= config->aux_output_mask;419	mask |= config->aux2_output_mask;420	mask |= config->early_output_mask;421	mask |= config->pre_div_mask;422	mask |= config->post_div_mask;423	mask |= config->vco_mask;424 425	regmap_update_bits(regmap, PLL_USER_CTL(pll), mask, val);426 427	if (config->test_ctl_mask)428		regmap_update_bits(regmap, PLL_TEST_CTL(pll),429				   config->test_ctl_mask,430				   config->test_ctl_val);431	else432		clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),433					   config->test_ctl_val);434 435	if (config->test_ctl_hi_mask)436		regmap_update_bits(regmap, PLL_TEST_CTL_U(pll),437				   config->test_ctl_hi_mask,438				   config->test_ctl_hi_val);439	else440		clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),441					   config->test_ctl_hi_val);442 443	if (pll->flags & SUPPORTS_FSM_MODE)444		qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0);445}446EXPORT_SYMBOL_GPL(clk_alpha_pll_configure);447 448static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)449{450	int ret;451	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);452	u32 val;453 454	ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);455	if (ret)456		return ret;457 458	val |= PLL_FSM_ENA;459 460	if (pll->flags & SUPPORTS_OFFLINE_REQ)461		val &= ~PLL_OFFLINE_REQ;462 463	ret = regmap_write(pll->clkr.regmap, PLL_MODE(pll), val);464	if (ret)465		return ret;466 467	/* Make sure enable request goes through before waiting for update */468	mb();469 470	return wait_for_pll_enable_active(pll);471}472 473static void clk_alpha_pll_hwfsm_disable(struct clk_hw *hw)474{475	int ret;476	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);477	u32 val;478 479	ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);480	if (ret)481		return;482 483	if (pll->flags & SUPPORTS_OFFLINE_REQ) {484		ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),485					 PLL_OFFLINE_REQ, PLL_OFFLINE_REQ);486		if (ret)487			return;488 489		ret = wait_for_pll_offline(pll);490		if (ret)491			return;492	}493 494	/* Disable hwfsm */495	ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),496				 PLL_FSM_ENA, 0);497	if (ret)498		return;499 500	wait_for_pll_disable(pll);501}502 503static int pll_is_enabled(struct clk_hw *hw, u32 mask)504{505	int ret;506	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);507	u32 val;508 509	ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);510	if (ret)511		return ret;512 513	return !!(val & mask);514}515 516static int clk_alpha_pll_hwfsm_is_enabled(struct clk_hw *hw)517{518	return pll_is_enabled(hw, PLL_ACTIVE_FLAG);519}520 521static int clk_alpha_pll_is_enabled(struct clk_hw *hw)522{523	return pll_is_enabled(hw, PLL_LOCK_DET);524}525 526static int clk_alpha_pll_enable(struct clk_hw *hw)527{528	int ret;529	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);530	u32 val, mask;531 532	mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;533	ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);534	if (ret)535		return ret;536 537	/* If in FSM mode, just vote for it */538	if (val & PLL_VOTE_FSM_ENA) {539		ret = clk_enable_regmap(hw);540		if (ret)541			return ret;542		return wait_for_pll_enable_active(pll);543	}544 545	/* Skip if already enabled */546	if ((val & mask) == mask)547		return 0;548 549	ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),550				 PLL_BYPASSNL, PLL_BYPASSNL);551	if (ret)552		return ret;553 554	/*555	 * H/W requires a 5us delay between disabling the bypass and556	 * de-asserting the reset.557	 */558	mb();559	udelay(5);560 561	ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),562				 PLL_RESET_N, PLL_RESET_N);563	if (ret)564		return ret;565 566	ret = wait_for_pll_enable_lock(pll);567	if (ret)568		return ret;569 570	ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),571				 PLL_OUTCTRL, PLL_OUTCTRL);572 573	/* Ensure that the write above goes through before returning. */574	mb();575	return ret;576}577 578static void clk_alpha_pll_disable(struct clk_hw *hw)579{580	int ret;581	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);582	u32 val, mask;583 584	ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);585	if (ret)586		return;587 588	/* If in FSM mode, just unvote it */589	if (val & PLL_VOTE_FSM_ENA) {590		clk_disable_regmap(hw);591		return;592	}593 594	mask = PLL_OUTCTRL;595	regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), mask, 0);596 597	/* Delay of 2 output clock ticks required until output is disabled */598	mb();599	udelay(1);600 601	mask = PLL_RESET_N | PLL_BYPASSNL;602	regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), mask, 0);603}604 605static unsigned long606alpha_pll_calc_rate(u64 prate, u32 l, u32 a, u32 alpha_width)607{608	return (prate * l) + ((prate * a) >> ALPHA_SHIFT(alpha_width));609}610 611static unsigned long612alpha_pll_round_rate(unsigned long rate, unsigned long prate, u32 *l, u64 *a,613		     u32 alpha_width)614{615	u64 remainder;616	u64 quotient;617 618	quotient = rate;619	remainder = do_div(quotient, prate);620	*l = quotient;621 622	if (!remainder) {623		*a = 0;624		return rate;625	}626 627	/* Upper ALPHA_BITWIDTH bits of Alpha */628	quotient = remainder << ALPHA_SHIFT(alpha_width);629 630	remainder = do_div(quotient, prate);631 632	if (remainder)633		quotient++;634 635	*a = quotient;636	return alpha_pll_calc_rate(prate, *l, *a, alpha_width);637}638 639static const struct pll_vco *640alpha_pll_find_vco(const struct clk_alpha_pll *pll, unsigned long rate)641{642	const struct pll_vco *v = pll->vco_table;643	const struct pll_vco *end = v + pll->num_vco;644 645	for (; v < end; v++)646		if (rate >= v->min_freq && rate <= v->max_freq)647			return v;648 649	return NULL;650}651 652static unsigned long653clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)654{655	u32 l, low, high, ctl;656	u64 a = 0, prate = parent_rate;657	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);658	u32 alpha_width = pll_alpha_width(pll);659 660	regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l);661 662	regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);663	if (ctl & PLL_ALPHA_EN) {664		regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &low);665		if (alpha_width > 32) {666			regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll),667				    &high);668			a = (u64)high << 32 | low;669		} else {670			a = low & GENMASK(alpha_width - 1, 0);671		}672 673		if (alpha_width > ALPHA_BITWIDTH)674			a >>= alpha_width - ALPHA_BITWIDTH;675	}676 677	return alpha_pll_calc_rate(prate, l, a, alpha_width);678}679 680 681static int __clk_alpha_pll_update_latch(struct clk_alpha_pll *pll)682{683	int ret;684	u32 mode;685 686	regmap_read(pll->clkr.regmap, PLL_MODE(pll), &mode);687 688	/* Latch the input to the PLL */689	regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_UPDATE,690			   PLL_UPDATE);691 692	/* Wait for 2 reference cycle before checking ACK bit */693	udelay(1);694 695	/*696	 * PLL will latch the new L, Alpha and freq control word.697	 * PLL will respond by raising PLL_ACK_LATCH output when new programming698	 * has been latched in and PLL is being updated. When699	 * UPDATE_LOGIC_BYPASS bit is not set, PLL_UPDATE will be cleared700	 * automatically by hardware when PLL_ACK_LATCH is asserted by PLL.701	 */702	if (mode & PLL_UPDATE_BYPASS) {703		ret = wait_for_pll_update_ack_set(pll);704		if (ret)705			return ret;706 707		regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_UPDATE, 0);708	} else {709		ret = wait_for_pll_update(pll);710		if (ret)711			return ret;712	}713 714	ret = wait_for_pll_update_ack_clear(pll);715	if (ret)716		return ret;717 718	/* Wait for PLL output to stabilize */719	udelay(10);720 721	return 0;722}723 724static int clk_alpha_pll_update_latch(struct clk_alpha_pll *pll,725				      int (*is_enabled)(struct clk_hw *))726{727	if (!is_enabled(&pll->clkr.hw) ||728	    !(pll->flags & SUPPORTS_DYNAMIC_UPDATE))729		return 0;730 731	return __clk_alpha_pll_update_latch(pll);732}733 734static int __clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,735				    unsigned long prate,736				    int (*is_enabled)(struct clk_hw *))737{738	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);739	const struct pll_vco *vco;740	u32 l, alpha_width = pll_alpha_width(pll);741	u64 a;742 743	rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);744	vco = alpha_pll_find_vco(pll, rate);745	if (pll->vco_table && !vco) {746		pr_err("%s: alpha pll not in a valid vco range\n",747		       clk_hw_get_name(hw));748		return -EINVAL;749	}750 751	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);752 753	if (alpha_width > ALPHA_BITWIDTH)754		a <<= alpha_width - ALPHA_BITWIDTH;755 756	if (alpha_width > 32)757		regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), a >> 32);758 759	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);760 761	if (vco) {762		regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),763				   PLL_VCO_MASK << PLL_VCO_SHIFT,764				   vco->val << PLL_VCO_SHIFT);765	}766 767	regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),768			   PLL_ALPHA_EN, PLL_ALPHA_EN);769 770	return clk_alpha_pll_update_latch(pll, is_enabled);771}772 773static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,774				  unsigned long prate)775{776	return __clk_alpha_pll_set_rate(hw, rate, prate,777					clk_alpha_pll_is_enabled);778}779 780static int clk_alpha_pll_hwfsm_set_rate(struct clk_hw *hw, unsigned long rate,781					unsigned long prate)782{783	return __clk_alpha_pll_set_rate(hw, rate, prate,784					clk_alpha_pll_hwfsm_is_enabled);785}786 787static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,788				     unsigned long *prate)789{790	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);791	u32 l, alpha_width = pll_alpha_width(pll);792	u64 a;793	unsigned long min_freq, max_freq;794 795	rate = alpha_pll_round_rate(rate, *prate, &l, &a, alpha_width);796	if (!pll->vco_table || alpha_pll_find_vco(pll, rate))797		return rate;798 799	min_freq = pll->vco_table[0].min_freq;800	max_freq = pll->vco_table[pll->num_vco - 1].max_freq;801 802	return clamp(rate, min_freq, max_freq);803}804 805void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,806				   const struct alpha_pll_config *config)807{808	u32 val;809 810	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);811	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);812	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);813	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);814	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);815	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);816	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);817	clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);818	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);819 820	/* Set PLL_BYPASSNL */821	regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL);822	regmap_read(regmap, PLL_MODE(pll), &val);823 824	/* Wait 5 us between setting BYPASS and deasserting reset */825	udelay(5);826 827	/* Take PLL out from reset state */828	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);829	regmap_read(regmap, PLL_MODE(pll), &val);830 831	/* Wait 50us for PLL_LOCK_DET bit to go high */832	usleep_range(50, 55);833 834	/* Enable PLL output */835	regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);836}837EXPORT_SYMBOL_GPL(clk_huayra_2290_pll_configure);838 839static unsigned long840alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a)841{842	/*843	 * a contains 16 bit alpha_val in two’s complement number in the range844	 * of [-0.5, 0.5).845	 */846	if (a >= BIT(PLL_HUAYRA_ALPHA_WIDTH - 1))847		l -= 1;848 849	return (prate * l) + (prate * a >> PLL_HUAYRA_ALPHA_WIDTH);850}851 852static unsigned long853alpha_huayra_pll_round_rate(unsigned long rate, unsigned long prate,854			    u32 *l, u32 *a)855{856	u64 remainder;857	u64 quotient;858 859	quotient = rate;860	remainder = do_div(quotient, prate);861	*l = quotient;862 863	if (!remainder) {864		*a = 0;865		return rate;866	}867 868	quotient = remainder << PLL_HUAYRA_ALPHA_WIDTH;869	remainder = do_div(quotient, prate);870 871	if (remainder)872		quotient++;873 874	/*875	 * alpha_val should be in two’s complement number in the range876	 * of [-0.5, 0.5) so if quotient >= 0.5 then increment the l value877	 * since alpha value will be subtracted in this case.878	 */879	if (quotient >= BIT(PLL_HUAYRA_ALPHA_WIDTH - 1))880		*l += 1;881 882	*a = quotient;883	return alpha_huayra_pll_calc_rate(prate, *l, *a);884}885 886static unsigned long887alpha_pll_huayra_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)888{889	u64 rate = parent_rate, tmp;890	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);891	u32 l, alpha = 0, ctl, alpha_m, alpha_n;892 893	regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l);894	regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);895 896	if (ctl & PLL_ALPHA_EN) {897		regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &alpha);898		/*899		 * Depending upon alpha_mode, it can be treated as M/N value or900		 * as a two’s complement number. When alpha_mode=1,901		 * pll_alpha_val<15:8>=M and pll_apla_val<7:0>=N902		 *903		 *		Fout=FIN*(L+(M/N))904		 *905		 * M is a signed number (-128 to 127) and N is unsigned906		 * (0 to 255). M/N has to be within +/-0.5.907		 *908		 * When alpha_mode=0, it is a two’s complement number in the909		 * range [-0.5, 0.5).910		 *911		 *		Fout=FIN*(L+(alpha_val)/2^16)912		 *913		 * where alpha_val is two’s complement number.914		 */915		if (!(ctl & PLL_ALPHA_MODE))916			return alpha_huayra_pll_calc_rate(rate, l, alpha);917 918		alpha_m = alpha >> PLL_HUAYRA_M_SHIFT & PLL_HUAYRA_M_MASK;919		alpha_n = alpha >> PLL_HUAYRA_N_SHIFT & PLL_HUAYRA_N_MASK;920 921		rate *= l;922		tmp = parent_rate;923		if (alpha_m >= BIT(PLL_HUAYRA_M_WIDTH - 1)) {924			alpha_m = BIT(PLL_HUAYRA_M_WIDTH) - alpha_m;925			tmp *= alpha_m;926			do_div(tmp, alpha_n);927			rate -= tmp;928		} else {929			tmp *= alpha_m;930			do_div(tmp, alpha_n);931			rate += tmp;932		}933 934		return rate;935	}936 937	return alpha_huayra_pll_calc_rate(rate, l, alpha);938}939 940static int alpha_pll_huayra_set_rate(struct clk_hw *hw, unsigned long rate,941				     unsigned long prate)942{943	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);944	u32 l, a, ctl, cur_alpha = 0;945 946	rate = alpha_huayra_pll_round_rate(rate, prate, &l, &a);947 948	regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);949 950	if (ctl & PLL_ALPHA_EN)951		regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &cur_alpha);952 953	/*954	 * Huayra PLL supports PLL dynamic programming. User can change L_VAL,955	 * without having to go through the power on sequence.956	 */957	if (clk_alpha_pll_is_enabled(hw)) {958		if (cur_alpha != a) {959			pr_err("%s: clock needs to be gated\n",960			       clk_hw_get_name(hw));961			return -EBUSY;962		}963 964		regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);965		/* Ensure that the write above goes to detect L val change. */966		mb();967		return wait_for_pll_enable_lock(pll);968	}969 970	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);971	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);972 973	if (a == 0)974		regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),975				   PLL_ALPHA_EN, 0x0);976	else977		regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),978				   PLL_ALPHA_EN | PLL_ALPHA_MODE, PLL_ALPHA_EN);979 980	return 0;981}982 983static long alpha_pll_huayra_round_rate(struct clk_hw *hw, unsigned long rate,984					unsigned long *prate)985{986	u32 l, a;987 988	return alpha_huayra_pll_round_rate(rate, *prate, &l, &a);989}990 991static int trion_pll_is_enabled(struct clk_alpha_pll *pll,992				struct regmap *regmap)993{994	u32 mode_val, opmode_val;995	int ret;996 997	ret = regmap_read(regmap, PLL_MODE(pll), &mode_val);998	ret |= regmap_read(regmap, PLL_OPMODE(pll), &opmode_val);999	if (ret)1000		return 0;1001 1002	return ((opmode_val & PLL_RUN) && (mode_val & PLL_OUTCTRL));1003}1004 1005static int clk_trion_pll_is_enabled(struct clk_hw *hw)1006{1007	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1008 1009	return trion_pll_is_enabled(pll, pll->clkr.regmap);1010}1011 1012static int clk_trion_pll_enable(struct clk_hw *hw)1013{1014	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1015	struct regmap *regmap = pll->clkr.regmap;1016	u32 val;1017	int ret;1018 1019	ret = regmap_read(regmap, PLL_MODE(pll), &val);1020	if (ret)1021		return ret;1022 1023	/* If in FSM mode, just vote for it */1024	if (val & PLL_VOTE_FSM_ENA) {1025		ret = clk_enable_regmap(hw);1026		if (ret)1027			return ret;1028		return wait_for_pll_enable_active(pll);1029	}1030 1031	/* Set operation mode to RUN */1032	regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN);1033 1034	ret = wait_for_pll_enable_lock(pll);1035	if (ret)1036		return ret;1037 1038	/* Enable the PLL outputs */1039	ret = regmap_update_bits(regmap, PLL_USER_CTL(pll),1040				 PLL_OUT_MASK, PLL_OUT_MASK);1041	if (ret)1042		return ret;1043 1044	/* Enable the global PLL outputs */1045	return regmap_update_bits(regmap, PLL_MODE(pll),1046				 PLL_OUTCTRL, PLL_OUTCTRL);1047}1048 1049static void clk_trion_pll_disable(struct clk_hw *hw)1050{1051	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1052	struct regmap *regmap = pll->clkr.regmap;1053	u32 val;1054	int ret;1055 1056	ret = regmap_read(regmap, PLL_MODE(pll), &val);1057	if (ret)1058		return;1059 1060	/* If in FSM mode, just unvote it */1061	if (val & PLL_VOTE_FSM_ENA) {1062		clk_disable_regmap(hw);1063		return;1064	}1065 1066	/* Disable the global PLL output */1067	ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);1068	if (ret)1069		return;1070 1071	/* Disable the PLL outputs */1072	ret = regmap_update_bits(regmap, PLL_USER_CTL(pll),1073				 PLL_OUT_MASK, 0);1074	if (ret)1075		return;1076 1077	/* Place the PLL mode in STANDBY */1078	regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);1079	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);1080}1081 1082static unsigned long1083clk_trion_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)1084{1085	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1086	u32 l, frac, alpha_width = pll_alpha_width(pll);1087 1088	regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l);1089	regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &frac);1090 1091	return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width);1092}1093 1094const struct clk_ops clk_alpha_pll_fixed_ops = {1095	.enable = clk_alpha_pll_enable,1096	.disable = clk_alpha_pll_disable,1097	.is_enabled = clk_alpha_pll_is_enabled,1098	.recalc_rate = clk_alpha_pll_recalc_rate,1099};1100EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_ops);1101 1102const struct clk_ops clk_alpha_pll_ops = {1103	.enable = clk_alpha_pll_enable,1104	.disable = clk_alpha_pll_disable,1105	.is_enabled = clk_alpha_pll_is_enabled,1106	.recalc_rate = clk_alpha_pll_recalc_rate,1107	.round_rate = clk_alpha_pll_round_rate,1108	.set_rate = clk_alpha_pll_set_rate,1109};1110EXPORT_SYMBOL_GPL(clk_alpha_pll_ops);1111 1112const struct clk_ops clk_alpha_pll_huayra_ops = {1113	.enable = clk_alpha_pll_enable,1114	.disable = clk_alpha_pll_disable,1115	.is_enabled = clk_alpha_pll_is_enabled,1116	.recalc_rate = alpha_pll_huayra_recalc_rate,1117	.round_rate = alpha_pll_huayra_round_rate,1118	.set_rate = alpha_pll_huayra_set_rate,1119};1120EXPORT_SYMBOL_GPL(clk_alpha_pll_huayra_ops);1121 1122const struct clk_ops clk_alpha_pll_hwfsm_ops = {1123	.enable = clk_alpha_pll_hwfsm_enable,1124	.disable = clk_alpha_pll_hwfsm_disable,1125	.is_enabled = clk_alpha_pll_hwfsm_is_enabled,1126	.recalc_rate = clk_alpha_pll_recalc_rate,1127	.round_rate = clk_alpha_pll_round_rate,1128	.set_rate = clk_alpha_pll_hwfsm_set_rate,1129};1130EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops);1131 1132const struct clk_ops clk_alpha_pll_fixed_trion_ops = {1133	.enable = clk_trion_pll_enable,1134	.disable = clk_trion_pll_disable,1135	.is_enabled = clk_trion_pll_is_enabled,1136	.recalc_rate = clk_trion_pll_recalc_rate,1137	.round_rate = clk_alpha_pll_round_rate,1138};1139EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_trion_ops);1140 1141static unsigned long1142clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)1143{1144	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);1145	u32 ctl;1146 1147	regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);1148 1149	ctl >>= PLL_POST_DIV_SHIFT;1150	ctl &= PLL_POST_DIV_MASK(pll);1151 1152	return parent_rate >> fls(ctl);1153}1154 1155static const struct clk_div_table clk_alpha_div_table[] = {1156	{ 0x0, 1 },1157	{ 0x1, 2 },1158	{ 0x3, 4 },1159	{ 0x7, 8 },1160	{ 0xf, 16 },1161	{ }1162};1163 1164static const struct clk_div_table clk_alpha_2bit_div_table[] = {1165	{ 0x0, 1 },1166	{ 0x1, 2 },1167	{ 0x3, 4 },1168	{ }1169};1170 1171static long1172clk_alpha_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate,1173				 unsigned long *prate)1174{1175	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);1176	const struct clk_div_table *table;1177 1178	if (pll->width == 2)1179		table = clk_alpha_2bit_div_table;1180	else1181		table = clk_alpha_div_table;1182 1183	return divider_round_rate(hw, rate, prate, table,1184				  pll->width, CLK_DIVIDER_POWER_OF_TWO);1185}1186 1187static long1188clk_alpha_pll_postdiv_round_ro_rate(struct clk_hw *hw, unsigned long rate,1189				    unsigned long *prate)1190{1191	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);1192	u32 ctl, div;1193 1194	regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);1195 1196	ctl >>= PLL_POST_DIV_SHIFT;1197	ctl &= BIT(pll->width) - 1;1198	div = 1 << fls(ctl);1199 1200	if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)1201		*prate = clk_hw_round_rate(clk_hw_get_parent(hw), div * rate);1202 1203	return DIV_ROUND_UP_ULL((u64)*prate, div);1204}1205 1206static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,1207					  unsigned long parent_rate)1208{1209	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);1210	int div;1211 1212	/* 16 -> 0xf, 8 -> 0x7, 4 -> 0x3, 2 -> 0x1, 1 -> 0x0 */1213	div = DIV_ROUND_UP_ULL(parent_rate, rate) - 1;1214 1215	return regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),1216				  PLL_POST_DIV_MASK(pll) << PLL_POST_DIV_SHIFT,1217				  div << PLL_POST_DIV_SHIFT);1218}1219 1220const struct clk_ops clk_alpha_pll_postdiv_ops = {1221	.recalc_rate = clk_alpha_pll_postdiv_recalc_rate,1222	.round_rate = clk_alpha_pll_postdiv_round_rate,1223	.set_rate = clk_alpha_pll_postdiv_set_rate,1224};1225EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ops);1226 1227const struct clk_ops clk_alpha_pll_postdiv_ro_ops = {1228	.round_rate = clk_alpha_pll_postdiv_round_ro_rate,1229	.recalc_rate = clk_alpha_pll_postdiv_recalc_rate,1230};1231EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ro_ops);1232 1233void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,1234			     const struct alpha_pll_config *config)1235{1236	u32 val, mask;1237 1238	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);1239	clk_alpha_pll_write_config(regmap, PLL_FRAC(pll), config->alpha);1240	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),1241						config->config_ctl_val);1242	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),1243						config->config_ctl_hi_val);1244	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),1245						config->user_ctl_val);1246	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll),1247						config->user_ctl_hi_val);1248	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),1249						config->test_ctl_val);1250	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),1251						config->test_ctl_hi_val);1252 1253	if (config->post_div_mask) {1254		mask = config->post_div_mask;1255		val = config->post_div_val;1256		regmap_update_bits(regmap, PLL_USER_CTL(pll), mask, val);1257	}1258 1259	if (pll->flags & SUPPORTS_FSM_LEGACY_MODE)1260		regmap_update_bits(regmap, PLL_MODE(pll), PLL_FSM_LEGACY_MODE,1261							PLL_FSM_LEGACY_MODE);1262 1263	regmap_update_bits(regmap, PLL_MODE(pll), PLL_UPDATE_BYPASS,1264							PLL_UPDATE_BYPASS);1265 1266	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);1267}1268EXPORT_SYMBOL_GPL(clk_fabia_pll_configure);1269 1270static int alpha_pll_fabia_enable(struct clk_hw *hw)1271{1272	int ret;1273	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1274	u32 val, opmode_val;1275	struct regmap *regmap = pll->clkr.regmap;1276 1277	ret = regmap_read(regmap, PLL_MODE(pll), &val);1278	if (ret)1279		return ret;1280 1281	/* If in FSM mode, just vote for it */1282	if (val & PLL_VOTE_FSM_ENA) {1283		ret = clk_enable_regmap(hw);1284		if (ret)1285			return ret;1286		return wait_for_pll_enable_active(pll);1287	}1288 1289	ret = regmap_read(regmap, PLL_OPMODE(pll), &opmode_val);1290	if (ret)1291		return ret;1292 1293	/* Skip If PLL is already running */1294	if ((opmode_val & PLL_RUN) && (val & PLL_OUTCTRL))1295		return 0;1296 1297	ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);1298	if (ret)1299		return ret;1300 1301	ret = regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);1302	if (ret)1303		return ret;1304 1305	ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N,1306				 PLL_RESET_N);1307	if (ret)1308		return ret;1309 1310	ret = regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN);1311	if (ret)1312		return ret;1313 1314	ret = wait_for_pll_enable_lock(pll);1315	if (ret)1316		return ret;1317 1318	ret = regmap_update_bits(regmap, PLL_USER_CTL(pll),1319				 PLL_OUT_MASK, PLL_OUT_MASK);1320	if (ret)1321		return ret;1322 1323	return regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL,1324				 PLL_OUTCTRL);1325}1326 1327static void alpha_pll_fabia_disable(struct clk_hw *hw)1328{1329	int ret;1330	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1331	u32 val;1332	struct regmap *regmap = pll->clkr.regmap;1333 1334	ret = regmap_read(regmap, PLL_MODE(pll), &val);1335	if (ret)1336		return;1337 1338	/* If in FSM mode, just unvote it */1339	if (val & PLL_FSM_ENA) {1340		clk_disable_regmap(hw);1341		return;1342	}1343 1344	ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);1345	if (ret)1346		return;1347 1348	/* Disable main outputs */1349	ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, 0);1350	if (ret)1351		return;1352 1353	/* Place the PLL in STANDBY */1354	regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);1355}1356 1357static unsigned long alpha_pll_fabia_recalc_rate(struct clk_hw *hw,1358						unsigned long parent_rate)1359{1360	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1361	u32 l, frac, alpha_width = pll_alpha_width(pll);1362 1363	regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l);1364	regmap_read(pll->clkr.regmap, PLL_FRAC(pll), &frac);1365 1366	return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width);1367}1368 1369/*1370 * Due to limited number of bits for fractional rate programming, the1371 * rounded up rate could be marginally higher than the requested rate.1372 */1373static int alpha_pll_check_rate_margin(struct clk_hw *hw,1374			unsigned long rrate, unsigned long rate)1375{1376	unsigned long rate_margin = rate + PLL_RATE_MARGIN;1377 1378	if (rrate > rate_margin || rrate < rate) {1379		pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n",1380		       clk_hw_get_name(hw), rrate, rate, rate_margin);1381		return -EINVAL;1382	}1383 1384	return 0;1385}1386 1387static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate,1388						unsigned long prate)1389{1390	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1391	u32 l, alpha_width = pll_alpha_width(pll);1392	unsigned long rrate;1393	int ret;1394	u64 a;1395 1396	rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);1397 1398	ret = alpha_pll_check_rate_margin(hw, rrate, rate);1399	if (ret < 0)1400		return ret;1401 1402	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);1403	regmap_write(pll->clkr.regmap, PLL_FRAC(pll), a);1404 1405	return __clk_alpha_pll_update_latch(pll);1406}1407 1408static int alpha_pll_fabia_prepare(struct clk_hw *hw)1409{1410	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1411	const struct pll_vco *vco;1412	struct clk_hw *parent_hw;1413	unsigned long cal_freq, rrate;1414	u32 cal_l, val, alpha_width = pll_alpha_width(pll);1415	const char *name = clk_hw_get_name(hw);1416	u64 a;1417	int ret;1418 1419	/* Check if calibration needs to be done i.e. PLL is in reset */1420	ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);1421	if (ret)1422		return ret;1423 1424	/* Return early if calibration is not needed. */1425	if (val & PLL_RESET_N)1426		return 0;1427 1428	vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw));1429	if (!vco) {1430		pr_err("%s: alpha pll not in a valid vco range\n", name);1431		return -EINVAL;1432	}1433 1434	cal_freq = DIV_ROUND_CLOSEST((pll->vco_table[0].min_freq +1435				pll->vco_table[0].max_freq) * 54, 100);1436 1437	parent_hw = clk_hw_get_parent(hw);1438	if (!parent_hw)1439		return -EINVAL;1440 1441	rrate = alpha_pll_round_rate(cal_freq, clk_hw_get_rate(parent_hw),1442					&cal_l, &a, alpha_width);1443 1444	ret = alpha_pll_check_rate_margin(hw, rrate, cal_freq);1445	if (ret < 0)1446		return ret;1447 1448	/* Setup PLL for calibration frequency */1449	regmap_write(pll->clkr.regmap, PLL_CAL_L_VAL(pll), cal_l);1450 1451	/* Bringup the PLL at calibration frequency */1452	ret = clk_alpha_pll_enable(hw);1453	if (ret) {1454		pr_err("%s: alpha pll calibration failed\n", name);1455		return ret;1456	}1457 1458	clk_alpha_pll_disable(hw);1459 1460	return 0;1461}1462 1463const struct clk_ops clk_alpha_pll_fabia_ops = {1464	.prepare = alpha_pll_fabia_prepare,1465	.enable = alpha_pll_fabia_enable,1466	.disable = alpha_pll_fabia_disable,1467	.is_enabled = clk_alpha_pll_is_enabled,1468	.set_rate = alpha_pll_fabia_set_rate,1469	.recalc_rate = alpha_pll_fabia_recalc_rate,1470	.round_rate = clk_alpha_pll_round_rate,1471};1472EXPORT_SYMBOL_GPL(clk_alpha_pll_fabia_ops);1473 1474const struct clk_ops clk_alpha_pll_fixed_fabia_ops = {1475	.enable = alpha_pll_fabia_enable,1476	.disable = alpha_pll_fabia_disable,1477	.is_enabled = clk_alpha_pll_is_enabled,1478	.recalc_rate = alpha_pll_fabia_recalc_rate,1479	.round_rate = clk_alpha_pll_round_rate,1480};1481EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_fabia_ops);1482 1483static unsigned long clk_alpha_pll_postdiv_fabia_recalc_rate(struct clk_hw *hw,1484					unsigned long parent_rate)1485{1486	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);1487	u32 i, div = 1, val;1488	int ret;1489 1490	ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);1491	if (ret)1492		return ret;1493 1494	val >>= pll->post_div_shift;1495	val &= BIT(pll->width) - 1;1496 1497	for (i = 0; i < pll->num_post_div; i++) {1498		if (pll->post_div_table[i].val == val) {1499			div = pll->post_div_table[i].div;1500			break;1501		}1502	}1503 1504	return (parent_rate / div);1505}1506 1507static unsigned long1508clk_trion_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)1509{1510	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);1511	struct regmap *regmap = pll->clkr.regmap;1512	u32 i, div = 1, val;1513 1514	regmap_read(regmap, PLL_USER_CTL(pll), &val);1515 1516	val >>= pll->post_div_shift;1517	val &= PLL_POST_DIV_MASK(pll);1518 1519	for (i = 0; i < pll->num_post_div; i++) {1520		if (pll->post_div_table[i].val == val) {1521			div = pll->post_div_table[i].div;1522			break;1523		}1524	}1525 1526	return (parent_rate / div);1527}1528 1529static long1530clk_trion_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate,1531				 unsigned long *prate)1532{1533	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);1534 1535	return divider_round_rate(hw, rate, prate, pll->post_div_table,1536				  pll->width, CLK_DIVIDER_ROUND_CLOSEST);1537};1538 1539static int1540clk_trion_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,1541			       unsigned long parent_rate)1542{1543	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);1544	struct regmap *regmap = pll->clkr.regmap;1545	int i, val = 0, div;1546 1547	div = DIV_ROUND_UP_ULL(parent_rate, rate);1548	for (i = 0; i < pll->num_post_div; i++) {1549		if (pll->post_div_table[i].div == div) {1550			val = pll->post_div_table[i].val;1551			break;1552		}1553	}1554 1555	return regmap_update_bits(regmap, PLL_USER_CTL(pll),1556				  PLL_POST_DIV_MASK(pll) << pll->post_div_shift,1557				  val << pll->post_div_shift);1558}1559 1560const struct clk_ops clk_alpha_pll_postdiv_trion_ops = {1561	.recalc_rate = clk_trion_pll_postdiv_recalc_rate,1562	.round_rate = clk_trion_pll_postdiv_round_rate,1563	.set_rate = clk_trion_pll_postdiv_set_rate,1564};1565EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_trion_ops);1566 1567static long clk_alpha_pll_postdiv_fabia_round_rate(struct clk_hw *hw,1568				unsigned long rate, unsigned long *prate)1569{1570	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);1571 1572	return divider_round_rate(hw, rate, prate, pll->post_div_table,1573				pll->width, CLK_DIVIDER_ROUND_CLOSEST);1574}1575 1576static int clk_alpha_pll_postdiv_fabia_set_rate(struct clk_hw *hw,1577				unsigned long rate, unsigned long parent_rate)1578{1579	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);1580	int i, val = 0, div, ret;1581 1582	/*1583	 * If the PLL is in FSM mode, then treat set_rate callback as a1584	 * no-operation.1585	 */1586	ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);1587	if (ret)1588		return ret;1589 1590	if (val & PLL_VOTE_FSM_ENA)1591		return 0;1592 1593	div = DIV_ROUND_UP_ULL(parent_rate, rate);1594	for (i = 0; i < pll->num_post_div; i++) {1595		if (pll->post_div_table[i].div == div) {1596			val = pll->post_div_table[i].val;1597			break;1598		}1599	}1600 1601	return regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),1602				(BIT(pll->width) - 1) << pll->post_div_shift,1603				val << pll->post_div_shift);1604}1605 1606const struct clk_ops clk_alpha_pll_postdiv_fabia_ops = {1607	.recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate,1608	.round_rate = clk_alpha_pll_postdiv_fabia_round_rate,1609	.set_rate = clk_alpha_pll_postdiv_fabia_set_rate,1610};1611EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_fabia_ops);1612 1613/**1614 * clk_trion_pll_configure - configure the trion pll1615 *1616 * @pll: clk alpha pll1617 * @regmap: register map1618 * @config: configuration to apply for pll1619 */1620void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,1621			     const struct alpha_pll_config *config)1622{1623	/*1624	 * If the bootloader left the PLL enabled it's likely that there are1625	 * RCGs that will lock up if we disable the PLL below.1626	 */1627	if (trion_pll_is_enabled(pll, regmap)) {1628		pr_debug("Trion PLL is already enabled, skipping configuration\n");1629		return;1630	}1631 1632	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);1633	regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL);1634	clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);1635	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),1636				     config->config_ctl_val);1637	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),1638				     config->config_ctl_hi_val);1639	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll),1640				     config->config_ctl_hi1_val);1641	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),1642					config->user_ctl_val);1643	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll),1644					config->user_ctl_hi_val);1645	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U1(pll),1646					config->user_ctl_hi1_val);1647	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),1648					config->test_ctl_val);1649	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),1650					config->test_ctl_hi_val);1651	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll),1652					config->test_ctl_hi1_val);1653 1654	regmap_update_bits(regmap, PLL_MODE(pll), PLL_UPDATE_BYPASS,1655			   PLL_UPDATE_BYPASS);1656 1657	/* Disable PLL output */1658	regmap_update_bits(regmap, PLL_MODE(pll),  PLL_OUTCTRL, 0);1659 1660	/* Set operation mode to OFF */1661	regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);1662 1663	/* Place the PLL in STANDBY mode */1664	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);1665}1666EXPORT_SYMBOL_GPL(clk_trion_pll_configure);1667 1668/*1669 * The TRION PLL requires a power-on self-calibration which happens when the1670 * PLL comes out of reset. Calibrate in case it is not completed.1671 */1672static int __alpha_pll_trion_prepare(struct clk_hw *hw, u32 pcal_done)1673{1674	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1675	u32 val;1676	int ret;1677 1678	/* Return early if calibration is not needed. */1679	regmap_read(pll->clkr.regmap, PLL_STATUS(pll), &val);1680	if (val & pcal_done)1681		return 0;1682 1683	/* On/off to calibrate */1684	ret = clk_trion_pll_enable(hw);1685	if (!ret)1686		clk_trion_pll_disable(hw);1687 1688	return ret;1689}1690 1691static int alpha_pll_trion_prepare(struct clk_hw *hw)1692{1693	return __alpha_pll_trion_prepare(hw, TRION_PCAL_DONE);1694}1695 1696static int alpha_pll_lucid_prepare(struct clk_hw *hw)1697{1698	return __alpha_pll_trion_prepare(hw, LUCID_PCAL_DONE);1699}1700 1701static int __alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,1702				      unsigned long prate, u32 latch_bit, u32 latch_ack)1703{1704	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1705	unsigned long rrate;1706	u32 val, l, alpha_width = pll_alpha_width(pll);1707	u64 a;1708	int ret;1709 1710	rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);1711 1712	ret = alpha_pll_check_rate_margin(hw, rrate, rate);1713	if (ret < 0)1714		return ret;1715 1716	regmap_update_bits(pll->clkr.regmap, PLL_L_VAL(pll), LUCID_EVO_PLL_L_VAL_MASK,  l);1717	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);1718 1719	/* Latch the PLL input */1720	ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), latch_bit, latch_bit);1721	if (ret)1722		return ret;1723 1724	/* Wait for 2 reference cycles before checking the ACK bit. */1725	udelay(1);1726	regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);1727	if (!(val & latch_ack)) {1728		pr_err("Lucid PLL latch failed. Output may be unstable!\n");1729		return -EINVAL;1730	}1731 1732	/* Return the latch input to 0 */1733	ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), latch_bit, 0);1734	if (ret)1735		return ret;1736 1737	if (clk_hw_is_enabled(hw)) {1738		ret = wait_for_pll_enable_lock(pll);1739		if (ret)1740			return ret;1741	}1742 1743	/* Wait for PLL output to stabilize */1744	udelay(100);1745	return 0;1746}1747 1748static int alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,1749				    unsigned long prate)1750{1751	return __alpha_pll_trion_set_rate(hw, rate, prate, PLL_UPDATE, ALPHA_PLL_ACK_LATCH);1752}1753 1754const struct clk_ops clk_alpha_pll_trion_ops = {1755	.prepare = alpha_pll_trion_prepare,1756	.enable = clk_trion_pll_enable,1757	.disable = clk_trion_pll_disable,1758	.is_enabled = clk_trion_pll_is_enabled,1759	.recalc_rate = clk_trion_pll_recalc_rate,1760	.round_rate = clk_alpha_pll_round_rate,1761	.set_rate = alpha_pll_trion_set_rate,1762};1763EXPORT_SYMBOL_GPL(clk_alpha_pll_trion_ops);1764 1765const struct clk_ops clk_alpha_pll_lucid_ops = {1766	.prepare = alpha_pll_lucid_prepare,1767	.enable = clk_trion_pll_enable,1768	.disable = clk_trion_pll_disable,1769	.is_enabled = clk_trion_pll_is_enabled,1770	.recalc_rate = clk_trion_pll_recalc_rate,1771	.round_rate = clk_alpha_pll_round_rate,1772	.set_rate = alpha_pll_trion_set_rate,1773};1774EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_ops);1775 1776const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = {1777	.recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate,1778	.round_rate = clk_alpha_pll_postdiv_fabia_round_rate,1779	.set_rate = clk_alpha_pll_postdiv_fabia_set_rate,1780};1781EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_ops);1782 1783void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,1784			const struct alpha_pll_config *config)1785{1786	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);1787	clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);1788	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),1789							config->user_ctl_val);1790	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),1791						config->config_ctl_val);1792	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),1793						config->config_ctl_hi_val);1794	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),1795						config->test_ctl_val);1796	clk_alpha_pll_write_config(regmap,  PLL_TEST_CTL_U(pll),1797						config->test_ctl_hi_val);1798}1799EXPORT_SYMBOL_GPL(clk_agera_pll_configure);1800 1801static int clk_alpha_pll_agera_set_rate(struct clk_hw *hw, unsigned long rate,1802							unsigned long prate)1803{1804	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1805	u32 l, alpha_width = pll_alpha_width(pll);1806	int ret;1807	unsigned long rrate;1808	u64 a;1809 1810	rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);1811	ret = alpha_pll_check_rate_margin(hw, rrate, rate);1812	if (ret < 0)1813		return ret;1814 1815	/* change L_VAL without having to go through the power on sequence */1816	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);1817	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);1818 1819	if (clk_hw_is_enabled(hw))1820		return wait_for_pll_enable_lock(pll);1821 1822	return 0;1823}1824 1825const struct clk_ops clk_alpha_pll_agera_ops = {1826	.enable = clk_alpha_pll_enable,1827	.disable = clk_alpha_pll_disable,1828	.is_enabled = clk_alpha_pll_is_enabled,1829	.recalc_rate = alpha_pll_fabia_recalc_rate,1830	.round_rate = clk_alpha_pll_round_rate,1831	.set_rate = clk_alpha_pll_agera_set_rate,1832};1833EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops);1834 1835/**1836 * clk_lucid_5lpe_pll_configure - configure the lucid 5lpe pll1837 *1838 * @pll: clk alpha pll1839 * @regmap: register map1840 * @config: configuration to apply for pll1841 */1842void clk_lucid_5lpe_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,1843				  const struct alpha_pll_config *config)1844{1845	/*1846	 * If the bootloader left the PLL enabled it's likely that there are1847	 * RCGs that will lock up if we disable the PLL below.1848	 */1849	if (trion_pll_is_enabled(pll, regmap)) {1850		pr_debug("Lucid 5LPE PLL is already enabled, skipping configuration\n");1851		return;1852	}1853 1854	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);1855	regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL);1856	clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);1857	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),1858				     config->config_ctl_val);1859	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),1860				     config->config_ctl_hi_val);1861	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll),1862				     config->config_ctl_hi1_val);1863	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),1864					config->user_ctl_val);1865	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll),1866					config->user_ctl_hi_val);1867	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U1(pll),1868					config->user_ctl_hi1_val);1869	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),1870					config->test_ctl_val);1871	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),1872					config->test_ctl_hi_val);1873	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll),1874					config->test_ctl_hi1_val);1875 1876	/* Disable PLL output */1877	regmap_update_bits(regmap, PLL_MODE(pll),  PLL_OUTCTRL, 0);1878 1879	/* Set operation mode to OFF */1880	regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);1881 1882	/* Place the PLL in STANDBY mode */1883	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);1884}1885EXPORT_SYMBOL_GPL(clk_lucid_5lpe_pll_configure);1886 1887static int alpha_pll_lucid_5lpe_enable(struct clk_hw *hw)1888{1889	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1890	u32 val;1891	int ret;1892 1893	ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);1894	if (ret)1895		return ret;1896 1897	/* If in FSM mode, just vote for it */1898	if (val & LUCID_5LPE_ENABLE_VOTE_RUN) {1899		ret = clk_enable_regmap(hw);1900		if (ret)1901			return ret;1902		return wait_for_pll_enable_lock(pll);1903	}1904 1905	/* Check if PLL is already enabled, return if enabled */1906	ret = trion_pll_is_enabled(pll, pll->clkr.regmap);1907	if (ret < 0)1908		return ret;1909 1910	ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);1911	if (ret)1912		return ret;1913 1914	regmap_write(pll->clkr.regmap, PLL_OPMODE(pll), PLL_RUN);1915 1916	ret = wait_for_pll_enable_lock(pll);1917	if (ret)1918		return ret;1919 1920	/* Enable the PLL outputs */1921	ret = regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, PLL_OUT_MASK);1922	if (ret)1923		return ret;1924 1925	/* Enable the global PLL outputs */1926	return regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);1927}1928 1929static void alpha_pll_lucid_5lpe_disable(struct clk_hw *hw)1930{1931	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1932	u32 val;1933	int ret;1934 1935	ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);1936	if (ret)1937		return;1938 1939	/* If in FSM mode, just unvote it */1940	if (val & LUCID_5LPE_ENABLE_VOTE_RUN) {1941		clk_disable_regmap(hw);1942		return;1943	}1944 1945	/* Disable the global PLL output */1946	ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);1947	if (ret)1948		return;1949 1950	/* Disable the PLL outputs */1951	ret = regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, 0);1952	if (ret)1953		return;1954 1955	/* Place the PLL mode in STANDBY */1956	regmap_write(pll->clkr.regmap, PLL_OPMODE(pll), PLL_STANDBY);1957}1958 1959/*1960 * The Lucid 5LPE PLL requires a power-on self-calibration which happens1961 * when the PLL comes out of reset. Calibrate in case it is not completed.1962 */1963static int alpha_pll_lucid_5lpe_prepare(struct clk_hw *hw)1964{1965	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);1966	struct clk_hw *p;1967	u32 val = 0;1968	int ret;1969 1970	/* Return early if calibration is not needed. */1971	regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);1972	if (val & LUCID_5LPE_PCAL_DONE)1973		return 0;1974 1975	p = clk_hw_get_parent(hw);1976	if (!p)1977		return -EINVAL;1978 1979	ret = alpha_pll_lucid_5lpe_enable(hw);1980	if (ret)1981		return ret;1982 1983	alpha_pll_lucid_5lpe_disable(hw);1984 1985	return 0;1986}1987 1988static int alpha_pll_lucid_5lpe_set_rate(struct clk_hw *hw, unsigned long rate,1989					 unsigned long prate)1990{1991	return __alpha_pll_trion_set_rate(hw, rate, prate,1992					  LUCID_5LPE_PLL_LATCH_INPUT,1993					  LUCID_5LPE_ALPHA_PLL_ACK_LATCH);1994}1995 1996static int __clk_lucid_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,1997					    unsigned long parent_rate,1998					    unsigned long enable_vote_run)1999{2000	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);2001	struct regmap *regmap = pll->clkr.regmap;2002	int i, val, div, ret;2003	u32 mask;2004 2005	/*2006	 * If the PLL is in FSM mode, then treat set_rate callback as a2007	 * no-operation.2008	 */2009	ret = regmap_read(regmap, PLL_USER_CTL(pll), &val);2010	if (ret)2011		return ret;2012 2013	if (val & enable_vote_run)2014		return 0;2015 2016	if (!pll->post_div_table) {2017		pr_err("Missing the post_div_table for the %s PLL\n",2018		       clk_hw_get_name(&pll->clkr.hw));2019		return -EINVAL;2020	}2021 2022	div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);2023	for (i = 0; i < pll->num_post_div; i++) {2024		if (pll->post_div_table[i].div == div) {2025			val = pll->post_div_table[i].val;2026			break;2027		}2028	}2029 2030	mask = GENMASK(pll->width + pll->post_div_shift - 1, pll->post_div_shift);2031	return regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),2032				  mask, val << pll->post_div_shift);2033}2034 2035static int clk_lucid_5lpe_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,2036					       unsigned long parent_rate)2037{2038	return __clk_lucid_pll_postdiv_set_rate(hw, rate, parent_rate, LUCID_5LPE_ENABLE_VOTE_RUN);2039}2040 2041const struct clk_ops clk_alpha_pll_lucid_5lpe_ops = {2042	.prepare = alpha_pll_lucid_5lpe_prepare,2043	.enable = alpha_pll_lucid_5lpe_enable,2044	.disable = alpha_pll_lucid_5lpe_disable,2045	.is_enabled = clk_trion_pll_is_enabled,2046	.recalc_rate = clk_trion_pll_recalc_rate,2047	.round_rate = clk_alpha_pll_round_rate,2048	.set_rate = alpha_pll_lucid_5lpe_set_rate,2049};2050EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_5lpe_ops);2051 2052const struct clk_ops clk_alpha_pll_fixed_lucid_5lpe_ops = {2053	.enable = alpha_pll_lucid_5lpe_enable,2054	.disable = alpha_pll_lucid_5lpe_disable,2055	.is_enabled = clk_trion_pll_is_enabled,2056	.recalc_rate = clk_trion_pll_recalc_rate,2057	.round_rate = clk_alpha_pll_round_rate,2058};2059EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_lucid_5lpe_ops);2060 2061const struct clk_ops clk_alpha_pll_postdiv_lucid_5lpe_ops = {2062	.recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate,2063	.round_rate = clk_alpha_pll_postdiv_fabia_round_rate,2064	.set_rate = clk_lucid_5lpe_pll_postdiv_set_rate,2065};2066EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_5lpe_ops);2067 2068void clk_zonda_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,2069			     const struct alpha_pll_config *config)2070{2071	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);2072	clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);2073	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);2074	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);2075	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);2076	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);2077	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val);2078	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U1(pll), config->user_ctl_hi1_val);2079	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);2080	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);2081	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);2082 2083	regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, 0);2084 2085	/* Disable PLL output */2086	regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);2087 2088	/* Set operation mode to OFF */2089	regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);2090 2091	/* Place the PLL in STANDBY mode */2092	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);2093}2094EXPORT_SYMBOL_GPL(clk_zonda_pll_configure);2095 2096static int clk_zonda_pll_enable(struct clk_hw *hw)2097{2098	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);2099	struct regmap *regmap = pll->clkr.regmap;2100	u32 val;2101	int ret;2102 2103	regmap_read(regmap, PLL_MODE(pll), &val);2104 2105	/* If in FSM mode, just vote for it */2106	if (val & PLL_VOTE_FSM_ENA) {2107		ret = clk_enable_regmap(hw);2108		if (ret)2109			return ret;2110		return wait_for_pll_enable_active(pll);2111	}2112 2113	/* Get the PLL out of bypass mode */2114	regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL);2115 2116	/*2117	 * H/W requires a 1us delay between disabling the bypass and2118	 * de-asserting the reset.2119	 */2120	udelay(1);2121 2122	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);2123 2124	/* Set operation mode to RUN */2125	regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN);2126 2127	regmap_read(regmap, PLL_TEST_CTL(pll), &val);2128 2129	/* If cfa mode then poll for freq lock */2130	if (val & ZONDA_STAY_IN_CFA)2131		ret = wait_for_zonda_pll_freq_lock(pll);2132	else2133		ret = wait_for_pll_enable_lock(pll);2134	if (ret)2135		return ret;2136 2137	/* Enable the PLL outputs */2138	regmap_update_bits(regmap, PLL_USER_CTL(pll), ZONDA_PLL_OUT_MASK, ZONDA_PLL_OUT_MASK);2139 2140	/* Enable the global PLL outputs */2141	regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);2142 2143	return 0;2144}2145 2146static void clk_zonda_pll_disable(struct clk_hw *hw)2147{2148	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);2149	struct regmap *regmap = pll->clkr.regmap;2150	u32 val;2151 2152	regmap_read(regmap, PLL_MODE(pll), &val);2153 2154	/* If in FSM mode, just unvote it */2155	if (val & PLL_VOTE_FSM_ENA) {2156		clk_disable_regmap(hw);2157		return;2158	}2159 2160	/* Disable the global PLL output */2161	regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);2162 2163	/* Disable the PLL outputs */2164	regmap_update_bits(regmap, PLL_USER_CTL(pll), ZONDA_PLL_OUT_MASK, 0);2165 2166	/* Put the PLL in bypass and reset */2167	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N | PLL_BYPASSNL, 0);2168 2169	/* Place the PLL mode in OFF state */2170	regmap_write(regmap, PLL_OPMODE(pll), 0x0);2171}2172 2173static void zonda_pll_adjust_l_val(unsigned long rate, unsigned long prate, u32 *l)2174{2175	u64 remainder, quotient;2176 2177	quotient = rate;2178	remainder = do_div(quotient, prate);2179 2180	*l = rate + (u32)(remainder * 2 >= prate);2181}2182 2183static int clk_zonda_pll_set_rate(struct clk_hw *hw, unsigned long rate,2184				  unsigned long prate)2185{2186	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);2187	unsigned long rrate;2188	u32 test_ctl_val;2189	u32 l, alpha_width = pll_alpha_width(pll);2190	u64 a;2191	int ret;2192 2193	rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);2194 2195	ret = alpha_pll_check_rate_margin(hw, rrate, rate);2196	if (ret < 0)2197		return ret;2198 2199	if (a & PLL_ALPHA_MSB)2200		zonda_pll_adjust_l_val(rate, prate, &l);2201 2202	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);2203	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);2204 2205	if (!clk_hw_is_enabled(hw))2206		return 0;2207 2208	/* Wait before polling for the frequency latch */2209	udelay(5);2210 2211	/* Read stay in cfa mode */2212	regmap_read(pll->clkr.regmap, PLL_TEST_CTL(pll), &test_ctl_val);2213 2214	/* If cfa mode then poll for freq lock */2215	if (test_ctl_val & ZONDA_STAY_IN_CFA)2216		ret = wait_for_zonda_pll_freq_lock(pll);2217	else2218		ret = wait_for_pll_enable_lock(pll);2219	if (ret)2220		return ret;2221 2222	/* Wait for PLL output to stabilize */2223	udelay(100);2224	return 0;2225}2226 2227const struct clk_ops clk_alpha_pll_zonda_ops = {2228	.enable = clk_zonda_pll_enable,2229	.disable = clk_zonda_pll_disable,2230	.is_enabled = clk_trion_pll_is_enabled,2231	.recalc_rate = clk_trion_pll_recalc_rate,2232	.round_rate = clk_alpha_pll_round_rate,2233	.set_rate = clk_zonda_pll_set_rate,2234};2235EXPORT_SYMBOL_GPL(clk_alpha_pll_zonda_ops);2236 2237void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,2238				 const struct alpha_pll_config *config)2239{2240	u32 lval = config->l;2241 2242	/*2243	 * If the bootloader left the PLL enabled it's likely that there are2244	 * RCGs that will lock up if we disable the PLL below.2245	 */2246	if (trion_pll_is_enabled(pll, regmap)) {2247		pr_debug("Lucid Evo PLL is already enabled, skipping configuration\n");2248		return;2249	}2250 2251	lval |= TRION_PLL_CAL_VAL << LUCID_EVO_PLL_CAL_L_VAL_SHIFT;2252	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), lval);2253	clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);2254	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);2255	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);2256	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);2257	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);2258	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val);2259	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);2260	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);2261	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);2262	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U2(pll), config->test_ctl_hi2_val);2263 2264	/* Disable PLL output */2265	regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);2266 2267	/* Set operation mode to STANDBY and de-assert the reset */2268	regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);2269	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);2270}2271EXPORT_SYMBOL_GPL(clk_lucid_evo_pll_configure);2272 2273void clk_lucid_ole_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,2274				 const struct alpha_pll_config *config)2275{2276	u32 lval = config->l;2277 2278	lval |= TRION_PLL_CAL_VAL << LUCID_EVO_PLL_CAL_L_VAL_SHIFT;2279	lval |= TRION_PLL_CAL_VAL << LUCID_OLE_PLL_RINGOSC_CAL_L_VAL_SHIFT;2280	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), lval);2281	clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);2282	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);2283	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);2284	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);2285	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);2286	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val);2287	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);2288	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);2289	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);2290	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U2(pll), config->test_ctl_hi2_val);2291 2292	/* Disable PLL output */2293	regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);2294 2295	/* Set operation mode to STANDBY and de-assert the reset */2296	regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);2297	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);2298}2299EXPORT_SYMBOL_GPL(clk_lucid_ole_pll_configure);2300 2301static int alpha_pll_lucid_evo_enable(struct clk_hw *hw)2302{2303	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);2304	struct regmap *regmap = pll->clkr.regmap;2305	u32 val;2306	int ret;2307 2308	ret = regmap_read(regmap, PLL_USER_CTL(pll), &val);2309	if (ret)2310		return ret;2311 2312	/* If in FSM mode, just vote for it */2313	if (val & LUCID_EVO_ENABLE_VOTE_RUN) {2314		ret = clk_enable_regmap(hw);2315		if (ret)2316			return ret;2317		return wait_for_pll_enable_lock(pll);2318	}2319 2320	/* Check if PLL is already enabled */2321	ret = trion_pll_is_enabled(pll, regmap);2322	if (ret < 0) {2323		return ret;2324	} else if (ret) {2325		pr_warn("%s PLL is already enabled\n", clk_hw_get_name(&pll->clkr.hw));2326		return 0;2327	}2328 2329	ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);2330	if (ret)2331		return ret;2332 2333	/* Set operation mode to RUN */2334	regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN);2335 2336	ret = wait_for_pll_enable_lock(pll);2337	if (ret)2338		return ret;2339 2340	/* Enable the PLL outputs */2341	ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, PLL_OUT_MASK);2342	if (ret)2343		return ret;2344 2345	/* Enable the global PLL outputs */2346	ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);2347	if (ret)2348		return ret;2349 2350	/* Ensure that the write above goes through before returning. */2351	mb();2352	return ret;2353}2354 2355static void _alpha_pll_lucid_evo_disable(struct clk_hw *hw, bool reset)2356{2357	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);2358	struct regmap *regmap = pll->clkr.regmap;2359	u32 val;2360	int ret;2361 2362	ret = regmap_read(regmap, PLL_USER_CTL(pll), &val);2363	if (ret)2364		return;2365 2366	/* If in FSM mode, just unvote it */2367	if (val & LUCID_EVO_ENABLE_VOTE_RUN) {2368		clk_disable_regmap(hw);2369		return;2370	}2371 2372	/* Disable the global PLL output */2373	ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);2374	if (ret)2375		return;2376 2377	/* Disable the PLL outputs */2378	ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, 0);2379	if (ret)2380		return;2381 2382	/* Place the PLL mode in STANDBY */2383	regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);2384 2385	if (reset)2386		regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, 0);2387}2388 2389static int _alpha_pll_lucid_evo_prepare(struct clk_hw *hw, bool reset)2390{2391	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);2392	struct clk_hw *p;2393	u32 val = 0;2394	int ret;2395 2396	/* Return early if calibration is not needed. */2397	regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);2398	if (!(val & LUCID_EVO_PCAL_NOT_DONE))2399		return 0;2400 2401	p = clk_hw_get_parent(hw);2402	if (!p)2403		return -EINVAL;2404 2405	ret = alpha_pll_lucid_evo_enable(hw);2406	if (ret)2407		return ret;2408 2409	_alpha_pll_lucid_evo_disable(hw, reset);2410 2411	return 0;2412}2413 2414static void alpha_pll_lucid_evo_disable(struct clk_hw *hw)2415{2416	_alpha_pll_lucid_evo_disable(hw, false);2417}2418 2419static int alpha_pll_lucid_evo_prepare(struct clk_hw *hw)2420{2421	return _alpha_pll_lucid_evo_prepare(hw, false);2422}2423 2424static void alpha_pll_reset_lucid_evo_disable(struct clk_hw *hw)2425{2426	_alpha_pll_lucid_evo_disable(hw, true);2427}2428 2429static int alpha_pll_reset_lucid_evo_prepare(struct clk_hw *hw)2430{2431	return _alpha_pll_lucid_evo_prepare(hw, true);2432}2433 2434static unsigned long alpha_pll_lucid_evo_recalc_rate(struct clk_hw *hw,2435						     unsigned long parent_rate)2436{2437	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);2438	struct regmap *regmap = pll->clkr.regmap;2439	u32 l, frac;2440 2441	regmap_read(regmap, PLL_L_VAL(pll), &l);2442	l &= LUCID_EVO_PLL_L_VAL_MASK;2443	regmap_read(regmap, PLL_ALPHA_VAL(pll), &frac);2444 2445	return alpha_pll_calc_rate(parent_rate, l, frac, pll_alpha_width(pll));2446}2447 2448static int clk_lucid_evo_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,2449					      unsigned long parent_rate)2450{2451	return __clk_lucid_pll_postdiv_set_rate(hw, rate, parent_rate, LUCID_EVO_ENABLE_VOTE_RUN);2452}2453 2454const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops = {2455	.enable = alpha_pll_lucid_evo_enable,2456	.disable = alpha_pll_lucid_evo_disable,2457	.is_enabled = clk_trion_pll_is_enabled,2458	.recalc_rate = alpha_pll_lucid_evo_recalc_rate,2459	.round_rate = clk_alpha_pll_round_rate,2460};2461EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_lucid_evo_ops);2462 2463const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops = {2464	.recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate,2465	.round_rate = clk_alpha_pll_postdiv_fabia_round_rate,2466	.set_rate = clk_lucid_evo_pll_postdiv_set_rate,2467};2468EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_evo_ops);2469 2470const struct clk_ops clk_alpha_pll_lucid_evo_ops = {2471	.prepare = alpha_pll_lucid_evo_prepare,2472	.enable = alpha_pll_lucid_evo_enable,2473	.disable = alpha_pll_lucid_evo_disable,2474	.is_enabled = clk_trion_pll_is_enabled,2475	.recalc_rate = alpha_pll_lucid_evo_recalc_rate,2476	.round_rate = clk_alpha_pll_round_rate,2477	.set_rate = alpha_pll_lucid_5lpe_set_rate,2478};2479EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_evo_ops);2480 2481const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops = {2482	.prepare = alpha_pll_reset_lucid_evo_prepare,2483	.enable = alpha_pll_lucid_evo_enable,2484	.disable = alpha_pll_reset_lucid_evo_disable,2485	.is_enabled = clk_trion_pll_is_enabled,2486	.recalc_rate = alpha_pll_lucid_evo_recalc_rate,2487	.round_rate = clk_alpha_pll_round_rate,2488	.set_rate = alpha_pll_lucid_5lpe_set_rate,2489};2490EXPORT_SYMBOL_GPL(clk_alpha_pll_reset_lucid_evo_ops);2491 2492void clk_rivian_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,2493				  const struct alpha_pll_config *config)2494{2495	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);2496	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);2497	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);2498	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);2499	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);2500	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);2501	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);2502	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val);2503 2504	regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);2505 2506	regmap_update_bits(regmap, PLL_MODE(pll),2507			   PLL_RESET_N | PLL_BYPASSNL | PLL_OUTCTRL,2508			   PLL_RESET_N | PLL_BYPASSNL);2509}2510EXPORT_SYMBOL_GPL(clk_rivian_evo_pll_configure);2511 2512static unsigned long clk_rivian_evo_pll_recalc_rate(struct clk_hw *hw,2513						    unsigned long parent_rate)2514{2515	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);2516	u32 l;2517 2518	regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l);2519 2520	return parent_rate * l;2521}2522 2523static long clk_rivian_evo_pll_round_rate(struct clk_hw *hw, unsigned long rate,2524					  unsigned long *prate)2525{2526	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);2527	unsigned long min_freq, max_freq;2528	u32 l;2529	u64 a;2530 2531	rate = alpha_pll_round_rate(rate, *prate, &l, &a, 0);2532	if (!pll->vco_table || alpha_pll_find_vco(pll, rate))2533		return rate;2534 2535	min_freq = pll->vco_table[0].min_freq;2536	max_freq = pll->vco_table[pll->num_vco - 1].max_freq;2537 2538	return clamp(rate, min_freq, max_freq);2539}2540 2541const struct clk_ops clk_alpha_pll_rivian_evo_ops = {2542	.enable = alpha_pll_lucid_5lpe_enable,2543	.disable = alpha_pll_lucid_5lpe_disable,2544	.is_enabled = clk_trion_pll_is_enabled,2545	.recalc_rate = clk_rivian_evo_pll_recalc_rate,2546	.round_rate = clk_rivian_evo_pll_round_rate,2547};2548EXPORT_SYMBOL_GPL(clk_alpha_pll_rivian_evo_ops);2549 2550void clk_stromer_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,2551			       const struct alpha_pll_config *config)2552{2553	u32 val, val_u, mask, mask_u;2554 2555	regmap_write(regmap, PLL_L_VAL(pll), config->l);2556	regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha);2557	regmap_write(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);2558 2559	if (pll_has_64bit_config(pll))2560		regmap_write(regmap, PLL_CONFIG_CTL_U(pll),2561			     config->config_ctl_hi_val);2562 2563	if (pll_alpha_width(pll) > 32)2564		regmap_write(regmap, PLL_ALPHA_VAL_U(pll), config->alpha_hi);2565 2566	val = config->main_output_mask;2567	val |= config->aux_output_mask;2568	val |= config->aux2_output_mask;2569	val |= config->early_output_mask;2570	val |= config->pre_div_val;2571	val |= config->post_div_val;2572	val |= config->vco_val;2573	val |= config->alpha_en_mask;2574	val |= config->alpha_mode_mask;2575 2576	mask = config->main_output_mask;2577	mask |= config->aux_output_mask;2578	mask |= config->aux2_output_mask;2579	mask |= config->early_output_mask;2580	mask |= config->pre_div_mask;2581	mask |= config->post_div_mask;2582	mask |= config->vco_mask;2583	mask |= config->alpha_en_mask;2584	mask |= config->alpha_mode_mask;2585 2586	regmap_update_bits(regmap, PLL_USER_CTL(pll), mask, val);2587 2588	/* Stromer APSS PLL does not enable LOCK_DET by default, so enable it */2589	val_u = config->status_val << ALPHA_PLL_STATUS_REG_SHIFT;2590	val_u |= config->lock_det;2591 2592	mask_u = config->status_mask;2593	mask_u |= config->lock_det;2594 2595	regmap_update_bits(regmap, PLL_USER_CTL_U(pll), mask_u, val_u);2596	regmap_write(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);2597	regmap_write(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);2598 2599	if (pll->flags & SUPPORTS_FSM_MODE)2600		qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0);2601}2602EXPORT_SYMBOL_GPL(clk_stromer_pll_configure);2603 2604static int clk_alpha_pll_stromer_determine_rate(struct clk_hw *hw,2605						struct clk_rate_request *req)2606{2607	u32 l;2608	u64 a;2609 2610	req->rate = alpha_pll_round_rate(req->rate, req->best_parent_rate,2611					 &l, &a, ALPHA_REG_BITWIDTH);2612 2613	return 0;2614}2615 2616static int clk_alpha_pll_stromer_set_rate(struct clk_hw *hw, unsigned long rate,2617					  unsigned long prate)2618{2619	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);2620	int ret;2621	u32 l;2622	u64 a;2623 2624	rate = alpha_pll_round_rate(rate, prate, &l, &a, ALPHA_REG_BITWIDTH);2625 2626	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);2627 2628	a <<= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH;2629	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);2630	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll),2631		     a >> ALPHA_BITWIDTH);2632 2633	regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),2634			   PLL_ALPHA_EN, PLL_ALPHA_EN);2635 2636	if (!clk_hw_is_enabled(hw))2637		return 0;2638 2639	/*2640	 * Stromer PLL supports Dynamic programming.2641	 * It allows the PLL frequency to be changed on-the-fly without first2642	 * execution of a shutdown procedure followed by a bring up procedure.2643	 */2644	regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_UPDATE,2645			   PLL_UPDATE);2646 2647	ret = wait_for_pll_update(pll);2648	if (ret)2649		return ret;2650 2651	return wait_for_pll_enable_lock(pll);2652}2653 2654const struct clk_ops clk_alpha_pll_stromer_ops = {2655	.enable = clk_alpha_pll_enable,2656	.disable = clk_alpha_pll_disable,2657	.is_enabled = clk_alpha_pll_is_enabled,2658	.recalc_rate = clk_alpha_pll_recalc_rate,2659	.determine_rate = clk_alpha_pll_stromer_determine_rate,2660	.set_rate = clk_alpha_pll_stromer_set_rate,2661};2662EXPORT_SYMBOL_GPL(clk_alpha_pll_stromer_ops);2663 2664static int clk_alpha_pll_stromer_plus_set_rate(struct clk_hw *hw,2665					       unsigned long rate,2666					       unsigned long prate)2667{2668	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);2669	u32 l, alpha_width = pll_alpha_width(pll);2670	int ret, pll_mode;2671	u64 a;2672 2673	rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);2674 2675	ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &pll_mode);2676	if (ret)2677		return ret;2678 2679	regmap_write(pll->clkr.regmap, PLL_MODE(pll), 0);2680 2681	/* Delay of 2 output clock ticks required until output is disabled */2682	udelay(1);2683 2684	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);2685 2686	if (alpha_width > ALPHA_BITWIDTH)2687		a <<= alpha_width - ALPHA_BITWIDTH;2688 2689	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);2690	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll),2691					a >> ALPHA_BITWIDTH);2692 2693	regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),2694			   PLL_ALPHA_EN, PLL_ALPHA_EN);2695 2696	regmap_write(pll->clkr.regmap, PLL_MODE(pll), PLL_BYPASSNL);2697 2698	/* Wait five micro seconds or more */2699	udelay(5);2700	regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_RESET_N,2701			   PLL_RESET_N);2702 2703	/* The lock time should be less than 50 micro seconds worst case */2704	usleep_range(50, 60);2705 2706	ret = wait_for_pll_enable_lock(pll);2707	if (ret) {2708		pr_err("Wait for PLL enable lock failed [%s] %d\n",2709		       clk_hw_get_name(hw), ret);2710		return ret;2711	}2712 2713	if (pll_mode & PLL_OUTCTRL)2714		regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_OUTCTRL,2715				   PLL_OUTCTRL);2716 2717	return 0;2718}2719 2720const struct clk_ops clk_alpha_pll_stromer_plus_ops = {2721	.prepare = clk_alpha_pll_enable,2722	.unprepare = clk_alpha_pll_disable,2723	.is_enabled = clk_alpha_pll_is_enabled,2724	.recalc_rate = clk_alpha_pll_recalc_rate,2725	.determine_rate = clk_alpha_pll_stromer_determine_rate,2726	.set_rate = clk_alpha_pll_stromer_plus_set_rate,2727};2728EXPORT_SYMBOL_GPL(clk_alpha_pll_stromer_plus_ops);2729 2730void clk_regera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,2731			     const struct alpha_pll_config *config)2732{2733	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);2734	clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);2735	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);2736	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);2737	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);2738	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);2739	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val);2740	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U1(pll), config->user_ctl_hi1_val);2741	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);2742	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);2743	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);2744 2745	/* Set operation mode to STANDBY */2746	regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);2747}2748EXPORT_SYMBOL_GPL(clk_regera_pll_configure);2749 2750const struct clk_ops clk_alpha_pll_regera_ops = {2751	.enable = clk_zonda_pll_enable,2752	.disable = clk_zonda_pll_disable,2753	.is_enabled = clk_alpha_pll_is_enabled,2754	.recalc_rate = clk_trion_pll_recalc_rate,2755	.round_rate = clk_alpha_pll_round_rate,2756	.set_rate = clk_zonda_pll_set_rate,2757};2758EXPORT_SYMBOL_GPL(clk_alpha_pll_regera_ops);2759