HW23: Add support for reset reason
Part of SSF integration BugzID: 71440
This commit is contained in:
parent
4a75ab8d4f
commit
d8d15bcfc8
|
|
@ -32,6 +32,8 @@
|
|||
#include <cdns3-uboot.h>
|
||||
#include <asm/arch/lpcg.h>
|
||||
#include "../nm-common/board_descriptor.h"
|
||||
#include "../nm-common/da9063.h"
|
||||
#include "../nm-common/reset_reason.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
|
@ -40,6 +42,9 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
#define BD_ADDRESS (0x0000)
|
||||
#define PD_ADDRESS (0x0200)
|
||||
|
||||
#define RESET_REASON_SHM_LOCATION 0x95000000
|
||||
|
||||
static uint32_t sys_start_event = 0x0;
|
||||
static BD_Context bdctx[3];
|
||||
|
||||
#define ESDHC_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \
|
||||
|
|
@ -511,9 +516,24 @@ void reset_cpu(ulong addr)
|
|||
putc('.');
|
||||
}
|
||||
|
||||
static void ft_start_event(void *blob, uint64_t reset_reason_shm_location)
|
||||
{
|
||||
volatile struct reset_registers* reset_regs = (struct reset_registers*)reset_reason_shm_location;
|
||||
if (rr_is_start_reason_valid(reset_regs)) {
|
||||
int node_offset;
|
||||
|
||||
node_offset = fdt_path_offset(blob, "/sysstate-start/");
|
||||
if (node_offset != -1) {
|
||||
|
||||
fdt_setprop_u32(blob, node_offset, "start-reason", reset_regs->sr_events);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_BOARD_SETUP
|
||||
int ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
ft_start_event(blob, RESET_REASON_SHM_LOCATION);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -539,6 +559,144 @@ int board_mmc_get_env_dev(int devno)
|
|||
return devno;
|
||||
}
|
||||
|
||||
static void check_reset_reason(uint64_t reset_reason_shm_location)
|
||||
{
|
||||
volatile struct reset_registers* reset_regs = (struct reset_registers*)reset_reason_shm_location;
|
||||
uint32_t start_reason = 0;
|
||||
uint32_t reset_reason = 0;
|
||||
uint8_t state = 0x00;
|
||||
int ret;
|
||||
char strbuf[256];
|
||||
|
||||
/*
|
||||
* Check/write boot marker to PMIC register GP_ID_1
|
||||
* If this marker is not present, we have a power on reset
|
||||
*/
|
||||
ret = da9063_get_reg(PMIC_GP_ID_1, &state);
|
||||
if ((ret == 0) && (state != 0xC5)) {
|
||||
(void)da9063_set_reg(PMIC_GP_ID_1, 0xC5);
|
||||
start_reason |= SR_POR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check Fault Log register for
|
||||
* - Power On Reset: No Power, RTC Delivery -> requires removal of RTC battery
|
||||
* - Watchdog
|
||||
*/
|
||||
ret = da9063_get_reg(PMIC_REG_FAULT_LOG, &state);
|
||||
if ((ret == 0) && (state != 0)) {
|
||||
/* clear pmic fault log by writing back all bits currently set */
|
||||
(void)da9063_set_reg(PMIC_REG_FAULT_LOG, state);
|
||||
|
||||
/* PMIC Power On Reset (only when RTC battery is removed) */
|
||||
if (state & PMIC_FAULT_POR_MASK) {
|
||||
start_reason |= SR_POR;
|
||||
}
|
||||
|
||||
/* PMIC Watchdog */
|
||||
if (state & PMIC_FAULT_TWD_ERROR_MASK) {
|
||||
start_reason |= SR_WATCHDOG;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check Wakeup Events
|
||||
* Event Register A holds:
|
||||
* - Event B, C Activity
|
||||
* - nONKEY: Button
|
||||
* - RTC Alarm
|
||||
* - RTC Tick
|
||||
* Event Register B
|
||||
* - COMP 1V2: Ignition
|
||||
*/
|
||||
ret = da9063_get_reg(PMIC_REG_EVENT_A, &state);
|
||||
if ((ret == 0) && (state != 0)) {
|
||||
(void)da9063_set_reg(PMIC_REG_EVENT_A, state);
|
||||
|
||||
if (state & PMIC_REG_EVENT_ONKEY_MASK) {
|
||||
start_reason |= (SR_WAKEUP | SR_EVT_BUTTON);
|
||||
}
|
||||
|
||||
if (state & PMIC_REG_EVENT_RTC_ALARM_MASK) {
|
||||
start_reason |= (SR_WAKEUP | SR_EVT_RTC_ALARM);
|
||||
}
|
||||
|
||||
if (state & PMIC_REG_EVENT_RTC_TICK_MASK) {
|
||||
start_reason |= (SR_WAKEUP | SR_EVT_RTC_TICK);
|
||||
}
|
||||
|
||||
if (state & PMIC_REG_EVENT_EVENTS_B_MASK) {
|
||||
uint8_t state_b;
|
||||
|
||||
ret = da9063_get_reg(PMIC_REG_EVENT_B, &state_b);
|
||||
if ((ret == 0) && (state_b != 0)) {
|
||||
(void)da9063_set_reg(PMIC_REG_EVENT_B, state_b);
|
||||
|
||||
if (state_b & PMIC_REG_EVENT_COMP1V2_MASK) {
|
||||
start_reason |= (SR_WAKEUP | SR_EVT_IGNITION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for software reboot indicated by OS via shared memory
|
||||
* - checksum valid?
|
||||
* - Reason == 'REBO' or 'OOPS'
|
||||
*/
|
||||
if (rr_is_reset_reason_valid(reset_regs))
|
||||
{
|
||||
if (reset_regs->rr_value == RR_REBOOT_PATTERN) {
|
||||
start_reason |= SR_REBOOT;
|
||||
}
|
||||
else if (reset_regs->rr_value == RR_OOPS_PATTERN) {
|
||||
/* Treat kernel oops as reboot */
|
||||
start_reason |= SR_REBOOT;
|
||||
}
|
||||
else if (reset_regs->rr_value == RR_WAKE_PATTERN) {
|
||||
start_reason |= SR_WAKEUP;
|
||||
}
|
||||
else {
|
||||
/* Unknown reset reason */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Priority decoder for start and reset reason
|
||||
*/
|
||||
if (start_reason & SR_WATCHDOG) {
|
||||
/* Watchdog has highest priority as it also sets POR and other events */
|
||||
start_reason = SR_WATCHDOG;
|
||||
reset_reason = RR_EXTERNAL_WATCHDOG_PATTERN;
|
||||
}
|
||||
else if (start_reason & SR_POR) {
|
||||
start_reason = SR_POR;
|
||||
reset_reason = RR_POWEROFF_PATTERN;
|
||||
}
|
||||
else if (start_reason & SR_WAKEUP) {
|
||||
/* Include start events when wakeup is detected */
|
||||
start_reason = SR_WAKEUP | (start_reason & SR_EVT_WAKE_MASK);
|
||||
reset_reason = RR_WAKE_PATTERN;
|
||||
}
|
||||
else if (start_reason & SR_REBOOT) {
|
||||
start_reason = SR_REBOOT;
|
||||
reset_reason = reset_regs->rr_value;
|
||||
}
|
||||
else {
|
||||
/* Unknown start reason, assume reboot */
|
||||
start_reason = SR_REBOOT;
|
||||
reset_reason = reset_regs->rr_value;
|
||||
}
|
||||
|
||||
sys_start_event = start_reason;
|
||||
|
||||
rr_set_reset_reason(reset_regs, reset_reason);
|
||||
rr_set_start_reason(reset_regs, start_reason);
|
||||
|
||||
rr_start_reason_to_str(reset_regs->sr_events, strbuf, sizeof(strbuf));
|
||||
printf("\nStart Events: %s\n", strbuf);
|
||||
}
|
||||
|
||||
static int _bd_init(void)
|
||||
{
|
||||
if (bd_get_context(&bdctx[0], BD_EEPROM_ADDR, BD_ADDRESS) != 0) {
|
||||
|
|
@ -584,6 +742,9 @@ int board_late_init(void)
|
|||
get_hw_version();
|
||||
|
||||
board_eth_init(NULL);
|
||||
da9063_init();
|
||||
check_reset_reason(RESET_REASON_SHM_LOCATION);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ int da9063_get_reg(uint32_t reg, uint8_t* val)
|
|||
if (reg < 0x100)
|
||||
param1 = CONFIG_PMIC_I2C_ADDR | reg << 8 | read << 16;
|
||||
else
|
||||
param1 = (CONFIG_PMIC_I2C_ADDR + 1) | reg << 8 | read << 16;
|
||||
param1 = (CONFIG_PMIC_I2C_ADDR + 1) | (reg & 0xff) << 8 | read << 16;
|
||||
|
||||
ret = sc_misc_board_ioctl(ipc, ¶m1, &data, &data_len);
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ int da9063_set_reg(uint32_t reg, uint8_t val)
|
|||
{
|
||||
sc_err_t ret;
|
||||
uint8_t read = 0;
|
||||
uint32_t param1 = CONFIG_PMIC_I2C_ADDR | reg << 8 | read << 16;
|
||||
uint32_t param1;
|
||||
uint32_t data = val;
|
||||
uint32_t data_len = 1;
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ int da9063_set_reg(uint32_t reg, uint8_t val)
|
|||
if (reg < 0x100)
|
||||
param1 = CONFIG_PMIC_I2C_ADDR | reg << 8 | read << 16;
|
||||
else
|
||||
param1 = (CONFIG_PMIC_I2C_ADDR + 1) | reg << 8 | read << 16;
|
||||
param1 = (CONFIG_PMIC_I2C_ADDR + 1) | (reg & 0xff) << 8 | read << 16;
|
||||
|
||||
ret = sc_misc_board_ioctl(ipc, ¶m1, &data, &data_len);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue