diff --git a/exosphere/lp0fw/src/car.h b/exosphere/lp0fw/src/car.h index 6716ef219..5cc0b5d90 100644 --- a/exosphere/lp0fw/src/car.h +++ b/exosphere/lp0fw/src/car.h @@ -63,6 +63,9 @@ #define CLK_RST_CONTROLLER_CLK_ENB_V_SET_0 MAKE_CAR_REG(0x440) #define CLK_RST_CONTROLLER_CLK_ENB_W_SET_0 MAKE_CAR_REG(0x448) +#define CLK_RST_CONTROLLER_CLK_ENB_H_CLR_0 MAKE_CAR_REG(0x32C) +#define CLK_RST_CONTROLLER_CLK_ENB_W_CLR_0 MAKE_CAR_REG(0x44C) + #define NUM_CAR_BANKS 7 typedef enum { diff --git a/exosphere/lp0fw/src/cluster.c b/exosphere/lp0fw/src/cluster.c index 05cacf2ea..0ffd20940 100644 --- a/exosphere/lp0fw/src/cluster.c +++ b/exosphere/lp0fw/src/cluster.c @@ -25,6 +25,20 @@ #include "i2c.h" #include "sysreg.h" +static void cluster_pmc_enable_partition(uint32_t mask, uint32_t toggle) { + /* Set toggle if unset. */ + if (!(APBDEV_PMC_PWRGATE_STATUS_0 & mask)) { + APBDEV_PMC_PWRGATE_TOGGLE_0 = toggle; + } + + /* Wait until toggle set. */ + while (!(APBDEV_PMC_PWRGATE_STATUS_0 & mask)) { } + + /* Remove clamping. */ + APBDEV_PMC_REMOVE_CLAMPING_CMD_0 = mask; + while (!(APBDEV_PMC_CLAMP_STATUS_0 & mask)) { } +} + void cluster_initialize_cpu(void) { /* Hold CoreSight in reset. */ CLK_RST_CONTROLLER_RST_DEV_U_SET_0 = 0x200; @@ -88,8 +102,32 @@ void cluster_initialize_cpu(void) { CLK_RST_CONTROLLER_CLK_SOURCE_I2C5_0 = 0x4; CLK_RST_CONTROLLER_RST_DEV_H_CLR_0 = 0x8000; - /* Enable the PMIC. */ + /* Enable the PMIC, wait 2ms. */ i2c_enable_pmic(); + timer_wait(2000); + + /* Enable power to the CRAIL partition. */ + cluster_pmc_enable_partition(1, 0x100); + + /* Remove SW clamp to CRAIL. */ + APBDEV_PMC_SET_SW_CLAMP_0 = 0; + APBDEV_PMC_REMOVE_CLAMPING_CMD_0 = 1; + while (!(APBDEV_PMC_CLAMP_STATUS_0 & 1)) { } + + /* Nintendo manually counts down from 8. I am not sure why this happens. */ + { + volatile int32_t counter = 8; + while (counter >= 0) { + counter--; + } + } + + /* Power off I2C5. */ + CLK_RST_CONTROLLER_RST_DEV_H_SET_0 = 0x8000; + CLK_RST_CONTROLLER_CLK_ENB_H_CLR_0 = 0x8000; + + /* Disable clock to CL_DVFS */ + CLK_RST_CONTROLLER_CLK_ENB_W_CLR_0 = 0x08000000; /* TODO: This function is enormous */ } diff --git a/exosphere/lp0fw/src/pmc.h b/exosphere/lp0fw/src/pmc.h index 08cd1f3b8..d4528e80c 100644 --- a/exosphere/lp0fw/src/pmc.h +++ b/exosphere/lp0fw/src/pmc.h @@ -31,12 +31,14 @@ #define APBDEV_PMC_CLAMP_STATUS_0 MAKE_PMC_REG(0x02C) -#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_PMC_REG(0x038) +#define APBDEV_PMC_PWRGATE_TOGGLE_0 MAKE_PMC_REG(0x030) +#define APBDEV_PMC_REMOVE_CLAMPING_CMD_0 MAKE_PMC_REG(0x034) +#define APBDEV_PMC_PWRGATE_STATUS_0 MAKE_PMC_REG(0x038) #define APBDEV_PMC_SCRATCH12_0 MAKE_PMC_REG(0x080) #define APBDEV_PMC_SCRATCH13_0 MAKE_PMC_REG(0x084) #define APBDEV_PMC_SCRATCH18_0 MAKE_PMC_REG(0x098) -#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818) +#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818) #define APBDEV_PMC_OSC_EDPD_OVER_0 MAKE_PMC_REG(0x1A4)