Yidi Lin has uploaded this change for review.

View Change

WIP: load spm firmware from cbfs

use mpufw_reserved region for experiment

Change-Id: I563c2d959cc2b597fee137ef1c53ee028e3c20c0
Signed-off-by: Yidi Lin <yidi.lin@mediatek.com>
---
M 3rdparty/amd_blobs
M 3rdparty/blobs
M src/soc/mediatek/mt8192/Makefile.inc
M src/soc/mediatek/mt8192/include/soc/spm.h
A src/soc/mediatek/mt8192/include/soc/symbols.h
M src/soc/mediatek/mt8192/mmu_operations.c
M src/soc/mediatek/mt8192/spm.c
7 files changed, 115 insertions(+), 9 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/87/47287/1
diff --git a/3rdparty/amd_blobs b/3rdparty/amd_blobs
index 335f577..539d31a 160000
--- a/3rdparty/amd_blobs
+++ b/3rdparty/amd_blobs
@@ -1 +1 @@
-Subproject commit 335f577697f7d27353a84b8a156a67a1dbad255f
+Subproject commit 539d31ab9ea89084fa5edf7cc9ac3122786d5454
diff --git a/3rdparty/blobs b/3rdparty/blobs
index 0839a7c..5e8dd64 160000
--- a/3rdparty/blobs
+++ b/3rdparty/blobs
@@ -1 +1 @@
-Subproject commit 0839a7cb848f783b42aa133606c9e109174c4a55
+Subproject commit 5e8dd6456365461e725b53968ef8b82656d86560
diff --git a/src/soc/mediatek/mt8192/Makefile.inc b/src/soc/mediatek/mt8192/Makefile.inc
index ca66095..f348a20 100755
--- a/src/soc/mediatek/mt8192/Makefile.inc
+++ b/src/soc/mediatek/mt8192/Makefile.inc
@@ -31,7 +31,7 @@
romstage-y += emi.c
romstage-y += flash_controller.c
romstage-y += ../common/gpio.c gpio.c
-romstage-y += ../common/mmu_operations.c
+romstage-y += ../common/mmu_operations.c mmu_operations.c
romstage-y += memory.c dramc_param.c ../common/memory_test.c
romstage-$(CONFIG_SPI_FLASH) += ../common/spi.c spi.c
romstage-y += ../common/timer.c
diff --git a/src/soc/mediatek/mt8192/include/soc/spm.h b/src/soc/mediatek/mt8192/include/soc/spm.h
index 53b86e5..1ff8fd2 100644
--- a/src/soc/mediatek/mt8192/include/soc/spm.h
+++ b/src/soc/mediatek/mt8192/include/soc/spm.h
@@ -659,14 +659,19 @@

static struct mtk_spm_regs *const mtk_spm = (void *)SPM_BASE;

-struct spm_desc {
- const char *version;
+struct pcm_desc {
u32 pmem_words;
u32 total_words;
u32 pmem_start;
u32 dmem_start;
};

+struct dyna_load_pcm {
+ u32 *buf; /* binary array */
+ struct pcm_desc desc;
+};
+
+
int spm_init(void);

#endif /* SOC_MEDIATEK_MT8192_SPM_H */
diff --git a/src/soc/mediatek/mt8192/include/soc/symbols.h b/src/soc/mediatek/mt8192/include/soc/symbols.h
new file mode 100644
index 0000000..87a87d3
--- /dev/null
+++ b/src/soc/mediatek/mt8192/include/soc/symbols.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_MEDIATEK_MT8192_SYMBOLS_H_
+#define _SOC_MEDIATEK_MT8192_SYMBOLS_H_
+#include <symbols.h>
+
+DECLARE_REGION(mpufw_reserved)
+
+#endif /* _SOC_MEDIATEK_MT8192_SYMBOLS_H_ */
diff --git a/src/soc/mediatek/mt8192/mmu_operations.c b/src/soc/mediatek/mt8192/mmu_operations.c
index fb3620e..482eaae 100644
--- a/src/soc/mediatek/mt8192/mmu_operations.c
+++ b/src/soc/mediatek/mt8192/mmu_operations.c
@@ -3,6 +3,8 @@
#include <device/mmio.h>
#include <soc/mcucfg.h>
#include <soc/mmu_operations.h>
+#include <soc/symbols.h>
+#include <console/console.h>

DEFINE_BIT(MP0_CLUSTER_CFG0_L3_SHARE_EN, 9)
DEFINE_BIT(MP0_CLUSTER_CFG0_L3_SHARE_PRE_EN, 8)
@@ -28,3 +30,11 @@
MP0_CLUSTER_CFG0_L3_SHARE_PRE_EN, 0);
dsb();
}
+
+void mtk_soc_after_dram(void)
+{
+ mmu_config_range(_mpufw_reserved, REGION_SIZE(mpufw_reserved),
+ NONSECURE_UNCACHED_MEM);
+
+ printk(BIOS_ERR, "%s mpufw_reserved%p\n", __func__, _mpufw_reserved);
+}
diff --git a/src/soc/mediatek/mt8192/spm.c b/src/soc/mediatek/mt8192/spm.c
index 5613027..58a4a16 100644
--- a/src/soc/mediatek/mt8192/spm.c
+++ b/src/soc/mediatek/mt8192/spm.c
@@ -6,8 +6,13 @@
#include <delay.h>
#include <device/mmio.h>
#include <soc/spm.h>
+#include <soc/symbols.h>
#include <timer.h>

