0001
0002
0003
0004 #include <linux/kernel.h>
0005 #include <linux/err.h>
0006 #include <linux/clk-provider.h>
0007 #include <linux/io.h>
0008 #include <linux/of.h>
0009 #include <linux/clkdev.h>
0010 #include <linux/of_address.h>
0011 #include <linux/delay.h>
0012
0013 #include "clk-iproc.h"
0014
0015 #define PLL_VCO_HIGH_SHIFT 19
0016 #define PLL_VCO_LOW_SHIFT 30
0017
0018
0019
0020
0021
0022 #define PLL_USER_MODE 7
0023
0024
0025 #define LOCK_DELAY 100
0026
0027
0028 #define NUM_FREQ_BANDS 8
0029
0030 #define NUM_KP_BANDS 3
0031 enum kp_band {
0032 KP_BAND_MID = 0,
0033 KP_BAND_HIGH,
0034 KP_BAND_HIGH_HIGH
0035 };
0036
0037 static const unsigned int kp_table[NUM_KP_BANDS][NUM_FREQ_BANDS] = {
0038 { 5, 6, 6, 7, 7, 8, 9, 10 },
0039 { 4, 4, 5, 5, 6, 7, 8, 9 },
0040 { 4, 5, 5, 6, 7, 8, 9, 10 },
0041 };
0042
0043 static const unsigned long ref_freq_table[NUM_FREQ_BANDS][2] = {
0044 { 10000000, 12500000 },
0045 { 12500000, 15000000 },
0046 { 15000000, 20000000 },
0047 { 20000000, 25000000 },
0048 { 25000000, 50000000 },
0049 { 50000000, 75000000 },
0050 { 75000000, 100000000 },
0051 { 100000000, 125000000 },
0052 };
0053
0054 enum vco_freq_range {
0055 VCO_LOW = 700000000U,
0056 VCO_MID = 1200000000U,
0057 VCO_HIGH = 2200000000U,
0058 VCO_HIGH_HIGH = 3100000000U,
0059 VCO_MAX = 4000000000U,
0060 };
0061
0062 struct iproc_pll {
0063 void __iomem *status_base;
0064 void __iomem *control_base;
0065 void __iomem *pwr_base;
0066 void __iomem *asiu_base;
0067
0068 const struct iproc_pll_ctrl *ctrl;
0069 const struct iproc_pll_vco_param *vco_param;
0070 unsigned int num_vco_entries;
0071 };
0072
0073 struct iproc_clk {
0074 struct clk_hw hw;
0075 struct iproc_pll *pll;
0076 const struct iproc_clk_ctrl *ctrl;
0077 };
0078
0079 #define to_iproc_clk(hw) container_of(hw, struct iproc_clk, hw)
0080
0081 static int pll_calc_param(unsigned long target_rate,
0082 unsigned long parent_rate,
0083 struct iproc_pll_vco_param *vco_out)
0084 {
0085 u64 ndiv_int, ndiv_frac, residual;
0086
0087 ndiv_int = target_rate / parent_rate;
0088
0089 if (!ndiv_int || (ndiv_int > 255))
0090 return -EINVAL;
0091
0092 residual = target_rate - (ndiv_int * parent_rate);
0093 residual <<= 20;
0094
0095
0096
0097
0098
0099 residual += (parent_rate / 2);
0100 ndiv_frac = div64_u64((u64)residual, (u64)parent_rate);
0101
0102 vco_out->ndiv_int = ndiv_int;
0103 vco_out->ndiv_frac = ndiv_frac;
0104 vco_out->pdiv = 1;
0105
0106 vco_out->rate = vco_out->ndiv_int * parent_rate;
0107 residual = (u64)vco_out->ndiv_frac * (u64)parent_rate;
0108 residual >>= 20;
0109 vco_out->rate += residual;
0110
0111 return 0;
0112 }
0113
0114
0115
0116
0117
0118 static int pll_get_rate_index(struct iproc_pll *pll, unsigned int target_rate)
0119 {
0120 int i;
0121
0122 for (i = 0; i < pll->num_vco_entries; i++)
0123 if (target_rate == pll->vco_param[i].rate)
0124 break;
0125
0126 if (i >= pll->num_vco_entries)
0127 return -EINVAL;
0128
0129 return i;
0130 }
0131
0132 static int get_kp(unsigned long ref_freq, enum kp_band kp_index)
0133 {
0134 int i;
0135
0136 if (ref_freq < ref_freq_table[0][0])
0137 return -EINVAL;
0138
0139 for (i = 0; i < NUM_FREQ_BANDS; i++) {
0140 if (ref_freq >= ref_freq_table[i][0] &&
0141 ref_freq < ref_freq_table[i][1])
0142 return kp_table[kp_index][i];
0143 }
0144 return -EINVAL;
0145 }
0146
0147 static int pll_wait_for_lock(struct iproc_pll *pll)
0148 {
0149 int i;
0150 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
0151
0152 for (i = 0; i < LOCK_DELAY; i++) {
0153 u32 val = readl(pll->status_base + ctrl->status.offset);
0154
0155 if (val & (1 << ctrl->status.shift))
0156 return 0;
0157 udelay(10);
0158 }
0159
0160 return -EIO;
0161 }
0162
0163 static void iproc_pll_write(const struct iproc_pll *pll, void __iomem *base,
0164 const u32 offset, u32 val)
0165 {
0166 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
0167
0168 writel(val, base + offset);
0169
0170 if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK &&
0171 (base == pll->status_base || base == pll->control_base)))
0172 val = readl(base + offset);
0173 }
0174
0175 static void __pll_disable(struct iproc_pll *pll)
0176 {
0177 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
0178 u32 val;
0179
0180 if (ctrl->flags & IPROC_CLK_PLL_ASIU) {
0181 val = readl(pll->asiu_base + ctrl->asiu.offset);
0182 val &= ~(1 << ctrl->asiu.en_shift);
0183 iproc_pll_write(pll, pll->asiu_base, ctrl->asiu.offset, val);
0184 }
0185
0186 if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) {
0187 val = readl(pll->control_base + ctrl->aon.offset);
0188 val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift;
0189 iproc_pll_write(pll, pll->control_base, ctrl->aon.offset, val);
0190 }
0191
0192 if (pll->pwr_base) {
0193
0194 val = readl(pll->pwr_base + ctrl->aon.offset);
0195 val |= 1 << ctrl->aon.iso_shift;
0196 iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val);
0197
0198
0199 val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
0200 iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val);
0201 }
0202 }
0203
0204 static int __pll_enable(struct iproc_pll *pll)
0205 {
0206 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
0207 u32 val;
0208
0209 if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) {
0210 val = readl(pll->control_base + ctrl->aon.offset);
0211 val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
0212 iproc_pll_write(pll, pll->control_base, ctrl->aon.offset, val);
0213 }
0214
0215 if (pll->pwr_base) {
0216
0217 val = readl(pll->pwr_base + ctrl->aon.offset);
0218 val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift;
0219 val &= ~(1 << ctrl->aon.iso_shift);
0220 iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val);
0221 }
0222
0223
0224 if (ctrl->flags & IPROC_CLK_PLL_ASIU) {
0225 val = readl(pll->asiu_base + ctrl->asiu.offset);
0226 val |= (1 << ctrl->asiu.en_shift);
0227 iproc_pll_write(pll, pll->asiu_base, ctrl->asiu.offset, val);
0228 }
0229
0230 return 0;
0231 }
0232
0233 static void __pll_put_in_reset(struct iproc_pll *pll)
0234 {
0235 u32 val;
0236 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
0237 const struct iproc_pll_reset_ctrl *reset = &ctrl->reset;
0238
0239 val = readl(pll->control_base + reset->offset);
0240 if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW)
0241 val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift);
0242 else
0243 val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift));
0244 iproc_pll_write(pll, pll->control_base, reset->offset, val);
0245 }
0246
0247 static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp,
0248 unsigned int ka, unsigned int ki)
0249 {
0250 u32 val;
0251 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
0252 const struct iproc_pll_reset_ctrl *reset = &ctrl->reset;
0253 const struct iproc_pll_dig_filter_ctrl *dig_filter = &ctrl->dig_filter;
0254
0255 val = readl(pll->control_base + dig_filter->offset);
0256 val &= ~(bit_mask(dig_filter->ki_width) << dig_filter->ki_shift |
0257 bit_mask(dig_filter->kp_width) << dig_filter->kp_shift |
0258 bit_mask(dig_filter->ka_width) << dig_filter->ka_shift);
0259 val |= ki << dig_filter->ki_shift | kp << dig_filter->kp_shift |
0260 ka << dig_filter->ka_shift;
0261 iproc_pll_write(pll, pll->control_base, dig_filter->offset, val);
0262
0263 val = readl(pll->control_base + reset->offset);
0264 if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW)
0265 val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift));
0266 else
0267 val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift);
0268 iproc_pll_write(pll, pll->control_base, reset->offset, val);
0269 }
0270
0271
0272
0273
0274
0275
0276 static bool pll_fractional_change_only(struct iproc_pll *pll,
0277 struct iproc_pll_vco_param *vco)
0278 {
0279 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
0280 u32 val;
0281 u32 ndiv_int;
0282 unsigned int pdiv;
0283
0284
0285 val = readl(pll->status_base + ctrl->status.offset);
0286 if ((val & (1 << ctrl->status.shift)) == 0)
0287 return false;
0288
0289 val = readl(pll->control_base + ctrl->ndiv_int.offset);
0290 ndiv_int = (val >> ctrl->ndiv_int.shift) &
0291 bit_mask(ctrl->ndiv_int.width);
0292
0293 if (ndiv_int != vco->ndiv_int)
0294 return false;
0295
0296 val = readl(pll->control_base + ctrl->pdiv.offset);
0297 pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width);
0298
0299 if (pdiv != vco->pdiv)
0300 return false;
0301
0302 return true;
0303 }
0304
0305 static int pll_set_rate(struct iproc_clk *clk, struct iproc_pll_vco_param *vco,
0306 unsigned long parent_rate)
0307 {
0308 struct iproc_pll *pll = clk->pll;
0309 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
0310 int ka = 0, ki, kp, ret;
0311 unsigned long rate = vco->rate;
0312 u32 val;
0313 enum kp_band kp_index;
0314 unsigned long ref_freq;
0315 const char *clk_name = clk_hw_get_name(&clk->hw);
0316
0317
0318
0319
0320
0321 if (vco->pdiv == 0)
0322 ref_freq = parent_rate * 2;
0323 else
0324 ref_freq = parent_rate / vco->pdiv;
0325
0326
0327 if (rate >= VCO_LOW && rate < VCO_HIGH) {
0328 ki = 4;
0329 kp_index = KP_BAND_MID;
0330 } else if (rate >= VCO_HIGH && rate < VCO_HIGH_HIGH) {
0331 ki = 3;
0332 kp_index = KP_BAND_HIGH;
0333 } else if (rate >= VCO_HIGH_HIGH && rate < VCO_MAX) {
0334 ki = 3;
0335 kp_index = KP_BAND_HIGH_HIGH;
0336 } else {
0337 pr_err("%s: pll: %s has invalid rate: %lu\n", __func__,
0338 clk_name, rate);
0339 return -EINVAL;
0340 }
0341
0342 kp = get_kp(ref_freq, kp_index);
0343 if (kp < 0) {
0344 pr_err("%s: pll: %s has invalid kp\n", __func__, clk_name);
0345 return kp;
0346 }
0347
0348 ret = __pll_enable(pll);
0349 if (ret) {
0350 pr_err("%s: pll: %s fails to enable\n", __func__, clk_name);
0351 return ret;
0352 }
0353
0354 if (pll_fractional_change_only(clk->pll, vco)) {
0355
0356 if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) {
0357 val = readl(pll->control_base + ctrl->ndiv_frac.offset);
0358 val &= ~(bit_mask(ctrl->ndiv_frac.width) <<
0359 ctrl->ndiv_frac.shift);
0360 val |= vco->ndiv_frac << ctrl->ndiv_frac.shift;
0361 iproc_pll_write(pll, pll->control_base,
0362 ctrl->ndiv_frac.offset, val);
0363 return 0;
0364 }
0365 }
0366
0367
0368 __pll_put_in_reset(pll);
0369
0370
0371 if (ctrl->flags & IPROC_CLK_PLL_USER_MODE_ON) {
0372 val = readl(pll->control_base + ctrl->macro_mode.offset);
0373 val &= ~(bit_mask(ctrl->macro_mode.width) <<
0374 ctrl->macro_mode.shift);
0375 val |= PLL_USER_MODE << ctrl->macro_mode.shift;
0376 iproc_pll_write(pll, pll->control_base,
0377 ctrl->macro_mode.offset, val);
0378 }
0379
0380 iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.u_offset, 0);
0381
0382 val = readl(pll->control_base + ctrl->vco_ctrl.l_offset);
0383
0384 if (rate >= VCO_LOW && rate < VCO_MID)
0385 val |= (1 << PLL_VCO_LOW_SHIFT);
0386
0387 if (rate < VCO_HIGH)
0388 val &= ~(1 << PLL_VCO_HIGH_SHIFT);
0389 else
0390 val |= (1 << PLL_VCO_HIGH_SHIFT);
0391
0392 iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.l_offset, val);
0393
0394
0395 val = readl(pll->control_base + ctrl->ndiv_int.offset);
0396 val &= ~(bit_mask(ctrl->ndiv_int.width) << ctrl->ndiv_int.shift);
0397 val |= vco->ndiv_int << ctrl->ndiv_int.shift;
0398 iproc_pll_write(pll, pll->control_base, ctrl->ndiv_int.offset, val);
0399
0400
0401 if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) {
0402 val = readl(pll->control_base + ctrl->ndiv_frac.offset);
0403 val &= ~(bit_mask(ctrl->ndiv_frac.width) <<
0404 ctrl->ndiv_frac.shift);
0405 val |= vco->ndiv_frac << ctrl->ndiv_frac.shift;
0406 iproc_pll_write(pll, pll->control_base, ctrl->ndiv_frac.offset,
0407 val);
0408 }
0409
0410
0411 val = readl(pll->control_base + ctrl->pdiv.offset);
0412 val &= ~(bit_mask(ctrl->pdiv.width) << ctrl->pdiv.shift);
0413 val |= vco->pdiv << ctrl->pdiv.shift;
0414 iproc_pll_write(pll, pll->control_base, ctrl->pdiv.offset, val);
0415
0416 __pll_bring_out_reset(pll, kp, ka, ki);
0417
0418 ret = pll_wait_for_lock(pll);
0419 if (ret < 0) {
0420 pr_err("%s: pll: %s failed to lock\n", __func__, clk_name);
0421 return ret;
0422 }
0423
0424 return 0;
0425 }
0426
0427 static int iproc_pll_enable(struct clk_hw *hw)
0428 {
0429 struct iproc_clk *clk = to_iproc_clk(hw);
0430 struct iproc_pll *pll = clk->pll;
0431
0432 return __pll_enable(pll);
0433 }
0434
0435 static void iproc_pll_disable(struct clk_hw *hw)
0436 {
0437 struct iproc_clk *clk = to_iproc_clk(hw);
0438 struct iproc_pll *pll = clk->pll;
0439 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
0440
0441 if (ctrl->flags & IPROC_CLK_AON)
0442 return;
0443
0444 __pll_disable(pll);
0445 }
0446
0447 static unsigned long iproc_pll_recalc_rate(struct clk_hw *hw,
0448 unsigned long parent_rate)
0449 {
0450 struct iproc_clk *clk = to_iproc_clk(hw);
0451 struct iproc_pll *pll = clk->pll;
0452 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
0453 u32 val;
0454 u64 ndiv, ndiv_int, ndiv_frac;
0455 unsigned int pdiv;
0456 unsigned long rate;
0457
0458 if (parent_rate == 0)
0459 return 0;
0460
0461
0462 val = readl(pll->status_base + ctrl->status.offset);
0463 if ((val & (1 << ctrl->status.shift)) == 0)
0464 return 0;
0465
0466
0467
0468
0469
0470
0471 val = readl(pll->control_base + ctrl->ndiv_int.offset);
0472 ndiv_int = (val >> ctrl->ndiv_int.shift) &
0473 bit_mask(ctrl->ndiv_int.width);
0474 ndiv = ndiv_int << 20;
0475
0476 if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) {
0477 val = readl(pll->control_base + ctrl->ndiv_frac.offset);
0478 ndiv_frac = (val >> ctrl->ndiv_frac.shift) &
0479 bit_mask(ctrl->ndiv_frac.width);
0480 ndiv += ndiv_frac;
0481 }
0482
0483 val = readl(pll->control_base + ctrl->pdiv.offset);
0484 pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width);
0485
0486 rate = (ndiv * parent_rate) >> 20;
0487
0488 if (pdiv == 0)
0489 rate *= 2;
0490 else
0491 rate /= pdiv;
0492
0493 return rate;
0494 }
0495
0496 static int iproc_pll_determine_rate(struct clk_hw *hw,
0497 struct clk_rate_request *req)
0498 {
0499 unsigned int i;
0500 struct iproc_clk *clk = to_iproc_clk(hw);
0501 struct iproc_pll *pll = clk->pll;
0502 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
0503 unsigned long diff, best_diff;
0504 unsigned int best_idx = 0;
0505 int ret;
0506
0507 if (req->rate == 0 || req->best_parent_rate == 0)
0508 return -EINVAL;
0509
0510 if (ctrl->flags & IPROC_CLK_PLL_CALC_PARAM) {
0511 struct iproc_pll_vco_param vco_param;
0512
0513 ret = pll_calc_param(req->rate, req->best_parent_rate,
0514 &vco_param);
0515 if (ret)
0516 return ret;
0517
0518 req->rate = vco_param.rate;
0519 return 0;
0520 }
0521
0522 if (!pll->vco_param)
0523 return -EINVAL;
0524
0525 best_diff = ULONG_MAX;
0526 for (i = 0; i < pll->num_vco_entries; i++) {
0527 diff = abs(req->rate - pll->vco_param[i].rate);
0528 if (diff <= best_diff) {
0529 best_diff = diff;
0530 best_idx = i;
0531 }
0532
0533 if (diff == 0)
0534 break;
0535 }
0536
0537 req->rate = pll->vco_param[best_idx].rate;
0538
0539 return 0;
0540 }
0541
0542 static int iproc_pll_set_rate(struct clk_hw *hw, unsigned long rate,
0543 unsigned long parent_rate)
0544 {
0545 struct iproc_clk *clk = to_iproc_clk(hw);
0546 struct iproc_pll *pll = clk->pll;
0547 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
0548 struct iproc_pll_vco_param vco_param;
0549 int rate_index, ret;
0550
0551 if (ctrl->flags & IPROC_CLK_PLL_CALC_PARAM) {
0552 ret = pll_calc_param(rate, parent_rate, &vco_param);
0553 if (ret)
0554 return ret;
0555 } else {
0556 rate_index = pll_get_rate_index(pll, rate);
0557 if (rate_index < 0)
0558 return rate_index;
0559
0560 vco_param = pll->vco_param[rate_index];
0561 }
0562
0563 ret = pll_set_rate(clk, &vco_param, parent_rate);
0564 return ret;
0565 }
0566
0567 static const struct clk_ops iproc_pll_ops = {
0568 .enable = iproc_pll_enable,
0569 .disable = iproc_pll_disable,
0570 .recalc_rate = iproc_pll_recalc_rate,
0571 .determine_rate = iproc_pll_determine_rate,
0572 .set_rate = iproc_pll_set_rate,
0573 };
0574
0575 static int iproc_clk_enable(struct clk_hw *hw)
0576 {
0577 struct iproc_clk *clk = to_iproc_clk(hw);
0578 const struct iproc_clk_ctrl *ctrl = clk->ctrl;
0579 struct iproc_pll *pll = clk->pll;
0580 u32 val;
0581
0582
0583 val = readl(pll->control_base + ctrl->enable.offset);
0584 val &= ~(1 << ctrl->enable.enable_shift);
0585 iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val);
0586
0587
0588 val = readl(pll->control_base + ctrl->enable.offset);
0589 val &= ~(1 << ctrl->enable.hold_shift);
0590 iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val);
0591
0592 return 0;
0593 }
0594
0595 static void iproc_clk_disable(struct clk_hw *hw)
0596 {
0597 struct iproc_clk *clk = to_iproc_clk(hw);
0598 const struct iproc_clk_ctrl *ctrl = clk->ctrl;
0599 struct iproc_pll *pll = clk->pll;
0600 u32 val;
0601
0602 if (ctrl->flags & IPROC_CLK_AON)
0603 return;
0604
0605 val = readl(pll->control_base + ctrl->enable.offset);
0606 val |= 1 << ctrl->enable.enable_shift;
0607 iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val);
0608 }
0609
0610 static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw,
0611 unsigned long parent_rate)
0612 {
0613 struct iproc_clk *clk = to_iproc_clk(hw);
0614 const struct iproc_clk_ctrl *ctrl = clk->ctrl;
0615 struct iproc_pll *pll = clk->pll;
0616 u32 val;
0617 unsigned int mdiv;
0618 unsigned long rate;
0619
0620 if (parent_rate == 0)
0621 return 0;
0622
0623 val = readl(pll->control_base + ctrl->mdiv.offset);
0624 mdiv = (val >> ctrl->mdiv.shift) & bit_mask(ctrl->mdiv.width);
0625 if (mdiv == 0)
0626 mdiv = 256;
0627
0628 if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
0629 rate = parent_rate / (mdiv * 2);
0630 else
0631 rate = parent_rate / mdiv;
0632
0633 return rate;
0634 }
0635
0636 static int iproc_clk_determine_rate(struct clk_hw *hw,
0637 struct clk_rate_request *req)
0638 {
0639 unsigned int bestdiv;
0640
0641 if (req->rate == 0)
0642 return -EINVAL;
0643 if (req->rate == req->best_parent_rate)
0644 return 0;
0645
0646 bestdiv = DIV_ROUND_CLOSEST(req->best_parent_rate, req->rate);
0647 if (bestdiv < 2)
0648 req->rate = req->best_parent_rate;
0649
0650 if (bestdiv > 256)
0651 bestdiv = 256;
0652
0653 req->rate = req->best_parent_rate / bestdiv;
0654
0655 return 0;
0656 }
0657
0658 static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
0659 unsigned long parent_rate)
0660 {
0661 struct iproc_clk *clk = to_iproc_clk(hw);
0662 const struct iproc_clk_ctrl *ctrl = clk->ctrl;
0663 struct iproc_pll *pll = clk->pll;
0664 u32 val;
0665 unsigned int div;
0666
0667 if (rate == 0 || parent_rate == 0)
0668 return -EINVAL;
0669
0670 div = DIV_ROUND_CLOSEST(parent_rate, rate);
0671 if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2)
0672 div /= 2;
0673
0674 if (div > 256)
0675 return -EINVAL;
0676
0677 val = readl(pll->control_base + ctrl->mdiv.offset);
0678 if (div == 256) {
0679 val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift);
0680 } else {
0681 val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift);
0682 val |= div << ctrl->mdiv.shift;
0683 }
0684 iproc_pll_write(pll, pll->control_base, ctrl->mdiv.offset, val);
0685
0686 return 0;
0687 }
0688
0689 static const struct clk_ops iproc_clk_ops = {
0690 .enable = iproc_clk_enable,
0691 .disable = iproc_clk_disable,
0692 .recalc_rate = iproc_clk_recalc_rate,
0693 .determine_rate = iproc_clk_determine_rate,
0694 .set_rate = iproc_clk_set_rate,
0695 };
0696
0697
0698
0699
0700
0701 static void iproc_pll_sw_cfg(struct iproc_pll *pll)
0702 {
0703 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
0704
0705 if (ctrl->flags & IPROC_CLK_PLL_NEEDS_SW_CFG) {
0706 u32 val;
0707
0708 val = readl(pll->control_base + ctrl->sw_ctrl.offset);
0709 val |= BIT(ctrl->sw_ctrl.shift);
0710 iproc_pll_write(pll, pll->control_base, ctrl->sw_ctrl.offset,
0711 val);
0712 }
0713 }
0714
0715 void iproc_pll_clk_setup(struct device_node *node,
0716 const struct iproc_pll_ctrl *pll_ctrl,
0717 const struct iproc_pll_vco_param *vco,
0718 unsigned int num_vco_entries,
0719 const struct iproc_clk_ctrl *clk_ctrl,
0720 unsigned int num_clks)
0721 {
0722 int i, ret;
0723 struct iproc_pll *pll;
0724 struct iproc_clk *iclk;
0725 struct clk_init_data init;
0726 const char *parent_name;
0727 struct iproc_clk *iclk_array;
0728 struct clk_hw_onecell_data *clk_data;
0729 const char *clk_name;
0730
0731 if (WARN_ON(!pll_ctrl) || WARN_ON(!clk_ctrl))
0732 return;
0733
0734 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
0735 if (WARN_ON(!pll))
0736 return;
0737
0738 clk_data = kzalloc(struct_size(clk_data, hws, num_clks), GFP_KERNEL);
0739 if (WARN_ON(!clk_data))
0740 goto err_clk_data;
0741 clk_data->num = num_clks;
0742
0743 iclk_array = kcalloc(num_clks, sizeof(struct iproc_clk), GFP_KERNEL);
0744 if (WARN_ON(!iclk_array))
0745 goto err_clks;
0746
0747 pll->control_base = of_iomap(node, 0);
0748 if (WARN_ON(!pll->control_base))
0749 goto err_pll_iomap;
0750
0751
0752 pll->pwr_base = of_iomap(node, 1);
0753
0754
0755 if (pll_ctrl->flags & IPROC_CLK_PLL_ASIU) {
0756 pll->asiu_base = of_iomap(node, 2);
0757 if (WARN_ON(!pll->asiu_base))
0758 goto err_asiu_iomap;
0759 }
0760
0761 if (pll_ctrl->flags & IPROC_CLK_PLL_SPLIT_STAT_CTRL) {
0762
0763
0764
0765 pll->status_base = of_iomap(node, 2);
0766 if (!pll->status_base)
0767 goto err_status_iomap;
0768 } else
0769 pll->status_base = pll->control_base;
0770
0771
0772 pll->ctrl = pll_ctrl;
0773
0774 iclk = &iclk_array[0];
0775 iclk->pll = pll;
0776
0777 ret = of_property_read_string_index(node, "clock-output-names",
0778 0, &clk_name);
0779 if (WARN_ON(ret))
0780 goto err_pll_register;
0781
0782 init.name = clk_name;
0783 init.ops = &iproc_pll_ops;
0784 init.flags = 0;
0785 parent_name = of_clk_get_parent_name(node, 0);
0786 init.parent_names = (parent_name ? &parent_name : NULL);
0787 init.num_parents = (parent_name ? 1 : 0);
0788 iclk->hw.init = &init;
0789
0790 if (vco) {
0791 pll->num_vco_entries = num_vco_entries;
0792 pll->vco_param = vco;
0793 }
0794
0795 iproc_pll_sw_cfg(pll);
0796
0797 ret = clk_hw_register(NULL, &iclk->hw);
0798 if (WARN_ON(ret))
0799 goto err_pll_register;
0800
0801 clk_data->hws[0] = &iclk->hw;
0802 parent_name = clk_name;
0803
0804
0805 for (i = 1; i < num_clks; i++) {
0806 memset(&init, 0, sizeof(init));
0807
0808 ret = of_property_read_string_index(node, "clock-output-names",
0809 i, &clk_name);
0810 if (WARN_ON(ret))
0811 goto err_clk_register;
0812
0813 iclk = &iclk_array[i];
0814 iclk->pll = pll;
0815 iclk->ctrl = &clk_ctrl[i];
0816
0817 init.name = clk_name;
0818 init.ops = &iproc_clk_ops;
0819 init.flags = 0;
0820 init.parent_names = (parent_name ? &parent_name : NULL);
0821 init.num_parents = (parent_name ? 1 : 0);
0822 iclk->hw.init = &init;
0823
0824 ret = clk_hw_register(NULL, &iclk->hw);
0825 if (WARN_ON(ret))
0826 goto err_clk_register;
0827
0828 clk_data->hws[i] = &iclk->hw;
0829 }
0830
0831 ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
0832 if (WARN_ON(ret))
0833 goto err_clk_register;
0834
0835 return;
0836
0837 err_clk_register:
0838 while (--i >= 0)
0839 clk_hw_unregister(clk_data->hws[i]);
0840
0841 err_pll_register:
0842 if (pll->status_base != pll->control_base)
0843 iounmap(pll->status_base);
0844
0845 err_status_iomap:
0846 if (pll->asiu_base)
0847 iounmap(pll->asiu_base);
0848
0849 err_asiu_iomap:
0850 if (pll->pwr_base)
0851 iounmap(pll->pwr_base);
0852
0853 iounmap(pll->control_base);
0854
0855 err_pll_iomap:
0856 kfree(iclk_array);
0857
0858 err_clks:
0859 kfree(clk_data);
0860
0861 err_clk_data:
0862 kfree(pll);
0863 }