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