]>
Commit | Line | Data |
---|---|---|
6b72333d SH |
1 | /* |
2 | * Marvell Armada 370 SoC clocks | |
3 | * | |
4 | * Copyright (C) 2012 Marvell | |
5 | * | |
6 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | |
7 | * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | |
8 | * Andrew Lunn <andrew@lunn.ch> | |
9 | * | |
10 | * This file is licensed under the terms of the GNU General Public | |
11 | * License version 2. This program is licensed "as is" without any | |
12 | * warranty of any kind, whether express or implied. | |
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 | * Core Clocks | |
23 | */ | |
24 | ||
25 | #define SARL 0 /* Low part [0:31] */ | |
26 | #define SARL_A370_PCLK_FREQ_OPT 11 | |
27 | #define SARL_A370_PCLK_FREQ_OPT_MASK 0xF | |
28 | #define SARL_A370_FAB_FREQ_OPT 15 | |
29 | #define SARL_A370_FAB_FREQ_OPT_MASK 0x1F | |
30 | #define SARL_A370_TCLK_FREQ_OPT 20 | |
31 | #define SARL_A370_TCLK_FREQ_OPT_MASK 0x1 | |
32 | ||
33 | enum { A370_CPU_TO_NBCLK, A370_CPU_TO_HCLK, A370_CPU_TO_DRAMCLK }; | |
34 | ||
682dfdc0 | 35 | static const struct coreclk_ratio a370_coreclk_ratios[] __initconst = { |
6b72333d SH |
36 | { .id = A370_CPU_TO_NBCLK, .name = "nbclk" }, |
37 | { .id = A370_CPU_TO_HCLK, .name = "hclk" }, | |
38 | { .id = A370_CPU_TO_DRAMCLK, .name = "dramclk" }, | |
39 | }; | |
40 | ||
682dfdc0 | 41 | static const u32 a370_tclk_freqs[] __initconst = { |
1022c75f SG |
42 | 166000000, |
43 | 200000000, | |
6b72333d SH |
44 | }; |
45 | ||
46 | static u32 __init a370_get_tclk_freq(void __iomem *sar) | |
47 | { | |
48 | u8 tclk_freq_select = 0; | |
49 | ||
50 | tclk_freq_select = ((readl(sar) >> SARL_A370_TCLK_FREQ_OPT) & | |
51 | SARL_A370_TCLK_FREQ_OPT_MASK); | |
52 | return a370_tclk_freqs[tclk_freq_select]; | |
53 | } | |
54 | ||
682dfdc0 | 55 | static const u32 a370_cpu_freqs[] __initconst = { |
6b72333d SH |
56 | 400000000, |
57 | 533000000, | |
58 | 667000000, | |
59 | 800000000, | |
60 | 1000000000, | |
61 | 1067000000, | |
62 | 1200000000, | |
63 | }; | |
64 | ||
65 | static u32 __init a370_get_cpu_freq(void __iomem *sar) | |
66 | { | |
67 | u32 cpu_freq; | |
68 | u8 cpu_freq_select = 0; | |
69 | ||
70 | cpu_freq_select = ((readl(sar) >> SARL_A370_PCLK_FREQ_OPT) & | |
71 | SARL_A370_PCLK_FREQ_OPT_MASK); | |
72 | if (cpu_freq_select >= ARRAY_SIZE(a370_cpu_freqs)) { | |
73 | pr_err("CPU freq select unsupported %d\n", cpu_freq_select); | |
74 | cpu_freq = 0; | |
75 | } else | |
76 | cpu_freq = a370_cpu_freqs[cpu_freq_select]; | |
77 | ||
78 | return cpu_freq; | |
79 | } | |
80 | ||
682dfdc0 | 81 | static const int a370_nbclk_ratios[32][2] __initconst = { |
6b72333d SH |
82 | {0, 1}, {1, 2}, {2, 2}, {2, 2}, |
83 | {1, 2}, {1, 2}, {1, 1}, {2, 3}, | |
84 | {0, 1}, {1, 2}, {2, 4}, {0, 1}, | |
85 | {1, 2}, {0, 1}, {0, 1}, {2, 2}, | |
86 | {0, 1}, {0, 1}, {0, 1}, {1, 1}, | |
87 | {2, 3}, {0, 1}, {0, 1}, {0, 1}, | |
88 | {0, 1}, {0, 1}, {0, 1}, {1, 1}, | |
89 | {0, 1}, {0, 1}, {0, 1}, {0, 1}, | |
90 | }; | |
91 | ||
682dfdc0 | 92 | static const int a370_hclk_ratios[32][2] __initconst = { |
6b72333d SH |
93 | {0, 1}, {1, 2}, {2, 6}, {2, 3}, |
94 | {1, 3}, {1, 4}, {1, 2}, {2, 6}, | |
95 | {0, 1}, {1, 6}, {2, 10}, {0, 1}, | |
96 | {1, 4}, {0, 1}, {0, 1}, {2, 5}, | |
97 | {0, 1}, {0, 1}, {0, 1}, {1, 2}, | |
98 | {2, 6}, {0, 1}, {0, 1}, {0, 1}, | |
99 | {0, 1}, {0, 1}, {0, 1}, {1, 1}, | |
100 | {0, 1}, {0, 1}, {0, 1}, {0, 1}, | |
101 | }; | |
102 | ||
682dfdc0 | 103 | static const int a370_dramclk_ratios[32][2] __initconst = { |
6b72333d SH |
104 | {0, 1}, {1, 2}, {2, 3}, {2, 3}, |
105 | {1, 3}, {1, 2}, {1, 2}, {2, 6}, | |
106 | {0, 1}, {1, 3}, {2, 5}, {0, 1}, | |
107 | {1, 4}, {0, 1}, {0, 1}, {2, 5}, | |
108 | {0, 1}, {0, 1}, {0, 1}, {1, 1}, | |
109 | {2, 3}, {0, 1}, {0, 1}, {0, 1}, | |
110 | {0, 1}, {0, 1}, {0, 1}, {1, 1}, | |
111 | {0, 1}, {0, 1}, {0, 1}, {0, 1}, | |
112 | }; | |
113 | ||
114 | static void __init a370_get_clk_ratio( | |
115 | void __iomem *sar, int id, int *mult, int *div) | |
116 | { | |
117 | u32 opt = ((readl(sar) >> SARL_A370_FAB_FREQ_OPT) & | |
118 | SARL_A370_FAB_FREQ_OPT_MASK); | |
119 | ||
120 | switch (id) { | |
121 | case A370_CPU_TO_NBCLK: | |
122 | *mult = a370_nbclk_ratios[opt][0]; | |
123 | *div = a370_nbclk_ratios[opt][1]; | |
124 | break; | |
125 | case A370_CPU_TO_HCLK: | |
126 | *mult = a370_hclk_ratios[opt][0]; | |
127 | *div = a370_hclk_ratios[opt][1]; | |
128 | break; | |
129 | case A370_CPU_TO_DRAMCLK: | |
130 | *mult = a370_dramclk_ratios[opt][0]; | |
131 | *div = a370_dramclk_ratios[opt][1]; | |
132 | break; | |
133 | } | |
134 | } | |
135 | ||
136 | static const struct coreclk_soc_desc a370_coreclks = { | |
137 | .get_tclk_freq = a370_get_tclk_freq, | |
138 | .get_cpu_freq = a370_get_cpu_freq, | |
139 | .get_clk_ratio = a370_get_clk_ratio, | |
140 | .ratios = a370_coreclk_ratios, | |
141 | .num_ratios = ARRAY_SIZE(a370_coreclk_ratios), | |
142 | }; | |
143 | ||
6b72333d SH |
144 | /* |
145 | * Clock Gating Control | |
146 | */ | |
147 | ||
682dfdc0 | 148 | static const struct clk_gating_soc_desc a370_gating_desc[] __initconst = { |
6b72333d SH |
149 | { "audio", NULL, 0, 0 }, |
150 | { "pex0_en", NULL, 1, 0 }, | |
151 | { "pex1_en", NULL, 2, 0 }, | |
152 | { "ge1", NULL, 3, 0 }, | |
153 | { "ge0", NULL, 4, 0 }, | |
154 | { "pex0", "pex0_en", 5, 0 }, | |
155 | { "pex1", "pex1_en", 9, 0 }, | |
156 | { "sata0", NULL, 15, 0 }, | |
157 | { "sdio", NULL, 17, 0 }, | |
158 | { "tdm", NULL, 25, 0 }, | |
159 | { "ddr", NULL, 28, CLK_IGNORE_UNUSED }, | |
160 | { "sata1", NULL, 30, 0 }, | |
161 | { } | |
162 | }; | |
163 | ||
07ad6836 | 164 | static void __init a370_clk_init(struct device_node *np) |
6b72333d | 165 | { |
07ad6836 SH |
166 | struct device_node *cgnp = |
167 | of_find_compatible_node(NULL, NULL, "marvell,armada-370-gating-clock"); | |
168 | ||
169 | mvebu_coreclk_setup(np, &a370_coreclks); | |
170 | ||
171 | if (cgnp) | |
172 | mvebu_clk_gating_setup(cgnp, a370_gating_desc); | |
6b72333d | 173 | } |
07ad6836 SH |
174 | CLK_OF_DECLARE(a370_clk, "marvell,armada-370-core-clock", a370_clk_init); |
175 |