linux/drivers/clk/mediatek/clk-pll.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2014 MediaTek Inc.
   4 * Author: James Liao <jamesjj.liao@mediatek.com>
   5 */
   6
   7#include <linux/of.h>
   8#include <linux/of_address.h>
   9#include <linux/io.h>
  10#include <linux/slab.h>
  11#include <linux/clkdev.h>
  12#include <linux/delay.h>
  13
  14#include "clk-mtk.h"
  15
  16#define REG_CON0                0
  17#define REG_CON1                4
  18
  19#define CON0_BASE_EN            BIT(0)
  20#define CON0_PWR_ON             BIT(0)
  21#define CON0_ISO_EN             BIT(1)
  22#define PCW_CHG_MASK            BIT(31)
  23
  24#define AUDPLL_TUNER_EN         BIT(31)
  25
  26#define POSTDIV_MASK            0x7
  27
  28/* default 7 bits integer, can be overridden with pcwibits. */
  29#define INTEGER_BITS            7
  30
  31/*
  32 * MediaTek PLLs are configured through their pcw value. The pcw value describes
  33 * a divider in the PLL feedback loop which consists of 7 bits for the integer
  34 * part and the remaining bits (if present) for the fractional part. Also they
  35 * have a 3 bit power-of-two post divider.
  36 */
  37
  38struct mtk_clk_pll {
  39        struct clk_hw   hw;
  40        void __iomem    *base_addr;
  41        void __iomem    *pd_addr;
  42        void __iomem    *pwr_addr;
  43        void __iomem    *tuner_addr;
  44        void __iomem    *tuner_en_addr;
  45        void __iomem    *pcw_addr;
  46        void __iomem    *pcw_chg_addr;
  47        void __iomem    *en_addr;
  48        const struct mtk_pll_data *data;
  49};
  50
  51static inline struct mtk_clk_pll *to_mtk_clk_pll(struct clk_hw *hw)
  52{
  53        return container_of(hw, struct mtk_clk_pll, hw);
  54}
  55
  56static int mtk_pll_is_prepared(struct clk_hw *hw)
  57{
  58        struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  59
  60        return (readl(pll->en_addr) & BIT(pll->data->pll_en_bit)) != 0;
  61}
  62
  63static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin,
  64                u32 pcw, int postdiv)
  65{
  66        int pcwbits = pll->data->pcwbits;
  67        int pcwfbits = 0;
  68        int ibits;
  69        u64 vco;
  70        u8 c = 0;
  71
  72        /* The fractional part of the PLL divider. */
  73        ibits = pll->data->pcwibits ? pll->data->pcwibits : INTEGER_BITS;
  74        if (pcwbits > ibits)
  75                pcwfbits = pcwbits - ibits;
  76
  77        vco = (u64)fin * pcw;
  78
  79        if (pcwfbits && (vco & GENMASK(pcwfbits - 1, 0)))
  80                c = 1;
  81
  82        vco >>= pcwfbits;
  83
  84        if (c)
  85                vco++;
  86
  87        return ((unsigned long)vco + postdiv - 1) / postdiv;
  88}
  89
  90static void __mtk_pll_tuner_enable(struct mtk_clk_pll *pll)
  91{
  92        u32 r;
  93
  94        if (pll->tuner_en_addr) {
  95                r = readl(pll->tuner_en_addr) | BIT(pll->data->tuner_en_bit);
  96                writel(r, pll->tuner_en_addr);
  97        } else if (pll->tuner_addr) {
  98                r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN;
  99                writel(r, pll->tuner_addr);
 100        }
 101}
 102
 103static void __mtk_pll_tuner_disable(struct mtk_clk_pll *pll)
 104{
 105        u32 r;
 106
 107        if (pll->tuner_en_addr) {
 108                r = readl(pll->tuner_en_addr) & ~BIT(pll->data->tuner_en_bit);
 109                writel(r, pll->tuner_en_addr);
 110        } else if (pll->tuner_addr) {
 111                r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN;
 112                writel(r, pll->tuner_addr);
 113        }
 114}
 115
 116static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
 117                int postdiv)
 118{
 119        u32 chg, val;
 120
 121        /* disable tuner */
 122        __mtk_pll_tuner_disable(pll);
 123
 124        /* set postdiv */
 125        val = readl(pll->pd_addr);
 126        val &= ~(POSTDIV_MASK << pll->data->pd_shift);
 127        val |= (ffs(postdiv) - 1) << pll->data->pd_shift;
 128
 129        /* postdiv and pcw need to set at the same time if on same register */
 130        if (pll->pd_addr != pll->pcw_addr) {
 131                writel(val, pll->pd_addr);
 132                val = readl(pll->pcw_addr);
 133        }
 134
 135        /* set pcw */
 136        val &= ~GENMASK(pll->data->pcw_shift + pll->data->pcwbits - 1,
 137                        pll->data->pcw_shift);
 138        val |= pcw << pll->data->pcw_shift;
 139        writel(val, pll->pcw_addr);
 140        chg = readl(pll->pcw_chg_addr) | PCW_CHG_MASK;
 141        writel(chg, pll->pcw_chg_addr);
 142        if (pll->tuner_addr)
 143                writel(val + 1, pll->tuner_addr);
 144
 145        /* restore tuner_en */
 146        __mtk_pll_tuner_enable(pll);
 147
 148        udelay(20);
 149}
 150
 151/*
 152 * mtk_pll_calc_values - calculate good values for a given input frequency.
 153 * @pll:        The pll
 154 * @pcw:        The pcw value (output)
 155 * @postdiv:    The post divider (output)
 156 * @freq:       The desired target frequency
 157 * @fin:        The input frequency
 158 *
 159 */
 160static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
 161                u32 freq, u32 fin)
 162{
 163        unsigned long fmin = pll->data->fmin ? pll->data->fmin : (1000 * MHZ);
 164        const struct mtk_pll_div_table *div_table = pll->data->div_table;
 165        u64 _pcw;
 166        int ibits;
 167        u32 val;
 168
 169        if (freq > pll->data->fmax)
 170                freq = pll->data->fmax;
 171
 172        if (div_table) {
 173                if (freq > div_table[0].freq)
 174                        freq = div_table[0].freq;
 175
 176                for (val = 0; div_table[val + 1].freq != 0; val++) {
 177                        if (freq > div_table[val + 1].freq)
 178                                break;
 179                }
 180                *postdiv = 1 << val;
 181        } else {
 182                for (val = 0; val < 5; val++) {
 183                        *postdiv = 1 << val;
 184                        if ((u64)freq * *postdiv >= fmin)
 185                                break;
 186                }
 187        }
 188
 189        /* _pcw = freq * postdiv / fin * 2^pcwfbits */
 190        ibits = pll->data->pcwibits ? pll->data->pcwibits : INTEGER_BITS;
 191        _pcw = ((u64)freq << val) << (pll->data->pcwbits - ibits);
 192        do_div(_pcw, fin);
 193
 194        *pcw = (u32)_pcw;
 195}
 196
 197static int mtk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 198                unsigned long parent_rate)
 199{
 200        struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
 201        u32 pcw = 0;
 202        u32 postdiv;
 203
 204        mtk_pll_calc_values(pll, &pcw, &postdiv, rate, parent_rate);
 205        mtk_pll_set_rate_regs(pll, pcw, postdiv);
 206
 207        return 0;
 208}
 209
 210static unsigned long mtk_pll_recalc_rate(struct clk_hw *hw,
 211                unsigned long parent_rate)
 212{
 213        struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
 214        u32 postdiv;
 215        u32 pcw;
 216
 217        postdiv = (readl(pll->pd_addr) >> pll->data->pd_shift) & POSTDIV_MASK;
 218        postdiv = 1 << postdiv;
 219
 220        pcw = readl(pll->pcw_addr) >> pll->data->pcw_shift;
 221        pcw &= GENMASK(pll->data->pcwbits - 1, 0);
 222
 223        return __mtk_pll_recalc_rate(pll, parent_rate, pcw, postdiv);
 224}
 225
 226static long mtk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 227                unsigned long *prate)
 228{
 229        struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
 230        u32 pcw = 0;
 231        int postdiv;
 232
 233        mtk_pll_calc_values(pll, &pcw, &postdiv, rate, *prate);
 234
 235        return __mtk_pll_recalc_rate(pll, *prate, pcw, postdiv);
 236}
 237
 238static int mtk_pll_prepare(struct clk_hw *hw)
 239{
 240        struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
 241        u32 r;
 242        u32 div_en_mask;
 243
 244        r = readl(pll->pwr_addr) | CON0_PWR_ON;
 245        writel(r, pll->pwr_addr);
 246        udelay(1);
 247
 248        r = readl(pll->pwr_addr) & ~CON0_ISO_EN;
 249        writel(r, pll->pwr_addr);
 250        udelay(1);
 251
 252        r = readl(pll->en_addr) | BIT(pll->data->pll_en_bit);
 253        writel(r, pll->en_addr);
 254
 255        div_en_mask = pll->data->en_mask & ~CON0_BASE_EN;
 256        if (div_en_mask) {
 257                r = readl(pll->base_addr + REG_CON0) | div_en_mask;
 258                writel(r, pll->base_addr + REG_CON0);
 259        }
 260
 261        __mtk_pll_tuner_enable(pll);
 262
 263        udelay(20);
 264
 265        if (pll->data->flags & HAVE_RST_BAR) {
 266                r = readl(pll->base_addr + REG_CON0);
 267                r |= pll->data->rst_bar_mask;
 268                writel(r, pll->base_addr + REG_CON0);
 269        }
 270
 271        return 0;
 272}
 273
 274static void mtk_pll_unprepare(struct clk_hw *hw)
 275{
 276        struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
 277        u32 r;
 278        u32 div_en_mask;
 279
 280        if (pll->data->flags & HAVE_RST_BAR) {
 281                r = readl(pll->base_addr + REG_CON0);
 282                r &= ~pll->data->rst_bar_mask;
 283                writel(r, pll->base_addr + REG_CON0);
 284        }
 285
 286        __mtk_pll_tuner_disable(pll);
 287
 288        div_en_mask = pll->data->en_mask & ~CON0_BASE_EN;
 289        if (div_en_mask) {
 290                r = readl(pll->base_addr + REG_CON0) & ~div_en_mask;
 291                writel(r, pll->base_addr + REG_CON0);
 292        }
 293
 294        r = readl(pll->en_addr) & ~BIT(pll->data->pll_en_bit);
 295        writel(r, pll->en_addr);
 296
 297        r = readl(pll->pwr_addr) | CON0_ISO_EN;
 298        writel(r, pll->pwr_addr);
 299
 300        r = readl(pll->pwr_addr) & ~CON0_PWR_ON;
 301        writel(r, pll->pwr_addr);
 302}
 303
 304static const struct clk_ops mtk_pll_ops = {
 305        .is_prepared    = mtk_pll_is_prepared,
 306        .prepare        = mtk_pll_prepare,
 307        .unprepare      = mtk_pll_unprepare,
 308        .recalc_rate    = mtk_pll_recalc_rate,
 309        .round_rate     = mtk_pll_round_rate,
 310        .set_rate       = mtk_pll_set_rate,
 311};
 312
 313static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
 314                void __iomem *base)
 315{
 316        struct mtk_clk_pll *pll;
 317        struct clk_init_data init = {};
 318        struct clk *clk;
 319        const char *parent_name = "clk26m";
 320
 321        pll = kzalloc(sizeof(*pll), GFP_KERNEL);
 322        if (!pll)
 323                return ERR_PTR(-ENOMEM);
 324
 325        pll->base_addr = base + data->reg;
 326        pll->pwr_addr = base + data->pwr_reg;
 327        pll->pd_addr = base + data->pd_reg;
 328        pll->pcw_addr = base + data->pcw_reg;
 329        if (data->pcw_chg_reg)
 330                pll->pcw_chg_addr = base + data->pcw_chg_reg;
 331        else
 332                pll->pcw_chg_addr = pll->base_addr + REG_CON1;
 333        if (data->tuner_reg)
 334                pll->tuner_addr = base + data->tuner_reg;
 335        if (data->tuner_en_reg)
 336                pll->tuner_en_addr = base + data->tuner_en_reg;
 337        if (data->en_reg)
 338                pll->en_addr = base + data->en_reg;
 339        else
 340                pll->en_addr = pll->base_addr + REG_CON0;
 341        pll->hw.init = &init;
 342        pll->data = data;
 343
 344        init.name = data->name;
 345        init.flags = (data->flags & PLL_AO) ? CLK_IS_CRITICAL : 0;
 346        init.ops = &mtk_pll_ops;
 347        if (data->parent_name)
 348                init.parent_names = &data->parent_name;
 349        else
 350                init.parent_names = &parent_name;
 351        init.num_parents = 1;
 352
 353        clk = clk_register(NULL, &pll->hw);
 354
 355        if (IS_ERR(clk))
 356                kfree(pll);
 357
 358        return clk;
 359}
 360
 361void mtk_clk_register_plls(struct device_node *node,
 362                const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
 363{
 364        void __iomem *base;
 365        int i;
 366        struct clk *clk;
 367
 368        base = of_iomap(node, 0);
 369        if (!base) {
 370                pr_err("%s(): ioremap failed\n", __func__);
 371                return;
 372        }
 373
 374        for (i = 0; i < num_plls; i++) {
 375                const struct mtk_pll_data *pll = &plls[i];
 376
 377                clk = mtk_clk_register_pll(pll, base);
 378
 379                if (IS_ERR(clk)) {
 380                        pr_err("Failed to register clk %s: %ld\n",
 381                                        pll->name, PTR_ERR(clk));
 382                        continue;
 383                }
 384
 385                clk_data->clks[pll->id] = clk;
 386        }
 387}
 388