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 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_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_RTC_TICK_MASK 0x04
|
||||
#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_A 0x0E /* Control register for power states */
|
||||
#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_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];
|
||||
#else
|
||||
static int hw_type = -1;
|
||||
static uint32_t sys_start_event = 0x0;
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD)
|
||||
static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
|
||||
#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)
|
||||
{
|
||||
int bus;
|
||||
|
|
@ -462,8 +443,6 @@ static void init_pmic_spl(void)
|
|||
(void)da9063_set_reg(PMIC_REG_LDO11_CONT, PMIC_LDOx_EN_MASK);
|
||||
mdelay(2);
|
||||
|
||||
pmic_ignition_gate_on();
|
||||
|
||||
if (hw_type == 21) {
|
||||
/* hw21: trim RTC to compensate +18ppm crystal deviation */
|
||||
(void)da9063_set_reg(PMIC_REG_TRIM_CLDR, (-18*10)/19);
|
||||
|
|
@ -499,17 +478,18 @@ struct reset_registers {
|
|||
#define SE_WATCHDOG 0x00000010
|
||||
#define SE_IGNITION 0x00000100
|
||||
#define SE_RTC_ALARM 0x00000200
|
||||
#define SE_RTC_TICK 0x00000400
|
||||
|
||||
|
||||
static void print_start_reason(uint32_t events)
|
||||
{
|
||||
puts("Start Events: ");
|
||||
puts("\nStart Events: ");
|
||||
|
||||
if (events == 0) {
|
||||
puts("-\n");
|
||||
}
|
||||
else {
|
||||
static char buffer[10+11+11+6+1];
|
||||
static char buffer[10+11+11+6+6+1];
|
||||
|
||||
buffer[0] = 0;
|
||||
if (events & SE_POR)
|
||||
|
|
@ -520,6 +500,8 @@ static void print_start_reason(uint32_t events)
|
|||
strncat(buffer, "Ignition, ", sizeof(buffer));
|
||||
if (events & SE_RTC_ALARM)
|
||||
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 */
|
||||
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 B Activity
|
||||
* - RTC Alarm
|
||||
* - RTC Tick
|
||||
*/
|
||||
ret = da9063_get_reg(PMIC_REG_EVENT_A, &state);
|
||||
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;
|
||||
}
|
||||
|
||||
if (state & PMIC_REG_EVENT_RTC_TICK_MASK) {
|
||||
start_event |= SE_RTC_TICK;
|
||||
}
|
||||
|
||||
if (state & PMIC_REG_EVENT_EVENTS_B_MASK) {
|
||||
/*
|
||||
* 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 */
|
||||
reset_regs->se_magic = SE_MAGIC;
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
hw_type = 21; /* Assume hw21, unless BD tells different */
|
||||
|
|
@ -648,6 +740,17 @@ void am33xx_spl_board_init(void)
|
|||
/* Detect reset/Wakeup reason */
|
||||
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 */
|
||||
init_pmic_spl();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue