blob: 7549e3a92ae4f36743716869cbeb0fee83742135 [file] [log] [blame]
Channagoud Kadabi130899b2015-12-03 14:28:07 -08001/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
Channagoud Kadabie240b702014-06-19 12:14:44 -07002 *
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
Channagoud Kadabie240b702014-06-19 12:14:44 -070080 /* Wait until redistributor is up */
81 while(readl(GICR_WAKER_CPU0) & GIC_WAKER_CHILDRENASLEEP)
82 {
83 retry--;
84 if (!retry)
85 {
86 dprintf(CRITICAL, "Failed to wake redistributor for CPU0\n");
87 ASSERT(0);
88 }
89 mdelay(1);
90 }
91
92
93 /* Make sure the system register access is enabled for us */
94 __asm__ volatile("mrc p15, 0, %0, c12, c12, 5" : "=r" (sre));
95 sre |= BIT(0);
96 __asm__ volatile("mcr p15, 0, %0, c12, c12, 5" :: "r" (sre));
97
98 isb();
99
100 /* If system register access is not set, we fail */
101 __asm__ volatile("mrc p15, 0, %0, c12, c12, 5" : "=r" (sre));
102 if (!(sre & BIT(0)))
103 {
104 dprintf(CRITICAL, "Failed to set SRE for NS world\n");
105 ASSERT(0);
106 }
107
108 /* Set the priortiy mask register, interrupts with priority
109 * higher than this value will be signalled to processor.
110 * Lower value means higher priority.
111 */
112 __asm__ volatile("mcr p15, 0, %0, c4, c6, 0" :: "r" (pmr));
113 isb();
114
115 /* Make sure EOI is handled in NS EL3 */
116 __asm__ volatile("mrc p15, 0, %0, c12, c12, 4" : "=r" (eoimode));
117 eoimode &= ~BIT(1);
118 __asm__ volatile("mcr p15, 0, %0, c12, c12, 4" :: "r" (eoimode));
119 isb();
120
121 /* Enable grp1 interrupts for NS EL3*/
122 __asm__ volatile("mcr p15, 0, %0, c12, c12, 7" :: "r" (grpen1));
123 isb();
124}
125
126uint32_t qgic_read_iar()
127{
128 uint32_t iar;
129
130 /* Read the interrupt ack register, for the current interrupt number */
131 __asm__ volatile("mrc p15, 0, %0, c12, c12, 0" : "=r" (iar));
132 isb();
133
134 return iar;
135}
136
137void qgic_write_eoi(uint32_t iar)
138{
139 /* Write end of interrupt to indicate CPU that this interrupt is processed*/
140 __asm__ volatile("mcr p15, 0, %0, c12, c12, 1" :: "r" (iar));
141 isb();
142}