0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/delay.h>
0009 #include <linux/err.h>
0010 #include <linux/regmap.h>
0011 #include <linux/slab.h>
0012
0013 #include "pll.h"
0014
0015 #define CLK_PLL_1M 1000000
0016 #define CLK_PLL_10M (CLK_PLL_1M * 10)
0017
0018 #define pindex(pll, member) \
0019 (pll->factors[member].shift / (8 * sizeof(pll->regs_num)))
0020
0021 #define pshift(pll, member) \
0022 (pll->factors[member].shift % (8 * sizeof(pll->regs_num)))
0023
0024 #define pwidth(pll, member) \
0025 pll->factors[member].width
0026
0027 #define pmask(pll, member) \
0028 ((pwidth(pll, member)) ? \
0029 GENMASK(pwidth(pll, member) + pshift(pll, member) - 1, \
0030 pshift(pll, member)) : 0)
0031
0032 #define pinternal(pll, cfg, member) \
0033 (cfg[pindex(pll, member)] & pmask(pll, member))
0034
0035 #define pinternal_val(pll, cfg, member) \
0036 (pinternal(pll, cfg, member) >> pshift(pll, member))
0037
0038 static inline unsigned int
0039 sprd_pll_read(const struct sprd_pll *pll, u8 index)
0040 {
0041 const struct sprd_clk_common *common = &pll->common;
0042 unsigned int val = 0;
0043
0044 if (WARN_ON(index >= pll->regs_num))
0045 return 0;
0046
0047 regmap_read(common->regmap, common->reg + index * 4, &val);
0048
0049 return val;
0050 }
0051
0052 static inline void
0053 sprd_pll_write(const struct sprd_pll *pll, u8 index,
0054 u32 msk, u32 val)
0055 {
0056 const struct sprd_clk_common *common = &pll->common;
0057 unsigned int offset, reg;
0058 int ret = 0;
0059
0060 if (WARN_ON(index >= pll->regs_num))
0061 return;
0062
0063 offset = common->reg + index * 4;
0064 ret = regmap_read(common->regmap, offset, ®);
0065 if (!ret)
0066 regmap_write(common->regmap, offset, (reg & ~msk) | val);
0067 }
0068
0069 static unsigned long pll_get_refin(const struct sprd_pll *pll)
0070 {
0071 u32 shift, mask, index, refin_id = 3;
0072 const unsigned long refin[4] = { 2, 4, 13, 26 };
0073
0074 if (pwidth(pll, PLL_REFIN)) {
0075 index = pindex(pll, PLL_REFIN);
0076 shift = pshift(pll, PLL_REFIN);
0077 mask = pmask(pll, PLL_REFIN);
0078 refin_id = (sprd_pll_read(pll, index) & mask) >> shift;
0079 if (refin_id > 3)
0080 refin_id = 3;
0081 }
0082
0083 return refin[refin_id];
0084 }
0085
0086 static u32 pll_get_ibias(u64 rate, const u64 *table)
0087 {
0088 u32 i, num = table[0];
0089
0090
0091 for (i = 0; i < num; i++)
0092 if (rate <= table[i + 1])
0093 break;
0094
0095 return i == num ? num - 1 : i;
0096 }
0097
0098 static unsigned long _sprd_pll_recalc_rate(const struct sprd_pll *pll,
0099 unsigned long parent_rate)
0100 {
0101 u32 *cfg;
0102 u32 i, mask, regs_num = pll->regs_num;
0103 unsigned long rate, nint, kint = 0;
0104 u64 refin;
0105 u16 k1, k2;
0106
0107 cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL);
0108 if (!cfg)
0109 return parent_rate;
0110
0111 for (i = 0; i < regs_num; i++)
0112 cfg[i] = sprd_pll_read(pll, i);
0113
0114 refin = pll_get_refin(pll);
0115
0116 if (pinternal(pll, cfg, PLL_PREDIV))
0117 refin = refin * 2;
0118
0119 if (pwidth(pll, PLL_POSTDIV) &&
0120 ((pll->fflag == 1 && pinternal(pll, cfg, PLL_POSTDIV)) ||
0121 (!pll->fflag && !pinternal(pll, cfg, PLL_POSTDIV))))
0122 refin = refin / 2;
0123
0124 if (!pinternal(pll, cfg, PLL_DIV_S)) {
0125 rate = refin * pinternal_val(pll, cfg, PLL_N) * CLK_PLL_10M;
0126 } else {
0127 nint = pinternal_val(pll, cfg, PLL_NINT);
0128 if (pinternal(pll, cfg, PLL_SDM_EN))
0129 kint = pinternal_val(pll, cfg, PLL_KINT);
0130
0131 mask = pmask(pll, PLL_KINT);
0132
0133 k1 = pll->k1;
0134 k2 = pll->k2;
0135 rate = DIV_ROUND_CLOSEST_ULL(refin * kint * k1,
0136 ((mask >> __ffs(mask)) + 1)) *
0137 k2 + refin * nint * CLK_PLL_1M;
0138 }
0139
0140 kfree(cfg);
0141 return rate;
0142 }
0143
0144 #define SPRD_PLL_WRITE_CHECK(pll, i, mask, val) \
0145 (((sprd_pll_read(pll, i) & mask) == val) ? 0 : (-EFAULT))
0146
0147 static int _sprd_pll_set_rate(const struct sprd_pll *pll,
0148 unsigned long rate,
0149 unsigned long parent_rate)
0150 {
0151 struct reg_cfg *cfg;
0152 int ret = 0;
0153 u32 mask, shift, width, ibias_val, index;
0154 u32 regs_num = pll->regs_num, i = 0;
0155 unsigned long kint, nint;
0156 u64 tmp, refin, fvco = rate;
0157
0158 cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL);
0159 if (!cfg)
0160 return -ENOMEM;
0161
0162 refin = pll_get_refin(pll);
0163
0164 mask = pmask(pll, PLL_PREDIV);
0165 index = pindex(pll, PLL_PREDIV);
0166 width = pwidth(pll, PLL_PREDIV);
0167 if (width && (sprd_pll_read(pll, index) & mask))
0168 refin = refin * 2;
0169
0170 mask = pmask(pll, PLL_POSTDIV);
0171 index = pindex(pll, PLL_POSTDIV);
0172 width = pwidth(pll, PLL_POSTDIV);
0173 cfg[index].msk = mask;
0174 if (width && ((pll->fflag == 1 && fvco <= pll->fvco) ||
0175 (pll->fflag == 0 && fvco > pll->fvco)))
0176 cfg[index].val |= mask;
0177
0178 if (width && fvco <= pll->fvco)
0179 fvco = fvco * 2;
0180
0181 mask = pmask(pll, PLL_DIV_S);
0182 index = pindex(pll, PLL_DIV_S);
0183 cfg[index].val |= mask;
0184 cfg[index].msk |= mask;
0185
0186 mask = pmask(pll, PLL_SDM_EN);
0187 index = pindex(pll, PLL_SDM_EN);
0188 cfg[index].val |= mask;
0189 cfg[index].msk |= mask;
0190
0191 nint = do_div(fvco, refin * CLK_PLL_1M);
0192 mask = pmask(pll, PLL_NINT);
0193 index = pindex(pll, PLL_NINT);
0194 shift = pshift(pll, PLL_NINT);
0195 cfg[index].val |= (nint << shift) & mask;
0196 cfg[index].msk |= mask;
0197
0198 mask = pmask(pll, PLL_KINT);
0199 index = pindex(pll, PLL_KINT);
0200 width = pwidth(pll, PLL_KINT);
0201 shift = pshift(pll, PLL_KINT);
0202 tmp = fvco - refin * nint * CLK_PLL_1M;
0203 tmp = do_div(tmp, 10000) * ((mask >> shift) + 1);
0204 kint = DIV_ROUND_CLOSEST_ULL(tmp, refin * 100);
0205 cfg[index].val |= (kint << shift) & mask;
0206 cfg[index].msk |= mask;
0207
0208 ibias_val = pll_get_ibias(fvco, pll->itable);
0209
0210 mask = pmask(pll, PLL_IBIAS);
0211 index = pindex(pll, PLL_IBIAS);
0212 shift = pshift(pll, PLL_IBIAS);
0213 cfg[index].val |= ibias_val << shift & mask;
0214 cfg[index].msk |= mask;
0215
0216 for (i = 0; i < regs_num; i++) {
0217 if (cfg[i].msk) {
0218 sprd_pll_write(pll, i, cfg[i].msk, cfg[i].val);
0219 ret |= SPRD_PLL_WRITE_CHECK(pll, i, cfg[i].msk,
0220 cfg[i].val);
0221 }
0222 }
0223
0224 if (!ret)
0225 udelay(pll->udelay);
0226
0227 kfree(cfg);
0228 return ret;
0229 }
0230
0231 static unsigned long sprd_pll_recalc_rate(struct clk_hw *hw,
0232 unsigned long parent_rate)
0233 {
0234 struct sprd_pll *pll = hw_to_sprd_pll(hw);
0235
0236 return _sprd_pll_recalc_rate(pll, parent_rate);
0237 }
0238
0239 static int sprd_pll_set_rate(struct clk_hw *hw,
0240 unsigned long rate,
0241 unsigned long parent_rate)
0242 {
0243 struct sprd_pll *pll = hw_to_sprd_pll(hw);
0244
0245 return _sprd_pll_set_rate(pll, rate, parent_rate);
0246 }
0247
0248 static int sprd_pll_clk_prepare(struct clk_hw *hw)
0249 {
0250 struct sprd_pll *pll = hw_to_sprd_pll(hw);
0251
0252 udelay(pll->udelay);
0253
0254 return 0;
0255 }
0256
0257 static long sprd_pll_round_rate(struct clk_hw *hw, unsigned long rate,
0258 unsigned long *prate)
0259 {
0260 return rate;
0261 }
0262
0263 const struct clk_ops sprd_pll_ops = {
0264 .prepare = sprd_pll_clk_prepare,
0265 .recalc_rate = sprd_pll_recalc_rate,
0266 .round_rate = sprd_pll_round_rate,
0267 .set_rate = sprd_pll_set_rate,
0268 };
0269 EXPORT_SYMBOL_GPL(sprd_pll_ops);