GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / clk / mvebu / orion.c
1 /*
2  * Marvell Orion SoC clocks
3  *
4  * Copyright (C) 2014 Thomas Petazzoni
5  *
6  * Thomas Petazzoni <thomas.petazzoni@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
13 #include <linux/kernel.h>
14 #include <linux/clk-provider.h>
15 #include <linux/io.h>
16 #include <linux/of.h>
17 #include "common.h"
18
19 static const struct coreclk_ratio orion_coreclk_ratios[] __initconst = {
20         { .id = 0, .name = "ddrclk", }
21 };
22
23 /*
24  * Orion 5181
25  */
26
27 #define SAR_MV88F5181_TCLK_FREQ      8
28 #define SAR_MV88F5181_TCLK_FREQ_MASK 0x3
29
30 static u32 __init mv88f5181_get_tclk_freq(void __iomem *sar)
31 {
32         u32 opt = (readl(sar) >> SAR_MV88F5181_TCLK_FREQ) &
33                 SAR_MV88F5181_TCLK_FREQ_MASK;
34         if (opt == 0)
35                 return 133333333;
36         else if (opt == 1)
37                 return 150000000;
38         else if (opt == 2)
39                 return 166666667;
40         else
41                 return 0;
42 }
43
44 #define SAR_MV88F5181_CPU_FREQ       4
45 #define SAR_MV88F5181_CPU_FREQ_MASK  0xf
46
47 static u32 __init mv88f5181_get_cpu_freq(void __iomem *sar)
48 {
49         u32 opt = (readl(sar) >> SAR_MV88F5181_CPU_FREQ) &
50                 SAR_MV88F5181_CPU_FREQ_MASK;
51         if (opt == 0)
52                 return 333333333;
53         else if (opt == 1 || opt == 2)
54                 return 400000000;
55         else if (opt == 3)
56                 return 500000000;
57         else
58                 return 0;
59 }
60
61 static void __init mv88f5181_get_clk_ratio(void __iomem *sar, int id,
62                                            int *mult, int *div)
63 {
64         u32 opt = (readl(sar) >> SAR_MV88F5181_CPU_FREQ) &
65                 SAR_MV88F5181_CPU_FREQ_MASK;
66         if (opt == 0 || opt == 1) {
67                 *mult = 1;
68                 *div  = 2;
69         } else if (opt == 2 || opt == 3) {
70                 *mult = 1;
71                 *div  = 3;
72         } else {
73                 *mult = 0;
74                 *div  = 1;
75         }
76 }
77
78 static const struct coreclk_soc_desc mv88f5181_coreclks = {
79         .get_tclk_freq = mv88f5181_get_tclk_freq,
80         .get_cpu_freq = mv88f5181_get_cpu_freq,
81         .get_clk_ratio = mv88f5181_get_clk_ratio,
82         .ratios = orion_coreclk_ratios,
83         .num_ratios = ARRAY_SIZE(orion_coreclk_ratios),
84 };
85
86 static void __init mv88f5181_clk_init(struct device_node *np)
87 {
88         return mvebu_coreclk_setup(np, &mv88f5181_coreclks);
89 }
90
91 CLK_OF_DECLARE(mv88f5181_clk, "marvell,mv88f5181-core-clock", mv88f5181_clk_init);
92
93 /*
94  * Orion 5182
95  */
96
97 #define SAR_MV88F5182_TCLK_FREQ      8
98 #define SAR_MV88F5182_TCLK_FREQ_MASK 0x3
99
100 static u32 __init mv88f5182_get_tclk_freq(void __iomem *sar)
101 {
102         u32 opt = (readl(sar) >> SAR_MV88F5182_TCLK_FREQ) &
103                 SAR_MV88F5182_TCLK_FREQ_MASK;
104         if (opt == 1)
105                 return 150000000;
106         else if (opt == 2)
107                 return 166666667;
108         else
109                 return 0;
110 }
111
112 #define SAR_MV88F5182_CPU_FREQ       4
113 #define SAR_MV88F5182_CPU_FREQ_MASK  0xf
114
115 static u32 __init mv88f5182_get_cpu_freq(void __iomem *sar)
116 {
117         u32 opt = (readl(sar) >> SAR_MV88F5182_CPU_FREQ) &
118                 SAR_MV88F5182_CPU_FREQ_MASK;
119         if (opt == 0)
120                 return 333333333;
121         else if (opt == 1 || opt == 2)
122                 return 400000000;
123         else if (opt == 3)
124                 return 500000000;
125         else
126                 return 0;
127 }
128
129 static void __init mv88f5182_get_clk_ratio(void __iomem *sar, int id,
130                                            int *mult, int *div)
131 {
132         u32 opt = (readl(sar) >> SAR_MV88F5182_CPU_FREQ) &
133                 SAR_MV88F5182_CPU_FREQ_MASK;
134         if (opt == 0 || opt == 1) {
135                 *mult = 1;
136                 *div  = 2;
137         } else if (opt == 2 || opt == 3) {
138                 *mult = 1;
139                 *div  = 3;
140         } else {
141                 *mult = 0;
142                 *div  = 1;
143         }
144 }
145
146 static const struct coreclk_soc_desc mv88f5182_coreclks = {
147         .get_tclk_freq = mv88f5182_get_tclk_freq,
148         .get_cpu_freq = mv88f5182_get_cpu_freq,
149         .get_clk_ratio = mv88f5182_get_clk_ratio,
150         .ratios = orion_coreclk_ratios,
151         .num_ratios = ARRAY_SIZE(orion_coreclk_ratios),
152 };
153
154 static void __init mv88f5182_clk_init(struct device_node *np)
155 {
156         return mvebu_coreclk_setup(np, &mv88f5182_coreclks);
157 }
158
159 CLK_OF_DECLARE(mv88f5182_clk, "marvell,mv88f5182-core-clock", mv88f5182_clk_init);
160
161 /*
162  * Orion 5281
163  */
164
165 static u32 __init mv88f5281_get_tclk_freq(void __iomem *sar)
166 {
167         /* On 5281, tclk is always 166 Mhz */
168         return 166666667;
169 }
170
171 #define SAR_MV88F5281_CPU_FREQ       4
172 #define SAR_MV88F5281_CPU_FREQ_MASK  0xf
173
174 static u32 __init mv88f5281_get_cpu_freq(void __iomem *sar)
175 {
176         u32 opt = (readl(sar) >> SAR_MV88F5281_CPU_FREQ) &
177                 SAR_MV88F5281_CPU_FREQ_MASK;
178         if (opt == 1 || opt == 2)
179                 return 400000000;
180         else if (opt == 3)
181                 return 500000000;
182         else
183                 return 0;
184 }
185
186 static void __init mv88f5281_get_clk_ratio(void __iomem *sar, int id,
187                                            int *mult, int *div)
188 {
189         u32 opt = (readl(sar) >> SAR_MV88F5281_CPU_FREQ) &
190                 SAR_MV88F5281_CPU_FREQ_MASK;
191         if (opt == 1) {
192                 *mult = 1;
193                 *div = 2;
194         } else if (opt == 2 || opt == 3) {
195                 *mult = 1;
196                 *div = 3;
197         } else {
198                 *mult = 0;
199                 *div = 1;
200         }
201 }
202
203 static const struct coreclk_soc_desc mv88f5281_coreclks = {
204         .get_tclk_freq = mv88f5281_get_tclk_freq,
205         .get_cpu_freq = mv88f5281_get_cpu_freq,
206         .get_clk_ratio = mv88f5281_get_clk_ratio,
207         .ratios = orion_coreclk_ratios,
208         .num_ratios = ARRAY_SIZE(orion_coreclk_ratios),
209 };
210
211 static void __init mv88f5281_clk_init(struct device_node *np)
212 {
213         return mvebu_coreclk_setup(np, &mv88f5281_coreclks);
214 }
215
216 CLK_OF_DECLARE(mv88f5281_clk, "marvell,mv88f5281-core-clock", mv88f5281_clk_init);
217
218 /*
219  * Orion 6183
220  */
221
222 #define SAR_MV88F6183_TCLK_FREQ      9
223 #define SAR_MV88F6183_TCLK_FREQ_MASK 0x1
224
225 static u32 __init mv88f6183_get_tclk_freq(void __iomem *sar)
226 {
227         u32 opt = (readl(sar) >> SAR_MV88F6183_TCLK_FREQ) &
228                 SAR_MV88F6183_TCLK_FREQ_MASK;
229         if (opt == 0)
230                 return 133333333;
231         else if (opt == 1)
232                 return 166666667;
233         else
234                 return 0;
235 }
236
237 #define SAR_MV88F6183_CPU_FREQ       1
238 #define SAR_MV88F6183_CPU_FREQ_MASK  0x3f
239
240 static u32 __init mv88f6183_get_cpu_freq(void __iomem *sar)
241 {
242         u32 opt = (readl(sar) >> SAR_MV88F6183_CPU_FREQ) &
243                 SAR_MV88F6183_CPU_FREQ_MASK;
244         if (opt == 9)
245                 return 333333333;
246         else if (opt == 17)
247                 return 400000000;
248         else
249                 return 0;
250 }
251
252 static void __init mv88f6183_get_clk_ratio(void __iomem *sar, int id,
253                                            int *mult, int *div)
254 {
255         u32 opt = (readl(sar) >> SAR_MV88F6183_CPU_FREQ) &
256                 SAR_MV88F6183_CPU_FREQ_MASK;
257         if (opt == 9 || opt == 17) {
258                 *mult = 1;
259                 *div  = 2;
260         } else {
261                 *mult = 0;
262                 *div  = 1;
263         }
264 }
265
266 static const struct coreclk_soc_desc mv88f6183_coreclks = {
267         .get_tclk_freq = mv88f6183_get_tclk_freq,
268         .get_cpu_freq = mv88f6183_get_cpu_freq,
269         .get_clk_ratio = mv88f6183_get_clk_ratio,
270         .ratios = orion_coreclk_ratios,
271         .num_ratios = ARRAY_SIZE(orion_coreclk_ratios),
272 };
273
274
275 static void __init mv88f6183_clk_init(struct device_node *np)
276 {
277         return mvebu_coreclk_setup(np, &mv88f6183_coreclks);
278 }
279
280 CLK_OF_DECLARE(mv88f6183_clk, "marvell,mv88f6183-core-clock", mv88f6183_clk_init);