diff --git a/boards/mediatek/index.rst b/boards/mediatek/index.rst index 4c41e0b4d8637..b285d97f9e512 100644 --- a/boards/mediatek/index.rst +++ b/boards/mediatek/index.rst @@ -5,18 +5,20 @@ Mediatek Audio DSPs Zephyr can be built and run on the Audio DSPs included in various members of the Mediatek MT8xxx series of ARM SOCs used in Chromebooks -from various manufacturers. +from various manufacturers and Mediatek Genio evaluations kits. -Two of these DSPs are in the market already, implemented via the -MT8195 ("Kompanio 1380") and MT8186 ("Kompanio 520") SOCs. -Development has been done on and validation performed on at least -these devices, though more exist: +Four of these DSPs are in the market already, implemented via the +MT8195 ("Kompanio 1380", MT8186 ("Kompanio 520"), MT8188 ("Kompanio 838") +and MT8365 ("Genio 350 EVK") SOCs. Development has been done on and +validation performed on at least these devices, though more exist: ====== ============= =================================== ================= SOC Product Name Example Device ChromeOS Codename ====== ============= =================================== ================= MT8195 Kompanio 1380 HP Chromebook x360 13b dojo MT8186 Kompanio 520 Lenovo 300e Yoga Chromebook Gen 4 steelix + MT8188 Kompanio 838 Lenovo Chromebook Duet 11 ciri + MT8365 Genio 350 Genio 350 EVK ====== ============= =================================== ================= Hardware @@ -67,7 +69,7 @@ my mt8186 device named "steelix": .. code-block:: console - user@dev_host:~$ west build -b mt8186//adsp samples/hello_world + user@dev_host:~$ west build -b mt8186/mt8186/adsp samples/hello_world ... ... # build output ... @@ -76,8 +78,8 @@ my mt8186 device named "steelix": user@dev_host:~$ ssh steelix root@steelix:~ # ./mtk_adsp_load.py load zephyr.img - *** Booting Zephyr OS build v3.6.0-5820-gd2a89b3c089e *** - Hello World! mt8186_adsp/mt8186_adsp + *** Booting Zephyr OS build v4.2.0-4743-g80fdfabcba48 *** + Hello World! mt8186/mt8186/adsp Debugging ========= @@ -93,60 +95,11 @@ but this is still unintegrated. Toolchains ********** -The MT8195 toolchain is already part of the Zephyr SDK, so builds for -the ``mt8195//adsp`` board should work out of the box simply following -the generic Zephyr build instructions in the Getting Started guide. - -The MT8186 toolchain is not, and given the proliferation of Xtensa -toolchains in the SDK may not be. The overlay files for the device -are maintained by the SOF project, however, and building a toolchain -yourself using crosstools-ng is not difficult or time-consuming. This -script should work for most users: - -.. code-block:: shell - - #!/bin/sh - - TC=mtk_mt818x_adsp - - # Grab source (these are small) - git clone https://github.com/crosstool-ng/crosstool-ng - git clone https://github.com/thesofproject/xtensa-overlay - - # Build ct-ng itself - cd crosstool-ng - ./bootstrap - ./configure --enable-local - make -j$(nproc) - - mkdir overlays - (cd overlays; ln -s ../../xtensa-overlay/xtensa_mt8186.tar.gz xtensa_${TC}.tar.gz) - - # Construct a .config file - cat >.config <; + downlink; + base = <0x00000000 0x11220040>; + cur = <0x00000000 0x11220044>; + end = <0x00000000 0x11220048>; + fs = <0x11220014 0 4>; + mono = <0x11220014 21 1>; + enable = <0x11220010 1 1>; + hd = <0x112203d8 16 1>; + }; + + afe_dl2: afe_dl2 { + compatible = "mediatek,afe"; + afe-name = "DL2"; + dai-id = <1>; + downlink; + base = <0x00000000 0x11220050>; + cur = <0x00000000 0x11220054>; + end = <0x00000000 0x11220058>; + fs = <0x11220014 4 4>; + mono = <0x11220014 22 1>; + enable = <0x11220010 2 1>; + hd = <0x112203d8 18 1>; + }; + + afe_tdm_out: afe_tdm_out { + compatible = "mediatek,afe"; + afe-name = "TDM_OUT"; + dai-id = <4>; + downlink; + base = <0x00000000 0x11220374>; + cur = <0x00000000 0x11220378>; + end = <0x00000000 0x1122037c>; + enable = <0x11220370 0 1>; + hd = <0x112203d8 28 1>; + }; + + afe_awb: afe_awb { + compatible = "mediatek,afe"; + afe-name = "AWB"; + dai-id = <2>; + base = <0x00000000 0x11220070>; + cur = <0x00000000 0x1122007c>; + end = <0x00000000 0x11220078>; + fs = <0x11220014 12 4>; + mono = <0x11220014 24 1>; + enable = <0x11220010 6 1>; + hd = <0x112203d8 20 1>; + msb = <0x112200cc 17 1>; + }; + + afe_vul: afe_vul { + compatible = "mediatek,afe"; + afe-name = "VUL"; + dai-id = <3>; + base = <0x00000000 0x11220080>; + cur = <0x00000000 0x1122008c>; + end = <0x00000000 0x11220088>; + fs = <0x11220014 16 4>; + mono = <0x11220014 27 1>; + enable = <0x11220010 3 1>; + hd = <0x112203d8 22 1>; + msb = <0x112200cc 20 1>; + }; + + afe_vul2: afe_vul2 { + compatible = "mediatek,afe"; + afe-name = "VUL2"; + dai-id = <5>; + base = <0x00000000 0x11220350>; + cur = <0x00000000 0x1122035c>; + end = <0x00000000 0x11220358>; + fs = <0x11220010 20 4>; + mono = <0x11220010 10 1>; + enable = <0x11220010 9 1>; + hd = <0x112203d8 14 1>; + msb = <0x112200cc 21 1>; + }; + + afe_vul3: afe_vul3 { + compatible = "mediatek,afe"; + afe-name = "VUL3"; + dai-id = <6>; + base = <0x00000000 0x112208c0>; + cur = <0x00000000 0x112208c4>; + end = <0x00000000 0x112208c8>; + fs = <0x11220014 8 4>; + mono = <0x11220010 13 1>; + enable = <0x11220010 12 1>; + hd = <0x112203ec 10 1>; + msb = <0x112200cc 27 1>; + }; + + afe_tdm_in: afe_tdm_in { + compatible = "mediatek,afe"; + afe-name = "TDM_IN"; + dai-id = <7>; + base = <0x00000000 0x112209c4>; + cur = <0x00000000 0x112209cc>; + end = <0x00000000 0x112209c8>; + mono = <0x112209c0 1 1>; + enable = <0x112209c0 0 1>; + hd = <0x112203ec 8 1>; + msb = <0x112200cc 28 1>; + }; diff --git a/boards/mediatek/mt8365/board.yml b/boards/mediatek/mt8365/board.yml new file mode 100644 index 0000000000000..4b84d3665ce74 --- /dev/null +++ b/boards/mediatek/mt8365/board.yml @@ -0,0 +1,6 @@ +boards: + - name: mt8365 + full_name: MT8365 ADSP + vendor: mediatek + socs: + - name: mt8365 diff --git a/boards/mediatek/mt8365/mt8365_adsp.dts b/boards/mediatek/mt8365/mt8365_adsp.dts new file mode 100644 index 0000000000000..552179c60b03c --- /dev/null +++ b/boards/mediatek/mt8365/mt8365_adsp.dts @@ -0,0 +1,80 @@ +/* Copyright 2025 Mediatek + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <1>; + + sram1: memory@1e000000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0x1e000000 DT_SIZE_K(416)>; + }; + + sram0: memory@40020000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0x40020000 DT_SIZE_K(256)>; + }; + + dram0: memory@60000000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0x60000000 DT_SIZE_K(13824)>; + }; + + dram1: memory@60d80000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0x60d80000 DT_SIZE_K(2560)>; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + + core_intc: core_intc@0 { + compatible = "cdns,xtensa-core-intc"; + reg = <0 4>; + interrupt-controller; + #interrupt-cells = <3>; + }; + + intc1: intc@1d062130 { + compatible = "mediatek,adsp_intc"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x1d062130 4>; + status-reg = <0x1d062150>; + interrupts = <1 0 0>; + mask = <0x3ff>; + interrupt-parent = <&core_intc>; + }; + + ostimer64: ostimer64@1d060000 { + compatible = "mediatek,ostimer64"; + reg = <0x1d060000 30>; + }; + + ostimer0: ostimer@1d060040 { + compatible = "mediatek,ostimer"; + reg = <0x1d060040 8>; + interrupt-parent = <&core_intc>; + interrupts = <2 0 0>; + }; + + ipi: ipi@1d062114 { + compatible = "mediatek,ipi"; + reg = <0x1d062114 4>; + interrupt-parent = <&intc1>; + interrupts = < 9 0 0 >; + }; + +/* Generated code for AFE devices */ +#include "afe-mt8365.dts" + + }; /* soc */ +}; diff --git a/boards/mediatek/mt8365/mt8365_mt8365_adsp.yaml b/boards/mediatek/mt8365/mt8365_mt8365_adsp.yaml new file mode 100644 index 0000000000000..629e788f40cf5 --- /dev/null +++ b/boards/mediatek/mt8365/mt8365_mt8365_adsp.yaml @@ -0,0 +1,11 @@ +identifier: mt8365/mt8365/adsp +name: Mediatek mt8365 Audio DSP +type: mcu +arch: xtensa +toolchain: + - zephyr +testing: + only_tags: + - kernel + - sof +vendor: mediatek diff --git a/boards/mediatek/twister.yaml b/boards/mediatek/twister.yaml index e941f64004818..d70649d6eaf32 100644 --- a/boards/mediatek/twister.yaml +++ b/boards/mediatek/twister.yaml @@ -16,3 +16,5 @@ variants: name: MediaTek MT8186 Audio DSP mt8196/mt8196/adsp: name: MediaTek MT8196 Audio DSP + mt8365/mt8365/adsp: + name: MediaTek MT8365 Audio DSP diff --git a/drivers/timer/mtk_adsp_timer.c b/drivers/timer/mtk_adsp_timer.c index 25fbf9286c839..aab4713a41ccc 100644 --- a/drivers/timer/mtk_adsp_timer.c +++ b/drivers/timer/mtk_adsp_timer.c @@ -32,6 +32,8 @@ const int32_t z_sys_timer_irq_for_test = DT_IRQN(DT_NODELABEL(ostimer0)); * slaved the same underlying clock -- they don't skew relative to * each other. */ + +#ifndef CONFIG_SOC_MT8365 struct mtk_ostimer { unsigned int con; unsigned int rst; @@ -48,6 +50,19 @@ struct mtk_ostimer64 { unsigned int tval_h; unsigned int irq_ack; }; +#else +struct mtk_ostimer { + unsigned int con; + unsigned int cur; +}; + +struct mtk_ostimer64 { + unsigned int cntcr; + unsigned int cntsr; + unsigned int cur_l; + unsigned int cur_h; +}; +#endif #define OSTIMER64 (*(volatile struct mtk_ostimer64 *)OSTIMER64_BASE) @@ -67,11 +82,22 @@ struct mtk_ostimer64 { #define OSTIMER_CON_CLKSRC_PCLK 0x30 /* ~312 MHz experimentally */ #endif -#define OSTIMER_IRQ_ACK_ENABLE BIT(0) +#if defined(CONFIG_SOC_MT8365) +#define OSTIMER_CON_IRQ_ENABLE BIT(1) +#define OSTIMER_CON_IRQ_STA_CLEAR BIT(4) /* read = status, write = clear */ +#else +#define OSTIMER_IRQ_ACK_ENABLE BIT(0) /* read = status, write = enable */ #define OSTIMER_IRQ_ACK_CLEAR BIT(5) +#endif #define OST64_HZ 13000000U + +#ifdef CONFIG_SOC_MT8365 +#define OST_HZ 13000000U +#else #define OST_HZ 26000000U +#endif + #define OST64_PER_TICK (OST64_HZ / CONFIG_SYS_CLOCK_TICKS_PER_SEC) #define OST_PER_TICK (OST_HZ / CONFIG_SYS_CLOCK_TICKS_PER_SEC) @@ -91,11 +117,20 @@ uint64_t sys_clock_cycle_get_64(void) { uint32_t l, h0, h1; +#ifndef CONFIG_SOC_MT8365 do { h0 = OSTIMER64.cur_h; l = OSTIMER64.cur_l; h1 = OSTIMER64.cur_h; } while (h0 != h1); +#else + /* cur_h is only updated when the cur_l is read. + * Always read cur_l before cur_h to get a valid 64-bit timestamp. + */ + l = OSTIMER64.cur_l; + h0 = OSTIMER64.cur_h; + (void)h1; /* silence the "unused variable" warning */ +#endif return (((uint64_t)h0) << 32) | l; } @@ -110,6 +145,7 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) /* Round up to tick boundary */ dt = ((dt + OST64_PER_TICK - 1) / OST64_PER_TICK) * OST64_PER_TICK; +#ifndef CONFIG_SOC_MT8365 /* Convert to "fast" OSTIMER[0] cycles! */ uint32_t cyc = 2 * (dt - (uint32_t)(now - last_announce)); @@ -121,6 +157,12 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) OSTIMERS[0].irq_ack |= OSTIMER_IRQ_ACK_CLEAR; OSTIMERS[0].irq_ack |= OSTIMER_IRQ_ACK_ENABLE; OSTIMERS[0].con |= OSTIMER_CON_ENABLE; +#else + uint32_t cyc = dt - (uint32_t)(now - last_announce); + + OSTIMERS[0].cur = cyc; + OSTIMERS[0].con |= OSTIMER_CON_IRQ_ENABLE; +#endif } uint32_t sys_clock_elapsed(void) @@ -150,9 +192,14 @@ static void timer_isr(__maybe_unused void *arg) * sys_clock_set_timeout() is responsible for turning it back * on. */ +#ifndef CONFIG_SOC_MT8365 OSTIMERS[0].irq_ack |= OSTIMER_IRQ_ACK_CLEAR; OSTIMERS[0].con &= ~OSTIMER_CON_ENABLE; OSTIMERS[0].irq_ack &= ~OSTIMER_IRQ_ACK_ENABLE; +#else + OSTIMERS[0].con |= OSTIMER_CON_IRQ_STA_CLEAR; + OSTIMERS[0].con &= ~OSTIMER_CON_IRQ_ENABLE; +#endif last_announce += ticks * OST64_PER_TICK; sys_clock_announce(ticks); @@ -169,18 +216,27 @@ static int mtk_adsp_timer_init(void) /* Disable all timers */ for (int i = 0; i < 4; i++) { +#ifndef CONFIG_SOC_MT8365 OSTIMERS[i].con &= ~OSTIMER_CON_ENABLE; OSTIMERS[i].irq_ack |= OSTIMER_IRQ_ACK_CLEAR; OSTIMERS[i].irq_ack &= ~OSTIMER_IRQ_ACK_ENABLE; +#else + OSTIMERS[i].con = OSTIMER_CON_IRQ_STA_CLEAR | OSTIMER_CON_ENABLE; + OSTIMERS[i].con &= ~OSTIMER_CON_ENABLE; +#endif } /* Set them up to use the same clock. Note that OSTIMER64 has * a built-in divide by two (or it's configurable and I don't * know the register) and exposes a 13 MHz counter! */ +#ifndef CONFIG_SOC_MT8365 OSTIMERS[0].con = ((OSTIMERS[0].con & ~OSTIMER_CON_CLKSRC_MASK) | OSTIMER_CON_CLKSRC_26M); OSTIMERS[0].con |= OSTIMER_CON_ENABLE; +#else + OSTIMERS[0].con |= OSTIMER_CON_IRQ_ENABLE | OSTIMER_CON_ENABLE; +#endif /* Clock is free running and survives reset, doesn't start at zero */ last_announce = sys_clock_cycle_get_64(); diff --git a/soc/mediatek/mt8xxx/CMakeLists.txt b/soc/mediatek/mt8xxx/CMakeLists.txt index 203f364e0aae5..db6bd87dbe926 100644 --- a/soc/mediatek/mt8xxx/CMakeLists.txt +++ b/soc/mediatek/mt8xxx/CMakeLists.txt @@ -1,7 +1,10 @@ # Copyright 2023 The ChromiumOS Authors # SPDX-License-Identifier: Apache-2.0 -zephyr_library_sources(soc.c irq.c mbox.c) +zephyr_library_sources(soc.c irq.c) + +zephyr_library_sources_ifndef(CONFIG_SOC_SERIES_MT8365 mbox.c) +zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_MT8365 ipi.c) zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_MT8195 ${CONFIG_SOC}/cpuclk.c) zephyr_library_sources_ifdef(CONFIG_SOC_MT8188 ${CONFIG_SOC}/cpuclk.c) diff --git a/soc/mediatek/mt8xxx/Kconfig.defconfig b/soc/mediatek/mt8xxx/Kconfig.defconfig index d8ebe43c402da..6bd3b8d4e68a8 100644 --- a/soc/mediatek/mt8xxx/Kconfig.defconfig +++ b/soc/mediatek/mt8xxx/Kconfig.defconfig @@ -62,6 +62,7 @@ config XTENSA_CCOUNT_HZ default 400000000 if SOC_MT8186 default 800000000 if SOC_MT8188 default 800000000 if SOC_MT8196 + default 600000000 if SOC_MT8365 config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_node_int_prop_int,$(dt_nodelabel_path,ostimer64),freq-hz) @@ -89,6 +90,7 @@ config SOC_TOOLCHAIN_NAME default "mtk_mt8195_adsp" if SOC_SERIES_MT8195 default "mtk_mt818x_adsp" if SOC_SERIES_MT818X default "mtk_mt8196_adsp" if SOC_SERIES_MT8196 + default "mtk_mt8365_adsp" if SOC_SERIES_MT8365 config XTENSA_RESET_VECTOR default n diff --git a/soc/mediatek/mt8xxx/Kconfig.soc b/soc/mediatek/mt8xxx/Kconfig.soc index ba52c9eb57465..62ef0b2c78230 100644 --- a/soc/mediatek/mt8xxx/Kconfig.soc +++ b/soc/mediatek/mt8xxx/Kconfig.soc @@ -22,6 +22,12 @@ config SOC_SERIES_MT8196 help Mediatek MT8196 Audio DSPs +config SOC_SERIES_MT8365 + bool + select SOC_FAMILY_MTK + help + Mediatek MT8365 Audio DSP + config SOC_MT8195 bool select SOC_SERIES_MT8195 @@ -38,8 +44,19 @@ config SOC_MT8196 bool select SOC_SERIES_MT8196 +config SOC_MT8365 + bool + select SOC_SERIES_MT8365 + +config SOC_SERIES + default "mt8195" if SOC_SERIES_MT8195 + default "mt818x" if SOC_SERIES_MT818X + default "mt8196" if SOC_SERIES_MT8196 + default "mt8365" if SOC_SERIES_MT8365 + config SOC default "mt8195" if SOC_MT8195 default "mt8186" if SOC_MT8186 default "mt8188" if SOC_MT8188 default "mt8196" if SOC_MT8196 + default "mt8365" if SOC_MT8365 diff --git a/soc/mediatek/mt8xxx/gen_img.py b/soc/mediatek/mt8xxx/gen_img.py index 83b69ec1b9a05..c435da606b27e 100755 --- a/soc/mediatek/mt8xxx/gen_img.py +++ b/soc/mediatek/mt8xxx/gen_img.py @@ -39,7 +39,7 @@ def sram_off(addr): global sram_block if addr < 0x40000000 or addr >= 0x50000000: return -1 - block = addr & ~0xFFFFF + block = addr & ~0xFFFF assert sram_block in (0, block) sram_block = block diff --git a/soc/mediatek/mt8xxx/ipi.c b/soc/mediatek/mt8xxx/ipi.c new file mode 100644 index 0000000000000..dae65774940f5 --- /dev/null +++ b/soc/mediatek/mt8xxx/ipi.c @@ -0,0 +1,92 @@ +/* Copyright 2025 Mediatek + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#define DT_DRV_COMPAT mediatek_ipi + +#define CPU2DSP_IRQ BIT(0) +#define DSP2CPU_IRQ BIT(1) +#define DSP2SPM_IRQ_B BIT(2) + +struct mtk_ipi { + uint32_t int2cirq; + uint32_t int_pol; + uint32_t int_en; + uint32_t int_status; +}; + +struct ipi_cfg { + volatile struct mtk_ipi *ipi; +}; + +struct ipi_data { + mtk_adsp_ipi_handler_t handler; + void *handler_arg; +}; + +void mtk_adsp_ipi_set_handler(const struct device *ipi, uint32_t chan, + mtk_adsp_ipi_handler_t handler, void *arg) +{ + struct ipi_data *data = ((struct device *)ipi)->data; + + data->handler = handler; + data->handler_arg = arg; +} + +void mtk_adsp_ipi_signal(const struct device *ipi, uint32_t op) +{ + const struct ipi_cfg *cfg = ((struct device *)ipi)->config; + + /* wakeup CPU */ + cfg->ipi->int2cirq &= ~(DSP2SPM_IRQ_B); + /* trigger IPI IRQ to CPU */ + cfg->ipi->int2cirq |= DSP2CPU_IRQ; +} + +#define DEF_DEVPTR(N) DEVICE_DT_INST_GET(N), +const struct device * const ipi_dev = { + DEF_DEVPTR(0) +}; + +static void ipi_handle(const void *arg) +{ + const struct ipi_cfg *cfg = ((struct device *)arg)->config; + struct ipi_data *data = ((struct device *)arg)->data; + + if (data->handler != NULL) { + data->handler(arg, data->handler_arg); + } + /* clear IPI IRQ from CPU */ + cfg->ipi->int2cirq &= ~(CPU2DSP_IRQ); +} + +static void ipi_isr(const void *arg) +{ + ipi_handle(ipi_dev); +} + +#define DEF_IRQ(N) \ + { IRQ_CONNECT(DT_INST_IRQN(N), 0, ipi_isr, DEVICE_DT_INST_GET(N), 0); \ + irq_enable(DT_INST_IRQN(N)); } + +static int ipi_init(void) +{ + DEF_IRQ(0); + return 0; +} + +SYS_INIT(ipi_init, POST_KERNEL, 0); + +#define DEF_DEV(N) \ + static struct ipi_data dev_data##N; \ + static const struct ipi_cfg dev_cfg##N = \ + { .ipi = (void *)DT_INST_REG_ADDR(N), }; \ + DEVICE_DT_INST_DEFINE(N, NULL, NULL, &dev_data##N, &dev_cfg##N, \ + POST_KERNEL, 0, NULL); + +DEF_DEV(0); diff --git a/soc/mediatek/mt8xxx/irq.c b/soc/mediatek/mt8xxx/irq.c index 6227c9d2cd039..a7245fb381f72 100644 --- a/soc/mediatek/mt8xxx/irq.c +++ b/soc/mediatek/mt8xxx/irq.c @@ -35,6 +35,12 @@ static const struct device *irq_dev(unsigned int *irq_inout) } __ASSERT_NO_MSG(lvl1 == 2); return DEVICE_DT_GET(DT_INST(1, mediatek_adsp_intc)); +#elif defined(CONFIG_SOC_SERIES_MT8365) + /* Controller 0 is on Xtensa vector 1 */ + if ((*irq_inout & 0xff) == 1) { + *irq_inout = (*irq_inout >> 8) - 1; + } + return DEVICE_DT_GET(DT_INST(0, mediatek_adsp_intc)); #else /* Only one on 818x */ return DEVICE_DT_GET(DT_INST(0, mediatek_adsp_intc)); @@ -50,6 +56,12 @@ void z_soc_irq_enable(unsigned int irq) if (irq < 25) { *(volatile uint32_t*)(DT_REG_ADDR(DT_NODELABEL(intc2))) |= BIT(irq); } +#elif defined(CONFIG_SOC_SERIES_MT8365) + if (irq >= 2 && irq <= 5) { + const struct device *dev = + DEVICE_DT_GET(DT_INST(0, mediatek_adsp_intc)); + intc_mtk_adsp_set_enable(dev, irq - 2, true); + } #endif } else { const struct device *dev = irq_dev(&irq); @@ -66,6 +78,12 @@ void z_soc_irq_disable(unsigned int irq) if (irq < 25) { *(volatile uint32_t*)(DT_REG_ADDR(DT_NODELABEL(intc2))) &= ~BIT(irq); } +#elif defined(CONFIG_SOC_SERIES_MT8365) + if (irq >= 2 && irq <= 5) { + const struct device *dev = + DEVICE_DT_GET(DT_INST(0, mediatek_adsp_intc)); + intc_mtk_adsp_set_enable(dev, irq - 2, false); + } #endif } else { const struct device *dev = irq_dev(&irq); diff --git a/soc/mediatek/mt8xxx/mt8365/Kconfig.defconfig b/soc/mediatek/mt8xxx/mt8365/Kconfig.defconfig new file mode 100644 index 0000000000000..3471a076c7d74 --- /dev/null +++ b/soc/mediatek/mt8xxx/mt8365/Kconfig.defconfig @@ -0,0 +1,12 @@ +# Copyright 2025 Mediatek +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_MT8365 + +config NUM_2ND_LEVEL_AGGREGATORS + default 1 + +config 2ND_LVL_INTR_00_OFFSET + default 1 + +endif # SOC_SERIES_MT8365 diff --git a/soc/mediatek/mt8xxx/mt8365/linker.ld b/soc/mediatek/mt8xxx/mt8365/linker.ld new file mode 100644 index 0000000000000..41361ef15a664 --- /dev/null +++ b/soc/mediatek/mt8xxx/mt8365/linker.ld @@ -0,0 +1,5 @@ +/* Copyright 2025 Mediatek + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../linker.ld" diff --git a/soc/mediatek/mt8xxx/mt8365/soc.h b/soc/mediatek/mt8xxx/mt8365/soc.h new file mode 100644 index 0000000000000..5db5ce6dd4ca1 --- /dev/null +++ b/soc/mediatek/mt8xxx/mt8365/soc.h @@ -0,0 +1,10 @@ +/* Copyright 2025 Mediatek + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_MT8365_SOC_H +#define ZEPHYR_SOC_MT8365_SOC_H + +#include "../soc.h" + +#endif /* ZEPHYR_SOC_MT8365_SOC_H */ diff --git a/soc/mediatek/mt8xxx/soc.c b/soc/mediatek/mt8xxx/soc.c index 218c21c2fec67..573d4e43bfef3 100644 --- a/soc/mediatek/mt8xxx/soc.c +++ b/soc/mediatek/mt8xxx/soc.c @@ -13,6 +13,12 @@ extern char _mtk_adsp_sram_end[]; #define SRAM_SIZE DT_REG_SIZE(DT_NODELABEL(sram0)) #define SRAM_END (SRAM_START + SRAM_SIZE) +#ifdef CONFIG_SOC_MT8365 +#define SRAM1_START DT_REG_ADDR(DT_NODELABEL(sram1)) +#define SRAM1_SIZE DT_REG_SIZE(DT_NODELABEL(sram1)) +#define SRAM1_END (SRAM1_START + SRAM1_SIZE) +#endif + extern char _mtk_adsp_dram_end[]; #define DRAM_START DT_REG_ADDR(DT_NODELABEL(dram0)) @@ -195,7 +201,12 @@ static void enable_mpu(void) static const uint32_t mpu[][2] = { { 0x00000000, 0x06000 }, /* inaccessible null region */ { 0x10000000, 0x06f00 }, /* MMIO registers */ +#ifndef CONFIG_SOC_MT8365 { 0x1d000000, 0x06000 }, /* inaccessible */ +#else + { SRAM1_START, 0xf7f00 }, /* cached SRAM */ + { SRAM1_END, 0x06000 }, /* inaccessible */ +#endif { SRAM_START, 0xf7f00 }, /* cached SRAM */ { SRAM_END, 0x06000 }, /* inaccessible */ { DRAM_START, 0xf7f00 }, /* cached DRAM */ diff --git a/soc/mediatek/mt8xxx/soc.h b/soc/mediatek/mt8xxx/soc.h index 6857547ea2afb..c4b2a44592194 100644 --- a/soc/mediatek/mt8xxx/soc.h +++ b/soc/mediatek/mt8xxx/soc.h @@ -26,4 +26,12 @@ void mtk_adsp_mbox_set_handler(const struct device *mbox, uint32_t chan, /* Signal an interrupt on the specified channel for the other side */ void mtk_adsp_mbox_signal(const struct device *mbox, uint32_t chan); +typedef void (*mtk_adsp_ipi_handler_t)(const struct device *ipi, void *arg); + +void mtk_adsp_ipi_set_handler(const struct device *ipi, uint32_t chan, + mtk_adsp_ipi_handler_t handler, void *arg); + +/* Signal an interrupt on the specified channel for the other side */ +void mtk_adsp_ipi_signal(const struct device *ipi, uint32_t chan); + #endif /* ZEPHYR_SOC_MTK_SOC_H */ diff --git a/soc/mediatek/mt8xxx/soc.yml b/soc/mediatek/mt8xxx/soc.yml index fd5cd68b04e0b..987d56c0f4137 100644 --- a/soc/mediatek/mt8xxx/soc.yml +++ b/soc/mediatek/mt8xxx/soc.yml @@ -19,3 +19,8 @@ family: - name: mt8196 cpuclusters: - name: adsp + - name: mt8365 + socs: + - name: mt8365 + cpuclusters: + - name: adsp