1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/kernel.h>
16#include <linux/clk-provider.h>
17#include <linux/io.h>
18#include <linux/of.h>
19#include "common.h"
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66#define SAR_DOVE_CPU_FREQ 5
67#define SAR_DOVE_CPU_FREQ_MASK 0xf
68#define SAR_DOVE_L2_RATIO 9
69#define SAR_DOVE_L2_RATIO_MASK 0x7
70#define SAR_DOVE_DDR_RATIO 12
71#define SAR_DOVE_DDR_RATIO_MASK 0xf
72#define SAR_DOVE_TCLK_FREQ 23
73#define SAR_DOVE_TCLK_FREQ_MASK 0x3
74
75enum { DOVE_CPU_TO_L2, DOVE_CPU_TO_DDR };
76
77static const struct coreclk_ratio dove_coreclk_ratios[] __initconst = {
78 { .id = DOVE_CPU_TO_L2, .name = "l2clk", },
79 { .id = DOVE_CPU_TO_DDR, .name = "ddrclk", }
80};
81
82static const u32 dove_tclk_freqs[] __initconst = {
83 166666667,
84 125000000,
85 0, 0
86};
87
88static u32 __init dove_get_tclk_freq(void __iomem *sar)
89{
90 u32 opt = (readl(sar) >> SAR_DOVE_TCLK_FREQ) &
91 SAR_DOVE_TCLK_FREQ_MASK;
92 return dove_tclk_freqs[opt];
93}
94
95static const u32 dove_cpu_freqs[] __initconst = {
96 0, 0, 0, 0, 0,
97 1000000000,
98 933333333, 933333333,
99 800000000, 800000000, 800000000,
100 1066666667,
101 666666667,
102 533333333,
103 400000000,
104 333333333
105};
106
107static u32 __init dove_get_cpu_freq(void __iomem *sar)
108{
109 u32 opt = (readl(sar) >> SAR_DOVE_CPU_FREQ) &
110 SAR_DOVE_CPU_FREQ_MASK;
111 return dove_cpu_freqs[opt];
112}
113
114static const int dove_cpu_l2_ratios[8][2] __initconst = {
115 { 1, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 },
116 { 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 }
117};
118
119static const int dove_cpu_ddr_ratios[16][2] __initconst = {
120 { 1, 1 }, { 0, 1 }, { 1, 2 }, { 2, 5 },
121 { 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 },
122 { 1, 5 }, { 0, 1 }, { 1, 6 }, { 0, 1 },
123 { 1, 7 }, { 0, 1 }, { 1, 8 }, { 1, 10 }
124};
125
126static void __init dove_get_clk_ratio(
127 void __iomem *sar, int id, int *mult, int *div)
128{
129 switch (id) {
130 case DOVE_CPU_TO_L2:
131 {
132 u32 opt = (readl(sar) >> SAR_DOVE_L2_RATIO) &
133 SAR_DOVE_L2_RATIO_MASK;
134 *mult = dove_cpu_l2_ratios[opt][0];
135 *div = dove_cpu_l2_ratios[opt][1];
136 break;
137 }
138 case DOVE_CPU_TO_DDR:
139 {
140 u32 opt = (readl(sar) >> SAR_DOVE_DDR_RATIO) &
141 SAR_DOVE_DDR_RATIO_MASK;
142 *mult = dove_cpu_ddr_ratios[opt][0];
143 *div = dove_cpu_ddr_ratios[opt][1];
144 break;
145 }
146 }
147}
148
149static const struct coreclk_soc_desc dove_coreclks = {
150 .get_tclk_freq = dove_get_tclk_freq,
151 .get_cpu_freq = dove_get_cpu_freq,
152 .get_clk_ratio = dove_get_clk_ratio,
153 .ratios = dove_coreclk_ratios,
154 .num_ratios = ARRAY_SIZE(dove_coreclk_ratios),
155};
156
157
158
159
160
161static const struct clk_gating_soc_desc dove_gating_desc[] __initconst = {
162 { "usb0", NULL, 0, 0 },
163 { "usb1", NULL, 1, 0 },
164 { "ge", "gephy", 2, 0 },
165 { "sata", NULL, 3, 0 },
166 { "pex0", NULL, 4, 0 },
167 { "pex1", NULL, 5, 0 },
168 { "sdio0", NULL, 8, 0 },
169 { "sdio1", NULL, 9, 0 },
170 { "nand", NULL, 10, 0 },
171 { "camera", NULL, 11, 0 },
172 { "i2s0", NULL, 12, 0 },
173 { "i2s1", NULL, 13, 0 },
174 { "crypto", NULL, 15, 0 },
175 { "ac97", NULL, 21, 0 },
176 { "pdma", NULL, 22, 0 },
177 { "xor0", NULL, 23, 0 },
178 { "xor1", NULL, 24, 0 },
179 { "gephy", NULL, 30, 0 },
180 { }
181};
182
183static void __init dove_clk_init(struct device_node *np)
184{
185 struct device_node *cgnp =
186 of_find_compatible_node(NULL, NULL, "marvell,dove-gating-clock");
187
188 mvebu_coreclk_setup(np, &dove_coreclks);
189
190 if (cgnp)
191 mvebu_clk_gating_setup(cgnp, dove_gating_desc);
192}
193CLK_OF_DECLARE(dove_clk, "marvell,dove-core-clock", dove_clk_init);
194