Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2014 Google, Inc.
0004  */
0005 
0006 #define pr_fmt(fmt) "%s: " fmt, __func__
0007 
0008 #include <linux/clk-provider.h>
0009 #include <linux/io.h>
0010 #include <linux/kernel.h>
0011 #include <linux/printk.h>
0012 #include <linux/slab.h>
0013 
0014 #include "clk.h"
0015 
0016 #define PLL_STATUS          0x0
0017 #define PLL_STATUS_LOCK         BIT(0)
0018 
0019 #define PLL_CTRL1           0x4
0020 #define PLL_CTRL1_REFDIV_SHIFT      0
0021 #define PLL_CTRL1_REFDIV_MASK       0x3f
0022 #define PLL_CTRL1_FBDIV_SHIFT       6
0023 #define PLL_CTRL1_FBDIV_MASK        0xfff
0024 #define PLL_INT_CTRL1_POSTDIV1_SHIFT    18
0025 #define PLL_INT_CTRL1_POSTDIV1_MASK 0x7
0026 #define PLL_INT_CTRL1_POSTDIV2_SHIFT    21
0027 #define PLL_INT_CTRL1_POSTDIV2_MASK 0x7
0028 #define PLL_INT_CTRL1_PD        BIT(24)
0029 #define PLL_INT_CTRL1_DSMPD     BIT(25)
0030 #define PLL_INT_CTRL1_FOUTPOSTDIVPD BIT(26)
0031 #define PLL_INT_CTRL1_FOUTVCOPD     BIT(27)
0032 
0033 #define PLL_CTRL2           0x8
0034 #define PLL_FRAC_CTRL2_FRAC_SHIFT   0
0035 #define PLL_FRAC_CTRL2_FRAC_MASK    0xffffff
0036 #define PLL_FRAC_CTRL2_POSTDIV1_SHIFT   24
0037 #define PLL_FRAC_CTRL2_POSTDIV1_MASK    0x7
0038 #define PLL_FRAC_CTRL2_POSTDIV2_SHIFT   27
0039 #define PLL_FRAC_CTRL2_POSTDIV2_MASK    0x7
0040 #define PLL_INT_CTRL2_BYPASS        BIT(28)
0041 
0042 #define PLL_CTRL3           0xc
0043 #define PLL_FRAC_CTRL3_PD       BIT(0)
0044 #define PLL_FRAC_CTRL3_DACPD        BIT(1)
0045 #define PLL_FRAC_CTRL3_DSMPD        BIT(2)
0046 #define PLL_FRAC_CTRL3_FOUTPOSTDIVPD    BIT(3)
0047 #define PLL_FRAC_CTRL3_FOUT4PHASEPD BIT(4)
0048 #define PLL_FRAC_CTRL3_FOUTVCOPD    BIT(5)
0049 
0050 #define PLL_CTRL4           0x10
0051 #define PLL_FRAC_CTRL4_BYPASS       BIT(28)
0052 
0053 #define MIN_PFD             9600000UL
0054 #define MIN_VCO_LA          400000000UL
0055 #define MAX_VCO_LA          1600000000UL
0056 #define MIN_VCO_FRAC_INT        600000000UL
0057 #define MAX_VCO_FRAC_INT        1600000000UL
0058 #define MIN_VCO_FRAC_FRAC       600000000UL
0059 #define MAX_VCO_FRAC_FRAC       2400000000UL
0060 #define MIN_OUTPUT_LA           8000000UL
0061 #define MAX_OUTPUT_LA           1600000000UL
0062 #define MIN_OUTPUT_FRAC         12000000UL
0063 #define MAX_OUTPUT_FRAC         1600000000UL
0064 
0065 /* Fractional PLL operating modes */
0066 enum pll_mode {
0067     PLL_MODE_FRAC,
0068     PLL_MODE_INT,
0069 };
0070 
0071 struct pistachio_clk_pll {
0072     struct clk_hw hw;
0073     void __iomem *base;
0074     struct pistachio_pll_rate_table *rates;
0075     unsigned int nr_rates;
0076 };
0077 
0078 static inline u32 pll_readl(struct pistachio_clk_pll *pll, u32 reg)
0079 {
0080     return readl(pll->base + reg);
0081 }
0082 
0083 static inline void pll_writel(struct pistachio_clk_pll *pll, u32 val, u32 reg)
0084 {
0085     writel(val, pll->base + reg);
0086 }
0087 
0088 static inline void pll_lock(struct pistachio_clk_pll *pll)
0089 {
0090     while (!(pll_readl(pll, PLL_STATUS) & PLL_STATUS_LOCK))
0091         cpu_relax();
0092 }
0093 
0094 static inline u64 do_div_round_closest(u64 dividend, u64 divisor)
0095 {
0096     dividend += divisor / 2;
0097     return div64_u64(dividend, divisor);
0098 }
0099 
0100 static inline struct pistachio_clk_pll *to_pistachio_pll(struct clk_hw *hw)
0101 {
0102     return container_of(hw, struct pistachio_clk_pll, hw);
0103 }
0104 
0105 static inline enum pll_mode pll_frac_get_mode(struct clk_hw *hw)
0106 {
0107     struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
0108     u32 val;
0109 
0110     val = pll_readl(pll, PLL_CTRL3) & PLL_FRAC_CTRL3_DSMPD;
0111     return val ? PLL_MODE_INT : PLL_MODE_FRAC;
0112 }
0113 
0114 static inline void pll_frac_set_mode(struct clk_hw *hw, enum pll_mode mode)
0115 {
0116     struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
0117     u32 val;
0118 
0119     val = pll_readl(pll, PLL_CTRL3);
0120     if (mode == PLL_MODE_INT)
0121         val |= PLL_FRAC_CTRL3_DSMPD | PLL_FRAC_CTRL3_DACPD;
0122     else
0123         val &= ~(PLL_FRAC_CTRL3_DSMPD | PLL_FRAC_CTRL3_DACPD);
0124 
0125     pll_writel(pll, val, PLL_CTRL3);
0126 }
0127 
0128 static struct pistachio_pll_rate_table *
0129 pll_get_params(struct pistachio_clk_pll *pll, unsigned long fref,
0130            unsigned long fout)
0131 {
0132     unsigned int i;
0133 
0134     for (i = 0; i < pll->nr_rates; i++) {
0135         if (pll->rates[i].fref == fref && pll->rates[i].fout == fout)
0136             return &pll->rates[i];
0137     }
0138 
0139     return NULL;
0140 }
0141 
0142 static long pll_round_rate(struct clk_hw *hw, unsigned long rate,
0143                unsigned long *parent_rate)
0144 {
0145     struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
0146     unsigned int i;
0147 
0148     for (i = 0; i < pll->nr_rates; i++) {
0149         if (i > 0 && pll->rates[i].fref == *parent_rate &&
0150             pll->rates[i].fout <= rate)
0151             return pll->rates[i - 1].fout;
0152     }
0153 
0154     return pll->rates[0].fout;
0155 }
0156 
0157 static int pll_gf40lp_frac_enable(struct clk_hw *hw)
0158 {
0159     struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
0160     u32 val;
0161 
0162     val = pll_readl(pll, PLL_CTRL3);
0163     val &= ~(PLL_FRAC_CTRL3_PD | PLL_FRAC_CTRL3_FOUTPOSTDIVPD |
0164          PLL_FRAC_CTRL3_FOUT4PHASEPD | PLL_FRAC_CTRL3_FOUTVCOPD);
0165     pll_writel(pll, val, PLL_CTRL3);
0166 
0167     val = pll_readl(pll, PLL_CTRL4);
0168     val &= ~PLL_FRAC_CTRL4_BYPASS;
0169     pll_writel(pll, val, PLL_CTRL4);
0170 
0171     pll_lock(pll);
0172 
0173     return 0;
0174 }
0175 
0176 static void pll_gf40lp_frac_disable(struct clk_hw *hw)
0177 {
0178     struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
0179     u32 val;
0180 
0181     val = pll_readl(pll, PLL_CTRL3);
0182     val |= PLL_FRAC_CTRL3_PD;
0183     pll_writel(pll, val, PLL_CTRL3);
0184 }
0185 
0186 static int pll_gf40lp_frac_is_enabled(struct clk_hw *hw)
0187 {
0188     struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
0189 
0190     return !(pll_readl(pll, PLL_CTRL3) & PLL_FRAC_CTRL3_PD);
0191 }
0192 
0193 static int pll_gf40lp_frac_set_rate(struct clk_hw *hw, unsigned long rate,
0194                     unsigned long parent_rate)
0195 {
0196     struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
0197     struct pistachio_pll_rate_table *params;
0198     int enabled = pll_gf40lp_frac_is_enabled(hw);
0199     u64 val, vco, old_postdiv1, old_postdiv2;
0200     const char *name = clk_hw_get_name(hw);
0201 
0202     if (rate < MIN_OUTPUT_FRAC || rate > MAX_OUTPUT_FRAC)
0203         return -EINVAL;
0204 
0205     params = pll_get_params(pll, parent_rate, rate);
0206     if (!params || !params->refdiv)
0207         return -EINVAL;
0208 
0209     /* calculate vco */
0210     vco = params->fref;
0211     vco *= (params->fbdiv << 24) + params->frac;
0212     vco = div64_u64(vco, params->refdiv << 24);
0213 
0214     if (vco < MIN_VCO_FRAC_FRAC || vco > MAX_VCO_FRAC_FRAC)
0215         pr_warn("%s: VCO %llu is out of range %lu..%lu\n", name, vco,
0216             MIN_VCO_FRAC_FRAC, MAX_VCO_FRAC_FRAC);
0217 
0218     val = div64_u64(params->fref, params->refdiv);
0219     if (val < MIN_PFD)
0220         pr_warn("%s: PFD %llu is too low (min %lu)\n",
0221             name, val, MIN_PFD);
0222     if (val > vco / 16)
0223         pr_warn("%s: PFD %llu is too high (max %llu)\n",
0224             name, val, vco / 16);
0225 
0226     val = pll_readl(pll, PLL_CTRL1);
0227     val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) |
0228          (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT));
0229     val |= (params->refdiv << PLL_CTRL1_REFDIV_SHIFT) |
0230         (params->fbdiv << PLL_CTRL1_FBDIV_SHIFT);
0231     pll_writel(pll, val, PLL_CTRL1);
0232 
0233     val = pll_readl(pll, PLL_CTRL2);
0234 
0235     old_postdiv1 = (val >> PLL_FRAC_CTRL2_POSTDIV1_SHIFT) &
0236                PLL_FRAC_CTRL2_POSTDIV1_MASK;
0237     old_postdiv2 = (val >> PLL_FRAC_CTRL2_POSTDIV2_SHIFT) &
0238                PLL_FRAC_CTRL2_POSTDIV2_MASK;
0239     if (enabled &&
0240         (params->postdiv1 != old_postdiv1 ||
0241          params->postdiv2 != old_postdiv2))
0242         pr_warn("%s: changing postdiv while PLL is enabled\n", name);
0243 
0244     if (params->postdiv2 > params->postdiv1)
0245         pr_warn("%s: postdiv2 should not exceed postdiv1\n", name);
0246 
0247     val &= ~((PLL_FRAC_CTRL2_FRAC_MASK << PLL_FRAC_CTRL2_FRAC_SHIFT) |
0248          (PLL_FRAC_CTRL2_POSTDIV1_MASK <<
0249           PLL_FRAC_CTRL2_POSTDIV1_SHIFT) |
0250          (PLL_FRAC_CTRL2_POSTDIV2_MASK <<
0251           PLL_FRAC_CTRL2_POSTDIV2_SHIFT));
0252     val |= (params->frac << PLL_FRAC_CTRL2_FRAC_SHIFT) |
0253         (params->postdiv1 << PLL_FRAC_CTRL2_POSTDIV1_SHIFT) |
0254         (params->postdiv2 << PLL_FRAC_CTRL2_POSTDIV2_SHIFT);
0255     pll_writel(pll, val, PLL_CTRL2);
0256 
0257     /* set operating mode */
0258     if (params->frac)
0259         pll_frac_set_mode(hw, PLL_MODE_FRAC);
0260     else
0261         pll_frac_set_mode(hw, PLL_MODE_INT);
0262 
0263     if (enabled)
0264         pll_lock(pll);
0265 
0266     return 0;
0267 }
0268 
0269 static unsigned long pll_gf40lp_frac_recalc_rate(struct clk_hw *hw,
0270                          unsigned long parent_rate)
0271 {
0272     struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
0273     u64 val, prediv, fbdiv, frac, postdiv1, postdiv2, rate;
0274 
0275     val = pll_readl(pll, PLL_CTRL1);
0276     prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK;
0277     fbdiv = (val >> PLL_CTRL1_FBDIV_SHIFT) & PLL_CTRL1_FBDIV_MASK;
0278 
0279     val = pll_readl(pll, PLL_CTRL2);
0280     postdiv1 = (val >> PLL_FRAC_CTRL2_POSTDIV1_SHIFT) &
0281         PLL_FRAC_CTRL2_POSTDIV1_MASK;
0282     postdiv2 = (val >> PLL_FRAC_CTRL2_POSTDIV2_SHIFT) &
0283         PLL_FRAC_CTRL2_POSTDIV2_MASK;
0284     frac = (val >> PLL_FRAC_CTRL2_FRAC_SHIFT) & PLL_FRAC_CTRL2_FRAC_MASK;
0285 
0286     /* get operating mode (int/frac) and calculate rate accordingly */
0287     rate = parent_rate;
0288     if (pll_frac_get_mode(hw) == PLL_MODE_FRAC)
0289         rate *= (fbdiv << 24) + frac;
0290     else
0291         rate *= (fbdiv << 24);
0292 
0293     rate = do_div_round_closest(rate, (prediv * postdiv1 * postdiv2) << 24);
0294 
0295     return rate;
0296 }
0297 
0298 static const struct clk_ops pll_gf40lp_frac_ops = {
0299     .enable = pll_gf40lp_frac_enable,
0300     .disable = pll_gf40lp_frac_disable,
0301     .is_enabled = pll_gf40lp_frac_is_enabled,
0302     .recalc_rate = pll_gf40lp_frac_recalc_rate,
0303     .round_rate = pll_round_rate,
0304     .set_rate = pll_gf40lp_frac_set_rate,
0305 };
0306 
0307 static const struct clk_ops pll_gf40lp_frac_fixed_ops = {
0308     .enable = pll_gf40lp_frac_enable,
0309     .disable = pll_gf40lp_frac_disable,
0310     .is_enabled = pll_gf40lp_frac_is_enabled,
0311     .recalc_rate = pll_gf40lp_frac_recalc_rate,
0312 };
0313 
0314 static int pll_gf40lp_laint_enable(struct clk_hw *hw)
0315 {
0316     struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
0317     u32 val;
0318 
0319     val = pll_readl(pll, PLL_CTRL1);
0320     val &= ~(PLL_INT_CTRL1_PD |
0321          PLL_INT_CTRL1_FOUTPOSTDIVPD | PLL_INT_CTRL1_FOUTVCOPD);
0322     pll_writel(pll, val, PLL_CTRL1);
0323 
0324     val = pll_readl(pll, PLL_CTRL2);
0325     val &= ~PLL_INT_CTRL2_BYPASS;
0326     pll_writel(pll, val, PLL_CTRL2);
0327 
0328     pll_lock(pll);
0329 
0330     return 0;
0331 }
0332 
0333 static void pll_gf40lp_laint_disable(struct clk_hw *hw)
0334 {
0335     struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
0336     u32 val;
0337 
0338     val = pll_readl(pll, PLL_CTRL1);
0339     val |= PLL_INT_CTRL1_PD;
0340     pll_writel(pll, val, PLL_CTRL1);
0341 }
0342 
0343 static int pll_gf40lp_laint_is_enabled(struct clk_hw *hw)
0344 {
0345     struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
0346 
0347     return !(pll_readl(pll, PLL_CTRL1) & PLL_INT_CTRL1_PD);
0348 }
0349 
0350 static int pll_gf40lp_laint_set_rate(struct clk_hw *hw, unsigned long rate,
0351                      unsigned long parent_rate)
0352 {
0353     struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
0354     struct pistachio_pll_rate_table *params;
0355     int enabled = pll_gf40lp_laint_is_enabled(hw);
0356     u32 val, vco, old_postdiv1, old_postdiv2;
0357     const char *name = clk_hw_get_name(hw);
0358 
0359     if (rate < MIN_OUTPUT_LA || rate > MAX_OUTPUT_LA)
0360         return -EINVAL;
0361 
0362     params = pll_get_params(pll, parent_rate, rate);
0363     if (!params || !params->refdiv)
0364         return -EINVAL;
0365 
0366     vco = div_u64(params->fref * params->fbdiv, params->refdiv);
0367     if (vco < MIN_VCO_LA || vco > MAX_VCO_LA)
0368         pr_warn("%s: VCO %u is out of range %lu..%lu\n", name, vco,
0369             MIN_VCO_LA, MAX_VCO_LA);
0370 
0371     val = div_u64(params->fref, params->refdiv);
0372     if (val < MIN_PFD)
0373         pr_warn("%s: PFD %u is too low (min %lu)\n",
0374             name, val, MIN_PFD);
0375     if (val > vco / 16)
0376         pr_warn("%s: PFD %u is too high (max %u)\n",
0377             name, val, vco / 16);
0378 
0379     val = pll_readl(pll, PLL_CTRL1);
0380 
0381     old_postdiv1 = (val >> PLL_INT_CTRL1_POSTDIV1_SHIFT) &
0382                PLL_INT_CTRL1_POSTDIV1_MASK;
0383     old_postdiv2 = (val >> PLL_INT_CTRL1_POSTDIV2_SHIFT) &
0384                PLL_INT_CTRL1_POSTDIV2_MASK;
0385     if (enabled &&
0386         (params->postdiv1 != old_postdiv1 ||
0387          params->postdiv2 != old_postdiv2))
0388         pr_warn("%s: changing postdiv while PLL is enabled\n", name);
0389 
0390     if (params->postdiv2 > params->postdiv1)
0391         pr_warn("%s: postdiv2 should not exceed postdiv1\n", name);
0392 
0393     val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) |
0394          (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT) |
0395          (PLL_INT_CTRL1_POSTDIV1_MASK << PLL_INT_CTRL1_POSTDIV1_SHIFT) |
0396          (PLL_INT_CTRL1_POSTDIV2_MASK << PLL_INT_CTRL1_POSTDIV2_SHIFT));
0397     val |= (params->refdiv << PLL_CTRL1_REFDIV_SHIFT) |
0398         (params->fbdiv << PLL_CTRL1_FBDIV_SHIFT) |
0399         (params->postdiv1 << PLL_INT_CTRL1_POSTDIV1_SHIFT) |
0400         (params->postdiv2 << PLL_INT_CTRL1_POSTDIV2_SHIFT);
0401     pll_writel(pll, val, PLL_CTRL1);
0402 
0403     if (enabled)
0404         pll_lock(pll);
0405 
0406     return 0;
0407 }
0408 
0409 static unsigned long pll_gf40lp_laint_recalc_rate(struct clk_hw *hw,
0410                           unsigned long parent_rate)
0411 {
0412     struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
0413     u32 val, prediv, fbdiv, postdiv1, postdiv2;
0414     u64 rate = parent_rate;
0415 
0416     val = pll_readl(pll, PLL_CTRL1);
0417     prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK;
0418     fbdiv = (val >> PLL_CTRL1_FBDIV_SHIFT) & PLL_CTRL1_FBDIV_MASK;
0419     postdiv1 = (val >> PLL_INT_CTRL1_POSTDIV1_SHIFT) &
0420         PLL_INT_CTRL1_POSTDIV1_MASK;
0421     postdiv2 = (val >> PLL_INT_CTRL1_POSTDIV2_SHIFT) &
0422         PLL_INT_CTRL1_POSTDIV2_MASK;
0423 
0424     rate *= fbdiv;
0425     rate = do_div_round_closest(rate, prediv * postdiv1 * postdiv2);
0426 
0427     return rate;
0428 }
0429 
0430 static const struct clk_ops pll_gf40lp_laint_ops = {
0431     .enable = pll_gf40lp_laint_enable,
0432     .disable = pll_gf40lp_laint_disable,
0433     .is_enabled = pll_gf40lp_laint_is_enabled,
0434     .recalc_rate = pll_gf40lp_laint_recalc_rate,
0435     .round_rate = pll_round_rate,
0436     .set_rate = pll_gf40lp_laint_set_rate,
0437 };
0438 
0439 static const struct clk_ops pll_gf40lp_laint_fixed_ops = {
0440     .enable = pll_gf40lp_laint_enable,
0441     .disable = pll_gf40lp_laint_disable,
0442     .is_enabled = pll_gf40lp_laint_is_enabled,
0443     .recalc_rate = pll_gf40lp_laint_recalc_rate,
0444 };
0445 
0446 static struct clk *pll_register(const char *name, const char *parent_name,
0447                 unsigned long flags, void __iomem *base,
0448                 enum pistachio_pll_type type,
0449                 struct pistachio_pll_rate_table *rates,
0450                 unsigned int nr_rates)
0451 {
0452     struct pistachio_clk_pll *pll;
0453     struct clk_init_data init;
0454     struct clk *clk;
0455 
0456     pll = kzalloc(sizeof(*pll), GFP_KERNEL);
0457     if (!pll)
0458         return ERR_PTR(-ENOMEM);
0459 
0460     init.name = name;
0461     init.flags = flags | CLK_GET_RATE_NOCACHE;
0462     init.parent_names = &parent_name;
0463     init.num_parents = 1;
0464 
0465     switch (type) {
0466     case PLL_GF40LP_FRAC:
0467         if (rates)
0468             init.ops = &pll_gf40lp_frac_ops;
0469         else
0470             init.ops = &pll_gf40lp_frac_fixed_ops;
0471         break;
0472     case PLL_GF40LP_LAINT:
0473         if (rates)
0474             init.ops = &pll_gf40lp_laint_ops;
0475         else
0476             init.ops = &pll_gf40lp_laint_fixed_ops;
0477         break;
0478     default:
0479         pr_err("Unrecognized PLL type %u\n", type);
0480         kfree(pll);
0481         return ERR_PTR(-EINVAL);
0482     }
0483 
0484     pll->hw.init = &init;
0485     pll->base = base;
0486     pll->rates = rates;
0487     pll->nr_rates = nr_rates;
0488 
0489     clk = clk_register(NULL, &pll->hw);
0490     if (IS_ERR(clk))
0491         kfree(pll);
0492 
0493     return clk;
0494 }
0495 
0496 void pistachio_clk_register_pll(struct pistachio_clk_provider *p,
0497                 struct pistachio_pll *pll,
0498                 unsigned int num)
0499 {
0500     struct clk *clk;
0501     unsigned int i;
0502 
0503     for (i = 0; i < num; i++) {
0504         clk = pll_register(pll[i].name, pll[i].parent,
0505                    0, p->base + pll[i].reg_base,
0506                    pll[i].type, pll[i].rates,
0507                    pll[i].nr_rates);
0508         p->clk_data.clks[pll[i].id] = clk;
0509     }
0510 }