1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Zynq UltraScale+ MPSoC PLL driver 4 * 5 * Copyright (C) 2016-2018 Xilinx 6 */ 7 8 #include <linux/clk.h> 9 #include <linux/clk-provider.h> 10 #include <linux/slab.h> 11 #include "clk-zynqmp.h" 12 13 /** 14 * struct zynqmp_pll - PLL clock 15 * @hw: Handle between common and hardware-specific interfaces 16 * @clk_id: PLL clock ID 17 */ 18 struct zynqmp_pll { 19 struct clk_hw hw; 20 u32 clk_id; 21 }; 22 23 #define to_zynqmp_pll(_hw) container_of(_hw, struct zynqmp_pll, hw) 24 25 #define PLL_FBDIV_MIN 25 26 #define PLL_FBDIV_MAX 125 27 28 #define PS_PLL_VCO_MIN 1500000000 29 #define PS_PLL_VCO_MAX 3000000000UL 30 31 enum pll_mode { 32 PLL_MODE_INT, 33 PLL_MODE_FRAC, 34 }; 35 36 #define FRAC_OFFSET 0x8 37 #define PLLFCFG_FRAC_EN BIT(31) 38 #define FRAC_DIV BIT(16) /* 2^16 */ 39 40 /** 41 * zynqmp_pll_get_mode() - Get mode of PLL 42 * @hw: Handle between common and hardware-specific interfaces 43 * 44 * Return: Mode of PLL 45 */ 46 static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw) 47 { 48 struct zynqmp_pll *clk = to_zynqmp_pll(hw); 49 u32 clk_id = clk->clk_id; 50 const char *clk_name = clk_hw_get_name(hw); 51 u32 ret_payload[PAYLOAD_ARG_CNT]; 52 int ret; 53 54 ret = zynqmp_pm_get_pll_frac_mode(clk_id, ret_payload); 55 if (ret) 56 pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n", 57 __func__, clk_name, ret); 58 59 return ret_payload[1]; 60 } 61 62 /** 63 * zynqmp_pll_set_mode() - Set the PLL mode 64 * @hw: Handle between common and hardware-specific interfaces 65 * @on: Flag to determine the mode 66 */ 67 static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on) 68 { 69 struct zynqmp_pll *clk = to_zynqmp_pll(hw); 70 u32 clk_id = clk->clk_id; 71 const char *clk_name = clk_hw_get_name(hw); 72 int ret; 73 u32 mode; 74 75 if (on) 76 mode = PLL_MODE_FRAC; 77 else 78 mode = PLL_MODE_INT; 79 80 ret = zynqmp_pm_set_pll_frac_mode(clk_id, mode); 81 if (ret) 82 pr_warn_once("%s() PLL set frac mode failed for %s, ret = %d\n", 83 __func__, clk_name, ret); 84 } 85 86 /** 87 * zynqmp_pll_round_rate() - Round a clock frequency 88 * @hw: Handle between common and hardware-specific interfaces 89 * @rate: Desired clock frequency 90 * @prate: Clock frequency of parent clock 91 * 92 * Return: Frequency closest to @rate the hardware can generate 93 */ 94 static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate, 95 unsigned long *prate) 96 { 97 u32 fbdiv; 98 long rate_div, f; 99 100 /* Enable the fractional mode if needed */ 101 rate_div = (rate * FRAC_DIV) / *prate; 102 f = rate_div % FRAC_DIV; 103 zynqmp_pll_set_mode(hw, !!f); 104 105 if (zynqmp_pll_get_mode(hw) == PLL_MODE_FRAC) { 106 if (rate > PS_PLL_VCO_MAX) { 107 fbdiv = rate / PS_PLL_VCO_MAX; 108 rate = rate / (fbdiv + 1); 109 } 110 if (rate < PS_PLL_VCO_MIN) { 111 fbdiv = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate); 112 rate = rate * fbdiv; 113 } 114 return rate; 115 } 116 117 fbdiv = DIV_ROUND_CLOSEST(rate, *prate); 118 fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX); 119 return *prate * fbdiv; 120 } 121 122 /** 123 * zynqmp_pll_recalc_rate() - Recalculate clock frequency 124 * @hw: Handle between common and hardware-specific interfaces 125 * @parent_rate: Clock frequency of parent clock 126 * 127 * Return: Current clock frequency 128 */ 129 static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw, 130 unsigned long parent_rate) 131 { 132 struct zynqmp_pll *clk = to_zynqmp_pll(hw); 133 u32 clk_id = clk->clk_id; 134 const char *clk_name = clk_hw_get_name(hw); 135 u32 fbdiv, data; 136 unsigned long rate, frac; 137 u32 ret_payload[PAYLOAD_ARG_CNT]; 138 int ret; 139 140 ret = zynqmp_pm_clock_getdivider(clk_id, &fbdiv); 141 if (ret) 142 pr_warn_once("%s() get divider failed for %s, ret = %d\n", 143 __func__, clk_name, ret); 144 145 rate = parent_rate * fbdiv; 146 if (zynqmp_pll_get_mode(hw) == PLL_MODE_FRAC) { 147 zynqmp_pm_get_pll_frac_data(clk_id, ret_payload); 148 data = ret_payload[1]; 149 frac = (parent_rate * data) / FRAC_DIV; 150 rate = rate + frac; 151 } 152 153 return rate; 154 } 155 156 /** 157 * zynqmp_pll_set_rate() - Set rate of PLL 158 * @hw: Handle between common and hardware-specific interfaces 159 * @rate: Frequency of clock to be set 160 * @parent_rate: Clock frequency of parent clock 161 * 162 * Set PLL divider to set desired rate. 163 * 164 * Returns: rate which is set on success else error code 165 */ 166 static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate, 167 unsigned long parent_rate) 168 { 169 struct zynqmp_pll *clk = to_zynqmp_pll(hw); 170 u32 clk_id = clk->clk_id; 171 const char *clk_name = clk_hw_get_name(hw); 172 u32 fbdiv; 173 long rate_div, frac, m, f; 174 int ret; 175 176 if (zynqmp_pll_get_mode(hw) == PLL_MODE_FRAC) { 177 rate_div = (rate * FRAC_DIV) / parent_rate; 178 m = rate_div / FRAC_DIV; 179 f = rate_div % FRAC_DIV; 180 m = clamp_t(u32, m, (PLL_FBDIV_MIN), (PLL_FBDIV_MAX)); 181 rate = parent_rate * m; 182 frac = (parent_rate * f) / FRAC_DIV; 183 184 ret = zynqmp_pm_clock_setdivider(clk_id, m); 185 if (ret == -EUSERS) 186 WARN(1, "More than allowed devices are using the %s, which is forbidden\n", 187 clk_name); 188 else if (ret) 189 pr_warn_once("%s() set divider failed for %s, ret = %d\n", 190 __func__, clk_name, ret); 191 zynqmp_pm_set_pll_frac_data(clk_id, f); 192 193 return rate + frac; 194 } 195 196 fbdiv = DIV_ROUND_CLOSEST(rate, parent_rate); 197 fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX); 198 ret = zynqmp_pm_clock_setdivider(clk_id, fbdiv); 199 if (ret) 200 pr_warn_once("%s() set divider failed for %s, ret = %d\n", 201 __func__, clk_name, ret); 202 203 return parent_rate * fbdiv; 204 } 205 206 /** 207 * zynqmp_pll_is_enabled() - Check if a clock is enabled 208 * @hw: Handle between common and hardware-specific interfaces 209 * 210 * Return: 1 if the clock is enabled, 0 otherwise 211 */ 212 static int zynqmp_pll_is_enabled(struct clk_hw *hw) 213 { 214 struct zynqmp_pll *clk = to_zynqmp_pll(hw); 215 const char *clk_name = clk_hw_get_name(hw); 216 u32 clk_id = clk->clk_id; 217 unsigned int state; 218 int ret; 219 220 ret = zynqmp_pm_clock_getstate(clk_id, &state); 221 if (ret) { 222 pr_warn_once("%s() clock get state failed for %s, ret = %d\n", 223 __func__, clk_name, ret); 224 return -EIO; 225 } 226 227 return state ? 1 : 0; 228 } 229 230 /** 231 * zynqmp_pll_enable() - Enable clock 232 * @hw: Handle between common and hardware-specific interfaces 233 * 234 * Return: 0 on success else error code 235 */ 236 static int zynqmp_pll_enable(struct clk_hw *hw) 237 { 238 struct zynqmp_pll *clk = to_zynqmp_pll(hw); 239 const char *clk_name = clk_hw_get_name(hw); 240 u32 clk_id = clk->clk_id; 241 int ret; 242 243 if (zynqmp_pll_is_enabled(hw)) 244 return 0; 245 246 ret = zynqmp_pm_clock_enable(clk_id); 247 if (ret) 248 pr_warn_once("%s() clock enable failed for %s, ret = %d\n", 249 __func__, clk_name, ret); 250 251 return ret; 252 } 253 254 /** 255 * zynqmp_pll_disable() - Disable clock 256 * @hw: Handle between common and hardware-specific interfaces 257 */ 258 static void zynqmp_pll_disable(struct clk_hw *hw) 259 { 260 struct zynqmp_pll *clk = to_zynqmp_pll(hw); 261 const char *clk_name = clk_hw_get_name(hw); 262 u32 clk_id = clk->clk_id; 263 int ret; 264 265 if (!zynqmp_pll_is_enabled(hw)) 266 return; 267 268 ret = zynqmp_pm_clock_disable(clk_id); 269 if (ret) 270 pr_warn_once("%s() clock disable failed for %s, ret = %d\n", 271 __func__, clk_name, ret); 272 } 273 274 static const struct clk_ops zynqmp_pll_ops = { 275 .enable = zynqmp_pll_enable, 276 .disable = zynqmp_pll_disable, 277 .is_enabled = zynqmp_pll_is_enabled, 278 .round_rate = zynqmp_pll_round_rate, 279 .recalc_rate = zynqmp_pll_recalc_rate, 280 .set_rate = zynqmp_pll_set_rate, 281 }; 282 283 /** 284 * zynqmp_clk_register_pll() - Register PLL with the clock framework 285 * @name: PLL name 286 * @clk_id: Clock ID 287 * @parents: Name of this clock's parents 288 * @num_parents: Number of parents 289 * @nodes: Clock topology node 290 * 291 * Return: clock hardware to the registered clock 292 */ 293 struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id, 294 const char * const *parents, 295 u8 num_parents, 296 const struct clock_topology *nodes) 297 { 298 struct zynqmp_pll *pll; 299 struct clk_hw *hw; 300 struct clk_init_data init; 301 int ret; 302 303 init.name = name; 304 init.ops = &zynqmp_pll_ops; 305 init.flags = nodes->flag; 306 init.parent_names = parents; 307 init.num_parents = 1; 308 309 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 310 if (!pll) 311 return ERR_PTR(-ENOMEM); 312 313 pll->hw.init = &init; 314 pll->clk_id = clk_id; 315 316 hw = &pll->hw; 317 ret = clk_hw_register(NULL, hw); 318 if (ret) { 319 kfree(pll); 320 return ERR_PTR(ret); 321 } 322 323 clk_hw_set_rate_range(hw, PS_PLL_VCO_MIN, PS_PLL_VCO_MAX); 324 if (ret < 0) 325 pr_err("%s:ERROR clk_set_rate_range failed %d\n", name, ret); 326 327 return hw; 328 } 329