linux/drivers/clk/imx/clk-pllv3.c
<<
>>
Prefs
   1/*
   2 * Copyright 2012 Freescale Semiconductor, Inc.
   3 * Copyright 2012 Linaro Ltd.
   4 *
   5 * The code contained herein is licensed under the GNU General Public
   6 * License. You may obtain a copy of the GNU General Public License
   7 * Version 2 or later at the following locations:
   8 *
   9 * http://www.opensource.org/licenses/gpl-license.html
  10 * http://www.gnu.org/copyleft/gpl.html
  11 */
  12
  13#include <linux/clk-provider.h>
  14#include <linux/delay.h>
  15#include <linux/io.h>
  16#include <linux/slab.h>
  17#include <linux/jiffies.h>
  18#include <linux/err.h>
  19#include "clk.h"
  20
  21#define PLL_NUM_OFFSET          0x10
  22#define PLL_DENOM_OFFSET        0x20
  23
  24#define BM_PLL_POWER            (0x1 << 12)
  25#define BM_PLL_LOCK             (0x1 << 31)
  26#define IMX7_ENET_PLL_POWER     (0x1 << 5)
  27
  28/**
  29 * struct clk_pllv3 - IMX PLL clock version 3
  30 * @clk_hw:      clock source
  31 * @base:        base address of PLL registers
  32 * @powerup_set: set POWER bit to power up the PLL
  33 * @powerdown:   pll powerdown offset bit
  34 * @div_mask:    mask of divider bits
  35 * @div_shift:   shift of divider bits
  36 *
  37 * IMX PLL clock version 3, found on i.MX6 series.  Divider for pllv3
  38 * is actually a multiplier, and always sits at bit 0.
  39 */
  40struct clk_pllv3 {
  41        struct clk_hw   hw;
  42        void __iomem    *base;
  43        bool            powerup_set;
  44        u32             powerdown;
  45        u32             div_mask;
  46        u32             div_shift;
  47};
  48
  49#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
  50
  51static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
  52{
  53        unsigned long timeout = jiffies + msecs_to_jiffies(10);
  54        u32 val = readl_relaxed(pll->base) & pll->powerdown;
  55
  56        /* No need to wait for lock when pll is not powered up */
  57        if ((pll->powerup_set && !val) || (!pll->powerup_set && val))
  58                return 0;
  59
  60        /* Wait for PLL to lock */
  61        do {
  62                if (readl_relaxed(pll->base) & BM_PLL_LOCK)
  63                        break;
  64                if (time_after(jiffies, timeout))
  65                        break;
  66                usleep_range(50, 500);
  67        } while (1);
  68
  69        return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT;
  70}
  71
  72static int clk_pllv3_prepare(struct clk_hw *hw)
  73{
  74        struct clk_pllv3 *pll = to_clk_pllv3(hw);
  75        u32 val;
  76
  77        val = readl_relaxed(pll->base);
  78        if (pll->powerup_set)
  79                val |= BM_PLL_POWER;
  80        else
  81                val &= ~BM_PLL_POWER;
  82        writel_relaxed(val, pll->base);
  83
  84        return clk_pllv3_wait_lock(pll);
  85}
  86
  87static void clk_pllv3_unprepare(struct clk_hw *hw)
  88{
  89        struct clk_pllv3 *pll = to_clk_pllv3(hw);
  90        u32 val;
  91
  92        val = readl_relaxed(pll->base);
  93        if (pll->powerup_set)
  94                val &= ~BM_PLL_POWER;
  95        else
  96                val |= BM_PLL_POWER;
  97        writel_relaxed(val, pll->base);
  98}
  99
 100static int clk_pllv3_is_prepared(struct clk_hw *hw)
 101{
 102        struct clk_pllv3 *pll = to_clk_pllv3(hw);
 103
 104        if (readl_relaxed(pll->base) & BM_PLL_LOCK)
 105                return 1;
 106
 107        return 0;
 108}
 109
 110static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
 111                                           unsigned long parent_rate)
 112{
 113        struct clk_pllv3 *pll = to_clk_pllv3(hw);
 114        u32 div = (readl_relaxed(pll->base) >> pll->div_shift)  & pll->div_mask;
 115
 116        return (div == 1) ? parent_rate * 22 : parent_rate * 20;
 117}
 118
 119static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate,
 120                                 unsigned long *prate)
 121{
 122        unsigned long parent_rate = *prate;
 123
 124        return (rate >= parent_rate * 22) ? parent_rate * 22 :
 125                                            parent_rate * 20;
 126}
 127
 128static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate,
 129                unsigned long parent_rate)
 130{
 131        struct clk_pllv3 *pll = to_clk_pllv3(hw);
 132        u32 val, div;
 133
 134        if (rate == parent_rate * 22)
 135                div = 1;
 136        else if (rate == parent_rate * 20)
 137                div = 0;
 138        else
 139                return -EINVAL;
 140
 141        val = readl_relaxed(pll->base);
 142        val &= ~(pll->div_mask << pll->div_shift);
 143        val |= (div << pll->div_shift);
 144        writel_relaxed(val, pll->base);
 145
 146        return clk_pllv3_wait_lock(pll);
 147}
 148
 149static const struct clk_ops clk_pllv3_ops = {
 150        .prepare        = clk_pllv3_prepare,
 151        .unprepare      = clk_pllv3_unprepare,
 152        .is_prepared    = clk_pllv3_is_prepared,
 153        .recalc_rate    = clk_pllv3_recalc_rate,
 154        .round_rate     = clk_pllv3_round_rate,
 155        .set_rate       = clk_pllv3_set_rate,
 156};
 157
 158static unsigned long clk_pllv3_sys_recalc_rate(struct clk_hw *hw,
 159                                               unsigned long parent_rate)
 160{
 161        struct clk_pllv3 *pll = to_clk_pllv3(hw);
 162        u32 div = readl_relaxed(pll->base) & pll->div_mask;
 163
 164        return parent_rate * div / 2;
 165}
 166
 167static long clk_pllv3_sys_round_rate(struct clk_hw *hw, unsigned long rate,
 168                                     unsigned long *prate)
 169{
 170        unsigned long parent_rate = *prate;
 171        unsigned long min_rate = parent_rate * 54 / 2;
 172        unsigned long max_rate = parent_rate * 108 / 2;
 173        u32 div;
 174
 175        if (rate > max_rate)
 176                rate = max_rate;
 177        else if (rate < min_rate)
 178                rate = min_rate;
 179        div = rate * 2 / parent_rate;
 180
 181        return parent_rate * div / 2;
 182}
 183
 184static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate,
 185                unsigned long parent_rate)
 186{
 187        struct clk_pllv3 *pll = to_clk_pllv3(hw);
 188        unsigned long min_rate = parent_rate * 54 / 2;
 189        unsigned long max_rate = parent_rate * 108 / 2;
 190        u32 val, div;
 191
 192        if (rate < min_rate || rate > max_rate)
 193                return -EINVAL;
 194
 195        div = rate * 2 / parent_rate;
 196        val = readl_relaxed(pll->base);
 197        val &= ~pll->div_mask;
 198        val |= div;
 199        writel_relaxed(val, pll->base);
 200
 201        return clk_pllv3_wait_lock(pll);
 202}
 203
 204static const struct clk_ops clk_pllv3_sys_ops = {
 205        .prepare        = clk_pllv3_prepare,
 206        .unprepare      = clk_pllv3_unprepare,
 207        .is_prepared    = clk_pllv3_is_prepared,
 208        .recalc_rate    = clk_pllv3_sys_recalc_rate,
 209        .round_rate     = clk_pllv3_sys_round_rate,
 210        .set_rate       = clk_pllv3_sys_set_rate,
 211};
 212
 213static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
 214                                              unsigned long parent_rate)
 215{
 216        struct clk_pllv3 *pll = to_clk_pllv3(hw);
 217        u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
 218        u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
 219        u32 div = readl_relaxed(pll->base) & pll->div_mask;
 220
 221        return (parent_rate * div) + ((parent_rate / mfd) * mfn);
 222}
 223
 224static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
 225                                    unsigned long *prate)
 226{
 227        unsigned long parent_rate = *prate;
 228        unsigned long min_rate = parent_rate * 27;
 229        unsigned long max_rate = parent_rate * 54;
 230        u32 div;
 231        u32 mfn, mfd = 1000000;
 232        u64 temp64;
 233
 234        if (rate > max_rate)
 235                rate = max_rate;
 236        else if (rate < min_rate)
 237                rate = min_rate;
 238
 239        div = rate / parent_rate;
 240        temp64 = (u64) (rate - div * parent_rate);
 241        temp64 *= mfd;
 242        do_div(temp64, parent_rate);
 243        mfn = temp64;
 244
 245        return parent_rate * div + parent_rate / mfd * mfn;
 246}
 247
 248static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
 249                unsigned long parent_rate)
 250{
 251        struct clk_pllv3 *pll = to_clk_pllv3(hw);
 252        unsigned long min_rate = parent_rate * 27;
 253        unsigned long max_rate = parent_rate * 54;
 254        u32 val, div;
 255        u32 mfn, mfd = 1000000;
 256        u64 temp64;
 257
 258        if (rate < min_rate || rate > max_rate)
 259                return -EINVAL;
 260
 261        div = rate / parent_rate;
 262        temp64 = (u64) (rate - div * parent_rate);
 263        temp64 *= mfd;
 264        do_div(temp64, parent_rate);
 265        mfn = temp64;
 266
 267        val = readl_relaxed(pll->base);
 268        val &= ~pll->div_mask;
 269        val |= div;
 270        writel_relaxed(val, pll->base);
 271        writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
 272        writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
 273
 274        return clk_pllv3_wait_lock(pll);
 275}
 276
 277static const struct clk_ops clk_pllv3_av_ops = {
 278        .prepare        = clk_pllv3_prepare,
 279        .unprepare      = clk_pllv3_unprepare,
 280        .is_prepared    = clk_pllv3_is_prepared,
 281        .recalc_rate    = clk_pllv3_av_recalc_rate,
 282        .round_rate     = clk_pllv3_av_round_rate,
 283        .set_rate       = clk_pllv3_av_set_rate,
 284};
 285
 286static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
 287                                                unsigned long parent_rate)
 288{
 289        return 500000000;
 290}
 291
 292static const struct clk_ops clk_pllv3_enet_ops = {
 293        .prepare        = clk_pllv3_prepare,
 294        .unprepare      = clk_pllv3_unprepare,
 295        .is_prepared    = clk_pllv3_is_prepared,
 296        .recalc_rate    = clk_pllv3_enet_recalc_rate,
 297};
 298
 299struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
 300                          const char *parent_name, void __iomem *base,
 301                          u32 div_mask)
 302{
 303        struct clk_pllv3 *pll;
 304        const struct clk_ops *ops;
 305        struct clk *clk;
 306        struct clk_init_data init;
 307
 308        pll = kzalloc(sizeof(*pll), GFP_KERNEL);
 309        if (!pll)
 310                return ERR_PTR(-ENOMEM);
 311
 312        pll->powerdown = BM_PLL_POWER;
 313
 314        switch (type) {
 315        case IMX_PLLV3_SYS:
 316                ops = &clk_pllv3_sys_ops;
 317                break;
 318        case IMX_PLLV3_USB_VF610:
 319                pll->div_shift = 1;
 320        case IMX_PLLV3_USB:
 321                ops = &clk_pllv3_ops;
 322                pll->powerup_set = true;
 323                break;
 324        case IMX_PLLV3_AV:
 325                ops = &clk_pllv3_av_ops;
 326                break;
 327        case IMX_PLLV3_ENET_IMX7:
 328                pll->powerdown = IMX7_ENET_PLL_POWER;
 329        case IMX_PLLV3_ENET:
 330                ops = &clk_pllv3_enet_ops;
 331                break;
 332        default:
 333                ops = &clk_pllv3_ops;
 334        }
 335        pll->base = base;
 336        pll->div_mask = div_mask;
 337
 338        init.name = name;
 339        init.ops = ops;
 340        init.flags = 0;
 341        init.parent_names = &parent_name;
 342        init.num_parents = 1;
 343
 344        pll->hw.init = &init;
 345
 346        clk = clk_register(NULL, &pll->hw);
 347        if (IS_ERR(clk))
 348                kfree(pll);
 349
 350        return clk;
 351}
 352