soc/mediatek/mt8186: Enable lastbus debug hardware
Lastbus is a bus debug tool. When the bus hangs, the bus transmission
information before resetting will be recorded.
The watchdog cannot clear it and it will be printed out for bus hanging
analysis.
TEST=build pass.
BUG=none
Signed-off-by: ot_zhenguo.li <ot_zhenguo.li@mediatek.corp-partner.google.com>
Change-Id: Iff39486dfad556a3104b2f2b6811c34c2ded6954
Reviewed-on: https://review.coreboot.org/c/coreboot/+/67437
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Yidi Lin <yidilin@google.com>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
diff --git a/src/soc/mediatek/common/include/soc/lastbus.h b/src/soc/mediatek/common/include/soc/lastbus.h
new file mode 100644
index 0000000..3c93efb
--- /dev/null
+++ b/src/soc/mediatek/common/include/soc/lastbus.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef SOC_MEDIATEK_COMMON_LASTBUS_H
+#define SOC_MEDIATEK_COMMON_LASTBUS_H
+
+/* INFRA LASTBUS INFO */
+#define BUS_INFRA_SNAPSHOT 0xd00
+#define BUS_INFRA_CTRL 0xd04
+#define INFRASYS_CONFIG 0xffff000c
+#define INFRA_NUM 17
+
+/* PERI LASTBUS INFO */
+#define BUS_PERI_R0 0x500
+#define BUS_PERI_R1 0x504
+#define PERISYS_ENABLE 0xc
+#define PERISYS_TIMEOUT 0xffff
+#define PERI_NUM 18
+
+void lastbus_init(void);
+
+#endif
diff --git a/src/soc/mediatek/common/lastbus.c b/src/soc/mediatek/common/lastbus.c
new file mode 100644
index 0000000..cf4f8d1
--- /dev/null
+++ b/src/soc/mediatek/common/lastbus.c
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <console/console.h>
+#include <device/mmio.h>
+#include <soc/addressmap.h>
+#include <soc/lastbus.h>
+
+static unsigned long preisys_dump_offset[] = {
+ 0x500, /* PERIBUS_DBG0 */
+ 0x504, /* PERIBUS_DBG1 */
+ 0x508, /* PERIBUS_DBG2 */
+ 0x50C, /* PERIBUS_DBG3 */
+ 0x510, /* PERIBUS_DBG4 */
+ 0x514, /* PERIBUS_DBG5 */
+ 0x518, /* PERIBUS_DBG6 */
+ 0x51C, /* PERIBUS_DBG7 */
+ 0x520, /* PERIBUS_DBG8 */
+ 0x524, /* PERIBUS_DBG9 */
+ 0x528, /* PERIBUS_DBG10 */
+ 0x52C, /* PERIBUS_DBG11 */
+ 0x530, /* PERIBUS_DBG12 */
+ 0x534, /* PERIBUS_DBG13 */
+ 0x538, /* PERIBUS_DBG14 */
+ 0x53C, /* PERIBUS_DBG15 */
+ 0x580, /* PERIBUS_DBG16 */
+ 0x584, /* PERIBUS_DBG17 */
+};
+
+static void lastbus_setup(void)
+{
+ /* peri lastbus init */
+ write32p(PERICFG_BASE + BUS_PERI_R0, PERISYS_TIMEOUT);
+ write32p(PERICFG_BASE + BUS_PERI_R1, PERISYS_ENABLE);
+
+ /* infra lastbus init */
+ write32p(INFRACFG_AO_BASE + BUS_INFRA_CTRL, INFRASYS_CONFIG);
+}
+
+static void lastbus_dump(void)
+{
+ unsigned int i;
+ uintptr_t reg;
+
+ if (read32p(INFRACFG_AO_BASE + BUS_INFRA_CTRL) & 0x1) {
+ printk(BIOS_DEBUG, "** Dump lastbus infra debug registers start **\n");
+ for (i = 0; i < INFRA_NUM; i++) {
+ reg = INFRACFG_AO_BASE + BUS_INFRA_SNAPSHOT + 4 * i;
+ printk(BIOS_DEBUG, "%08x\n", read32p(reg));
+ }
+ }
+
+ if (read32p(PERICFG_BASE + BUS_PERI_R1) & 0x1) {
+ printk(BIOS_DEBUG, "** Dump lastbus peri debug registers start **\n");
+ for (i = 0; i < PERI_NUM; i++) {
+ reg = PERICFG_BASE + preisys_dump_offset[i];
+ printk(BIOS_DEBUG, "%08x\n", read32p(reg));
+ }
+ }
+}
+
+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 bd1e560..724f80f 100644
--- a/src/soc/mediatek/mt8186/Makefile.inc
+++ b/src/soc/mediatek/mt8186/Makefile.inc
@@ -12,6 +12,7 @@
bootblock-y += bootblock.c
bootblock-y += ../common/eint_event.c
bootblock-y += gic.c
+bootblock-y += ../common/lastbus.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 e5d1e73..9b12e56 100644
--- a/src/soc/mediatek/mt8186/bootblock.c
+++ b/src/soc/mediatek/mt8186/bootblock.c
@@ -3,6 +3,7 @@
#include <bootblock_common.h>
#include <soc/eint_event.h>
#include <soc/gic.h>
+#include <soc/lastbus.h>
#include <soc/mmu_operations.h>
#include <soc/pll.h>
#include <soc/tracker_common.h>
@@ -12,6 +13,7 @@
{
mtk_mmu_init();
bustracker_init();
+ lastbus_init();
mtk_wdt_init();
mt_pll_init();
unmask_eint_event_mask();