soc/qualcomm/common: Add spmi_read8_safe helper with retry logic
Introduce `spmi_read8_safe` to handle transient SPMI bus errors that can occur during early power sequencing. This helper implements a retry mechanism (up to 6 attempts) with a 50ms delay between reads. Providing a "safe" read wrapper prevents the system from misinterpreting transient arbiter errors (ERROR_SPMI_READ_FAILED) as valid zero data, which is critical for preventing premature power-offs when reading input current . BUG=b:436391478 BRANCH=none TEST=Verified that SPMI read failures in the charging applet now trigger the retry loop and successfully recover on Bluey. Change-Id: Id1b770d2cd91ccb069933bd9b023b867a7507009 Signed-off-by: Subrata Banik <subratabanik@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/91766 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Kapil Porwal <kapilporwal@google.com>
This commit is contained in:
parent
444691603d
commit
2f93e4331e
2 changed files with 29 additions and 1 deletions
|
|
@ -12,5 +12,6 @@
|
|||
int spmi_read8(uint32_t addr);
|
||||
int spmi_write8(uint32_t addr, uint8_t data);
|
||||
int spmi_read_bytes(uint32_t addr, uint8_t *data, uint32_t num_bytes);
|
||||
int spmi_read8_safe(uint32_t reg);
|
||||
|
||||
#endif // __SOC_QCOM_SPMI_H__
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <arch/mmio.h>
|
||||
#include <commonlib/bsd/stdlib.h>
|
||||
#include <delay.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/qcom_spmi.h>
|
||||
#include <timer.h>
|
||||
|
|
@ -19,9 +20,14 @@
|
|||
|
||||
#define ERROR_APID_NOT_FOUND (-(int)BIT(8))
|
||||
#define ERROR_TIMEOUT (-(int)BIT(9))
|
||||
/* Add this for your specific SPMI read error (-9) */
|
||||
#define ERROR_SPMI_READ_FAILED (-9)
|
||||
|
||||
#define ARB_COMMAND_TIMEOUT_MS 100
|
||||
|
||||
#define MAX_SPMI_RETRIES 6
|
||||
#define SPMI_RETRY_DELAY_MS 50
|
||||
|
||||
// Individual register block per APID
|
||||
struct qcom_spmi_regs {
|
||||
uint32_t cmd;
|
||||
|
|
@ -101,7 +107,7 @@ int spmi_read8(uint32_t addr)
|
|||
int ret = wait_for_done(regs);
|
||||
if (ret != 0) {
|
||||
printk(BIOS_ERR, "ERROR: SPMI_ARB read error [0x%x]: 0x%x\n", addr, ret);
|
||||
return ret;
|
||||
return ERROR_SPMI_READ_FAILED;
|
||||
}
|
||||
|
||||
return read32(®s->rdata0) & 0xff;
|
||||
|
|
@ -141,3 +147,24 @@ int spmi_read_bytes(uint32_t addr, uint8_t *data, uint32_t num_bytes)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper to handle transient SPMI bus errors with retries */
|
||||
int spmi_read8_safe(uint32_t reg)
|
||||
{
|
||||
int val;
|
||||
int retries = 0;
|
||||
|
||||
do {
|
||||
val = spmi_read8(reg);
|
||||
if (val != ERROR_SPMI_READ_FAILED)
|
||||
return val;
|
||||
|
||||
printk(BIOS_WARNING, "SPMI read error at 0x%x. Retry %d/%d in %dms\n",
|
||||
reg, retries + 1, MAX_SPMI_RETRIES, SPMI_RETRY_DELAY_MS);
|
||||
|
||||
mdelay(SPMI_RETRY_DELAY_MS);
|
||||
retries++;
|
||||
} while (retries < MAX_SPMI_RETRIES);
|
||||
|
||||
return ERROR_SPMI_READ_FAILED;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue