soc/mediatek/mt8196: Initialize MCUPM
Load MCUPM firmware and boot up MCUPM in ramstage. It takes 54 ms to load mcupm.bin. coreboot logs: CBFS: Found 'mcupm.bin' @0x37a80 size 0xdbda in mcache @0xfffdd308 mtk_init_mcu: Loaded (and reset) mcupm.bin in 54 msecs (486931 bytes) TEST=Build pass and we can see the mcupm logs after reset releases. BUG=b:317009620 Change-Id: I223f245d384f32d54f6170a28b29573638f77296 Signed-off-by: Agogo Huang <agogo.huang@mediatek.corp-partner.google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/85888 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Yidi Lin <yidilin@google.com> Reviewed-by: Yu-Ping Wu <yupingso@google.com>
This commit is contained in:
parent
928189fd04
commit
c5f6daba81
6 changed files with 235 additions and 1 deletions
|
|
@ -57,4 +57,10 @@ config GPUEB_FIRMWARE
|
|||
help
|
||||
The file name of the MediaTek GPUEB firmware.
|
||||
|
||||
config MCUPM_FIRMWARE
|
||||
string
|
||||
default "mcupm.bin"
|
||||
help
|
||||
The file name of the MediaTek MCUPM firmware.
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ ramstage-y += ../common/early_init.c
|
|||
ramstage-y += ../common/emi.c
|
||||
ramstage-y += gpueb.c
|
||||
ramstage-y += l2c_ops.c
|
||||
ramstage-y += ../common/mcu.c
|
||||
ramstage-y += ../common/mcu.c mcupm.c
|
||||
ramstage-y += ../common/mmu_operations.c ../common/mmu_cmops.c
|
||||
ramstage-$(CONFIG_PCI) += ../common/pcie.c pcie.c
|
||||
ramstage-$(CONFIG_COMMONLIB_STORAGE_MMC) += msdc.c
|
||||
|
|
@ -80,6 +80,7 @@ mcu-firmware-files := \
|
|||
$(CONFIG_DPM_DM_FIRMWARE) \
|
||||
$(CONFIG_DPM_PM_FIRMWARE) \
|
||||
$(CONFIG_GPUEB_FIRMWARE) \
|
||||
$(CONFIG_MCUPM_FIRMWARE) \
|
||||
$(CONFIG_SSPM_FIRMWARE) \
|
||||
$(CONFIG_SPM_FIRMWARE)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
enum {
|
||||
MCUSYS_BASE = 0x0C000000,
|
||||
MCUPM_CFG_BASE = 0x0C240000,
|
||||
MCUPM_SRAM_BASE = 0x0C250000,
|
||||
BUS_TRACE_MONITOR_BASE = 0x0D040000,
|
||||
IO_PHYS = 0x10000000,
|
||||
MFGSYS_BASE = 0x40000000,
|
||||
|
|
@ -45,6 +46,7 @@ enum {
|
|||
APINFRA_IO_AO_DEBUG_BASE = IO_PHYS + 0x00155000,
|
||||
APINFRA_IO_CTRL_AO_BCRM_BASE = IO_PHYS + 0x00156000,
|
||||
APINFRA_IO_CTRL_AO_DEBUG_BASE = IO_PHYS + 0x00157000,
|
||||
DEVAPC_INFRA_SECU_AO_BASE = IO_PHYS + 0x001C8000,
|
||||
DRAMC_CHA_AO_BASE = IO_PHYS + 0x00230000,
|
||||
APINFRA_DRAMC_AO_DEBUG_BASE = IO_PHYS + 0x002F1000,
|
||||
EMI0_BASE = IO_PHYS + 0x00469000,
|
||||
|
|
|
|||
97
src/soc/mediatek/mt8196/include/soc/mcupm_plat.h
Normal file
97
src/soc/mediatek/mt8196/include/soc/mcupm_plat.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
|
||||
|
||||
#ifndef __SOC_MEDIATEK_MT8196_INCLUDE_SOC_MCUPM_PLAT_H__
|
||||
#define __SOC_MEDIATEK_MT8196_INCLUDE_SOC_MCUPM_PLAT_H__
|
||||
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/mcupm_plat.h>
|
||||
#include <types.h>
|
||||
|
||||
#define MCUPM_SW_RSTN (MCUCFG_BASE + 0x00240000)
|
||||
#define CLK_CFG_14 (CKSYS_BASE + 0x000000F0)
|
||||
|
||||
/*
|
||||
* mcusys_par_wrap config
|
||||
*/
|
||||
/* CPU_EB_CLK_SRC_CONFIG */
|
||||
#define CPUEB_CLK_SRC (MCUCFG_BASE + 0x000002E8)
|
||||
|
||||
#define CPUEB_SPMC_STATUS (MCUCFG_BASE + 0x00000B48)
|
||||
#define CPUEB_FSM_STATE_ON 0xF
|
||||
#define CPUEB_FSM_STATE_OFF 0x0
|
||||
#define CPUEB_FSM_STATE_RET 0x1D
|
||||
#define CPUEB_FSM_STATE_FUNC_RET 0x13
|
||||
|
||||
#define CPUEB_SPMC_SEL (MCUCFG_BASE + 0x00000B4C)
|
||||
|
||||
#define MCU_PORT_SET_W1C_0 (IFRBUS_AO_REG_BUS_BASE + 0x00000708)
|
||||
#define CPUEB_PROTECT_EN_0 BIT(8)
|
||||
#define CPUEB_PROTECT_EN_1 BIT(9)
|
||||
#define MCU_PORT_SET_R0_0 (IFRBUS_AO_REG_BUS_BASE + 0x0000070C)
|
||||
#define CPUEB_PROTECT_RDY_0 BIT(8)
|
||||
#define CPUEB_PROTECT_RDY_1 BIT(9)
|
||||
|
||||
/*
|
||||
* SPM config:
|
||||
* Enable register access key, POWERON_CONFIG_EN = 0x0B160001
|
||||
*/
|
||||
#define POWERON_CONFIG_EN_MCU (SPM_BASE + 0x000)
|
||||
#define SPM_PROJECT_CODE 0xB16
|
||||
#define SPM_REGWR_CFG_KEY (SPM_PROJECT_CODE << 16)
|
||||
/* POWERON_CONFIG_EN */
|
||||
#define BCLK_CG_EN_LSB BIT(0)
|
||||
/* CPUEB SPMC Control */
|
||||
/* SPM and MCUPM SPMC sideband control */
|
||||
#define SPM_MCUPM_SPMC_CON (SPM_BASE + 0x288)
|
||||
/* 1'b0, SPM power state, 0: invalid, 1: valid */
|
||||
#define CPUEB_STATE_VALID BIT(0)
|
||||
/* 1'b0, power state request for CPUEB */
|
||||
#define REQ_PWR_ON BIT(1)
|
||||
/* 1'b0, memory retention state request for CPUEB */
|
||||
#define REQ_MEM_RET BIT(2)
|
||||
/* 1'b0, spmc finish operation, 0:unfinish, 1:finish */
|
||||
#define CPUEB_STATE_FINISH_ACK BIT(31)
|
||||
|
||||
/* 512K Bytes */
|
||||
#define MCUPM_SRAM_SIZE (512 * KiB)
|
||||
|
||||
/* GPR */
|
||||
#define MCUPM_GPR_SIZE 0x00000070 /* 112 Bytes */
|
||||
/* IPI */
|
||||
#define IPI_NUMBER 16
|
||||
#define IPI_MBOX_TOTAL IPI_NUMBER
|
||||
|
||||
/* MCUPM REG */
|
||||
#define MCUPM_CFGREG_SW_RSTN_SW_RSTN BIT(0)
|
||||
#define MCUPM_CFGREG_SW_RSTN_DMA_BUSY_MASK (BIT(1)|BIT(2)|BIT(3)|BIT(4))
|
||||
|
||||
#define DEVAPC_INFRA_SECU_AO_SEC_REPLACE_0 (DEVAPC_INFRA_SECU_AO_BASE + 0x0300)
|
||||
#define POLLING_MCU_RETRY_COUNTS 10
|
||||
#define POLLING_ACK_RETRY_COUNTS 10
|
||||
#define ABNORMALBOOT_REG_STATUS 0x0
|
||||
#define WARMBOOT_REG_STATUS 0x0
|
||||
#define MCUPM_RSTN_RESET 0x1F
|
||||
#define MCUPM_RSTN_RSTN_INIT 0x0
|
||||
|
||||
#define CPUEB_SPMC_STATUS_OFFSET 3
|
||||
#define CPUEB_SPMC_STATUS_MASK 0x3F
|
||||
|
||||
#define SRAM_GPR_SIZE 0x4 /* 4 Bytes */
|
||||
|
||||
#define MBOX_SLOT_SIZE 0x4
|
||||
/* 0x14 = 20 slots = 20*4Bytes = 80 Bytes */
|
||||
#define SRAM_SLOT_NUM 0x14
|
||||
#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 ABNORMALBOOT_REG GPR_BASE_ADDR_MCU(1)
|
||||
#define WARMBOOT_REG GPR_BASE_ADDR_MCU(23)
|
||||
|
||||
#endif /* __SOC_MEDIATEK_MT8196_INCLUDE_SOC_MCUPM_PLAT_H__ */
|
||||
126
src/soc/mediatek/mt8196/mcupm.c
Normal file
126
src/soc/mediatek/mt8196/mcupm.c
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
|
||||
|
||||
#include <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <device/mmio.h>
|
||||
#include <soc/mcu_common.h>
|
||||
#include <soc/mcupm.h>
|
||||
#include <soc/mcupm_plat.h>
|
||||
#include <soc/symbols.h>
|
||||
|
||||
static int eb_sleep_protect(void)
|
||||
{
|
||||
/* Set MCU_PORT_SET_W1C_0[9:8] = 2'b11 */
|
||||
setbits32p(MCU_PORT_SET_W1C_0, CPUEB_PROTECT_EN_0 | CPUEB_PROTECT_EN_1);
|
||||
|
||||
/* Poll MCU_PORT_SET_R0_0[9:8] = 2'b00 */
|
||||
if (!retry(POLLING_MCU_RETRY_COUNTS,
|
||||
(read32p(MCU_PORT_SET_R0_0) &
|
||||
(CPUEB_PROTECT_RDY_0 | CPUEB_PROTECT_RDY_1)) == 0, udelay(1))) {
|
||||
printk(BIOS_ERR,
|
||||
"[EB_SPMC] CPUEB_PROTECT_RDY not set after %d us, value %#x\n",
|
||||
POLLING_MCU_RETRY_COUNTS, read32p(MCU_PORT_SET_R0_0));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_cpueb_state(bool state_valid)
|
||||
{
|
||||
if (state_valid)
|
||||
setbits32p(SPM_MCUPM_SPMC_CON, CPUEB_STATE_VALID);
|
||||
else
|
||||
clrbits32p(SPM_MCUPM_SPMC_CON, CPUEB_STATE_VALID);
|
||||
|
||||
if (!retry(POLLING_ACK_RETRY_COUNTS,
|
||||
((read32p(SPM_MCUPM_SPMC_CON) & CPUEB_STATE_FINISH_ACK) != 0) == state_valid,
|
||||
udelay(1))) {
|
||||
printk(BIOS_ERR, "[EB_SPMC] Polling ACK timeout, %#x\n",
|
||||
read32p(SPM_MCUPM_SPMC_CON));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eb_spmc_spm(void)
|
||||
{
|
||||
/* Unlock SPM POWERON_CONFIG_EN */
|
||||
setbits32p(POWERON_CONFIG_EN_MCU, SPM_REGWR_CFG_KEY | BCLK_CG_EN_LSB);
|
||||
|
||||
/* Set REQ_PWR_ON = 1 and REQ_MEM_RET = 0 */
|
||||
setbits32p(SPM_MCUPM_SPMC_CON, REQ_PWR_ON);
|
||||
|
||||
clrbits32p(SPM_MCUPM_SPMC_CON, REQ_MEM_RET);
|
||||
|
||||
/* Set CPUEB_STATE_VALID = 1 */
|
||||
if (set_cpueb_state(true))
|
||||
return -1;
|
||||
|
||||
/* Set CPUEB_STATE_VALID = 0 */
|
||||
if (set_cpueb_state(false))
|
||||
return -1;
|
||||
|
||||
return eb_sleep_protect();
|
||||
}
|
||||
|
||||
static int eb_spmc(void)
|
||||
{
|
||||
uint32_t spmc_status = (read32p(CPUEB_SPMC_STATUS) >> CPUEB_SPMC_STATUS_OFFSET) &
|
||||
CPUEB_SPMC_STATUS_MASK;
|
||||
int ret;
|
||||
|
||||
switch (spmc_status) {
|
||||
case CPUEB_FSM_STATE_OFF:
|
||||
case CPUEB_FSM_STATE_ON:
|
||||
case CPUEB_FSM_STATE_RET:
|
||||
case CPUEB_FSM_STATE_FUNC_RET:
|
||||
printk(BIOS_INFO, "[EB_SPMC] spmc_status = %#x\n", spmc_status);
|
||||
ret = eb_spmc_spm();
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_ERR, "[EB_SPMC] EB SPMC in wrong state, spmc_status = %#x\n",
|
||||
spmc_status);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
write32p(MCUPM_SW_RSTN,
|
||||
MCUPM_CFGREG_SW_RSTN_SW_RSTN | MCUPM_CFGREG_SW_RSTN_DMA_BUSY_MASK);
|
||||
}
|
||||
|
||||
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 */
|
||||
printk(BIOS_INFO, "Before: DEVAPC_MCUPM = %#x\n",
|
||||
read32p(DEVAPC_INFRA_SECU_AO_SEC_REPLACE_0));
|
||||
setbits32p(DEVAPC_INFRA_SECU_AO_SEC_REPLACE_0, BIT(15));
|
||||
printk(BIOS_INFO, "After: DEVAPC_MCUPM = %#x\n",
|
||||
read32p(DEVAPC_INFRA_SECU_AO_SEC_REPLACE_0));
|
||||
|
||||
if (eb_spmc() != 0)
|
||||
die("%s: eb sram power on failed\n", __func__);
|
||||
write32(&mcupm_reg->sw_rstn, MCUPM_RSTN_RSTN_INIT);
|
||||
if (mtk_init_mcu(&mcupm))
|
||||
die("%s: failed\n", __func__);
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
#include <soc/dramc_info.h>
|
||||
#include <soc/emi.h>
|
||||
#include <soc/gpueb.h>
|
||||
#include <soc/mcupm.h>
|
||||
#include <soc/mmu_operations.h>
|
||||
#include <soc/pcie.h>
|
||||
#include <soc/sspm.h>
|
||||
|
|
@ -35,6 +36,7 @@ static void soc_init(struct device *dev)
|
|||
mtk_mmu_disable_l2c_sram();
|
||||
sspm_init();
|
||||
gpueb_init();
|
||||
mcupm_init();
|
||||
}
|
||||
|
||||
static struct device_operations soc_ops = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue