brintos

brintos / linux-shallow public Read only

0
0
Text · 34.4 KiB · fe76756 Raw
1211 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (c) 2014 MundoReader S.L.4 * Author: Heiko Stuebner <heiko@sntech.de>5 *6 * Copyright (c) 2015 Rockchip Electronics Co. Ltd.7 * Author: Xing Zheng <zhengxing@rock-chips.com>8 */9 10#include <asm/div64.h>11#include <linux/slab.h>12#include <linux/io.h>13#include <linux/delay.h>14#include <linux/clk-provider.h>15#include <linux/iopoll.h>16#include <linux/regmap.h>17#include <linux/clk.h>18#include "clk.h"19 20#define PLL_MODE_MASK		0x321#define PLL_MODE_SLOW		0x022#define PLL_MODE_NORM		0x123#define PLL_MODE_DEEP		0x224#define PLL_RK3328_MODE_MASK	0x125 26struct rockchip_clk_pll {27	struct clk_hw		hw;28 29	struct clk_mux		pll_mux;30	const struct clk_ops	*pll_mux_ops;31 32	struct notifier_block	clk_nb;33 34	void __iomem		*reg_base;35	int			lock_offset;36	unsigned int		lock_shift;37	enum rockchip_pll_type	type;38	u8			flags;39	const struct rockchip_pll_rate_table *rate_table;40	unsigned int		rate_count;41	spinlock_t		*lock;42 43	struct rockchip_clk_provider *ctx;44};45 46#define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw)47#define to_rockchip_clk_pll_nb(nb) \48			container_of(nb, struct rockchip_clk_pll, clk_nb)49 50static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(51			    struct rockchip_clk_pll *pll, unsigned long rate)52{53	const struct rockchip_pll_rate_table  *rate_table = pll->rate_table;54	int i;55 56	for (i = 0; i < pll->rate_count; i++) {57		if (rate == rate_table[i].rate)58			return &rate_table[i];59	}60 61	return NULL;62}63 64static long rockchip_pll_round_rate(struct clk_hw *hw,65			    unsigned long drate, unsigned long *prate)66{67	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);68	const struct rockchip_pll_rate_table *rate_table = pll->rate_table;69	int i;70 71	/* Assumming rate_table is in descending order */72	for (i = 0; i < pll->rate_count; i++) {73		if (drate >= rate_table[i].rate)74			return rate_table[i].rate;75	}76 77	/* return minimum supported value */78	return rate_table[i - 1].rate;79}80 81/*82 * Wait for the pll to reach the locked state.83 * The calling set_rate function is responsible for making sure the84 * grf regmap is available.85 */86static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)87{88	struct regmap *grf = pll->ctx->grf;89	unsigned int val;90	int ret;91 92	ret = regmap_read_poll_timeout(grf, pll->lock_offset, val,93				       val & BIT(pll->lock_shift), 0, 1000);94	if (ret)95		pr_err("%s: timeout waiting for pll to lock\n", __func__);96 97	return ret;98}99 100/*101 * PLL used in RK3036102 */103 104#define RK3036_PLLCON(i)			(i * 0x4)105#define RK3036_PLLCON0_FBDIV_MASK		0xfff106#define RK3036_PLLCON0_FBDIV_SHIFT		0107#define RK3036_PLLCON0_POSTDIV1_MASK		0x7108#define RK3036_PLLCON0_POSTDIV1_SHIFT		12109#define RK3036_PLLCON1_REFDIV_MASK		0x3f110#define RK3036_PLLCON1_REFDIV_SHIFT		0111#define RK3036_PLLCON1_POSTDIV2_MASK		0x7112#define RK3036_PLLCON1_POSTDIV2_SHIFT		6113#define RK3036_PLLCON1_LOCK_STATUS		BIT(10)114#define RK3036_PLLCON1_DSMPD_MASK		0x1115#define RK3036_PLLCON1_DSMPD_SHIFT		12116#define RK3036_PLLCON1_PWRDOWN			BIT(13)117#define RK3036_PLLCON2_FRAC_MASK		0xffffff118#define RK3036_PLLCON2_FRAC_SHIFT		0119 120static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll)121{122	u32 pllcon;123	int ret;124 125	/*126	 * Lock time typical 250, max 500 input clock cycles @24MHz127	 * So define a very safe maximum of 1000us, meaning 24000 cycles.128	 */129	ret = readl_relaxed_poll_timeout(pll->reg_base + RK3036_PLLCON(1),130					 pllcon,131					 pllcon & RK3036_PLLCON1_LOCK_STATUS,132					 0, 1000);133	if (ret)134		pr_err("%s: timeout waiting for pll to lock\n", __func__);135 136	return ret;137}138 139static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll,140					struct rockchip_pll_rate_table *rate)141{142	u32 pllcon;143 144	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0));145	rate->fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT)146				& RK3036_PLLCON0_FBDIV_MASK);147	rate->postdiv1 = ((pllcon >> RK3036_PLLCON0_POSTDIV1_SHIFT)148				& RK3036_PLLCON0_POSTDIV1_MASK);149 150	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));151	rate->refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT)152				& RK3036_PLLCON1_REFDIV_MASK);153	rate->postdiv2 = ((pllcon >> RK3036_PLLCON1_POSTDIV2_SHIFT)154				& RK3036_PLLCON1_POSTDIV2_MASK);155	rate->dsmpd = ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT)156				& RK3036_PLLCON1_DSMPD_MASK);157 158	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));159	rate->frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT)160				& RK3036_PLLCON2_FRAC_MASK);161}162 163static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw,164						     unsigned long prate)165{166	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);167	struct rockchip_pll_rate_table cur;168	u64 rate64 = prate;169 170	rockchip_rk3036_pll_get_params(pll, &cur);171 172	rate64 *= cur.fbdiv;173	do_div(rate64, cur.refdiv);174 175	if (cur.dsmpd == 0) {176		/* fractional mode */177		u64 frac_rate64 = prate * cur.frac;178 179		do_div(frac_rate64, cur.refdiv);180		rate64 += frac_rate64 >> 24;181	}182 183	do_div(rate64, cur.postdiv1);184	do_div(rate64, cur.postdiv2);185 186	return (unsigned long)rate64;187}188 189static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,190				const struct rockchip_pll_rate_table *rate)191{192	const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;193	struct clk_mux *pll_mux = &pll->pll_mux;194	struct rockchip_pll_rate_table cur;195	u32 pllcon;196	int rate_change_remuxed = 0;197	int cur_parent;198	int ret;199 200	pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",201		__func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,202		rate->postdiv2, rate->dsmpd, rate->frac);203 204	rockchip_rk3036_pll_get_params(pll, &cur);205	cur.rate = 0;206 207	cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);208	if (cur_parent == PLL_MODE_NORM) {209		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);210		rate_change_remuxed = 1;211	}212 213	/* update pll values */214	writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK,215					  RK3036_PLLCON0_FBDIV_SHIFT) |216		       HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK,217					     RK3036_PLLCON0_POSTDIV1_SHIFT),218		       pll->reg_base + RK3036_PLLCON(0));219 220	writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK,221						   RK3036_PLLCON1_REFDIV_SHIFT) |222		       HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK,223						     RK3036_PLLCON1_POSTDIV2_SHIFT) |224		       HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK,225						  RK3036_PLLCON1_DSMPD_SHIFT),226		       pll->reg_base + RK3036_PLLCON(1));227 228	/* GPLL CON2 is not HIWORD_MASK */229	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));230	pllcon &= ~(RK3036_PLLCON2_FRAC_MASK << RK3036_PLLCON2_FRAC_SHIFT);231	pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT;232	writel_relaxed(pllcon, pll->reg_base + RK3036_PLLCON(2));233 234	/* wait for the pll to lock */235	ret = rockchip_rk3036_pll_wait_lock(pll);236	if (ret) {237		pr_warn("%s: pll update unsuccessful, trying to restore old params\n",238			__func__);239		rockchip_rk3036_pll_set_params(pll, &cur);240	}241 242	if (rate_change_remuxed)243		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);244 245	return ret;246}247 248static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate,249					unsigned long prate)250{251	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);252	const struct rockchip_pll_rate_table *rate;253 254	pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",255		 __func__, __clk_get_name(hw->clk), drate, prate);256 257	/* Get required rate settings from table */258	rate = rockchip_get_pll_settings(pll, drate);259	if (!rate) {260		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,261			drate, __clk_get_name(hw->clk));262		return -EINVAL;263	}264 265	return rockchip_rk3036_pll_set_params(pll, rate);266}267 268static int rockchip_rk3036_pll_enable(struct clk_hw *hw)269{270	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);271 272	writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0),273	       pll->reg_base + RK3036_PLLCON(1));274	rockchip_rk3036_pll_wait_lock(pll);275 276	return 0;277}278 279static void rockchip_rk3036_pll_disable(struct clk_hw *hw)280{281	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);282 283	writel(HIWORD_UPDATE(RK3036_PLLCON1_PWRDOWN,284			     RK3036_PLLCON1_PWRDOWN, 0),285	       pll->reg_base + RK3036_PLLCON(1));286}287 288static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw)289{290	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);291	u32 pllcon = readl(pll->reg_base + RK3036_PLLCON(1));292 293	return !(pllcon & RK3036_PLLCON1_PWRDOWN);294}295 296static int rockchip_rk3036_pll_init(struct clk_hw *hw)297{298	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);299	const struct rockchip_pll_rate_table *rate;300	struct rockchip_pll_rate_table cur;301	unsigned long drate;302 303	if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))304		return 0;305 306	drate = clk_hw_get_rate(hw);307	rate = rockchip_get_pll_settings(pll, drate);308 309	/* when no rate setting for the current rate, rely on clk_set_rate */310	if (!rate)311		return 0;312 313	rockchip_rk3036_pll_get_params(pll, &cur);314 315	pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),316		 drate);317	pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",318		 cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,319		 cur.dsmpd, cur.frac);320	pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",321		 rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,322		 rate->dsmpd, rate->frac);323 324	if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||325		rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||326		rate->dsmpd != cur.dsmpd ||327		(!cur.dsmpd && (rate->frac != cur.frac))) {328		struct clk *parent = clk_get_parent(hw->clk);329 330		if (!parent) {331			pr_warn("%s: parent of %s not available\n",332				__func__, __clk_get_name(hw->clk));333			return 0;334		}335 336		pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",337			 __func__, __clk_get_name(hw->clk));338		rockchip_rk3036_pll_set_params(pll, rate);339	}340 341	return 0;342}343 344static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {345	.recalc_rate = rockchip_rk3036_pll_recalc_rate,346	.enable = rockchip_rk3036_pll_enable,347	.disable = rockchip_rk3036_pll_disable,348	.is_enabled = rockchip_rk3036_pll_is_enabled,349};350 351static const struct clk_ops rockchip_rk3036_pll_clk_ops = {352	.recalc_rate = rockchip_rk3036_pll_recalc_rate,353	.round_rate = rockchip_pll_round_rate,354	.set_rate = rockchip_rk3036_pll_set_rate,355	.enable = rockchip_rk3036_pll_enable,356	.disable = rockchip_rk3036_pll_disable,357	.is_enabled = rockchip_rk3036_pll_is_enabled,358	.init = rockchip_rk3036_pll_init,359};360 361/*362 * PLL used in RK3066, RK3188 and RK3288363 */364 365#define RK3066_PLL_RESET_DELAY(nr)	((nr * 500) / 24 + 1)366 367#define RK3066_PLLCON(i)		(i * 0x4)368#define RK3066_PLLCON0_OD_MASK		0xf369#define RK3066_PLLCON0_OD_SHIFT		0370#define RK3066_PLLCON0_NR_MASK		0x3f371#define RK3066_PLLCON0_NR_SHIFT		8372#define RK3066_PLLCON1_NF_MASK		0x1fff373#define RK3066_PLLCON1_NF_SHIFT		0374#define RK3066_PLLCON2_NB_MASK		0xfff375#define RK3066_PLLCON2_NB_SHIFT		0376#define RK3066_PLLCON3_RESET		(1 << 5)377#define RK3066_PLLCON3_PWRDOWN		(1 << 1)378#define RK3066_PLLCON3_BYPASS		(1 << 0)379 380static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll,381					struct rockchip_pll_rate_table *rate)382{383	u32 pllcon;384 385	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));386	rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT)387				& RK3066_PLLCON0_NR_MASK) + 1;388	rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT)389				& RK3066_PLLCON0_OD_MASK) + 1;390 391	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));392	rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT)393				& RK3066_PLLCON1_NF_MASK) + 1;394 395	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));396	rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT)397				& RK3066_PLLCON2_NB_MASK) + 1;398}399 400static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,401						     unsigned long prate)402{403	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);404	struct rockchip_pll_rate_table cur;405	u64 rate64 = prate;406	u32 pllcon;407 408	pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));409	if (pllcon & RK3066_PLLCON3_BYPASS) {410		pr_debug("%s: pll %s is bypassed\n", __func__,411			clk_hw_get_name(hw));412		return prate;413	}414 415	rockchip_rk3066_pll_get_params(pll, &cur);416 417	rate64 *= cur.nf;418	do_div(rate64, cur.nr);419	do_div(rate64, cur.no);420 421	return (unsigned long)rate64;422}423 424static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,425				const struct rockchip_pll_rate_table *rate)426{427	const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;428	struct clk_mux *pll_mux = &pll->pll_mux;429	struct rockchip_pll_rate_table cur;430	int rate_change_remuxed = 0;431	int cur_parent;432	int ret;433 434	pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",435		 __func__, rate->rate, rate->nr, rate->no, rate->nf);436 437	rockchip_rk3066_pll_get_params(pll, &cur);438	cur.rate = 0;439 440	cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);441	if (cur_parent == PLL_MODE_NORM) {442		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);443		rate_change_remuxed = 1;444	}445 446	/* enter reset mode */447	writel(HIWORD_UPDATE(RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0),448	       pll->reg_base + RK3066_PLLCON(3));449 450	/* update pll values */451	writel(HIWORD_UPDATE(rate->nr - 1, RK3066_PLLCON0_NR_MASK,452					   RK3066_PLLCON0_NR_SHIFT) |453	       HIWORD_UPDATE(rate->no - 1, RK3066_PLLCON0_OD_MASK,454					   RK3066_PLLCON0_OD_SHIFT),455	       pll->reg_base + RK3066_PLLCON(0));456 457	writel_relaxed(HIWORD_UPDATE(rate->nf - 1, RK3066_PLLCON1_NF_MASK,458						   RK3066_PLLCON1_NF_SHIFT),459		       pll->reg_base + RK3066_PLLCON(1));460	writel_relaxed(HIWORD_UPDATE(rate->nb - 1, RK3066_PLLCON2_NB_MASK,461						   RK3066_PLLCON2_NB_SHIFT),462		       pll->reg_base + RK3066_PLLCON(2));463 464	/* leave reset and wait the reset_delay */465	writel(HIWORD_UPDATE(0, RK3066_PLLCON3_RESET, 0),466	       pll->reg_base + RK3066_PLLCON(3));467	udelay(RK3066_PLL_RESET_DELAY(rate->nr));468 469	/* wait for the pll to lock */470	ret = rockchip_pll_wait_lock(pll);471	if (ret) {472		pr_warn("%s: pll update unsuccessful, trying to restore old params\n",473			__func__);474		rockchip_rk3066_pll_set_params(pll, &cur);475	}476 477	if (rate_change_remuxed)478		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);479 480	return ret;481}482 483static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,484					unsigned long prate)485{486	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);487	const struct rockchip_pll_rate_table *rate;488 489	pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",490		 __func__, clk_hw_get_name(hw), drate, prate);491 492	/* Get required rate settings from table */493	rate = rockchip_get_pll_settings(pll, drate);494	if (!rate) {495		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,496			drate, clk_hw_get_name(hw));497		return -EINVAL;498	}499 500	return rockchip_rk3066_pll_set_params(pll, rate);501}502 503static int rockchip_rk3066_pll_enable(struct clk_hw *hw)504{505	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);506 507	writel(HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0),508	       pll->reg_base + RK3066_PLLCON(3));509	rockchip_pll_wait_lock(pll);510 511	return 0;512}513 514static void rockchip_rk3066_pll_disable(struct clk_hw *hw)515{516	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);517 518	writel(HIWORD_UPDATE(RK3066_PLLCON3_PWRDOWN,519			     RK3066_PLLCON3_PWRDOWN, 0),520	       pll->reg_base + RK3066_PLLCON(3));521}522 523static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)524{525	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);526	u32 pllcon = readl(pll->reg_base + RK3066_PLLCON(3));527 528	return !(pllcon & RK3066_PLLCON3_PWRDOWN);529}530 531static int rockchip_rk3066_pll_init(struct clk_hw *hw)532{533	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);534	const struct rockchip_pll_rate_table *rate;535	struct rockchip_pll_rate_table cur;536	unsigned long drate;537 538	if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))539		return 0;540 541	drate = clk_hw_get_rate(hw);542	rate = rockchip_get_pll_settings(pll, drate);543 544	/* when no rate setting for the current rate, rely on clk_set_rate */545	if (!rate)546		return 0;547 548	rockchip_rk3066_pll_get_params(pll, &cur);549 550	pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n",551		 __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr,552		 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);553	if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf554						     || rate->nb != cur.nb) {555		pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",556			 __func__, clk_hw_get_name(hw));557		rockchip_rk3066_pll_set_params(pll, rate);558	}559 560	return 0;561}562 563static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {564	.recalc_rate = rockchip_rk3066_pll_recalc_rate,565	.enable = rockchip_rk3066_pll_enable,566	.disable = rockchip_rk3066_pll_disable,567	.is_enabled = rockchip_rk3066_pll_is_enabled,568};569 570static const struct clk_ops rockchip_rk3066_pll_clk_ops = {571	.recalc_rate = rockchip_rk3066_pll_recalc_rate,572	.round_rate = rockchip_pll_round_rate,573	.set_rate = rockchip_rk3066_pll_set_rate,574	.enable = rockchip_rk3066_pll_enable,575	.disable = rockchip_rk3066_pll_disable,576	.is_enabled = rockchip_rk3066_pll_is_enabled,577	.init = rockchip_rk3066_pll_init,578};579 580/*581 * PLL used in RK3399582 */583 584#define RK3399_PLLCON(i)			(i * 0x4)585#define RK3399_PLLCON0_FBDIV_MASK		0xfff586#define RK3399_PLLCON0_FBDIV_SHIFT		0587#define RK3399_PLLCON1_REFDIV_MASK		0x3f588#define RK3399_PLLCON1_REFDIV_SHIFT		0589#define RK3399_PLLCON1_POSTDIV1_MASK		0x7590#define RK3399_PLLCON1_POSTDIV1_SHIFT		8591#define RK3399_PLLCON1_POSTDIV2_MASK		0x7592#define RK3399_PLLCON1_POSTDIV2_SHIFT		12593#define RK3399_PLLCON2_FRAC_MASK		0xffffff594#define RK3399_PLLCON2_FRAC_SHIFT		0595#define RK3399_PLLCON2_LOCK_STATUS		BIT(31)596#define RK3399_PLLCON3_PWRDOWN			BIT(0)597#define RK3399_PLLCON3_DSMPD_MASK		0x1598#define RK3399_PLLCON3_DSMPD_SHIFT		3599 600static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll)601{602	u32 pllcon;603	int ret;604 605	/*606	 * Lock time typical 250, max 500 input clock cycles @24MHz607	 * So define a very safe maximum of 1000us, meaning 24000 cycles.608	 */609	ret = readl_relaxed_poll_timeout(pll->reg_base + RK3399_PLLCON(2),610					 pllcon,611					 pllcon & RK3399_PLLCON2_LOCK_STATUS,612					 0, 1000);613	if (ret)614		pr_err("%s: timeout waiting for pll to lock\n", __func__);615 616	return ret;617}618 619static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll,620					struct rockchip_pll_rate_table *rate)621{622	u32 pllcon;623 624	pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0));625	rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT)626				& RK3399_PLLCON0_FBDIV_MASK);627 628	pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(1));629	rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT)630				& RK3399_PLLCON1_REFDIV_MASK);631	rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT)632				& RK3399_PLLCON1_POSTDIV1_MASK);633	rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT)634				& RK3399_PLLCON1_POSTDIV2_MASK);635 636	pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));637	rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT)638				& RK3399_PLLCON2_FRAC_MASK);639 640	pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(3));641	rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT)642				& RK3399_PLLCON3_DSMPD_MASK);643}644 645static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw,646						     unsigned long prate)647{648	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);649	struct rockchip_pll_rate_table cur;650	u64 rate64 = prate;651 652	rockchip_rk3399_pll_get_params(pll, &cur);653 654	rate64 *= cur.fbdiv;655	do_div(rate64, cur.refdiv);656 657	if (cur.dsmpd == 0) {658		/* fractional mode */659		u64 frac_rate64 = prate * cur.frac;660 661		do_div(frac_rate64, cur.refdiv);662		rate64 += frac_rate64 >> 24;663	}664 665	do_div(rate64, cur.postdiv1);666	do_div(rate64, cur.postdiv2);667 668	return (unsigned long)rate64;669}670 671static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll,672				const struct rockchip_pll_rate_table *rate)673{674	const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;675	struct clk_mux *pll_mux = &pll->pll_mux;676	struct rockchip_pll_rate_table cur;677	u32 pllcon;678	int rate_change_remuxed = 0;679	int cur_parent;680	int ret;681 682	pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",683		__func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,684		rate->postdiv2, rate->dsmpd, rate->frac);685 686	rockchip_rk3399_pll_get_params(pll, &cur);687	cur.rate = 0;688 689	cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);690	if (cur_parent == PLL_MODE_NORM) {691		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);692		rate_change_remuxed = 1;693	}694 695	/* update pll values */696	writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK,697						  RK3399_PLLCON0_FBDIV_SHIFT),698		       pll->reg_base + RK3399_PLLCON(0));699 700	writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK,701						   RK3399_PLLCON1_REFDIV_SHIFT) |702		       HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK,703						     RK3399_PLLCON1_POSTDIV1_SHIFT) |704		       HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK,705						     RK3399_PLLCON1_POSTDIV2_SHIFT),706		       pll->reg_base + RK3399_PLLCON(1));707 708	/* xPLL CON2 is not HIWORD_MASK */709	pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));710	pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT);711	pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT;712	writel_relaxed(pllcon, pll->reg_base + RK3399_PLLCON(2));713 714	writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK,715					    RK3399_PLLCON3_DSMPD_SHIFT),716		       pll->reg_base + RK3399_PLLCON(3));717 718	/* wait for the pll to lock */719	ret = rockchip_rk3399_pll_wait_lock(pll);720	if (ret) {721		pr_warn("%s: pll update unsuccessful, trying to restore old params\n",722			__func__);723		rockchip_rk3399_pll_set_params(pll, &cur);724	}725 726	if (rate_change_remuxed)727		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);728 729	return ret;730}731 732static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drate,733					unsigned long prate)734{735	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);736	const struct rockchip_pll_rate_table *rate;737 738	pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",739		 __func__, __clk_get_name(hw->clk), drate, prate);740 741	/* Get required rate settings from table */742	rate = rockchip_get_pll_settings(pll, drate);743	if (!rate) {744		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,745			drate, __clk_get_name(hw->clk));746		return -EINVAL;747	}748 749	return rockchip_rk3399_pll_set_params(pll, rate);750}751 752static int rockchip_rk3399_pll_enable(struct clk_hw *hw)753{754	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);755 756	writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0),757	       pll->reg_base + RK3399_PLLCON(3));758	rockchip_rk3399_pll_wait_lock(pll);759 760	return 0;761}762 763static void rockchip_rk3399_pll_disable(struct clk_hw *hw)764{765	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);766 767	writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN,768			     RK3399_PLLCON3_PWRDOWN, 0),769	       pll->reg_base + RK3399_PLLCON(3));770}771 772static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw)773{774	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);775	u32 pllcon = readl(pll->reg_base + RK3399_PLLCON(3));776 777	return !(pllcon & RK3399_PLLCON3_PWRDOWN);778}779 780static int rockchip_rk3399_pll_init(struct clk_hw *hw)781{782	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);783	const struct rockchip_pll_rate_table *rate;784	struct rockchip_pll_rate_table cur;785	unsigned long drate;786 787	if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))788		return 0;789 790	drate = clk_hw_get_rate(hw);791	rate = rockchip_get_pll_settings(pll, drate);792 793	/* when no rate setting for the current rate, rely on clk_set_rate */794	if (!rate)795		return 0;796 797	rockchip_rk3399_pll_get_params(pll, &cur);798 799	pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),800		 drate);801	pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",802		 cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,803		 cur.dsmpd, cur.frac);804	pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",805		 rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,806		 rate->dsmpd, rate->frac);807 808	if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||809		rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||810		rate->dsmpd != cur.dsmpd ||811		(!cur.dsmpd && (rate->frac != cur.frac))) {812		struct clk *parent = clk_get_parent(hw->clk);813 814		if (!parent) {815			pr_warn("%s: parent of %s not available\n",816				__func__, __clk_get_name(hw->clk));817			return 0;818		}819 820		pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",821			 __func__, __clk_get_name(hw->clk));822		rockchip_rk3399_pll_set_params(pll, rate);823	}824 825	return 0;826}827 828static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {829	.recalc_rate = rockchip_rk3399_pll_recalc_rate,830	.enable = rockchip_rk3399_pll_enable,831	.disable = rockchip_rk3399_pll_disable,832	.is_enabled = rockchip_rk3399_pll_is_enabled,833};834 835static const struct clk_ops rockchip_rk3399_pll_clk_ops = {836	.recalc_rate = rockchip_rk3399_pll_recalc_rate,837	.round_rate = rockchip_pll_round_rate,838	.set_rate = rockchip_rk3399_pll_set_rate,839	.enable = rockchip_rk3399_pll_enable,840	.disable = rockchip_rk3399_pll_disable,841	.is_enabled = rockchip_rk3399_pll_is_enabled,842	.init = rockchip_rk3399_pll_init,843};844 845/*846 * PLL used in RK3588847 */848 849#define RK3588_PLLCON(i)               (i * 0x4)850#define RK3588_PLLCON0_M_MASK          0x3ff851#define RK3588_PLLCON0_M_SHIFT         0852#define RK3588_PLLCON1_P_MASK          0x3f853#define RK3588_PLLCON1_P_SHIFT         0854#define RK3588_PLLCON1_S_MASK          0x7855#define RK3588_PLLCON1_S_SHIFT         6856#define RK3588_PLLCON2_K_MASK          0xffff857#define RK3588_PLLCON2_K_SHIFT         0858#define RK3588_PLLCON1_PWRDOWN         BIT(13)859#define RK3588_PLLCON6_LOCK_STATUS     BIT(15)860 861static int rockchip_rk3588_pll_wait_lock(struct rockchip_clk_pll *pll)862{863	u32 pllcon;864	int ret;865 866	/*867	 * Lock time typical 250, max 500 input clock cycles @24MHz868	 * So define a very safe maximum of 1000us, meaning 24000 cycles.869	 */870	ret = readl_relaxed_poll_timeout(pll->reg_base + RK3588_PLLCON(6),871					 pllcon,872					 pllcon & RK3588_PLLCON6_LOCK_STATUS,873					 0, 1000);874	if (ret)875		pr_err("%s: timeout waiting for pll to lock\n", __func__);876 877	return ret;878}879 880static void rockchip_rk3588_pll_get_params(struct rockchip_clk_pll *pll,881					   struct rockchip_pll_rate_table *rate)882{883	u32 pllcon;884 885	pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(0));886	rate->m = ((pllcon >> RK3588_PLLCON0_M_SHIFT) & RK3588_PLLCON0_M_MASK);887 888	pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(1));889	rate->p = ((pllcon >> RK3588_PLLCON1_P_SHIFT) & RK3588_PLLCON1_P_MASK);890	rate->s = ((pllcon >> RK3588_PLLCON1_S_SHIFT) & RK3588_PLLCON1_S_MASK);891 892	pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(2));893	rate->k = ((pllcon >> RK3588_PLLCON2_K_SHIFT) & RK3588_PLLCON2_K_MASK);894}895 896static unsigned long rockchip_rk3588_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)897{898	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);899	struct rockchip_pll_rate_table cur;900	u64 rate64 = prate, postdiv;901 902	rockchip_rk3588_pll_get_params(pll, &cur);903 904	rate64 *= cur.m;905	do_div(rate64, cur.p);906 907	if (cur.k) {908		/* fractional mode */909		u64 frac_rate64 = prate * cur.k;910 911		postdiv = cur.p * 65535;912		do_div(frac_rate64, postdiv);913		rate64 += frac_rate64;914	}915	rate64 = rate64 >> cur.s;916 917	if (pll->type == pll_rk3588_ddr)918		return (unsigned long)rate64 * 2;919	else920		return (unsigned long)rate64;921}922 923static int rockchip_rk3588_pll_set_params(struct rockchip_clk_pll *pll,924					  const struct rockchip_pll_rate_table *rate)925{926	const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;927	struct clk_mux *pll_mux = &pll->pll_mux;928	struct rockchip_pll_rate_table cur;929	int rate_change_remuxed = 0;930	int cur_parent;931	int ret;932 933	pr_debug("%s: rate settings for %lu p: %d, m: %d, s: %d, k: %d\n",934		 __func__, rate->rate, rate->p, rate->m, rate->s, rate->k);935 936	rockchip_rk3588_pll_get_params(pll, &cur);937	cur.rate = 0;938 939	if (pll->type == pll_rk3588) {940		cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);941		if (cur_parent == PLL_MODE_NORM) {942			pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);943			rate_change_remuxed = 1;944		}945	}946 947	/* set pll power down */948	writel(HIWORD_UPDATE(RK3588_PLLCON1_PWRDOWN,949			     RK3588_PLLCON1_PWRDOWN, 0),950	       pll->reg_base + RK3399_PLLCON(1));951 952	/* update pll values */953	writel_relaxed(HIWORD_UPDATE(rate->m, RK3588_PLLCON0_M_MASK, RK3588_PLLCON0_M_SHIFT),954		       pll->reg_base + RK3399_PLLCON(0));955 956	writel_relaxed(HIWORD_UPDATE(rate->p, RK3588_PLLCON1_P_MASK, RK3588_PLLCON1_P_SHIFT) |957		       HIWORD_UPDATE(rate->s, RK3588_PLLCON1_S_MASK, RK3588_PLLCON1_S_SHIFT),958		       pll->reg_base + RK3399_PLLCON(1));959 960	writel_relaxed(HIWORD_UPDATE(rate->k, RK3588_PLLCON2_K_MASK, RK3588_PLLCON2_K_SHIFT),961		       pll->reg_base + RK3399_PLLCON(2));962 963	/* set pll power up */964	writel(HIWORD_UPDATE(0, RK3588_PLLCON1_PWRDOWN, 0),965	       pll->reg_base + RK3588_PLLCON(1));966 967	/* wait for the pll to lock */968	ret = rockchip_rk3588_pll_wait_lock(pll);969	if (ret) {970		pr_warn("%s: pll update unsuccessful, trying to restore old params\n",971			__func__);972		rockchip_rk3588_pll_set_params(pll, &cur);973	}974 975	if ((pll->type == pll_rk3588) && rate_change_remuxed)976		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);977 978	return ret;979}980 981static int rockchip_rk3588_pll_set_rate(struct clk_hw *hw, unsigned long drate,982					unsigned long prate)983{984	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);985	const struct rockchip_pll_rate_table *rate;986 987	pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",988		 __func__, __clk_get_name(hw->clk), drate, prate);989 990	/* Get required rate settings from table */991	rate = rockchip_get_pll_settings(pll, drate);992	if (!rate) {993		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,994			drate, __clk_get_name(hw->clk));995		return -EINVAL;996	}997 998	return rockchip_rk3588_pll_set_params(pll, rate);999}1000 1001static int rockchip_rk3588_pll_enable(struct clk_hw *hw)1002{1003	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);1004 1005	writel(HIWORD_UPDATE(0, RK3588_PLLCON1_PWRDOWN, 0),1006	       pll->reg_base + RK3588_PLLCON(1));1007	rockchip_rk3588_pll_wait_lock(pll);1008 1009	return 0;1010}1011 1012static void rockchip_rk3588_pll_disable(struct clk_hw *hw)1013{1014	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);1015 1016	writel(HIWORD_UPDATE(RK3588_PLLCON1_PWRDOWN, RK3588_PLLCON1_PWRDOWN, 0),1017	       pll->reg_base + RK3588_PLLCON(1));1018}1019 1020static int rockchip_rk3588_pll_is_enabled(struct clk_hw *hw)1021{1022	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);1023	u32 pllcon = readl(pll->reg_base + RK3588_PLLCON(1));1024 1025	return !(pllcon & RK3588_PLLCON1_PWRDOWN);1026}1027 1028static int rockchip_rk3588_pll_init(struct clk_hw *hw)1029{1030	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);1031 1032	if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))1033		return 0;1034 1035	return 0;1036}1037 1038static const struct clk_ops rockchip_rk3588_pll_clk_norate_ops = {1039	.recalc_rate = rockchip_rk3588_pll_recalc_rate,1040	.enable = rockchip_rk3588_pll_enable,1041	.disable = rockchip_rk3588_pll_disable,1042	.is_enabled = rockchip_rk3588_pll_is_enabled,1043};1044 1045static const struct clk_ops rockchip_rk3588_pll_clk_ops = {1046	.recalc_rate = rockchip_rk3588_pll_recalc_rate,1047	.round_rate = rockchip_pll_round_rate,1048	.set_rate = rockchip_rk3588_pll_set_rate,1049	.enable = rockchip_rk3588_pll_enable,1050	.disable = rockchip_rk3588_pll_disable,1051	.is_enabled = rockchip_rk3588_pll_is_enabled,1052	.init = rockchip_rk3588_pll_init,1053};1054 1055/*1056 * Common registering of pll clocks1057 */1058 1059struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,1060		enum rockchip_pll_type pll_type,1061		const char *name, const char *const *parent_names,1062		u8 num_parents, int con_offset, int grf_lock_offset,1063		int lock_shift, int mode_offset, int mode_shift,1064		struct rockchip_pll_rate_table *rate_table,1065		unsigned long flags, u8 clk_pll_flags)1066{1067	const char *pll_parents[3];1068	struct clk_init_data init;1069	struct rockchip_clk_pll *pll;1070	struct clk_mux *pll_mux;1071	struct clk *pll_clk, *mux_clk;1072	char pll_name[20];1073 1074	if ((pll_type != pll_rk3328 && num_parents != 2) ||1075	    (pll_type == pll_rk3328 && num_parents != 1)) {1076		pr_err("%s: needs two parent clocks\n", __func__);1077		return ERR_PTR(-EINVAL);1078	}1079 1080	/* name the actual pll */1081	snprintf(pll_name, sizeof(pll_name), "pll_%s", name);1082 1083	pll = kzalloc(sizeof(*pll), GFP_KERNEL);1084	if (!pll)1085		return ERR_PTR(-ENOMEM);1086 1087	/* create the mux on top of the real pll */1088	pll->pll_mux_ops = &clk_mux_ops;1089	pll_mux = &pll->pll_mux;1090	pll_mux->reg = ctx->reg_base + mode_offset;1091	pll_mux->shift = mode_shift;1092	if (pll_type == pll_rk3328)1093		pll_mux->mask = PLL_RK3328_MODE_MASK;1094	else1095		pll_mux->mask = PLL_MODE_MASK;1096	pll_mux->flags = 0;1097	pll_mux->lock = &ctx->lock;1098	pll_mux->hw.init = &init;1099 1100	if (pll_type == pll_rk3036 ||1101	    pll_type == pll_rk3066 ||1102	    pll_type == pll_rk3328 ||1103	    pll_type == pll_rk3399 ||1104	    pll_type == pll_rk3588)1105		pll_mux->flags |= CLK_MUX_HIWORD_MASK;1106 1107	/* the actual muxing is xin24m, pll-output, xin32k */1108	pll_parents[0] = parent_names[0];1109	pll_parents[1] = pll_name;1110	pll_parents[2] = parent_names[1];1111 1112	init.name = name;1113	init.flags = CLK_SET_RATE_PARENT;1114	init.ops = pll->pll_mux_ops;1115	init.parent_names = pll_parents;1116	if (pll_type == pll_rk3328)1117		init.num_parents = 2;1118	else1119		init.num_parents = ARRAY_SIZE(pll_parents);1120 1121	mux_clk = clk_register(NULL, &pll_mux->hw);1122	if (IS_ERR(mux_clk))1123		goto err_mux;1124 1125	/* now create the actual pll */1126	init.name = pll_name;1127 1128	/* keep all plls untouched for now */1129	init.flags = flags | CLK_IGNORE_UNUSED;1130 1131	init.parent_names = &parent_names[0];1132	init.num_parents = 1;1133 1134	if (rate_table) {1135		int len;1136 1137		/* find count of rates in rate_table */1138		for (len = 0; rate_table[len].rate != 0; )1139			len++;1140 1141		pll->rate_count = len;1142		pll->rate_table = kmemdup_array(rate_table,1143						pll->rate_count,1144						sizeof(*pll->rate_table),1145						GFP_KERNEL);1146		WARN(!pll->rate_table,1147			"%s: could not allocate rate table for %s\n",1148			__func__, name);1149	}1150 1151	switch (pll_type) {1152	case pll_rk3036:1153	case pll_rk3328:1154		if (!pll->rate_table)1155			init.ops = &rockchip_rk3036_pll_clk_norate_ops;1156		else1157			init.ops = &rockchip_rk3036_pll_clk_ops;1158		break;1159	case pll_rk3066:1160		if (!pll->rate_table || IS_ERR(ctx->grf))1161			init.ops = &rockchip_rk3066_pll_clk_norate_ops;1162		else1163			init.ops = &rockchip_rk3066_pll_clk_ops;1164		break;1165	case pll_rk3399:1166		if (!pll->rate_table)1167			init.ops = &rockchip_rk3399_pll_clk_norate_ops;1168		else1169			init.ops = &rockchip_rk3399_pll_clk_ops;1170		break;1171	case pll_rk3588:1172	case pll_rk3588_core:1173	case pll_rk3588_ddr:1174		if (!pll->rate_table)1175			init.ops = &rockchip_rk3588_pll_clk_norate_ops;1176		else1177			init.ops = &rockchip_rk3588_pll_clk_ops;1178		init.flags = flags;1179		break;1180	default:1181		pr_warn("%s: Unknown pll type for pll clk %s\n",1182			__func__, name);1183	}1184 1185	pll->hw.init = &init;1186	pll->type = pll_type;1187	pll->reg_base = ctx->reg_base + con_offset;1188	pll->lock_offset = grf_lock_offset;1189	pll->lock_shift = lock_shift;1190	pll->flags = clk_pll_flags;1191	pll->lock = &ctx->lock;1192	pll->ctx = ctx;1193 1194	pll_clk = clk_register(NULL, &pll->hw);1195	if (IS_ERR(pll_clk)) {1196		pr_err("%s: failed to register pll clock %s : %ld\n",1197			__func__, name, PTR_ERR(pll_clk));1198		goto err_pll;1199	}1200 1201	return mux_clk;1202 1203err_pll:1204	kfree(pll->rate_table);1205	clk_unregister(mux_clk);1206	mux_clk = pll_clk;1207err_mux:1208	kfree(pll);1209	return mux_clk;1210}1211