diff --git a/bdk/soc/hw_init.c b/bdk/soc/hw_init.c index ea73f3e..dd79dc6 100644 --- a/bdk/soc/hw_init.c +++ b/bdk/soc/hw_init.c @@ -56,6 +56,14 @@ extern volatile nyx_storage_t *nyx_str; * PCLK - 68MHz init (-> 136MHz -> OC/4). */ +u32 hw_get_chip_id() +{ + if (((APB_MISC(APB_MISC_GP_HIDREV) >> 4) & 0xF) >= GP_HIDREV_MAJOR_T210B01) + return GP_HIDREV_MAJOR_T210B01; + else + return GP_HIDREV_MAJOR_T210; +} + static void _config_oscillators() { CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4; // Set CLK_M_DIVISOR to 2. @@ -79,32 +87,38 @@ static void _config_oscillators() CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3. } -static void _config_gpios() +static void _config_gpios(bool nx_hoag) { // Clamp inputs when tristated. APB_MISC(APB_MISC_PP_PINMUX_GLOBAL) = 0; - PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0; - PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0; + if (!nx_hoag) + { + PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0; + PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0; + + // Set pin mode for UARTB/C TX pins. +#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B + gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO); +#endif +#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_C + gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO); +#endif + + // Enable input logic for UARTB/C TX pins. + gpio_output_enable(GPIO_PORT_G, GPIO_PIN_0, GPIO_OUTPUT_DISABLE); + gpio_output_enable(GPIO_PORT_D, GPIO_PIN_1, GPIO_OUTPUT_DISABLE); + } // Set Joy-Con IsAttached direction. PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; - // Set pin mode for Joy-Con IsAttached and UARTB/C TX pins. -#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B - gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO); -#endif -#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_C - gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO); -#endif // Set Joy-Con IsAttached mode. gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO); gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO); - // Enable input logic for Joy-Con IsAttached and UARTB/C TX pins. - gpio_output_enable(GPIO_PORT_G, GPIO_PIN_0, GPIO_OUTPUT_DISABLE); - gpio_output_enable(GPIO_PORT_D, GPIO_PIN_1, GPIO_OUTPUT_DISABLE); + // Enable input logic for Joy-Con IsAttached pins. gpio_output_enable(GPIO_PORT_E, GPIO_PIN_6, GPIO_OUTPUT_DISABLE); gpio_output_enable(GPIO_PORT_H, GPIO_PIN_6, GPIO_OUTPUT_DISABLE); @@ -269,13 +283,13 @@ static void _config_se_brom() APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10); } -static void _config_regulators() +static void _config_regulators(bool tegra_t210) { // Disable low battery shutdown monitor. max77620_low_battery_monitor_config(false); // Disable SDMMC1 IO power. - gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE); + gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW); max77620_regulator_enable(REGULATOR_LDO2, 0); sd_power_cycle_time_start = get_tmr_ms(); @@ -283,46 +297,52 @@ static void _config_regulators() i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, BIT(6) | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off. - // Configure all Flexible Power Sequencers. - i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0, - (7 << MAX77620_FPS_TIME_PERIOD_SHIFT)); - i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1, - (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (1 << MAX77620_FPS_EN_SRC_SHIFT)); - i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2, - (7 << MAX77620_FPS_TIME_PERIOD_SHIFT)); - max77620_regulator_config_fps(REGULATOR_LDO4); - max77620_regulator_config_fps(REGULATOR_LDO8); - max77620_regulator_config_fps(REGULATOR_SD0); - max77620_regulator_config_fps(REGULATOR_SD1); - max77620_regulator_config_fps(REGULATOR_SD3); + if (tegra_t210) + { + // Configure all Flexible Power Sequencers for MAX77620. + i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT)); + i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (1 << MAX77620_FPS_EN_SRC_SHIFT)); + i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT)); + max77620_regulator_config_fps(REGULATOR_LDO4); + max77620_regulator_config_fps(REGULATOR_LDO8); + max77620_regulator_config_fps(REGULATOR_SD0); + max77620_regulator_config_fps(REGULATOR_SD1); + max77620_regulator_config_fps(REGULATOR_SD3); - i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3, - (4 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT)); // 3.x+ + i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3, + (4 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT)); // 3.x+ - // Set vdd_core voltage to 1.125V. - max77620_regulator_set_voltage(REGULATOR_SD0, 1125000); + // Set vdd_core voltage to 1.125V. + max77620_regulator_set_voltage(REGULATOR_SD0, 1125000); - // Fix CPU/GPU after a L4T warmboot. - i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 2); - i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO6, 2); + // Fix CPU/GPU after a L4T warmboot. + i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 2); + i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO6, 2); - i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_0_95V); // Disable power. - i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVS_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_1_09V); // Enable DVS power. - i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL1_REG, MAX77621_RAMP_50mV_PER_US); - i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL2_REG, - MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS | - MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL); + i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_0_95V); // Disable power. + i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVS_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_1_09V); // Enable DVS power. + i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL1_REG, MAX77621_RAMP_50mV_PER_US); + i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL2_REG, + MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS | + MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL); - i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_0_95V); // Disable power. - i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_VOUT_DVS_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_1_09V); // Enable DVS power. - i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL1_REG, MAX77621_RAMP_50mV_PER_US); - i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL2_REG, - MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS | - MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL); + i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_0_95V); // Disable power. + i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_VOUT_DVS_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_1_09V); // Enable DVS power. + i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL1_REG, MAX77621_RAMP_50mV_PER_US); + i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL2_REG, + MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS | + MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL); + } + else // Tegra X1+ set vdd_core voltage to 1.05V. + max77620_regulator_set_voltage(REGULATOR_SD0, 1050000); } void hw_init() { + // Get Chip ID. + bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210; + bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG; + // Bootrom stuff we skipped by going through rcm. _config_se_brom(); //FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11; @@ -330,7 +350,8 @@ void hw_init() PMC(APBDEV_PMC_SCRATCH49) = PMC(APBDEV_PMC_SCRATCH49) & 0xFFFFFFFC; // Perform Memory Built-In Self Test WAR if T210. - _mbist_workaround(); + if (tegra_t210) + _mbist_workaround(); // Enable Security Engine clock. clock_enable_se(); @@ -348,7 +369,7 @@ void hw_init() _config_oscillators(); // Initialize pin configuration. - _config_gpios(); + _config_gpios(nx_hoag); #ifdef DEBUG_UART_PORT clock_enable_uart(DEBUG_UART_PORT); @@ -365,21 +386,34 @@ void hw_init() // Enable clock to TZRAM. clock_enable_tzram(); - // Initialize I2C5, mandatory for PMIC comms. - i2c_init(I2C_1); + // Initialize I2C5, mandatory for PMIC. i2c_init(I2C_5); + //! TODO: Why? Device is NFC MCU on Lite. + if (nx_hoag) + max77620_regulator_set_volt_and_flags(REGULATOR_LDO8, 2800000, MAX77620_POWER_MODE_NORMAL); + + // Initialize I2C1 for various power related devices. + i2c_init(I2C_1); + // Enable charger in case it's disabled. bq24193_enable_charger(); // Initialize various regulators based on Erista/Mariko platform. - _config_regulators(); + _config_regulators(tegra_t210); _config_pmc_scratch(); // Missing from 4.x+ // Set BPMP/SCLK to PLLP_OUT (408MHz). CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; + // Disable TZRAM shutdown control and lock the regs. + if (!tegra_t210) + { + PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= 0xFFFFFFFE; + PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = 3; + PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = 3; + } // Initialize External memory controller and configure DRAM parameters. sdram_init(); diff --git a/bdk/soc/hw_init.h b/bdk/soc/hw_init.h index 9cbd917..ff9ae4a 100644 --- a/bdk/soc/hw_init.h +++ b/bdk/soc/hw_init.h @@ -22,5 +22,6 @@ void hw_init(); void hw_reinit_workaround(bool extra_reconfig, u32 magic); +u32 hw_get_chip_id(); #endif diff --git a/bdk/soc/pmc.h b/bdk/soc/pmc.h index 82796dd..45fa034 100644 --- a/bdk/soc/pmc.h +++ b/bdk/soc/pmc.h @@ -90,6 +90,9 @@ #define APBDEV_PMC_SCRATCH188 0x810 #define APBDEV_PMC_SCRATCH190 0x818 #define APBDEV_PMC_SCRATCH200 0x840 +#define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8 +#define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC +#define APBDEV_PMC_TZRAM_NON_SEC_DISABLE 0xBF0 int pmc_enable_partition(u32 part, int enable);