Merge branch 'master' of git://git.denx.de/u-boot-samsung
[platform/kernel/u-boot.git] / arch / arm / lib / gic_64.S
1 /*
2  * GIC Initialization Routines.
3  *
4  * (C) Copyright 2013
5  * David Feng <fenghua@phytium.com.cn>
6  *
7  * SPDX-License-Identifier:     GPL-2.0+
8  */
9
10 #include <asm-offsets.h>
11 #include <config.h>
12 #include <linux/linkage.h>
13 #include <asm/gic.h>
14 #include <asm/macro.h>
15
16
17 /*************************************************************************
18  *
19  * void gic_init_secure(DistributorBase);
20  *
21  * Initialize secure copy of GIC at EL3.
22  *
23  *************************************************************************/
24 ENTRY(gic_init_secure)
25         /*
26          * Initialize Distributor
27          * x0: Distributor Base
28          */
29 #if defined(CONFIG_GICV3)
30         mov     w9, #0x37               /* EnableGrp0 | EnableGrp1NS */
31                                         /* EnableGrp1S | ARE_S | ARE_NS */
32         str     w9, [x0, GICD_CTLR]     /* Secure GICD_CTLR */
33         ldr     w9, [x0, GICD_TYPER]
34         and     w10, w9, #0x1f          /* ITLinesNumber */
35         cbz     w10, 1f                 /* No SPIs */
36         add     x11, x0, (GICD_IGROUPRn + 4)
37         add     x12, x0, (GICD_IGROUPMODRn + 4)
38         mov     w9, #~0
39 0:      str     w9, [x11], #0x4
40         str     wzr, [x12], #0x4        /* Config SPIs as Group1NS */
41         sub     w10, w10, #0x1
42         cbnz    w10, 0b
43 #elif defined(CONFIG_GICV2)
44         mov     w9, #0x3                /* EnableGrp0 | EnableGrp1 */
45         str     w9, [x0, GICD_CTLR]     /* Secure GICD_CTLR */
46         ldr     w9, [x0, GICD_TYPER]
47         and     w10, w9, #0x1f          /* ITLinesNumber */
48         cbz     w10, 1f                 /* No SPIs */
49         add     x11, x0, GICD_IGROUPRn
50         mov     w9, #~0                 /* Config SPIs as Grp1 */
51         str     w9, [x11], #0x4
52 0:      str     w9, [x11], #0x4
53         sub     w10, w10, #0x1
54         cbnz    w10, 0b
55
56         ldr     x1, =GICC_BASE          /* GICC_CTLR */
57         mov     w0, #3                  /* EnableGrp0 | EnableGrp1 */
58         str     w0, [x1]
59
60         mov     w0, #1 << 7             /* allow NS access to GICC_PMR */
61         str     w0, [x1, #4]            /* GICC_PMR */
62 #endif
63 1:
64         ret
65 ENDPROC(gic_init_secure)
66
67
68 /*************************************************************************
69  * For Gicv2:
70  * void gic_init_secure_percpu(DistributorBase, CpuInterfaceBase);
71  * For Gicv3:
72  * void gic_init_secure_percpu(ReDistributorBase);
73  *
74  * Initialize secure copy of GIC at EL3.
75  *
76  *************************************************************************/
77 ENTRY(gic_init_secure_percpu)
78 #if defined(CONFIG_GICV3)
79         /*
80          * Initialize ReDistributor
81          * x0: ReDistributor Base
82          */
83         mrs     x10, mpidr_el1
84         lsr     x9, x10, #32
85         bfi     x10, x9, #24, #8        /* w10 is aff3:aff2:aff1:aff0 */
86         mov     x9, x0
87 1:      ldr     x11, [x9, GICR_TYPER]
88         lsr     x11, x11, #32           /* w11 is aff3:aff2:aff1:aff0 */
89         cmp     w10, w11
90         b.eq    2f
91         add     x9, x9, #(2 << 16)
92         b       1b
93
94         /* x9: ReDistributor Base Address of Current CPU */
95 2:      mov     w10, #~0x2
96         ldr     w11, [x9, GICR_WAKER]
97         and     w11, w11, w10           /* Clear ProcessorSleep */
98         str     w11, [x9, GICR_WAKER]
99         dsb     st
100         isb
101 3:      ldr     w10, [x9, GICR_WAKER]
102         tbnz    w10, #2, 3b             /* Wait Children be Alive */
103
104         add     x10, x9, #(1 << 16)     /* SGI_Base */
105         mov     w11, #~0
106         str     w11, [x10, GICR_IGROUPRn]
107         str     wzr, [x10, GICR_IGROUPMODRn]    /* SGIs|PPIs Group1NS */
108         mov     w11, #0x1               /* Enable SGI 0 */
109         str     w11, [x10, GICR_ISENABLERn]
110
111         /* Initialize Cpu Interface */
112         mrs     x10, ICC_SRE_EL3
113         orr     x10, x10, #0xf          /* SRE & Disable IRQ/FIQ Bypass & */
114                                         /* Allow EL2 access to ICC_SRE_EL2 */
115         msr     ICC_SRE_EL3, x10
116         isb
117
118         mrs     x10, ICC_SRE_EL2
119         orr     x10, x10, #0xf          /* SRE & Disable IRQ/FIQ Bypass & */
120                                         /* Allow EL1 access to ICC_SRE_EL1 */
121         msr     ICC_SRE_EL2, x10
122         isb
123
124         mov     x10, #0x3               /* EnableGrp1NS | EnableGrp1S */
125         msr     ICC_IGRPEN1_EL3, x10
126         isb
127
128         msr     ICC_CTLR_EL3, xzr
129         isb
130
131         msr     ICC_CTLR_EL1, xzr       /* NonSecure ICC_CTLR_EL1 */
132         isb
133
134         mov     x10, #0x1 << 7          /* Non-Secure access to ICC_PMR_EL1 */
135         msr     ICC_PMR_EL1, x10
136         isb
137 #elif defined(CONFIG_GICV2)
138         /*
139          * Initialize SGIs and PPIs
140          * x0: Distributor Base
141          * x1: Cpu Interface Base
142          */
143         mov     w9, #~0                 /* Config SGIs and PPIs as Grp1 */
144         str     w9, [x0, GICD_IGROUPRn] /* GICD_IGROUPR0 */
145         mov     w9, #0x1                /* Enable SGI 0 */
146         str     w9, [x0, GICD_ISENABLERn]
147
148         /* Initialize Cpu Interface */
149         mov     w9, #0x1e7              /* Disable IRQ/FIQ Bypass & */
150                                         /* Enable Ack Group1 Interrupt & */
151                                         /* EnableGrp0 & EnableGrp1 */
152         str     w9, [x1, GICC_CTLR]     /* Secure GICC_CTLR */
153
154         mov     w9, #0x1 << 7           /* Non-Secure access to GICC_PMR */
155         str     w9, [x1, GICC_PMR]
156 #endif
157         ret
158 ENDPROC(gic_init_secure_percpu)
159
160
161 /*************************************************************************
162  * For Gicv2:
163  * void gic_kick_secondary_cpus(DistributorBase);
164  * For Gicv3:
165  * void gic_kick_secondary_cpus(void);
166  *
167  *************************************************************************/
168 ENTRY(gic_kick_secondary_cpus)
169 #if defined(CONFIG_GICV3)
170         mov     x9, #(1 << 40)
171         msr     ICC_ASGI1R_EL1, x9
172         isb
173 #elif defined(CONFIG_GICV2)
174         mov     w9, #0x8000
175         movk    w9, #0x100, lsl #16
176         str     w9, [x0, GICD_SGIR]
177 #endif
178         ret
179 ENDPROC(gic_kick_secondary_cpus)
180
181
182 /*************************************************************************
183  * For Gicv2:
184  * void gic_wait_for_interrupt(CpuInterfaceBase);
185  * For Gicv3:
186  * void gic_wait_for_interrupt(void);
187  *
188  * Wait for SGI 0 from master.
189  *
190  *************************************************************************/
191 ENTRY(gic_wait_for_interrupt)
192 #if defined(CONFIG_GICV3)
193         gic_wait_for_interrupt_m x9
194 #elif defined(CONFIG_GICV2)
195         gic_wait_for_interrupt_m x0, w9
196 #endif
197         ret
198 ENDPROC(gic_wait_for_interrupt)