[Skiboot] [PATCH 6/6] lpc: Silence LPC SYNC no-response error when necessary

Andrew Jeffery andrew at aj.id.au
Tue Jul 17 12:02:54 AEST 2018


Add the ability to silence particular errors from the LPC bus when they
can be expected, particularly:

	LPC[000]: Got SYNC no-response error. Error address reg: 0xd001002f

This is necessary on platform exit on some astbmc machines to avoid
unnecessary noise in the msglog.

Signed-off-by: Andrew Jeffery <andrew at aj.id.au>
---
 hw/ast-bmc/ast-io.c       | 45 +++++++++++++++++++++++++++++++++++++++
 hw/lpc.c                  | 23 +++++++++++++++++++-
 include/ast.h             |  1 +
 include/lpc.h             |  3 +++
 platforms/astbmc/common.c | 28 +-----------------------
 5 files changed, 72 insertions(+), 28 deletions(-)

diff --git a/hw/ast-bmc/ast-io.c b/hw/ast-bmc/ast-io.c
index eb80181e481a..4277e2d10ec3 100644
--- a/hw/ast-bmc/ast-io.c
+++ b/hw/ast-bmc/ast-io.c
@@ -360,6 +360,51 @@ bool ast_sio_init(void)
 	return enabled;
 }
 
+bool ast_sio_disable(void)
+{
+	uint32_t hw_strapping;
+	uint32_t silicon_rev;
+	uint8_t family;
+
+	/* Determine the necessary strapping value */
+	silicon_rev = ast_ahb_readl(SCU_REVISION_ID);
+	family = SCU_REVISION_SOC_FAMILY(silicon_rev);
+
+	if (family == SCU_REVISION_SOC_FAMILY_2400) {
+		/* Strapping is read-modify-write on SCU70 */
+		hw_strapping = SCU_STRAP_SIO_DECODE_DISABLE;
+		hw_strapping |= ast_ahb_readl(SCU_HW_STRAPPING);
+	} else if (family == SCU_REVISION_SOC_FAMILY_2500) {
+		/*
+		 * Strapping is W1S on SCU70, W1C on SCU7C. We're setting a bit
+		 * so read-modify-write *should* work, but in reality it breaks
+		 * the AXI/AHB divider, so don't do that.
+		 */
+		hw_strapping = SCU_STRAP_SIO_DECODE_DISABLE;
+	} else {
+		prerror("PLAT: Unrecognised BMC silicon revision 0x%x\n",
+			silicon_rev);
+		return false;
+	}
+
+	/* Apply the strapping value */
+	bmc_sio_get(BMC_SIO_DEV_LPC2AHB);
+
+	bmc_sio_ahb_prep(SCU_HW_STRAPPING, 2);
+
+	bmc_sio_outb(hw_strapping >> 24, 0xf4);
+	bmc_sio_outb(hw_strapping >> 16, 0xf5);
+	bmc_sio_outb(hw_strapping >>  8, 0xf6);
+	bmc_sio_outb(hw_strapping      , 0xf7);
+
+	lpc_irq_err_mask_sync_no_response();
+	bmc_sio_outb(0xcf, 0xfe);
+
+	bmc_sio_put(true);
+
+	return true;
+}
+
 bool ast_can_isolate_sp(void)
 {
 	return bmc_sio_inb(BMC_SIO_PLAT_FLAGS) & BMC_SIO_PLAT_ISOLATE_SP;
diff --git a/hw/lpc.c b/hw/lpc.c
index fbc49c556f04..0eccad820168 100644
--- a/hw/lpc.c
+++ b/hw/lpc.c
@@ -891,6 +891,20 @@ static void lpc_dispatch_reset(struct lpcm *lpc)
 		lpc_setup_serirq(lpc);
 }
 
