^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) }