Skip to content

Commit ed4c323

Browse files
hailong-fankv2019i
authored andcommitted
drivers: mediatek: Add drivers for mt8196
Add interrupt, timer and ipc driver for mt8196. Signed-off-by: hailong.fan <hailong.fan@mediatek.com>
1 parent fe82f08 commit ed4c323

File tree

6 files changed

+876
-0
lines changed

6 files changed

+876
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
3+
add_local_sources(sof interrupt.c intc.c intc_map.c ipc.c timer.c)
4+

src/drivers/mediatek/mt8196/intc.c

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
/*
3+
* Copyright(c) 2024 MediaTek. All rights reserved.
4+
*
5+
* Author: Hailong Fan <hailong.fan@mediatek.com>
6+
*/
7+
8+
#include <rtos/interrupt.h>
9+
#include <sof/lib/memory.h>
10+
#include <sof/platform.h>
11+
#include <sof/lib/uuid.h>
12+
#include <platform/drivers/interrupt.h>
13+
#include <platform/drivers/intc.h>
14+
#include <errno.h>
15+
#include <stdint.h>
16+
17+
SOF_DEFINE_REG_UUID(intc_mt8196);
18+
DECLARE_TR_CTX(intc_tr, SOF_UUID(intc_mt8196_uuid), LOG_LEVEL_INFO);
19+
20+
static struct intc_desc_t intc_desc;
21+
22+
void intc_init(void)
23+
{
24+
uint32_t word, group, irq;
25+
26+
for (group = 0; group < INTC_GRP_NUM; group++) {
27+
for (word = 0; word < INTC_GRP_LEN; word++)
28+
intc_desc.grp_irqs[group][word] = 0x0;
29+
}
30+
31+
for (word = 0; word < INTC_GRP_LEN; word++)
32+
intc_desc.int_en[word] = 0x0;
33+
34+
for (irq = 0; irq < IRQ_MAX_CHANNEL; irq++) {
35+
intc_desc.irqs[irq].id = irq;
36+
intc_desc.irqs[irq].group = irq2grp_map[irq];
37+
intc_desc.irqs[irq].pol = INTC_POL_LOW;
38+
}
39+
40+
for (word = 0; word < INTC_GRP_LEN; word++) {
41+
io_reg_write(INTC_IRQ_EN(word), 0x0);
42+
io_reg_write(INTC_IRQ_WAKE_EN(word), 0x0);
43+
io_reg_write(INTC_IRQ_STAGE1_EN(word), 0x0);
44+
io_reg_write(INTC_IRQ_POL(word), 0xFFFFFFFF);
45+
}
46+
47+
for (group = 0; group < INTC_GRP_NUM; group++) {
48+
for (word = 0; word < INTC_GRP_LEN; word++)
49+
io_reg_write(INTC_IRQ_GRP(group, word), 0x0);
50+
}
51+
}
52+
53+
void intc_irq_unmask(enum IRQn_Type irq)
54+
{
55+
uint32_t word, group;
56+
57+
if (irq < IRQ_MAX_CHANNEL && intc_desc.irqs[irq].group < INTC_GRP_NUM) {
58+
word = INTC_WORD(irq);
59+
group = intc_desc.irqs[irq].group;
60+
io_reg_update_bits(INTC_IRQ_EN(word), INTC_BIT(irq), INTC_BIT(irq));
61+
} else {
62+
tr_err(&intc_tr, "Invalid INTC interrupt %d", irq);
63+
}
64+
}
65+
66+
void intc_irq_mask(enum IRQn_Type irq)
67+
{
68+
uint32_t word;
69+
70+
if (irq < IRQ_MAX_CHANNEL) {
71+
word = INTC_WORD(irq);
72+
io_reg_update_bits(INTC_IRQ_EN(word), INTC_BIT(irq), 0);
73+
} else {
74+
tr_err(&intc_tr, "Invalid INTC interrupt %d", irq);
75+
}
76+
}
77+
78+
int intc_irq_enable(enum IRQn_Type irq)
79+
{
80+
uint32_t word, irq_b, group, pol;
81+
int ret;
82+
83+
if (irq < IRQ_MAX_CHANNEL && intc_desc.irqs[irq].group < INTC_GRP_NUM &&
84+
intc_desc.irqs[irq].pol < INTC_POL_NUM) {
85+
word = INTC_WORD(irq);
86+
irq_b = INTC_BIT(irq);
87+
group = intc_desc.irqs[irq].group;
88+
pol = intc_desc.irqs[irq].pol;
89+
90+
intc_desc.int_en[word] |= irq_b;
91+
intc_desc.grp_irqs[group][word] |= irq_b;
92+
io_reg_update_bits(INTC_IRQ_EN(word), irq_b, 0);
93+
if (pol == INTC_POL_HIGH)
94+
io_reg_update_bits(INTC_IRQ_POL(word), irq_b, 0);
95+
else
96+
io_reg_update_bits(INTC_IRQ_POL(word), irq_b, irq_b);
97+
98+
io_reg_update_bits(INTC_IRQ_GRP(group, word), irq_b, irq_b);
99+
io_reg_update_bits(INTC_IRQ_EN(word), irq_b, irq_b);
100+
101+
ret = 1;
102+
} else {
103+
tr_err(&intc_tr, "Invalid INTC interrupt %d", irq);
104+
ret = 0;
105+
}
106+
107+
return ret;
108+
}
109+
110+
int intc_irq_disable(enum IRQn_Type irq)
111+
{
112+
uint32_t word, irq_b, group;
113+
int ret;
114+
115+
if (irq < IRQ_MAX_CHANNEL && intc_desc.irqs[irq].group < INTC_GRP_NUM) {
116+
word = INTC_WORD(irq);
117+
irq_b = INTC_BIT(irq);
118+
group = intc_desc.irqs[irq].group;
119+
120+
intc_desc.int_en[word] &= ~irq_b;
121+
intc_desc.grp_irqs[group][word] &= ~irq_b;
122+
io_reg_update_bits(INTC_IRQ_EN(word), irq_b, 0);
123+
io_reg_update_bits(INTC_IRQ_GRP(group, word), irq_b, 0);
124+
125+
ret = 1;
126+
} else {
127+
tr_err(&intc_tr, "INTC fail to disable irq %u\n", irq);
128+
ret = 0;
129+
}
130+
131+
return ret;
132+
}
133+
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
/*
3+
* Copyright(c) 2024 MediaTek. All rights reserved.
4+
*
5+
* Author: Hailong Fan <hailong.fan@mediatek.com>
6+
*/
7+
8+
#include <sof/audio/component_ext.h>
9+
#include <rtos/interrupt.h>
10+
#include <sof/lib/memory.h>
11+
#include <sof/platform.h>
12+
#include <platform/drivers/timer.h>
13+
#include <platform/drivers/interrupt.h>
14+
#include <ipc/stream.h>
15+
#include <errno.h>
16+
#include <stdint.h>
17+
18+
const unsigned char grp_pri[INTC_GRP_NUM] = {
19+
INTC_GRP0_LEVEL, INTC_GRP1_LEVEL, INTC_GRP2_LEVEL, INTC_GRP3_LEVEL,
20+
INTC_GRP4_LEVEL, INTC_GRP5_LEVEL, INTC_GRP6_LEVEL, INTC_GRP7_LEVEL,
21+
INTC_GRP8_LEVEL, INTC_GRP9_LEVEL, INTC_GRP10_LEVEL, INTC_GRP11_LEVEL,
22+
INTC_GRP12_LEVEL, INTC_GRP13_LEVEL, INTC_GRP14_LEVEL, INTC_GRP15_LEVEL,
23+
};
24+
25+
const uint8_t irq2grp_map[IRQ_MAX_CHANNEL] = {
26+
[CCU_IRQn] = INTC_GRP1,
27+
[SCP_IRQn] = INTC_GRP1,
28+
[SPM_IRQn] = INTC_GRP1,
29+
[PCIE_IRQn] = INTC_GRP1,
30+
[INFRA_HANG_IRQn] = INTC_GRP1,
31+
[PERI_TIMEOUT_IRQn] = INTC_GRP1,
32+
[MBOX_C0_IRQn] = INTC_GRP2,
33+
[MBOX_C1_IRQn] = INTC_GRP2,
34+
[TIMER0_IRQn] = INTC_GRP1,
35+
[TIMER1_IRQn] = INTC_GRP1,
36+
[IPC_C0_IRQn] = INTC_GRP1,
37+
[IPC_C1_IRQn] = INTC_GRP1,
38+
[IPC1_RSV_IRQn] = INTC_GRP1,
39+
[C2C_SW_C0_IRQn] = INTC_GRP1,
40+
[C2C_SW_C1_IRQn] = INTC_GRP1,
41+
[UART_IRQn] = INTC_GRP12,
42+
[UART_BT_IRQn] = INTC_GRP12,
43+
[LATENCY_MON_IRQn] = INTC_GRP11,
44+
[BUS_TRACKER_IRQn] = INTC_GRP13,
45+
[USB0_IRQn] = INTC_GRP8,
46+
[USB1_IRQn] = INTC_GRP8,
47+
[SCPVOW_IRQn] = NO_GRP,
48+
[CCIF3_C0_IRQn] = INTC_GRP8,
49+
[CCIF3_C1_IRQn] = INTC_GRP8,
50+
[PWR_CTRL_IRQn] = NO_GRP,
51+
[DMA_C0_IRQn] = INTC_GRP10,
52+
[DMA_C1_IRQn] = NO_GRP,
53+
[AXI_DMA0_IRQn] = INTC_GRP9,
54+
[AXI_DMA1_IRQn] = NO_GRP,
55+
[AUDIO_C0_IRQn] = INTC_GRP10,
56+
[AUDIO_C1_IRQn] = INTC_GRP10,
57+
[HIFI5_WDT_C0_IRQn] = INTC_GRP13,
58+
[HIFI5_WDT_C1_IRQn] = INTC_GRP13,
59+
[APU_MBOX_C0_IRQn] = INTC_GRP0,
60+
[APU_MBOX_C1_IRQn] = INTC_GRP0,
61+
[TIMER2_IRQn] = INTC_GRP13,
62+
[PWR_ON_C0_IRQ] = INTC_GRP13,
63+
[PWR_ON_C1_IRQ] = INTC_GRP13,
64+
[WAKEUP_SRC_C0_IRQn] = INTC_GRP13,
65+
[WAKEUP_SRC_C1_IRQn] = INTC_GRP13,
66+
[WDT_IRQn] = NO_GRP,
67+
[CONNSYS1_IRQn] = INTC_GRP3,
68+
[CONNSYS3_IRQn] = INTC_GRP3,
69+
[CONNSYS4_IRQn] = INTC_GRP3,
70+
[CONNSYS2_IRQn] = INTC_GRP3,
71+
[IPIC_IRQn] = INTC_GRP1,
72+
[AXI_DMA2_IRQn] = INTC_GRP9,
73+
[AXI_DMA3_IRQn] = NO_GRP,
74+
[APSRC_DDREN_IRQn] = INTC_GRP4,
75+
[LAT_MON_EMI_IRQn] = INTC_GRP11,
76+
[LAT_MON_INFRA_IRQn] = INTC_GRP11,
77+
[DEVAPC_VIO_IRQn] = INTC_GRP11,
78+
[AO_INFRA_HANG_IRQn] = NO_GRP,
79+
[BUS_TRA_EMI_IRQn] = INTC_GRP13,
80+
[BUS_TRA_INFRA_IRQn] = INTC_GRP13,
81+
[L2SRAM_VIO_IRQn] = INTC_GRP11,
82+
[L2SRAM_SETERR_IRQn] = INTC_GRP11,
83+
[PCIERC_GRP2_IRQn] = INTC_GRP8,
84+
[PCIERC_GRP3_IRQn] = INTC_GRP8,
85+
};
86+
87+
const uint8_t grp2hifi_irq_map[INTC_GRP_NUM] = {
88+
[INTC_GRP0] = 0,
89+
[INTC_GRP1] = 1,
90+
[INTC_GRP2] = 2,
91+
[INTC_GRP3] = 3,
92+
[INTC_GRP4] = 4,
93+
[INTC_GRP5] = 5,
94+
[INTC_GRP6] = 7,
95+
[INTC_GRP7] = 8,
96+
[INTC_GRP8] = 9,
97+
[INTC_GRP9] = 10,
98+
[INTC_GRP10] = 11,
99+
[INTC_GRP11] = 16,
100+
[INTC_GRP12] = 17,
101+
[INTC_GRP13] = 18,
102+
[INTC_GRP14] = 20,
103+
[INTC_GRP15] = 21,
104+
};

0 commit comments

Comments
 (0)