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