1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2023 Nuvoton Technology Corp. 4 * Author: Chi-Fang Li <cfli0@nuvoton.com> 5 */ 6 7 #include <linux/bitfield.h> 8 #include <linux/clk-provider.h> 9 #include <linux/container_of.h> 10 #include <linux/device.h> 11 #include <linux/io.h> 12 #include <linux/kernel.h> 13 #include <linux/math64.h> 14 #include <linux/slab.h> 15 #include <linux/units.h> 16 #include <dt-bindings/clock/nuvoton,ma35d1-clk.h> 17 18 #include "clk-ma35d1.h" 19 20 /* PLL frequency limits */ 21 #define PLL_FREF_MAX_FREQ (200 * HZ_PER_MHZ) 22 #define PLL_FREF_MIN_FREQ (1 * HZ_PER_MHZ) 23 #define PLL_FREF_M_MAX_FREQ (40 * HZ_PER_MHZ) 24 #define PLL_FREF_M_MIN_FREQ (10 * HZ_PER_MHZ) 25 #define PLL_FCLK_MAX_FREQ (2400 * HZ_PER_MHZ) 26 #define PLL_FCLK_MIN_FREQ (600 * HZ_PER_MHZ) 27 #define PLL_FCLKO_MAX_FREQ (2400 * HZ_PER_MHZ) 28 #define PLL_FCLKO_MIN_FREQ (85700 * HZ_PER_KHZ) 29 #define PLL_SS_RATE 0x77 30 #define PLL_SLOPE 0x58CFA 31 32 #define REG_PLL_CTL0_OFFSET 0x0 33 #define REG_PLL_CTL1_OFFSET 0x4 34 #define REG_PLL_CTL2_OFFSET 0x8 35 36 /* bit fields for REG_CLK_PLL0CTL0, which is SMIC PLL design */ 37 #define SPLL0_CTL0_FBDIV GENMASK(7, 0) 38 #define SPLL0_CTL0_INDIV GENMASK(11, 8) 39 #define SPLL0_CTL0_OUTDIV GENMASK(13, 12) 40 #define SPLL0_CTL0_PD BIT(16) 41 #define SPLL0_CTL0_BP BIT(17) 42 43 /* bit fields for REG_CLK_PLLxCTL0 ~ REG_CLK_PLLxCTL2, where x = 2 ~ 5 */ 44 #define PLL_CTL0_FBDIV GENMASK(10, 0) 45 #define PLL_CTL0_INDIV GENMASK(17, 12) 46 #define PLL_CTL0_MODE GENMASK(19, 18) 47 #define PLL_CTL0_SSRATE GENMASK(30, 20) 48 #define PLL_CTL1_PD BIT(0) 49 #define PLL_CTL1_BP BIT(1) 50 #define PLL_CTL1_OUTDIV GENMASK(6, 4) 51 #define PLL_CTL1_FRAC GENMASK(31, 24) 52 #define PLL_CTL2_SLOPE GENMASK(23, 0) 53 54 #define INDIV_MIN 1 55 #define INDIV_MAX 63 56 #define FBDIV_MIN 16 57 #define FBDIV_MAX 2047 58 #define FBDIV_FRAC_MIN 1600 59 #define FBDIV_FRAC_MAX 204700 60 #define OUTDIV_MIN 1 61 #define OUTDIV_MAX 7 62 63 #define PLL_MODE_INT 0 64 #define PLL_MODE_FRAC 1 65 #define PLL_MODE_SS 2 66 67 struct ma35d1_clk_pll { 68 struct clk_hw hw; 69 u32 id; 70 u8 mode; 71 void __iomem *ctl0_base; 72 void __iomem *ctl1_base; 73 void __iomem *ctl2_base; 74 }; 75 76 static inline struct ma35d1_clk_pll *to_ma35d1_clk_pll(struct clk_hw *_hw) 77 { 78 return container_of(_hw, struct ma35d1_clk_pll, hw); 79 } 80 81 static unsigned long ma35d1_calc_smic_pll_freq(u32 pll0_ctl0, 82 unsigned long parent_rate) 83 { 84 u32 m, n, p, outdiv; 85 u64 pll_freq; 86 87 if (pll0_ctl0 & SPLL0_CTL0_BP) 88 return parent_rate; 89 90 n = FIELD_GET(SPLL0_CTL0_FBDIV, pll0_ctl0); 91 m = FIELD_GET(SPLL0_CTL0_INDIV, pll0_ctl0); 92 p = FIELD_GET(SPLL0_CTL0_OUTDIV, pll0_ctl0); 93 outdiv = 1 << p; 94 pll_freq = (u64)parent_rate * n; 95 div_u64(pll_freq, m * outdiv); 96 return pll_freq; 97 } 98 99 static unsigned long ma35d1_calc_pll_freq(u8 mode, u32 *reg_ctl, unsigned long parent_rate) 100 { 101 unsigned long pll_freq, x; 102 u32 m, n, p; 103 104 if (reg_ctl[1] & PLL_CTL1_BP) 105 return parent_rate; 106 107 n = FIELD_GET(PLL_CTL0_FBDIV, reg_ctl[0]); 108 m = FIELD_GET(PLL_CTL0_INDIV, reg_ctl[0]); 109 p = FIELD_GET(PLL_CTL1_OUTDIV, reg_ctl[1]); 110 111 if (mode == PLL_MODE_INT) { 112 pll_freq = (u64)parent_rate * n; 113 div_u64(pll_freq, m * p); 114 } else { 115 x = FIELD_GET(PLL_CTL1_FRAC, reg_ctl[1]); 116 /* 2 decimal places floating to integer (ex. 1.23 to 123) */ 117 n = n * 100 + ((x * 100) / FIELD_MAX(PLL_CTL1_FRAC)); 118 pll_freq = div_u64(parent_rate * n, 100 * m * p); 119 } 120 return pll_freq; 121 } 122 123 static int ma35d1_pll_find_closest(struct ma35d1_clk_pll *pll, unsigned long rate, 124 unsigned long parent_rate, u32 *reg_ctl, 125 unsigned long *freq) 126 { 127 unsigned long min_diff = ULONG_MAX; 128 int fbdiv_min, fbdiv_max; 129 int p, m, n; 130 131 *freq = 0; 132 if (rate < PLL_FCLKO_MIN_FREQ || rate > PLL_FCLKO_MAX_FREQ) 133 return -EINVAL; 134 135 if (pll->mode == PLL_MODE_INT) { 136 fbdiv_min = FBDIV_MIN; 137 fbdiv_max = FBDIV_MAX; 138 } else { 139 fbdiv_min = FBDIV_FRAC_MIN; 140 fbdiv_max = FBDIV_FRAC_MAX; 141 } 142 143 for (m = INDIV_MIN; m <= INDIV_MAX; m++) { 144 for (n = fbdiv_min; n <= fbdiv_max; n++) { 145 for (p = OUTDIV_MIN; p <= OUTDIV_MAX; p++) { 146 unsigned long tmp, fout, fclk, diff; 147 148 tmp = div_u64(parent_rate, m); 149 if (tmp < PLL_FREF_M_MIN_FREQ || 150 tmp > PLL_FREF_M_MAX_FREQ) 151 continue; /* constrain */ 152 153 fclk = div_u64(parent_rate * n, m); 154 /* for 2 decimal places */ 155 if (pll->mode != PLL_MODE_INT) 156 fclk = div_u64(fclk, 100); 157 158 if (fclk < PLL_FCLK_MIN_FREQ || 159 fclk > PLL_FCLK_MAX_FREQ) 160 continue; /* constrain */ 161 162 fout = div_u64(fclk, p); 163 if (fout < PLL_FCLKO_MIN_FREQ || 164 fout > PLL_FCLKO_MAX_FREQ) 165 continue; /* constrain */ 166 167 diff = abs(rate - fout); 168 if (diff < min_diff) { 169 reg_ctl[0] = FIELD_PREP(PLL_CTL0_INDIV, m) | 170 FIELD_PREP(PLL_CTL0_FBDIV, n); 171 reg_ctl[1] = FIELD_PREP(PLL_CTL1_OUTDIV, p); 172 *freq = fout; 173 min_diff = diff; 174 if (min_diff == 0) 175 break; 176 } 177 } 178 } 179 } 180 if (*freq == 0) 181 return -EINVAL; /* cannot find even one valid setting */ 182 return 0; 183 } 184 185 static int ma35d1_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, 186 unsigned long parent_rate) 187 { 188 struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw); 189 u32 reg_ctl[3] = { 0 }; 190 unsigned long pll_freq; 191 int ret; 192 193 if (parent_rate < PLL_FREF_MIN_FREQ || parent_rate > PLL_FREF_MAX_FREQ) 194 return -EINVAL; 195 196 ret = ma35d1_pll_find_closest(pll, rate, parent_rate, reg_ctl, &pll_freq); 197 if (ret != 0) 198 return ret; 199 200 switch (pll->mode) { 201 case PLL_MODE_INT: 202 reg_ctl[0] |= FIELD_PREP(PLL_CTL0_MODE, PLL_MODE_INT); 203 break; 204 case PLL_MODE_FRAC: 205 reg_ctl[0] |= FIELD_PREP(PLL_CTL0_MODE, PLL_MODE_FRAC); 206 break; 207 case PLL_MODE_SS: 208 reg_ctl[0] |= FIELD_PREP(PLL_CTL0_MODE, PLL_MODE_SS) | 209 FIELD_PREP(PLL_CTL0_SSRATE, PLL_SS_RATE); 210 reg_ctl[2] = FIELD_PREP(PLL_CTL2_SLOPE, PLL_SLOPE); 211 break; 212 } 213 reg_ctl[1] |= PLL_CTL1_PD; 214 215 writel_relaxed(reg_ctl[0], pll->ctl0_base); 216 writel_relaxed(reg_ctl[1], pll->ctl1_base); 217 writel_relaxed(reg_ctl[2], pll->ctl2_base); 218 return 0; 219 } 220 221 static unsigned long ma35d1_clk_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 222 { 223 struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw); 224 u32 reg_ctl[3]; 225 unsigned long pll_freq; 226 227 if (parent_rate < PLL_FREF_MIN_FREQ || parent_rate > PLL_FREF_MAX_FREQ) 228 return 0; 229 230 switch (pll->id) { 231 case CAPLL: 232 reg_ctl[0] = readl_relaxed(pll->ctl0_base); 233 pll_freq = ma35d1_calc_smic_pll_freq(reg_ctl[0], parent_rate); 234 return pll_freq; 235 case DDRPLL: 236 case APLL: 237 case EPLL: 238 case VPLL: 239 reg_ctl[0] = readl_relaxed(pll->ctl0_base); 240 reg_ctl[1] = readl_relaxed(pll->ctl1_base); 241 pll_freq = ma35d1_calc_pll_freq(pll->mode, reg_ctl, parent_rate); 242 return pll_freq; 243 } 244 return 0; 245 } 246 247 static long ma35d1_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, 248 unsigned long *parent_rate) 249 { 250 struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw); 251 u32 reg_ctl[3] = { 0 }; 252 unsigned long pll_freq; 253 long ret; 254 255 if (*parent_rate < PLL_FREF_MIN_FREQ || *parent_rate > PLL_FREF_MAX_FREQ) 256 return -EINVAL; 257 258 ret = ma35d1_pll_find_closest(pll, rate, *parent_rate, reg_ctl, &pll_freq); 259 if (ret < 0) 260 return ret; 261 262 switch (pll->id) { 263 case CAPLL: 264 reg_ctl[0] = readl_relaxed(pll->ctl0_base); 265 pll_freq = ma35d1_calc_smic_pll_freq(reg_ctl[0], *parent_rate); 266 return pll_freq; 267 case DDRPLL: 268 case APLL: 269 case EPLL: 270 case VPLL: 271 reg_ctl[0] = readl_relaxed(pll->ctl0_base); 272 reg_ctl[1] = readl_relaxed(pll->ctl1_base); 273 pll_freq = ma35d1_calc_pll_freq(pll->mode, reg_ctl, *parent_rate); 274 return pll_freq; 275 } 276 return 0; 277 } 278 279 static int ma35d1_clk_pll_is_prepared(struct clk_hw *hw) 280 { 281 struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw); 282 u32 val = readl_relaxed(pll->ctl1_base); 283 284 return !(val & PLL_CTL1_PD); 285 } 286 287 static int ma35d1_clk_pll_prepare(struct clk_hw *hw) 288 { 289 struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw); 290 u32 val; 291 292 val = readl_relaxed(pll->ctl1_base); 293 val &= ~PLL_CTL1_PD; 294 writel_relaxed(val, pll->ctl1_base); 295 return 0; 296 } 297 298 static void ma35d1_clk_pll_unprepare(struct clk_hw *hw) 299 { 300 struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw); 301 u32 val; 302 303 val = readl_relaxed(pll->ctl1_base); 304 val |= PLL_CTL1_PD; 305 writel_relaxed(val, pll->ctl1_base); 306 } 307 308 static const struct clk_ops ma35d1_clk_pll_ops = { 309 .is_prepared = ma35d1_clk_pll_is_prepared, 310 .prepare = ma35d1_clk_pll_prepare, 311 .unprepare = ma35d1_clk_pll_unprepare, 312 .set_rate = ma35d1_clk_pll_set_rate, 313 .recalc_rate = ma35d1_clk_pll_recalc_rate, 314 .round_rate = ma35d1_clk_pll_round_rate, 315 }; 316 317 static const struct clk_ops ma35d1_clk_fixed_pll_ops = { 318 .recalc_rate = ma35d1_clk_pll_recalc_rate, 319 .round_rate = ma35d1_clk_pll_round_rate, 320 }; 321 322 struct clk_hw *ma35d1_reg_clk_pll(struct device *dev, u32 id, u8 u8mode, const char *name, 323 struct clk_hw *parent_hw, void __iomem *base) 324 { 325 struct clk_parent_data pdata = { .index = 0 }; 326 struct clk_init_data init = {}; 327 struct ma35d1_clk_pll *pll; 328 struct clk_hw *hw; 329 int ret; 330 331 pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL); 332 if (!pll) 333 return ERR_PTR(-ENOMEM); 334 335 pll->id = id; 336 pll->mode = u8mode; 337 pll->ctl0_base = base + REG_PLL_CTL0_OFFSET; 338 pll->ctl1_base = base + REG_PLL_CTL1_OFFSET; 339 pll->ctl2_base = base + REG_PLL_CTL2_OFFSET; 340 341 init.name = name; 342 init.flags = 0; 343 pdata.hw = parent_hw; 344 init.parent_data = &pdata; 345 init.num_parents = 1; 346 347 if (id == CAPLL || id == DDRPLL) 348 init.ops = &ma35d1_clk_fixed_pll_ops; 349 else 350 init.ops = &ma35d1_clk_pll_ops; 351 352 pll->hw.init = &init; 353 hw = &pll->hw; 354 355 ret = devm_clk_hw_register(dev, hw); 356 if (ret) 357 return ERR_PTR(ret); 358 return hw; 359 } 360 EXPORT_SYMBOL_GPL(ma35d1_reg_clk_pll); 361