]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/arm/mach-imx/clk-pllv1.c
Merge remote-tracking branch 'drm/drm-next'
[karo-tx-linux.git] / arch / arm / mach-imx / clk-pllv1.c
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 struct clk_pllv1 {
22         struct clk_hw   hw;
23         void __iomem    *base;
24 };
25
26 #define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk))
27
28 static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
29                 unsigned long parent_rate)
30 {
31         struct clk_pllv1 *pll = to_clk_pllv1(hw);
32         long long ll;
33         int mfn_abs;
34         unsigned int mfi, mfn, mfd, pd;
35         u32 reg;
36         unsigned long rate;
37
38         reg = readl(pll->base);
39
40         /*
41          * Get the resulting clock rate from a PLL register value and the input
42          * frequency. PLLs with this register layout can be found on i.MX1,
43          * i.MX21, i.MX27 and i,MX31
44          *
45          *                  mfi + mfn / (mfd + 1)
46          *  f = 2 * f_ref * --------------------
47          *                        pd + 1
48          */
49
50         mfi = (reg >> 10) & 0xf;
51         mfn = reg & 0x3ff;
52         mfd = (reg >> 16) & 0x3ff;
53         pd =  (reg >> 26) & 0xf;
54
55         mfi = mfi <= 5 ? 5 : mfi;
56
57         mfn_abs = mfn;
58
59         /*
60          * On all i.MXs except i.MX1 and i.MX21 mfn is a 10bit
61          * 2's complements number
62          */
63         if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200)
64                 mfn_abs = 0x400 - mfn;
65
66         rate = parent_rate * 2;
67         rate /= pd + 1;
68
69         ll = (unsigned long long)rate * mfn_abs;
70
71         do_div(ll, mfd + 1);
72
73         if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200)
74                 ll = -ll;
75
76         ll = (rate * mfi) + ll;
77
78         return ll;
79 }
80
81 static struct clk_ops clk_pllv1_ops = {
82         .recalc_rate = clk_pllv1_recalc_rate,
83 };
84
85 struct clk *imx_clk_pllv1(const char *name, const char *parent,
86                 void __iomem *base)
87 {
88         struct clk_pllv1 *pll;
89         struct clk *clk;
90         struct clk_init_data init;
91
92         pll = kmalloc(sizeof(*pll), GFP_KERNEL);
93         if (!pll)
94                 return ERR_PTR(-ENOMEM);
95
96         pll->base = base;
97
98         init.name = name;
99         init.ops = &clk_pllv1_ops;
100         init.flags = 0;
101         init.parent_names = &parent;
102         init.num_parents = 1;
103
104         pll->hw.init = &init;
105
106         clk = clk_register(NULL, &pll->hw);
107         if (IS_ERR(clk))
108                 kfree(pll);
109
110         return clk;
111 }