hw21,26: add start/wakeup reason detection logic (#58)
Move detection logic before PMIC rails init Add detection logic in hw21/26 Detect start events from pmic Co-authored-by: Rene Straub <rene.straub@netmodule.com> Reviewed-on: https://git.netmodule.intranet/nmrouter/u-boot/pulls/58
This commit is contained in:
parent
dc6ed546db
commit
f82ac7239a
|
|
@ -18,6 +18,14 @@
|
||||||
#define PMIC_REG_STATUS_A 0x01 /* Status of ON_KEY, WAKE, COMP1V2, DVC */
|
#define PMIC_REG_STATUS_A 0x01 /* Status of ON_KEY, WAKE, COMP1V2, DVC */
|
||||||
#define PMIC_REG_FAULT_LOG 0x05 /* PMIC fault log register, holding reset reason */
|
#define PMIC_REG_FAULT_LOG 0x05 /* PMIC fault log register, holding reset reason */
|
||||||
#define PMIC_FAULT_TWD_ERROR_MASK 0x01 /* Watchdog timeout detected */
|
#define PMIC_FAULT_TWD_ERROR_MASK 0x01 /* Watchdog timeout detected */
|
||||||
|
#define PMIC_FAULT_POR_MASK 0x02 /* Startup from No-Power/RTC/Delivery mode */
|
||||||
|
|
||||||
|
#define PMIC_REG_EVENT_A 0x06
|
||||||
|
#define PMIC_REG_EVENT_RTC_ALARM_MASK 0x02
|
||||||
|
#define PMIC_REG_EVENT_EVENTS_B_MASK 0x20
|
||||||
|
|
||||||
|
#define PMIC_REG_EVENT_B 0x07
|
||||||
|
#define PMIC_REG_EVENT_COMP1V2_MASK 0x04
|
||||||
|
|
||||||
#define PMIC_REG_CONTROL_D 0x11 /* Control register for blink/watchdog */
|
#define PMIC_REG_CONTROL_D 0x11 /* Control register for blink/watchdog */
|
||||||
#define PMIC_REG_GPIO14_15 0x1C /* Configuration of GPIO14/15 (mode, wake) */
|
#define PMIC_REG_GPIO14_15 0x1C /* Configuration of GPIO14/15 (mode, wake) */
|
||||||
|
|
@ -64,6 +72,8 @@
|
||||||
|
|
||||||
#define PMIC_REG_TRIM_CLDR 0x120 /* Calendar Trim register, 2's complement, 1.9ppm per bit */
|
#define PMIC_REG_TRIM_CLDR 0x120 /* Calendar Trim register, 2's complement, 1.9ppm per bit */
|
||||||
|
|
||||||
|
#define PMIC_GP_ID_0 0x121 /* General purpose ID 0 (R/W) */
|
||||||
|
|
||||||
#define PMIC_REG_CONFIG_ID 0x184 /* OTP Config ID <ver.rev> */
|
#define PMIC_REG_CONFIG_ID 0x184 /* OTP Config ID <ver.rev> */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* ether_crc.c
|
||||||
|
*
|
||||||
|
* Ethernet CRC computation
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018-2020 NetModule AG - http://www.netmodule.com/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
|
||||||
|
#include "ether_crc.h"
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t ether_crc(size_t len, uint8_t const *p)
|
||||||
|
{
|
||||||
|
uint32_t crc;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
crc = ~0;
|
||||||
|
while (len--) {
|
||||||
|
crc ^= *p++;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* an reverse the bits, cuz of way they arrive -- last-first */
|
||||||
|
crc = (crc >> 16) | (crc << 16);
|
||||||
|
crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00);
|
||||||
|
crc = (crc >> 4 & 0x0f0f0f0f) | (crc << 4 & 0xf0f0f0f0);
|
||||||
|
crc = (crc >> 2 & 0x33333333) | (crc << 2 & 0xcccccccc);
|
||||||
|
crc = (crc >> 1 & 0x55555555) | (crc << 1 & 0xaaaaaaaa);
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* ether_crc.h
|
||||||
|
*
|
||||||
|
* Ethernet CRC computation
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018-2020 NetModule AG - http://www.netmodule.com/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ETHER_CRC_H
|
||||||
|
#define ETHER_CRC_H
|
||||||
|
|
||||||
|
|
||||||
|
extern uint32_t ether_crc(size_t len, uint8_t const *p);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ETHER_CRC_H */
|
||||||
|
|
@ -10,4 +10,4 @@ ifeq ($(CONFIG_SKIP_LOWLEVEL_INIT),)
|
||||||
obj-y := mux.o
|
obj-y := mux.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
obj-y += board.o ../common/bdparser.o ../common/board_descriptor.o ../common/da9063.o fileaccess.o sja1105.o ui.o um.o
|
obj-y += board.o ../common/bdparser.o ../common/board_descriptor.o ../common/da9063.o ../common/ether_crc.o fileaccess.o sja1105.o ui.o um.o
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include "../common/bdparser.h"
|
#include "../common/bdparser.h"
|
||||||
#include "../common/board_descriptor.h"
|
#include "../common/board_descriptor.h"
|
||||||
#include "../common/da9063.h"
|
#include "../common/da9063.h"
|
||||||
|
#include "../common/ether_crc.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "sja1105.h"
|
#include "sja1105.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
|
@ -475,60 +476,142 @@ static void init_pmic_spl(void)
|
||||||
da9063_release_i2c_bus(bus);
|
da9063_release_i2c_bus(bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct reset_registers {
|
struct reset_registers {
|
||||||
uint32_t value;
|
/* Reboot Reasons, set by OS, expect watchdog set by bootloader */
|
||||||
uint32_t value_crc;
|
uint32_t rr_value;
|
||||||
|
uint32_t rr_value_crc;
|
||||||
|
|
||||||
|
/* Start Events */
|
||||||
|
uint32_t se_magic; /* Token to check presence of following fields */
|
||||||
|
uint32_t se_events; /* Events bitmask, see SE_... defines */
|
||||||
|
uint32_t se_checksum; /* Checksum over se_events */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_NRSW_BUILD
|
/* Watchdog reboot reason event */
|
||||||
|
#define RR_EXTERNAL_WATCHDOG_PATTERN 0x781f9ce2
|
||||||
|
|
||||||
static uint32_t ether_crc(size_t len, uint8_t const *p)
|
/* Start event token 'SRTE' */
|
||||||
|
#define SE_MAGIC 0x53525445
|
||||||
|
|
||||||
|
/* Possible start events (see se_events) */
|
||||||
|
#define SE_POR 0x00000001
|
||||||
|
#define SE_WATCHDOG 0x00000010
|
||||||
|
#define SE_IGNITION 0x00000100
|
||||||
|
#define SE_RTC_ALARM 0x00000200
|
||||||
|
|
||||||
|
|
||||||
|
static void print_start_reason(uint32_t events)
|
||||||
{
|
{
|
||||||
uint32_t crc;
|
puts("Start Events: ");
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
crc = ~0;
|
if (events == 0) {
|
||||||
while (len--) {
|
puts("-\n");
|
||||||
crc ^= *p++;
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
static char buffer[10+11+11+6+1];
|
||||||
|
|
||||||
/* an reverse the bits, cuz of way they arrive -- last-first */
|
buffer[0] = 0;
|
||||||
crc = (crc >> 16) | (crc << 16);
|
if (events & SE_POR)
|
||||||
crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00);
|
strncat(buffer, "PowerOn, ", sizeof(buffer));
|
||||||
crc = (crc >> 4 & 0x0f0f0f0f) | (crc << 4 & 0xf0f0f0f0);
|
if (events & SE_WATCHDOG)
|
||||||
crc = (crc >> 2 & 0x33333333) | (crc << 2 & 0xcccccccc);
|
strncat(buffer, "Watchdog, ", sizeof(buffer));
|
||||||
crc = (crc >> 1 & 0x55555555) | (crc << 1 & 0xaaaaaaaa);
|
if (events & SE_IGNITION)
|
||||||
|
strncat(buffer, "Ignition, ", sizeof(buffer));
|
||||||
|
if (events & SE_RTC_ALARM)
|
||||||
|
strncat(buffer, "RTC, ", sizeof(buffer));
|
||||||
|
|
||||||
return crc;
|
/* Trim last comma, no 0 len check required, at least one entry is present */
|
||||||
|
buffer[strlen(buffer)-2] = 0;
|
||||||
|
printf("%s\n", buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_pmic_reset_reason(unsigned int reset_reason_shm_location)
|
static void check_pmic_reset_reason(unsigned int reset_reason_shm_location)
|
||||||
{
|
{
|
||||||
volatile struct reset_registers* reset_regs = (struct reset_registers*)reset_reason_shm_location;
|
volatile struct reset_registers* reset_regs = (struct reset_registers*)reset_reason_shm_location;
|
||||||
|
uint32_t start_event = 0;
|
||||||
uint8_t state = 0x00;
|
uint8_t state = 0x00;
|
||||||
int bus;
|
int bus;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
bus = da9063_claim_i2c_bus();
|
bus = da9063_claim_i2c_bus();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check/write boot marker to GP_ID_0
|
||||||
|
* If this marker is not present, we have a power on reset
|
||||||
|
*/
|
||||||
|
ret = da9063_get_reg(PMIC_GP_ID_0, &state);
|
||||||
|
if ((ret == 0) && (state != 0xC5)) {
|
||||||
|
start_event |= SE_POR;
|
||||||
|
(void)da9063_set_reg(PMIC_GP_ID_0, 0xC5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
ret = da9063_get_reg(PMIC_REG_FAULT_LOG, &state);
|
||||||
if ((ret == 0) && (state != 0)) {
|
if ((ret == 0) && (state != 0)) {
|
||||||
|
// PMIC Watchdog
|
||||||
if (state & PMIC_FAULT_TWD_ERROR_MASK) {
|
if (state & PMIC_FAULT_TWD_ERROR_MASK) {
|
||||||
reset_regs->value = EXTERNAL_WATCHDOG_PATTERN;
|
start_event |= SE_WATCHDOG;
|
||||||
reset_regs->value_crc = ether_crc(sizeof(reset_regs->value),
|
|
||||||
(const uint8_t*)&(reset_regs->value));
|
reset_regs->rr_value = RR_EXTERNAL_WATCHDOG_PATTERN;
|
||||||
|
reset_regs->rr_value_crc = ether_crc(sizeof(reset_regs->rr_value),
|
||||||
|
(const uint8_t*)&(reset_regs->rr_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// PMIC Power On Reset (only when RTC battery is removed)
|
||||||
|
if (state & PMIC_FAULT_POR_MASK) {
|
||||||
|
start_event |= SE_POR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear pmic fault log by writing back all bits currently set */
|
/* clear pmic fault log by writing back all bits currently set */
|
||||||
da9063_set_reg(PMIC_REG_FAULT_LOG, state);
|
(void)da9063_set_reg(PMIC_REG_FAULT_LOG, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
da9063_release_i2c_bus(bus);
|
/*
|
||||||
}
|
* Event Register A
|
||||||
|
* - Event B Activity
|
||||||
|
* - RTC Alarm
|
||||||
|
*/
|
||||||
|
ret = da9063_get_reg(PMIC_REG_EVENT_A, &state);
|
||||||
|
if ((ret == 0) && (state != 0)) {
|
||||||
|
(void)da9063_set_reg(PMIC_REG_EVENT_A, state);
|
||||||
|
|
||||||
#endif
|
if (state & PMIC_REG_EVENT_RTC_ALARM_MASK) {
|
||||||
|
start_event |= SE_RTC_ALARM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state & PMIC_REG_EVENT_EVENTS_B_MASK) {
|
||||||
|
/*
|
||||||
|
* Event Register B
|
||||||
|
* - COMP 1V2: Ignition
|
||||||
|
*/
|
||||||
|
ret = da9063_get_reg(PMIC_REG_EVENT_B, &state);
|
||||||
|
if ((ret == 0) && (state != 0)) {
|
||||||
|
(void)da9063_set_reg(PMIC_REG_EVENT_B, state);
|
||||||
|
|
||||||
|
if (state & PMIC_REG_EVENT_COMP1V2_MASK) {
|
||||||
|
start_event |= SE_IGNITION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store start events in shared memory region for OS */
|
||||||
|
reset_regs->se_magic = SE_MAGIC;
|
||||||
|
reset_regs->se_events = start_event;
|
||||||
|
reset_regs->se_checksum = 0;
|
||||||
|
reset_regs->se_checksum = ether_crc(sizeof(reset_regs->se_events),
|
||||||
|
(const uint8_t*)&(reset_regs->se_events));
|
||||||
|
|
||||||
|
da9063_release_i2c_bus(bus);
|
||||||
|
|
||||||
|
print_start_reason(reset_regs->se_events);
|
||||||
|
}
|
||||||
|
|
||||||
static void init_bd_spl(void)
|
static void init_bd_spl(void)
|
||||||
{
|
{
|
||||||
|
|
@ -562,6 +645,9 @@ void am33xx_spl_board_init(void)
|
||||||
/* Get board descriptor */
|
/* Get board descriptor */
|
||||||
init_bd_spl();
|
init_bd_spl();
|
||||||
|
|
||||||
|
/* Detect reset/Wakeup reason */
|
||||||
|
check_pmic_reset_reason(RESET_REASON_SHM_LOCATION);
|
||||||
|
|
||||||
/* Setup PMIC */
|
/* Setup PMIC */
|
||||||
init_pmic_spl();
|
init_pmic_spl();
|
||||||
|
|
||||||
|
|
@ -583,10 +669,6 @@ void am33xx_spl_board_init(void)
|
||||||
/* Set MPU Frequency to what we detected now that voltages are set */
|
/* Set MPU Frequency to what we detected now that voltages are set */
|
||||||
do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
|
do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
|
||||||
|
|
||||||
#ifdef CONFIG_NRSW_BUILD
|
|
||||||
check_pmic_reset_reason(RESET_REASON_SHM_LOCATION);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Debugger can place marker at end of SRAM to stop boot here */
|
/* Debugger can place marker at end of SRAM to stop boot here */
|
||||||
if (is_jtag_boot(CONFIG_JTAG_MARKER_SPL))
|
if (is_jtag_boot(CONFIG_JTAG_MARKER_SPL))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -298,11 +298,8 @@ int eth_phy_timeout(void);
|
||||||
#define CONFIG_JTAG_MARKER_SPL 0x402FFF00
|
#define CONFIG_JTAG_MARKER_SPL 0x402FFF00
|
||||||
#define CONFIG_JTAG_MARKER_UBOOT 0x807FFF00
|
#define CONFIG_JTAG_MARKER_UBOOT 0x807FFF00
|
||||||
|
|
||||||
/* NRSW PMIC Reset Reason */
|
/* Reset and Start Reason */
|
||||||
#ifdef CONFIG_NRSW_BUILD
|
|
||||||
#define RESET_REASON_SHM_LOCATION 0x8e000000
|
#define RESET_REASON_SHM_LOCATION 0x8e000000
|
||||||
#define EXTERNAL_WATCHDOG_PATTERN 0x781f9ce2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* SPL command is not needed */
|
/* SPL command is not needed */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue