Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / clk / mvebu / clk-cpu.c
1 /*
2  * Marvell MVEBU CPU clock handling.
3  *
4  * Copyright (C) 2012 Marvell
5  *
6  * Gregory CLEMENT <gregory.clement@free-electrons.com>
7  *
8  * This file is licensed under the terms of the GNU General Public
9  * License version 2.  This program is licensed "as is" without any
10  * warranty of any kind, whether express or implied.
11  */
12 #include <linux/kernel.h>
13 #include <linux/clkdev.h>
14 #include <linux/clk-provider.h>
15 #include <linux/of_address.h>
16 #include <linux/io.h>
17 #include <linux/of.h>
18 #include <linux/delay.h>
19 #include <linux/mvebu-pmsu.h>
20 #include <asm/smp_plat.h>
21
22 #define SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET               0x0
23 #define   SYS_CTRL_CLK_DIVIDER_CTRL_RESET_ALL          0xff
24 #define   SYS_CTRL_CLK_DIVIDER_CTRL_RESET_SHIFT        8
25 #define SYS_CTRL_CLK_DIVIDER_CTRL2_OFFSET              0x8
26 #define   SYS_CTRL_CLK_DIVIDER_CTRL2_NBCLK_RATIO_SHIFT 16
27 #define SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET              0xC
28 #define SYS_CTRL_CLK_DIVIDER_MASK                      0x3F
29
30 #define PMU_DFS_RATIO_SHIFT 16
31 #define PMU_DFS_RATIO_MASK  0x3F
32
33 #define MAX_CPU     4
34 struct cpu_clk {
35         struct clk_hw hw;
36         int cpu;
37         const char *clk_name;
38         const char *parent_name;
39         void __iomem *reg_base;
40         void __iomem *pmu_dfs;
41 };
42
43 static struct clk **clks;
44
45 static struct clk_onecell_data clk_data;
46
47 #define to_cpu_clk(p) container_of(p, struct cpu_clk, hw)
48
49 static unsigned long clk_cpu_recalc_rate(struct clk_hw *hwclk,
50                                          unsigned long parent_rate)
51 {
52         struct cpu_clk *cpuclk = to_cpu_clk(hwclk);
53         u32 reg, div;
54
55         reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET);
56         div = (reg >> (cpuclk->cpu * 8)) & SYS_CTRL_CLK_DIVIDER_MASK;
57         return parent_rate / div;
58 }
59
60 static long clk_cpu_round_rate(struct clk_hw *hwclk, unsigned long rate,
61                                unsigned long *parent_rate)
62 {
63         /* Valid ratio are 1:1, 1:2 and 1:3 */
64         u32 div;
65
66         div = *parent_rate / rate;
67         if (div == 0)
68                 div = 1;
69         else if (div > 3)
70                 div = 3;
71
72         return *parent_rate / div;
73 }
74
75 static int clk_cpu_off_set_rate(struct clk_hw *hwclk, unsigned long rate,
76                                 unsigned long parent_rate)
77
78 {
79         struct cpu_clk *cpuclk = to_cpu_clk(hwclk);
80         u32 reg, div;
81         u32 reload_mask;
82
83         div = parent_rate / rate;
84         reg = (readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET)
85                 & (~(SYS_CTRL_CLK_DIVIDER_MASK << (cpuclk->cpu * 8))))
86                 | (div << (cpuclk->cpu * 8));
87         writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET);
88         /* Set clock divider reload smooth bit mask */
89         reload_mask = 1 << (20 + cpuclk->cpu);
90
91         reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET)
92             | reload_mask;
93         writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET);
94
95         /* Now trigger the clock update */
96         reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET)
97             | 1 << 24;
98         writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET);
99
100         /* Wait for clocks to settle down then clear reload request */
101         udelay(1000);
102         reg &= ~(reload_mask | 1 << 24);
103         writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET);
104         udelay(1000);
105
106         return 0;
107 }
108
109 static int clk_cpu_on_set_rate(struct clk_hw *hwclk, unsigned long rate,
110                                unsigned long parent_rate)
111 {
112         u32 reg;
113         unsigned long fabric_div, target_div, cur_rate;
114         struct cpu_clk *cpuclk = to_cpu_clk(hwclk);
115
116         /*
117          * PMU DFS registers are not mapped, Device Tree does not
118          * describes them. We cannot change the frequency dynamically.
119          */
120         if (!cpuclk->pmu_dfs)
121                 return -ENODEV;
122
123         cur_rate = __clk_get_rate(hwclk->clk);
124
125         reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL2_OFFSET);
126         fabric_div = (reg >> SYS_CTRL_CLK_DIVIDER_CTRL2_NBCLK_RATIO_SHIFT) &
127                 SYS_CTRL_CLK_DIVIDER_MASK;
128
129         /* Frequency is going up */
130         if (rate == 2 * cur_rate)
131                 target_div = fabric_div / 2;
132         /* Frequency is going down */
133         else
134                 target_div = fabric_div;
135
136         if (target_div == 0)
137                 target_div = 1;
138
139         reg = readl(cpuclk->pmu_dfs);
140         reg &= ~(PMU_DFS_RATIO_MASK << PMU_DFS_RATIO_SHIFT);
141         reg |= (target_div << PMU_DFS_RATIO_SHIFT);
142         writel(reg, cpuclk->pmu_dfs);
143
144         reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET);
145         reg |= (SYS_CTRL_CLK_DIVIDER_CTRL_RESET_ALL <<
146                 SYS_CTRL_CLK_DIVIDER_CTRL_RESET_SHIFT);
147         writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET);
148
149         return mvebu_pmsu_dfs_request(cpuclk->cpu);
150 }
151
152 static int clk_cpu_set_rate(struct clk_hw *hwclk, unsigned long rate,
153                             unsigned long parent_rate)
154 {
155         if (__clk_is_enabled(hwclk->clk))
156                 return clk_cpu_on_set_rate(hwclk, rate, parent_rate);
157         else
158                 return clk_cpu_off_set_rate(hwclk, rate, parent_rate);
159 }
160
161 static const struct clk_ops cpu_ops = {
162         .recalc_rate = clk_cpu_recalc_rate,
163         .round_rate = clk_cpu_round_rate,
164         .set_rate = clk_cpu_set_rate,
165 };
166
167 static void __init of_cpu_clk_setup(struct device_node *node)
168 {
169         struct cpu_clk *cpuclk;
170         void __iomem *clock_complex_base = of_iomap(node, 0);
171         void __iomem *pmu_dfs_base = of_iomap(node, 1);
172         int ncpus = 0;
173         struct device_node *dn;
174
175         if (clock_complex_base == NULL) {
176                 pr_err("%s: clock-complex base register not set\n",
177                         __func__);
178                 return;
179         }
180
181         if (pmu_dfs_base == NULL)
182                 pr_warn("%s: pmu-dfs base register not set, dynamic frequency scaling not available\n",
183                         __func__);
184
185         for_each_node_by_type(dn, "cpu")
186                 ncpus++;
187
188         cpuclk = kzalloc(ncpus * sizeof(*cpuclk), GFP_KERNEL);
189         if (WARN_ON(!cpuclk))
190                 goto cpuclk_out;
191
192         clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
193         if (WARN_ON(!clks))
194                 goto clks_out;
195
196         for_each_node_by_type(dn, "cpu") {
197                 struct clk_init_data init;
198                 struct clk *clk;
199                 struct clk *parent_clk;
200                 char *clk_name = kzalloc(5, GFP_KERNEL);
201                 int cpu, err;
202
203                 if (WARN_ON(!clk_name))
204                         goto bail_out;
205
206                 err = of_property_read_u32(dn, "reg", &cpu);
207                 if (WARN_ON(err))
208                         goto bail_out;
209
210                 sprintf(clk_name, "cpu%d", cpu);
211                 parent_clk = of_clk_get(node, 0);
212
213                 cpuclk[cpu].parent_name = __clk_get_name(parent_clk);
214                 cpuclk[cpu].clk_name = clk_name;
215                 cpuclk[cpu].cpu = cpu;
216                 cpuclk[cpu].reg_base = clock_complex_base;
217                 if (pmu_dfs_base)
218                         cpuclk[cpu].pmu_dfs = pmu_dfs_base + 4 * cpu;
219                 cpuclk[cpu].hw.init = &init;
220
221                 init.name = cpuclk[cpu].clk_name;
222                 init.ops = &cpu_ops;
223                 init.flags = 0;
224                 init.parent_names = &cpuclk[cpu].parent_name;
225                 init.num_parents = 1;
226
227                 clk = clk_register(NULL, &cpuclk[cpu].hw);
228                 if (WARN_ON(IS_ERR(clk)))
229                         goto bail_out;
230                 clks[cpu] = clk;
231         }
232         clk_data.clk_num = MAX_CPU;
233         clk_data.clks = clks;
234         of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);
235
236         return;
237 bail_out:
238         kfree(clks);
239         while(ncpus--)
240                 kfree(cpuclk[ncpus].clk_name);
241 clks_out:
242         kfree(cpuclk);
243 cpuclk_out:
244         iounmap(clock_complex_base);
245 }
246
247 CLK_OF_DECLARE(armada_xp_cpu_clock, "marvell,armada-xp-cpu-clock",
248                                          of_cpu_clk_setup);