+uint32_t lpc_irq_err_mask;
+
+void lpc_irq_err_mask_sync_no_response(void)
+{
+	lpc_irq_err_mask |= LPC_HC_IRQ_SYNC_NORESP_ERR;
+	lwsync();
+}
+
+static void lpc_irq_err_mask_reset(void)
+{
+	lpc_irq_err_mask = 0;
+	lwsync();
+}
+
 static void lpc_dispatch_err_irqs(struct lpcm *lpc, uint32_t irqs)
 {
 	const char *sync_err = "Unknown LPC error";
@@ -911,8 +925,12 @@ static void lpc_dispatch_err_irqs(struct lpcm *lpc, uint32_t irqs)
 		lpc_dispatch_reset(lpc);
 	if (irqs & LPC_HC_IRQ_SYNC_ABNORM_ERR)
 		sync_err = "Got SYNC abnormal error.";
-	if (irqs & LPC_HC_IRQ_SYNC_NORESP_ERR)
+	if (irqs & LPC_HC_IRQ_SYNC_NORESP_ERR) {
+		if (lpc_irq_err_mask & LPC_HC_IRQ_SYNC_NORESP_ERR)
+			goto done;
+
 		sync_err = "Got SYNC no-response error.";
+	}
 	if (irqs & LPC_HC_IRQ_SYNC_NORM_ERR)
 		sync_err = "Got SYNC normal error.";
 	if (irqs & LPC_HC_IRQ_SYNC_TIMEOUT_ERR)
@@ -940,6 +958,9 @@ static void lpc_dispatch_err_irqs(struct lpcm *lpc, uint32_t irqs)
 		log_simple_error(info, "LPC[%03x]: %s Error address reg: "
 				 "0x%08x\n",
 				 lpc->chip_id, sync_err, err_addr);
+
+done:
+	lpc_irq_err_mask_reset();
 }
 
 static void lpc_dispatch_ser_irqs(struct lpcm *lpc, uint32_t irqs,
diff --git a/include/ast.h b/include/ast.h
index 1b5e0013542b..b30f7bf27737 100644
--- a/include/ast.h
+++ b/include/ast.h
@@ -83,6 +83,7 @@ uint32_t ast_ahb_readl(uint32_t reg);
 
 bool ast_sio_init(void);
 bool ast_can_isolate_sp(void);
+bool ast_sio_disable(void);
 bool ast_io_init(void);
 bool ast_io_is_rw(void);
 bool ast_lpc_fw_is_flash(void);
diff --git a/include/lpc.h b/include/lpc.h
index 2347011d3657..bd6200e2e77c 100644
--- a/include/lpc.h
+++ b/include/lpc.h
@@ -168,4 +168,7 @@ static inline uint32_t lpc_inl(uint32_t addr)
 	return (rc == OPAL_SUCCESS) ? le32_to_cpu(d32) : 0xffffffff;
 }
 
+/* LPC IRQ error masking - required for some corner cases */
+extern void lpc_irq_err_mask_sync_no_response(void);
+
 #endif /* __LPC_H */
diff --git a/platforms/astbmc/common.c b/platforms/astbmc/common.c
index 393ddbe7dd7e..18d257c5fe46 100644
--- a/platforms/astbmc/common.c
+++ b/platforms/astbmc/common.c
@@ -439,33 +439,7 @@ void astbmc_early_init(void)
 
 static bool astbmc_isolate_via_io(void)
 {
-	uint32_t hw_strapping;
-	uint32_t silicon_rev;
-	uint8_t family;
-
-	silicon_rev = ast_ahb_readl(SCU_REVISION_ID);
-	family = SCU_REVISION_SOC_FAMILY(silicon_rev);
-
-	if (family == SCU_REVISION_SOC_FAMILY_2400) {
-		/* Strapping is read-modify-write on SCU70 */
-		hw_strapping = SCU_STRAP_SIO_DECODE_DISABLE;
-		hw_strapping |= ast_ahb_readl(SCU_HW_STRAPPING);
-	} else if (family == SCU_REVISION_SOC_FAMILY_2500) {
-		/*
-		 * Strapping is W1S on SCU70, W1C on SCU7C. We're setting a bit
-		 * so read-modify-write *should* work, but in reality it breaks
-		 * the AXI/AHB divider, so don't do that.
-		 */
-		hw_strapping = SCU_STRAP_SIO_DECODE_DISABLE;
-	} else {
-		prerror("PLAT: Unrecognised BMC silicon revision 0x%x, isolation failed\n",
-			silicon_rev);
-		return false;
-	}
-
-	ast_ahb_writel(hw_strapping, SCU_HW_STRAPPING);
-
-	return true;
+	return ast_sio_disable();
 }
 
 static bool astbmc_isolate_via_ipmi(void)
-- 
2.17.1



More information about the Skiboot mailing list