0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/clk.h>
0009 #include <linux/clk-provider.h>
0010 #include <linux/slab.h>
0011 #include "clk-zynqmp.h"
0012
0013
0014
0015
0016
0017
0018
0019 struct zynqmp_pll {
0020 struct clk_hw hw;
0021 u32 clk_id;
0022 bool set_pll_mode;
0023 };
0024
0025 #define to_zynqmp_pll(_hw) container_of(_hw, struct zynqmp_pll, hw)
0026
0027 #define PLL_FBDIV_MIN 25
0028 #define PLL_FBDIV_MAX 125
0029
0030 #define PS_PLL_VCO_MIN 1500000000
0031 #define PS_PLL_VCO_MAX 3000000000UL
0032
0033 enum pll_mode {
0034 PLL_MODE_INT = 0,
0035 PLL_MODE_FRAC = 1,
0036 PLL_MODE_ERROR = 2,
0037 };
0038
0039 #define FRAC_OFFSET 0x8
0040 #define PLLFCFG_FRAC_EN BIT(31)
0041 #define FRAC_DIV BIT(16)
0042
0043
0044
0045
0046
0047
0048
0049 static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw)
0050 {
0051 struct zynqmp_pll *clk = to_zynqmp_pll(hw);
0052 u32 clk_id = clk->clk_id;
0053 const char *clk_name = clk_hw_get_name(hw);
0054 u32 ret_payload[PAYLOAD_ARG_CNT];
0055 int ret;
0056
0057 ret = zynqmp_pm_get_pll_frac_mode(clk_id, ret_payload);
0058 if (ret) {
0059 pr_debug("%s() PLL get frac mode failed for %s, ret = %d\n",
0060 __func__, clk_name, ret);
0061 return PLL_MODE_ERROR;
0062 }
0063
0064 return ret_payload[1];
0065 }
0066
0067
0068
0069
0070
0071
0072 static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on)
0073 {
0074 struct zynqmp_pll *clk = to_zynqmp_pll(hw);
0075 u32 clk_id = clk->clk_id;
0076 const char *clk_name = clk_hw_get_name(hw);
0077 int ret;
0078 u32 mode;
0079
0080 if (on)
0081 mode = PLL_MODE_FRAC;
0082 else
0083 mode = PLL_MODE_INT;
0084
0085 ret = zynqmp_pm_set_pll_frac_mode(clk_id, mode);
0086 if (ret)
0087 pr_debug("%s() PLL set frac mode failed for %s, ret = %d\n",
0088 __func__, clk_name, ret);
0089 else
0090 clk->set_pll_mode = true;
0091 }
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
0102 unsigned long *prate)
0103 {
0104 u32 fbdiv;
0105 long rate_div, f;
0106
0107
0108 rate_div = (rate * FRAC_DIV) / *prate;
0109 f = rate_div % FRAC_DIV;
0110 if (f) {
0111 if (rate > PS_PLL_VCO_MAX) {
0112 fbdiv = rate / PS_PLL_VCO_MAX;
0113 rate = rate / (fbdiv + 1);
0114 }
0115 if (rate < PS_PLL_VCO_MIN) {
0116 fbdiv = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate);
0117 rate = rate * fbdiv;
0118 }
0119 return rate;
0120 }
0121
0122 fbdiv = DIV_ROUND_CLOSEST(rate, *prate);
0123 fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
0124 return *prate * fbdiv;
0125 }
0126
0127
0128
0129
0130
0131
0132
0133
0134 static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,
0135 unsigned long parent_rate)
0136 {
0137 struct zynqmp_pll *clk = to_zynqmp_pll(hw);
0138 u32 clk_id = clk->clk_id;
0139 const char *clk_name = clk_hw_get_name(hw);
0140 u32 fbdiv, data;
0141 unsigned long rate, frac;
0142 u32 ret_payload[PAYLOAD_ARG_CNT];
0143 int ret;
0144 enum pll_mode mode;
0145
0146 ret = zynqmp_pm_clock_getdivider(clk_id, &fbdiv);
0147 if (ret) {
0148 pr_debug("%s() get divider failed for %s, ret = %d\n",
0149 __func__, clk_name, ret);
0150 return 0ul;
0151 }
0152
0153 mode = zynqmp_pll_get_mode(hw);
0154 if (mode == PLL_MODE_ERROR)
0155 return 0ul;
0156
0157 rate = parent_rate * fbdiv;
0158 if (mode == PLL_MODE_FRAC) {
0159 zynqmp_pm_get_pll_frac_data(clk_id, ret_payload);
0160 data = ret_payload[1];
0161 frac = (parent_rate * data) / FRAC_DIV;
0162 rate = rate + frac;
0163 }
0164
0165 return rate;
0166 }
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178 static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
0179 unsigned long parent_rate)
0180 {
0181 struct zynqmp_pll *clk = to_zynqmp_pll(hw);
0182 u32 clk_id = clk->clk_id;
0183 const char *clk_name = clk_hw_get_name(hw);
0184 u32 fbdiv;
0185 long rate_div, frac, m, f;
0186 int ret;
0187
0188 rate_div = (rate * FRAC_DIV) / parent_rate;
0189 f = rate_div % FRAC_DIV;
0190 zynqmp_pll_set_mode(hw, !!f);
0191
0192 if (f) {
0193 m = rate_div / FRAC_DIV;
0194 m = clamp_t(u32, m, (PLL_FBDIV_MIN), (PLL_FBDIV_MAX));
0195 rate = parent_rate * m;
0196 frac = (parent_rate * f) / FRAC_DIV;
0197
0198 ret = zynqmp_pm_clock_setdivider(clk_id, m);
0199 if (ret == -EUSERS)
0200 WARN(1, "More than allowed devices are using the %s, which is forbidden\n",
0201 clk_name);
0202 else if (ret)
0203 pr_debug("%s() set divider failed for %s, ret = %d\n",
0204 __func__, clk_name, ret);
0205 zynqmp_pm_set_pll_frac_data(clk_id, f);
0206
0207 return rate + frac;
0208 }
0209
0210 fbdiv = DIV_ROUND_CLOSEST(rate, parent_rate);
0211 fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
0212 ret = zynqmp_pm_clock_setdivider(clk_id, fbdiv);
0213 if (ret)
0214 pr_debug("%s() set divider failed for %s, ret = %d\n",
0215 __func__, clk_name, ret);
0216
0217 return parent_rate * fbdiv;
0218 }
0219
0220
0221
0222
0223
0224
0225
0226 static int zynqmp_pll_is_enabled(struct clk_hw *hw)
0227 {
0228 struct zynqmp_pll *clk = to_zynqmp_pll(hw);
0229 const char *clk_name = clk_hw_get_name(hw);
0230 u32 clk_id = clk->clk_id;
0231 unsigned int state;
0232 int ret;
0233
0234 ret = zynqmp_pm_clock_getstate(clk_id, &state);
0235 if (ret) {
0236 pr_debug("%s() clock get state failed for %s, ret = %d\n",
0237 __func__, clk_name, ret);
0238 return -EIO;
0239 }
0240
0241 return state ? 1 : 0;
0242 }
0243
0244
0245
0246
0247
0248
0249
0250 static int zynqmp_pll_enable(struct clk_hw *hw)
0251 {
0252 struct zynqmp_pll *clk = to_zynqmp_pll(hw);
0253 const char *clk_name = clk_hw_get_name(hw);
0254 u32 clk_id = clk->clk_id;
0255 int ret;
0256
0257
0258
0259
0260
0261 if (zynqmp_pll_is_enabled(hw) && (!clk->set_pll_mode))
0262 return 0;
0263
0264 clk->set_pll_mode = false;
0265
0266 ret = zynqmp_pm_clock_enable(clk_id);
0267 if (ret)
0268 pr_debug("%s() clock enable failed for %s, ret = %d\n",
0269 __func__, clk_name, ret);
0270
0271 return ret;
0272 }
0273
0274
0275
0276
0277
0278 static void zynqmp_pll_disable(struct clk_hw *hw)
0279 {
0280 struct zynqmp_pll *clk = to_zynqmp_pll(hw);
0281 const char *clk_name = clk_hw_get_name(hw);
0282 u32 clk_id = clk->clk_id;
0283 int ret;
0284
0285 if (!zynqmp_pll_is_enabled(hw))
0286 return;
0287
0288 ret = zynqmp_pm_clock_disable(clk_id);
0289 if (ret)
0290 pr_debug("%s() clock disable failed for %s, ret = %d\n",
0291 __func__, clk_name, ret);
0292 }
0293
0294 static const struct clk_ops zynqmp_pll_ops = {
0295 .enable = zynqmp_pll_enable,
0296 .disable = zynqmp_pll_disable,
0297 .is_enabled = zynqmp_pll_is_enabled,
0298 .round_rate = zynqmp_pll_round_rate,
0299 .recalc_rate = zynqmp_pll_recalc_rate,
0300 .set_rate = zynqmp_pll_set_rate,
0301 };
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313 struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id,
0314 const char * const *parents,
0315 u8 num_parents,
0316 const struct clock_topology *nodes)
0317 {
0318 struct zynqmp_pll *pll;
0319 struct clk_hw *hw;
0320 struct clk_init_data init;
0321 int ret;
0322
0323 init.name = name;
0324 init.ops = &zynqmp_pll_ops;
0325
0326 init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag);
0327
0328 init.parent_names = parents;
0329 init.num_parents = 1;
0330
0331 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
0332 if (!pll)
0333 return ERR_PTR(-ENOMEM);
0334
0335 pll->hw.init = &init;
0336 pll->clk_id = clk_id;
0337
0338 hw = &pll->hw;
0339 ret = clk_hw_register(NULL, hw);
0340 if (ret) {
0341 kfree(pll);
0342 return ERR_PTR(ret);
0343 }
0344
0345 clk_hw_set_rate_range(hw, PS_PLL_VCO_MIN, PS_PLL_VCO_MAX);
0346
0347 return hw;
0348 }