File Index
Files and directories
Sign in
FILE

clk-pll.c

File preview with syntax highlighting.

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