diff --git a/board/nm/common/da9063.h b/board/nm/common/da9063.h index 2692c98b88..0a0fd97586 100644 --- a/board/nm/common/da9063.h +++ b/board/nm/common/da9063.h @@ -57,6 +57,7 @@ #define PMIC_LDOx_CONF_MASK 0x80 #define PMIC_REG_ID_4_3 0x84 +#define PMIC_REG_ID_6_5 0x85 #define PMIC_REG_BUCK_ILIM_A 0x9A #define PMIC_REG_BUCK_ILIM_B 0x9B diff --git a/board/nm/nmhw21/board.c b/board/nm/nmhw21/board.c index d605e5c01c..143488e7ea 100644 --- a/board/nm/nmhw21/board.c +++ b/board/nm/nmhw21/board.c @@ -454,6 +454,26 @@ static void pmic_disable_auto_mode(void) } } +static void pmic_gnss_pwr_sequence(void) +{ + int rc; + uint8_t val; + + /* + * GNSS 3.3V needs to start at same time as board 3.3V. + * Modify LDO6 configuration accordingly if not already done. + */ + rc = da9063_get_reg(PMIC_REG_ID_6_5, &val); + if (!rc && (val != 0x20)) { + (void)da9063_set_reg(PMIC_REG_ID_6_5, 0x20); /* Add LDO6 to sequencer, slot 2 */ + (void)da9063_set_reg(PMIC_REG_CONFIG_G, 0x64); /* LDO6 automatic enable control by sequencer */ + } + + /* Enable +3V3_GNSS (LDO6) */ + (void)da9063_set_reg(PMIC_REG_LDO6_CONT, PMIC_LDOx_EN_MASK); + mdelay(2); +} + static void init_pmic_spl(void) { int bus; @@ -471,9 +491,7 @@ static void init_pmic_spl(void) pmic_disable_auto_mode(); } - /* Enable +3V3_GNSS (LDO6) */ - (void)da9063_set_reg(PMIC_REG_LDO6_CONT, PMIC_LDOx_EN_MASK); - mdelay(2); + pmic_gnss_pwr_sequence(); /* Enable +5V_CAN (LDO11 Switch) */ (void)da9063_set_reg(PMIC_REG_LDO11_CONT, PMIC_LDOx_EN_MASK); @@ -1148,12 +1166,33 @@ static void init_gsm(void) #endif } -static void init_gnss(void) +static void init_gnss(uint32_t reset_reason_shm_location) { + volatile struct reset_registers* reset_regs = (struct reset_registers*)reset_reason_shm_location; + bool do_reset = false; + /* - * Release GNSS reset line, so that module starts up early + * Release GNSS reset line, so that module starts up early. + * Excpetion: If this is an initial power up, we reset the module to ensure defined operation. + * Reasoning: Some NEO-M9 modems start in Safe Boot mode, due to power sequencing. */ - REQUEST_AND_SET_GPIO(GPIO_RST_GNSS); + puts("GNSS: "); + + if (rr_is_start_reason_valid(reset_regs)) { + if ((reset_regs->sr_events & SR_POR) == SR_POR) { + do_reset = true; + } + } + + if (do_reset) { + puts("reset\n"); + REQUEST_AND_CLEAR_GPIO(GPIO_RST_GNSS); + mdelay(110); + gpio_set_value(GPIO_RST_GNSS, 1); + } else { + puts("init\n"); + REQUEST_AND_SET_GPIO(GPIO_RST_GNSS); + } } static void init_timepulse(void) @@ -1909,7 +1948,7 @@ int board_late_init(void) #endif init_sim_mux(); init_gsm(); - init_gnss(); + init_gnss(RESET_REASON_SHM_LOCATION); init_timepulse(); /*