diff --git a/board/nm/common/da9063.h b/board/nm/common/da9063.h index 344d6ce518..fa730dc097 100644 --- a/board/nm/common/da9063.h +++ b/board/nm/common/da9063.h @@ -52,6 +52,8 @@ #define PMIC_REG_ID_4_3 0x84 +#define PMIC_REG_SEQ_A 0x95 /* Sequencer End States for System and Power State */ + #define PMIC_REG_BUCK_ILIM_A 0x9A #define PMIC_REG_BUCK_ILIM_B 0x9B #define PMIC_REG_BUCK_ILIM_C 0x9C diff --git a/board/nm/nmhw21/board.c b/board/nm/nmhw21/board.c index c74256f945..7c1616d033 100644 --- a/board/nm/nmhw21/board.c +++ b/board/nm/nmhw21/board.c @@ -143,6 +143,31 @@ DECLARE_GLOBAL_DATA_PTR; #endif +struct reset_registers { + /* Reboot Reasons, set by OS, expect watchdog set by bootloader */ + 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 */ +}; + +/* Watchdog reboot reason event */ +#define RR_EXTERNAL_WATCHDOG_PATTERN 0x781f9ce2 + +/* 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 +#define SE_RTC_TICK 0x00000400 + + #if !defined(CONFIG_SPL_BUILD) /* Hardware version information of mainboard, loaded by get_hw_version() */ @@ -397,6 +422,27 @@ static void pmic_fix_config(void) } } +static void pmic_fix_config_hw26(void) +{ + int rc; + uint8_t val; + + /* Version 3.0 config for DA9063 Rev. E silicon accidentally enables GPO5 */ + rc = da9063_get_reg(PMIC_REG_CONFIG_ID, &val); + if (!rc && (val == 0x30)) { + printf("Detected v3.0 PMIC config. Fixing registers\n"); + + /* Disable GPO5 in case it was activated */ + da9063_set_gpio(5, 0); + + /* + * Move power sequencer end before to slot 12 so that + * GPO5 slot 13 does not get processed + */ + (void)da9063_set_reg(PMIC_REG_SEQ_A, 0xC2); + } +} + static void pmic_disable_auto_mode(void) { /* @@ -434,7 +480,11 @@ static void init_pmic_spl(void) /* Disable automatic mode switching */ pmic_disable_auto_mode(); } - +/* + if (hw_type == 26) { + pmic_fix_config_hw26(); + } +*/ /* Enable +3V3_GNSS (LDO6) */ (void)da9063_set_reg(PMIC_REG_LDO6_CONT, PMIC_LDOx_EN_MASK); mdelay(2); @@ -455,32 +505,6 @@ static void init_pmic_spl(void) da9063_release_i2c_bus(bus); } - -struct reset_registers { - /* Reboot Reasons, set by OS, expect watchdog set by bootloader */ - 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 */ -}; - -/* Watchdog reboot reason event */ -#define RR_EXTERNAL_WATCHDOG_PATTERN 0x781f9ce2 - -/* 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 -#define SE_RTC_TICK 0x00000400 - - static void print_start_reason(uint32_t events) { puts("\nStart Events: "); @@ -1803,6 +1827,7 @@ int board_late_init(void) switch (ui_ver) { case 1: puts("UI: V1.0\n"); break; case 2: puts("UI: V2.0\n"); break; + case 3: puts("UI: V3.0\n"); break; default: puts("UI: N/A\n"); break; } #endif @@ -2060,6 +2085,17 @@ static void ft_hw_info(void *blob) } } +static void ft_start_reason(void *blob) +{ + volatile struct reset_registers* reset_regs = (struct reset_registers*)RESET_REASON_SHM_LOCATION; + int node_offset; + + node_offset = fdt_path_offset(blob, "/"); + if (node_offset != -1) { + fdt_setprop_u32(blob, node_offset, "nm,startreason", reset_regs->se_events); + } +} + #ifndef CONFIG_NRSW_BUILD static void ft_user_module(void *blob) @@ -2187,6 +2223,7 @@ int ft_board_setup(void *blob, bd_t *bd) { ft_bootloader_version(blob); ft_hw_info(blob); + ft_start_reason(blob); #ifndef CONFIG_NRSW_BUILD ft_user_interface(blob); ft_user_module(blob); diff --git a/board/nm/nmhw21/ui.c b/board/nm/nmhw21/ui.c index 0908081d17..d3a9157559 100644 --- a/board/nm/nmhw21/ui.c +++ b/board/nm/nmhw21/ui.c @@ -38,8 +38,6 @@ - - static int ioext_i2c_bus = 0; /* -1: unitialized, 0: UI not available, 1: UI V1.x, 2: UI V2.x */ @@ -49,7 +47,6 @@ static int bus_claimed = 0; static uint8_t out_reg[2]; - static void set_output(uint bit, bool state) { if (state) { @@ -92,6 +89,8 @@ static void detect_version(void) uint8_t temp = 0; hw_version = 0; + printf("trying to detect ui\n"); + /* Try to detect PCA9539 on V1.x HW */ ret = i2c_read(CONFIG_UI_V1_I2C_ADDR, 0x00, 1, &temp, 1); @@ -106,6 +105,16 @@ static void detect_version(void) hw_version = 2; } } + + if (hw_version == 0) { + printf("trying to detect v3 ui\n"); + /* Try to detect PCA9538 on V3.x HW */ + ret = i2c_read(CONFIG_UI_V3_I2C_ADDR, 0x00, 1, &temp, 1); + if (ret == 0) { + printf("detected\n"); + hw_version = 3; + } + } } static void init_io(void) @@ -128,6 +137,14 @@ static void init_io(void) break; } + case 3: { + uint8_t dir[1] = { 0x03 }; /* Keep IO 0 & 1 as inputs */ + (void)i2c_write(CONFIG_UI_V3_I2C_ADDR, PCA9538_CONF_REG, 1, dir, 1); + + out_reg[0] = 0xFF; + break; + } + default: break; } @@ -165,6 +182,22 @@ static void v2_set_bottom_leds(int red, int green) (void)i2c_write(CONFIG_UI_V2_I2C_ADDR, PCA9538_OUT_REG, 1, out_reg, 1); } +static void v3_set_top_leds(int red, int green) +{ + set_output(UI_V2_TOP_LED_RED, red); + set_output(UI_V2_TOP_LED_GREEN, green); + + (void)i2c_write(CONFIG_UI_V3_I2C_ADDR, PCA9538_OUT_REG, 1, out_reg, 1); +} + +static void v3_set_bottom_leds(int red, int green) +{ + set_output(UI_V2_BOTTOM_LED_RED, red); + set_output(UI_V2_BOTTOM_LED_GREEN, green); + + (void)i2c_write(CONFIG_UI_V3_I2C_ADDR, PCA9538_OUT_REG, 1, out_reg, 1); +} + void ui_init(int i2c_bus) { @@ -196,6 +229,7 @@ void ui_set_top_led(int red, int green) switch (hw_version) { case 1: v1_set_top_leds(red, green); break; case 2: v2_set_top_leds(red, green); break; + case 3: v3_set_top_leds(red, green); break; default: break; } revert_i2c_bus(bus); @@ -212,6 +246,7 @@ void ui_set_bottom_led(int red, int green) switch (hw_version) { case 1: v1_set_bottom_leds(red, green); break; case 2: v2_set_bottom_leds(red, green); break; + case 3: v3_set_bottom_leds(red, green); break; default: break; } revert_i2c_bus(bus); diff --git a/board/nm/nmhw21/ui.h b/board/nm/nmhw21/ui.h index 5d86e2aa62..29200873db 100644 --- a/board/nm/nmhw21/ui.h +++ b/board/nm/nmhw21/ui.h @@ -16,6 +16,7 @@ #define CONFIG_UI_V1_I2C_ADDR 0x74 #define CONFIG_UI_V2_I2C_ADDR 0x70 +#define CONFIG_UI_V3_I2C_ADDR 0x71 /**