soc/mediatek: Add support for MediaTek firmware support package

Starting from MT8196, MediaTek platform introudces a new blob named
MediaTek firmware support package (mtk-fsp). The features of mtk-fsp
include but not limit to,
- Security settings, e.g: Device Access Proctection Control, Security
  Memory Protection Unit.
- Initialization for advanced CPU frequency control.

This patch implements APIs for
1) Exchanging data between coreboot and mtk-fsp.
2) Loading and running the mtk-fsp blob at a specific bootstage.

BUG=b:373797027
TEST=emerge-rauru coreboot; Run mock blob and return from mock blob.

Change-Id: Idef3518f9763fe5f74adb459c137db164563e483
Signed-off-by: Yidi Lin <yidilin@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/85665
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Yidi Lin 2024-12-19 15:44:25 +08:00
commit 1380ed0cd2
4 changed files with 184 additions and 0 deletions

View file

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
#ifndef __SOC_MEDIATEK_COMMON_INCLUDE_SOC_MTK_FSP_H__
#define __SOC_MEDIATEK_COMMON_INCLUDE_SOC_MTK_FSP_H__
#include <soc/mtk_fsp_common.h>
void mtk_fsp_init(enum fsp_phase phase);
enum cb_err mtk_fsp_add_param(enum fsp_param_type type, size_t param_size,
void *param);
enum cb_err mtk_fsp_load_and_run(void);
#endif /* __SOC_MEDIATEK_COMMON_INCLUDE_SOC_MTK_FSP_H__ */

View file

@ -0,0 +1,61 @@
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
#ifndef __COMMON_INCLUDE_MTK_FSP_COMMON_H__
#define __COMMON_INCLUDE_MTK_FSP_COMMON_H__
#include <stdarg.h>
#include <stdint.h>
#define INTF_MAJOR_VER 1
#define INTF_MINOR_VER 0
enum fsp_status {
FSP_STATUS_SUCCESS = 0,
FSP_STATUS_INVALID_VERSION,
};
enum fsp_phase {
ROMSTAGE_INIT = 0x30,
RAMSTAGE_MAINBOARD_INIT = 0x40,
RAMSTAGE_SOC_INIT = 0x50,
};
enum fsp_param_io {
FSP_PARAM_IO_INVALID = 0,
FSP_PARAM_IO_IN,
FSP_PARAM_IO_OUT,
FSP_PARAM_IO_INOUT,
};
#define FSP_PARAM_IO_ENCODE(x) ((uint32_t)(x) << 30)
enum fsp_param_type {
FSP_PARAM_TYPE_INVALID = 0,
/* 0x40000000+ reserved for input type params */
FSP_PARAM_TYPE_IN = FSP_PARAM_IO_ENCODE(FSP_PARAM_IO_IN),
/* 0x80000000+ reserved for output type params */
FSP_PARAM_TYPE_OUT = FSP_PARAM_IO_ENCODE(FSP_PARAM_IO_OUT),
/* 0xC0000000+ reserved for the params that support both input and output */
FSP_PARAM_TYPE_INOUT = FSP_PARAM_IO_ENCODE(FSP_PARAM_IO_INOUT),
};
struct mtk_fsp_intf {
uint8_t major_version;
uint8_t minor_version;
uint16_t header_size;
uint32_t phase; /* enum fsp_phase */
int32_t status; /* enum fsp_status */
uint16_t entry_size;
uint8_t num_entries;
uint8_t reserved;
int (*do_vprintf)(const char *fmt, va_list args);
struct mtk_fsp_param {
uint32_t param_type;
uint32_t param_size;
void *param;
} entries[];
};
#endif /* __COMMON_INCLUDE_MTK_FSP_COMMON_H__ */

View file

