diff options
author | Andrew Jeffery <andrew@aj.id.au> | 2018-07-17 11:32:54 +0930 |
---|---|---|
committer | Stewart Smith <stewart@linux.ibm.com> | 2018-10-31 16:49:21 +1100 |
commit | 79c821bcfc4b629f633fed9744300ae7dd4fb5fc (patch) | |
tree | b18e767ec2fe68153d5e4dd456e16534f6842099 | |
parent | 20e3d130d003e592387d65da8912c859eb4241f1 (diff) | |
download | skiboot-79c821bcfc4b629f633fed9744300ae7dd4fb5fc.zip skiboot-79c821bcfc4b629f633fed9744300ae7dd4fb5fc.tar.gz skiboot-79c821bcfc4b629f633fed9744300ae7dd4fb5fc.tar.bz2 |
lpc: Silence LPC SYNC no-response error when necessary
[ Upstream commit 1d8793c64b596cfdcc3cf6035a3b4cbe3c341ae9 ]
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@aj.id.au>
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
-rw-r--r-- | hw/ast-bmc/ast-io.c | 45 | ||||
-rw-r--r-- | hw/lpc.c | 23 | ||||
-rw-r--r-- | include/ast.h | 1 | ||||
-rw-r--r-- | include/lpc.h | 3 | ||||
-rw-r--r-- | 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 eb80181..4277e2d 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; @@ -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 1b5e001..b30f7bf 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 2347011..bd6200e 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 03482fe..563d463 100644 --- a/platforms/astbmc/common.c +++ b/platforms/astbmc/common.c @@ -438,33 +438,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) |