Yidi Lin has submitted this change. ( https://review.coreboot.org/c/coreboot/+/84929?usp=email )
Change subject: soc/mediatek/mt8196: Add tracker driver ......................................................................
soc/mediatek/mt8196: Add tracker driver
Tracker is a debugging tool, including AP/INFRA/PERI tracker. When bus timeout occurs, the system reboots and latches some values which could be used for debug.
Rename VLPCFG_BASE to VLP_CFG_BASE.
TEST=Build pass, When we encounter a bus hang and HW watchdog triggers a reset to the platform, the tracker will print the latched information: [INFO ] **Dump %s aw debug register start** [INFO ] xxxxxx, 0x1c600000, 0x0, 63 This means that the 63rd entry latch accessing 0x1c600000 has a bus timeout.
BUG=b:317009620
Signed-off-by: Xiwen Shao xiwen.shao@mediatek.corp-partner.google.com Change-Id: Ib9784a370acec45ce36a800f3955b9cf96651298 Reviewed-on: https://review.coreboot.org/c/coreboot/+/84929 Reviewed-by: Yidi Lin yidilin@google.com Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Yu-Ping Wu yupingso@google.com --- M src/soc/mediatek/mt8196/Makefile.mk M src/soc/mediatek/mt8196/bootblock.c M src/soc/mediatek/mt8196/include/soc/addressmap.h A src/soc/mediatek/mt8196/include/soc/tracker.h A src/soc/mediatek/mt8196/tracker.c 5 files changed, 175 insertions(+), 1 deletion(-)
Approvals: Yidi Lin: Looks good to me, approved Yu-Ping Wu: Looks good to me, approved build bot (Jenkins): Verified
diff --git a/src/soc/mediatek/mt8196/Makefile.mk b/src/soc/mediatek/mt8196/Makefile.mk index 13ba5c3..2af541f 100644 --- a/src/soc/mediatek/mt8196/Makefile.mk +++ b/src/soc/mediatek/mt8196/Makefile.mk @@ -19,6 +19,7 @@ bootblock-y += ../common/mmu_operations.c bootblock-y += mtcmos.c bootblock-$(CONFIG_PCI) += ../common/pcie.c pcie.c +bootblock-y += tracker.c bootblock-y += ../common/wdt.c ../common/wdt_req.c wdt.c
romstage-y += ../common/cbmem.c diff --git a/src/soc/mediatek/mt8196/bootblock.c b/src/soc/mediatek/mt8196/bootblock.c index d675a5a..95555d1 100644 --- a/src/soc/mediatek/mt8196/bootblock.c +++ b/src/soc/mediatek/mt8196/bootblock.c @@ -8,12 +8,14 @@ #include <soc/mmu_operations.h> #include <soc/pll.h> #include <soc/spm_mtcmos.h> +#include <soc/tracker.h> #include <soc/wdt.h>
void bootblock_soc_init(void) { booker_init(); mtk_mmu_init(); + bustracker_init(); lastbus_init(); mtk_wdt_init(); mt_pll_init(); diff --git a/src/soc/mediatek/mt8196/include/soc/addressmap.h b/src/soc/mediatek/mt8196/include/soc/addressmap.h index 3de16fd..dc21f60 100644 --- a/src/soc/mediatek/mt8196/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8196/include/soc/addressmap.h @@ -143,7 +143,7 @@ APINFRA_SSR_AO_DEBUG_BASE = IO_PHYS + 0x080F1000, AUDIO_BASE = IO_PHYS + 0x0A110000, VLP_AO_BASE = IO_PHYS + 0x0C000000, - VLPCFG_BASE = IO_PHYS + 0x0C001000, + VLP_CFG_BASE = IO_PHYS + 0x0C001000, SPM_BASE = IO_PHYS + 0x0C004000, SPM_PBUS_BASE = IO_PHYS + 0x0C00D000, RGU_BASE = IO_PHYS + 0x0C010000, diff --git a/src/soc/mediatek/mt8196/include/soc/tracker.h b/src/soc/mediatek/mt8196/include/soc/tracker.h new file mode 100644 index 0000000..c82ee83 --- /dev/null +++ b/src/soc/mediatek/mt8196/include/soc/tracker.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#ifndef SOC_MEDIATEK_MT8196_TRACKER_H +#define SOC_MEDIATEK_MT8196_TRACKER_H + +#include <soc/tracker_common.h> +#include <stdint.h> + +#define BUS_DBG_CON 0x000 +#define BUS_TRACE_CON_AO_PRESCALE 0x8f8 +#define BUS_TRACE_CON_AO_1_PRESCALE 0x9f8 +#define VLP_TRACE_CON_AO_PRESCALE 0x114 +#define BUS_TRACE_CON_1 0x800 +#define BUS_TRACE_CON_AO_1 0x8FC +#define BUS_TRACE_CON_2 0x900 +#define BUS_TRACE_CON_AO_2 0x9FC +#define VLP_CON_AO 0x30C +#define BUS_TRACE_EN 16 + +#define SYS_TRACK_ENTRY 64 +#define INFRA_ENTRY_NUM 32 +#define VLP_ENTRY_NUM 4 + +#define AR_TRACK_LOG_OFFSET 0x0200 +#define AR_ENTRY_ID_OFFSET 0x0300 +#define AR_TRACK_L_OFFSET 0x0400 +#define AR_TRACK_H_OFFSET 0x0600 +#define AW_TRACK_LOG_OFFSET 0x0800 +#define AW_ENTRY_ID_OFFSET 0x0900 +#define AW_TRACK_L_OFFSET 0x0A00 +#define AW_TRACK_H_OFFSET 0x0C00 + +#define BUSTRACKER_TIMEOUT 0x300 + +enum { + TRACKER_SYSTRACKER = 0, + TRACKER_INFRATRACKER, + TRACKER_VLPSYSTRACKER, + TRACKER_NUM, +}; + +#endif diff --git a/src/soc/mediatek/mt8196/tracker.c b/src/soc/mediatek/mt8196/tracker.c new file mode 100644 index 0000000..1fc03b99 --- /dev/null +++ b/src/soc/mediatek/mt8196/tracker.c @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <commonlib/bsd/helpers.h> +#include <console/console.h> +#include <device/mmio.h> +#include <soc/addressmap.h> +#include <soc/tracker.h> + +/* + * for systracker: + * offset[0] dump from offset 0x100 ~ 0x2F8 + * offset[1] dump from offset 0x300 ~ 0x4FC + * + * for infra tracker: + * offset[0] dump from offset 0x100 ~ 0x1F8 + * offset[1] dump from offset 0x300 ~ 0x3FC + * + * for vlpsys tracker: + * offset[0] dump from offset 0x100 ~ 0x2F8 + * offset[1] dump from offset 0x300 ~ 0x4FC + */ + +static const u32 offsets[] = { + AR_TRACK_LOG_OFFSET, AR_ENTRY_ID_OFFSET, AR_TRACK_L_OFFSET, + AR_TRACK_H_OFFSET, AW_TRACK_LOG_OFFSET, AW_ENTRY_ID_OFFSET, + AW_TRACK_L_OFFSET, AW_TRACK_H_OFFSET, +}; + +struct tracker tracker_data[TRACKER_NUM] = { + [TRACKER_SYSTRACKER] = { + .base_addr = INFRA_TRACKER_BASE, + .timeout = BUS_DBG_CON_TIMEOUT, + .entry = SYS_TRACK_ENTRY, + .offsets = offsets, + .offsets_size = ARRAY_SIZE(offsets), + .str = "systracker", + }, + [TRACKER_INFRATRACKER] = { + .base_addr = INFRA_TRACKER_BASE, + .timeout = BUS_DBG_CON_TIMEOUT, + .entry = INFRA_ENTRY_NUM, + .offsets = offsets, + .offsets_size = ARRAY_SIZE(offsets), + .str = "infra_tracker", + }, + [TRACKER_VLPSYSTRACKER] = { + .base_addr = VLP_TRACKER_BASE, + .timeout = BUS_DBG_CON_TIMEOUT, + .entry = VLP_ENTRY_NUM, + .offsets = offsets, + .offsets_size = ARRAY_SIZE(offsets), + .str = "vlp_tracker", + }, +}; + +void tracker_setup(void) +{ + u32 val; + /* + * Set infra/peri tracker timeout. + * timeout = clock_in_mhz / 15 * timeout_in_us + * + * timeout: 10ms + * ap tracker clock: 26MHz + * infra tracker clock: 26MHz + * vlp tracker clock: 26MHz + */ + val = 26 / 15 * 10000; + + write32p(BUS_TRACE_MONITOR_BASE + BUS_TRACE_CON_AO_PRESCALE, val); + write32p(BUS_TRACE_MONITOR_BASE + BUS_TRACE_CON_AO_1_PRESCALE, val); + write32p(VLP_CFG_BASE + VLP_TRACE_CON_AO_PRESCALE, val); + /* + * Enable infra/peri tracker. + * bit[0] - BUS_DBG_EN + * bit[1] - TIMEOUT_EN + * bit[2] - SLV_ERR_EN + * bit[13] - HALT_ON_TIMEOUT_EN + * bit[14] - BUS_OT_WEN_CTRL + */ + val = BIT(0) | BIT(1) | BIT(2) | BIT(13) | BIT(14); + write32p(VLP_AO_BASE + VLP_CON_AO, val); + write32p(BUS_TRACE_MONITOR_BASE + BUS_TRACE_CON_AO_1, val); + write32p(BUS_TRACE_MONITOR_BASE + BUS_TRACE_CON_AO_2, val); +} + +static void tracker_dump_data(void) +{ + u64 reg_entry; + int i, j; + uintptr_t reg_log, reg_id, reg_low, reg_high; + struct tracker *tra; + + for (j = 0; j < TRACKER_NUM; j++) { + tra = &tracker_data[j]; + + if (!(read32p(tra->base_addr) & tra->timeout)) + continue; + printk(BIOS_INFO, "**Dump %s ar debug register start**\n", tra->str); + for (i = 0; i < tra->entry; i++) { + reg_log = tra->base_addr + tra->offsets[0] + i * 4; + reg_id = tra->base_addr + tra->offsets[1] + i * 4; + reg_low = tra->base_addr + tra->offsets[2] + i * 4; + reg_high = tra->base_addr + tra->offsets[3] + i * 4; + reg_entry = ((u64)read32p(reg_high)) << 32 | read32p(reg_low); + printk(BIOS_INFO, "%#lx:%#x:%#x:%#x:%#x:%#llx\n", + reg_low, read32p(reg_log), read32p(reg_id), read32p(reg_low), + read32p(reg_high), reg_entry); + } + printk(BIOS_INFO, "**Dump %s aw debug register start**\n", tra->str); + for (i = 0; i < tra->entry; i++) { + reg_log = tra->base_addr + tra->offsets[4] + i * 4; + reg_id = tra->base_addr + tra->offsets[5] + i * 4; + reg_low = tra->base_addr + tra->offsets[6] + i * 4; + reg_high = tra->base_addr + tra->offsets[7] + i * 4; + reg_entry = ((u64)read32p(reg_high)) << 32 | read32p(reg_low); + printk(BIOS_INFO, "%#lx:%#x:%#x:%#x:%#x:%#llx\n", + reg_low, read32p(reg_log), read32p(reg_id), read32p(reg_low), + read32p(reg_high), reg_entry); + } + printk(BIOS_INFO, "**Dump %s debug register end**\n", tra->str); + } +} + +void bustracker_init(void) +{ + tracker_dump_data(); + tracker_setup(); +}