@ -0,0 +1,108 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <cbfs.h>
#include <console/console.h>
#include <soc/mtk_fsp.h>
#define MAX_PARAM_ENTRIES 32
#define FSP_INTF_SIZE (sizeof(struct mtk_fsp_intf) + \
sizeof(struct mtk_fsp_param) * MAX_PARAM_ENTRIES)
static struct mtk_fsp_intf *intf;
static uint8_t fsp_intf_buf[FSP_INTF_SIZE] __aligned(8);
static int vprintf_wrapper(const char *fmt, va_list args)
{
return vprintk(BIOS_INFO, fmt, args);
}
void mtk_fsp_init(enum fsp_phase phase)
{
intf = (struct mtk_fsp_intf *)fsp_intf_buf;
intf->major_version = INTF_MAJOR_VER;
intf->minor_version = INTF_MINOR_VER;
intf->header_size = sizeof(struct mtk_fsp_intf);
intf->entry_size = sizeof(struct mtk_fsp_param);
intf->num_entries = 0;
intf->phase = phase;
intf->do_vprintf = vprintf_wrapper;
}
enum cb_err mtk_fsp_add_param(enum fsp_param_type type, size_t param_size,
void *param)
{
struct mtk_fsp_param *entry;
if (!intf) {
printk(BIOS_ERR, "%s: intf is not initialized\n", __func__);
return CB_ERR;
}
if (intf->num_entries == MAX_PARAM_ENTRIES) {
printk(BIOS_ERR, "%s: run out all entries\n", __func__);
return CB_ERR;
}
entry = &intf->entries[intf->num_entries];
entry->param_type = type;
entry->param_size = param_size;
entry->param = param;
intf->num_entries++;
return CB_SUCCESS;
}
static void mtk_fsp_dump_intf(void)
{
struct mtk_fsp_param *entry;
if (!intf) {
printk(BIOS_ERR, "%s: intf is not initialized\n", __func__);
return;
}
printk(BIOS_DEBUG, "%s: major version: %u, minor version: %u\n",
__func__, intf->major_version, intf->minor_version);
printk(BIOS_DEBUG, "%s: FSP phase: %u, status: %d\n",
__func__, intf->phase, intf->status);
printk(BIOS_DEBUG, "%-5s %-10s %-10s %s\n", "Param", "type", "size", "address");
for (int i = 0; i < intf->num_entries; i++) {
entry = &intf->entries[i];
printk(BIOS_DEBUG, "%-5u %-10u %-10u %p\n",
i, entry->param_type, entry->param_size, entry->param);
}
}
static const char *mtk_fsp_file(void)
{
return CONFIG_CBFS_PREFIX "/mtk_fsp_" ENV_STRING;
}
enum cb_err mtk_fsp_load_and_run(void)
{
struct prog fsp = PROG_INIT(PROG_REFCODE, mtk_fsp_file());
if (cbfs_prog_stage_load(&fsp)) {
printk(BIOS_ERR, "%s: CBFS load program failed\n", __func__);
return CB_ERR;
}
if (!intf) {
printk(BIOS_ERR, "%s: intf is not initialized\n", __func__);
return CB_ERR;
}
prog_set_arg(&fsp, intf);
prog_run(&fsp);
if (intf->status != FSP_STATUS_SUCCESS) {
mtk_fsp_dump_intf();
return CB_ERR;
}
printk(BIOS_INFO, "%s: run %s at phase %#x done\n",
__func__, mtk_fsp_file(), intf->phase);
return CB_SUCCESS;
}

View file

@ -34,6 +34,7 @@ romstage-y += ../common/memory_test.c
romstage-y += ../common/mmu_operations.c ../common/mmu_cmops.c
romstage-y += ../common/mt6363.c mt6363.c
romstage-y += ../common/mt6373.c mt6373.c
romstage-y += ../common/mtk_fsp.c
romstage-y += mtk_pwrsel.c
romstage-y += ../common/pmif_clk.c pmif_clk.c
romstage-y += ../common/pmif.c pmif_init.c
@ -52,6 +53,7 @@ ramstage-$(CONFIG_COMMONLIB_STORAGE_MMC) += msdc.c
ramstage-y += ../common/mt6363.c mt6363.c
ramstage-y += ../common/mt6363_sdmadc.c
ramstage-y += ../common/mt6373.c mt6373.c
ramstage-y += ../common/mtk_fsp.c
ramstage-y += soc.c
ramstage-y += ../common/spm.c spm.c
ramstage-y += ../common/sspm.c sspm_sram.c