Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  *  Copyright (C) 2019 Microchip Technology Inc.
0004  *
0005  */
0006 
0007 #include <linux/bitfield.h>
0008 #include <linux/clk.h>
0009 #include <linux/clk-provider.h>
0010 #include <linux/clkdev.h>
0011 #include <linux/clk/at91_pmc.h>
0012 #include <linux/of.h>
0013 #include <linux/mfd/syscon.h>
0014 #include <linux/regmap.h>
0015 
0016 #include "pmc.h"
0017 
0018 #define PMC_PLL_CTRL0_DIV_MSK   GENMASK(7, 0)
0019 #define PMC_PLL_CTRL1_MUL_MSK   GENMASK(31, 24)
0020 #define PMC_PLL_CTRL1_FRACR_MSK GENMASK(21, 0)
0021 
0022 #define PLL_DIV_MAX     (FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1)
0023 #define UPLL_DIV        2
0024 #define PLL_MUL_MAX     (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
0025 
0026 #define FCORE_MIN       (600000000)
0027 #define FCORE_MAX       (1200000000)
0028 
0029 #define PLL_MAX_ID      7
0030 
0031 struct sam9x60_pll_core {
0032     struct regmap *regmap;
0033     spinlock_t *lock;
0034     const struct clk_pll_characteristics *characteristics;
0035     const struct clk_pll_layout *layout;
0036     struct clk_hw hw;
0037     u8 id;
0038 };
0039 
0040 struct sam9x60_frac {
0041     struct sam9x60_pll_core core;
0042     struct at91_clk_pms pms;
0043     u32 frac;
0044     u16 mul;
0045 };
0046 
0047 struct sam9x60_div {
0048     struct sam9x60_pll_core core;
0049     struct at91_clk_pms pms;
0050     u8 div;
0051     u8 safe_div;
0052 };
0053 
0054 #define to_sam9x60_pll_core(hw) container_of(hw, struct sam9x60_pll_core, hw)
0055 #define to_sam9x60_frac(core)   container_of(core, struct sam9x60_frac, core)
0056 #define to_sam9x60_div(core)    container_of(core, struct sam9x60_div, core)
0057 
0058 static struct sam9x60_div *notifier_div;
0059 
0060 static inline bool sam9x60_pll_ready(struct regmap *regmap, int id)
0061 {
0062     unsigned int status;
0063 
0064     regmap_read(regmap, AT91_PMC_PLL_ISR0, &status);
0065 
0066     return !!(status & BIT(id));
0067 }
0068 
0069 static bool sam9x60_frac_pll_ready(struct regmap *regmap, u8 id)
0070 {
0071     return sam9x60_pll_ready(regmap, id);
0072 }
0073 
0074 static unsigned long sam9x60_frac_pll_recalc_rate(struct clk_hw *hw,
0075                           unsigned long parent_rate)
0076 {
0077     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0078     struct sam9x60_frac *frac = to_sam9x60_frac(core);
0079 
0080     return parent_rate * (frac->mul + 1) +
0081         DIV_ROUND_CLOSEST_ULL((u64)parent_rate * frac->frac, (1 << 22));
0082 }
0083 
0084 static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core)
0085 {
0086     struct sam9x60_frac *frac = to_sam9x60_frac(core);
0087     struct regmap *regmap = core->regmap;
0088     unsigned int val, cfrac, cmul;
0089     unsigned long flags;
0090 
0091     spin_lock_irqsave(core->lock, flags);
0092 
0093     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0094                AT91_PMC_PLL_UPDT_ID_MSK, core->id);
0095     regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val);
0096     cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift;
0097     cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift;
0098 
0099     if (sam9x60_frac_pll_ready(regmap, core->id) &&
0100         (cmul == frac->mul && cfrac == frac->frac))
0101         goto unlock;
0102 
0103     /* Recommended value for PMC_PLL_ACR */
0104     if (core->characteristics->upll)
0105         val = AT91_PMC_PLL_ACR_DEFAULT_UPLL;
0106     else
0107         val = AT91_PMC_PLL_ACR_DEFAULT_PLLA;
0108     regmap_write(regmap, AT91_PMC_PLL_ACR, val);
0109 
0110     regmap_write(regmap, AT91_PMC_PLL_CTRL1,
0111              (frac->mul << core->layout->mul_shift) |
0112              (frac->frac << core->layout->frac_shift));
0113 
0114     if (core->characteristics->upll) {
0115         /* Enable the UTMI internal bandgap */
0116         val |= AT91_PMC_PLL_ACR_UTMIBG;
0117         regmap_write(regmap, AT91_PMC_PLL_ACR, val);
0118 
0119         udelay(10);
0120 
0121         /* Enable the UTMI internal regulator */
0122         val |= AT91_PMC_PLL_ACR_UTMIVR;
0123         regmap_write(regmap, AT91_PMC_PLL_ACR, val);
0124 
0125         udelay(10);
0126     }
0127 
0128     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0129                AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
0130                AT91_PMC_PLL_UPDT_UPDATE | core->id);
0131 
0132     regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
0133                AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL,
0134                AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL);
0135 
0136     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0137                AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
0138                AT91_PMC_PLL_UPDT_UPDATE | core->id);
0139 
0140     while (!sam9x60_pll_ready(regmap, core->id))
0141         cpu_relax();
0142 
0143 unlock:
0144     spin_unlock_irqrestore(core->lock, flags);
0145 
0146     return 0;
0147 }
0148 
0149 static int sam9x60_frac_pll_prepare(struct clk_hw *hw)
0150 {
0151     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0152 
0153     return sam9x60_frac_pll_set(core);
0154 }
0155 
0156 static void sam9x60_frac_pll_unprepare(struct clk_hw *hw)
0157 {
0158     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0159     struct regmap *regmap = core->regmap;
0160     unsigned long flags;
0161 
0162     spin_lock_irqsave(core->lock, flags);
0163 
0164     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0165                AT91_PMC_PLL_UPDT_ID_MSK, core->id);
0166 
0167     regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, AT91_PMC_PLL_CTRL0_ENPLL, 0);
0168 
0169     if (core->characteristics->upll)
0170         regmap_update_bits(regmap, AT91_PMC_PLL_ACR,
0171                    AT91_PMC_PLL_ACR_UTMIBG | AT91_PMC_PLL_ACR_UTMIVR, 0);
0172 
0173     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0174                AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
0175                AT91_PMC_PLL_UPDT_UPDATE | core->id);
0176 
0177     spin_unlock_irqrestore(core->lock, flags);
0178 }
0179 
0180 static int sam9x60_frac_pll_is_prepared(struct clk_hw *hw)
0181 {
0182     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0183 
0184     return sam9x60_pll_ready(core->regmap, core->id);
0185 }
0186 
0187 static long sam9x60_frac_pll_compute_mul_frac(struct sam9x60_pll_core *core,
0188                           unsigned long rate,
0189                           unsigned long parent_rate,
0190                           bool update)
0191 {
0192     struct sam9x60_frac *frac = to_sam9x60_frac(core);
0193     unsigned long tmprate, remainder;
0194     unsigned long nmul = 0;
0195     unsigned long nfrac = 0;
0196 
0197     if (rate < FCORE_MIN || rate > FCORE_MAX)
0198         return -ERANGE;
0199 
0200     /*
0201      * Calculate the multiplier associated with the current
0202      * divider that provide the closest rate to the requested one.
0203      */
0204     nmul = mult_frac(rate, 1, parent_rate);
0205     tmprate = mult_frac(parent_rate, nmul, 1);
0206     remainder = rate - tmprate;
0207 
0208     if (remainder) {
0209         nfrac = DIV_ROUND_CLOSEST_ULL((u64)remainder * (1 << 22),
0210                           parent_rate);
0211 
0212         tmprate += DIV_ROUND_CLOSEST_ULL((u64)nfrac * parent_rate,
0213                          (1 << 22));
0214     }
0215 
0216     /* Check if resulted rate is a valid.  */
0217     if (tmprate < FCORE_MIN || tmprate > FCORE_MAX)
0218         return -ERANGE;
0219 
0220     if (update) {
0221         frac->mul = nmul - 1;
0222         frac->frac = nfrac;
0223     }
0224 
0225     return tmprate;
0226 }
0227 
0228 static long sam9x60_frac_pll_round_rate(struct clk_hw *hw, unsigned long rate,
0229                     unsigned long *parent_rate)
0230 {
0231     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0232 
0233     return sam9x60_frac_pll_compute_mul_frac(core, rate, *parent_rate, false);
0234 }
0235 
0236 static int sam9x60_frac_pll_set_rate(struct clk_hw *hw, unsigned long rate,
0237                      unsigned long parent_rate)
0238 {
0239     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0240 
0241     return sam9x60_frac_pll_compute_mul_frac(core, rate, parent_rate, true);
0242 }
0243 
0244 static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate,
0245                      unsigned long parent_rate)
0246 {
0247     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0248     struct sam9x60_frac *frac = to_sam9x60_frac(core);
0249     struct regmap *regmap = core->regmap;
0250     unsigned long irqflags;
0251     unsigned int val, cfrac, cmul;
0252     long ret;
0253 
0254     ret = sam9x60_frac_pll_compute_mul_frac(core, rate, parent_rate, true);
0255     if (ret <= 0)
0256         return ret;
0257 
0258     spin_lock_irqsave(core->lock, irqflags);
0259 
0260     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
0261                core->id);
0262     regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val);
0263     cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift;
0264     cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift;
0265 
0266     if (cmul == frac->mul && cfrac == frac->frac)
0267         goto unlock;
0268 
0269     regmap_write(regmap, AT91_PMC_PLL_CTRL1,
0270              (frac->mul << core->layout->mul_shift) |
0271              (frac->frac << core->layout->frac_shift));
0272 
0273     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0274                AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
0275                AT91_PMC_PLL_UPDT_UPDATE | core->id);
0276 
0277     regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
0278                AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL,
0279                AT91_PMC_PLL_CTRL0_ENLOCK |
0280                AT91_PMC_PLL_CTRL0_ENPLL);
0281 
0282     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0283                AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
0284                AT91_PMC_PLL_UPDT_UPDATE | core->id);
0285 
0286     while (!sam9x60_pll_ready(regmap, core->id))
0287         cpu_relax();
0288 
0289 unlock:
0290     spin_unlock_irqrestore(core->lock, irqflags);
0291 
0292     return ret;
0293 }
0294 
0295 static int sam9x60_frac_pll_save_context(struct clk_hw *hw)
0296 {
0297     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0298     struct sam9x60_frac *frac = to_sam9x60_frac(core);
0299 
0300     frac->pms.status = sam9x60_pll_ready(core->regmap, core->id);
0301 
0302     return 0;
0303 }
0304 
0305 static void sam9x60_frac_pll_restore_context(struct clk_hw *hw)
0306 {
0307     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0308     struct sam9x60_frac *frac = to_sam9x60_frac(core);
0309 
0310     if (frac->pms.status)
0311         sam9x60_frac_pll_set(core);
0312 }
0313 
0314 static const struct clk_ops sam9x60_frac_pll_ops = {
0315     .prepare = sam9x60_frac_pll_prepare,
0316     .unprepare = sam9x60_frac_pll_unprepare,
0317     .is_prepared = sam9x60_frac_pll_is_prepared,
0318     .recalc_rate = sam9x60_frac_pll_recalc_rate,
0319     .round_rate = sam9x60_frac_pll_round_rate,
0320     .set_rate = sam9x60_frac_pll_set_rate,
0321     .save_context = sam9x60_frac_pll_save_context,
0322     .restore_context = sam9x60_frac_pll_restore_context,
0323 };
0324 
0325 static const struct clk_ops sam9x60_frac_pll_ops_chg = {
0326     .prepare = sam9x60_frac_pll_prepare,
0327     .unprepare = sam9x60_frac_pll_unprepare,
0328     .is_prepared = sam9x60_frac_pll_is_prepared,
0329     .recalc_rate = sam9x60_frac_pll_recalc_rate,
0330     .round_rate = sam9x60_frac_pll_round_rate,
0331     .set_rate = sam9x60_frac_pll_set_rate_chg,
0332     .save_context = sam9x60_frac_pll_save_context,
0333     .restore_context = sam9x60_frac_pll_restore_context,
0334 };
0335 
0336 /* This function should be called with spinlock acquired. */
0337 static void sam9x60_div_pll_set_div(struct sam9x60_pll_core *core, u32 div,
0338                     bool enable)
0339 {
0340     struct regmap *regmap = core->regmap;
0341     u32 ena_msk = enable ? core->layout->endiv_mask : 0;
0342     u32 ena_val = enable ? (1 << core->layout->endiv_shift) : 0;
0343 
0344     regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
0345                core->layout->div_mask | ena_msk,
0346                (div << core->layout->div_shift) | ena_val);
0347 
0348     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0349                AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
0350                AT91_PMC_PLL_UPDT_UPDATE | core->id);
0351 
0352     while (!sam9x60_pll_ready(regmap, core->id))
0353         cpu_relax();
0354 }
0355 
0356 static int sam9x60_div_pll_set(struct sam9x60_pll_core *core)
0357 {
0358     struct sam9x60_div *div = to_sam9x60_div(core);
0359     struct regmap *regmap = core->regmap;
0360     unsigned long flags;
0361     unsigned int val, cdiv;
0362 
0363     spin_lock_irqsave(core->lock, flags);
0364     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0365                AT91_PMC_PLL_UPDT_ID_MSK, core->id);
0366     regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
0367     cdiv = (val & core->layout->div_mask) >> core->layout->div_shift;
0368 
0369     /* Stop if enabled an nothing changed. */
0370     if (!!(val & core->layout->endiv_mask) && cdiv == div->div)
0371         goto unlock;
0372 
0373     sam9x60_div_pll_set_div(core, div->div, 1);
0374 
0375 unlock:
0376     spin_unlock_irqrestore(core->lock, flags);
0377 
0378     return 0;
0379 }
0380 
0381 static int sam9x60_div_pll_prepare(struct clk_hw *hw)
0382 {
0383     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0384 
0385     return sam9x60_div_pll_set(core);
0386 }
0387 
0388 static void sam9x60_div_pll_unprepare(struct clk_hw *hw)
0389 {
0390     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0391     struct regmap *regmap = core->regmap;
0392     unsigned long flags;
0393 
0394     spin_lock_irqsave(core->lock, flags);
0395 
0396     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0397                AT91_PMC_PLL_UPDT_ID_MSK, core->id);
0398 
0399     regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
0400                core->layout->endiv_mask, 0);
0401 
0402     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0403                AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
0404                AT91_PMC_PLL_UPDT_UPDATE | core->id);
0405 
0406     spin_unlock_irqrestore(core->lock, flags);
0407 }
0408 
0409 static int sam9x60_div_pll_is_prepared(struct clk_hw *hw)
0410 {
0411     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0412     struct regmap *regmap = core->regmap;
0413     unsigned long flags;
0414     unsigned int val;
0415 
0416     spin_lock_irqsave(core->lock, flags);
0417 
0418     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0419                AT91_PMC_PLL_UPDT_ID_MSK, core->id);
0420     regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
0421 
0422     spin_unlock_irqrestore(core->lock, flags);
0423 
0424     return !!(val & core->layout->endiv_mask);
0425 }
0426 
0427 static unsigned long sam9x60_div_pll_recalc_rate(struct clk_hw *hw,
0428                          unsigned long parent_rate)
0429 {
0430     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0431     struct sam9x60_div *div = to_sam9x60_div(core);
0432 
0433     return DIV_ROUND_CLOSEST_ULL(parent_rate, (div->div + 1));
0434 }
0435 
0436 static long sam9x60_div_pll_compute_div(struct sam9x60_pll_core *core,
0437                     unsigned long *parent_rate,
0438                     unsigned long rate)
0439 {
0440     const struct clk_pll_characteristics *characteristics =
0441                             core->characteristics;
0442     struct clk_hw *parent = clk_hw_get_parent(&core->hw);
0443     unsigned long tmp_rate, tmp_parent_rate, tmp_diff;
0444     long best_diff = -1, best_rate = -EINVAL;
0445     u32 divid;
0446 
0447     if (!rate)
0448         return 0;
0449 
0450     if (rate < characteristics->output[0].min ||
0451         rate > characteristics->output[0].max)
0452         return -ERANGE;
0453 
0454     for (divid = 1; divid < core->layout->div_mask; divid++) {
0455         tmp_parent_rate = clk_hw_round_rate(parent, rate * divid);
0456         if (!tmp_parent_rate)
0457             continue;
0458 
0459         tmp_rate = DIV_ROUND_CLOSEST_ULL(tmp_parent_rate, divid);
0460         tmp_diff = abs(rate - tmp_rate);
0461 
0462         if (best_diff < 0 || best_diff > tmp_diff) {
0463             *parent_rate = tmp_parent_rate;
0464             best_rate = tmp_rate;
0465             best_diff = tmp_diff;
0466         }
0467 
0468         if (!best_diff)
0469             break;
0470     }
0471 
0472     if (best_rate < characteristics->output[0].min ||
0473         best_rate > characteristics->output[0].max)
0474         return -ERANGE;
0475 
0476     return best_rate;
0477 }
0478 
0479 static long sam9x60_div_pll_round_rate(struct clk_hw *hw, unsigned long rate,
0480                        unsigned long *parent_rate)
0481 {
0482     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0483 
0484     return sam9x60_div_pll_compute_div(core, parent_rate, rate);
0485 }
0486 
0487 static int sam9x60_div_pll_set_rate(struct clk_hw *hw, unsigned long rate,
0488                     unsigned long parent_rate)
0489 {
0490     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0491     struct sam9x60_div *div = to_sam9x60_div(core);
0492 
0493     div->div = DIV_ROUND_CLOSEST(parent_rate, rate) - 1;
0494 
0495     return 0;
0496 }
0497 
0498 static int sam9x60_div_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate,
0499                     unsigned long parent_rate)
0500 {
0501     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0502     struct sam9x60_div *div = to_sam9x60_div(core);
0503     struct regmap *regmap = core->regmap;
0504     unsigned long irqflags;
0505     unsigned int val, cdiv;
0506 
0507     div->div = DIV_ROUND_CLOSEST(parent_rate, rate) - 1;
0508 
0509     spin_lock_irqsave(core->lock, irqflags);
0510     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
0511                core->id);
0512     regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
0513     cdiv = (val & core->layout->div_mask) >> core->layout->div_shift;
0514 
0515     /* Stop if nothing changed. */
0516     if (cdiv == div->div)
0517         goto unlock;
0518 
0519     sam9x60_div_pll_set_div(core, div->div, 0);
0520 
0521 unlock:
0522     spin_unlock_irqrestore(core->lock, irqflags);
0523 
0524     return 0;
0525 }
0526 
0527 static int sam9x60_div_pll_save_context(struct clk_hw *hw)
0528 {
0529     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0530     struct sam9x60_div *div = to_sam9x60_div(core);
0531 
0532     div->pms.status = sam9x60_div_pll_is_prepared(hw);
0533 
0534     return 0;
0535 }
0536 
0537 static void sam9x60_div_pll_restore_context(struct clk_hw *hw)
0538 {
0539     struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
0540     struct sam9x60_div *div = to_sam9x60_div(core);
0541 
0542     if (div->pms.status)
0543         sam9x60_div_pll_set(core);
0544 }
0545 
0546 static int sam9x60_div_pll_notifier_fn(struct notifier_block *notifier,
0547                        unsigned long code, void *data)
0548 {
0549     struct sam9x60_div *div = notifier_div;
0550     struct sam9x60_pll_core core = div->core;
0551     struct regmap *regmap = core.regmap;
0552     unsigned long irqflags;
0553     u32 val, cdiv;
0554     int ret = NOTIFY_DONE;
0555 
0556     if (code != PRE_RATE_CHANGE)
0557         return ret;
0558 
0559     /*
0560      * We switch to safe divider to avoid overclocking of other domains
0561      * feed by us while the frac PLL (our parent) is changed.
0562      */
0563     div->div = div->safe_div;
0564 
0565     spin_lock_irqsave(core.lock, irqflags);
0566     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
0567                core.id);
0568     regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
0569     cdiv = (val & core.layout->div_mask) >> core.layout->div_shift;
0570 
0571     /* Stop if nothing changed. */
0572     if (cdiv == div->safe_div)
0573         goto unlock;
0574 
0575     sam9x60_div_pll_set_div(&core, div->div, 0);
0576     ret = NOTIFY_OK;
0577 
0578 unlock:
0579     spin_unlock_irqrestore(core.lock, irqflags);
0580 
0581     return ret;
0582 }
0583 
0584 static struct notifier_block sam9x60_div_pll_notifier = {
0585     .notifier_call = sam9x60_div_pll_notifier_fn,
0586 };
0587 
0588 static const struct clk_ops sam9x60_div_pll_ops = {
0589     .prepare = sam9x60_div_pll_prepare,
0590     .unprepare = sam9x60_div_pll_unprepare,
0591     .is_prepared = sam9x60_div_pll_is_prepared,
0592     .recalc_rate = sam9x60_div_pll_recalc_rate,
0593     .round_rate = sam9x60_div_pll_round_rate,
0594     .set_rate = sam9x60_div_pll_set_rate,
0595     .save_context = sam9x60_div_pll_save_context,
0596     .restore_context = sam9x60_div_pll_restore_context,
0597 };
0598 
0599 static const struct clk_ops sam9x60_div_pll_ops_chg = {
0600     .prepare = sam9x60_div_pll_prepare,
0601     .unprepare = sam9x60_div_pll_unprepare,
0602     .is_prepared = sam9x60_div_pll_is_prepared,
0603     .recalc_rate = sam9x60_div_pll_recalc_rate,
0604     .round_rate = sam9x60_div_pll_round_rate,
0605     .set_rate = sam9x60_div_pll_set_rate_chg,
0606     .save_context = sam9x60_div_pll_save_context,
0607     .restore_context = sam9x60_div_pll_restore_context,
0608 };
0609 
0610 struct clk_hw * __init
0611 sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock,
0612                   const char *name, const char *parent_name,
0613                   struct clk_hw *parent_hw, u8 id,
0614                   const struct clk_pll_characteristics *characteristics,
0615                   const struct clk_pll_layout *layout, u32 flags)
0616 {
0617     struct sam9x60_frac *frac;
0618     struct clk_hw *hw;
0619     struct clk_init_data init;
0620     unsigned long parent_rate, irqflags;
0621     unsigned int val;
0622     int ret;
0623 
0624     if (id > PLL_MAX_ID || !lock || !parent_hw)
0625         return ERR_PTR(-EINVAL);
0626 
0627     frac = kzalloc(sizeof(*frac), GFP_KERNEL);
0628     if (!frac)
0629         return ERR_PTR(-ENOMEM);
0630 
0631     init.name = name;
0632     init.parent_names = &parent_name;
0633     init.num_parents = 1;
0634     if (flags & CLK_SET_RATE_GATE)
0635         init.ops = &sam9x60_frac_pll_ops;
0636     else
0637         init.ops = &sam9x60_frac_pll_ops_chg;
0638 
0639     init.flags = flags;
0640 
0641     frac->core.id = id;
0642     frac->core.hw.init = &init;
0643     frac->core.characteristics = characteristics;
0644     frac->core.layout = layout;
0645     frac->core.regmap = regmap;
0646     frac->core.lock = lock;
0647 
0648     spin_lock_irqsave(frac->core.lock, irqflags);
0649     if (sam9x60_pll_ready(regmap, id)) {
0650         regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0651                    AT91_PMC_PLL_UPDT_ID_MSK, id);
0652         regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val);
0653         frac->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val);
0654         frac->frac = FIELD_GET(PMC_PLL_CTRL1_FRACR_MSK, val);
0655     } else {
0656         /*
0657          * This means the PLL is not setup by bootloaders. In this
0658          * case we need to set the minimum rate for it. Otherwise
0659          * a clock child of this PLL may be enabled before setting
0660          * its rate leading to enabling this PLL with unsupported
0661          * rate. This will lead to PLL not being locked at all.
0662          */
0663         parent_rate = clk_hw_get_rate(parent_hw);
0664         if (!parent_rate) {
0665             hw = ERR_PTR(-EINVAL);
0666             goto free;
0667         }
0668 
0669         ret = sam9x60_frac_pll_compute_mul_frac(&frac->core, FCORE_MIN,
0670                             parent_rate, true);
0671         if (ret <= 0) {
0672             hw = ERR_PTR(ret);
0673             goto free;
0674         }
0675     }
0676     spin_unlock_irqrestore(frac->core.lock, irqflags);
0677 
0678     hw = &frac->core.hw;
0679     ret = clk_hw_register(NULL, hw);
0680     if (ret) {
0681         kfree(frac);
0682         hw = ERR_PTR(ret);
0683     }
0684 
0685     return hw;
0686 
0687 free:
0688     spin_unlock_irqrestore(frac->core.lock, irqflags);
0689     kfree(frac);
0690     return hw;
0691 }
0692 
0693 struct clk_hw * __init
0694 sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock,
0695                  const char *name, const char *parent_name, u8 id,
0696                  const struct clk_pll_characteristics *characteristics,
0697                  const struct clk_pll_layout *layout, u32 flags,
0698                  u32 safe_div)
0699 {
0700     struct sam9x60_div *div;
0701     struct clk_hw *hw;
0702     struct clk_init_data init;
0703     unsigned long irqflags;
0704     unsigned int val;
0705     int ret;
0706 
0707     /* We only support one changeable PLL. */
0708     if (id > PLL_MAX_ID || !lock || (safe_div && notifier_div))
0709         return ERR_PTR(-EINVAL);
0710 
0711     if (safe_div >= PLL_DIV_MAX)
0712         safe_div = PLL_DIV_MAX - 1;
0713 
0714     div = kzalloc(sizeof(*div), GFP_KERNEL);
0715     if (!div)
0716         return ERR_PTR(-ENOMEM);
0717 
0718     init.name = name;
0719     init.parent_names = &parent_name;
0720     init.num_parents = 1;
0721     if (flags & CLK_SET_RATE_GATE)
0722         init.ops = &sam9x60_div_pll_ops;
0723     else
0724         init.ops = &sam9x60_div_pll_ops_chg;
0725     init.flags = flags;
0726 
0727     div->core.id = id;
0728     div->core.hw.init = &init;
0729     div->core.characteristics = characteristics;
0730     div->core.layout = layout;
0731     div->core.regmap = regmap;
0732     div->core.lock = lock;
0733     div->safe_div = safe_div;
0734 
0735     spin_lock_irqsave(div->core.lock, irqflags);
0736 
0737     regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
0738                AT91_PMC_PLL_UPDT_ID_MSK, id);
0739     regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
0740     div->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val);
0741 
0742     spin_unlock_irqrestore(div->core.lock, irqflags);
0743 
0744     hw = &div->core.hw;
0745     ret = clk_hw_register(NULL, hw);
0746     if (ret) {
0747         kfree(div);
0748         hw = ERR_PTR(ret);
0749     } else if (div->safe_div) {
0750         notifier_div = div;
0751         clk_notifier_register(hw->clk, &sam9x60_div_pll_notifier);
0752     }
0753 
0754     return hw;
0755 }
0756