fusee: cleanup code and start fleshing out mariko keygen

This commit is contained in:
hexkyz
2020-12-18 18:54:23 +00:00
committed by SciresM
parent 4809ced64d
commit a05e87f78a
19 changed files with 1125 additions and 2087 deletions

View File

@@ -62,169 +62,25 @@ static void dsi_wait(uint32_t timeout, uint32_t offset, uint32_t mask, uint32_t
udelay(delay);
}
static void display_init_erista(void) {
volatile tegra_car_t *car = car_get_regs();
volatile tegra_pmc_t *pmc = pmc_get_regs();
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
/* Power on. */
uint8_t val = 0xD0;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1);
/* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */
car->rst_dev_h_clr = 0x1010000;
car->clk_enb_h_set = 0x1010000;
car->rst_dev_l_clr = 0x18000000;
car->clk_enb_l_set = 0x18000000;
car->clk_enb_x_set = 0x20000;
car->clk_source_uart_fst_mipi_cal = 0xA;
car->clk_enb_w_set = 0x80000;
car->clk_source_dsia_lp = 0xA;
/* DPD idle. */
pmc->io_dpd_req = 0x40000000;
pmc->io_dpd2_req = 0x40000000;
/* Configure pins. */
pinmux->nfc_en &= ~PINMUX_TRISTATE;
pinmux->nfc_int &= ~PINMUX_TRISTATE;
pinmux->lcd_bl_pwm &= ~PINMUX_TRISTATE;
pinmux->lcd_bl_en &= ~PINMUX_TRISTATE;
pinmux->lcd_rst &= ~PINMUX_TRISTATE;
/* Configure Backlight +-5V GPIOs. */
gpio_configure_mode(GPIO_LCD_BL_P5V, GPIO_MODE_GPIO);
gpio_configure_mode(GPIO_LCD_BL_N5V, GPIO_MODE_GPIO);
gpio_configure_direction(GPIO_LCD_BL_P5V, GPIO_DIRECTION_OUTPUT);
gpio_configure_direction(GPIO_LCD_BL_N5V, GPIO_DIRECTION_OUTPUT);
/* Enable Backlight +5V. */
gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_HIGH);
udelay(10000);
/* Enable Backlight -5V. */
gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_HIGH);
udelay(10000);
/* Configure Backlight PWM, EN and RST GPIOs. */
gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_GPIO);
gpio_configure_mode(GPIO_LCD_BL_EN, GPIO_MODE_GPIO);
gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO);
gpio_configure_direction(GPIO_LCD_BL_PWM, GPIO_DIRECTION_OUTPUT);
gpio_configure_direction(GPIO_LCD_BL_EN, GPIO_DIRECTION_OUTPUT);
gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT);
/* Enable Backlight EN. */
gpio_write(GPIO_LCD_BL_EN, GPIO_LEVEL_HIGH);
/* Configure display interface and display. */
MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG2) = 0;
do_register_writes(CAR_BASE, display_config_plld_01_erista, 4);
do_register_writes(DI_BASE, display_config_dc_01, 94);
do_register_writes(DSI_BASE, display_config_dsi_01_init_01, 8);
do_register_writes(DSI_BASE, display_config_dsi_01_init_02_erista, 1);
do_register_writes(DSI_BASE, display_config_dsi_01_init_03, 14);
do_register_writes(DSI_BASE, display_config_dsi_01_init_04_erista, 0);
do_register_writes(DSI_BASE, display_config_dsi_01_init_05, 10);
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1);
do_register_writes(DSI_BASE, display_config_dsi_01_init_06, 12);
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1);
do_register_writes(DSI_BASE, display_config_dsi_01_init_07, 14);
udelay(10000);
/* Enable Backlight RST. */
gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_HIGH);
udelay(60000);
MAKE_DSI_REG(DSI_BTA_TIMING) = 0x50204;
MAKE_DSI_REG(DSI_WR_DATA) = 0x337;
MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO), 5);
MAKE_DSI_REG(DSI_WR_DATA) = 0x406;
MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO), 5);
MAKE_DSI_REG(DSI_HOST_CONTROL) = (DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC);
dsi_wait(150000, DSI_HOST_CONTROL, DSI_HOST_CONTROL_IMM_BTA, 5000);
/* Parse LCD vendor. */
uint32_t host_response[3];
for (uint32_t i = 0; i < 3; i++) {
host_response[i] = MAKE_DSI_REG(DSI_RD_DATA);
}
/* The last word from host response is:
Bits 0-7: FAB
Bits 8-15: REV
Bits 16-23: Minor REV
*/
if ((host_response[2] & 0xFF) == 0x10) {
g_lcd_vendor = 0;
} else {
g_lcd_vendor = (host_response[2] >> 8) & 0xFF00;
}
g_lcd_vendor = (g_lcd_vendor & 0xFFFFFF00) | (host_response[2] & 0xFF);
/* LCD vendor specific configuration. */
switch (g_lcd_vendor) {
case 0x10: /* Japan Display Inc screens. */
do_dsi_sleep_or_register_writes(display_config_jdi_specific_init_01, 48);
break;
case 0xF20: /* Innolux nx-abca2 screens. */
do_dsi_sleep_or_register_writes(display_config_innolux_nx_abca2_specific_init_01, 14);
break;
case 0xF30: /* AUO nx-abca2 screens. */
do_dsi_sleep_or_register_writes(display_config_auo_nx_abca2_specific_init_01, 14);
break;
default:
/* Innolux and AUO nx-abcc screens. */
if ((g_lcd_vendor | 0x10) == 0x1030) {
do_dsi_sleep_or_register_writes(display_config_innolux_auo_40_nx_abcc_specific_init_01, 5);
}
break;
}
udelay(20000);
do_register_writes(CAR_BASE, display_config_plld_02_erista, 3);
do_register_writes(DSI_BASE, display_config_dsi_01_init_08, 1);
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1);
do_register_writes(DSI_BASE, display_config_dsi_01_init_09, 19);
MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4;
do_register_writes(DSI_BASE, display_config_dsi_01_init_10, 10);
udelay(10000);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_erista, 2);
do_register_writes(DSI_BASE, display_config_dsi_01_init_11_erista, 4);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_erista, 6);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10);
udelay(10000);
do_register_writes(DI_BASE, display_config_dc_02, 113);
}
static void display_init_mariko(void) {
void display_init(void) {
volatile tegra_car_t *car = car_get_regs();
volatile tegra_pmc_t *pmc = pmc_get_regs();
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
bool is_mariko = is_soc_mariko();
uint32_t hardware_type = fuse_get_hardware_type();
/* Power on. */
uint8_t val = 0x3A;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2, &val, 1);
val = 0x71;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2_CFG, &val, 1);
val = 0xD0;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1);
if (is_mariko) {
uint8_t val = 0x3A;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2, &val, 1);
val = 0x71;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2_CFG, &val, 1);
val = 0xD0;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1);
} else {
uint8_t val = 0xD0;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1);
}
/* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */
car->rst_dev_h_clr = 0x1010000;
@@ -247,7 +103,7 @@ static void display_init_mariko(void) {
pinmux->lcd_bl_en &= ~PINMUX_TRISTATE;
pinmux->lcd_rst &= ~PINMUX_TRISTATE;
if (hardware_type == 5) {
if (is_mariko && (hardware_type == 5)) {
/* HardwareType_Five only configures GPIO_LCD_BL_RST. */
gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO);
gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT);
@@ -282,19 +138,41 @@ static void display_init_mariko(void) {
/* Configure display interface and display. */
MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG2) = 0;
MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG0) = 0;
APB_MISC_GP_DSI_PAD_CONTROL_0 = 0;
do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4);
if (is_mariko) {
MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG0) = 0;
APB_MISC_GP_DSI_PAD_CONTROL_0 = 0;
}
if (is_mariko) {
do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4);
} else {
do_register_writes(CAR_BASE, display_config_plld_01_erista, 4);
}
do_register_writes(DI_BASE, display_config_dc_01, 94);
do_register_writes(DSI_BASE, display_config_dsi_01_init_01, 8);
do_register_writes(DSI_BASE, display_config_dsi_01_init_02_mariko, 1);
if (is_mariko) {
do_register_writes(DSI_BASE, display_config_dsi_01_init_02_mariko, 1);
} else {
do_register_writes(DSI_BASE, display_config_dsi_01_init_02_erista, 1);
}
do_register_writes(DSI_BASE, display_config_dsi_01_init_03, 14);
do_register_writes(DSI_BASE, display_config_dsi_01_init_04_mariko, 7);
if (is_mariko) {
do_register_writes(DSI_BASE, display_config_dsi_01_init_04_mariko, 7);
} else {
do_register_writes(DSI_BASE, display_config_dsi_01_init_04_erista, 0);
}
do_register_writes(DSI_BASE, display_config_dsi_01_init_05, 10);
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1);
if (is_mariko) {
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1);
} else {
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1);
}
do_register_writes(DSI_BASE, display_config_dsi_01_init_06, 12);
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1);
if (is_mariko) {
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1);
} else {
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1);
}
do_register_writes(DSI_BASE, display_config_dsi_01_init_07, 14);
udelay(10000);
@@ -303,8 +181,8 @@ static void display_init_mariko(void) {
gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_HIGH);
udelay(60000);
if (hardware_type == 5) {
if (is_mariko && (hardware_type == 5)) {
MAKE_DSI_REG(DSI_BTA_TIMING) = 0x40103;
} else {
MAKE_DSI_REG(DSI_BTA_TIMING) = 0x50204;
@@ -362,33 +240,50 @@ static void display_init_mariko(void) {
udelay(20000);
do_register_writes(CAR_BASE, display_config_plld_02_mariko, 3);
if (is_mariko) {
do_register_writes(CAR_BASE, display_config_plld_02_mariko, 3);
} else {
do_register_writes(CAR_BASE, display_config_plld_02_erista, 3);
}
do_register_writes(DSI_BASE, display_config_dsi_01_init_08, 1);
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1);
if (is_mariko) {
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1);
} else {
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1);
}
do_register_writes(DSI_BASE, display_config_dsi_01_init_09, 19);
MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4;
do_register_writes(DSI_BASE, display_config_dsi_01_init_10, 10);
udelay(10000);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2);
do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2);
do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10);
if (is_mariko) {
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2);
do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2);
do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10);
} else {
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_erista, 2);
do_register_writes(DSI_BASE, display_config_dsi_01_init_11_erista, 4);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_erista, 6);
do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10);
}
udelay(10000);
do_register_writes(DI_BASE, display_config_dc_02, 113);
}
static void display_end_erista(void) {
void display_end(void) {
volatile tegra_car_t *car = car_get_regs();
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
bool is_mariko = is_soc_mariko();
/* Disable Backlight. */
display_backlight(false);
@@ -408,93 +303,17 @@ static void display_end_erista(void) {
do_register_writes(DI_BASE, display_config_dc_01_fini_01, 13);
udelay(40000);
do_register_writes(CAR_BASE, display_config_plld_01_erista, 4);
do_register_writes(DSI_BASE, display_config_dsi_01_fini_01, 2);
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1);
do_register_writes(DSI_BASE, display_config_dsi_01_fini_02, 13);
udelay(10000);
/* LCD vendor specific shutdown. */
switch (g_lcd_vendor) {
case 0x10: /* Japan Display Inc screens. */
do_dsi_sleep_or_register_writes(display_config_jdi_specific_fini_01, 22);
break;
case 0xF30: /* AUO nx-abca2 screens. */
do_dsi_sleep_or_register_writes(display_config_auo_nx_abca2_specific_fini_01, 38);
break;
case 0x1020: /* Innolux nx-abcc screens. */
do_dsi_sleep_or_register_writes(display_config_innolux_nx_abcc_specific_fini_01, 10);
break;
case 0x1030: /* AUO nx-abcc screens. */
do_dsi_sleep_or_register_writes(display_config_auo_nx_abcc_specific_fini_01, 10);
break;
default:
break;
if (is_mariko) {
do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4);
} else {
do_register_writes(CAR_BASE, display_config_plld_01_erista, 4);
}
udelay(5000);
MAKE_DSI_REG(DSI_WR_DATA) = 0x1005;
MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST;
udelay(50000);
/* Disable Backlight RST. */
gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW);
udelay(10000);
/* Disable Backlight -5V. */
gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_LOW);
udelay(10000);
/* Disable Backlight +5V. */
gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_LOW);
udelay(10000);
/* Disable clocks. */
car->rst_dev_h_set = 0x1010000;
car->clk_enb_h_clr = 0x1010000;
car->rst_dev_l_set = 0x18000000;
car->clk_enb_l_clr = 0x18000000;
MAKE_DSI_REG(DSI_PAD_CONTROL_0) = (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF));
MAKE_DSI_REG(DSI_POWER_CONTROL) = 0;
/* Backlight PWM. */
gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_SFIO);
pinmux->lcd_bl_pwm = ((pinmux->lcd_bl_pwm & ~PINMUX_TRISTATE) | PINMUX_TRISTATE);
pinmux->lcd_bl_pwm = (((pinmux->lcd_bl_pwm >> 2) << 2) | 1);
}
static void display_end_mariko(void) {
volatile tegra_car_t *car = car_get_regs();
/* Disable Backlight. */
display_backlight(false);
MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 1;
MAKE_DSI_REG(DSI_WR_DATA) = 0x2805;
/* Wait 5 frames. */
uint32_t start_val = MAKE_HOST1X_REG(0x30A4);
while (MAKE_HOST1X_REG(0x30A4) < start_val + 5) {
/* Wait. */
}
MAKE_DI_REG(DC_CMD_STATE_ACCESS) = (READ_MUX | WRITE_MUX);
MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 0;
do_register_writes(DI_BASE, display_config_dc_01_fini_01, 13);
udelay(40000);
do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4);
do_register_writes(DSI_BASE, display_config_dsi_01_fini_01, 2);
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1);
if (is_mariko) {
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1);
} else {
do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1);
}
do_register_writes(DSI_BASE, display_config_dsi_01_fini_02, 13);
if (g_lcd_vendor != 0x2050) {
@@ -527,8 +346,8 @@ static void display_end_mariko(void) {
udelay((g_lcd_vendor == 0x2050) ? 120000 : 50000);
/* Disable Backlight RST. */
gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW);
gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW);
if (g_lcd_vendor == 0x2050) {
udelay(30000);
} else {
@@ -553,21 +372,13 @@ static void display_end_mariko(void) {
MAKE_DSI_REG(DSI_PAD_CONTROL_0) = (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF));
MAKE_DSI_REG(DSI_POWER_CONTROL) = 0;
}
void display_init(void) {
if (is_soc_mariko()) {
display_init_mariko();
} else {
display_init_erista();
}
}
void display_end(void) {
if (is_soc_mariko()) {
display_end_mariko();
} else {
display_end_erista();
if (!is_mariko) {
/* Backlight PWM. */
gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_SFIO);
pinmux->lcd_bl_pwm = ((pinmux->lcd_bl_pwm & ~PINMUX_TRISTATE) | PINMUX_TRISTATE);
pinmux->lcd_bl_pwm = (((pinmux->lcd_bl_pwm >> 2) << 2) | 1);
}
}

