linux/drivers/video/fbdev/omap2/omapfb/dss/pll.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2014 Texas Instruments Incorporated
   4 */
   5
   6#define DSS_SUBSYS_NAME "PLL"
   7
   8#include <linux/clk.h>
   9#include <linux/io.h>
  10#include <linux/kernel.h>
  11#include <linux/regulator/consumer.h>
  12#include <linux/sched.h>
  13
  14#include <video/omapfb_dss.h>
  15
  16#include "dss.h"
  17
  18#define PLL_CONTROL                     0x0000
  19#define PLL_STATUS                      0x0004
  20#define PLL_GO                          0x0008
  21#define PLL_CONFIGURATION1              0x000C
  22#define PLL_CONFIGURATION2              0x0010
  23#define PLL_CONFIGURATION3              0x0014
  24#define PLL_SSC_CONFIGURATION1          0x0018
  25#define PLL_SSC_CONFIGURATION2          0x001C
  26#define PLL_CONFIGURATION4              0x0020
  27
  28static struct dss_pll *dss_plls[4];
  29
  30int dss_pll_register(struct dss_pll *pll)
  31{
  32        int i;
  33
  34        for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
  35                if (!dss_plls[i]) {
  36                        dss_plls[i] = pll;
  37                        return 0;
  38                }
  39        }
  40
  41        return -EBUSY;
  42}
  43
  44void dss_pll_unregister(struct dss_pll *pll)
  45{
  46        int i;
  47
  48        for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
  49                if (dss_plls[i] == pll) {
  50                        dss_plls[i] = NULL;
  51                        return;
  52                }
  53        }
  54}
  55
  56struct dss_pll *dss_pll_find(const char *name)
  57{
  58        int i;
  59
  60        for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
  61                if (dss_plls[i] && strcmp(dss_plls[i]->name, name) == 0)
  62                        return dss_plls[i];
  63        }
  64
  65        return NULL;
  66}
  67
  68int dss_pll_enable(struct dss_pll *pll)
  69{
  70        int r;
  71
  72        r = clk_prepare_enable(pll->clkin);
  73        if (r)
  74                return r;
  75
  76        if (pll->regulator) {
  77                r = regulator_enable(pll->regulator);
  78                if (r)
  79                        goto err_reg;
  80        }
  81
  82        r = pll->ops->enable(pll);
  83        if (r)
  84                goto err_enable;
  85
  86        return 0;
  87
  88err_enable:
  89        if (pll->regulator)
  90                regulator_disable(pll->regulator);
  91err_reg:
  92        clk_disable_unprepare(pll->clkin);
  93        return r;
  94}
  95
  96void dss_pll_disable(struct dss_pll *pll)
  97{
  98        pll->ops->disable(pll);
  99
 100        if (pll->regulator)
 101                regulator_disable(pll->regulator);
 102
 103        clk_disable_unprepare(pll->clkin);
 104
 105        memset(&pll->cinfo, 0, sizeof(pll->cinfo));
 106}
 107
 108int dss_pll_set_config(struct dss_pll *pll, const struct dss_pll_clock_info *cinfo)
 109{
 110        int r;
 111
 112        r = pll->ops->set_config(pll, cinfo);
 113        if (r)
 114                return r;
 115
 116        pll->cinfo = *cinfo;
 117
 118        return 0;
 119}
 120
 121bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco,
 122                unsigned long out_min, unsigned long out_max,
 123                dss_hsdiv_calc_func func, void *data)
 124{
 125        const struct dss_pll_hw *hw = pll->hw;
 126        int m, m_start, m_stop;
 127        unsigned long out;
 128
 129        out_min = out_min ? out_min : 1;
 130        out_max = out_max ? out_max : ULONG_MAX;
 131
 132        m_start = max(DIV_ROUND_UP(clkdco, out_max), 1ul);
 133
 134        m_stop = min((unsigned)(clkdco / out_min), hw->mX_max);
 135
 136        for (m = m_start; m <= m_stop; ++m) {
 137                out = clkdco / m;
 138
 139                if (func(m, out, data))
 140                        return true;
 141        }
 142
 143        return false;
 144}
 145
 146bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin,
 147                unsigned long pll_min, unsigned long pll_max,
 148                dss_pll_calc_func func, void *data)
 149{
 150        const struct dss_pll_hw *hw = pll->hw;
 151        int n, n_start, n_stop;
 152        int m, m_start, m_stop;
 153        unsigned long fint, clkdco;
 154        unsigned long pll_hw_max;
 155        unsigned long fint_hw_min, fint_hw_max;
 156
 157        pll_hw_max = hw->clkdco_max;
 158
 159        fint_hw_min = hw->fint_min;
 160        fint_hw_max = hw->fint_max;
 161
 162        n_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
 163        n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max);
 164
 165        pll_max = pll_max ? pll_max : ULONG_MAX;
 166
 167        for (n = n_start; n <= n_stop; ++n) {
 168                fint = clkin / n;
 169
 170                m_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
 171                                1ul);
 172                m_stop = min3((unsigned)(pll_max / fint / 2),
 173                                (unsigned)(pll_hw_max / fint / 2),
 174                                hw->m_max);
 175
 176                for (m = m_start; m <= m_stop; ++m) {
 177                        clkdco = 2 * m * fint;
 178
 179                        if (func(n, m, fint, clkdco, data))
 180                                return true;
 181                }
 182        }
 183
 184        return false;
 185}
 186
 187static int wait_for_bit_change(void __iomem *reg, int bitnum, int value)
 188{
 189        unsigned long timeout;
 190        ktime_t wait;
 191        int t;
 192
 193        /* first busyloop to see if the bit changes right away */
 194        t = 100;
 195        while (t-- > 0) {
 196                if (FLD_GET(readl_relaxed(reg), bitnum, bitnum) == value)
 197                        return value;
 198        }
 199
 200        /* then loop for 500ms, sleeping for 1ms in between */
 201        timeout = jiffies + msecs_to_jiffies(500);
 202        while (time_before(jiffies, timeout)) {
 203                if (FLD_GET(readl_relaxed(reg), bitnum, bitnum) == value)
 204                        return value;
 205
 206                wait = ns_to_ktime(1000 * 1000);
 207                set_current_state(TASK_UNINTERRUPTIBLE);
 208                schedule_hrtimeout(&wait, HRTIMER_MODE_REL);
 209        }
 210
 211        return !value;
 212}
 213
 214int dss_pll_wait_reset_done(struct dss_pll *pll)
 215{
 216        void __iomem *base = pll->base;
 217
 218        if (wait_for_bit_change(base + PLL_STATUS, 0, 1) != 1)
 219                return -ETIMEDOUT;
 220        else
 221                return 0;
 222}
 223
 224static int dss_wait_hsdiv_ack(struct dss_pll *pll, u32 hsdiv_ack_mask)
 225{
 226        int t = 100;
 227
 228        while (t-- > 0) {
 229                u32 v = readl_relaxed(pll->base + PLL_STATUS);
 230                v &= hsdiv_ack_mask;
 231                if (v == hsdiv_ack_mask)
 232                        return 0;
 233        }
 234
 235        return -ETIMEDOUT;
 236}
 237
 238int dss_pll_write_config_type_a(struct dss_pll *pll,
 239                const struct dss_pll_clock_info *cinfo)
 240{
 241        const struct dss_pll_hw *hw = pll->hw;
 242        void __iomem *base = pll->base;
 243        int r = 0;
 244        u32 l;
 245
 246        l = 0;
 247        if (hw->has_stopmode)
 248                l = FLD_MOD(l, 1, 0, 0);                /* PLL_STOPMODE */
 249        l = FLD_MOD(l, cinfo->n - 1, hw->n_msb, hw->n_lsb);     /* PLL_REGN */
 250        l = FLD_MOD(l, cinfo->m, hw->m_msb, hw->m_lsb);         /* PLL_REGM */
 251        /* M4 */
 252        l = FLD_MOD(l, cinfo->mX[0] ? cinfo->mX[0] - 1 : 0,
 253                        hw->mX_msb[0], hw->mX_lsb[0]);
 254        /* M5 */
 255        l = FLD_MOD(l, cinfo->mX[1] ? cinfo->mX[1] - 1 : 0,
 256                        hw->mX_msb[1], hw->mX_lsb[1]);
 257        writel_relaxed(l, base + PLL_CONFIGURATION1);
 258
 259        l = 0;
 260        /* M6 */
 261        l = FLD_MOD(l, cinfo->mX[2] ? cinfo->mX[2] - 1 : 0,
 262                        hw->mX_msb[2], hw->mX_lsb[2]);
 263        /* M7 */
 264        l = FLD_MOD(l, cinfo->mX[3] ? cinfo->mX[3] - 1 : 0,
 265                        hw->mX_msb[3], hw->mX_lsb[3]);
 266        writel_relaxed(l, base + PLL_CONFIGURATION3);
 267
 268        l = readl_relaxed(base + PLL_CONFIGURATION2);
 269        if (hw->has_freqsel) {
 270                u32 f = cinfo->fint < 1000000 ? 0x3 :
 271                        cinfo->fint < 1250000 ? 0x4 :
 272                        cinfo->fint < 1500000 ? 0x5 :
 273                        cinfo->fint < 1750000 ? 0x6 :
 274                        0x7;
 275
 276                l = FLD_MOD(l, f, 4, 1);        /* PLL_FREQSEL */
 277        } else if (hw->has_selfreqdco) {
 278                u32 f = cinfo->clkdco < hw->clkdco_low ? 0x2 : 0x4;
 279
 280                l = FLD_MOD(l, f, 3, 1);        /* PLL_SELFREQDCO */
 281        }
 282        l = FLD_MOD(l, 1, 13, 13);              /* PLL_REFEN */
 283        l = FLD_MOD(l, 0, 14, 14);              /* PHY_CLKINEN */
 284        l = FLD_MOD(l, 0, 16, 16);              /* M4_CLOCK_EN */
 285        l = FLD_MOD(l, 0, 18, 18);              /* M5_CLOCK_EN */
 286        l = FLD_MOD(l, 1, 20, 20);              /* HSDIVBYPASS */
 287        if (hw->has_refsel)
 288                l = FLD_MOD(l, 3, 22, 21);      /* REFSEL = sysclk */
 289        l = FLD_MOD(l, 0, 23, 23);              /* M6_CLOCK_EN */
 290        l = FLD_MOD(l, 0, 25, 25);              /* M7_CLOCK_EN */
 291        writel_relaxed(l, base + PLL_CONFIGURATION2);
 292
 293        writel_relaxed(1, base + PLL_GO);       /* PLL_GO */
 294
 295        if (wait_for_bit_change(base + PLL_GO, 0, 0) != 0) {
 296                DSSERR("DSS DPLL GO bit not going down.\n");
 297                r = -EIO;
 298                goto err;
 299        }
 300
 301        if (wait_for_bit_change(base + PLL_STATUS, 1, 1) != 1) {
 302                DSSERR("cannot lock DSS DPLL\n");
 303                r = -EIO;
 304                goto err;
 305        }
 306
 307        l = readl_relaxed(base + PLL_CONFIGURATION2);
 308        l = FLD_MOD(l, 1, 14, 14);                      /* PHY_CLKINEN */
 309        l = FLD_MOD(l, cinfo->mX[0] ? 1 : 0, 16, 16);   /* M4_CLOCK_EN */
 310        l = FLD_MOD(l, cinfo->mX[1] ? 1 : 0, 18, 18);   /* M5_CLOCK_EN */
 311        l = FLD_MOD(l, 0, 20, 20);                      /* HSDIVBYPASS */
 312        l = FLD_MOD(l, cinfo->mX[2] ? 1 : 0, 23, 23);   /* M6_CLOCK_EN */
 313        l = FLD_MOD(l, cinfo->mX[3] ? 1 : 0, 25, 25);   /* M7_CLOCK_EN */
 314        writel_relaxed(l, base + PLL_CONFIGURATION2);
 315
 316        r = dss_wait_hsdiv_ack(pll,
 317                (cinfo->mX[0] ? BIT(7) : 0) |
 318                (cinfo->mX[1] ? BIT(8) : 0) |
 319                (cinfo->mX[2] ? BIT(10) : 0) |
 320                (cinfo->mX[3] ? BIT(11) : 0));
 321        if (r) {
 322                DSSERR("failed to enable HSDIV clocks\n");
 323                goto err;
 324        }
 325
 326err:
 327        return r;
 328}
 329
 330int dss_pll_write_config_type_b(struct dss_pll *pll,
 331                const struct dss_pll_clock_info *cinfo)
 332{
 333        const struct dss_pll_hw *hw = pll->hw;
 334        void __iomem *base = pll->base;
 335        u32 l;
 336
 337        l = 0;
 338        l = FLD_MOD(l, cinfo->m, 20, 9);        /* PLL_REGM */
 339        l = FLD_MOD(l, cinfo->n - 1, 8, 1);     /* PLL_REGN */
 340        writel_relaxed(l, base + PLL_CONFIGURATION1);
 341
 342        l = readl_relaxed(base + PLL_CONFIGURATION2);
 343        l = FLD_MOD(l, 0x0, 12, 12);    /* PLL_HIGHFREQ divide by 2 */
 344        l = FLD_MOD(l, 0x1, 13, 13);    /* PLL_REFEN */
 345        l = FLD_MOD(l, 0x0, 14, 14);    /* PHY_CLKINEN */
 346        if (hw->has_refsel)
 347                l = FLD_MOD(l, 0x3, 22, 21);    /* REFSEL = SYSCLK */
 348
 349        /* PLL_SELFREQDCO */
 350        if (cinfo->clkdco > hw->clkdco_low)
 351                l = FLD_MOD(l, 0x4, 3, 1);
 352        else
 353                l = FLD_MOD(l, 0x2, 3, 1);
 354        writel_relaxed(l, base + PLL_CONFIGURATION2);
 355
 356        l = readl_relaxed(base + PLL_CONFIGURATION3);
 357        l = FLD_MOD(l, cinfo->sd, 17, 10);      /* PLL_REGSD */
 358        writel_relaxed(l, base + PLL_CONFIGURATION3);
 359
 360        l = readl_relaxed(base + PLL_CONFIGURATION4);
 361        l = FLD_MOD(l, cinfo->mX[0], 24, 18);   /* PLL_REGM2 */
 362        l = FLD_MOD(l, cinfo->mf, 17, 0);       /* PLL_REGM_F */
 363        writel_relaxed(l, base + PLL_CONFIGURATION4);
 364
 365        writel_relaxed(1, base + PLL_GO);       /* PLL_GO */
 366
 367        if (wait_for_bit_change(base + PLL_GO, 0, 0) != 0) {
 368                DSSERR("DSS DPLL GO bit not going down.\n");
 369                return -EIO;
 370        }
 371
 372        if (wait_for_bit_change(base + PLL_STATUS, 1, 1) != 1) {
 373                DSSERR("cannot lock DSS DPLL\n");
 374                return -ETIMEDOUT;
 375        }
 376
 377        return 0;
 378}
 379