forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
kernel/arch/arc/plat-hsdk/platform.c
....@@ -1,42 +1,25 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * ARC HSDK Platform support code
34 *
45 * Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com)
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License version 2 as
8
- * published by the Free Software Foundation.
96 */
107
118 #include <linux/init.h>
9
+#include <linux/of_fdt.h>
10
+#include <linux/libfdt.h>
1211 #include <linux/smp.h>
1312 #include <asm/arcregs.h>
1413 #include <asm/io.h>
1514 #include <asm/mach_desc.h>
1615
16
+int arc_hsdk_axi_dmac_coherent __section(".data") = 0;
17
+
1718 #define ARC_CCM_UNUSED_ADDR 0x60000000
1819
19
-static void __init hsdk_init_per_cpu(unsigned int cpu)
20
-{
21
- /*
22
- * By default ICCM is mapped to 0x7z while this area is used for
23
- * kernel virtual mappings, so move it to currently unused area.
24
- */
25
- if (cpuinfo_arc700[cpu].iccm.sz)
26
- write_aux_reg(ARC_REG_AUX_ICCM, ARC_CCM_UNUSED_ADDR);
27
-
28
- /*
29
- * By default DCCM is mapped to 0x8z while this area is used by kernel,
30
- * so move it to currently unused area.
31
- */
32
- if (cpuinfo_arc700[cpu].dccm.sz)
33
- write_aux_reg(ARC_REG_AUX_DCCM, ARC_CCM_UNUSED_ADDR);
34
-}
3520
3621 #define ARC_PERIPHERAL_BASE 0xf0000000
3722 #define CREG_BASE (ARC_PERIPHERAL_BASE + 0x1000)
38
-#define CREG_PAE (CREG_BASE + 0x180)
39
-#define CREG_PAE_UPDATE (CREG_BASE + 0x194)
4023
4124 #define SDIO_BASE (ARC_PERIPHERAL_BASE + 0xA000)
4225 #define SDIO_UHS_REG_EXT (SDIO_BASE + 0x108)
....@@ -102,20 +85,226 @@
10285 iowrite32(GPIO_INT_CONNECTED_MASK, (void __iomem *) GPIO_INTEN);
10386 }
10487
105
-static void __init hsdk_init_early(void)
88
+static int __init hsdk_tweak_node_coherency(const char *path, bool coherent)
10689 {
90
+ void *fdt = initial_boot_params;
91
+ const void *prop;
92
+ int node, ret;
93
+ bool dt_coh_set;
94
+
95
+ node = fdt_path_offset(fdt, path);
96
+ if (node < 0)
97
+ goto tweak_fail;
98
+
99
+ prop = fdt_getprop(fdt, node, "dma-coherent", &ret);
100
+ if (!prop && ret != -FDT_ERR_NOTFOUND)
101
+ goto tweak_fail;
102
+
103
+ dt_coh_set = ret != -FDT_ERR_NOTFOUND;
104
+ ret = 0;
105
+
106
+ /* need to remove "dma-coherent" property */
107
+ if (dt_coh_set && !coherent)
108
+ ret = fdt_delprop(fdt, node, "dma-coherent");
109
+
110
+ /* need to set "dma-coherent" property */
111
+ if (!dt_coh_set && coherent)
112
+ ret = fdt_setprop(fdt, node, "dma-coherent", NULL, 0);
113
+
114
+ if (ret < 0)
115
+ goto tweak_fail;
116
+
117
+ return 0;
118
+
119
+tweak_fail:
120
+ pr_err("failed to tweak %s to %scoherent\n", path, coherent ? "" : "non");
121
+ return -EFAULT;
122
+}
123
+
124
+enum hsdk_axi_masters {
125
+ M_HS_CORE = 0,
126
+ M_HS_RTT,
127
+ M_AXI_TUN,
128
+ M_HDMI_VIDEO,
129
+ M_HDMI_AUDIO,
130
+ M_USB_HOST,
131
+ M_ETHERNET,
132
+ M_SDIO,
133
+ M_GPU,
134
+ M_DMAC_0,
135
+ M_DMAC_1,
136
+ M_DVFS
137
+};
138
+
139
+#define UPDATE_VAL 1
140
+
141
+/*
142
+ * This is modified configuration of AXI bridge. Default settings
143
+ * are specified in "Table 111 CREG Address Decoder register reset values".
144
+ *
145
+ * AXI_M_m_SLV{0|1} - Slave Select register for master 'm'.
146
+ * Possible slaves are:
147
+ * - 0 => no slave selected
148
+ * - 1 => DDR controller port #1
149
+ * - 2 => SRAM controller
150
+ * - 3 => AXI tunnel
151
+ * - 4 => EBI controller
152
+ * - 5 => ROM controller
153
+ * - 6 => AXI2APB bridge
154
+ * - 7 => DDR controller port #2
155
+ * - 8 => DDR controller port #3
156
+ * - 9 => HS38x4 IOC
157
+ * - 10 => HS38x4 DMI
158
+ * AXI_M_m_OFFSET{0|1} - Addr Offset register for master 'm'
159
+ *
160
+ * Please read ARC HS Development IC Specification, section 17.2 for more
161
+ * information about apertures configuration.
162
+ *
163
+ * m master AXI_M_m_SLV0 AXI_M_m_SLV1 AXI_M_m_OFFSET0 AXI_M_m_OFFSET1
164
+ * 0 HS (CBU) 0x11111111 0x63111111 0xFEDCBA98 0x0E543210
165
+ * 1 HS (RTT) 0x77777777 0x77777777 0xFEDCBA98 0x76543210
166
+ * 2 AXI Tunnel 0x88888888 0x88888888 0xFEDCBA98 0x76543210
167
+ * 3 HDMI-VIDEO 0x77777777 0x77777777 0xFEDCBA98 0x76543210
168
+ * 4 HDMI-ADUIO 0x77777777 0x77777777 0xFEDCBA98 0x76543210
169
+ * 5 USB-HOST 0x77777777 0x77999999 0xFEDCBA98 0x76DCBA98
170
+ * 6 ETHERNET 0x77777777 0x77999999 0xFEDCBA98 0x76DCBA98
171
+ * 7 SDIO 0x77777777 0x77999999 0xFEDCBA98 0x76DCBA98
172
+ * 8 GPU 0x77777777 0x77777777 0xFEDCBA98 0x76543210
173
+ * 9 DMAC (port #1) 0x77777777 0x77777777 0xFEDCBA98 0x76543210
174
+ * 10 DMAC (port #2) 0x77777777 0x77777777 0xFEDCBA98 0x76543210
175
+ * 11 DVFS 0x00000000 0x60000000 0x00000000 0x00000000
176
+ */
177
+
178
+#define CREG_AXI_M_SLV0(m) ((void __iomem *)(CREG_BASE + 0x20 * (m)))
179
+#define CREG_AXI_M_SLV1(m) ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x04))
180
+#define CREG_AXI_M_OFT0(m) ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x08))
181
+#define CREG_AXI_M_OFT1(m) ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x0C))
182
+#define CREG_AXI_M_UPDT(m) ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x14))
183
+
184
+#define CREG_AXI_M_HS_CORE_BOOT ((void __iomem *)(CREG_BASE + 0x010))
185
+
186
+#define CREG_PAE ((void __iomem *)(CREG_BASE + 0x180))
187
+#define CREG_PAE_UPDT ((void __iomem *)(CREG_BASE + 0x194))
188
+
189
+static void __init hsdk_init_memory_bridge_axi_dmac(void)
190
+{
191
+ bool coherent = !!arc_hsdk_axi_dmac_coherent;
192
+ u32 axi_m_slv1, axi_m_oft1;
193
+
194
+ /*
195
+ * Don't tweak memory bridge configuration if we failed to tweak DTB
196
+ * as we will end up in a inconsistent state.
197
+ */
198
+ if (hsdk_tweak_node_coherency("/soc/dmac@80000", coherent))
199
+ return;
200
+
201
+ if (coherent) {
202
+ axi_m_slv1 = 0x77999999;
203
+ axi_m_oft1 = 0x76DCBA98;
204
+ } else {
205
+ axi_m_slv1 = 0x77777777;
206
+ axi_m_oft1 = 0x76543210;
207
+ }
208
+
209
+ writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_0));
210
+ writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_0));
211
+ writel(axi_m_slv1, CREG_AXI_M_SLV1(M_DMAC_0));
212
+ writel(axi_m_oft1, CREG_AXI_M_OFT1(M_DMAC_0));
213
+ writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_0));
214
+
215
+ writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_1));
216
+ writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_1));
217
+ writel(axi_m_slv1, CREG_AXI_M_SLV1(M_DMAC_1));
218
+ writel(axi_m_oft1, CREG_AXI_M_OFT1(M_DMAC_1));
219
+ writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_1));
220
+}
221
+
222
+static void __init hsdk_init_memory_bridge(void)
223
+{
224
+ u32 reg;
225
+
226
+ /*
227
+ * M_HS_CORE has one unique register - BOOT.
228
+ * We need to clean boot mirror (BOOT[1:0]) bits in them to avoid first
229
+ * aperture to be masked by 'boot mirror'.
230
+ */
231
+ reg = readl(CREG_AXI_M_HS_CORE_BOOT) & (~0x3);
232
+ writel(reg, CREG_AXI_M_HS_CORE_BOOT);
233
+ writel(0x11111111, CREG_AXI_M_SLV0(M_HS_CORE));
234
+ writel(0x63111111, CREG_AXI_M_SLV1(M_HS_CORE));
235
+ writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HS_CORE));
236
+ writel(0x0E543210, CREG_AXI_M_OFT1(M_HS_CORE));
237
+ writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HS_CORE));
238
+
239
+ writel(0x77777777, CREG_AXI_M_SLV0(M_HS_RTT));
240
+ writel(0x77777777, CREG_AXI_M_SLV1(M_HS_RTT));
241
+ writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HS_RTT));
242
+ writel(0x76543210, CREG_AXI_M_OFT1(M_HS_RTT));
243
+ writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HS_RTT));
244
+
245
+ writel(0x88888888, CREG_AXI_M_SLV0(M_AXI_TUN));
246
+ writel(0x88888888, CREG_AXI_M_SLV1(M_AXI_TUN));
247
+ writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_AXI_TUN));
248
+ writel(0x76543210, CREG_AXI_M_OFT1(M_AXI_TUN));
249
+ writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_AXI_TUN));
250
+
251
+ writel(0x77777777, CREG_AXI_M_SLV0(M_HDMI_VIDEO));
252
+ writel(0x77777777, CREG_AXI_M_SLV1(M_HDMI_VIDEO));
253
+ writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HDMI_VIDEO));
254
+ writel(0x76543210, CREG_AXI_M_OFT1(M_HDMI_VIDEO));
255
+ writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HDMI_VIDEO));
256
+
257
+ writel(0x77777777, CREG_AXI_M_SLV0(M_HDMI_AUDIO));
258
+ writel(0x77777777, CREG_AXI_M_SLV1(M_HDMI_AUDIO));
259
+ writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HDMI_AUDIO));
260
+ writel(0x76543210, CREG_AXI_M_OFT1(M_HDMI_AUDIO));
261
+ writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HDMI_AUDIO));
262
+
263
+ writel(0x77777777, CREG_AXI_M_SLV0(M_USB_HOST));
264
+ writel(0x77999999, CREG_AXI_M_SLV1(M_USB_HOST));
265
+ writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_USB_HOST));
266
+ writel(0x76DCBA98, CREG_AXI_M_OFT1(M_USB_HOST));
267
+ writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_USB_HOST));
268
+
269
+ writel(0x77777777, CREG_AXI_M_SLV0(M_ETHERNET));
270
+ writel(0x77999999, CREG_AXI_M_SLV1(M_ETHERNET));
271
+ writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_ETHERNET));
272
+ writel(0x76DCBA98, CREG_AXI_M_OFT1(M_ETHERNET));
273
+ writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_ETHERNET));
274
+
275
+ writel(0x77777777, CREG_AXI_M_SLV0(M_SDIO));
276
+ writel(0x77999999, CREG_AXI_M_SLV1(M_SDIO));
277
+ writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_SDIO));
278
+ writel(0x76DCBA98, CREG_AXI_M_OFT1(M_SDIO));
279
+ writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_SDIO));
280
+
281
+ writel(0x77777777, CREG_AXI_M_SLV0(M_GPU));
282
+ writel(0x77777777, CREG_AXI_M_SLV1(M_GPU));
283
+ writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_GPU));
284
+ writel(0x76543210, CREG_AXI_M_OFT1(M_GPU));
285
+ writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_GPU));
286
+
287
+ writel(0x00000000, CREG_AXI_M_SLV0(M_DVFS));
288
+ writel(0x60000000, CREG_AXI_M_SLV1(M_DVFS));
289
+ writel(0x00000000, CREG_AXI_M_OFT0(M_DVFS));
290
+ writel(0x00000000, CREG_AXI_M_OFT1(M_DVFS));
291
+ writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DVFS));
292
+
293
+ hsdk_init_memory_bridge_axi_dmac();
294
+
107295 /*
108296 * PAE remapping for DMA clients does not work due to an RTL bug, so
109297 * CREG_PAE register must be programmed to all zeroes, otherwise it
110298 * will cause problems with DMA to/from peripherals even if PAE40 is
111299 * not used.
112300 */
301
+ writel(0x00000000, CREG_PAE);
302
+ writel(UPDATE_VAL, CREG_PAE_UPDT);
303
+}
113304
114
- /* Default is 1, which means "PAE offset = 4GByte" */
115
- writel_relaxed(0, (void __iomem *) CREG_PAE);
116
-
117
- /* Really apply settings made above */
118
- writel(1, (void __iomem *) CREG_PAE_UPDATE);
305
+static void __init hsdk_init_early(void)
306
+{
307
+ hsdk_init_memory_bridge();
119308
120309 /*
121310 * Switch SDIO external ciu clock divider from default div-by-8 to
....@@ -134,5 +323,4 @@
134323 MACHINE_START(SIMULATION, "hsdk")
135324 .dt_compat = hsdk_compat,
136325 .init_early = hsdk_init_early,
137
- .init_per_cpu = hsdk_init_per_cpu,
138326 MACHINE_END