diff --git a/bdk/display/di.c b/bdk/display/di.c index 1c79823..ee4b45d 100644 --- a/bdk/display/di.c +++ b/bdk/display/di.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer + * Copyright (c) 2018-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ extern volatile nyx_storage_t *nyx_str; static u32 _display_id = 0; +static bool nx_aula = false; static void _display_panel_and_hw_end(bool no_panel_deinit); @@ -91,7 +93,7 @@ int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled) // Wait for vblank before starting the transfer. DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt. - while (DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT) + while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT)) ; } @@ -134,19 +136,22 @@ int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled) case DCS_2_BYTE_SHORT_RD_RES: memcpy(data, &fifo[2], 2); break; + case ACK_ERROR_RES: default: res = 1; break; } } + else + res = 1; // Disable host cmd packets during video and restore host control. if (video_enabled) { // Wait for vblank before reseting sync points. DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt. - while (DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT) + while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT)) ; // Reset all states of syncpt block. @@ -181,7 +186,7 @@ void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled) host_control = DSI(_DSIREG(DSI_HOST_CONTROL)); // Enable host transfer trigger. - DSI(_DSIREG(DSI_HOST_CONTROL)) |= DSI_HOST_CONTROL_TX_TRIG_HOST; + DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control | DSI_HOST_CONTROL_TX_TRIG_HOST; switch (len) { @@ -216,8 +221,71 @@ void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled) DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control; } +void display_dsi_vblank_write(u8 cmd, u32 len, void *data) +{ + u8 *fifo8; + u32 *fifo32; + + // Enable vblank interrupt. + DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = DC_CMD_INT_FRAME_END_INT; + + // Use the 4th line to transmit the host cmd packet. + DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE | DSI_DSI_LINE_TYPE(4); + + // Wait for vblank before starting the transfer. + DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt. + while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT)) + ; + + switch (len) + { + case 0: + DSI(_DSIREG(DSI_WR_DATA)) = (cmd << 8) | MIPI_DSI_DCS_SHORT_WRITE; + break; + + case 1: + DSI(_DSIREG(DSI_WR_DATA)) = ((cmd | (*(u8 *)data << 8)) << 8) | MIPI_DSI_DCS_SHORT_WRITE_PARAM; + break; + + default: + fifo32 = calloc(DSI_STATUS_RX_FIFO_SIZE * 8, 4); + fifo8 = (u8 *)fifo32; + fifo32[0] = (len << 8) | MIPI_DSI_DCS_LONG_WRITE; + fifo8[4] = cmd; + memcpy(&fifo8[5], data, len); + len += 4 + 1; // Increase length by CMD/length word and DCS CMD. + for (u32 i = 0; i < (ALIGN(len, 4) / 4); i++) + DSI(_DSIREG(DSI_WR_DATA)) = fifo32[i]; + free(fifo32); + break; + } + + // Wait for vblank before reseting sync points. + DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt. + while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT)) + ; + + // Reset all states of syncpt block. + DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = DSI_INCR_SYNCPT_SOFT_RESET; + usleep(300); // Stabilization delay. + + // Clear syncpt block reset. + DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = 0; + usleep(300); // Stabilization delay. + + // Restore video mode and host control. + DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0; + + // Disable and clear vblank interrupt. + DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = 0; + DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; +} + void display_init() { + // Get Hardware type, as it's used in various DI functions. + nx_aula = fuse_read_hw_type() == FUSE_NX_HW_TYPE_AULA; + // Check if display is already initialized. if (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_DISP1)) _display_panel_and_hw_end(true); @@ -270,22 +338,31 @@ void display_init() PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= ~PINMUX_TRISTATE; // PULL_DOWN | 1 PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN - // Set LCD +-5V pins mode and direction - gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO); - gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE); + if (nx_aula) + { + // Configure LCD RST pin. + gpio_config(GPIO_PORT_V, GPIO_PIN_2, GPIO_MODE_GPIO); + gpio_output_enable(GPIO_PORT_V, GPIO_PIN_2, GPIO_OUTPUT_ENABLE); + } + else + { + // Set LCD +-5V pins mode and direction + gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO); + gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE); - // Enable LCD power. - gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); // LCD +5V enable. - usleep(10000); - gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); // LCD -5V enable. - usleep(10000); + // Enable LCD power. + gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); // LCD +5V enable. + usleep(10000); + gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); // LCD -5V enable. + usleep(10000); - // Configure Backlight PWM/EN and LCD RST pins (BL PWM, BL EN, LCD RST). - gpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO); - gpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE); + // Configure Backlight PWM/EN and LCD RST pins (BL PWM, BL EN, LCD RST). + gpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO); + gpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE); - // Enable Backlight power. - gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH); + // Enable Backlight power. + gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH); + } // Power up supply regulator for display interface. MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0; @@ -336,35 +413,18 @@ void display_init() usleep(60000); // Setup DSI device takeover timeout. - DSI(_DSIREG(DSI_BTA_TIMING)) = 0x50204; + DSI(_DSIREG(DSI_BTA_TIMING)) = nx_aula ? 0x40103 : 0x50204; -#if 0 // Get Display ID. - _display_id = 0xCCCCCC; // Set initial value. 4th byte cleared. - display_dsi_read(MIPI_DCS_GET_DISPLAY_ID, 3, &_display_id, DSI_VIDEO_DISABLED); -#else - // Drain RX FIFO. - _display_dsi_read_rx_fifo(NULL); - - // Set reply size. - _display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, 3, 0); - _display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO); - - // Request register read. - _display_dsi_send_cmd(MIPI_DSI_DCS_READ, MIPI_DCS_GET_DISPLAY_ID, 0); - _display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO); - - // Transfer bus control to device for transmitting the reply. - DSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC; - _display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA); - - // Wait a bit for the reply. - usleep(5000); - - // MIPI_DCS_GET_DISPLAY_ID reply is a long read, size 3 x u32. + _display_id = 0xCCCCCC; for (u32 i = 0; i < 3; i++) - _display_id = DSI(_DSIREG(DSI_RD_DATA)) & 0xFFFFFF; // Skip ack and msg type info and get the payload (display id). -#endif + { + if (!display_dsi_read(MIPI_DCS_GET_DISPLAY_ID, 3, &_display_id, DSI_VIDEO_DISABLED)) + break; + + usleep(10000); + } + // Save raw Display ID to Nyx storage. nyx_str->info.disp_id = _display_id; @@ -374,9 +434,23 @@ void display_init() if ((_display_id & 0xFF) == PANEL_JDI_XXX062M) _display_id = PANEL_JDI_XXX062M; + // For Aula ensure that we have a compatible panel id. + if (nx_aula && _display_id == 0xCCCC) + _display_id = PANEL_SAM_70_UNK; + // Initialize display panel. switch (_display_id) { + case PANEL_SAM_70_UNK: + _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000); + _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0xA0, 0); // Write 0 to 0xA0. + _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, MIPI_DCS_SET_CONTROL_DISPLAY | (DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL << 8), 0); // Enable brightness control. + DSI(_DSIREG(DSI_WR_DATA)) = 0x339; // MIPI_DSI_DCS_LONG_WRITE: 3 bytes. + DSI(_DSIREG(DSI_WR_DATA)) = 0x000051; // MIPI_DCS_SET_BRIGHTNESS 0000: 0%. FF07: 100%. + DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST; + usleep(5000); + break; + case PANEL_JDI_XXX062M: exec_cfg((u32 *)DSI_BASE, _display_init_config_jdi, 43); _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000); @@ -415,7 +489,7 @@ void display_init() _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_SET_DISPLAY_ON, 20000); // Configure PLLD for DISP1. - plld_div = (1 << 20) | (24 << 11) | 1; // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 234 MHz (offset). + plld_div = (1 << 20) | (24 << 11) | 1; // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 234 MHz (offset, it's ddr btw, so normally div2). CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div; if (tegra_t210) @@ -465,6 +539,9 @@ void display_init() void display_backlight_pwm_init() { + if (_display_id == PANEL_SAM_70_UNK) + return; + clock_enable_pwm(); PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN; // Enable PWM and set it to 25KHz PFM. 29.5KHz is stock. @@ -478,20 +555,23 @@ void display_backlight(bool enable) gpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW); // Backlight PWM GPIO. } -void display_backlight_brightness(u32 brightness, u32 step_delay) +void display_dsi_backlight_brightness(u32 brightness) +{ + u16 bl_ctrl = byte_swap_16((u16)(brightness * 8)); + display_dsi_vblank_write(MIPI_DCS_SET_BRIGHTNESS, 2, &bl_ctrl); +} + +void display_pwm_backlight_brightness(u32 brightness, u32 step_delay) { u32 old_value = (PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF; if (brightness == old_value) return; - if (brightness > 255) - brightness = 255; - if (old_value < brightness) { for (u32 i = old_value; i < brightness + 1; i++) { - PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); // Enable PWM and set it to 25KHz PFM. + PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); usleep(step_delay); } } @@ -499,7 +579,7 @@ void display_backlight_brightness(u32 brightness, u32 step_delay) { for (u32 i = old_value; i > brightness; i--) { - PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); // Enable PWM and set it to 25KHz PFM. + PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); usleep(step_delay); } } @@ -507,6 +587,17 @@ void display_backlight_brightness(u32 brightness, u32 step_delay) PWM(PWM_CONTROLLER_PWM_CSR_0) = 0; } +void display_backlight_brightness(u32 brightness, u32 step_delay) +{ + if (brightness > 255) + brightness = 255; + + if (_display_id != PANEL_SAM_70_UNK) + display_pwm_backlight_brightness(brightness, step_delay); + else + display_dsi_backlight_brightness(brightness); +} + u32 display_get_backlight_brightness() { return ((PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF); @@ -532,7 +623,9 @@ static void _display_panel_and_hw_end(bool no_panel_deinit) // De-initialize video controller. exec_cfg((u32 *)DISPLAY_A_BASE, _display_video_disp_controller_disable_config, 17); exec_cfg((u32 *)DSI_BASE, _display_dsi_timing_deinit_config, 16); - usleep(10000); + + if (_display_id != PANEL_SAM_70_UNK) + usleep(10000); // De-initialize display panel. switch (_display_id) @@ -584,16 +677,23 @@ static void _display_panel_and_hw_end(bool no_panel_deinit) } // Blank - powerdown. - _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_ENTER_SLEEP_MODE, 50000); + _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_ENTER_SLEEP_MODE, + (_display_id == PANEL_SAM_70_UNK) ? 120000 : 50000); skip_panel_deinit: // Disable LCD power pins. - gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); // LCD Reset disable. - usleep(10000); - gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); // LCD -5V disable. - usleep(10000); - gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); // LCD +5V disable. - usleep(10000); + gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); // LCD Reset disable. + + if (!nx_aula) // HOS uses panel id. + { + usleep(10000); + gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); // LCD -5V disable. + usleep(10000); + gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); // LCD +5V disable. + usleep(10000); + } + else + usleep(30000); // Aula Panel. // Disable Display Interface specific clocks. CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI); @@ -606,9 +706,12 @@ skip_panel_deinit: DSI(_DSIREG(DSI_POWER_CONTROL)) = 0; // Switch LCD PWM backlight pin to special function mode and enable PWM0 mode. - gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM. - PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_TRISTATE) | PINMUX_TRISTATE; - PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode. + if (!nx_aula) + { + gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM. + PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_TRISTATE) | PINMUX_TRISTATE; + PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode. + } } void display_end() { _display_panel_and_hw_end(false); }; @@ -620,11 +723,18 @@ u16 display_get_decoded_panel_id() void display_set_decoded_panel_id(u32 id) { + // Get Hardware type, as it's used in various DI functions. + nx_aula = fuse_read_hw_type() == FUSE_NX_HW_TYPE_AULA; + // Decode Display ID. _display_id = ((id >> 8) & 0xFF00) | (id & 0xFF); if ((_display_id & 0xFF) == PANEL_JDI_XXX062M) _display_id = PANEL_JDI_XXX062M; + + // For Aula ensure that we have a compatible panel id. + if (nx_aula && _display_id == 0xCCCC) + _display_id = PANEL_SAM_70_UNK; } void display_color_screen(u32 color) @@ -637,9 +747,12 @@ void display_color_screen(u32 color) DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0; DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color; DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ; - usleep(35000); + usleep(35000); // No need to wait on Aula. - display_backlight(true); + if (_display_id != PANEL_SAM_70_UNK) + display_backlight(true); + else + display_backlight_brightness(255, 0); } u32 *display_init_framebuffer_pitch() @@ -649,7 +762,7 @@ u32 *display_init_framebuffer_pitch() // This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 1280x720 (line stride 720). exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch, 32); - usleep(35000); + usleep(35000); // No need to wait on Aula. return (u32 *)IPL_FB_ADDRESS; } @@ -658,8 +771,7 @@ u32 *display_init_framebuffer_pitch_inv() { // This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720). exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch_inv, 34); - - usleep(35000); + usleep(35000); // No need to wait on Aula. return (u32 *)NYX_FB_ADDRESS; } @@ -668,8 +780,7 @@ u32 *display_init_framebuffer_block() { // This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720). exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_block, 34); - - usleep(35000); + usleep(35000); // No need to wait on Aula. return (u32 *)NYX_FB_ADDRESS; } diff --git a/bdk/display/di.h b/bdk/display/di.h index 7682bdb..9229a22 100644 --- a/bdk/display/di.h +++ b/bdk/display/di.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer + * Copyright (c) 2018-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -547,17 +547,17 @@ #define MIPI_DCS_GET_DISPLAY_ID1 0xDA // GET_DISPLAY_ID Byte0, Module Manufacturer ID. #define MIPI_DCS_GET_DISPLAY_ID2 0xDB // GET_DISPLAY_ID Byte1, Module/Driver Version ID. #define MIPI_DCS_GET_DISPLAY_ID3 0xDC // GET_DISPLAY_ID Byte2, Module/Driver ID. -#define MIPI_DCS_GET_NUM_ERRORS 0x05 +#define MIPI_DCS_GET_NUM_ERRORS 0x05 // 1 byte. #define MIPI_DCS_GET_RED_CHANNEL 0x06 #define MIPI_DCS_GET_GREEN_CHANNEL 0x07 #define MIPI_DCS_GET_BLUE_CHANNEL 0x08 -#define MIPI_DCS_GET_DISPLAY_STATUS 0x09 -#define MIPI_DCS_GET_POWER_MODE 0x0A -#define MIPI_DCS_GET_ADDRESS_MODE 0x0B -#define MIPI_DCS_GET_PIXEL_FORMAT 0x0C -#define MIPI_DCS_GET_DISPLAY_MODE 0x0D -#define MIPI_DCS_GET_SIGNAL_MODE 0x0E -#define MIPI_DCS_GET_DIAGNOSTIC_RESULT 0x0F +#define MIPI_DCS_GET_DISPLAY_STATUS 0x09 // 4 bytes. +#define MIPI_DCS_GET_POWER_MODE 0x0A // 1 byte. 2: DISON, 3: NORON, 4: SLPOUT, 7: BSTON. +#define MIPI_DCS_GET_ADDRESS_MODE 0x0B // Display Access Control. 1 byte. 0: GS, 1: SS, 3: BGR. +#define MIPI_DCS_GET_PIXEL_FORMAT 0x0C // 1 byte. 4-6: DPI. +#define MIPI_DCS_GET_DISPLAY_MODE 0x0D // 1 byte. 0-2: GCS, 3: ALLPOFF, 4: ALLPON, 5: INVON. +#define MIPI_DCS_GET_SIGNAL_MODE 0x0E // 1 byte. 0: EODSI, 2: DEON, 3: PCLKON, 4: VSON, 5: HSON, 7: TEON. +#define MIPI_DCS_GET_DIAGNOSTIC_RESULT 0x0F // 1 byte. 6: FUNDT, 7: REGLD. #define MIPI_DCS_ENTER_SLEEP_MODE 0x10 #define MIPI_DCS_EXIT_SLEEP_MODE 0x11 #define MIPI_DCS_ENTER_PARTIAL_MODE 0x12 @@ -567,7 +567,7 @@ #define MIPI_DCS_ALL_PIXELS_OFF 0x22 #define MIPI_DCS_ALL_PIXELS_ON 0x23 #define MIPI_DCS_SET_CONTRAST 0x25 // VCON in 40mV steps. 7-bit integer. -#define MIPI_DCS_SET_GAMMA_CURVE 0x26 +#define MIPI_DCS_SET_GAMMA_CURVE 0x26 // 1 byte. 0-7: GC. #define MIPI_DCS_SET_DISPLAY_OFF 0x28 #define MIPI_DCS_SET_DISPLAY_ON 0x29 #define MIPI_DCS_SET_COLUMN_ADDRESS 0x2A @@ -580,11 +580,11 @@ #define MIPI_DCS_SET_SCROLL_AREA 0x33 #define MIPI_DCS_SET_TEAR_OFF 0x34 #define MIPI_DCS_SET_TEAR_ON 0x35 -#define MIPI_DCS_SET_ADDRESS_MODE 0x36 +#define MIPI_DCS_SET_ADDRESS_MODE 0x36 // Display Access Control. 1 byte. 0: GS, 1: SS, 3: BGR. #define MIPI_DCS_SET_SCROLL_START 0x37 #define MIPI_DCS_EXIT_IDLE_MODE 0x38 #define MIPI_DCS_ENTER_IDLE_MODE 0x39 -#define MIPI_DCS_SET_PIXEL_FORMAT 0x3A +#define MIPI_DCS_SET_PIXEL_FORMAT 0x3A // 1 byte. 4-6: DPI. #define MIPI_DCS_WRITE_MEMORY_CONTINUE 0x3C #define MIPI_DCS_READ_MEMORY_CONTINUE 0x3E #define MIPI_DCS_GET_3D_CONTROL 0x3F @@ -593,26 +593,34 @@ #define MIPI_DCS_GET_SCANLINE 0x45 #define MIPI_DCS_SET_TEAR_SCANLINE_WIDTH 0x46 #define MIPI_DCS_GET_SCANLINE_WIDTH 0x47 -#define MIPI_DCS_SET_BRIGHTNESS 0x51 // DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL. -#define MIPI_DCS_GET_BRIGHTNESS 0x52 -#define MIPI_DCS_SET_CONTROL_DISPLAY 0x53 -#define MIPI_DCS_GET_CONTROL_DISPLAY 0x54 -#define MIPI_DCS_SET_CABC_VALUE 0x55 -#define MIPI_DCS_GET_CABC_VALUE 0x56 -#define MIPI_DCS_SET_CABC_MIN_BRI 0x5E -#define MIPI_DCS_GET_CABC_MIN_BRI 0x5F +#define MIPI_DCS_SET_BRIGHTNESS 0x51 // DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL. 1 byte. 0-7: DBV. +#define MIPI_DCS_GET_BRIGHTNESS 0x52 // 1 byte. 0-7: DBV. +#define MIPI_DCS_SET_CONTROL_DISPLAY 0x53 // 1 byte. 2: BL, 3: DD, 5: BCTRL. +#define MIPI_DCS_GET_CONTROL_DISPLAY 0x54 // 1 byte. 2: BL, 3: DD, 5: BCTRL. +#define MIPI_DCS_SET_CABC_VALUE 0x55 // 1 byte. 0-32: C, 4-7: C. +#define MIPI_DCS_GET_CABC_VALUE 0x56 // 1 byte. 0-32: C, 4-7: C. +#define MIPI_DCS_SET_CABC_MIN_BRI 0x5E // 1 byte. 0-7: CMB. +#define MIPI_DCS_GET_CABC_MIN_BRI 0x5F // 1 byte. 0-7: CMB. +#define MIPI_DCS_GET_AUTO_BRI_DIAG_RES 0x68 // 1 byte. 6-7: D. #define MIPI_DCS_READ_DDB_START 0xA1 -#define MIPI_DCS_READ_DDB_CONTINUE 0xA8 +#define MIPI_DCS_READ_DDB_CONTINUE 0xA8 // 0x100 size. /*! MIPI DCS Panel Private CMDs. */ #define MIPI_DCS_PRIV_UNK_A0 0xA0 #define MIPI_DCS_PRIV_SET_POWER_CONTROL 0xB1 -#define MIPI_DCS_PRIV_SET_EXTC 0xB9 +#define MIPI_DCS_PRIV_SET_EXTC 0xB9 // Enable extended commands. #define MIPI_DCS_PRIV_UNK_BD 0xBD #define MIPI_DCS_PRIV_UNK_D5 0xD5 #define MIPI_DCS_PRIV_UNK_D6 0xD6 #define MIPI_DCS_PRIV_UNK_D8 0xD8 #define MIPI_DCS_PRIV_UNK_D9 0xD9 +#define MIPI_DCS_PRIV_READ_EXTC_CMD_SPI 0xFE // Read EXTC Command In SPI. 1 byte. 0-6: EXT_SPI_CNT, 7:EXT_SP. +#define MIPI_DCS_PRIV_SET_EXTC_CMD_REG 0xFF // EXTC Command Set enable register. 5 bytes. Pass: FF 98 06 04, PAGE. + +/*! MIPI DCS Panel Private CMDs PAGE 1. */ +#define MIPI_DCS_PRIV_GET_DISPLAY_ID4 0x00 +#define MIPI_DCS_PRIV_GET_DISPLAY_ID5 0x01 +#define MIPI_DCS_PRIV_GET_DISPLAY_ID6 0x02 /*! MIPI DCS CMD Defines. */ #define DCS_POWER_MODE_DISPLAY_ON BIT(2) @@ -655,11 +663,15 @@ * [20] 98 [0F]: InnoLux P062CCA-??? [UNCONFIRMED MODEL REV] * [30] 94 [0F]: AUO A062TAN01 (59.06A33.001) * [30] 95 [0F]: AUO A062TAN02 (59.06A33.002) + * [30] XX [0F]: AUO A062TAN03 (59.06A33.003) [UNCONFIRMED ID] * * 5.5" panels for Hoag skus: * [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1) - * [30] XX [10]: AUO A055TAN01 (59.05A30.001) [UNCONFIRMED ID] + * [30] 93 [10]: AUO A055TAN01 (59.05A30.001) * [40] XX [10]: Vendor 40 [UNCONFIRMED ID] + * + * 7.0" OLED panels for Aula skus: + * [50] XX [20]: Samsung AMS700XXXX [UNCONFIRMED ID and MODEL] */ /* Display ID Decoding: @@ -672,13 +684,13 @@ * 10h: Japan Display Inc. * 20h: InnoLux Corporation * 30h: AU Optronics - * 40h: Unknown1 - * 50h: Unknown2 (OLED? Samsung? LG?) + * 40h: Unknown0 + * 50h: Samsung * * Boards, Panel Size: * 0Fh: Icosa/Iowa, 6.2" * 10h: Hoag, 5.5" - * 20h: Unknown, x.x" + * 20h: Aula, 7.0" */ enum @@ -690,7 +702,8 @@ enum PANEL_AUO_A062TAN01 = 0x0F30, PANEL_INL_2J055IA_27A = 0x1020, PANEL_AUO_A055TAN01 = 0x1030, - PANEL_V40_55_UNK = 0x1040 + PANEL_V40_55_UNK = 0x1040, + PANEL_SAM_70_UNK = 0x2050 }; void display_init(); diff --git a/bdk/display/di.inl b/bdk/display/di.inl index f98c5c7..c1e5d84 100644 --- a/bdk/display/di.inl +++ b/bdk/display/di.inl @@ -200,10 +200,10 @@ static const cfg_op_t _display_dsi_init_config_part6[14] = { //DSI panel config. static const cfg_op_t _display_init_config_jdi[43] = { - {DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes. + {DSI_WR_DATA, 0x0439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes. {DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94). {DSI_TRIGGER, DSI_TRIGGER_HOST}, - {DSI_WR_DATA, 0x00BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0 to 0xBD. + {DSI_WR_DATA, 0xBD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0 to 0xBD. {DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_WR_DATA, 0x1939}, // MIPI_DSI_DCS_LONG_WRITE: 25 bytes. {DSI_WR_DATA, 0xAAAAAAD8}, // Register: 0xD8. diff --git a/bdk/input/als.c b/bdk/input/als.c index 918661b..be55426 100644 --- a/bdk/input/als.c +++ b/bdk/input/als.c @@ -23,79 +23,117 @@ #include #include -#define HOS_GAIN BH1730_GAIN_64X -#define HOS_ITIME 38 +#define BH1730_DEFAULT_GAIN BH1730_GAIN_64X +#define BH1730_DEFAULT_ICYCLE 38 -void set_als_cfg(als_table_t *als_val, u8 gain, u8 itime) +#define BH1730_INTERNAL_CLOCK_NS 2800 +#define BH1730_ADC_CALC_DELAY_US 2000 /* BH1730_INTERNAL_CLOCK_MS * 714 */ +#define BH1730_ITIME_CYCLE_TO_US 2700 /* BH1730_INTERNAL_CLOCK_MS * 964 */ + +#define BH1730_DEFAULT_ITIME_MS 100 + +#define BH1730_LUX_MULTIPLIER 3600 +#define BH1730_LUX_MULTIPLIER_AULA 1410 + +#define BH1730_LUX_MAX 100000 + +typedef struct _opt_win_cal_t { - i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain); - i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - itime)); + u32 rc; + u32 cv; + u32 ci; +} opt_win_cal_t; - als_val->gain = gain; - als_val->itime = itime; +// Nintendo Switch Icosa/Iowa Optical Window calibration. +const opt_win_cal_t opt_win_cal_default[] = { + { 500, 5002, 7502 }, + { 754, 2250, 2000 }, + { 1029, 1999, 1667 }, + { 1373, 884, 583 }, + { 1879, 309, 165 } +}; + +// Nintendo Switch Aula Optical Window calibration. +const opt_win_cal_t opt_win_cal_aula[] = { + { 231, 9697, 30300 }, + { 993, 3333, 2778 }, + { 1478, 1621, 1053 }, + { 7500, 81, 10 } +}; + +const u32 als_gain_idx_tbl[4] = { 1, 2, 64, 128 }; + +void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle) +{ + if (gain > BH1730_GAIN_128X) + gain = BH1730_GAIN_128X; + + if (!cycle) + cycle = 1; + else if (cycle > 255) + cycle = 255; + + i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain); + i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - cycle)); + + als_ctxt->gain = gain; + als_ctxt->cycle = cycle; } -void get_als_lux(als_table_t *als_val) +void get_als_lux(als_ctxt_t *als_ctxt) { u32 data[2]; - float pre_gain_lux; - float visible_light; - float ir_light; - float light_ratio; + u32 visible_light; + u32 ir_light; + u64 lux = 0; + u32 itime_us = BH1730_ITIME_CYCLE_TO_US * als_ctxt->cycle; - u8 adc_ready = 0; - u8 retries = 100; - - const float als_gain_idx_tbl[4] = { 1.0, 2.0, 64.0, 128.0 }; - const float als_norm_res = 100.0; - const float als_multiplier = 3.6; - const float als_tint = 2.7; - - // Wait for ADC to prepare new data. - while (!(adc_ready & BH1730_CTL_ADC_VALID) && retries) - { - retries--; - adc_ready = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG)); - } - - // Get visible and ir light raw data. + // Get visible and ir light raw data. Mode is continuous so waiting for new values doesn't matter. data[0] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0LOW_REG)) + (i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0HIGH_REG)) << 8); data[1] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1LOW_REG)) + (i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1HIGH_REG)) << 8); - als_val->over_limit = data[0] > 65534 || data[1] > 65534; - als_val->vi_light = data[0]; - als_val->ir_light = data[1]; + visible_light = data[0]; + ir_light = data[1]; - if (!data[0] || !retries) + als_ctxt->over_limit = visible_light > 65534 || ir_light > 65534; + als_ctxt->vi_light = visible_light; + als_ctxt->ir_light = ir_light; + + if (!visible_light) { - als_val->lux = 0.0; + als_ctxt->lux = 0; return; } - visible_light = (float)data[0]; - ir_light = (float)data[1]; - light_ratio = (float)data[1] / (float)data[0]; + // Set calibration parameters. + u32 lux_multiplier = BH1730_LUX_MULTIPLIER; + u32 opt_win_cal_count = ARRAY_SIZE(opt_win_cal_default); + const opt_win_cal_t *opt_win_cal = opt_win_cal_default; - // The following are specific to the light filter Switch uses. - if (light_ratio < 0.5) - pre_gain_lux = visible_light * 5.002 - ir_light * 7.502; - else if (light_ratio < 0.754) - pre_gain_lux = visible_light * 2.250 - ir_light * 2.000; - else if (light_ratio < 1.029) - pre_gain_lux = visible_light * 1.999 - ir_light * 1.667; - else if (light_ratio < 1.373) - pre_gain_lux = visible_light * 0.884 - ir_light * 0.583; - else if (light_ratio < 1.879) - pre_gain_lux = visible_light * 0.309 - ir_light * 0.165; - else pre_gain_lux = 0.0; + // Apply optical window calibration coefficients. + for (u32 i = 0; i < opt_win_cal_count; i++) + { + if (1000 * ir_light / visible_light < opt_win_cal[i].rc) + { + lux = ((u64)opt_win_cal[i].cv * data[0]) - (opt_win_cal[i].ci * data[1]); + break; + } + } - als_val->lux = (pre_gain_lux / als_gain_idx_tbl[als_val->gain]) * (als_norm_res / ((float)als_val->itime * als_tint)) * als_multiplier; + lux *= BH1730_DEFAULT_ITIME_MS * lux_multiplier; + lux /= als_gain_idx_tbl[als_ctxt->gain] * itime_us; + lux /= 1000; + + if (lux > BH1730_LUX_MAX) + lux = BH1730_LUX_MAX; + + als_ctxt->lux = lux; } -u8 als_init(als_table_t *als_val) +u8 als_power_on(als_ctxt_t *als_ctxt) { // Enable power to ALS IC. max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000); @@ -109,12 +147,10 @@ u8 als_init(als_table_t *als_val) // Initialize ALS. u8 id = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(0x12)); i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_SPEC(BH1730_SPECCMD_RESET), 0); - i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), HOS_GAIN); - i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - HOS_ITIME)); - i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG), BH1730_CTL_POWER_ON | BH1730_CTL_ADC_EN); - als_val->gain = HOS_GAIN; - als_val->itime = HOS_ITIME; + set_als_cfg(als_ctxt, BH1730_DEFAULT_GAIN, BH1730_DEFAULT_ICYCLE); + + i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG), BH1730_CTL_POWER_ON | BH1730_CTL_ADC_EN); return id; } diff --git a/bdk/input/als.h b/bdk/input/als.h index 09adcb6..0ce0956 100644 --- a/bdk/input/als.h +++ b/bdk/input/als.h @@ -48,18 +48,18 @@ #define BH1730_ADDR(reg) (BH1730_CMD_MAGIC | BH1730_CMD_SETADDR | (reg)) #define BH1730_SPEC(cmd) (BH1730_CMD_MAGIC | BH1730_CMD_SPECCMD | (cmd)) -typedef struct _als_table_t +typedef struct _als_ctxt_t { - float lux; + u32 lux; bool over_limit; - u32 vi_light; - u32 ir_light; - u8 gain; - u8 itime; -} als_table_t; + u32 vi_light; + u32 ir_light; + u8 gain; + u8 cycle; +} als_ctxt_t; -void set_als_cfg(als_table_t *als_val, u8 gain, u8 itime); -void get_als_lux(als_table_t *als_val); -u8 als_init(als_table_t *als_val); +void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle); +void get_als_lux(als_ctxt_t *als_ctxt); +u8 als_power_on(als_ctxt_t *als_ctxt); #endif /* __ALS_H_ */ diff --git a/bdk/input/touch.c b/bdk/input/touch.c index 17d31b3..2aba0e4 100644 --- a/bdk/input/touch.c +++ b/bdk/input/touch.c @@ -39,7 +39,7 @@ static touch_panel_info_t _panels[] = { 1, 0, 1, 1, "GiS GGM6 B2X" }, { 2, 0, 0, 0, "NISSHA NBF-K9A" }, { 3, 1, 0, 0, "GiS 5.5\"" }, - { 4, 0, 0, 1, "Unknown" }, + { 4, 0, 0, 1, "Unknown_001" }, { -1, 1, 0, 1, "GiS VA 6.2\"" } }; diff --git a/bdk/input/touch.h b/bdk/input/touch.h index 3345faa..871659e 100644 --- a/bdk/input/touch.h +++ b/bdk/input/touch.h @@ -53,6 +53,7 @@ #define STMFTS_RW_FRAMEBUFFER_REG 0xD0 #define STMFTS_SAVE_CX_TUNING 0xFC +#define STMFTS_DETECTION_CONFIG 0xB0 #define STMFTS_REQU_COMP_DATA 0xB8 #define STMFTS_VENDOR 0xCF #define STMFTS_FLASH_UNLOCK 0xF7 diff --git a/bdk/mem/mc.c b/bdk/mem/mc.c index c695987..d577bd7 100644 --- a/bdk/mem/mc.c +++ b/bdk/mem/mc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer + * Copyright (c) 2018-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -15,6 +15,7 @@ * along with this program. If not, see . */ +#include #include #include #include @@ -124,13 +125,13 @@ void mc_config_carveout() MC(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F; } -void mc_enable_ahb_redirect() +void mc_enable_ahb_redirect(bool full_aperture) { // Enable ARC_CLK_OVR_ON. CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) = (CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) & 0xFFF7FFFF) | 0x80000; //MC(MC_IRAM_REG_CTRL) &= 0xFFFFFFFE; MC(MC_IRAM_BOM) = 0x40000000; - MC(MC_IRAM_TOM) = 0x4003F000; + MC(MC_IRAM_TOM) = full_aperture ? DRAM_START : 0x4003F000; } void mc_disable_ahb_redirect() diff --git a/bdk/mem/mc.h b/bdk/mem/mc.h index 1a9bc83..d873c7d 100644 --- a/bdk/mem/mc.h +++ b/bdk/mem/mc.h @@ -23,7 +23,7 @@ void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock); void mc_config_carveout(); void mc_config_carveout_finalize(); -void mc_enable_ahb_redirect(); +void mc_enable_ahb_redirect(bool full_aperture); void mc_disable_ahb_redirect(); void mc_enable(); diff --git a/bdk/mem/sdram.c b/bdk/mem/sdram.c index b119f46..0f2ce3e 100644 --- a/bdk/mem/sdram.c +++ b/bdk/mem/sdram.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2018 naehrwert * Copyright (c) 2018 balika011 - * Copyright (c) 2019-2020 CTCaer + * Copyright (c) 2019-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -36,22 +36,46 @@ #define CONFIG_SDRAM_KEEP_ALIVE -//#define CONFIG_SDRAM_COMPRESS_CFG - typedef struct _sdram_vendor_patch_t { u32 val; - u32 addr:10; - u32 dramid:22; + u32 offset:16; + u32 dramcf:16; } sdram_vendor_patch_t; -#ifdef CONFIG_SDRAM_COMPRESS_CFG - #include - #include "sdram_config_lz.inl" -#else - #include "sdram_config.inl" -#endif +static const u8 dram_encoding_t210b01[] = { + LPDDR4X_UNUSED, + LPDDR4X_UNUSED, + LPDDR4X_UNUSED, + LPDDR4X_4GB_HYNIX_1Y_A, + LPDDR4X_UNUSED, + LPDDR4X_4GB_HYNIX_1Y_A, + LPDDR4X_4GB_HYNIX_1Y_A, + LPDDR4X_4GB_SAMSUNG_X1X2, + LPDDR4X_NO_PATCH, + LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ, + LPDDR4X_NO_PATCH, + LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046, + LPDDR4X_NO_PATCH, + LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ, + LPDDR4X_NO_PATCH, + LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046, + LPDDR4X_4GB_SAMSUNG_Y, + LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL, + LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL, + LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL, + LPDDR4X_4GB_SAMSUNG_1Y_Y, + LPDDR4X_8GB_SAMSUNG_1Y_Y, + LPDDR4X_UNUSED, // Removed. + LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL, + LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL, + LPDDR4X_4GB_MICRON_1Y_A, + LPDDR4X_4GB_MICRON_1Y_A, + LPDDR4X_4GB_MICRON_1Y_A, + LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL, +}; +#include "sdram_config.inl" #include "sdram_config_t210b01.inl" static bool _sdram_wait_emc_status(u32 reg_offset, u32 bit_mask, bool updated_state, s32 emc_channel) @@ -1350,57 +1374,21 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) SYSREG(AHB_ARBITRATION_XBAR_CTRL) = (SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF) | (params->ahb_arbitration_xbar_ctrl_meminit_done << 16); } -#ifndef CONFIG_SDRAM_COMPRESS_CFG -static void _sdram_patch_model_params_t210(u32 dramid, u32 *params) -{ - for (u32 i = 0; i < ARRAY_SIZE(sdram_cfg_vendor_patches_t210); i++) - if (sdram_cfg_vendor_patches_t210[i].dramid & DRAM_ID(dramid)) - params[sdram_cfg_vendor_patches_t210[i].addr] = sdram_cfg_vendor_patches_t210[i].val; -} -#endif - -static void _sdram_patch_model_params_t210b01(u32 dramid, u32 *params) -{ - for (u32 i = 0; i < ARRAY_SIZE(sdram_cfg_vendor_patches_t210b01); i++) - if (sdram_cfg_vendor_patches_t210b01[i].dramid & DRAM_ID2(dramid)) - params[sdram_cfg_vendor_patches_t210b01[i].addr] = sdram_cfg_vendor_patches_t210b01[i].val; -} - static void *_sdram_get_params_t210() { // Check if id is proper. u32 dramid = fuse_read_dramid(false); -#ifdef CONFIG_SDRAM_COMPRESS_CFG + // Copy base parameters. + u32 *params = (u32 *)SDRAM_PARAMS_ADDR; + memcpy(params, &_dram_cfg_0_samsung_4gb, sizeof(sdram_params_t210_t)); - u8 *buf = (u8 *)SDRAM_PARAMS_ADDR; - LZ_Uncompress(_dram_cfg_lz, buf, sizeof(_dram_cfg_lz)); - return (void *)&buf[sizeof(sdram_params_t210_t) * dramid]; + // Patch parameters if needed. + for (u32 i = 0; i < ARRAY_SIZE(sdram_cfg_vendor_patches_t210); i++) + if (sdram_cfg_vendor_patches_t210[i].dramcf & DRAM_ID(dramid)) + params[sdram_cfg_vendor_patches_t210[i].offset] = sdram_cfg_vendor_patches_t210[i].val; -#else - - u32 *buf = (u32 *)SDRAM_PARAMS_ADDR; - memcpy(buf, &_dram_cfg_0_samsung_4gb, sizeof(sdram_params_t210_t)); - - switch (dramid) - { - case LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH: - case LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT: - break; - - case LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE: - case LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH: -#ifdef CONFIG_SDRAM_COPPER_SUPPORT - case LPDDR4_COPPER_4GB_SAMSUNG_K4F6E304HB_MGCH: - case LPDDR4_COPPER_4GB_HYNIX_H9HCNNNBPUMLHR_NLE: - case LPDDR4_COPPER_4GB_MICRON_MT53B512M32D2NP_062_WT: -#endif - _sdram_patch_model_params_t210(dramid, (u32 *)buf); - break; - } - return (void *)buf; - -#endif + return (void *)params; } void *sdram_get_params_t210b01() @@ -1408,38 +1396,20 @@ void *sdram_get_params_t210b01() // Check if id is proper. u32 dramid = fuse_read_dramid(false); - u32 *buf = (u32 *)SDRAM_PARAMS_ADDR; - memcpy(buf, &_dram_cfg_08_10_12_14_samsung_hynix_4gb, sizeof(sdram_params_t210b01_t)); + // Copy base parameters. + u32 *params = (u32 *)SDRAM_PARAMS_ADDR; + memcpy(params, &_dram_cfg_08_10_12_14_samsung_hynix_4gb, sizeof(sdram_params_t210b01_t)); - switch (dramid) - { - case LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ: - case LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME: - case LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ: - case LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME: - break; + // Patch parameters if needed. + u8 dram_code = dram_encoding_t210b01[dramid]; + if (!dram_code) + return (void *)params; - case LPDDR4X_IOWA_4GB_SAMSUNG_X1X2: - case LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ: - case LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WT: - case LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ: - case LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WT: - case LPDDR4X_IOWA_4GB_SAMSUNG_Y: - case LPDDR4X_IOWA_4GB_SAMSUNG_1Y_X: - case LPDDR4X_IOWA_8GB_SAMSUNG_1Y_X: - case LPDDR4X_HOAG_4GB_SAMSUNG_1Y_X: - case LPDDR4X_IOWA_4GB_SAMSUNG_1Y_Y: - case LPDDR4X_IOWA_8GB_SAMSUNG_1Y_Y: - case LPDDR4X_AULA_4GB_SAMSUNG_1Y_A: - case LPDDR4X_AULA_8GB_SAMSUNG_1Y_X: - case LPDDR4X_AULA_4GB_SAMSUNG_1Y_X: - case LPDDR4X_IOWA_4GB_MICRON_1Y_A: - case LPDDR4X_HOAG_4GB_MICRON_1Y_A: - case LPDDR4X_AULA_4GB_MICRON_1Y_A: - _sdram_patch_model_params_t210b01(dramid, (u32 *)buf); - break; - } - return (void *)buf; + for (u32 i = 0; i < ARRAY_SIZE(sdram_cfg_vendor_patches_t210b01); i++) + if (sdram_cfg_vendor_patches_t210b01[i].dramcf == dram_code) + params[sdram_cfg_vendor_patches_t210b01[i].offset] = sdram_cfg_vendor_patches_t210b01[i].val; + + return (void *)params; } /* @@ -1485,7 +1455,7 @@ static void _sdram_init_t210() const sdram_params_t210_t *params = (const sdram_params_t210_t *)_sdram_get_params_t210(); // Set DRAM voltage. - max7762x_regulator_set_voltage(REGULATOR_SD1, 1100000); + max7762x_regulator_set_voltage(REGULATOR_SD1, 1100000); // HOS uses 1.125V // VDDP Select. PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel; diff --git a/bdk/mem/sdram.h b/bdk/mem/sdram.h index 8455862..90e688d 100644 --- a/bdk/mem/sdram.h +++ b/bdk/mem/sdram.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2020 CTCaer + * Copyright (c) 2020-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -23,20 +23,26 @@ /* * Tegra X1/X1+ EMC/DRAM Bandwidth Chart: * - * 40.8 MHz: 0.61 GiB/s - * 68.0 MHz: 1.01 GiB/s - * 102.0 MHz: 1.52 GiB/s - * 204.0 MHz: 3.04 GiB/s <-- Tegra X1/X1+ Init/SC7 Frequency - * 408.0 MHz: 6.08 GiB/s - * 665.6 MHz: 9.92 GiB/s - * 800.0 MHz: 11.92 GiB/s <-- Tegra X1/X1+ Nvidia OS Boot Frequency - * 1065.6 MHz: 15.89 GiB/s - * 1331.2 MHz: 19.84 GiB/s - * 1600.0 MHz: 23.84 GiB/s <-- Tegra X1 Official Max Frequency - * 1862.4 MHz: 27.75 GiB/s <-- Tegra X1+ Official Max Frequency - * 2131.2 MHz: 31.76 GiB/s + * Note: BWbits T210 = Hz x ddr x bus width x channels = Hz x 2 x 32 x 2. + * BWbits T210B01 = Hz x ddr x bus width x channels = Hz x 2 x 64 x 2. + * Both assume that both sub-partitions are used and thus reaching max + * bandwidth per channel. (T210: 2x16-bit, T210B01: 2x32-bit). + * Retail Mariko use one sub-partition, in order to meet Erista perf. + * + * T210 T210B01 + * 40.8 MHz: 0.61 1.22 GiB/s + * 68.0 MHz: 1.01 2.02 GiB/s + * 102.0 MHz: 1.52 3.04 GiB/s + * 204.0 MHz: 3.04 6.08 GiB/s <-- Tegra X1/X1+ Init/SC7 Frequency + * 408.0 MHz: 6.08 12.16 GiB/s + * 665.6 MHz: 9.92 19.84 GiB/s + * 800.0 MHz: 11.92 23.84 GiB/s <-- Tegra X1/X1+ Nvidia OS Boot Frequency + * 1065.6 MHz: 15.89 31.78 GiB/s + * 1331.2 MHz: 19.84 39.68 GiB/s + * 1600.0 MHz: 23.84 47.68 GiB/s <-- Tegra X1/X1+ HOS Max Frequency + * 1862.4 MHz: 27.75 55.50 GiB/s <-- Tegra X1 Official Max Frequency + * 2131.2 MHz: 31.76 63.52 GiB/s <-- Tegra X1+ Official Max Frequency * - * Note: BWbits = Hz x bus width x channels = Hz x 64 x 2. */ enum sdram_ids_erista @@ -45,45 +51,73 @@ enum sdram_ids_erista LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0, LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1, LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT = 2, - LPDDR4_COPPER_4GB_SAMSUNG_K4F6E304HB_MGCH = 3, // Changed to AULA Hynix 4GB 1Y-A. + LPDDR4_COPPER_4GB_SAMSUNG_K4F6E304HB_MGCH = 3, // Changed to Iowa Hynix 4GB 1Y-A. LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4, - LPDDR4_COPPER_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 5, - LPDDR4_COPPER_4GB_MICRON_MT53B512M32D2NP_062_WT = 6, + LPDDR4_COPPER_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 5, // Changed to Hoag Hynix 4GB 1Y-A. + LPDDR4_COPPER_4GB_MICRON_MT53B512M32D2NP_062_WT = 6, // Changed to Aula Hynix 4GB 1Y-A. }; enum sdram_ids_mariko { + // LPDDR4X 4266Mbps. + LPDDR4X_IOWA_4GB_HYNIX_1Y_A = 3, // Replaced from Copper. + LPDDR4X_HOAG_4GB_HYNIX_1Y_A = 5, // Replaced from Copper. + LPDDR4X_AULA_4GB_HYNIX_1Y_A = 6, // Replaced from Copper. + // LPDDR4X 3733Mbps. LPDDR4X_IOWA_4GB_SAMSUNG_X1X2 = 7, - LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, - LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, - LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, - LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WT = 11, // 4266Mbps. + LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. + LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9, // Die-M. + LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10, // Die-M. + LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WT = 11, // 4266Mbps. WT:E. Die-E. - LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, - LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, - LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, - LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WT = 15, // 4266Mbps. + LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M. + LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13, // Die-M. + LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14, // Die-M. + LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WT = 15, // 4266Mbps. WT:E. Die-E. - // LPDDR4X 4266Mbps? + // LPDDR4X 4266Mbps. LPDDR4X_IOWA_4GB_SAMSUNG_Y = 16, - LPDDR4X_IOWA_4GB_SAMSUNG_1Y_X = 17, - LPDDR4X_IOWA_8GB_SAMSUNG_1Y_X = 18, - LPDDR4X_HOAG_4GB_SAMSUNG_1Y_X = 19, + LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17, // Die-A. + LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 18, // Die-A. + LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19, // Die-A. LPDDR4X_IOWA_4GB_SAMSUNG_1Y_Y = 20, LPDDR4X_IOWA_8GB_SAMSUNG_1Y_Y = 21, - LPDDR4X_AULA_4GB_SAMSUNG_1Y_A = 22, + // LPDDR4X_AULA_4GB_SAMSUNG_1Y_A = 22, // Unused. - LPDDR4X_AULA_8GB_SAMSUNG_1Y_X = 23, - LPDDR4X_AULA_4GB_SAMSUNG_1Y_X = 24, + LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23, // Die-A. + LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A. LPDDR4X_IOWA_4GB_MICRON_1Y_A = 25, LPDDR4X_HOAG_4GB_MICRON_1Y_A = 26, - LPDDR4X_AULA_4GB_MICRON_1Y_A = 27 + LPDDR4X_AULA_4GB_MICRON_1Y_A = 27, + + LPDDR4X_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A. +}; + +enum sdram_codes_mariko +{ + LPDDR4X_NO_PATCH = 0, + LPDDR4X_UNUSED = 0, + + // LPDDR4X_4GB_SAMSUNG_K4U6E3S4AM_MGCJ DRAM IDs: 08, 12. + // LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLHR_NME DRAM IDs: 10, 14. + + LPDDR4X_4GB_SAMSUNG_X1X2 = 1, // DRAM IDs: 07. + LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 2, // DRAM IDs: 09, 13. + LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 = 3, // DRAM IDs: 11, 15. + LPDDR4X_4GB_SAMSUNG_Y = 4, // DRAM IDs: 16. + LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 5, // DRAM IDs: 17, 19, 24. + LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 6, // DRAM IDs: 18, 23, 28. + LPDDR4X_4GB_SAMSUNG_1Y_Y = 7, // DRAM IDs: 20. + LPDDR4X_8GB_SAMSUNG_1Y_Y = 8, // DRAM IDs: 21. + //LPDDR4X_4GB_SAMSUNG_1Y_A = 9, // DRAM IDs: 22. Unused. + LPDDR4X_4GB_MICRON_1Y_A = 10, // DRAM IDs: 25, 26, 27. + LPDDR4X_4GB_HYNIX_1Y_A = 11, // DRAM IDs: 03, 05, 06. }; void sdram_init(); diff --git a/bdk/mem/sdram_config.inl b/bdk/mem/sdram_config.inl index 97c723a..4548981 100644 --- a/bdk/mem/sdram_config.inl +++ b/bdk/mem/sdram_config.inl @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2020 CTCaer + * Copyright (c) 2020-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -646,46 +646,51 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = { static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210[] = { // Hynix timing config. - { 0x0000000D, 67, DRAM_ID(1) | DRAM_ID(5) }, // emc_r2w. - { 0x00000001, 91, DRAM_ID(1) | DRAM_ID(5) }, // emc_puterm_extra. - { 0x80000000, 92, DRAM_ID(1) | DRAM_ID(5) }, // emc_puterm_width. - { 0x00000210, 317, DRAM_ID(1) | DRAM_ID(5) }, // emc_pmacro_data_rx_term_mode. - { 0x00000005, 368, DRAM_ID(1) | DRAM_ID(5) }, // mc_emem_arb_timing_r2w. + { 0x0000000D, 0x10C / 4, DRAM_ID(1) }, // emc_r2w. + { 0x00000001, 0x16C / 4, DRAM_ID(1) }, // emc_puterm_extra. + { 0x80000000, 0x170 / 4, DRAM_ID(1) }, // emc_puterm_width. + { 0x00000210, 0x4F4 / 4, DRAM_ID(1) }, // emc_pmacro_data_rx_term_mode. + { 0x00000005, 0x5C0 / 4, DRAM_ID(1) }, // mc_emem_arb_timing_r2w. // Samsung 6GB density config. - { 0x000C0302, 347, DRAM_ID(4) }, // mc_emem_adr_cfg_dev0. 768MB Rank 0 density. - { 0x000C0302, 348, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB Rank 1 density. - { 0x00001800, 353, DRAM_ID(4) }, // mc_emem_cfg. 6GB total density. + { 0x000C0302, 0x56C / 4, DRAM_ID(4) }, // mc_emem_adr_cfg_dev0. 768MB Rank 0 density. + { 0x000C0302, 0x570 / 4, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB Rank 1 density. + { 0x00001800, 0x584 / 4, DRAM_ID(4) }, // mc_emem_cfg. 6GB total density. #ifdef CONFIG_SDRAM_COPPER_SUPPORT // Copper prototype Samsung/Hynix/Micron timing configs. - { 0x0000003A, 59, DRAM_ID(6) }, // emc_rfc. Auto refresh. - { 0x0000001D, 60, DRAM_ID(6) }, // emc_rfc_pb. Bank Auto refresh. - { 0x00000012, 108, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_rw2pden. - { 0x0000003B, 112, DRAM_ID(6) }, // emc_txsr. - { 0x0000003B, 113, DRAM_ID(6) }, // emc_txsr_dll. - { 0x00000003, 119, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_tclkstable. - { 0x00120015, 205, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_4. - { 0x00160012, 206, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_5. - { 0x00120015, 211, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_4. - { 0x00160012, 212, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_5. - { 0x002F0032, 213, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0. - { 0x00310032, 214, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1. - { 0x00360034, 215, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2. - { 0x0033002F, 216, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3. - { 0x00000006, 217, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4. - { 0x002F0032, 219, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0. - { 0x00310032, 220, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1. - { 0x00360034, 221, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2. - { 0x0033002F, 222, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3. - { 0x00000006, 223, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4. - { 0x00150015, 233, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_0. - { 0x00120012, 235, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_2. - { 0x00160016, 236, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_3. - { 0x00000015, 237, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_4. - { 0x00000012, 295, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft2. - { 0x00000012, 296, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft3. - { 0x00000007, 370, DRAM_ID(6) }, // mc_emem_arb_timing_rfcpb. Bank refresh. - { 0x72A30504, 373, DRAM_ID(6) }, // mc_emem_arb_misc0. + { 0x0000003A, 0xEC / 4, DRAM_ID(6) }, // emc_rfc. Auto refresh. + { 0x0000001D, 0xF0 / 4, DRAM_ID(6) }, // emc_rfc_pb. Bank Auto refresh. + { 0x0000000D, 0x10C / 4, DRAM_ID(5) }, // emc_r2w. + { 0x00000001, 0x16C / 4, DRAM_ID(5) }, // emc_puterm_extra. + { 0x80000000, 0x170 / 4, DRAM_ID(5) }, // emc_puterm_width. + { 0x00000012, 0x1B0 / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_rw2pden. + { 0x0000003B, 0x1C0 / 4, DRAM_ID(6) }, // emc_txsr. + { 0x0000003B, 0x1C4 / 4, DRAM_ID(6) }, // emc_txsr_dll. + { 0x00000003, 0x1DC / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_tclkstable. + { 0x00120015, 0x334 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_4. + { 0x00160012, 0x338 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank0_5. + { 0x00120015, 0x34C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_4. + { 0x00160012, 0x350 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dq_rank1_5. + { 0x002F0032, 0x354 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0. + { 0x00310032, 0x358 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1. + { 0x00360034, 0x35C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2. + { 0x0033002F, 0x360 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3. + { 0x00000006, 0x364 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4. + { 0x002F0032, 0x36C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0. + { 0x00310032, 0x370 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1. + { 0x00360034, 0x374 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2. + { 0x0033002F, 0x378 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3. + { 0x00000006, 0x37C / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4. + { 0x00150015, 0x3A4 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_0. + { 0x00120012, 0x3AC / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_2. + { 0x00160016, 0x3B0 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_3. + { 0x00000015, 0x3B4 / 4, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_4. + { 0x00000012, 0x49C / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft2. + { 0x00000012, 0x4A0 / 4, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft3. + { 0x00000210, 0x4F4 / 4, DRAM_ID(5) }, // emc_pmacro_data_rx_term_mode. + { 0x00000005, 0x5C0 / 4, DRAM_ID(5) }, // mc_emem_arb_timing_r2w. + { 0x00000007, 0x5C8 / 4, DRAM_ID(6) }, // mc_emem_arb_timing_rfcpb. Bank refresh. + { 0x72A30504, 0x5D4 / 4, DRAM_ID(6) }, // mc_emem_arb_misc0. #endif }; diff --git a/bdk/mem/sdram_config_lz.inl b/bdk/mem/sdram_config_lz.inl deleted file mode 100644 index 832b5b4..0000000 --- a/bdk/mem/sdram_config_lz.inl +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2018 naehrwert - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -static const u8 _dram_cfg_lz[1262] = { - 0x17, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, - 0x00, 0x2C, 0x17, 0x04, 0x09, 0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08, - 0x17, 0x10, 0x10, 0x00, 0x00, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, - 0x00, 0x04, 0xB4, 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, - 0x70, 0x17, 0x10, 0x24, 0x34, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, - 0x00, 0x00, 0x00, 0x17, 0x04, 0x04, 0x17, 0x09, 0x18, 0xFF, 0xFF, 0x1F, - 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, - 0x00, 0x17, 0x04, 0x04, 0x17, 0x08, 0x08, 0x17, 0x08, 0x08, 0xA6, 0xA6, - 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x04, - 0x04, 0x04, 0x17, 0x04, 0x04, 0x17, 0x04, 0x3C, 0x1F, 0x1F, 0x1F, 0x1F, - 0x17, 0x04, 0x04, 0x17, 0x06, 0x06, 0x00, 0x00, 0x04, 0x08, 0x17, 0x06, - 0x46, 0xA1, 0x01, 0x00, 0x00, 0x32, 0x17, 0x0B, 0x64, 0x01, 0x17, 0x04, - 0x7C, 0x17, 0x07, 0x0C, 0x03, 0x17, 0x04, 0x04, 0x00, 0x00, 0x00, 0x1E, - 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, - 0x17, 0x0B, 0x2C, 0x09, 0x00, 0x00, 0x00, 0x17, 0x05, 0x5D, 0x17, 0x07, - 0x10, 0x0B, 0x17, 0x07, 0x28, 0x08, 0x17, 0x07, 0x0C, 0x17, 0x04, 0x1C, - 0x20, 0x00, 0x00, 0x00, 0x06, 0x17, 0x04, 0x04, 0x17, 0x07, 0x08, 0x17, - 0x04, 0x50, 0x17, 0x04, 0x2C, 0x17, 0x04, 0x1C, 0x17, 0x04, 0x10, 0x17, - 0x08, 0x6C, 0x17, 0x04, 0x10, 0x17, 0x04, 0x38, 0x17, 0x04, 0x40, 0x05, - 0x17, 0x07, 0x1C, 0x17, 0x08, 0x58, 0x17, 0x04, 0x24, 0x17, 0x04, 0x18, - 0x17, 0x08, 0x64, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, - 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x17, 0x09, 0x0C, 0x17, 0x05, 0x82, - 0x58, 0x17, 0x07, 0x61, 0xC1, 0x17, 0x07, 0x50, 0x17, 0x04, 0x04, 0x17, - 0x08, 0x81, 0x48, 0x17, 0x04, 0x04, 0x17, 0x04, 0x28, 0x17, 0x04, 0x60, - 0x17, 0x08, 0x54, 0x27, 0x17, 0x04, 0x04, 0x17, 0x07, 0x14, 0x17, 0x04, - 0x04, 0x04, 0x17, 0x07, 0x81, 0x58, 0x17, 0x0C, 0x0C, 0x1C, 0x03, 0x00, - 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x17, 0x04, 0x5A, 0xF3, 0x0C, - 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, - 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, - 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, - 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, - 0x24, 0x06, 0x07, 0x9A, 0x12, 0x17, 0x05, 0x83, 0x41, 0x00, 0xFF, 0x17, - 0x10, 0x83, 0x6C, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, - 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x71, 0x71, 0x03, 0x08, 0x00, - 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x17, 0x04, 0x20, 0x08, 0x08, - 0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x17, 0x06, - 0x2C, 0x11, 0x08, 0x17, 0x10, 0x84, 0x67, 0x15, 0x00, 0xCC, 0x00, 0x0A, - 0x00, 0x33, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF, - 0x0F, 0xFF, 0x0F, 0x17, 0x08, 0x83, 0x4C, 0x01, 0x03, 0x00, 0x70, 0x00, - 0x0C, 0x00, 0x01, 0x17, 0x04, 0x0C, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, - 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x17, 0x04, 0x10, 0xA0, 0x00, 0x2C, - 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x17, 0x06, 0x48, 0x08, 0x00, - 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x28, - 0x28, 0x28, 0x17, 0x04, 0x04, 0x11, 0x11, 0x11, 0x11, 0x17, 0x04, 0x04, - 0xBE, 0x00, 0x00, 0x17, 0x05, 0x58, 0x17, 0x08, 0x5C, 0x17, 0x22, 0x85, - 0x6A, 0x17, 0x1A, 0x1A, 0x14, 0x00, 0x12, 0x00, 0x10, 0x17, 0x05, 0x83, - 0x0A, 0x17, 0x16, 0x18, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, - 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x17, 0x05, 0x83, 0x0C, 0x17, - 0x04, 0x20, 0x17, 0x18, 0x18, 0x28, 0x00, 0x28, 0x17, 0x04, 0x04, 0x17, - 0x08, 0x08, 0x17, 0x10, 0x10, 0x00, 0x14, 0x17, 0x05, 0x5A, 0x17, 0x04, - 0x5C, 0x17, 0x04, 0x5E, 0x17, 0x04, 0x0E, 0x17, 0x0E, 0x78, 0x17, 0x09, - 0x82, 0x50, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, - 0x17, 0x08, 0x18, 0x80, 0x01, 0x00, 0x00, 0x40, 0x17, 0x04, 0x20, 0x03, - 0x00, 0x00, 0x00, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x17, 0x08, 0x82, 0x58, - 0x17, 0x0C, 0x38, 0x17, 0x1B, 0x81, 0x6C, 0x17, 0x08, 0x85, 0x60, 0x17, - 0x08, 0x86, 0x50, 0x17, 0x08, 0x86, 0x60, 0x17, 0x06, 0x83, 0x21, 0x22, - 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x17, 0x0C, 0x86, 0x74, 0x17, 0x08, 0x2C, - 0x8B, 0xFF, 0x07, 0x17, 0x06, 0x81, 0x04, 0x32, 0x54, 0x76, 0x10, 0x47, - 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, - 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, - 0x32, 0x67, 0x17, 0x04, 0x24, 0x49, 0x92, 0x24, 0x17, 0x04, 0x04, 0x17, - 0x11, 0x7C, 0x1B, 0x17, 0x04, 0x04, 0x17, 0x13, 0x81, 0x14, 0x2F, 0x41, - 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x17, 0x04, 0x7C, 0xFF, 0xFF, 0xFF, - 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x03, - 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x17, 0x06, 0x86, 0x59, - 0x17, 0x0F, 0x89, 0x14, 0x37, 0x17, 0x07, 0x82, 0x72, 0x10, 0x17, 0x06, - 0x83, 0x0D, 0x00, 0x11, 0x01, 0x17, 0x05, 0x85, 0x39, 0x17, 0x04, 0x0E, - 0x0A, 0x17, 0x07, 0x89, 0x29, 0x17, 0x04, 0x1B, 0x17, 0x08, 0x86, 0x77, - 0x17, 0x09, 0x12, 0x20, 0x00, 0x00, 0x00, 0x81, 0x10, 0x09, 0x28, 0x93, - 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x17, 0x18, 0x82, 0x2C, 0xFF, - 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0x17, 0x04, 0x04, 0xDC, 0xDC, - 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x17, 0x04, 0x04, 0x17, 0x04, 0x04, - 0x17, 0x05, 0x82, 0x24, 0x03, 0x07, 0x17, 0x04, 0x04, 0x00, 0x00, 0x24, - 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, - 0x9C, 0x4B, 0x17, 0x04, 0x64, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, - 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x17, 0x06, 0x85, 0x60, 0x17, - 0x10, 0x82, 0x74, 0x17, 0x08, 0x08, 0x17, 0x08, 0x88, 0x00, 0x17, 0x04, - 0x10, 0x04, 0x17, 0x0B, 0x87, 0x6C, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, - 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x17, 0x08, 0x8B, 0x18, - 0x1F, 0x17, 0x09, 0x81, 0x73, 0x00, 0xFF, 0x00, 0xFF, 0x17, 0x05, 0x86, - 0x48, 0x17, 0x04, 0x0C, 0x17, 0x07, 0x86, 0x34, 0x00, 0x00, 0xF0, 0x17, - 0x09, 0x87, 0x54, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x17, 0x0C, 0x81, - 0x52, 0x17, 0x0A, 0x1C, 0x17, 0x10, 0x81, 0x6C, 0x17, 0x0A, 0x82, 0x21, - 0x17, 0x07, 0x82, 0x4D, 0x17, 0x0A, 0x8A, 0x1B, 0x17, 0x11, 0x2C, 0x76, - 0x0C, 0x17, 0x0A, 0x8A, 0x67, 0x17, 0x0F, 0x84, 0x28, 0x17, 0x06, 0x34, - 0x17, 0x17, 0x3A, 0x7E, 0x16, 0x40, 0x17, 0x0C, 0x8B, 0x1F, 0x17, 0x2A, - 0x38, 0x1E, 0x17, 0x0A, 0x38, 0x17, 0x13, 0x81, 0x28, 0x00, 0xC0, 0x17, - 0x17, 0x55, 0x46, 0x24, 0x17, 0x0A, 0x81, 0x28, 0x17, 0x14, 0x38, 0x17, - 0x18, 0x81, 0x60, 0x46, 0x2C, 0x17, 0x06, 0x38, 0xEC, 0x17, 0x0D, 0x16, - 0x17, 0x0E, 0x82, 0x3C, 0x17, 0x82, 0x0C, 0x8E, 0x68, 0x17, 0x04, 0x24, - 0x17, 0x5C, 0x8E, 0x68, 0x17, 0x07, 0x82, 0x5F, 0x80, 0x17, 0x87, 0x01, - 0x8E, 0x68, 0x02, 0x17, 0x81, 0x4A, 0x8E, 0x68, 0x17, 0x0C, 0x87, 0x78, - 0x17, 0x85, 0x28, 0x8E, 0x68, 0x17, 0x8E, 0x68, 0x9D, 0x50, 0x17, 0x81, - 0x24, 0x8E, 0x68, 0x17, 0x04, 0x2C, 0x17, 0x28, 0x8E, 0x68, 0x17, 0x04, - 0x30, 0x17, 0x85, 0x3C, 0x8E, 0x68, 0x12, 0x17, 0x07, 0x85, 0x70, 0x17, - 0x88, 0x74, 0x8E, 0x68, 0x17, 0x87, 0x3E, 0x9D, 0x50, 0x0C, 0x17, 0x04, - 0x04, 0x17, 0x12, 0x8E, 0x68, 0x18, 0x17, 0x87, 0x12, 0xBB, 0x20, 0x17, - 0x83, 0x04, 0x9D, 0x50, 0x15, 0x17, 0x05, 0x8D, 0x76, 0x17, 0x0F, 0x8B, - 0x49, 0x17, 0x0B, 0x18, 0x32, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x31, 0x00, - 0x34, 0x00, 0x36, 0x00, 0x2F, 0x00, 0x33, 0x17, 0x09, 0x84, 0x0C, 0x17, - 0x18, 0x18, 0x17, 0x20, 0x8E, 0x68, 0x15, 0x17, 0x07, 0x5A, 0x17, 0x06, - 0x5E, 0x16, 0x00, 0x15, 0x17, 0x82, 0x40, 0x9D, 0x50, 0x17, 0x86, 0x5F, - 0xBB, 0x20, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x17, 0x81, 0x4F, 0xAC, 0x38, - 0x3B, 0x17, 0x04, 0x04, 0x17, 0x86, 0x30, 0x8E, 0x68, 0x17, 0x81, 0x53, - 0xAC, 0x38, 0x07, 0x17, 0x0D, 0x8E, 0x68, 0xA3, 0x72, 0x17, 0x83, 0x10, - 0x8E, 0x68 -}; diff --git a/bdk/mem/sdram_config_t210b01.inl b/bdk/mem/sdram_config_t210b01.inl index e5c197e..745399d 100644 --- a/bdk/mem/sdram_config_t210b01.inl +++ b/bdk/mem/sdram_config_t210b01.inl @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 CTCaer + * Copyright (c) 2020-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -16,8 +16,6 @@ #define DRAM_CFG_T210B01_SIZE 2104 -#define DRAM_ID2(x) BIT((x) - 7) - static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = { /* Specifies the type of memory device */ .memory_type = MEMORY_TYPE_LPDDR4, @@ -109,7 +107,7 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = { .emc_pmacro_ca_tx_drive = 0x3F3F3F3F, .emc_pmacro_cmd_tx_drive = 0x00001220, .emc_pmacro_auto_cal_common = 0x00000804, - .emc_pmacro_zcrtl = 0x505050, + .emc_pmacro_zcrtl = 0x00505050, /* Specifies the time for the calibration to stabilize (in microseconds) */ .emc_auto_cal_wait = 0x000001A1, @@ -708,295 +706,314 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = { static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210b01[] = { // Samsung LPDDR4X 4GB X1X2 for prototype Iowa. - { 0x000E0022, 0x3AC / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dq_rank0_4. - { 0x001B0010, 0x3B0 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dq_rank0_5. - { 0x000E0022, 0x3C4 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dq_rank1_4. - { 0x001B0010, 0x3C8 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dq_rank1_5. - { 0x00490043, 0x3CC / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0. - { 0x00420045, 0x3D0 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1. - { 0x00490047, 0x3D4 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2. - { 0x00460047, 0x3D8 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3. - { 0x00000016, 0x3DC / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4. - { 0x00100000, 0x3E0 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank0_5. - { 0x00490043, 0x3E4 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0. - { 0x00420045, 0x3E8 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1. - { 0x00490047, 0x3EC / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2. - { 0x00460047, 0x3F0 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3. - { 0x00000016, 0x3F4 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4. - { 0x00100000, 0x3F8 / 4, DRAM_ID2(7) }, // emc_pmacro_ob_ddll_long_dqs_rank1_5. - { 0x00220022, 0x41C / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_0. - { 0x000E000E, 0x420 / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_1. - { 0x00100010, 0x424 / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_2. - { 0x001B001B, 0x428 / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_3. - { 0x00000022, 0x42C / 4, DRAM_ID2(7) }, // emc_pmacro_ddll_long_cmd_4. + { 0x000E0022, 0x3AC / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dq_rank0_4. + { 0x001B0010, 0x3B0 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dq_rank0_5. + { 0x000E0022, 0x3C4 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dq_rank1_4. + { 0x001B0010, 0x3C8 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dq_rank1_5. + { 0x00490043, 0x3CC / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_0. + { 0x00420045, 0x3D0 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_1. + { 0x00490047, 0x3D4 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_2. + { 0x00460047, 0x3D8 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_3. + { 0x00000016, 0x3DC / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_4. + { 0x00100000, 0x3E0 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank0_5. + { 0x00490043, 0x3E4 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_0. + { 0x00420045, 0x3E8 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_1. + { 0x00490047, 0x3EC / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_2. + { 0x00460047, 0x3F0 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_3. + { 0x00000016, 0x3F4 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_4. + { 0x00100000, 0x3F8 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ob_ddll_long_dqs_rank1_5. + { 0x00220022, 0x41C / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_0. + { 0x000E000E, 0x420 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_1. + { 0x00100010, 0x424 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_2. + { 0x001B001B, 0x428 / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_3. + { 0x00000022, 0x42C / 4, LPDDR4X_4GB_SAMSUNG_X1X2 }, // emc_pmacro_ddll_long_cmd_4. - // Samsung LPDDR4X 8GB K4UBE3D4AM-MGCJ for SDEV Iowa and Hoag. - { 0x05500000, 0x0D4 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_auto_cal_config2. - { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_auto_cal_vref_sel0. - { 0x00000001, 0x134 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_adr_cfg. 2 Ranks. - { 0x00000006, 0x1CC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_quse. - { 0x00000005, 0x1D0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_quse_width. - { 0x00000003, 0x1DC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_einput. - { 0x0000000C, 0x1E0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_einput_duration. - { 0x08010004, 0x2B8 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw1. - { 0x08020000, 0x2BC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw2. - { 0x080D0000, 0x2C0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw3. - { 0x08033131, 0x2C8 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw6. - { 0x080B0000, 0x2CC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw8. - { 0x0C0E5D5D, 0x2D0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw9. - { 0x080C5D5D, 0x2D4 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw10. - { 0x0C0D0808, 0x2D8 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw12. - { 0x0C0D0000, 0x2DC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw13. - { 0x08161414, 0x2E0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw14. - { 0x08010004, 0x2E4 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_mrw_extra. - { 0x00000000, 0x340 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_dev_select. Both devices. - { 0x35353535, 0x350 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_vref_dq_0. - { 0x35353535, 0x354 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_vref_dq_1. - { 0x00100010, 0x3FC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank0_0. - { 0x00100010, 0x400 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank0_1. - { 0x00100010, 0x404 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank0_2. - { 0x00100010, 0x408 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank0_3. - { 0x00100010, 0x40C / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank1_0. - { 0x00100010, 0x410 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank1_1. - { 0x00100010, 0x414 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank1_2. - { 0x00100010, 0x418 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_ib_ddll_long_dqs_rank1_3. - { 0x0051004F, 0x450 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_zcal_mrw_cmd. - { 0x40000001, 0x45C / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_zcal_init_dev1. - { 0x00000000, 0x594 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_tx_pwrd4. - { 0x00001000, 0x598 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // emc_pmacro_tx_pwrd5. - { 0x00000001, 0x630 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_emem_adr_cfg. 2 Ranks. - { 0x00002000, 0x64C / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_emem_cfg. 8GB total density. - { 0x00000002, 0x680 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_emem_arb_timing_r2r. - { 0x02020001, 0x694 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_emem_arb_da_turns. - { 0x2A800000, 0x6DC / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_video_protect_gpu_override0. - { 0x00000002, 0x6E0 / 4, DRAM_ID2(9) | DRAM_ID2(13) }, // mc_video_protect_gpu_override1. + // Samsung LPDDR4X 8GB K4UBE3D4AM-MGCJ Die-M for SDEV Iowa and Hoag. + { 0x05500000, 0x0D4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_auto_cal_config2. + { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_auto_cal_vref_sel0. + { 0x00000001, 0x134 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_adr_cfg. 2 Ranks. + { 0x00000006, 0x1CC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_quse. + { 0x00000005, 0x1D0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_quse_width. + { 0x00000003, 0x1DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_einput. + { 0x0000000C, 0x1E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_einput_duration. + { 0x08010004, 0x2B8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw1. + { 0x08020000, 0x2BC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw2. + { 0x080D0000, 0x2C0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw3. + { 0x08033131, 0x2C8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw6. + { 0x080B0000, 0x2CC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw8. + { 0x0C0E5D5D, 0x2D0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw9. + { 0x080C5D5D, 0x2D4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw10. + { 0x0C0D0808, 0x2D8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw12. + { 0x0C0D0000, 0x2DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw13. + { 0x08161414, 0x2E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw14. + { 0x08010004, 0x2E4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_mrw_extra. + { 0x00000000, 0x340 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_dev_select. Both devices. + { 0x35353535, 0x350 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_vref_dq_0. + { 0x35353535, 0x354 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_vref_dq_1. + { 0x00100010, 0x3FC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank0_0. + { 0x00100010, 0x400 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank0_1. + { 0x00100010, 0x404 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank0_2. + { 0x00100010, 0x408 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank0_3. + { 0x00100010, 0x40C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank1_0. + { 0x00100010, 0x410 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank1_1. + { 0x00100010, 0x414 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank1_2. + { 0x00100010, 0x418 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_ib_ddll_long_dqs_rank1_3. + { 0x0051004F, 0x450 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_zcal_mrw_cmd. + { 0x40000001, 0x45C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_zcal_init_dev1. + { 0x00000000, 0x594 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_tx_pwrd4. + { 0x00001000, 0x598 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // emc_pmacro_tx_pwrd5. + { 0x00000001, 0x630 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_emem_adr_cfg. 2 Ranks. + { 0x00002000, 0x64C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_emem_cfg. 8GB total density. + { 0x00000002, 0x680 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_emem_arb_timing_r2r. + { 0x02020001, 0x694 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_emem_arb_da_turns. + { 0x2A800000, 0x6DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_video_protect_gpu_override0. + { 0x00000002, 0x6E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ }, // mc_video_protect_gpu_override1. - // Micron LPDDR4X 4GB MT53D1024M32D1NP-053-WT for Iowa and Hoag. - { 0x05500000, 0x0D4 / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // emc_auto_cal_config2. - { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // emc_auto_cal_vref_sel0. - { 0x88161414, 0x2E0 / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // emc_mrw14. - { 0x80000713, 0x32C / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // emc_dyn_self_ref_control. - { 0x2A800000, 0x6DC / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // mc_video_protect_gpu_override0. - { 0x00000002, 0x6E0 / 4, DRAM_ID2(11) | DRAM_ID2(15) }, // mc_video_protect_gpu_override1. + // Micron LPDDR4X 4GB MT53D1024M32D1NP-053-WT Die-E for retail Iowa and Hoag. + { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 }, // emc_auto_cal_config2. + { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 }, // emc_auto_cal_vref_sel0. + { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 }, // emc_mrw14. + { 0x80000713, 0x32C / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 }, // emc_dyn_self_ref_control. + { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 }, // mc_video_protect_gpu_override0. + { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046 }, // mc_video_protect_gpu_override1. - // Samsung LPDDR4X 4GB Die-Y for Iowa. - { 0x05500000, 0x0D4 / 4, DRAM_ID2(16) }, // emc_auto_cal_config2. - { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(16) }, // emc_auto_cal_vref_sel0. - { 0x88161414, 0x2E0 / 4, DRAM_ID2(16) }, // emc_mrw14. - { 0x80000713, 0x32C / 4, DRAM_ID2(16) }, // emc_dyn_self_ref_control. - { 0x32323232, 0x350 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_vref_dq_0. - { 0x32323232, 0x354 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_vref_dq_1. - { 0x000F0018, 0x3AC / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dq_rank0_4. - { 0x000F0018, 0x3C4 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dq_rank1_4. - { 0x00440048, 0x3CC / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0. - { 0x00440045, 0x3D0 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1. - { 0x00470047, 0x3D4 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2. - { 0x0005000D, 0x3DC / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4. - { 0x00440048, 0x3E4 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0. - { 0x00440045, 0x3E8 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1. - { 0x00470047, 0x3EC / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2. - { 0x0005000D, 0x3F4 / 4, DRAM_ID2(16) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4. - { 0x00780078, 0x3FC / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank0_0. - { 0x00780078, 0x400 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank0_1. - { 0x00780078, 0x404 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank0_2. - { 0x00780078, 0x408 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank0_3. - { 0x00780078, 0x40C / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank1_0. - { 0x00780078, 0x410 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank1_1. - { 0x00780078, 0x414 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank1_2. - { 0x00780078, 0x418 / 4, DRAM_ID2(16) }, // emc_pmacro_ib_ddll_long_dqs_rank1_3. - { 0x00180018, 0x41C / 4, DRAM_ID2(16) }, // emc_pmacro_ddll_long_cmd_0. - { 0x000F000F, 0x420 / 4, DRAM_ID2(16) }, // emc_pmacro_ddll_long_cmd_1. - { 0x00000018, 0x42C / 4, DRAM_ID2(16) }, // emc_pmacro_ddll_long_cmd_4. - { 0x2A800000, 0x6DC / 4, DRAM_ID2(16) }, // mc_video_protect_gpu_override0. - { 0x00000002, 0x6E0 / 4, DRAM_ID2(16) }, // mc_video_protect_gpu_override1. + // Samsung LPDDR4X 4GB (Y01) Die-? for Iowa. + { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_auto_cal_config2. + { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_auto_cal_vref_sel0. + { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_mrw14. + { 0x80000713, 0x32C / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_dyn_self_ref_control. + { 0x32323232, 0x350 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_vref_dq_0. + { 0x32323232, 0x354 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_vref_dq_1. + { 0x000F0018, 0x3AC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dq_rank0_4. + { 0x000F0018, 0x3C4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dq_rank1_4. + { 0x00440048, 0x3CC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_0. + { 0x00440045, 0x3D0 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_1. + { 0x00470047, 0x3D4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_2. + { 0x0005000D, 0x3DC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_4. + { 0x00440048, 0x3E4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_0. + { 0x00440045, 0x3E8 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_1. + { 0x00470047, 0x3EC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_2. + { 0x0005000D, 0x3F4 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_4. + { 0x00780078, 0x3FC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank0_0. + { 0x00780078, 0x400 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank0_1. + { 0x00780078, 0x404 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank0_2. + { 0x00780078, 0x408 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank0_3. + { 0x00780078, 0x40C / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank1_0. + { 0x00780078, 0x410 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank1_1. + { 0x00780078, 0x414 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank1_2. + { 0x00780078, 0x418 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ib_ddll_long_dqs_rank1_3. + { 0x00180018, 0x41C / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ddll_long_cmd_0. + { 0x000F000F, 0x420 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ddll_long_cmd_1. + { 0x00000018, 0x42C / 4, LPDDR4X_4GB_SAMSUNG_Y }, // emc_pmacro_ddll_long_cmd_4. + { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_SAMSUNG_Y }, // mc_video_protect_gpu_override0. + { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_SAMSUNG_Y }, // mc_video_protect_gpu_override1. - // Samsung LPDDR4X 4GB 10nm-class (1y) Die-X for Iowa, Hoag and Aula. - { 0x05500000, 0x0D4 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_auto_cal_config2. - { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_auto_cal_vref_sel0. - { 0x00000006, 0x1CC / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_quse. - { 0x00000005, 0x1D0 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_quse_width. - { 0x00000003, 0x1DC / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_einput. - { 0x0000000C, 0x1E0 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_einput_duration. - { 0x88161414, 0x2E0 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_mrw14. - { 0x80000713, 0x32C / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // emc_dyn_self_ref_control. - { 0x2A800000, 0x6DC / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // mc_video_protect_gpu_override0. - { 0x00000002, 0x6E0 / 4, DRAM_ID2(17) | DRAM_ID2(19) | DRAM_ID2(24) }, // mc_video_protect_gpu_override1. + // Samsung LPDDR4X 4GB K4U6E3S4AA-MGCL 10nm-class (1y-X03) Die-A for retail Iowa, Hoag and Aula. + { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_auto_cal_config2. + { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_auto_cal_vref_sel0. + { 0x00000006, 0x1CC / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_quse. + { 0x00000005, 0x1D0 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_quse_width. + { 0x00000003, 0x1DC / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_einput. + { 0x0000000C, 0x1E0 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_einput_duration. + { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_mrw14. + { 0x80000713, 0x32C / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // emc_dyn_self_ref_control. + { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // mc_video_protect_gpu_override0. + { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL }, // mc_video_protect_gpu_override1. - // Samsung LPDDR4X 8GB 10nm-class (1y) Die-X for SDEV Iowa and Aula. - { 0x05500000, 0x0D4 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_auto_cal_config2. - { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_auto_cal_vref_sel0. - { 0x00000001, 0x134 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_adr_cfg. 2 Ranks. - { 0x00000006, 0x1CC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_quse. - { 0x00000005, 0x1D0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_quse_width. - { 0x00000003, 0x1DC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_einput. - { 0x0000000C, 0x1E0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_einput_duration. - { 0x00000008, 0x24C / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_tfaw. - { 0x08010004, 0x2B8 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw1. - { 0x08020000, 0x2BC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw2. - { 0x080D0000, 0x2C0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw3. - { 0x08033131, 0x2C8 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw6. - { 0x080B0000, 0x2CC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw8. - { 0x0C0E5D5D, 0x2D0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw9. - { 0x080C5D5D, 0x2D4 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw10. - { 0x0C0D0808, 0x2D8 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw12. - { 0x0C0D0000, 0x2DC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw13. - { 0x08161414, 0x2E0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw14. - { 0x08010004, 0x2E4 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_mrw_extra. - { 0x00000000, 0x340 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_dev_select. Both devices. - { 0x0051004F, 0x450 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_zcal_mrw_cmd. - { 0x40000001, 0x45C / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_zcal_init_dev1. - { 0x00000000, 0x594 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_pmacro_tx_pwrd4. - { 0x00001000, 0x598 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // emc_pmacro_tx_pwrd5. - { 0x00000001, 0x630 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_adr_cfg. 2 Ranks. - { 0x00002000, 0x64C / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_cfg. 8GB total density. - { 0x00000001, 0x670 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_arb_timing_faw. - { 0x00000002, 0x680 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_arb_timing_r2r. - { 0x02020001, 0x694 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_emem_arb_da_turns. - { 0x2A800000, 0x6DC / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_video_protect_gpu_override0. - { 0x00000002, 0x6E0 / 4, DRAM_ID2(18) | DRAM_ID2(23) }, // mc_video_protect_gpu_override1. + // Samsung LPDDR4X 8GB K4UBE3D4AA-MGCL 10nm-class (1y-X03) Die-A for SDEV Iowa, Hoag and Aula. + { 0x05500000, 0x0D4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_auto_cal_config2. + { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_auto_cal_vref_sel0. + { 0x00000001, 0x134 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_adr_cfg. 2 Ranks. + { 0x00000006, 0x1CC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_quse. + { 0x00000005, 0x1D0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_quse_width. + { 0x00000003, 0x1DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_einput. + { 0x0000000C, 0x1E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_einput_duration. + { 0x00000008, 0x24C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_tfaw. + { 0x08010004, 0x2B8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw1. + { 0x08020000, 0x2BC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw2. + { 0x080D0000, 0x2C0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw3. + { 0x08033131, 0x2C8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw6. + { 0x080B0000, 0x2CC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw8. + { 0x0C0E5D5D, 0x2D0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw9. + { 0x080C5D5D, 0x2D4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw10. + { 0x0C0D0808, 0x2D8 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw12. + { 0x0C0D0000, 0x2DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw13. + { 0x08161414, 0x2E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw14. + { 0x08010004, 0x2E4 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_mrw_extra. + { 0x00000000, 0x340 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_dev_select. Both devices. + { 0x0051004F, 0x450 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_zcal_mrw_cmd. + { 0x40000001, 0x45C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_zcal_init_dev1. + { 0x00000000, 0x594 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_pmacro_tx_pwrd4. + { 0x00001000, 0x598 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // emc_pmacro_tx_pwrd5. + { 0x00000001, 0x630 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_adr_cfg. 2 Ranks. + { 0x00002000, 0x64C / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_cfg. 8GB total density. + { 0x00000001, 0x670 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_arb_timing_faw. + { 0x00000002, 0x680 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_arb_timing_r2r. + { 0x02020001, 0x694 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_emem_arb_da_turns. + { 0x2A800000, 0x6DC / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_video_protect_gpu_override0. + { 0x00000002, 0x6E0 / 4, LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL }, // mc_video_protect_gpu_override1. - // Samsung LPDDR4X 4GB 10nm-class (1y) Die-Y for Iowa. - { 0x05500000, 0x0D4 / 4, DRAM_ID2(20) }, // emc_auto_cal_config2. - { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(20) }, // emc_auto_cal_vref_sel0. - { 0x00000008, 0x24C / 4, DRAM_ID2(20) }, // emc_tfaw. - { 0x88161414, 0x2E0 / 4, DRAM_ID2(20) }, // emc_mrw14. - { 0x80000713, 0x32C / 4, DRAM_ID2(20) }, // emc_dyn_self_ref_control. - { 0x000F0018, 0x3AC / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dq_rank0_4. - { 0x000F0018, 0x3C4 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dq_rank1_4. - { 0x00440048, 0x3CC / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0. - { 0x00440045, 0x3D0 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1. - { 0x00470047, 0x3D4 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2. - { 0x0005000D, 0x3DC / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4. - { 0x00440048, 0x3E4 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0. - { 0x00440045, 0x3E8 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1. - { 0x00470047, 0x3EC / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2. - { 0x0005000D, 0x3F4 / 4, DRAM_ID2(20) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4. - { 0x00180018, 0x41C / 4, DRAM_ID2(20) }, // emc_pmacro_ddll_long_cmd_0. - { 0x000F000F, 0x420 / 4, DRAM_ID2(20) }, // emc_pmacro_ddll_long_cmd_1. - { 0x00000018, 0x42C / 4, DRAM_ID2(20) }, // emc_pmacro_ddll_long_cmd_4. - { 0x00000001, 0x670 / 4, DRAM_ID2(20) }, // mc_emem_arb_timing_faw. - { 0x2A800000, 0x6DC / 4, DRAM_ID2(20) }, // mc_video_protect_gpu_override0. - { 0x00000002, 0x6E0 / 4, DRAM_ID2(20) }, // mc_video_protect_gpu_override1. + // Samsung LPDDR4X 4GB 10nm-class (1y-Y01) Die-? for Iowa. + { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_auto_cal_config2. + { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_auto_cal_vref_sel0. + { 0x00000008, 0x24C / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_tfaw. + { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_mrw14. + { 0x80000713, 0x32C / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_dyn_self_ref_control. + { 0x000F0018, 0x3AC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dq_rank0_4. + { 0x000F0018, 0x3C4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dq_rank1_4. + { 0x00440048, 0x3CC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_0. + { 0x00440045, 0x3D0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_1. + { 0x00470047, 0x3D4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_2. + { 0x0005000D, 0x3DC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_4. + { 0x00440048, 0x3E4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_0. + { 0x00440045, 0x3E8 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_1. + { 0x00470047, 0x3EC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_2. + { 0x0005000D, 0x3F4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_4. + { 0x00180018, 0x41C / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_0. + { 0x000F000F, 0x420 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_1. + { 0x00000018, 0x42C / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_4. + { 0x00000001, 0x670 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // mc_emem_arb_timing_faw. + { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // mc_video_protect_gpu_override0. + { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_Y }, // mc_video_protect_gpu_override1. - // Samsung LPDDR4X 8GB 10nm-class (1y) Die-Y for SDEV Iowa. - { 0x05500000, 0x0D4 / 4, DRAM_ID2(21) }, // emc_auto_cal_config2. - { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(21) }, // emc_auto_cal_vref_sel0. - { 0x00000001, 0x134 / 4, DRAM_ID2(21) }, // emc_adr_cfg. 2 Ranks. - { 0x00000008, 0x24C / 4, DRAM_ID2(21) }, // emc_tfaw. - { 0x08010004, 0x2B8 / 4, DRAM_ID2(21) }, // emc_mrw1. - { 0x08020000, 0x2BC / 4, DRAM_ID2(21) }, // emc_mrw2. - { 0x080D0000, 0x2C0 / 4, DRAM_ID2(21) }, // emc_mrw3. - { 0x08033131, 0x2C8 / 4, DRAM_ID2(21) }, // emc_mrw6. - { 0x080B0000, 0x2CC / 4, DRAM_ID2(21) }, // emc_mrw8. - { 0x0C0E5D5D, 0x2D0 / 4, DRAM_ID2(21) }, // emc_mrw9. - { 0x080C5D5D, 0x2D4 / 4, DRAM_ID2(21) }, // emc_mrw10. - { 0x0C0D0808, 0x2D8 / 4, DRAM_ID2(21) }, // emc_mrw12. - { 0x0C0D0000, 0x2DC / 4, DRAM_ID2(21) }, // emc_mrw13. - { 0x08161414, 0x2E0 / 4, DRAM_ID2(21) }, // emc_mrw14. - { 0x08010004, 0x2E4 / 4, DRAM_ID2(21) }, // emc_mrw_extra. - { 0x00000000, 0x340 / 4, DRAM_ID2(21) }, // emc_dev_select. Both devices. - { 0x32323232, 0x350 / 4, DRAM_ID2(21) }, // emc_pmacro_ib_vref_dq_0. - { 0x32323232, 0x354 / 4, DRAM_ID2(21) }, // emc_pmacro_ib_vref_dq_1. - { 0x000F0018, 0x3AC / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dq_rank0_4. - { 0x000F0018, 0x3C4 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dq_rank1_4. - { 0x00440048, 0x3CC / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0. - { 0x00440045, 0x3D0 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1. - { 0x00470047, 0x3D4 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2. - { 0x0005000D, 0x3DC / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4. - { 0x00440048, 0x3E4 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0. - { 0x00440045, 0x3E8 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1. - { 0x00470047, 0x3EC / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2. - { 0x0005000D, 0x3F4 / 4, DRAM_ID2(21) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4. - { 0x00180018, 0x41C / 4, DRAM_ID2(21) }, // emc_pmacro_ddll_long_cmd_0. - { 0x000F000F, 0x420 / 4, DRAM_ID2(21) }, // emc_pmacro_ddll_long_cmd_1. - { 0x00000018, 0x42C / 4, DRAM_ID2(21) }, // emc_pmacro_ddll_long_cmd_4. - { 0x0051004F, 0x450 / 4, DRAM_ID2(21) }, // emc_zcal_mrw_cmd. - { 0x40000001, 0x45C / 4, DRAM_ID2(21) }, // emc_zcal_init_dev1. - { 0x00000000, 0x594 / 4, DRAM_ID2(21) }, // emc_pmacro_tx_pwrd4. - { 0x00001000, 0x598 / 4, DRAM_ID2(21) }, // emc_pmacro_tx_pwrd5. - { 0x00000001, 0x630 / 4, DRAM_ID2(21) }, // mc_emem_adr_cfg. 2 Ranks. - { 0x00002000, 0x64C / 4, DRAM_ID2(21) }, // mc_emem_cfg. 8GB total density. - { 0x00000001, 0x670 / 4, DRAM_ID2(21) }, // mc_emem_arb_timing_faw. - { 0x00000002, 0x680 / 4, DRAM_ID2(21) }, // mc_emem_arb_timing_r2r. - { 0x02020001, 0x694 / 4, DRAM_ID2(21) }, // mc_emem_arb_da_turns. - { 0x2A800000, 0x6DC / 4, DRAM_ID2(21) }, // mc_video_protect_gpu_override0. - { 0x00000002, 0x6E0 / 4, DRAM_ID2(21) }, // mc_video_protect_gpu_override1. + // Samsung LPDDR4X 8GB 10nm-class (1y-Y01) Die-? for SDEV Iowa. + { 0x05500000, 0x0D4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_auto_cal_config2. + { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_auto_cal_vref_sel0. + { 0x00000001, 0x134 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_adr_cfg. 2 Ranks. + { 0x00000008, 0x24C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_tfaw. + { 0x08010004, 0x2B8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw1. + { 0x08020000, 0x2BC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw2. + { 0x080D0000, 0x2C0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw3. + { 0x08033131, 0x2C8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw6. + { 0x080B0000, 0x2CC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw8. + { 0x0C0E5D5D, 0x2D0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw9. + { 0x080C5D5D, 0x2D4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw10. + { 0x0C0D0808, 0x2D8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw12. + { 0x0C0D0000, 0x2DC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw13. + { 0x08161414, 0x2E0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw14. + { 0x08010004, 0x2E4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_mrw_extra. + { 0x00000000, 0x340 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_dev_select. Both devices. + { 0x32323232, 0x350 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ib_vref_dq_0. + { 0x32323232, 0x354 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ib_vref_dq_1. + { 0x000F0018, 0x3AC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dq_rank0_4. + { 0x000F0018, 0x3C4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dq_rank1_4. + { 0x00440048, 0x3CC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_0. + { 0x00440045, 0x3D0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_1. + { 0x00470047, 0x3D4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_2. + { 0x0005000D, 0x3DC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank0_4. + { 0x00440048, 0x3E4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_0. + { 0x00440045, 0x3E8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_1. + { 0x00470047, 0x3EC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_2. + { 0x0005000D, 0x3F4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ob_ddll_long_dqs_rank1_4. + { 0x00180018, 0x41C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_0. + { 0x000F000F, 0x420 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_1. + { 0x00000018, 0x42C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_ddll_long_cmd_4. + { 0x0051004F, 0x450 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_zcal_mrw_cmd. + { 0x40000001, 0x45C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_zcal_init_dev1. + { 0x00000000, 0x594 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_tx_pwrd4. + { 0x00001000, 0x598 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // emc_pmacro_tx_pwrd5. + { 0x00000001, 0x630 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_adr_cfg. 2 Ranks. + { 0x00002000, 0x64C / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_cfg. 8GB total density. + { 0x00000001, 0x670 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_arb_timing_faw. + { 0x00000002, 0x680 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_arb_timing_r2r. + { 0x02020001, 0x694 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_emem_arb_da_turns. + { 0x2A800000, 0x6DC / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_video_protect_gpu_override0. + { 0x00000002, 0x6E0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_Y }, // mc_video_protect_gpu_override1. - // Samsung LPDDR4X 4GB 10nm-class (1y) Die-A for Unknown Aula. - { 0x05500000, 0x0D4 / 4, DRAM_ID2(22) }, // emc_auto_cal_config2. - { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(22) }, // emc_auto_cal_vref_sel0. - { 0x00000008, 0x24C / 4, DRAM_ID2(22) }, // emc_tfaw. - { 0x1C041B06, 0x26C / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd0_0. - { 0x02050307, 0x270 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd0_1. - { 0x03252500, 0x274 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd0_2. - { 0x081D1E00, 0x278 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd1_0. - { 0x090C0A0D, 0x27C / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd1_1. - { 0x0526260B, 0x280 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd1_2. - { 0x05030402, 0x284 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd2_0. - { 0x1B1C0600, 0x288 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd2_1. - { 0x07252507, 0x28C / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd2_2. - { 0x0C1D0B0A, 0x290 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd3_0. - { 0x0800090D, 0x294 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd3_1. - { 0x0926261E, 0x298 / 4, DRAM_ID2(22) }, // emc_cmd_mapping_cmd3_2. - { 0x2A080624, 0x29C / 4, DRAM_ID2(22) }, // emc_cmd_mapping_byte. - { 0x88161414, 0x2E0 / 4, DRAM_ID2(22) }, // emc_mrw14. - { 0x80000713, 0x32C / 4, DRAM_ID2(22) }, // emc_dyn_self_ref_control. - { 0x00140010, 0x3AC / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dq_rank0_4. - { 0x0013000B, 0x3B0 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dq_rank0_5. - { 0x00140010, 0x3C4 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dq_rank1_4. - { 0x0013000B, 0x3C8 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dq_rank1_5. - { 0x00450047, 0x3CC / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_0. - { 0x004D004F, 0x3D0 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_1. - { 0x00460046, 0x3D4 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_2. - { 0x00480048, 0x3D8 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_3. - { 0x000C0008, 0x3DC / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_4. - { 0x000B000C, 0x3E0 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank0_5. - { 0x00450047, 0x3E4 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_0. - { 0x004D004F, 0x3E8 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_1. - { 0x00460046, 0x3EC / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_2. - { 0x00480048, 0x3F0 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_3. - { 0x000C0008, 0x3F4 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_4. - { 0x000B000C, 0x3F8 / 4, DRAM_ID2(22) }, // emc_pmacro_ob_ddll_long_dqs_rank1_5. - { 0x00100010, 0x41C / 4, DRAM_ID2(22) }, // emc_pmacro_ddll_long_cmd_0. - { 0x00140014, 0x420 / 4, DRAM_ID2(22) }, // emc_pmacro_ddll_long_cmd_1. - { 0x00130013, 0x428 / 4, DRAM_ID2(22) }, // emc_pmacro_ddll_long_cmd_3. - { 0x00000010, 0x42C / 4, DRAM_ID2(22) }, // emc_pmacro_ddll_long_cmd_4. - { 0x40280100, 0x4B4 / 4, DRAM_ID2(22) }, // pmc_ddr_cfg. - { 0x4F9F9FFF, 0x4B8 / 4, DRAM_ID2(22) }, // pmc_io_dpd3_req. - { 0x64032157, 0x4D8 / 4, DRAM_ID2(22) }, // emc_swizzle_rank0_byte0. - { 0x51320467, 0x4DC / 4, DRAM_ID2(22) }, // emc_swizzle_rank0_byte1. - { 0x04735621, 0x4E0 / 4, DRAM_ID2(22) }, // emc_swizzle_rank0_byte2. - { 0x47356012, 0x4E4 / 4, DRAM_ID2(22) }, // emc_swizzle_rank0_byte3. - { 0x12045673, 0x4E8 / 4, DRAM_ID2(22) }, // emc_swizzle_rank1_byte0. - { 0x43657210, 0x4EC / 4, DRAM_ID2(22) }, // emc_swizzle_rank1_byte1. - { 0x65402137, 0x4F0 / 4, DRAM_ID2(22) }, // emc_swizzle_rank1_byte2. - { 0x57302164, 0x4F4 / 4, DRAM_ID2(22) }, // emc_swizzle_rank1_byte3. - { 0x4F9F9FFF, 0x534 / 4, DRAM_ID2(22) }, // emc_pmc_scratch1. - { 0x4033CF1F, 0x53C / 4, DRAM_ID2(22) }, // emc_pmc_scratch3. - { 0x10000000, 0x590 / 4, DRAM_ID2(22) }, // emc_pmacro_tx_pwrd3. - { 0x00030108, 0x594 / 4, DRAM_ID2(22) }, // emc_pmacro_tx_pwrd4. - { 0x01400050, 0x598 / 4, DRAM_ID2(22) }, // emc_pmacro_tx_pwrd5. - { 0x29081081, 0x5A0 / 4, DRAM_ID2(22) }, // emc_pmacro_brick_mapping0. - { 0x54A59332, 0x5A4 / 4, DRAM_ID2(22) }, // emc_pmacro_brick_mapping1. - { 0x87766B4A, 0x5A8 / 4, DRAM_ID2(22) }, // emc_pmacro_brick_mapping2. - { 0x00000001, 0x670 / 4, DRAM_ID2(22) }, // mc_emem_arb_timing_faw. - { 0xE4FACB43, 0x6D4 / 4, DRAM_ID2(22) }, // mc_video_protect_vpr_override. + TSEC, NVENC. - { 0x0600FED3, 0x6D8 / 4, DRAM_ID2(22) }, // mc_video_protect_vpr_override1. + TSECB, TSEC1, TSECB1. - { 0x2A800000, 0x6DC / 4, DRAM_ID2(22) }, // mc_video_protect_gpu_override0. - { 0x00000002, 0x6E0 / 4, DRAM_ID2(22) }, // mc_video_protect_gpu_override1. - { 0x0000009C, 0x814 / 4, DRAM_ID2(22) }, // swizzle_rank_byte_encode. +/* + // Samsung LPDDR4X 4GB 10nm-class (1y-A01) Die-? for prototype (?) Aula. Unused. + { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_auto_cal_config2. + { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_auto_cal_vref_sel0. + { 0x00000008, 0x24C / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_tfaw. + { 0x1C041B06, 0x26C / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_cmd_mapping_cmd0_0. + { 0x02050307, 0x270 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_cmd_mapping_cmd0_1. + { 0x03252500, 0x274 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_cmd_mapping_cmd0_2. + { 0x081D1E00, 0x278 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_cmd_mapping_cmd1_0. + { 0x090C0A0D, 0x27C / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_cmd_mapping_cmd1_1. + { 0x0526260B, 0x280 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_cmd_mapping_cmd1_2. + { 0x05030402, 0x284 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_cmd_mapping_cmd2_0. + { 0x1B1C0600, 0x288 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_cmd_mapping_cmd2_1. + { 0x07252507, 0x28C / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_cmd_mapping_cmd2_2. + { 0x0C1D0B0A, 0x290 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_cmd_mapping_cmd3_0. + { 0x0800090D, 0x294 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_cmd_mapping_cmd3_1. + { 0x0926261E, 0x298 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_cmd_mapping_cmd3_2. + { 0x2A080624, 0x29C / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_cmd_mapping_byte. + { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_mrw14. + { 0x80000713, 0x32C / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_dyn_self_ref_control. + { 0x00140010, 0x3AC / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dq_rank0_4. + { 0x0013000B, 0x3B0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dq_rank0_5. + { 0x00140010, 0x3C4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dq_rank1_4. + { 0x0013000B, 0x3C8 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dq_rank1_5. + { 0x00450047, 0x3CC / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dqs_rank0_0. + { 0x004D004F, 0x3D0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dqs_rank0_1. + { 0x00460046, 0x3D4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dqs_rank0_2. + { 0x00480048, 0x3D8 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dqs_rank0_3. + { 0x000C0008, 0x3DC / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dqs_rank0_4. + { 0x000B000C, 0x3E0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dqs_rank0_5. + { 0x00450047, 0x3E4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dqs_rank1_0. + { 0x004D004F, 0x3E8 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dqs_rank1_1. + { 0x00460046, 0x3EC / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dqs_rank1_2. + { 0x00480048, 0x3F0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dqs_rank1_3. + { 0x000C0008, 0x3F4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dqs_rank1_4. + { 0x000B000C, 0x3F8 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ob_ddll_long_dqs_rank1_5. + { 0x00100010, 0x41C / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ddll_long_cmd_0. + { 0x00140014, 0x420 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ddll_long_cmd_1. + { 0x00130013, 0x428 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ddll_long_cmd_3. + { 0x00000010, 0x42C / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_ddll_long_cmd_4. + { 0x40280100, 0x4B4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // pmc_ddr_cfg. + { 0x4F9F9FFF, 0x4B8 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // pmc_io_dpd3_req. + { 0x64032157, 0x4D8 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_swizzle_rank0_byte0. + { 0x51320467, 0x4DC / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_swizzle_rank0_byte1. + { 0x04735621, 0x4E0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_swizzle_rank0_byte2. + { 0x47356012, 0x4E4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_swizzle_rank0_byte3. + { 0x12045673, 0x4E8 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_swizzle_rank1_byte0. + { 0x43657210, 0x4EC / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_swizzle_rank1_byte1. + { 0x65402137, 0x4F0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_swizzle_rank1_byte2. + { 0x57302164, 0x4F4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_swizzle_rank1_byte3. + { 0x4F9F9FFF, 0x534 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmc_scratch1. + { 0x4033CF1F, 0x53C / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmc_scratch3. + { 0x10000000, 0x590 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_tx_pwrd3. + { 0x00030108, 0x594 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_tx_pwrd4. + { 0x01400050, 0x598 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_tx_pwrd5. + { 0x29081081, 0x5A0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_brick_mapping0. + { 0x54A59332, 0x5A4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_brick_mapping1. + { 0x87766B4A, 0x5A8 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // emc_pmacro_brick_mapping2. + { 0x00000001, 0x670 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // mc_emem_arb_timing_faw. + { 0xE4FACB43, 0x6D4 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // mc_video_protect_vpr_override. + TSEC, NVENC. + { 0x0600FED3, 0x6D8 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // mc_video_protect_vpr_override1. + TSECB, TSEC1, TSECB1. + { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // mc_video_protect_gpu_override0. + { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // mc_video_protect_gpu_override1. + { 0x0000009C, 0x814 / 4, LPDDR4X_4GB_SAMSUNG_1Y_A }, // swizzle_rank_byte_encode. +*/ + // Micron LPDDR4X 4GB 10nm-class (1y-01) Die-A for Unknown Iowa/Hoag/Aula. + { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_auto_cal_config2. + { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_auto_cal_vref_sel0. + { 0x00000006, 0x1CC / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_quse. + { 0x00000005, 0x1D0 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_quse_width. + { 0x00000003, 0x1DC / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_einput. + { 0x0000000C, 0x1E0 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_einput_duration. + { 0x00000008, 0x24C / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_tfaw. + { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_mrw14. + { 0x80000713, 0x32C / 4, LPDDR4X_4GB_MICRON_1Y_A }, // emc_dyn_self_ref_control. + { 0x00000001, 0x670 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // mc_emem_arb_timing_faw. + { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_MICRON_1Y_A }, // mc_video_protect_gpu_override0. + { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_MICRON_1Y_A }, // mc_video_protect_gpu_override1. - // Micron LPDDR4X 4GB 10nm-class (1y) Die-A for Unknown Iowa/Hoag/Aula. - { 0x05500000, 0x0D4 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_auto_cal_config2. - { 0xC9AFBCBC, 0x0F4 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_auto_cal_vref_sel0. - { 0x00000006, 0x1CC / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_quse. - { 0x00000005, 0x1D0 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_quse_width. - { 0x00000003, 0x1DC / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_einput. - { 0x0000000C, 0x1E0 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_einput_duration. - { 0x00000008, 0x24C / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_tfaw. - { 0x88161414, 0x2E0 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_mrw14. - { 0x80000713, 0x32C / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // emc_dyn_self_ref_control. - { 0x00000001, 0x670 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // mc_emem_arb_timing_faw. - { 0x2A800000, 0x6DC / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // mc_video_protect_gpu_override0. - { 0x00000002, 0x6E0 / 4, DRAM_ID2(25) | DRAM_ID2(26) | DRAM_ID2(27) }, // mc_video_protect_gpu_override1. + // Hynix LPDDR4X 4GB 10nm-class (1y-01) Die-A for Unknown Iowa/Hoag/Aula. + { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_auto_cal_config2. + { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_auto_cal_vref_sel0. + { 0x00000006, 0x1CC / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_quse. + { 0x00000005, 0x1D0 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_quse_width. + { 0x00000003, 0x1DC / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_einput. + { 0x0000000C, 0x1E0 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_einput_duration. + { 0x00000008, 0x24C / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_tfaw. + { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_mrw14. + { 0x80000713, 0x32C / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // emc_dyn_self_ref_control. + { 0x00000001, 0x670 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_emem_arb_timing_faw. + { 0xE4FACB43, 0x6D4 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_video_protect_vpr_override. + TSEC, NVENC. + { 0x0600FED3, 0x6D8 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_video_protect_vpr_override1. + TSECB, TSEC1, TSECB1. + { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_video_protect_gpu_override0. + { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_HYNIX_1Y_A }, // mc_video_protect_gpu_override1. + + //!TODO: Too many duplicates. }; diff --git a/bdk/power/regulator_5v.c b/bdk/power/regulator_5v.c index 64fd7d7..7b8924b 100644 --- a/bdk/power/regulator_5v.c +++ b/bdk/power/regulator_5v.c @@ -21,25 +21,25 @@ #include static u8 reg_5v_dev = 0; -static bool batt_src = false; +static bool usb_src = false; void regulator_5v_enable(u8 dev) { // The power supply selection from battery or USB is automatic. if (!reg_5v_dev) { - // Fan and Rail power from internal 5V regulator (battery). + // Fan and Rail power from battery 5V regulator. PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = 1; gpio_config(GPIO_PORT_A, GPIO_PIN_5, GPIO_MODE_GPIO); gpio_output_enable(GPIO_PORT_A, GPIO_PIN_5, GPIO_OUTPUT_ENABLE); gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH); - batt_src = true; - // Fan and Rail power from USB 5V VDD. + // Fan and Rail power from USB 5V VBUS. PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_LPDR | 1; gpio_config(GPIO_PORT_CC, GPIO_PIN_4, GPIO_MODE_GPIO); gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_4, GPIO_OUTPUT_ENABLE); - gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_HIGH); + gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW); + usb_src = false; // Make sure GPIO power is enabled. PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO_IO_EN; @@ -55,18 +55,18 @@ void regulator_5v_disable(u8 dev) if (!reg_5v_dev) { - // Rail power from internal 5V regulator (battery). + // Rail power from battery 5V regulator. gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_LOW); gpio_output_enable(GPIO_PORT_A, GPIO_PIN_5, GPIO_OUTPUT_DISABLE); gpio_config(GPIO_PORT_A, GPIO_PIN_5, GPIO_MODE_SPIO); PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = PINMUX_PARKED | PINMUX_INPUT_ENABLE; - batt_src = false; - // Rail power from USB 5V VDD. + // Rail power from USB 5V VBUS. gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW); gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_4, GPIO_OUTPUT_DISABLE); gpio_config(GPIO_PORT_CC, GPIO_PIN_4, GPIO_MODE_SPIO); PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_PARKED | PINMUX_INPUT_ENABLE; + usb_src = false; // GPIO AO IO rails. PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_GPIO_IO_EN; @@ -78,16 +78,16 @@ bool regulator_5v_get_dev_enabled(u8 dev) return (reg_5v_dev & dev); } -void regulator_5v_batt_src_enable(bool enable) +void regulator_5v_usb_src_enable(bool enable) { - if (enable && !batt_src) + if (enable && !usb_src) { - gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH); - batt_src = true; + gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_HIGH); + usb_src = true; } - else if (!enable && batt_src) + else if (!enable && usb_src) { - gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_LOW); - batt_src = false; + gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW); + usb_src = false; } } diff --git a/bdk/power/regulator_5v.h b/bdk/power/regulator_5v.h index b7d7490..527c18a 100644 --- a/bdk/power/regulator_5v.h +++ b/bdk/power/regulator_5v.h @@ -30,6 +30,6 @@ enum void regulator_5v_enable(u8 dev); void regulator_5v_disable(u8 dev); bool regulator_5v_get_dev_enabled(u8 dev); -void regulator_5v_batt_src_enable(bool enable); +void regulator_5v_usb_src_enable(bool enable); #endif \ No newline at end of file diff --git a/bdk/sec/se.c b/bdk/sec/se.c index a879cb0..45652dc 100644 --- a/bdk/sec/se.c +++ b/bdk/sec/se.c @@ -255,7 +255,7 @@ int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_siz // Copy output hash. u32 *dst32 = (u32 *)dst; for (u32 i = 0; i < dst_size / 4; i++) - dst32[dst_size / 4 - i - 1] = byte_swap_32(SE(SE_RSA_OUTPUT_REG + (i << 2))); + dst32[dst_size / 4 - i - 1] = byte_swap_32(SE(SE_RSA_OUTPUT_REG + (i * 4))); return res; } @@ -485,7 +485,7 @@ int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst tweak[i] = sec & 0xFF; sec >>= 8; } - if (!se_aes_crypt_block_ecb(tweak_ks, 1, tweak, tweak)) + if (!se_aes_crypt_block_ecb(tweak_ks, ENCRYPT, tweak, tweak)) return 0; memcpy(orig_tweak, tweak, 0x10); @@ -538,7 +538,7 @@ int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size) u8 *last_block = (u8 *)calloc(0x10, 1); // generate derived key - if (!se_aes_crypt_block_ecb(ks, 1, key, key)) + if (!se_aes_crypt_block_ecb(ks, ENCRYPT, key, key)) goto out; _gf256_mul_x(key); if (src_size & 0xF) @@ -668,7 +668,7 @@ int se_calc_sha256_finalize(void *hash, u32 *msg_left) // Copy output hash. for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++) - hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i << 2))); + hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4))); memcpy(hash, hash32, SE_SHA_256_SIZE); return res; @@ -841,6 +841,6 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize) // Decrypt context. se_aes_key_clear(3); se_aes_key_set(3, srk, SE_KEY_128_SIZE); - se_aes_crypt_cbc(3, 0, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize); + se_aes_crypt_cbc(3, DECRYPT, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize); se_aes_key_clear(3); } diff --git a/bdk/sec/se_t210.h b/bdk/sec/se_t210.h index 0233e1d..350bc15 100644 --- a/bdk/sec/se_t210.h +++ b/bdk/sec/se_t210.h @@ -50,6 +50,9 @@ #define SE_RSA1536_DIGEST_SIZE 192 #define SE_RSA2048_DIGEST_SIZE 256 +#define DECRYPT 0 +#define ENCRYPT 1 + /* SE register definitions */ #define SE_SE_SECURITY_REG 0x000 #define SE_HARD_SETTING BIT(0) diff --git a/bdk/sec/tsec.c b/bdk/sec/tsec.c index c154062..ad13b87 100644 --- a/bdk/sec/tsec.c +++ b/bdk/sec/tsec.c @@ -33,7 +33,8 @@ // #include #define PKG11_MAGIC 0x31314B50 -#define KB_TSEC_FW_EMU_COMPAT 6 // KB ID for HOS 6.2.0. + +#define TSEC_HOS_KB_620 6 static int _tsec_dma_wait_idle() { @@ -62,10 +63,13 @@ static int _tsec_dma_pa_to_internal_100(int not_imem, int i_offset, int pa_offse return _tsec_dma_wait_idle(); } -int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) +int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt) { int res = 0; u8 *fwbuf = NULL; + u32 type = tsec_ctxt->type; + u32 *pdir, *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec; + u32 *pkg11_magic_off; bpmp_mmu_disable(); bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL); @@ -81,7 +85,10 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) kfuse_wait_ready(); - //Configure Falcon. + if (type == TSEC_FW_TYPE_NEW) + mc_enable_ahb_redirect(true); + + // Configure Falcon. TSEC(TSEC_DMACTL) = 0; TSEC(TSEC_IRQMSET) = TSEC_IRQMSET_EXT(0xFF) | @@ -103,8 +110,8 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) goto out; } - //Load firmware or emulate memio environment for newer TSEC fw. - if (kb == KB_TSEC_FW_EMU_COMPAT) + // Load firmware or emulate memio environment for newer TSEC fw. + if (type == TSEC_FW_TYPE_EMU) TSEC(TSEC_DMATRFBASE) = (u32)tsec_ctxt->fw >> 8; else { @@ -123,40 +130,159 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) } } - //Execute firmware. + if (type == TSEC_FW_TYPE_EMU) + { + // Init SMMU translation for TSEC. + pdir = smmu_init_for_tsec(); + smmu_init(tsec_ctxt->secmon_base); + // Enable SMMU + if (!smmu_is_used()) + smmu_enable(); + + // Clock reset controller. + car = page_alloc(1); + memcpy(car, (void *)CLOCK_BASE, 0x1000); + car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = 2; + smmu_map(pdir, CLOCK_BASE, (u32)car, 1, _WRITABLE | _READABLE | _NONSECURE); + + // Fuse driver. + fuse = page_alloc(1); + memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, 0x400); + fuse[0x82C / 4] = 0; + fuse[0x9E0 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1; + fuse[0x9E4 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1; + smmu_map(pdir, (FUSE_BASE - 0x800), (u32)fuse, 1, _READABLE | _NONSECURE); + + // Power management controller. + pmc = page_alloc(1); + smmu_map(pdir, RTC_BASE, (u32)pmc, 1, _READABLE | _NONSECURE); + + // Flow control. + flowctrl = page_alloc(1); + smmu_map(pdir, FLOW_CTLR_BASE, (u32)flowctrl, 1, _WRITABLE | _NONSECURE); + + // Security engine. + se = page_alloc(1); + memcpy(se, (void *)SE_BASE, 0x1000); + smmu_map(pdir, SE_BASE, (u32)se, 1, _READABLE | _WRITABLE | _NONSECURE); + + // Memory controller. + mc = page_alloc(1); + memcpy(mc, (void *)MC_BASE, 0x1000); + mc[MC_IRAM_BOM / 4] = 0; + mc[MC_IRAM_TOM / 4] = 0x80000000; + smmu_map(pdir, MC_BASE, (u32)mc, 1, _READABLE | _NONSECURE); + + // IRAM + iram = page_alloc(0x30); + memcpy(iram, tsec_ctxt->pkg1, 0x30000); + // PKG1.1 magic offset. + pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / 4)); + smmu_map(pdir, 0x40010000, (u32)iram, 0x30, _READABLE | _WRITABLE | _NONSECURE); + + // Exception vectors + evec = page_alloc(1); + smmu_map(pdir, EXCP_VEC_BASE, (u32)evec, 1, _READABLE | _WRITABLE | _NONSECURE); + } + + // Execute firmware. HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0x34C2E1DA; TSEC(TSEC_STATUS) = 0; TSEC(TSEC_BOOTKEYVER) = 1; // HOS uses key version 1. TSEC(TSEC_BOOTVEC) = 0; TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU; - if (!_tsec_dma_wait_idle()) + if (type == TSEC_FW_TYPE_EMU) { - res = -3; - goto out_free; - } - u32 timeout = get_tmr_ms() + 4000; - while (!(TSEC(TSEC_CPUCTL) & TSEC_CPUCTL_KEYGEN_DONE)) - if (get_tmr_ms() > timeout) + u32 start = get_tmr_us(); + u32 k = se[SE_CRYPTO_KEYTABLE_DATA_REG / 4]; + u32 key[16] = {0}; + u32 kidx = 0; + + while (*pkg11_magic_off != PKG11_MAGIC) { - res = -4; + smmu_flush_all(); + + if (k != se[SE_CRYPTO_KEYTABLE_DATA_REG / 4]) + { + k = se[SE_CRYPTO_KEYTABLE_DATA_REG / 4]; + key[kidx++] = k; + } + + // Failsafe. + if ((u32)get_tmr_us() - start > 125000) + break; + } + + if (kidx != 8) + { + res = -6; + smmu_deinit_for_tsec(); + goto out_free; } - if (TSEC(TSEC_STATUS) != 0xB0B0B0B0) - { - res = -5; - goto out_free; - } - //Fetch result. - HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0; + // Give some extra time to make sure PKG1.1 is decrypted. + msleep(50); + + memcpy(tsec_keys, &key, 0x20); + memcpy(tsec_ctxt->pkg1, iram, 0x30000); + + smmu_deinit_for_tsec(); + + // for (int i = 0; i < kidx; i++) + // gfx_printf("key %08X\n", key[i]); + + // gfx_printf("cpuctl (%08X) mbox (%08X)\n", TSEC(TSEC_CPUCTL), TSEC(TSEC_STATUS)); + + // u32 errst = MC(MC_ERR_STATUS); + // gfx_printf(" MC %08X %08X %08X\n", MC(MC_INTSTATUS), errst, MC(MC_ERR_ADR)); + // gfx_printf(" type: %02X\n", errst >> 28); + // gfx_printf(" smmu: %02X\n", (errst >> 25) & 3); + // gfx_printf(" dir: %s\n", (errst >> 16) & 1 ? "W" : "R"); + // gfx_printf(" cid: %02x\n", errst & 0xFF); + } + else + { + if (!_tsec_dma_wait_idle()) + { + res = -3; + goto out_free; + } + u32 timeout = get_tmr_ms() + 2000; + while (!TSEC(TSEC_STATUS)) + if (get_tmr_ms() > timeout) + { + res = -4; + goto out_free; + } + if (TSEC(TSEC_STATUS) != 0xB0B0B0B0) + { + res = -5; + goto out_free; + } + + // Fetch result. + HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0; + u32 buf[4]; + buf[0] = SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB); + buf[1] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB); + buf[2] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB); + buf[3] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB); + SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB) = 0; + SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB) = 0; + SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB) = 0; + SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 0; + + memcpy(tsec_keys, &buf, SE_KEY_128_SIZE); + } out_free:; free(fwbuf); out:; - //Disable clocks. + // Disable clocks. clock_disable_kfuse(); clock_disable_sor1(); clock_disable_sor0(); @@ -165,28 +291,8 @@ out:; bpmp_mmu_enable(); bpmp_clk_rate_set(prev_fid); - return res; -} - -int tsec_run_fw(tsec_ctxt_t *tsec_ctxt) -{ - /* Ensure that the ahb redirect is enabled. */ - mc_enable_ahb_redirect(); - - /* Get bom/tom */ - u32 bom = MC(MC_IRAM_BOM); - u32 tom = MC(MC_IRAM_TOM); - - /* Override the ahb redirect extents. */ - MC(MC_IRAM_BOM) = 0x40000000; - MC(MC_IRAM_TOM) = 0x80000000; - - /* Run the fw. */ - int res = tsec_query(NULL, 0, tsec_ctxt); - - /* Reset the ahb redirect extents. */ - MC(MC_IRAM_BOM) = bom; - MC(MC_IRAM_TOM) = tom; + if (type == TSEC_FW_TYPE_NEW) + mc_disable_ahb_redirect(); return res; } diff --git a/bdk/sec/tsec.h b/bdk/sec/tsec.h index 47c9f45..734ca41 100644 --- a/bdk/sec/tsec.h +++ b/bdk/sec/tsec.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert -* Copyright (c) 2018 CTCaer +* Copyright (c) 2018-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -20,33 +20,24 @@ #include -#define TSEC_KEY_DATA_OFFSET 0x300 +enum tsec_fw_type +{ + // Retail Hovi Keygen. + TSEC_FW_TYPE_OLD = 0, // 1.0.0 - 6.1.0. + TSEC_FW_TYPE_EMU = 1, // 6.2.0 emulated enviroment. + TSEC_FW_TYPE_NEW = 2, // 7.0.0+. +}; typedef struct _tsec_ctxt_t { const void *fw; u32 size; + u32 type; void *pkg1; + u32 pkg11_off; + u32 secmon_base; } tsec_ctxt_t; -typedef struct _tsec_key_data_t -{ - u8 debug_key[0x10]; - u8 blob0_auth_hash[0x10]; - u8 blob1_auth_hash[0x10]; - u8 blob2_auth_hash[0x10]; - u8 blob2_aes_iv[0x10]; - u8 hovi_eks_seed[0x10]; - u8 hovi_common_seed[0x10]; - u32 blob0_size; - u32 blob1_size; - u32 blob2_size; - u32 blob3_size; - u32 blob4_size; - u8 reserved[0x7C]; -} tsec_key_data_t; - -int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt); -int tsec_run_fw(tsec_ctxt_t *tsec_ctxt); +int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt); #endif diff --git a/bdk/sec/tsec_t210.h b/bdk/sec/tsec_t210.h index 9d473cb..889d0d4 100644 --- a/bdk/sec/tsec_t210.h +++ b/bdk/sec/tsec_t210.h @@ -37,7 +37,6 @@ #define TSEC_IRQDEST_EXT(val) (((val) & 0xFF) << 8) #define TSEC_CPUCTL 0x1100 #define TSEC_CPUCTL_STARTCPU BIT(1) -#define TSEC_CPUCTL_KEYGEN_DONE BIT(4) #define TSEC_BOOTVEC 0x1104 #define TSEC_DMACTL 0x110C #define TSEC_DMATRFBASE 0x1110 diff --git a/bdk/soc/fuse.c b/bdk/soc/fuse.c index e350b64..39a50c1 100644 --- a/bdk/soc/fuse.c +++ b/bdk/soc/fuse.c @@ -2,7 +2,8 @@ * Copyright (c) 2018 naehrwert * Copyright (c) 2018 shuffle2 * Copyright (c) 2018 balika011 - * Copyright (c) 2019-2020 CTCaer + * Copyright (c) 2019-2021 CTCaer + * Copyright (c) 2021 shchmue * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -19,6 +20,8 @@ #include +#include +#include #include #include #include @@ -99,7 +102,7 @@ u32 fuse_read_dramid(bool raw_id) } else { - if (dramid > 27) + if (dramid > 28) dramid = 8; } @@ -120,26 +123,41 @@ u32 fuse_read_hw_type() { switch ((fuse_read_odm(4) & 0xF0000) >> 16) { - case 1: - return FUSE_NX_HW_TYPE_IOWA; case 2: return FUSE_NX_HW_TYPE_HOAG; + case 4: + return FUSE_NX_HW_TYPE_AULA; + case 1: + default: + return FUSE_NX_HW_TYPE_IOWA; } } return FUSE_NX_HW_TYPE_ICOSA; } -u8 fuse_count_burnt(u32 val) +int fuse_set_sbk() { - u8 burnt_fuses = 0; - for (u32 i = 0; i < 32; i++) + if (FUSE(FUSE_PRIVATE_KEY0) != 0xFFFFFFFF) { - if ((val >> i) & 1) - burnt_fuses++; + // Read SBK from fuses. + u32 sbk[4] = { + FUSE(FUSE_PRIVATE_KEY0), + FUSE(FUSE_PRIVATE_KEY1), + FUSE(FUSE_PRIVATE_KEY2), + FUSE(FUSE_PRIVATE_KEY3) + }; + + // Set SBK to slot 14. + se_aes_key_set(14, sbk, SE_KEY_128_SIZE); + + // Lock SBK from being read. + se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG); + + return 1; } - return burnt_fuses; + return 0; } void fuse_wait_idle() diff --git a/bdk/soc/fuse.h b/bdk/soc/fuse.h index 481923c..99759d9 100644 --- a/bdk/soc/fuse.h +++ b/bdk/soc/fuse.h @@ -2,7 +2,8 @@ * Copyright (c) 2018 naehrwert * Copyright (c) 2018 shuffle2 * Copyright (c) 2018 balika011 - * Copyright (c) 2019-2020 CTCaer + * Copyright (c) 2019-2021 CTCaer + * Copyright (c) 2021 shchmue * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -82,7 +83,8 @@ enum { FUSE_NX_HW_TYPE_ICOSA, FUSE_NX_HW_TYPE_IOWA, - FUSE_NX_HW_TYPE_HOAG + FUSE_NX_HW_TYPE_HOAG, + FUSE_NX_HW_TYPE_AULA }; enum @@ -98,7 +100,7 @@ u32 fuse_read_bootrom_rev(); u32 fuse_read_dramid(bool raw_id); u32 fuse_read_hw_state(); u32 fuse_read_hw_type(); -u8 fuse_count_burnt(u32 val); +int fuse_set_sbk(); void fuse_wait_idle(); int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value)); int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len); diff --git a/bdk/soc/hw_init.c b/bdk/soc/hw_init.c index afde017..5efe5df 100644 --- a/bdk/soc/hw_init.c +++ b/bdk/soc/hw_init.c @@ -250,28 +250,14 @@ static void _mbist_workaround() static void _config_se_brom() { - // Enable fuse clock. + // Enable Fuse visibility. clock_enable_fuse(true); - // Skip SBK/SSK if running on patched Erista. - if (!(FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF)) - { - // Bootrom part we skipped. - u32 sbk[4] = { - FUSE(FUSE_PRIVATE_KEY0), - FUSE(FUSE_PRIVATE_KEY1), - FUSE(FUSE_PRIVATE_KEY2), - FUSE(FUSE_PRIVATE_KEY3) - }; - // Set SBK to slot 14. - se_aes_key_set(14, sbk, SE_KEY_128_SIZE); + // Try to set SBK from fuses. If patched, skip. + fuse_set_sbk(); - // Lock SBK from being read. - se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG); - - // Lock SSK (although it's not set and unused anyways). - se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEYREAD_FLAG); - } + // Lock SSK (although it's not set and unused anyways). + // se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEYREAD_FLAG); // This memset needs to happen here, else TZRAM will behave weirdly later on. memset((void *)TZRAM_BASE, 0, 0x10000); @@ -351,7 +337,7 @@ void hw_init() // Enable Security Engine clock. clock_enable_se(); - // Enable Fuse clock. + // Enable Fuse visibility. clock_enable_fuse(true); // Disable Fuse programming. diff --git a/bdk/storage/mmc.h b/bdk/storage/mmc.h index fc6c2f8..ee81e69 100644 --- a/bdk/storage/mmc.h +++ b/bdk/storage/mmc.h @@ -2,6 +2,7 @@ * Header for MultiMediaCard (MMC) * * Copyright 2002 Hewlett-Packard Company + * Copyright 2018-2021 CTCaer * * Use consistent with the GNU GPL is permitted, * provided that this copyright notice is @@ -21,8 +22,8 @@ * 15 May 2002 */ -#ifndef LINUX_MMC_MMC_H -#define LINUX_MMC_MMC_H +#ifndef MMC_H +#define MMC_H /* Standard MMC commands (4.1) type argument response */ /* class 1 */ @@ -97,29 +98,29 @@ #define MMC_CMDQ_TASK_MGMT 48 /* ac [20:16] task id R1b */ /* -* MMC_SWITCH argument format: -* -* [31:26] Always 0 -* [25:24] Access Mode -* [23:16] Location of target Byte in EXT_CSD -* [15:08] Value Byte -* [07:03] Always 0 -* [02:00] Command Set -*/ + * MMC_SWITCH argument format: + * + * [31:26] Always 0 + * [25:24] Access Mode + * [23:16] Location of target Byte in EXT_CSD + * [15:08] Value Byte + * [07:03] Always 0 + * [02:00] Command Set + */ /* -MMC status in R1, for native mode (SPI bits are different) -Type -e : error bit -s : status bit -r : detected and set for the actual command response -x : detected and set during command execution. the host must poll -the card by sending status command in order to read these bits. -Clear condition -a : according to the card state -b : always related to the previous command. Reception of -a valid command will clear it (with a delay of one command) -c : clear by read + * MMC status in R1, for native mode (SPI bits are different) + * Type + * e : error bit + * s : status bit + * r : detected and set for the actual command response + * x : detected and set during command execution. the host must poll + * the card by sending status command in order to read these bits. + * Clear condition + * a : according to the card state + * b : always related to the previous command. Reception of a valid + * command will clear it (with a delay of one command) + * c : clear by read */ #define R1_OUT_OF_RANGE (1 << 31) /* er, c */ @@ -151,6 +152,7 @@ c : clear by read #define R1_AKE_SEQ_ERROR (1 << 3) /* R1_CURRENT_STATE 12:9 */ +#define R1_STATE(x) ((x) << 9) #define R1_STATE_IDLE 0 #define R1_STATE_READY 1 #define R1_STATE_IDENT 2 @@ -162,9 +164,9 @@ c : clear by read #define R1_STATE_DIS 8 /* -* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS -* R1 is the low order byte; R2 is the next highest byte, when present. -*/ + * MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS + * R1 is the low order byte; R2 is the next highest byte, when present. + */ #define R1_SPI_IDLE (1 << 0) #define R1_SPI_ERASE_RESET (1 << 1) #define R1_SPI_ILLEGAL_COMMAND (1 << 2) @@ -185,16 +187,16 @@ c : clear by read #define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE /* -* OCR bits are mostly in host.h -*/ + * OCR bits are mostly in host.h + */ #define MMC_CARD_VDD_18 (1 << 7) /* Card VDD voltage 1.8 */ #define MMC_CARD_VDD_27_34 (0x7F << 15) /* Card VDD voltage 2.7 ~ 3.4 */ #define MMC_CARD_CCS (1 << 30) /* Card Capacity status bit */ #define MMC_CARD_BUSY (1 << 31) /* Card Power up status bit */ /* -* Card Command Classes (CCC) -*/ + * Card Command Classes (CCC) + */ #define CCC_BASIC (1<<0) /* (0) Basic protocol functions */ /* (CMD0,1,2,3,4,7,9,10,12,13,15) */ /* (and for SPI, CMD58,59) */ @@ -222,8 +224,8 @@ c : clear by read /* (CMD?) */ /* -* CSD field definitions -*/ + * CSD field definitions + */ #define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */ #define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */ @@ -237,8 +239,8 @@ c : clear by read #define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */ /* -* EXT_CSD fields -*/ + * EXT_CSD fields + */ #define EXT_CSD_CMDQ_MODE_EN 15 /* R/W */ #define EXT_CSD_FLUSH_CACHE 32 /* W */ @@ -316,8 +318,8 @@ c : clear by read #define EXT_CSD_HPI_FEATURES 503 /* RO */ /* -* EXT_CSD field definitions -*/ + * EXT_CSD field definitions + */ #define EXT_CSD_WR_REL_PARAM_EN (1<<2) @@ -393,8 +395,8 @@ c : clear by read #define EXT_CSD_PACKED_EVENT_EN (1<<3) /* -* EXCEPTION_EVENT_STATUS field -*/ + * EXCEPTION_EVENT_STATUS field + */ #define EXT_CSD_URGENT_BKOPS (1<<0) #define EXT_CSD_DYNCAP_NEEDED (1<<1) #define EXT_CSD_SYSPOOL_EXHAUSTED (1<<2) @@ -404,34 +406,34 @@ c : clear by read #define EXT_CSD_PACKED_INDEXED_ERROR (1<<1) /* -* BKOPS status level -*/ + * BKOPS status level + */ #define EXT_CSD_BKOPS_LEVEL_2 0x2 /* -* BKOPS modes -*/ + * BKOPS modes + */ #define EXT_CSD_MANUAL_BKOPS_MASK 0x01 #define EXT_CSD_AUTO_BKOPS_MASK 0x02 /* -* Command Queue -*/ + * Command Queue + */ #define EXT_CSD_CMDQ_MODE_ENABLED (1<<0) #define EXT_CSD_CMDQ_DEPTH_MASK 0x1F #define EXT_CSD_CMDQ_SUPPORTED (1<<0) /* -* MMC_SWITCH access modes -*/ + * MMC_SWITCH access modes + */ #define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ #define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */ #define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */ #define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ /* -* Erase/trim/discard -*/ + * Erase/trim/discard + */ #define MMC_ERASE_ARG 0x00000000 #define MMC_SECURE_ERASE_ARG 0x80000000 #define MMC_TRIM_ARG 0x00000001 @@ -441,4 +443,9 @@ c : clear by read #define MMC_SECURE_ARGS 0x80000000 #define MMC_TRIM_ARGS 0x00008001 -#endif /* LINUX_MMC_MMC_H */ +/* + * Vendor definitions and structs + */ +#define MMC_SANDISK_HEALTH_REPORT 0x96C9D71C + +#endif /* MMC_H */ diff --git a/bdk/storage/sdmmc.c b/bdk/storage/sdmmc.c index 54b19de..c87db83 100644 --- a/bdk/storage/sdmmc.c +++ b/bdk/storage/sdmmc.c @@ -139,6 +139,60 @@ static int _sdmmc_storage_check_status(sdmmc_storage_t *storage) return _sdmmc_storage_get_status(storage, &tmp, 0); } +int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg) +{ + sdmmc_cmd_t cmdbuf; + sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_62_CMD, arg, SDMMC_RSP_TYPE_1, 1); + if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0)) + return 0; + + u32 resp; + sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_1); + + resp = -1; + u32 timeout = get_tmr_ms() + 1500; + while (resp != (R1_READY_FOR_DATA | R1_STATE(R1_STATE_TRAN))) + { + _sdmmc_storage_get_status(storage, &resp, 0); + + if (get_tmr_ms() > timeout) + break; + } + + return _sdmmc_storage_check_card_status(resp); +} + +int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf) +{ + // Request health report. + if (!sdmmc_storage_execute_vendor_cmd(storage, MMC_SANDISK_HEALTH_REPORT)) + return 2; + + u32 tmp = 0; + sdmmc_cmd_t cmdbuf; + sdmmc_req_t reqbuf; + + sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_63_CMD, 0, SDMMC_RSP_TYPE_1, 0); // similar to CMD17 with arg 0x0. + + reqbuf.buf = buf; + reqbuf.num_sectors = 1; + reqbuf.blksize = 512; + reqbuf.is_write = 0; + reqbuf.is_multi_block = 0; + reqbuf.is_auto_stop_trn = 0; + + u32 blkcnt_out; + if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, &blkcnt_out)) + { + sdmmc_stop_transmission(storage->sdmmc, &tmp); + _sdmmc_storage_get_status(storage, &tmp, 0); + + return 0; + } + + return 1; +} + static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out, u32 sector, u32 num_sectors, void *buf, u32 is_write) { u32 tmp = 0; @@ -1360,8 +1414,6 @@ DPRINTF("[SD] SD does not support wide bus width\n"); if (!_sd_storage_enable_uhs_low_volt(storage, type, buf)) return 0; DPRINTF("[SD] enabled UHS\n"); - - sdmmc_card_clock_powersave(sdmmc, SDMMC_POWER_SAVE_ENABLE); } else if (type != SDHCI_TIMING_SD_DS12 && storage->scr.sda_vsn) // Not default speed and not SD Version 1.0. { @@ -1387,6 +1439,8 @@ DPRINTF("[SD] enabled HS\n"); DPRINTF("[SD] got sd status\n"); } + sdmmc_card_clock_powersave(sdmmc, SDMMC_POWER_SAVE_ENABLE); + storage->initialized = 1; return 1; diff --git a/bdk/storage/sdmmc.h b/bdk/storage/sdmmc.h index 2b59f7d..5dcd10f 100644 --- a/bdk/storage/sdmmc.h +++ b/bdk/storage/sdmmc.h @@ -34,6 +34,81 @@ typedef enum _sdmmc_type EMMC_RPMB = 3 } sdmmc_type; +typedef struct _mmc_sandisk_advanced_report_t +{ + u32 power_inits; + + u32 max_erase_cycles_sys; + u32 max_erase_cycles_slc; + u32 max_erase_cycles_mlc; + + u32 min_erase_cycles_sys; + u32 min_erase_cycles_slc; + u32 min_erase_cycles_mlc; + + u32 max_erase_cycles_euda; + u32 min_erase_cycles_euda; + u32 avg_erase_cycles_euda; + u32 read_reclaim_cnt_euda; + u32 bad_blocks_euda; + + u32 pre_eol_euda; + u32 pre_eol_sys; + u32 pre_eol_mlc; + + u32 uncorrectable_ecc; + + u32 temperature_now; + u32 temperature_min; + u32 temperature_max; + + u32 health_pct_euda; + u32 health_pct_sys; + u32 health_pct_mlc; + + u32 unk0; + u32 unk1; + u32 unk2; + + u32 reserved[78]; +} mmc_sandisk_advanced_report_t; + +typedef struct _mmc_sandisk_report_t +{ + u32 avg_erase_cycles_sys; + u32 avg_erase_cycles_slc; + u32 avg_erase_cycles_mlc; + + u32 read_reclaim_cnt_sys; + u32 read_reclaim_cnt_slc; + u32 read_reclaim_cnt_mlc; + + u32 bad_blocks_factory; + u32 bad_blocks_sys; + u32 bad_blocks_slc; + u32 bad_blocks_mlc; + + u32 fw_updates_cnt; + + u8 fw_update_date[12]; + u8 fw_update_time[8]; + + u32 total_writes_100mb; + u32 vdrops; + u32 vdroops; + + u32 vdrops_failed_data_rec; + u32 vdrops_data_rec_ops; + + u32 total_writes_slc_100mb; + u32 total_writes_mlc_100mb; + + u32 mlc_bigfile_mode_limit_exceeded; + u32 avg_erase_cycles_hybrid; + + mmc_sandisk_advanced_report_t advanced; +} mmc_sandisk_report_t; + typedef struct _mmc_cid { u32 manfid; @@ -131,6 +206,9 @@ void sdmmc_storage_init_wait_sd(); int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type); int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc); +int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg); +int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf); + int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf); u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage); diff --git a/bdk/usb/usb_gadget_ums.c b/bdk/usb/usb_gadget_ums.c index 10bd56a..4be2436 100644 --- a/bdk/usb/usb_gadget_ums.c +++ b/bdk/usb/usb_gadget_ums.c @@ -4,7 +4,7 @@ * Copyright (c) 2003-2008 Alan Stern * Copyright (c) 2009 Samsung Electronics * Author: Michal Nazarewicz - * Copyright (c) 2019-2020 CTCaer + * Copyright (c) 2019-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -109,7 +109,7 @@ #define SS_WRITE_ERROR 0x30C02 #define SS_WRITE_PROTECTED 0x72700 -#define SK(x) ((u8) ((x) >> 16)) /* Sense Key byte, etc. */ +#define SK(x) ((u8) ((x) >> 16)) // Sense Key byte, etc. #define ASC(x) ((u8) ((x) >> 8)) #define ASCQ(x) ((u8) (x)) @@ -217,6 +217,7 @@ typedef struct _usbd_gadget_ums_t { u32 tag; u32 residue; u32 usb_amount_left; + bool cbw_req_queued; u32 phase_error; u32 short_packet_received; @@ -368,12 +369,12 @@ static void _ums_transfer_out_big_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL; } -static void _ums_transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32 ep) +static void _ums_transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32 ep, u32 sync_timeout) { if (ep == bulk_ctxt->bulk_in) { bulk_ctxt->bulk_in_status = usb_ops.usb_device_ep1_in_writing_finish( - &bulk_ctxt->bulk_in_length_actual); + &bulk_ctxt->bulk_in_length_actual, sync_timeout); if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR) { @@ -386,7 +387,7 @@ static void _ums_transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, else { bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_reading_finish( - &bulk_ctxt->bulk_out_length_actual); + &bulk_ctxt->bulk_out_length_actual, sync_timeout); if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR) { @@ -460,6 +461,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) } if (lba_offset >= ums->lun.num_sectors) { + ums->set_text(ums->label, "#FF8000 Warn:# Read - Out of range! Host notified."); ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; return UMS_RES_INVALID_ARG; @@ -497,7 +499,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) // Wait for the async USB transfer to finish. if (!first_read) - _ums_transfer_finish(ums, bulk_ctxt, bulk_ctxt->bulk_in); + _ums_transfer_finish(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED); lba_offset += amount; amount_left -= amount; @@ -548,6 +550,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) if (ums->lun.ro) { + ums->set_text(ums->label, "#FF8000 Warn:# Write - Read only! Host notified."); ums->lun.sense_data = SS_WRITE_PROTECTED; return UMS_RES_INVALID_ARG; @@ -571,19 +574,20 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) // Check that starting LBA is not past the end sector offset. if (lba_offset >= ums->lun.num_sectors) { + ums->set_text(ums->label, "#FF8000 Warn:# Write - Out of range! Host notified."); ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; return UMS_RES_INVALID_ARG; } - /* Carry out the file writes */ + // Carry out the file writes. usb_lba_offset = lba_offset; amount_left_to_req = ums->data_size_from_cmnd; amount_left_to_write = ums->data_size_from_cmnd; while (amount_left_to_write > 0) { - /* Queue a request for more data from the host */ + // Queue a request for more data from the host. if (amount_left_to_req > 0) { @@ -638,12 +642,12 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) */ amount = MIN(amount, bulk_ctxt->bulk_out_length); - /* Don't write a partial block */ + // Don't write a partial block. amount -= (amount & 511); if (amount == 0) goto empty_write; - /* Perform the write */ + // Perform the write. if (!sdmmc_storage_write(ums->lun.storage, ums->lun.offset + lba_offset, amount >> UMS_DISK_LBA_SHIFT, (u8 *)bulk_ctxt->bulk_out_buf)) amount = 0; @@ -654,7 +658,7 @@ DPRINTF("file write %X @ %X\n", amount, lba_offset); amount_left_to_write -= amount; ums->residue -= amount; - /* If an error occurred, report it and its position */ + // If an error occurred, report it and its position. if (!amount) { ums->set_text(ums->label, "#FFDD00 Error:# SDMMC Write!"); @@ -684,6 +688,7 @@ static int _scsi_verify(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) u32 lba_offset = get_array_be_to_le32(&ums->cmnd[2]); if (lba_offset >= ums->lun.num_sectors) { + ums->set_text(ums->label, "#FF8000 Warn:# Verif - Out of range! Host notified."); ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; return UMS_RES_INVALID_ARG; @@ -1005,7 +1010,7 @@ static int _scsi_mode_sense(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) return UMS_RES_INVALID_ARG; } - /* Store the mode data length */ + // Store the mode data length. if (ums->cmnd[0] == SC_MODE_SENSE_6) buf0[0] = len - 1; else @@ -1538,12 +1543,12 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) { - /* Was this a real packet? Should it be ignored? */ + // Was this a real packet? Should it be ignored? if (bulk_ctxt->bulk_out_status || bulk_ctxt->bulk_out_ignore || ums->lun.unmounted) { if (bulk_ctxt->bulk_out_status || ums->lun.unmounted) { - DPRINTF("USB: EP timeout\n"); + DPRINTF("USB: EP timeout (%d)\n", bulk_ctxt->bulk_out_status); // In case we disconnected, exit UMS. // Raise timeout if removable and didn't got a unit ready command inside 4s. if (bulk_ctxt->bulk_out_status == USB2_ERROR_XFER_EP_DISABLED || @@ -1574,6 +1579,8 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) { ums->set_text(ums->label, "#C7EA46 Status:# Medium unmounted"); ums->timeouts++; + if (!bulk_ctxt->bulk_out_status) + ums->timeouts += 3; } if (ums->timeouts > 20) @@ -1584,27 +1591,32 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) return UMS_RES_INVALID_ARG; } - /* Is the CBW valid? */ + // Clear request flag to allow a new one to be queued. + ums->cbw_req_queued = false; + + // Is the CBW valid? bulk_recv_pkt_t *cbw = (bulk_recv_pkt_t *)bulk_ctxt->bulk_out_buf; if (bulk_ctxt->bulk_out_length_actual != USB_BULK_CB_WRAP_LEN || cbw->Signature != USB_BULK_CB_SIG) { gfx_printf("USB: invalid CBW: len %X sig 0x%X\n", bulk_ctxt->bulk_out_length_actual, cbw->Signature); - // The Bulk-only spec says we MUST stall the IN endpoint - // (6.6.1), so it's unavoidable. It also says we must - // retain this state until the next reset, but there's - // no way to tell the controller driver it should ignore - // Clear-Feature(HALT) requests. - // - // We aren't required to halt the OUT endpoint; instead - // we can simply accept and discard any data received - // until the next reset. + /* + * The Bulk-only spec says we MUST stall the IN endpoint + * (6.6.1), so it's unavoidable. It also says we must + * retain this state until the next reset, but there's + * no way to tell the controller driver it should ignore + * Clear-Feature(HALT) requests. + * + * We aren't required to halt the OUT endpoint; instead + * we can simply accept and discard any data received + * until the next reset. + */ ums_wedge_bulk_in_endpoint(ums); bulk_ctxt->bulk_out_ignore = 1; return UMS_RES_INVALID_ARG; } - /* Is the CBW meaningful? */ + // Is the CBW meaningful? if (cbw->Lun >= UMS_MAX_LUN || cbw->Flags & ~USB_BULK_IN_FLAG || cbw->Length == 0 || cbw->Length > SCSI_MAX_CMD_SZ) { @@ -1623,7 +1635,7 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) return UMS_RES_INVALID_ARG; } - /* Save the command for later */ + // Save the command for later. ums->cmnd_size = cbw->Length; memcpy(ums->cmnd, cbw->CDB, ums->cmnd_size); @@ -1658,8 +1670,20 @@ static int get_next_command(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) bulk_ctxt->bulk_out_length = USB_BULK_CB_WRAP_LEN; - /* Queue a request to read a Bulk-only CBW */ - _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_CMD); + // Queue a request to read a Bulk-only CBW. + if (!ums->cbw_req_queued) + _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_CMD); + else + _ums_transfer_finish(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_CMD); + + /* + * On XUSB do not allow multiple requests for CBW to be done. + * This avoids an issue with some XHCI controllers and OS combos (e.g. ASMedia and Linux/Mac OS) + * which confuse that and concatenate an old CBW request with another write request (SCSI Write) + * and create a babble error (transmit overflow). + */ + if (ums->xusb) + ums->cbw_req_queued = true; /* We will drain the buffer in software, which means we * can reuse it for the next filling. No need to advance @@ -1696,7 +1720,7 @@ static void send_status(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) SK(sd), ASC(sd), ASCQ(sd), ums->lun.sense_data_info); } - /* Store and send the Bulk-only CSW */ + // Store and send the Bulk-only CSW. bulk_send_pkt_t *csw = (bulk_send_pkt_t *)bulk_ctxt->bulk_in_buf; csw->Signature = USB_BULK_CS_SIG; @@ -1712,7 +1736,7 @@ static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) { enum ums_state old_state; - /* Clear out the controller's fifos */ + // Clear out the controller's fifos. ums_flush_endpoint(bulk_ctxt->bulk_in); ums_flush_endpoint(bulk_ctxt->bulk_out); @@ -1735,7 +1759,7 @@ static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) ums->state = UMS_STATE_NORMAL; - /* Carry out any extra actions required for the exception */ + // Carry out any extra actions required for the exception. switch (old_state) { case UMS_STATE_NORMAL: @@ -1757,7 +1781,7 @@ static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) break; case UMS_STATE_EXIT: - ums->state = UMS_STATE_TERMINATED; /* Stop the thread */ + ums->state = UMS_STATE_TERMINATED; // Stop the thread. break; default: diff --git a/bdk/usb/usb_t210.h b/bdk/usb/usb_t210.h index e677a5f..3485a58 100644 --- a/bdk/usb/usb_t210.h +++ b/bdk/usb/usb_t210.h @@ -1,7 +1,7 @@ /* * Enhanced & eXtensible USB device (EDCI & XDCI) driver for Tegra X1 * - * Copyright (c) 2019-2020 CTCaer + * Copyright (c) 2019-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -200,6 +200,8 @@ typedef struct _t210_usb2d_t #define XHCI_ST_IP BIT(4) #define XUSB_DEV_XHCI_RT_IMOD 0x38 #define XUSB_DEV_XHCI_PORTSC 0x3C +#define XHCI_PORTSC_CCS BIT(0) +#define XHCI_PORTSC_PED BIT(1) #define XHCI_PORTSC_PR BIT(4) #define XHCI_PORTSC_PLS_MASK (0xF << 5) #define XHCI_PORTSC_PLS_U0 (0 << 5) @@ -226,11 +228,12 @@ typedef struct _t210_usb2d_t #define XUSB_DEV_XHCI_ECPLO 0x40 #define XUSB_DEV_XHCI_ECPHI 0x44 #define XUSB_DEV_XHCI_EP_HALT 0x50 -#define XHCI_EP_HALT_DCI BIT(0) +#define XHCI_EP_HALT_DCI_EP0_IN BIT(0) #define XUSB_DEV_XHCI_EP_PAUSE 0x54 #define XUSB_DEV_XHCI_EP_RELOAD 0x58 #define XUSB_DEV_XHCI_EP_STCHG 0x5C #define XUSB_DEV_XHCI_PORTHALT 0x6C +#define XUSB_DEV_XHCI_EP_STOPPED 0x78 #define XHCI_PORTHALT_HALT_LTSSM BIT(0) #define XHCI_PORTHALT_STCHG_REQ BIT(20) #define XUSB_DEV_XHCI_CFG_DEV_FE 0x85C diff --git a/bdk/usb/usbd.c b/bdk/usb/usbd.c index 95d1ed5..81d719a 100644 --- a/bdk/usb/usbd.c +++ b/bdk/usb/usbd.c @@ -1,7 +1,7 @@ /* * Enhanced USB Device (EDCI) driver for Tegra X1 * - * Copyright (c) 2019-2020 CTCaer + * Copyright (c) 2019-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -1455,7 +1455,7 @@ static int _usbd_get_ep1_out_bytes_read() return (usbdaemon->ep_bytes_requested[USB_EP_BULK_OUT] - (usbdaemon->qhs[USB_EP_BULK_OUT].token >> 16)); } -int usb_device_ep1_out_reading_finish(u32 *pending_bytes) +int usb_device_ep1_out_reading_finish(u32 *pending_bytes, u32 sync_timeout) { usb_ep_status_t ep_status; do @@ -1504,7 +1504,7 @@ static int _usbd_get_ep1_in_bytes_written() return (usbdaemon->ep_bytes_requested[USB_EP_BULK_IN] - (usbdaemon->qhs[USB_EP_BULK_IN].token >> 16)); } -int usb_device_ep1_in_writing_finish(u32 *pending_bytes) +int usb_device_ep1_in_writing_finish(u32 *pending_bytes, u32 sync_timeout) { usb_ep_status_t ep_status; do diff --git a/bdk/usb/usbd.h b/bdk/usb/usbd.h index a0e4a63..86aa8fa 100644 --- a/bdk/usb/usbd.h +++ b/bdk/usb/usbd.h @@ -1,7 +1,7 @@ /* * Enhanced & eXtensible USB Device (EDCI & XDCI) driver for Tegra X1 * - * Copyright (c) 2019 CTCaer + * Copyright (c) 2019-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -148,6 +148,7 @@ typedef enum _usb_error_t XUSB_ERROR_INVALID_EP = USB_ERROR_XFER_ERROR, // From 2. XUSB_ERROR_XFER_BULK_IN_RESIDUE = 7, XUSB_ERROR_INVALID_CYCLE = USB2_ERROR_XFER_EP_DISABLED, // From 8. + XUSB_ERROR_BABBLE_DETECTED = 50, XUSB_ERROR_SEQ_NUM = 51, XUSB_ERROR_XFER_DIR = 52, XUSB_ERROR_PORT_CFG = 54 @@ -175,9 +176,9 @@ typedef struct _usb_ops_t int (*usb_device_ep1_out_read)(u8 *, u32, u32 *, u32); int (*usb_device_ep1_out_read_big)(u8 *, u32, u32 *); - int (*usb_device_ep1_out_reading_finish)(u32 *); + int (*usb_device_ep1_out_reading_finish)(u32 *, u32); int (*usb_device_ep1_in_write)(u8 *, u32, u32 *, u32); - int (*usb_device_ep1_in_writing_finish)(u32 *); + int (*usb_device_ep1_in_writing_finish)(u32 *, u32); bool (*usb_device_get_suspended)(); bool (*usb_device_get_port_in_sleep)(); } usb_ops_t; diff --git a/bdk/usb/xusbd.c b/bdk/usb/xusbd.c index 4beefcd..0f68ec7 100644 --- a/bdk/usb/xusbd.c +++ b/bdk/usb/xusbd.c @@ -1,7 +1,7 @@ /* * eXtensible USB Device driver (XDCI) for Tegra X1 * - * Copyright (c) 2020 CTCaer + * Copyright (c) 2020-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -368,7 +368,7 @@ typedef struct _xusbd_controller_t event_trb_t *event_dequeue_ptr; u32 event_ccs; u32 device_state; - u32 bytes_remaining[2]; + u32 tx_bytes[2]; u32 tx_count[2]; u32 ctrl_seq_num; u32 config_num; @@ -881,7 +881,7 @@ int xusb_device_init() _xusbd_init_device_clocks(); // Enable AHB redirect for access to IRAM for Event/EP ring buffers. - mc_enable_ahb_redirect(); // Can be skipped if IRAM is not used. + mc_enable_ahb_redirect(false); // Can be skipped if IRAM is not used. // Enable XUSB device IPFS. XUSB_DEV_DEV(XUSB_DEV_CONFIGURATION) |= DEV_CONFIGURATION_EN_FPCI; @@ -927,7 +927,7 @@ int xusb_device_init() return USB_RES_OK; } -static int _xusb_queue_trb(int ep_idx, void *trb, bool ring_doorbell) +static int _xusb_queue_trb(u32 ep_idx, void *trb, bool ring_doorbell) { int res = USB_RES_OK; data_trb_t *next_trb; @@ -1073,7 +1073,7 @@ static int _xusb_issue_normal_trb(u8 *buf, u32 len, usb_dir_t direction) normal_trb_t trb = {0}; _xusb_create_normal_trb(&trb, buf, len, direction); - int ep_idx = USB_EP_BULK_IN; + u32 ep_idx = USB_EP_BULK_IN; if (direction == USB_DIR_OUT) ep_idx = USB_EP_BULK_OUT; int res = _xusb_queue_trb(ep_idx, &trb, EP_RING_DOORBELL); @@ -1100,19 +1100,32 @@ static int _xusb_issue_data_trb(u8 *buf, u32 len, usb_dir_t direction) int xusb_set_ep_stall(u32 endpoint, int ep_stall) { - int ep_idx = BIT(endpoint); + u32 ep_mask = BIT(endpoint); if (ep_stall) - XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) |= ep_idx; + XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) |= ep_mask; else - XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) &= ~ep_idx; + XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) &= ~ep_mask; // Wait for EP status to change. - int res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_EP_STCHG, ep_idx, ep_idx, 1000); + int res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_EP_STCHG, ep_mask, ep_mask, 1000); if (res) return res; // Clear status change. - XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_STCHG) = ep_idx; + XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_STCHG) = ep_mask; + + return USB_RES_OK; +} + +static int _xusb_wait_ep_stopped(u32 endpoint) +{ + u32 ep_mask = BIT(endpoint); + + // Wait for EP status to change. + _xusb_xhci_mask_wait(XUSB_DEV_XHCI_EP_STOPPED, ep_mask, ep_mask, 1000); + + // Clear status change. + XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_STOPPED) = ep_mask; return USB_RES_OK; } @@ -1158,20 +1171,27 @@ static int _xusb_handle_transfer_event(transfer_event_trb_t *trb) return _xusb_issue_status_trb(USB_DIR_OUT); else if (usbd_xotg->wait_for_event_trb == XUSB_TRB_STATUS) { - if (usbd_xotg->device_state == XUSB_ADDRESSED_STS_WAIT) + switch (usbd_xotg->device_state) + { + case XUSB_ADDRESSED_STS_WAIT: usbd_xotg->device_state = XUSB_ADDRESSED; - else if (usbd_xotg->device_state == XUSB_CONFIGURED_STS_WAIT) + break; + case XUSB_CONFIGURED_STS_WAIT: usbd_xotg->device_state = XUSB_CONFIGURED; - else if (usbd_xotg->device_state == XUSB_LUN_CONFIGURED_STS_WAIT) + break; + case XUSB_LUN_CONFIGURED_STS_WAIT: usbd_xotg->device_state = XUSB_LUN_CONFIGURED; - else if (usbd_xotg->device_state == XUSB_HID_CONFIGURED_STS_WAIT) + break; + case XUSB_HID_CONFIGURED_STS_WAIT: usbd_xotg->device_state = XUSB_HID_CONFIGURED; + break; + } } break; case USB_EP_BULK_IN: - usbd_xotg->bytes_remaining[USB_DIR_IN] -= trb->trb_tx_len; - if (usbd_xotg->tx_count[USB_DIR_IN])/////////// + usbd_xotg->tx_bytes[USB_DIR_IN] -= trb->trb_tx_len; + if (usbd_xotg->tx_count[USB_DIR_IN]) usbd_xotg->tx_count[USB_DIR_IN]--; // If bytes remaining for a Bulk IN transfer, return error. @@ -1181,8 +1201,8 @@ static int _xusb_handle_transfer_event(transfer_event_trb_t *trb) case USB_EP_BULK_OUT: // If short packet and Bulk OUT, it's not an error because we prime EP for 4KB. - usbd_xotg->bytes_remaining[USB_DIR_OUT] -= trb->trb_tx_len; - if (usbd_xotg->tx_count[USB_DIR_OUT])/////////// + usbd_xotg->tx_bytes[USB_DIR_OUT] -= trb->trb_tx_len; + if (usbd_xotg->tx_count[USB_DIR_OUT]) usbd_xotg->tx_count[USB_DIR_OUT]--; break; } @@ -1196,6 +1216,11 @@ static int _xusb_handle_transfer_event(transfer_event_trb_t *trb) xusb_set_ep_stall(trb->ep_id, USB_EP_CFG_STALL); return USB_RES_OK; */ + case XUSB_COMP_BABBLE_DETECTED_ERROR: + _xusb_wait_ep_stopped(trb->ep_id); + xusb_set_ep_stall(trb->ep_id, USB_EP_CFG_STALL); + return XUSB_ERROR_BABBLE_DETECTED; + case XUSB_COMP_CTRL_DIR_ERROR: return XUSB_ERROR_XFER_DIR; @@ -1216,11 +1241,52 @@ static int _xusb_handle_transfer_event(transfer_event_trb_t *trb) static int _xusb_handle_port_change() { - u32 res = USB_RES_OK; u32 status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC); u32 halt = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT); + u32 clear_mask = XHCI_PORTSC_CEC | XHCI_PORTSC_PLC | XHCI_PORTSC_PRC | XHCI_PORTSC_WRC | XHCI_PORTSC_CSC; - // Connect status change (CSC). + // Port reset (PR). + if (status & XHCI_PORTSC_PR) + { + //! TODO: + // XHCI_PORTSC_PR: device_state = XUSB_RESET + + //_disable_usb_wdt4(); + } + + // Port Reset Change (PRC). + if (status & XHCI_PORTSC_PRC) + { + // Clear PRC bit. + status &= ~clear_mask; + status |= XHCI_PORTSC_PRC; + XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) = status; + } + + // Warm Port Reset (WPR). + if (status & XHCI_PORTSC_WPR) + { + //_disable_usb_wdt4(); + + XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT) &= ~XHCI_PORTHALT_HALT_LTSSM; + (void)XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT); + + //! TODO: XHCI_PORTSC_WPR: device_state = XUSB_RESET + } + + // Warm Port Reset Change (WRC). + if (status & XHCI_PORTSC_WRC) + { + // Clear WRC bit. + status &= ~clear_mask; + status |= XHCI_PORTSC_WRC; + XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) = status; + } + + // Reread port status to handle more changes. + status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC); + + // Connect Status Change (CSC). if (status & XHCI_PORTSC_CSC) { //! TODO: Check CCS. @@ -1238,90 +1304,64 @@ static int _xusb_handle_port_change() volatile xusb_ep_ctx_t *ep_ctxt = &xusb_evtq->xusb_ep_ctxt[XUSB_EP_CTRL_IN]; ep_ctxt->avg_trb_len = 8; ep_ctxt->max_packet_size = 64; + //! TODO: If super speed is supported, ep context reload, unpause and unhalt must happen. } // Clear CSC bit. + status &= ~clear_mask; status |= XHCI_PORTSC_CSC; XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) = status; } - // Port reset (PR), Port reset change (PRC). - if (status & XHCI_PORTSC_PR || status & XHCI_PORTSC_PRC) - { - //! TODO: - // XHCI_PORTSC_PR: device_state = XUSB_RESET - - //_disable_usb_wdt4(); - - //res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_PORTSC, XHCI_PORTSC_PRC, XHCI_PORTSC_PRC, 50000); // unpatched0 - // if (res) return res; - _xusb_xhci_mask_wait(XUSB_DEV_XHCI_PORTSC, XHCI_PORTSC_PRC, XHCI_PORTSC_PRC, 50000); // patched0 - - // Clear PRC bit. - status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) | XHCI_PORTSC_PRC; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) |= XHCI_PORTSC_PRC; - } - - // Warm Port Reset (WPR), Warm Port Reset Change (WRC). - if (status & XHCI_PORTSC_WPR || status & XHCI_PORTSC_WRC) - { - XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT) &= ~XHCI_PORTHALT_HALT_LTSSM; - (void)XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC); - res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_PORTSC, XHCI_PORTSC_WRC, XHCI_PORTSC_WRC, 1000); - - // Clear WRC bit. - status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) | XHCI_PORTSC_WRC; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) |= XHCI_PORTSC_WRC; - - //! TODO: WPR: device_state = XUSB_RESET - } - // Handle Config Request (STCHG_REQ). if (halt & XHCI_PORTHALT_STCHG_REQ) { - // Clear Link Training Status. - status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT) & ~XHCI_PORTHALT_HALT_LTSSM; + // Clear Link Training Status and pending request/reject. XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT) &= ~XHCI_PORTHALT_HALT_LTSSM; + (void)XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT); } + // Reread port status to handle more changes. + status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC); + // Port link state change (PLC). if (status & XHCI_PORTSC_PLC) { - //! WAR: Sometimes port speed changes without a CSC event. Set again. - usbd_xotg->port_speed = (status & XHCI_PORTSC_PS) >> 10; - - // check PLS - // if U3 + // check XHCI_PORTSC_PLS_MASK + // if XHCI_PORTSC_PLS_U3 // device_state = XUSB_SUSPENDED - // else if U0 and XUSB_SUSPENDED + // else if XHCI_PORTSC_PLS_U0 and XUSB_SUSPENDED // val = XUSB_DEV_XHCI_EP_PAUSE // XUSB_DEV_XHCI_EP_PAUSE = 0 // XUSB_DEV_XHCI_EP_STCHG = val; // Clear PLC bit. - status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) | XHCI_PORTSC_PLC; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) |= XHCI_PORTSC_PLC; + status &= ~clear_mask; + status |= XHCI_PORTSC_PLC; + XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) = status; } // Port configuration link error (CEC). if (status & XHCI_PORTSC_CEC) { - XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) |= XHCI_PORTSC_CEC; - res = XUSB_ERROR_PORT_CFG; + status = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC); + status &= ~clear_mask; + status |= XHCI_PORTSC_CEC; + XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) = status; + + return XUSB_ERROR_PORT_CFG; } - return res; + return USB_RES_OK; } -static int _xusb_handle_get_ep_status(usb_ctrl_setup_t *ctrl_setup) +static int _xusb_handle_get_ep_status(u32 ep_idx) { + u32 ep_mask = BIT(ep_idx); static u8 xusb_ep_status_descriptor[2] = {0}; - // Get EP context pointer. - volatile xusb_ep_ctx_t *ep_ctxt = (volatile xusb_ep_ctx_t *)(XUSB_DEV_XHCI(XUSB_DEV_XHCI_ECPLO) & 0xFFFFFFF0); - ep_ctxt = &ep_ctxt[ctrl_setup->wIndex]; - - xusb_ep_status_descriptor[0] = (ep_ctxt->ep_state == EP_HALTED) ? USB_STATUS_EP_HALTED : USB_STATUS_EP_OK; + xusb_ep_status_descriptor[0] = + (XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) & ep_mask) ? USB_STATUS_EP_HALTED : USB_STATUS_EP_OK; return _xusb_issue_data_trb(xusb_ep_status_descriptor, 2, USB_DIR_IN); } @@ -1536,8 +1576,9 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup) //gfx_printf("ctrl: %02X %02X %04X %04X %04X\n", _bmRequestType, _bRequest, _wValue, _wIndex, _wLength); - XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) &= ~XHCI_EP_HALT_DCI; - u32 res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_EP_HALT, XHCI_EP_HALT_DCI, 0, 1000); + // Unhalt EP0 IN. + XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) &= ~XHCI_EP_HALT_DCI_EP0_IN; + u32 res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_EP_HALT, XHCI_EP_HALT_DCI_EP0_IN, 0, 1000); if (res) return res; @@ -1557,14 +1598,33 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup) case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): if ((_wValue & 0xFF) == USB_FEATURE_ENDPOINT_HALT) { - if (_bRequest == USB_REQUEST_CLEAR_FEATURE) + if (_bRequest == USB_REQUEST_CLEAR_FEATURE || _bRequest == USB_REQUEST_SET_FEATURE) { - xusb_set_ep_stall(_wIndex, USB_EP_CFG_CLEAR); - return _xusb_issue_status_trb(USB_DIR_IN); - } - else if (_bRequest == USB_REQUEST_SET_FEATURE) - { - xusb_set_ep_stall(_wIndex, USB_EP_CFG_STALL); + u32 ep = 0; + switch (_wIndex) // endpoint + { + case USB_EP_ADDR_CTRL_OUT: + ep = XUSB_EP_CTRL_OUT; + break; + case USB_EP_ADDR_CTRL_IN: + ep = XUSB_EP_CTRL_IN; + break; + case USB_EP_ADDR_BULK_OUT: + ep = USB_EP_BULK_OUT; + break; + case USB_EP_ADDR_BULK_IN: + ep = USB_EP_BULK_IN; + break; + default: + xusb_set_ep_stall(XUSB_EP_CTRL_IN, USB_EP_CFG_STALL); + return USB_RES_OK; + } + + if (_bRequest == USB_REQUEST_CLEAR_FEATURE) + xusb_set_ep_stall(ep, USB_EP_CFG_CLEAR); + else if (_bRequest == USB_REQUEST_SET_FEATURE) + xusb_set_ep_stall(ep, USB_EP_CFG_STALL); + return _xusb_issue_status_trb(USB_DIR_IN); } } @@ -1631,7 +1691,28 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup) case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): if (_bRequest == USB_REQUEST_GET_STATUS) - return _xusb_handle_get_ep_status(ctrl_setup); + { + u32 ep = 0; + switch (_wIndex) // endpoint + { + case USB_EP_ADDR_CTRL_OUT: + ep = XUSB_EP_CTRL_OUT; + break; + case USB_EP_ADDR_CTRL_IN: + ep = XUSB_EP_CTRL_IN; + break; + case USB_EP_ADDR_BULK_OUT: + ep = USB_EP_BULK_OUT; + break; + case USB_EP_ADDR_BULK_IN: + ep = USB_EP_BULK_IN; + break; + default: + xusb_set_ep_stall(XUSB_EP_CTRL_IN, USB_EP_CFG_STALL); + return USB_RES_OK; + } + return _xusb_handle_get_ep_status(ep); + } ep_stall = true; break; @@ -1821,6 +1902,7 @@ int xusb_device_enumerate(usb_gadget_type gadget) return USB_RES_OK; } +//! TODO: Do a full deinit. void xusb_end(bool reset_ep, bool only_controller) { CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB_SS); @@ -1855,7 +1937,7 @@ int xusb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, u32 sync_tries) int res = USB_RES_OK; usbd_xotg->tx_count[USB_DIR_OUT] = 0; - usbd_xotg->bytes_remaining[USB_DIR_OUT] = len; + usbd_xotg->tx_bytes[USB_DIR_OUT] = len; _xusb_issue_normal_trb(buf, len, USB_DIR_OUT); usbd_xotg->tx_count[USB_DIR_OUT]++; @@ -1865,7 +1947,7 @@ int xusb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, u32 sync_tries) res = _xusb_ep_operation(sync_tries); if (bytes_read) - *bytes_read = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_OUT]; + *bytes_read = res ? 0 : usbd_xotg->tx_bytes[USB_DIR_OUT]; bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); } @@ -1898,14 +1980,14 @@ int xusb_device_ep1_out_read_big(u8 *buf, u32 len, u32 *bytes_read) return USB_RES_OK; } -int xusb_device_ep1_out_reading_finish(u32 *pending_bytes) +int xusb_device_ep1_out_reading_finish(u32 *pending_bytes, u32 sync_tries) { int res = USB_RES_OK; while (!res && usbd_xotg->tx_count[USB_DIR_OUT]) - res = _xusb_ep_operation(USB_XFER_SYNCED); // Infinite retries. + res = _xusb_ep_operation(sync_tries); // Infinite retries. if (pending_bytes) - *pending_bytes = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_OUT]; + *pending_bytes = res ? 0 : usbd_xotg->tx_bytes[USB_DIR_OUT]; bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); @@ -1921,7 +2003,7 @@ int xusb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, u32 sync_trie int res = USB_RES_OK; usbd_xotg->tx_count[USB_DIR_IN] = 0; - usbd_xotg->bytes_remaining[USB_DIR_IN] = len; + usbd_xotg->tx_bytes[USB_DIR_IN] = len; _xusb_issue_normal_trb(buf, len, USB_DIR_IN); usbd_xotg->tx_count[USB_DIR_IN]++; @@ -1931,7 +2013,7 @@ int xusb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, u32 sync_trie res = _xusb_ep_operation(sync_tries); if (bytes_written) - *bytes_written = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_IN]; + *bytes_written = res ? 0 : usbd_xotg->tx_bytes[USB_DIR_IN]; } else { @@ -1947,14 +2029,14 @@ int xusb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, u32 sync_trie return res; } -int xusb_device_ep1_in_writing_finish(u32 *pending_bytes) +int xusb_device_ep1_in_writing_finish(u32 *pending_bytes, u32 sync_tries) { int res = USB_RES_OK; while (!res && usbd_xotg->tx_count[USB_DIR_IN]) - res = _xusb_ep_operation(USB_XFER_SYNCED); // Infinite retries. + res = _xusb_ep_operation(sync_tries); // Infinite retries. if (pending_bytes) - *pending_bytes = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_IN]; + *pending_bytes = res ? 0 : usbd_xotg->tx_bytes[USB_DIR_IN]; return res; } @@ -2010,7 +2092,7 @@ void xusb_device_get_ops(usb_ops_t *ops) ops->usbd_flush_endpoint = NULL; ops->usbd_set_ep_stall = xusb_set_ep_stall; ops->usbd_handle_ep0_ctrl_setup = xusb_handle_ep0_ctrl_setup; - ops->usbd_end = xusb_end;////////////////// + ops->usbd_end = xusb_end; ops->usb_device_init = xusb_device_init; ops->usb_device_enumerate = xusb_device_enumerate; ops->usb_device_class_send_max_lun = xusb_device_class_send_max_lun; diff --git a/bdk/utils/types.h b/bdk/utils/types.h index 57fb509..9e6f70e 100644 --- a/bdk/utils/types.h +++ b/bdk/utils/types.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 naehrwert +* Copyright (c) 2018-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/bdk/utils/util.c b/bdk/utils/util.c index f267236..2c21b28 100644 --- a/bdk/utils/util.c +++ b/bdk/utils/util.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert -* Copyright (c) 2018-2020 CTCaer +* Copyright (c) 2018-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -30,6 +30,27 @@ extern volatile nyx_storage_t *nyx_str; +u8 bit_count(u32 val) +{ + u8 cnt = 0; + for (u32 i = 0; i < 32; i++) + { + if ((val >> i) & 1) + cnt++; + } + + return cnt; +} + +u32 bit_count_mask(u8 bits) +{ + u32 val = 0; + for (u32 i = 0; i < bits; i++) + val |= 1 << i; + + return val; +} + u32 get_tmr_s() { return RTC(APBDEV_RTC_SECONDS); diff --git a/bdk/utils/util.h b/bdk/utils/util.h index 3503e1e..213d9cf 100644 --- a/bdk/utils/util.h +++ b/bdk/utils/util.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018 CTCaer + * Copyright (c) 2018-2021 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -81,6 +81,9 @@ typedef struct _nyx_storage_t emc_table_t mtc_table[10]; } nyx_storage_t; +u8 bit_count(u32 val); +u32 bit_count_mask(u8 bits); + void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops); u32 crc32_calc(u32 crc, const u8 *buf, u32 len); diff --git a/source/config.c b/source/config.c index 526eb55..f8ce2d9 100644 --- a/source/config.c +++ b/source/config.c @@ -38,19 +38,14 @@ void set_default_configuration() h_cfg.autoboot = 0; h_cfg.autoboot_list = 0; h_cfg.bootwait = 3; - h_cfg.se_keygen_done = 0; h_cfg.backlight = 100; h_cfg.autohosoff = 0; h_cfg.autonogc = 1; h_cfg.updater2p = 0; h_cfg.bootprotect = 0; h_cfg.errors = 0; - h_cfg.eks = NULL; h_cfg.aes_slots_new = false; h_cfg.rcm_patched = fuse_check_patched_rcm(); - h_cfg.sbk_set = FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF; h_cfg.emummc_force_disable = false; h_cfg.t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01; - - sd_power_cycle_time_start = 0; } diff --git a/source/config.h b/source/config.h index bfb0b3b..03fd69b 100644 --- a/source/config.h +++ b/source/config.h @@ -17,7 +17,6 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ -#include "hos/hos.h" #include typedef struct _hekate_config @@ -33,13 +32,10 @@ typedef struct _hekate_config u32 bootprotect; // Global temporary config. bool t210b01; - bool se_keygen_done; bool aes_slots_new; bool emummc_force_disable; bool rcm_patched; - bool sbk_set; u32 errors; - hos_eks_mbr_t *eks; } hekate_config; void set_default_configuration(); diff --git a/source/hos/hos.h b/source/hos/hos.h index 94136fa..984ae3b 100644 --- a/source/hos/hos.h +++ b/source/hos/hos.h @@ -18,122 +18,18 @@ #ifndef _HOS_H_ #define _HOS_H_ -#include "pkg1.h" -#include "pkg2.h" -#include -#include -#include -#include - -#include - -#define KB_FIRMWARE_VERSION_100_200 0 -#define KB_FIRMWARE_VERSION_300 1 -#define KB_FIRMWARE_VERSION_301 2 -#define KB_FIRMWARE_VERSION_400 3 -#define KB_FIRMWARE_VERSION_500 4 -#define KB_FIRMWARE_VERSION_600 5 -#define KB_FIRMWARE_VERSION_620 6 -#define KB_FIRMWARE_VERSION_700 7 -#define KB_FIRMWARE_VERSION_810 8 -#define KB_FIRMWARE_VERSION_900 9 -#define KB_FIRMWARE_VERSION_910 10 +#define KB_FIRMWARE_VERSION_100 0 +#define KB_FIRMWARE_VERSION_300 1 +#define KB_FIRMWARE_VERSION_301 2 +#define KB_FIRMWARE_VERSION_400 3 +#define KB_FIRMWARE_VERSION_500 4 +#define KB_FIRMWARE_VERSION_600 5 +#define KB_FIRMWARE_VERSION_620 6 +#define KB_FIRMWARE_VERSION_700 7 +#define KB_FIRMWARE_VERSION_810 8 +#define KB_FIRMWARE_VERSION_900 9 +#define KB_FIRMWARE_VERSION_910 10 #define KB_FIRMWARE_VERSION_1210 11 -#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_1210 - -#define HOS_PKG11_MAGIC 0x31314B50 -#define HOS_EKS_MAGIC 0x30534B45 - -// Use official Mariko secmon when in stock. -//#define HOS_MARIKO_STOCK_SECMON - -typedef struct _exo_ctxt_t -{ - bool fs_is_510; - bool no_user_exceptions; - bool user_pmu; - bool *usb3_force; - bool *cal0_blank; - bool *cal0_allow_writes_sys; -} exo_ctxt_t; - -typedef struct _hos_eks_keys_t -{ - u8 mkk[SE_KEY_128_SIZE]; - u8 fdk[SE_KEY_128_SIZE]; -} hos_eks_keys_t; - -typedef struct _hos_eks_bis_keys_t -{ - u8 crypt[SE_KEY_128_SIZE]; - u8 tweak[SE_KEY_128_SIZE]; -} hos_eks_bis_keys_t; - -typedef struct _hos_eks_mbr_t -{ - u32 magic; - u8 enabled[5]; - u8 enabled_bis; - u8 rsvd[2]; - u32 lot0; - u8 dkg[SE_KEY_128_SIZE]; - u8 dkk[SE_KEY_128_SIZE]; - hos_eks_keys_t keys[5]; - hos_eks_bis_keys_t bis_keys[3]; -} hos_eks_mbr_t; - -static_assert(sizeof(hos_eks_mbr_t) == 304, "HOS EKS size is wrong!"); - -typedef struct _launch_ctxt_t -{ - void *keyblob; - - void *pkg1; - const pkg1_id_t *pkg1_id; - const pkg2_kernel_id_t *pkg2_kernel_id; - - void *warmboot; - u32 warmboot_size; - void *secmon; - u32 secmon_size; - void *exofatal; - u32 exofatal_size; - - void *pkg2; - u32 pkg2_size; - bool new_pkg2; - - void *kernel; - u32 kernel_size; - - link_t kip1_list; - char* kip1_patches; - - bool svcperm; - bool debugmode; - bool stock; - bool emummc_forced; - - char *fss0_main_path; - u32 fss0_hosver; - bool fss0_experimental; - bool atmosphere; - - exo_ctxt_t exo_ctx; - - ini_sec_t *cfg; -} launch_ctxt_t; - -typedef struct _merge_kip_t -{ - void *kip1; - link_t link; -} merge_kip_t; - -void hos_eks_get(); -void hos_eks_save(u32 kb); -void hos_eks_clear(u32 kb); -int hos_launch(ini_sec_t *cfg); -int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt); +#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_1210 //!TODO: Update on mkey changes. #endif diff --git a/source/hos/pkg2.c b/source/hos/pkg2.c deleted file mode 100644 index b80c06d..0000000 --- a/source/hos/pkg2.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer - * Copyright (c) 2018 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#include "pkg2.h" -#include -#include -#include -#include - -#include - -u32 pkg2_newkern_ini1_val; -u32 pkg2_newkern_ini1_start; -u32 pkg2_newkern_ini1_end; - -/*#include "util.h" -#define DPRINTF(...) gfx_printf(__VA_ARGS__) -#define DEBUG_PRINTING*/ -#define DPRINTF(...) - -static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1) -{ - u32 size = sizeof(pkg2_kip1_t); - for (u32 j = 0; j < KIP1_NUM_SECTIONS; j++) - size += kip1->sections[j].size_comp; - return size; -} - -void pkg2_get_newkern_info(u8 *kern_data) -{ - u32 pkg2_newkern_ini1_off = 0; - pkg2_newkern_ini1_start = 0; - - // Find static OP offset that is close to INI1 offset. - u32 counter_ops = 0x100; - while (counter_ops) - { - if (*(u32 *)(kern_data + 0x100 - counter_ops) == PKG2_NEWKERN_GET_INI1_HEURISTIC) - { - pkg2_newkern_ini1_off = 0x100 - counter_ops + 12; // OP found. Add 12 for the INI1 offset. - break; - } - - counter_ops -= 4; - } - - // Offset not found? - if (!counter_ops) - return; - - u32 info_op = *(u32 *)(kern_data + pkg2_newkern_ini1_off); - pkg2_newkern_ini1_val = ((info_op & 0xFFFF) >> 3) + pkg2_newkern_ini1_off; // Parse ADR and PC. - - pkg2_newkern_ini1_start = *(u32 *)(kern_data + pkg2_newkern_ini1_val); - pkg2_newkern_ini1_end = *(u32 *)(kern_data + pkg2_newkern_ini1_val + 0x8); - } - -bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2) -{ - u8 *ptr; - // Check for new pkg2 type. - if (!pkg2->sec_size[PKG2_SEC_INI1]) - { - pkg2_get_newkern_info(pkg2->data); - - if (!pkg2_newkern_ini1_start) - return false; - - ptr = pkg2->data + pkg2_newkern_ini1_start; - *new_pkg2 = true; - } - else - ptr = pkg2->data + pkg2->sec_size[PKG2_SEC_KERNEL]; - - pkg2_ini1_t *ini1 = (pkg2_ini1_t *)ptr; - ptr += sizeof(pkg2_ini1_t); - - for (u32 i = 0; i < ini1->num_procs; i++) - { - pkg2_kip1_t *kip1 = (pkg2_kip1_t *)ptr; - pkg2_kip1_info_t *ki = (pkg2_kip1_info_t *)malloc(sizeof(pkg2_kip1_info_t)); - ki->kip1 = kip1; - ki->size = _pkg2_calc_kip1_size(kip1); - list_append(info, &ki->link); - ptr += ki->size; -DPRINTF(" kip1 %d:%s @ %08X (%08X)\n", i, kip1->name, (u32)kip1, ki->size); - } - - return true; -} - -int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp) -{ - u32 compClearMask = ~sectsToDecomp; - if ((ki->kip1->flags & compClearMask) == ki->kip1->flags) - return 0; // Already decompressed, nothing to do. - - pkg2_kip1_t hdr; - memcpy(&hdr, ki->kip1, sizeof(hdr)); - - unsigned int newKipSize = sizeof(hdr); - for (u32 sectIdx = 0; sectIdx < KIP1_NUM_SECTIONS; sectIdx++) - { - u32 sectCompBit = 1u << sectIdx; - // For compressed, cant get actual decompressed size without doing it, so use safe "output size". - if (sectIdx < 3 && (sectsToDecomp & sectCompBit) && (hdr.flags & sectCompBit)) - newKipSize += hdr.sections[sectIdx].size_decomp; - else - newKipSize += hdr.sections[sectIdx].size_comp; - } - - pkg2_kip1_t* newKip = malloc(newKipSize); - unsigned char* dstDataPtr = newKip->data; - const unsigned char* srcDataPtr = ki->kip1->data; - for (u32 sectIdx = 0; sectIdx < KIP1_NUM_SECTIONS; sectIdx++) - { - u32 sectCompBit = 1u << sectIdx; - // Easy copy path for uncompressed or ones we dont want to uncompress. - if (sectIdx >= 3 || !(sectsToDecomp & sectCompBit) || !(hdr.flags & sectCompBit)) - { - unsigned int dataSize = hdr.sections[sectIdx].size_comp; - if (dataSize == 0) - continue; - - memcpy(dstDataPtr, srcDataPtr, dataSize); - srcDataPtr += dataSize; - dstDataPtr += dataSize; - continue; - } - - unsigned int compSize = hdr.sections[sectIdx].size_comp; - unsigned int outputSize = hdr.sections[sectIdx].size_decomp; - //gfx_printf("Decomping %s KIP1 sect %d of size %d...\n", (const char*)hdr.name, sectIdx, compSize); - if (blz_uncompress_srcdest(srcDataPtr, compSize, dstDataPtr, outputSize) == 0) - { - gfx_printf("%kERROR decomping sect %d of %s KIP!%k\n", 0xFFFF0000, sectIdx, (char*)hdr.name, 0xFFCCCCCC); - free(newKip); - - return 1; - } - else - { - DPRINTF("Done! Decompressed size is %d!\n", outputSize); - } - hdr.sections[sectIdx].size_comp = outputSize; - srcDataPtr += compSize; - dstDataPtr += outputSize; - } - - hdr.flags &= compClearMask; - memcpy(newKip, &hdr, sizeof(hdr)); - newKipSize = dstDataPtr-(unsigned char*)(newKip); - - free(ki->kip1); - ki->kip1 = newKip; - ki->size = newKipSize; - - return 0; -} - -pkg2_hdr_t *pkg2_decrypt(void *data) -{ - u8 *pdata = (u8 *)data; - - // Skip signature. - pdata += 0x100; - - pkg2_hdr_t *hdr = (pkg2_hdr_t *)pdata; - - // Skip header. - pdata += sizeof(pkg2_hdr_t); - - // Decrypt header. - se_aes_crypt_ctr(8, hdr, sizeof(pkg2_hdr_t), hdr, sizeof(pkg2_hdr_t), hdr); - //gfx_hexdump((u32)hdr, hdr, 0x100); - - if (hdr->magic != PKG2_MAGIC) - return NULL; - - for (u32 i = 0; i < 4; i++) - { -DPRINTF("sec %d has size %08X\n", i, hdr->sec_size[i]); - if (!hdr->sec_size[i]) - continue; - - se_aes_crypt_ctr(8, pdata, hdr->sec_size[i], pdata, hdr->sec_size[i], &hdr->sec_ctr[i * 0x10]); - //gfx_hexdump((u32)pdata, pdata, 0x100); - - pdata += hdr->sec_size[i]; - } - - return hdr; -} diff --git a/source/hos/pkg2.h b/source/hos/pkg2.h deleted file mode 100644 index e416fba..0000000 --- a/source/hos/pkg2.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef _PKG2_H_ -#define _PKG2_H_ - -#include -#include - -#define PKG2_MAGIC 0x31324B50 -#define PKG2_SEC_BASE 0x80000000 -#define PKG2_SEC_KERNEL 0 -#define PKG2_SEC_INI1 1 - -#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015 // Offset of OP + 12 is the INI1 offset. - -extern u32 pkg2_newkern_ini1_val; -extern u32 pkg2_newkern_ini1_start; -extern u32 pkg2_newkern_ini1_end; - -typedef struct _kernel_patch_t -{ - u32 id; - u32 off; - u32 val; - u32 *ptr; -} kernel_patch_t; - -typedef struct _pkg2_hdr_t -{ - u8 ctr[0x10]; - u8 sec_ctr[0x40]; - u32 magic; - u32 base; - u32 pad0; - u8 pkg2_ver; - u8 bl_ver; - u16 pad1; - u32 sec_size[4]; - u32 sec_off[4]; - u8 sec_sha256[0x80]; - u8 data[]; -} pkg2_hdr_t; - -typedef struct _pkg2_ini1_t -{ - u32 magic; - u32 size; - u32 num_procs; - u32 pad; -} pkg2_ini1_t; - -typedef struct _pkg2_kip1_sec_t -{ - u32 offset; - u32 size_decomp; - u32 size_comp; - u32 attrib; -} pkg2_kip1_sec_t; - -#define KIP1_NUM_SECTIONS 6 - -typedef struct _pkg2_kip1_t -{ - u32 magic; - u8 name[12]; - u64 tid; - u32 proc_cat; - u8 main_thrd_prio; - u8 def_cpu_core; - u8 res; - u8 flags; - pkg2_kip1_sec_t sections[KIP1_NUM_SECTIONS]; - u32 caps[0x20]; - u8 data[]; -} pkg2_kip1_t; - -typedef struct _pkg2_kip1_info_t -{ - pkg2_kip1_t *kip1; - u32 size; - link_t link; -} pkg2_kip1_info_t; - -typedef struct _pkg2_kernel_id_t -{ - u8 hash[8]; - kernel_patch_t *kernel_patchset; -} pkg2_kernel_id_t; - -bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2); -int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp); -pkg2_hdr_t *pkg2_decrypt(void *data); - -#endif diff --git a/source/keys/keys.c b/source/keys/keys.c index 387ebfc..0103c26 100644 --- a/source/keys/keys.c +++ b/source/keys/keys.c @@ -23,7 +23,6 @@ #include #include "../gfx/tui.h" #include "../hos/pkg1.h" -#include "../hos/pkg2.h" #include #include #include @@ -79,21 +78,6 @@ static void _get_device_key(u32 ks, key_derivation_ctx_t *keys, void *out_device // titlekey functions static bool _test_key_pair(const void *E, const void *D, const void *N); -static ALWAYS_INLINE u8 *_find_tsec_fw(const u8 *pkg1) { - const u32 tsec_fw_align = 0x100; - const u32 tsec_fw_first_instruction = 0xCF42004D; - - for (const u32 *pos = (const u32 *)pkg1; (u8 *)pos < pkg1 + PKG1_MAX_SIZE; pos += tsec_fw_align / sizeof(u32)) - if (*pos == tsec_fw_first_instruction) - return (u8 *)pos; - - return NULL; -} - -static ALWAYS_INLINE u32 _get_tsec_fw_size(tsec_key_data_t *key_data) { - return key_data->blob0_size + sizeof(tsec_key_data_t) + key_data->blob1_size + key_data->blob2_size + key_data->blob3_size + key_data->blob4_size; -} - static u8 *_read_pkg1(const pkg1_id_t **pkg1_id) { if (emummc_storage_init_mmc()) { EPRINTF("Unable to init MMC."); @@ -125,17 +109,18 @@ static u8 *_read_pkg1(const pkg1_id_t **pkg1_id) { static void _derive_master_key_mariko(key_derivation_ctx_t *keys, bool is_dev) { // Relies on the SBK being properly set in slot 14 - se_aes_crypt_block_ecb(14, 0, keys->device_key_4x, device_master_key_source_kek_source); + se_aes_crypt_block_ecb(14, DECRYPT, keys->device_key_4x, device_master_key_source_kek_source); // Relies on the Mariko KEK being properly set in slot 12 se_aes_unwrap_key(8, 12, is_dev ? &mariko_master_kek_sources_dev[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_600] : &mariko_master_kek_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_600]); - se_aes_crypt_block_ecb(8, 0, keys->master_key[KB_FIRMWARE_VERSION_MAX], master_key_source); + se_aes_crypt_block_ecb(8, DECRYPT, keys->master_key[KB_FIRMWARE_VERSION_MAX], master_key_source); } static int _run_ams_keygen(key_derivation_ctx_t *keys) { tsec_ctxt_t tsec_ctxt; tsec_ctxt.fw = tsec_keygen; tsec_ctxt.size = sizeof(tsec_keygen); - int res = tsec_run_fw(&tsec_ctxt); + tsec_ctxt.type = TSEC_FW_TYPE_NEW; + int res = tsec_query(keys->temp_key, &tsec_ctxt); if (res) { EPRINTFARGS("ERROR %d running keygen.\n", res); @@ -149,19 +134,19 @@ static void _derive_master_keys_from_latest_key(key_derivation_ctx_t *keys, bool u32 tsec_root_key_slot = is_dev ? 11 : 13; // Derive all master keys based on current root key for (u32 i = KB_FIRMWARE_VERSION_810 - KB_FIRMWARE_VERSION_620; i < ARRAY_SIZE(master_kek_sources); i++) { - se_aes_crypt_block_ecb(tsec_root_key_slot, 0, keys->master_kek[i + KB_FIRMWARE_VERSION_620], master_kek_sources[i]); // mkek = unwrap(tsec_root, mkeks) + se_aes_crypt_block_ecb(tsec_root_key_slot, DECRYPT, keys->master_kek[i + KB_FIRMWARE_VERSION_620], master_kek_sources[i]); // mkek = unwrap(tsec_root, mkeks) se_aes_key_set(8, keys->master_kek[i + KB_FIRMWARE_VERSION_620], AES_128_KEY_SIZE); // mkey = unwrap(mkek, mkeys) - se_aes_crypt_block_ecb(8, 0, keys->master_key[i + KB_FIRMWARE_VERSION_620], master_key_source); + se_aes_crypt_block_ecb(8, DECRYPT, keys->master_key[i + KB_FIRMWARE_VERSION_620], master_key_source); } } // Derive all lower master keys for (u32 i = KB_FIRMWARE_VERSION_MAX; i > 0; i--) { se_aes_key_set(8, keys->master_key[i], AES_128_KEY_SIZE); - se_aes_crypt_block_ecb(8, 0, keys->master_key[i - 1], is_dev ? master_key_vectors_dev[i] : master_key_vectors[i]); + se_aes_crypt_block_ecb(8, DECRYPT, keys->master_key[i - 1], is_dev ? master_key_vectors_dev[i] : master_key_vectors[i]); } se_aes_key_set(8, keys->master_key[0], AES_128_KEY_SIZE); - se_aes_crypt_block_ecb(8, 0, keys->temp_key, is_dev ? master_key_vectors_dev[0] : master_key_vectors[0]); + se_aes_crypt_block_ecb(8, DECRYPT, keys->temp_key, is_dev ? master_key_vectors_dev[0] : master_key_vectors[0]); if (_key_exists(keys->temp_key)) { EPRINTFARGS("Unable to derive master keys for %s.", is_dev ? "dev" : "prod"); @@ -174,7 +159,7 @@ static void _derive_keyblob_keys(key_derivation_ctx_t *keys) { encrypted_keyblob_t *current_keyblob = (encrypted_keyblob_t *)keyblob_block; u32 keyblob_mac[AES_128_KEY_SIZE / 4] = {0}; - if (h_cfg.sbk_set) { + if (FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF) { u8 *aes_keys = (u8 *)calloc(0x1000, 1); se_get_aes_keys(aes_keys + 0x800, aes_keys, AES_128_KEY_SIZE); memcpy(keys->sbk, aes_keys + 14 * AES_128_KEY_SIZE, AES_128_KEY_SIZE); @@ -192,13 +177,13 @@ static void _derive_keyblob_keys(key_derivation_ctx_t *keys) { for (u32 i = 0; i <= KB_FIRMWARE_VERSION_600; i++, current_keyblob++) { minerva_periodic_training(); - se_aes_crypt_block_ecb(12, 0, keys->keyblob_key[i], keyblob_key_sources[i]); // temp = unwrap(kbks, tsec) - se_aes_crypt_block_ecb(14, 0, keys->keyblob_key[i], keys->keyblob_key[i]); // kbk = unwrap(temp, sbk) + se_aes_crypt_block_ecb(12, DECRYPT, keys->keyblob_key[i], keyblob_key_sources[i]); // temp = unwrap(kbks, tsec) + se_aes_crypt_block_ecb(14, DECRYPT, keys->keyblob_key[i], keys->keyblob_key[i]); // kbk = unwrap(temp, sbk) se_aes_key_set(7, keys->keyblob_key[i], sizeof(keys->keyblob_key[i])); - se_aes_crypt_block_ecb(7, 0, keys->keyblob_mac_key[i], keyblob_mac_key_source); // kbm = unwrap(kbms, kbk) + se_aes_crypt_block_ecb(7, DECRYPT, keys->keyblob_mac_key[i], keyblob_mac_key_source); // kbm = unwrap(kbms, kbk) if (i == 0) { - se_aes_crypt_block_ecb(7, 0, keys->device_key, per_console_key_source); // devkey = unwrap(pcks, kbk0) - se_aes_crypt_block_ecb(7, 0, keys->device_key_4x, device_master_key_source_kek_source); + se_aes_crypt_block_ecb(7, DECRYPT, keys->device_key, per_console_key_source); // devkey = unwrap(pcks, kbk0) + se_aes_crypt_block_ecb(7, DECRYPT, keys->device_key_4x, device_master_key_source_kek_source); } // verify keyblob is not corrupt @@ -217,7 +202,7 @@ static void _derive_keyblob_keys(key_derivation_ctx_t *keys) { memcpy(keys->master_kek[i], keys->keyblob[i].master_kek, sizeof(keys->master_kek[i])); se_aes_key_set(7, keys->master_kek[i], sizeof(keys->master_kek[i])); if (!_key_exists(keys->master_key[i])) { - se_aes_crypt_block_ecb(7, 0, keys->master_key[i], master_key_source); + se_aes_crypt_block_ecb(7, DECRYPT, keys->master_key[i], master_key_source); } } free(keyblob_block); @@ -238,15 +223,15 @@ static void _derive_bis_keys(key_derivation_ctx_t *keys) { _generate_specific_aes_key(8, keys, &keys->bis_key[0], &bis_key_sources[0], key_generation); // kek = generate_kek(bkeks, devkey, aeskek, aeskey) _generate_kek(8, bis_kek_source, keys->temp_key, aes_kek_generation_source, aes_key_generation_source); - se_aes_crypt_ecb(8, 0, keys->bis_key[1], AES_128_KEY_SIZE * 2, bis_key_sources[1], AES_128_KEY_SIZE * 2); // bkey = unwrap(bkeys, kek) - se_aes_crypt_ecb(8, 0, keys->bis_key[2], AES_128_KEY_SIZE * 2, bis_key_sources[2], AES_128_KEY_SIZE * 2); + se_aes_crypt_ecb(8, DECRYPT, keys->bis_key[1], AES_128_KEY_SIZE * 2, bis_key_sources[1], AES_128_KEY_SIZE * 2); // bkey = unwrap(bkeys, kek) + se_aes_crypt_ecb(8, DECRYPT, keys->bis_key[2], AES_128_KEY_SIZE * 2, bis_key_sources[2], AES_128_KEY_SIZE * 2); memcpy(keys->bis_key[3], keys->bis_key[2], 0x20); } static void _derive_non_unique_keys(key_derivation_ctx_t *keys, bool is_dev) { if (_key_exists(keys->master_key[0])) { _generate_kek(8, header_kek_source, keys->master_key[0], aes_kek_generation_source, aes_key_generation_source); - se_aes_crypt_ecb(8, 0, keys->header_key, AES_128_KEY_SIZE * 2, header_key_source, AES_128_KEY_SIZE * 2); + se_aes_crypt_ecb(8, DECRYPT, keys->header_key, AES_128_KEY_SIZE * 2, header_key_source, AES_128_KEY_SIZE * 2); } } @@ -254,19 +239,19 @@ static void _derive_misc_keys(key_derivation_ctx_t *keys, bool is_dev) { if (_key_exists(keys->device_key) || (_key_exists(keys->master_key[0]) && _key_exists(keys->device_key_4x))) { _get_device_key(8, keys, keys->temp_key, 0); _generate_kek(8, save_mac_kek_source, keys->temp_key, aes_kek_generation_source, NULL); - se_aes_crypt_block_ecb(8, 0, keys->save_mac_key, save_mac_key_source); + se_aes_crypt_block_ecb(8, DECRYPT, keys->save_mac_key, save_mac_key_source); } if (_key_exists(keys->master_key[0])) { for (u32 i = 0; i < AES_128_KEY_SIZE; i++) keys->temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_03[i]; _generate_kek(8, eticket_rsa_kekek_source, keys->master_key[0], keys->temp_key, NULL); - se_aes_crypt_block_ecb(8, 0, keys->eticket_rsa_kek, is_dev ? eticket_rsa_kek_source_dev : eticket_rsa_kek_source); + se_aes_crypt_block_ecb(8, DECRYPT, keys->eticket_rsa_kek, is_dev ? eticket_rsa_kek_source_dev : eticket_rsa_kek_source); for (u32 i = 0; i < AES_128_KEY_SIZE; i++) keys->temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_01[i]; _generate_kek(8, ssl_rsa_kek_source_x, keys->master_key[0], keys->temp_key, NULL); - se_aes_crypt_block_ecb(8, 0, keys->ssl_rsa_kek, ssl_rsa_kek_source_y); + se_aes_crypt_block_ecb(8, DECRYPT, keys->ssl_rsa_kek, ssl_rsa_kek_source_y); } } @@ -276,11 +261,11 @@ static void _derive_master_key_per_generation_keys(key_derivation_ctx_t *keys) { continue; for (u32 j = 0; j < 3; j++) { _generate_kek(8, key_area_key_sources[j], keys->master_key[i], aes_kek_generation_source, NULL); - se_aes_crypt_block_ecb(8, 0, keys->key_area_key[j][i], aes_key_generation_source); + se_aes_crypt_block_ecb(8, DECRYPT, keys->key_area_key[j][i], aes_key_generation_source); } se_aes_key_set(8, keys->master_key[i], AES_128_KEY_SIZE); - se_aes_crypt_block_ecb(8, 0, keys->package2_key[i], package2_key_source); - se_aes_crypt_block_ecb(8, 0, keys->titlekek[i], titlekek_source); + se_aes_crypt_block_ecb(8, DECRYPT, keys->package2_key[i], package2_key_source); + se_aes_crypt_block_ecb(8, DECRYPT, keys->titlekek[i], titlekek_source); } } @@ -478,7 +463,7 @@ static bool _derive_titlekeys(key_derivation_ctx_t *keys, titlekey_buffer_t *tit return false; } - se_aes_xts_crypt(1, 0, 0, 0, titlekey_buffer->read_buffer, titlekey_buffer->read_buffer, XTS_CLUSTER_SIZE, NX_EMMC_CALIBRATION_SIZE / XTS_CLUSTER_SIZE); + se_aes_xts_crypt(1, 0, DECRYPT, 0, titlekey_buffer->read_buffer, titlekey_buffer->read_buffer, XTS_CLUSTER_SIZE, NX_EMMC_CALIBRATION_SIZE / XTS_CLUSTER_SIZE); nx_emmc_cal0_t *cal0 = (nx_emmc_cal0_t *)titlekey_buffer->read_buffer; if (cal0->magic != MAGIC_CAL0) { @@ -496,7 +481,7 @@ static bool _derive_titlekeys(key_derivation_ctx_t *keys, titlekey_buffer_t *tit u32 temp_device_key[AES_128_KEY_SIZE / 4] = {0}; _get_device_key(7, keys, temp_device_key, keypair_generation); _generate_kek(7, eticket_rsa_kekek_source, temp_device_key, keys->temp_key, NULL); - se_aes_crypt_block_ecb(7, 0, keys->eticket_rsa_kek_personalized, eticket_rsa_kek_source); + se_aes_crypt_block_ecb(7, DECRYPT, keys->eticket_rsa_kek_personalized, eticket_rsa_kek_source); memcpy(keys->temp_key, keys->eticket_rsa_kek_personalized, sizeof(keys->temp_key)); } else { memcpy(keys->temp_key, keys->eticket_rsa_kek, sizeof(keys->temp_key)); @@ -594,21 +579,21 @@ static void _save_mariko_partial_keys(u32 start, u32 count, bool append) { for (u32 ks = start; ks < start + count; ks++) { // Check if key is as expected if (ks < ARRAY_SIZE(mariko_key_vectors)) { - se_aes_crypt_block_ecb(ks, 0, &data[0], mariko_key_vectors[ks]); + se_aes_crypt_block_ecb(ks, DECRYPT, &data[0], mariko_key_vectors[ks]); if (_key_exists(data)) { continue; } } // Encrypt zeros with complete key - se_aes_crypt_block_ecb(ks, 1, &data[3 * AES_128_KEY_SIZE], zeros); + se_aes_crypt_block_ecb(ks, ENCRYPT, &data[3 * AES_128_KEY_SIZE], zeros); // We only need to overwrite 3 of the dwords of the key for (u32 i = 0; i < 3; i++) { // Overwrite ith dword of key with zeros se_aes_key_partial_set(ks, i, 0); // Encrypt zeros with more of the key zeroed out - se_aes_crypt_block_ecb(ks, 1, &data[(2 - i) * AES_128_KEY_SIZE], zeros); + se_aes_crypt_block_ecb(ks, ENCRYPT, &data[(2 - i) * AES_128_KEY_SIZE], zeros); } // Skip saving key if two results are the same indicating unsuccessful overwrite or empty slot @@ -785,7 +770,7 @@ static bool _check_keyslot_access() { u8 test_data[AES_128_KEY_SIZE] = {0}; const u8 test_ciphertext[AES_128_KEY_SIZE] = {0}; se_aes_key_set(8, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", SE_KEY_128_SIZE); - se_aes_crypt_block_ecb(8, 0, test_data, test_ciphertext); + se_aes_crypt_block_ecb(8, DECRYPT, test_data, test_ciphertext); return memcmp(test_data, "\x7b\x1d\x29\xa1\x6c\xf8\xcc\xab\x84\xf0\xb8\xa5\x98\xe4\x2f\xa6", SE_KEY_128_SIZE) == 0; } @@ -944,14 +929,14 @@ static void _generate_specific_aes_key(u32 ks, key_derivation_ctx_t *keys, void _get_device_key(ks, keys, keys->temp_key, key_generation); se_aes_key_set(ks, keys->temp_key, AES_128_KEY_SIZE); se_aes_unwrap_key(ks, ks, retail_specific_aes_key_source); // kek = unwrap(rsaks, devkey) - se_aes_crypt_ecb(ks, 0, out_key, AES_128_KEY_SIZE * 2, key_source, AES_128_KEY_SIZE * 2); // bkey = unwrap(bkeys, kek) + se_aes_crypt_ecb(ks, DECRYPT, out_key, AES_128_KEY_SIZE * 2, key_source, AES_128_KEY_SIZE * 2); // bkey = unwrap(bkeys, kek) } else { _get_secure_data(keys, out_key); } } static void _get_device_key(u32 ks, key_derivation_ctx_t *keys, void *out_device_key, u32 revision) { - if (revision == KB_FIRMWARE_VERSION_100_200 && !h_cfg.t210b01) { + if (revision == KB_FIRMWARE_VERSION_100 && !h_cfg.t210b01) { memcpy(out_device_key, keys->device_key, AES_128_KEY_SIZE); return; } @@ -963,11 +948,11 @@ static void _get_device_key(u32 ks, key_derivation_ctx_t *keys, void *out_device } u32 temp_key[AES_128_KEY_SIZE / 4] = {0}; se_aes_key_set(ks, keys->device_key_4x, AES_128_KEY_SIZE); - se_aes_crypt_block_ecb(ks, 0, temp_key, device_master_key_source_sources[revision]); + se_aes_crypt_block_ecb(ks, DECRYPT, temp_key, device_master_key_source_sources[revision]); se_aes_key_set(ks, keys->master_key[0], AES_128_KEY_SIZE); const void *kek_source = fuse_read_hw_state() == FUSE_NX_HW_STATE_PROD ? device_master_kek_sources[revision] : device_master_kek_sources_dev[revision]; se_aes_unwrap_key(ks, ks, kek_source); - se_aes_crypt_block_ecb(ks, 0, out_device_key, temp_key); + se_aes_crypt_block_ecb(ks, DECRYPT, out_device_key, temp_key); } static bool _test_key_pair(const void *public_exponent, const void *private_exponent, const void *modulus) { diff --git a/source/main.c b/source/main.c index 1eea1fb..f9f2e19 100644 --- a/source/main.c +++ b/source/main.c @@ -23,6 +23,7 @@ #include #include #include "gfx/tui.h" +#include "hos/pkg1.h" #include #include #include diff --git a/source/storage/nx_emmc_bis.c b/source/storage/nx_emmc_bis.c index 1362274..a6f51b9 100644 --- a/source/storage/nx_emmc_bis.c +++ b/source/storage/nx_emmc_bis.c @@ -160,7 +160,7 @@ static int nx_emmc_bis_write_block(u32 sector, u32 count, void *buff, bool force } // Encrypt and write. - if (!_nx_aes_xts_crypt_sec(ks_tweak, ks_crypt, 1, tweak, true, sector_index_in_cluster, cluster, bis_cache->emmc_buffer, buff, count * NX_EMMC_BLOCKSIZE) || + if (!_nx_aes_xts_crypt_sec(ks_tweak, ks_crypt, ENCRYPT, tweak, true, sector_index_in_cluster, cluster, bis_cache->emmc_buffer, buff, count * NX_EMMC_BLOCKSIZE) || !nx_emmc_part_write(&emmc_storage, system_part, sector, count, bis_cache->emmc_buffer) ) return 1; // R/W error. @@ -227,7 +227,7 @@ static int nx_emmc_bis_read_block(u32 sector, u32 count, void *buff) // Read and decrypt the whole cluster the sector resides in. if (!nx_emmc_part_read(&emmc_storage, system_part, aligned_sector, SECTORS_PER_CLUSTER, bis_cache->emmc_buffer) || - !_nx_aes_xts_crypt_sec(ks_tweak, ks_crypt, 0, cache_tweak, true, 0, cluster, bis_cache->emmc_buffer, bis_cache->emmc_buffer, XTS_CLUSTER_SIZE) + !_nx_aes_xts_crypt_sec(ks_tweak, ks_crypt, DECRYPT, cache_tweak, true, 0, cluster, bis_cache->emmc_buffer, bis_cache->emmc_buffer, XTS_CLUSTER_SIZE) ) return 1; // R/W error. @@ -257,7 +257,7 @@ static int nx_emmc_bis_read_block(u32 sector, u32 count, void *buff) tweak_exp = sector_index_in_cluster; // Maximum one cluster (1 XTS crypto block 16KB). - if (!_nx_aes_xts_crypt_sec(ks_tweak, ks_crypt, 0, tweak, regen_tweak, tweak_exp, prev_cluster, buff, bis_cache->emmc_buffer, count * NX_EMMC_BLOCKSIZE)) + if (!_nx_aes_xts_crypt_sec(ks_tweak, ks_crypt, DECRYPT, tweak, regen_tweak, tweak_exp, prev_cluster, buff, bis_cache->emmc_buffer, count * NX_EMMC_BLOCKSIZE)) return 1; // R/W error. prev_sector = sector + count - 1;