Merge branch 'regulator-5.4' into regulator-linus
[sfrench/cifs-2.6.git] / arch / arc / plat-hsdk / platform.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * ARC HSDK Platform support code
4  *
5  * Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com)
6  */
7
8 #include <linux/init.h>
9 #include <linux/of_fdt.h>
10 #include <linux/libfdt.h>
11 #include <linux/smp.h>
12 #include <asm/arcregs.h>
13 #include <asm/io.h>
14 #include <asm/mach_desc.h>
15
16 int arc_hsdk_axi_dmac_coherent __section(.data) = 0;
17
18 #define ARC_CCM_UNUSED_ADDR     0x60000000
19
20 static void __init hsdk_init_per_cpu(unsigned int cpu)
21 {
22         /*
23          * By default ICCM is mapped to 0x7z while this area is used for
24          * kernel virtual mappings, so move it to currently unused area.
25          */
26         if (cpuinfo_arc700[cpu].iccm.sz)
27                 write_aux_reg(ARC_REG_AUX_ICCM, ARC_CCM_UNUSED_ADDR);
28
29         /*
30          * By default DCCM is mapped to 0x8z while this area is used by kernel,
31          * so move it to currently unused area.
32          */
33         if (cpuinfo_arc700[cpu].dccm.sz)
34                 write_aux_reg(ARC_REG_AUX_DCCM, ARC_CCM_UNUSED_ADDR);
35 }
36
37 #define ARC_PERIPHERAL_BASE     0xf0000000
38 #define CREG_BASE               (ARC_PERIPHERAL_BASE + 0x1000)
39
40 #define SDIO_BASE               (ARC_PERIPHERAL_BASE + 0xA000)
41 #define SDIO_UHS_REG_EXT        (SDIO_BASE + 0x108)
42 #define SDIO_UHS_REG_EXT_DIV_2  (2 << 30)
43
44 #define HSDK_GPIO_INTC          (ARC_PERIPHERAL_BASE + 0x3000)
45
46 static void __init hsdk_enable_gpio_intc_wire(void)
47 {
48         /*
49          * Peripherals on CPU Card are wired to cpu intc via intermediate
50          * DW APB GPIO blocks (mainly for debouncing)
51          *
52          *         ---------------------
53          *        |  snps,archs-intc  |
54          *        ---------------------
55          *                  |
56          *        ----------------------
57          *        | snps,archs-idu-intc |
58          *        ----------------------
59          *         |   |     |   |    |
60          *         | [eth] [USB]    [... other peripherals]
61          *         |
62          * -------------------
63          * | snps,dw-apb-intc |
64          * -------------------
65          *  |      |   |   |
66          * [Bt] [HAPS]   [... other peripherals]
67          *
68          * Current implementation of "irq-dw-apb-ictl" driver doesn't work well
69          * with stacked INTCs. In particular problem happens if its master INTC
70          * not yet instantiated. See discussion here -
71          * https://lkml.org/lkml/2015/3/4/755
72          *
73          * So setup the first gpio block as a passive pass thru and hide it from
74          * DT hardware topology - connect intc directly to cpu intc
75          * The GPIO "wire" needs to be init nevertheless (here)
76          *
77          * One side adv is that peripheral interrupt handling avoids one nested
78          * intc ISR hop
79          *
80          * According to HSDK User's Manual [1], "Table 2 Interrupt Mapping"
81          * we have the following GPIO input lines used as sources of interrupt:
82          * - GPIO[0] - Bluetooth interrupt of RS9113 module
83          * - GPIO[2] - HAPS interrupt (on HapsTrak 3 connector)
84          * - GPIO[3] - Audio codec (MAX9880A) interrupt
85          * - GPIO[8-23] - Available on Arduino and PMOD_x headers
86          * For now there's no use of Arduino and PMOD_x headers in Linux
87          * use-case so we only enable lines 0, 2 and 3.
88          *
89          * [1] https://github.com/foss-for-synopsys-dwc-arc-processors/ARC-Development-Systems-Forum/wiki/docs/ARC_HSDK_User_Guide.pdf
90          */
91 #define GPIO_INTEN              (HSDK_GPIO_INTC + 0x30)
92 #define GPIO_INTMASK            (HSDK_GPIO_INTC + 0x34)
93 #define GPIO_INTTYPE_LEVEL      (HSDK_GPIO_INTC + 0x38)
94 #define GPIO_INT_POLARITY       (HSDK_GPIO_INTC + 0x3c)
95 #define GPIO_INT_CONNECTED_MASK 0x0d
96
97         iowrite32(0xffffffff, (void __iomem *) GPIO_INTMASK);
98         iowrite32(~GPIO_INT_CONNECTED_MASK, (void __iomem *) GPIO_INTMASK);
99         iowrite32(0x00000000, (void __iomem *) GPIO_INTTYPE_LEVEL);
100         iowrite32(0xffffffff, (void __iomem *) GPIO_INT_POLARITY);
101         iowrite32(GPIO_INT_CONNECTED_MASK, (void __iomem *) GPIO_INTEN);
102 }
103
104 static int __init hsdk_tweak_node_coherency(const char *path, bool coherent)
105 {
106         void *fdt = initial_boot_params;
107         const void *prop;
108         int node, ret;
109         bool dt_coh_set;
110
111         node = fdt_path_offset(fdt, path);
112         if (node < 0)
113                 goto tweak_fail;
114
115         prop = fdt_getprop(fdt, node, "dma-coherent", &ret);
116         if (!prop && ret != -FDT_ERR_NOTFOUND)
117                 goto tweak_fail;
118
119         dt_coh_set = ret != -FDT_ERR_NOTFOUND;
120         ret = 0;
121
122         /* need to remove "dma-coherent" property */
123         if (dt_coh_set && !coherent)
124                 ret = fdt_delprop(fdt, node, "dma-coherent");
125
126         /* need to set "dma-coherent" property */
127         if (!dt_coh_set && coherent)
128                 ret = fdt_setprop(fdt, node, "dma-coherent", NULL, 0);
129
130         if (ret < 0)
131                 goto tweak_fail;
132
133         return 0;
134
135 tweak_fail:
136         pr_err("failed to tweak %s to %scoherent\n", path, coherent ? "" : "non");
137         return -EFAULT;
138 }
139
140 enum hsdk_axi_masters {
141         M_HS_CORE = 0,
142         M_HS_RTT,
143         M_AXI_TUN,
144         M_HDMI_VIDEO,
145         M_HDMI_AUDIO,
146         M_USB_HOST,
147         M_ETHERNET,
148         M_SDIO,
149         M_GPU,
150         M_DMAC_0,
151         M_DMAC_1,
152         M_DVFS
153 };
154
155 #define UPDATE_VAL      1
156
157 /*
158  * This is modified configuration of AXI bridge. Default settings
159  * are specified in "Table 111 CREG Address Decoder register reset values".
160  *
161  * AXI_M_m_SLV{0|1} - Slave Select register for master 'm'.
162  * Possible slaves are:
163  *  - 0  => no slave selected
164  *  - 1  => DDR controller port #1
165  *  - 2  => SRAM controller
166  *  - 3  => AXI tunnel
167  *  - 4  => EBI controller
168  *  - 5  => ROM controller
169  *  - 6  => AXI2APB bridge
170  *  - 7  => DDR controller port #2
171  *  - 8  => DDR controller port #3
172  *  - 9  => HS38x4 IOC
173  *  - 10 => HS38x4 DMI
174  * AXI_M_m_OFFSET{0|1} - Addr Offset register for master 'm'
175  *
176  * Please read ARC HS Development IC Specification, section 17.2 for more
177  * information about apertures configuration.
178  *
179  * m    master          AXI_M_m_SLV0    AXI_M_m_SLV1    AXI_M_m_OFFSET0 AXI_M_m_OFFSET1
180  * 0    HS (CBU)        0x11111111      0x63111111      0xFEDCBA98      0x0E543210
181  * 1    HS (RTT)        0x77777777      0x77777777      0xFEDCBA98      0x76543210
182  * 2    AXI Tunnel      0x88888888      0x88888888      0xFEDCBA98      0x76543210
183  * 3    HDMI-VIDEO      0x77777777      0x77777777      0xFEDCBA98      0x76543210
184  * 4    HDMI-ADUIO      0x77777777      0x77777777      0xFEDCBA98      0x76543210
185  * 5    USB-HOST        0x77777777      0x77999999      0xFEDCBA98      0x76DCBA98
186  * 6    ETHERNET        0x77777777      0x77999999      0xFEDCBA98      0x76DCBA98
187  * 7    SDIO            0x77777777      0x77999999      0xFEDCBA98      0x76DCBA98
188  * 8    GPU             0x77777777      0x77777777      0xFEDCBA98      0x76543210
189  * 9    DMAC (port #1)  0x77777777      0x77777777      0xFEDCBA98      0x76543210
190  * 10   DMAC (port #2)  0x77777777      0x77777777      0xFEDCBA98      0x76543210
191  * 11   DVFS            0x00000000      0x60000000      0x00000000      0x00000000
192  */
193
194 #define CREG_AXI_M_SLV0(m)  ((void __iomem *)(CREG_BASE + 0x20 * (m)))
195 #define CREG_AXI_M_SLV1(m)  ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x04))
196 #define CREG_AXI_M_OFT0(m)  ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x08))
197 #define CREG_AXI_M_OFT1(m)  ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x0C))
198 #define CREG_AXI_M_UPDT(m)  ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x14))
199
200 #define CREG_AXI_M_HS_CORE_BOOT ((void __iomem *)(CREG_BASE + 0x010))
201
202 #define CREG_PAE                ((void __iomem *)(CREG_BASE + 0x180))
203 #define CREG_PAE_UPDT           ((void __iomem *)(CREG_BASE + 0x194))
204
205 static void __init hsdk_init_memory_bridge_axi_dmac(void)
206 {
207         bool coherent = !!arc_hsdk_axi_dmac_coherent;
208         u32 axi_m_slv1, axi_m_oft1;
209
210         /*
211          * Don't tweak memory bridge configuration if we failed to tweak DTB
212          * as we will end up in a inconsistent state.
213          */
214         if (hsdk_tweak_node_coherency("/soc/dmac@80000", coherent))
215                 return;
216
217         if (coherent) {
218                 axi_m_slv1 = 0x77999999;
219                 axi_m_oft1 = 0x76DCBA98;
220         } else {
221                 axi_m_slv1 = 0x77777777;
222                 axi_m_oft1 = 0x76543210;
223         }
224
225         writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_0));
226         writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_0));
227         writel(axi_m_slv1, CREG_AXI_M_SLV1(M_DMAC_0));
228         writel(axi_m_oft1, CREG_AXI_M_OFT1(M_DMAC_0));
229         writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_0));
230
231         writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_1));
232         writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_1));
233         writel(axi_m_slv1, CREG_AXI_M_SLV1(M_DMAC_1));
234         writel(axi_m_oft1, CREG_AXI_M_OFT1(M_DMAC_1));
235         writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_1));
236 }
237
238 static void __init hsdk_init_memory_bridge(void)
239 {
240         u32 reg;
241
242         /*
243          * M_HS_CORE has one unique register - BOOT.
244          * We need to clean boot mirror (BOOT[1:0]) bits in them to avoid first
245          * aperture to be masked by 'boot mirror'.
246          */
247         reg = readl(CREG_AXI_M_HS_CORE_BOOT) & (~0x3);
248         writel(reg, CREG_AXI_M_HS_CORE_BOOT);
249         writel(0x11111111, CREG_AXI_M_SLV0(M_HS_CORE));
250         writel(0x63111111, CREG_AXI_M_SLV1(M_HS_CORE));
251         writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HS_CORE));
252         writel(0x0E543210, CREG_AXI_M_OFT1(M_HS_CORE));
253         writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HS_CORE));
254
255         writel(0x77777777, CREG_AXI_M_SLV0(M_HS_RTT));
256         writel(0x77777777, CREG_AXI_M_SLV1(M_HS_RTT));
257         writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HS_RTT));
258         writel(0x76543210, CREG_AXI_M_OFT1(M_HS_RTT));
259         writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HS_RTT));
260
261         writel(0x88888888, CREG_AXI_M_SLV0(M_AXI_TUN));
262         writel(0x88888888, CREG_AXI_M_SLV1(M_AXI_TUN));
263         writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_AXI_TUN));
264         writel(0x76543210, CREG_AXI_M_OFT1(M_AXI_TUN));
265         writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_AXI_TUN));
266
267         writel(0x77777777, CREG_AXI_M_SLV0(M_HDMI_VIDEO));
268         writel(0x77777777, CREG_AXI_M_SLV1(M_HDMI_VIDEO));
269         writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HDMI_VIDEO));
270         writel(0x76543210, CREG_AXI_M_OFT1(M_HDMI_VIDEO));
271         writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HDMI_VIDEO));
272
273         writel(0x77777777, CREG_AXI_M_SLV0(M_HDMI_AUDIO));
274         writel(0x77777777, CREG_AXI_M_SLV1(M_HDMI_AUDIO));
275         writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HDMI_AUDIO));
276         writel(0x76543210, CREG_AXI_M_OFT1(M_HDMI_AUDIO));
277         writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HDMI_AUDIO));
278
279         writel(0x77777777, CREG_AXI_M_SLV0(M_USB_HOST));
280         writel(0x77999999, CREG_AXI_M_SLV1(M_USB_HOST));
281         writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_USB_HOST));
282         writel(0x76DCBA98, CREG_AXI_M_OFT1(M_USB_HOST));
283         writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_USB_HOST));
284
285         writel(0x77777777, CREG_AXI_M_SLV0(M_ETHERNET));
286         writel(0x77999999, CREG_AXI_M_SLV1(M_ETHERNET));
287         writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_ETHERNET));
288         writel(0x76DCBA98, CREG_AXI_M_OFT1(M_ETHERNET));
289         writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_ETHERNET));
290
291         writel(0x77777777, CREG_AXI_M_SLV0(M_SDIO));
292         writel(0x77999999, CREG_AXI_M_SLV1(M_SDIO));
293         writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_SDIO));
294         writel(0x76DCBA98, CREG_AXI_M_OFT1(M_SDIO));
295         writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_SDIO));
296
297         writel(0x77777777, CREG_AXI_M_SLV0(M_GPU));
298         writel(0x77777777, CREG_AXI_M_SLV1(M_GPU));
299         writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_GPU));
300         writel(0x76543210, CREG_AXI_M_OFT1(M_GPU));
301         writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_GPU));
302
303         writel(0x00000000, CREG_AXI_M_SLV0(M_DVFS));
304         writel(0x60000000, CREG_AXI_M_SLV1(M_DVFS));
305         writel(0x00000000, CREG_AXI_M_OFT0(M_DVFS));
306         writel(0x00000000, CREG_AXI_M_OFT1(M_DVFS));
307         writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DVFS));
308
309         hsdk_init_memory_bridge_axi_dmac();
310
311         /*
312          * PAE remapping for DMA clients does not work due to an RTL bug, so
313          * CREG_PAE register must be programmed to all zeroes, otherwise it
314          * will cause problems with DMA to/from peripherals even if PAE40 is
315          * not used.
316          */
317         writel(0x00000000, CREG_PAE);
318         writel(UPDATE_VAL, CREG_PAE_UPDT);
319 }
320
321 static void __init hsdk_init_early(void)
322 {
323         hsdk_init_memory_bridge();
324
325         /*
326          * Switch SDIO external ciu clock divider from default div-by-8 to
327          * minimum possible div-by-2.
328          */
329         iowrite32(SDIO_UHS_REG_EXT_DIV_2, (void __iomem *) SDIO_UHS_REG_EXT);
330
331         hsdk_enable_gpio_intc_wire();
332 }
333
334 static const char *hsdk_compat[] __initconst = {
335         "snps,hsdk",
336         NULL,
337 };
338
339 MACHINE_START(SIMULATION, "hsdk")
340         .dt_compat      = hsdk_compat,
341         .init_early     = hsdk_init_early,
342         .init_per_cpu   = hsdk_init_per_cpu,
343 MACHINE_END