xref: /rk3399_ARM-atf/plat/mediatek/drivers/spm/mt8189/constraints/mt_spm_rc_api.c (revision af0370f25a6663a0d737bbfb3985df4232eaaa55)
1 /*
2  * Copyright (c) 2025, Mediatek Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <common/debug.h>
8 
9 #include <constraints/mt_spm_rc_api.h>
10 #include <lpm_v2/mt_lpm_smc.h>
11 #ifndef MTK_PLAT_CIRQ_UNSUPPORT
12 #include <mt_gic_v3.h>
13 #endif
14 #include <mt_plat_spm_setting.h>
15 #include <mt_spm_common.h>
16 
spm_rc_condition_modifier(uint32_t id,uint32_t act,const void * val,enum mt_spm_rm_rc_type dest_rc_id,struct mt_spm_cond_tables * const tlb)17 int spm_rc_condition_modifier(uint32_t id, uint32_t act, const void *val,
18 			      enum mt_spm_rm_rc_type dest_rc_id,
19 			      struct mt_spm_cond_tables *const tlb)
20 {
21 	uint32_t rc_id, cond_id, cond = 0;
22 	int res = 0;
23 
24 	plat_spm_lock();
25 	rc_id = SPM_RC_UPDATE_COND_RC_ID_GET(id);
26 	cond_id = SPM_RC_UPDATE_COND_ID_GET(id);
27 
28 	do {
29 		if ((dest_rc_id != rc_id) || !val || !tlb) {
30 			res = -1;
31 			break;
32 		}
33 
34 		cond = *((uint32_t *)val);
35 
36 		if ((cond_id - PLAT_SPM_COND_MAX) < PLAT_SPM_COND_PLL_MAX) {
37 			uint32_t pll_idx = cond_id - PLAT_SPM_COND_MAX;
38 
39 			cond = !!cond;
40 			if (act & MT_LPM_SMC_ACT_SET)
41 				tlb->table_pll |= (cond << pll_idx);
42 			else if (act & MT_LPM_SMC_ACT_CLR)
43 				tlb->table_pll &= ~(cond << pll_idx);
44 			else
45 				res = -1;
46 		} else
47 			res = -1;
48 	} while (0);
49 
50 	plat_spm_unlock();
51 
52 	return res;
53 }
54 
55 /*
56  * CIRQ will respresent interrupt which type is edge
57  * when gic mask. But if the 26 clk have turned off before
58  * then cirq won't work normally.
59  * So we need to set irq pending for specific wakeup source.
60  */
61 #ifndef MTK_PLAT_CIRQ_UNSUPPORT
mt_spm_irq_remain_dump(struct mt_irqremain * irqs,uint32_t irq_index,struct wake_status * wakeup)62 static void mt_spm_irq_remain_dump(struct mt_irqremain *irqs,
63 				   uint32_t irq_index,
64 				   struct wake_status *wakeup)
65 {
66 	INFO("[SPM] r12=0x%08x(0x%08x), irq:%u(0x%08x) set pending\n",
67 	     wakeup->tr.comm.r12,
68 	     wakeup->md32pcm_wakeup_sta,
69 	     irqs->wakeupsrc[irq_index],
70 	     irqs->irqs[irq_index]);
71 }
72 
do_irqs_delivery(struct mt_irqremain * irqs,struct wake_status * wakeup)73 void do_irqs_delivery(struct mt_irqremain *irqs, struct wake_status *wakeup)
74 {
75 	uint32_t idx;
76 
77 	if (!irqs || !wakeup)
78 		return;
79 
80 	for (idx = 0; idx < irqs->count; idx++) {
81 		if ((wakeup->tr.comm.raw_sta & irqs->wakeupsrc[idx]) ||
82 		    (wakeup->tr.comm.r12 & irqs->wakeupsrc[idx])) {
83 			if ((irqs->wakeupsrc_cat[idx] & MT_IRQ_REMAIN_CAT_LOG))
84 				mt_spm_irq_remain_dump(irqs, idx, wakeup);
85 
86 			mt_irq_set_pending(irqs->irqs[idx]);
87 		}
88 	}
89 }
90 #endif
91