diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/soc/mediatek/common/include/soc/lastbus_v1.h (renamed from src/soc/mediatek/common/include/soc/lastbus.h) | 4 | ||||
-rw-r--r-- | src/soc/mediatek/common/include/soc/lastbus_v2.h | 40 | ||||
-rw-r--r-- | src/soc/mediatek/common/lastbus_v1.c (renamed from src/soc/mediatek/common/lastbus.c) | 2 | ||||
-rw-r--r-- | src/soc/mediatek/common/lastbus_v2.c | 112 | ||||
-rw-r--r-- | src/soc/mediatek/mt8186/Makefile.inc | 2 | ||||
-rw-r--r-- | src/soc/mediatek/mt8186/bootblock.c | 2 | ||||
-rw-r--r-- | src/soc/mediatek/mt8188/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/mediatek/mt8188/bootblock.c | 2 | ||||
-rw-r--r-- | src/soc/mediatek/mt8188/include/soc/addressmap.h | 6 | ||||
-rw-r--r-- | src/soc/mediatek/mt8188/lastbus.c | 79 |
10 files changed, 245 insertions, 5 deletions
diff --git a/src/soc/mediatek/common/include/soc/lastbus.h b/src/soc/mediatek/common/include/soc/lastbus_v1.h index 3c93efbf60..bd6cd86776 100644 --- a/src/soc/mediatek/common/include/soc/lastbus.h +++ b/src/soc/mediatek/common/include/soc/lastbus_v1.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef SOC_MEDIATEK_COMMON_LASTBUS_H -#define SOC_MEDIATEK_COMMON_LASTBUS_H +#ifndef SOC_MEDIATEK_COMMON_LASTBUS_V1_H +#define SOC_MEDIATEK_COMMON_LASTBUS_V1_H /* INFRA LASTBUS INFO */ #define BUS_INFRA_SNAPSHOT 0xd00 diff --git a/src/soc/mediatek/common/include/soc/lastbus_v2.h b/src/soc/mediatek/common/include/soc/lastbus_v2.h new file mode 100644 index 0000000000..d58da76b57 --- /dev/null +++ b/src/soc/mediatek/common/include/soc/lastbus_v2.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SOC_MEDIATEK_COMMON_LASTBUS_V2_H +#define SOC_MEDIATEK_COMMON_LASTBUS_V2_H + +#define NR_MAX_LASTBUS_IDLE_MASK 8 +#define NR_MAX_LASTBUS_MONITOR 16 +#define TIMEOUT_THRES_SHIFT 16 +#define TIMEOUT_TYPE_SHIFT 1 +#define LASTBUS_TIMEOUT_CLR 0x0200 +#define LASTBUS_DEBUG_CKEN 0x0008 +#define LASTBUS_DEBUG_EN 0x0004 +#define LASTBUS_TIMEOUT 0x0001 + +struct lastbus_idle_mask { + u32 reg_offset; + u32 reg_value; +}; + +struct lastbus_monitor { + const char *name; + uintptr_t base; + size_t num_ports; + u16 bus_freq_mhz; + size_t num_idle_mask; + struct lastbus_idle_mask idle_masks[NR_MAX_LASTBUS_IDLE_MASK]; +}; + +struct lastbus_config { + const char *latch_platform; + unsigned int timeout_ms; + unsigned int timeout_type; + unsigned int num_used_monitors; + struct lastbus_monitor monitors[NR_MAX_LASTBUS_MONITOR]; +}; + +void lastbus_init(void); +extern const struct lastbus_config lastbus_cfg; + +#endif diff --git a/src/soc/mediatek/common/lastbus.c b/src/soc/mediatek/common/lastbus_v1.c index cf4f8d1a42..cf3fb1db39 100644 --- a/src/soc/mediatek/common/lastbus.c +++ b/src/soc/mediatek/common/lastbus_v1.c @@ -3,7 +3,7 @@ #include <console/console.h> #include <device/mmio.h> #include <soc/addressmap.h> -#include <soc/lastbus.h> +#include <soc/lastbus_v1.h> static unsigned long preisys_dump_offset[] = { 0x500, /* PERIBUS_DBG0 */ diff --git a/src/soc/mediatek/common/lastbus_v2.c b/src/soc/mediatek/common/lastbus_v2.c new file mode 100644 index 0000000000..2893c5a72a --- /dev/null +++ b/src/soc/mediatek/common/lastbus_v2.c @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/mmio.h> +#include <soc/addressmap.h> +#include <soc/lastbus_v2.h> +#include <timer.h> + +#define SYS_TIMER_0_OFFSET 0x400 +#define SYS_TIMER_1_OFFSET 0x404 +#define DEBUG_RESULT_OFFSET 0x408 + +static bool lastbus_is_timeout(const struct lastbus_monitor *m) +{ + return read32p(m->base) & LASTBUS_TIMEOUT; +} + +static uint64_t gray_code_to_binary(uint64_t gray_code) +{ + uint64_t value = 0; + while (gray_code) { + value ^= gray_code; + gray_code >>= 1; + } + return value; +} + +static void lastbus_dump_monitor(const struct lastbus_monitor *m) +{ + int i; + uint64_t gray_code, bin_code; + + printk(BIOS_INFO, "--- %s %#lx %ld ---\n", m->name, m->base, m->num_ports); + + for (i = 0; i < m->num_ports; i++) + printk(BIOS_INFO, "%08x\n", + read32p(m->base + DEBUG_RESULT_OFFSET + (i * 4))); + + gray_code = (uint64_t)read32p(m->base + SYS_TIMER_1_OFFSET) << 32 | + read32p(m->base + SYS_TIMER_0_OFFSET); + bin_code = gray_code_to_binary(gray_code); + printk(BIOS_INFO, "\ntimestamp: %#llx\n", bin_code); +} + +static void lastbus_dump(void) +{ + const struct lastbus_monitor *m; + bool found = false; + int i; + + for (i = 0; i < lastbus_cfg.num_used_monitors; i++) { + m = &lastbus_cfg.monitors[i]; + if (!lastbus_is_timeout(m)) + continue; + + if (!found) + printk(BIOS_INFO, + "\n******************* %s lastbus ******************\n", + lastbus_cfg.latch_platform); + found = true; + lastbus_dump_monitor(m); + } +} + +static u16 calculate_timeout_thres(u16 bus_freq_mhz, u32 timeout_ms) +{ + u64 value; + value = ((u64)timeout_ms * USECS_PER_MSEC * bus_freq_mhz) >> 10; + if (value >= UINT16_MAX) + return UINT16_MAX - 1; + return value >= 1 ? value - 1 : 0; +} + +static void lastbus_init_monitor(const struct lastbus_monitor *m, + u32 timeout_ms, u32 timeout_type) +{ + u16 timeout_thres; + int i; + + for (i = 0; i < m->num_idle_mask; i++) + write32p(m->base + m->idle_masks[i].reg_offset, + m->idle_masks[i].reg_value); + + /* clear timeout status with DBG_CKEN */ + write32p(m->base, LASTBUS_TIMEOUT_CLR | LASTBUS_DEBUG_CKEN); + /* de-assert clear bit */ + clrbits32p(m->base, LASTBUS_TIMEOUT_CLR); + + if (timeout_ms == UINT32_MAX) + timeout_thres = 0xFFFF; + else + timeout_thres = calculate_timeout_thres(m->bus_freq_mhz, timeout_ms); + + setbits32p(m->base, (timeout_thres << TIMEOUT_THRES_SHIFT) | + (timeout_type << TIMEOUT_TYPE_SHIFT)); + setbits32p(m->base, LASTBUS_DEBUG_EN); +} + +static void lastbus_setup(void) +{ + int i; + + for (i = 0; i < lastbus_cfg.num_used_monitors; i++) + lastbus_init_monitor(&lastbus_cfg.monitors[i], lastbus_cfg.timeout_ms, + lastbus_cfg.timeout_type); +} + +void lastbus_init(void) +{ + lastbus_dump(); + lastbus_setup(); +} diff --git a/src/soc/mediatek/mt8186/Makefile.inc b/src/soc/mediatek/mt8186/Makefile.inc index d03ea0e791..04d047acf1 100644 --- a/src/soc/mediatek/mt8186/Makefile.inc +++ b/src/soc/mediatek/mt8186/Makefile.inc @@ -14,7 +14,7 @@ all-y += ../common/uart.c bootblock-y += bootblock.c bootblock-y += ../common/eint_event.c bootblock-y += gic.c -bootblock-y += ../common/lastbus.c +bootblock-y += ../common/lastbus_v1.c bootblock-y += ../common/mmu_operations.c bootblock-y += ../common/tracker.c ../common/tracker_v1.c bootblock-y += ../common/wdt.c ../common/wdt_req.c wdt.c diff --git a/src/soc/mediatek/mt8186/bootblock.c b/src/soc/mediatek/mt8186/bootblock.c index 9b12e562a1..d06b11113b 100644 --- a/src/soc/mediatek/mt8186/bootblock.c +++ b/src/soc/mediatek/mt8186/bootblock.c @@ -3,7 +3,7 @@ #include <bootblock_common.h> #include <soc/eint_event.h> #include <soc/gic.h> -#include <soc/lastbus.h> +#include <soc/lastbus_v1.h> #include <soc/mmu_operations.h> #include <soc/pll.h> #include <soc/tracker_common.h> diff --git a/src/soc/mediatek/mt8188/Makefile.inc b/src/soc/mediatek/mt8188/Makefile.inc index 95df6dc1d9..651cff0d5a 100644 --- a/src/soc/mediatek/mt8188/Makefile.inc +++ b/src/soc/mediatek/mt8188/Makefile.inc @@ -11,6 +11,7 @@ all-y += ../common/uart.c bootblock-y += bootblock.c bootblock-y += ../common/eint_event.c +bootblock-y += ../common/lastbus_v2.c lastbus.c bootblock-y += ../common/mmu_operations.c bootblock-y += ../common/tracker.c ../common/tracker_v2.c bootblock-y += ../common/wdt.c ../common/wdt_req.c wdt.c diff --git a/src/soc/mediatek/mt8188/bootblock.c b/src/soc/mediatek/mt8188/bootblock.c index 32ef4af2e3..f7b7849b36 100644 --- a/src/soc/mediatek/mt8188/bootblock.c +++ b/src/soc/mediatek/mt8188/bootblock.c @@ -4,6 +4,7 @@ #include <soc/eint_event.h> #include <soc/mmu_operations.h> #include <soc/pll.h> +#include <soc/lastbus_v2.h> #include <soc/tracker_common.h> #include <soc/wdt.h> @@ -11,6 +12,7 @@ void bootblock_soc_init(void) { mtk_mmu_init(); bustracker_init(); + lastbus_init(); mtk_wdt_init(); mt_pll_init(); unmask_eint_event_mask(); diff --git a/src/soc/mediatek/mt8188/include/soc/addressmap.h b/src/soc/mediatek/mt8188/include/soc/addressmap.h index 63f059616f..74489764f9 100644 --- a/src/soc/mediatek/mt8188/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8188/include/soc/addressmap.h @@ -27,14 +27,20 @@ enum { APMIXED_BASE = IO_PHYS + 0x0000C000, SYSTIMER_BASE = IO_PHYS + 0x00017000, INFRACFG_AO_BCRM_BASE = IO_PHYS + 0x00022000, + INFRA_AO_DBUG_BASE = IO_PHYS + 0x00023000, PMIF_SPI_BASE = IO_PHYS + 0x00024000, PMICSPI_MST_BASE = IO_PHYS + 0x00025000, PMIF_SPMI_BASE = IO_PHYS + 0x00027000, + INFRA2_AO_DBUG_BASE = IO_PHYS + 0x00028000, SPMI_MST_BASE = IO_PHYS + 0x00029000, + PERI_AO_BASE = IO_PHYS + 0x0002B000, + PERI_AO2_BASE = IO_PHYS + 0x0002E000, DEVAPC_INFRA_AO_BASE = IO_PHYS + 0x00030000, DEVAPC_PERI_AO_BASE = IO_PHYS + 0x00034000, DEVAPC_PERI2_AO_BASE = IO_PHYS + 0x00038000, DEVAPC_PERI_PAR_AO_BASE = IO_PHYS + 0x0003C000, + PERI_PAR_AO_BASE = IO_PHYS + 0x00040000, + FMEM_AO_BASE = IO_PHYS + 0x00042000, DBG_TRACKER_BASE = IO_PHYS + 0x00208000, PERI_TRACKER_BASE = IO_PHYS + 0x00218000, EMI0_BASE = IO_PHYS + 0x00219000, diff --git a/src/soc/mediatek/mt8188/lastbus.c b/src/soc/mediatek/mt8188/lastbus.c new file mode 100644 index 0000000000..f2c0b0d57f --- /dev/null +++ b/src/soc/mediatek/mt8188/lastbus.c @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/mmio.h> +#include <soc/addressmap.h> +#include <soc/lastbus_v2.h> + +const struct lastbus_config lastbus_cfg = { + .latch_platform = "MT8188", + .timeout_ms = 200, + .timeout_type = 0, + .num_used_monitors = 6, + .monitors = { + { + .name = "debug_ctrl_ao_INFRA_AO", + .base = INFRA_AO_DBUG_BASE, + .num_ports = 34, + .num_idle_mask = 2, + .idle_masks = { + { + .reg_offset = 0x04, + .reg_value = 0x2, + }, + { + .reg_offset = 0x08, + .reg_value = 0x10000, + }, + }, + .bus_freq_mhz = 78, + }, + { + .name = "debug_ctrl_ao_INFRA2_AO", + .base = INFRA2_AO_DBUG_BASE, + .num_ports = 9, + .num_idle_mask = 0, + .bus_freq_mhz = 78, + }, + { + .name = "debug_ctrl_ao_PERI_AO", + .base = PERI_AO_BASE, + .num_ports = 25, + .num_idle_mask = 1, + .idle_masks = { + { + .reg_offset = 0x04, + .reg_value = 0x20000, + }, + }, + .bus_freq_mhz = 78, + }, + { + .name = "debug_ctrl_ao_PERI_AO2", + .base = PERI_AO2_BASE, + .num_ports = 20, + .num_idle_mask = 0, + .bus_freq_mhz = 78, + }, + { + .name = "debug_ctrl_ao_PERI_PAR_AO", + .base = PERI_PAR_AO_BASE, + .num_ports = 18, + .num_idle_mask = 0, + .bus_freq_mhz = 78, + }, + { + .name = "debug_ctrl_ao_FMEM_AO", + .base = FMEM_AO_BASE, + .num_ports = 28, + .num_idle_mask = 1, + .idle_masks = { + { + .reg_offset = 0x14, + .reg_value = 0x204, + }, + }, + .bus_freq_mhz = 78, + }, + }, +}; |