+#if 0
+#define BUF_SIZE (16 * KiB)
+static u32 spm_bin[BUF_SIZE / 4] __aligned(8);
+
static const u32 spm_firmware_binary[] = {
0x3200001e, 0x6a00001e, 0x6e00001e, 0x6800001e, 0x6200001e, 0x6000001e,
0x5e00001e, 0x5c00001e, 0x6000001e, 0x5800001e, 0x5600001e, 0x5400001e,
@@ -438,6 +443,7 @@
.pmem_start = 0x10000000,
.dmem_start = 0x10003800
};
+#endif

static struct pwr_ctrl spm_init_ctrl = {
/* Auto-gen Start */
@@ -914,7 +920,7 @@
RG_AHBMIF_APBEN_LSB | REG_MD32_APB_INTERNAL_EN_LSB);
}

-static void spm_kick_im_to_fetch(void)
+static void spm_kick_im_to_fetch(struct dyna_load_pcm *pcm)
{
uintptr_t ptr;
u32 pmem_words;
@@ -923,11 +929,25 @@
u32 dmem_start;
u32 con0;

+#if 0
ptr = (uintptr_t) spm_firmware_binary + 0x40000000;
pmem_words = spm_firmware.pmem_words;
total_words = spm_firmware.total_words;
pmem_start = spm_firmware.pmem_start;
dmem_start = spm_firmware.dmem_start;
+#endif
+ //memcpy(spm_bin, pcm->buf, pcm->desc.total_words * sizeof(u32));
+ ptr = (uintptr_t) pcm->buf + 0x40000000;
+ //ptr = (uintptr_t) spm_bin + 0x40000000;
+ pmem_words = pcm->desc.pmem_words;
+ total_words = pcm->desc.total_words;
+ pmem_start = pcm->desc.pmem_start;
+ dmem_start = pcm->desc.dmem_start;
+
+ for (int i = 0; i < 32; i++)
+ printk(BIOS_ERR, "%#x\n", pcm->buf[i]);
+
+ printk(BIOS_ERR, "%#x %#x %#x %#x\n", pmem_words, total_words, pmem_start, dmem_start);

/* tell IM where is PCM code (use slave mode if code existed) */
if (read32(&mtk_spm->md32pcm_dma0_src) != ptr ||
@@ -968,6 +988,61 @@
write32(&mtk_spm->pcm_pwr_io_en, 0);
}

+static int spm_load_firmware(struct dyna_load_pcm *pcm)
+{
+ struct stopwatch sw;
+ const char *file_name = "spm_firmware.bin";
+ size_t file_size;
+ int copy_size, offset;
+ u16 firmware_size;
+
+ stopwatch_init(&sw);
+
+ file_size = cbfs_boot_load_file(file_name, _mpufw_reserved,
+ REGION_SIZE(mpufw_reserved), CBFS_TYPE_RAW);
+
+ mb();
+
+ if (file_size == 0) {
+ printk(BIOS_ERR, "SPM binary %s not found\n", file_name);
+ return -1;
+ }
+
+ /*
+ * spmfw layout:
+ * u16 firmware_size
+ * u32 binary[firmware_size]
+ * struct pcm_desc descriptor
+ * char *version
+ */
+
+ /* firmware size */
+ offset = 0;
+ copy_size = sizeof(firmware_size);
+ memcpy(&firmware_size, _mpufw_reserved + offset, copy_size);
+ printk(BIOS_DEBUG, "SPM: binary array size = 0x%x\n", firmware_size);
+
+ /* binary */
+ offset += 16; /* binary start offset */
+ copy_size = firmware_size * sizeof(u32);
+ assert(offset < file_size);
+ pcm->buf = (u32 *)(_mpufw_reserved + offset);
+
+ /* descriptor */
+ offset += copy_size;
+ assert(offset < file_size);
+ copy_size = sizeof(struct pcm_desc);
+ memcpy((void *)&(pcm->desc.pmem_words), _mpufw_reserved + offset, copy_size);
+
+ /* version */
+ offset += copy_size;
+ assert(offset < file_size);
+ printk(BIOS_INFO, "spmfw version = %s and is loaded in %ld msecs\n",
+ (_mpufw_reserved + offset), stopwatch_duration_msecs(&sw));
+
+ return 0;
+}
+
static void spm_set_wakeup_event(struct pwr_ctrl *pwrctrl)
{
u32 val, mask, isr;
@@ -1064,6 +1139,7 @@

int spm_init(void)
{
+ struct dyna_load_pcm pcm;
struct stopwatch sw;

stopwatch_init(&sw);
@@ -1071,14 +1147,20 @@
spm_register_init();
spm_set_power_control(&spm_init_ctrl);
spm_set_sysclk_settle();
+
+ if (spm_load_firmware(&pcm)) {
+ printk(BIOS_ERR, "SPM: firmware is not ready\n");
+ return -1;
+ }
+
spm_reset_and_init_pcm();
- spm_kick_im_to_fetch();
+ spm_kick_im_to_fetch(&pcm);
spm_init_pcm_register();
spm_set_wakeup_event(&spm_init_ctrl);
spm_kick_pcm_to_run(&spm_init_ctrl);

- printk(BIOS_INFO, "SPM: %s done in %ld msecs, %s, spm pc = 0x%x\n",
- __func__, stopwatch_duration_msecs(&sw), spm_firmware.version,
+ printk(BIOS_INFO, "SPM: %s done in %ld msecs, spm pc = 0x%x\n",
+ __func__, stopwatch_duration_msecs(&sw),
read32(&mtk_spm->md32pcm_pc));

return 0;

To view, visit change 47287. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I563c2d959cc2b597fee137ef1c53ee028e3c20c0
Gerrit-Change-Number: 47287
Gerrit-PatchSet: 1
Gerrit-Owner: Yidi Lin <yidi.lin@mediatek.com>
Gerrit-MessageType: newchange