fusee: perform only pmic reboots on mariko
This commit is contained in:
@@ -22,9 +22,11 @@
|
||||
#include "fuse.h"
|
||||
#include "pmc.h"
|
||||
#include "timers.h"
|
||||
#include "i2c.h"
|
||||
#include "panic.h"
|
||||
#include "car.h"
|
||||
#include "btn.h"
|
||||
#include "max77620.h"
|
||||
#include "../../../fusee/common/log.h"
|
||||
#include "../../../fusee/common/vsprintf.h"
|
||||
#include "../../../fusee/common/display/video_fb.h"
|
||||
@@ -37,6 +39,37 @@
|
||||
#undef u8
|
||||
#undef u32
|
||||
|
||||
static bool is_soc_mariko(void) {
|
||||
return fuse_get_soc_type() == 1;
|
||||
}
|
||||
|
||||
__attribute__((noreturn)) static void shutdown_system(bool reboot) {
|
||||
/* Ensure that i2c5 is in a coherent state. */
|
||||
i2c_config(I2C_5);
|
||||
clkrst_reboot(CARDEVICE_I2C5);
|
||||
i2c_init(I2C_5);
|
||||
|
||||
/* Get value, set or clear software reset mask. */
|
||||
uint8_t on_off_2_val = 0;
|
||||
i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG2, &on_off_2_val, 1);
|
||||
if (reboot) {
|
||||
on_off_2_val |= MAX77620_ONOFFCNFG2_SFT_RST_WK;
|
||||
} else {
|
||||
on_off_2_val &= ~(MAX77620_ONOFFCNFG2_SFT_RST_WK);
|
||||
}
|
||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG2, &on_off_2_val, 1);
|
||||
|
||||
/* Set software reset mask. */
|
||||
uint8_t on_off_1_val = 0;
|
||||
i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &on_off_1_val, 1);
|
||||
on_off_1_val |= MAX77620_ONOFFCNFG1_SFT_RST;
|
||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &on_off_1_val, 1);
|
||||
|
||||
while (true) {
|
||||
/* Wait for reboot. */
|
||||
}
|
||||
}
|
||||
|
||||
extern uint8_t __reboot_start__[], __reboot_end__[];
|
||||
|
||||
void wait(uint32_t microseconds) {
|
||||
@@ -70,43 +103,47 @@ __attribute__((noreturn)) void pmc_reboot(uint32_t scratch0) {
|
||||
}
|
||||
|
||||
__attribute__((noreturn)) void reboot_to_self(void) {
|
||||
/* Patch SDRAM init to perform an SVC immediately after second write */
|
||||
APBDEV_PMC_SCRATCH45_0 = 0x2E38DFFF;
|
||||
APBDEV_PMC_SCRATCH46_0 = 0x6001DC28;
|
||||
/* Set SVC handler to jump to reboot stub in IRAM. */
|
||||
APBDEV_PMC_SCRATCH33_0 = 0x4003F000;
|
||||
APBDEV_PMC_SCRATCH40_0 = 0x6000F208;
|
||||
if (is_soc_mariko()) {
|
||||
/* If mariko, we can't reboot to self/payload, so just reboot. */
|
||||
shutdown_system(true);
|
||||
} else {
|
||||
/* Patch SDRAM init to perform an SVC immediately after second write */
|
||||
APBDEV_PMC_SCRATCH45_0 = 0x2E38DFFF;
|
||||
APBDEV_PMC_SCRATCH46_0 = 0x6001DC28;
|
||||
/* Set SVC handler to jump to reboot stub in IRAM. */
|
||||
APBDEV_PMC_SCRATCH33_0 = 0x4003F000;
|
||||
APBDEV_PMC_SCRATCH40_0 = 0x6000F208;
|
||||
|
||||
/* Copy reboot stub into IRAM high. */
|
||||
for (size_t i = 0; i < rebootstub_bin_size; i += sizeof(uint32_t)) {
|
||||
write32le((void *)0x4003F000, i, read32le(rebootstub_bin, i));
|
||||
/* Copy reboot stub into IRAM high. */
|
||||
for (size_t i = 0; i < rebootstub_bin_size; i += sizeof(uint32_t)) {
|
||||
write32le((void *)0x4003F000, i, read32le(rebootstub_bin, i));
|
||||
}
|
||||
|
||||
/* Copy our low part into safe IRAM. */
|
||||
for (size_t i = 0; i < 0x8000; i += sizeof(uint32_t)) {
|
||||
write32le((void *)0x40030000, i, read32le((void *)0x40008000, i));
|
||||
}
|
||||
|
||||
/* Copy our start page into fatal IRAM. */
|
||||
for (size_t i = 0; i < 0x1000; i += sizeof(uint32_t)) {
|
||||
write32le((void *)0x4003D000, i, read32le((void *)0x40010000, i));
|
||||
}
|
||||
|
||||
/* Copy our reboot handler to the rebootstub target. */
|
||||
for (size_t i = 0; i < (__reboot_end__ - __reboot_start__); i += sizeof(uint32_t)) {
|
||||
write32le((void *)0x40010000, i, read32le(__reboot_start__, i));
|
||||
}
|
||||
|
||||
/* Trigger warm reboot. */
|
||||
APBDEV_PMC_SCRATCH0_0 = (1 << 0);
|
||||
|
||||
/* Reset the processor. */
|
||||
APBDEV_PMC_CONTROL = BIT(4);
|
||||
|
||||
while (true) {
|
||||
/* Wait for reboot. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy our low part into safe IRAM. */
|
||||
for (size_t i = 0; i < 0x8000; i += sizeof(uint32_t)) {
|
||||
write32le((void *)0x40030000, i, read32le((void *)0x40008000, i));
|
||||
}
|
||||
|
||||
/* Copy our start page into fatal IRAM. */
|
||||
for (size_t i = 0; i < 0x1000; i += sizeof(uint32_t)) {
|
||||
write32le((void *)0x4003D000, i, read32le((void *)0x40010000, i));
|
||||
}
|
||||
|
||||
/* Copy our reboot handler to the rebootstub target. */
|
||||
for (size_t i = 0; i < (__reboot_end__ - __reboot_start__); i += sizeof(uint32_t)) {
|
||||
write32le((void *)0x40010000, i, read32le(__reboot_start__, i));
|
||||
}
|
||||
|
||||
/* Trigger warm reboot. */
|
||||
APBDEV_PMC_SCRATCH0_0 = (1 << 0);
|
||||
|
||||
/* Reset the processor. */
|
||||
APBDEV_PMC_CONTROL = BIT(4);
|
||||
|
||||
while (true) {
|
||||
/* Wait for reboot. */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
__attribute__((noreturn)) void wait_for_button_and_reboot(void) {
|
||||
|
||||
Reference in New Issue
Block a user