View File

@@ -61,52 +61,39 @@ static void config_oscillators(void) {
car->clk_sys_rate = 2;
}
static void config_gpios_erista(void) {
static void config_gpios(void) {
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
bool is_mariko = is_soc_mariko();
pinmux->uart2_tx = 0;
pinmux->uart3_tx = 0;
pinmux->pe6 = PINMUX_INPUT;
pinmux->ph6 = PINMUX_INPUT;
gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO);
gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO);
gpio_configure_mode(TEGRA_GPIO(E, 6), GPIO_MODE_GPIO);
gpio_configure_mode(TEGRA_GPIO(H, 6), GPIO_MODE_GPIO);
gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT);
gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT);
gpio_configure_direction(TEGRA_GPIO(E, 6), GPIO_DIRECTION_INPUT);
gpio_configure_direction(TEGRA_GPIO(H, 6), GPIO_DIRECTION_INPUT);
i2c_config(I2C_1);
i2c_config(I2C_5);
uart_config(UART_A);
/* Configure volume up/down buttons as inputs. */
gpio_configure_mode(GPIO_BUTTON_VOL_UP, GPIO_MODE_GPIO);
gpio_configure_mode(GPIO_BUTTON_VOL_DOWN, GPIO_MODE_GPIO);
gpio_configure_direction(GPIO_BUTTON_VOL_UP, GPIO_DIRECTION_INPUT);
gpio_configure_direction(GPIO_BUTTON_VOL_DOWN, GPIO_DIRECTION_INPUT);
}
static void config_gpios_mariko(void) {
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
uint32_t hardware_type = fuse_get_hardware_type();
/* Only for HardwareType_Iowa and HardwareType_Five. */
if ((hardware_type == 3) || (hardware_type == 5)) {
if (is_mariko) {
uint32_t hardware_type = fuse_get_hardware_type();
/* Only for HardwareType_Iowa and HardwareType_Five. */
if ((hardware_type == 3) || (hardware_type == 5)) {
pinmux->uart2_tx = 0;
pinmux->uart3_tx = 0;
gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO);
gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO);
gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT);
gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT);
}
} else {
pinmux->uart2_tx = 0;
pinmux->uart3_tx = 0;
gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO);
gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO);
gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT);
gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT);
}
pinmux->pe6 = PINMUX_INPUT;
pinmux->ph6 = PINMUX_INPUT;
if (!is_mariko) {
gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO);
gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO);
}
gpio_configure_mode(TEGRA_GPIO(E, 6), GPIO_MODE_GPIO);
gpio_configure_mode(TEGRA_GPIO(H, 6), GPIO_MODE_GPIO);
if (!is_mariko) {
gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT);
gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT);
}
gpio_configure_direction(TEGRA_GPIO(E, 6), GPIO_DIRECTION_INPUT);
gpio_configure_direction(TEGRA_GPIO(H, 6), GPIO_DIRECTION_INPUT);
@@ -120,17 +107,11 @@ static void config_gpios_mariko(void) {
gpio_configure_direction(GPIO_BUTTON_VOL_UP, GPIO_DIRECTION_INPUT);
gpio_configure_direction(GPIO_BUTTON_VOL_DOWN, GPIO_DIRECTION_INPUT);
/* Configure home button as input. */
gpio_configure_mode(TEGRA_GPIO(Y, 1), GPIO_MODE_GPIO);
gpio_configure_direction(TEGRA_GPIO(Y, 1), GPIO_DIRECTION_INPUT);
}
static void config_pmc_scratch(void) {
volatile tegra_pmc_t *pmc = pmc_get_regs();
pmc->scratch20 &= 0xFFF3FFFF;
pmc->scratch190 &= 0xFFFFFFFE;
pmc->secure_scratch21 |= 0x10;
if (is_mariko) {
/* Configure home button as input. */
gpio_configure_mode(TEGRA_GPIO(Y, 1), GPIO_MODE_GPIO);
gpio_configure_direction(TEGRA_GPIO(Y, 1), GPIO_DIRECTION_INPUT);
}
}
static void mbist_workaround(void) {
@@ -214,27 +195,36 @@ static void config_se_brom(void) {
pmc->rst_status = 0;
}
static void nx_hwinit_erista(bool enable_log) {
void nx_hwinit(bool enable_log) {
volatile tegra_pmc_t *pmc = pmc_get_regs();
volatile tegra_car_t *car = car_get_regs();
bool is_mariko = is_soc_mariko();
/* Bootrom stuff we skipped by going through RCM. */
config_se_brom();
if (!is_mariko) {
/* Bootrom stuff we skipped by going through RCM. */
config_se_brom();
AHB_AHB_SPARE_REG_0 &= 0xFFFFFF9F;
pmc->scratch49 = (((pmc->scratch49 >> 1) << 1) & 0xFFFFFFFD);
AHB_AHB_SPARE_REG_0 &= 0xFFFFFF9F;
pmc->scratch49 = (((pmc->scratch49 >> 1) << 1) & 0xFFFFFFFD);
/* Apply the memory built-in self test workaround. */
mbist_workaround();
/* Apply the memory built-in self test workaround. */
mbist_workaround();
}
/* Reboot SE. */
/* Enable SE clock. */
clkrst_reboot(CARDEVICE_SE);
if (is_mariko) {
/* Lock the SE clock. */
car->clk_source_se |= 0x100;
}
/* Initialize the fuse driver. */
fuse_init();
/* Initialize the memory controller. */
mc_enable();
if (!is_mariko) {
/* Initialize the memory controller. */
mc_enable();
}
/* Configure oscillators. */
config_oscillators();
@@ -243,9 +233,7 @@ static void nx_hwinit_erista(bool enable_log) {
APB_MISC_PP_PINMUX_GLOBAL_0 = 0;
/* Configure GPIOs. */
/* NOTE: [3.0.0+] Part of the GPIO configuration is skipped if the unit is SDEV. */
/* NOTE: [6.0.0+] The GPIO configuration's order was changed a bit. */
config_gpios_erista();
config_gpios();
/* UART debugging. */
if (enable_log) {
@@ -253,111 +241,7 @@ static void nx_hwinit_erista(bool enable_log) {
uart_init(UART_A, 115200);
}
/* Reboot CL-DVFS. */
clkrst_reboot(CARDEVICE_CL_DVFS);
/* Reboot I2C1. */
clkrst_reboot(CARDEVICE_I2C1);
/* Reboot I2C5. */
clkrst_reboot(CARDEVICE_I2C5);
/* Reboot SE. */
/* NOTE: [4.0.0+] This was removed. */
/* clkrst_reboot(CARDEVICE_SE); */
/* Reboot TZRAM. */
clkrst_reboot(CARDEVICE_TZRAM);
/* Initialize I2C1. */
/* NOTE: [6.0.0+] This was moved to after the PMIC is configured. */
i2c_init(I2C_1);
/* Initialize I2C5. */
i2c_init(I2C_5);
/* Configure the PMIC. */
uint8_t val = 0x40;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
val = 0x60;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
val = 0x38;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1);
val = 0x3A;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG1, &val, 1);
val = 0x38;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG2, &val, 1);
val = 0xF;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO4, &val, 1);
val = 0xC7;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO8, &val, 1);
val = 0x4F;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD0, &val, 1);
val = 0x29;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD1, &val, 1);
val = 0x1B;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD3, &val, 1);
/* NOTE: [3.0.0+] This was added. */
val = 0x22;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_GPIO3, &val, 1);
/* TODO: In 3.x+, if the unit is SDEV, the MBLPD bit is set. */
/*
i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1);
val |= 0x40;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1);
*/
/* Configure SD0 voltage. */
val = 42; /* 42 = (1125000 - 600000) / 12500 -> 1.125V */
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD0, &val, 1);
/* Configure and lock PMC scratch registers. */
/* NOTE: [4.0.0+] This was removed. */
config_pmc_scratch();
/* Set super clock burst policy. */
car->sclk_brst_pol = ((car->sclk_brst_pol & 0xFFFF8888) | 0x3333);
/* Configure memory controller carveouts. */
/* NOTE: [4.0.0+] This is now done in the Secure Monitor. */
/* mc_config_carveout(); */
/* Save SDRAM parameters to scratch. */
sdram_save_params(sdram_get_params(fuse_get_dram_id()));
/* Initialize SDRAM. */
sdram_init();
}
static void nx_hwinit_mariko(bool enable_log) {
volatile tegra_pmc_t *pmc = pmc_get_regs();
volatile tegra_car_t *car = car_get_regs();
/* Enable SE clock and lock it. */
clkrst_reboot(CARDEVICE_SE);
car->clk_source_se |= 0x100;
/* Make all fuse registers visible. */
clkrst_enable_fuse_regs(true);
/* Configure oscillators. */
config_oscillators();
/* Disable pinmux tristate input clamping. */
APB_MISC_PP_PINMUX_GLOBAL_0 = 0;
/* Configure GPIOs. */
config_gpios_mariko();
/* UART debugging. */
if (enable_log) {
clkrst_reboot(CARDEVICE_UARTA);
uart_init(UART_A, 115200);
}
/* Enable CL-DVFS clock. */
/* Enable CL-DVFS clock. */
clkrst_reboot(CARDEVICE_CL_DVFS);
/* Enable I2C1 clock. */
@@ -373,43 +257,71 @@ static void nx_hwinit_mariko(bool enable_log) {
i2c_init(I2C_5);
/* Configure the PMIC. */
uint8_t val = 0x40;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
val = 0x78;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
if (is_mariko) {
uint8_t val = 0x40;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
val = 0x78;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
} else {
uint8_t val = 0x40;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1);
val = 0x60;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1);
val = 0x38;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1);
val = 0x3A;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG1, &val, 1);
val = 0x38;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG2, &val, 1);
val = 0xF;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO4, &val, 1);
val = 0xC7;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO8, &val, 1);
val = 0x4F;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD0, &val, 1);
val = 0x29;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD1, &val, 1);
val = 0x1B;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD3, &val, 1);
/* NOTE: [3.0.0+] This was added. */
val = 0x22;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_GPIO3, &val, 1);
/* TODO: In 3.x+, if the unit is SDEV, the MBLPD bit is set. */
/*
i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1);
val |= 0x40;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1);
*/
}
/* Configure SD0 voltage. */
val = 0x24;
uint8_t val = 0x24;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD0, &val, 1);
/* Enable LDO8 in HardwareType_Hoag only. */
if (fuse_get_hardware_type() == 2) {
if (is_mariko && (fuse_get_hardware_type() == 2)) {
val = 0xE8;
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO8_CFG, &val, 1);
}
/* Initialize I2C1. */
i2c_init(I2C_1);
/* Set super clock burst policy. */
car->sclk_brst_pol = ((car->sclk_brst_pol & 0xFFFF8888) | 0x3333);
/* Mariko only PMC configuration for TZRAM. */
pmc->tzram_pwr_cntrl &= 0xFFFFFFFE;
pmc->tzram_non_sec_disable = 0x3;
pmc->tzram_sec_disable = 0x3;
if (is_mariko) {
/* Mariko only PMC configuration for TZRAM. */
pmc->tzram_pwr_cntrl &= 0xFFFFFFFE;
pmc->tzram_non_sec_disable = 0x3;
pmc->tzram_sec_disable = 0x3;
}
/* Save SDRAM parameters to scratch. */
sdram_save_params(sdram_get_params(fuse_get_dram_id()));
/* Initialize SDRAM. */
sdram_init();
}
void nx_hwinit(bool enable_log) {
if (is_soc_mariko()) {
nx_hwinit_mariko(enable_log);
} else {
nx_hwinit_erista(enable_log);
}
}

View File

@@ -37,6 +37,9 @@
/* This keyslot was added in 5.0.0. */
#define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA
/* Mariko keyslots. */
#define KEYSLOT_SWITCH_MASTERKEY_MARIKO 0x7
#define KEYSLOT_AES_MAX 0x10
#define KEYSLOT_RSA_MAX 0x2