linux/arch/arm/mach-imx/clk-pllv1.c
<<
>>
Prefs
   1#include <linux/clk.h>
   2#include <linux/clk-provider.h>
   3#include <linux/io.h>
   4#include <linux/slab.h>
   5#include <linux/kernel.h>
   6#include <linux/err.h>
   7
   8#include "clk.h"
   9#include "common.h"
  10#include "hardware.h"
  11
  12/**
  13 * pll v1
  14 *
  15 * @clk_hw      clock source
  16 * @parent      the parent clock name
  17 * @base        base address of pll registers
  18 *
  19 * PLL clock version 1, found on i.MX1/21/25/27/31/35
  20 */
  21
  22#define MFN_BITS        (10)
  23#define MFN_SIGN        (BIT(MFN_BITS - 1))
  24#define MFN_MASK        (MFN_SIGN - 1)
  25
  26struct clk_pllv1 {
  27        struct clk_hw   hw;
  28        void __iomem    *base;
  29};
  30
  31#define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk))
  32
  33static inline bool mfn_is_negative(unsigned int mfn)
  34{
  35        return !cpu_is_mx1() && !cpu_is_mx21() && (mfn & MFN_SIGN);
  36}
  37
  38static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
  39                unsigned long parent_rate)
  40{
  41        struct clk_pllv1 *pll = to_clk_pllv1(hw);
  42        long long ll;
  43        int mfn_abs;
  44        unsigned int mfi, mfn, mfd, pd;
  45        u32 reg;
  46        unsigned long rate;
  47
  48        reg = readl(pll->base);
  49
  50        /*
  51         * Get the resulting clock rate from a PLL register value and the input
  52         * frequency. PLLs with this register layout can be found on i.MX1,
  53         * i.MX21, i.MX27 and i,MX31
  54         *
  55         *                  mfi + mfn / (mfd + 1)
  56         *  f = 2 * f_ref * --------------------
  57         *                        pd + 1
  58         */
  59
  60        mfi = (reg >> 10) & 0xf;
  61        mfn = reg & 0x3ff;
  62        mfd = (reg >> 16) & 0x3ff;
  63        pd =  (reg >> 26) & 0xf;
  64
  65        mfi = mfi <= 5 ? 5 : mfi;
  66
  67        mfn_abs = mfn;
  68
  69        /*
  70         * On all i.MXs except i.MX1 and i.MX21 mfn is a 10bit
  71         * 2's complements number.
  72         * On i.MX27 the bit 9 is the sign bit.
  73         */
  74        if (mfn_is_negative(mfn)) {
  75                if (cpu_is_mx27())
  76                        mfn_abs = mfn & MFN_MASK;
  77                else
  78                        mfn_abs = BIT(MFN_BITS) - mfn;
  79        }
  80
  81        rate = parent_rate * 2;
  82        rate /= pd + 1;
  83
  84        ll = (unsigned long long)rate * mfn_abs;
  85
  86        do_div(ll, mfd + 1);
  87
  88        if (mfn_is_negative(mfn))
  89                ll = -ll;
  90
  91        ll = (rate * mfi) + ll;
  92
  93        return ll;
  94}
  95
  96static struct clk_ops clk_pllv1_ops = {
  97        .recalc_rate = clk_pllv1_recalc_rate,
  98};
  99
 100struct clk *imx_clk_pllv1(const char *name, const char *parent,
 101                void __iomem *base)
 102{
 103        struct clk_pllv1 *pll;
 104        struct clk *clk;
 105        struct clk_init_data init;
 106
 107        pll = kmalloc(sizeof(*pll), GFP_KERNEL);
 108        if (!pll)
 109                return ERR_PTR(-ENOMEM);
 110
 111        pll->base = base;
 112
 113        init.name = name;
 114        init.ops = &clk_pllv1_ops;
 115        init.flags = 0;
 116        init.parent_names = &parent;
 117        init.num_parents = 1;
 118
 119        pll->hw.init = &init;
 120
 121        clk = clk_register(NULL, &pll->hw);
 122        if (IS_ERR(clk))
 123                kfree(pll);
 124
 125        return clk;
 126}
 127