From dacff81a66676e8816740b98266aa2257137fd81 Mon Sep 17 00:00:00 2001 From: Zhenguo Li Date: Tue, 7 Sep 2021 19:45:37 +0800 Subject: [PATCH] soc/mediatek/mt8195: add tracker dump Tracker is a debugging tool, include AP/INFRA/PERI tracker. When bus timeout occurs, the system reboots and latches some values which could be used for debug. Signed-off-by: Zhenguo Li Change-Id: If457f4a096cd63038bf6b40552aa3caaba33d5fd Reviewed-on: https://review.coreboot.org/c/coreboot/+/58243 Reviewed-by: Rex-BC Chen Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- .../common/include/soc/tracker_common.h | 40 ++++++ src/soc/mediatek/common/tracker.c | 125 ++++++++++++++++++ src/soc/mediatek/mt8195/Makefile.inc | 2 +- .../mediatek/mt8195/include/soc/addressmap.h | 12 +- src/soc/mediatek/mt8195/soc.c | 2 + 5 files changed, 176 insertions(+), 5 deletions(-) create mode 100644 src/soc/mediatek/common/include/soc/tracker_common.h create mode 100644 src/soc/mediatek/common/tracker.c diff --git a/src/soc/mediatek/common/include/soc/tracker_common.h b/src/soc/mediatek/common/include/soc/tracker_common.h new file mode 100644 index 0000000000..a68d329a25 --- /dev/null +++ b/src/soc/mediatek/common/include/soc/tracker_common.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SOC_MEDIATEK_COMMON_TRACKER_H +#define SOC_MEDIATEK_COMMON_TRACKER_H + +#define BUS_DBG_CON 0x000 +#define BUS_DBG_TIMER_CON0 0x004 +#define BUS_DBG_TIMER_CON1 0x008 +#define BUS_TRACE_CON_1 0x900 +#define BUS_TRACE_CON_AO_1 0x9FC +#define BUS_TRACE_CON_2 0xA00 +#define BUS_TRACE_CON_AO_2 0xAFC +#define BUS_TRACE_EN 16 + +#define SYS_TRACK_ENTRY 64 +#define INFRA_ENTRY_NUM 32 +#define PERI_ENTRY_NUM 16 + +#define AR_TRACK_OFFSET 0x0100 +#define AW_TRACK_OFFSET 0x0300 + +#define BUSTRACKER_TIMEOUT 0x300 + +#define BUS_DBG_CON_IRQ_AR_STA0 0x00000100 +#define BUS_DBG_CON_IRQ_AW_STA0 0x00000200 +#define BUS_DBG_CON_IRQ_AR_STA1 0x00100000 +#define BUS_DBG_CON_IRQ_AW_STA1 0x00200000 +#define BUS_DBG_CON_TIMEOUT (BUS_DBG_CON_IRQ_AR_STA0 | BUS_DBG_CON_IRQ_AW_STA0 | \ + BUS_DBG_CON_IRQ_AR_STA1 | BUS_DBG_CON_IRQ_AW_STA1) + +enum { + TRACKER_SYSTRACKER = 0, + TRACKER_INFRATRACKER, + TRACKER_PERISYSTRACKER, + TRACKER_NUM, +}; + +void bustracker_init(void); + +#endif diff --git a/src/soc/mediatek/common/tracker.c b/src/soc/mediatek/common/tracker.c new file mode 100644 index 0000000000..6d4e6b2f05 --- /dev/null +++ b/src/soc/mediatek/common/tracker.c @@ -0,0 +1,125 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +static struct tracker { + uintptr_t base_addr; + u32 timeout; + u32 entry; + u32 offset[2]; + const char *str; +} tracker_data[TRACKER_NUM] = { + [TRACKER_SYSTRACKER] = { + .base_addr = DBG_TRACKER_BASE, + .timeout = BUS_DBG_CON_TIMEOUT, + .entry = SYS_TRACK_ENTRY, + .offset[0] = AR_TRACK_OFFSET, + .offset[1] = AW_TRACK_OFFSET, + .str = "systracker", + }, + [TRACKER_INFRATRACKER] = { + .base_addr = INFRA_TRACKER_BASE, + .timeout = BUSTRACKER_TIMEOUT, + .entry = INFRA_ENTRY_NUM, + .offset[0] = AR_TRACK_OFFSET, + .offset[1] = AW_TRACK_OFFSET, + .str = "infra_tracker", + }, + [TRACKER_PERISYSTRACKER] = { + .base_addr = PERI_TRACKER_BASE, + .timeout = BUSTRACKER_TIMEOUT, + .entry = PERI_ENTRY_NUM, + .offset[0] = AR_TRACK_OFFSET, + .offset[1] = AW_TRACK_OFFSET, + .str = "peri_tracker", + }, +}; + +static void setup_init(void) +{ + u32 val; + /* + * Set infra/peri tracker timeout. + * timeout = clock_in_mhz * 1000 / 16 * timeout_in_ms + * + * timeout: 200ms + * infra tracker clock: 156MHz + * peri tracker clock: 78MHz + */ + val = 156 * 1000 / 16 * 200; + write32((void *)(INFRA_TRACKER_BASE + BUS_DBG_TIMER_CON0), val); + write32((void *)(INFRA_TRACKER_BASE + BUS_DBG_TIMER_CON1), val); + + val = 78 * 1000 / 16 * 200; + write32((void *)(PERI_TRACKER_BASE + BUS_DBG_TIMER_CON0), val); + write32((void *)(PERI_TRACKER_BASE + BUS_DBG_TIMER_CON1), val); + + /* Enable infra/peri tracer because tracker and tracer share the same enable bit. */ + write32((void *)(BUS_TRACE_MONITOR_BASE + BUS_TRACE_CON_1), 1 << BUS_TRACE_EN); + write32((void *)(BUS_TRACE_MONITOR_BASE + BUS_TRACE_CON_2), 1 << BUS_TRACE_EN); + + /* + * 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); + write32((void *)(BUS_TRACE_MONITOR_BASE + BUS_TRACE_CON_AO_1), val); + write32((void *)(BUS_TRACE_MONITOR_BASE + BUS_TRACE_CON_AO_2), val); + +} + +static void tracker_dump_data(void) +{ + int i, j, k; + int size; + uintptr_t reg; + struct tracker *tra; + + for (j = 0; j < TRACKER_NUM; j++) { + tra = &tracker_data[j]; + + if (!(read32((void *)(tra->base_addr)) & tra->timeout)) + continue; + + printk(BIOS_INFO, "**Dump %s debug register start**\n", tra->str); + for (k = 0; k < 2; k++) { + /* + * 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 perisys tracker: + * offset[0] dump from offset 0x100 ~ 0x2F8 + * offset[1] dump from offset 0x300 ~ 0x4FC + */ + size = 2 * tra->entry; + for (i = 0; i < size; i++) { + reg = tra->base_addr + tra->offset[k] + i * 4; + printk(BIOS_INFO, "%#lx:%#x,", reg, read32((void *)reg)); + + if (i % 4 == 3 || i == size - 1) + printk(BIOS_INFO, "\n"); + } + } + + printk(BIOS_INFO, "**Dump %s debug register end**\n", tra->str); + } +} + +void bustracker_init(void) +{ + tracker_dump_data(); + setup_init(); +} diff --git a/src/soc/mediatek/mt8195/Makefile.inc b/src/soc/mediatek/mt8195/Makefile.inc index 6540ce2288..5d444c7564 100644 --- a/src/soc/mediatek/mt8195/Makefile.inc +++ b/src/soc/mediatek/mt8195/Makefile.inc @@ -48,7 +48,7 @@ romstage-y += ../common/mt6359p.c mt6359p.c romstage-y += mt6691.c romstage-y += mt6360.c romstage-y += ../common/rtc.c ../common/rtc_osc_init.c ../common/rtc_mt6359p.c - +ramstage-y += ../common/tracker.c ramstage-y += ../common/auxadc.c ramstage-y += ../common/ddp.c ddp.c ramstage-y += devapc.c diff --git a/src/soc/mediatek/mt8195/include/soc/addressmap.h b/src/soc/mediatek/mt8195/include/soc/addressmap.h index 3ddaa54d74..88b545a97e 100644 --- a/src/soc/mediatek/mt8195/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8195/include/soc/addressmap.h @@ -4,10 +4,11 @@ #define __SOC_MEDIATEK_MT8195_INCLUDE_SOC_ADDRESSMAP_H__ enum { - MCUSYS_BASE = 0x0C530000, - MCUPM_SRAM_BASE = 0x0C540000, - MCUPM_CFG_BASE = 0x0C560000, - IO_PHYS = 0x10000000, + MCUSYS_BASE = 0x0C530000, + MCUPM_SRAM_BASE = 0x0C540000, + MCUPM_CFG_BASE = 0x0C560000, + BUS_TRACE_MONITOR_BASE = 0x0D040000, + IO_PHYS = 0x10000000, }; enum { @@ -35,12 +36,15 @@ enum { DEVAPC_PERI2_AO_BASE = IO_PHYS + 0x00038000, DEVAPC_PERI_PAR_AO_BASE = IO_PHYS + 0x0003C000, DEVAPC_FMEM_AO_BASE = IO_PHYS + 0x00044000, + DBG_TRACKER_BASE = IO_PHYS + 0x00208000, + PERI_TRACKER_BASE = IO_PHYS + 0x00218000, EMI0_BASE = IO_PHYS + 0x00219000, EMI1_BASE = IO_PHYS + 0x0021D000, I2C_DMA_BASE = IO_PHYS + 0x00220080, EMI1_SUB_BASE = IO_PHYS + 0x00225000, EMI0_MPU_BASE = IO_PHYS + 0x00226000, DRAMC_CHA_AO_BASE = IO_PHYS + 0x00230000, + INFRA_TRACKER_BASE = IO_PHYS + 0x00314000, SSPM_SRAM_BASE = IO_PHYS + 0x00400000, SSPM_CFG_BASE = IO_PHYS + 0x00440000, SCP_CFG_BASE = IO_PHYS + 0x00700000, diff --git a/src/soc/mediatek/mt8195/soc.c b/src/soc/mediatek/mt8195/soc.c index 399196489a..20bd226cc9 100644 --- a/src/soc/mediatek/mt8195/soc.c +++ b/src/soc/mediatek/mt8195/soc.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,7 @@ static void soc_init(struct device *dev) ufs_disable_refclk(); hdmi_low_power_setting(); + bustracker_init(); } static struct device_operations soc_ops = {