blob: 9002b7ee1df410bc1cf9c820a2144c23969c71ed [file] [log] [blame]
gtk_pangaob6cec332019-12-19 15:58:20 +08001/*
2 * Copyright (c) 2020, MediaTek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <common/debug.h>
9#include <drivers/arm/gic_common.h>
gtk_pangaob6cec332019-12-19 15:58:20 +080010#include <lib/mmio.h>
11
12#include <mt_gic_v3.h>
gtk_pangaob6cec332019-12-19 15:58:20 +080013#include <plat_mt_cirq.h>
14#include <platform_def.h>
15
16static struct cirq_events cirq_all_events = {
G.Pangao49fd68a2020-11-06 09:20:25 +080017 .spi_start = CIRQ_SPI_START,
gtk_pangaob6cec332019-12-19 15:58:20 +080018};
G.Pangao49fd68a2020-11-06 09:20:25 +080019static uint32_t already_cloned;
20/*
21 * mt_irq_mask_restore: restore all interrupts
22 * @mask: pointer to struct mtk_irq_mask for storing the original mask value.
23 * Return 0 for success; return negative values for failure.
24 * (This is ONLY used for the idle current measurement by the factory mode.)
25 */
26int mt_irq_mask_restore(struct mtk_irq_mask *mask)
gtk_pangaob6cec332019-12-19 15:58:20 +080027{
G.Pangao49fd68a2020-11-06 09:20:25 +080028 if (mask == NULL) {
29 return -1;
30 }
31 if (mask->header != IRQ_MASK_HEADER) {
32 return -1;
33 }
34 if (mask->footer != IRQ_MASK_FOOTER) {
35 return -1;
36 }
gtk_pangaob6cec332019-12-19 15:58:20 +080037
G.Pangao49fd68a2020-11-06 09:20:25 +080038 mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x4),
39 mask->mask1);
40 mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x8),
41 mask->mask2);
42 mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0xc),
43 mask->mask3);
44 mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x10),
45 mask->mask4);
46 mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x14),
47 mask->mask5);
48 mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x18),
49 mask->mask6);
50 mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x1c),
51 mask->mask7);
52 mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x20),
53 mask->mask8);
54 mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x24),
55 mask->mask9);
56 mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x28),
57 mask->mask10);
58 mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x2c),
59 mask->mask11);
60 mmio_write_32((BASE_GICD_BASE + GICD_ISENABLER + 0x30),
61 mask->mask12);
62 /* make sure dist changes happen */
63 dsb();
64
65 return 0;
gtk_pangaob6cec332019-12-19 15:58:20 +080066}
67
68/*
G.Pangao49fd68a2020-11-06 09:20:25 +080069 * mt_irq_mask_all: disable all interrupts
70 * @mask: pointer to struct mtk_irq_mask for storing the original mask value.
71 * Return 0 for success; return negative values for failure.
72 * (This is ONLY used for the idle current measurement by the factory mode.)
gtk_pangaob6cec332019-12-19 15:58:20 +080073 */
G.Pangao49fd68a2020-11-06 09:20:25 +080074int mt_irq_mask_all(struct mtk_irq_mask *mask)
75{
76 if (mask != NULL) {
77 /* for SPI */
78 mask->mask1 = mmio_read_32((BASE_GICD_BASE +
79 GICD_ISENABLER + 0x4));
80 mask->mask2 = mmio_read_32((BASE_GICD_BASE +
81 GICD_ISENABLER + 0x8));
82 mask->mask3 = mmio_read_32((BASE_GICD_BASE +
83 GICD_ISENABLER + 0xc));
84 mask->mask4 = mmio_read_32((BASE_GICD_BASE +
85 GICD_ISENABLER + 0x10));
86 mask->mask5 = mmio_read_32((BASE_GICD_BASE +
87 GICD_ISENABLER + 0x14));
88 mask->mask6 = mmio_read_32((BASE_GICD_BASE +
89 GICD_ISENABLER + 0x18));
90 mask->mask7 = mmio_read_32((BASE_GICD_BASE +
91 GICD_ISENABLER + 0x1c));
92 mask->mask8 = mmio_read_32((BASE_GICD_BASE +
93 GICD_ISENABLER + 0x20));
94 mask->mask9 = mmio_read_32((BASE_GICD_BASE +
95 GICD_ISENABLER + 0x24));
96 mask->mask10 = mmio_read_32((BASE_GICD_BASE +
97 GICD_ISENABLER + 0x28));
98 mask->mask11 = mmio_read_32((BASE_GICD_BASE +
99 GICD_ISENABLER + 0x2c));
100 mask->mask12 = mmio_read_32((BASE_GICD_BASE +
101 GICD_ISENABLER + 0x30));
gtk_pangaob6cec332019-12-19 15:58:20 +0800102
G.Pangao49fd68a2020-11-06 09:20:25 +0800103 /* for SPI */
104 mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x4),
105 0xFFFFFFFF);
106 mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x8),
107 0xFFFFFFFF);
108 mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0xC),
109 0xFFFFFFFF);
110 mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x10),
111 0xFFFFFFFF);
112 mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x14),
113 0xFFFFFFFF);
114 mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x18),
115 0xFFFFFFFF);
116 mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x1C),
117 0xFFFFFFFF);
118 mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x20),
119 0xFFFFFFFF);
120 mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x24),
121 0xFFFFFFFF);
122 mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x28),
123 0xFFFFFFFF);
124 mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x2c),
125 0xFFFFFFFF);
126 mmio_write_32((BASE_GICD_BASE + GICD_ICENABLER + 0x30),
127 0xFFFFFFFF);
128 /* make sure distributor changes happen */
129 dsb();
gtk_pangaob6cec332019-12-19 15:58:20 +0800130
G.Pangao49fd68a2020-11-06 09:20:25 +0800131 mask->header = IRQ_MASK_HEADER;
132 mask->footer = IRQ_MASK_FOOTER;
gtk_pangaob6cec332019-12-19 15:58:20 +0800133
G.Pangao49fd68a2020-11-06 09:20:25 +0800134 return 0;
135 } else {
136 return -1;
137 }
138}
139
140static uint32_t mt_irq_get_pol(uint32_t irq)
141{
142#ifdef CIRQ_WITH_POLARITY
143 uint32_t reg;
144 uint32_t base = INT_POL_CTL0;
145
146 if (irq < 32U) {
147 return 0;
148 }
149
150 reg = ((irq - 32U) / 32U);
151
152 return mmio_read_32(base + reg * 4U);
153#else
154 return 0;
155#endif
156}
157
158unsigned int mt_irq_get_sens(unsigned int irq)
159{
160 unsigned int config;
161
162 /*
163 * 2'b10 edge
164 * 2'b01 level
165 */
166 config = mmio_read_32(MT_GIC_BASE + GICD_ICFGR + (irq / 16U) * 4U);
167 config = (config >> (irq % 16U) * 2U) & 0x3;
168
169 return config;
170}
171
172static void collect_all_wakeup_events(void)
gtk_pangaob6cec332019-12-19 15:58:20 +0800173{
174 unsigned int i;
G.Pangao49fd68a2020-11-06 09:20:25 +0800175 uint32_t gic_irq;
176 uint32_t cirq;
177 uint32_t cirq_reg;
178 uint32_t cirq_offset;
179 uint32_t mask;
180 uint32_t pol_mask;
181 uint32_t irq_offset;
182 uint32_t irq_mask;
gtk_pangaob6cec332019-12-19 15:58:20 +0800183
G.Pangao49fd68a2020-11-06 09:20:25 +0800184 if ((cirq_all_events.wakeup_events == NULL) ||
185 cirq_all_events.num_of_events == 0U) {
186 return;
gtk_pangaob6cec332019-12-19 15:58:20 +0800187 }
G.Pangao49fd68a2020-11-06 09:20:25 +0800188
189 for (i = 0U; i < cirq_all_events.num_of_events; i++) {
190 if (cirq_all_events.wakeup_events[i] > 0U) {
191 gic_irq = cirq_all_events.wakeup_events[i];
192 cirq = gic_irq - cirq_all_events.spi_start - 32U;
193 cirq_reg = cirq / 32U;
194 cirq_offset = cirq % 32U;
195 mask = 0x1 << cirq_offset;
196 irq_offset = gic_irq % 32U;
197 irq_mask = 0x1 << irq_offset;
198 /*
199 * CIRQ default masks all
200 */
201 cirq_all_events.table[cirq_reg].mask |= mask;
202 /*
203 * CIRQ default pol is low
204 */
205 pol_mask = mt_irq_get_pol(
206 cirq_all_events.wakeup_events[i])
207 & irq_mask;
208 /*
209 * 0 means rising
210 */
211 if (pol_mask == 0U) {
212 cirq_all_events.table[cirq_reg].pol |= mask;
213 }
214 /*
215 * CIRQ could monitor edge/level trigger
216 * cirq register (0: edge, 1: level)
217 */
218 if (mt_irq_get_sens(cirq_all_events.wakeup_events[i])
219 == SENS_EDGE) {
220 cirq_all_events.table[cirq_reg].sen |= mask;
221 }
222
223 cirq_all_events.table[cirq_reg].used = 1U;
224 cirq_all_events.table[cirq_reg].reg_num = cirq_reg;
225 }
226 }
gtk_pangaob6cec332019-12-19 15:58:20 +0800227}
228
229/*
G.Pangao49fd68a2020-11-06 09:20:25 +0800230 * mt_cirq_set_pol: Set the polarity for the specified SYS_CIRQ number.
231 * @cirq_num: the SYS_CIRQ number to set
232 * @pol: polarity to set
gtk_pangaob6cec332019-12-19 15:58:20 +0800233 * @return:
G.Pangao49fd68a2020-11-06 09:20:25 +0800234 * 0: set pol success
235 * -1: cirq num is out of range
gtk_pangaob6cec332019-12-19 15:58:20 +0800236 */
G.Pangao49fd68a2020-11-06 09:20:25 +0800237#ifdef CIRQ_WITH_POLARITY
238static int mt_cirq_set_pol(uint32_t cirq_num, uint32_t pol)
gtk_pangaob6cec332019-12-19 15:58:20 +0800239{
G.Pangao49fd68a2020-11-06 09:20:25 +0800240 uint32_t base;
241 uint32_t bit = 1U << (cirq_num % 32U);
gtk_pangaob6cec332019-12-19 15:58:20 +0800242
243 if (cirq_num >= CIRQ_IRQ_NUM) {
G.Pangao49fd68a2020-11-06 09:20:25 +0800244 return -1;
gtk_pangaob6cec332019-12-19 15:58:20 +0800245 }
246
G.Pangao49fd68a2020-11-06 09:20:25 +0800247 if (pol == MT_CIRQ_POL_NEG) {
248 base = (cirq_num / 32U) * 4U + CIRQ_POL_CLR_BASE;
249 } else if (pol == MT_CIRQ_POL_POS) {
250 base = (cirq_num / 32U) * 4U + CIRQ_POL_SET_BASE;
251 } else {
252 return -1;
gtk_pangaob6cec332019-12-19 15:58:20 +0800253 }
gtk_pangaob6cec332019-12-19 15:58:20 +0800254
G.Pangao49fd68a2020-11-06 09:20:25 +0800255 mmio_write_32(base, bit);
256 return 0;
gtk_pangaob6cec332019-12-19 15:58:20 +0800257}
G.Pangao49fd68a2020-11-06 09:20:25 +0800258#endif
gtk_pangaob6cec332019-12-19 15:58:20 +0800259
260/*
261 * mt_cirq_mask: Mask the specified SYS_CIRQ.
262 * @cirq_num: the SYS_CIRQ number to mask
263 * @return:
264 * 0: mask success
265 * -1: cirq num is out of range
266 */
267static int mt_cirq_mask(uint32_t cirq_num)
268{
269 uint32_t bit = 1U << (cirq_num % 32U);
270
271 if (cirq_num >= CIRQ_IRQ_NUM) {
gtk_pangaob6cec332019-12-19 15:58:20 +0800272 return -1;
273 }
274
G.Pangao49fd68a2020-11-06 09:20:25 +0800275 mmio_write_32((cirq_num / 32U) * 4U + CIRQ_MASK_SET_BASE, bit);
276
gtk_pangaob6cec332019-12-19 15:58:20 +0800277 return 0;
278}
279
280/*
281 * mt_cirq_unmask: Unmask the specified SYS_CIRQ.
282 * @cirq_num: the SYS_CIRQ number to unmask
283 * @return:
284 * 0: umask success
285 * -1: cirq num is out of range
286 */
287static int mt_cirq_unmask(uint32_t cirq_num)
288{
289 uint32_t bit = 1U << (cirq_num % 32U);
290
291 if (cirq_num >= CIRQ_IRQ_NUM) {
gtk_pangaob6cec332019-12-19 15:58:20 +0800292 return -1;
293 }
294
G.Pangao49fd68a2020-11-06 09:20:25 +0800295 mmio_write_32((cirq_num / 32U) * 4U + CIRQ_MASK_CLR_BASE, bit);
296
gtk_pangaob6cec332019-12-19 15:58:20 +0800297 return 0;
298}
299
G.Pangao49fd68a2020-11-06 09:20:25 +0800300uint32_t mt_irq_get_en(uint32_t irq)
gtk_pangaob6cec332019-12-19 15:58:20 +0800301{
G.Pangao49fd68a2020-11-06 09:20:25 +0800302 uint32_t addr, st, val;
gtk_pangaob6cec332019-12-19 15:58:20 +0800303
G.Pangao49fd68a2020-11-06 09:20:25 +0800304 addr = BASE_GICD_BASE + GICD_ISENABLER + (irq / 32U) * 4U;
305 st = mmio_read_32(addr);
gtk_pangaob6cec332019-12-19 15:58:20 +0800306
G.Pangao49fd68a2020-11-06 09:20:25 +0800307 val = (st >> (irq % 32U)) & 1U;
gtk_pangaob6cec332019-12-19 15:58:20 +0800308
gtk_pangaob6cec332019-12-19 15:58:20 +0800309 return val;
310}
311
G.Pangao49fd68a2020-11-06 09:20:25 +0800312static void __cirq_fast_clone(void)
gtk_pangaob6cec332019-12-19 15:58:20 +0800313{
G.Pangao49fd68a2020-11-06 09:20:25 +0800314 struct cirq_reg *reg;
315 unsigned int i;
gtk_pangaob6cec332019-12-19 15:58:20 +0800316
G.Pangao49fd68a2020-11-06 09:20:25 +0800317 for (i = 0U; i < CIRQ_REG_NUM ; ++i) {
318 uint32_t cirq_bit;
gtk_pangaob6cec332019-12-19 15:58:20 +0800319
G.Pangao49fd68a2020-11-06 09:20:25 +0800320 reg = &cirq_all_events.table[i];
gtk_pangaob6cec332019-12-19 15:58:20 +0800321
G.Pangao49fd68a2020-11-06 09:20:25 +0800322 if (reg->used == 0U) {
323 continue;
gtk_pangaob6cec332019-12-19 15:58:20 +0800324 }
325
G.Pangao49fd68a2020-11-06 09:20:25 +0800326 mmio_write_32(CIRQ_SENS_CLR_BASE + (reg->reg_num * 4U),
327 reg->sen);
gtk_pangaob6cec332019-12-19 15:58:20 +0800328
G.Pangao49fd68a2020-11-06 09:20:25 +0800329 for (cirq_bit = 0U; cirq_bit < 32U; ++cirq_bit) {
330 uint32_t val, cirq_id;
331 uint32_t gic_id;
332#ifdef CIRQ_WITH_POLARITY
333 uint32_t gic_bit, pol;
334#endif
335 uint32_t en;
336
337 val = ((1U << cirq_bit) & reg->mask);
338
339 if (val == 0U) {
340 continue;
341 }
342
343 cirq_id = (reg->reg_num << 5U) + cirq_bit;
344 gic_id = CIRQ_TO_IRQ_NUM(cirq_id);
345#ifdef CIRQ_WITH_POLARITY
346 gic_bit = (0x1U << ((gic_id - 32U) % 32U));
347 pol = mt_irq_get_pol(gic_id) & gic_bit;
348 if (pol != 0U) {
349 mt_cirq_set_pol(cirq_id, MT_CIRQ_POL_NEG);
350 } else {
351 mt_cirq_set_pol(cirq_id, MT_CIRQ_POL_POS);
352 }
353#endif
354 en = mt_irq_get_en(gic_id);
355 if (en == 1U) {
356 mt_cirq_unmask(cirq_id);
357 } else {
358 mt_cirq_mask(cirq_id);
359 }
gtk_pangaob6cec332019-12-19 15:58:20 +0800360 }
361 }
362}
363
G.Pangao49fd68a2020-11-06 09:20:25 +0800364static void cirq_fast_clone(void)
gtk_pangaob6cec332019-12-19 15:58:20 +0800365{
G.Pangao49fd68a2020-11-06 09:20:25 +0800366 if (already_cloned == 0U) {
367 collect_all_wakeup_events();
368 already_cloned = 1U;
gtk_pangaob6cec332019-12-19 15:58:20 +0800369 }
G.Pangao49fd68a2020-11-06 09:20:25 +0800370 __cirq_fast_clone();
gtk_pangaob6cec332019-12-19 15:58:20 +0800371}
372
G.Pangao49fd68a2020-11-06 09:20:25 +0800373void set_wakeup_sources(uint32_t *list, uint32_t num_of_events)
374{
375 cirq_all_events.num_of_events = num_of_events;
376 cirq_all_events.wakeup_events = list;
377}
gtk_pangaob6cec332019-12-19 15:58:20 +0800378/*
379 * mt_cirq_clone_gic: Copy the setting from GIC to SYS_CIRQ
380 */
381void mt_cirq_clone_gic(void)
382{
G.Pangao49fd68a2020-11-06 09:20:25 +0800383 cirq_fast_clone();
384}
385
386uint32_t mt_irq_get_pending_vec(uint32_t start_irq)
387{
388 uint32_t base = 0U;
389 uint32_t pending_vec = 0U;
390 uint32_t reg = start_irq / 32U;
391 uint32_t LSB_num, MSB_num;
392 uint32_t LSB_vec, MSB_vec;
393
394 base = BASE_GICD_BASE;
395
396 /* if start_irq is not aligned 32, do some assembling */
397 MSB_num = start_irq % 32U;
398 if (MSB_num != 0U) {
399 LSB_num = 32U - MSB_num;
400 LSB_vec = mmio_read_32(base + GICD_ISPENDR +
401 reg * 4U) >> MSB_num;
402 MSB_vec = mmio_read_32(base + GICD_ISPENDR +
403 (reg + 1U) * 4U) << LSB_num;
404 pending_vec = MSB_vec | LSB_vec;
405 } else {
406 pending_vec = mmio_read_32(base + GICD_ISPENDR + reg * 4);
407 }
408
409 return pending_vec;
410}
411
412static int mt_cirq_get_mask_vec(unsigned int i)
413{
414 return mmio_read_32((i * 4U) + CIRQ_MASK_BASE);
415}
416
417/*
418 * mt_cirq_ack_all: Ack all the interrupt on SYS_CIRQ
419 */
420void mt_cirq_ack_all(void)
421{
422 uint32_t ack_vec, pend_vec, mask_vec;
423 unsigned int i;
424
425 for (i = 0; i < CIRQ_CTRL_REG_NUM; i++) {
426 /*
427 * if a irq is pending & not masked, don't ack it
428 * , since cirq start irq might not be 32 aligned with gic,
429 * need an exotic API to get proper vector of pending irq
430 */
431 pend_vec = mt_irq_get_pending_vec(CIRQ_SPI_START
432 + (i + 1U) * 32U);
433 mask_vec = mt_cirq_get_mask_vec(i);
434 /* those should be acked are: "not (pending & not masked)",
435 */
436 ack_vec = (~pend_vec) | mask_vec;
437 mmio_write_32(CIRQ_ACK_BASE + (i * 4U), ack_vec);
438 }
439
440 /*
441 * make sure all cirq setting take effect
442 * before doing other things
443 */
444 dsb();
445}
446/*
447 * mt_cirq_enable: Enable SYS_CIRQ
448 */
449void mt_cirq_enable(void)
450{
451 uint32_t st;
452
453 /* level only */
454 mt_cirq_ack_all();
455
456 st = mmio_read_32(CIRQ_CON);
457 /*
458 * CIRQ could monitor edge/level trigger
459 */
460 st |= (CIRQ_CON_EN << CIRQ_CON_EN_BITS);
461
462 mmio_write_32(CIRQ_CON, (st & CIRQ_CON_BITS_MASK));
463}
464
465/*
466 * mt_cirq_disable: Disable SYS_CIRQ
467 */
468void mt_cirq_disable(void)
469{
470 uint32_t st;
471
472 st = mmio_read_32(CIRQ_CON);
473 st &= ~(CIRQ_CON_EN << CIRQ_CON_EN_BITS);
474 mmio_write_32(CIRQ_CON, (st & CIRQ_CON_BITS_MASK));
475}
476
477void mt_irq_unmask_for_sleep_ex(uint32_t irq)
478{
479 uint32_t mask;
480
481 mask = 1U << (irq % 32U);
482
483 mmio_write_32(BASE_GICD_BASE + GICD_ISENABLER +
484 ((irq / 32U) * 4U), mask);
485}
486
487void mt_cirq_mask_all(void)
488{
489 unsigned int i;
490
491 for (i = 0U; i < CIRQ_CTRL_REG_NUM; i++) {
492 mmio_write_32(CIRQ_MASK_SET_BASE + (i * 4U), 0xFFFFFFFF);
493 }
494 dsb();
495}
496
497static void cirq_fast_sw_flush(void)
498{
499 struct cirq_reg *reg;
500 unsigned int i;
501
502 for (i = 0U; i < CIRQ_REG_NUM ; ++i) {
503 uint32_t cirq_bit;
504
505 reg = &cirq_all_events.table[i];
506
507 if (reg->used == 0U) {
508 continue;
509 }
510
511 reg->pending = mmio_read_32(CIRQ_STA_BASE +
512 (reg->reg_num << 2U));
513 reg->pending &= reg->mask;
514
515 for (cirq_bit = 0U; cirq_bit < 32U; ++cirq_bit) {
516 uint32_t val, cirq_id;
517
518 val = (1U << cirq_bit) & reg->pending;
519 if (val == 0U) {
520 continue;
521 }
522
523 cirq_id = (reg->reg_num << 5U) + cirq_bit;
524 mt_irq_set_pending(CIRQ_TO_IRQ_NUM(cirq_id));
525 if (CIRQ_TO_IRQ_NUM(cirq_id) == MD_WDT_IRQ_BIT_ID) {
526 INFO("Set MD_WDT_IRQ pending in %s\n",
527 __func__);
528 }
529 }
530 }
gtk_pangaob6cec332019-12-19 15:58:20 +0800531}
532
533/*
534 * mt_cirq_disable: Flush interrupt from SYS_CIRQ to GIC
535 */
536void mt_cirq_flush(void)
537{
G.Pangao49fd68a2020-11-06 09:20:25 +0800538 cirq_fast_sw_flush();
gtk_pangaob6cec332019-12-19 15:58:20 +0800539 mt_cirq_mask_all();
540 mt_cirq_ack_all();
541}
542
543void mt_cirq_sw_reset(void)
544{
G.Pangao49fd68a2020-11-06 09:20:25 +0800545#ifdef CIRQ_NEED_SW_RESET
gtk_pangaob6cec332019-12-19 15:58:20 +0800546 uint32_t st;
547
G.Pangao49fd68a2020-11-06 09:20:25 +0800548 st = mmio_read_32(CIRQ_CON);
gtk_pangaob6cec332019-12-19 15:58:20 +0800549 st |= (CIRQ_SW_RESET << CIRQ_CON_SW_RST_BITS);
G.Pangao49fd68a2020-11-06 09:20:25 +0800550 mmio_write_32(CIRQ_CON, st);
551#endif
gtk_pangaob6cec332019-12-19 15:58:20 +0800552}