diff --git a/src/soc/mediatek/mt8189/Kconfig b/src/soc/mediatek/mt8189/Kconfig index d6f4ca91dc..430b868582 100644 --- a/src/soc/mediatek/mt8189/Kconfig +++ b/src/soc/mediatek/mt8189/Kconfig @@ -36,6 +36,12 @@ config DPM_PM_FIRMWARE help The file name of the MediaTek DPM PM firmware. +config MCUPM_FIRMWARE + string + default "mcupm.bin" + help + The file name of the MediaTek MCUPM firmware. + config SPM_FIRMWARE string default "spm_firmware.bin" diff --git a/src/soc/mediatek/mt8189/Makefile.mk b/src/soc/mediatek/mt8189/Makefile.mk index 78d523b36e..fc1f8ff8f9 100644 --- a/src/soc/mediatek/mt8189/Makefile.mk +++ b/src/soc/mediatek/mt8189/Makefile.mk @@ -34,7 +34,7 @@ ramstage-$(CONFIG_ARM64_USE_ARM_TRUSTED_FIRMWARE) += ../common/bl31.c ramstage-y += ../common/dpm.c ../common/dpm_v2.c ramstage-y += ../common/dramc_info.c ramstage-y += ../common/emi.c -ramstage-y += ../common/mcu.c +ramstage-y += ../common/mcu.c mcupm.c ramstage-y += ../common/memory.c ramstage-y += ../common/mmu_operations.c ../common/mmu_cmops.c ramstage-y += ../common/mt6315.c mt6315.c @@ -58,6 +58,7 @@ MT8189_BLOB_DIR := 3rdparty/blobs/soc/mediatek/mt8189 firmware-files := \ $(CONFIG_DPM_DM_FIRMWARE) \ $(CONFIG_DPM_PM_FIRMWARE) \ + $(CONFIG_MCUPM_FIRMWARE) \ $(CONFIG_SPM_FIRMWARE) $(foreach fw, $(call strip_quotes,$(firmware-files)), \ diff --git a/src/soc/mediatek/mt8189/include/soc/addressmap.h b/src/soc/mediatek/mt8189/include/soc/addressmap.h index 3f6fe3e598..41d6557c7d 100644 --- a/src/soc/mediatek/mt8189/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8189/include/soc/addressmap.h @@ -4,10 +4,13 @@ #define __SOC_MEDIATEK_MT8189_INCLUDE_SOC_ADDRESSMAP_H__ enum { - MCUCFG_BASE = 0x0C530000, - DBGAO_BASE = 0x0D01A000, - DEM_BASE = 0x0D0A0000, - IO_PHYS = 0x10000000, + GIC_BASE = 0x0C000000, + MCUCFG_BASE = 0x0C530000, + MCUPM_SRAM_BASE = 0x0C540000, + MCUPM_CFG_BASE = 0x0C580000, + DBGAO_BASE = 0x0D01A000, + DEM_BASE = 0x0D0A0000, + IO_PHYS = 0x10000000, }; enum { diff --git a/src/soc/mediatek/mt8189/include/soc/mcupm_plat.h b/src/soc/mediatek/mt8189/include/soc/mcupm_plat.h new file mode 100644 index 0000000000..4d8bc706e0 --- /dev/null +++ b/src/soc/mediatek/mt8189/include/soc/mcupm_plat.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#ifndef __SOC_MEDIATEK_MT8189_INCLUDE_SOC_MCUPM_PLAT_H__ +#define __SOC_MEDIATEK_MT8189_INCLUDE_SOC_MCUPM_PLAT_H__ + +#include + +#define MCUPM_SW_RSTN MCUPM_CFG_BASE + +/* + * SPM config: + * Enable register access key, POWERON_CONFIG_EN = 0x0B160001 + */ +#define DEVAPC_INFRA_SECU_AO_SEC_REPLACE_0 (DEVAPC_INFRA_SECU_AO_BASE + 0x0300) +#define POLLING_ACK_RETRY_COUNTS 10 +#define POLLING_SRAM_RETRY_COUNTS 10 + +/* CPUEB_PWR_CON (0x1C001000+0xEB4) */ +#define CPUEB_PWR_RST_B_LSB BIT(0) +#define CPUEB_PWR_ISO_LSB BIT(1) +#define CPUEB_PWR_ON_LSB BIT(2) +#define CPUEB_PWR_ON_2ND_LSB BIT(3) +#define CPUEB_PWR_CLK_DIS_LSB BIT(4) +#define CPUEB_SRAM_CKISO_LSB BIT(5) +#define CPUEB_SRAM_ISOINT_B_LSB BIT(6) +#define CPUEB_SRAM_PDN_LSB BIT(8) +#define CPUEB_SRAM_SLEEP_B_LSB BIT(9) +#define SC_CPUEB_SRAM_PDN_ACK_LSB BIT(12) +#define SC_CPUEB_SRAM_SLEEP_B_ACK_LSB BIT(13) +#define SC_CPUEB_PWR_ACK_LSB BIT(30) +#define SC_CPUEB_PWR_ACK_2ND_LSB BIT(31) + +#define MCUPM_SRAM_SIZE 0x30000 /* 192K Bytes */ + +#define MCUPM_LOADER_SIZE 0x2300 /* CFG_MTCMOS_OFF_SUPPORT */ +#define MCUPM_TCM_SZ 0x30000 /* 192K */ +#define MCUPM_IMG_OFS 0x2300 /* CFG_MTCMOS_OFF_SUPPORT */ +#define MCUPM_RDMP_OFS 0x30000 + +#define ABNORMALBOOT_REG_STATUS 0x0 +#define WARMBOOT_REG_STATUS 0x0 +#define MCUPM_RSTN_RESET 0x1F +#define MCUPM_RSTN_RSTN_INIT 0x0 +#define MCUPM_CFGREG_SW_RSTN_SW_RSTN BIT(0) +#define MCUPM_CFGREG_SW_RSTN_DMA_BUSY_MASK BIT(1) + +#define MCUPM_GPR_SIZE 0x64 +#define SRAM_GPR_SIZE 0x4 /* 4 Bytes */ +#define IPI_NUMBER 8 +#define IPI_MBOX_TOTAL IPI_NUMBER +#define MBOX_SLOT_SIZE 0x4 +#define SRAM_SLOT_NUM 0x14 /* 0x14 = 20 slots = 20*4Bytes = 80 Bytes */ +#define PIN_S_NUM SRAM_SLOT_NUM +#define PIN_R_NUM SRAM_SLOT_NUM +#define MBOX_TABLE_NUM (PIN_S_NUM + PIN_R_NUM) + +#define GPR_BASE_ADDR_MCU(x) (MCUPM_SRAM_BASE + \ + MCUPM_SRAM_SIZE - \ + (IPI_MBOX_TOTAL * MBOX_TABLE_NUM * MBOX_SLOT_SIZE) - \ + MCUPM_GPR_SIZE + \ + ((x) * SRAM_GPR_SIZE)) + +#define MCUPM_INFO GPR_BASE_ADDR_MCU(0) +#define ABNORMALBOOT_REG GPR_BASE_ADDR_MCU(1) +#define WARMBOOT_REG GPR_BASE_ADDR_MCU(23) + +#endif diff --git a/src/soc/mediatek/mt8189/include/soc/spm.h b/src/soc/mediatek/mt8189/include/soc/spm.h index b0be7d2990..1e47d3a21c 100644 --- a/src/soc/mediatek/mt8189/include/soc/spm.h +++ b/src/soc/mediatek/mt8189/include/soc/spm.h @@ -1027,6 +1027,7 @@ check_member(mtk_spm_regs, dp_tx_pwr_con, 0x0E80); check_member(mtk_spm_regs, scp_peri_pwr_con, 0x0E88); check_member(mtk_spm_regs, csi_rx_pwr_con, 0x0E9C); check_member(mtk_spm_regs, ssusb_pwr_con, 0x0EA8); +check_member(mtk_spm_regs, cpueb_pwr_con, 0x0EB0); check_member(mtk_spm_regs, mfg0_pwr_con, 0x0EB4); check_member(mtk_spm_regs, mfg3_pwr_con, 0x0EC0); check_member(mtk_spm_regs, pwr_status, 0x0F40); diff --git a/src/soc/mediatek/mt8189/mcupm.c b/src/soc/mediatek/mt8189/mcupm.c new file mode 100644 index 0000000000..cf4124f7bf --- /dev/null +++ b/src/soc/mediatek/mt8189/mcupm.c @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void reset_mcupm(struct mtk_mcu *mcu) +{ + /* Clear abnormal boot register */ + write32p(ABNORMALBOOT_REG, ABNORMALBOOT_REG_STATUS); + write32p(WARMBOOT_REG, WARMBOOT_REG_STATUS); + write32(&mcupm_reg->sw_rstn, MCUPM_RSTN_RESET); +} + +static struct mtk_mcu mcupm = { + .firmware_name = CONFIG_MCUPM_FIRMWARE, + .run_address = (void *)MCUPM_SRAM_BASE, + .reset = reset_mcupm, +}; + +void mcupm_init(void) +{ + mcupm.load_buffer = _dram_dma; + mcupm.buffer_size = REGION_SIZE(dram_dma); + + /* Set CPUEB as secure master */ + setbits32(&mtk_spm->poweron_config_set, BIT(15)); + + /* Unlock SPM POWERON_CONFIG_EN */ + setbits32(&mtk_spm->poweron_config_set, SPM_REGWR_CFG_KEY | BCLK_CG_EN_LSB); + + /* Reinit CPUEB_PWR_CON */ + /* (1) CPUEB MTCMOS */ + setbits32(&mtk_spm->cpueb_pwr_con, CPUEB_PWR_ON_LSB); + setbits32(&mtk_spm->cpueb_pwr_con, CPUEB_PWR_ON_2ND_LSB); + u32 pwr_con_mask = SC_CPUEB_PWR_ACK_LSB | SC_CPUEB_PWR_ACK_2ND_LSB; + if (!retry(POLLING_ACK_RETRY_COUNTS, + ((read32(&mtk_spm->cpueb_pwr_con) & pwr_con_mask) == pwr_con_mask), + udelay(1))) { + printk(BIOS_ERR, "%s Polling ACK timeout, %#x\n", __func__, + read32(&mtk_spm->cpueb_pwr_con)); + return; + } + + clrbits32(&mtk_spm->cpueb_pwr_con, CPUEB_PWR_CLK_DIS_LSB); + clrbits32(&mtk_spm->cpueb_pwr_con, CPUEB_PWR_ISO_LSB); + setbits32(&mtk_spm->cpueb_pwr_con, CPUEB_PWR_RST_B_LSB); + + /* (2) SRAM leave DORMANT mode */ + setbits32(&mtk_spm->cpueb_pwr_con, CPUEB_SRAM_SLEEP_B_LSB); + if (!retry(POLLING_ACK_RETRY_COUNTS, + ((read32(&mtk_spm->cpueb_pwr_con) & SC_CPUEB_SRAM_SLEEP_B_ACK_LSB) != 0), + udelay(1))) { + printk(BIOS_ERR, "%s Polling SRAM Sleep B ACK timeout, %#x\n", __func__, + read32(&mtk_spm->cpueb_pwr_con)); + return; + } + + udelay(1); + setbits32(&mtk_spm->cpueb_pwr_con, CPUEB_SRAM_ISOINT_B_LSB); + clrbits32(&mtk_spm->cpueb_pwr_con, CPUEB_SRAM_CKISO_LSB); + + /* Power on MCUPM sram */ + clrbits32(&mtk_spm->cpueb_pwr_con, CPUEB_SRAM_PDN_LSB); + pwr_con_mask = SC_CPUEB_SRAM_PDN_ACK_LSB; + if (!retry(POLLING_SRAM_RETRY_COUNTS, + (read32(&mtk_spm->cpueb_pwr_con) & pwr_con_mask) != pwr_con_mask, + udelay(1))) { + printk(BIOS_ERR, "%s Polling SRAM Power on timeout, %#x\n", __func__, + read32(&mtk_spm->cpueb_pwr_con)); + return; + } + + printk(BIOS_INFO, "%s Power on MCUPM SRAM success\n", __func__); + + write32(&mcupm_reg->sw_rstn, MCUPM_RSTN_RSTN_INIT); + if (mtk_init_mcu(&mcupm)) + die("%s() mtk_init_mcu failed\n", __func__); + + setbits32p(MCUPM_SW_RSTN, + MCUPM_CFGREG_SW_RSTN_SW_RSTN | MCUPM_CFGREG_SW_RSTN_DMA_BUSY_MASK); + + printk(BIOS_DEBUG, "mcupm: MCUPM_SRAM_GPR0: %#x, %#x\n", + MCUPM_INFO, read32p(MCUPM_INFO)); + printk(BIOS_DEBUG, "mcupm: MCUPM_SRAM_GPR1: %#x, %#x\n", + ABNORMALBOOT_REG, read32p(ABNORMALBOOT_REG)); + printk(BIOS_DEBUG, "mcupm: MCUPM_SRAM_GPR23: %#x, %#x\n", + WARMBOOT_REG, read32p(WARMBOOT_REG)); + printk(BIOS_DEBUG, "mcupm: MCUPM_SW_RSTN: %#x, %#x\n", + MCUPM_SW_RSTN, read32p(MCUPM_SW_RSTN)); + printk(BIOS_DEBUG, "mcupm: MCUPM_SRAM_BASE: %#x, %#x\n", + MCUPM_SRAM_BASE, read32p(MCUPM_SRAM_BASE)); + printk(BIOS_DEBUG, "%s MCUPM part. load & reset finished\n", __func__); +} diff --git a/src/soc/mediatek/mt8189/soc.c b/src/soc/mediatek/mt8189/soc.c index e53136d16b..93f6a4264c 100644 --- a/src/soc/mediatek/mt8189/soc.c +++ b/src/soc/mediatek/mt8189/soc.c @@ -4,6 +4,7 @@ #include #include #include +#include #include void bootmem_platform_add_ranges(void) @@ -18,6 +19,7 @@ static void soc_read_resources(struct device *dev) static void soc_init(struct device *dev) { + mcupm_init(); } static struct device_operations soc_ops = {