Nicolas Boichat has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/47357 )
Change subject: WIP: spm: Code to dump back the content ......................................................................
WIP: spm: Code to dump back the content
Wondering if we should clean this up and commit it, might be useful in the future.
Change-Id: Iebd276d293f30dc9c5d67d0d83aa117826c74444 --- M src/soc/mediatek/mt8192/spm.c 1 file changed, 174 insertions(+), 3 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/57/47357/1
diff --git a/src/soc/mediatek/mt8192/spm.c b/src/soc/mediatek/mt8192/spm.c index 85d2e13..8d69696 100644 --- a/src/soc/mediatek/mt8192/spm.c +++ b/src/soc/mediatek/mt8192/spm.c @@ -8,6 +8,9 @@ #include <soc/spm.h> #include <soc/symbols.h> #include <timer.h> +#include <arch/cache.h> + +static u8 spm_dump[0x4000] __aligned(16);
static struct pwr_ctrl spm_init_ctrl = { /* Auto-gen Start */ @@ -493,6 +496,9 @@ u32 dmem_start; u32 con0;
+ dcache_clean_invalidate_all(); + printk(BIOS_INFO, "SPM firmware @%08lx.\n", (long)(_dram_dma+16)); + ptr = (uintptr_t) pcm->buf + 0x40000000; pmem_words = pcm->desc.pmem_words; total_words = pcm->desc.total_words; @@ -512,15 +518,155 @@ write32(&mtk_spm->md32pcm_dma0_wpto, dmem_start); write32(&mtk_spm->md32pcm_dma0_count, total_words); write32(&mtk_spm->md32pcm_dma0_con, MD32PCM_DMA0_CON_VAL); + write32(&mtk_spm->md32pcm_dma0_start, 0); write32(&mtk_spm->md32pcm_dma0_start, MD32PCM_DMA0_START_VAL); + + { + u32 rlct[32]; u32 pc[32]; int i; + for (i = 0; i < ARRAY_SIZE(rlct); i++) { + pc[i] = read32(&mtk_spm->md32pcm_pc); + rlct[i] = read32(&mtk_spm->md32pcm_dma0_rlct); + udelay(1); + } + + printk(BIOS_INFO, "spm md32pcm_dma0_rlct @%08lx\n", (long)&mtk_spm->md32pcm_dma0_rlct); + for (i = 0; i < ARRAY_SIZE(rlct); i++) { + printk(BIOS_INFO, "spm rlct[%d] = 0x%x\n", i, rlct[i]); + printk(BIOS_INFO, "spm pc[%d] = 0x%x\n", i, pc[i]); + } + } } else { write32(&mtk_spm->pcm_con1, read32(&mtk_spm->pcm_con1) | SPM_REGWR_CFG_KEY | RG_IM_SLAVE_LSB); }
+ while (read32(&mtk_spm->md32pcm_dma0_rlct) != 0x0) + ; + /* kick IM to fetch (only toggle IM_KICK) */ con0 = read32(&mtk_spm->pcm_con0); write32(&mtk_spm->pcm_con0, con0 | SPM_REGWR_CFG_KEY | PCM_CK_EN_LSB); + printk(BIOS_INFO, "SPM con0 0x%08x/0x%08x\n", con0, con0 | SPM_REGWR_CFG_KEY | PCM_CK_EN_LSB); +} + +static void spm_read_back(struct dyna_load_pcm *pcm) +{ + uintptr_t ptr; + u32 pmem_words; + u32 total_words; + u32 pmem_start; + u32 dmem_start; + + dcache_clean_invalidate_all(); + + printk(BIOS_INFO, "SPM firmware readback@%08lx.\n", (long)spm_dump); + + ptr = (uintptr_t) spm_dump + 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; + + write32(&mtk_spm->md32pcm_dma0_src, pmem_start); + write32(&mtk_spm->md32pcm_dma0_dst, ptr); + write32(&mtk_spm->md32pcm_dma0_wppt, pmem_words); + write32(&mtk_spm->md32pcm_dma0_wpto, dmem_start); + write32(&mtk_spm->md32pcm_dma0_count, pmem_words); + write32(&mtk_spm->md32pcm_dma0_con, MD32PCM_DMA0_CON_VAL); + write32(&mtk_spm->md32pcm_dma0_start, 0); + write32(&mtk_spm->md32pcm_dma0_start, MD32PCM_DMA0_START_VAL); + + { + u32 rlct[32]; int i; + for (i = 0; i < ARRAY_SIZE(rlct); i++) { + rlct[i] = read32(&mtk_spm->md32pcm_dma0_rlct); + udelay(10); + } + + printk(BIOS_INFO, "spm md32pcm_dma0_rlct @%08lx\n", (long)&mtk_spm->md32pcm_dma0_rlct); + for (i = 0; i < ARRAY_SIZE(rlct); i++) { + printk(BIOS_INFO, "spm rlct[%d] = 0x%x\n", i, rlct[i]); + } + } + + /* No need to wait for DMA to finish here, printf is slow enough */ + + dcache_clean_invalidate_all(); + { + int i; + + printk(BIOS_INFO, "SPM firmware DUMP.\n"); + + u32 *spm_dump32 = (u32 *)spm_dump; + u32 *dram_dma32 = (u32 *)(_dram_dma+16); + + for (i = 0; i < pmem_words; i++) { + printk(BIOS_INFO, "%08x(%08lx): cbfs(0x%08x) back(0x%08x) %s\n", + i, (long)&dram_dma32[i], dram_dma32[i], spm_dump32[i], + spm_dump32[i] == dram_dma32[i] ? "" : "DIFF"); + } + } +} + +static void spm_read_back_data(struct dyna_load_pcm *pcm) +{ + uintptr_t ptr; + u32 pmem_words; + u32 dmem_words; + u32 total_words; + u32 pmem_start; + u32 dmem_start; + + dcache_clean_invalidate_all(); + + printk(BIOS_INFO, "SPM firmware readback DATA@%08lx.\n", (long)spm_dump); + + ptr = (uintptr_t) spm_dump + 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; + dmem_words = total_words-pmem_words; + + write32(&mtk_spm->md32pcm_dma0_src, dmem_start); + write32(&mtk_spm->md32pcm_dma0_dst, ptr); + write32(&mtk_spm->md32pcm_dma0_wppt, dmem_words); + write32(&mtk_spm->md32pcm_dma0_wpto, dmem_start); + write32(&mtk_spm->md32pcm_dma0_count, dmem_words); + write32(&mtk_spm->md32pcm_dma0_con, MD32PCM_DMA0_CON_VAL); + write32(&mtk_spm->md32pcm_dma0_start, 0); + write32(&mtk_spm->md32pcm_dma0_start, MD32PCM_DMA0_START_VAL); + + { + u32 rlct[32]; int i; + for (i = 0; i < ARRAY_SIZE(rlct); i++) { + rlct[i] = read32(&mtk_spm->md32pcm_dma0_rlct); + udelay(10); + } + + printk(BIOS_INFO, "spm md32pcm_dma0_rlct @%08lx\n", (long)&mtk_spm->md32pcm_dma0_rlct); + for (i = 0; i < ARRAY_SIZE(rlct); i++) { + printk(BIOS_INFO, "spm rlct[%d] = 0x%x\n", i, rlct[i]); + } + } + + /* No need to wait for DMA to finish here, printf is slow enough */ + + dcache_clean_invalidate_all(); + { + int i; + + printk(BIOS_INFO, "SPM firmware DUMP (DATA).\n"); + + u32 *spm_dump32 = (u32 *)spm_dump; + u32 *dram_dma32 = (u32 *)(_dram_dma+16)+pmem_words; + + for (i = 0; i < dmem_words; i++) { + printk(BIOS_INFO, "%08x(%08lx): cbfs(0x%08x) back(0x%08x) %s\n", + i, (long)&dram_dma32[i], dram_dma32[i], spm_dump32[i], + spm_dump32[i] == dram_dma32[i] ? "" : "DIFF"); + } + } }
static void spm_init_pcm_register(void) @@ -655,9 +801,12 @@ write32(&mtk_spm->spm_sw_rsv_8, pwrctrl->pcm_flags1); }
+static u32 pc[4096]; + static void spm_kick_pcm_to_run(struct pwr_ctrl *pwrctrl) { u32 con0, rstn; + int i, cnt;
/* Waiting for loading SPMFW done*/ while (read32(&mtk_spm->md32pcm_dma0_rlct) != 0x0) @@ -680,14 +829,24 @@ write32(&mtk_spm->md32pcm_cfgreg_sw_rstn, rstn | MD32PCM_CFGREG_SW_RSTN_RESET);
- /* Waiting for SPM init done */ - udelay(SPM_INIT_DONE_US); + for (cnt = 0; cnt < ARRAY_SIZE(pc); cnt++) { + pc[cnt] = read32(&mtk_spm->md32pcm_pc); + if (pc[cnt] == 0x3f4) + break; + /* Waiting for SPM init done */ + //udelay(SPM_INIT_DONE_US/ARRAY_SIZE(pc)); + } + + printk(BIOS_INFO, "spm pc @%08lx (%d loops)\n", (long)&mtk_spm->md32pcm_pc, cnt); + for (i = 0; i < cnt; i++) + printk(BIOS_INFO, "spm pc[%d] = 0x%x\n", i, pc[i]); }
-int spm_init(void) +static inline int spm_init_lon(void) { struct dyna_load_pcm pcm; struct stopwatch sw; + int i;
stopwatch_init(&sw);
@@ -702,6 +861,8 @@
spm_reset_and_init_pcm(); spm_kick_im_to_fetch(&pcm); + spm_read_back(&pcm); + spm_read_back_data(&pcm); spm_init_pcm_register(); spm_set_wakeup_event(&spm_init_ctrl); spm_kick_pcm_to_run(&spm_init_ctrl); @@ -710,5 +871,15 @@ __func__, stopwatch_duration_msecs(&sw), read32(&mtk_spm->md32pcm_pc));
+ for (i = 0; i < sizeof(*mtk_spm)/4; i++) { + u32* p = (u32 *)mtk_spm; + printk(BIOS_INFO, "SPM: %08lx=%08x\n", (long)&p[i], read32(&p[i])); + } + return 0; } + +int spm_init(void) { + /* Shorten __func__ in function above */ + return spm_init_lon(); +}