]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/gic.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_RENESAS / TARGET_RZ_A1H / gic.c
1 /**************************************************************************//**
2  * @file     gic.c
3  * @brief    Implementation of GIC functions declared in CMSIS Cortex-A9 Core Peripheral Access Layer Header File
4  * @version
5  * @date     19 Sept 2013
6  *
7  * @note
8  *
9  ******************************************************************************/
10 /* Copyright (c) 2011 - 2013 ARM LIMITED
11
12    All rights reserved.
13    Redistribution and use in source and binary forms, with or without
14    modification, are permitted provided that the following conditions are met:
15    - Redistributions of source code must retain the above copyright
16      notice, this list of conditions and the following disclaimer.
17    - Redistributions in binary form must reproduce the above copyright
18      notice, this list of conditions and the following disclaimer in the
19      documentation and/or other materials provided with the distribution.
20    - Neither the name of ARM nor the names of its contributors may be used
21      to endorse or promote products derived from this software without
22      specific prior written permission.
23    *
24    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27    ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34    POSSIBILITY OF SUCH DAMAGE.
35    ---------------------------------------------------------------------------*/
36
37 #include "MBRZA1H.h"
38
39 #define GICDistributor      ((GICDistributor_Type      *)     Renesas_RZ_A1_GIC_DISTRIBUTOR_BASE ) /*!< GIC Distributor configuration struct */
40 #define GICInterface        ((GICInterface_Type        *)     Renesas_RZ_A1_GIC_INTERFACE_BASE )   /*!< GIC Interface configuration struct */
41
42 /* Globals for use of post-scatterloading code that must access GIC */
43 const uint32_t GICDistributor_BASE = Renesas_RZ_A1_GIC_DISTRIBUTOR_BASE;
44 const uint32_t GICInterface_BASE = Renesas_RZ_A1_GIC_INTERFACE_BASE;
45
46 void GIC_EnableDistributor(void)
47 {
48     GICDistributor->ICDDCR |= 1; //enable distributor
49 }
50
51 void GIC_DisableDistributor(void)
52 {
53     GICDistributor->ICDDCR &=~1; //disable distributor
54 }
55
56 uint32_t GIC_DistributorInfo(void)
57 {
58     return (uint32_t)(GICDistributor->ICDICTR);
59 }
60
61 uint32_t GIC_DistributorImplementer(void)
62 {
63     return (uint32_t)(GICDistributor->ICDIIDR);
64 }
65
66 void GIC_SetTarget(IRQn_Type IRQn, uint32_t cpu_target)
67 {
68     volatile uint8_t* field = (volatile uint8_t*)&(GICDistributor->ICDIPTR[IRQn / 4]);
69     field += IRQn % 4;
70     *field = (uint8_t)cpu_target & 0xf;
71 }
72
73 void GIC_SetICDICFR (const uint32_t *ICDICFRn)
74 {
75     uint32_t i, num_irq;
76
77     //Get the maximum number of interrupts that the GIC supports
78     num_irq = 32 * ((GIC_DistributorInfo() & 0x1f) + 1);
79
80     for (i = 0; i < (num_irq/16); i++)
81     {
82         GICDistributor->ICDISPR[i] = *ICDICFRn++;
83     }
84 }
85
86 uint32_t GIC_GetTarget(IRQn_Type IRQn)
87 {
88     volatile uint8_t* field = (volatile uint8_t*)&(GICDistributor->ICDIPTR[IRQn / 4]);
89     field += IRQn % 4;
90     return ((uint32_t)*field & 0xf);
91 }
92
93 void GIC_EnableInterface(void)
94 {
95     GICInterface->ICCICR |= 1; //enable interface
96 }
97
98 void GIC_DisableInterface(void)
99 {
100     GICInterface->ICCICR &=~1; //disable distributor
101 }
102
103 IRQn_Type GIC_AcknowledgePending(void)
104 {
105     return (IRQn_Type)(GICInterface->ICCIAR);
106 }
107
108 void GIC_EndInterrupt(IRQn_Type IRQn)
109 {
110     GICInterface->ICCEOIR = IRQn;
111 }
112
113 void GIC_EnableIRQ(IRQn_Type IRQn)
114 {
115     GICDistributor->ICDISER[IRQn / 32] = 1 << (IRQn % 32);
116 }
117
118 void GIC_DisableIRQ(IRQn_Type IRQn)
119 {
120     GICDistributor->ICDICER[IRQn / 32] = 1 << (IRQn % 32);
121 }
122
123 void GIC_SetPendingIRQ(IRQn_Type IRQn)
124 {
125     GICDistributor->ICDISPR[IRQn / 32] = 1 << (IRQn % 32);
126 }
127
128 void GIC_ClearPendingIRQ(IRQn_Type IRQn)
129 {
130     GICDistributor->ICDICPR[IRQn / 32] = 1 << (IRQn % 32);
131 }
132
133 void GIC_SetLevelModel(IRQn_Type IRQn, int8_t edge_level, int8_t model)
134 {
135     volatile uint8_t* field = (volatile uint8_t*)&(GICDistributor->ICDICFR[IRQn / 16]);
136     int  bit_shift = (IRQn % 16)<<1;
137     uint8_t save_byte;
138
139     field += (bit_shift / 8);
140     bit_shift %= 8;
141
142     save_byte = *field;
143     save_byte &= ((uint8_t)~(3u << bit_shift));
144
145     *field = save_byte | ((uint8_t)((edge_level<<1) | model)<< bit_shift);
146 }
147
148 void GIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
149 {
150     volatile uint8_t* field = (volatile uint8_t*)&(GICDistributor->ICDIPR[IRQn / 4]);
151     field += (IRQn % 4);
152     *field = (uint8_t)priority;
153 }
154
155 uint32_t GIC_GetPriority(IRQn_Type IRQn)
156 {
157     volatile uint8_t* field = (volatile uint8_t*)&(GICDistributor->ICDIPR[IRQn / 4]);
158     field += (IRQn % 4);
159     return (uint32_t)*field;
160 }
161
162 void GIC_InterfacePriorityMask(uint32_t priority)
163 {
164     GICInterface->ICCPMR = priority & 0xff; //set priority mask
165 }
166
167 void GIC_SetBinaryPoint(uint32_t binary_point)
168 {
169     GICInterface->ICCBPR = binary_point & 0x07; //set binary point
170 }
171
172 uint32_t GIC_GetBinaryPoint(uint32_t binary_point)
173 {
174     return (uint32_t)GICInterface->ICCBPR;
175 }
176
177 uint32_t GIC_GetIRQStatus(IRQn_Type IRQn)
178 {
179     uint32_t pending, active;
180
181     active = ((GICDistributor->ICDABR[IRQn / 32])  >> (IRQn % 32)) & 0x1;
182     pending =((GICDistributor->ICDISPR[IRQn / 32]) >> (IRQn % 32)) & 0x1;
183
184     return ((active<<1) | pending);
185 }
186
187 void GIC_SendSGI(IRQn_Type IRQn, uint32_t target_list, uint32_t filter_list)
188 {
189     GICDistributor->ICDSGIR = ((filter_list & 0x3) << 24) | ((target_list & 0xff) << 16) | (IRQn & 0xf);
190 }
191
192 void GIC_DistInit(void)
193 {
194     //IRQn_Type i;
195     uint32_t i;
196     uint32_t num_irq = 0;
197     uint32_t priority_field;
198
199     //A reset sets all bits in the ICDISRs corresponding to the SPIs to 0,
200     //configuring all of the interrupts as Secure.
201
202     //Disable interrupt forwarding
203     GIC_DisableDistributor();
204     //Get the maximum number of interrupts that the GIC supports
205     num_irq = 32 * ((GIC_DistributorInfo() & 0x1f) + 1);
206
207     /* Priority level is implementation defined.
208      To determine the number of priority bits implemented write 0xFF to an ICDIPR
209      priority field and read back the value stored.*/
210     GIC_SetPriority((IRQn_Type)0, 0xff);
211     priority_field = GIC_GetPriority((IRQn_Type)0);
212
213     for (i = 32; i < num_irq; i++)
214     {
215         //Disable all SPI the interrupts
216         GIC_DisableIRQ((IRQn_Type)i);
217         //Set level-sensitive and N-N model
218         //GIC_SetLevelModel(i, 0, 0);
219         //Set priority
220         GIC_SetPriority((IRQn_Type)i, priority_field/2);
221         //Set target list to "all cpus"
222         GIC_SetTarget((IRQn_Type)i, 0xff);
223     }
224     /* Set level-edge and 1-N model */
225     /* GICDistributor->ICDICFR[ 0] is read only */
226     GICDistributor->ICDICFR[ 1] = 0x00000055;
227     GICDistributor->ICDICFR[ 2] = 0xFFFD5555;
228     GICDistributor->ICDICFR[ 3] = 0x555FFFFF;
229     GICDistributor->ICDICFR[ 4] = 0x55555555;
230     GICDistributor->ICDICFR[ 5] = 0x55555555;
231     GICDistributor->ICDICFR[ 6] = 0x55555555;
232     GICDistributor->ICDICFR[ 7] = 0x55555555;
233     GICDistributor->ICDICFR[ 8] = 0x5555F555;
234     GICDistributor->ICDICFR[ 9] = 0x55555555;
235     GICDistributor->ICDICFR[10] = 0x55555555;
236     GICDistributor->ICDICFR[11] = 0xF5555555;
237     GICDistributor->ICDICFR[12] = 0xF555F555;
238     GICDistributor->ICDICFR[13] = 0x5555F555;
239     GICDistributor->ICDICFR[14] = 0x55555555;
240     GICDistributor->ICDICFR[15] = 0x55555555;
241     GICDistributor->ICDICFR[16] = 0x55555555;
242     GICDistributor->ICDICFR[17] = 0xFD555555;
243     GICDistributor->ICDICFR[18] = 0x55555557;
244     GICDistributor->ICDICFR[19] = 0x55555555;
245     GICDistributor->ICDICFR[20] = 0xFFD55555;
246     GICDistributor->ICDICFR[21] = 0x5F55557F;
247     GICDistributor->ICDICFR[22] = 0xFD55555F;
248     GICDistributor->ICDICFR[23] = 0x55555557;
249     GICDistributor->ICDICFR[24] = 0x55555555;
250     GICDistributor->ICDICFR[25] = 0x55555555;
251     GICDistributor->ICDICFR[26] = 0x55555555;
252     GICDistributor->ICDICFR[27] = 0x55555555;
253     GICDistributor->ICDICFR[28] = 0x55555555;
254     GICDistributor->ICDICFR[29] = 0x55555555;
255     GICDistributor->ICDICFR[30] = 0x55555555;
256     GICDistributor->ICDICFR[31] = 0x55555555;
257     GICDistributor->ICDICFR[32] = 0x55555555;
258     GICDistributor->ICDICFR[33] = 0x55555555;
259
260     //Enable distributor
261     GIC_EnableDistributor();
262 }
263
264 void GIC_CPUInterfaceInit(void)
265 {
266     IRQn_Type i;
267     uint32_t priority_field;
268
269     //A reset sets all bits in the ICDISRs corresponding to the SPIs to 0,
270     //configuring all of the interrupts as Secure.
271
272     //Disable interrupt forwarding
273     GIC_DisableInterface();
274
275     /* Priority level is implementation defined.
276      To determine the number of priority bits implemented write 0xFF to an ICDIPR
277      priority field and read back the value stored.*/
278     GIC_SetPriority((IRQn_Type)0, 0xff);
279     priority_field = GIC_GetPriority((IRQn_Type)0);
280
281     //SGI and PPI
282     for (i = (IRQn_Type)0; i < 32; i++)
283     {
284         //Set level-sensitive and N-N model for PPI
285         //if(i > 15)
286             //GIC_SetLevelModel(i, 0, 0);
287         //Disable SGI and PPI interrupts
288         GIC_DisableIRQ(i);
289         //Set priority
290         GIC_SetPriority(i, priority_field/2);
291     }
292     //Enable interface
293     GIC_EnableInterface();
294     //Set binary point to 0
295     GIC_SetBinaryPoint(0);
296     //Set priority mask
297     GIC_InterfacePriorityMask(0xff);
298 }
299
300 void GIC_Enable(void)
301 {
302     GIC_DistInit();
303     GIC_CPUInterfaceInit(); //per CPU
304 }
305