Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright (C) 2014 Broadcom Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * modify it under the terms of the GNU General Public License as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * published by the Free Software Foundation version 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * kind, whether express or implied; without even the implied warranty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/clkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "clk-iproc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define PLL_VCO_HIGH_SHIFT 19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define PLL_VCO_LOW_SHIFT  30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * PLL MACRO_SELECT modes 0 to 5 choose pre-calculated PLL output frequencies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * from a look-up table. Mode 7 allows user to manipulate PLL clock dividers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define PLL_USER_MODE 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /* number of delay loops waiting for PLL to lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define LOCK_DELAY 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) /* number of VCO frequency bands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define NUM_FREQ_BANDS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define NUM_KP_BANDS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) enum kp_band {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	KP_BAND_MID = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	KP_BAND_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	KP_BAND_HIGH_HIGH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static const unsigned int kp_table[NUM_KP_BANDS][NUM_FREQ_BANDS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	{ 5, 6, 6, 7, 7, 8, 9, 10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	{ 4, 4, 5, 5, 6, 7, 8, 9  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	{ 4, 5, 5, 6, 7, 8, 9, 10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) static const unsigned long ref_freq_table[NUM_FREQ_BANDS][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	{ 10000000,  12500000  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	{ 12500000,  15000000  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	{ 15000000,  20000000  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	{ 20000000,  25000000  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	{ 25000000,  50000000  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	{ 50000000,  75000000  },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	{ 75000000,  100000000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	{ 100000000, 125000000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) enum vco_freq_range {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	VCO_LOW       = 700000000U,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	VCO_MID       = 1200000000U,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	VCO_HIGH      = 2200000000U,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	VCO_HIGH_HIGH = 3100000000U,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	VCO_MAX       = 4000000000U,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) struct iproc_pll {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	void __iomem *status_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	void __iomem *control_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	void __iomem *pwr_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	void __iomem *asiu_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	const struct iproc_pll_ctrl *ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	const struct iproc_pll_vco_param *vco_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	unsigned int num_vco_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) struct iproc_clk {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct iproc_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	const struct iproc_clk_ctrl *ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #define to_iproc_clk(hw) container_of(hw, struct iproc_clk, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) static int pll_calc_param(unsigned long target_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			unsigned long parent_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			struct iproc_pll_vco_param *vco_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	u64 ndiv_int, ndiv_frac, residual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	ndiv_int = target_rate / parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	if (!ndiv_int || (ndiv_int > 255))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	residual = target_rate - (ndiv_int * parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	residual <<= 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	 * Add half of the divisor so the result will be rounded to closest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	 * instead of rounded down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	residual += (parent_rate / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	ndiv_frac = div64_u64((u64)residual, (u64)parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	vco_out->ndiv_int = ndiv_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	vco_out->ndiv_frac = ndiv_frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	vco_out->pdiv = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	vco_out->rate = vco_out->ndiv_int * parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	residual = (u64)vco_out->ndiv_frac * (u64)parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	residual >>= 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	vco_out->rate += residual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * Based on the target frequency, find a match from the VCO frequency parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * table and return its index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static int pll_get_rate_index(struct iproc_pll *pll, unsigned int target_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	for (i = 0; i < pll->num_vco_entries; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		if (target_rate == pll->vco_param[i].rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	if (i >= pll->num_vco_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static int get_kp(unsigned long ref_freq, enum kp_band kp_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (ref_freq < ref_freq_table[0][0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	for (i = 0; i < NUM_FREQ_BANDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		if (ref_freq >= ref_freq_table[i][0] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		    ref_freq < ref_freq_table[i][1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			return kp_table[kp_index][i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int pll_wait_for_lock(struct iproc_pll *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	for (i = 0; i < LOCK_DELAY; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		u32 val = readl(pll->status_base + ctrl->status.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		if (val & (1 << ctrl->status.shift))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static void iproc_pll_write(const struct iproc_pll *pll, void __iomem *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 			    const u32 offset, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	writel(val, base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		     (base == pll->status_base || base == pll->control_base)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		val = readl(base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static void __pll_disable(struct iproc_pll *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (ctrl->flags & IPROC_CLK_PLL_ASIU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		val = readl(pll->asiu_base + ctrl->asiu.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		val &= ~(1 << ctrl->asiu.en_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		iproc_pll_write(pll, pll->asiu_base, ctrl->asiu.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		val = readl(pll->control_base + ctrl->aon.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		iproc_pll_write(pll, pll->control_base, ctrl->aon.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	if (pll->pwr_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		/* latch input value so core power can be shut down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		val = readl(pll->pwr_base + ctrl->aon.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		val |= 1 << ctrl->aon.iso_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		/* power down the core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static int __pll_enable(struct iproc_pll *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		val = readl(pll->control_base + ctrl->aon.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		iproc_pll_write(pll, pll->control_base, ctrl->aon.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	if (pll->pwr_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		/* power up the PLL and make sure it's not latched */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		val = readl(pll->pwr_base + ctrl->aon.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		val &= ~(1 << ctrl->aon.iso_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	/* certain PLLs also need to be ungated from the ASIU top level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	if (ctrl->flags & IPROC_CLK_PLL_ASIU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		val = readl(pll->asiu_base + ctrl->asiu.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		val |= (1 << ctrl->asiu.en_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		iproc_pll_write(pll, pll->asiu_base, ctrl->asiu.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static void __pll_put_in_reset(struct iproc_pll *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	const struct iproc_pll_reset_ctrl *reset = &ctrl->reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	val = readl(pll->control_base + reset->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	iproc_pll_write(pll, pll->control_base, reset->offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 				  unsigned int ka, unsigned int ki)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	const struct iproc_pll_reset_ctrl *reset = &ctrl->reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	const struct iproc_pll_dig_filter_ctrl *dig_filter = &ctrl->dig_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	val = readl(pll->control_base + dig_filter->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	val &= ~(bit_mask(dig_filter->ki_width) << dig_filter->ki_shift |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		bit_mask(dig_filter->kp_width) << dig_filter->kp_shift |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		bit_mask(dig_filter->ka_width) << dig_filter->ka_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	val |= ki << dig_filter->ki_shift | kp << dig_filter->kp_shift |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	       ka << dig_filter->ka_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	iproc_pll_write(pll, pll->control_base, dig_filter->offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	val = readl(pll->control_base + reset->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	iproc_pll_write(pll, pll->control_base, reset->offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)  * Determines if the change to be applied to the PLL is minor (just an update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)  * or the fractional divider). If so, then we can avoid going through a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)  * disruptive reset and lock sequence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static bool pll_fractional_change_only(struct iproc_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 				       struct iproc_pll_vco_param *vco)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	u32 ndiv_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	unsigned int pdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	/* PLL needs to be locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	val = readl(pll->status_base + ctrl->status.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	if ((val & (1 << ctrl->status.shift)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	val = readl(pll->control_base + ctrl->ndiv_int.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	ndiv_int = (val >> ctrl->ndiv_int.shift) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		bit_mask(ctrl->ndiv_int.width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	if (ndiv_int != vco->ndiv_int)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	val = readl(pll->control_base + ctrl->pdiv.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	if (pdiv != vco->pdiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static int pll_set_rate(struct iproc_clk *clk, struct iproc_pll_vco_param *vco,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	struct iproc_pll *pll = clk->pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	int ka = 0, ki, kp, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	unsigned long rate = vco->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	enum kp_band kp_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	unsigned long ref_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	const char *clk_name = clk_hw_get_name(&clk->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	 * reference frequency = parent frequency / PDIV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	 * If PDIV = 0, then it becomes a multiplier (x2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	if (vco->pdiv == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		ref_freq = parent_rate * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		ref_freq = parent_rate / vco->pdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	/* determine Ki and Kp index based on target VCO frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	if (rate >= VCO_LOW && rate < VCO_HIGH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		ki = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		kp_index = KP_BAND_MID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	} else if (rate >= VCO_HIGH && rate < VCO_HIGH_HIGH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		ki = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		kp_index = KP_BAND_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	} else if (rate >= VCO_HIGH_HIGH && rate < VCO_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		ki = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		kp_index = KP_BAND_HIGH_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		pr_err("%s: pll: %s has invalid rate: %lu\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 				clk_name, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	kp = get_kp(ref_freq, kp_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	if (kp < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		pr_err("%s: pll: %s has invalid kp\n", __func__, clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		return kp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	ret = __pll_enable(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		pr_err("%s: pll: %s fails to enable\n", __func__, clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	if (pll_fractional_change_only(clk->pll, vco)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		/* program fractional part of NDIV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 			val = readl(pll->control_base + ctrl->ndiv_frac.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 			val &= ~(bit_mask(ctrl->ndiv_frac.width) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 				 ctrl->ndiv_frac.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 			val |= vco->ndiv_frac << ctrl->ndiv_frac.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			iproc_pll_write(pll, pll->control_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 					ctrl->ndiv_frac.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	/* put PLL in reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	__pll_put_in_reset(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	/* set PLL in user mode before modifying PLL controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (ctrl->flags & IPROC_CLK_PLL_USER_MODE_ON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		val = readl(pll->control_base + ctrl->macro_mode.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		val &= ~(bit_mask(ctrl->macro_mode.width) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 			ctrl->macro_mode.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		val |= PLL_USER_MODE << ctrl->macro_mode.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		iproc_pll_write(pll, pll->control_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 			ctrl->macro_mode.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.u_offset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	val = readl(pll->control_base + ctrl->vco_ctrl.l_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	if (rate >= VCO_LOW && rate < VCO_MID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		val |= (1 << PLL_VCO_LOW_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	if (rate < VCO_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		val &= ~(1 << PLL_VCO_HIGH_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		val |= (1 << PLL_VCO_HIGH_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.l_offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	/* program integer part of NDIV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	val = readl(pll->control_base + ctrl->ndiv_int.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	val &= ~(bit_mask(ctrl->ndiv_int.width) << ctrl->ndiv_int.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	val |= vco->ndiv_int << ctrl->ndiv_int.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	iproc_pll_write(pll, pll->control_base, ctrl->ndiv_int.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	/* program fractional part of NDIV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		val = readl(pll->control_base + ctrl->ndiv_frac.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		val &= ~(bit_mask(ctrl->ndiv_frac.width) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			 ctrl->ndiv_frac.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		val |= vco->ndiv_frac << ctrl->ndiv_frac.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		iproc_pll_write(pll, pll->control_base, ctrl->ndiv_frac.offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 				val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	/* program PDIV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	val = readl(pll->control_base + ctrl->pdiv.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	val &= ~(bit_mask(ctrl->pdiv.width) << ctrl->pdiv.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	val |= vco->pdiv << ctrl->pdiv.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	iproc_pll_write(pll, pll->control_base, ctrl->pdiv.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	__pll_bring_out_reset(pll, kp, ka, ki);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	ret = pll_wait_for_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		pr_err("%s: pll: %s failed to lock\n", __func__, clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static int iproc_pll_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	struct iproc_clk *clk = to_iproc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	struct iproc_pll *pll = clk->pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	return __pll_enable(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static void iproc_pll_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	struct iproc_clk *clk = to_iproc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	struct iproc_pll *pll = clk->pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	if (ctrl->flags & IPROC_CLK_AON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	__pll_disable(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static unsigned long iproc_pll_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 					   unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	struct iproc_clk *clk = to_iproc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	struct iproc_pll *pll = clk->pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	u64 ndiv, ndiv_int, ndiv_frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	unsigned int pdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	if (parent_rate == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	/* PLL needs to be locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	val = readl(pll->status_base + ctrl->status.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	if ((val & (1 << ctrl->status.shift)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	 * PLL output frequency =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	 * ((ndiv_int + ndiv_frac / 2^20) * (parent clock rate / pdiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	val = readl(pll->control_base + ctrl->ndiv_int.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	ndiv_int = (val >> ctrl->ndiv_int.shift) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		bit_mask(ctrl->ndiv_int.width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	ndiv = ndiv_int << 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		val = readl(pll->control_base + ctrl->ndiv_frac.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		ndiv_frac = (val >> ctrl->ndiv_frac.shift) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 			bit_mask(ctrl->ndiv_frac.width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		ndiv += ndiv_frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	val = readl(pll->control_base + ctrl->pdiv.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	rate = (ndiv * parent_rate) >> 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	if (pdiv == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		rate *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		rate /= pdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static int iproc_pll_determine_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	unsigned int  i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	struct iproc_clk *clk = to_iproc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	struct iproc_pll *pll = clk->pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	unsigned long  diff, best_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	unsigned int  best_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	if (req->rate == 0 || req->best_parent_rate == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	if (ctrl->flags & IPROC_CLK_PLL_CALC_PARAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		struct iproc_pll_vco_param vco_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		ret = pll_calc_param(req->rate, req->best_parent_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 					&vco_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		req->rate = vco_param.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	if (!pll->vco_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	best_diff = ULONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	for (i = 0; i < pll->num_vco_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		diff = abs(req->rate - pll->vco_param[i].rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		if (diff <= best_diff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 			best_diff = diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 			best_idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		/* break now if perfect match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		if (diff == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	req->rate = pll->vco_param[best_idx].rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static int iproc_pll_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	struct iproc_clk *clk = to_iproc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	struct iproc_pll *pll = clk->pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	struct iproc_pll_vco_param vco_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	int rate_index, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	if (ctrl->flags & IPROC_CLK_PLL_CALC_PARAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		ret = pll_calc_param(rate, parent_rate, &vco_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		rate_index = pll_get_rate_index(pll, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		if (rate_index < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 			return rate_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		vco_param = pll->vco_param[rate_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	ret = pll_set_rate(clk, &vco_param, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static const struct clk_ops iproc_pll_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	.enable = iproc_pll_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	.disable = iproc_pll_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	.recalc_rate = iproc_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	.determine_rate = iproc_pll_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	.set_rate = iproc_pll_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static int iproc_clk_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	struct iproc_clk *clk = to_iproc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	const struct iproc_clk_ctrl *ctrl = clk->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	struct iproc_pll *pll = clk->pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	/* channel enable is active low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	val = readl(pll->control_base + ctrl->enable.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	val &= ~(1 << ctrl->enable.enable_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	/* also make sure channel is not held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	val = readl(pll->control_base + ctrl->enable.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	val &= ~(1 << ctrl->enable.hold_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static void iproc_clk_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	struct iproc_clk *clk = to_iproc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	const struct iproc_clk_ctrl *ctrl = clk->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	struct iproc_pll *pll = clk->pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	if (ctrl->flags & IPROC_CLK_AON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	val = readl(pll->control_base + ctrl->enable.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	val |= 1 << ctrl->enable.enable_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	struct iproc_clk *clk = to_iproc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	const struct iproc_clk_ctrl *ctrl = clk->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	struct iproc_pll *pll = clk->pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	unsigned int mdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	if (parent_rate == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	val = readl(pll->control_base + ctrl->mdiv.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	mdiv = (val >> ctrl->mdiv.shift) & bit_mask(ctrl->mdiv.width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	if (mdiv == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		mdiv = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		rate = parent_rate / (mdiv * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		rate = parent_rate / mdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static int iproc_clk_determine_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	unsigned int bestdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	if (req->rate == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	if (req->rate == req->best_parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	bestdiv = DIV_ROUND_CLOSEST(req->best_parent_rate, req->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	if (bestdiv < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		req->rate = req->best_parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	if (bestdiv > 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 		bestdiv = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	req->rate = req->best_parent_rate / bestdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	struct iproc_clk *clk = to_iproc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	const struct iproc_clk_ctrl *ctrl = clk->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	struct iproc_pll *pll = clk->pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	unsigned int div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	if (rate == 0 || parent_rate == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	div = DIV_ROUND_CLOSEST(parent_rate, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		div /=  2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	if (div > 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	val = readl(pll->control_base + ctrl->mdiv.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	if (div == 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		val |= div << ctrl->mdiv.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	iproc_pll_write(pll, pll->control_base, ctrl->mdiv.offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static const struct clk_ops iproc_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	.enable = iproc_clk_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	.disable = iproc_clk_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	.recalc_rate = iproc_clk_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	.determine_rate = iproc_clk_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	.set_rate = iproc_clk_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)  * Some PLLs require the PLL SW override bit to be set before changes can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)  * applied to the PLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static void iproc_pll_sw_cfg(struct iproc_pll *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	const struct iproc_pll_ctrl *ctrl = pll->ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	if (ctrl->flags & IPROC_CLK_PLL_NEEDS_SW_CFG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 		u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 		val = readl(pll->control_base + ctrl->sw_ctrl.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		val |= BIT(ctrl->sw_ctrl.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 		iproc_pll_write(pll, pll->control_base, ctrl->sw_ctrl.offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 				val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) void iproc_pll_clk_setup(struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 			 const struct iproc_pll_ctrl *pll_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 			 const struct iproc_pll_vco_param *vco,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 			 unsigned int num_vco_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 			 const struct iproc_clk_ctrl *clk_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 			 unsigned int num_clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	struct iproc_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	struct iproc_clk *iclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	const char *parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	struct iproc_clk *iclk_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	struct clk_hw_onecell_data *clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	if (WARN_ON(!pll_ctrl) || WARN_ON(!clk_ctrl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	if (WARN_ON(!pll))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	clk_data = kzalloc(struct_size(clk_data, hws, num_clks), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	if (WARN_ON(!clk_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 		goto err_clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	clk_data->num = num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	iclk_array = kcalloc(num_clks, sizeof(struct iproc_clk), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	if (WARN_ON(!iclk_array))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		goto err_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	pll->control_base = of_iomap(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	if (WARN_ON(!pll->control_base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 		goto err_pll_iomap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	/* Some SoCs do not require the pwr_base, thus failing is not fatal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	pll->pwr_base = of_iomap(node, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	/* some PLLs require gating control at the top ASIU level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	if (pll_ctrl->flags & IPROC_CLK_PLL_ASIU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 		pll->asiu_base = of_iomap(node, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 		if (WARN_ON(!pll->asiu_base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 			goto err_asiu_iomap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	if (pll_ctrl->flags & IPROC_CLK_PLL_SPLIT_STAT_CTRL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 		/* Some SoCs have a split status/control.  If this does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 		 * exist, assume they are unified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		pll->status_base = of_iomap(node, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 		if (!pll->status_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 			goto err_status_iomap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 		pll->status_base = pll->control_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	/* initialize and register the PLL itself */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	pll->ctrl = pll_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	iclk = &iclk_array[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	iclk->pll = pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	init.name = node->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	init.ops = &iproc_pll_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	init.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	parent_name = of_clk_get_parent_name(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	init.parent_names = (parent_name ? &parent_name : NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	init.num_parents = (parent_name ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	iclk->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	if (vco) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 		pll->num_vco_entries = num_vco_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 		pll->vco_param = vco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	iproc_pll_sw_cfg(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	ret = clk_hw_register(NULL, &iclk->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	if (WARN_ON(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 		goto err_pll_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	clk_data->hws[0] = &iclk->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	/* now initialize and register all leaf clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	for (i = 1; i < num_clks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 		const char *clk_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 		memset(&init, 0, sizeof(init));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 		parent_name = node->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 		ret = of_property_read_string_index(node, "clock-output-names",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 						    i, &clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 		if (WARN_ON(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 			goto err_clk_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 		iclk = &iclk_array[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 		iclk->pll = pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 		iclk->ctrl = &clk_ctrl[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 		init.name = clk_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 		init.ops = &iproc_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 		init.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 		init.parent_names = (parent_name ? &parent_name : NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 		init.num_parents = (parent_name ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 		iclk->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 		ret = clk_hw_register(NULL, &iclk->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 		if (WARN_ON(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 			goto err_clk_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 		clk_data->hws[i] = &iclk->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 	ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	if (WARN_ON(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 		goto err_clk_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) err_clk_register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	while (--i >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 		clk_hw_unregister(clk_data->hws[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) err_pll_register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	if (pll->status_base != pll->control_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 		iounmap(pll->status_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) err_status_iomap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 	if (pll->asiu_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 		iounmap(pll->asiu_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) err_asiu_iomap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 	if (pll->pwr_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 		iounmap(pll->pwr_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	iounmap(pll->control_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) err_pll_iomap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	kfree(iclk_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) err_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 	kfree(clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) err_clk_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 	kfree(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }