Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2014 Texas Instruments Incorporated
0004  */
0005 
0006 #define DSS_SUBSYS_NAME "PLL"
0007 
0008 #include <linux/clk.h>
0009 #include <linux/io.h>
0010 #include <linux/kernel.h>
0011 #include <linux/regulator/consumer.h>
0012 #include <linux/sched.h>
0013 
0014 #include <video/omapfb_dss.h>
0015 
0016 #include "dss.h"
0017 
0018 #define PLL_CONTROL         0x0000
0019 #define PLL_STATUS          0x0004
0020 #define PLL_GO              0x0008
0021 #define PLL_CONFIGURATION1      0x000C
0022 #define PLL_CONFIGURATION2      0x0010
0023 #define PLL_CONFIGURATION3      0x0014
0024 #define PLL_SSC_CONFIGURATION1      0x0018
0025 #define PLL_SSC_CONFIGURATION2      0x001C
0026 #define PLL_CONFIGURATION4      0x0020
0027 
0028 static struct dss_pll *dss_plls[4];
0029 
0030 int dss_pll_register(struct dss_pll *pll)
0031 {
0032     int i;
0033 
0034     for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
0035         if (!dss_plls[i]) {
0036             dss_plls[i] = pll;
0037             return 0;
0038         }
0039     }
0040 
0041     return -EBUSY;
0042 }
0043 
0044 void dss_pll_unregister(struct dss_pll *pll)
0045 {
0046     int i;
0047 
0048     for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
0049         if (dss_plls[i] == pll) {
0050             dss_plls[i] = NULL;
0051             return;
0052         }
0053     }
0054 }
0055 
0056 struct dss_pll *dss_pll_find(const char *name)
0057 {
0058     int i;
0059 
0060     for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
0061         if (dss_plls[i] && strcmp(dss_plls[i]->name, name) == 0)
0062             return dss_plls[i];
0063     }
0064 
0065     return NULL;
0066 }
0067 
0068 int dss_pll_enable(struct dss_pll *pll)
0069 {
0070     int r;
0071 
0072     r = clk_prepare_enable(pll->clkin);
0073     if (r)
0074         return r;
0075 
0076     if (pll->regulator) {
0077         r = regulator_enable(pll->regulator);
0078         if (r)
0079             goto err_reg;
0080     }
0081 
0082     r = pll->ops->enable(pll);
0083     if (r)
0084         goto err_enable;
0085 
0086     return 0;
0087 
0088 err_enable:
0089     if (pll->regulator)
0090         regulator_disable(pll->regulator);
0091 err_reg:
0092     clk_disable_unprepare(pll->clkin);
0093     return r;
0094 }
0095 
0096 void dss_pll_disable(struct dss_pll *pll)
0097 {
0098     pll->ops->disable(pll);
0099 
0100     if (pll->regulator)
0101         regulator_disable(pll->regulator);
0102 
0103     clk_disable_unprepare(pll->clkin);
0104 
0105     memset(&pll->cinfo, 0, sizeof(pll->cinfo));
0106 }
0107 
0108 int dss_pll_set_config(struct dss_pll *pll, const struct dss_pll_clock_info *cinfo)
0109 {
0110     int r;
0111 
0112     r = pll->ops->set_config(pll, cinfo);
0113     if (r)
0114         return r;
0115 
0116     pll->cinfo = *cinfo;
0117 
0118     return 0;
0119 }
0120 
0121 bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco,
0122         unsigned long out_min, unsigned long out_max,
0123         dss_hsdiv_calc_func func, void *data)
0124 {
0125     const struct dss_pll_hw *hw = pll->hw;
0126     int m, m_start, m_stop;
0127     unsigned long out;
0128 
0129     out_min = out_min ? out_min : 1;
0130     out_max = out_max ? out_max : ULONG_MAX;
0131 
0132     m_start = max(DIV_ROUND_UP(clkdco, out_max), 1ul);
0133 
0134     m_stop = min((unsigned)(clkdco / out_min), hw->mX_max);
0135 
0136     for (m = m_start; m <= m_stop; ++m) {
0137         out = clkdco / m;
0138 
0139         if (func(m, out, data))
0140             return true;
0141     }
0142 
0143     return false;
0144 }
0145 
0146 bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin,
0147         unsigned long pll_min, unsigned long pll_max,
0148         dss_pll_calc_func func, void *data)
0149 {
0150     const struct dss_pll_hw *hw = pll->hw;
0151     int n, n_start, n_stop;
0152     int m, m_start, m_stop;
0153     unsigned long fint, clkdco;
0154     unsigned long pll_hw_max;
0155     unsigned long fint_hw_min, fint_hw_max;
0156 
0157     pll_hw_max = hw->clkdco_max;
0158 
0159     fint_hw_min = hw->fint_min;
0160     fint_hw_max = hw->fint_max;
0161 
0162     n_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
0163     n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max);
0164 
0165     pll_max = pll_max ? pll_max : ULONG_MAX;
0166 
0167     for (n = n_start; n <= n_stop; ++n) {
0168         fint = clkin / n;
0169 
0170         m_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
0171                 1ul);
0172         m_stop = min3((unsigned)(pll_max / fint / 2),
0173                 (unsigned)(pll_hw_max / fint / 2),
0174                 hw->m_max);
0175 
0176         for (m = m_start; m <= m_stop; ++m) {
0177             clkdco = 2 * m * fint;
0178 
0179             if (func(n, m, fint, clkdco, data))
0180                 return true;
0181         }
0182     }
0183 
0184     return false;
0185 }
0186 
0187 static int wait_for_bit_change(void __iomem *reg, int bitnum, int value)
0188 {
0189     unsigned long timeout;
0190     ktime_t wait;
0191     int t;
0192 
0193     /* first busyloop to see if the bit changes right away */
0194     t = 100;
0195     while (t-- > 0) {
0196         if (FLD_GET(readl_relaxed(reg), bitnum, bitnum) == value)
0197             return value;
0198     }
0199 
0200     /* then loop for 500ms, sleeping for 1ms in between */
0201     timeout = jiffies + msecs_to_jiffies(500);
0202     while (time_before(jiffies, timeout)) {
0203         if (FLD_GET(readl_relaxed(reg), bitnum, bitnum) == value)
0204             return value;
0205 
0206         wait = ns_to_ktime(1000 * 1000);
0207         set_current_state(TASK_UNINTERRUPTIBLE);
0208         schedule_hrtimeout(&wait, HRTIMER_MODE_REL);
0209     }
0210 
0211     return !value;
0212 }
0213 
0214 int dss_pll_wait_reset_done(struct dss_pll *pll)
0215 {
0216     void __iomem *base = pll->base;
0217 
0218     if (wait_for_bit_change(base + PLL_STATUS, 0, 1) != 1)
0219         return -ETIMEDOUT;
0220     else
0221         return 0;
0222 }
0223 
0224 static int dss_wait_hsdiv_ack(struct dss_pll *pll, u32 hsdiv_ack_mask)
0225 {
0226     int t = 100;
0227 
0228     while (t-- > 0) {
0229         u32 v = readl_relaxed(pll->base + PLL_STATUS);
0230         v &= hsdiv_ack_mask;
0231         if (v == hsdiv_ack_mask)
0232             return 0;
0233     }
0234 
0235     return -ETIMEDOUT;
0236 }
0237 
0238 int dss_pll_write_config_type_a(struct dss_pll *pll,
0239         const struct dss_pll_clock_info *cinfo)
0240 {
0241     const struct dss_pll_hw *hw = pll->hw;
0242     void __iomem *base = pll->base;
0243     int r = 0;
0244     u32 l;
0245 
0246     l = 0;
0247     if (hw->has_stopmode)
0248         l = FLD_MOD(l, 1, 0, 0);        /* PLL_STOPMODE */
0249     l = FLD_MOD(l, cinfo->n - 1, hw->n_msb, hw->n_lsb); /* PLL_REGN */
0250     l = FLD_MOD(l, cinfo->m, hw->m_msb, hw->m_lsb);     /* PLL_REGM */
0251     /* M4 */
0252     l = FLD_MOD(l, cinfo->mX[0] ? cinfo->mX[0] - 1 : 0,
0253             hw->mX_msb[0], hw->mX_lsb[0]);
0254     /* M5 */
0255     l = FLD_MOD(l, cinfo->mX[1] ? cinfo->mX[1] - 1 : 0,
0256             hw->mX_msb[1], hw->mX_lsb[1]);
0257     writel_relaxed(l, base + PLL_CONFIGURATION1);
0258 
0259     l = 0;
0260     /* M6 */
0261     l = FLD_MOD(l, cinfo->mX[2] ? cinfo->mX[2] - 1 : 0,
0262             hw->mX_msb[2], hw->mX_lsb[2]);
0263     /* M7 */
0264     l = FLD_MOD(l, cinfo->mX[3] ? cinfo->mX[3] - 1 : 0,
0265             hw->mX_msb[3], hw->mX_lsb[3]);
0266     writel_relaxed(l, base + PLL_CONFIGURATION3);
0267 
0268     l = readl_relaxed(base + PLL_CONFIGURATION2);
0269     if (hw->has_freqsel) {
0270         u32 f = cinfo->fint < 1000000 ? 0x3 :
0271             cinfo->fint < 1250000 ? 0x4 :
0272             cinfo->fint < 1500000 ? 0x5 :
0273             cinfo->fint < 1750000 ? 0x6 :
0274             0x7;
0275 
0276         l = FLD_MOD(l, f, 4, 1);    /* PLL_FREQSEL */
0277     } else if (hw->has_selfreqdco) {
0278         u32 f = cinfo->clkdco < hw->clkdco_low ? 0x2 : 0x4;
0279 
0280         l = FLD_MOD(l, f, 3, 1);    /* PLL_SELFREQDCO */
0281     }
0282     l = FLD_MOD(l, 1, 13, 13);      /* PLL_REFEN */
0283     l = FLD_MOD(l, 0, 14, 14);      /* PHY_CLKINEN */
0284     l = FLD_MOD(l, 0, 16, 16);      /* M4_CLOCK_EN */
0285     l = FLD_MOD(l, 0, 18, 18);      /* M5_CLOCK_EN */
0286     l = FLD_MOD(l, 1, 20, 20);      /* HSDIVBYPASS */
0287     if (hw->has_refsel)
0288         l = FLD_MOD(l, 3, 22, 21);  /* REFSEL = sysclk */
0289     l = FLD_MOD(l, 0, 23, 23);      /* M6_CLOCK_EN */
0290     l = FLD_MOD(l, 0, 25, 25);      /* M7_CLOCK_EN */
0291     writel_relaxed(l, base + PLL_CONFIGURATION2);
0292 
0293     writel_relaxed(1, base + PLL_GO);   /* PLL_GO */
0294 
0295     if (wait_for_bit_change(base + PLL_GO, 0, 0) != 0) {
0296         DSSERR("DSS DPLL GO bit not going down.\n");
0297         r = -EIO;
0298         goto err;
0299     }
0300 
0301     if (wait_for_bit_change(base + PLL_STATUS, 1, 1) != 1) {
0302         DSSERR("cannot lock DSS DPLL\n");
0303         r = -EIO;
0304         goto err;
0305     }
0306 
0307     l = readl_relaxed(base + PLL_CONFIGURATION2);
0308     l = FLD_MOD(l, 1, 14, 14);          /* PHY_CLKINEN */
0309     l = FLD_MOD(l, cinfo->mX[0] ? 1 : 0, 16, 16);   /* M4_CLOCK_EN */
0310     l = FLD_MOD(l, cinfo->mX[1] ? 1 : 0, 18, 18);   /* M5_CLOCK_EN */
0311     l = FLD_MOD(l, 0, 20, 20);          /* HSDIVBYPASS */
0312     l = FLD_MOD(l, cinfo->mX[2] ? 1 : 0, 23, 23);   /* M6_CLOCK_EN */
0313     l = FLD_MOD(l, cinfo->mX[3] ? 1 : 0, 25, 25);   /* M7_CLOCK_EN */
0314     writel_relaxed(l, base + PLL_CONFIGURATION2);
0315 
0316     r = dss_wait_hsdiv_ack(pll,
0317         (cinfo->mX[0] ? BIT(7) : 0) |
0318         (cinfo->mX[1] ? BIT(8) : 0) |
0319         (cinfo->mX[2] ? BIT(10) : 0) |
0320         (cinfo->mX[3] ? BIT(11) : 0));
0321     if (r) {
0322         DSSERR("failed to enable HSDIV clocks\n");
0323         goto err;
0324     }
0325 
0326 err:
0327     return r;
0328 }
0329 
0330 int dss_pll_write_config_type_b(struct dss_pll *pll,
0331         const struct dss_pll_clock_info *cinfo)
0332 {
0333     const struct dss_pll_hw *hw = pll->hw;
0334     void __iomem *base = pll->base;
0335     u32 l;
0336 
0337     l = 0;
0338     l = FLD_MOD(l, cinfo->m, 20, 9);    /* PLL_REGM */
0339     l = FLD_MOD(l, cinfo->n - 1, 8, 1); /* PLL_REGN */
0340     writel_relaxed(l, base + PLL_CONFIGURATION1);
0341 
0342     l = readl_relaxed(base + PLL_CONFIGURATION2);
0343     l = FLD_MOD(l, 0x0, 12, 12);    /* PLL_HIGHFREQ divide by 2 */
0344     l = FLD_MOD(l, 0x1, 13, 13);    /* PLL_REFEN */
0345     l = FLD_MOD(l, 0x0, 14, 14);    /* PHY_CLKINEN */
0346     if (hw->has_refsel)
0347         l = FLD_MOD(l, 0x3, 22, 21);    /* REFSEL = SYSCLK */
0348 
0349     /* PLL_SELFREQDCO */
0350     if (cinfo->clkdco > hw->clkdco_low)
0351         l = FLD_MOD(l, 0x4, 3, 1);
0352     else
0353         l = FLD_MOD(l, 0x2, 3, 1);
0354     writel_relaxed(l, base + PLL_CONFIGURATION2);
0355 
0356     l = readl_relaxed(base + PLL_CONFIGURATION3);
0357     l = FLD_MOD(l, cinfo->sd, 17, 10);  /* PLL_REGSD */
0358     writel_relaxed(l, base + PLL_CONFIGURATION3);
0359 
0360     l = readl_relaxed(base + PLL_CONFIGURATION4);
0361     l = FLD_MOD(l, cinfo->mX[0], 24, 18);   /* PLL_REGM2 */
0362     l = FLD_MOD(l, cinfo->mf, 17, 0);   /* PLL_REGM_F */
0363     writel_relaxed(l, base + PLL_CONFIGURATION4);
0364 
0365     writel_relaxed(1, base + PLL_GO);   /* PLL_GO */
0366 
0367     if (wait_for_bit_change(base + PLL_GO, 0, 0) != 0) {
0368         DSSERR("DSS DPLL GO bit not going down.\n");
0369         return -EIO;
0370     }
0371 
0372     if (wait_for_bit_change(base + PLL_STATUS, 1, 1) != 1) {
0373         DSSERR("cannot lock DSS DPLL\n");
0374         return -ETIMEDOUT;
0375     }
0376 
0377     return 0;
0378 }