diff options
author | Zhenguo Li <ot_zhenguo.li@mediatek.corp-partner.google.com> | 2021-09-07 19:45:37 +0800 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2021-10-13 13:57:45 +0000 |
commit | dacff81a66676e8816740b98266aa2257137fd81 (patch) | |
tree | b5ded74c8f31437959adcc3900ee95c7186c806c /src/soc/mediatek/common | |
parent | a31d6cd5d02a21452d92859a682ebbc674080c49 (diff) |
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 <ot_zhenguo.li@mediatek.corp-partner.google.com>
Change-Id: If457f4a096cd63038bf6b40552aa3caaba33d5fd
Reviewed-on: https://review.coreboot.org/c/coreboot/+/58243
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.corp-partner.google.com>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/soc/mediatek/common')
-rw-r--r-- | src/soc/mediatek/common/include/soc/tracker_common.h | 40 | ||||
-rw-r--r-- | src/soc/mediatek/common/tracker.c | 125 |
2 files changed, 165 insertions, 0 deletions
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 <stdio.h> +#include <console/console.h> +#include <device/mmio.h> +#include <soc/addressmap.h> +#include <soc/tracker_common.h> + +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(); +} |