hw21, 26: suppress power on with ignition off
power down system in SPL when ignition is not active on a power-on start.
This commit is contained in:
parent
f82ac7239a
commit
f5b16d4cf7
|
|
@ -16,17 +16,21 @@
|
||||||
#define CONFIG_PMIC_I2C_ADDR 0x58 /* Pages 0 and 1, Pages 2 and 3 -> 0x59 */
|
#define CONFIG_PMIC_I2C_ADDR 0x58 /* Pages 0 and 1, Pages 2 and 3 -> 0x59 */
|
||||||
|
|
||||||
#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_STATUS_A_COMP1V2_MASK 0x08
|
||||||
|
|
||||||
#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_FAULT_POR_MASK 0x02 /* Startup from No-Power/RTC/Delivery mode */
|
||||||
|
|
||||||
#define PMIC_REG_EVENT_A 0x06
|
#define PMIC_REG_EVENT_A 0x06
|
||||||
#define PMIC_REG_EVENT_RTC_ALARM_MASK 0x02
|
#define PMIC_REG_EVENT_RTC_ALARM_MASK 0x02
|
||||||
|
#define PMIC_REG_EVENT_RTC_TICK_MASK 0x04
|
||||||
#define PMIC_REG_EVENT_EVENTS_B_MASK 0x20
|
#define PMIC_REG_EVENT_EVENTS_B_MASK 0x20
|
||||||
|
|
||||||
#define PMIC_REG_EVENT_B 0x07
|
#define PMIC_REG_EVENT_B 0x07
|
||||||
#define PMIC_REG_EVENT_COMP1V2_MASK 0x04
|
#define PMIC_REG_EVENT_COMP1V2_MASK 0x04
|
||||||
|
|
||||||
|
#define PMIC_REG_CONTROL_A 0x0E /* Control register for power states */
|
||||||
#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) */
|
||||||
#define PMIC_REG_GPIO_MODE0_7 0x1D /* Control register for GPIOs 0..7 */
|
#define PMIC_REG_GPIO_MODE0_7 0x1D /* Control register for GPIOs 0..7 */
|
||||||
|
|
|
||||||
|
|
@ -153,8 +153,10 @@ static int hw_type = -1;
|
||||||
static char hw_variant_name[64];
|
static char hw_variant_name[64];
|
||||||
#else
|
#else
|
||||||
static int hw_type = -1;
|
static int hw_type = -1;
|
||||||
|
static uint32_t sys_start_event = 0x0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(CONFIG_SPL_BUILD)
|
#if !defined(CONFIG_SPL_BUILD)
|
||||||
static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
|
static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -416,27 +418,6 @@ static void pmic_disable_auto_mode(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pmic_ignition_gate_on(void)
|
|
||||||
{
|
|
||||||
uint8_t val;
|
|
||||||
|
|
||||||
/* Configure GPIO15 to permanent high, so that ignition sense signal is readable */
|
|
||||||
|
|
||||||
(void)da9063_set_reg(PMIC_REG_GPIO14_15, 0xCC); /* GPIO14/15 = Outputs open drain */
|
|
||||||
|
|
||||||
(void)da9063_get_reg(PMIC_REG_CONFIG_L, &val); /* Enable pull ups on GPIO14/15 */
|
|
||||||
val |= 0xC0;
|
|
||||||
(void)da9063_set_reg(PMIC_REG_CONFIG_L, val);
|
|
||||||
|
|
||||||
(void)da9063_get_reg(PMIC_REG_CONTROL_D, &val); /* No blinking, state selected by GPIOxx_MODE */
|
|
||||||
val &= ~0xF8;
|
|
||||||
(void)da9063_set_reg(PMIC_REG_CONTROL_D, val);
|
|
||||||
|
|
||||||
(void)da9063_get_reg(PMIC_REG_GPIO_MODE8_15, &val); /* Set to GPIO14,15 to high */
|
|
||||||
val |= 0xC0;
|
|
||||||
(void)da9063_set_reg(PMIC_REG_GPIO_MODE8_15, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_pmic_spl(void)
|
static void init_pmic_spl(void)
|
||||||
{
|
{
|
||||||
int bus;
|
int bus;
|
||||||
|
|
@ -462,8 +443,6 @@ static void init_pmic_spl(void)
|
||||||
(void)da9063_set_reg(PMIC_REG_LDO11_CONT, PMIC_LDOx_EN_MASK);
|
(void)da9063_set_reg(PMIC_REG_LDO11_CONT, PMIC_LDOx_EN_MASK);
|
||||||
mdelay(2);
|
mdelay(2);
|
||||||
|
|
||||||
pmic_ignition_gate_on();
|
|
||||||
|
|
||||||
if (hw_type == 21) {
|
if (hw_type == 21) {
|
||||||
/* hw21: trim RTC to compensate +18ppm crystal deviation */
|
/* hw21: trim RTC to compensate +18ppm crystal deviation */
|
||||||
(void)da9063_set_reg(PMIC_REG_TRIM_CLDR, (-18*10)/19);
|
(void)da9063_set_reg(PMIC_REG_TRIM_CLDR, (-18*10)/19);
|
||||||
|
|
@ -499,17 +478,18 @@ struct reset_registers {
|
||||||
#define SE_WATCHDOG 0x00000010
|
#define SE_WATCHDOG 0x00000010
|
||||||
#define SE_IGNITION 0x00000100
|
#define SE_IGNITION 0x00000100
|
||||||
#define SE_RTC_ALARM 0x00000200
|
#define SE_RTC_ALARM 0x00000200
|
||||||
|
#define SE_RTC_TICK 0x00000400
|
||||||
|
|
||||||
|
|
||||||
static void print_start_reason(uint32_t events)
|
static void print_start_reason(uint32_t events)
|
||||||
{
|
{
|
||||||
puts("Start Events: ");
|
puts("\nStart Events: ");
|
||||||
|
|
||||||
if (events == 0) {
|
if (events == 0) {
|
||||||
puts("-\n");
|
puts("-\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
static char buffer[10+11+11+6+1];
|
static char buffer[10+11+11+6+6+1];
|
||||||
|
|
||||||
buffer[0] = 0;
|
buffer[0] = 0;
|
||||||
if (events & SE_POR)
|
if (events & SE_POR)
|
||||||
|
|
@ -520,6 +500,8 @@ static void print_start_reason(uint32_t events)
|
||||||
strncat(buffer, "Ignition, ", sizeof(buffer));
|
strncat(buffer, "Ignition, ", sizeof(buffer));
|
||||||
if (events & SE_RTC_ALARM)
|
if (events & SE_RTC_ALARM)
|
||||||
strncat(buffer, "RTC, ", sizeof(buffer));
|
strncat(buffer, "RTC, ", sizeof(buffer));
|
||||||
|
if (events & SE_RTC_TICK)
|
||||||
|
strncat(buffer, "Tick, ", sizeof(buffer));
|
||||||
|
|
||||||
/* Trim last comma, no 0 len check required, at least one entry is present */
|
/* Trim last comma, no 0 len check required, at least one entry is present */
|
||||||
buffer[strlen(buffer)-2] = 0;
|
buffer[strlen(buffer)-2] = 0;
|
||||||
|
|
@ -576,6 +558,7 @@ static void check_pmic_reset_reason(unsigned int reset_reason_shm_location)
|
||||||
* Event Register A
|
* Event Register A
|
||||||
* - Event B Activity
|
* - Event B Activity
|
||||||
* - RTC Alarm
|
* - RTC Alarm
|
||||||
|
* - RTC Tick
|
||||||
*/
|
*/
|
||||||
ret = da9063_get_reg(PMIC_REG_EVENT_A, &state);
|
ret = da9063_get_reg(PMIC_REG_EVENT_A, &state);
|
||||||
if ((ret == 0) && (state != 0)) {
|
if ((ret == 0) && (state != 0)) {
|
||||||
|
|
@ -585,6 +568,10 @@ static void check_pmic_reset_reason(unsigned int reset_reason_shm_location)
|
||||||
start_event |= SE_RTC_ALARM;
|
start_event |= SE_RTC_ALARM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state & PMIC_REG_EVENT_RTC_TICK_MASK) {
|
||||||
|
start_event |= SE_RTC_TICK;
|
||||||
|
}
|
||||||
|
|
||||||
if (state & PMIC_REG_EVENT_EVENTS_B_MASK) {
|
if (state & PMIC_REG_EVENT_EVENTS_B_MASK) {
|
||||||
/*
|
/*
|
||||||
* Event Register B
|
* Event Register B
|
||||||
|
|
@ -599,8 +586,12 @@ static void check_pmic_reset_reason(unsigned int reset_reason_shm_location)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: Should we clear events here or leave them for Linux driver? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sys_start_event = start_event;
|
||||||
|
|
||||||
/* Store start events in shared memory region for OS */
|
/* Store start events in shared memory region for OS */
|
||||||
reset_regs->se_magic = SE_MAGIC;
|
reset_regs->se_magic = SE_MAGIC;
|
||||||
reset_regs->se_events = start_event;
|
reset_regs->se_events = start_event;
|
||||||
|
|
@ -613,6 +604,107 @@ static void check_pmic_reset_reason(unsigned int reset_reason_shm_location)
|
||||||
print_start_reason(reset_regs->se_events);
|
print_start_reason(reset_regs->se_events);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pmic_ignition_gate_on(void)
|
||||||
|
{
|
||||||
|
int bus;
|
||||||
|
uint8_t val;
|
||||||
|
|
||||||
|
bus = da9063_claim_i2c_bus();
|
||||||
|
|
||||||
|
/* Configure GPIO15 to permanent high, so that ignition sense signal is readable */
|
||||||
|
|
||||||
|
(void)da9063_set_reg(PMIC_REG_GPIO14_15, 0xCC); /* GPIO14/15 = Outputs open drain */
|
||||||
|
|
||||||
|
(void)da9063_get_reg(PMIC_REG_CONFIG_L, &val); /* Enable pull ups on GPIO14/15 */
|
||||||
|
val |= 0xC0;
|
||||||
|
(void)da9063_set_reg(PMIC_REG_CONFIG_L, val);
|
||||||
|
|
||||||
|
(void)da9063_get_reg(PMIC_REG_CONTROL_D, &val); /* No blinking, state selected by GPIOxx_MODE */
|
||||||
|
val &= ~0xF8;
|
||||||
|
(void)da9063_set_reg(PMIC_REG_CONTROL_D, val);
|
||||||
|
|
||||||
|
(void)da9063_get_reg(PMIC_REG_GPIO_MODE8_15, &val); /* Set to GPIO14,15 to high */
|
||||||
|
val |= 0xC0;
|
||||||
|
(void)da9063_set_reg(PMIC_REG_GPIO_MODE8_15, val);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Comparator input is debounced (10ms), see DA9063 datasheet 5.13.5
|
||||||
|
* Give enough time to stabilize input reading.
|
||||||
|
*/
|
||||||
|
mdelay(10+10);
|
||||||
|
|
||||||
|
da9063_release_i2c_bus(bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void powerdown(void)
|
||||||
|
{
|
||||||
|
int bus;
|
||||||
|
|
||||||
|
bus = da9063_claim_i2c_bus();
|
||||||
|
|
||||||
|
/* Final call, will not return */
|
||||||
|
da9063_set_reg(PMIC_REG_CONTROL_A, 0x00);
|
||||||
|
|
||||||
|
da9063_release_i2c_bus(bus);
|
||||||
|
|
||||||
|
puts("ERROR: PMIC power down failed\n");
|
||||||
|
for (;;) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reset(void)
|
||||||
|
{
|
||||||
|
/* Code copied from arm v7 lib */
|
||||||
|
udelay (50000);
|
||||||
|
|
||||||
|
disable_interrupts();
|
||||||
|
reset_misc();
|
||||||
|
reset_cpu(0);
|
||||||
|
|
||||||
|
puts("ERROR: Reset failed\n");
|
||||||
|
for (;;) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stop_if_ignition_is_off(void)
|
||||||
|
{
|
||||||
|
uint8_t state = 0x00;
|
||||||
|
int bus;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
bus = da9063_claim_i2c_bus();
|
||||||
|
|
||||||
|
ret = da9063_get_reg(PMIC_REG_STATUS_A, &state);
|
||||||
|
if (ret == 0) {
|
||||||
|
if ((state & PMIC_REG_STATUS_A_COMP1V2_MASK) == PMIC_REG_STATUS_A_COMP1V2_MASK) {
|
||||||
|
puts("Ignition : On\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
puts("Ignition : Off\n");
|
||||||
|
/*
|
||||||
|
* Ignition is off, if this is a power-on start, power down
|
||||||
|
* as this is considered an unwanted system start.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There is a chance for a race condition, when ignition is enabled
|
||||||
|
* between the check above and here. In this case we should just reset
|
||||||
|
* not power down.
|
||||||
|
* Although the risk is minimal here due to the very short time interval
|
||||||
|
* we do the check. The same logic will have to be added in other
|
||||||
|
* components.
|
||||||
|
*/
|
||||||
|
ret = da9063_get_reg(PMIC_REG_EVENT_B, &state);
|
||||||
|
if ((ret == 0) && ((state & PMIC_REG_EVENT_COMP1V2_MASK) == 0)) {
|
||||||
|
powerdown();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
da9063_release_i2c_bus(bus);
|
||||||
|
}
|
||||||
|
|
||||||
static void init_bd_spl(void)
|
static void init_bd_spl(void)
|
||||||
{
|
{
|
||||||
hw_type = 21; /* Assume hw21, unless BD tells different */
|
hw_type = 21; /* Assume hw21, unless BD tells different */
|
||||||
|
|
@ -648,6 +740,17 @@ void am33xx_spl_board_init(void)
|
||||||
/* Detect reset/Wakeup reason */
|
/* Detect reset/Wakeup reason */
|
||||||
check_pmic_reset_reason(RESET_REASON_SHM_LOCATION);
|
check_pmic_reset_reason(RESET_REASON_SHM_LOCATION);
|
||||||
|
|
||||||
|
/* Switch on ignition gate so we can read state later */
|
||||||
|
pmic_ignition_gate_on();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this is a power-on start, see if ignition is active.
|
||||||
|
* If not, power down as this is considered an unwanted system start.
|
||||||
|
*/
|
||||||
|
if (sys_start_event & SE_POR) {
|
||||||
|
stop_if_ignition_is_off();
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup PMIC */
|
/* Setup PMIC */
|
||||||
init_pmic_spl();
|
init_pmic_spl();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue