blob: 692801be53105a2a3bcb38682345e48ac830695b [file] [log] [blame]
Channagoud Kadabie240b702014-06-19 12:14:44 -07001/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Fundation, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#include <reg.h>
31#include <bits.h>
32#include <debug.h>
33#include <arch/arm.h>
34#include <arch/defines.h>
Channagoud Kadabic4b752c2014-12-22 12:06:27 -080035#include <qtimer.h>
Channagoud Kadabie240b702014-06-19 12:14:44 -070036#include <qgic_v3.h>
37
38#define GIC_WAKER_PROCESSORSLEEP BIT(1)
39#define GIC_WAKER_CHILDRENASLEEP BIT(2)
40
41void qgic_dist_init()
42{
43 uint32_t num_irq;
44 uint32_t affinity;
45 uint32_t i;
46
47 /* Read the mpidr register to find out the boot up cluster */
48 __asm__ volatile("mrc p15, 0, %0, c0, c0, 5" : "=r" (affinity));
49
50 /* For aarch32 mode we have only 3 affinity values: aff0:aff1:aff2*/
51 affinity = affinity & 0x00ffffff;
52
53 writel(0, GIC_DIST_CTRL);
54
55 /*
56 * Find out how many interrupts are supported.
57 */
58 num_irq = readl(GIC_DIST_CTR) & 0x1f;
59 num_irq = (num_irq + 1) * 32;
60
61 /* Do the qgic dist initialization */
62 qgic_dist_config(num_irq);
63
64 /* Write the affinity value, for routing all the SPIs */
65 for (i = 32; i < num_irq; i++)
66 writel(affinity, GICD_IROUTER + i * 8);
67
68 /* Enable affinity routing of grp0/grp1 interrupts */
69 writel(ENABLE_GRP0_SEC | ENABLE_GRP1_NS | ENABLE_ARE, GIC_DIST_CTRL);
70}
71
72void qgic_cpu_init()
73{
Channagoud Kadabie240b702014-06-19 12:14:44 -070074 uint32_t retry = 1000;
75 uint32_t sre = 0;
76 uint32_t pmr = 0xff;
77 uint32_t eoimode = 0;
78 uint32_t grpen1 = 0x1;
79
80 /* For cpu init need to wake up the redistributor */
81 writel((readl(GICR_WAKER_CPU0) & ~GIC_WAKER_PROCESSORSLEEP), GICR_WAKER_CPU0);
82
83 /* Wait until redistributor is up */
84 while(readl(GICR_WAKER_CPU0) & GIC_WAKER_CHILDRENASLEEP)
85 {
86 retry--;
87 if (!retry)
88 {
89 dprintf(CRITICAL, "Failed to wake redistributor for CPU0\n");
90 ASSERT(0);
91 }
92 mdelay(1);
93 }
94
95
96 /* Make sure the system register access is enabled for us */
97 __asm__ volatile("mrc p15, 0, %0, c12, c12, 5" : "=r" (sre));
98 sre |= BIT(0);
99 __asm__ volatile("mcr p15, 0, %0, c12, c12, 5" :: "r" (sre));
100
101 isb();
102
103 /* If system register access is not set, we fail */
104 __asm__ volatile("mrc p15, 0, %0, c12, c12, 5" : "=r" (sre));
105 if (!(sre & BIT(0)))
106 {
107 dprintf(CRITICAL, "Failed to set SRE for NS world\n");
108 ASSERT(0);
109 }
110
111 /* Set the priortiy mask register, interrupts with priority
112 * higher than this value will be signalled to processor.
113 * Lower value means higher priority.
114 */
115 __asm__ volatile("mcr p15, 0, %0, c4, c6, 0" :: "r" (pmr));
116 isb();
117
118 /* Make sure EOI is handled in NS EL3 */
119 __asm__ volatile("mrc p15, 0, %0, c12, c12, 4" : "=r" (eoimode));
120 eoimode &= ~BIT(1);
121 __asm__ volatile("mcr p15, 0, %0, c12, c12, 4" :: "r" (eoimode));
122 isb();
123
124 /* Enable grp1 interrupts for NS EL3*/
125 __asm__ volatile("mcr p15, 0, %0, c12, c12, 7" :: "r" (grpen1));
126 isb();
127}
128
129uint32_t qgic_read_iar()
130{
131 uint32_t iar;
132
133 /* Read the interrupt ack register, for the current interrupt number */
134 __asm__ volatile("mrc p15, 0, %0, c12, c12, 0" : "=r" (iar));
135 isb();
136
137 return iar;
138}
139
140void qgic_write_eoi(uint32_t iar)
141{
142 /* Write end of interrupt to indicate CPU that this interrupt is processed*/
143 __asm__ volatile("mcr p15, 0, %0, c12, c12, 1" :: "r" (iar));
144 isb();
145}