bcm63xx: AD1018-nor: add NAND flash
[openwrt/staging/rmilecki.git] / target / linux / bmips / patches-5.10 / 200-bmips-automatically-detect-CPU-frequency.patch
1 From 38d5e4b3bcc25db14a2d5f428acf56dff862c97e Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
3 Date: Fri, 5 Mar 2021 15:14:32 +0100
4 Subject: [PATCH] bmips: automatically detect CPU frequency
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Some BCM63xx SoCs support multiple CPU frequencies depending on HW config.
10
11 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
12 ---
13 arch/mips/bmips/setup.c | 197 +++++++++++++++++++++-
14 arch/mips/configs/bmips_bcm63xx_defconfig | 91 ++++++++++
15 2 files changed, 281 insertions(+), 7 deletions(-)
16 create mode 100644 arch/mips/configs/bmips_bcm63xx_defconfig
17
18 --- a/arch/mips/bmips/setup.c
19 +++ b/arch/mips/bmips/setup.c
20 @@ -31,11 +31,51 @@
21
22 #define RELO_NORMAL_VEC BIT(18)
23
24 +#define REG_BCM6318_SOB ((void __iomem *)CKSEG1ADDR(0x10000900))
25 +#define BCM6318_FREQ_SHIFT 23
26 +#define BCM6318_FREQ_MASK (0x3 << BCM6318_FREQ_SHIFT)
27 +
28 #define REG_BCM6328_OTP ((void __iomem *)CKSEG1ADDR(0x1000062c))
29 #define BCM6328_TP1_DISABLED BIT(9)
30 +#define REG_BCM6328_MISC_SB ((void __iomem *)CKSEG1ADDR(0x10001a40))
31 +#define BCM6328_FCVO_SHIFT 7
32 +#define BCM6328_FCVO_MASK (0x1f << BCM6328_FCVO_SHIFT)
33 +
34 +#define REG_BCM6358_DDR_PLLC ((void __iomem *)CKSEG1ADDR(0x100012b8))
35 +#define BCM6358_PLLC_M1_SHIFT 0
36 +#define BCM6358_PLLC_M1_MASK (0xff << BCM6358_PLLC_M1_SHIFT)
37 +#define BCM6358_PLLC_N1_SHIFT 23
38 +#define BCM6358_PLLC_N1_MASK (0x3f << BCM6358_PLLC_N1_SHIFT)
39 +#define BCM6358_PLLC_N2_SHIFT 29
40 +#define BCM6358_PLLC_N2_MASK (0x7 << BCM6358_PLLC_N2_SHIFT)
41 +
42 +#define REG_BCM6362_MISC_SB ((void __iomem *)CKSEG1ADDR(0x10001814))
43 +#define BCM6362_FCVO_SHIFT 1
44 +#define BCM6362_FCVO_MASK (0x1f << BCM6362_FCVO_SHIFT)
45 +
46 +#define REG_BCM6368_DDR_PLLC ((void __iomem *)CKSEG1ADDR(0x100012a0))
47 +#define BCM6368_PLLC_P1_SHIFT 0
48 +#define BCM6368_PLLC_P1_MASK (0xf << BCM6368_PLLC_P1_SHIFT)
49 +#define BCM6368_PLLC_P2_SHIFT 4
50 +#define BCM6368_PLLC_P2_MASK (0xf << BCM6368_PLLC_P2_SHIFT)
51 +#define BCM6368_PLLC_NDIV_SHIFT 16
52 +#define BCM6368_PLLC_NDIV_MASK (0x1ff << BCM6368_PLLC_NDIV_SHIFT)
53 +#define REG_BCM6368_DDR_PLLD ((void __iomem *)CKSEG1ADDR(0x100012a4))
54 +#define BCM6368_PLLD_MDIV_SHIFT 0
55 +#define BCM6368_PLLD_MDIV_MASK (0xff << BCM6368_PLLD_MDIV_SHIFT)
56 +
57 +#define REG_BCM63268_MISC_SB ((void __iomem *)CKSEG1ADDR(0x10001814))
58 +#define BCM63268_FCVO_SHIFT 21
59 +#define BCM63268_FCVO_MASK (0xf << BCM63268_FCVO_SHIFT)
60 +
61
62 static const unsigned long kbase = VMLINUX_LOAD_ADDRESS & 0xfff00000;
63
64 +struct bmips_cpufreq {
65 + const char *compatible;
66 + u32 (*cpu_freq)(void);
67 +};
68 +
69 struct bmips_quirk {
70 const char *compatible;
71 void (*quirk_fn)(void);
72 @@ -138,17 +178,160 @@ const char *get_system_type(void)
73 return "Generic BMIPS kernel";
74 }
75
76 +static u32 bcm6318_cpufreq(void)
77 +{
78 + u32 val = __raw_readl(REG_BCM6318_SOB);
79 +
80 + switch ((val & BCM6318_FREQ_MASK) >> BCM6318_FREQ_SHIFT) {
81 + case 0:
82 + return 166000000;
83 + case 2:
84 + return 250000000;
85 + case 3:
86 + return 333000000;
87 + case 1:
88 + return 400000000;
89 + default:
90 + return 0;
91 + }
92 +}
93 +
94 +static u32 bcm6328_cpufreq(void)
95 +{
96 + u32 val = __raw_readl(REG_BCM6328_MISC_SB);
97 +
98 + switch ((val & BCM6328_FCVO_MASK) >> BCM6328_FCVO_SHIFT) {
99 + case 0x12:
100 + case 0x14:
101 + case 0x19:
102 + return 160000000;
103 + case 0x1c:
104 + return 192000000;
105 + case 0x13:
106 + case 0x15:
107 + return 200000000;
108 + case 0x1a:
109 + return 384000000;
110 + case 0x16:
111 + return 400000000;
112 + default:
113 + return 320000000;
114 + }
115 +}
116 +
117 +static u32 bcm6358_cpufreq(void)
118 +{
119 + u32 val, n1, n2, m1;
120 +
121 + val = __raw_readl(REG_BCM6358_DDR_PLLC);
122 + n1 = (val & BCM6358_PLLC_M1_MASK) >> BCM6358_PLLC_N1_SHIFT;
123 + n2 = (val & BCM6358_PLLC_N2_MASK) >> BCM6358_PLLC_N2_SHIFT;
124 + m1 = (val & BCM6358_PLLC_M1_MASK) >> BCM6358_PLLC_M1_SHIFT;
125 +
126 + return (16 * 1000000 * n1 * n2) / m1;
127 +}
128 +
129 +static u32 bcm6362_cpufreq(void)
130 +{
131 + u32 val = __raw_readl(REG_BCM6362_MISC_SB);
132 +
133 + switch ((val & BCM6362_FCVO_MASK) >> BCM6362_FCVO_SHIFT) {
134 + case 0x04:
135 + case 0x0c:
136 + case 0x14:
137 + case 0x1c:
138 + return 160000000;
139 + case 0x15:
140 + case 0x1d:
141 + return 200000000;
142 + case 0x03:
143 + case 0x0b:
144 + case 0x13:
145 + case 0x1b:
146 + return 240000000;
147 + case 0x07:
148 + case 0x17:
149 + return 384000000;
150 + case 0x05:
151 + case 0x0e:
152 + case 0x16:
153 + case 0x1e:
154 + case 0x1f:
155 + return 400000000;
156 + case 0x06:
157 + return 440000000;
158 + default:
159 + return 320000000;
160 + }
161 +}
162 +
163 +static u32 bcm6368_cpufreq(void)
164 +{
165 + unsigned int val, p1, p2, ndiv, m1;
166 +
167 + val = __raw_readl(REG_BCM6368_DDR_PLLC);
168 + p1 = (val & BCM6368_PLLC_P1_MASK) >> BCM6368_PLLC_P1_SHIFT;
169 + p2 = (val & BCM6368_PLLC_P2_MASK) >> BCM6368_PLLC_P2_SHIFT;
170 + ndiv = (val & BCM6368_PLLC_NDIV_MASK) >>
171 + BCM6368_PLLC_NDIV_SHIFT;
172 +
173 + val = __raw_readl(REG_BCM6368_DDR_PLLD);
174 + m1 = (val & BCM6368_PLLD_MDIV_MASK) >> BCM6368_PLLD_MDIV_SHIFT;
175 +
176 + return (((64 * 1000000) / p1) * p2 * ndiv) / m1;
177 +}
178 +
179 +static u32 bcm63268_cpufreq(void)
180 +{
181 + u32 val = __raw_readl(REG_BCM63268_MISC_SB);
182 +
183 + switch ((val & BCM63268_FCVO_MASK) >> BCM63268_FCVO_SHIFT) {
184 + case 0x3:
185 + case 0xe:
186 + return 320000000;
187 + case 0xa:
188 + return 333000000;
189 + case 0x2:
190 + case 0xb:
191 + case 0xf:
192 + return 400000000;
193 + default:
194 + return 0;
195 + }
196 +}
197 +
198 +static const struct bmips_cpufreq bmips_cpufreq_list[] = {
199 + { "brcm,bcm6318", &bcm6318_cpufreq },
200 + { "brcm,bcm6328", &bcm6328_cpufreq },
201 + { "brcm,bcm6358", &bcm6358_cpufreq },
202 + { "brcm,bcm6362", &bcm6362_cpufreq },
203 + { "brcm,bcm6368", &bcm6368_cpufreq },
204 + { "brcm,bcm63268", &bcm63268_cpufreq },
205 + { /* sentinel */ }
206 +};
207 +
208 void __init plat_time_init(void)
209 {
210 + const struct bmips_cpufreq *cf;
211 struct device_node *np;
212 - u32 freq;
213 + u32 freq = 0;
214
215 - np = of_find_node_by_name(NULL, "cpus");
216 - if (!np)
217 - panic("missing 'cpus' DT node");
218 - if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
219 - panic("missing 'mips-hpt-frequency' property");
220 - of_node_put(np);
221 + for (cf = bmips_cpufreq_list; cf->cpu_freq; cf++) {
222 + if (of_flat_dt_is_compatible(of_get_flat_dt_root(),
223 + cf->compatible)) {
224 + freq = cf->cpu_freq() / 2;
225 + printk("%s detected @ %u MHz\n", cf->compatible, freq / 500000);
226 + }
227 + }
228 +
229 + if (!freq) {
230 + np = of_find_node_by_name(NULL, "cpus");
231 + if (!np)
232 + panic("missing 'cpus' DT node");
233 + if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
234 + panic("missing 'mips-hpt-frequency' property");
235 + of_node_put(np);
236 + }
237
238 mips_hpt_frequency = freq;
239 }