1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2018, The Linux Foundation. All rights reserved. 3 4 #include <linux/kernel.h> 5 #include <linux/export.h> 6 #include <linux/regmap.h> 7 #include <linux/delay.h> 8 #include <linux/err.h> 9 #include <linux/clk-provider.h> 10 #include <linux/spinlock.h> 11 12 #include "clk-regmap.h" 13 #include "clk-hfpll.h" 14 15 #define PLL_OUTCTRL BIT(0) 16 #define PLL_BYPASSNL BIT(1) 17 #define PLL_RESET_N BIT(2) 18 19 /* Initialize a HFPLL at a given rate and enable it. */ 20 static void __clk_hfpll_init_once(struct clk_hw *hw) 21 { 22 struct clk_hfpll *h = to_clk_hfpll(hw); 23 struct hfpll_data const *hd = h->d; 24 struct regmap *regmap = h->clkr.regmap; 25 26 if (likely(h->init_done)) 27 return; 28 29 /* Configure PLL parameters for integer mode. */ 30 if (hd->config_val) 31 regmap_write(regmap, hd->config_reg, hd->config_val); 32 regmap_write(regmap, hd->m_reg, 0); 33 regmap_write(regmap, hd->n_reg, 1); 34 35 if (hd->user_reg) { 36 u32 regval = hd->user_val; 37 unsigned long rate; 38 39 rate = clk_hw_get_rate(hw); 40 41 /* Pick the right VCO. */ 42 if (hd->user_vco_mask && rate > hd->low_vco_max_rate) 43 regval |= hd->user_vco_mask; 44 regmap_write(regmap, hd->user_reg, regval); 45 } 46 47 if (hd->droop_reg) 48 regmap_write(regmap, hd->droop_reg, hd->droop_val); 49 50 h->init_done = true; 51 } 52 53 static void __clk_hfpll_enable(struct clk_hw *hw) 54 { 55 struct clk_hfpll *h = to_clk_hfpll(hw); 56 struct hfpll_data const *hd = h->d; 57 struct regmap *regmap = h->clkr.regmap; 58 u32 val; 59 60 __clk_hfpll_init_once(hw); 61 62 /* Disable PLL bypass mode. */ 63 regmap_update_bits(regmap, hd->mode_reg, PLL_BYPASSNL, PLL_BYPASSNL); 64 65 /* 66 * H/W requires a 5us delay between disabling the bypass and 67 * de-asserting the reset. Delay 10us just to be safe. 68 */ 69 udelay(10); 70 71 /* De-assert active-low PLL reset. */ 72 regmap_update_bits(regmap, hd->mode_reg, PLL_RESET_N, PLL_RESET_N); 73 74 /* Wait for PLL to lock. */ 75 if (hd->status_reg) 76 /* 77 * Busy wait. Should never timeout, we add a timeout to 78 * prevent any sort of stall. 79 */ 80 regmap_read_poll_timeout(regmap, hd->status_reg, val, 81 !(val & BIT(hd->lock_bit)), 0, 82 100 * USEC_PER_MSEC); 83 else 84 udelay(60); 85 86 /* Enable PLL output. */ 87 regmap_update_bits(regmap, hd->mode_reg, PLL_OUTCTRL, PLL_OUTCTRL); 88 } 89 90 /* Enable an already-configured HFPLL. */ 91 static int clk_hfpll_enable(struct clk_hw *hw) 92 { 93 unsigned long flags; 94 struct clk_hfpll *h = to_clk_hfpll(hw); 95 struct hfpll_data const *hd = h->d; 96 struct regmap *regmap = h->clkr.regmap; 97 u32 mode; 98 99 spin_lock_irqsave(&h->lock, flags); 100 regmap_read(regmap, hd->mode_reg, &mode); 101 if (!(mode & (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL))) 102 __clk_hfpll_enable(hw); 103 spin_unlock_irqrestore(&h->lock, flags); 104 105 return 0; 106 } 107 108 static void __clk_hfpll_disable(struct clk_hfpll *h) 109 { 110 struct hfpll_data const *hd = h->d; 111 struct regmap *regmap = h->clkr.regmap; 112 113 /* 114 * Disable the PLL output, disable test mode, enable the bypass mode, 115 * and assert the reset. 116 */ 117 regmap_update_bits(regmap, hd->mode_reg, 118 PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL, 0); 119 } 120 121 static void clk_hfpll_disable(struct clk_hw *hw) 122 { 123 struct clk_hfpll *h = to_clk_hfpll(hw); 124 unsigned long flags; 125 126 spin_lock_irqsave(&h->lock, flags); 127 __clk_hfpll_disable(h); 128 spin_unlock_irqrestore(&h->lock, flags); 129 } 130 131 static long clk_hfpll_round_rate(struct clk_hw *hw, unsigned long rate, 132 unsigned long *parent_rate) 133 { 134 struct clk_hfpll *h = to_clk_hfpll(hw); 135 struct hfpll_data const *hd = h->d; 136 unsigned long rrate; 137 138 rate = clamp(rate, hd->min_rate, hd->max_rate); 139 140 rrate = DIV_ROUND_UP(rate, *parent_rate) * *parent_rate; 141 if (rrate > hd->max_rate) 142 rrate -= *parent_rate; 143 144 return rrate; 145 } 146 147 /* 148 * For optimization reasons, assumes no downstream clocks are actively using 149 * it. 150 */ 151 static int clk_hfpll_set_rate(struct clk_hw *hw, unsigned long rate, 152 unsigned long parent_rate) 153 { 154 struct clk_hfpll *h = to_clk_hfpll(hw); 155 struct hfpll_data const *hd = h->d; 156 struct regmap *regmap = h->clkr.regmap; 157 unsigned long flags; 158 u32 l_val, val; 159 bool enabled; 160 161 l_val = rate / parent_rate; 162 163 spin_lock_irqsave(&h->lock, flags); 164 165 enabled = __clk_is_enabled(hw->clk); 166 if (enabled) 167 __clk_hfpll_disable(h); 168 169 /* Pick the right VCO. */ 170 if (hd->user_reg && hd->user_vco_mask) { 171 regmap_read(regmap, hd->user_reg, &val); 172 if (rate <= hd->low_vco_max_rate) 173 val &= ~hd->user_vco_mask; 174 else 175 val |= hd->user_vco_mask; 176 regmap_write(regmap, hd->user_reg, val); 177 } 178 179 regmap_write(regmap, hd->l_reg, l_val); 180 181 if (enabled) 182 __clk_hfpll_enable(hw); 183 184 spin_unlock_irqrestore(&h->lock, flags); 185 186 return 0; 187 } 188 189 static unsigned long clk_hfpll_recalc_rate(struct clk_hw *hw, 190 unsigned long parent_rate) 191 { 192 struct clk_hfpll *h = to_clk_hfpll(hw); 193 struct hfpll_data const *hd = h->d; 194 struct regmap *regmap = h->clkr.regmap; 195 u32 l_val; 196 197 regmap_read(regmap, hd->l_reg, &l_val); 198 199 return l_val * parent_rate; 200 } 201 202 static int clk_hfpll_init(struct clk_hw *hw) 203 { 204 struct clk_hfpll *h = to_clk_hfpll(hw); 205 struct hfpll_data const *hd = h->d; 206 struct regmap *regmap = h->clkr.regmap; 207 u32 mode, status; 208 209 regmap_read(regmap, hd->mode_reg, &mode); 210 if (mode != (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)) { 211 __clk_hfpll_init_once(hw); 212 return 0; 213 } 214 215 if (hd->status_reg) { 216 regmap_read(regmap, hd->status_reg, &status); 217 if (!(status & BIT(hd->lock_bit))) { 218 WARN(1, "HFPLL %s is ON, but not locked!\n", 219 __clk_get_name(hw->clk)); 220 clk_hfpll_disable(hw); 221 __clk_hfpll_init_once(hw); 222 } 223 } 224 225 return 0; 226 } 227 228 static int hfpll_is_enabled(struct clk_hw *hw) 229 { 230 struct clk_hfpll *h = to_clk_hfpll(hw); 231 struct hfpll_data const *hd = h->d; 232 struct regmap *regmap = h->clkr.regmap; 233 u32 mode; 234 235 regmap_read(regmap, hd->mode_reg, &mode); 236 mode &= 0x7; 237 return mode == (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL); 238 } 239 240 const struct clk_ops clk_ops_hfpll = { 241 .enable = clk_hfpll_enable, 242 .disable = clk_hfpll_disable, 243 .is_enabled = hfpll_is_enabled, 244 .round_rate = clk_hfpll_round_rate, 245 .set_rate = clk_hfpll_set_rate, 246 .recalc_rate = clk_hfpll_recalc_rate, 247 .init = clk_hfpll_init, 248 }; 249 EXPORT_SYMBOL_GPL(clk_ops_hfpll); 250