Skip to content

Commit

Permalink
lpc: Silence LPC SYNC no-response error when necessary
Browse files Browse the repository at this point in the history
[ Upstream commit 1d8793c ]

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>
  • Loading branch information
amboar authored and stewartsmith committed Oct 31, 2018
1 parent 20e3d13 commit 79c821b
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 28 deletions.
45 changes: 45 additions & 0 deletions hw/ast-bmc/ast-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
23 changes: 22 additions & 1 deletion hw/lpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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)
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions include/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions include/lpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
28 changes: 1 addition & 27 deletions platforms/astbmc/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 79c821b

Please sign in to comment.