soc/mediatek/mt8189: Add MCUPM loader

Add MCUPM loader for mt8189.

It takes 36 ms to load mcupm.bin.

coreboot logs:
CBFS: Found 'mcupm.bin' @0x10d00 size 0x7fd6 in mcache @0xffffeb20
mtk_init_mcu: Loaded (and reset) mcupm.bin in 36 msecs (84124 bytes)

BUG=b:379008996
BRANCH=none
TEST=build pass and we can see the mcupm logs after reset releases.

Signed-off-by: Justin Yeh <justin.yeh@mediatek.corp-partner.google.com>
Change-Id: I4f3a4eb63d801df123e45f46fc715c39d858c377
Reviewed-on: https://review.coreboot.org/c/coreboot/+/87758
Reviewed-by: Yidi Lin <yidilin@google.com>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Paul Menzel <paulepanter@mailbox.org>
This commit is contained in:
Justin Yeh 2024-10-29 16:41:00 +08:00 committed by Yidi Lin
commit 368eeb7da4
7 changed files with 185 additions and 5 deletions

View file

@ -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"

View file

@ -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)), \

View file

@ -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 {

View file

@ -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 <soc/addressmap.h>
#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

View file

@ -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);

View file

@ -0,0 +1,100 @@
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
#include <console/console.h>
#include <delay.h>
#include <device/mmio.h>
#include <soc/addressmap.h>
#include <soc/mcu_common.h>
#include <soc/mcupm.h>
#include <soc/mcupm_plat.h>
#include <soc/spm.h>
#include <soc/symbols.h>
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__);
}

View file

@ -4,6 +4,7 @@
#include <device/device.h>
#include <soc/dramc_info.h>
#include <soc/emi.h>
#include <soc/mcupm.h>
#include <symbols.h>
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 = {