diff --git a/Makefile b/Makefile index 1f2c8b9..c5a24dd 100644 --- a/Makefile +++ b/Makefile @@ -41,9 +41,11 @@ FFCFG_INC := '"../$(SOURCEDIR)/libs/fatfs/ffconf.h"' ################################################################################ CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR) -CUSTOMDEFINES += -DLP_VER_MJ=$(LPVERSION_MAJOR) -DLP_VER_MN=$(LPVERSION_MINOR) -DLP_VER_BF=$(LPVERSION_BUGFX) -DLP_VER=$(LPVERSION) +CUSTOMDEFINES += -DLP_VER_MJ=$(LPVERSION_MAJOR) -DLP_VER_MN=$(LPVERSION_MINOR) -DLP_VER_BF=$(LPVERSION_BUGFX) -DLP_VER=$(LPVERSION) -DBDK_EMUMMC_ENABLE CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC) +FFCFG_INC := '"../$(PROJECT_DIR)/libs/fatfs/ffconf.h"' + # 0: UART_A, 1: UART_B. #CUSTOMDEFINES += -DDEBUG_UART_PORT=0 diff --git a/Modified BDK files.md b/Modified BDK files.md new file mode 100644 index 0000000..de2044a --- /dev/null +++ b/Modified BDK files.md @@ -0,0 +1,16 @@ +For future reference if updating the BDK + +// TODO: fatfs, ini parser, memory map + +## /bdk/sec/SE.c&h +- Added se_aes_cmac + +## /bdk/usb +- Removed entirely + +## /bdk/storage/sd.c +- in sd_file_read(), extend read buffer by 1 and place a NULL byte at the end + +## /bdk/libs/fatfs/ff.c&h +- Added f_fdisk_mod +- Stubbed exfat partition creation \ No newline at end of file diff --git a/bdk/bdk.h b/bdk/bdk.h new file mode 100644 index 0000000..3c7810e --- /dev/null +++ b/bdk/bdk.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022 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 BDK_H +#define BDK_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#endif \ No newline at end of file diff --git a/bdk/display/di.c b/bdk/display/di.c index 1c79823..061a0ca 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-2022 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. @@ -171,17 +176,21 @@ int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled) void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled) { + static u32 *fifo32 = NULL; u8 *fifo8; - u32 *fifo32; u32 host_control; + // Allocate fifo buffer. + if (!fifo32) + fifo32 = malloc(DSI_STATUS_RX_FIFO_SIZE * 8 * sizeof(u32)); + // Enable host cmd packets during video and save host control. if (video_enabled) DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE; 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) { @@ -194,7 +203,7 @@ void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled) break; default: - fifo32 = calloc(DSI_STATUS_RX_FIFO_SIZE * 8, 4); + memset(fifo32, 0, DSI_STATUS_RX_FIFO_SIZE * 8 * sizeof(u32)); fifo8 = (u8 *)fifo32; fifo32[0] = (len << 8) | MIPI_DSI_DCS_LONG_WRITE; fifo8[4] = cmd; @@ -203,7 +212,6 @@ void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled) for (u32 i = 0; i < (ALIGN(len, 4) / 4); i++) DSI(_DSIREG(DSI_WR_DATA)) = fifo32[i]; DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST; - free(fifo32); break; } @@ -216,8 +224,74 @@ 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) +{ + static u32 *fifo32 = NULL; + u8 *fifo8; + + // Allocate fifo buffer. + if (!fifo32) + fifo32 = malloc(DSI_STATUS_RX_FIFO_SIZE * 8 * sizeof(u32)); + + // 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: + memset(fifo32, 0, DSI_STATUS_RX_FIFO_SIZE * 8 * sizeof(u32)); + 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]; + 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 +344,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 +419,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 +440,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_AMS699VC01; + // Initialize display panel. switch (_display_id) { + case PANEL_SAM_AMS699VC01: + _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 +495,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 +545,9 @@ void display_init() void display_backlight_pwm_init() { + if (_display_id == PANEL_SAM_AMS699VC01) + 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 +561,27 @@ 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) +{ + // Normalize brightness value by 82% and a base of 45 duty. + if (brightness) + brightness = (brightness * PANEL_OLED_BL_COEFF / 100) + PANEL_OLED_BL_OFFSET; + + 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 +589,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 +597,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_AMS699VC01) + 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 +633,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_AMS699VC01) + usleep(10000); // De-initialize display panel. switch (_display_id) @@ -584,16 +687,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_AMS699VC01) ? 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 +716,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 +733,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_AMS699VC01; } void display_color_screen(u32 color) @@ -637,41 +757,42 @@ 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_AMS699VC01) + display_backlight(true); + else + display_backlight_brightness(255, 0); } u32 *display_init_framebuffer_pitch() { // Sanitize framebuffer area. - memset((u32 *)IPL_FB_ADDRESS, 0, 0x3C0000); + memset((u32 *)IPL_FB_ADDRESS, 0, IPL_FB_SZ); // 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; + return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR)); } 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); // No need to wait on Aula. - usleep(35000); - - return (u32 *)NYX_FB_ADDRESS; + return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR)); } 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); // No need to wait on Aula. - usleep(35000); - - return (u32 *)NYX_FB_ADDRESS; + return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR)); } u32 *display_init_framebuffer_log() @@ -679,7 +800,7 @@ u32 *display_init_framebuffer_log() // This configures the framebuffer @ LOG_FB_ADDRESS with a resolution of 1280x720 (line stride 720). exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_log, 20); - return (u32 *)LOG_FB_ADDRESS; + return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR)); } void display_activate_console() diff --git a/bdk/display/di.h b/bdk/display/di.h index 7682bdb..cf4f0de 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) @@ -644,22 +652,30 @@ #define DCS_CONTROL_DISPLAY_DIMMING_CTRL BIT(3) #define DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL BIT(5) +#define PANEL_OLED_BL_COEFF 82 // 82%. +#define PANEL_OLED_BL_OFFSET 45 // Least legible backlight duty. + /* Switch Panels: * - * 6.2" panels for Icosa and Iowa skus: + * 6.2" panels for Icosa and Iowa SKUs: * [10] 81 [26]: JDI LPM062M326A * [10] 96 [09]: JDI LAM062M109A * [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1) * [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1) * [20] 96 [0F]: InnoLux P062CCA-AZ3 [UNCONFIRMED MODEL REV] + * [20] 97 [0F]: InnoLux P062CCA-??? [UNCONFIRMED MODEL REV] * [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: + * 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] 9B [20]: Samsung AMS699VC01-0 (Rev 2.5) */ /* Display ID Decoding: @@ -672,13 +688,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 +706,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_AMS699VC01 = 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/fatfs_cfg.h b/bdk/fatfs_cfg.h index a12585f..77b26dd 100644 --- a/bdk/fatfs_cfg.h +++ b/bdk/fatfs_cfg.h @@ -17,8 +17,12 @@ #ifndef _FATFS_CFG_H_ #define _FATFS_CFG_H_ +// define FFCFG_INC in a project to use a specific FatFS configuration. +// Example: FFCFG_INC := '"../$(PROJECT_DIR)/libs/fatfs/ffconf.h"' #ifdef FFCFG_INC #include FFCFG_INC +#else +#include "fatfs_conf.h" #endif #endif diff --git a/bdk/fatfs_conf.h b/bdk/fatfs_conf.h new file mode 100644 index 0000000..e87219d --- /dev/null +++ b/bdk/fatfs_conf.h @@ -0,0 +1,305 @@ +/*---------------------------------------------------------------------------/ +/ FatFs Functional Configurations +/---------------------------------------------------------------------------*/ + +#define FFCONF_DEF 86604 /* Revision ID */ + +/*---------------------------------------------------------------------------/ +/ Function Configurations +/---------------------------------------------------------------------------*/ + +#define FF_FS_READONLY 0 +/* This option switches read-only configuration. (0:Read/Write or 1:Read-only) +/ Read-only configuration removes writing API functions, f_write(), f_sync(), +/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() +/ and optional writing functions as well. */ + + +#define FF_FS_MINIMIZE 0 +/* This option defines minimization level to remove some basic API functions. +/ +/ 0: Basic functions are fully enabled. +/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() +/ are removed. +/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. +/ 3: f_lseek() function is removed in addition to 2. */ + + +#define FF_USE_STRFUNC 2 +/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf(). +/ +/ 0: Disable string functions. +/ 1: Enable without LF-CRLF conversion. +/ 2: Enable with LF-CRLF conversion. */ + + +#define FF_USE_FIND 1 +/* This option switches filtered directory read functions, f_findfirst() and +/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ + + +#define FF_USE_MKFS 0 +/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ + +#if FF_USE_MKFS +#define FF_MKFS_LABEL "SWITCH SD " +#endif +/* This sets FAT/FAT32 label. Exactly 11 characters, all caps. */ + + +#define FF_USE_FASTSEEK 0 +/* This option switches fast seek function. (0:Disable or 1:Enable) */ + +#define FF_FASTFS 0 +#if FF_FASTFS +#undef FF_USE_FASTSEEK +#define FF_USE_FASTSEEK 1 +#endif +/* This option switches fast access to chained clusters. (0:Disable or 1:Enable) */ + + +#define FF_SIMPLE_GPT 1 +/* This option switches support for the first GPT partition. (0:Disable or 1:Enable) */ + + +#define FF_USE_EXPAND 0 +/* This option switches f_expand function. (0:Disable or 1:Enable) */ + + +#define FF_USE_CHMOD 1 +/* This option switches attribute manipulation functions, f_chmod() and f_utime(). +/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */ + + +#define FF_USE_LABEL 0 +/* This option switches volume label functions, f_getlabel() and f_setlabel(). +/ (0:Disable or 1:Enable) */ + + +#define FF_USE_FORWARD 0 +/* This option switches f_forward() function. (0:Disable or 1:Enable) */ + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/---------------------------------------------------------------------------*/ + +#define FF_CODE_PAGE 850 +/* This option specifies the OEM code page to be used on the target system. +/ Incorrect code page setting can cause a file open failure. +/ +/ 437 - U.S. +/ 720 - Arabic +/ 737 - Greek +/ 771 - KBL +/ 775 - Baltic +/ 850 - Latin 1 +/ 852 - Latin 2 +/ 855 - Cyrillic +/ 857 - Turkish +/ 860 - Portuguese +/ 861 - Icelandic +/ 862 - Hebrew +/ 863 - Canadian French +/ 864 - Arabic +/ 865 - Nordic +/ 866 - Russian +/ 869 - Greek 2 +/ 932 - Japanese (DBCS) +/ 936 - Simplified Chinese (DBCS) +/ 949 - Korean (DBCS) +/ 950 - Traditional Chinese (DBCS) +/ 0 - Include all code pages above and configured by f_setcp() +*/ + + +#define FF_USE_LFN 3 +#define FF_MAX_LFN 255 +/* The FF_USE_LFN switches the support for LFN (long file name). +/ +/ 0: Disable LFN. FF_MAX_LFN has no effect. +/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function +/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and +/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled. +/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can +/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN +/ specification. +/ When use stack for the working buffer, take care on stack overflow. When use heap +/ memory for the working buffer, memory management functions, ff_memalloc() and +/ ff_memfree() in ffsystem.c, need to be added to the project. */ + + +#define FF_LFN_UNICODE 0 +/* This option switches the character encoding on the API when LFN is enabled. +/ +/ 0: ANSI/OEM in current CP (TCHAR = char) +/ 1: Unicode in UTF-16 (TCHAR = WCHAR) +/ 2: Unicode in UTF-8 (TCHAR = char) +/ 3: Unicode in UTF-32 (TCHAR = DWORD) +/ +/ Also behavior of string I/O functions will be affected by this option. +/ When LFN is not enabled, this option has no effect. */ + + +#define FF_LFN_BUF 255 +#define FF_SFN_BUF 12 +/* This set of options defines size of file name members in the FILINFO structure +/ which is used to read out directory items. These values should be suffcient for +/ the file names to read. The maximum possible length of the read file name depends +/ on character encoding. When LFN is not enabled, these options have no effect. */ + + +#define FF_STRF_ENCODE 0 +/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(), +/ f_putc(), f_puts and f_printf() convert the character encoding in it. +/ This option selects assumption of character encoding ON THE FILE to be +/ read/written via those functions. +/ +/ 0: ANSI/OEM in current CP +/ 1: Unicode in UTF-16LE +/ 2: Unicode in UTF-16BE +/ 3: Unicode in UTF-8 +*/ + + +#define FF_FS_RPATH 0 +/* This option configures support for relative path. +/ +/ 0: Disable relative path and remove related functions. +/ 1: Enable relative path. f_chdir() and f_chdrive() are available. +/ 2: f_getcwd() function is available in addition to 1. +*/ + + +/*---------------------------------------------------------------------------/ +/ Drive/Volume Configurations +/---------------------------------------------------------------------------*/ + +#define FF_VOLUMES 1 +/* Number of volumes (logical drives) to be used. (1-10) */ + + +#define FF_STR_VOLUME_ID 0 +#define FF_VOLUME_STRS "sd" +/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings. +/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive +/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each +/ logical drives. Number of items must not be less than FF_VOLUMES. Valid +/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are +/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is +/ not defined, a user defined volume string table needs to be defined as: +/ +/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",... +/ Order is important. Any change to order, must also be reflected to diskio drive enum. +*/ + + +#define FF_MULTI_PARTITION 0 +/* This option switches support for multiple volumes on the physical drive. +/ By default (0), each logical drive number is bound to the same physical drive +/ number and only an FAT volume found on the physical drive will be mounted. +/ When this function is enabled (1), each logical drive number can be bound to +/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk() +/ funciton will be available. */ + + +#define FF_MIN_SS 512 +#define FF_MAX_SS 512 +/* This set of options configures the range of sector size to be supported. (512, +/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and +/ harddisk. But a larger value may be required for on-board flash memory and some +/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured +/ for variable sector size mode and disk_ioctl() function needs to implement +/ GET_SECTOR_SIZE command. */ + + +#define FF_USE_TRIM 0 +/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable) +/ To enable Trim function, also CTRL_TRIM command should be implemented to the +/ disk_ioctl() function. */ + + +#define FF_FS_NOFSINFO 1 +/* If you need to know correct free space on the FAT32 volume, set bit 0 of this +/ option, and f_getfree() function at first time after volume mount will force +/ a full FAT scan. Bit 1 controls the use of last allocated cluster number. +/ +/ bit0=0: Use free cluster count in the FSINFO if available. +/ bit0=1: Do not trust free cluster count in the FSINFO. +/ bit1=0: Use last allocated cluster number in the FSINFO if available. +/ bit1=1: Do not trust last allocated cluster number in the FSINFO. +*/ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/---------------------------------------------------------------------------*/ + +#define FF_FS_TINY 0 +/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) +/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes. +/ Instead of private sector buffer eliminated from the file object, common sector +/ buffer in the filesystem object (FATFS) is used for the file data transfer. */ + + +#define FF_FS_EXFAT 1 +/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) +/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1) +/ Note that enabling exFAT discards ANSI C (C89) compatibility. */ + + +#define FF_FS_NORTC 1 +#define FF_NORTC_MON 1 +#define FF_NORTC_MDAY 1 +#define FF_NORTC_YEAR 2022 +/* The option FF_FS_NORTC switches timestamp function. If the system does not have +/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable +/ the timestamp function. Every object modified by FatFs will have a fixed timestamp +/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time. +/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be +/ added to the project to read current time form real-time clock. FF_NORTC_MON, +/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect. +/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */ + + +#define FF_FS_LOCK 0 +/* The option FF_FS_LOCK switches file lock function to control duplicated file open +/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY +/ is 1. +/ +/ 0: Disable file lock function. To avoid volume corruption, application program +/ should avoid illegal open, remove and rename to the open objects. +/ >0: Enable file lock function. The value defines how many files/sub-directories +/ can be opened simultaneously under file lock control. Note that the file +/ lock control is independent of re-entrancy. */ + + +/* #include // O/S definitions */ +#define FF_FS_REENTRANT 0 +#define FF_FS_TIMEOUT 1000 +#define FF_SYNC_t HANDLE +/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs +/ module itself. Note that regardless of this option, file access to different +/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs() +/ and f_fdisk() function, are always not re-entrant. Only file/directory access +/ to the same volume is under control of this function. +/ +/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect. +/ 1: Enable re-entrancy. Also user provided synchronization handlers, +/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() +/ function, must be added to the project. Samples are available in +/ option/syscall.c. +/ +/ The FF_FS_TIMEOUT defines timeout period in unit of time tick. +/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, +/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be +/ included somewhere in the scope of ff.h. */ + + + +/*--- End of configuration options ---*/ diff --git a/bdk/ianos/elfload/elf.h b/bdk/ianos/elfload/elf.h index 196cf87..0dcfecc 100644 --- a/bdk/ianos/elfload/elf.h +++ b/bdk/ianos/elfload/elf.h @@ -29,33 +29,34 @@ #ifndef ELF_H #define ELF_H -#include -typedef uint8_t Elf_Byte; +#include -typedef uint32_t Elf32_Addr; /* Unsigned program address */ -typedef uint32_t Elf32_Off; /* Unsigned file offset */ -typedef int32_t Elf32_Sword; /* Signed large integer */ -typedef uint32_t Elf32_Word; /* Unsigned large integer */ -typedef uint16_t Elf32_Half; /* Unsigned medium integer */ +typedef u8 Elf_Byte; -typedef uint64_t Elf64_Addr; -typedef uint64_t Elf64_Off; -typedef int32_t Elf64_Shalf; +typedef u32 Elf32_Addr; /* Unsigned program address */ +typedef u32 Elf32_Off; /* Unsigned file offset */ +typedef s32 Elf32_Sword; /* Signed large integer */ +typedef u32 Elf32_Word; /* Unsigned large integer */ +typedef u16 Elf32_Half; /* Unsigned medium integer */ + +typedef u64 Elf64_Addr; +typedef u64 Elf64_Off; +typedef s32 Elf64_Shalf; #ifdef __alpha__ -typedef int64_t Elf64_Sword; -typedef uint64_t Elf64_Word; +typedef s64 Elf64_Sword; +typedef u64 Elf64_Word; #else -typedef int32_t Elf64_Sword; -typedef uint32_t Elf64_Word; +typedef s32 Elf64_Sword; +typedef u32 Elf64_Word; #endif -typedef int64_t Elf64_Sxword; -typedef uint64_t Elf64_Xword; +typedef s64 Elf64_Sxword; +typedef u64 Elf64_Xword; -typedef uint32_t Elf64_Half; -typedef uint16_t Elf64_Quarter; +typedef u32 Elf64_Half; +typedef u16 Elf64_Quarter; /* * e_ident[] identification indexes @@ -376,7 +377,7 @@ typedef struct #define ELF64_R_SYM(info) ((info) >> 32) #define ELF64_R_TYPE(info) ((info)&0xFFFFFFFF) -#define ELF64_R_INFO(s, t) (((s) << 32) + (__uint32_t)(t)) +#define ELF64_R_INFO(s, t) (((s) << 32) + (u32)(t)) #if defined(__mips64__) && defined(__MIPSEL__) /* @@ -389,7 +390,7 @@ typedef struct #undef ELF64_R_INFO #define ELF64_R_TYPE(info) (swap32((info) >> 32)) #define ELF64_R_SYM(info) ((info)&0xFFFFFFFF) -#define ELF64_R_INFO(s, t) (((__uint64_t)swap32(t) << 32) + (__uint32_t)(s)) +#define ELF64_R_INFO(s, t) (((u64)swap32(t) << 32) + (u32)(s)) #endif /* __mips64__ && __MIPSEL__ */ /* Program Header */ diff --git a/bdk/ianos/elfload/elfload.c b/bdk/ianos/elfload/elfload.c index 16f8200..daf561a 100644 --- a/bdk/ianos/elfload/elfload.c +++ b/bdk/ianos/elfload/elfload.c @@ -25,7 +25,7 @@ el_status el_pread(el_ctx *ctx, void *def, size_t nb, size_t offset) } #define EL_PHOFF(ctx, num) (((ctx)->ehdr.e_phoff + (num) *(ctx)->ehdr.e_phentsize)) -el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i) +el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, u32 type, unsigned *i) { el_status rv = EL_OK; for (; *i < ctx->ehdr.e_phnum; (*i)++) @@ -44,7 +44,7 @@ el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i) } #define EL_SHOFF(ctx, num) (((ctx)->ehdr.e_shoff + (num) *(ctx)->ehdr.e_shentsize)) -el_status el_findshdr(el_ctx *ctx, Elf_Shdr *shdr, uint32_t type, unsigned *i) +el_status el_findshdr(el_ctx *ctx, Elf_Shdr *shdr, u32 type, unsigned *i) { el_status rv = EL_OK; @@ -213,7 +213,7 @@ el_status el_load(el_ctx *ctx, el_alloc_cb alloc) return rv; } -el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t tag) +el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, u32 tag) { el_status rv = EL_OK; size_t ndyn = ctx->dynsize / sizeof(Elf_Dyn); @@ -231,7 +231,7 @@ el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t tag) return EL_OK; } -el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, uint32_t type) +el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, u32 type) { el_status rv = EL_OK; diff --git a/bdk/ianos/elfload/elfload.h b/bdk/ianos/elfload/elfload.h index 2b9bb67..0a73e05 100644 --- a/bdk/ianos/elfload/elfload.h +++ b/bdk/ianos/elfload/elfload.h @@ -22,8 +22,6 @@ #include "elfarch.h" #include "elf.h" -#include - #ifdef DEBUG #include #define EL_DEBUG(format, ...) \ @@ -100,7 +98,7 @@ el_status el_load(el_ctx *ctx, el_alloc_cb alloccb); * If the end of the phdrs table was reached, *i is set to -1 and the contents * of *phdr are undefined */ -el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, uint32_t type, unsigned *i); +el_status el_findphdr(el_ctx *ctx, Elf_Phdr *phdr, u32 type, unsigned *i); /* Relocate the loaded executable */ el_status el_relocate(el_ctx *ctx); @@ -108,7 +106,7 @@ el_status el_relocate(el_ctx *ctx); /* find a dynamic table entry * returns the entry on success, dyn->d_tag = DT_NULL on failure */ -el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, uint32_t type); +el_status el_finddyn(el_ctx *ctx, Elf_Dyn *dyn, u32 type); typedef struct { @@ -122,6 +120,6 @@ typedef struct * pass DT_REL or DT_RELA for type * sets ri->entrysize = 0 if not found */ -el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, uint32_t type); +el_status el_findrelocs(el_ctx *ctx, el_relocinfo *ri, u32 type); #endif diff --git a/bdk/ianos/elfload/elfreloc_aarch64.c b/bdk/ianos/elfload/elfreloc_aarch64.c index bbb0ce4..736ad46 100644 --- a/bdk/ianos/elfload/elfreloc_aarch64.c +++ b/bdk/ianos/elfload/elfreloc_aarch64.c @@ -23,9 +23,9 @@ el_status el_applyrela(el_ctx *ctx, Elf_RelA *rel) { - uintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr); - uint32_t type = ELF_R_TYPE(rel->r_info); - uint32_t sym = ELF_R_SYM(rel->r_info); + uptr *p = (uptr *)(rel->r_offset + ctx->base_load_paddr); + u32 type = ELF_R_TYPE(rel->r_info); + u32 sym = ELF_R_SYM(rel->r_info); switch (type) { @@ -53,9 +53,9 @@ el_status el_applyrela(el_ctx *ctx, Elf_RelA *rel) el_status el_applyrel(el_ctx *ctx, Elf_Rel *rel) { - uintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr); - uint32_t type = ELF_R_TYPE(rel->r_info); - uint32_t sym = ELF_R_SYM(rel->r_info); + uptr *p = (uptr *)(rel->r_offset + ctx->base_load_paddr); + u32 type = ELF_R_TYPE(rel->r_info); + u32 sym = ELF_R_SYM(rel->r_info); switch (type) { diff --git a/bdk/ianos/elfload/elfreloc_arm.c b/bdk/ianos/elfload/elfreloc_arm.c index 8b905cb..77ce654 100644 --- a/bdk/ianos/elfload/elfreloc_arm.c +++ b/bdk/ianos/elfload/elfreloc_arm.c @@ -20,9 +20,9 @@ el_status el_applyrel(el_ctx *ctx, Elf_Rel *rel) { - uint32_t sym = ELF_R_SYM(rel->r_info); // Symbol offset - uint32_t type = ELF_R_TYPE(rel->r_info); // Relocation Type - uintptr_t *p = (uintptr_t *)(rel->r_offset + ctx->base_load_paddr); // Target Addr + u32 sym = ELF_R_SYM(rel->r_info); // Symbol offset + u32 type = ELF_R_TYPE(rel->r_info); // Relocation Type + uptr *p = (uptr *)(rel->r_offset + ctx->base_load_paddr); // Target Addr #if 0 // For later symbol usage Elf32_Sym *elfSym; diff --git a/bdk/ianos/ianos.c b/bdk/ianos/ianos.c index 8deca45..fdc3488 100644 --- a/bdk/ianos/ianos.c +++ b/bdk/ianos/ianos.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include 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..af696d9 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, "Samsung BH2109" }, { -1, 1, 0, 1, "GiS VA 6.2\"" } }; @@ -410,7 +410,7 @@ int touch_power_on() gpio_output_enable(GPIO_PORT_J, GPIO_PIN_7, GPIO_OUTPUT_ENABLE); gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_HIGH); - // IRQ and more. + // Touscreen IRQ. // PINMUX_AUX(PINMUX_AUX_TOUCH_INT) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 3; // gpio_config(GPIO_PORT_X, GPIO_PIN_1, GPIO_MODE_GPIO); // gpio_write(GPIO_PORT_X, GPIO_PIN_1, GPIO_LOW); 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/libs/fatfs/ff.c b/bdk/libs/fatfs/ff.c index 1d7e34b..1584710 100644 --- a/bdk/libs/fatfs/ff.c +++ b/bdk/libs/fatfs/ff.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2019 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, @@ -38,8 +38,9 @@ #include "ff.h" /* Declarations of FatFs API */ #include "diskio.h" /* Declarations of device I/O functions */ +#include #include -#include "../../storage/nx_sd.h" +#include #define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF); //#define EFSPRINTF(...) @@ -3274,7 +3275,6 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ stat = disk_status(fs->pdrv); if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */ if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */ - EFSPRINTF("WPEN1"); return FR_WRITE_PROTECTED; } return FR_OK; /* The filesystem object is valid */ @@ -3285,14 +3285,13 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ /* Following code attempts to mount the volume. (analyze BPB and initialize the filesystem object) */ fs->fs_type = 0; /* Clear the filesystem object */ + fs->part_type = 0; /* Clear the Partition object */ fs->pdrv = LD2PD(vol); /* Bind the logical drive and a physical drive */ stat = disk_initialize(fs->pdrv); /* Initialize the physical drive */ if (stat & STA_NOINIT) { /* Check if the initialization succeeded */ - EFSPRINTF("MDNR"); return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */ } if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */ - EFSPRINTF("WPEN2"); return FR_WRITE_PROTECTED; } #if FF_MAX_SS != FF_MIN_SS /* Get sector size (multiple sector size cfg only) */ @@ -3319,6 +3318,20 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ EFSPRINTF("BRNL"); return FR_DISK_ERR; /* An error occured in the disk I/O layer */ } +#if FF_SIMPLE_GPT + if (fmt >= 2) { + /* If GPT Check the first partition */ + gpt_header_t *gpt_header = (gpt_header_t *)fs->win; + if (move_window(fs, 1) != FR_OK) return FR_DISK_ERR; + if (!mem_cmp(&gpt_header->signature, "EFI PART", 8)) { + if (move_window(fs, gpt_header->part_ent_lba) != FR_OK) return FR_DISK_ERR; + gpt_entry_t *gpt_entry = (gpt_entry_t *)fs->win; + fs->part_type = 1; + bsect = gpt_entry->lba_start; + fmt = bsect ? check_fs(fs, bsect) : 3; /* Check the partition */ + } + } +#endif if (fmt >= 2) { EFSPRINTF("NOFAT"); return FR_NO_FILESYSTEM; /* No FAT volume is found */ @@ -4049,8 +4062,7 @@ FRESULT f_write ( } if (clst == 0) { EFSPRINTF("DSKFULL"); - fp->flag |= FA_MODIFIED; - ABORT(fs, FR_DISK_ERR); /* Could not allocate a new cluster (disk full) */ + break; /* Could not allocate a new cluster (disk full) */ } if (clst == 1) { EFSPRINTF("CCHK"); @@ -4698,9 +4710,9 @@ DWORD *f_expand_cltbl ( } if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */ ff_memfree(fp->cltbl); - fp->cltbl = NULL; + fp->cltbl = (void *)0; EFSPRINTF("CLTBLSZ"); - return NULL; + return (void *)0; } f_lseek(fp, 0); @@ -5862,7 +5874,7 @@ FRESULT f_mkfs ( if (vol < 0) return FR_INVALID_DRIVE; if (FatFs[vol]) FatFs[vol]->fs_type = 0; /* Clear the volume if mounted */ pdrv = LD2PD(vol); /* Physical drive */ - part = 1; /* Partition (0:create as new, 1-4:get from partition table) */ + part = LD2PT(vol); /* Partition (0:create as new, 1-4:get from partition table) */ /* Check physical drive status */ stat = disk_initialize(pdrv); @@ -5893,7 +5905,7 @@ FRESULT f_mkfs ( if (!buf || sz_buf == 0) return FR_NOT_ENOUGH_CORE; /* Determine where the volume to be located (b_vol, sz_vol) */ - if (part > 0) { + if (FF_MULTI_PARTITION && part != 0) { /* Get partition information from partition table in the MBR */ if (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Load MBR */ if (ld_word(buf + BS_55AA) != 0xAA55) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if MBR is valid */ @@ -6172,7 +6184,9 @@ FRESULT f_mkfs ( #endif /* Create FAT VBR */ mem_set(buf, 0, ss); - mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code (x86), OEM name */ + /* Boot jump code (x86), OEM name */ + if (!(opt & FM_PRF2)) mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "NYX1.0.0", 11); + else mem_cpy(buf + BS_JmpBoot, "\xEB\xE9\x90\x00\x00\x00\x00\x00\x00\x00\x00", 11); st_word(buf + BPB_BytsPerSec, ss); /* Sector size [byte] */ buf[BPB_SecPerClus] = (BYTE)pau; /* Cluster size [sector] */ st_word(buf + BPB_RsvdSecCnt, (WORD)sz_rsv); /* Size of reserved area */ @@ -6185,23 +6199,27 @@ FRESULT f_mkfs ( } buf[BPB_Media] = 0xF8; /* Media descriptor byte */ st_word(buf + BPB_SecPerTrk, 63); /* Number of sectors per track (for int13) */ - st_word(buf + BPB_NumHeads, 255); /* Number of heads (for int13) */ + st_word(buf + BPB_NumHeads, (opt & FM_PRF2) ? 16 : 255); /* Number of heads (for int13) */ st_dword(buf + BPB_HiddSec, b_vol); /* Volume offset in the physical drive [sector] */ if (fmt == FS_FAT32) { - st_dword(buf + BS_VolID32, GET_FATTIME()); /* VSN */ + st_dword(buf + BS_VolID32, (opt & FM_PRF2) ? 0 : GET_FATTIME()); /* VSN */ st_dword(buf + BPB_FATSz32, sz_fat); /* FAT size [sector] */ st_dword(buf + BPB_RootClus32, 2); /* Root directory cluster # (2) */ st_word(buf + BPB_FSInfo32, 1); /* Offset of FSINFO sector (VBR + 1) */ st_word(buf + BPB_BkBootSec32, 6); /* Offset of backup VBR (VBR + 6) */ buf[BS_DrvNum32] = 0x80; /* Drive number (for int13) */ buf[BS_BootSig32] = 0x29; /* Extended boot signature */ - mem_cpy(buf + BS_VolLab32, "SWITCH SD " "FAT32 ", 19); /* Volume label, FAT signature */ + /* Volume label, FAT signature */ + if (!(opt & FM_PRF2)) mem_cpy(buf + BS_VolLab32, FF_MKFS_LABEL "FAT32 ", 19); + else mem_cpy(buf + BS_VolLab32, "NO NAME " "FAT32 ", 19); } else { st_dword(buf + BS_VolID, GET_FATTIME()); /* VSN */ st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */ buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */ buf[BS_BootSig] = 0x29; /* Extended boot signature */ - mem_cpy(buf + BS_VolLab, "SWITCH SD " "FAT ", 19); /* Volume label, FAT signature */ + /* Volume label, FAT signature */ + if (!(opt & FM_PRF2)) mem_cpy(buf + BS_VolLab, FF_MKFS_LABEL "FAT ", 19); + else mem_cpy(buf + BS_VolLab, "NO NAME " "FAT ", 19); } st_word(buf + BS_55AA, 0xAA55); /* Signature (offset is fixed here regardless of sector size) */ if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */ @@ -6219,6 +6237,16 @@ FRESULT f_mkfs ( disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */ } + /* Create PRF2SAFE info */ + if (fmt == FS_FAT32 && opt & FM_PRF2) { + mem_set(buf, 0, ss); + buf[16] = 0x64; /* Record type */ + st_dword(buf + 32, 0x03); /* Unknown. SYSTEM: 0x3F00. USER: 0x03. Volatile. */ + st_dword(buf + 36, 25); /* Entries. SYSTEM: 22. USER: 25.Static? */ + st_dword(buf + 508, 0x517BBFE0); /* Custom CRC32. SYSTEM: 0x6B673904. USER: 0x517BBFE0. */ + disk_write(pdrv, buf, b_vol + 3, 1); /* Write PRF2SAFE info (VBR + 3) */ + } + /* Initialize FAT area */ mem_set(buf, 0, (UINT)szb_buf); sect = b_fat; /* FAT start sector */ @@ -6264,7 +6292,7 @@ FRESULT f_mkfs ( } /* Update partition information */ - if (part != 0) { /* Created in the existing partition */ + if (FF_MULTI_PARTITION && part != 0) { /* Created in the existing partition */ /* Update system ID in the partition table */ if (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Read the MBR */ buf[MBR_Table + (part - 1) * SZ_PTE + PTE_System] = sys; /* Set system ID */ @@ -6372,6 +6400,7 @@ FRESULT f_fdisk ( #endif /* FF_MULTI_PARTITION */ #endif /* FF_USE_MKFS && !FF_FS_READONLY */ +// We don't need these where we're going... extern sdmmc_storage_t sd_storage; @@ -6449,7 +6478,6 @@ FRESULT f_fdisk_mod ( LEAVE_MKFS(res); } - #if FF_USE_STRFUNC #if FF_USE_LFN && FF_LFN_UNICODE && (FF_STRF_ENCODE < 0 || FF_STRF_ENCODE > 3) #error Wrong FF_STRF_ENCODE setting @@ -6782,6 +6810,8 @@ int f_puts ( putbuff pb; + if (str == (void *)0) return EOF; /* String is NULL */ + putc_init(&pb, fp); while (*str) putc_bfd(&pb, *str++); /* Put the string */ return putc_flush(&pb); @@ -6808,6 +6838,8 @@ int f_printf ( TCHAR c, d, str[32], *p; + if (fmt == (void *)0) return EOF; /* String is NULL */ + putc_init(&pb, fp); va_start(arp, fmt); diff --git a/bdk/libs/fatfs/ff.h b/bdk/libs/fatfs/ff.h index 29b1ba2..457b8e2 100644 --- a/bdk/libs/fatfs/ff.h +++ b/bdk/libs/fatfs/ff.h @@ -95,8 +95,8 @@ typedef DWORD FSIZE_t; /* Filesystem object structure (FATFS) */ typedef struct { - BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ BYTE fs_type; /* Filesystem type (0:not mounted) */ + BYTE part_type; /* Partition type (0:MBR, 1:GPT) */ BYTE pdrv; /* Associated physical drive */ BYTE n_fats; /* Number of FATs (1 or 2) */ BYTE wflag; /* win[] flag (b0:dirty) */ @@ -138,6 +138,7 @@ typedef struct { DWORD bitbase; /* Allocation bitmap base sector */ #endif DWORD winsect; /* Current sector appearing in the win[] */ + BYTE win[FF_MAX_SS] __attribute__((aligned(8))); /* Disk access window for Directory, FAT (and file data at tiny cfg). DMA aligned. */ } FATFS; @@ -168,9 +169,6 @@ typedef struct { /* File object structure (FIL) */ typedef struct { -#if !FF_FS_TINY - BYTE buf[FF_MAX_SS]; /* File private data read/write window */ -#endif FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */ BYTE flag; /* File status flags */ BYTE err; /* Abort flag (error code) */ @@ -184,6 +182,9 @@ typedef struct { #if FF_USE_FASTSEEK DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */ #endif +#if !FF_FS_TINY + BYTE buf[FF_MAX_SS] __attribute__((aligned(8))); /* File private data read/write window. DMA aligned. */ +#endif } FIL; @@ -291,7 +292,7 @@ FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */ FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */ -FRESULT f_fdisk_mod (BYTE pdrv, const DWORD* szt, void* work); // Modded version of f_fdisk that works:tm: +FRESULT f_fdisk_mod (BYTE pdrv, const DWORD* szt, void* work); FRESULT f_setcp (WORD cp); /* Set current code page */ int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */ int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */ @@ -366,6 +367,7 @@ int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */ #define FM_EXFAT 0x04 #define FM_ANY 0x07 #define FM_SFD 0x08 +#define FM_PRF2 0x10 /* Filesystem type (FATFS.fs_type) */ #define FS_FAT12 1 diff --git a/bdk/libs/nx_savedata/save.c b/bdk/libs/nx_savedata/save.c index b7fea65..5cc4b9f 100644 --- a/bdk/libs/nx_savedata/save.c +++ b/bdk/libs/nx_savedata/save.c @@ -34,14 +34,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "save.h" -#include -#include -#include -#include -#include -#include -#include - +#include #include #include 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/mc_t210.h b/bdk/mem/mc_t210.h index a7a9877..5bf8ce8 100644 --- a/bdk/mem/mc_t210.h +++ b/bdk/mem/mc_t210.h @@ -464,11 +464,19 @@ #define MC_UNTRANSLATED_REGION_CHECK 0x948 #define MC_DA_CONFIG0 0x9dc +// MC_VIDEO_PROTECT_REG_CTRL +#define VPR_LOCK_MODE_SHIFT 0 +#define VPR_CTRL_UNLOCKED (0 << VPR_LOCK_MODE_SHIFT) +#define VPR_CTRL_LOCKED (1 << VPR_LOCK_MODE_SHIFT) +#define VPR_PROTECT_MODE_SHIFT 1 +#define SEC_CTRL_SECURE (0 << VPR_PROTECT_MODE_SHIFT) +#define VPR_CTRL_TZ_SECURE (1 << VPR_PROTECT_MODE_SHIFT) + // MC_SECURITY_CARVEOUTX_CFG0 // Mode of LOCK_MODE. #define PROTECT_MODE_SHIFT 0 -#define SEC_CARVEOUT_CFG_SECURE (0 << PROTECT_MODE_SHIFT0) -#define SEC_CARVEOUT_CFG_TZ_SECURE (1 << PROTECT_MODE_SHIFT0) +#define SEC_CARVEOUT_CFG_SECURE (0 << PROTECT_MODE_SHIFT) +#define SEC_CARVEOUT_CFG_TZ_SECURE (1 << PROTECT_MODE_SHIFT) // Enables PROTECT_MODE. #define LOCK_MODE_SHIFT 1 #define SEC_CARVEOUT_CFG_UNLOCKED (0 << LOCK_MODE_SHIFT) diff --git a/bdk/mem/minerva.c b/bdk/mem/minerva.c index 2560dfe..301eced 100644 --- a/bdk/mem/minerva.c +++ b/bdk/mem/minerva.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 CTCaer + * Copyright (c) 2019-2022 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, @@ -19,8 +19,8 @@ #include "minerva.h" -#include #include +#include #include #include #include @@ -42,7 +42,7 @@ u32 minerva_init() if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) return 0; -#ifdef NYX +#ifdef BDK_MINERVA_CFG_FROM_RAM // Set table to nyx storage. mtc_cfg->mtc_table = (emc_table_t *)nyx_str->mtc_table; @@ -97,9 +97,10 @@ u32 minerva_init() return 1; // Get current frequency + u32 current_emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC); for (curr_ram_idx = 0; curr_ram_idx < 10; curr_ram_idx++) { - if (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) == mtc_cfg->mtc_table[curr_ram_idx].clk_src_emc) + if (current_emc_clk_src == mtc_cfg->mtc_table[curr_ram_idx].clk_src_emc) break; } @@ -156,6 +157,39 @@ void minerva_prep_boot_freq() minerva_change_freq(FREQ_800); } +void minerva_prep_boot_l4t() +{ + if (!minerva_cfg) + return; + + mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg; + + // Set init frequency. + minerva_change_freq(FREQ_204); + + // Train the rest of the frequencies. + mtc_cfg->train_mode = OP_TRAIN; + for (u32 i = 0; i < mtc_cfg->table_entries; i++) + { + mtc_cfg->rate_to = mtc_cfg->mtc_table[i].rate_khz; + // Skip already trained frequencies. + if (mtc_cfg->rate_to == FREQ_204 || mtc_cfg->rate_to == FREQ_800 || mtc_cfg->rate_to == FREQ_1600) + continue; + + // Train frequency. + minerva_cfg(mtc_cfg, NULL); + } + + // Do FSP WAR and scale to 800 MHz as boot freq. + bool fsp_opwr_enabled = !!(EMC(EMC_MRW3) & 0xC0); + if (fsp_opwr_enabled) + minerva_change_freq(FREQ_666); + minerva_change_freq(FREQ_800); + + // Do not let other mtc ops. + mtc_cfg->init_done = 0; +} + void minerva_periodic_training() { if (!minerva_cfg) @@ -167,4 +201,13 @@ void minerva_periodic_training() mtc_cfg->train_mode = OP_PERIODIC_TRAIN; minerva_cfg(mtc_cfg, NULL); } -} \ No newline at end of file +} + +emc_table_t *minerva_get_mtc_table() +{ + if (!minerva_cfg) + return NULL; + + mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg; + return mtc_cfg->mtc_table; +} diff --git a/bdk/mem/minerva.h b/bdk/mem/minerva.h index 51cb215..9e7f684 100644 --- a/bdk/mem/minerva.h +++ b/bdk/mem/minerva.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 CTCaer + * Copyright (c) 2019-2022 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, @@ -27,8 +27,8 @@ typedef struct { - s32 rate_to; - s32 rate_from; + u32 rate_to; + u32 rate_from; emc_table_t *mtc_table; u32 table_entries; emc_table_t *current_emc_table; @@ -53,6 +53,7 @@ enum train_mode_t typedef enum { FREQ_204 = 204000, + FREQ_666 = 665600, FREQ_800 = 800000, FREQ_1600 = 1600000 } minerva_freq_t; @@ -61,6 +62,8 @@ extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *); u32 minerva_init(); void minerva_change_freq(minerva_freq_t freq); void minerva_prep_boot_freq(); +void minerva_prep_boot_l4t(); void minerva_periodic_training(); +emc_table_t *minerva_get_mtc_table(); #endif diff --git a/bdk/mem/sdram.c b/bdk/mem/sdram.c index b119f46..00ec355 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_WTE, + LPDDR4X_NO_PATCH, + LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ, + LPDDR4X_NO_PATCH, + LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE, + 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_MT53E512M32D2NP_046_WTF, + LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF, + LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF, + 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..42907f9 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 @@ -44,46 +50,74 @@ enum sdram_ids_erista // LPDDR4 3200Mbps. 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_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT = 2, // WT:C. + 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_WTE = 11, // 4266Mbps. 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_WTE = 15, // 4266Mbps. 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_8GB_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_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25, // 4266Mbps. Die-F. + LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // 4266Mbps. Die-F. + LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // 4266Mbps. Die-F. + + 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_WTE = 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_8GB_SAMSUNG_1Y_A = 9, // DRAM IDs: 22. Unused. + LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF = 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..28cc063 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,287 @@ 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:E Die-E for retail Iowa and Hoag. + { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE }, // emc_auto_cal_config2. + { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE }, // emc_auto_cal_vref_sel0. + { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE }, // emc_mrw14. + { 0x80000713, 0x32C / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE }, // emc_dyn_self_ref_control. + { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE }, // mc_video_protect_gpu_override0. + { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE }, // 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 8GB 10nm-class (1y-A01) Die-? for SDEV Aula? + { 0x00000001, 0x134 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_adr_cfg. 2 Ranks. + { 0x08010004, 0x2B8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw1. + { 0x08020000, 0x2BC / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw2. + { 0x080D0000, 0x2C0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw3. + { 0x08033131, 0x2C8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw6. + { 0x080B0000, 0x2CC / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw8. + { 0x0C0E5D5D, 0x2D0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw9. + { 0x080C5D5D, 0x2D4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw10. + { 0x0C0D0808, 0x2D8 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw12. + { 0x0C0D0000, 0x2DC / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw13. + { 0x08161414, 0x2E0 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw14. + { 0x08010004, 0x2E4 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_mrw_extra. + { 0x00000000, 0x340 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_dev_select. Both devices. + { 0x35353535, 0x350 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_vref_dq_0. + { 0x35353535, 0x354 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_vref_dq_1. + { 0x35353535, 0x358 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_vref_dqs_0. + { 0x35353535, 0x35C / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_vref_dqs_1. + { 0x00480048, 0x3FC / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank0_0. + { 0x00480048, 0x400 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank0_1. + { 0x00480048, 0x404 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank0_2. + { 0x00480048, 0x408 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank0_3. + { 0x00480048, 0x40C / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank1_0. + { 0x00480048, 0x410 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank1_1. + { 0x00480048, 0x414 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank1_2. + { 0x00480048, 0x418 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_ib_ddll_long_dqs_rank1_3. + { 0x0051004F, 0x450 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_zcal_mrw_cmd. + { 0x40000001, 0x45C / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_zcal_init_dev1. + { 0x00010100, 0x594 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_tx_pwrd4. + { 0x00400010, 0x598 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // emc_pmacro_tx_pwrd5. + { 0x00000001, 0x630 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_adr_cfg. 2 Ranks. + { 0x00002000, 0x64C / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_cfg. 8GB total density. + { 0x00000002, 0x670 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_arb_timing_faw. + { 0x00000002, 0x680 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_arb_timing_r2r. + { 0x02020001, 0x694 / 4, LPDDR4X_8GB_SAMSUNG_1Y_A }, // mc_emem_arb_da_turns. +*/ - // 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. + // Micron LPDDR4X 4GB MT53D1024M32D1NP-053-WT:F 10nm-class (1y-01) Die-F for Newer Iowa/Hoag/Aula. + { 0x05500000, 0x0D4 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_auto_cal_config2. + { 0xC9AFBCBC, 0x0F4 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_auto_cal_vref_sel0. + { 0x00000006, 0x1CC / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_quse. + { 0x00000005, 0x1D0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_quse_width. + { 0x00000003, 0x1DC / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_einput. + { 0x0000000C, 0x1E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_einput_duration. + { 0x00000008, 0x24C / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_tfaw. + { 0x88161414, 0x2E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_mrw14. + { 0x80000713, 0x32C / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // emc_dyn_self_ref_control. + { 0x00000001, 0x670 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // mc_emem_arb_timing_faw. + { 0x2A800000, 0x6DC / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // mc_video_protect_gpu_override0. + { 0x00000002, 0x6E0 / 4, LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF }, // 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/mem/sdram_lp0.c b/bdk/mem/sdram_lp0.c index 1c6e7e3..1e50103 100644 --- a/bdk/mem/sdram_lp0.c +++ b/bdk/mem/sdram_lp0.c @@ -1126,413 +1126,413 @@ static void _sdram_lp0_save_params_t210(const void *params) s(PllMStableTime, 9:0, scratch4, 9:0); } -// #pragma GCC diagnostic ignored "-Wparentheses" +#pragma GCC diagnostic ignored "-Wparentheses" -// static void _sdram_lp0_save_params_t210b01(const void *params) -// { -// struct sdram_params_t210b01 *sdram = (struct sdram_params_t210b01 *)params; -// struct tegra_pmc_regs *pmc = (struct tegra_pmc_regs *)PMC_BASE; +static void _sdram_lp0_save_params_t210b01(const void *params) +{ + struct sdram_params_t210b01 *sdram = (struct sdram_params_t210b01 *)params; + struct tegra_pmc_regs *pmc = (struct tegra_pmc_regs *)PMC_BASE; -// u32 tmp = 0; + u32 tmp = 0; -// sdram->mc_generalized_carveout1_cfg0 = 0; -// sdram->mc_generalized_carveout2_cfg0 = 0; -// sdram->mc_generalized_carveout3_cfg0 = 0; -// sdram->mc_generalized_carveout4_cfg0 = 0; -// sdram->mc_generalized_carveout5_cfg0 = 0; + sdram->mc_generalized_carveout1_cfg0 = 0; + sdram->mc_generalized_carveout2_cfg0 = 0; + sdram->mc_generalized_carveout3_cfg0 = 0; + sdram->mc_generalized_carveout4_cfg0 = 0; + sdram->mc_generalized_carveout5_cfg0 = 0; -// // Patch SDRAM parameters. -// u32 t0 = sdram->emc_swizzle_rank0_byte0 << 5 >> 29 > sdram->emc_swizzle_rank0_byte0 << 1 >> 29; -// u32 t1 = (t0 & 0xFFFFFFEF) | ((sdram->emc_swizzle_rank1_byte0 << 5 >> 29 > sdram->emc_swizzle_rank1_byte0 << 1 >> 29) << 4); -// u32 t2 = (t1 & 0xFFFFFFFD) | ((sdram->emc_swizzle_rank0_byte1 << 5 >> 29 > sdram->emc_swizzle_rank0_byte1 << 1 >> 29) << 1); -// u32 t3 = (t2 & 0xFFFFFFDF) | ((sdram->emc_swizzle_rank1_byte1 << 5 >> 29 > sdram->emc_swizzle_rank1_byte1 << 1 >> 29) << 5); -// u32 t4 = (t3 & 0xFFFFFFFB) | ((sdram->emc_swizzle_rank0_byte2 << 5 >> 29 > sdram->emc_swizzle_rank0_byte2 << 1 >> 29) << 2); -// u32 t5 = (t4 & 0xFFFFFFBF) | ((sdram->emc_swizzle_rank1_byte2 << 5 >> 29 > sdram->emc_swizzle_rank1_byte2 << 1 >> 29) << 6); -// u32 t6 = (t5 & 0xFFFFFFF7) | ((sdram->emc_swizzle_rank0_byte3 << 5 >> 29 > sdram->emc_swizzle_rank0_byte3 << 1 >> 29) << 3); -// u32 t7 = (t6 & 0xFFFFFF7F) | ((sdram->emc_swizzle_rank1_byte3 << 5 >> 29 > sdram->emc_swizzle_rank1_byte3 << 1 >> 29) << 7); -// sdram->swizzle_rank_byte_encode = t7; -// sdram->emc_bct_spare2 = 0x40000DD8; -// sdram->emc_bct_spare3 = t7; + // Patch SDRAM parameters. + u32 t0 = sdram->emc_swizzle_rank0_byte0 << 5 >> 29 > sdram->emc_swizzle_rank0_byte0 << 1 >> 29; + u32 t1 = (t0 & 0xFFFFFFEF) | ((sdram->emc_swizzle_rank1_byte0 << 5 >> 29 > sdram->emc_swizzle_rank1_byte0 << 1 >> 29) << 4); + u32 t2 = (t1 & 0xFFFFFFFD) | ((sdram->emc_swizzle_rank0_byte1 << 5 >> 29 > sdram->emc_swizzle_rank0_byte1 << 1 >> 29) << 1); + u32 t3 = (t2 & 0xFFFFFFDF) | ((sdram->emc_swizzle_rank1_byte1 << 5 >> 29 > sdram->emc_swizzle_rank1_byte1 << 1 >> 29) << 5); + u32 t4 = (t3 & 0xFFFFFFFB) | ((sdram->emc_swizzle_rank0_byte2 << 5 >> 29 > sdram->emc_swizzle_rank0_byte2 << 1 >> 29) << 2); + u32 t5 = (t4 & 0xFFFFFFBF) | ((sdram->emc_swizzle_rank1_byte2 << 5 >> 29 > sdram->emc_swizzle_rank1_byte2 << 1 >> 29) << 6); + u32 t6 = (t5 & 0xFFFFFFF7) | ((sdram->emc_swizzle_rank0_byte3 << 5 >> 29 > sdram->emc_swizzle_rank0_byte3 << 1 >> 29) << 3); + u32 t7 = (t6 & 0xFFFFFF7F) | ((sdram->emc_swizzle_rank1_byte3 << 5 >> 29 > sdram->emc_swizzle_rank1_byte3 << 1 >> 29) << 7); + sdram->swizzle_rank_byte_encode = t7; + sdram->emc_bct_spare2 = 0x40000DD8; + sdram->emc_bct_spare3 = t7; -// s(emc_clock_source, 7:0, scratch6, 15:8); -// s(emc_clock_source_dll, 7:0, scratch6, 23:16); -// s(emc_clock_source, 31:29, scratch6, 26:24); -// s(emc_clock_source_dll, 31:29, scratch6, 29:27); -// s(emc_clock_source_dll, 11:10, scratch6, 31:30); -// pmc->scratch7 = (sdram->emc_rc << 24) | ((sdram->emc_zqcal_lpddr4_warm_boot << 27 >> 31 << 23) | ((sdram->emc_zqcal_lpddr4_warm_boot << 30 >> 31 << 22) | ((sdram->emc_zqcal_lpddr4_warm_boot << 21) & 0x3FFFFF | ((sdram->clk_rst_pllm_misc20_override << 20) & 0x1FFFFF | ((sdram->clk_rst_pllm_misc20_override << 28 >> 31 << 19) | ((sdram->clk_rst_pllm_misc20_override << 27 >> 31 << 18) | ((sdram->clk_rst_pllm_misc20_override << 26 >> 31 << 17) | ((sdram->clk_rst_pllm_misc20_override << 21 >> 31 << 16) | ((sdram->clk_rst_pllm_misc20_override << 20 >> 31 << 15) | ((sdram->clk_rst_pllm_misc20_override << 19 >> 31 << 14) | ((sdram->clk_rst_pllm_misc20_override << 18 >> 31 << 13) | ((sdram->emc_clock_source << 15 >> 31 << 12) | ((sdram->emc_clock_source << 11 >> 31 << 11) | ((sdram->emc_clock_source << 12 >> 31 << 10) | ((sdram->emc_clock_source << 6 >> 31 << 9) | ((sdram->emc_clock_source << 16 >> 31 << 8) | ((32 * sdram->emc_clock_source >> 31 << 7) | ((16 * sdram->emc_clock_source >> 31 << 6) | (16 * (sdram->emc_zqcal_lpddr4_warm_boot >> 30) | (4 * (sdram->clk_rst_pllm_misc20_override << 29 >> 30) | ((sdram->clk_rst_pllm_misc20_override << 22 >> 30) | 4 * (pmc->scratch7 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFFFFFF; -// pmc->scratch8 = (sdram->emc_pmacro_bg_bias_ctrl0 << 18 >> 30 << 30) | ((4 * pmc->scratch8) >> 2); -// pmc->scratch14 = ((u8)(sdram->emc_cfg_pipe_clk) << 31) | (2 * (((u8)(sdram->emc_fdpd_ctrl_cmd_no_ramp) << 30) | pmc->scratch14 & 0xBFFFFFFF) >> 1); -// s(emc_qrst, 6:0, scratch15, 26:20); -// s(emc_qrst, 20:16, scratch15, 31:27); -// s(emc_pmacro_cmd_tx_drive, 5:0, scratch16, 25:20); -// s(emc_pmacro_cmd_tx_drive, 13:8, scratch16, 31:26); -// pmc->scratch17 = (16 * sdram->emc_fbio_cfg8 >> 31 << 31) | (2 * ((32 * sdram->emc_fbio_cfg8 >> 31 << 30) | ((sdram->emc_fbio_cfg8 << 6 >> 31 << 29) | ((sdram->emc_fbio_cfg8 << 7 >> 31 << 28) | ((sdram->emc_fbio_cfg8 << 8 >> 31 << 27) | ((sdram->emc_fbio_cfg8 << 9 >> 31 << 26) | ((sdram->emc_fbio_cfg8 << 10 >> 31 << 25) | ((sdram->emc_fbio_cfg8 << 11 >> 31 << 24) | ((sdram->emc_fbio_cfg8 << 12 >> 31 << 23) | ((sdram->emc_fbio_cfg8 << 13 >> 31 << 22) | ((sdram->emc_fbio_cfg8 << 14 >> 31 << 21) | ((sdram->emc_fbio_cfg8 << 15 >> 31 << 20) | pmc->scratch17 & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch18 = ((u16)(sdram->emc_txsr_dll) << 20) | pmc->scratch18 & 0xFFFFF; -// pmc->scratch19 = (sdram->emc_txdsrvttgen << 20) | pmc->scratch19 & 0xFFFFF; -// s32(emc_cfg_rsv, scratch22); -// s32(emc_auto_cal_config, scratch23); -// s32(emc_auto_cal_vref_sel0, scratch24); -// s32(emc_pmacro_brick_ctrl_rfu1, scratch25); -// s32(emc_pmacro_brick_ctrl_rfu2, scratch26); -// s32(emc_pmc_scratch1, scratch27); -// s32(emc_pmc_scratch2, scratch28); -// s32(emc_pmc_scratch3, scratch29); -// pmc->scratch30 = (sdram->emc_pmacro_perbit_rfu_ctrl0 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl0 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl0 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl0 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl0 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl0 & 3 | 4 * (pmc->scratch30 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); -// pmc->scratch31 = (sdram->emc_pmacro_perbit_rfu_ctrl1 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl1 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl1 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl1 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl1 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl1 & 3 | 4 * (pmc->scratch31 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); -// pmc->scratch32 = (sdram->emc_pmacro_perbit_rfu_ctrl2 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl2 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl2 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl2 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl2 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl2 & 3 | 4 * (pmc->scratch32 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); -// pmc->scratch33 = (sdram->emc_pmacro_perbit_rfu_ctrl3 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl3 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl3 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl3 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl3 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl3 & 3 | 4 * (pmc->scratch33 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); -// pmc->scratch40 = (sdram->emc_pmacro_perbit_rfu_ctrl4 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl4 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl4 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl4 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl4 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl4 & 3 | 4 * (pmc->scratch40 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); -// pmc->scratch42 = (sdram->emc_pmacro_perbit_rfu_ctrl5 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl5 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl5 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl5 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl5 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl5 & 3 | 4 * (pmc->scratch42 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); -// pmc->scratch44 = (sdram->mc_emem_arb_da_turns >> 24 << 24) | ((sdram->mc_emem_arb_da_turns >> 16 << 16) | ((sdram->mc_emem_arb_da_turns << 16 >> 24 << 8) | (sdram->mc_emem_arb_da_turns & 0xFF | (pmc->scratch44 >> 8 << 8)) & 0xFFFF00FF) & 0xFF00FFFF) & 0xFFFFFF; -// pmc->scratch64 = ((u16)(sdram->mc_emem_arb_misc2) << 31) | (2 * ((sdram->emc_fbio_spare << 30) | ((sdram->emc_fbio_spare << 24 >> 26 << 24) | ((sdram->emc_fbio_spare << 16 >> 24 << 16) | ((sdram->emc_fbio_spare << 8 >> 24 << 8) | ((sdram->emc_fbio_spare >> 24) | (pmc->scratch64 >> 8 << 8)) & 0xFFFF00FF) & 0xFF00FFFF) & 0xC0FFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch65 = ((u16)(sdram->mc_da_cfg0) << 31 >> 1) | ((2 * sdram->mc_emem_arb_misc0 >> 29 << 27) | ((16 * sdram->mc_emem_arb_misc0 >> 31 << 26) | ((32 * sdram->mc_emem_arb_misc0 >> 26 << 20) | ((sdram->mc_emem_arb_misc0 << 11 >> 27 << 15) | ((sdram->mc_emem_arb_misc0 << 17 >> 25 << 8) | ((u8)sdram->mc_emem_arb_misc0 | (pmc->scratch65 >> 8 << 8)) & 0xFFFF80FF) & 0xFFF07FFF) & 0xFC0FFFFF) & 0xFBFFFFFF) & 0xC7FFFFFF) & 0xBFFFFFFF; -// pmc->scratch66 = (sdram->emc_fdpd_ctrl_cmd >> 30 << 27) | ((4 * sdram->emc_fdpd_ctrl_cmd >> 31 << 26) | ((8 * sdram->emc_fdpd_ctrl_cmd >> 27 << 21) | ((sdram->emc_fdpd_ctrl_cmd << 8 >> 28 << 17) | ((sdram->emc_fdpd_ctrl_cmd << 15 >> 27 << 12) | ((sdram->emc_fdpd_ctrl_cmd << 20 >> 28 << 8) | ((u8)sdram->emc_fdpd_ctrl_cmd | (pmc->scratch66 >> 8 << 8)) & 0xFFFFF0FF) & 0xFFFE0FFF) & 0xFFE1FFFF) & 0xFC1FFFFF) & 0xFBFFFFFF) & 0xE7FFFFFF; -// pmc->scratch67 = ((u8)(sdram->emc_burst_refresh_num) << 28) | ((16 * sdram->emc_auto_cal_config2 >> 30 << 26) | ((sdram->emc_auto_cal_config2 << 6 >> 30 << 24) | ((sdram->emc_auto_cal_config2 << 8 >> 30 << 22) | ((sdram->emc_auto_cal_config2 << 10 >> 30 << 20) | ((sdram->emc_auto_cal_config2 << 12 >> 30 << 18) | ((sdram->emc_auto_cal_config2 << 14 >> 30 << 16) | ((sdram->emc_auto_cal_config2 << 16 >> 30 << 14) | ((sdram->emc_auto_cal_config2 << 18 >> 30 << 12) | ((sdram->emc_auto_cal_config2 << 20 >> 30 << 10) | ((sdram->emc_auto_cal_config2 << 22 >> 30 << 8) | ((sdram->emc_auto_cal_config2 << 24 >> 30 << 6) | (16 * (sdram->emc_auto_cal_config2 << 26 >> 30) | (4 * (sdram->emc_auto_cal_config2 << 28 >> 30) | (sdram->emc_auto_cal_config2 & 3 | 4 * (pmc->scratch67 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xFFFFFFF; -// pmc->scratch68 = ((u8)(sdram->emc_tppd) << 28) | ((sdram->emc_cfg_dig_dll >> 31 << 27) | ((2 * sdram->emc_cfg_dig_dll >> 31 << 26) | ((16 * sdram->emc_cfg_dig_dll >> 31 << 25) | ((sdram->emc_cfg_dig_dll << 6 >> 22 << 15) | ((sdram->emc_cfg_dig_dll << 16 >> 31 << 14) | ((sdram->emc_cfg_dig_dll << 17 >> 31 << 13) | ((sdram->emc_cfg_dig_dll << 18 >> 30 << 11) | ((sdram->emc_cfg_dig_dll << 21 >> 29 << 8) | ((sdram->emc_cfg_dig_dll << 24 >> 30 << 6) | (32 * (sdram->emc_cfg_dig_dll << 26 >> 31) | (16 * (sdram->emc_cfg_dig_dll << 27 >> 31) | (8 * (sdram->emc_cfg_dig_dll << 28 >> 31) | (4 * (sdram->emc_cfg_dig_dll << 29 >> 31) | (2 * (sdram->emc_cfg_dig_dll << 30 >> 31) | (sdram->emc_cfg_dig_dll & 1 | 2 * (pmc->scratch68 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFF3F) & 0xFFFFF8FF) & 0xFFFFE7FF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFE007FFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xFFFFFFF; -// pmc->scratch69 = (sdram->emc_r2r << 28) | ((sdram->emc_fdpd_ctrl_dq >> 30 << 26) | ((8 * sdram->emc_fdpd_ctrl_dq >> 27 << 21) | ((sdram->emc_fdpd_ctrl_dq << 8 >> 28 << 17) | ((sdram->emc_fdpd_ctrl_dq << 15 >> 27 << 12) | ((sdram->emc_fdpd_ctrl_dq << 20 >> 28 << 8) | ((u8)sdram->emc_fdpd_ctrl_dq | (pmc->scratch69 >> 8 << 8)) & 0xFFFFF0FF) & 0xFFFE0FFF) & 0xFFE1FFFF) & 0xFC1FFFFF) & 0xF3FFFFFF) & 0xFFFFFFF; -// pmc->scratch70 = (sdram->emc_w2w << 28) | ((2 * sdram->emc_pmacro_ib_vref_dq_0 >> 25 << 21) | ((sdram->emc_pmacro_ib_vref_dq_0 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ib_vref_dq_0 << 17 >> 25 << 7) | (sdram->emc_pmacro_ib_vref_dq_0 & 0x7F | (pmc->scratch70 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xFFFFFFF; -// pmc->scratch71 = (sdram->emc_pmacro_vttgen_ctrl0 << 12 >> 28 << 28) | ((2 * sdram->emc_pmacro_ib_vref_dq_1 >> 25 << 21) | ((sdram->emc_pmacro_ib_vref_dq_1 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ib_vref_dq_1 << 17 >> 25 << 7) | ((pmc->scratch71 >> 7 << 7) | sdram->emc_pmacro_ib_vref_dq_1 & 0x7F) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xFFFFFFF; -// pmc->scratch72 = (((sdram->emc_pmacro_ib_vref_dqs_0 << 17 >> 25 << 7) | ((pmc->scratch72 >> 7 << 7) | sdram->emc_pmacro_ib_vref_dqs_0 & 0x7F) & 0xFFFFC07F) & 0xFFE03FFF | (sdram->emc_pmacro_ib_vref_dqs_0 << 9 >> 25 << 14)) & 0xF01FFFFF | (2 * sdram->emc_pmacro_ib_vref_dqs_0 >> 25 << 21); -// pmc->scratch73 = (2 * sdram->emc_pmacro_ib_vref_dqs_1 >> 25 << 21) | ((sdram->emc_pmacro_ib_vref_dqs_1 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ib_vref_dqs_1 << 17 >> 25 << 7) | ((pmc->scratch73 >> 7 << 7) | sdram->emc_pmacro_ib_vref_dqs_1 & 0x7F) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF; -// pmc->scratch74 = (2 * sdram->emc_pmacro_ddll_short_cmd_0 >> 25 << 21) | ((sdram->emc_pmacro_ddll_short_cmd_0 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ddll_short_cmd_0 << 17 >> 25 << 7) | (sdram->emc_pmacro_ddll_short_cmd_0 & 0x7F | (pmc->scratch74 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF; -// pmc->scratch75 = (2 * sdram->emc_pmacro_ddll_short_cmd_1 >> 25 << 21) | ((sdram->emc_pmacro_ddll_short_cmd_1 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ddll_short_cmd_1 << 17 >> 25 << 7) | (sdram->emc_pmacro_ddll_short_cmd_1 & 0x7F | (pmc->scratch75 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF; -// pmc->scratch76 = (sdram->emc_rp << 26) | ((4 * sdram->emc_dll_cfg0 >> 31 << 25) | ((8 * sdram->emc_dll_cfg0 >> 31 << 24) | ((16 * sdram->emc_dll_cfg0 >> 28 << 20) | ((sdram->emc_dll_cfg0 << 8 >> 28 << 16) | ((sdram->emc_dll_cfg0 << 12 >> 28 << 12) | ((sdram->emc_dll_cfg0 << 16 >> 28 << 8) | ((sdram->emc_dll_cfg0 << 20 >> 24) | (pmc->scratch76 >> 8 << 8)) & 0xFFFFF0FF) & 0xFFFF0FFF) & 0xFFF0FFFF) & 0xFF0FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0x3FFFFFF; -// tmp = (sdram->emc_pmacro_tx_pwrd0 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd0 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd0 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd0 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd0 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd0 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd0 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd0 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd0 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd0 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd0 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd0 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd0 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd0 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd0 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd0 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd0 & 1 | 2 * (pmc->scratch77 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF; -// pmc->scratch77 = (sdram->emc_r2w << 26) | ((4 * sdram->emc_pmacro_tx_pwrd0 >> 31 << 25) | ((8 * sdram->emc_pmacro_tx_pwrd0 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd0 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd0 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd0 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd0 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd0 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd0 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd0 << 11 >> 31 << 17) | tmp & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0x3FFFFFF; -// tmp = ((8 * sdram->emc_pmacro_tx_pwrd1 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd1 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd1 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd1 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd1 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd1 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd1 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd1 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd1 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd1 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd1 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd1 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd1 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd1 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd1 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd1 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd1 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd1 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd1 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd1 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd1 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd1 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd1 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd1 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd1 & 1 | 2 * (pmc->scratch78 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF; -// pmc->scratch78 = (sdram->emc_w2r << 26) | ((4 * sdram->emc_pmacro_tx_pwrd1 >> 31 << 25) | tmp) & 0x3FFFFFF; -// tmp = ((8 * sdram->emc_pmacro_tx_pwrd2 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd2 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd2 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd2 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd2 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd2 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd2 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd2 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd2 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd2 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd2 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd2 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd2 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd2 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd2 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd2 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd2 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd2 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd2 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd2 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd2 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd2 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd2 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd2 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd2 & 1 | 2 * (pmc->scratch79 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF; -// pmc->scratch79 = (sdram->emc_r2p << 26) | ((4 * sdram->emc_pmacro_tx_pwrd2 >> 31 << 25) | tmp) & 0x3FFFFFF; -// tmp = (sdram->emc_pmacro_tx_pwrd3 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd3 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd3 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd3 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd3 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd3 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd3 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd3 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd3 & 1 | 2 * (pmc->scratch80 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF; -// pmc->scratch80 = ((u8)(sdram->emc_ccdmw) << 26) | ((4 * sdram->emc_pmacro_tx_pwrd3 >> 31 << 25) | ((8 * sdram->emc_pmacro_tx_pwrd3 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd3 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd3 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd3 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd3 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd3 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd3 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd3 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd3 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd3 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd3 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd3 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd3 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd3 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd3 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd3 << 22 >> 31 << 9) | tmp & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0x3FFFFFF; -// tmp = ((8 * sdram->emc_pmacro_tx_pwrd4 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd4 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd4 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd4 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd4 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd4 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd4 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd4 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd4 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd4 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd4 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd4 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd4 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd4 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd4 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd4 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd4 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd4 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd4 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd4 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd4 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd4 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd4 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd4 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd4 & 1 | 2 * (pmc->scratch81 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF; -// pmc->scratch81 = ((u8)(sdram->emc_rd_rcd) << 26) | ((4 * sdram->emc_pmacro_tx_pwrd4 >> 31 << 25) | tmp) & 0x3FFFFFF; -// tmp = ((8 * sdram->emc_pmacro_tx_pwrd5 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd5 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd5 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd5 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd5 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd5 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd5 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd5 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd5 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd5 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd5 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd5 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd5 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd5 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd5 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd5 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd5 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd5 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd5 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd5 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd5 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd5 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd5 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd5 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd5 & 1 | 2 * (pmc->scratch82 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF; -// pmc->scratch82 = ((u16)(sdram->emc_wr_rcd) << 26) | ((4 * sdram->emc_pmacro_tx_pwrd5 >> 31 << 25) | tmp) & 0x3FFFFFF; -// pmc->scratch83 = ((u8)(sdram->emc_config_sample_delay) << 25) | ((sdram->emc_auto_cal_channel >> 31 << 24) | ((2 * sdram->emc_auto_cal_channel >> 31 << 23) | ((4 * sdram->emc_auto_cal_channel >> 31 << 22) | ((16 * sdram->emc_auto_cal_channel >> 25 << 15) | ((sdram->emc_auto_cal_channel << 11 >> 27 << 10) | ((sdram->emc_auto_cal_channel << 20 >> 28 << 6) | (sdram->emc_auto_cal_channel & 0x3F | (pmc->scratch83 >> 6 << 6)) & 0xFFFFFC3F) & 0xFFFF83FF) & 0xFFC07FFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0x1FFFFFF; -// pmc->scratch84 = (sdram->emc_sel_dpd_ctrl << 13 >> 29 << 29) | ((sdram->emc_sel_dpd_ctrl << 23 >> 31 << 28) | ((sdram->emc_sel_dpd_ctrl << 26 >> 31 << 27) | ((sdram->emc_sel_dpd_ctrl << 27 >> 31 << 26) | ((sdram->emc_sel_dpd_ctrl << 28 >> 31 << 25) | ((sdram->emc_sel_dpd_ctrl << 29 >> 31 << 24) | ((4 * sdram->emc_pmacro_rx_term >> 26 << 18) | ((sdram->emc_pmacro_rx_term << 10 >> 26 << 12) | ((sdram->emc_pmacro_rx_term << 18 >> 26 << 6) | (sdram->emc_pmacro_rx_term & 0x3F | (pmc->scratch84 >> 6 << 6)) & 0xFFFFF03F) & 0xFFFC0FFF) & 0xFF03FFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF; -// pmc->scratch85 = (4 * sdram->emc_obdly >> 30 << 30) | (4 * ((sdram->emc_obdly << 24) | ((4 * sdram->emc_pmacro_dq_tx_drive >> 26 << 18) | ((sdram->emc_pmacro_dq_tx_drive << 10 >> 26 << 12) | ((sdram->emc_pmacro_dq_tx_drive << 18 >> 26 << 6) | (sdram->emc_pmacro_dq_tx_drive & 0x3F | (pmc->scratch85 >> 6 << 6)) & 0xFFFFF03F) & 0xFFFC0FFF) & 0xFF03FFFF) & 0xC0FFFFFF) >> 2); -// pmc->scratch86 = (sdram->emc_pmacro_vttgen_ctrl1 << 10 >> 30 << 30) | (4 * ((sdram->emc_pmacro_vttgen_ctrl1 << 16 >> 26 << 24) | ((4 * sdram->emc_pmacro_ca_tx_drive >> 26 << 18) | ((sdram->emc_pmacro_ca_tx_drive << 10 >> 26 << 12) | ((sdram->emc_pmacro_ca_tx_drive << 18 >> 26 << 6) | (sdram->emc_pmacro_ca_tx_drive & 0x3F | (pmc->scratch86 >> 6 << 6)) & 0xFFFFF03F) & 0xFFFC0FFF) & 0xFF03FFFF) & 0xC0FFFFFF) >> 2); -// pmc->scratch87 = (sdram->emc_pmacro_vttgen_ctrl2 >> 16 << 24) | ((16 * sdram->emc_pmacro_zcrtl >> 30 << 22) | ((sdram->emc_pmacro_zcrtl << 6 >> 30 << 20) | ((sdram->emc_pmacro_zcrtl << 8 >> 30 << 18) | ((sdram->emc_pmacro_zcrtl << 10 >> 30 << 16) | ((sdram->emc_pmacro_zcrtl << 12 >> 30 << 14) | ((sdram->emc_pmacro_zcrtl << 14 >> 30 << 12) | ((sdram->emc_pmacro_zcrtl << 16 >> 30 << 10) | ((sdram->emc_pmacro_zcrtl << 18 >> 30 << 8) | ((sdram->emc_pmacro_zcrtl << 20 >> 30 << 6) | (16 * (sdram->emc_pmacro_zcrtl << 22 >> 30) | (4 * (sdram->emc_pmacro_zcrtl << 24 >> 30) | ((sdram->emc_pmacro_zcrtl << 26 >> 30) | 4 * (pmc->scratch87 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFFFFFF; -// pmc->scratch88 = (sdram->mc_emem_arb_timing_rc << 24) | ((sdram->emc_zcal_interval << 14) | ((sdram->emc_zcal_interval << 8 >> 18) | (pmc->scratch88 >> 14 << 14)) & 0xFF003FFF) & 0xFFFFFF; -// pmc->scratch89 = ((u16)(sdram->mc_emem_arb_rsv) << 24) | ((sdram->emc_data_brlshft0 << 8 >> 29 << 21) | ((sdram->emc_data_brlshft0 << 11 >> 29 << 18) | ((sdram->emc_data_brlshft0 << 14 >> 29 << 15) | ((sdram->emc_data_brlshft0 << 17 >> 29 << 12) | ((sdram->emc_data_brlshft0 << 20 >> 29 << 9) | ((sdram->emc_data_brlshft0 << 23 >> 29 << 6) | (8 * (sdram->emc_data_brlshft0 << 26 >> 29) | (sdram->emc_data_brlshft0 & 7 | 8 * (pmc->scratch89 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0xFFFFFF; -// pmc->scratch90 = (sdram->emc_data_brlshft1 << 8 >> 29 << 21) | ((sdram->emc_data_brlshft1 << 11 >> 29 << 18) | ((sdram->emc_data_brlshft1 << 14 >> 29 << 15) | ((sdram->emc_data_brlshft1 << 17 >> 29 << 12) | ((sdram->emc_data_brlshft1 << 20 >> 29 << 9) | ((sdram->emc_data_brlshft1 << 23 >> 29 << 6) | (8 * (sdram->emc_data_brlshft1 << 26 >> 29) | (sdram->emc_data_brlshft1 & 7 | 8 * (pmc->scratch90 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF; -// pmc->scratch91 = (sdram->emc_dqs_brlshft0 << 8 >> 29 << 21) | ((sdram->emc_dqs_brlshft0 << 11 >> 29 << 18) | ((sdram->emc_dqs_brlshft0 << 14 >> 29 << 15) | ((sdram->emc_dqs_brlshft0 << 17 >> 29 << 12) | ((sdram->emc_dqs_brlshft0 << 20 >> 29 << 9) | ((sdram->emc_dqs_brlshft0 << 23 >> 29 << 6) | (8 * (sdram->emc_dqs_brlshft0 << 26 >> 29) | (sdram->emc_dqs_brlshft0 & 7 | 8 * (pmc->scratch91 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF; -// pmc->scratch92 = (sdram->emc_dqs_brlshft1 << 8 >> 29 << 21) | ((sdram->emc_dqs_brlshft1 << 11 >> 29 << 18) | ((sdram->emc_dqs_brlshft1 << 14 >> 29 << 15) | ((sdram->emc_dqs_brlshft1 << 17 >> 29 << 12) | ((sdram->emc_dqs_brlshft1 << 20 >> 29 << 9) | ((sdram->emc_dqs_brlshft1 << 23 >> 29 << 6) | (8 * (sdram->emc_dqs_brlshft1 << 26 >> 29) | (sdram->emc_dqs_brlshft1 & 7 | 8 * (pmc->scratch92 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF; -// pmc->scratch93 = (2 * sdram->emc_swizzle_rank0_byte0 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank0_byte0 >> 29 << 18) | ((sdram->emc_swizzle_rank0_byte0 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank0_byte0 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank0_byte0 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank0_byte0 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank0_byte0 << 25 >> 29) | (sdram->emc_swizzle_rank0_byte0 & 7 | 8 * (pmc->scratch93 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF; -// pmc->scratch94 = ((u8)(sdram->emc_cfg) << 27 >> 31 << 31) | (2 * ((sdram->emc_ras << 24) | ((2 * sdram->emc_swizzle_rank0_byte1 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank0_byte1 >> 29 << 18) | ((sdram->emc_swizzle_rank0_byte1 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank0_byte1 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank0_byte1 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank0_byte1 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank0_byte1 << 25 >> 29) | (sdram->emc_swizzle_rank0_byte1 & 7 | 8 * (pmc->scratch94 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); -// pmc->scratch95 = ((u8)(sdram->emc_cfg) << 26 >> 31 << 31) | (2 * ((sdram->emc_w2p << 24) | ((2 * sdram->emc_swizzle_rank0_byte2 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank0_byte2 >> 29 << 18) | ((sdram->emc_swizzle_rank0_byte2 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank0_byte2 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank0_byte2 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank0_byte2 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank0_byte2 << 25 >> 29) | (sdram->emc_swizzle_rank0_byte2 & 7 | 8 * (pmc->scratch95 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); -// pmc->scratch96 = ((u8)(sdram->emc_cfg) << 25 >> 31 << 31) | (2 * ((sdram->emc_qsafe << 24) | ((2 * sdram->emc_swizzle_rank0_byte3 >> 29 << 21) | (((sdram->emc_swizzle_rank0_byte3 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank0_byte3 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank0_byte3 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank0_byte3 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank0_byte3 << 25 >> 29) | (sdram->emc_swizzle_rank0_byte3 & 7 | 8 * (pmc->scratch96 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF | (32 * sdram->emc_swizzle_rank0_byte3 >> 29 << 18)) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); -// pmc->scratch97 = ((u8)(sdram->emc_cfg) << 24 >> 31 << 31) | (2 * ((sdram->emc_rdv << 24) | ((2 * sdram->emc_swizzle_rank1_byte0 >> 29 << 21) | (((sdram->emc_swizzle_rank1_byte0 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank1_byte0 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank1_byte0 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank1_byte0 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank1_byte0 << 25 >> 29) | (sdram->emc_swizzle_rank1_byte0 & 7 | 8 * (pmc->scratch97 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF | (32 * sdram->emc_swizzle_rank1_byte0 >> 29 << 18)) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); -// pmc->scratch98 = ((u16)(sdram->emc_cfg) << 23 >> 31 << 31) | (2 * (((u16)(sdram->emc_rw2pden) << 24) | ((2 * sdram->emc_swizzle_rank1_byte1 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank1_byte1 >> 29 << 18) | ((sdram->emc_swizzle_rank1_byte1 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank1_byte1 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank1_byte1 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank1_byte1 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank1_byte1 << 25 >> 29) | (sdram->emc_swizzle_rank1_byte1 & 7 | 8 * (pmc->scratch98 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); -// pmc->scratch99 = ((u16)(sdram->emc_cfg) << 22 >> 31 << 31) | (2 * ((sdram->emc_tfaw << 24) | ((2 * sdram->emc_swizzle_rank1_byte2 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank1_byte2 >> 29 << 18) | ((sdram->emc_swizzle_rank1_byte2 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank1_byte2 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank1_byte2 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank1_byte2 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank1_byte2 << 25 >> 29) | (sdram->emc_swizzle_rank1_byte2 & 7 | 8 * (pmc->scratch99 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); -// pmc->scratch100 = (sdram->emc_cfg << 13 >> 31 << 31) | (2 * ((sdram->emc_tclkstable << 24) | ((2 * sdram->emc_swizzle_rank1_byte3 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank1_byte3 >> 29 << 18) | ((sdram->emc_swizzle_rank1_byte3 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank1_byte3 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank1_byte3 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank1_byte3 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank1_byte3 << 25 >> 29) | (sdram->emc_swizzle_rank1_byte3 & 7 | 8 * (pmc->scratch100 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); -// tmp = 2 * (((u8)(sdram->emc_trtm) << 24) | ((16 * sdram->emc_cfg_pipe2 >> 31 << 23) | ((32 * sdram->emc_cfg_pipe2 >> 31 << 22) | ((sdram->emc_cfg_pipe2 << 6 >> 31 << 21) | ((sdram->emc_cfg_pipe2 << 7 >> 31 << 20) | ((sdram->emc_cfg_pipe2 << 8 >> 31 << 19) | ((sdram->emc_cfg_pipe2 << 9 >> 31 << 18) | ((sdram->emc_cfg_pipe2 << 10 >> 31 << 17) | ((sdram->emc_cfg_pipe2 << 11 >> 31 << 16) | ((sdram->emc_cfg_pipe2 << 12 >> 31 << 15) | ((sdram->emc_cfg_pipe2 << 13 >> 31 << 14) | ((sdram->emc_cfg_pipe2 << 14 >> 31 << 13) | ((sdram->emc_cfg_pipe2 << 15 >> 31 << 12) | ((sdram->emc_cfg_pipe2 << 20 >> 31 << 11) | ((sdram->emc_cfg_pipe2 << 21 >> 31 << 10) | ((sdram->emc_cfg_pipe2 << 22 >> 31 << 9) | ((sdram->emc_cfg_pipe2 << 23 >> 31 << 8) | ((sdram->emc_cfg_pipe2 << 24 >> 31 << 7) | ((sdram->emc_cfg_pipe2 << 25 >> 31 << 6) | (32 * (sdram->emc_cfg_pipe2 << 26 >> 31) | (16 * (sdram->emc_cfg_pipe2 << 27 >> 31) | (8 * (sdram->emc_cfg_pipe2 << 28 >> 31) | (4 * (sdram->emc_cfg_pipe2 << 29 >> 31) | (2 * (sdram->emc_cfg_pipe2 << 30 >> 31) | (sdram->emc_cfg_pipe2 & 1 | 2 * (pmc->scratch101 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1; -// pmc->scratch101 = (sdram->emc_cfg << 10 >> 31 << 31) | tmp; -// tmp = (2 * (pmc->scratch102 >> 1) | sdram->emc_cfg_pipe1 & 1) & 0xFFFFFFFD; -// pmc->scratch102 = (sdram->emc_cfg << 9 >> 31 << 31) | (2 * (((u8)(sdram->emc_twtm) << 24) | ((16 * sdram->emc_cfg_pipe1 >> 31 << 23) | ((32 * sdram->emc_cfg_pipe1 >> 31 << 22) | ((sdram->emc_cfg_pipe1 << 6 >> 31 << 21) | ((sdram->emc_cfg_pipe1 << 7 >> 31 << 20) | ((sdram->emc_cfg_pipe1 << 8 >> 31 << 19) | ((sdram->emc_cfg_pipe1 << 9 >> 31 << 18) | ((sdram->emc_cfg_pipe1 << 10 >> 31 << 17) | ((sdram->emc_cfg_pipe1 << 11 >> 31 << 16) | ((sdram->emc_cfg_pipe1 << 12 >> 31 << 15) | ((sdram->emc_cfg_pipe1 << 13 >> 31 << 14) | ((sdram->emc_cfg_pipe1 << 14 >> 31 << 13) | ((sdram->emc_cfg_pipe1 << 15 >> 31 << 12) | ((sdram->emc_cfg_pipe1 << 20 >> 31 << 11) | ((sdram->emc_cfg_pipe1 << 21 >> 31 << 10) | ((sdram->emc_cfg_pipe1 << 22 >> 31 << 9) | ((sdram->emc_cfg_pipe1 << 23 >> 31 << 8) | ((sdram->emc_cfg_pipe1 << 24 >> 31 << 7) | ((sdram->emc_cfg_pipe1 << 25 >> 31 << 6) | (32 * (sdram->emc_cfg_pipe1 << 26 >> 31) | (16 * (sdram->emc_cfg_pipe1 << 27 >> 31) | (8 * (sdram->emc_cfg_pipe1 << 28 >> 31) | (4 * (sdram->emc_cfg_pipe1 << 29 >> 31) | (2 * (sdram->emc_cfg_pipe1 << 30 >> 31) | tmp) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1); -// tmp = 2 * (((u8)(sdram->emc_tratm) << 24) | ((sdram->emc_pmacro_ddll_pwrd0 >> 31 << 23) | ((2 * sdram->emc_pmacro_ddll_pwrd0 >> 31 << 22) | ((8 * sdram->emc_pmacro_ddll_pwrd0 >> 31 << 21) | ((16 * sdram->emc_pmacro_ddll_pwrd0 >> 31 << 20) | ((32 * sdram->emc_pmacro_ddll_pwrd0 >> 31 << 19) | ((sdram->emc_pmacro_ddll_pwrd0 << 6 >> 31 << 18) | ((sdram->emc_pmacro_ddll_pwrd0 << 8 >> 31 << 17) | ((sdram->emc_pmacro_ddll_pwrd0 << 9 >> 31 << 16) | ((sdram->emc_pmacro_ddll_pwrd0 << 11 >> 31 << 15) | ((sdram->emc_pmacro_ddll_pwrd0 << 12 >> 31 << 14) | ((sdram->emc_pmacro_ddll_pwrd0 << 13 >> 31 << 13) | ((sdram->emc_pmacro_ddll_pwrd0 << 14 >> 31 << 12) | ((sdram->emc_pmacro_ddll_pwrd0 << 16 >> 31 << 11) | ((sdram->emc_pmacro_ddll_pwrd0 << 17 >> 31 << 10) | ((sdram->emc_pmacro_ddll_pwrd0 << 19 >> 31 << 9) | ((sdram->emc_pmacro_ddll_pwrd0 << 20 >> 31 << 8) | ((sdram->emc_pmacro_ddll_pwrd0 << 21 >> 31 << 7) | ((sdram->emc_pmacro_ddll_pwrd0 << 22 >> 31 << 6) | (32 * (sdram->emc_pmacro_ddll_pwrd0 << 24 >> 31) | (16 * (sdram->emc_pmacro_ddll_pwrd0 << 25 >> 31) | (8 * (sdram->emc_pmacro_ddll_pwrd0 << 27 >> 31) | (4 * (sdram->emc_pmacro_ddll_pwrd0 << 28 >> 31) | (2 * (sdram->emc_pmacro_ddll_pwrd0 << 29 >> 31) | ((sdram->emc_pmacro_ddll_pwrd0 << 30 >> 31) | 2 * (pmc->scratch103 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1; -// pmc->scratch103 = (sdram->emc_cfg << 8 >> 31 << 31) | tmp; -// tmp = 2 * (((u8)(sdram->emc_twatm) << 24) | ((sdram->emc_pmacro_ddll_pwrd1 >> 31 << 23) | ((2 * sdram->emc_pmacro_ddll_pwrd1 >> 31 << 22) | ((8 * sdram->emc_pmacro_ddll_pwrd1 >> 31 << 21) | ((16 * sdram->emc_pmacro_ddll_pwrd1 >> 31 << 20) | ((32 * sdram->emc_pmacro_ddll_pwrd1 >> 31 << 19) | ((sdram->emc_pmacro_ddll_pwrd1 << 6 >> 31 << 18) | ((sdram->emc_pmacro_ddll_pwrd1 << 8 >> 31 << 17) | ((sdram->emc_pmacro_ddll_pwrd1 << 9 >> 31 << 16) | ((sdram->emc_pmacro_ddll_pwrd1 << 11 >> 31 << 15) | ((sdram->emc_pmacro_ddll_pwrd1 << 12 >> 31 << 14) | ((sdram->emc_pmacro_ddll_pwrd1 << 13 >> 31 << 13) | ((sdram->emc_pmacro_ddll_pwrd1 << 14 >> 31 << 12) | ((sdram->emc_pmacro_ddll_pwrd1 << 16 >> 31 << 11) | ((sdram->emc_pmacro_ddll_pwrd1 << 17 >> 31 << 10) | ((sdram->emc_pmacro_ddll_pwrd1 << 19 >> 31 << 9) | ((sdram->emc_pmacro_ddll_pwrd1 << 20 >> 31 << 8) | ((sdram->emc_pmacro_ddll_pwrd1 << 21 >> 31 << 7) | ((sdram->emc_pmacro_ddll_pwrd1 << 22 >> 31 << 6) | (32 * (sdram->emc_pmacro_ddll_pwrd1 << 24 >> 31) | (16 * (sdram->emc_pmacro_ddll_pwrd1 << 25 >> 31) | (8 * (sdram->emc_pmacro_ddll_pwrd1 << 27 >> 31) | (4 * (sdram->emc_pmacro_ddll_pwrd1 << 28 >> 31) | (2 * (sdram->emc_pmacro_ddll_pwrd1 << 29 >> 31) | ((sdram->emc_pmacro_ddll_pwrd1 << 30 >> 31) | 2 * (pmc->scratch104 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1; -// pmc->scratch104 = (sdram->emc_cfg << 7 >> 31 << 31) | tmp; -// tmp = (sdram->emc_pmacro_ddll_pwrd2 << 22 >> 31 << 6) | (32 * (sdram->emc_pmacro_ddll_pwrd2 << 24 >> 31) | (16 * (sdram->emc_pmacro_ddll_pwrd2 << 25 >> 31) | (8 * (sdram->emc_pmacro_ddll_pwrd2 << 27 >> 31) | (4 * (sdram->emc_pmacro_ddll_pwrd2 << 28 >> 31) | (2 * (sdram->emc_pmacro_ddll_pwrd2 << 29 >> 31) | ((sdram->emc_pmacro_ddll_pwrd2 << 30 >> 31) | 2 * (pmc->scratch105 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF; -// pmc->scratch105 = (sdram->emc_cfg << 6 >> 31 << 31) | (2 * (((u8)(sdram->emc_tr2ref) << 24) | ((sdram->emc_pmacro_ddll_pwrd2 >> 31 << 23) | ((2 * sdram->emc_pmacro_ddll_pwrd2 >> 31 << 22) | ((8 * sdram->emc_pmacro_ddll_pwrd2 >> 31 << 21) | ((16 * sdram->emc_pmacro_ddll_pwrd2 >> 31 << 20) | ((32 * sdram->emc_pmacro_ddll_pwrd2 >> 31 << 19) | ((sdram->emc_pmacro_ddll_pwrd2 << 6 >> 31 << 18) | ((sdram->emc_pmacro_ddll_pwrd2 << 8 >> 31 << 17) | ((sdram->emc_pmacro_ddll_pwrd2 << 9 >> 31 << 16) | ((sdram->emc_pmacro_ddll_pwrd2 << 11 >> 31 << 15) | ((sdram->emc_pmacro_ddll_pwrd2 << 12 >> 31 << 14) | ((sdram->emc_pmacro_ddll_pwrd2 << 13 >> 31 << 13) | ((sdram->emc_pmacro_ddll_pwrd2 << 14 >> 31 << 12) | ((sdram->emc_pmacro_ddll_pwrd2 << 16 >> 31 << 11) | ((sdram->emc_pmacro_ddll_pwrd2 << 17 >> 31 << 10) | ((sdram->emc_pmacro_ddll_pwrd2 << 19 >> 31 << 9) | ((sdram->emc_pmacro_ddll_pwrd2 << 20 >> 31 << 8) | ((sdram->emc_pmacro_ddll_pwrd2 << 21 >> 31 << 7) | tmp & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1); -// pmc->scratch106 = (32 * sdram->emc_cfg >> 31 << 31) | (2 * (((u16)(sdram->emc_pdex2mrr) << 24) | ((8 * sdram->emc_pmacro_ddll_periodic_offset >> 31 << 23) | ((16 * sdram->emc_pmacro_ddll_periodic_offset >> 31 << 22) | ((32 * sdram->emc_pmacro_ddll_periodic_offset >> 31 << 21) | ((sdram->emc_pmacro_ddll_periodic_offset << 6 >> 31 << 20) | ((sdram->emc_pmacro_ddll_periodic_offset << 7 >> 31 << 19) | ((sdram->emc_pmacro_ddll_periodic_offset << 8 >> 31 << 18) | ((sdram->emc_pmacro_ddll_periodic_offset << 9 >> 31 << 17) | ((sdram->emc_pmacro_ddll_periodic_offset << 10 >> 31 << 16) | ((sdram->emc_pmacro_ddll_periodic_offset << 11 >> 31 << 15) | ((sdram->emc_pmacro_ddll_periodic_offset << 15 >> 31 << 14) | ((sdram->emc_pmacro_ddll_periodic_offset << 16 >> 31 << 13) | ((sdram->emc_pmacro_ddll_periodic_offset << 17 >> 31 << 12) | ((sdram->emc_pmacro_ddll_periodic_offset << 18 >> 31 << 11) | ((sdram->emc_pmacro_ddll_periodic_offset << 19 >> 31 << 10) | ((sdram->emc_pmacro_ddll_periodic_offset << 20 >> 31 << 9) | ((sdram->emc_pmacro_ddll_periodic_offset << 21 >> 31 << 8) | ((sdram->emc_pmacro_ddll_periodic_offset << 22 >> 31 << 7) | ((sdram->emc_pmacro_ddll_periodic_offset << 23 >> 31 << 6) | (sdram->emc_pmacro_ddll_periodic_offset & 0x3F | (pmc->scratch106 >> 6 << 6)) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1); -// pmc->scratch107 = (8 * sdram->emc_cfg >> 31 << 31) | (2 * ((sdram->emc_clken_override << 15 >> 31 << 30) | ((sdram->emc_clken_override << 23 >> 31 << 29) | ((sdram->emc_clken_override << 24 >> 31 << 28) | ((sdram->emc_clken_override << 25 >> 31 << 27) | ((sdram->emc_clken_override << 28 >> 31 << 26) | ((sdram->emc_clken_override << 29 >> 31 << 25) | ((sdram->emc_clken_override << 30 >> 31 << 24) | ((sdram->mc_emem_arb_da_covers << 8 >> 24 << 16) | ((sdram->mc_emem_arb_da_covers << 16 >> 24 << 8) | (sdram->mc_emem_arb_da_covers & 0xFF | (pmc->scratch107 >> 8 << 8)) & 0xFFFF00FF) & 0xFF00FFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch108 = (sdram->emc_rfc_pb << 23) | ((sdram->emc_xm2_comp_pad_ctrl >> 24 << 15) | ((sdram->emc_xm2_comp_pad_ctrl << 12 >> 24 << 7) | ((sdram->emc_xm2_comp_pad_ctrl << 20 >> 31 << 6) | (32 * (sdram->emc_xm2_comp_pad_ctrl << 22 >> 31) | (4 * (sdram->emc_xm2_comp_pad_ctrl << 25 >> 29) | (sdram->emc_xm2_comp_pad_ctrl & 3 | 4 * (pmc->scratch108 >> 2)) & 0xFFFFFFE3) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFF807F) & 0xFF807FFF) & 0x7FFFFF; -// pmc->scratch109 = (sdram->emc_cfg_update >> 31 << 31) | (2 * ((2 * sdram->emc_cfg_update >> 31 << 30) | ((4 * sdram->emc_cfg_update >> 31 << 29) | ((8 * sdram->emc_cfg_update >> 31 << 28) | ((sdram->emc_cfg_update << 21 >> 30 << 26) | ((sdram->emc_cfg_update << 23 >> 31 << 25) | ((sdram->emc_cfg_update << 29 >> 30 << 23) | ((sdram->emc_cfg_update << 22) & 0x7FFFFF | ((sdram->emc_auto_cal_config3 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config3 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config3 << 17 >> 25 << 7) | ((pmc->scratch109 >> 7 << 7) | sdram->emc_auto_cal_config3 & 0x7F) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFE7FFFFF) & 0xFDFFFFFF) & 0xF3FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch110 = (sdram->emc_rfc << 22) | ((sdram->emc_auto_cal_config4 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config4 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config4 << 17 >> 25 << 7) | (sdram->emc_auto_cal_config4 & 0x7F | (pmc->scratch110 >> 7 << 7)) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0x3FFFFF; -// pmc->scratch111 = ((u16)(sdram->emc_txsr) << 22) | ((sdram->emc_auto_cal_config5 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config5 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config5 << 17 >> 25 << 7) | ((pmc->scratch111 >> 7 << 7) | sdram->emc_auto_cal_config5 & 0x7F) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0x3FFFFF; -// pmc->scratch112 = (16 * sdram->emc_mc2emc_q >> 28 << 28) | ((sdram->emc_mc2emc_q << 21 >> 29 << 25) | ((sdram->emc_mc2emc_q << 22) & 0x1FFFFFF | ((sdram->emc_auto_cal_config6 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config6 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config6 << 17 >> 25 << 7) | (sdram->emc_auto_cal_config6 & 0x7F | (pmc->scratch112 >> 7 << 7)) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xFFFFFFF; -// pmc->scratch113 = (sdram->mc_emem_arb_ring1_throttle << 11 >> 27 << 27) | ((sdram->mc_emem_arb_ring1_throttle << 22) | ((sdram->emc_auto_cal_config7 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config7 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config7 << 17 >> 25 << 7) | (sdram->emc_auto_cal_config7 & 0x7F | (pmc->scratch113 >> 7 << 7)) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xF83FFFFF) & 0x7FFFFFF; -// pmc->scratch114 = (sdram->emc_auto_cal_config8 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config8 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config8 << 17 >> 25 << 7) | (sdram->emc_auto_cal_config8 & 0x7F | (pmc->scratch114 >> 7 << 7)) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF; -// pmc->scratch115 = (4 * sdram->emc_cfg >> 31 << 31) | (2 * (((u16)(sdram->emc_ar2pden) << 22) | ((sdram->emc_fbio_cfg7 << 10 >> 30 << 20) | ((sdram->emc_fbio_cfg7 << 12 >> 31 << 19) | ((sdram->emc_fbio_cfg7 << 13 >> 31 << 18) | ((sdram->emc_fbio_cfg7 << 14 >> 31 << 17) | ((sdram->emc_fbio_cfg7 << 15 >> 31 << 16) | ((sdram->emc_fbio_cfg7 << 16 >> 31 << 15) | ((sdram->emc_fbio_cfg7 << 17 >> 31 << 14) | ((sdram->emc_fbio_cfg7 << 18 >> 31 << 13) | ((sdram->emc_fbio_cfg7 << 19 >> 31 << 12) | ((sdram->emc_fbio_cfg7 << 20 >> 31 << 11) | ((sdram->emc_fbio_cfg7 << 21 >> 31 << 10) | ((sdram->emc_fbio_cfg7 << 22 >> 31 << 9) | ((sdram->emc_fbio_cfg7 << 23 >> 31 << 8) | ((sdram->emc_fbio_cfg7 << 24 >> 31 << 7) | ((sdram->emc_fbio_cfg7 << 25 >> 31 << 6) | (32 * (sdram->emc_fbio_cfg7 << 26 >> 31) | (16 * (sdram->emc_fbio_cfg7 << 27 >> 31) | (8 * (sdram->emc_fbio_cfg7 << 28 >> 31) | (4 * (sdram->emc_fbio_cfg7 << 29 >> 31) | (2 * (sdram->emc_fbio_cfg7 << 30 >> 31) | (sdram->emc_fbio_cfg7 & 1 | 2 * (pmc->scratch115 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFCFFFFF) & 0x803FFFFF) >> 1); -// pmc->scratch123 = (2 * sdram->emc_cfg >> 31 << 31) | (2 * ((sdram->emc_rfc_slr << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank0_0 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_0 & 0x7FF | (pmc->scratch123 >> 11 << 11)) & 0xFFC007FF) & 0x803FFFFF) >> 1); -// pmc->scratch124 = (sdram->emc_cfg >> 31 << 31) | (2 * ((4 * sdram->emc_ibdly >> 30 << 29) | ((sdram->emc_ibdly << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank0_1 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_1 & 0x7FF | (pmc->scratch124 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1); -// pmc->scratch125 = (sdram->emc_fbio_cfg5 << 27 >> 31 << 31) | (2 * (((u16)(sdram->mc_emem_arb_timing_rfcpb) << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank0_2 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_2 & 0x7FF | (pmc->scratch125 >> 11 << 11)) & 0xFFC007FF) & 0x803FFFFF) >> 1); -// pmc->scratch126 = (sdram->emc_fbio_cfg5 << 16 >> 29 << 29) | ((sdram->emc_auto_cal_config9 << 25 >> 31 << 28) | ((sdram->emc_auto_cal_config9 << 26 >> 31 << 27) | ((sdram->emc_auto_cal_config9 << 27 >> 31 << 26) | ((sdram->emc_auto_cal_config9 << 28 >> 31 << 25) | ((sdram->emc_auto_cal_config9 << 29 >> 31 << 24) | ((sdram->emc_auto_cal_config9 << 30 >> 31 << 23) | ((sdram->emc_auto_cal_config9 << 22) & 0x7FFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank0_3 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_3 & 0x7FF | (pmc->scratch126 >> 11 << 11)) & 0xFFC007FF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF; -// pmc->scratch127 = ((u8)(sdram->emc_cfg2) << 26 >> 29 << 29) | ((sdram->emc_rdv_mask << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank0_4 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_4 & 0x7FF | (pmc->scratch127 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF; -// pmc->scratch128 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 27 >> 29 << 29) | (((u8)(sdram->emc_rdv_early_mask) << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank0_5 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_5 & 0x7FF | (pmc->scratch128 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF; -// pmc->scratch129 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 22 >> 29 << 29) | ((sdram->emc_rdv_early << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank1_0 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_0 & 0x7FF | (pmc->scratch129 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF; -// pmc->scratch130 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 17 >> 29 << 29) | ((4 * sdram->emc_quse_width >> 31 << 28) | ((8 * sdram->emc_quse_width >> 31 << 27) | ((sdram->emc_quse_width << 22) & 0x7FFFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank1_1 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_1 & 0x7FF | (pmc->scratch130 >> 11 << 11)) & 0xFFC007FF) & 0xF83FFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF; -// pmc->scratch131 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 12 >> 29 << 29) | (((u16)(sdram->emc_pmacro_ddll_short_cmd_2) << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank1_2 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_2 & 0x7FF | (pmc->scratch131 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF; -// pmc->scratch132 = (sdram->emc_pmacro_data_pad_tx_ctrl << 27 >> 29 << 29) | ((sdram->emc_pmacro_cmd_rx_term_mode << 18 >> 31 << 28) | ((sdram->emc_pmacro_cmd_rx_term_mode << 22 >> 30 << 26) | ((sdram->emc_pmacro_cmd_rx_term_mode << 26 >> 30 << 24) | ((sdram->emc_pmacro_cmd_rx_term_mode << 22) & 0xFFFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank1_3 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_3 & 0x7FF | (pmc->scratch132 >> 11 << 11)) & 0xFFC007FF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF; -// pmc->scratch133 = (sdram->emc_pmacro_data_pad_tx_ctrl << 22 >> 29 << 29) | ((sdram->emc_pmacro_data_rx_term_mode << 18 >> 31 << 28) | ((sdram->emc_pmacro_data_rx_term_mode << 22 >> 30 << 26) | ((sdram->emc_pmacro_data_rx_term_mode << 26 >> 30 << 24) | ((sdram->emc_pmacro_data_rx_term_mode << 22) & 0xFFFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank1_4 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_4 & 0x7FF | (pmc->scratch133 >> 11 << 11)) & 0xFFC007FF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF; -// pmc->scratch134 = (sdram->emc_pmacro_data_pad_tx_ctrl << 17 >> 29 << 29) | ((sdram->mc_emem_arb_timing_rp << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank1_5 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_5 & 0x7FF | (pmc->scratch134 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF; -// pmc->scratch135 = (sdram->emc_pmacro_data_pad_tx_ctrl << 12 >> 29 << 29) | ((sdram->mc_emem_arb_timing_ras << 22) | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_0 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_0 & 0x7FF | (pmc->scratch135 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF; -// pmc->scratch136 = (sdram->emc_fbio_cfg5 << 23 >> 31 << 31) | (2 * ((sdram->emc_cfg << 14 >> 30 << 29) | ((sdram->mc_emem_arb_timing_faw << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_1 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_1 & 0x7FF | (pmc->scratch136 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1); -// pmc->scratch137 = (sdram->emc_fbio_cfg5 << 21 >> 31 << 31) | (2 * ((sdram->emc_fbio_cfg5 << 29) | ((sdram->mc_emem_arb_timing_rap2pre << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_2 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_2 & 0x7FF | (pmc->scratch137 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1); -// pmc->scratch138 = (sdram->emc_fbio_cfg5 << 19 >> 31 << 31) | (2 * ((sdram->emc_fbio_cfg5 << 28 >> 30 << 29) | ((sdram->mc_emem_arb_timing_wap2pre << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_3 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_3 & 0x7FF | (pmc->scratch138 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1); -// pmc->scratch139 = (sdram->emc_fbio_cfg5 << 7 >> 31 << 31) | (2 * ((16 * sdram->emc_cfg2 >> 30 << 29) | (((u8)(sdram->mc_emem_arb_timing_r2w) << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_4 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_4 & 0x7FF | (pmc->scratch139 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1); -// pmc->scratch140 = (16 * sdram->emc_fbio_cfg5 >> 31 << 31) | (2 * ((32 * sdram->emc_fbio_cfg5 >> 31 << 30) | ((sdram->emc_fbio_cfg5 << 6 >> 31 << 29) | (((u8)(sdram->mc_emem_arb_timing_w2r) << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_5 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_5 & 0x7FF | (pmc->scratch140 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch141 = (sdram->emc_fbio_cfg5 << 8 >> 28 << 28) | (((u16)(sdram->emc_wdv) << 22) | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_0 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_0 & 0x7FF | (pmc->scratch141 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xFFFFFFF; -// pmc->scratch142 = ((u8)(sdram->emc_cfg2) << 31) | (2 * ((sdram->emc_fbio_cfg5 >> 31 << 30) | ((2 * sdram->emc_fbio_cfg5 >> 31 << 29) | ((8 * sdram->emc_fbio_cfg5 >> 31 << 28) | ((sdram->emc_quse << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_1 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_1 & 0x7FF | (pmc->scratch142 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch143 = (((u16)(sdram->emc_cfg2) << 21) >> 31 << 31) | (2 * ((((u16)(sdram->emc_cfg2) << 24) >> 31 << 30) | ((((u16)(sdram->emc_cfg2) << 29) >> 31 << 29) | ((((u16)(sdram->emc_cfg2) << 30) >> 31 << 28) | (((u8)(sdram->emc_pdex2wr) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_2 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_2 & 0x7FF | (pmc->scratch143 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch144 = (sdram->emc_cfg2 << 15 >> 31 << 31) | (2 * ((sdram->emc_cfg2 << 16 >> 31 << 30) | ((sdram->emc_cfg2 << 17 >> 31 << 29) | ((sdram->emc_cfg2 << 20 >> 31 << 28) | (((u8)(sdram->emc_pdex2rd) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_3 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_3 & 0x7FF | (pmc->scratch144 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch145 = (sdram->emc_cfg2 << 7 >> 31 << 31) | (2 * ((sdram->emc_cfg2 << 8 >> 31 << 30) | ((sdram->emc_cfg2 << 9 >> 31 << 29) | ((sdram->emc_cfg2 << 11 >> 31 << 28) | (((u16)(sdram->emc_pdex2che) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_4 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_4 & 0x7FF | (pmc->scratch145 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch146 = (2 * sdram->emc_cfg2 >> 31 << 31) | (2 * ((4 * sdram->emc_cfg2 >> 31 << 30) | (((sdram->emc_cfg2 << 6 >> 31 << 28) | (((u8)(sdram->emc_pchg2pden) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_5 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_5 & 0x7FF | (pmc->scratch146 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF | (8 * sdram->emc_cfg2 >> 31 << 29)) & 0xBFFFFFFF) >> 1); -// pmc->scratch147 = (((u8)(sdram->emc_cfg_pipe) << 29) >> 31 << 31) | (2 * ((((u8)(sdram->emc_cfg_pipe) << 30) >> 31 << 30) | ((((u8)(sdram->emc_cfg_pipe) << 31) >> 2) | ((sdram->emc_cfg2 >> 31 << 28) | (((u16)(sdram->emc_act2pden) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_0 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_0 & 0x7FF | (pmc->scratch147 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch148 = (((u8)(sdram->emc_cfg_pipe) << 25) >> 31 << 31) | (2 * ((((u8)(sdram->emc_cfg_pipe) << 26) >> 31 << 30) | ((((u8)(sdram->emc_cfg_pipe) << 27) >> 31 << 29) | ((((u8)(sdram->emc_cfg_pipe) << 28) >> 31 << 28) | (((u16)(sdram->emc_cke2pden) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_1 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_1 & 0x7FF | (pmc->scratch148 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch149 = (((u16)(sdram->emc_cfg_pipe) << 21) >> 31 << 31) | (2 * ((((u16)(sdram->emc_cfg_pipe) << 22) >> 31 << 30) | ((((u16)(sdram->emc_cfg_pipe) << 23) >> 31 << 29) | ((((u16)(sdram->emc_cfg_pipe) << 24) >> 31 << 28) | ((sdram->emc_tcke << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_2 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_2 & 0x7FF | (pmc->scratch149 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch150 = (sdram->emc_cfg_pipe << 13 >> 31 << 31) | (2 * ((sdram->emc_cfg_pipe << 14 >> 31 << 30) | (((sdram->emc_cfg_pipe << 20 >> 31 << 28) | ((sdram->emc_trpab << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_3 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_3 & 0x7FF | (pmc->scratch150 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF | (sdram->emc_cfg_pipe << 15 >> 31 << 29)) & 0xBFFFFFFF) >> 1); -// pmc->scratch151 = (sdram->emc_cfg_pipe << 9 >> 31 << 31) | (2 * ((sdram->emc_cfg_pipe << 10 >> 31 << 30) | ((sdram->emc_cfg_pipe << 11 >> 31 << 29) | ((sdram->emc_cfg_pipe << 12 >> 31 << 28) | ((sdram->emc_einput << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_4 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_4 & 0x7FF | (pmc->scratch151 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch152 = (32 * sdram->emc_cfg_pipe >> 31 << 31) | (2 * ((sdram->emc_cfg_pipe << 6 >> 31 << 30) | ((sdram->emc_cfg_pipe << 7 >> 31 << 29) | ((sdram->emc_cfg_pipe << 8 >> 31 << 28) | ((sdram->emc_einput_duration << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_5 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_5 & 0x7FF | (pmc->scratch152 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch153 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 29) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 30) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 31) >> 2) | ((16 * sdram->emc_cfg_pipe >> 31 << 28) | ((sdram->emc_puterm_extra << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_0 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_0 & 0x7FF | (pmc->scratch153 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch154 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 25) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 26) >> 31 << 30) | (((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 28) >> 31 << 28) | ((sdram->emc_tckesr << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_1 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_1 & 0x7FF | (pmc->scratch154 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF | (((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 27) >> 31 << 29)) & 0xBFFFFFFF) >> 1); -// pmc->scratch155 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 21) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 22) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 23) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 24) >> 31 << 28) | ((sdram->emc_tpd << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_2 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_2 & 0x7FF | (pmc->scratch155 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch156 = (sdram->emc_pmacro_tx_sel_clk_src0 << 12 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src0 << 13 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 14 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 15 >> 31 << 28) | ((sdram->emc_wdv_mask << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_3 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_3 & 0x7FF | (pmc->scratch156 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch157 = (sdram->emc_pmacro_tx_sel_clk_src0 << 8 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src0 << 9 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 10 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 11 >> 31 << 28) | (((u16)(sdram->emc_wdv_chk) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_4 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_4 & 0x7FF | (pmc->scratch157 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch158 = ((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 31) | (2 * ((32 * sdram->emc_pmacro_tx_sel_clk_src0 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 6 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 7 >> 31 << 28) | (((u8)(sdram->emc_cmd_brlshft0) << 26 >> 29 << 25) | (((u8)(sdram->emc_cmd_brlshft0) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_5 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_5 & 0x7FF | (pmc->scratch158 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch159 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 27) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 28) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 29) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 30) >> 31 << 28) | (((u8)(sdram->emc_cmd_brlshft1) << 26 >> 29 << 25) | (((u8)(sdram->emc_cmd_brlshft1) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank0_0 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank0_0 & 0x7FF | (pmc->scratch159 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch160 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 23) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 24) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 25) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 26) >> 31 << 28) | (((u8)(sdram->emc_cmd_brlshft2) << 26 >> 29 << 25) | (((u8)(sdram->emc_cmd_brlshft2) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank0_1 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank0_1 & 0x7FF | (pmc->scratch160 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch161 = (sdram->emc_pmacro_tx_sel_clk_src1 << 14 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src1 << 15 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 21 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 22 >> 31 << 28) | (((u8)(sdram->emc_cmd_brlshft3) << 26 >> 29 << 25) | (((u8)(sdram->emc_cmd_brlshft3) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank0_2 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank0_2 & 0x7FF | (pmc->scratch161 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch162 = (sdram->emc_pmacro_tx_sel_clk_src1 << 10 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src1 << 11 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 12 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 13 >> 31 << 28) | (((u16)(sdram->emc_wev) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank0_3 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank0_3 & 0x7FF | (pmc->scratch162 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch163 = (sdram->emc_pmacro_tx_sel_clk_src1 << 6 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src1 << 7 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 8 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 9 >> 31 << 28) | (((u16)(sdram->emc_wsv) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank1_0 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank1_0 & 0x7FF | (pmc->scratch163 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch164 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 29) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 30) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 31) >> 2) | ((32 * sdram->emc_pmacro_tx_sel_clk_src1 >> 31 << 28) | (((u8)(sdram->emc_cfg3) << 25 >> 29 << 25) | (((u8)(sdram->emc_cfg3) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank1_1 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank1_1 & 0x7FF | (pmc->scratch164 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch165 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 25) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 26) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 27) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 28) >> 31 << 28) | ((sdram->emc_puterm_width << 23) & 0xFFFFFFF | ((sdram->emc_puterm_width >> 31 << 22) | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank1_2 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank1_2 & 0x7FF | (pmc->scratch165 >> 11 << 11)) & 0xFFC007FF) & 0xFFBFFFFF) & 0xF07FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch166 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 21) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 22) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 23) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 24) >> 31 << 28) | ((sdram->mc_emem_arb_timing_rcd << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank1_3 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank1_3 & 0x7FF | (pmc->scratch166 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch167 = (sdram->emc_pmacro_tx_sel_clk_src3 << 12 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src3 << 13 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 14 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 15 >> 31 << 28) | (((u16)(sdram->mc_emem_arb_timing_ccdmw) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ddll_long_cmd_0 >> 21 << 11) | (sdram->emc_pmacro_ddll_long_cmd_0 & 0x7FF | (pmc->scratch167 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch168 = (sdram->emc_pmacro_tx_sel_clk_src3 << 8 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src3 << 9 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 10 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 11 >> 31 << 28) | ((sdram->mc_emem_arb_override << 28 >> 31 << 27) | (((sdram->mc_emem_arb_override << 21 >> 31 << 25) | ((sdram->mc_emem_arb_override << 15 >> 31 << 24) | ((32 * sdram->mc_emem_arb_override >> 31 << 23) | ((16 * sdram->mc_emem_arb_override >> 31 << 22) | ((32 * sdram->emc_pmacro_ddll_long_cmd_1 >> 21 << 11) | (sdram->emc_pmacro_ddll_long_cmd_1 & 0x7FF | (pmc->scratch168 >> 11 << 11)) & 0xFFC007FF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF | (sdram->mc_emem_arb_override << 27 >> 31 << 26)) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch169 = ((u16)(sdram->emc_rext) << 27) | (((u16)(sdram->emc_rrd) << 22) | ((32 * sdram->emc_pmacro_ddll_long_cmd_2 >> 21 << 11) | (sdram->emc_pmacro_ddll_long_cmd_2 & 0x7FF | (pmc->scratch169 >> 11 << 11)) & 0xFFC007FF) & 0xF83FFFFF) & 0x7FFFFFF; -// pmc->scratch170 = ((u16)(sdram->emc_wext) << 27) | ((sdram->emc_tclkstop << 22) | ((32 * sdram->emc_pmacro_ddll_long_cmd_3 >> 21 << 11) | (sdram->emc_pmacro_ddll_long_cmd_3 & 0x7FF | (pmc->scratch170 >> 11 << 11)) & 0xFFC007FF) & 0xF83FFFFF) & 0x7FFFFFF; -// tmp = (32 * sdram->emc_pmacro_perbit_fgcg_ctrl0 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl0 & 1 | 2 * (pmc->scratch171 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF; -// pmc->scratch171 = (sdram->emc_we_duration << 27) | ((sdram->emc_ref_ctrl2 >> 31 << 26) | ((32 * sdram->emc_ref_ctrl2 >> 29 << 23) | ((sdram->emc_ref_ctrl2 << 22) & 0x7FFFFF | tmp & 0xFFBFFFFF) & 0xFC7FFFFF) & 0xFBFFFFFF) & 0x7FFFFFF; -// tmp = (sdram->emc_pmacro_pad_cfg_ctrl << 22 >> 31 << 28) | ((sdram->emc_pmacro_pad_cfg_ctrl << 27) & 0xFFFFFFF | ((sdram->emc_ws_duration << 22) & 0x7FFFFFF | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl1 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl1 & 1 | 2 * (pmc->scratch172 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xF83FFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF; -// pmc->scratch172 = (sdram->emc_pmacro_pad_cfg_ctrl << 14 >> 30 << 30) | (4 * ((sdram->emc_pmacro_pad_cfg_ctrl << 18 >> 31 << 29) | tmp & 0xDFFFFFFF) >> 2); -// pmc->scratch173 = ((u8)(sdram->mc_emem_arb_timing_r2r) << 27) | ((sdram->mc_emem_arb_timing_rrd << 22) | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl2 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl2 & 1 | 2 * (pmc->scratch173 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xF83FFFFF) & 0x7FFFFFF; -// tmp = 32 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl3 & 1 | 2 * (pmc->scratch174 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF; -// pmc->scratch174 = ((u16)(sdram->emc_pmacro_tx_sel_clk_src2) << 30 >> 31 << 31) | (2 * (((u16)(sdram->emc_pmacro_tx_sel_clk_src2) << 30) | ((32 * sdram->emc_pmacro_tx_sel_clk_src3 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 6 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 7 >> 31 << 27) | (((u8)(sdram->mc_emem_arb_timing_w2w) << 22) & 0x7FFFFFF | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl3 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 25 >> 31 << 6) | tmp & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xF83FFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// tmp = (sdram->emc_pmacro_tx_sel_clk_src2 << 28 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 29 >> 31 << 22) | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl4 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl4 & 1 | 2 * (pmc->scratch175 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF; -// pmc->scratch175 = (sdram->emc_pmacro_tx_sel_clk_src2 << 15 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src2 << 21 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 22 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 23 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 24 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 25 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 26 >> 31 << 25) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 27 >> 31 << 24) | tmp & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// tmp = (sdram->emc_pmacro_tx_sel_clk_src2 << 12 >> 31 << 24) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 13 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 14 >> 31 << 22) | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl5 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl5 & 1 | 2 * (pmc->scratch176 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF; -// pmc->scratch176 = (32 * sdram->emc_pmacro_tx_sel_clk_src2 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src2 << 6 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 7 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 8 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 9 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 10 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 11 >> 31 << 25) | tmp & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch177 = (sdram->emc_pmacro_tx_sel_clk_src4 << 22 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src4 << 23 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 24 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 25 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 26 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 27 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 28 >> 31 << 25) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 29 >> 31 << 24) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 30 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 22) & 0x7FFFFF | ((sdram->mc_emem_arb_cfg >> 28 << 18) | ((16 * sdram->mc_emem_arb_cfg >> 28 << 14) | ((sdram->mc_emem_arb_cfg << 11 >> 27 << 9) | (sdram->mc_emem_arb_cfg & 0x1FF | (pmc->scratch177 >> 9 << 9)) & 0xFFFFC1FF) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch178 = (sdram->emc_pmacro_tx_sel_clk_src4 << 7 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src4 << 8 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 9 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 10 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 11 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 12 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 13 >> 31 << 25) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 14 >> 31 << 24) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 15 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 21 >> 31 << 22) | ((sdram->mc_emem_arb_misc1 >> 28 << 18) | ((sdram->mc_emem_arb_misc1 << 6 >> 30 << 16) | ((sdram->mc_emem_arb_misc1 << 8 >> 29 << 13) | (16 * (sdram->mc_emem_arb_misc1 << 19 >> 23) | (8 * (sdram->mc_emem_arb_misc1 << 28 >> 31) | (4 * (sdram->mc_emem_arb_misc1 << 29 >> 31) | (2 * (sdram->mc_emem_arb_misc1 << 30 >> 31) | (sdram->mc_emem_arb_misc1 & 1 | 2 * (pmc->scratch178 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFE00F) & 0xFFFF1FFF) & 0xFFFCFFFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch179 = (sdram->emc_odt_write >> 31 << 31) | (2 * ((sdram->emc_odt_write << 20 >> 28 << 27) | ((sdram->emc_odt_write << 26 >> 31 << 26) | ((sdram->emc_odt_write << 27 >> 31 << 25) | ((sdram->emc_odt_write << 21) & 0x1FFFFFF | ((32 * sdram->emc_mrs_wait_cnt2 >> 21 << 10) | (sdram->emc_mrs_wait_cnt2 & 0x3FF | (pmc->scratch179 >> 10 << 10)) & 0xFFE003FF) & 0xFE1FFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0x87FFFFFF) >> 1); -// pmc->scratch180 = (sdram->emc_pmacro_ib_rxrt << 21) | ((32 * sdram->emc_mrs_wait_cnt >> 21 << 10) | (sdram->emc_mrs_wait_cnt & 0x3FF | (pmc->scratch180 >> 10 << 10)) & 0xFFE003FF) & 0x1FFFFF; -// pmc->scratch181 = ((u16)(sdram->emc_pmacro_ddll_long_cmd_4) << 21) | sdram->emc_auto_cal_interval & 0x1FFFFF; -// pmc->scratch182 = (sdram->mc_emem_arb_outstanding_req >> 31 << 31) | (2 * ((2 * sdram->mc_emem_arb_outstanding_req >> 31 << 30) | ((sdram->mc_emem_arb_outstanding_req << 23 >> 2) | ((sdram->emc_emem_arb_refpb_hp_ctrl << 9 >> 25 << 14) | ((sdram->emc_emem_arb_refpb_hp_ctrl << 17 >> 25 << 7) | (sdram->emc_emem_arb_refpb_hp_ctrl & 0x7F | (pmc->scratch182 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xC01FFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch183 = (4 * sdram->emc_pmacro_cmd_ctrl0 >> 31 << 31) | (2 * ((8 * sdram->emc_pmacro_cmd_ctrl0 >> 31 << 30) | ((sdram->emc_pmacro_cmd_ctrl0 << 7 >> 31 << 29) | ((sdram->emc_pmacro_cmd_ctrl0 << 10 >> 31 << 28) | ((sdram->emc_pmacro_cmd_ctrl0 << 11 >> 31 << 27) | ((sdram->emc_pmacro_cmd_ctrl0 << 15 >> 31 << 26) | ((sdram->emc_pmacro_cmd_ctrl0 << 18 >> 31 << 25) | ((sdram->emc_pmacro_cmd_ctrl0 << 19 >> 31 << 24) | ((sdram->emc_pmacro_cmd_ctrl0 << 23 >> 31 << 23) | ((sdram->emc_pmacro_cmd_ctrl0 << 26 >> 31 << 22) | ((sdram->emc_pmacro_cmd_ctrl0 << 27 >> 31 << 21) | ((sdram->emc_pmacro_cmd_ctrl0 << 20) & 0x1FFFFF | ((4 * sdram->emc_xm2_comp_pad_ctrl2 >> 26 << 14) | ((sdram->emc_xm2_comp_pad_ctrl2 << 10 >> 30 << 12) | ((sdram->emc_xm2_comp_pad_ctrl2 << 14 >> 31 << 11) | ((sdram->emc_xm2_comp_pad_ctrl2 << 15 >> 31 << 10) | ((sdram->emc_xm2_comp_pad_ctrl2 << 16 >> 30 << 8) | ((sdram->emc_xm2_comp_pad_ctrl2 << 18 >> 30 << 6) | (4 * (sdram->emc_xm2_comp_pad_ctrl2 << 26 >> 28) | (sdram->emc_xm2_comp_pad_ctrl2 & 3 | 4 * (pmc->scratch183 >> 2)) & 0xFFFFFFC3) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFCFFF) & 0xFFF03FFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch184 = (4 * sdram->emc_pmacro_cmd_ctrl1 >> 31 << 31) | (2 * ((8 * sdram->emc_pmacro_cmd_ctrl1 >> 31 << 30) | ((sdram->emc_pmacro_cmd_ctrl1 << 7 >> 31 << 29) | ((sdram->emc_pmacro_cmd_ctrl1 << 10 >> 31 << 28) | ((sdram->emc_pmacro_cmd_ctrl1 << 11 >> 31 << 27) | ((sdram->emc_pmacro_cmd_ctrl1 << 15 >> 31 << 26) | ((sdram->emc_pmacro_cmd_ctrl1 << 18 >> 31 << 25) | ((sdram->emc_pmacro_cmd_ctrl1 << 19 >> 31 << 24) | ((sdram->emc_pmacro_cmd_ctrl1 << 23 >> 31 << 23) | ((sdram->emc_pmacro_cmd_ctrl1 << 26 >> 31 << 22) | ((sdram->emc_pmacro_cmd_ctrl1 << 27 >> 31 << 21) | ((sdram->emc_pmacro_cmd_ctrl1 << 20) & 0x1FFFFF | ((sdram->emc_cfg_dig_dll_1 << 12 >> 28 << 16) | ((sdram->emc_cfg_dig_dll_1 << 16 >> 28 << 12) | ((sdram->emc_cfg_dig_dll_1 << 20 >> 26 << 6) | (2 * (sdram->emc_cfg_dig_dll_1 << 26 >> 27) | (sdram->emc_cfg_dig_dll_1 & 1 | 2 * (pmc->scratch184 >> 1)) & 0xFFFFFFC1) & 0xFFFFF03F) & 0xFFFF0FFF) & 0xFFF0FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch185 = (4 * sdram->emc_pmacro_cmd_ctrl2 >> 31 << 31) | (2 * ((8 * sdram->emc_pmacro_cmd_ctrl2 >> 31 << 30) | ((sdram->emc_pmacro_cmd_ctrl2 << 7 >> 31 << 29) | ((sdram->emc_pmacro_cmd_ctrl2 << 10 >> 31 << 28) | ((sdram->emc_pmacro_cmd_ctrl2 << 11 >> 31 << 27) | ((sdram->emc_pmacro_cmd_ctrl2 << 15 >> 31 << 26) | ((sdram->emc_pmacro_cmd_ctrl2 << 18 >> 31 << 25) | ((sdram->emc_pmacro_cmd_ctrl2 << 19 >> 31 << 24) | ((sdram->emc_pmacro_cmd_ctrl2 << 23 >> 31 << 23) | ((sdram->emc_pmacro_cmd_ctrl2 << 26 >> 31 << 22) | ((sdram->emc_pmacro_cmd_ctrl2 << 27 >> 31 << 21) | ((sdram->emc_pmacro_cmd_ctrl2 << 20) & 0x1FFFFF | ((sdram->emc_quse_brlshft0 << 12 >> 27 << 15) | ((sdram->emc_quse_brlshft0 << 17 >> 27 << 10) | (32 * (sdram->emc_quse_brlshft0 << 22 >> 27) | (sdram->emc_quse_brlshft0 & 0x1F | 32 * (pmc->scratch185 >> 5)) & 0xFFFFFC1F) & 0xFFFF83FF) & 0xFFF07FFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch186 = (sdram->emc_pmacro_dsr_vttgen_ctrl0 >> 8 << 24) | ((sdram->emc_pmacro_dsr_vttgen_ctrl0 << 20) | ((sdram->emc_quse_brlshft1 << 12 >> 27 << 15) | ((sdram->emc_quse_brlshft1 << 17 >> 27 << 10) | (32 * (sdram->emc_quse_brlshft1 << 22 >> 27) | (sdram->emc_quse_brlshft1 & 0x1F | 32 * (pmc->scratch186 >> 5)) & 0xFFFFFC1F) & 0xFFFF83FF) & 0xFFF07FFF) & 0xFF0FFFFF) & 0xFFFFFF; -// pmc->scratch187 = (sdram->emc_pmacro_perbit_rfu1_ctrl0 << 10 >> 30 << 30) | (4 * ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 12 >> 30 << 28) | ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 14 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 26 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 28 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 20) & 0x3FFFFF | ((sdram->emc_quse_brlshft2 << 12 >> 27 << 15) | ((sdram->emc_quse_brlshft2 << 17 >> 27 << 10) | (32 * (sdram->emc_quse_brlshft2 << 22 >> 27) | (sdram->emc_quse_brlshft2 & 0x1F | 32 * (pmc->scratch187 >> 5)) & 0xFFFFFC1F) & 0xFFFF83FF) & 0xFFF07FFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); -// pmc->scratch188 = (sdram->emc_pmacro_perbit_rfu1_ctrl1 << 10 >> 30 << 30) | (4 * ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 12 >> 30 << 28) | ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 14 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 26 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 28 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 20) & 0x3FFFFF | ((sdram->emc_quse_brlshft3 << 12 >> 27 << 15) | ((sdram->emc_quse_brlshft3 << 17 >> 27 << 10) | (32 * (sdram->emc_quse_brlshft3 << 22 >> 27) | (sdram->emc_quse_brlshft3 & 0x1F | 32 * (pmc->scratch188 >> 5)) & 0xFFFFFC1F) & 0xFFFF83FF) & 0xFFF07FFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); -// pmc->scratch189 = (sdram->emc_trefbw << 18) | ((sdram->emc_dbg >> 31 << 17) | ((2 * sdram->emc_dbg >> 31 << 16) | ((4 * sdram->emc_dbg >> 31 << 15) | ((8 * sdram->emc_dbg >> 31 << 14) | ((16 * sdram->emc_dbg >> 30 << 12) | ((sdram->emc_dbg << 6 >> 31 << 11) | ((sdram->emc_dbg << 7 >> 31 << 10) | ((sdram->emc_dbg << 18 >> 31 << 9) | ((sdram->emc_dbg << 19 >> 31 << 8) | ((sdram->emc_dbg << 20 >> 31 << 7) | ((sdram->emc_dbg << 21 >> 31 << 6) | (32 * (sdram->emc_dbg << 22 >> 31) | (16 * (sdram->emc_dbg << 27 >> 31) | (8 * (sdram->emc_dbg << 28 >> 31) | (4 * (sdram->emc_dbg << 29 >> 31) | (2 * (sdram->emc_dbg << 30 >> 31) | (sdram->emc_dbg & 1 | 2 * (pmc->scratch189 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFCFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0x3FFFF; -// pmc->scratch191 = (sdram->emc_qpop << 9 >> 25 << 25) | ((sdram->emc_qpop << 18) | ((sdram->emc_zcal_wait_cnt >> 31 << 17) | ((sdram->emc_zcal_wait_cnt << 10 >> 26 << 11) | (sdram->emc_zcal_wait_cnt & 0x7FF | (pmc->scratch191 >> 11 << 11)) & 0xFFFE07FF) & 0xFFFDFFFF) & 0xFE03FFFF) & 0x1FFFFFF; -// pmc->scratch192 = (sdram->emc_pmacro_tx_sel_clk_src4 << 6 >> 31 << 31) | (2 * ((sdram->emc_pmacro_auto_cal_common << 15 >> 31 << 30) | ((sdram->emc_pmacro_auto_cal_common << 18 >> 26 << 24) | ((sdram->emc_pmacro_auto_cal_common << 18) & 0xFFFFFF | ((sdram->emc_zcal_mrw_cmd >> 30 << 16) | ((sdram->emc_zcal_mrw_cmd << 8 >> 24 << 8) | (sdram->emc_zcal_mrw_cmd & 0xFF | (pmc->scratch192 >> 8 << 8)) & 0xFFFF00FF) & 0xFFFCFFFF) & 0xFF03FFFF) & 0xC0FFFFFF) & 0xBFFFFFFF) >> 1); -// tmp = (sdram->emc_dll_cfg1 << 7 >> 31 << 17) | ((sdram->emc_dll_cfg1 << 10 >> 31 << 16) | ((sdram->emc_dll_cfg1 << 11 >> 31 << 15) | ((sdram->emc_dll_cfg1 << 14 >> 30 << 13) | ((sdram->emc_dll_cfg1 << 18 >> 31 << 12) | ((sdram->emc_dll_cfg1 << 19 >> 31 << 11) | ((pmc->scratch193 >> 11 << 11) | sdram->emc_dll_cfg1 & 0x7FF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFF9FFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF; -// pmc->scratch193 = (sdram->emc_pmacro_tx_sel_clk_src5 << 31) | (2 * ((32 * sdram->emc_pmacro_tx_sel_clk_src4 >> 31 << 30) | ((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 10 >> 30 << 28) | (((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 14 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 26 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 28 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 18) & 0xFFFFF | tmp & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl2 << 12 >> 30 << 26)) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch194 = (sdram->emc_pmacro_tx_sel_clk_src5 << 29 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src5 << 30 >> 31 << 30) | ((sdram->emc_pmacro_perbit_rfu1_ctrl3 << 10 >> 30 << 28) | (((sdram->emc_pmacro_perbit_rfu1_ctrl3 << 14 >> 30 << 24) | (((sdram->emc_pmacro_perbit_rfu1_ctrl3 << 28 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu1_ctrl3 << 18) & 0xFFFFF | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 14 >> 30 << 16) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 16 >> 30 << 14) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 18 >> 30 << 12) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 20 >> 30 << 10) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 22 >> 30 << 8) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 26 >> 30) | (4 * (sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 28 >> 30) | (sdram->emc_pmacro_cmd_brick_ctrl_fdpd & 3 | 4 * (pmc->scratch194 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl3 << 26 >> 30 << 22)) & 0xFCFFFFFF) & 0xF3FFFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl3 << 12 >> 30 << 26)) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch195 = (sdram->emc_pmacro_tx_sel_clk_src5 << 27 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src5 << 28 >> 31 << 30) | ((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 10 >> 30 << 28) | (((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 14 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 26 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 28 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 18) & 0xFFFFF | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 14 >> 30 << 16) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 16 >> 30 << 14) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 18 >> 30 << 12) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 20 >> 30 << 10) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 22 >> 30 << 8) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_data_brick_ctrl_fdpd << 26 >> 30) | (4 * (sdram->emc_pmacro_data_brick_ctrl_fdpd << 28 >> 30) | (sdram->emc_pmacro_data_brick_ctrl_fdpd & 3 | 4 * (pmc->scratch195 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl4 << 12 >> 30 << 26)) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch196 = (sdram->emc_emem_arb_refpb_bank_ctrl >> 31 << 31) | (2 * ((sdram->emc_emem_arb_refpb_bank_ctrl << 17 >> 25 << 24) | ((sdram->emc_emem_arb_refpb_bank_ctrl << 17) & 0xFFFFFF | ((sdram->emc_dyn_self_ref_control >> 31 << 16) | (sdram->emc_dyn_self_ref_control & 0xFFFF | (pmc->scratch196 >> 16 << 16)) & 0xFFFEFFFF) & 0xFF01FFFF) & 0x80FFFFFF) >> 1); -// pmc->scratch197 = (sdram->emc_pmacro_tx_sel_clk_src5 << 24 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src5 << 25 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 26 >> 31 << 29) | ((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 10 >> 30 << 27) | (((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 14 >> 30 << 23) | ((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 26 >> 30 << 21) | ((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 28 >> 30 << 19) | ((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 17) & 0x7FFFF | ((16 * sdram->emc_pmacro_cmd_pad_rx_ctrl >> 28 << 13) | ((sdram->emc_pmacro_cmd_pad_rx_ctrl << 8 >> 31 << 12) | ((sdram->emc_pmacro_cmd_pad_rx_ctrl << 9 >> 31 << 11) | ((sdram->emc_pmacro_cmd_pad_rx_ctrl << 10 >> 31 << 10) | ((sdram->emc_pmacro_cmd_pad_rx_ctrl << 12 >> 28 << 6) | (32 * (sdram->emc_pmacro_cmd_pad_rx_ctrl << 16 >> 31) | (16 * (sdram->emc_pmacro_cmd_pad_rx_ctrl << 19 >> 31) | (4 * (sdram->emc_pmacro_cmd_pad_rx_ctrl << 26 >> 30) | (sdram->emc_pmacro_cmd_pad_rx_ctrl & 3 | 4 * (pmc->scratch197 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFC3F) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFE1FFF) & 0xFFF9FFFF) & 0xFFE7FFFF) & 0xFF9FFFFF) & 0xFE7FFFFF) & 0xF9FFFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl5 << 12 >> 30 << 25)) & 0xE7FFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch198 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 31) | (2 * ((32 * sdram->emc_pmacro_tx_sel_clk_src5 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 6 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 7 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 8 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 9 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 10 >> 31 << 25) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 11 >> 31 << 24) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 12 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 13 >> 31 << 22) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 14 >> 31 << 21) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 15 >> 31 << 20) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 21 >> 31 << 19) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 22 >> 31 << 18) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 23 >> 31 << 17) | ((16 * sdram->emc_pmacro_data_pad_rx_ctrl >> 28 << 13) | ((sdram->emc_pmacro_data_pad_rx_ctrl << 8 >> 31 << 12) | ((sdram->emc_pmacro_data_pad_rx_ctrl << 9 >> 31 << 11) | ((sdram->emc_pmacro_data_pad_rx_ctrl << 10 >> 31 << 10) | ((sdram->emc_pmacro_data_pad_rx_ctrl << 12 >> 28 << 6) | (32 * (sdram->emc_pmacro_data_pad_rx_ctrl << 16 >> 31) | (16 * (sdram->emc_pmacro_data_pad_rx_ctrl << 19 >> 31) | (4 * (sdram->emc_pmacro_data_pad_rx_ctrl << 26 >> 30) | (sdram->emc_pmacro_data_pad_rx_ctrl & 3 | 4 * (pmc->scratch198 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFC3F) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFE1FFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch199 = (8 * sdram->emc_cmd_q >> 27 << 27) | ((sdram->emc_cmd_q << 17 >> 29 << 24) | ((sdram->emc_cmd_q << 21 >> 29 << 21) | ((sdram->emc_cmd_q << 16) & 0x1FFFFF | (((u16)(sdram->emc_refresh) << 16 >> 22 << 6) | (sdram->emc_refresh & 0x3F | (pmc->scratch199 >> 6 << 6)) & 0xFFFF003F) & 0xFFE0FFFF) & 0xFF1FFFFF) & 0xF8FFFFFF) & 0x7FFFFFF; -// pmc->scratch210 = (sdram->emc_auto_cal_vref_sel1 << 16 >> 31 << 31) | (2 * ((sdram->emc_auto_cal_vref_sel1 << 17 >> 25 << 24) | ((sdram->emc_auto_cal_vref_sel1 << 24 >> 31 << 23) | ((sdram->emc_auto_cal_vref_sel1 << 16) & 0x7FFFFF | (sdram->emc_acpd_control & 0xFFFF | (pmc->scratch210 >> 16 << 16)) & 0xFF80FFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1); -// tmp = 8 * (sdram->emc_pmacro_auto_cal_cfg0 << 28 >> 31) | (4 * (sdram->emc_pmacro_auto_cal_cfg0 << 29 >> 31) | (2 * (sdram->emc_pmacro_auto_cal_cfg0 << 30 >> 31) | (sdram->emc_pmacro_auto_cal_cfg0 & 1 | 2 * (pmc->scratch211 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7; -// tmp = (sdram->emc_pmacro_auto_cal_cfg1 << 7 >> 31 << 28) | ((sdram->emc_pmacro_auto_cal_cfg1 << 12 >> 31 << 27) | ((sdram->emc_pmacro_auto_cal_cfg1 << 13 >> 31 << 26) | ((sdram->emc_pmacro_auto_cal_cfg1 << 14 >> 31 << 25) | ((sdram->emc_pmacro_auto_cal_cfg1 << 15 >> 31 << 24) | ((sdram->emc_pmacro_auto_cal_cfg1 << 20 >> 31 << 23) | ((sdram->emc_pmacro_auto_cal_cfg1 << 21 >> 31 << 22) | ((sdram->emc_pmacro_auto_cal_cfg1 << 22 >> 31 << 21) | ((sdram->emc_pmacro_auto_cal_cfg1 << 23 >> 31 << 20) | ((sdram->emc_pmacro_auto_cal_cfg1 << 28 >> 31 << 19) | ((sdram->emc_pmacro_auto_cal_cfg1 << 29 >> 31 << 18) | ((sdram->emc_pmacro_auto_cal_cfg1 << 30 >> 31 << 17) | ((sdram->emc_pmacro_auto_cal_cfg1 << 16) & 0x1FFFF | ((16 * sdram->emc_pmacro_auto_cal_cfg0 >> 31 << 15) | ((32 * sdram->emc_pmacro_auto_cal_cfg0 >> 31 << 14) | ((sdram->emc_pmacro_auto_cal_cfg0 << 6 >> 31 << 13) | ((sdram->emc_pmacro_auto_cal_cfg0 << 7 >> 31 << 12) | ((sdram->emc_pmacro_auto_cal_cfg0 << 12 >> 31 << 11) | ((sdram->emc_pmacro_auto_cal_cfg0 << 13 >> 31 << 10) | ((sdram->emc_pmacro_auto_cal_cfg0 << 14 >> 31 << 9) | ((sdram->emc_pmacro_auto_cal_cfg0 << 15 >> 31 << 8) | ((sdram->emc_pmacro_auto_cal_cfg0 << 20 >> 31 << 7) | ((sdram->emc_pmacro_auto_cal_cfg0 << 21 >> 31 << 6) | (32 * (sdram->emc_pmacro_auto_cal_cfg0 << 22 >> 31) | (16 * (sdram->emc_pmacro_auto_cal_cfg0 << 23 >> 31) | tmp & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF; -// pmc->scratch211 = (16 * sdram->emc_pmacro_auto_cal_cfg1 >> 31 << 31) | (2 * ((32 * sdram->emc_pmacro_auto_cal_cfg1 >> 31 << 30) | ((sdram->emc_pmacro_auto_cal_cfg1 << 6 >> 31 << 29) | tmp & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->scratch212 = (sdram->emc_xm2_comp_pad_ctrl3 << 8 >> 28 << 28) | ((sdram->emc_xm2_comp_pad_ctrl3 << 14 >> 31 << 27) | ((sdram->emc_xm2_comp_pad_ctrl3 << 15 >> 31 << 26) | ((sdram->emc_xm2_comp_pad_ctrl3 << 16 >> 30 << 24) | ((sdram->emc_xm2_comp_pad_ctrl3 << 18 >> 30 << 22) | ((sdram->emc_xm2_comp_pad_ctrl3 << 26 >> 28 << 18) | ((sdram->emc_xm2_comp_pad_ctrl3 << 16) & 0x3FFFF | ((16 * sdram->emc_pmacro_auto_cal_cfg2 >> 31 << 15) | ((32 * sdram->emc_pmacro_auto_cal_cfg2 >> 31 << 14) | ((sdram->emc_pmacro_auto_cal_cfg2 << 6 >> 31 << 13) | ((sdram->emc_pmacro_auto_cal_cfg2 << 7 >> 31 << 12) | ((sdram->emc_pmacro_auto_cal_cfg2 << 12 >> 31 << 11) | ((sdram->emc_pmacro_auto_cal_cfg2 << 13 >> 31 << 10) | ((sdram->emc_pmacro_auto_cal_cfg2 << 14 >> 31 << 9) | ((sdram->emc_pmacro_auto_cal_cfg2 << 15 >> 31 << 8) | ((sdram->emc_pmacro_auto_cal_cfg2 << 20 >> 31 << 7) | ((sdram->emc_pmacro_auto_cal_cfg2 << 21 >> 31 << 6) | (32 * (sdram->emc_pmacro_auto_cal_cfg2 << 22 >> 31) | (16 * (sdram->emc_pmacro_auto_cal_cfg2 << 23 >> 31) | (8 * (sdram->emc_pmacro_auto_cal_cfg2 << 28 >> 31) | (4 * (sdram->emc_pmacro_auto_cal_cfg2 << 29 >> 31) | (2 * (sdram->emc_pmacro_auto_cal_cfg2 << 30 >> 31) | (sdram->emc_pmacro_auto_cal_cfg2 & 1 | 2 * (pmc->scratch212 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFCFFFF) & 0xFFC3FFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xFFFFFFF; -// pmc->scratch213 = ((u16)(sdram->emc_prerefresh_req_cnt) << 16) | (u16)(sdram->emc_cfg_dig_dll_period); -// pmc->scratch214 = (sdram->emc_pmacro_data_pi_ctrl << 10 >> 26 << 26) | ((sdram->emc_pmacro_data_pi_ctrl << 19 >> 31 << 25) | ((sdram->emc_pmacro_data_pi_ctrl << 20 >> 28 << 21) | ((sdram->emc_pmacro_data_pi_ctrl << 27 >> 31 << 20) | ((sdram->emc_pmacro_data_pi_ctrl << 16) & 0xFFFFF | ((sdram->emc_pmacro_ddll_bypass >> 31 << 15) | ((2 * sdram->emc_pmacro_ddll_bypass >> 31 << 14) | ((4 * sdram->emc_pmacro_ddll_bypass >> 31 << 13) | ((16 * sdram->emc_pmacro_ddll_bypass >> 31 << 12) | ((32 * sdram->emc_pmacro_ddll_bypass >> 31 << 11) | ((sdram->emc_pmacro_ddll_bypass << 6 >> 31 << 10) | ((sdram->emc_pmacro_ddll_bypass << 7 >> 31 << 9) | ((sdram->emc_pmacro_ddll_bypass << 15 >> 31 << 8) | ((sdram->emc_pmacro_ddll_bypass << 16 >> 31 << 7) | ((sdram->emc_pmacro_ddll_bypass << 17 >> 31 << 6) | (32 * (sdram->emc_pmacro_ddll_bypass << 18 >> 31) | (16 * (sdram->emc_pmacro_ddll_bypass << 20 >> 31) | (8 * (sdram->emc_pmacro_ddll_bypass << 21 >> 31) | (4 * (sdram->emc_pmacro_ddll_bypass << 22 >> 31) | (2 * (sdram->emc_pmacro_ddll_bypass << 23 >> 31) | (sdram->emc_pmacro_ddll_bypass & 1 | 2 * (pmc->scratch214 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFF0FFFF) & 0xFFEFFFFF) & 0xFE1FFFFF) & 0xFDFFFFFF) & 0x3FFFFFF; -// pmc->scratch215 = (sdram->emc_pmacro_cmd_pi_ctrl << 10 >> 26 << 10) | ((sdram->emc_pmacro_cmd_pi_ctrl << 19 >> 31 << 9) | (32 * (sdram->emc_pmacro_cmd_pi_ctrl << 20 >> 28) | (16 * (sdram->emc_pmacro_cmd_pi_ctrl << 27 >> 31) | (sdram->emc_pmacro_cmd_pi_ctrl & 0xF | 16 * (pmc->scratch215 >> 4)) & 0xFFFFFFEF) & 0xFFFFFE1F) & 0xFFFFFDFF) & 0xFFFF03FF; -// tmp = (sdram->emc_pmacro_data_pad_tx_ctrl << 7 >> 31 << 24) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 8 >> 31 << 23) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 9 >> 31 << 22) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 10 >> 31 << 21) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 15 >> 31 << 20) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 16 >> 31 << 19) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 21 >> 31 << 18) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 25 >> 31 << 17) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 26 >> 31 << 16) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 15) & 0xFFFF | ((2 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 14) | ((4 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 13) | ((8 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 12) | ((16 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 11) | ((32 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 10) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 6 >> 31 << 9) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 7 >> 31 << 8) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 8 >> 31 << 7) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 9 >> 31 << 6) | (32 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 10 >> 31) | (16 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 15 >> 31) | (8 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 16 >> 31) | (4 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 21 >> 31) | (2 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 25 >> 31) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 26 >> 31) | 2 * (pmc->scratch216 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF; + s(emc_clock_source, 7:0, scratch6, 15:8); + s(emc_clock_source_dll, 7:0, scratch6, 23:16); + s(emc_clock_source, 31:29, scratch6, 26:24); + s(emc_clock_source_dll, 31:29, scratch6, 29:27); + s(emc_clock_source_dll, 11:10, scratch6, 31:30); + pmc->scratch7 = (sdram->emc_rc << 24) | ((sdram->emc_zqcal_lpddr4_warm_boot << 27 >> 31 << 23) | ((sdram->emc_zqcal_lpddr4_warm_boot << 30 >> 31 << 22) | ((sdram->emc_zqcal_lpddr4_warm_boot << 21) & 0x3FFFFF | ((sdram->clk_rst_pllm_misc20_override << 20) & 0x1FFFFF | ((sdram->clk_rst_pllm_misc20_override << 28 >> 31 << 19) | ((sdram->clk_rst_pllm_misc20_override << 27 >> 31 << 18) | ((sdram->clk_rst_pllm_misc20_override << 26 >> 31 << 17) | ((sdram->clk_rst_pllm_misc20_override << 21 >> 31 << 16) | ((sdram->clk_rst_pllm_misc20_override << 20 >> 31 << 15) | ((sdram->clk_rst_pllm_misc20_override << 19 >> 31 << 14) | ((sdram->clk_rst_pllm_misc20_override << 18 >> 31 << 13) | ((sdram->emc_clock_source << 15 >> 31 << 12) | ((sdram->emc_clock_source << 11 >> 31 << 11) | ((sdram->emc_clock_source << 12 >> 31 << 10) | ((sdram->emc_clock_source << 6 >> 31 << 9) | ((sdram->emc_clock_source << 16 >> 31 << 8) | ((32 * sdram->emc_clock_source >> 31 << 7) | ((16 * sdram->emc_clock_source >> 31 << 6) | (16 * (sdram->emc_zqcal_lpddr4_warm_boot >> 30) | (4 * (sdram->clk_rst_pllm_misc20_override << 29 >> 30) | ((sdram->clk_rst_pllm_misc20_override << 22 >> 30) | 4 * (pmc->scratch7 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFFFFFF; + pmc->scratch8 = (sdram->emc_pmacro_bg_bias_ctrl0 << 18 >> 30 << 30) | ((4 * pmc->scratch8) >> 2); + pmc->scratch14 = ((u8)(sdram->emc_cfg_pipe_clk) << 31) | (2 * (((u8)(sdram->emc_fdpd_ctrl_cmd_no_ramp) << 30) | pmc->scratch14 & 0xBFFFFFFF) >> 1); + s(emc_qrst, 6:0, scratch15, 26:20); + s(emc_qrst, 20:16, scratch15, 31:27); + s(emc_pmacro_cmd_tx_drive, 5:0, scratch16, 25:20); + s(emc_pmacro_cmd_tx_drive, 13:8, scratch16, 31:26); + pmc->scratch17 = (16 * sdram->emc_fbio_cfg8 >> 31 << 31) | (2 * ((32 * sdram->emc_fbio_cfg8 >> 31 << 30) | ((sdram->emc_fbio_cfg8 << 6 >> 31 << 29) | ((sdram->emc_fbio_cfg8 << 7 >> 31 << 28) | ((sdram->emc_fbio_cfg8 << 8 >> 31 << 27) | ((sdram->emc_fbio_cfg8 << 9 >> 31 << 26) | ((sdram->emc_fbio_cfg8 << 10 >> 31 << 25) | ((sdram->emc_fbio_cfg8 << 11 >> 31 << 24) | ((sdram->emc_fbio_cfg8 << 12 >> 31 << 23) | ((sdram->emc_fbio_cfg8 << 13 >> 31 << 22) | ((sdram->emc_fbio_cfg8 << 14 >> 31 << 21) | ((sdram->emc_fbio_cfg8 << 15 >> 31 << 20) | pmc->scratch17 & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch18 = ((u16)(sdram->emc_txsr_dll) << 20) | pmc->scratch18 & 0xFFFFF; + pmc->scratch19 = (sdram->emc_txdsrvttgen << 20) | pmc->scratch19 & 0xFFFFF; + s32(emc_cfg_rsv, scratch22); + s32(emc_auto_cal_config, scratch23); + s32(emc_auto_cal_vref_sel0, scratch24); + s32(emc_pmacro_brick_ctrl_rfu1, scratch25); + s32(emc_pmacro_brick_ctrl_rfu2, scratch26); + s32(emc_pmc_scratch1, scratch27); + s32(emc_pmc_scratch2, scratch28); + s32(emc_pmc_scratch3, scratch29); + pmc->scratch30 = (sdram->emc_pmacro_perbit_rfu_ctrl0 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl0 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl0 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl0 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl0 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl0 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl0 & 3 | 4 * (pmc->scratch30 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); + pmc->scratch31 = (sdram->emc_pmacro_perbit_rfu_ctrl1 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl1 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl1 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl1 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl1 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl1 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl1 & 3 | 4 * (pmc->scratch31 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); + pmc->scratch32 = (sdram->emc_pmacro_perbit_rfu_ctrl2 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl2 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl2 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl2 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl2 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl2 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl2 & 3 | 4 * (pmc->scratch32 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); + pmc->scratch33 = (sdram->emc_pmacro_perbit_rfu_ctrl3 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl3 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl3 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl3 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl3 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl3 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl3 & 3 | 4 * (pmc->scratch33 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); + pmc->scratch40 = (sdram->emc_pmacro_perbit_rfu_ctrl4 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl4 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl4 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl4 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl4 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl4 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl4 & 3 | 4 * (pmc->scratch40 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); + pmc->scratch42 = (sdram->emc_pmacro_perbit_rfu_ctrl5 >> 30 << 30) | (4 * ((4 * sdram->emc_pmacro_perbit_rfu_ctrl5 >> 30 << 28) | ((16 * sdram->emc_pmacro_perbit_rfu_ctrl5 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 6 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 8 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 10 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 12 >> 30 << 18) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 14 >> 30 << 16) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 16 >> 30 << 14) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 18 >> 30 << 12) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 20 >> 30 << 10) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 22 >> 30 << 8) | ((sdram->emc_pmacro_perbit_rfu_ctrl5 << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_perbit_rfu_ctrl5 << 26 >> 30) | (4 * (sdram->emc_pmacro_perbit_rfu_ctrl5 << 28 >> 30) | (sdram->emc_pmacro_perbit_rfu_ctrl5 & 3 | 4 * (pmc->scratch42 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); + pmc->scratch44 = (sdram->mc_emem_arb_da_turns >> 24 << 24) | ((sdram->mc_emem_arb_da_turns >> 16 << 16) | ((sdram->mc_emem_arb_da_turns << 16 >> 24 << 8) | (sdram->mc_emem_arb_da_turns & 0xFF | (pmc->scratch44 >> 8 << 8)) & 0xFFFF00FF) & 0xFF00FFFF) & 0xFFFFFF; + pmc->scratch64 = ((u16)(sdram->mc_emem_arb_misc2) << 31) | (2 * ((sdram->emc_fbio_spare << 30) | ((sdram->emc_fbio_spare << 24 >> 26 << 24) | ((sdram->emc_fbio_spare << 16 >> 24 << 16) | ((sdram->emc_fbio_spare << 8 >> 24 << 8) | ((sdram->emc_fbio_spare >> 24) | (pmc->scratch64 >> 8 << 8)) & 0xFFFF00FF) & 0xFF00FFFF) & 0xC0FFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch65 = ((u16)(sdram->mc_da_cfg0) << 31 >> 1) | ((2 * sdram->mc_emem_arb_misc0 >> 29 << 27) | ((16 * sdram->mc_emem_arb_misc0 >> 31 << 26) | ((32 * sdram->mc_emem_arb_misc0 >> 26 << 20) | ((sdram->mc_emem_arb_misc0 << 11 >> 27 << 15) | ((sdram->mc_emem_arb_misc0 << 17 >> 25 << 8) | ((u8)sdram->mc_emem_arb_misc0 | (pmc->scratch65 >> 8 << 8)) & 0xFFFF80FF) & 0xFFF07FFF) & 0xFC0FFFFF) & 0xFBFFFFFF) & 0xC7FFFFFF) & 0xBFFFFFFF; + pmc->scratch66 = (sdram->emc_fdpd_ctrl_cmd >> 30 << 27) | ((4 * sdram->emc_fdpd_ctrl_cmd >> 31 << 26) | ((8 * sdram->emc_fdpd_ctrl_cmd >> 27 << 21) | ((sdram->emc_fdpd_ctrl_cmd << 8 >> 28 << 17) | ((sdram->emc_fdpd_ctrl_cmd << 15 >> 27 << 12) | ((sdram->emc_fdpd_ctrl_cmd << 20 >> 28 << 8) | ((u8)sdram->emc_fdpd_ctrl_cmd | (pmc->scratch66 >> 8 << 8)) & 0xFFFFF0FF) & 0xFFFE0FFF) & 0xFFE1FFFF) & 0xFC1FFFFF) & 0xFBFFFFFF) & 0xE7FFFFFF; + pmc->scratch67 = ((u8)(sdram->emc_burst_refresh_num) << 28) | ((16 * sdram->emc_auto_cal_config2 >> 30 << 26) | ((sdram->emc_auto_cal_config2 << 6 >> 30 << 24) | ((sdram->emc_auto_cal_config2 << 8 >> 30 << 22) | ((sdram->emc_auto_cal_config2 << 10 >> 30 << 20) | ((sdram->emc_auto_cal_config2 << 12 >> 30 << 18) | ((sdram->emc_auto_cal_config2 << 14 >> 30 << 16) | ((sdram->emc_auto_cal_config2 << 16 >> 30 << 14) | ((sdram->emc_auto_cal_config2 << 18 >> 30 << 12) | ((sdram->emc_auto_cal_config2 << 20 >> 30 << 10) | ((sdram->emc_auto_cal_config2 << 22 >> 30 << 8) | ((sdram->emc_auto_cal_config2 << 24 >> 30 << 6) | (16 * (sdram->emc_auto_cal_config2 << 26 >> 30) | (4 * (sdram->emc_auto_cal_config2 << 28 >> 30) | (sdram->emc_auto_cal_config2 & 3 | 4 * (pmc->scratch67 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xFFFFFFF; + pmc->scratch68 = ((u8)(sdram->emc_tppd) << 28) | ((sdram->emc_cfg_dig_dll >> 31 << 27) | ((2 * sdram->emc_cfg_dig_dll >> 31 << 26) | ((16 * sdram->emc_cfg_dig_dll >> 31 << 25) | ((sdram->emc_cfg_dig_dll << 6 >> 22 << 15) | ((sdram->emc_cfg_dig_dll << 16 >> 31 << 14) | ((sdram->emc_cfg_dig_dll << 17 >> 31 << 13) | ((sdram->emc_cfg_dig_dll << 18 >> 30 << 11) | ((sdram->emc_cfg_dig_dll << 21 >> 29 << 8) | ((sdram->emc_cfg_dig_dll << 24 >> 30 << 6) | (32 * (sdram->emc_cfg_dig_dll << 26 >> 31) | (16 * (sdram->emc_cfg_dig_dll << 27 >> 31) | (8 * (sdram->emc_cfg_dig_dll << 28 >> 31) | (4 * (sdram->emc_cfg_dig_dll << 29 >> 31) | (2 * (sdram->emc_cfg_dig_dll << 30 >> 31) | (sdram->emc_cfg_dig_dll & 1 | 2 * (pmc->scratch68 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFF3F) & 0xFFFFF8FF) & 0xFFFFE7FF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFE007FFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xFFFFFFF; + pmc->scratch69 = (sdram->emc_r2r << 28) | ((sdram->emc_fdpd_ctrl_dq >> 30 << 26) | ((8 * sdram->emc_fdpd_ctrl_dq >> 27 << 21) | ((sdram->emc_fdpd_ctrl_dq << 8 >> 28 << 17) | ((sdram->emc_fdpd_ctrl_dq << 15 >> 27 << 12) | ((sdram->emc_fdpd_ctrl_dq << 20 >> 28 << 8) | ((u8)sdram->emc_fdpd_ctrl_dq | (pmc->scratch69 >> 8 << 8)) & 0xFFFFF0FF) & 0xFFFE0FFF) & 0xFFE1FFFF) & 0xFC1FFFFF) & 0xF3FFFFFF) & 0xFFFFFFF; + pmc->scratch70 = (sdram->emc_w2w << 28) | ((2 * sdram->emc_pmacro_ib_vref_dq_0 >> 25 << 21) | ((sdram->emc_pmacro_ib_vref_dq_0 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ib_vref_dq_0 << 17 >> 25 << 7) | (sdram->emc_pmacro_ib_vref_dq_0 & 0x7F | (pmc->scratch70 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xFFFFFFF; + pmc->scratch71 = (sdram->emc_pmacro_vttgen_ctrl0 << 12 >> 28 << 28) | ((2 * sdram->emc_pmacro_ib_vref_dq_1 >> 25 << 21) | ((sdram->emc_pmacro_ib_vref_dq_1 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ib_vref_dq_1 << 17 >> 25 << 7) | ((pmc->scratch71 >> 7 << 7) | sdram->emc_pmacro_ib_vref_dq_1 & 0x7F) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xFFFFFFF; + pmc->scratch72 = (((sdram->emc_pmacro_ib_vref_dqs_0 << 17 >> 25 << 7) | ((pmc->scratch72 >> 7 << 7) | sdram->emc_pmacro_ib_vref_dqs_0 & 0x7F) & 0xFFFFC07F) & 0xFFE03FFF | (sdram->emc_pmacro_ib_vref_dqs_0 << 9 >> 25 << 14)) & 0xF01FFFFF | (2 * sdram->emc_pmacro_ib_vref_dqs_0 >> 25 << 21); + pmc->scratch73 = (2 * sdram->emc_pmacro_ib_vref_dqs_1 >> 25 << 21) | ((sdram->emc_pmacro_ib_vref_dqs_1 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ib_vref_dqs_1 << 17 >> 25 << 7) | ((pmc->scratch73 >> 7 << 7) | sdram->emc_pmacro_ib_vref_dqs_1 & 0x7F) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF; + pmc->scratch74 = (2 * sdram->emc_pmacro_ddll_short_cmd_0 >> 25 << 21) | ((sdram->emc_pmacro_ddll_short_cmd_0 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ddll_short_cmd_0 << 17 >> 25 << 7) | (sdram->emc_pmacro_ddll_short_cmd_0 & 0x7F | (pmc->scratch74 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF; + pmc->scratch75 = (2 * sdram->emc_pmacro_ddll_short_cmd_1 >> 25 << 21) | ((sdram->emc_pmacro_ddll_short_cmd_1 << 9 >> 25 << 14) | ((sdram->emc_pmacro_ddll_short_cmd_1 << 17 >> 25 << 7) | (sdram->emc_pmacro_ddll_short_cmd_1 & 0x7F | (pmc->scratch75 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF; + pmc->scratch76 = (sdram->emc_rp << 26) | ((4 * sdram->emc_dll_cfg0 >> 31 << 25) | ((8 * sdram->emc_dll_cfg0 >> 31 << 24) | ((16 * sdram->emc_dll_cfg0 >> 28 << 20) | ((sdram->emc_dll_cfg0 << 8 >> 28 << 16) | ((sdram->emc_dll_cfg0 << 12 >> 28 << 12) | ((sdram->emc_dll_cfg0 << 16 >> 28 << 8) | ((sdram->emc_dll_cfg0 << 20 >> 24) | (pmc->scratch76 >> 8 << 8)) & 0xFFFFF0FF) & 0xFFFF0FFF) & 0xFFF0FFFF) & 0xFF0FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0x3FFFFFF; + tmp = (sdram->emc_pmacro_tx_pwrd0 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd0 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd0 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd0 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd0 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd0 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd0 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd0 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd0 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd0 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd0 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd0 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd0 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd0 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd0 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd0 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd0 & 1 | 2 * (pmc->scratch77 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF; + pmc->scratch77 = (sdram->emc_r2w << 26) | ((4 * sdram->emc_pmacro_tx_pwrd0 >> 31 << 25) | ((8 * sdram->emc_pmacro_tx_pwrd0 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd0 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd0 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd0 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd0 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd0 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd0 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd0 << 11 >> 31 << 17) | tmp & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0x3FFFFFF; + tmp = ((8 * sdram->emc_pmacro_tx_pwrd1 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd1 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd1 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd1 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd1 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd1 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd1 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd1 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd1 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd1 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd1 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd1 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd1 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd1 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd1 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd1 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd1 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd1 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd1 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd1 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd1 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd1 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd1 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd1 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd1 & 1 | 2 * (pmc->scratch78 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF; + pmc->scratch78 = (sdram->emc_w2r << 26) | ((4 * sdram->emc_pmacro_tx_pwrd1 >> 31 << 25) | tmp) & 0x3FFFFFF; + tmp = ((8 * sdram->emc_pmacro_tx_pwrd2 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd2 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd2 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd2 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd2 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd2 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd2 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd2 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd2 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd2 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd2 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd2 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd2 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd2 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd2 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd2 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd2 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd2 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd2 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd2 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd2 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd2 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd2 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd2 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd2 & 1 | 2 * (pmc->scratch79 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF; + pmc->scratch79 = (sdram->emc_r2p << 26) | ((4 * sdram->emc_pmacro_tx_pwrd2 >> 31 << 25) | tmp) & 0x3FFFFFF; + tmp = (sdram->emc_pmacro_tx_pwrd3 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd3 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd3 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd3 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd3 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd3 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd3 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd3 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd3 & 1 | 2 * (pmc->scratch80 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF; + pmc->scratch80 = ((u8)(sdram->emc_ccdmw) << 26) | ((4 * sdram->emc_pmacro_tx_pwrd3 >> 31 << 25) | ((8 * sdram->emc_pmacro_tx_pwrd3 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd3 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd3 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd3 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd3 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd3 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd3 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd3 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd3 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd3 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd3 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd3 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd3 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd3 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd3 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd3 << 22 >> 31 << 9) | tmp & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0x3FFFFFF; + tmp = ((8 * sdram->emc_pmacro_tx_pwrd4 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd4 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd4 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd4 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd4 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd4 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd4 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd4 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd4 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd4 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd4 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd4 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd4 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd4 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd4 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd4 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd4 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd4 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd4 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd4 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd4 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd4 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd4 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd4 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd4 & 1 | 2 * (pmc->scratch81 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF; + pmc->scratch81 = ((u8)(sdram->emc_rd_rcd) << 26) | ((4 * sdram->emc_pmacro_tx_pwrd4 >> 31 << 25) | tmp) & 0x3FFFFFF; + tmp = ((8 * sdram->emc_pmacro_tx_pwrd5 >> 31 << 24) | ((32 * sdram->emc_pmacro_tx_pwrd5 >> 31 << 23) | ((sdram->emc_pmacro_tx_pwrd5 << 6 >> 31 << 22) | ((sdram->emc_pmacro_tx_pwrd5 << 7 >> 31 << 21) | ((sdram->emc_pmacro_tx_pwrd5 << 8 >> 31 << 20) | ((sdram->emc_pmacro_tx_pwrd5 << 9 >> 31 << 19) | ((sdram->emc_pmacro_tx_pwrd5 << 10 >> 31 << 18) | ((sdram->emc_pmacro_tx_pwrd5 << 11 >> 31 << 17) | ((sdram->emc_pmacro_tx_pwrd5 << 12 >> 31 << 16) | ((sdram->emc_pmacro_tx_pwrd5 << 13 >> 31 << 15) | ((sdram->emc_pmacro_tx_pwrd5 << 14 >> 31 << 14) | ((sdram->emc_pmacro_tx_pwrd5 << 15 >> 31 << 13) | ((sdram->emc_pmacro_tx_pwrd5 << 18 >> 31 << 12) | ((sdram->emc_pmacro_tx_pwrd5 << 19 >> 31 << 11) | ((sdram->emc_pmacro_tx_pwrd5 << 21 >> 31 << 10) | ((sdram->emc_pmacro_tx_pwrd5 << 22 >> 31 << 9) | ((sdram->emc_pmacro_tx_pwrd5 << 23 >> 31 << 8) | ((sdram->emc_pmacro_tx_pwrd5 << 24 >> 31 << 7) | ((sdram->emc_pmacro_tx_pwrd5 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_tx_pwrd5 << 26 >> 31) | (16 * (sdram->emc_pmacro_tx_pwrd5 << 27 >> 31) | (8 * (sdram->emc_pmacro_tx_pwrd5 << 28 >> 31) | (4 * (sdram->emc_pmacro_tx_pwrd5 << 29 >> 31) | (2 * (sdram->emc_pmacro_tx_pwrd5 << 30 >> 31) | (sdram->emc_pmacro_tx_pwrd5 & 1 | 2 * (pmc->scratch82 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF; + pmc->scratch82 = ((u16)(sdram->emc_wr_rcd) << 26) | ((4 * sdram->emc_pmacro_tx_pwrd5 >> 31 << 25) | tmp) & 0x3FFFFFF; + pmc->scratch83 = ((u8)(sdram->emc_config_sample_delay) << 25) | ((sdram->emc_auto_cal_channel >> 31 << 24) | ((2 * sdram->emc_auto_cal_channel >> 31 << 23) | ((4 * sdram->emc_auto_cal_channel >> 31 << 22) | ((16 * sdram->emc_auto_cal_channel >> 25 << 15) | ((sdram->emc_auto_cal_channel << 11 >> 27 << 10) | ((sdram->emc_auto_cal_channel << 20 >> 28 << 6) | (sdram->emc_auto_cal_channel & 0x3F | (pmc->scratch83 >> 6 << 6)) & 0xFFFFFC3F) & 0xFFFF83FF) & 0xFFC07FFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0x1FFFFFF; + pmc->scratch84 = (sdram->emc_sel_dpd_ctrl << 13 >> 29 << 29) | ((sdram->emc_sel_dpd_ctrl << 23 >> 31 << 28) | ((sdram->emc_sel_dpd_ctrl << 26 >> 31 << 27) | ((sdram->emc_sel_dpd_ctrl << 27 >> 31 << 26) | ((sdram->emc_sel_dpd_ctrl << 28 >> 31 << 25) | ((sdram->emc_sel_dpd_ctrl << 29 >> 31 << 24) | ((4 * sdram->emc_pmacro_rx_term >> 26 << 18) | ((sdram->emc_pmacro_rx_term << 10 >> 26 << 12) | ((sdram->emc_pmacro_rx_term << 18 >> 26 << 6) | (sdram->emc_pmacro_rx_term & 0x3F | (pmc->scratch84 >> 6 << 6)) & 0xFFFFF03F) & 0xFFFC0FFF) & 0xFF03FFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF; + pmc->scratch85 = (4 * sdram->emc_obdly >> 30 << 30) | (4 * ((sdram->emc_obdly << 24) | ((4 * sdram->emc_pmacro_dq_tx_drive >> 26 << 18) | ((sdram->emc_pmacro_dq_tx_drive << 10 >> 26 << 12) | ((sdram->emc_pmacro_dq_tx_drive << 18 >> 26 << 6) | (sdram->emc_pmacro_dq_tx_drive & 0x3F | (pmc->scratch85 >> 6 << 6)) & 0xFFFFF03F) & 0xFFFC0FFF) & 0xFF03FFFF) & 0xC0FFFFFF) >> 2); + pmc->scratch86 = (sdram->emc_pmacro_vttgen_ctrl1 << 10 >> 30 << 30) | (4 * ((sdram->emc_pmacro_vttgen_ctrl1 << 16 >> 26 << 24) | ((4 * sdram->emc_pmacro_ca_tx_drive >> 26 << 18) | ((sdram->emc_pmacro_ca_tx_drive << 10 >> 26 << 12) | ((sdram->emc_pmacro_ca_tx_drive << 18 >> 26 << 6) | (sdram->emc_pmacro_ca_tx_drive & 0x3F | (pmc->scratch86 >> 6 << 6)) & 0xFFFFF03F) & 0xFFFC0FFF) & 0xFF03FFFF) & 0xC0FFFFFF) >> 2); + pmc->scratch87 = (sdram->emc_pmacro_vttgen_ctrl2 >> 16 << 24) | ((16 * sdram->emc_pmacro_zcrtl >> 30 << 22) | ((sdram->emc_pmacro_zcrtl << 6 >> 30 << 20) | ((sdram->emc_pmacro_zcrtl << 8 >> 30 << 18) | ((sdram->emc_pmacro_zcrtl << 10 >> 30 << 16) | ((sdram->emc_pmacro_zcrtl << 12 >> 30 << 14) | ((sdram->emc_pmacro_zcrtl << 14 >> 30 << 12) | ((sdram->emc_pmacro_zcrtl << 16 >> 30 << 10) | ((sdram->emc_pmacro_zcrtl << 18 >> 30 << 8) | ((sdram->emc_pmacro_zcrtl << 20 >> 30 << 6) | (16 * (sdram->emc_pmacro_zcrtl << 22 >> 30) | (4 * (sdram->emc_pmacro_zcrtl << 24 >> 30) | ((sdram->emc_pmacro_zcrtl << 26 >> 30) | 4 * (pmc->scratch87 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFFFFFF; + pmc->scratch88 = (sdram->mc_emem_arb_timing_rc << 24) | ((sdram->emc_zcal_interval << 14) | ((sdram->emc_zcal_interval << 8 >> 18) | (pmc->scratch88 >> 14 << 14)) & 0xFF003FFF) & 0xFFFFFF; + pmc->scratch89 = ((u16)(sdram->mc_emem_arb_rsv) << 24) | ((sdram->emc_data_brlshft0 << 8 >> 29 << 21) | ((sdram->emc_data_brlshft0 << 11 >> 29 << 18) | ((sdram->emc_data_brlshft0 << 14 >> 29 << 15) | ((sdram->emc_data_brlshft0 << 17 >> 29 << 12) | ((sdram->emc_data_brlshft0 << 20 >> 29 << 9) | ((sdram->emc_data_brlshft0 << 23 >> 29 << 6) | (8 * (sdram->emc_data_brlshft0 << 26 >> 29) | (sdram->emc_data_brlshft0 & 7 | 8 * (pmc->scratch89 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0xFFFFFF; + pmc->scratch90 = (sdram->emc_data_brlshft1 << 8 >> 29 << 21) | ((sdram->emc_data_brlshft1 << 11 >> 29 << 18) | ((sdram->emc_data_brlshft1 << 14 >> 29 << 15) | ((sdram->emc_data_brlshft1 << 17 >> 29 << 12) | ((sdram->emc_data_brlshft1 << 20 >> 29 << 9) | ((sdram->emc_data_brlshft1 << 23 >> 29 << 6) | (8 * (sdram->emc_data_brlshft1 << 26 >> 29) | (sdram->emc_data_brlshft1 & 7 | 8 * (pmc->scratch90 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF; + pmc->scratch91 = (sdram->emc_dqs_brlshft0 << 8 >> 29 << 21) | ((sdram->emc_dqs_brlshft0 << 11 >> 29 << 18) | ((sdram->emc_dqs_brlshft0 << 14 >> 29 << 15) | ((sdram->emc_dqs_brlshft0 << 17 >> 29 << 12) | ((sdram->emc_dqs_brlshft0 << 20 >> 29 << 9) | ((sdram->emc_dqs_brlshft0 << 23 >> 29 << 6) | (8 * (sdram->emc_dqs_brlshft0 << 26 >> 29) | (sdram->emc_dqs_brlshft0 & 7 | 8 * (pmc->scratch91 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF; + pmc->scratch92 = (sdram->emc_dqs_brlshft1 << 8 >> 29 << 21) | ((sdram->emc_dqs_brlshft1 << 11 >> 29 << 18) | ((sdram->emc_dqs_brlshft1 << 14 >> 29 << 15) | ((sdram->emc_dqs_brlshft1 << 17 >> 29 << 12) | ((sdram->emc_dqs_brlshft1 << 20 >> 29 << 9) | ((sdram->emc_dqs_brlshft1 << 23 >> 29 << 6) | (8 * (sdram->emc_dqs_brlshft1 << 26 >> 29) | (sdram->emc_dqs_brlshft1 & 7 | 8 * (pmc->scratch92 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF; + pmc->scratch93 = (2 * sdram->emc_swizzle_rank0_byte0 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank0_byte0 >> 29 << 18) | ((sdram->emc_swizzle_rank0_byte0 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank0_byte0 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank0_byte0 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank0_byte0 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank0_byte0 << 25 >> 29) | (sdram->emc_swizzle_rank0_byte0 & 7 | 8 * (pmc->scratch93 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF; + pmc->scratch94 = ((u8)(sdram->emc_cfg) << 27 >> 31 << 31) | (2 * ((sdram->emc_ras << 24) | ((2 * sdram->emc_swizzle_rank0_byte1 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank0_byte1 >> 29 << 18) | ((sdram->emc_swizzle_rank0_byte1 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank0_byte1 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank0_byte1 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank0_byte1 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank0_byte1 << 25 >> 29) | (sdram->emc_swizzle_rank0_byte1 & 7 | 8 * (pmc->scratch94 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); + pmc->scratch95 = ((u8)(sdram->emc_cfg) << 26 >> 31 << 31) | (2 * ((sdram->emc_w2p << 24) | ((2 * sdram->emc_swizzle_rank0_byte2 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank0_byte2 >> 29 << 18) | ((sdram->emc_swizzle_rank0_byte2 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank0_byte2 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank0_byte2 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank0_byte2 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank0_byte2 << 25 >> 29) | (sdram->emc_swizzle_rank0_byte2 & 7 | 8 * (pmc->scratch95 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); + pmc->scratch96 = ((u8)(sdram->emc_cfg) << 25 >> 31 << 31) | (2 * ((sdram->emc_qsafe << 24) | ((2 * sdram->emc_swizzle_rank0_byte3 >> 29 << 21) | (((sdram->emc_swizzle_rank0_byte3 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank0_byte3 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank0_byte3 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank0_byte3 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank0_byte3 << 25 >> 29) | (sdram->emc_swizzle_rank0_byte3 & 7 | 8 * (pmc->scratch96 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF | (32 * sdram->emc_swizzle_rank0_byte3 >> 29 << 18)) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); + pmc->scratch97 = ((u8)(sdram->emc_cfg) << 24 >> 31 << 31) | (2 * ((sdram->emc_rdv << 24) | ((2 * sdram->emc_swizzle_rank1_byte0 >> 29 << 21) | (((sdram->emc_swizzle_rank1_byte0 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank1_byte0 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank1_byte0 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank1_byte0 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank1_byte0 << 25 >> 29) | (sdram->emc_swizzle_rank1_byte0 & 7 | 8 * (pmc->scratch97 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF | (32 * sdram->emc_swizzle_rank1_byte0 >> 29 << 18)) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); + pmc->scratch98 = ((u16)(sdram->emc_cfg) << 23 >> 31 << 31) | (2 * (((u16)(sdram->emc_rw2pden) << 24) | ((2 * sdram->emc_swizzle_rank1_byte1 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank1_byte1 >> 29 << 18) | ((sdram->emc_swizzle_rank1_byte1 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank1_byte1 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank1_byte1 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank1_byte1 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank1_byte1 << 25 >> 29) | (sdram->emc_swizzle_rank1_byte1 & 7 | 8 * (pmc->scratch98 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); + pmc->scratch99 = ((u16)(sdram->emc_cfg) << 22 >> 31 << 31) | (2 * ((sdram->emc_tfaw << 24) | ((2 * sdram->emc_swizzle_rank1_byte2 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank1_byte2 >> 29 << 18) | ((sdram->emc_swizzle_rank1_byte2 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank1_byte2 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank1_byte2 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank1_byte2 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank1_byte2 << 25 >> 29) | (sdram->emc_swizzle_rank1_byte2 & 7 | 8 * (pmc->scratch99 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); + pmc->scratch100 = (sdram->emc_cfg << 13 >> 31 << 31) | (2 * ((sdram->emc_tclkstable << 24) | ((2 * sdram->emc_swizzle_rank1_byte3 >> 29 << 21) | ((32 * sdram->emc_swizzle_rank1_byte3 >> 29 << 18) | ((sdram->emc_swizzle_rank1_byte3 << 9 >> 29 << 15) | ((sdram->emc_swizzle_rank1_byte3 << 13 >> 29 << 12) | ((sdram->emc_swizzle_rank1_byte3 << 17 >> 29 << 9) | ((sdram->emc_swizzle_rank1_byte3 << 21 >> 29 << 6) | (8 * (sdram->emc_swizzle_rank1_byte3 << 25 >> 29) | (sdram->emc_swizzle_rank1_byte3 & 7 | 8 * (pmc->scratch100 >> 3)) & 0xFFFFFFC7) & 0xFFFFFE3F) & 0xFFFFF1FF) & 0xFFFF8FFF) & 0xFFFC7FFF) & 0xFFE3FFFF) & 0xFF1FFFFF) & 0x80FFFFFF) >> 1); + tmp = 2 * (((u8)(sdram->emc_trtm) << 24) | ((16 * sdram->emc_cfg_pipe2 >> 31 << 23) | ((32 * sdram->emc_cfg_pipe2 >> 31 << 22) | ((sdram->emc_cfg_pipe2 << 6 >> 31 << 21) | ((sdram->emc_cfg_pipe2 << 7 >> 31 << 20) | ((sdram->emc_cfg_pipe2 << 8 >> 31 << 19) | ((sdram->emc_cfg_pipe2 << 9 >> 31 << 18) | ((sdram->emc_cfg_pipe2 << 10 >> 31 << 17) | ((sdram->emc_cfg_pipe2 << 11 >> 31 << 16) | ((sdram->emc_cfg_pipe2 << 12 >> 31 << 15) | ((sdram->emc_cfg_pipe2 << 13 >> 31 << 14) | ((sdram->emc_cfg_pipe2 << 14 >> 31 << 13) | ((sdram->emc_cfg_pipe2 << 15 >> 31 << 12) | ((sdram->emc_cfg_pipe2 << 20 >> 31 << 11) | ((sdram->emc_cfg_pipe2 << 21 >> 31 << 10) | ((sdram->emc_cfg_pipe2 << 22 >> 31 << 9) | ((sdram->emc_cfg_pipe2 << 23 >> 31 << 8) | ((sdram->emc_cfg_pipe2 << 24 >> 31 << 7) | ((sdram->emc_cfg_pipe2 << 25 >> 31 << 6) | (32 * (sdram->emc_cfg_pipe2 << 26 >> 31) | (16 * (sdram->emc_cfg_pipe2 << 27 >> 31) | (8 * (sdram->emc_cfg_pipe2 << 28 >> 31) | (4 * (sdram->emc_cfg_pipe2 << 29 >> 31) | (2 * (sdram->emc_cfg_pipe2 << 30 >> 31) | (sdram->emc_cfg_pipe2 & 1 | 2 * (pmc->scratch101 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1; + pmc->scratch101 = (sdram->emc_cfg << 10 >> 31 << 31) | tmp; + tmp = (2 * (pmc->scratch102 >> 1) | sdram->emc_cfg_pipe1 & 1) & 0xFFFFFFFD; + pmc->scratch102 = (sdram->emc_cfg << 9 >> 31 << 31) | (2 * (((u8)(sdram->emc_twtm) << 24) | ((16 * sdram->emc_cfg_pipe1 >> 31 << 23) | ((32 * sdram->emc_cfg_pipe1 >> 31 << 22) | ((sdram->emc_cfg_pipe1 << 6 >> 31 << 21) | ((sdram->emc_cfg_pipe1 << 7 >> 31 << 20) | ((sdram->emc_cfg_pipe1 << 8 >> 31 << 19) | ((sdram->emc_cfg_pipe1 << 9 >> 31 << 18) | ((sdram->emc_cfg_pipe1 << 10 >> 31 << 17) | ((sdram->emc_cfg_pipe1 << 11 >> 31 << 16) | ((sdram->emc_cfg_pipe1 << 12 >> 31 << 15) | ((sdram->emc_cfg_pipe1 << 13 >> 31 << 14) | ((sdram->emc_cfg_pipe1 << 14 >> 31 << 13) | ((sdram->emc_cfg_pipe1 << 15 >> 31 << 12) | ((sdram->emc_cfg_pipe1 << 20 >> 31 << 11) | ((sdram->emc_cfg_pipe1 << 21 >> 31 << 10) | ((sdram->emc_cfg_pipe1 << 22 >> 31 << 9) | ((sdram->emc_cfg_pipe1 << 23 >> 31 << 8) | ((sdram->emc_cfg_pipe1 << 24 >> 31 << 7) | ((sdram->emc_cfg_pipe1 << 25 >> 31 << 6) | (32 * (sdram->emc_cfg_pipe1 << 26 >> 31) | (16 * (sdram->emc_cfg_pipe1 << 27 >> 31) | (8 * (sdram->emc_cfg_pipe1 << 28 >> 31) | (4 * (sdram->emc_cfg_pipe1 << 29 >> 31) | (2 * (sdram->emc_cfg_pipe1 << 30 >> 31) | tmp) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1); + tmp = 2 * (((u8)(sdram->emc_tratm) << 24) | ((sdram->emc_pmacro_ddll_pwrd0 >> 31 << 23) | ((2 * sdram->emc_pmacro_ddll_pwrd0 >> 31 << 22) | ((8 * sdram->emc_pmacro_ddll_pwrd0 >> 31 << 21) | ((16 * sdram->emc_pmacro_ddll_pwrd0 >> 31 << 20) | ((32 * sdram->emc_pmacro_ddll_pwrd0 >> 31 << 19) | ((sdram->emc_pmacro_ddll_pwrd0 << 6 >> 31 << 18) | ((sdram->emc_pmacro_ddll_pwrd0 << 8 >> 31 << 17) | ((sdram->emc_pmacro_ddll_pwrd0 << 9 >> 31 << 16) | ((sdram->emc_pmacro_ddll_pwrd0 << 11 >> 31 << 15) | ((sdram->emc_pmacro_ddll_pwrd0 << 12 >> 31 << 14) | ((sdram->emc_pmacro_ddll_pwrd0 << 13 >> 31 << 13) | ((sdram->emc_pmacro_ddll_pwrd0 << 14 >> 31 << 12) | ((sdram->emc_pmacro_ddll_pwrd0 << 16 >> 31 << 11) | ((sdram->emc_pmacro_ddll_pwrd0 << 17 >> 31 << 10) | ((sdram->emc_pmacro_ddll_pwrd0 << 19 >> 31 << 9) | ((sdram->emc_pmacro_ddll_pwrd0 << 20 >> 31 << 8) | ((sdram->emc_pmacro_ddll_pwrd0 << 21 >> 31 << 7) | ((sdram->emc_pmacro_ddll_pwrd0 << 22 >> 31 << 6) | (32 * (sdram->emc_pmacro_ddll_pwrd0 << 24 >> 31) | (16 * (sdram->emc_pmacro_ddll_pwrd0 << 25 >> 31) | (8 * (sdram->emc_pmacro_ddll_pwrd0 << 27 >> 31) | (4 * (sdram->emc_pmacro_ddll_pwrd0 << 28 >> 31) | (2 * (sdram->emc_pmacro_ddll_pwrd0 << 29 >> 31) | ((sdram->emc_pmacro_ddll_pwrd0 << 30 >> 31) | 2 * (pmc->scratch103 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1; + pmc->scratch103 = (sdram->emc_cfg << 8 >> 31 << 31) | tmp; + tmp = 2 * (((u8)(sdram->emc_twatm) << 24) | ((sdram->emc_pmacro_ddll_pwrd1 >> 31 << 23) | ((2 * sdram->emc_pmacro_ddll_pwrd1 >> 31 << 22) | ((8 * sdram->emc_pmacro_ddll_pwrd1 >> 31 << 21) | ((16 * sdram->emc_pmacro_ddll_pwrd1 >> 31 << 20) | ((32 * sdram->emc_pmacro_ddll_pwrd1 >> 31 << 19) | ((sdram->emc_pmacro_ddll_pwrd1 << 6 >> 31 << 18) | ((sdram->emc_pmacro_ddll_pwrd1 << 8 >> 31 << 17) | ((sdram->emc_pmacro_ddll_pwrd1 << 9 >> 31 << 16) | ((sdram->emc_pmacro_ddll_pwrd1 << 11 >> 31 << 15) | ((sdram->emc_pmacro_ddll_pwrd1 << 12 >> 31 << 14) | ((sdram->emc_pmacro_ddll_pwrd1 << 13 >> 31 << 13) | ((sdram->emc_pmacro_ddll_pwrd1 << 14 >> 31 << 12) | ((sdram->emc_pmacro_ddll_pwrd1 << 16 >> 31 << 11) | ((sdram->emc_pmacro_ddll_pwrd1 << 17 >> 31 << 10) | ((sdram->emc_pmacro_ddll_pwrd1 << 19 >> 31 << 9) | ((sdram->emc_pmacro_ddll_pwrd1 << 20 >> 31 << 8) | ((sdram->emc_pmacro_ddll_pwrd1 << 21 >> 31 << 7) | ((sdram->emc_pmacro_ddll_pwrd1 << 22 >> 31 << 6) | (32 * (sdram->emc_pmacro_ddll_pwrd1 << 24 >> 31) | (16 * (sdram->emc_pmacro_ddll_pwrd1 << 25 >> 31) | (8 * (sdram->emc_pmacro_ddll_pwrd1 << 27 >> 31) | (4 * (sdram->emc_pmacro_ddll_pwrd1 << 28 >> 31) | (2 * (sdram->emc_pmacro_ddll_pwrd1 << 29 >> 31) | ((sdram->emc_pmacro_ddll_pwrd1 << 30 >> 31) | 2 * (pmc->scratch104 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1; + pmc->scratch104 = (sdram->emc_cfg << 7 >> 31 << 31) | tmp; + tmp = (sdram->emc_pmacro_ddll_pwrd2 << 22 >> 31 << 6) | (32 * (sdram->emc_pmacro_ddll_pwrd2 << 24 >> 31) | (16 * (sdram->emc_pmacro_ddll_pwrd2 << 25 >> 31) | (8 * (sdram->emc_pmacro_ddll_pwrd2 << 27 >> 31) | (4 * (sdram->emc_pmacro_ddll_pwrd2 << 28 >> 31) | (2 * (sdram->emc_pmacro_ddll_pwrd2 << 29 >> 31) | ((sdram->emc_pmacro_ddll_pwrd2 << 30 >> 31) | 2 * (pmc->scratch105 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF; + pmc->scratch105 = (sdram->emc_cfg << 6 >> 31 << 31) | (2 * (((u8)(sdram->emc_tr2ref) << 24) | ((sdram->emc_pmacro_ddll_pwrd2 >> 31 << 23) | ((2 * sdram->emc_pmacro_ddll_pwrd2 >> 31 << 22) | ((8 * sdram->emc_pmacro_ddll_pwrd2 >> 31 << 21) | ((16 * sdram->emc_pmacro_ddll_pwrd2 >> 31 << 20) | ((32 * sdram->emc_pmacro_ddll_pwrd2 >> 31 << 19) | ((sdram->emc_pmacro_ddll_pwrd2 << 6 >> 31 << 18) | ((sdram->emc_pmacro_ddll_pwrd2 << 8 >> 31 << 17) | ((sdram->emc_pmacro_ddll_pwrd2 << 9 >> 31 << 16) | ((sdram->emc_pmacro_ddll_pwrd2 << 11 >> 31 << 15) | ((sdram->emc_pmacro_ddll_pwrd2 << 12 >> 31 << 14) | ((sdram->emc_pmacro_ddll_pwrd2 << 13 >> 31 << 13) | ((sdram->emc_pmacro_ddll_pwrd2 << 14 >> 31 << 12) | ((sdram->emc_pmacro_ddll_pwrd2 << 16 >> 31 << 11) | ((sdram->emc_pmacro_ddll_pwrd2 << 17 >> 31 << 10) | ((sdram->emc_pmacro_ddll_pwrd2 << 19 >> 31 << 9) | ((sdram->emc_pmacro_ddll_pwrd2 << 20 >> 31 << 8) | ((sdram->emc_pmacro_ddll_pwrd2 << 21 >> 31 << 7) | tmp & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1); + pmc->scratch106 = (32 * sdram->emc_cfg >> 31 << 31) | (2 * (((u16)(sdram->emc_pdex2mrr) << 24) | ((8 * sdram->emc_pmacro_ddll_periodic_offset >> 31 << 23) | ((16 * sdram->emc_pmacro_ddll_periodic_offset >> 31 << 22) | ((32 * sdram->emc_pmacro_ddll_periodic_offset >> 31 << 21) | ((sdram->emc_pmacro_ddll_periodic_offset << 6 >> 31 << 20) | ((sdram->emc_pmacro_ddll_periodic_offset << 7 >> 31 << 19) | ((sdram->emc_pmacro_ddll_periodic_offset << 8 >> 31 << 18) | ((sdram->emc_pmacro_ddll_periodic_offset << 9 >> 31 << 17) | ((sdram->emc_pmacro_ddll_periodic_offset << 10 >> 31 << 16) | ((sdram->emc_pmacro_ddll_periodic_offset << 11 >> 31 << 15) | ((sdram->emc_pmacro_ddll_periodic_offset << 15 >> 31 << 14) | ((sdram->emc_pmacro_ddll_periodic_offset << 16 >> 31 << 13) | ((sdram->emc_pmacro_ddll_periodic_offset << 17 >> 31 << 12) | ((sdram->emc_pmacro_ddll_periodic_offset << 18 >> 31 << 11) | ((sdram->emc_pmacro_ddll_periodic_offset << 19 >> 31 << 10) | ((sdram->emc_pmacro_ddll_periodic_offset << 20 >> 31 << 9) | ((sdram->emc_pmacro_ddll_periodic_offset << 21 >> 31 << 8) | ((sdram->emc_pmacro_ddll_periodic_offset << 22 >> 31 << 7) | ((sdram->emc_pmacro_ddll_periodic_offset << 23 >> 31 << 6) | (sdram->emc_pmacro_ddll_periodic_offset & 0x3F | (pmc->scratch106 >> 6 << 6)) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1); + pmc->scratch107 = (8 * sdram->emc_cfg >> 31 << 31) | (2 * ((sdram->emc_clken_override << 15 >> 31 << 30) | ((sdram->emc_clken_override << 23 >> 31 << 29) | ((sdram->emc_clken_override << 24 >> 31 << 28) | ((sdram->emc_clken_override << 25 >> 31 << 27) | ((sdram->emc_clken_override << 28 >> 31 << 26) | ((sdram->emc_clken_override << 29 >> 31 << 25) | ((sdram->emc_clken_override << 30 >> 31 << 24) | ((sdram->mc_emem_arb_da_covers << 8 >> 24 << 16) | ((sdram->mc_emem_arb_da_covers << 16 >> 24 << 8) | (sdram->mc_emem_arb_da_covers & 0xFF | (pmc->scratch107 >> 8 << 8)) & 0xFFFF00FF) & 0xFF00FFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch108 = (sdram->emc_rfc_pb << 23) | ((sdram->emc_xm2_comp_pad_ctrl >> 24 << 15) | ((sdram->emc_xm2_comp_pad_ctrl << 12 >> 24 << 7) | ((sdram->emc_xm2_comp_pad_ctrl << 20 >> 31 << 6) | (32 * (sdram->emc_xm2_comp_pad_ctrl << 22 >> 31) | (4 * (sdram->emc_xm2_comp_pad_ctrl << 25 >> 29) | (sdram->emc_xm2_comp_pad_ctrl & 3 | 4 * (pmc->scratch108 >> 2)) & 0xFFFFFFE3) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFF807F) & 0xFF807FFF) & 0x7FFFFF; + pmc->scratch109 = (sdram->emc_cfg_update >> 31 << 31) | (2 * ((2 * sdram->emc_cfg_update >> 31 << 30) | ((4 * sdram->emc_cfg_update >> 31 << 29) | ((8 * sdram->emc_cfg_update >> 31 << 28) | ((sdram->emc_cfg_update << 21 >> 30 << 26) | ((sdram->emc_cfg_update << 23 >> 31 << 25) | ((sdram->emc_cfg_update << 29 >> 30 << 23) | ((sdram->emc_cfg_update << 22) & 0x7FFFFF | ((sdram->emc_auto_cal_config3 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config3 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config3 << 17 >> 25 << 7) | ((pmc->scratch109 >> 7 << 7) | sdram->emc_auto_cal_config3 & 0x7F) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFE7FFFFF) & 0xFDFFFFFF) & 0xF3FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch110 = (sdram->emc_rfc << 22) | ((sdram->emc_auto_cal_config4 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config4 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config4 << 17 >> 25 << 7) | (sdram->emc_auto_cal_config4 & 0x7F | (pmc->scratch110 >> 7 << 7)) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0x3FFFFF; + pmc->scratch111 = ((u16)(sdram->emc_txsr) << 22) | ((sdram->emc_auto_cal_config5 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config5 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config5 << 17 >> 25 << 7) | ((pmc->scratch111 >> 7 << 7) | sdram->emc_auto_cal_config5 & 0x7F) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0x3FFFFF; + pmc->scratch112 = (16 * sdram->emc_mc2emc_q >> 28 << 28) | ((sdram->emc_mc2emc_q << 21 >> 29 << 25) | ((sdram->emc_mc2emc_q << 22) & 0x1FFFFFF | ((sdram->emc_auto_cal_config6 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config6 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config6 << 17 >> 25 << 7) | (sdram->emc_auto_cal_config6 & 0x7F | (pmc->scratch112 >> 7 << 7)) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xFFFFFFF; + pmc->scratch113 = (sdram->mc_emem_arb_ring1_throttle << 11 >> 27 << 27) | ((sdram->mc_emem_arb_ring1_throttle << 22) | ((sdram->emc_auto_cal_config7 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config7 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config7 << 17 >> 25 << 7) | (sdram->emc_auto_cal_config7 & 0x7F | (pmc->scratch113 >> 7 << 7)) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xF83FFFFF) & 0x7FFFFFF; + pmc->scratch114 = (sdram->emc_auto_cal_config8 << 8 >> 28 << 18) | ((sdram->emc_auto_cal_config8 << 12 >> 28 << 14) | ((sdram->emc_auto_cal_config8 << 17 >> 25 << 7) | (sdram->emc_auto_cal_config8 & 0x7F | (pmc->scratch114 >> 7 << 7)) & 0xFFFFC07F) & 0xFFFC3FFF) & 0xFFC3FFFF; + pmc->scratch115 = (4 * sdram->emc_cfg >> 31 << 31) | (2 * (((u16)(sdram->emc_ar2pden) << 22) | ((sdram->emc_fbio_cfg7 << 10 >> 30 << 20) | ((sdram->emc_fbio_cfg7 << 12 >> 31 << 19) | ((sdram->emc_fbio_cfg7 << 13 >> 31 << 18) | ((sdram->emc_fbio_cfg7 << 14 >> 31 << 17) | ((sdram->emc_fbio_cfg7 << 15 >> 31 << 16) | ((sdram->emc_fbio_cfg7 << 16 >> 31 << 15) | ((sdram->emc_fbio_cfg7 << 17 >> 31 << 14) | ((sdram->emc_fbio_cfg7 << 18 >> 31 << 13) | ((sdram->emc_fbio_cfg7 << 19 >> 31 << 12) | ((sdram->emc_fbio_cfg7 << 20 >> 31 << 11) | ((sdram->emc_fbio_cfg7 << 21 >> 31 << 10) | ((sdram->emc_fbio_cfg7 << 22 >> 31 << 9) | ((sdram->emc_fbio_cfg7 << 23 >> 31 << 8) | ((sdram->emc_fbio_cfg7 << 24 >> 31 << 7) | ((sdram->emc_fbio_cfg7 << 25 >> 31 << 6) | (32 * (sdram->emc_fbio_cfg7 << 26 >> 31) | (16 * (sdram->emc_fbio_cfg7 << 27 >> 31) | (8 * (sdram->emc_fbio_cfg7 << 28 >> 31) | (4 * (sdram->emc_fbio_cfg7 << 29 >> 31) | (2 * (sdram->emc_fbio_cfg7 << 30 >> 31) | (sdram->emc_fbio_cfg7 & 1 | 2 * (pmc->scratch115 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFCFFFFF) & 0x803FFFFF) >> 1); + pmc->scratch123 = (2 * sdram->emc_cfg >> 31 << 31) | (2 * ((sdram->emc_rfc_slr << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank0_0 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_0 & 0x7FF | (pmc->scratch123 >> 11 << 11)) & 0xFFC007FF) & 0x803FFFFF) >> 1); + pmc->scratch124 = (sdram->emc_cfg >> 31 << 31) | (2 * ((4 * sdram->emc_ibdly >> 30 << 29) | ((sdram->emc_ibdly << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank0_1 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_1 & 0x7FF | (pmc->scratch124 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1); + pmc->scratch125 = (sdram->emc_fbio_cfg5 << 27 >> 31 << 31) | (2 * (((u16)(sdram->mc_emem_arb_timing_rfcpb) << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank0_2 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_2 & 0x7FF | (pmc->scratch125 >> 11 << 11)) & 0xFFC007FF) & 0x803FFFFF) >> 1); + pmc->scratch126 = (sdram->emc_fbio_cfg5 << 16 >> 29 << 29) | ((sdram->emc_auto_cal_config9 << 25 >> 31 << 28) | ((sdram->emc_auto_cal_config9 << 26 >> 31 << 27) | ((sdram->emc_auto_cal_config9 << 27 >> 31 << 26) | ((sdram->emc_auto_cal_config9 << 28 >> 31 << 25) | ((sdram->emc_auto_cal_config9 << 29 >> 31 << 24) | ((sdram->emc_auto_cal_config9 << 30 >> 31 << 23) | ((sdram->emc_auto_cal_config9 << 22) & 0x7FFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank0_3 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_3 & 0x7FF | (pmc->scratch126 >> 11 << 11)) & 0xFFC007FF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF; + pmc->scratch127 = ((u8)(sdram->emc_cfg2) << 26 >> 29 << 29) | ((sdram->emc_rdv_mask << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank0_4 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_4 & 0x7FF | (pmc->scratch127 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF; + pmc->scratch128 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 27 >> 29 << 29) | (((u8)(sdram->emc_rdv_early_mask) << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank0_5 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank0_5 & 0x7FF | (pmc->scratch128 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF; + pmc->scratch129 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 22 >> 29 << 29) | ((sdram->emc_rdv_early << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank1_0 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_0 & 0x7FF | (pmc->scratch129 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF; + pmc->scratch130 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 17 >> 29 << 29) | ((4 * sdram->emc_quse_width >> 31 << 28) | ((8 * sdram->emc_quse_width >> 31 << 27) | ((sdram->emc_quse_width << 22) & 0x7FFFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank1_1 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_1 & 0x7FF | (pmc->scratch130 >> 11 << 11)) & 0xFFC007FF) & 0xF83FFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF; + pmc->scratch131 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 12 >> 29 << 29) | (((u16)(sdram->emc_pmacro_ddll_short_cmd_2) << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank1_2 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_2 & 0x7FF | (pmc->scratch131 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF; + pmc->scratch132 = (sdram->emc_pmacro_data_pad_tx_ctrl << 27 >> 29 << 29) | ((sdram->emc_pmacro_cmd_rx_term_mode << 18 >> 31 << 28) | ((sdram->emc_pmacro_cmd_rx_term_mode << 22 >> 30 << 26) | ((sdram->emc_pmacro_cmd_rx_term_mode << 26 >> 30 << 24) | ((sdram->emc_pmacro_cmd_rx_term_mode << 22) & 0xFFFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank1_3 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_3 & 0x7FF | (pmc->scratch132 >> 11 << 11)) & 0xFFC007FF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF; + pmc->scratch133 = (sdram->emc_pmacro_data_pad_tx_ctrl << 22 >> 29 << 29) | ((sdram->emc_pmacro_data_rx_term_mode << 18 >> 31 << 28) | ((sdram->emc_pmacro_data_rx_term_mode << 22 >> 30 << 26) | ((sdram->emc_pmacro_data_rx_term_mode << 26 >> 30 << 24) | ((sdram->emc_pmacro_data_rx_term_mode << 22) & 0xFFFFFF | ((32 * sdram->emc_pmacro_quse_ddll_rank1_4 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_4 & 0x7FF | (pmc->scratch133 >> 11 << 11)) & 0xFFC007FF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xEFFFFFFF) & 0x1FFFFFFF; + pmc->scratch134 = (sdram->emc_pmacro_data_pad_tx_ctrl << 17 >> 29 << 29) | ((sdram->mc_emem_arb_timing_rp << 22) | ((32 * sdram->emc_pmacro_quse_ddll_rank1_5 >> 21 << 11) | (sdram->emc_pmacro_quse_ddll_rank1_5 & 0x7FF | (pmc->scratch134 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF; + pmc->scratch135 = (sdram->emc_pmacro_data_pad_tx_ctrl << 12 >> 29 << 29) | ((sdram->mc_emem_arb_timing_ras << 22) | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_0 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_0 & 0x7FF | (pmc->scratch135 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x1FFFFFFF; + pmc->scratch136 = (sdram->emc_fbio_cfg5 << 23 >> 31 << 31) | (2 * ((sdram->emc_cfg << 14 >> 30 << 29) | ((sdram->mc_emem_arb_timing_faw << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_1 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_1 & 0x7FF | (pmc->scratch136 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1); + pmc->scratch137 = (sdram->emc_fbio_cfg5 << 21 >> 31 << 31) | (2 * ((sdram->emc_fbio_cfg5 << 29) | ((sdram->mc_emem_arb_timing_rap2pre << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_2 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_2 & 0x7FF | (pmc->scratch137 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1); + pmc->scratch138 = (sdram->emc_fbio_cfg5 << 19 >> 31 << 31) | (2 * ((sdram->emc_fbio_cfg5 << 28 >> 30 << 29) | ((sdram->mc_emem_arb_timing_wap2pre << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_3 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_3 & 0x7FF | (pmc->scratch138 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1); + pmc->scratch139 = (sdram->emc_fbio_cfg5 << 7 >> 31 << 31) | (2 * ((16 * sdram->emc_cfg2 >> 30 << 29) | (((u8)(sdram->mc_emem_arb_timing_r2w) << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_4 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_4 & 0x7FF | (pmc->scratch139 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0x9FFFFFFF) >> 1); + pmc->scratch140 = (16 * sdram->emc_fbio_cfg5 >> 31 << 31) | (2 * ((32 * sdram->emc_fbio_cfg5 >> 31 << 30) | ((sdram->emc_fbio_cfg5 << 6 >> 31 << 29) | (((u8)(sdram->mc_emem_arb_timing_w2r) << 22) & 0x1FFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank0_5 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank0_5 & 0x7FF | (pmc->scratch140 >> 11 << 11)) & 0xFFC007FF) & 0xE03FFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch141 = (sdram->emc_fbio_cfg5 << 8 >> 28 << 28) | (((u16)(sdram->emc_wdv) << 22) | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_0 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_0 & 0x7FF | (pmc->scratch141 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xFFFFFFF; + pmc->scratch142 = ((u8)(sdram->emc_cfg2) << 31) | (2 * ((sdram->emc_fbio_cfg5 >> 31 << 30) | ((2 * sdram->emc_fbio_cfg5 >> 31 << 29) | ((8 * sdram->emc_fbio_cfg5 >> 31 << 28) | ((sdram->emc_quse << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_1 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_1 & 0x7FF | (pmc->scratch142 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch143 = (((u16)(sdram->emc_cfg2) << 21) >> 31 << 31) | (2 * ((((u16)(sdram->emc_cfg2) << 24) >> 31 << 30) | ((((u16)(sdram->emc_cfg2) << 29) >> 31 << 29) | ((((u16)(sdram->emc_cfg2) << 30) >> 31 << 28) | (((u8)(sdram->emc_pdex2wr) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_2 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_2 & 0x7FF | (pmc->scratch143 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch144 = (sdram->emc_cfg2 << 15 >> 31 << 31) | (2 * ((sdram->emc_cfg2 << 16 >> 31 << 30) | ((sdram->emc_cfg2 << 17 >> 31 << 29) | ((sdram->emc_cfg2 << 20 >> 31 << 28) | (((u8)(sdram->emc_pdex2rd) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_3 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_3 & 0x7FF | (pmc->scratch144 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch145 = (sdram->emc_cfg2 << 7 >> 31 << 31) | (2 * ((sdram->emc_cfg2 << 8 >> 31 << 30) | ((sdram->emc_cfg2 << 9 >> 31 << 29) | ((sdram->emc_cfg2 << 11 >> 31 << 28) | (((u16)(sdram->emc_pdex2che) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_4 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_4 & 0x7FF | (pmc->scratch145 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch146 = (2 * sdram->emc_cfg2 >> 31 << 31) | (2 * ((4 * sdram->emc_cfg2 >> 31 << 30) | (((sdram->emc_cfg2 << 6 >> 31 << 28) | (((u8)(sdram->emc_pchg2pden) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dq_rank1_5 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dq_rank1_5 & 0x7FF | (pmc->scratch146 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF | (8 * sdram->emc_cfg2 >> 31 << 29)) & 0xBFFFFFFF) >> 1); + pmc->scratch147 = (((u8)(sdram->emc_cfg_pipe) << 29) >> 31 << 31) | (2 * ((((u8)(sdram->emc_cfg_pipe) << 30) >> 31 << 30) | ((((u8)(sdram->emc_cfg_pipe) << 31) >> 2) | ((sdram->emc_cfg2 >> 31 << 28) | (((u16)(sdram->emc_act2pden) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_0 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_0 & 0x7FF | (pmc->scratch147 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch148 = (((u8)(sdram->emc_cfg_pipe) << 25) >> 31 << 31) | (2 * ((((u8)(sdram->emc_cfg_pipe) << 26) >> 31 << 30) | ((((u8)(sdram->emc_cfg_pipe) << 27) >> 31 << 29) | ((((u8)(sdram->emc_cfg_pipe) << 28) >> 31 << 28) | (((u16)(sdram->emc_cke2pden) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_1 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_1 & 0x7FF | (pmc->scratch148 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch149 = (((u16)(sdram->emc_cfg_pipe) << 21) >> 31 << 31) | (2 * ((((u16)(sdram->emc_cfg_pipe) << 22) >> 31 << 30) | ((((u16)(sdram->emc_cfg_pipe) << 23) >> 31 << 29) | ((((u16)(sdram->emc_cfg_pipe) << 24) >> 31 << 28) | ((sdram->emc_tcke << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_2 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_2 & 0x7FF | (pmc->scratch149 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch150 = (sdram->emc_cfg_pipe << 13 >> 31 << 31) | (2 * ((sdram->emc_cfg_pipe << 14 >> 31 << 30) | (((sdram->emc_cfg_pipe << 20 >> 31 << 28) | ((sdram->emc_trpab << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_3 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_3 & 0x7FF | (pmc->scratch150 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF | (sdram->emc_cfg_pipe << 15 >> 31 << 29)) & 0xBFFFFFFF) >> 1); + pmc->scratch151 = (sdram->emc_cfg_pipe << 9 >> 31 << 31) | (2 * ((sdram->emc_cfg_pipe << 10 >> 31 << 30) | ((sdram->emc_cfg_pipe << 11 >> 31 << 29) | ((sdram->emc_cfg_pipe << 12 >> 31 << 28) | ((sdram->emc_einput << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_4 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_4 & 0x7FF | (pmc->scratch151 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch152 = (32 * sdram->emc_cfg_pipe >> 31 << 31) | (2 * ((sdram->emc_cfg_pipe << 6 >> 31 << 30) | ((sdram->emc_cfg_pipe << 7 >> 31 << 29) | ((sdram->emc_cfg_pipe << 8 >> 31 << 28) | ((sdram->emc_einput_duration << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank0_5 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank0_5 & 0x7FF | (pmc->scratch152 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch153 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 29) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 30) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 31) >> 2) | ((16 * sdram->emc_cfg_pipe >> 31 << 28) | ((sdram->emc_puterm_extra << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_0 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_0 & 0x7FF | (pmc->scratch153 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch154 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 25) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 26) >> 31 << 30) | (((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 28) >> 31 << 28) | ((sdram->emc_tckesr << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_1 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_1 & 0x7FF | (pmc->scratch154 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF | (((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 27) >> 31 << 29)) & 0xBFFFFFFF) >> 1); + pmc->scratch155 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 21) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 22) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 23) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src0) << 24) >> 31 << 28) | ((sdram->emc_tpd << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_2 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_2 & 0x7FF | (pmc->scratch155 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch156 = (sdram->emc_pmacro_tx_sel_clk_src0 << 12 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src0 << 13 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 14 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 15 >> 31 << 28) | ((sdram->emc_wdv_mask << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_3 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_3 & 0x7FF | (pmc->scratch156 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch157 = (sdram->emc_pmacro_tx_sel_clk_src0 << 8 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src0 << 9 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 10 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 11 >> 31 << 28) | (((u16)(sdram->emc_wdv_chk) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_4 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_4 & 0x7FF | (pmc->scratch157 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch158 = ((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 31) | (2 * ((32 * sdram->emc_pmacro_tx_sel_clk_src0 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 6 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src0 << 7 >> 31 << 28) | (((u8)(sdram->emc_cmd_brlshft0) << 26 >> 29 << 25) | (((u8)(sdram->emc_cmd_brlshft0) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ob_ddll_long_dqs_rank1_5 >> 21 << 11) | (sdram->emc_pmacro_ob_ddll_long_dqs_rank1_5 & 0x7FF | (pmc->scratch158 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch159 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 27) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 28) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 29) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 30) >> 31 << 28) | (((u8)(sdram->emc_cmd_brlshft1) << 26 >> 29 << 25) | (((u8)(sdram->emc_cmd_brlshft1) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank0_0 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank0_0 & 0x7FF | (pmc->scratch159 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch160 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 23) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 24) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 25) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src1) << 26) >> 31 << 28) | (((u8)(sdram->emc_cmd_brlshft2) << 26 >> 29 << 25) | (((u8)(sdram->emc_cmd_brlshft2) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank0_1 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank0_1 & 0x7FF | (pmc->scratch160 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch161 = (sdram->emc_pmacro_tx_sel_clk_src1 << 14 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src1 << 15 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 21 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 22 >> 31 << 28) | (((u8)(sdram->emc_cmd_brlshft3) << 26 >> 29 << 25) | (((u8)(sdram->emc_cmd_brlshft3) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank0_2 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank0_2 & 0x7FF | (pmc->scratch161 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch162 = (sdram->emc_pmacro_tx_sel_clk_src1 << 10 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src1 << 11 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 12 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 13 >> 31 << 28) | (((u16)(sdram->emc_wev) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank0_3 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank0_3 & 0x7FF | (pmc->scratch162 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch163 = (sdram->emc_pmacro_tx_sel_clk_src1 << 6 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src1 << 7 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 8 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src1 << 9 >> 31 << 28) | (((u16)(sdram->emc_wsv) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank1_0 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank1_0 & 0x7FF | (pmc->scratch163 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch164 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 29) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 30) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 31) >> 2) | ((32 * sdram->emc_pmacro_tx_sel_clk_src1 >> 31 << 28) | (((u8)(sdram->emc_cfg3) << 25 >> 29 << 25) | (((u8)(sdram->emc_cfg3) << 22) & 0x1FFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank1_1 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank1_1 & 0x7FF | (pmc->scratch164 >> 11 << 11)) & 0xFFC007FF) & 0xFE3FFFFF) & 0xF1FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch165 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 25) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 26) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 27) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 28) >> 31 << 28) | ((sdram->emc_puterm_width << 23) & 0xFFFFFFF | ((sdram->emc_puterm_width >> 31 << 22) | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank1_2 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank1_2 & 0x7FF | (pmc->scratch165 >> 11 << 11)) & 0xFFC007FF) & 0xFFBFFFFF) & 0xF07FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch166 = (((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 21) >> 31 << 31) | (2 * ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 22) >> 31 << 30) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 23) >> 31 << 29) | ((((u16)(sdram->emc_pmacro_tx_sel_clk_src3) << 24) >> 31 << 28) | ((sdram->mc_emem_arb_timing_rcd << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ib_ddll_long_dqs_rank1_3 >> 21 << 11) | (sdram->emc_pmacro_ib_ddll_long_dqs_rank1_3 & 0x7FF | (pmc->scratch166 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch167 = (sdram->emc_pmacro_tx_sel_clk_src3 << 12 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src3 << 13 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 14 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 15 >> 31 << 28) | (((u16)(sdram->mc_emem_arb_timing_ccdmw) << 22) & 0xFFFFFFF | ((32 * sdram->emc_pmacro_ddll_long_cmd_0 >> 21 << 11) | (sdram->emc_pmacro_ddll_long_cmd_0 & 0x7FF | (pmc->scratch167 >> 11 << 11)) & 0xFFC007FF) & 0xF03FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch168 = (sdram->emc_pmacro_tx_sel_clk_src3 << 8 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src3 << 9 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 10 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 11 >> 31 << 28) | ((sdram->mc_emem_arb_override << 28 >> 31 << 27) | (((sdram->mc_emem_arb_override << 21 >> 31 << 25) | ((sdram->mc_emem_arb_override << 15 >> 31 << 24) | ((32 * sdram->mc_emem_arb_override >> 31 << 23) | ((16 * sdram->mc_emem_arb_override >> 31 << 22) | ((32 * sdram->emc_pmacro_ddll_long_cmd_1 >> 21 << 11) | (sdram->emc_pmacro_ddll_long_cmd_1 & 0x7FF | (pmc->scratch168 >> 11 << 11)) & 0xFFC007FF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF | (sdram->mc_emem_arb_override << 27 >> 31 << 26)) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch169 = ((u16)(sdram->emc_rext) << 27) | (((u16)(sdram->emc_rrd) << 22) | ((32 * sdram->emc_pmacro_ddll_long_cmd_2 >> 21 << 11) | (sdram->emc_pmacro_ddll_long_cmd_2 & 0x7FF | (pmc->scratch169 >> 11 << 11)) & 0xFFC007FF) & 0xF83FFFFF) & 0x7FFFFFF; + pmc->scratch170 = ((u16)(sdram->emc_wext) << 27) | ((sdram->emc_tclkstop << 22) | ((32 * sdram->emc_pmacro_ddll_long_cmd_3 >> 21 << 11) | (sdram->emc_pmacro_ddll_long_cmd_3 & 0x7FF | (pmc->scratch170 >> 11 << 11)) & 0xFFC007FF) & 0xF83FFFFF) & 0x7FFFFFF; + tmp = (32 * sdram->emc_pmacro_perbit_fgcg_ctrl0 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl0 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl0 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl0 & 1 | 2 * (pmc->scratch171 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF; + pmc->scratch171 = (sdram->emc_we_duration << 27) | ((sdram->emc_ref_ctrl2 >> 31 << 26) | ((32 * sdram->emc_ref_ctrl2 >> 29 << 23) | ((sdram->emc_ref_ctrl2 << 22) & 0x7FFFFF | tmp & 0xFFBFFFFF) & 0xFC7FFFFF) & 0xFBFFFFFF) & 0x7FFFFFF; + tmp = (sdram->emc_pmacro_pad_cfg_ctrl << 22 >> 31 << 28) | ((sdram->emc_pmacro_pad_cfg_ctrl << 27) & 0xFFFFFFF | ((sdram->emc_ws_duration << 22) & 0x7FFFFFF | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl1 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl1 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl1 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl1 & 1 | 2 * (pmc->scratch172 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xF83FFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF; + pmc->scratch172 = (sdram->emc_pmacro_pad_cfg_ctrl << 14 >> 30 << 30) | (4 * ((sdram->emc_pmacro_pad_cfg_ctrl << 18 >> 31 << 29) | tmp & 0xDFFFFFFF) >> 2); + pmc->scratch173 = ((u8)(sdram->mc_emem_arb_timing_r2r) << 27) | ((sdram->mc_emem_arb_timing_rrd << 22) | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl2 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl2 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl2 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl2 & 1 | 2 * (pmc->scratch173 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xF83FFFFF) & 0x7FFFFFF; + tmp = 32 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl3 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl3 & 1 | 2 * (pmc->scratch174 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF; + pmc->scratch174 = ((u16)(sdram->emc_pmacro_tx_sel_clk_src2) << 30 >> 31 << 31) | (2 * (((u16)(sdram->emc_pmacro_tx_sel_clk_src2) << 30) | ((32 * sdram->emc_pmacro_tx_sel_clk_src3 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 6 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src3 << 7 >> 31 << 27) | (((u8)(sdram->mc_emem_arb_timing_w2w) << 22) & 0x7FFFFFF | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl3 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl3 << 25 >> 31 << 6) | tmp & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xF83FFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + tmp = (sdram->emc_pmacro_tx_sel_clk_src2 << 28 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 29 >> 31 << 22) | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl4 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl4 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl4 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl4 & 1 | 2 * (pmc->scratch175 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF; + pmc->scratch175 = (sdram->emc_pmacro_tx_sel_clk_src2 << 15 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src2 << 21 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 22 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 23 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 24 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 25 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 26 >> 31 << 25) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 27 >> 31 << 24) | tmp & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + tmp = (sdram->emc_pmacro_tx_sel_clk_src2 << 12 >> 31 << 24) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 13 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 14 >> 31 << 22) | ((32 * sdram->emc_pmacro_perbit_fgcg_ctrl5 >> 31 << 21) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 6 >> 31 << 20) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 7 >> 31 << 19) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 8 >> 31 << 18) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 9 >> 31 << 17) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 10 >> 31 << 16) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 11 >> 31 << 15) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 12 >> 31 << 14) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 13 >> 31 << 13) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 14 >> 31 << 12) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 15 >> 31 << 11) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 21 >> 31 << 10) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 22 >> 31 << 9) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 23 >> 31 << 8) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 24 >> 31 << 7) | ((sdram->emc_pmacro_perbit_fgcg_ctrl5 << 25 >> 31 << 6) | (32 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 26 >> 31) | (16 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 27 >> 31) | (8 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 28 >> 31) | (4 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 29 >> 31) | (2 * (sdram->emc_pmacro_perbit_fgcg_ctrl5 << 30 >> 31) | (sdram->emc_pmacro_perbit_fgcg_ctrl5 & 1 | 2 * (pmc->scratch176 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF; + pmc->scratch176 = (32 * sdram->emc_pmacro_tx_sel_clk_src2 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src2 << 6 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 7 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 8 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 9 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 10 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src2 << 11 >> 31 << 25) | tmp & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch177 = (sdram->emc_pmacro_tx_sel_clk_src4 << 22 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src4 << 23 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 24 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 25 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 26 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 27 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 28 >> 31 << 25) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 29 >> 31 << 24) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 30 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 22) & 0x7FFFFF | ((sdram->mc_emem_arb_cfg >> 28 << 18) | ((16 * sdram->mc_emem_arb_cfg >> 28 << 14) | ((sdram->mc_emem_arb_cfg << 11 >> 27 << 9) | (sdram->mc_emem_arb_cfg & 0x1FF | (pmc->scratch177 >> 9 << 9)) & 0xFFFFC1FF) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch178 = (sdram->emc_pmacro_tx_sel_clk_src4 << 7 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src4 << 8 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 9 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 10 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 11 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 12 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 13 >> 31 << 25) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 14 >> 31 << 24) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 15 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src4 << 21 >> 31 << 22) | ((sdram->mc_emem_arb_misc1 >> 28 << 18) | ((sdram->mc_emem_arb_misc1 << 6 >> 30 << 16) | ((sdram->mc_emem_arb_misc1 << 8 >> 29 << 13) | (16 * (sdram->mc_emem_arb_misc1 << 19 >> 23) | (8 * (sdram->mc_emem_arb_misc1 << 28 >> 31) | (4 * (sdram->mc_emem_arb_misc1 << 29 >> 31) | (2 * (sdram->mc_emem_arb_misc1 << 30 >> 31) | (sdram->mc_emem_arb_misc1 & 1 | 2 * (pmc->scratch178 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFE00F) & 0xFFFF1FFF) & 0xFFFCFFFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch179 = (sdram->emc_odt_write >> 31 << 31) | (2 * ((sdram->emc_odt_write << 20 >> 28 << 27) | ((sdram->emc_odt_write << 26 >> 31 << 26) | ((sdram->emc_odt_write << 27 >> 31 << 25) | ((sdram->emc_odt_write << 21) & 0x1FFFFFF | ((32 * sdram->emc_mrs_wait_cnt2 >> 21 << 10) | (sdram->emc_mrs_wait_cnt2 & 0x3FF | (pmc->scratch179 >> 10 << 10)) & 0xFFE003FF) & 0xFE1FFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0x87FFFFFF) >> 1); + pmc->scratch180 = (sdram->emc_pmacro_ib_rxrt << 21) | ((32 * sdram->emc_mrs_wait_cnt >> 21 << 10) | (sdram->emc_mrs_wait_cnt & 0x3FF | (pmc->scratch180 >> 10 << 10)) & 0xFFE003FF) & 0x1FFFFF; + pmc->scratch181 = ((u16)(sdram->emc_pmacro_ddll_long_cmd_4) << 21) | sdram->emc_auto_cal_interval & 0x1FFFFF; + pmc->scratch182 = (sdram->mc_emem_arb_outstanding_req >> 31 << 31) | (2 * ((2 * sdram->mc_emem_arb_outstanding_req >> 31 << 30) | ((sdram->mc_emem_arb_outstanding_req << 23 >> 2) | ((sdram->emc_emem_arb_refpb_hp_ctrl << 9 >> 25 << 14) | ((sdram->emc_emem_arb_refpb_hp_ctrl << 17 >> 25 << 7) | (sdram->emc_emem_arb_refpb_hp_ctrl & 0x7F | (pmc->scratch182 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xC01FFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch183 = (4 * sdram->emc_pmacro_cmd_ctrl0 >> 31 << 31) | (2 * ((8 * sdram->emc_pmacro_cmd_ctrl0 >> 31 << 30) | ((sdram->emc_pmacro_cmd_ctrl0 << 7 >> 31 << 29) | ((sdram->emc_pmacro_cmd_ctrl0 << 10 >> 31 << 28) | ((sdram->emc_pmacro_cmd_ctrl0 << 11 >> 31 << 27) | ((sdram->emc_pmacro_cmd_ctrl0 << 15 >> 31 << 26) | ((sdram->emc_pmacro_cmd_ctrl0 << 18 >> 31 << 25) | ((sdram->emc_pmacro_cmd_ctrl0 << 19 >> 31 << 24) | ((sdram->emc_pmacro_cmd_ctrl0 << 23 >> 31 << 23) | ((sdram->emc_pmacro_cmd_ctrl0 << 26 >> 31 << 22) | ((sdram->emc_pmacro_cmd_ctrl0 << 27 >> 31 << 21) | ((sdram->emc_pmacro_cmd_ctrl0 << 20) & 0x1FFFFF | ((4 * sdram->emc_xm2_comp_pad_ctrl2 >> 26 << 14) | ((sdram->emc_xm2_comp_pad_ctrl2 << 10 >> 30 << 12) | ((sdram->emc_xm2_comp_pad_ctrl2 << 14 >> 31 << 11) | ((sdram->emc_xm2_comp_pad_ctrl2 << 15 >> 31 << 10) | ((sdram->emc_xm2_comp_pad_ctrl2 << 16 >> 30 << 8) | ((sdram->emc_xm2_comp_pad_ctrl2 << 18 >> 30 << 6) | (4 * (sdram->emc_xm2_comp_pad_ctrl2 << 26 >> 28) | (sdram->emc_xm2_comp_pad_ctrl2 & 3 | 4 * (pmc->scratch183 >> 2)) & 0xFFFFFFC3) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFCFFF) & 0xFFF03FFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch184 = (4 * sdram->emc_pmacro_cmd_ctrl1 >> 31 << 31) | (2 * ((8 * sdram->emc_pmacro_cmd_ctrl1 >> 31 << 30) | ((sdram->emc_pmacro_cmd_ctrl1 << 7 >> 31 << 29) | ((sdram->emc_pmacro_cmd_ctrl1 << 10 >> 31 << 28) | ((sdram->emc_pmacro_cmd_ctrl1 << 11 >> 31 << 27) | ((sdram->emc_pmacro_cmd_ctrl1 << 15 >> 31 << 26) | ((sdram->emc_pmacro_cmd_ctrl1 << 18 >> 31 << 25) | ((sdram->emc_pmacro_cmd_ctrl1 << 19 >> 31 << 24) | ((sdram->emc_pmacro_cmd_ctrl1 << 23 >> 31 << 23) | ((sdram->emc_pmacro_cmd_ctrl1 << 26 >> 31 << 22) | ((sdram->emc_pmacro_cmd_ctrl1 << 27 >> 31 << 21) | ((sdram->emc_pmacro_cmd_ctrl1 << 20) & 0x1FFFFF | ((sdram->emc_cfg_dig_dll_1 << 12 >> 28 << 16) | ((sdram->emc_cfg_dig_dll_1 << 16 >> 28 << 12) | ((sdram->emc_cfg_dig_dll_1 << 20 >> 26 << 6) | (2 * (sdram->emc_cfg_dig_dll_1 << 26 >> 27) | (sdram->emc_cfg_dig_dll_1 & 1 | 2 * (pmc->scratch184 >> 1)) & 0xFFFFFFC1) & 0xFFFFF03F) & 0xFFFF0FFF) & 0xFFF0FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch185 = (4 * sdram->emc_pmacro_cmd_ctrl2 >> 31 << 31) | (2 * ((8 * sdram->emc_pmacro_cmd_ctrl2 >> 31 << 30) | ((sdram->emc_pmacro_cmd_ctrl2 << 7 >> 31 << 29) | ((sdram->emc_pmacro_cmd_ctrl2 << 10 >> 31 << 28) | ((sdram->emc_pmacro_cmd_ctrl2 << 11 >> 31 << 27) | ((sdram->emc_pmacro_cmd_ctrl2 << 15 >> 31 << 26) | ((sdram->emc_pmacro_cmd_ctrl2 << 18 >> 31 << 25) | ((sdram->emc_pmacro_cmd_ctrl2 << 19 >> 31 << 24) | ((sdram->emc_pmacro_cmd_ctrl2 << 23 >> 31 << 23) | ((sdram->emc_pmacro_cmd_ctrl2 << 26 >> 31 << 22) | ((sdram->emc_pmacro_cmd_ctrl2 << 27 >> 31 << 21) | ((sdram->emc_pmacro_cmd_ctrl2 << 20) & 0x1FFFFF | ((sdram->emc_quse_brlshft0 << 12 >> 27 << 15) | ((sdram->emc_quse_brlshft0 << 17 >> 27 << 10) | (32 * (sdram->emc_quse_brlshft0 << 22 >> 27) | (sdram->emc_quse_brlshft0 & 0x1F | 32 * (pmc->scratch185 >> 5)) & 0xFFFFFC1F) & 0xFFFF83FF) & 0xFFF07FFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch186 = (sdram->emc_pmacro_dsr_vttgen_ctrl0 >> 8 << 24) | ((sdram->emc_pmacro_dsr_vttgen_ctrl0 << 20) | ((sdram->emc_quse_brlshft1 << 12 >> 27 << 15) | ((sdram->emc_quse_brlshft1 << 17 >> 27 << 10) | (32 * (sdram->emc_quse_brlshft1 << 22 >> 27) | (sdram->emc_quse_brlshft1 & 0x1F | 32 * (pmc->scratch186 >> 5)) & 0xFFFFFC1F) & 0xFFFF83FF) & 0xFFF07FFF) & 0xFF0FFFFF) & 0xFFFFFF; + pmc->scratch187 = (sdram->emc_pmacro_perbit_rfu1_ctrl0 << 10 >> 30 << 30) | (4 * ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 12 >> 30 << 28) | ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 14 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 26 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 28 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu1_ctrl0 << 20) & 0x3FFFFF | ((sdram->emc_quse_brlshft2 << 12 >> 27 << 15) | ((sdram->emc_quse_brlshft2 << 17 >> 27 << 10) | (32 * (sdram->emc_quse_brlshft2 << 22 >> 27) | (sdram->emc_quse_brlshft2 & 0x1F | 32 * (pmc->scratch187 >> 5)) & 0xFFFFFC1F) & 0xFFFF83FF) & 0xFFF07FFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); + pmc->scratch188 = (sdram->emc_pmacro_perbit_rfu1_ctrl1 << 10 >> 30 << 30) | (4 * ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 12 >> 30 << 28) | ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 14 >> 30 << 26) | ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 26 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 28 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu1_ctrl1 << 20) & 0x3FFFFF | ((sdram->emc_quse_brlshft3 << 12 >> 27 << 15) | ((sdram->emc_quse_brlshft3 << 17 >> 27 << 10) | (32 * (sdram->emc_quse_brlshft3 << 22 >> 27) | (sdram->emc_quse_brlshft3 & 0x1F | 32 * (pmc->scratch188 >> 5)) & 0xFFFFFC1F) & 0xFFFF83FF) & 0xFFF07FFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF) & 0xCFFFFFFF) >> 2); + pmc->scratch189 = (sdram->emc_trefbw << 18) | ((sdram->emc_dbg >> 31 << 17) | ((2 * sdram->emc_dbg >> 31 << 16) | ((4 * sdram->emc_dbg >> 31 << 15) | ((8 * sdram->emc_dbg >> 31 << 14) | ((16 * sdram->emc_dbg >> 30 << 12) | ((sdram->emc_dbg << 6 >> 31 << 11) | ((sdram->emc_dbg << 7 >> 31 << 10) | ((sdram->emc_dbg << 18 >> 31 << 9) | ((sdram->emc_dbg << 19 >> 31 << 8) | ((sdram->emc_dbg << 20 >> 31 << 7) | ((sdram->emc_dbg << 21 >> 31 << 6) | (32 * (sdram->emc_dbg << 22 >> 31) | (16 * (sdram->emc_dbg << 27 >> 31) | (8 * (sdram->emc_dbg << 28 >> 31) | (4 * (sdram->emc_dbg << 29 >> 31) | (2 * (sdram->emc_dbg << 30 >> 31) | (sdram->emc_dbg & 1 | 2 * (pmc->scratch189 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFCFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0x3FFFF; + pmc->scratch191 = (sdram->emc_qpop << 9 >> 25 << 25) | ((sdram->emc_qpop << 18) | ((sdram->emc_zcal_wait_cnt >> 31 << 17) | ((sdram->emc_zcal_wait_cnt << 10 >> 26 << 11) | (sdram->emc_zcal_wait_cnt & 0x7FF | (pmc->scratch191 >> 11 << 11)) & 0xFFFE07FF) & 0xFFFDFFFF) & 0xFE03FFFF) & 0x1FFFFFF; + pmc->scratch192 = (sdram->emc_pmacro_tx_sel_clk_src4 << 6 >> 31 << 31) | (2 * ((sdram->emc_pmacro_auto_cal_common << 15 >> 31 << 30) | ((sdram->emc_pmacro_auto_cal_common << 18 >> 26 << 24) | ((sdram->emc_pmacro_auto_cal_common << 18) & 0xFFFFFF | ((sdram->emc_zcal_mrw_cmd >> 30 << 16) | ((sdram->emc_zcal_mrw_cmd << 8 >> 24 << 8) | (sdram->emc_zcal_mrw_cmd & 0xFF | (pmc->scratch192 >> 8 << 8)) & 0xFFFF00FF) & 0xFFFCFFFF) & 0xFF03FFFF) & 0xC0FFFFFF) & 0xBFFFFFFF) >> 1); + tmp = (sdram->emc_dll_cfg1 << 7 >> 31 << 17) | ((sdram->emc_dll_cfg1 << 10 >> 31 << 16) | ((sdram->emc_dll_cfg1 << 11 >> 31 << 15) | ((sdram->emc_dll_cfg1 << 14 >> 30 << 13) | ((sdram->emc_dll_cfg1 << 18 >> 31 << 12) | ((sdram->emc_dll_cfg1 << 19 >> 31 << 11) | ((pmc->scratch193 >> 11 << 11) | sdram->emc_dll_cfg1 & 0x7FF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFF9FFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF; + pmc->scratch193 = (sdram->emc_pmacro_tx_sel_clk_src5 << 31) | (2 * ((32 * sdram->emc_pmacro_tx_sel_clk_src4 >> 31 << 30) | ((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 10 >> 30 << 28) | (((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 14 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 26 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 28 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu1_ctrl2 << 18) & 0xFFFFF | tmp & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl2 << 12 >> 30 << 26)) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch194 = (sdram->emc_pmacro_tx_sel_clk_src5 << 29 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src5 << 30 >> 31 << 30) | ((sdram->emc_pmacro_perbit_rfu1_ctrl3 << 10 >> 30 << 28) | (((sdram->emc_pmacro_perbit_rfu1_ctrl3 << 14 >> 30 << 24) | (((sdram->emc_pmacro_perbit_rfu1_ctrl3 << 28 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu1_ctrl3 << 18) & 0xFFFFF | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 14 >> 30 << 16) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 16 >> 30 << 14) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 18 >> 30 << 12) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 20 >> 30 << 10) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 22 >> 30 << 8) | ((sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 26 >> 30) | (4 * (sdram->emc_pmacro_cmd_brick_ctrl_fdpd << 28 >> 30) | (sdram->emc_pmacro_cmd_brick_ctrl_fdpd & 3 | 4 * (pmc->scratch194 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl3 << 26 >> 30 << 22)) & 0xFCFFFFFF) & 0xF3FFFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl3 << 12 >> 30 << 26)) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch195 = (sdram->emc_pmacro_tx_sel_clk_src5 << 27 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src5 << 28 >> 31 << 30) | ((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 10 >> 30 << 28) | (((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 14 >> 30 << 24) | ((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 26 >> 30 << 22) | ((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 28 >> 30 << 20) | ((sdram->emc_pmacro_perbit_rfu1_ctrl4 << 18) & 0xFFFFF | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 14 >> 30 << 16) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 16 >> 30 << 14) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 18 >> 30 << 12) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 20 >> 30 << 10) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 22 >> 30 << 8) | ((sdram->emc_pmacro_data_brick_ctrl_fdpd << 24 >> 30 << 6) | (16 * (sdram->emc_pmacro_data_brick_ctrl_fdpd << 26 >> 30) | (4 * (sdram->emc_pmacro_data_brick_ctrl_fdpd << 28 >> 30) | (sdram->emc_pmacro_data_brick_ctrl_fdpd & 3 | 4 * (pmc->scratch195 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFCF) & 0xFFFFFF3F) & 0xFFFFFCFF) & 0xFFFFF3FF) & 0xFFFFCFFF) & 0xFFFF3FFF) & 0xFFFCFFFF) & 0xFFF3FFFF) & 0xFFCFFFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xF3FFFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl4 << 12 >> 30 << 26)) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch196 = (sdram->emc_emem_arb_refpb_bank_ctrl >> 31 << 31) | (2 * ((sdram->emc_emem_arb_refpb_bank_ctrl << 17 >> 25 << 24) | ((sdram->emc_emem_arb_refpb_bank_ctrl << 17) & 0xFFFFFF | ((sdram->emc_dyn_self_ref_control >> 31 << 16) | (sdram->emc_dyn_self_ref_control & 0xFFFF | (pmc->scratch196 >> 16 << 16)) & 0xFFFEFFFF) & 0xFF01FFFF) & 0x80FFFFFF) >> 1); + pmc->scratch197 = (sdram->emc_pmacro_tx_sel_clk_src5 << 24 >> 31 << 31) | (2 * ((sdram->emc_pmacro_tx_sel_clk_src5 << 25 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 26 >> 31 << 29) | ((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 10 >> 30 << 27) | (((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 14 >> 30 << 23) | ((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 26 >> 30 << 21) | ((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 28 >> 30 << 19) | ((sdram->emc_pmacro_perbit_rfu1_ctrl5 << 17) & 0x7FFFF | ((16 * sdram->emc_pmacro_cmd_pad_rx_ctrl >> 28 << 13) | ((sdram->emc_pmacro_cmd_pad_rx_ctrl << 8 >> 31 << 12) | ((sdram->emc_pmacro_cmd_pad_rx_ctrl << 9 >> 31 << 11) | ((sdram->emc_pmacro_cmd_pad_rx_ctrl << 10 >> 31 << 10) | ((sdram->emc_pmacro_cmd_pad_rx_ctrl << 12 >> 28 << 6) | (32 * (sdram->emc_pmacro_cmd_pad_rx_ctrl << 16 >> 31) | (16 * (sdram->emc_pmacro_cmd_pad_rx_ctrl << 19 >> 31) | (4 * (sdram->emc_pmacro_cmd_pad_rx_ctrl << 26 >> 30) | (sdram->emc_pmacro_cmd_pad_rx_ctrl & 3 | 4 * (pmc->scratch197 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFC3F) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFE1FFF) & 0xFFF9FFFF) & 0xFFE7FFFF) & 0xFF9FFFFF) & 0xFE7FFFFF) & 0xF9FFFFFF | (sdram->emc_pmacro_perbit_rfu1_ctrl5 << 12 >> 30 << 25)) & 0xE7FFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch198 = (sdram->emc_pmacro_cmd_pad_tx_ctrl << 31) | (2 * ((32 * sdram->emc_pmacro_tx_sel_clk_src5 >> 31 << 30) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 6 >> 31 << 29) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 7 >> 31 << 28) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 8 >> 31 << 27) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 9 >> 31 << 26) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 10 >> 31 << 25) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 11 >> 31 << 24) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 12 >> 31 << 23) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 13 >> 31 << 22) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 14 >> 31 << 21) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 15 >> 31 << 20) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 21 >> 31 << 19) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 22 >> 31 << 18) | ((sdram->emc_pmacro_tx_sel_clk_src5 << 23 >> 31 << 17) | ((16 * sdram->emc_pmacro_data_pad_rx_ctrl >> 28 << 13) | ((sdram->emc_pmacro_data_pad_rx_ctrl << 8 >> 31 << 12) | ((sdram->emc_pmacro_data_pad_rx_ctrl << 9 >> 31 << 11) | ((sdram->emc_pmacro_data_pad_rx_ctrl << 10 >> 31 << 10) | ((sdram->emc_pmacro_data_pad_rx_ctrl << 12 >> 28 << 6) | (32 * (sdram->emc_pmacro_data_pad_rx_ctrl << 16 >> 31) | (16 * (sdram->emc_pmacro_data_pad_rx_ctrl << 19 >> 31) | (4 * (sdram->emc_pmacro_data_pad_rx_ctrl << 26 >> 30) | (sdram->emc_pmacro_data_pad_rx_ctrl & 3 | 4 * (pmc->scratch198 >> 2)) & 0xFFFFFFF3) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFC3F) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFE1FFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch199 = (8 * sdram->emc_cmd_q >> 27 << 27) | ((sdram->emc_cmd_q << 17 >> 29 << 24) | ((sdram->emc_cmd_q << 21 >> 29 << 21) | ((sdram->emc_cmd_q << 16) & 0x1FFFFF | (((u16)(sdram->emc_refresh) << 16 >> 22 << 6) | (sdram->emc_refresh & 0x3F | (pmc->scratch199 >> 6 << 6)) & 0xFFFF003F) & 0xFFE0FFFF) & 0xFF1FFFFF) & 0xF8FFFFFF) & 0x7FFFFFF; + pmc->scratch210 = (sdram->emc_auto_cal_vref_sel1 << 16 >> 31 << 31) | (2 * ((sdram->emc_auto_cal_vref_sel1 << 17 >> 25 << 24) | ((sdram->emc_auto_cal_vref_sel1 << 24 >> 31 << 23) | ((sdram->emc_auto_cal_vref_sel1 << 16) & 0x7FFFFF | (sdram->emc_acpd_control & 0xFFFF | (pmc->scratch210 >> 16 << 16)) & 0xFF80FFFF) & 0xFF7FFFFF) & 0x80FFFFFF) >> 1); + tmp = 8 * (sdram->emc_pmacro_auto_cal_cfg0 << 28 >> 31) | (4 * (sdram->emc_pmacro_auto_cal_cfg0 << 29 >> 31) | (2 * (sdram->emc_pmacro_auto_cal_cfg0 << 30 >> 31) | (sdram->emc_pmacro_auto_cal_cfg0 & 1 | 2 * (pmc->scratch211 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7; + tmp = (sdram->emc_pmacro_auto_cal_cfg1 << 7 >> 31 << 28) | ((sdram->emc_pmacro_auto_cal_cfg1 << 12 >> 31 << 27) | ((sdram->emc_pmacro_auto_cal_cfg1 << 13 >> 31 << 26) | ((sdram->emc_pmacro_auto_cal_cfg1 << 14 >> 31 << 25) | ((sdram->emc_pmacro_auto_cal_cfg1 << 15 >> 31 << 24) | ((sdram->emc_pmacro_auto_cal_cfg1 << 20 >> 31 << 23) | ((sdram->emc_pmacro_auto_cal_cfg1 << 21 >> 31 << 22) | ((sdram->emc_pmacro_auto_cal_cfg1 << 22 >> 31 << 21) | ((sdram->emc_pmacro_auto_cal_cfg1 << 23 >> 31 << 20) | ((sdram->emc_pmacro_auto_cal_cfg1 << 28 >> 31 << 19) | ((sdram->emc_pmacro_auto_cal_cfg1 << 29 >> 31 << 18) | ((sdram->emc_pmacro_auto_cal_cfg1 << 30 >> 31 << 17) | ((sdram->emc_pmacro_auto_cal_cfg1 << 16) & 0x1FFFF | ((16 * sdram->emc_pmacro_auto_cal_cfg0 >> 31 << 15) | ((32 * sdram->emc_pmacro_auto_cal_cfg0 >> 31 << 14) | ((sdram->emc_pmacro_auto_cal_cfg0 << 6 >> 31 << 13) | ((sdram->emc_pmacro_auto_cal_cfg0 << 7 >> 31 << 12) | ((sdram->emc_pmacro_auto_cal_cfg0 << 12 >> 31 << 11) | ((sdram->emc_pmacro_auto_cal_cfg0 << 13 >> 31 << 10) | ((sdram->emc_pmacro_auto_cal_cfg0 << 14 >> 31 << 9) | ((sdram->emc_pmacro_auto_cal_cfg0 << 15 >> 31 << 8) | ((sdram->emc_pmacro_auto_cal_cfg0 << 20 >> 31 << 7) | ((sdram->emc_pmacro_auto_cal_cfg0 << 21 >> 31 << 6) | (32 * (sdram->emc_pmacro_auto_cal_cfg0 << 22 >> 31) | (16 * (sdram->emc_pmacro_auto_cal_cfg0 << 23 >> 31) | tmp & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF; + pmc->scratch211 = (16 * sdram->emc_pmacro_auto_cal_cfg1 >> 31 << 31) | (2 * ((32 * sdram->emc_pmacro_auto_cal_cfg1 >> 31 << 30) | ((sdram->emc_pmacro_auto_cal_cfg1 << 6 >> 31 << 29) | tmp & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->scratch212 = (sdram->emc_xm2_comp_pad_ctrl3 << 8 >> 28 << 28) | ((sdram->emc_xm2_comp_pad_ctrl3 << 14 >> 31 << 27) | ((sdram->emc_xm2_comp_pad_ctrl3 << 15 >> 31 << 26) | ((sdram->emc_xm2_comp_pad_ctrl3 << 16 >> 30 << 24) | ((sdram->emc_xm2_comp_pad_ctrl3 << 18 >> 30 << 22) | ((sdram->emc_xm2_comp_pad_ctrl3 << 26 >> 28 << 18) | ((sdram->emc_xm2_comp_pad_ctrl3 << 16) & 0x3FFFF | ((16 * sdram->emc_pmacro_auto_cal_cfg2 >> 31 << 15) | ((32 * sdram->emc_pmacro_auto_cal_cfg2 >> 31 << 14) | ((sdram->emc_pmacro_auto_cal_cfg2 << 6 >> 31 << 13) | ((sdram->emc_pmacro_auto_cal_cfg2 << 7 >> 31 << 12) | ((sdram->emc_pmacro_auto_cal_cfg2 << 12 >> 31 << 11) | ((sdram->emc_pmacro_auto_cal_cfg2 << 13 >> 31 << 10) | ((sdram->emc_pmacro_auto_cal_cfg2 << 14 >> 31 << 9) | ((sdram->emc_pmacro_auto_cal_cfg2 << 15 >> 31 << 8) | ((sdram->emc_pmacro_auto_cal_cfg2 << 20 >> 31 << 7) | ((sdram->emc_pmacro_auto_cal_cfg2 << 21 >> 31 << 6) | (32 * (sdram->emc_pmacro_auto_cal_cfg2 << 22 >> 31) | (16 * (sdram->emc_pmacro_auto_cal_cfg2 << 23 >> 31) | (8 * (sdram->emc_pmacro_auto_cal_cfg2 << 28 >> 31) | (4 * (sdram->emc_pmacro_auto_cal_cfg2 << 29 >> 31) | (2 * (sdram->emc_pmacro_auto_cal_cfg2 << 30 >> 31) | (sdram->emc_pmacro_auto_cal_cfg2 & 1 | 2 * (pmc->scratch212 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFCFFFF) & 0xFFC3FFFF) & 0xFF3FFFFF) & 0xFCFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xFFFFFFF; + pmc->scratch213 = ((u16)(sdram->emc_prerefresh_req_cnt) << 16) | (u16)(sdram->emc_cfg_dig_dll_period); + pmc->scratch214 = (sdram->emc_pmacro_data_pi_ctrl << 10 >> 26 << 26) | ((sdram->emc_pmacro_data_pi_ctrl << 19 >> 31 << 25) | ((sdram->emc_pmacro_data_pi_ctrl << 20 >> 28 << 21) | ((sdram->emc_pmacro_data_pi_ctrl << 27 >> 31 << 20) | ((sdram->emc_pmacro_data_pi_ctrl << 16) & 0xFFFFF | ((sdram->emc_pmacro_ddll_bypass >> 31 << 15) | ((2 * sdram->emc_pmacro_ddll_bypass >> 31 << 14) | ((4 * sdram->emc_pmacro_ddll_bypass >> 31 << 13) | ((16 * sdram->emc_pmacro_ddll_bypass >> 31 << 12) | ((32 * sdram->emc_pmacro_ddll_bypass >> 31 << 11) | ((sdram->emc_pmacro_ddll_bypass << 6 >> 31 << 10) | ((sdram->emc_pmacro_ddll_bypass << 7 >> 31 << 9) | ((sdram->emc_pmacro_ddll_bypass << 15 >> 31 << 8) | ((sdram->emc_pmacro_ddll_bypass << 16 >> 31 << 7) | ((sdram->emc_pmacro_ddll_bypass << 17 >> 31 << 6) | (32 * (sdram->emc_pmacro_ddll_bypass << 18 >> 31) | (16 * (sdram->emc_pmacro_ddll_bypass << 20 >> 31) | (8 * (sdram->emc_pmacro_ddll_bypass << 21 >> 31) | (4 * (sdram->emc_pmacro_ddll_bypass << 22 >> 31) | (2 * (sdram->emc_pmacro_ddll_bypass << 23 >> 31) | (sdram->emc_pmacro_ddll_bypass & 1 | 2 * (pmc->scratch214 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFF0FFFF) & 0xFFEFFFFF) & 0xFE1FFFFF) & 0xFDFFFFFF) & 0x3FFFFFF; + pmc->scratch215 = (sdram->emc_pmacro_cmd_pi_ctrl << 10 >> 26 << 10) | ((sdram->emc_pmacro_cmd_pi_ctrl << 19 >> 31 << 9) | (32 * (sdram->emc_pmacro_cmd_pi_ctrl << 20 >> 28) | (16 * (sdram->emc_pmacro_cmd_pi_ctrl << 27 >> 31) | (sdram->emc_pmacro_cmd_pi_ctrl & 0xF | 16 * (pmc->scratch215 >> 4)) & 0xFFFFFFEF) & 0xFFFFFE1F) & 0xFFFFFDFF) & 0xFFFF03FF; + tmp = (sdram->emc_pmacro_data_pad_tx_ctrl << 7 >> 31 << 24) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 8 >> 31 << 23) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 9 >> 31 << 22) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 10 >> 31 << 21) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 15 >> 31 << 20) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 16 >> 31 << 19) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 21 >> 31 << 18) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 25 >> 31 << 17) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 26 >> 31 << 16) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 15) & 0xFFFF | ((2 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 14) | ((4 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 13) | ((8 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 12) | ((16 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 11) | ((32 * sdram->emc_pmacro_cmd_pad_tx_ctrl >> 31 << 10) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 6 >> 31 << 9) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 7 >> 31 << 8) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 8 >> 31 << 7) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 9 >> 31 << 6) | (32 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 10 >> 31) | (16 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 15 >> 31) | (8 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 16 >> 31) | (4 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 21 >> 31) | (2 * (sdram->emc_pmacro_cmd_pad_tx_ctrl << 25 >> 31) | ((sdram->emc_pmacro_cmd_pad_tx_ctrl << 26 >> 31) | 2 * (pmc->scratch216 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF) & 0xFFFFFFBF) & 0xFFFFFF7F) & 0xFFFFFEFF) & 0xFFFFFDFF) & 0xFFFFFBFF) & 0xFFFFF7FF) & 0xFFFFEFFF) & 0xFFFFDFFF) & 0xFFFFBFFF) & 0xFFFF7FFF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFFBFFFF) & 0xFFF7FFFF) & 0xFFEFFFFF) & 0xFFDFFFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF; -// s(emc_pin_gpio, 1:0, scratch9, 31:30); -// s(emc_pin_gpio_enable, 1:0, scratch10, 31:30); -// s(emc_dev_select, 1:0, scratch11, 31:30); -// s(emc_zcal_warm_cold_boot_enables, 1:0, scratch12, 31:30); -// s(emc_cfg_dig_dll_period_warm_boot, 1:0, scratch13, 31:30); -// s32(emc_bct_spare13, scratch45); -// s32(emc_bct_spare12, scratch46); -// s32(emc_bct_spare7, scratch47); -// s32(emc_bct_spare6, scratch48); -// s32(emc_bct_spare5, scratch50); -// s32(emc_bct_spare4, scratch51); -// s32(emc_bct_spare3, scratch56); -// s32(emc_bct_spare2, scratch57); -// s32(emc_bct_spare1, scratch58); -// s32(emc_bct_spare0, scratch59); -// s32(emc_bct_spare9, scratch60); -// s32(emc_bct_spare8, scratch61); -// s32(boot_rom_patch_data, scratch62); -// s32(boot_rom_patch_control, scratch63); -// s(mc_clken_override_allwarm_boot, 0:0, scratch65, 31:31); -// pmc->scratch66 = pmc->scratch66 & 0x1FFFFFFF | ((u8)(sdram->emc_extra_refresh_num) << 29); -// pmc->scratch72 = pmc->scratch72 & 0x8FFFFFFF | ((u16)(sdram->pmc_io_dpd3_req_wait) << 28) & 0x70000000; -// pmc->scratch72 = ((2 * pmc->scratch72) >> 1) | ((u16)(sdram->emc_clken_override_allwarm_boot) << 31); -// pmc->scratch73 = pmc->scratch73 & 0x8FFFFFFF | ((u8)(sdram->memory_type) << 28) & 0x70000000; -// pmc->scratch73 = ((2 * pmc->scratch73) >> 1) | (sdram->emc_mrs_warm_boot_enable << 31); -// pmc->scratch74 = pmc->scratch74 & 0x8FFFFFFF | (sdram->pmc_io_dpd4_req_wait << 28) & 0x70000000; -// pmc->scratch74 = ((2 * pmc->scratch74) >> 1) | (sdram->clear_clock2_mc1 << 31); -// pmc->scratch75 = pmc->scratch75 & 0xEFFFFFFF | (sdram->emc_warm_boot_extramode_reg_write_enable << 28) & 0x10000000; -// pmc->scratch75 = pmc->scratch75 & 0xDFFFFFFF | (sdram->clk_rst_pllm_misc20_override_enable << 29) & 0x20000000; -// pmc->scratch75 = pmc->scratch75 & 0xBFFFFFFF | ((u16)(sdram->emc_dbg_write_mux) << 30) & 0x40000000; -// pmc->scratch75 = ((2 * pmc->scratch75) >> 1) | ((u16)(sdram->ahb_arbitration_xbar_ctrl_meminit_done) << 31); -// pmc->scratch90 = pmc->scratch90 & 0xFFFFFF | (sdram->emc_timing_control_wait << 24); -// pmc->scratch91 = pmc->scratch91 & 0xFFFFFF | (sdram->emc_zcal_warm_boot_wait << 24); -// pmc->scratch92 = pmc->scratch92 & 0xFFFFFF | (sdram->warm_boot_wait << 24); -// pmc->scratch93 = pmc->scratch93 & 0xFFFFFF | ((u16)(sdram->emc_pin_program_wait) << 24); -// pmc->scratch114 = pmc->scratch114 & 0x3FFFFF | ((u16)(sdram->emc_auto_cal_wait) << 22); -// pmc->scratch215 = (u16)pmc->scratch215 | ((u16)(sdram->swizzle_rank_byte_encode) << 16); -// pmc->scratch216 = (2 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 30) | ((4 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 29) | ((8 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 28) | ((16 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 27) | ((32 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 26) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 6 >> 31 << 25) | tmp & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF; -// s(emc_mrw_lpddr2zcal_warm_boot, 23:16, scratch5, 7:0); -// s(emc_mrw_lpddr2zcal_warm_boot, 7:0, scratch5, 15:8); -// s(emc_warm_boot_mrw_extra, 23:16, scratch5, 23:16); -// s(emc_warm_boot_mrw_extra, 7:0, scratch5, 31:24); -// s(emc_mrw_lpddr2zcal_warm_boot, 31:30, scratch6, 1:0); -// s(emc_warm_boot_mrw_extra, 31:30, scratch6, 3:2); -// s(emc_mrw_lpddr2zcal_warm_boot, 27:26, scratch6, 5:4); -// s(emc_warm_boot_mrw_extra, 27:26, scratch6, 7:6); -// s(EmcMrw6, 27:0, scratch8, 27:0); -// s(EmcMrw6, 31:30, scratch8, 29:28); -// s(EmcMrw8, 27:0, scratch9, 27:0); -// s(EmcMrw8, 31:30, scratch9, 29:28); -// s(EmcMrw9, 27:0, scratch10, 27:0); -// s(EmcMrw9, 31:30, scratch10, 29:28); -// s(EmcMrw10, 27:0, scratch11, 27:0); -// s(EmcMrw10, 31:30, scratch11, 29:28); -// s(EmcMrw12, 27:0, scratch12, 27:0); -// s(EmcMrw12, 31:30, scratch12, 29:28); -// s(EmcMrw13, 27:0, scratch13, 27:0); -// s(EmcMrw13, 31:30, scratch13, 29:28); -// s(EmcMrw14, 27:0, scratch14, 27:0); -// s(EmcMrw14, 31:30, scratch14, 29:28); -// s(EmcMrw1, 7:0, scratch15, 7:0); -// s(EmcMrw1, 23:16, scratch15, 15:8); -// s(EmcMrw1, 27:26, scratch15, 17:16); -// s(EmcMrw1, 31:30, scratch15, 19:18); -// s(emc_warm_boot_mrw_extra, 7:0, scratch16, 7:0); -// s(emc_warm_boot_mrw_extra, 23:16, scratch16, 15:8); -// s(emc_warm_boot_mrw_extra, 27:26, scratch16, 17:16); -// s(emc_warm_boot_mrw_extra, 31:30, scratch16, 19:18); -// s(emc_mrw2, 7:0, scratch17, 7:0); -// s(emc_mrw2, 23:16, scratch17, 15:8); -// s(emc_mrw2, 27:26, scratch17, 17:16); -// s(emc_mrw2, 31:30, scratch17, 19:18); -// pmc->scratch18 = (sdram->emc_mrw3 >> 30 << 18) | ((16 * sdram->emc_mrw3 >> 31 << 17) | ((32 * sdram->emc_mrw3 >> 31 << 16) | ((sdram->emc_mrw3 << 8 >> 24 << 8) | ((u8)sdram->emc_mrw3 | (pmc->scratch18 >> 8 << 8)) & 0xFFFF00FF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFF3FFFF; -// pmc->scratch19 = (sdram->emc_mrw4 >> 30 << 18) | ((16 * sdram->emc_mrw4 >> 31 << 17) | ((32 * sdram->emc_mrw4 >> 31 << 16) | ((sdram->emc_mrw4 << 8 >> 24 << 8) | ((u8)sdram->emc_mrw4 | (pmc->scratch19 >> 8 << 8)) & 0xFFFF00FF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFF3FFFF; -// s32(emc_cmd_mapping_byte, secure_scratch8); -// s32(emc_pmacro_brick_mapping0, secure_scratch9); -// s32(emc_pmacro_brick_mapping1, secure_scratch10); -// s32(emc_pmacro_brick_mapping2, secure_scratch11); -// s32(mc_video_protect_gpu_override0, secure_scratch12); -// pmc->secure_scratch13 = ((u16)(sdram->emc_adr_cfg) << 31) | (2 * ((((u16)(sdram->mc_untranslated_region_check) << 22) >> 31 << 30) | ((((u16)(sdram->mc_untranslated_region_check) << 23) >> 31 << 29) | (((u16)(sdram->mc_untranslated_region_check) << 28) & 0x1FFFFFFF | ((2 * sdram->emc_cmd_mapping_cmd0_0 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd0_0 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd0_0 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd0_0 & 0x7F | (pmc->secure_scratch13 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->secure_scratch14 = (sdram->mc_video_protect_write_access << 30 >> 31 << 31) | (2 * ((sdram->mc_video_protect_write_access << 30) | ((sdram->mc_video_protect_bom_adr_hi << 30 >> 2) | ((2 * sdram->emc_cmd_mapping_cmd0_1 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd0_1 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd0_1 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd0_1 & 0x7F | (pmc->secure_scratch14 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->secure_scratch15 = ((u16)(sdram->mc_mts_carveout_adr_hi) << 30) | (4 * ((sdram->mc_sec_carveout_adr_hi << 28) | ((2 * sdram->emc_cmd_mapping_cmd1_0 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd1_0 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd1_0 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd1_0 & 0x7F | (pmc->secure_scratch15 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) >> 2); -// pmc->secure_scratch16 = (sdram->mc_generalized_carveout3_bom_hi << 30) | (4 * ((sdram->mc_generalized_carveout5_bom_hi << 28) | ((2 * sdram->emc_cmd_mapping_cmd1_1 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd1_1 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd1_1 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd1_1 & 0x7F | (pmc->secure_scratch16 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) >> 2); -// pmc->secure_scratch17 = ((u16)(sdram->mc_generalized_carveout4_bom_hi) << 30) | (4 * (((u16)(sdram->mc_generalized_carveout2_bom_hi) << 28) | ((2 * sdram->emc_cmd_mapping_cmd2_0 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd2_0 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd2_0 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd2_0 & 0x7F | (pmc->secure_scratch17 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) >> 2); -// pmc->secure_scratch18 = (sdram->emc_fbio_cfg8 << 16 >> 31 << 31) | (2 * (((u16)(sdram->emc_fbio_spare) << 30 >> 31 << 30) | ((sdram->mc_generalized_carveout1_bom_hi << 30 >> 2) | ((2 * sdram->emc_cmd_mapping_cmd2_1 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd2_1 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd2_1 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd2_1 & 0x7F | (pmc->secure_scratch18 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->secure_scratch19 = (sdram->mc_video_protect_vpr_override << 31) | (2 * (((u16)(sdram->mc_mts_carveout_reg_ctrl) << 30) | ((sdram->mc_sec_carveout_protect_write_access << 31 >> 2) | (((u16)(sdram->mc_emem_adr_cfg) << 28) & 0x1FFFFFFF | ((2 * sdram->emc_cmd_mapping_cmd3_0 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd3_0 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd3_0 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd3_0 & 0x7F | (pmc->secure_scratch19 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->secure_scratch20 = (sdram->mc_generalized_carveout2_cfg0 << 25 >> 28 << 28) | ((2 * sdram->emc_cmd_mapping_cmd3_1 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd3_1 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd3_1 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd3_1 & 0x7F | (pmc->secure_scratch20 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xFFFFFFF; -// pmc->secure_scratch39 = (sdram->mc_video_protect_vpr_override << 30 >> 31 << 31) | (2 * ((sdram->mc_generalized_carveout2_cfg0 << 21 >> 28 << 27) | ((32 * sdram->mc_generalized_carveout4_cfg0 >> 31 << 26) | ((sdram->mc_generalized_carveout4_cfg0 << 6 >> 31 << 25) | ((sdram->mc_generalized_carveout4_cfg0 << 7 >> 31 << 24) | ((sdram->mc_generalized_carveout4_cfg0 << 8 >> 31 << 23) | ((sdram->mc_generalized_carveout4_cfg0 << 9 >> 31 << 22) | ((sdram->mc_generalized_carveout4_cfg0 << 10 >> 28 << 18) | ((sdram->mc_generalized_carveout4_cfg0 << 14 >> 28 << 14) | ((sdram->mc_generalized_carveout4_cfg0 << 18 >> 29 << 11) | ((sdram->mc_generalized_carveout4_cfg0 << 21 >> 28 << 7) | (8 * (sdram->mc_generalized_carveout4_cfg0 << 25 >> 28) | (4 * (sdram->mc_generalized_carveout4_cfg0 << 29 >> 31) | (2 * (sdram->mc_generalized_carveout4_cfg0 << 30 >> 31) | (sdram->mc_generalized_carveout4_cfg0 & 1 | 2 * (pmc->secure_scratch39 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFF87) & 0xFFFFF87F) & 0xFFFFC7FF) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0x87FFFFFF) >> 1); -// pmc->secure_scratch40 = (sdram->mc_video_protect_vpr_override << 29 >> 31 << 31) | (2 * ((sdram->mc_generalized_carveout2_cfg0 << 14 >> 28 << 27) | ((32 * sdram->mc_generalized_carveout5_cfg0 >> 31 << 26) | ((sdram->mc_generalized_carveout5_cfg0 << 6 >> 31 << 25) | ((sdram->mc_generalized_carveout5_cfg0 << 7 >> 31 << 24) | ((sdram->mc_generalized_carveout5_cfg0 << 8 >> 31 << 23) | ((sdram->mc_generalized_carveout5_cfg0 << 9 >> 31 << 22) | ((sdram->mc_generalized_carveout5_cfg0 << 10 >> 28 << 18) | ((sdram->mc_generalized_carveout5_cfg0 << 14 >> 28 << 14) | ((sdram->mc_generalized_carveout5_cfg0 << 18 >> 29 << 11) | ((sdram->mc_generalized_carveout5_cfg0 << 21 >> 28 << 7) | (8 * (sdram->mc_generalized_carveout5_cfg0 << 25 >> 28) | (4 * (sdram->mc_generalized_carveout5_cfg0 << 29 >> 31) | (2 * (sdram->mc_generalized_carveout5_cfg0 << 30 >> 31) | (sdram->mc_generalized_carveout5_cfg0 & 1 | 2 * (pmc->secure_scratch40 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFF87) & 0xFFFFF87F) & 0xFFFFC7FF) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0x87FFFFFF) >> 1); -// pmc->secure_scratch41 = (sdram->mc_generalized_carveout2_cfg0 << 18 >> 29 << 29) | ((sdram->mc_generalized_carveout2_cfg0 << 10 >> 28 << 25) | ((16 * sdram->emc_cmd_mapping_cmd0_2 >> 28 << 21) | ((sdram->emc_cmd_mapping_cmd0_2 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd0_2 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd0_2 & 0x7F | (pmc->secure_scratch41 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xFE1FFFFF) & 0xE1FFFFFF) & 0x1FFFFFFF; -// pmc->secure_scratch42 = ((u16)(sdram->mc_generalized_carveout1_cfg0) << 18 >> 29 << 29) | (((u16)(sdram->mc_generalized_carveout1_cfg0) << 25 >> 28 << 25) | ((16 * sdram->emc_cmd_mapping_cmd1_2 >> 28 << 21) | ((sdram->emc_cmd_mapping_cmd1_2 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd1_2 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd1_2 & 0x7F | (pmc->secure_scratch42 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xFE1FFFFF) & 0xE1FFFFFF) & 0x1FFFFFFF; -// pmc->secure_scratch43 = ((u16)(sdram->mc_generalized_carveout3_cfg0) << 18 >> 29 << 29) | (((u16)(sdram->mc_generalized_carveout1_cfg0) << 21 >> 28 << 25) | ((16 * sdram->emc_cmd_mapping_cmd2_2 >> 28 << 21) | ((sdram->emc_cmd_mapping_cmd2_2 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd2_2 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd2_2 & 0x7F | (pmc->secure_scratch43 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xFE1FFFFF) & 0xE1FFFFFF) & 0x1FFFFFFF; -// pmc->secure_scratch44 = (sdram->mc_video_protect_vpr_override << 24 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 25 >> 31 << 30) | ((sdram->mc_video_protect_vpr_override << 28 >> 31 << 29) | ((sdram->mc_generalized_carveout1_cfg0 << 14 >> 28 << 25) | ((16 * sdram->emc_cmd_mapping_cmd3_2 >> 28 << 21) | ((sdram->emc_cmd_mapping_cmd3_2 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd3_2 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd3_2 & 0x7F | (pmc->secure_scratch44 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xFE1FFFFF) & 0xE1FFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// s(mc_emem_adr_cfg_channel_mask, 31:9, secure_scratch45, 22:0); -// s(mc_emem_adr_cfg_dev0, 2:0, secure_scratch45, 25:23); -// s(mc_emem_adr_cfg_dev0, 9:8, secure_scratch45, 27:26); -// s(mc_emem_adr_cfg_dev0, 19:16, secure_scratch45, 31:28); -// pmc->secure_scratch46 = (sdram->mc_video_protect_vpr_override << 23 >> 31 << 31) | (2 * ((sdram->mc_emem_adr_cfg_dev1 << 12 >> 28 << 27) | ((sdram->mc_emem_adr_cfg_dev1 << 22 >> 30 << 25) | ((sdram->mc_emem_adr_cfg_dev1 << 22) & 0x1FFFFFF | ((sdram->mc_emem_adr_cfg_bank_mask0 >> 10) | (pmc->secure_scratch46 >> 22 << 22)) & 0xFE3FFFFF) & 0xF9FFFFFF) & 0x87FFFFFF) >> 1); -// pmc->secure_scratch47 = (sdram->mc_video_protect_vpr_override << 20 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 22 >> 31 << 30) | (((u8)(sdram->mc_generalized_carveout3_cfg0) << 25 >> 28 << 26) | ((sdram->mc_generalized_carveout1_cfg0 << 10 >> 28 << 22) | ((sdram->mc_emem_adr_cfg_bank_mask1 >> 10) | (pmc->secure_scratch47 >> 22 << 22)) & 0xFC3FFFFF) & 0xC3FFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->secure_scratch48 = (sdram->mc_video_protect_vpr_override << 16 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 17 >> 31 << 30) | ((sdram->mc_generalized_carveout3_cfg0 << 14 >> 28 << 26) | ((sdram->mc_generalized_carveout3_cfg0 << 21 >> 28 << 22) | ((sdram->mc_emem_adr_cfg_bank_mask2 >> 10) | (pmc->secure_scratch48 >> 22 << 22)) & 0xFC3FFFFF) & 0xC3FFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->secure_scratch49 = (sdram->mc_video_protect_vpr_override << 14 >> 31 << 31) | (2 * ((sdram->mc_emem_cfg >> 31 << 30) | ((sdram->mc_emem_cfg << 18 >> 2) | (sdram->mc_video_protect_gpu_override1 & 0xFFFF | (pmc->secure_scratch49 >> 16 << 16)) & 0xC000FFFF) & 0xBFFFFFFF) >> 1); -// pmc->secure_scratch50 = (sdram->mc_video_protect_vpr_override << 12 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 13 >> 31 << 30) | ((sdram->mc_generalized_carveout1_bom >> 17 << 15) | ((sdram->mc_generalized_carveout3_bom >> 17) | (pmc->secure_scratch50 >> 15 << 15)) & 0xC0007FFF) & 0xBFFFFFFF) >> 1); -// pmc->secure_scratch51 = (sdram->mc_video_protect_vpr_override << 10 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 11 >> 31 << 30) | ((sdram->mc_generalized_carveout2_bom >> 17 << 15) | ((sdram->mc_generalized_carveout4_bom >> 17) | (pmc->secure_scratch51 >> 15 << 15)) & 0xC0007FFF) & 0xBFFFFFFF) >> 1); -// pmc->secure_scratch52 = (sdram->mc_video_protect_vpr_override << 9 >> 31 << 31) | (2 * ((sdram->mc_generalized_carveout3_cfg0 << 10 >> 28 << 27) | ((sdram->mc_video_protect_bom >> 20 << 15) | ((sdram->mc_generalized_carveout5_bom >> 17) | (pmc->secure_scratch52 >> 15 << 15)) & 0xF8007FFF) & 0x87FFFFFF) >> 1); -// pmc->secure_scratch53 = (sdram->mc_video_protect_vpr_override1 << 27 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override1 << 30 >> 31 << 30) | ((sdram->mc_video_protect_vpr_override1 << 31 >> 2) | ((sdram->mc_video_protect_vpr_override >> 31 << 28) | ((2 * sdram->mc_video_protect_vpr_override >> 31 << 27) | ((4 * sdram->mc_video_protect_vpr_override >> 31 << 26) | ((32 * sdram->mc_video_protect_vpr_override >> 31 << 25) | ((sdram->mc_video_protect_vpr_override << 8 >> 31 << 24) | ((sdram->mc_sec_carveout_bom >> 20 << 12) | (sdram->mc_video_protect_size_mb & 0xFFF | (pmc->secure_scratch53 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->secure_scratch54 = (sdram->mc_video_protect_vpr_override1 << 19 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override1 << 20 >> 31 << 30) | ((sdram->mc_video_protect_vpr_override1 << 21 >> 31 << 29) | ((sdram->mc_video_protect_vpr_override1 << 22 >> 31 << 28) | ((sdram->mc_video_protect_vpr_override1 << 23 >> 31 << 27) | ((sdram->mc_video_protect_vpr_override1 << 24 >> 31 << 26) | ((sdram->mc_video_protect_vpr_override1 << 25 >> 31 << 25) | ((sdram->mc_video_protect_vpr_override1 << 26 >> 31 << 24) | ((sdram->mc_mts_carveout_bom >> 20 << 12) | (sdram->mc_sec_carveout_size_mb & 0xFFF | (pmc->secure_scratch54 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->secure_scratch55 = (sdram->mc_generalized_carveout2_cfg0 << 30 >> 31 << 31) | (2 * ((sdram->mc_generalized_carveout2_cfg0 << 30) | ((32 * sdram->mc_video_protect_vpr_override1 >> 31 << 29) | ((sdram->mc_video_protect_vpr_override1 << 6 >> 31 << 28) | ((sdram->mc_video_protect_vpr_override1 << 15 >> 31 << 27) | ((sdram->mc_video_protect_vpr_override1 << 16 >> 31 << 26) | ((sdram->mc_video_protect_vpr_override1 << 17 >> 31 << 25) | ((sdram->mc_video_protect_vpr_override1 << 18 >> 31 << 24) | (((u16)(sdram->mc_generalized_carveout4_size_128kb) << 12) & 0xFFFFFF | (sdram->mc_mts_carveout_size_mb & 0xFFF | (pmc->secure_scratch55 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->secure_scratch56 = ((u16)(sdram->mc_generalized_carveout1_cfg0) << 30 >> 31 << 31) | (2 * (((u16)(sdram->mc_generalized_carveout1_cfg0) << 30) | ((32 * sdram->mc_generalized_carveout2_cfg0 >> 31 << 29) | ((sdram->mc_generalized_carveout2_cfg0 << 6 >> 31 << 28) | ((sdram->mc_generalized_carveout2_cfg0 << 7 >> 31 << 27) | ((sdram->mc_generalized_carveout2_cfg0 << 8 >> 31 << 26) | ((sdram->mc_generalized_carveout2_cfg0 << 9 >> 31 << 25) | ((sdram->mc_generalized_carveout2_cfg0 << 29 >> 31 << 24) | (((u16)(sdram->mc_generalized_carveout2_size_128kb) << 12) & 0xFFFFFF | (sdram->mc_generalized_carveout3_size_128kb & 0xFFF | (pmc->secure_scratch56 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// pmc->secure_scratch57 = ((u8)(sdram->mc_generalized_carveout3_cfg0) << 30 >> 31 << 31) | (2 * (((u8)(sdram->mc_generalized_carveout3_cfg0) << 30) | ((32 * sdram->mc_generalized_carveout1_cfg0 >> 31 << 29) | ((sdram->mc_generalized_carveout1_cfg0 << 6 >> 31 << 28) | ((sdram->mc_generalized_carveout1_cfg0 << 7 >> 31 << 27) | ((sdram->mc_generalized_carveout1_cfg0 << 8 >> 31 << 26) | ((sdram->mc_generalized_carveout1_cfg0 << 9 >> 31 << 25) | ((sdram->mc_generalized_carveout1_cfg0 << 29 >> 31 << 24) | ((sdram->mc_generalized_carveout5_size_128kb << 12) & 0xFFFFFF | (sdram->mc_generalized_carveout1_size_128kb & 0xFFF | (pmc->secure_scratch57 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + s(emc_pin_gpio, 1:0, scratch9, 31:30); + s(emc_pin_gpio_enable, 1:0, scratch10, 31:30); + s(emc_dev_select, 1:0, scratch11, 31:30); + s(emc_zcal_warm_cold_boot_enables, 1:0, scratch12, 31:30); + s(emc_cfg_dig_dll_period_warm_boot, 1:0, scratch13, 31:30); + s32(emc_bct_spare13, scratch45); + s32(emc_bct_spare12, scratch46); + s32(emc_bct_spare7, scratch47); + s32(emc_bct_spare6, scratch48); + s32(emc_bct_spare5, scratch50); + s32(emc_bct_spare4, scratch51); + s32(emc_bct_spare3, scratch56); + s32(emc_bct_spare2, scratch57); + s32(emc_bct_spare1, scratch58); + s32(emc_bct_spare0, scratch59); + s32(emc_bct_spare9, scratch60); + s32(emc_bct_spare8, scratch61); + s32(boot_rom_patch_data, scratch62); + s32(boot_rom_patch_control, scratch63); + s(mc_clken_override_allwarm_boot, 0:0, scratch65, 31:31); + pmc->scratch66 = pmc->scratch66 & 0x1FFFFFFF | ((u8)(sdram->emc_extra_refresh_num) << 29); + pmc->scratch72 = pmc->scratch72 & 0x8FFFFFFF | ((u16)(sdram->pmc_io_dpd3_req_wait) << 28) & 0x70000000; + pmc->scratch72 = ((2 * pmc->scratch72) >> 1) | ((u16)(sdram->emc_clken_override_allwarm_boot) << 31); + pmc->scratch73 = pmc->scratch73 & 0x8FFFFFFF | ((u8)(sdram->memory_type) << 28) & 0x70000000; + pmc->scratch73 = ((2 * pmc->scratch73) >> 1) | (sdram->emc_mrs_warm_boot_enable << 31); + pmc->scratch74 = pmc->scratch74 & 0x8FFFFFFF | (sdram->pmc_io_dpd4_req_wait << 28) & 0x70000000; + pmc->scratch74 = ((2 * pmc->scratch74) >> 1) | (sdram->clear_clock2_mc1 << 31); + pmc->scratch75 = pmc->scratch75 & 0xEFFFFFFF | (sdram->emc_warm_boot_extramode_reg_write_enable << 28) & 0x10000000; + pmc->scratch75 = pmc->scratch75 & 0xDFFFFFFF | (sdram->clk_rst_pllm_misc20_override_enable << 29) & 0x20000000; + pmc->scratch75 = pmc->scratch75 & 0xBFFFFFFF | ((u16)(sdram->emc_dbg_write_mux) << 30) & 0x40000000; + pmc->scratch75 = ((2 * pmc->scratch75) >> 1) | ((u16)(sdram->ahb_arbitration_xbar_ctrl_meminit_done) << 31); + pmc->scratch90 = pmc->scratch90 & 0xFFFFFF | (sdram->emc_timing_control_wait << 24); + pmc->scratch91 = pmc->scratch91 & 0xFFFFFF | (sdram->emc_zcal_warm_boot_wait << 24); + pmc->scratch92 = pmc->scratch92 & 0xFFFFFF | (sdram->warm_boot_wait << 24); + pmc->scratch93 = pmc->scratch93 & 0xFFFFFF | ((u16)(sdram->emc_pin_program_wait) << 24); + pmc->scratch114 = pmc->scratch114 & 0x3FFFFF | ((u16)(sdram->emc_auto_cal_wait) << 22); + pmc->scratch215 = (u16)pmc->scratch215 | ((u16)(sdram->swizzle_rank_byte_encode) << 16); + pmc->scratch216 = (2 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 30) | ((4 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 29) | ((8 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 28) | ((16 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 27) | ((32 * sdram->emc_pmacro_data_pad_tx_ctrl >> 31 << 26) | ((sdram->emc_pmacro_data_pad_tx_ctrl << 6 >> 31 << 25) | tmp & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF; + s(emc_mrw_lpddr2zcal_warm_boot, 23:16, scratch5, 7:0); + s(emc_mrw_lpddr2zcal_warm_boot, 7:0, scratch5, 15:8); + s(emc_warm_boot_mrw_extra, 23:16, scratch5, 23:16); + s(emc_warm_boot_mrw_extra, 7:0, scratch5, 31:24); + s(emc_mrw_lpddr2zcal_warm_boot, 31:30, scratch6, 1:0); + s(emc_warm_boot_mrw_extra, 31:30, scratch6, 3:2); + s(emc_mrw_lpddr2zcal_warm_boot, 27:26, scratch6, 5:4); + s(emc_warm_boot_mrw_extra, 27:26, scratch6, 7:6); + s(emc_mrw6, 27:0, scratch8, 27:0); + s(emc_mrw6, 31:30, scratch8, 29:28); + s(emc_mrw8, 27:0, scratch9, 27:0); + s(emc_mrw8, 31:30, scratch9, 29:28); + s(emc_mrw9, 27:0, scratch10, 27:0); + s(emc_mrw9, 31:30, scratch10, 29:28); + s(emc_mrw10, 27:0, scratch11, 27:0); + s(emc_mrw10, 31:30, scratch11, 29:28); + s(emc_mrw12, 27:0, scratch12, 27:0); + s(emc_mrw12, 31:30, scratch12, 29:28); + s(emc_mrw13, 27:0, scratch13, 27:0); + s(emc_mrw13, 31:30, scratch13, 29:28); + s(emc_mrw14, 27:0, scratch14, 27:0); + s(emc_mrw14, 31:30, scratch14, 29:28); + s(emc_mrw1, 7:0, scratch15, 7:0); + s(emc_mrw1, 23:16, scratch15, 15:8); + s(emc_mrw1, 27:26, scratch15, 17:16); + s(emc_mrw1, 31:30, scratch15, 19:18); + s(emc_warm_boot_mrw_extra, 7:0, scratch16, 7:0); + s(emc_warm_boot_mrw_extra, 23:16, scratch16, 15:8); + s(emc_warm_boot_mrw_extra, 27:26, scratch16, 17:16); + s(emc_warm_boot_mrw_extra, 31:30, scratch16, 19:18); + s(emc_mrw2, 7:0, scratch17, 7:0); + s(emc_mrw2, 23:16, scratch17, 15:8); + s(emc_mrw2, 27:26, scratch17, 17:16); + s(emc_mrw2, 31:30, scratch17, 19:18); + pmc->scratch18 = (sdram->emc_mrw3 >> 30 << 18) | ((16 * sdram->emc_mrw3 >> 31 << 17) | ((32 * sdram->emc_mrw3 >> 31 << 16) | ((sdram->emc_mrw3 << 8 >> 24 << 8) | ((u8)sdram->emc_mrw3 | (pmc->scratch18 >> 8 << 8)) & 0xFFFF00FF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFF3FFFF; + pmc->scratch19 = (sdram->emc_mrw4 >> 30 << 18) | ((16 * sdram->emc_mrw4 >> 31 << 17) | ((32 * sdram->emc_mrw4 >> 31 << 16) | ((sdram->emc_mrw4 << 8 >> 24 << 8) | ((u8)sdram->emc_mrw4 | (pmc->scratch19 >> 8 << 8)) & 0xFFFF00FF) & 0xFFFEFFFF) & 0xFFFDFFFF) & 0xFFF3FFFF; + s32(emc_cmd_mapping_byte, secure_scratch8); + s32(emc_pmacro_brick_mapping0, secure_scratch9); + s32(emc_pmacro_brick_mapping1, secure_scratch10); + s32(emc_pmacro_brick_mapping2, secure_scratch11); + s32(mc_video_protect_gpu_override0, secure_scratch12); + pmc->secure_scratch13 = ((u16)(sdram->emc_adr_cfg) << 31) | (2 * ((((u16)(sdram->mc_untranslated_region_check) << 22) >> 31 << 30) | ((((u16)(sdram->mc_untranslated_region_check) << 23) >> 31 << 29) | (((u16)(sdram->mc_untranslated_region_check) << 28) & 0x1FFFFFFF | ((2 * sdram->emc_cmd_mapping_cmd0_0 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd0_0 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd0_0 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd0_0 & 0x7F | (pmc->secure_scratch13 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->secure_scratch14 = (sdram->mc_video_protect_write_access << 30 >> 31 << 31) | (2 * ((sdram->mc_video_protect_write_access << 30) | ((sdram->mc_video_protect_bom_adr_hi << 30 >> 2) | ((2 * sdram->emc_cmd_mapping_cmd0_1 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd0_1 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd0_1 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd0_1 & 0x7F | (pmc->secure_scratch14 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->secure_scratch15 = ((u16)(sdram->mc_mts_carveout_adr_hi) << 30) | (4 * ((sdram->mc_sec_carveout_adr_hi << 28) | ((2 * sdram->emc_cmd_mapping_cmd1_0 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd1_0 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd1_0 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd1_0 & 0x7F | (pmc->secure_scratch15 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) >> 2); + pmc->secure_scratch16 = (sdram->mc_generalized_carveout3_bom_hi << 30) | (4 * ((sdram->mc_generalized_carveout5_bom_hi << 28) | ((2 * sdram->emc_cmd_mapping_cmd1_1 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd1_1 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd1_1 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd1_1 & 0x7F | (pmc->secure_scratch16 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) >> 2); + pmc->secure_scratch17 = ((u16)(sdram->mc_generalized_carveout4_bom_hi) << 30) | (4 * (((u16)(sdram->mc_generalized_carveout2_bom_hi) << 28) | ((2 * sdram->emc_cmd_mapping_cmd2_0 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd2_0 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd2_0 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd2_0 & 0x7F | (pmc->secure_scratch17 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) >> 2); + pmc->secure_scratch18 = (sdram->emc_fbio_cfg8 << 16 >> 31 << 31) | (2 * (((u16)(sdram->emc_fbio_spare) << 30 >> 31 << 30) | ((sdram->mc_generalized_carveout1_bom_hi << 30 >> 2) | ((2 * sdram->emc_cmd_mapping_cmd2_1 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd2_1 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd2_1 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd2_1 & 0x7F | (pmc->secure_scratch18 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xCFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->secure_scratch19 = (sdram->mc_video_protect_vpr_override << 31) | (2 * (((u16)(sdram->mc_mts_carveout_reg_ctrl) << 30) | ((sdram->mc_sec_carveout_protect_write_access << 31 >> 2) | (((u16)(sdram->mc_emem_adr_cfg) << 28) & 0x1FFFFFFF | ((2 * sdram->emc_cmd_mapping_cmd3_0 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd3_0 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd3_0 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd3_0 & 0x7F | (pmc->secure_scratch19 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->secure_scratch20 = (sdram->mc_generalized_carveout2_cfg0 << 25 >> 28 << 28) | ((2 * sdram->emc_cmd_mapping_cmd3_1 >> 25 << 21) | ((sdram->emc_cmd_mapping_cmd3_1 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd3_1 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd3_1 & 0x7F | (pmc->secure_scratch20 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xF01FFFFF) & 0xFFFFFFF; + pmc->secure_scratch39 = (sdram->mc_video_protect_vpr_override << 30 >> 31 << 31) | (2 * ((sdram->mc_generalized_carveout2_cfg0 << 21 >> 28 << 27) | ((32 * sdram->mc_generalized_carveout4_cfg0 >> 31 << 26) | ((sdram->mc_generalized_carveout4_cfg0 << 6 >> 31 << 25) | ((sdram->mc_generalized_carveout4_cfg0 << 7 >> 31 << 24) | ((sdram->mc_generalized_carveout4_cfg0 << 8 >> 31 << 23) | ((sdram->mc_generalized_carveout4_cfg0 << 9 >> 31 << 22) | ((sdram->mc_generalized_carveout4_cfg0 << 10 >> 28 << 18) | ((sdram->mc_generalized_carveout4_cfg0 << 14 >> 28 << 14) | ((sdram->mc_generalized_carveout4_cfg0 << 18 >> 29 << 11) | ((sdram->mc_generalized_carveout4_cfg0 << 21 >> 28 << 7) | (8 * (sdram->mc_generalized_carveout4_cfg0 << 25 >> 28) | (4 * (sdram->mc_generalized_carveout4_cfg0 << 29 >> 31) | (2 * (sdram->mc_generalized_carveout4_cfg0 << 30 >> 31) | (sdram->mc_generalized_carveout4_cfg0 & 1 | 2 * (pmc->secure_scratch39 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFF87) & 0xFFFFF87F) & 0xFFFFC7FF) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0x87FFFFFF) >> 1); + pmc->secure_scratch40 = (sdram->mc_video_protect_vpr_override << 29 >> 31 << 31) | (2 * ((sdram->mc_generalized_carveout2_cfg0 << 14 >> 28 << 27) | ((32 * sdram->mc_generalized_carveout5_cfg0 >> 31 << 26) | ((sdram->mc_generalized_carveout5_cfg0 << 6 >> 31 << 25) | ((sdram->mc_generalized_carveout5_cfg0 << 7 >> 31 << 24) | ((sdram->mc_generalized_carveout5_cfg0 << 8 >> 31 << 23) | ((sdram->mc_generalized_carveout5_cfg0 << 9 >> 31 << 22) | ((sdram->mc_generalized_carveout5_cfg0 << 10 >> 28 << 18) | ((sdram->mc_generalized_carveout5_cfg0 << 14 >> 28 << 14) | ((sdram->mc_generalized_carveout5_cfg0 << 18 >> 29 << 11) | ((sdram->mc_generalized_carveout5_cfg0 << 21 >> 28 << 7) | (8 * (sdram->mc_generalized_carveout5_cfg0 << 25 >> 28) | (4 * (sdram->mc_generalized_carveout5_cfg0 << 29 >> 31) | (2 * (sdram->mc_generalized_carveout5_cfg0 << 30 >> 31) | (sdram->mc_generalized_carveout5_cfg0 & 1 | 2 * (pmc->secure_scratch40 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFF87) & 0xFFFFF87F) & 0xFFFFC7FF) & 0xFFFC3FFF) & 0xFFC3FFFF) & 0xFFBFFFFF) & 0xFF7FFFFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0x87FFFFFF) >> 1); + pmc->secure_scratch41 = (sdram->mc_generalized_carveout2_cfg0 << 18 >> 29 << 29) | ((sdram->mc_generalized_carveout2_cfg0 << 10 >> 28 << 25) | ((16 * sdram->emc_cmd_mapping_cmd0_2 >> 28 << 21) | ((sdram->emc_cmd_mapping_cmd0_2 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd0_2 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd0_2 & 0x7F | (pmc->secure_scratch41 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xFE1FFFFF) & 0xE1FFFFFF) & 0x1FFFFFFF; + pmc->secure_scratch42 = ((u16)(sdram->mc_generalized_carveout1_cfg0) << 18 >> 29 << 29) | (((u16)(sdram->mc_generalized_carveout1_cfg0) << 25 >> 28 << 25) | ((16 * sdram->emc_cmd_mapping_cmd1_2 >> 28 << 21) | ((sdram->emc_cmd_mapping_cmd1_2 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd1_2 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd1_2 & 0x7F | (pmc->secure_scratch42 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xFE1FFFFF) & 0xE1FFFFFF) & 0x1FFFFFFF; + pmc->secure_scratch43 = ((u16)(sdram->mc_generalized_carveout3_cfg0) << 18 >> 29 << 29) | (((u16)(sdram->mc_generalized_carveout1_cfg0) << 21 >> 28 << 25) | ((16 * sdram->emc_cmd_mapping_cmd2_2 >> 28 << 21) | ((sdram->emc_cmd_mapping_cmd2_2 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd2_2 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd2_2 & 0x7F | (pmc->secure_scratch43 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xFE1FFFFF) & 0xE1FFFFFF) & 0x1FFFFFFF; + pmc->secure_scratch44 = (sdram->mc_video_protect_vpr_override << 24 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 25 >> 31 << 30) | ((sdram->mc_video_protect_vpr_override << 28 >> 31 << 29) | ((sdram->mc_generalized_carveout1_cfg0 << 14 >> 28 << 25) | ((16 * sdram->emc_cmd_mapping_cmd3_2 >> 28 << 21) | ((sdram->emc_cmd_mapping_cmd3_2 << 9 >> 25 << 14) | ((sdram->emc_cmd_mapping_cmd3_2 << 17 >> 25 << 7) | (sdram->emc_cmd_mapping_cmd3_2 & 0x7F | (pmc->secure_scratch44 >> 7 << 7)) & 0xFFFFC07F) & 0xFFE03FFF) & 0xFE1FFFFF) & 0xE1FFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + s(mc_emem_adr_cfg_channel_mask, 31:9, secure_scratch45, 22:0); + s(mc_emem_adr_cfg_dev0, 2:0, secure_scratch45, 25:23); + s(mc_emem_adr_cfg_dev0, 9:8, secure_scratch45, 27:26); + s(mc_emem_adr_cfg_dev0, 19:16, secure_scratch45, 31:28); + pmc->secure_scratch46 = (sdram->mc_video_protect_vpr_override << 23 >> 31 << 31) | (2 * ((sdram->mc_emem_adr_cfg_dev1 << 12 >> 28 << 27) | ((sdram->mc_emem_adr_cfg_dev1 << 22 >> 30 << 25) | ((sdram->mc_emem_adr_cfg_dev1 << 22) & 0x1FFFFFF | ((sdram->mc_emem_adr_cfg_bank_mask0 >> 10) | (pmc->secure_scratch46 >> 22 << 22)) & 0xFE3FFFFF) & 0xF9FFFFFF) & 0x87FFFFFF) >> 1); + pmc->secure_scratch47 = (sdram->mc_video_protect_vpr_override << 20 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 22 >> 31 << 30) | (((u8)(sdram->mc_generalized_carveout3_cfg0) << 25 >> 28 << 26) | ((sdram->mc_generalized_carveout1_cfg0 << 10 >> 28 << 22) | ((sdram->mc_emem_adr_cfg_bank_mask1 >> 10) | (pmc->secure_scratch47 >> 22 << 22)) & 0xFC3FFFFF) & 0xC3FFFFFF) & 0xBFFFFFFF) >> 1); + pmc->secure_scratch48 = (sdram->mc_video_protect_vpr_override << 16 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 17 >> 31 << 30) | ((sdram->mc_generalized_carveout3_cfg0 << 14 >> 28 << 26) | ((sdram->mc_generalized_carveout3_cfg0 << 21 >> 28 << 22) | ((sdram->mc_emem_adr_cfg_bank_mask2 >> 10) | (pmc->secure_scratch48 >> 22 << 22)) & 0xFC3FFFFF) & 0xC3FFFFFF) & 0xBFFFFFFF) >> 1); + pmc->secure_scratch49 = (sdram->mc_video_protect_vpr_override << 14 >> 31 << 31) | (2 * ((sdram->mc_emem_cfg >> 31 << 30) | ((sdram->mc_emem_cfg << 18 >> 2) | (sdram->mc_video_protect_gpu_override1 & 0xFFFF | (pmc->secure_scratch49 >> 16 << 16)) & 0xC000FFFF) & 0xBFFFFFFF) >> 1); + pmc->secure_scratch50 = (sdram->mc_video_protect_vpr_override << 12 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 13 >> 31 << 30) | ((sdram->mc_generalized_carveout1_bom >> 17 << 15) | ((sdram->mc_generalized_carveout3_bom >> 17) | (pmc->secure_scratch50 >> 15 << 15)) & 0xC0007FFF) & 0xBFFFFFFF) >> 1); + pmc->secure_scratch51 = (sdram->mc_video_protect_vpr_override << 10 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override << 11 >> 31 << 30) | ((sdram->mc_generalized_carveout2_bom >> 17 << 15) | ((sdram->mc_generalized_carveout4_bom >> 17) | (pmc->secure_scratch51 >> 15 << 15)) & 0xC0007FFF) & 0xBFFFFFFF) >> 1); + pmc->secure_scratch52 = (sdram->mc_video_protect_vpr_override << 9 >> 31 << 31) | (2 * ((sdram->mc_generalized_carveout3_cfg0 << 10 >> 28 << 27) | ((sdram->mc_video_protect_bom >> 20 << 15) | ((sdram->mc_generalized_carveout5_bom >> 17) | (pmc->secure_scratch52 >> 15 << 15)) & 0xF8007FFF) & 0x87FFFFFF) >> 1); + pmc->secure_scratch53 = (sdram->mc_video_protect_vpr_override1 << 27 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override1 << 30 >> 31 << 30) | ((sdram->mc_video_protect_vpr_override1 << 31 >> 2) | ((sdram->mc_video_protect_vpr_override >> 31 << 28) | ((2 * sdram->mc_video_protect_vpr_override >> 31 << 27) | ((4 * sdram->mc_video_protect_vpr_override >> 31 << 26) | ((32 * sdram->mc_video_protect_vpr_override >> 31 << 25) | ((sdram->mc_video_protect_vpr_override << 8 >> 31 << 24) | ((sdram->mc_sec_carveout_bom >> 20 << 12) | (sdram->mc_video_protect_size_mb & 0xFFF | (pmc->secure_scratch53 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->secure_scratch54 = (sdram->mc_video_protect_vpr_override1 << 19 >> 31 << 31) | (2 * ((sdram->mc_video_protect_vpr_override1 << 20 >> 31 << 30) | ((sdram->mc_video_protect_vpr_override1 << 21 >> 31 << 29) | ((sdram->mc_video_protect_vpr_override1 << 22 >> 31 << 28) | ((sdram->mc_video_protect_vpr_override1 << 23 >> 31 << 27) | ((sdram->mc_video_protect_vpr_override1 << 24 >> 31 << 26) | ((sdram->mc_video_protect_vpr_override1 << 25 >> 31 << 25) | ((sdram->mc_video_protect_vpr_override1 << 26 >> 31 << 24) | ((sdram->mc_mts_carveout_bom >> 20 << 12) | (sdram->mc_sec_carveout_size_mb & 0xFFF | (pmc->secure_scratch54 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->secure_scratch55 = (sdram->mc_generalized_carveout2_cfg0 << 30 >> 31 << 31) | (2 * ((sdram->mc_generalized_carveout2_cfg0 << 30) | ((32 * sdram->mc_video_protect_vpr_override1 >> 31 << 29) | ((sdram->mc_video_protect_vpr_override1 << 6 >> 31 << 28) | ((sdram->mc_video_protect_vpr_override1 << 15 >> 31 << 27) | ((sdram->mc_video_protect_vpr_override1 << 16 >> 31 << 26) | ((sdram->mc_video_protect_vpr_override1 << 17 >> 31 << 25) | ((sdram->mc_video_protect_vpr_override1 << 18 >> 31 << 24) | (((u16)(sdram->mc_generalized_carveout4_size_128kb) << 12) & 0xFFFFFF | (sdram->mc_mts_carveout_size_mb & 0xFFF | (pmc->secure_scratch55 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->secure_scratch56 = ((u16)(sdram->mc_generalized_carveout1_cfg0) << 30 >> 31 << 31) | (2 * (((u16)(sdram->mc_generalized_carveout1_cfg0) << 30) | ((32 * sdram->mc_generalized_carveout2_cfg0 >> 31 << 29) | ((sdram->mc_generalized_carveout2_cfg0 << 6 >> 31 << 28) | ((sdram->mc_generalized_carveout2_cfg0 << 7 >> 31 << 27) | ((sdram->mc_generalized_carveout2_cfg0 << 8 >> 31 << 26) | ((sdram->mc_generalized_carveout2_cfg0 << 9 >> 31 << 25) | ((sdram->mc_generalized_carveout2_cfg0 << 29 >> 31 << 24) | (((u16)(sdram->mc_generalized_carveout2_size_128kb) << 12) & 0xFFFFFF | (sdram->mc_generalized_carveout3_size_128kb & 0xFFF | (pmc->secure_scratch56 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); + pmc->secure_scratch57 = ((u8)(sdram->mc_generalized_carveout3_cfg0) << 30 >> 31 << 31) | (2 * (((u8)(sdram->mc_generalized_carveout3_cfg0) << 30) | ((32 * sdram->mc_generalized_carveout1_cfg0 >> 31 << 29) | ((sdram->mc_generalized_carveout1_cfg0 << 6 >> 31 << 28) | ((sdram->mc_generalized_carveout1_cfg0 << 7 >> 31 << 27) | ((sdram->mc_generalized_carveout1_cfg0 << 8 >> 31 << 26) | ((sdram->mc_generalized_carveout1_cfg0 << 9 >> 31 << 25) | ((sdram->mc_generalized_carveout1_cfg0 << 29 >> 31 << 24) | ((sdram->mc_generalized_carveout5_size_128kb << 12) & 0xFFFFFF | (sdram->mc_generalized_carveout1_size_128kb & 0xFFF | (pmc->secure_scratch57 >> 12 << 12)) & 0xFF000FFF) & 0xFEFFFFFF) & 0xFDFFFFFF) & 0xFBFFFFFF) & 0xF7FFFFFF) & 0xEFFFFFFF) & 0xDFFFFFFF) & 0xBFFFFFFF) >> 1); -// s32(mc_generalized_carveout1_access0, secure_scratch59); -// s32(mc_generalized_carveout1_access1, secure_scratch60); -// s32(mc_generalized_carveout1_access2, secure_scratch61); -// s32(mc_generalized_carveout1_access3, secure_scratch62); -// s32(mc_generalized_carveout1_access4, secure_scratch63); -// s32(mc_generalized_carveout2_access0, secure_scratch64); -// s32(mc_generalized_carveout2_access1, secure_scratch65); -// s32(mc_generalized_carveout2_access2, secure_scratch66); -// s32(mc_generalized_carveout2_access3, secure_scratch67); -// s32(mc_generalized_carveout2_access4, secure_scratch68); -// s32(mc_generalized_carveout3_access0, secure_scratch69); -// s32(mc_generalized_carveout3_access1, secure_scratch70); -// s32(mc_generalized_carveout3_access2, secure_scratch71); -// s32(mc_generalized_carveout3_access3, secure_scratch72); -// s32(mc_generalized_carveout3_access4, secure_scratch73); -// s32(mc_generalized_carveout4_access0, secure_scratch74); -// s32(mc_generalized_carveout4_access1, secure_scratch75); -// s32(mc_generalized_carveout4_access2, secure_scratch76); -// s32(mc_generalized_carveout4_access3, secure_scratch77); -// s32(mc_generalized_carveout4_access4, secure_scratch78); -// s32(mc_generalized_carveout5_access0, secure_scratch79); -// s32(mc_generalized_carveout5_access1, secure_scratch80); -// s32(mc_generalized_carveout5_access2, secure_scratch81); -// s32(mc_generalized_carveout5_access3, secure_scratch82); -// s32(mc_generalized_carveout1_force_internal_access0, secure_scratch84); -// s32(mc_generalized_carveout1_force_internal_access1, secure_scratch85); -// s32(mc_generalized_carveout1_force_internal_access2, secure_scratch86); -// s32(mc_generalized_carveout1_force_internal_access3, secure_scratch87); -// s32(mc_generalized_carveout1_force_internal_access4, secure_scratch88); -// s32(mc_generalized_carveout2_force_internal_access0, secure_scratch89); -// s32(mc_generalized_carveout2_force_internal_access1, secure_scratch90); -// s32(mc_generalized_carveout2_force_internal_access2, secure_scratch91); -// s32(mc_generalized_carveout2_force_internal_access3, secure_scratch92); -// s32(mc_generalized_carveout2_force_internal_access4, secure_scratch93); -// s32(mc_generalized_carveout3_force_internal_access0, secure_scratch94); -// s32(mc_generalized_carveout3_force_internal_access1, secure_scratch95); -// s32(mc_generalized_carveout3_force_internal_access2, secure_scratch96); -// s32(mc_generalized_carveout3_force_internal_access3, secure_scratch97); -// s32(mc_generalized_carveout3_force_internal_access4, secure_scratch98); -// s32(mc_generalized_carveout4_force_internal_access0, secure_scratch99); -// s32(mc_generalized_carveout4_force_internal_access1, secure_scratch100); -// s32(mc_generalized_carveout4_force_internal_access2, secure_scratch101); -// s32(mc_generalized_carveout4_force_internal_access3, secure_scratch102); -// s32(mc_generalized_carveout4_force_internal_access4, secure_scratch103); -// s32(mc_generalized_carveout5_force_internal_access0, secure_scratch104); -// s32(mc_generalized_carveout5_force_internal_access1, secure_scratch105); -// s32(mc_generalized_carveout5_force_internal_access2, secure_scratch106); -// s32(mc_generalized_carveout5_force_internal_access3, secure_scratch107); + s32(mc_generalized_carveout1_access0, secure_scratch59); + s32(mc_generalized_carveout1_access1, secure_scratch60); + s32(mc_generalized_carveout1_access2, secure_scratch61); + s32(mc_generalized_carveout1_access3, secure_scratch62); + s32(mc_generalized_carveout1_access4, secure_scratch63); + s32(mc_generalized_carveout2_access0, secure_scratch64); + s32(mc_generalized_carveout2_access1, secure_scratch65); + s32(mc_generalized_carveout2_access2, secure_scratch66); + s32(mc_generalized_carveout2_access3, secure_scratch67); + s32(mc_generalized_carveout2_access4, secure_scratch68); + s32(mc_generalized_carveout3_access0, secure_scratch69); + s32(mc_generalized_carveout3_access1, secure_scratch70); + s32(mc_generalized_carveout3_access2, secure_scratch71); + s32(mc_generalized_carveout3_access3, secure_scratch72); + s32(mc_generalized_carveout3_access4, secure_scratch73); + s32(mc_generalized_carveout4_access0, secure_scratch74); + s32(mc_generalized_carveout4_access1, secure_scratch75); + s32(mc_generalized_carveout4_access2, secure_scratch76); + s32(mc_generalized_carveout4_access3, secure_scratch77); + s32(mc_generalized_carveout4_access4, secure_scratch78); + s32(mc_generalized_carveout5_access0, secure_scratch79); + s32(mc_generalized_carveout5_access1, secure_scratch80); + s32(mc_generalized_carveout5_access2, secure_scratch81); + s32(mc_generalized_carveout5_access3, secure_scratch82); + s32(mc_generalized_carveout1_force_internal_access0, secure_scratch84); + s32(mc_generalized_carveout1_force_internal_access1, secure_scratch85); + s32(mc_generalized_carveout1_force_internal_access2, secure_scratch86); + s32(mc_generalized_carveout1_force_internal_access3, secure_scratch87); + s32(mc_generalized_carveout1_force_internal_access4, secure_scratch88); + s32(mc_generalized_carveout2_force_internal_access0, secure_scratch89); + s32(mc_generalized_carveout2_force_internal_access1, secure_scratch90); + s32(mc_generalized_carveout2_force_internal_access2, secure_scratch91); + s32(mc_generalized_carveout2_force_internal_access3, secure_scratch92); + s32(mc_generalized_carveout2_force_internal_access4, secure_scratch93); + s32(mc_generalized_carveout3_force_internal_access0, secure_scratch94); + s32(mc_generalized_carveout3_force_internal_access1, secure_scratch95); + s32(mc_generalized_carveout3_force_internal_access2, secure_scratch96); + s32(mc_generalized_carveout3_force_internal_access3, secure_scratch97); + s32(mc_generalized_carveout3_force_internal_access4, secure_scratch98); + s32(mc_generalized_carveout4_force_internal_access0, secure_scratch99); + s32(mc_generalized_carveout4_force_internal_access1, secure_scratch100); + s32(mc_generalized_carveout4_force_internal_access2, secure_scratch101); + s32(mc_generalized_carveout4_force_internal_access3, secure_scratch102); + s32(mc_generalized_carveout4_force_internal_access4, secure_scratch103); + s32(mc_generalized_carveout5_force_internal_access0, secure_scratch104); + s32(mc_generalized_carveout5_force_internal_access1, secure_scratch105); + s32(mc_generalized_carveout5_force_internal_access2, secure_scratch106); + s32(mc_generalized_carveout5_force_internal_access3, secure_scratch107); -// pmc->secure_scratch58 = 32 * (32 * sdram->mc_generalized_carveout3_cfg0 >> 31) | (16 * (sdram->mc_generalized_carveout3_cfg0 << 6 >> 31) | (8 * (sdram->mc_generalized_carveout3_cfg0 << 7 >> 31) | (4 * (sdram->mc_generalized_carveout3_cfg0 << 8 >> 31) | (2 * (sdram->mc_generalized_carveout3_cfg0 << 9 >> 31) | ((sdram->mc_generalized_carveout3_cfg0 << 29 >> 31) | 2 * (pmc->secure_scratch58 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF; + pmc->secure_scratch58 = 32 * (32 * sdram->mc_generalized_carveout3_cfg0 >> 31) | (16 * (sdram->mc_generalized_carveout3_cfg0 << 6 >> 31) | (8 * (sdram->mc_generalized_carveout3_cfg0 << 7 >> 31) | (4 * (sdram->mc_generalized_carveout3_cfg0 << 8 >> 31) | (2 * (sdram->mc_generalized_carveout3_cfg0 << 9 >> 31) | ((sdram->mc_generalized_carveout3_cfg0 << 29 >> 31) | 2 * (pmc->secure_scratch58 >> 1)) & 0xFFFFFFFD) & 0xFFFFFFFB) & 0xFFFFFFF7) & 0xFFFFFFEF) & 0xFFFFFFDF; -// c32(0, scratch2); -// s(pllm_input_divider, 7:0, scratch2, 7:0); -// s(pllm_feedback_divider, 7:0, scratch2, 15:8); -// s(pllm_post_divider, 4:0, scratch2, 20:16); -// s(pllm_kvco, 0:0, scratch2, 17:17); -// s(pllm_kcp, 1:0, scratch2, 19:18); + c32(0, scratch2); + s(pllm_input_divider, 7:0, scratch2, 7:0); + s(pllm_feedback_divider, 7:0, scratch2, 15:8); + s(pllm_post_divider, 4:0, scratch2, 20:16); + s(pllm_kvco, 0:0, scratch2, 17:17); + s(pllm_kcp, 1:0, scratch2, 19:18); -// c32(0, scratch35); -// s(pllm_setup_control, 15:0, scratch35, 15:0); + c32(0, scratch35); + s(pllm_setup_control, 15:0, scratch35, 15:0); -// c32(0, scratch3); -// s(pllm_input_divider, 7:0, scratch3, 7:0); -// c(0x3e, scratch3, 15:8); -// c(0, scratch3, 20:16); -// s(pllm_kvco, 0:0, scratch3, 21:21); -// s(pllm_kcp, 1:0, scratch3, 23:22); + c32(0, scratch3); + s(pllm_input_divider, 7:0, scratch3, 7:0); + c(0x3e, scratch3, 15:8); + c(0, scratch3, 20:16); + s(pllm_kvco, 0:0, scratch3, 21:21); + s(pllm_kcp, 1:0, scratch3, 23:22); -// c32(0, scratch36); -// s(PllMSetupControl, 23:0, scratch36, 23:0); + c32(0, scratch36); + s(pllm_setup_control, 23:0, scratch36, 23:0); -// c32(0, scratch4); -// s(pllm_stable_time, 9:0, scratch4, 9:0); // s32(pllm_stable_time, scratch4);, s(pllm_stable_time, 31:0, scratch4, 31:10); -// s(pllm_stable_time, 31:0, scratch4, 31:10); -// } + c32(0, scratch4); + s(pllm_stable_time, 9:0, scratch4, 9:0); // s32(pllm_stable_time, scratch4);, s(pllm_stable_time, 31:0, scratch4, 31:10); + s(pllm_stable_time, 31:0, scratch4, 31:10); +} #pragma GCC diagnostic pop void sdram_lp0_save_params(const void *params) { - // u32 chip_id = (APB_MISC(APB_MISC_GP_HIDREV) >> 4) & 0xF; + u32 chip_id = (APB_MISC(APB_MISC_GP_HIDREV) >> 4) & 0xF; - // if (chip_id != GP_HIDREV_MAJOR_T210B01) + if (chip_id != GP_HIDREV_MAJOR_T210B01) _sdram_lp0_save_params_t210(params); - // else - // _sdram_lp0_save_params_t210b01(params); + else + _sdram_lp0_save_params_t210b01(params); } diff --git a/bdk/mem/smmu.c b/bdk/mem/smmu.c index 6ee99b9..f2f20fb 100644 --- a/bdk/mem/smmu.c +++ b/bdk/mem/smmu.c @@ -48,8 +48,8 @@ u8 smmu_payload[] __attribute__((aligned(16))) = { void *page_alloc(u32 num) { u8 *res = _pageheap; - _pageheap += 0x1000 * num; - memset(res, 0, 0x1000 * num); + _pageheap += SZ_PAGE * num; + memset(res, 0, SZ_PAGE * num); return res; } @@ -150,8 +150,8 @@ void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr) { u32 *pte = smmu_get_pte(pdir, addr); *pte = SMMU_ADDR_TO_PFN(page) | attr; - addr += 0x1000; - page += 0x1000; + addr += SZ_PAGE; + page += SZ_PAGE; } smmu_flush_all(); } diff --git a/bdk/mem/smmu.h b/bdk/mem/smmu.h index 7846253..97cd9d5 100644 --- a/bdk/mem/smmu.h +++ b/bdk/mem/smmu.h @@ -30,6 +30,7 @@ #define MC_SMMU_TLB_FLUSH 0x30 #define MC_SMMU_PTC_FLUSH 0x34 #define MC_SMMU_ASID_SECURITY 0x38 +#define MC_SMMU_AVPC_ASID 0x23C #define MC_SMMU_TSEC_ASID 0x294 #define MC_SMMU_TRANSLATION_ENABLE_0 0x228 #define MC_SMMU_TRANSLATION_ENABLE_1 0x22c diff --git a/bdk/memory_map.h b/bdk/memory_map.h index 1db19f1..467364e 100644 --- a/bdk/memory_map.h +++ b/bdk/memory_map.h @@ -1,5 +1,5 @@ /* - * 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, @@ -19,11 +19,11 @@ //#define IPL_STACK_TOP 0x4003FF00 /* --- BIT/BCT: 0x40000000 - 0x40003000 --- */ -/* --- IPL: 0x40003000 - 0x40028000 --- */ -#define LDR_LOAD_ADDR 0x40003000 +/* --- IPL: 0x40008000 - 0x40028000 --- */ +#define LDR_LOAD_ADDR 0x40007000 #define IPL_LOAD_ADDR 0x40008000 -#define IPL_SZ_MAX 0x20000 // 128KB. +#define IPL_SZ_MAX SZ_128K /* --- XUSB EP context and TRB ring buffers --- */ #define XUSB_RING_ADDR 0x40020000 @@ -35,45 +35,50 @@ /* --- DRAM START --- */ #define DRAM_START 0x80000000 -#define HOS_RSVD 0x1000000 // Do not write anything in this area. +#define HOS_RSVD SZ_16M // Do not write anything in this area. #define NYX_LOAD_ADDR 0x81000000 -#define NYX_SZ_MAX 0x1000000 // 16MB +#define NYX_SZ_MAX SZ_16M /* --- Gap: 0x82000000 - 0x82FFFFFF --- */ /* Stack theoretical max: 33MB */ #define IPL_STACK_TOP 0x83100000 #define IPL_HEAP_START 0x84000000 -#define IPL_HEAP_SZ 0x20000000 // 512MB. +#define IPL_HEAP_SZ SZ_512M /* --- Gap: 1040MB 0xA4000000 - 0xE4FFFFFF --- */ // Virtual disk / Chainloader buffers. -#define RAM_DISK_ADDR 0xA4000000 -#define NX_BIS_CACHE_ADDR RAM_DISK_ADDR -#define RAM_DISK_SZ 0x41000000 // 1040MB. +#define RAM_DISK_ADDR 0xA4000000 +#define RAM_DISK_SZ 0x41000000 // 1040MB. +#define RAM_DISK2_SZ 0x21000000 // 528MB. + +// NX BIS driver sector cache. +#define NX_BIS_CACHE_ADDR 0xC5000000 +#define NX_BIS_CACHE_SZ 0x10020000 // 256MB. +#define NX_BIS_LOOKUP_ADDR 0xD6000000 +#define NX_BIS_LOOKUP_SZ 0xF000000 // 240MB. // L4T Kernel Panic Storage (PSTORE). #define PSTORE_ADDR 0xB0000000 -#define PSTORE_SZ 0x200000 // 2MB. +#define PSTORE_SZ SZ_2M //#define DRAM_LIB_ADDR 0xE0000000 /* --- Chnldr: 252MB 0xC03C0000 - 0xCFFFFFFF --- */ //! Only used when chainloading. // SDMMC DMA buffers 1 #define SDMMC_UPPER_BUFFER 0xE5000000 -#define SDMMC_UP_BUF_SZ 0x8000000 // 128MB. +#define SDMMC_UP_BUF_SZ SZ_128M // Nyx buffers. #define NYX_STORAGE_ADDR 0xED000000 #define NYX_RES_ADDR 0xEE000000 -#define NYX_RES_SZ 0x1000000 // 16MB. +#define NYX_RES_SZ SZ_16M // SDMMC DMA buffers 2 #define SDXC_BUF_ALIGNED 0xEF000000 #define MIXD_BUF_ALIGNED 0xF0000000 -#define TITLEKEY_BUF_ADR MIXD_BUF_ALIGNED #define EMMC_BUF_ALIGNED MIXD_BUF_ALIGNED -#define SDMMC_DMA_BUF_SZ 0x1000000 // 16MB (4MB currently used). +#define SDMMC_DMA_BUF_SZ SZ_16M // 4MB currently used. // Nyx LvGL buffers. #define NYX_LV_VDB_ADR 0xF1000000 @@ -91,22 +96,17 @@ #define NYX_FB_SZ 0x384000 // 1280 x 720 x 4. #define DRAM_MEM_HOLE_ADR 0xF6A00000 -#define NX_BIS_LOOKUP_ADR DRAM_MEM_HOLE_ADR #define DRAM_MEM_HOLE_SZ 0x8140000 /* --- Hole: 129MB 0xF6A00000 - 0xFEB3FFFF --- */ #define DRAM_START2 0xFEB40000 -// NX BIS driver sector cache. -// #define NX_BIS_CACHE_ADDR 0xFEE00000 -// #define NX_BIS_CACHE_SZ 0x100000 - // USB buffers. #define USBD_ADDR 0xFEF00000 #define USB_DESCRIPTOR_ADDR 0xFEF40000 #define USB_EP_CONTROL_BUF_ADDR 0xFEF80000 #define USB_EP_BULK_IN_BUF_ADDR 0xFF000000 #define USB_EP_BULK_OUT_BUF_ADDR 0xFF800000 -#define USB_EP_BULK_OUT_MAX_XFER 0x800000 +#define USB_EP_BULK_OUT_MAX_XFER SZ_8M // #define EXT_PAYLOAD_ADDR 0xC0000000 // #define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10)) diff --git a/bdk/power/max77620.h b/bdk/power/max77620.h index d54909f..03c9512 100644 --- a/bdk/power/max77620.h +++ b/bdk/power/max77620.h @@ -95,9 +95,9 @@ #define MAX77620_IRQSD_PFI_SD1 BIT(6) #define MAX77620_IRQSD_PFI_SD0 BIT(7) -#define MAX77620_REG_IRQ_LVL2_L0_7 0x08 // LDO number that irq occured. +#define MAX77620_REG_IRQ_LVL2_L0_7 0x08 // LDO number that irq occurred. #define MAX77620_REG_IRQ_MSK_L0_7 0x10 -#define MAX77620_REG_IRQ_LVL2_L8 0x09 // LDO number that irq occured. Only bit0: LDO8 is valid. +#define MAX77620_REG_IRQ_LVL2_L8 0x09 // LDO number that irq occurred. Only bit0: LDO8 is valid. #define MAX77620_REG_IRQ_MSK_L8 0x11 #define MAX77620_REG_IRQ_LVL2_GPIO 0x0A // Edge detection interrupt. @@ -139,8 +139,8 @@ #define MAX77620_REG_DVSSD0 0x1B #define MAX77620_REG_DVSSD1 0x1C #define MAX77620_SDX_VOLT_MASK 0xFF -#define MAX77620_SD0_VOLT_MASK 0x3F -#define MAX77620_SD1_VOLT_MASK 0x7F +#define MAX77620_SD0_VOLT_MASK 0x7F // Max is 0x40. +#define MAX77620_SD1_VOLT_MASK 0x7F // Max is 0x4C. #define MAX77620_LDO_VOLT_MASK 0x3F #define MAX77620_REG_SD0_CFG 0x1D diff --git a/bdk/power/max7762x.h b/bdk/power/max7762x.h index 3478530..379b946 100644 --- a/bdk/power/max7762x.h +++ b/bdk/power/max7762x.h @@ -20,6 +20,14 @@ #include +/* + * SDx actual min is 625 mV. Multipliers 0/1 reserved. + * SD0 max is 1400 mV + * SD1 max is 1550 mV + * SD2 max is 3787.5 mV + * SD3 max is 3787.5 mV + */ + /* * Switch Power domains (max77620): * Name | Usage | uV step | uV min | uV default | uV max | Init diff --git a/bdk/power/max77812.h b/bdk/power/max77812.h index 89c3baf..c7db199 100644 --- a/bdk/power/max77812.h +++ b/bdk/power/max77812.h @@ -17,8 +17,8 @@ #ifndef _MAX77812_H_ #define _MAX77812_H_ -#define MAX77812_PHASE31_CPU_I2C_ADDR 0x31 // 2 Outputs: 3-phase M1 + 1-phase M4. -#define MAX77812_PHASE211_CPU_I2C_ADDR 0x33 // 3 Outputs: 2-phase M1 + 1-phase M3 + 1-phase M4. +#define MAX77812_PHASE31_CPU_I2C_ADDR 0x31 // High power GPU. 2 Outputs: 3-phase M1 + 1-phase M4. +#define MAX77812_PHASE211_CPU_I2C_ADDR 0x33 // Low power GPU. 3 Outputs: 2-phase M1 + 1-phase M3 + 1-phase M4. #define MAX77812_REG_RSET 0x00 #define MAX77812_REG_INT_SRC 0x01 @@ -74,14 +74,14 @@ #define MAX77812_REG_GLB_CFG2 0x34 #define MAX77812_REG_GLB_CFG3 0x35 -/*! Protected area and settings only for MAX77812_REG_VERSION 4 */ +/*! Protected area and settings only for MAX77812_ES2_VERSION */ #define MAX77812_REG_GLB_CFG4 0x36 #define MAX77812_REG_GLB_CFG5 0x37 #define MAX77812_REG_GLB_CFG6 0x38 #define MAX77812_REG_GLB_CFG7 0x39 #define MAX77812_REG_GLB_CFG8 0x3A #define MAX77812_REG_PROT_ACCESS 0xFD -#define MAX77812_REG_MAX 0xFE +#define MAX77812_REG_MAX 0xFD #define MAX77812_REG_EN_CTRL_MASK(n) BIT(n) #define MAX77812_START_SLEW_RATE_MASK 0x07 diff --git a/bdk/power/regulator_5v.c b/bdk/power/regulator_5v.c index 64fd7d7..379f7a6 100644 --- a/bdk/power/regulator_5v.c +++ b/bdk/power/regulator_5v.c @@ -1,5 +1,5 @@ /* - * 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, @@ -14,37 +14,52 @@ * along with this program. If not, see . */ +#include #include +#include #include #include #include #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. - 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); + // Only Icosa and Iowa have USB 5V VBUS rails. Skip on Hoag/Aula. + u32 hw_type = fuse_read_hw_type(); + if (hw_type == FUSE_NX_HW_TYPE_ICOSA || + hw_type == FUSE_NX_HW_TYPE_IOWA) + { + // 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_LOW); + } - // Make sure GPIO power is enabled. - PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO_IO_EN; - // Override power detect for GPIO AO IO rails. - PMC(APBDEV_PMC_PWR_DET_VAL) &= ~PMC_PWR_DET_GPIO_IO_EN; + // Enable GPIO AO IO rail for T210. + if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210) + { + // Make sure GPIO power is enabled. + PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO_IO_EN; + (void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write. + + // Override power detect for GPIO AO IO rails. + PMC(APBDEV_PMC_PWR_DET_VAL) &= ~PMC_PWR_DET_GPIO_IO_EN; + (void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write. + } + usb_src = false; } reg_5v_dev |= dev; } @@ -55,21 +70,32 @@ 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. - 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; + // Only Icosa and Iowa have USB 5V VBUS rails. Skip on Hoag/Aula. + u32 hw_type = fuse_read_hw_type(); + if (hw_type == FUSE_NX_HW_TYPE_ICOSA || + hw_type == FUSE_NX_HW_TYPE_IOWA) + { + // 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; + if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210) + { + PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_GPIO_IO_EN; + (void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write. + } } } @@ -78,16 +104,22 @@ 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) + // Only for Icosa/Iowa. Skip on Hoag/Aula. + u32 hw_type = fuse_read_hw_type(); + if (hw_type != FUSE_NX_HW_TYPE_ICOSA && + hw_type != FUSE_NX_HW_TYPE_IOWA) + return; + + 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 92767b9..3621005 100644 --- a/bdk/sec/se.c +++ b/bdk/sec/se.c @@ -1,8 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2021 CTCaer - * Copyright (c) 2018 Atmosphère-NX - * Copyright (c) 2019-2021 shchmue + * Copyright (c) 2018-2022 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,10 +18,10 @@ #include #include "se.h" -#include "se_t210.h" #include #include #include +#include #include #include #include @@ -35,8 +33,7 @@ typedef struct _se_ll_t vu32 size; } se_ll_t; -static u32 _se_rsa_mod_sizes[SE_RSA_KEYSLOT_COUNT]; -static u32 _se_rsa_exp_sizes[SE_RSA_KEYSLOT_COUNT]; +se_ll_t *ll_dst, *ll_src; static void _gf256_mul_x(void *block) { @@ -79,22 +76,52 @@ static void _se_ll_init(se_ll_t *ll, u32 addr, u32 size) static void _se_ll_set(se_ll_t *dst, se_ll_t *src) { - SE(SE_IN_LL_ADDR_REG) = (u32)src; + SE(SE_IN_LL_ADDR_REG) = (u32)src; SE(SE_OUT_LL_ADDR_REG) = (u32)dst; } static int _se_wait() { + bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210; + + // Wait for operation to be done. while (!(SE(SE_INT_STATUS_REG) & SE_INT_OP_DONE)) ; - if (SE(SE_INT_STATUS_REG) & SE_INT_ERR_STAT || - (SE(SE_STATUS_REG) & SE_STATUS_STATE_MASK) != SE_STATUS_STATE_IDLE || - SE(SE_ERR_STATUS_REG) != 0) + + // Check for errors. + if ((SE(SE_INT_STATUS_REG) & SE_INT_ERR_STAT) || + (SE(SE_STATUS_REG) & SE_STATUS_STATE_MASK) != SE_STATUS_STATE_IDLE || + SE(SE_ERR_STATUS_REG) != 0) return 0; + + // T210B01: IRAM/TZRAM/DRAM AHB coherency WAR. + if (!tegra_t210 && ll_dst) + { + u32 timeout = get_tmr_us() + 1000000; + // Ensure data is out from SE. + while (SE(SE_STATUS_REG) & SE_STATUS_MEM_IF_BUSY) + { + if (get_tmr_us() > timeout) + return 0; + usleep(1); + } + + // Ensure data is out from AHB. + if(ll_dst->addr >= DRAM_START) + { + timeout = get_tmr_us() + 200000; + while (AHB_GIZMO(AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID) & MEM_WRQUE_SE_MST_ID) + { + if (get_tmr_us() > timeout) + return 0; + usleep(1); + } + } + } + return 1; } -se_ll_t *ll_dst, *ll_src; static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot) { ll_dst = NULL; @@ -128,9 +155,15 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); if (src) + { free(ll_src); + ll_src = NULL; + } if (dst) + { free(ll_dst); + ll_dst = NULL; + } return res; } @@ -200,66 +233,6 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags) SE(SE_RSA_SECURITY_PERKEY_REG) &= ~BIT(rs); } -// se_rsa_key_set() was derived from Atmosphère's set_rsa_keyslot -void se_rsa_key_set(u32 ks, const void *mod, u32 mod_size, const void *exp, u32 exp_size) -{ - u32 *data = (u32 *)mod; - for (u32 i = 0; i < mod_size / 4; i++) - { - SE(SE_RSA_KEYTABLE_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_MOD) | i; - SE(SE_RSA_KEYTABLE_DATA_REG) = byte_swap_32(data[mod_size / 4 - i - 1]); - } - - data = (u32 *)exp; - for (u32 i = 0; i < exp_size / 4; i++) - { - SE(SE_RSA_KEYTABLE_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_EXP) | i; - SE(SE_RSA_KEYTABLE_DATA_REG) = byte_swap_32(data[exp_size / 4 - i - 1]); - } - - _se_rsa_mod_sizes[ks] = mod_size; - _se_rsa_exp_sizes[ks] = exp_size; -} - -// se_rsa_key_clear() was derived from Atmosphère's clear_rsa_keyslot -void se_rsa_key_clear(u32 ks) -{ - for (u32 i = 0; i < SE_RSA2048_DIGEST_SIZE / 4; i++) - { - SE(SE_RSA_KEYTABLE_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_MOD) | i; - SE(SE_RSA_KEYTABLE_DATA_REG) = 0; - } - for (u32 i = 0; i < SE_RSA2048_DIGEST_SIZE / 4; i++) - { - SE(SE_RSA_KEYTABLE_ADDR_REG) = RSA_KEY_NUM(ks) | SE_RSA_KEYTABLE_TYPE(RSA_KEY_TYPE_EXP) | i; - SE(SE_RSA_KEYTABLE_DATA_REG) = 0; - } -} - -// se_rsa_exp_mod() was derived from Atmosphère's se_synchronous_exp_mod and se_get_exp_mod_output -int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size) -{ - int res; - u8 stack_buf[SE_RSA2048_DIGEST_SIZE]; - - for (u32 i = 0; i < src_size; i++) - stack_buf[i] = *((u8 *)src + src_size - i - 1); - - SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_RSA) | SE_CONFIG_DST(DST_RSAREG); - SE(SE_RSA_CONFIG) = RSA_KEY_SLOT(ks); - SE(SE_RSA_KEY_SIZE_REG) = (_se_rsa_mod_sizes[ks] >> 6) - 1; - SE(SE_RSA_EXP_SIZE_REG) = _se_rsa_exp_sizes[ks] >> 2; - - res = _se_execute_oneshot(SE_OP_START, NULL, 0, stack_buf, src_size); - - // 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))); - - return res; -} - void se_key_acc_ctrl(u32 ks, u32 flags) { if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG) @@ -273,7 +246,7 @@ u32 se_key_acc_ctrl_get(u32 ks) return SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks); } -void se_aes_key_set(u32 ks, const void *key, u32 size) +void se_aes_key_set(u32 ks, void *key, u32 size) { u32 data[SE_AES_MAX_KEY_SIZE / 4]; memcpy(data, key, size); @@ -285,13 +258,7 @@ void se_aes_key_set(u32 ks, const void *key, u32 size) } } -void se_aes_key_partial_set(u32 ks, u32 index, u32 data) -{ - SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | index; - SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data; -} - -void se_aes_iv_set(u32 ks, const void *iv) +void se_aes_iv_set(u32 ks, void *iv) { u32 data[SE_AES_IV_SIZE / 4]; memcpy(data, iv, SE_AES_IV_SIZE); @@ -334,6 +301,7 @@ void se_aes_iv_clear(u32 ks) } } + int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input) { SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE); @@ -409,89 +377,69 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s return 1; } -// random calls were derived from Atmosphère's -int se_initialize_rng() +int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize) { - static bool initialized = false; + int res = 0; + u8 *tweak = (u8 *)malloc(SE_AES_BLOCK_SIZE); + u8 *pdst = (u8 *)dst; + u8 *psrc = (u8 *)src; - if (initialized) - return 1; - - u8 *output_buf = (u8 *)malloc(0x10); - - SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); - SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_MODE(MODE_FORCE_INSTANTION) | SE_RNG_CONFIG_SRC(SRC_ENTROPY); - SE(SE_RNG_RESEED_INTERVAL_REG) = 70001; - SE(SE_RNG_SRC_CONFIG_REG) = SE_RNG_SRC_CONFIG_ENTR_SRC(RO_ENTR_ENABLE) | - SE_RNG_SRC_CONFIG_ENTR_SRC_LOCK(RO_ENTR_LOCK_ENABLE); - SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0; - - int res =_se_execute_oneshot(SE_OP_START, output_buf, 0x10, NULL, 0); - - free(output_buf); - if (res) - initialized = true; - return res; -} - -int se_generate_random(void *dst, u32 size) -{ - SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); - SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_MODE(MODE_NORMAL) | SE_RNG_CONFIG_SRC(SRC_ENTROPY); - - u32 num_blocks = size >> 4; - u32 aligned_size = num_blocks << 4; - if (num_blocks) - { - SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 1; - if (!_se_execute_oneshot(SE_OP_START, dst, aligned_size, NULL, 0)) - return 0; - } - if (size > aligned_size) - return _se_execute_one_block(SE_OP_START, dst + aligned_size, size - aligned_size, NULL, 0); - return 1; -} - -int se_generate_random_key(u32 ks_dst, u32 ks_src) -{ - SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | - SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); - SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_MODE(MODE_NORMAL) | SE_RNG_CONFIG_SRC(SRC_ENTROPY); - - SE(SE_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst); - if (!_se_execute_oneshot(SE_OP_START, NULL, 0, NULL, 0)) - return 0; - SE(SE_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst) | 1; - if (!_se_execute_oneshot(SE_OP_START, NULL, 0, NULL, 0)) - return 0; - - return 1; -} - -int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, const void *src, u32 sec_size) -{ - u8 tweak[0x10]; - u8 orig_tweak[0x10]; - u32 *pdst = (u32 *)dst; - u32 *psrc = (u32 *)src; - u32 *ptweak = (u32 *)tweak; - - //Generate tweak. + // Generate tweak. for (int i = 0xF; i >= 0; i--) { tweak[i] = sec & 0xFF; sec >>= 8; } - if (!se_aes_crypt_block_ecb(tweak_ks, 1, tweak, tweak)) - return 0; - - memcpy(orig_tweak, tweak, 0x10); + if (!se_aes_crypt_block_ecb(tweak_ks, ENCRYPT, tweak, tweak)) + goto out; // We are assuming a 0x10-aligned sector size in this implementation. - for (u32 i = 0; i < sec_size / 0x10; i++) + for (u32 i = 0; i < secsize / SE_AES_BLOCK_SIZE; i++) + { + for (u32 j = 0; j < SE_AES_BLOCK_SIZE; j++) + pdst[j] = psrc[j] ^ tweak[j]; + if (!se_aes_crypt_block_ecb(crypt_ks, enc, pdst, pdst)) + goto out; + for (u32 j = 0; j < SE_AES_BLOCK_SIZE; j++) + pdst[j] = pdst[j] ^ tweak[j]; + _gf256_mul_x(tweak); + psrc += SE_AES_BLOCK_SIZE; + pdst += SE_AES_BLOCK_SIZE; + } + + res = 1; + +out:; + free(tweak); + return res; +} + +int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size) +{ + u32 *pdst = (u32 *)dst; + u32 *psrc = (u32 *)src; + u32 *ptweak = (u32 *)tweak; + + if (regen_tweak) + { + for (int i = 0xF; i >= 0; i--) + { + tweak[i] = sec & 0xFF; + sec >>= 8; + } + if (!se_aes_crypt_block_ecb(tweak_ks, ENCRYPT, tweak, tweak)) + return 0; + } + + // tweak_exp allows using a saved tweak to reduce _gf256_mul_x_le calls. + for (u32 i = 0; i < (tweak_exp << 5); i++) + _gf256_mul_x_le(tweak); + + u8 orig_tweak[SE_KEY_128_SIZE] __attribute__((aligned(4))); + memcpy(orig_tweak, tweak, SE_KEY_128_SIZE); + + // We are assuming a 16 sector aligned size in this implementation. + for (u32 i = 0; i < (sec_size >> 4); i++) { for (u32 j = 0; j < 4; j++) pdst[j] = psrc[j] ^ ptweak[j]; @@ -506,7 +454,7 @@ int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst pdst = (u32 *)dst; ptweak = (u32 *)orig_tweak; - for (u32 i = 0; i < sec_size / 0x10; i++) + for (u32 i = 0; i < (sec_size >> 4); i++) { for (u32 j = 0; j < 4; j++) pdst[j] = pdst[j] ^ ptweak[j]; @@ -518,73 +466,18 @@ int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst return 1; } -int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, const void *src, u32 sec_size, u32 num_secs) +int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs) { u8 *pdst = (u8 *)dst; u8 *psrc = (u8 *)src; for (u32 i = 0; i < num_secs; i++) - if (!se_aes_xts_crypt_sec(tweak_ks, crypt_ks, enc, sec + i, pdst + sec_size * i, psrc + sec_size * i, sec_size)) + if (!se_aes_xts_crypt_sec(tweak_ks, crypt_ks, enc, sec + i, pdst + secsize * i, psrc + secsize * i, secsize)) return 0; return 1; } -// se_aes_cmac() was derived from Atmosphère's se_compute_aes_cmac -int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size) -{ - int res = 0; - u8 *key = (u8 *)calloc(0x10, 1); - u8 *last_block = (u8 *)calloc(0x10, 1); - - // generate derived key - if (!se_aes_crypt_block_ecb(ks, 1, key, key)) - goto out; - _gf256_mul_x(key); - if (src_size & 0xF) - _gf256_mul_x(key); - - SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) | - SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) | - SE_CRYPTO_CORE_SEL(CORE_ENCRYPT); - se_aes_iv_clear(ks); - - u32 num_blocks = (src_size + 0xf) >> 4; - if (num_blocks > 1) - { - SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2; - if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size)) - goto out; - SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED); - } - - if (src_size & 0xf) - { - memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf); - last_block[src_size & 0xf] = 0x80; - } - else if (src_size >= 0x10) - { - memcpy(last_block, src + src_size - 0x10, 0x10); - } - - for (u32 i = 0; i < 0x10; i++) - last_block[i] ^= key[i]; - - SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0; - res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, 0x10); - - u32 *dst32 = (u32 *)dst; - for (u32 i = 0; i < (dst_size >> 2); i++) - dst32[i] = SE(SE_HASH_RESULT_REG + (i << 2)); - -out:; - free(key); - free(last_block); - return res; -} - int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot) { int res; @@ -668,124 +561,26 @@ 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; } -int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size) +int se_gen_prng128(void *dst) { - int res = 0; - u8 *secret = (u8 *)malloc(0x40); - u8 *ipad = (u8 *)malloc(0x40 + src_size); - u8 *opad = (u8 *)malloc(0x60); + // Setup config for X931 PRNG. + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_HASH(HASH_DISABLE) | SE_CRYPTO_XOR_POS(XOR_BYPASS) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); + SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_NORMAL); + //SE(SE_RNG_SRC_CONFIG_REG) = + // SE_RNG_SRC_CONFIG_ENTR_SRC(RO_ENTR_ENABLE) | SE_RNG_SRC_CONFIG_ENTR_SRC_LOCK(RO_ENTR_LOCK_ENABLE); + SE(SE_RNG_RESEED_INTERVAL_REG) = 1; - if (key_size > 0x40) - { - if (!se_calc_sha256_oneshot(secret, key, key_size)) - goto out; - memset(secret + 0x20, 0, 0x20); - } - else - { - memcpy(secret, key, key_size); - memset(secret + key_size, 0, 0x40 - key_size); - } + SE(SE_CRYPTO_BLOCK_COUNT_REG) = (16 >> 4) - 1; - u32 *secret32 = (u32 *)secret; - u32 *ipad32 = (u32 *)ipad; - u32 *opad32 = (u32 *)opad; - for (u32 i = 0; i < 0x10; i++) - { - ipad32[i] = secret32[i] ^ 0x36363636; - opad32[i] = secret32[i] ^ 0x5C5C5C5C; - } - - memcpy(ipad + 0x40, src, src_size); - if (!se_calc_sha256_oneshot(dst, ipad, 0x40 + src_size)) - goto out; - memcpy(opad + 0x40, dst, 0x20); - if (!se_calc_sha256_oneshot(dst, opad, 0x60)) - goto out; - - res = 1; - -out:; - free(secret); - free(ipad); - free(opad); - return res; -} - -// _mgf1_xor() and rsa_oaep_decode were derived from Atmosphère -static void _mgf1_xor(void *masked, u32 masked_size, const void *seed, u32 seed_size) -{ - u8 cur_hash[0x20] __attribute__((aligned(4))); - u8 hash_buf[0xe4] __attribute__((aligned(4))); - - u32 hash_buf_size = seed_size + 4; - memcpy(hash_buf, seed, seed_size); - u32 round_num = 0; - - u8 *p_out = (u8 *)masked; - - while (masked_size) { - u32 cur_size = MIN(masked_size, 0x20); - - for (u32 i = 0; i < 4; i++) - hash_buf[seed_size + 3 - i] = (round_num >> (8 * i)) & 0xff; - round_num++; - - se_calc_sha256_oneshot(cur_hash, hash_buf, hash_buf_size); - - for (unsigned int i = 0; i < cur_size; i++) { - *p_out ^= cur_hash[i]; - p_out++; - } - - masked_size -= cur_size; - } -} - -u32 se_rsa_oaep_decode(void *dst, u32 dst_size, const void *label_digest, u32 label_digest_size, u8 *buf, u32 buf_size) -{ - if (dst_size <= 0 || buf_size < 0x43 || label_digest_size != 0x20) - return 0; - - bool is_valid = buf[0] == 0; - - u32 db_len = buf_size - 0x21; - u8 *seed = buf + 1; - u8 *db = seed + 0x20; - _mgf1_xor(seed, 0x20, db, db_len); - _mgf1_xor(db, db_len, seed, 0x20); - - is_valid &= memcmp(label_digest, db, 0x20) ? 0 : 1; - - db += 0x20; - db_len -= 0x20; - - int msg_ofs = 0; - int looking_for_one = 1; - int invalid_db_padding = 0; - int is_zero; - int is_one; - for (int i = 0; i < db_len; ) - { - is_zero = (db[i] == 0); - is_one = (db[i] == 1); - msg_ofs += (looking_for_one & is_one) * (++i); - looking_for_one &= ~is_one; - invalid_db_padding |= (looking_for_one & ~is_zero); - } - - is_valid &= (invalid_db_padding == 0); - - const u32 msg_size = MIN(dst_size, is_valid * (db_len - msg_ofs)); - memcpy(dst, db + msg_ofs, msg_size); - - return msg_size; + // Trigger the operation. + return _se_execute_oneshot(SE_OP_START, dst, 16, NULL, 0); } void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize) @@ -841,6 +636,105 @@ 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); } + +// se_aes_cmac() was derived from Atmosphère's se_compute_aes_cmac +int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size) +{ + int res = 0; + u8 *key = (u8 *)calloc(0x10, 1); + u8 *last_block = (u8 *)calloc(0x10, 1); + + // generate derived key + if (!se_aes_crypt_block_ecb(ks, 1, key, key)) + goto out; + _gf256_mul_x(key); + if (src_size & 0xF) + _gf256_mul_x(key); + + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) | + SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) | + SE_CRYPTO_CORE_SEL(CORE_ENCRYPT); + se_aes_iv_clear(ks); + + u32 num_blocks = (src_size + 0xf) >> 4; + if (num_blocks > 1) + { + SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2; + if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size)) + goto out; + SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED); + } + + if (src_size & 0xf) + { + memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf); + last_block[src_size & 0xf] = 0x80; + } + else if (src_size >= 0x10) + { + memcpy(last_block, src + src_size - 0x10, 0x10); + } + + for (u32 i = 0; i < 0x10; i++) + last_block[i] ^= key[i]; + + SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0; + res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, 0x10); + + u32 *dst32 = (u32 *)dst; + for (u32 i = 0; i < (dst_size >> 2); i++) + dst32[i] = SE(SE_HASH_RESULT_REG + (i << 2)); + +out:; + free(key); + free(last_block); + return res; +} + +int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size) +{ + int res = 0; + u8 *secret = (u8 *)malloc(0x40); + u8 *ipad = (u8 *)malloc(0x40 + src_size); + u8 *opad = (u8 *)malloc(0x60); + + if (key_size > 0x40) + { + if (!se_calc_sha256_oneshot(secret, key, key_size)) + goto out; + memset(secret + 0x20, 0, 0x20); + } + else + { + memcpy(secret, key, key_size); + memset(secret + key_size, 0, 0x40 - key_size); + } + + u32 *secret32 = (u32 *)secret; + u32 *ipad32 = (u32 *)ipad; + u32 *opad32 = (u32 *)opad; + for (u32 i = 0; i < 0x10; i++) + { + ipad32[i] = secret32[i] ^ 0x36363636; + opad32[i] = secret32[i] ^ 0x5C5C5C5C; + } + + memcpy(ipad + 0x40, src, src_size); + if (!se_calc_sha256_oneshot(dst, ipad, 0x40 + src_size)) + goto out; + memcpy(opad + 0x40, dst, 0x20); + if (!se_calc_sha256_oneshot(dst, opad, 0x60)) + goto out; + + res = 1; + +out:; + free(secret); + free(ipad); + free(opad); + return res; +} \ No newline at end of file diff --git a/bdk/sec/se.h b/bdk/sec/se.h index a52fd53..be1c820 100644 --- a/bdk/sec/se.h +++ b/bdk/sec/se.h @@ -1,54 +1,48 @@ /* -* Copyright (c) 2018 naehrwert -* Copyright (c) 2019-2021 CTCaer -* Copyright (c) 2019-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, -* 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 . -*/ + * Copyright (c) 2018 naehrwert + * Copyright (c) 2019-2022 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 _SE_H_ #define _SE_H_ +#include "se_t210.h" #include void se_rsa_acc_ctrl(u32 rs, u32 flags); -void se_rsa_key_set(u32 ks, const void *mod, u32 mod_size, const void *exp, u32 exp_size); -void se_rsa_key_clear(u32 ks); -int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size); void se_key_acc_ctrl(u32 ks, u32 flags); u32 se_key_acc_ctrl_get(u32 ks); void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize); -void se_aes_key_set(u32 ks, const void *key, u32 size); -void se_aes_iv_set(u32 ks, const void *iv); -void se_aes_key_partial_set(u32 ks, u32 index, u32 data); +void se_aes_key_set(u32 ks, void *key, u32 size); +void se_aes_iv_set(u32 ks, void *iv); void se_aes_key_get(u32 ks, void *key, u32 size); void se_aes_key_clear(u32 ks); void se_aes_iv_clear(u32 ks); -int se_initialize_rng(); -int se_generate_random(void *dst, u32 size); -int se_generate_random_key(u32 ks_dst, u32 ks_src); -int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input); -int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size); -int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size); -int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src); -int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr); -int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, const void *src, u32 sec_size); -int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, const void *src, u32 sec_size, u32 num_secs); +int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input); +int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size); +int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size); +int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src); +int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize); +int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size); +int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs); +int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr); +int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot); +int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size); +int se_calc_sha256_finalize(void *hash, u32 *msg_left); +int se_gen_prng128(void *dst); int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size); -int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot); -int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size); -int se_calc_sha256_finalize(void *hash, u32 *msg_left); int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size); -u32 se_rsa_oaep_decode(void *dst, u32 dst_size, const void *label_digest, u32 label_digest_size, u8 *buf, u32 buf_size); #endif diff --git a/bdk/sec/se_t210.h b/bdk/sec/se_t210.h index 0233e1d..317c4fa 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) @@ -301,6 +304,8 @@ #define SE_STATUS_STATE_WAIT_OUT 2 #define SE_STATUS_STATE_WAIT_IN 3 #define SE_STATUS_STATE_MASK 3 +#define SE_STATUS_MEM_IF_IDLE (0 << 2) +#define SE_STATUS_MEM_IF_BUSY BIT(2) #define SE_ERR_STATUS_REG 0x804 #define SE_ERR_STATUS_SE_NS_ACCESS BIT(0) diff --git a/bdk/sec/tsec.c b/bdk/sec/tsec.c index adf5ac2..50a90ae 100644 --- a/bdk/sec/tsec.c +++ b/bdk/sec/tsec.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -33,7 +34,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 +64,11 @@ 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; @@ -83,7 +86,19 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) kfuse_wait_ready(); - //Configure Falcon. + if (type == TSEC_FW_TYPE_NEW) + { + // Disable all CCPLEX core rails. + pmc_enable_partition(POWER_RAIL_CE0, DISABLE); + pmc_enable_partition(POWER_RAIL_CE1, DISABLE); + pmc_enable_partition(POWER_RAIL_CE2, DISABLE); + pmc_enable_partition(POWER_RAIL_CE3, DISABLE); + + // Enable AHB aperture and set it to full mmio. + mc_enable_ahb_redirect(true); + } + + // Configure Falcon. TSEC(TSEC_DMACTL) = 0; TSEC(TSEC_IRQMSET) = TSEC_IRQMSET_EXT(0xFF) | @@ -105,12 +120,12 @@ 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 { - fwbuf = (u8 *)malloc(0x4000); + fwbuf = (u8 *)malloc(SZ_16K); u8 *fwbuf_aligned = (u8 *)ALIGN((u32)fwbuf, 0x100); memcpy(fwbuf_aligned, tsec_ctxt->fw, tsec_ctxt->size); TSEC(TSEC_DMATRFBASE) = (u32)fwbuf_aligned >> 8; @@ -125,27 +140,27 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) } } - if (kb == KB_TSEC_FW_EMU_COMPAT) + if (type == TSEC_FW_TYPE_EMU) { // Init SMMU translation for TSEC. pdir = smmu_init_for_tsec(); - smmu_init(0x4002B000); + 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); + memcpy(car, (void *)CLOCK_BASE, SZ_PAGE); 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); + memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, SZ_1K); fuse[0x82C / 4] = 0; - fuse[0x9E0 / 4] = (1 << (kb + 2)) - 1; - fuse[0x9E4 / 4] = (1 << (kb + 2)) - 1; + 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. @@ -158,12 +173,12 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) // Security engine. se = page_alloc(1); - memcpy(se, (void *)SE_BASE, 0x1000); + memcpy(se, (void *)SE_BASE, SZ_PAGE); smmu_map(pdir, SE_BASE, (u32)se, 1, _READABLE | _WRITABLE | _NONSECURE); // Memory controller. mc = page_alloc(1); - memcpy(mc, (void *)MC_BASE, 0x1000); + memcpy(mc, (void *)MC_BASE, SZ_PAGE); mc[MC_IRAM_BOM / 4] = 0; mc[MC_IRAM_TOM / 4] = 0x80000000; smmu_map(pdir, MC_BASE, (u32)mc, 1, _READABLE | _NONSECURE); @@ -172,7 +187,7 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) iram = page_alloc(0x30); memcpy(iram, tsec_ctxt->pkg1, 0x30000); // PKG1.1 magic offset. - pkg11_magic_off = (u32 *)(iram + (0x7000 / 4)); + pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / 4)); smmu_map(pdir, 0x40010000, (u32)iram, 0x30, _READABLE | _WRITABLE | _NONSECURE); // Exception vectors @@ -180,14 +195,14 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) smmu_map(pdir, EXCP_VEC_BASE, (u32)evec, 1, _READABLE | _WRITABLE | _NONSECURE); } - //Execute firmware. + // 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 (kb == KB_TSEC_FW_EMU_COMPAT) + if (type == TSEC_FW_TYPE_EMU) { u32 start = get_tmr_us(); u32 k = se[SE_CRYPTO_KEYTABLE_DATA_REG / 4]; @@ -257,7 +272,7 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) goto out_free; } - //Fetch result. + // Fetch result. HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0; u32 buf[4]; buf[0] = SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB); @@ -277,7 +292,7 @@ out_free:; out:; - //Disable clocks. + // Disable clocks. clock_disable_kfuse(); clock_disable_sor1(); clock_disable_sor0(); @@ -286,5 +301,9 @@ out:; bpmp_mmu_enable(); bpmp_clk_rate_set(prev_fid); + // Disable AHB aperture. + 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 274b6e7..7456e44 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,32 +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 { 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_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt); #endif diff --git a/bdk/soc/actmon.c b/bdk/soc/actmon.c new file mode 100644 index 0000000..4df80eb --- /dev/null +++ b/bdk/soc/actmon.c @@ -0,0 +1,173 @@ +/* + * Activity Monitor driver for Tegra X1 + * + * Copyright (c) 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, + * 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 "actmon.h" +#include "clock.h" +#include "t210.h" + +/* Global registers */ +#define ACTMON_GLB_STATUS 0x0 +#define ACTMON_MCCPU_MON_ACT BIT(8) +#define ACTMON_MCALL_MON_ACT BIT(9) +#define ACTMON_CPU_FREQ_MON_ACT BIT(10) +#define ACTMON_APB_MON_ACT BIT(12) +#define ACTMON_AHB_MON_ACT BIT(13) +#define ACTMON_BPMP_MON_ACT BIT(14) +#define ACTMON_CPU_MON_ACT BIT(15) +#define ACTMON_MCCPU_INTR BIT(25) +#define ACTMON_MCALL_INTR BIT(26) +#define ACTMON_CPU_FREQ_INTR BIT(27) +#define ACTMON_APB_INTR BIT(28) +#define ACTMON_AHB_INTR BIT(29) +#define ACTMON_BPMP_INTR BIT(30) +#define ACTMON_CPU_INTR BIT(31) +#define ACTMON_GLB_PERIOD_CTRL 0x4 +#define ACTMON_GLB_PERIOD_USEC BIT(8) +#define ACTMON_GLB_PERIOD_SAMPLE(n) (((n) - 1) & 0xFF) + +/* Device Registers */ +#define ACTMON_DEV_BASE ACTMON_BASE + 0x80 +#define ACTMON_DEV_SIZE 0x40 +/* CTRL */ +#define ACTMON_DEV_CTRL_K_VAL(k) (((k) & 7) << 10) +#define ACTMON_DEV_CTRL_ENB_PERIODIC BIT(18) +#define ACTMON_DEV_CTRL_AT_END_EN BIT(19) +#define ACTMON_DEV_CTRL_AVG_BELOW_WMARK_EN BIT(20) +#define ACTMON_DEV_CTRL_AVG_ABOVE_WMARK_EN BIT(21) +#define ACTMON_DEV_CTRL_WHEN_OVERFLOW_EN BIT(22) +#define ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_NUM(n) (((n) & 7) << 23) +#define ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_NUM(n) (((n) & 7) << 26) +#define ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN BIT(29) +#define ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN BIT(30) +#define ACTMON_DEV_CTRL_ENB BIT(31) +/* INTR_STATUS */ +#define ACTMON_DEV_ISTS_AVG_ABOVE_WMARK BIT(24) +#define ACTMON_DEV_ISTS_AVG_BELOW_WMARK BIT(25) +#define ACTMON_DEV_ISTS_WHEN_OVERFLOW BIT(26) +#define ACTMON_DEV_ISTS_AT_END BIT(29) +#define ACTMON_DEV_ISTS_CONSECUTIVE_LOWER BIT(30) +#define ACTMON_DEV_ISTS_CONSECUTIVE_UPPER BIT(31) + +/* Histogram Registers */ +#define ACTMON_HISTOGRAM_CONFIG 0x300 +#define ACTMON_HIST_CFG_ACTIVE BIT(0) +#define ACTMON_HIST_CFG_LINEAR_MODE BIT(1) +#define ACTMON_HIST_CFG_NO_UNDERFLOW_BUCKET BIT(2) +#define ACTMON_HIST_CFG_STALL_ON_SINGLE_SATURATE BIT(3) +#define ACTMON_HIST_CFG_SHIFT(s) (((s) & 0x1F) << 4) +#define ACTMON_HIST_CFG_SOURCE(s) (((s) & 0xF) << 12) +#define ACTMON_HISTOGRAM_CTRL 0x304 +#define ACTMON_HIST_CTRL_CLEAR_ALL BIT(0) +#define ACTMON_HISTOGRAM_DATA_BASE 0x380 +#define ACTMON_HISTOGRAM_DATA_NUM 32 + +#define ACTMON_FREQ 19200000 + +typedef struct _actmon_dev_reg_t +{ + vu32 ctrl; + vu32 upper_wnark; + vu32 lower_wmark; + vu32 init_avg; + vu32 avg_upper_wmark; + vu32 avg_lower_wmark; + vu32 count_weight; + vu32 count; + vu32 avg_count; + vu32 intr_status; + vu32 ctrl2; + vu32 unk[5]; +} actmon_dev_reg_t; + +u32 sample_period = 0; + +void actmon_hist_enable(actmon_hist_src_t src) +{ + ACTMON(ACTMON_HISTOGRAM_CONFIG) = ACTMON_HIST_CFG_SOURCE(src) | ACTMON_HIST_CFG_ACTIVE; + ACTMON(ACTMON_HISTOGRAM_CTRL) = ACTMON_HIST_CTRL_CLEAR_ALL; +} + +void actmon_hist_disable() +{ + ACTMON(ACTMON_HISTOGRAM_CONFIG) = 0; +} + +void actmon_hist_get(u32 *histogram) +{ + if (histogram) + { + for (u32 i = 0; i < ACTMON_HISTOGRAM_DATA_NUM; i++) + histogram[i] = ACTMON(ACTMON_HISTOGRAM_DATA_BASE + i * sizeof(u32)); + } +} + +void actmon_dev_enable(actmon_dev_t dev) +{ + actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE)); + + regs->init_avg = 0; + regs->count_weight = 5; + + regs->ctrl = ACTMON_DEV_CTRL_ENB | ACTMON_DEV_CTRL_ENB_PERIODIC; +} + +void actmon_dev_disable(actmon_dev_t dev) +{ + actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE)); + + regs->ctrl = 0; +} + +u32 actmon_dev_get_load(actmon_dev_t dev) +{ + actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE)); + + // Get load-based sampling. 1 decimal point precision. + u32 load = regs->count / (ACTMON_FREQ / 1000); + + return load; +} + +u32 actmon_dev_get_load_avg(actmon_dev_t dev) +{ + actmon_dev_reg_t *regs = (actmon_dev_reg_t *)(ACTMON_DEV_BASE + (dev * ACTMON_DEV_SIZE)); + + // Get load-based sampling. 1 decimal point precision. + u32 avg_load = regs->avg_count / (ACTMON_FREQ / 1000); + + return avg_load; +} + +void atmon_dev_all_disable() +{ + // TODO: do a global reset? +} + +void actmon_init() +{ + clock_enable_actmon(); + + // Set period to 200ms. + ACTMON(ACTMON_GLB_PERIOD_CTRL) &= ~ACTMON_GLB_PERIOD_USEC; + ACTMON(ACTMON_GLB_PERIOD_CTRL) |= ACTMON_GLB_PERIOD_SAMPLE(200); +} + +void actmon_end() +{ + clock_disable_actmon(); +} \ No newline at end of file diff --git a/bdk/soc/actmon.h b/bdk/soc/actmon.h new file mode 100644 index 0000000..dc9d0c5 --- /dev/null +++ b/bdk/soc/actmon.h @@ -0,0 +1,62 @@ +/* + * Activity Monitor driver for Tegra X1 + * + * Copyright (c) 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, + * 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 __ACTMON_H_ +#define __ACTMON_H_ + +#include + +typedef enum _actmon_dev_t +{ + ACTMON_DEV_CPU, + ACTMON_DEV_BPMP, + ACTMON_DEV_AHB, + ACTMON_DEV_APB, + ACTMON_DEV_CPU_FREQ, + ACTMON_DEV_MC_ALL, + ACTMON_DEV_MC_CPU, + + ACTMON_DEV_NUM, +} actmon_dev_t; + +typedef enum _actmon_hist_src_t +{ + ACTMON_HIST_SRC_NONE = 0, + ACTMON_HIST_SRC_AHB = 1, + ACTMON_HIST_SRC_APB = 2, + ACTMON_HIST_SRC_BPMP = 3, + ACTMON_HIST_SRC_CPU = 4, + ACTMON_HIST_SRC_MC_ALL = 5, + ACTMON_HIST_SRC_MC_CPU = 6, + ACTMON_HIST_SRC_CPU_FREQ = 7, + ACTMON_HIST_SRC_NA = 8, + ACTMON_HIST_SRC_APB_MMIO = 9, +} actmon_hist_src_t; + +void actmon_hist_enable(actmon_hist_src_t src); +void actmon_hist_disable(); +void actmon_hist_get(u32 *histogram); +void actmon_dev_enable(actmon_dev_t dev); +void actmon_dev_disable(actmon_dev_t dev); +u32 actmon_dev_get_load(actmon_dev_t dev); +u32 actmon_dev_get_load_avg(actmon_dev_t dev); +void atmon_dev_all_disable(); +void actmon_init(); +void actmon_end(); + +#endif \ No newline at end of file diff --git a/bdk/soc/ccplex.c b/bdk/soc/ccplex.c index 894cb28..825c546 100644 --- a/bdk/soc/ccplex.c +++ b/bdk/soc/ccplex.c @@ -58,24 +58,7 @@ void ccplex_boot_cpu0(u32 entry) else _ccplex_enable_power_t210b01(); - // Enable PLLX and set it to 300 MHz. - if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLLX_BASE_ENABLE)) // PLLX_ENABLE. - { - CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= 0xFFFFFFF7; // Disable IDDQ. - usleep(2); - - // Bypass dividers. - CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLLX_BASE_BYPASS | (4 << 20) | (78 << 8) | 2; // P div: 4 (5), N div: 78, M div: 2. - // Disable bypass - CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = (4 << 20) | (78 << 8) | 2; - // Set PLLX_LOCK_ENABLE. - CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) = (CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) & 0xFFFBFFFF) | 0x40000; - // Enable PLLX. - CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLLX_BASE_ENABLE | (4 << 20) | (78 << 8) | 2; - } - // Wait for PLL to stabilize. - while (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLLX_BASE_LOCK)) - ; + clock_enable_pllx(); // Configure MSELECT source and enable clock to 102MHz. CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6; @@ -108,6 +91,7 @@ void ccplex_boot_cpu0(u32 entry) // Set reset vector. SB(SB_AA64_RESET_LOW) = entry | SB_AA64_RST_AARCH64_MODE_EN; SB(SB_AA64_RESET_HIGH) = 0; + // Non-secure reset vector write disable. SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS; (void)SB(SB_CSR); diff --git a/bdk/soc/clock.c b/bdk/soc/clock.c index 31bdb8f..b122cf9 100644 --- a/bdk/soc/clock.c +++ b/bdk/soc/clock.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer + * Copyright (c) 2018-2022 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, @@ -79,7 +79,7 @@ static clock_t _clock_sor0 = { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NOT_USED, CLK_X_SOR0, 0, 0 }; static clock_t _clock_sor1 = { - CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, 2 //204MHz. + CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, 2 // 204MHz. }; static clock_t _clock_kfuse = { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, 0 @@ -100,6 +100,18 @@ static clock_t _clock_sdmmc_legacy_tm = { CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, 66 }; +static clock_t _clock_apbdma = { + CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_APBDMA, 0, 0 +}; + +static clock_t _clock_ahbdma = { + CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, 0 +}; + +static clock_t _clock_actmon = { + CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, 0 // 19.2MHz. +}; + void clock_enable(const clock_t *clk) { // Put clock into reset. @@ -279,6 +291,62 @@ void clock_disable_pwm() clock_disable(&_clock_pwm); } +void clock_enable_apbdma() +{ + clock_enable(&_clock_apbdma); +} + +void clock_disable_apbdma() +{ + clock_disable(&_clock_apbdma); +} + +void clock_enable_ahbdma() +{ + clock_enable(&_clock_ahbdma); +} + +void clock_disable_ahbdma() +{ + clock_disable(&_clock_ahbdma); +} + +void clock_enable_actmon() +{ + clock_enable(&_clock_actmon); +} + +void clock_disable_actmon() +{ + clock_disable(&_clock_actmon); +} + +void clock_enable_pllx() +{ + // Configure and enable PLLX if disabled. + if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLLX_BASE_ENABLE)) // PLLX_ENABLE. + { + CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= ~PLLX_MISC3_IDDQ; // Disable IDDQ. + usleep(2); + + // Set div configuration. + const u32 pllx_div_cfg = (2 << 20) | (156 << 8) | 2; // P div: 2 (3), N div: 156, M div: 2. 998.4 MHz. + + // Bypass dividers. + CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLLX_BASE_BYPASS | pllx_div_cfg; + // Disable bypass + CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = pllx_div_cfg; + // Set PLLX_LOCK_ENABLE. + CLOCK(CLK_RST_CONTROLLER_PLLX_MISC) |= PLLX_MISC_LOCK_EN; + // Enable PLLX. + CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = PLLX_BASE_ENABLE | pllx_div_cfg; + } + + // Wait for PLL to stabilize. + while (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & PLLX_BASE_LOCK)) + ; +} + void clock_enable_pllc(u32 divn) { u8 pll_divn_curr = (CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) >> 10) & 0xFF; @@ -757,15 +825,25 @@ u32 clock_get_osc_freq() u32 clock_get_dev_freq(clock_pto_id_t id) { - u32 val = ((id & PTO_SRC_SEL_MASK) << PTO_SRC_SEL_SHIFT) | PTO_DIV_SEL_DIV1 | PTO_CLK_ENABLE | (16 - 1); // 16 periods of 32.76KHz window. + const u32 pto_win = 16; + const u32 pto_osc = 32768; + + u32 val = ((id & PTO_SRC_SEL_MASK) << PTO_SRC_SEL_SHIFT) | PTO_DIV_SEL_DIV1 | PTO_CLK_ENABLE | (pto_win - 1); CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL) = val; + (void)CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL); usleep(2); + CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL) = val | PTO_CNT_RST; + (void)CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL); usleep(2); + CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL) = val; + (void)CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL); usleep(2); + CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL) = val | PTO_CNT_EN; - usleep(502); + (void)CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL); + usleep((1000000 * pto_win / pto_osc) + 12 + 2); while (CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_STATUS) & PTO_CLK_CNT_BUSY) ; @@ -773,9 +851,11 @@ u32 clock_get_dev_freq(clock_pto_id_t id) u32 cnt = CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_STATUS) & PTO_CLK_CNT; CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL) = 0; + (void)CLOCK(CLK_RST_CONTROLLER_PTO_CLK_CNT_CNTL); + usleep(2); - u32 freq = ((cnt << 8) | 0x3E) / 125; + u32 freq_khz = (u64)cnt * pto_osc / pto_win / 1000; - return freq; + return freq_khz; } diff --git a/bdk/soc/clock.h b/bdk/soc/clock.h index 67e9b4d..6b504f8 100644 --- a/bdk/soc/clock.h +++ b/bdk/soc/clock.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer + * Copyright (c) 2018-2022 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, @@ -117,6 +117,7 @@ #define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD 0x3A4 #define CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT 0x3B4 #define CLK_RST_CONTROLLER_CLK_SOURCE_I2C4 0x3C4 +#define CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON 0x3E8 #define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1 0x3EC #define CLK_RST_CONTROLLER_CLK_SOURCE_SYS 0x400 #define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410 @@ -167,6 +168,8 @@ #define PLLX_BASE_REF_DIS BIT(29) #define PLLX_BASE_ENABLE BIT(30) #define PLLX_BASE_BYPASS BIT(31) +#define PLLX_MISC_LOCK_EN BIT(18) +#define PLLX_MISC3_IDDQ BIT(3) #define PLLCX_BASE_LOCK BIT(27) #define PLLCX_BASE_REF_DIS BIT(29) @@ -215,7 +218,7 @@ #define OSC_FREQ_DET_BUSY BIT(31) #define OSC_FREQ_DET_CNT 0xFFFF -/*! PLLs omitted as they need PTO enabled in MISC registers. Norm div is 2. */ +/*! PTO IDs. */ typedef enum _clock_pto_id_t { CLK_PTO_PCLK_SYS = 0x06, @@ -239,6 +242,9 @@ typedef enum _clock_pto_id_t CLK_PTO_SDMMC4 = 0x23, CLK_PTO_EMC = 0x24, + CLK_PTO_CCLK_LP = 0x2B, + CLK_PTO_CCLK_LP_DIV2 = 0x2C, + CLK_PTO_MSELECT = 0x2F, CLK_PTO_VIC = 0x36, @@ -321,6 +327,32 @@ typedef enum _clock_pto_id_t CLK_PTO_XUSB_SS_HOST_DEV = 0x137, CLK_PTO_XUSB_CORE_HOST = 0x138, CLK_PTO_XUSB_CORE_DEV = 0x139, + + /* + * PLL need PTO enabled in MISC registers. + * Normal div is 2 so result is multiplied with it. + */ + CLK_PTO_PLLC_DIV2 = 0x01, + CLK_PTO_PLLM_DIV2 = 0x02, + CLK_PTO_PLLP_DIV2 = 0x03, + CLK_PTO_PLLA_DIV2 = 0x04, + CLK_PTO_PLLX_DIV2 = 0x05, + + CLK_PTO_PLLMB_DIV2 = 0x25, + + CLK_PTO_PLLC4_DIV2 = 0x51, + + CLK_PTO_PLLA1_DIV2 = 0x55, + CLK_PTO_PLLC2_DIV2 = 0x58, + CLK_PTO_PLLC3_DIV2 = 0x5A, + + CLK_PTO_PLLD_DIV2 = 0xCB, + CLK_PTO_PLLD2_DIV2 = 0xCD, + CLK_PTO_PLLDP_DIV2 = 0xCF, + + CLK_PTO_PLLU_DIV2 = 0x10D, + + CLK_PTO_PLLREFE_DIV2 = 0x10F, } clock_pto_id_t; /* @@ -628,6 +660,14 @@ void clock_enable_coresight(); void clock_disable_coresight(); void clock_enable_pwm(); void clock_disable_pwm(); +void clock_enable_apbdma(); +void clock_disable_apbdma(); +void clock_enable_ahbdma(); +void clock_disable_ahbdma(); +void clock_enable_actmon(); +void clock_disable_actmon(); + +void clock_enable_pllx(); void clock_enable_pllc(u32 divn); void clock_disable_pllc(); void clock_enable_pllu(); diff --git a/bdk/soc/fuse.c b/bdk/soc/fuse.c index 0a37a4b..63037e9 100644 --- a/bdk/soc/fuse.c +++ b/bdk/soc/fuse.c @@ -2,7 +2,7 @@ * Copyright (c) 2018 naehrwert * Copyright (c) 2018 shuffle2 * 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, @@ -19,6 +19,8 @@ #include +#include +#include #include #include #include @@ -90,7 +92,7 @@ u32 fuse_read_dramid(bool raw_id) } else { - if (dramid > 27) + if (dramid > 28) dramid = 8; } @@ -111,26 +113,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 810efd6..a9154bb 100644 --- a/bdk/soc/fuse.h +++ b/bdk/soc/fuse.h @@ -2,7 +2,7 @@ * Copyright (c) 2018 naehrwert * Copyright (c) 2018 shuffle2 * 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, @@ -37,6 +37,8 @@ #define FUSE_DISABLEREGPROGRAM 0x2C #define FUSE_WRITE_ACCESS_SW 0x30 #define FUSE_PWR_GOOD_SW 0x34 + +/*! Fuse Cached registers */ #define FUSE_SKU_INFO 0x110 #define FUSE_CPU_SPEEDO_0_CALIB 0x114 #define FUSE_CPU_IDDQ_CALIB 0x118 @@ -64,8 +66,10 @@ #define FUSE_OPT_WAFER_ID 0x210 #define FUSE_OPT_X_COORDINATE 0x214 #define FUSE_OPT_Y_COORDINATE 0x218 +#define FUSE_OPT_OPS_RESERVED 0x220 #define FUSE_GPU_IDDQ_CALIB 0x228 #define FUSE_USB_CALIB_EXT 0x350 +#define FUSE_RESERVED_FIELD 0x354 #define FUSE_RESERVED_ODM28_T210B01 0x240 @@ -82,7 +86,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 @@ -97,7 +102,7 @@ u32 fuse_read_odm_keygen_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 1da102f..c57b653 100644 --- a/bdk/soc/hw_init.c +++ b/bdk/soc/hw_init.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2021 CTCaer + * Copyright (c) 2018-2022 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, @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include #include @@ -48,6 +48,17 @@ extern boot_cfg_t b_cfg; extern volatile nyx_storage_t *nyx_str; +u32 hw_rst_status; +u32 hw_rst_reason; + +u32 hw_get_chip_id() +{ + if (((APB_MISC(APB_MISC_GP_HIDREV) >> 4) & 0xF) >= GP_HIDREV_MAJOR_T210B01) + return GP_HIDREV_MAJOR_T210B01; + else + return GP_HIDREV_MAJOR_T210; +} + /* * CLK_OSC - 38.4 MHz crystal. * CLK_M - 19.2 MHz (osc/2). @@ -57,14 +68,6 @@ extern volatile nyx_storage_t *nyx_str; * PCLK - 68MHz init (-> 136MHz -> OC/4). */ -u32 hw_get_chip_id() -{ - if (((APB_MISC(APB_MISC_GP_HIDREV) >> 4) & 0xF) >= GP_HIDREV_MAJOR_T210B01) - return GP_HIDREV_MAJOR_T210B01; - else - return GP_HIDREV_MAJOR_T210; -} - static void _config_oscillators() { CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4; // Set CLK_M_DIVISOR to 2. @@ -75,7 +78,7 @@ static void _config_oscillators() PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE; // Set LP0 OSC drive strength. PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF) | PMC_OSC_EDPD_OVER_OSC_CTRL_OVER; PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN; - PMC(APBDEV_PMC_SCRATCH188) = (PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF) | (4 << 23); // LP0 EMC2TMC_CFG_XM2COMP_PU_VREF_SEL_RANGE. + PMC(APB_MISC_GP_ASDBGREG) = (PMC(APB_MISC_GP_ASDBGREG) & 0xFCFFFFFF) | (2 << 24); // CFG2TMC_RAM_SVOP_PDP. CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1. CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable. @@ -135,8 +138,8 @@ static void _config_gpios(bool nx_hoag) gpio_output_enable(GPIO_PORT_X, GPIO_PIN_7, GPIO_OUTPUT_DISABLE); // Configure HOME as inputs. - // PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; - // gpio_config(GPIO_PORT_Y, GPIO_PIN_1, GPIO_MODE_GPIO); + PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; + gpio_config(GPIO_PORT_Y, GPIO_PIN_1, GPIO_MODE_GPIO); } static void _config_pmc_scratch() @@ -250,36 +253,25 @@ static void _mbist_workaround() static void _config_se_brom() { - // Enable fuse clock. + // Enable Fuse visibility. clock_enable_fuse(true); - // Skip SBK/SSK if sept was run. - bool sbk_skip = b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN || FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF; - if (!sbk_skip) - { - // 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); + memset((void *)TZRAM_BASE, 0, SZ_64K); PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE; SE(SE_INT_STATUS_REG) = 0x1F; // Clear all SE interrupts. - // Clear the boot reason to avoid problems later + // Save reset reason. + hw_rst_status = PMC(APBDEV_PMC_SCRATCH200); + hw_rst_reason = PMC(APBDEV_PMC_RST_STATUS) & PMC_RST_STATUS_MASK; + + // Clear the boot reason to avoid problems later. PMC(APBDEV_PMC_SCRATCH200) = 0x0; PMC(APBDEV_PMC_RST_STATUS) = 0x0; APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10); @@ -352,7 +344,7 @@ void hw_init() // Enable Security Engine clock. clock_enable_se(); - // Enable Fuse clock. + // Enable Fuse visibility. clock_enable_fuse(true); // Disable Fuse programming. @@ -407,12 +399,12 @@ void hw_init() // Set BPMP/SCLK to PLLP_OUT (408MHz). CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; - // Disable TZRAM shutdown control and lock the regs. + // Power on T210B01 shadow TZRAM and lock the reg. if (!tegra_t210) { - PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= 0xFFFFFFFE; - PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = 3; - PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = 3; + PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= ~PMC_TZRAM_PWR_CNTRL_SD; + PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ; + PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ; } // Initialize External memory controller and configure DRAM parameters. @@ -426,7 +418,7 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic) // Disable BPMP max clock. bpmp_clk_rate_set(BPMP_CLK_NORMAL); -#ifdef NYX +#ifdef BDK_HW_EXTRA_DEINIT // Disable temperature sensor, touchscreen, 5V regulators and Joy-Con. tmp451_end(); set_fan_duty(0); diff --git a/bdk/soc/hw_init.h b/bdk/soc/hw_init.h index a1b2dfc..a36498b 100644 --- a/bdk/soc/hw_init.h +++ b/bdk/soc/hw_init.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, @@ -21,8 +21,12 @@ #include #define BL_MAGIC_CRBOOT_SLD 0x30444C53 // SLD0, seamless display type 0. +#define BL_MAGIC_HEKATF_SLD 0x31444C53 // SLD1, seamless display type 1. #define BL_MAGIC_BROKEN_HWI 0xBAADF00D // Broken hwinit. +extern u32 hw_rst_status; +extern u32 hw_rst_reason; + void hw_init(); void hw_reinit_workaround(bool coreboot, u32 magic); u32 hw_get_chip_id(); diff --git a/bdk/soc/pmc.h b/bdk/soc/pmc.h index 42bd869..c5ad559 100644 --- a/bdk/soc/pmc.h +++ b/bdk/soc/pmc.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2018 naehrwert * Copyright (c) 2018 st4rk - * Copyright (c) 2018-2020 CTCaer + * Copyright (c) 2018-2022 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, @@ -53,13 +53,20 @@ #define PMC_CRYPTO_OP_SE_DISABLE 1 #define APBDEV_PMC_SCRATCH33 0x120 #define APBDEV_PMC_SCRATCH37 0x130 -#define PMC_SCRATCH37_KERNEL_PANIC_FLAG BIT(24) +#define PMC_SCRATCH37_KERNEL_PANIC_MAGIC 0x4E415054 #define APBDEV_PMC_SCRATCH40 0x13C #define APBDEV_PMC_OSC_EDPD_OVER 0x1A4 #define PMC_OSC_EDPD_OVER_OSC_CTRL_OVER 0x400000 #define APBDEV_PMC_CLK_OUT_CNTRL 0x1A8 #define PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN BIT(2) #define APBDEV_PMC_RST_STATUS 0x1B4 +#define PMC_RST_STATUS_MASK 0x7 +#define PMC_RST_STATUS_POR 0 +#define PMC_RST_STATUS_WATCHDOG 1 +#define PMC_RST_STATUS_SENSOR 2 +#define PMC_RST_STATUS_SW_MAIN 3 +#define PMC_RST_STATUS_LP0 4 +#define PMC_RST_STATUS_AOTAG 5 #define APBDEV_PMC_IO_DPD_REQ 0x1B8 #define PMC_IO_DPD_REQ_DPD_OFF BIT(30) #define APBDEV_PMC_IO_DPD2_REQ 0x1C0 @@ -96,9 +103,15 @@ #define APBDEV_PMC_SCRATCH188 0x810 #define APBDEV_PMC_SCRATCH190 0x818 #define APBDEV_PMC_SCRATCH200 0x840 +#define APBDEV_PMC_SECURE_SCRATCH108 0xB08 +#define APBDEV_PMC_SECURE_SCRATCH109 0xB0C +#define APBDEV_PMC_SECURE_SCRATCH110 0xB10 #define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8 +#define PMC_TZRAM_PWR_CNTRL_SD BIT(0) #define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC #define APBDEV_PMC_TZRAM_NON_SEC_DISABLE 0xBF0 +#define PMC_TZRAM_DISABLE_REG_WRITE BIT(0) +#define PMC_TZRAM_DISABLE_REG_READ BIT(1) typedef enum _pmc_sec_lock_t { diff --git a/bdk/soc/t210.h b/bdk/soc/t210.h index e48f53a..cbacfdf 100644 --- a/bdk/soc/t210.h +++ b/bdk/soc/t210.h @@ -35,6 +35,7 @@ #define AHBDMA_BASE 0x60008000 #define SYSREG_BASE 0x6000C000 #define SB_BASE (SYSREG_BASE + 0x200) +#define ACTMON_BASE 0x6000C800 #define GPIO_BASE 0x6000D000 #define GPIO_1_BASE (GPIO_BASE) #define GPIO_2_BASE (GPIO_BASE + 0x100) @@ -89,6 +90,7 @@ #define SYSREG(off) _REG(SYSREG_BASE, off) #define AHB_GIZMO(off) _REG(SYSREG_BASE, off) #define SB(off) _REG(SB_BASE, off) +#define ACTMON(off) _REG(ACTMON_BASE, off) #define GPIO(off) _REG(GPIO_BASE, off) #define GPIO_1(off) _REG(GPIO_1_BASE, off) #define GPIO_2(off) _REG(GPIO_2_BASE, off) @@ -184,6 +186,8 @@ #define MEM_PREFETCH_USB3_MST_ID MST_ID(17) // XUSB. #define MEM_PREFETCH_ADDR_BNDRY(x) (((x) & 0xF) << 21) #define MEM_PREFETCH_ENABLE BIT(31) +#define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID 0xFC +#define MEM_WRQUE_SE_MST_ID BIT(14) #define AHB_AHB_SPARE_REG 0x110 /*! Misc registers. */ @@ -192,6 +196,7 @@ #define APB_MISC_GP_HIDREV 0x804 #define GP_HIDREV_MAJOR_T210 0x1 #define GP_HIDREV_MAJOR_T210B01 0x2 +#define APB_MISC_GP_ASDBGREG 0x810 #define APB_MISC_GP_AUD_MCLK_CFGPADCTRL 0x8F4 #define APB_MISC_GP_LCD_BL_PWM_CFGPADCTRL 0xA34 #define APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL 0xA98 @@ -281,7 +286,6 @@ /*! Special registers. */ #define EMC_SCRATCH0 0x324 #define EMC_HEKA_UPD BIT(30) -#define EMC_SEPT_RUN BIT(31) /*! Flow controller registers. */ #define FLOW_CTLR_HALT_COP_EVENTS 0x4 diff --git a/bdk/soc/uart.c b/bdk/soc/uart.c index 582bca1..00ee1ad 100644 --- a/bdk/soc/uart.c +++ b/bdk/soc/uart.c @@ -172,3 +172,22 @@ void uart_empty_fifo(u32 idx, u32 which) } } } + +#ifdef DEBUG_UART_PORT +#include +#include + +#include + +void uart_print(const char *fmt, ...) +{ + va_list ap; + char text[256]; + + va_start(ap, fmt); + s_vprintf(text, fmt, ap); + va_end(ap); + + uart_send(DEBUG_UART_PORT, (u8 *)text, strlen(text)); +} +#endif diff --git a/bdk/soc/uart.h b/bdk/soc/uart.h index 6a4c073..103db13 100644 --- a/bdk/soc/uart.h +++ b/bdk/soc/uart.h @@ -94,5 +94,8 @@ void uart_invert(u32 idx, bool enable, u32 invert_mask); u32 uart_get_IIR(u32 idx); void uart_set_IIR(u32 idx); void uart_empty_fifo(u32 idx, u32 which); +#ifdef DEBUG_UART_PORT +void uart_print(const char *fmt, ...); +#endif #endif diff --git a/bdk/storage/emmc.c b/bdk/storage/emmc.c new file mode 100644 index 0000000..a344a94 --- /dev/null +++ b/bdk/storage/emmc.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2018 naehrwert + * Copyright (c) 2019-2022 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 . + */ + +#include + +#include "emmc.h" +#include +#include +#include +#include + +static u16 emmc_errors[3] = { 0 }; // Init and Read/Write errors. +static u32 emmc_mode = EMMC_MMC_HS400; + +sdmmc_t emmc_sdmmc; +sdmmc_storage_t emmc_storage; +FATFS emmc_fs; + +#ifdef BDK_EMUMMC_ENABLE +int emummc_storage_read(u32 sector, u32 num_sectors, void *buf); +int emummc_storage_write(u32 sector, u32 num_sectors, void *buf); +#endif + +void emmc_error_count_increment(u8 type) +{ + switch (type) + { + case EMMC_ERROR_INIT_FAIL: + emmc_errors[0]++; + break; + case EMMC_ERROR_RW_FAIL: + emmc_errors[1]++; + break; + case EMMC_ERROR_RW_RETRY: + emmc_errors[2]++; + break; + } +} + +u16 *emmc_get_error_count() +{ + return emmc_errors; +} + +u32 emmc_get_mode() +{ + return emmc_mode; +} + +int emmc_init_retry(bool power_cycle) +{ + u32 bus_width = SDMMC_BUS_WIDTH_8; + u32 type = SDHCI_TIMING_MMC_HS400; + + // Power cycle SD eMMC. + if (power_cycle) + { + emmc_mode--; + sdmmc_storage_end(&emmc_storage); + } + + // Get init parameters. + switch (emmc_mode) + { + case EMMC_INIT_FAIL: // Reset to max. + return 0; + case EMMC_1BIT_HS52: + bus_width = SDMMC_BUS_WIDTH_1; + type = SDHCI_TIMING_MMC_HS52; + break; + case EMMC_8BIT_HS52: + type = SDHCI_TIMING_MMC_HS52; + break; + case EMMC_MMC_HS200: + type = SDHCI_TIMING_MMC_HS200; + break; + case EMMC_MMC_HS400: + type = SDHCI_TIMING_MMC_HS400; + break; + default: + emmc_mode = EMMC_MMC_HS400; + } + + return sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, bus_width, type); +} + +bool emmc_initialize(bool power_cycle) +{ + // Reset mode in case of previous failure. + if (emmc_mode == EMMC_INIT_FAIL) + emmc_mode = EMMC_MMC_HS400; + + if (power_cycle) + sdmmc_storage_end(&emmc_storage); + + int res = !emmc_init_retry(false); + + while (true) + { + if (!res) + return true; + else + { + emmc_errors[EMMC_ERROR_INIT_FAIL]++; + + if (emmc_mode == EMMC_INIT_FAIL) + break; + else + res = !emmc_init_retry(true); + } + } + + sdmmc_storage_end(&emmc_storage); + + return false; +} + +void emmc_gpt_parse(link_t *gpt) +{ + gpt_t *gpt_buf = (gpt_t *)calloc(GPT_NUM_BLOCKS, EMMC_BLOCKSIZE); + +#ifdef BDK_EMUMMC_ENABLE + emummc_storage_read(GPT_FIRST_LBA, GPT_NUM_BLOCKS, gpt_buf); +#else + sdmmc_storage_read(&emmc_storage, GPT_FIRST_LBA, GPT_NUM_BLOCKS, gpt_buf); +#endif + + // Check if no GPT or more than max allowed entries. + if (memcmp(&gpt_buf->header.signature, "EFI PART", 8) || gpt_buf->header.num_part_ents > 128) + goto out; + + for (u32 i = 0; i < gpt_buf->header.num_part_ents; i++) + { + emmc_part_t *part = (emmc_part_t *)calloc(sizeof(emmc_part_t), 1); + + if (gpt_buf->entries[i].lba_start < gpt_buf->header.first_use_lba) + continue; + + part->index = i; + part->lba_start = gpt_buf->entries[i].lba_start; + part->lba_end = gpt_buf->entries[i].lba_end; + part->attrs = gpt_buf->entries[i].attrs; + + // ASCII conversion. Copy only the LSByte of the UTF-16LE name. + for (u32 j = 0; j < 36; j++) + part->name[j] = gpt_buf->entries[i].name[j]; + part->name[35] = 0; + + list_append(gpt, &part->link); + } + +out: + free(gpt_buf); +} + +void emmc_gpt_free(link_t *gpt) +{ + LIST_FOREACH_SAFE(iter, gpt) + free(CONTAINER_OF(iter, emmc_part_t, link)); +} + +emmc_part_t *emmc_part_find(link_t *gpt, const char *name) +{ + LIST_FOREACH_ENTRY(emmc_part_t, part, gpt, link) + if (!strcmp(part->name, name)) + return part; + + return NULL; +} + +int emmc_part_read(emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf) +{ + // The last LBA is inclusive. + if (part->lba_start + sector_off > part->lba_end) + return 0; + +#ifdef BDK_EMUMMC_ENABLE + return emummc_storage_read(part->lba_start + sector_off, num_sectors, buf); +#else + return sdmmc_storage_read(&emmc_storage, part->lba_start + sector_off, num_sectors, buf); +#endif +} + +int emmc_part_write(emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf) +{ + // The last LBA is inclusive. + if (part->lba_start + sector_off > part->lba_end) + return 0; + +#ifdef BDK_EMUMMC_ENABLE + return emummc_storage_write(part->lba_start + sector_off, num_sectors, buf); +#else + return sdmmc_storage_write(&emmc_storage, part->lba_start + sector_off, num_sectors, buf); +#endif +} + +void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1) +{ + if (fuse_read_hw_state() == FUSE_NX_HW_STATE_PROD) + { + *mod0 = 0xF7; + *mod1 = 0x86; + } + else + { + *mod0 = 0x37; + *mod1 = 0x84; + } +} diff --git a/source/storage/nx_emmc.h b/bdk/storage/emmc.h similarity index 51% rename from source/storage/nx_emmc.h rename to bdk/storage/emmc.h index 5db6a1f..840b960 100644 --- a/source/storage/nx_emmc.h +++ b/bdk/storage/emmc.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 naehrwert + * Copyright (c) 2019-2022 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, @@ -14,17 +15,34 @@ * along with this program. If not, see . */ -#ifndef _NX_EMMC_H_ -#define _NX_EMMC_H_ +#ifndef _EMMC_H_ +#define _EMMC_H_ #include -#include #include #include -#define NX_GPT_FIRST_LBA 1 -#define NX_GPT_NUM_BLOCKS 33 -#define NX_EMMC_BLOCKSIZE 512 +#include + +#define GPT_FIRST_LBA 1 +#define GPT_NUM_BLOCKS 33 +#define EMMC_BLOCKSIZE 512 + +enum +{ + EMMC_INIT_FAIL = 0, + EMMC_1BIT_HS52 = 1, + EMMC_8BIT_HS52 = 2, + EMMC_MMC_HS200 = 3, + EMMC_MMC_HS400 = 4, +}; + +enum +{ + EMMC_ERROR_INIT_FAIL = 0, + EMMC_ERROR_RW_FAIL = 1, + EMMC_ERROR_RW_RETRY = 2 +}; typedef struct _emmc_part_t { @@ -40,10 +58,18 @@ extern sdmmc_t emmc_sdmmc; extern sdmmc_storage_t emmc_storage; extern FATFS emmc_fs; -void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage); -void nx_emmc_gpt_free(link_t *gpt); -emmc_part_t *nx_emmc_part_find(link_t *gpt, const char *name); -int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf); -int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf); +void emmc_error_count_increment(u8 type); +u16 *emmc_get_error_count(); +u32 emmc_get_mode(); +int emmc_init_retry(bool power_cycle); +bool emmc_initialize(bool power_cycle); + +void emmc_gpt_parse(link_t *gpt); +void emmc_gpt_free(link_t *gpt); +emmc_part_t *emmc_part_find(link_t *gpt, const char *name); +int emmc_part_read(emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf); +int emmc_part_write(emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf); + +void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1); #endif 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/nx_emmc_bis.c b/bdk/storage/nx_emmc_bis.c new file mode 100644 index 0000000..4bcbc47 --- /dev/null +++ b/bdk/storage/nx_emmc_bis.c @@ -0,0 +1,315 @@ +/* + * eMMC BIS driver for Nintendo Switch + * + * Copyright (c) 2019-2020 shchmue + * Copyright (c) 2019-2022 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 . + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define BIS_CLUSTER_SECTORS 32 +#define BIS_CLUSTER_SIZE 16384 +#define BIS_CACHE_MAX_ENTRIES 16384 +#define BIS_CACHE_LOOKUP_TBL_EMPTY_ENTRY -1 + +typedef struct _cluster_cache_t +{ + u32 cluster_idx; // Index of the cluster in the partition. + bool dirty; // Has been modified without write-back flag. + u8 data[BIS_CLUSTER_SIZE]; // The cached cluster itself. Aligned to 8 bytes for DMA engine. +} cluster_cache_t; + +typedef struct _bis_cache_t +{ + bool full; + bool enabled; + u32 dirty_cnt; + u32 top_idx; + u8 dma_buff[BIS_CLUSTER_SIZE]; // Aligned to 8 bytes for DMA engine. + cluster_cache_t clusters[]; +} bis_cache_t; + +static u8 ks_crypt = 0; +static u8 ks_tweak = 0; +static u32 emu_offset = 0; +static emmc_part_t *system_part = NULL; +static u32 *cache_lookup_tbl = (u32 *)NX_BIS_LOOKUP_ADDR; +static bis_cache_t *bis_cache = (bis_cache_t *)NX_BIS_CACHE_ADDR; + +static int nx_emmc_bis_write_block(u32 sector, u32 count, void *buff, bool flush) +{ + if (!system_part) + return 3; // Not ready. + + int res; + u8 tweak[SE_KEY_128_SIZE] __attribute__((aligned(4))); + u32 cluster = sector / BIS_CLUSTER_SECTORS; + u32 aligned_sector = cluster * BIS_CLUSTER_SECTORS; + u32 sector_in_cluster = sector % BIS_CLUSTER_SECTORS; + u32 lookup_idx = cache_lookup_tbl[cluster]; + bool is_cached = lookup_idx != (u32)BIS_CACHE_LOOKUP_TBL_EMPTY_ENTRY; + + // Write to cached cluster. + if (is_cached) + { + if (buff) + memcpy(bis_cache->clusters[lookup_idx].data + sector_in_cluster * EMMC_BLOCKSIZE, buff, count * EMMC_BLOCKSIZE); + else + buff = bis_cache->clusters[lookup_idx].data; + if (!bis_cache->clusters[lookup_idx].dirty) + bis_cache->dirty_cnt++; + bis_cache->clusters[lookup_idx].dirty = true; + + if (!flush) + return 0; // Success. + + // Reset args to trigger a full cluster flush to emmc. + sector_in_cluster = 0; + sector = aligned_sector; + count = BIS_CLUSTER_SECTORS; + } + + // Encrypt cluster. + if (!se_aes_xts_crypt_sec_nx(ks_tweak, ks_crypt, ENCRYPT, cluster, tweak, true, sector_in_cluster, bis_cache->dma_buff, buff, count * EMMC_BLOCKSIZE)) + return 1; // Encryption error. + + // If not reading from cache, do a regular read and decrypt. + if (!emu_offset) + res = emmc_part_write(system_part, sector, count, bis_cache->dma_buff); + else + res = sdmmc_storage_write(&sd_storage, emu_offset + system_part->lba_start + sector, count, bis_cache->dma_buff); + if (!res) + return 1; // R/W error. + + // Mark cache entry not dirty if write succeeds. + if (is_cached) + { + bis_cache->clusters[lookup_idx].dirty = false; + bis_cache->dirty_cnt--; + } + + return 0; // Success. +} + +static void _nx_emmc_bis_cluster_cache_init(bool enable_cache) +{ + u32 cache_lookup_tbl_size = (system_part->lba_end - system_part->lba_start + 1) / BIS_CLUSTER_SECTORS * sizeof(*cache_lookup_tbl); + + // Clear cache header. + memset(bis_cache, 0, sizeof(bis_cache_t)); + + // Clear cluster lookup table. + memset(cache_lookup_tbl, BIS_CACHE_LOOKUP_TBL_EMPTY_ENTRY, cache_lookup_tbl_size); + + // Enable cache. + bis_cache->enabled = enable_cache; +} + +static void _nx_emmc_bis_flush_cache() +{ + if (!bis_cache->enabled || !bis_cache->dirty_cnt) + return; + + for (u32 i = 0; i < bis_cache->top_idx && bis_cache->dirty_cnt; i++) + { + if (bis_cache->clusters[i].dirty) { + nx_emmc_bis_write_block(bis_cache->clusters[i].cluster_idx * BIS_CLUSTER_SECTORS, BIS_CLUSTER_SECTORS, NULL, true); + bis_cache->dirty_cnt--; + } + } + + _nx_emmc_bis_cluster_cache_init(true); +} + +static int nx_emmc_bis_read_block_normal(u32 sector, u32 count, void *buff) +{ + static u32 prev_cluster = -1; + static u32 prev_sector = 0; + static u8 tweak[SE_KEY_128_SIZE] __attribute__((aligned(4))); + + int res; + bool regen_tweak = true; + u32 tweak_exp = 0; + u32 cluster = sector / BIS_CLUSTER_SECTORS; + u32 sector_in_cluster = sector % BIS_CLUSTER_SECTORS; + + // If not reading from cache, do a regular read and decrypt. + if (!emu_offset) + res = emmc_part_read(system_part, sector, count, bis_cache->dma_buff); + else + res = sdmmc_storage_read(&sd_storage, emu_offset + system_part->lba_start + sector, count, bis_cache->dma_buff); + if (!res) + return 1; // R/W error. + + if (prev_cluster != cluster) // Sector in different cluster than last read. + { + prev_cluster = cluster; + tweak_exp = sector_in_cluster; + } + else if (sector > prev_sector) // Sector in same cluster and past last sector. + { + // Calculates the new tweak using the saved one, reducing expensive _gf256_mul_x_le calls. + tweak_exp = sector - prev_sector - 1; + regen_tweak = false; + } + else // Sector in same cluster and before or same as last sector. + tweak_exp = sector_in_cluster; + + // Maximum one cluster (1 XTS crypto block 16KB). + if (!se_aes_xts_crypt_sec_nx(ks_tweak, ks_crypt, DECRYPT, prev_cluster, tweak, regen_tweak, tweak_exp, buff, bis_cache->dma_buff, count * EMMC_BLOCKSIZE)) + return 1; // R/W error. + + prev_sector = sector + count - 1; + + return 0; // Success. +} + +static int nx_emmc_bis_read_block_cached(u32 sector, u32 count, void *buff) +{ + int res; + u8 cache_tweak[SE_KEY_128_SIZE] __attribute__((aligned(4))); + u32 cluster = sector / BIS_CLUSTER_SECTORS; + u32 cluster_sector = cluster * BIS_CLUSTER_SECTORS; + u32 sector_in_cluster = sector % BIS_CLUSTER_SECTORS; + u32 lookup_idx = cache_lookup_tbl[cluster]; + + // Read from cached cluster. + if (lookup_idx != (u32)BIS_CACHE_LOOKUP_TBL_EMPTY_ENTRY) + { + memcpy(buff, bis_cache->clusters[lookup_idx].data + sector_in_cluster * EMMC_BLOCKSIZE, count * EMMC_BLOCKSIZE); + + return 0; // Success. + } + + // Flush cache if full. + if (bis_cache->top_idx >= BIS_CACHE_MAX_ENTRIES) + _nx_emmc_bis_flush_cache(); + + // Set new cached cluster parameters. + bis_cache->clusters[bis_cache->top_idx].cluster_idx = cluster; + bis_cache->clusters[bis_cache->top_idx].dirty = false; + cache_lookup_tbl[cluster] = bis_cache->top_idx; + + // Read the whole cluster the sector resides in. + if (!emu_offset) + res = emmc_part_read(system_part, cluster_sector, BIS_CLUSTER_SECTORS, bis_cache->dma_buff); + else + res = sdmmc_storage_read(&sd_storage, emu_offset + system_part->lba_start + cluster_sector, BIS_CLUSTER_SECTORS, bis_cache->dma_buff); + if (!res) + return 1; // R/W error. + + // Decrypt cluster. + if (!se_aes_xts_crypt_sec_nx(ks_tweak, ks_crypt, DECRYPT, cluster, cache_tweak, true, 0, bis_cache->dma_buff, bis_cache->dma_buff, BIS_CLUSTER_SIZE)) + return 1; // Decryption error. + + // Copy to cluster cache. + memcpy(bis_cache->clusters[bis_cache->top_idx].data, bis_cache->dma_buff, BIS_CLUSTER_SIZE); + memcpy(buff, bis_cache->dma_buff + sector_in_cluster * EMMC_BLOCKSIZE, count * EMMC_BLOCKSIZE); + + // Increment cache count. + bis_cache->top_idx++; + + return 0; // Success. +} + +static int nx_emmc_bis_read_block(u32 sector, u32 count, void *buff) +{ + if (!system_part) + return 3; // Not ready. + + if (bis_cache->enabled) + return nx_emmc_bis_read_block_cached(sector, count, buff); + else + return nx_emmc_bis_read_block_normal(sector, count, buff); +} + +int nx_emmc_bis_read(u32 sector, u32 count, void *buff) +{ + u8 *buf = (u8 *)buff; + u32 curr_sct = sector; + + while (count) + { + u32 sct_cnt = MIN(count, BIS_CLUSTER_SECTORS); + if (nx_emmc_bis_read_block(curr_sct, sct_cnt, buf)) + return 0; + + count -= sct_cnt; + curr_sct += sct_cnt; + buf += sct_cnt * EMMC_BLOCKSIZE; + } + + return 1; +} + +int nx_emmc_bis_write(u32 sector, u32 count, void *buff) +{ + u8 *buf = (u8 *)buff; + u32 curr_sct = sector; + + while (count) + { + u32 sct_cnt = MIN(count, BIS_CLUSTER_SECTORS); + if (nx_emmc_bis_write_block(curr_sct, sct_cnt, buf, false)) + return 0; + + count -= sct_cnt; + curr_sct += sct_cnt; + buf += sct_cnt * EMMC_BLOCKSIZE; + } + + return 1; +} + +void nx_emmc_bis_init(emmc_part_t *part, bool enable_cache, u32 emummc_offset) +{ + system_part = part; + emu_offset = emummc_offset; + + _nx_emmc_bis_cluster_cache_init(enable_cache); + + if (!strcmp(part->name, "PRODINFO") || !strcmp(part->name, "PRODINFOF")) + { + ks_crypt = 0; + ks_tweak = 1; + } + else if (!strcmp(part->name, "SAFE")) + { + ks_crypt = 2; + ks_tweak = 3; + } + else if (!strcmp(part->name, "SYSTEM") || !strcmp(part->name, "USER")) + { + ks_crypt = 4; + ks_tweak = 5; + } + else + system_part = NULL; +} + +void nx_emmc_bis_end() +{ + _nx_emmc_bis_flush_cache(); + system_part = NULL; +} diff --git a/source/storage/nx_emmc_bis.h b/bdk/storage/nx_emmc_bis.h similarity index 89% rename from source/storage/nx_emmc_bis.h rename to bdk/storage/nx_emmc_bis.h index 4eb5d82..8b07008 100644 --- a/source/storage/nx_emmc_bis.h +++ b/bdk/storage/nx_emmc_bis.h @@ -18,7 +18,7 @@ #ifndef NX_EMMC_BIS_H #define NX_EMMC_BIS_H -#include "../storage/nx_emmc.h" +#include #include typedef struct _nx_emmc_cal0_spk_t @@ -163,10 +163,8 @@ typedef struct _nx_emmc_cal0_t u8 crc16_pad36[0x10]; u8 ext_ecc_b233_eticket_key[0x50]; u8 crc16_pad37[0x10]; - u8 ext_ecc_rsa2048_eticket_key_iv[0x10]; - u8 ext_ecc_rsa2048_eticket_key[0x230]; - u32 ext_ecc_rsa2048_eticket_key_ver; - u8 crc16_pad38[0xC]; + u8 ext_ecc_rsa2048_eticket_key[0x240]; + u8 crc16_pad38[0x10]; u8 ext_ssl_key[0x130]; u8 crc16_pad39[0x10]; u8 ext_gc_key[0x130]; @@ -225,16 +223,9 @@ typedef struct _nx_emmc_cal0_t u8 console_6axis_sensor_mount_type; } __attribute__((packed)) nx_emmc_cal0_t; -#define MAGIC_CAL0 0x304C4143 -#define NX_EMMC_CALIBRATION_OFFSET 0x4400 -#define NX_EMMC_CALIBRATION_SIZE 0x8000 -#define XTS_CLUSTER_SIZE 0x4000 +int nx_emmc_bis_read(u32 sector, u32 count, void *buff); +int nx_emmc_bis_write(u32 sector, u32 count, void *buff); +void nx_emmc_bis_init(emmc_part_t *part, bool enable_cache, u32 emummc_offset); +void nx_emmc_bis_end(); -int nx_emmc_bis_read(u32 sector, u32 count, void *buff); -int nx_emmc_bis_write(u32 sector, u32 count, void *buff); -void nx_emmc_bis_cluster_cache_init(); -void nx_emmc_bis_init(emmc_part_t *part); -void nx_emmc_bis_finalize(); -void nx_emmc_bis_cache_lock(bool lock); - -#endif \ No newline at end of file +#endif diff --git a/bdk/storage/nx_sd.h b/bdk/storage/nx_sd.h deleted file mode 100644 index e2b703f..0000000 --- a/bdk/storage/nx_sd.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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, - * 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 NX_SD_H -#define NX_SD_H - -#include -#include -#include - -enum -{ - SD_INIT_FAIL = 0, - SD_1BIT_HS25 = 1, - SD_4BIT_HS25 = 2, - SD_UHS_SDR82 = 3, - SD_UHS_SDR104 = 4 -}; - -enum -{ - SD_ERROR_INIT_FAIL = 0, - SD_ERROR_RW_FAIL = 1, - SD_ERROR_RW_RETRY = 2 -}; - -extern sdmmc_t sd_sdmmc; -extern sdmmc_storage_t sd_storage; -extern FATFS sd_fs; - -void sd_error_count_increment(u8 type); -u16 *sd_get_error_count(); -bool sd_get_card_removed(); -bool sd_get_card_initialized(); -bool sd_get_card_mounted(); -u32 sd_get_mode(); -int sd_init_retry(bool power_cycle); -bool sd_initialize(bool power_cycle); -bool sd_mount(); -void sd_unmount(); -void sd_end(); -bool sd_is_gpt(); -void *sd_file_read(const char *path, u32 *fsize); -int sd_save_to_file(void *buf, u32 size, const char *filename); - -#endif \ No newline at end of file diff --git a/bdk/storage/ramdisk.c b/bdk/storage/ramdisk.c index 315075d..3a86ebf 100644 --- a/bdk/storage/ramdisk.c +++ b/bdk/storage/ramdisk.c @@ -20,6 +20,7 @@ #include "ramdisk.h" #include +#include #include #include @@ -27,10 +28,11 @@ static u32 disk_size = 0; -int ram_disk_init(FATFS *ram_fs, u32 ramdisk_size) +int ram_disk_init(void *ram_fs, u32 ramdisk_size) { int res = 0; disk_size = ramdisk_size; + FATFS *ram_fatfs = (FATFS *)ram_fs; // If ramdisk is not raw, format it. if (ram_fs) @@ -49,7 +51,7 @@ int ram_disk_init(FATFS *ram_fs, u32 ramdisk_size) // Mount ramdisk. if (!res) - res = f_mount(ram_fs, "ram:", 1); + res = f_mount(ram_fatfs, "ram:", 1); free(buf); } diff --git a/bdk/storage/ramdisk.h b/bdk/storage/ramdisk.h index e625235..67bc0a5 100644 --- a/bdk/storage/ramdisk.h +++ b/bdk/storage/ramdisk.h @@ -19,11 +19,11 @@ #ifndef RAM_DISK_H #define RAM_DISK_H -#include +#include #define RAMDISK_CLUSTER_SZ 32768 -int ram_disk_init(FATFS *ram_fs, u32 ramdisk_size); +int ram_disk_init(void *ram_fs, u32 ramdisk_size); int ram_disk_read(u32 sector, u32 sector_count, void *buf); int ram_disk_write(u32 sector, u32 sector_count, const void *buf); diff --git a/source/storage/nx_sd.c b/bdk/storage/sd.c similarity index 78% rename from source/storage/nx_sd.c rename to bdk/storage/sd.c index f122380..ccc9f49 100644 --- a/source/storage/nx_sd.c +++ b/bdk/storage/sd.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2019 CTCaer + * Copyright (c) 2018-2022 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,16 +15,17 @@ * along with this program. If not, see . */ -#include +#include #include #include #include #include #include -bool sd_mounted = false; +static bool sd_mounted = false; +static bool sd_init_done = false; static u16 sd_errors[3] = { 0 }; // Init and Read/Write errors. -static u32 sd_mode = SD_UHS_SDR82; +static u32 sd_mode = SD_UHS_SDR104; sdmmc_t sd_sdmmc; sdmmc_storage_t sd_storage; @@ -53,12 +54,22 @@ u16 *sd_get_error_count() bool sd_get_card_removed() { - if (!sdmmc_get_sd_inserted()) + if (sd_init_done && !sdmmc_get_sd_inserted()) return true; return false; } +bool sd_get_card_initialized() +{ + return sd_init_done; +} + +bool sd_get_card_mounted() +{ + return sd_mounted; +} + u32 sd_get_mode() { return sd_mode; @@ -67,7 +78,7 @@ u32 sd_get_mode() int sd_init_retry(bool power_cycle) { u32 bus_width = SDMMC_BUS_WIDTH_4; - u32 type = SDHCI_TIMING_UHS_SDR82; + u32 type = SDHCI_TIMING_UHS_SDR104; // Power cycle SD card. if (power_cycle) @@ -91,8 +102,11 @@ int sd_init_retry(bool power_cycle) case SD_UHS_SDR82: type = SDHCI_TIMING_UHS_SDR82; break; + case SD_UHS_SDR104: + type = SDHCI_TIMING_UHS_SDR104; + break; default: - sd_mode = SD_UHS_SDR82; + sd_mode = SD_UHS_SDR104; } return sdmmc_storage_init_sd(&sd_storage, &sd_sdmmc, bus_width, type); @@ -111,7 +125,7 @@ bool sd_initialize(bool power_cycle) return true; else if (!sdmmc_get_sd_inserted()) // SD Card is not inserted. { - sd_mode = SD_UHS_SDR82; + sd_mode = SD_UHS_SDR104; break; } else @@ -130,15 +144,15 @@ bool sd_initialize(bool power_cycle) return false; } -bool is_sd_inited = false; - bool sd_mount() { if (sd_mounted) return true; - int res = !sd_initialize(false); - is_sd_inited = !res; + int res = 0; + + if (!sd_init_done) + res = !sd_initialize(false); if (res) { @@ -151,7 +165,8 @@ bool sd_mount() } else { - res = f_mount(&sd_fs, "", 1); + sd_init_done = true; + res = f_mount(&sd_fs, "0:", 1); // Volume 0 is SD. if (res == FR_OK) { sd_mounted = true; @@ -167,22 +182,30 @@ bool sd_mount() return false; } -static void _sd_deinit() +static void _sd_deinit(bool deinit) { - if (sd_mode == SD_INIT_FAIL) - sd_mode = SD_UHS_SDR82; + if (deinit && sd_mode == SD_INIT_FAIL) + sd_mode = SD_UHS_SDR104; - if (sd_mounted) + if (sd_init_done && sd_mounted) { - f_mount(NULL, "", 1); - sdmmc_storage_end(&sd_storage); + f_mount(NULL, "0:", 1); // Volume 0 is SD. sd_mounted = false; - is_sd_inited = false; + } + if (sd_init_done && deinit) + { + sdmmc_storage_end(&sd_storage); + sd_init_done = false; } } -void sd_unmount() { _sd_deinit(); } -void sd_end() { _sd_deinit(); } +void sd_unmount() { _sd_deinit(false); } +void sd_end() { _sd_deinit(true); } + +bool sd_is_gpt() +{ + return sd_fs.part_type; +} void *sd_file_read(const char *path, u32 *fsize) { diff --git a/bdk/storage/sd.h b/bdk/storage/sd.h index 22d3359..19eb6d5 100644 --- a/bdk/storage/sd.h +++ b/bdk/storage/sd.h @@ -1,150 +1,60 @@ /* - * Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved. - * Copyright (c) 2018-2021 CTCaer + * 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 of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - */ - -#ifndef MMC_SD_H -#define MMC_SD_H - -/* SD commands type argument response */ -/* class 0 */ -/* This is basically the same command as for MMC with some quirks. */ -#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ -#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ -#define SD_SWITCH_VOLTAGE 11 /* ac R1 */ -/* class 10 */ -#define SD_SWITCH 6 /* adtc [31:0] See below R1 */ -/* class 5 */ -#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */ -#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */ - -/* Application commands */ -#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ -#define SD_APP_SD_STATUS 13 /* adtc R1 */ -#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */ -#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ -#define SD_APP_SET_CLR_CARD_DETECT 42 /* adtc R1 */ -#define SD_APP_SEND_SCR 51 /* adtc R1 */ - -/* Application secure commands */ -#define SD_APP_SECURE_READ_MULTI_BLOCK 18 /* adtc R1 */ -#define SD_APP_SECURE_WRITE_MULTI_BLOCK 25 /* adtc R1 */ -#define SD_APP_SECURE_WRITE_MKB 26 /* adtc R1 */ -#define SD_APP_SECURE_ERASE 38 /* adtc R1b */ -#define SD_APP_GET_MKB 43 /* adtc [31:0] See below R1 */ -#define SD_APP_GET_MID 44 /* adtc R1 */ -#define SD_APP_SET_CER_RN1 45 /* adtc R1 */ -#define SD_APP_GET_CER_RN2 46 /* adtc R1 */ -#define SD_APP_SET_CER_RES2 47 /* adtc R1 */ -#define SD_APP_GET_CER_RES1 48 /* adtc R1 */ -#define SD_APP_CHANGE_SECURE_AREA 49 /* adtc R1b */ - -/* OCR bit definitions */ -#define SD_OCR_VDD_18 (1 << 7) /* VDD voltage 1.8 */ -#define SD_VHD_27_36 (1 << 8) /* VDD voltage 2.7 ~ 3.6 */ -#define SD_OCR_VDD_27_34 (0x7F << 15) /* VDD voltage 2.7 ~ 3.4 */ -#define SD_OCR_VDD_32_33 (1 << 20) /* VDD voltage 3.2 ~ 3.3 */ -#define SD_OCR_S18R (1 << 24) /* 1.8V switching request */ -#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */ -#define SD_OCR_XPC (1 << 28) /* SDXC power control */ -#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */ -#define SD_OCR_BUSY (1 << 31) /* Card Power up Status */ - -/* - * SD_SWITCH argument format: + * 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. * - * [31] Check (0) or switch (1) - * [30:24] Reserved (0) - * [23:20] Function group 6 - * [19:16] Function group 5 - * [15:12] Function group 4 - * [11:8] Function group 3 - * [7:4] Function group 2 - * [3:0] Function group 1 - */ - -/* - * SD_SEND_IF_COND argument format: + * 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. * - * [31:12] Reserved (0) - * [11:8] Host Voltage Supply Flags - * [7:0] Check Pattern (0xAA) + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ -/* - * SD_APP_GET_MKB argument format: - * - * [31:24] Number of blocks to read (512 block size) - * [23:16] MKB ID - * [15:0] Block offset - */ +#ifndef SD_H +#define SD_H -/* - * SCR field definitions - */ -#define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */ -#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */ -#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00-3.0X */ -#define SD_SCR_BUS_WIDTH_1 (1<<0) -#define SD_SCR_BUS_WIDTH_4 (1<<2) +#include +#include +#include -/* - * SD bus widths - */ -#define SD_BUS_WIDTH_1 0 -#define SD_BUS_WIDTH_4 2 +enum +{ + SD_INIT_FAIL = 0, + SD_1BIT_HS25 = 1, + SD_4BIT_HS25 = 2, + SD_UHS_SDR82 = 3, + SD_UHS_SDR104 = 4 +}; -/* - * SD bus speeds - */ -#define UHS_SDR12_BUS_SPEED 0 -#define HIGH_SPEED_BUS_SPEED 1 -#define UHS_SDR25_BUS_SPEED 1 -#define UHS_SDR50_BUS_SPEED 2 -#define UHS_SDR104_BUS_SPEED 3 -#define UHS_DDR50_BUS_SPEED 4 -#define HS400_BUS_SPEED 5 +enum +{ + SD_ERROR_INIT_FAIL = 0, + SD_ERROR_RW_FAIL = 1, + SD_ERROR_RW_RETRY = 2 +}; -#define SD_MODE_HIGH_SPEED (1 << HIGH_SPEED_BUS_SPEED) -#define SD_MODE_UHS_SDR12 (1 << UHS_SDR12_BUS_SPEED) -#define SD_MODE_UHS_SDR25 (1 << UHS_SDR25_BUS_SPEED) -#define SD_MODE_UHS_SDR50 (1 << UHS_SDR50_BUS_SPEED) -#define SD_MODE_UHS_SDR104 (1 << UHS_SDR104_BUS_SPEED) -#define SD_MODE_UHS_DDR50 (1 << UHS_DDR50_BUS_SPEED) +extern sdmmc_t sd_sdmmc; +extern sdmmc_storage_t sd_storage; +extern FATFS sd_fs; -#define SD_DRIVER_TYPE_B 0x01 -#define SD_DRIVER_TYPE_A 0x02 +void sd_error_count_increment(u8 type); +u16 *sd_get_error_count(); +bool sd_get_card_removed(); +bool sd_get_card_initialized(); +bool sd_get_card_mounted(); +u32 sd_get_mode(); +int sd_init_retry(bool power_cycle); +bool sd_initialize(bool power_cycle); +bool sd_mount(); +void sd_unmount(); +void sd_end(); +bool sd_is_gpt(); +void *sd_file_read(const char *path, u32 *fsize); +int sd_save_to_file(void *buf, u32 size, const char *filename); -#define SD_SET_CURRENT_LIMIT_200 0 -#define SD_SET_CURRENT_LIMIT_400 1 -#define SD_SET_CURRENT_LIMIT_600 2 -#define SD_SET_CURRENT_LIMIT_800 3 - -#define SD_MAX_CURRENT_200 (1 << SD_SET_CURRENT_LIMIT_200) -#define SD_MAX_CURRENT_400 (1 << SD_SET_CURRENT_LIMIT_400) -#define SD_MAX_CURRENT_600 (1 << SD_SET_CURRENT_LIMIT_600) -#define SD_MAX_CURRENT_800 (1 << SD_SET_CURRENT_LIMIT_800) - -/* - * SD_SWITCH mode - */ -#define SD_SWITCH_CHECK 0 -#define SD_SWITCH_SET 1 - -/* - * SD_SWITCH function groups - */ -#define SD_SWITCH_GRP_ACCESS 0 - -/* - * SD_SWITCH access modes - */ -#define SD_SWITCH_ACCESS_DEF 0 -#define SD_SWITCH_ACCESS_HS 1 - -#endif /* LINUX_MMC_SD_H */ +#endif \ No newline at end of file diff --git a/bdk/storage/sd_def.h b/bdk/storage/sd_def.h new file mode 100644 index 0000000..9d030f5 --- /dev/null +++ b/bdk/storage/sd_def.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved. + * Copyright (c) 2018-2021 CTCaer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + +#ifndef SD_DEF_H +#define SD_DEF_H + +/* SD commands type argument response */ +/* class 0 */ +/* This is basically the same command as for MMC with some quirks. */ +#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ +#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ +#define SD_SWITCH_VOLTAGE 11 /* ac R1 */ +/* class 10 */ +#define SD_SWITCH 6 /* adtc [31:0] See below R1 */ +/* class 5 */ +#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */ +#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */ + +/* Application commands */ +#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ +#define SD_APP_SD_STATUS 13 /* adtc R1 */ +#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */ +#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ +#define SD_APP_SET_CLR_CARD_DETECT 42 /* adtc R1 */ +#define SD_APP_SEND_SCR 51 /* adtc R1 */ + +/* Application secure commands */ +#define SD_APP_SECURE_READ_MULTI_BLOCK 18 /* adtc R1 */ +#define SD_APP_SECURE_WRITE_MULTI_BLOCK 25 /* adtc R1 */ +#define SD_APP_SECURE_WRITE_MKB 26 /* adtc R1 */ +#define SD_APP_SECURE_ERASE 38 /* adtc R1b */ +#define SD_APP_GET_MKB 43 /* adtc [31:0] See below R1 */ +#define SD_APP_GET_MID 44 /* adtc R1 */ +#define SD_APP_SET_CER_RN1 45 /* adtc R1 */ +#define SD_APP_GET_CER_RN2 46 /* adtc R1 */ +#define SD_APP_SET_CER_RES2 47 /* adtc R1 */ +#define SD_APP_GET_CER_RES1 48 /* adtc R1 */ +#define SD_APP_CHANGE_SECURE_AREA 49 /* adtc R1b */ + +/* OCR bit definitions */ +#define SD_OCR_VDD_18 (1 << 7) /* VDD voltage 1.8 */ +#define SD_VHD_27_36 (1 << 8) /* VDD voltage 2.7 ~ 3.6 */ +#define SD_OCR_VDD_27_34 (0x7F << 15) /* VDD voltage 2.7 ~ 3.4 */ +#define SD_OCR_VDD_32_33 (1 << 20) /* VDD voltage 3.2 ~ 3.3 */ +#define SD_OCR_S18R (1 << 24) /* 1.8V switching request */ +#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */ +#define SD_OCR_XPC (1 << 28) /* SDXC power control */ +#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */ +#define SD_OCR_BUSY (1 << 31) /* Card Power up Status */ + +/* + * SD_SWITCH argument format: + * + * [31] Check (0) or switch (1) + * [30:24] Reserved (0) + * [23:20] Function group 6 + * [19:16] Function group 5 + * [15:12] Function group 4 + * [11:8] Function group 3 + * [7:4] Function group 2 + * [3:0] Function group 1 + */ + +/* + * SD_SEND_IF_COND argument format: + * + * [31:12] Reserved (0) + * [11:8] Host Voltage Supply Flags + * [7:0] Check Pattern (0xAA) + */ + +/* + * SD_APP_GET_MKB argument format: + * + * [31:24] Number of blocks to read (512 block size) + * [23:16] MKB ID + * [15:0] Block offset + */ + +/* + * SCR field definitions + */ +#define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */ +#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */ +#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00-3.0X */ +#define SD_SCR_BUS_WIDTH_1 (1<<0) +#define SD_SCR_BUS_WIDTH_4 (1<<2) + +/* + * SD bus widths + */ +#define SD_BUS_WIDTH_1 0 +#define SD_BUS_WIDTH_4 2 + +/* + * SD bus speeds + */ +#define UHS_SDR12_BUS_SPEED 0 +#define HIGH_SPEED_BUS_SPEED 1 +#define UHS_SDR25_BUS_SPEED 1 +#define UHS_SDR50_BUS_SPEED 2 +#define UHS_SDR104_BUS_SPEED 3 +#define UHS_DDR50_BUS_SPEED 4 +#define HS400_BUS_SPEED 5 + +#define SD_MODE_HIGH_SPEED (1 << HIGH_SPEED_BUS_SPEED) +#define SD_MODE_UHS_SDR12 (1 << UHS_SDR12_BUS_SPEED) +#define SD_MODE_UHS_SDR25 (1 << UHS_SDR25_BUS_SPEED) +#define SD_MODE_UHS_SDR50 (1 << UHS_SDR50_BUS_SPEED) +#define SD_MODE_UHS_SDR104 (1 << UHS_SDR104_BUS_SPEED) +#define SD_MODE_UHS_DDR50 (1 << UHS_DDR50_BUS_SPEED) + +#define SD_DRIVER_TYPE_B 0x01 +#define SD_DRIVER_TYPE_A 0x02 + +#define SD_SET_CURRENT_LIMIT_200 0 +#define SD_SET_CURRENT_LIMIT_400 1 +#define SD_SET_CURRENT_LIMIT_600 2 +#define SD_SET_CURRENT_LIMIT_800 3 + +#define SD_MAX_CURRENT_200 (1 << SD_SET_CURRENT_LIMIT_200) +#define SD_MAX_CURRENT_400 (1 << SD_SET_CURRENT_LIMIT_400) +#define SD_MAX_CURRENT_600 (1 << SD_SET_CURRENT_LIMIT_600) +#define SD_MAX_CURRENT_800 (1 << SD_SET_CURRENT_LIMIT_800) + +/* + * SD_SWITCH mode + */ +#define SD_SWITCH_CHECK 0 +#define SD_SWITCH_SET 1 + +/* + * SD_SWITCH function groups + */ +#define SD_SWITCH_GRP_ACCESS 0 + +/* + * SD_SWITCH access modes + */ +#define SD_SWITCH_ACCESS_DEF 0 +#define SD_SWITCH_ACCESS_HS 1 + +#endif /* SD_DEF_H */ diff --git a/bdk/storage/sdmmc.c b/bdk/storage/sdmmc.c index 54b19de..8980d61 100644 --- a/bdk/storage/sdmmc.c +++ b/bdk/storage/sdmmc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2021 CTCaer + * Copyright (c) 2018-2022 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,10 +16,11 @@ */ #include +#include #include #include -#include #include +#include #include #include #include @@ -139,6 +140,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; @@ -210,20 +265,36 @@ reinit_try: msleep(50); } while (retries); - // Disk IO failure! Reinit SD Card to a lower speed. - if (storage->sdmmc->id == SDMMC_1) + // Disk IO failure! Reinit SD/EMMC to a lower speed. + if (storage->sdmmc->id == SDMMC_1 || storage->sdmmc->id == SDMMC_4) { int res; - sd_error_count_increment(SD_ERROR_RW_FAIL); - - if (first_reinit) - res = sd_initialize(true); - else + if (storage->sdmmc->id == SDMMC_1) { - res = sd_init_retry(true); - if (!res) - sd_error_count_increment(SD_ERROR_INIT_FAIL); + sd_error_count_increment(SD_ERROR_RW_FAIL); + + if (first_reinit) + res = sd_initialize(true); + else + { + res = sd_init_retry(true); + if (!res) + sd_error_count_increment(SD_ERROR_INIT_FAIL); + } + } + else if (storage->sdmmc->id == SDMMC_4) + { + emmc_error_count_increment(EMMC_ERROR_RW_FAIL); + + if (first_reinit) + res = emmc_initialize(true); + else + { + res = emmc_init_retry(true); + if (!res) + emmc_error_count_increment(EMMC_ERROR_INIT_FAIL); + } } // Reset values for a retry. @@ -231,7 +302,7 @@ reinit_try: retries = 3; first_reinit = false; - // If succesful reinit, restart xfer. + // If successful reinit, restart xfer. if (res) { bbuf = (u8 *)buf; @@ -1360,8 +1431,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 +1456,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/storage/sdmmc_driver.c b/bdk/storage/sdmmc_driver.c index 5ceb2e7..f31271e 100644 --- a/bdk/storage/sdmmc_driver.c +++ b/bdk/storage/sdmmc_driver.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2021 CTCaer + * Copyright (c) 2018-2022 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, @@ -34,7 +34,7 @@ //#define ERROR_EXTRA_PRINTING #define DPRINTF(...) -#ifdef NYX +#ifdef BDK_SDMMC_OC_AND_EXTRA_PRINT #define ERROR_EXTRA_PRINTING #define SDMMC_EMMC_OC #endif @@ -1033,12 +1033,10 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_ } int result = _sdmmc_wait_response(sdmmc); - if (!result) - { #ifdef ERROR_EXTRA_PRINTING + if (!result) EPRINTF("SDMMC: Transfer timeout!"); #endif - } DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result, sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3); if (result) @@ -1047,22 +1045,18 @@ DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result, { sdmmc->expected_rsp_type = cmd->rsp_type; result = _sdmmc_cache_rsp(sdmmc, sdmmc->rsp, 0x10, cmd->rsp_type); - if (!result) - { #ifdef ERROR_EXTRA_PRINTING + if (!result) EPRINTF("SDMMC: Unknown response type!"); #endif - } } if (req && result) { result = _sdmmc_update_dma(sdmmc); - if (!result) - { #ifdef ERROR_EXTRA_PRINTING + if (!result) EPRINTF("SDMMC: DMA Update failed!"); #endif - } } } @@ -1085,12 +1079,10 @@ DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result, if (cmd->check_busy || req) { result = _sdmmc_wait_card_busy(sdmmc); - if (!result) - { #ifdef ERROR_EXTRA_PRINTING + if (!result) EPRINTF("SDMMC: Busy timeout!"); #endif - } return result; } } diff --git a/bdk/thermal/fan.c b/bdk/thermal/fan.c index 14379e3..9e7a65e 100644 --- a/bdk/thermal/fan.c +++ b/bdk/thermal/fan.c @@ -1,7 +1,7 @@ /* * Fan driver for Nintendo Switch * - * 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, @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -28,9 +29,20 @@ void set_fan_duty(u32 duty) static bool fan_init = false; static u16 curr_duty = -1; + if (duty > 236) + duty = 236; + if (curr_duty == duty) return; + curr_duty = duty; + + //! TODO: Add HOAG/AULA support. + u32 hw_type = fuse_read_hw_type(); + if (hw_type != FUSE_NX_HW_TYPE_ICOSA && + hw_type != FUSE_NX_HW_TYPE_IOWA) + return; + if (!fan_init) { // Fan tachometer. @@ -46,9 +58,6 @@ void set_fan_duty(u32 duty) fan_init = true; } - if (duty > 236) - duty = 236; - // Inverted polarity. u32 inv_duty = 236 - duty; @@ -71,8 +80,6 @@ void set_fan_duty(u32 duty) // Enable fan. PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = 1; // Set source to PWM1. } - - curr_duty = duty; } void get_fan_speed(u32 *duty, u32 *rpm) diff --git a/bdk/usb/usb_descriptor_types.h b/bdk/usb/usb_descriptor_types.h deleted file mode 100644 index 9f86e9d..0000000 --- a/bdk/usb/usb_descriptor_types.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * USB driver for Tegra X1 - * - * Copyright (c) 2019-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 _USB_DESCRIPTORS_TYPES_H_ -#define _USB_DESCRIPTORS_TYPES_H_ - -#include - -typedef enum { - USB_DESCRIPTOR_DEVICE = 1, - USB_DESCRIPTOR_CONFIGURATION = 2, - USB_DESCRIPTOR_STRING = 3, - USB_DESCRIPTOR_INTERFACE = 4, - USB_DESCRIPTOR_ENDPOINT = 5, - USB_DESCRIPTOR_DEVICE_QUALIFIER = 6, - USB_DESCRIPTOR_OTHER_SPEED_CONFIGURATION = 7, - USB_DESCRIPTOR_INTERFACE_POWER = 8, - USB_DESCRIPTOR_INTERFACE_OTG = 9, - USB_DESCRIPTOR_DEVICE_BINARY_OBJECT = 15, - USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP = 16, - USB_DESCRIPTOR_HID = 33, - USB_DESCRIPTOR_HID_REPORT = 34 -} usb_desc_type_t; - -typedef enum { - USB_DESCRIPTOR_MS_COMPAT_ID = 4, - USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES = 5 -} usb_vendor_desc_type_t; - -typedef enum { - USB_ATTR_REMOTE_WAKE_UP = 0x20, - USB_ATTR_SELF_POWERED = 0x40, - USB_ATTR_BUS_POWERED_RSVD = 0x80 -} usb_cfg_attr_type_t; - -typedef enum -{ - USB_EP_TYPE_CTRL = 0, - USB_EP_TYPE_ISO = 1, - USB_EP_TYPE_BULK = 2, - USB_EP_TYPE_INTR = 3 -} usb_cfg_ep_type_t; - -/* Device descriptor structure */ -typedef struct _usb_dev_descr_t -{ - u8 bLength; // Size of this descriptor in bytes. - u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE) - u16 bcdUSB; // USB Spec. Release number (2.1). - u8 bDeviceClass; // Class is specified in the interface descriptor. - u8 bDeviceSubClass; // SubClass is specified in the interface descriptor. - u8 bDeviceProtocol; // Protocol is specified in the interface descriptor. - u8 bMaxPacketSize; // Maximum packet size for EP0. - u16 idVendor; // Vendor ID assigned by USB forum. - u16 idProduct; // Product ID assigned by Organization. - u16 bcdDevice; // Device Release number in BCD. - u8 iManufacturer; // Index of String descriptor describing Manufacturer. - u8 iProduct; // Index of String descriptor describing Product. - u8 iSerialNumber; // Index of String descriptor describing Serial number. - u8 bNumConfigs; // Number of possible configuration. -} __attribute__((packed)) usb_dev_descr_t; - -/* Device Qualifier descriptor structure */ -typedef struct _usb_dev_qual_descr_t -{ - u8 bLength; // Size of this descriptor in bytes. - u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE_QUALIFIER) - u16 bcdUSB; // USB Spec. Release number (2.1). - u8 bDeviceClass; // Class is specified in the interface descriptor. - u8 bDeviceSubClass; // SubClass is specified in the interface descriptor. - u8 bDeviceProtocol; // Protocol is specified in the interface descriptor. - u8 bMaxPacketSize; // Maximum packet size for EP0. - u8 bNumOtherConfigs; // Number of possible other-speed configurations. - u8 bReserved; // Reserved for future use, must be zero -} __attribute__((packed)) usb_dev_qual_descr_t; - -/* Configuration descriptor structure */ -typedef struct _usb_cfg_descr_t -{ - u8 bLength; // Length of this descriptor. - u8 bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION). - u16 wTotalLength; // Total length of all descriptors for this configuration. - u8 bNumInterfaces; // Number of interfaces in this configuration. - u8 bConfigurationValue; // Value of this configuration (1 based). - u8 iConfiguration; // Index of String Descriptor describing the configuration. - u8 bmAttributes; // Configuration characteristics. - u8 bMaxPower; // Maximum power consumed by this configuration. -} __attribute__((packed)) usb_cfg_descr_t; - -/* Interface descriptor structure */ -typedef struct _usb_inter_descr_t -{ - u8 bLength; // Length of this descriptor. - u8 bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE). - u8 bInterfaceNumber; // Number of this interface (0 based). - u8 bAlternateSetting; // Value of this alternate interface setting. - u8 bNumEndpoints; // Number of endpoints in this interface. - u8 bInterfaceClass; // Class code (assigned by the USB-IF). - u8 bInterfaceSubClass; // Subclass code (assigned by the USB-IF). - u8 bInterfaceProtocol; // Protocol code (assigned by the USB-IF). - u8 iInterface; // Index of String Descriptor describing the interface. -} __attribute__((packed)) usb_inter_descr_t; - -/* HID descriptor structure */ -typedef struct _usb_hid_descr_t -{ - u8 bLength; // Length of this descriptor. - u8 bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_HID). - u16 bcdHID; // HID class specification release - u8 bCountryCode; // Country code. - u8 bNumDescriptors; // Number of descriptors. - u8 bClassDescriptorType; // Type of class descriptor (USB_DESCRIPTOR_HID_REPORT). - u16 bDescriptorLength; // Report descriptor length. -} __attribute__((packed)) usb_hid_descr_t; - -/* Endpoint descriptor structure */ -typedef struct _usb_ep_descr_t -{ - u8 bLength; // Length of this descriptor. - u8 bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT). - u8 bEndpointAddress; // Endpoint address. bit7 indicates direction (0=OUT, 1=IN). - u8 bmAttributes; // Endpoint transfer type. - u16 wMaxPacketSize; // Maximum packet size. - u8 bInterval; // Polling interval in frames. For Interrupt and Isochronous data transfer only. -} __attribute__((packed)) usb_ep_descr_t; - -typedef struct _usb_cfg_simple_descr_t -{ - usb_cfg_descr_t config; - usb_inter_descr_t interface; - usb_ep_descr_t endpoint[2]; -} __attribute__((packed)) usb_cfg_simple_descr_t; - -typedef struct _usb_cfg_hid_descr_t -{ - usb_cfg_descr_t config; - usb_inter_descr_t interface; - usb_hid_descr_t hid; - usb_ep_descr_t endpoint[2]; -} __attribute__((packed)) usb_cfg_hid_descr_t; - -typedef struct _usb_dev_bot_t -{ - u8 bLength; // Size of this descriptor in bytes. - u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT) - u16 wTotalLength; // Size of this descriptor in bytes. - u8 bNumDeviceCaps; // Number of device capabilities in this descriptor. - - /* Device Capability USB 2.0 Extension Descriptor */ - /* Needed for a USB2.10 device. */ - u8 bLengthCap0; // Size of this capability descriptor in bytes. - u8 bDescriptorTypeCap0; // Device Capability Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP) - u8 bDevCapabilityTypeCap0; // USB2: 2. - u32 bmAttributesCap0; // bit1: Link Power Management (LPM). - - u8 bLengthCap1; // Size of this capability descriptor in bytes. - u8 bDescriptorTypeCap1; // Device Capability Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP) - u8 bDevCapabilityTypeCap1; // USB3: 3. - u8 bmAttributesCap1; // bit1: Latency Tolerance Messaging (LTM). - u16 wSpeedsSupported; // Supported bus speeds. 1: Low Speed, 2: Full Speed, 4: High Speed, 8: Super Speed. - u8 bFunctionalitySupport; // Lowest speed at which all the functionality is available. 1: Full speed and above. - u8 bU1DevExitLat; // USB3.0 U1 exit latency. - u16 wU2DevExitLat; // USB3.0 U2 exit latency. - -} __attribute__((packed)) usb_dev_bot_t; - -/* Microsoft OS String descriptor structure */ -typedef struct _usb_ms_os_descr_t -{ - u8 bLength; // 0x12 - u8 bDescriptorType; // 3 - u16 wSignature[7]; // "MSFT100" UTF16 LE - u8 bVendorCode; // - u8 bPadding; -} __attribute__((packed)) usb_ms_os_descr_t; - -/* Microsoft Compatible ID Feature descriptor structure */ -typedef struct _usb_ms_cid_descr_t -{ - u32 dLength; - u16 wVersion; - u16 wCompatibilityId; - u8 bSections; - u8 bReserved0[7]; - u8 bInterfaceNumber; - u8 bReserved1; - u8 bCompatibleId[8]; - u8 bSubCompatibleId[8]; - u8 bReserved2[6]; -} __attribute__((packed)) usb_ms_cid_descr_t; - -/* Microsoft Extended Properties Feature descriptor structure */ -typedef struct _usb_ms_ext_prop_descr_t -{ - u32 dLength; - u16 wVersion; - u16 wExtendedProperty; - u16 wSections; - u32 dPropertySize; - u32 dPropertyType; - u16 wPropertyNameLength; - u16 wPropertyName[22]; // UTF16 LE - u32 dPropertyDataLength; - u16 wPropertyData[2]; // UTF16 LE -} __attribute__((packed)) usb_ms_ext_prop_descr_t; - -typedef struct _usb_desc_t -{ - usb_dev_descr_t *dev; - usb_dev_qual_descr_t *dev_qual; - usb_cfg_simple_descr_t *cfg; - usb_cfg_simple_descr_t *cfg_other; - usb_dev_bot_t *dev_bot; - u8 *vendor; - u8 *product; - u8 *serial; - u8 *lang_id; - usb_ms_os_descr_t *ms_os; - usb_ms_cid_descr_t *ms_cid; - usb_ms_ext_prop_descr_t *mx_ext; -} usb_desc_t; - -#endif diff --git a/bdk/usb/usb_descriptors.c b/bdk/usb/usb_descriptors.c deleted file mode 100644 index 389a70d..0000000 --- a/bdk/usb/usb_descriptors.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - * USB driver for Tegra X1 - * - * Copyright (c) 2019-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 . - */ - -#include -#include - -static usb_dev_descr_t usb_device_descriptor_ums = -{ - .bLength = 18, - .bDescriptorType = USB_DESCRIPTOR_DEVICE, - .bcdUSB = 0x210, - .bDeviceClass = 0x00, - .bDeviceSubClass = 0x00, - .bDeviceProtocol = 0x00, - .bMaxPacketSize = 0x40, - .idVendor = 0x11EC, // Nintendo: 0x057E, Nvidia: 0x0955 - .idProduct = 0xA7E0, // Switch: 0x2000, usbd: 0x3000 - .bcdDevice = 0x0101, - .iManufacturer = 1, - .iProduct = 2, - .iSerialNumber = 3, - .bNumConfigs = 1 -}; - -static usb_dev_qual_descr_t usb_device_qualifier_descriptor = -{ - .bLength = 10, - .bDescriptorType = USB_DESCRIPTOR_DEVICE_QUALIFIER, - .bcdUSB = 0x210, - .bDeviceClass = 0x00, - .bDeviceSubClass = 0x00, - .bDeviceProtocol = 0x00, - .bMaxPacketSize = 0x40, - .bNumOtherConfigs = 0x01, - .bReserved = 0x00 -}; - -static usb_cfg_simple_descr_t usb_configuration_descriptor_ums = -{ - /* Configuration descriptor structure */ - .config.bLength = 9, - .config.bDescriptorType = USB_DESCRIPTOR_CONFIGURATION, - .config.wTotalLength = 0x20, - .config.bNumInterfaces = 0x01, - .config.bConfigurationValue = 0x01, - .config.iConfiguration = 0x00, - .config.bmAttributes = USB_ATTR_SELF_POWERED | USB_ATTR_BUS_POWERED_RSVD, - .config.bMaxPower = 32 / 2, - - /* Interface descriptor structure */ - .interface.bLength = 9, - .interface.bDescriptorType = USB_DESCRIPTOR_INTERFACE, - .interface.bInterfaceNumber = 0, - .interface.bAlternateSetting = 0, - .interface.bNumEndpoints = 2, - .interface.bInterfaceClass = 0x08, // Mass Storage Class. - .interface.bInterfaceSubClass = 0x06, // SCSI Transparent Command Set. - .interface.bInterfaceProtocol = 0x50, // Bulk-Only Transport. - .interface.iInterface = 0x00, - - /* Endpoint descriptor structure EP1 IN */ - .endpoint[0].bLength = 7, - .endpoint[0].bDescriptorType = USB_DESCRIPTOR_ENDPOINT, - .endpoint[0].bEndpointAddress = 0x81, // USB_EP_ADDR_BULK_IN. - .endpoint[0].bmAttributes = USB_EP_TYPE_BULK, - .endpoint[0].wMaxPacketSize = 0x200, - .endpoint[0].bInterval = 0x00, - - /* Endpoint descriptor structure EP1 OUT */ - .endpoint[1].bLength = 7, - .endpoint[1].bDescriptorType = USB_DESCRIPTOR_ENDPOINT, - .endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT. - .endpoint[1].bmAttributes = USB_EP_TYPE_BULK, - .endpoint[1].wMaxPacketSize = 0x200, - .endpoint[1].bInterval = 0x00 -}; - -static usb_cfg_simple_descr_t usb_other_speed_config_descriptor_ums = -{ - /* Other Speed Configuration descriptor structure */ - .config.bLength = 9, - .config.bDescriptorType = USB_DESCRIPTOR_OTHER_SPEED_CONFIGURATION, - .config.wTotalLength = 0x20, - .config.bNumInterfaces = 0x01, - .config.bConfigurationValue = 0x01, - .config.iConfiguration = 0x00, - .config.bmAttributes = USB_ATTR_SELF_POWERED | USB_ATTR_BUS_POWERED_RSVD, - .config.bMaxPower = 32 / 2, - - /* Interface descriptor structure */ - .interface.bLength = 9, - .interface.bDescriptorType = USB_DESCRIPTOR_INTERFACE, - .interface.bInterfaceNumber = 0x00, - .interface.bAlternateSetting = 0x00, - .interface.bNumEndpoints = 2, - .interface.bInterfaceClass = 0x08, // Mass Storage Class. - .interface.bInterfaceSubClass = 0x06, // SCSI Transparent Command Set. - .interface.bInterfaceProtocol = 0x50, // Bulk-Only Transport. - .interface.iInterface = 0x00, - - /* Endpoint descriptor structure EP1 IN */ - .endpoint[0].bLength = 7, - .endpoint[0].bDescriptorType = USB_DESCRIPTOR_ENDPOINT, - .endpoint[0].bEndpointAddress = 0x81, // USB_EP_ADDR_BULK_IN. - .endpoint[0].bmAttributes = USB_EP_TYPE_BULK, - .endpoint[0].wMaxPacketSize = 0x40, - .endpoint[0].bInterval = 0, - - /* Endpoint descriptor structure EP1 OUT */ - .endpoint[1].bLength = 7, - .endpoint[1].bDescriptorType = USB_DESCRIPTOR_ENDPOINT, - .endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT. - .endpoint[1].bmAttributes = USB_EP_TYPE_BULK, - .endpoint[1].wMaxPacketSize = 0x40, - .endpoint[1].bInterval = 0 -}; - -static usb_dev_bot_t usb_device_binary_object_descriptor = -{ - .bLength = 5, - .bDescriptorType = USB_DESCRIPTOR_DEVICE_BINARY_OBJECT, - .wTotalLength = 22, - .bNumDeviceCaps = 2, - - /* Device Capability USB 2.0 Extension Descriptor */ - .bLengthCap0 = 7, - .bDescriptorTypeCap0 = USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP, - .bDevCapabilityTypeCap0 = 2, // USB2. - .bmAttributesCap0 = 0, - - /* Device Capability SuperSpeed Descriptor */ - /* Needed for a USB2.10 device. */ - .bLengthCap1 = 10, - .bDescriptorTypeCap1 = USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP, - .bDevCapabilityTypeCap1 = 3, // USB3. - .bmAttributesCap1 = 0, - .wSpeedsSupported = 0x6, // FS | HS. - .bFunctionalitySupport = 1, // FS and above. - .bU1DevExitLat = 0, - .wU2DevExitLat = 0 -}; - -static u8 usb_lang_id_string_descriptor[4] = -{ - 4, 3, - 0x09, 0x04 -}; - -static u8 usb_serial_string_descriptor[26] = -{ - 26, 0x03, - 'C', 0x00, '7', 0x00, 'C', 0x00, '0', 0x00, - '9', 0x00, '2', 0x00, '4', 0x00, '2', 0x00, 'F', 0x00, '7', 0x00, '0', 0x00, '3', 0x00 -}; - -static u8 usb_vendor_string_descriptor_ums[32] = -{ - 26, 0x03, - 'N', 0, 'y', 0, 'x', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0, ' ', 0, - 'D', 0, 'i', 0, 's', 0, 'k', 0 -}; - -static u8 usb_product_string_descriptor_ums[22] = -{ - 8, 0x03, - 'U', 0, 'M', 0, 'S', 0 -}; - -static usb_ms_os_descr_t usb_ms_os_descriptor = -{ - .bLength = 0x28, - .bDescriptorType = 0x03, - .wSignature[0] = 'M', - .wSignature[1] = 'S', - .wSignature[2] = 'F', - .wSignature[3] = 'T', - .wSignature[4] = '1', - .wSignature[5] = '0', - .wSignature[6] = '0', - .bVendorCode = 0x99, -}; - -static usb_ms_cid_descr_t usb_ms_cid_descriptor = -{ - .dLength = 0x28, - .wVersion = 0x100, - .wCompatibilityId = USB_DESCRIPTOR_MS_COMPAT_ID, - .bSections = 1, - .bInterfaceNumber = 0, - .bReserved1 = 1, - - .bCompatibleId[0] = 'N', - .bCompatibleId[1] = 'Y', - .bCompatibleId[2] = 'X', - .bCompatibleId[3] = 'U', - .bCompatibleId[4] = 'S', - .bCompatibleId[5] = 'B', -}; - -static usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_ums = -{ - .dLength = 0x48, - .wVersion = 0x100, - .wExtendedProperty = USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES, - .wSections = 1, - - .dPropertySize = 0x3E, - .dPropertyType = 4, // DWORD - - .wPropertyNameLength = 0x2C, - .wPropertyName[0] = 'M', // MaximumTransferLength. - .wPropertyName[1] = 'a', - .wPropertyName[2] = 'x', - .wPropertyName[3] = 'i', - .wPropertyName[4] = 'm', - .wPropertyName[5] = 'u', - .wPropertyName[6] = 'm', - .wPropertyName[7] = 'T', - .wPropertyName[8] = 'r', - .wPropertyName[9] = 'a', - .wPropertyName[10] = 'n', - .wPropertyName[11] = 's', - .wPropertyName[12] = 'f', - .wPropertyName[13] = 'e', - .wPropertyName[14] = 'r', - .wPropertyName[15] = 'L', - .wPropertyName[16] = 'e', - .wPropertyName[17] = 'n', - .wPropertyName[18] = 'g', - .wPropertyName[19] = 't', - .wPropertyName[20] = 'h', - .wPropertyName[21] = 0, - - .dPropertyDataLength = 0x4, - .wPropertyData[0] = 0x00, // 1MB. - .wPropertyData[1] = 0x10, -}; - -static usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_hid = -{ - .dLength = 7, - .wVersion = 0x100, - .wExtendedProperty = USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES, - .wSections = 0, -}; - -static usb_dev_descr_t usb_device_descriptor_hid_jc = -{ - .bLength = 18, - .bDescriptorType = USB_DESCRIPTOR_DEVICE, - .bcdUSB = 0x210, - .bDeviceClass = 0x00, - .bDeviceSubClass = 0x00, - .bDeviceProtocol = 0x00, - .bMaxPacketSize = 0x40, - .idVendor = 0x11EC, // Nintendo: 0x057E, Nvidia: 0x0955 - .idProduct = 0xA7E1, // Switch: 0x2000, usbd: 0x3000 - .bcdDevice = 0x0101, - .iManufacturer = 1, - .iProduct = 2, - .iSerialNumber = 3, - .bNumConfigs = 1 -}; - -static usb_dev_descr_t usb_device_descriptor_hid_touch = -{ - .bLength = 18, - .bDescriptorType = USB_DESCRIPTOR_DEVICE, - .bcdUSB = 0x210, - .bDeviceClass = 0x00, - .bDeviceSubClass = 0x00, - .bDeviceProtocol = 0x00, - .bMaxPacketSize = 0x40, - .idVendor = 0x11EC, // Nintendo: 0x057E, Nvidia: 0x0955 - .idProduct = 0xA7E2, // Switch: 0x2000, usbd: 0x3000 - .bcdDevice = 0x0101, - .iManufacturer = 1, - .iProduct = 2, - .iSerialNumber = 3, - .bNumConfigs = 1 -}; - -u8 hid_report_descriptor_jc[] = -{ - 0x05, 0x01, // USAGE_PAGE (Generic Desktop), - 0x09, 0x04, // USAGE (Joystick), - 0xa1, 0x01, // COLLECTION (Application), - 0xa1, 0x02, // COLLECTION (Logical), - 0x75, 0x08, // REPORT_SIZE (8), - 0x95, 0x04, // REPORT_COUNT (4), - 0x15, 0x00, // LOGICAL_MINIMUM (0), - 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255), - 0x35, 0x00, // PHYSICAL_MINIMUM (0), - 0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255), - 0x09, 0x30, // USAGE (X_ID), - 0x09, 0x31, // USAGE (Y_ID), - 0x09, 0x32, // USAGE (Z_ID), - 0x09, 0x35, // USAGE (Rz_ID), - 0x81, 0x02, // INPUT (IOF_Variable), - 0x75, 0x04, // REPORT_SIZE (4), - 0x95, 0x01, // REPORT_COUNT (1), - 0x25, 0x07, // LOGICAL_MAXIMUM (7), - 0x46, 0x3b, 0x01, // PHYSICAL_MAXIMUM (315), - 0x65, 0x14, // UNIT (Eng_Rot_Angular_Pos), - 0x09, 0x39, // USAGE (Hat_Switch), - 0x81, 0x42, // INPUT (IOF_NullposVar), - 0x65, 0x00, // UNIT (Unit_None), - 0x75, 0x01, // REPORT_SIZE (1), - 0x95, 0x0c, // REPORT_COUNT (12), - 0x25, 0x01, // LOGICAL_MAXIMUM (1), - 0x45, 0x01, // PHYSICAL_MAXIMUM (1), - 0x05, 0x09, // USAGE_PAGE (Button_ID), - 0x19, 0x01, // USAGE_MINIMUM (1), - 0x29, 0x0c, // USAGE_MAXIMUM (12), - 0x81, 0x02, // INPUT (IOF_Variable), - 0xc0, // END_COLLECTION(), - 0xc0 // END_COLLECTION(), -}; - -u32 hid_report_descriptor_jc_size = sizeof(hid_report_descriptor_jc); - -u8 hid_report_descriptor_touch[] = -{ - 0x05, 0x0d, // USAGE_PAGE (Digitizers) - 0x09, 0x05, // USAGE (Touch Pad) - 0xa1, 0x01, // COLLECTION (Application) - 0x85, 0x05, // REPORT_ID (Touch pad) - 0x09, 0x22, // USAGE (Finger) - 0xa1, 0x02, // COLLECTION (Logical) - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x09, 0x42, // USAGE (Tip switch) - 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x01, // REPORT_SIZE (1) - 0x81, 0x02, // INPUT (Data,Var,Abs) - - 0x15, 0x00, // LOGICAL_MINIMUM (1) - 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x75, 0x01, // REPORT_SIZE (1) - 0x95, 0x07, // REPORT_COUNT (7) - 0x09, 0x54, // USAGE (Contact Count) - 0x81, 0x02, // INPUT (Data,Var,Abs) - - 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x08, // REPORT_SIZE (8) - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0x0A, // LOGICAL_MAXIMUM (10) - 0x09, 0x51, // USAGE (Contact Identifier) - 0x81, 0x02, // INPUT (Data,Var,Abs) - - // 0x15, 0x00, // LOGICAL_MINIMUM (0) - // 0x26, 0xF8, 0x2A, // LOGICAL_MAXIMUM (11000) - // 0x95, 0x01, // REPORT_COUNT (1) - // 0x75, 0x08, // REPORT_SIZE (16) - // 0x09, 0x30, // USAGE (Pressure) - // 0x81, 0x02, // INPUT (Data,Var,Abs) - - 0x05, 0x01, // USAGE_PAGE (Generic Desk.. - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x26, 0xff, 0x04, // LOGICAL_MAXIMUM (1279) - 0x75, 0x10, // REPORT_SIZE (16) - 0x55, 0x0e, // UNIT_EXPONENT (-2) - 0x65, 0x13, // UNIT(Inch,EngLinear) - 0x09, 0x30, // USAGE (X) - 0x35, 0x00, // PHYSICAL_MINIMUM (0) - 0x46, 0xFF, 0x04, // PHYSICAL_MAXIMUM (1279) - 0x95, 0x01, // REPORT_COUNT (1) - 0x81, 0x02, // INPUT (Data,Var,Abs) - 0x26, 0xCF, 0x02, // LOGICAL_MAXIMUM (719) - 0x46, 0xCF, 0x02, // PHYSICAL_MAXIMUM (719) - 0x09, 0x31, // USAGE (Y) - 0x81, 0x02, // INPUT (Data,Var,Abs) - - 0x05, 0x0d, // USAGE PAGE (Digitizers) - 0xc0, // END_COLLECTION - 0xc0, // END_COLLECTION -}; -u32 hid_report_descriptor_touch_size = sizeof(hid_report_descriptor_touch); - -static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_jc = -{ - /* Configuration descriptor structure */ - .config.bLength = 9, - .config.bDescriptorType = USB_DESCRIPTOR_CONFIGURATION, - .config.wTotalLength = sizeof(usb_cfg_hid_descr_t), - .config.bNumInterfaces = 0x01, - .config.bConfigurationValue = 0x01, - .config.iConfiguration = 0x00, - .config.bmAttributes = USB_ATTR_SELF_POWERED | USB_ATTR_BUS_POWERED_RSVD, - .config.bMaxPower = 32 / 2, - - /* Interface descriptor structure */ - .interface.bLength = 9, - .interface.bDescriptorType = USB_DESCRIPTOR_INTERFACE, - .interface.bInterfaceNumber = 0, - .interface.bAlternateSetting = 0, - .interface.bNumEndpoints = 2, - .interface.bInterfaceClass = 0x03, // Human Interface Device Class. - .interface.bInterfaceSubClass = 0x00, // SCSI Transparent Command Set. - .interface.bInterfaceProtocol = 0x00, // Bulk-Only Transport. - .interface.iInterface = 0x00, - - .hid.bLength = 9, - .hid.bDescriptorType = USB_DESCRIPTOR_HID, - .hid.bcdHID = 0x110, - .hid.bCountryCode = 0, - .hid.bNumDescriptors = 1, - .hid.bClassDescriptorType = USB_DESCRIPTOR_HID_REPORT, - .hid.bDescriptorLength = sizeof(hid_report_descriptor_jc), - - /* Endpoint descriptor structure EP1 IN */ - .endpoint[0].bLength = 7, - .endpoint[0].bDescriptorType = USB_DESCRIPTOR_ENDPOINT, - .endpoint[0].bEndpointAddress = 0x81, // USB_EP_ADDR_BULK_IN. - .endpoint[0].bmAttributes = USB_EP_TYPE_INTR, - .endpoint[0].wMaxPacketSize = 0x200, - .endpoint[0].bInterval = 4, // 8ms on HS. - - /* Endpoint descriptor structure EP1 OUT */ - .endpoint[1].bLength = 7, - .endpoint[1].bDescriptorType = USB_DESCRIPTOR_ENDPOINT, - .endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT. - .endpoint[1].bmAttributes = USB_EP_TYPE_INTR, - .endpoint[1].wMaxPacketSize = 0x200, - .endpoint[1].bInterval = 4 // 8ms on HS. -}; - -static u8 usb_vendor_string_descriptor_hid[22] = -{ - 16, 0x03, - 'N', 0, 'y', 0, 'x', 0, ' ', 0, - 'U', 0, 'S', 0, 'B', 0 -}; - -static u8 usb_product_string_descriptor_hid_jc[24] = -{ - 24, 0x03, - 'N', 0, 'y', 0, 'x', 0, ' ', 0, - 'J', 0, 'o', 0, 'y', 0, '-', 0, 'C', 0, 'o', 0, 'n', 0 -}; - -static u8 usb_product_string_descriptor_hid_touch[26] = -{ - 26, 0x03, - 'N', 0, 'y', 0, 'x', 0, ' ', 0, - 'T', 0, 'o', 0, 'u', 0, 'c', 0, 'h', 0, 'p', 0, 'a', 0, 'd', 0 -}; - -static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_touch = -{ - /* Configuration descriptor structure */ - .config.bLength = 9, - .config.bDescriptorType = USB_DESCRIPTOR_CONFIGURATION, - .config.wTotalLength = sizeof(usb_cfg_hid_descr_t), - .config.bNumInterfaces = 0x01, - .config.bConfigurationValue = 0x01, - .config.iConfiguration = 0x00, - .config.bmAttributes = USB_ATTR_SELF_POWERED | USB_ATTR_BUS_POWERED_RSVD, - .config.bMaxPower = 32 / 2, - - /* Interface descriptor structure */ - .interface.bLength = 9, - .interface.bDescriptorType = USB_DESCRIPTOR_INTERFACE, - .interface.bInterfaceNumber = 0, - .interface.bAlternateSetting = 0, - .interface.bNumEndpoints = 2, - .interface.bInterfaceClass = 0x03, // Human Interface Device Class. - .interface.bInterfaceSubClass = 0x00, // SCSI Transparent Command Set. - .interface.bInterfaceProtocol = 0x00, // Bulk-Only Transport. - .interface.iInterface = 0x00, - - .hid.bLength = 9, - .hid.bDescriptorType = USB_DESCRIPTOR_HID, - .hid.bcdHID = 0x111, - .hid.bCountryCode = 0, - .hid.bNumDescriptors = 1, - .hid.bClassDescriptorType = USB_DESCRIPTOR_HID_REPORT, - .hid.bDescriptorLength = sizeof(hid_report_descriptor_touch), - - /* Endpoint descriptor structure EP1 IN */ - .endpoint[0].bLength = 7, - .endpoint[0].bDescriptorType = USB_DESCRIPTOR_ENDPOINT, - .endpoint[0].bEndpointAddress = 0x81, // USB_EP_ADDR_BULK_IN. - .endpoint[0].bmAttributes = USB_EP_TYPE_INTR, - .endpoint[0].wMaxPacketSize = 0x200, - .endpoint[0].bInterval = 3, // 4ms on HS. - - /* Endpoint descriptor structure EP1 OUT */ - .endpoint[1].bLength = 7, - .endpoint[1].bDescriptorType = USB_DESCRIPTOR_ENDPOINT, - .endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT. - .endpoint[1].bmAttributes = USB_EP_TYPE_INTR, - .endpoint[1].wMaxPacketSize = 0x200, - .endpoint[1].bInterval = 3 // 4ms on HS. -}; - -usb_desc_t usb_gadget_ums_descriptors = -{ - .dev = &usb_device_descriptor_ums, - .dev_qual = &usb_device_qualifier_descriptor, - .cfg = &usb_configuration_descriptor_ums, - .cfg_other = &usb_other_speed_config_descriptor_ums, - .dev_bot = &usb_device_binary_object_descriptor, - .vendor = usb_vendor_string_descriptor_ums, - .product = usb_product_string_descriptor_ums, - .serial = usb_serial_string_descriptor, - .lang_id = usb_lang_id_string_descriptor, - .ms_os = &usb_ms_os_descriptor, - .ms_cid = &usb_ms_cid_descriptor, - .mx_ext = &usb_ms_ext_prop_descriptor_ums -}; - -usb_desc_t usb_gadget_hid_jc_descriptors = -{ - .dev = &usb_device_descriptor_hid_jc, - .dev_qual = &usb_device_qualifier_descriptor, - .cfg = (usb_cfg_simple_descr_t *)&usb_configuration_descriptor_hid_jc, - .cfg_other = NULL, - .dev_bot = &usb_device_binary_object_descriptor, - .vendor = usb_vendor_string_descriptor_hid, - .product = usb_product_string_descriptor_hid_jc, - .serial = usb_serial_string_descriptor, - .lang_id = usb_lang_id_string_descriptor, - .ms_os = &usb_ms_os_descriptor, - .ms_cid = &usb_ms_cid_descriptor, - .mx_ext = &usb_ms_ext_prop_descriptor_hid -}; - -usb_desc_t usb_gadget_hid_touch_descriptors = -{ - .dev = &usb_device_descriptor_hid_touch, - .dev_qual = &usb_device_qualifier_descriptor, - .cfg = (usb_cfg_simple_descr_t *)&usb_configuration_descriptor_hid_touch, - .cfg_other = NULL, - .dev_bot = &usb_device_binary_object_descriptor, - .vendor = usb_vendor_string_descriptor_hid, - .product = usb_product_string_descriptor_hid_touch, - .serial = usb_serial_string_descriptor, - .lang_id = usb_lang_id_string_descriptor, - .ms_os = &usb_ms_os_descriptor, - .ms_cid = &usb_ms_cid_descriptor, - .mx_ext = &usb_ms_ext_prop_descriptor_hid -}; diff --git a/bdk/usb/usb_gadget_hid.c b/bdk/usb/usb_gadget_hid.c deleted file mode 100644 index b7c2e24..0000000 --- a/bdk/usb/usb_gadget_hid.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * USB Gadget HID driver for Tegra X1 - * - * Copyright (c) 2019-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 . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -//#define DPRINTF(...) gfx_printf(__VA_ARGS__) -#define DPRINTF(...) - -typedef struct _gamepad_report_t -{ - u8 x; - u8 y; - u8 z; - u8 rz; - - u8 hat:4; - u8 btn1:1; - u8 btn2:1; - u8 btn3:1; - u8 btn4:1; - - u8 btn5:1; - u8 btn6:1; - u8 btn7:1; - u8 btn8:1; - u8 btn9:1; - u8 btn10:1; - u8 btn11:1; - u8 btn12:1; -} __attribute__((packed)) gamepad_report_t; - -typedef struct _jc_cal_t -{ - bool cl_done; - bool cr_done; - u16 clx_max; - u16 clx_min; - u16 cly_max; - u16 cly_min; - u16 crx_max; - u16 crx_min; - u16 cry_max; - u16 cry_min; -} jc_cal_t; - -static jc_cal_t jc_cal_ctx; -static usb_ops_t usb_ops; - -static bool _jc_calibration(jc_gamepad_rpt_t *jc_pad) -{ - // Calibrate left stick. - if (!jc_cal_ctx.cl_done) - { - if (jc_pad->conn_l - && jc_pad->lstick_x > 0x400 && jc_pad->lstick_y > 0x400 - && jc_pad->lstick_x < 0xC00 && jc_pad->lstick_y < 0xC00) - { - jc_cal_ctx.clx_max = jc_pad->lstick_x + 0x72; - jc_cal_ctx.clx_min = jc_pad->lstick_x - 0x72; - jc_cal_ctx.cly_max = jc_pad->lstick_y + 0x72; - jc_cal_ctx.cly_min = jc_pad->lstick_y - 0x72; - jc_cal_ctx.cl_done = true; - } - else - return false; - } - - // Calibrate right stick. - if (!jc_cal_ctx.cr_done) - { - if (jc_pad->conn_r - && jc_pad->rstick_x > 0x400 && jc_pad->rstick_y > 0x400 - && jc_pad->rstick_x < 0xC00 && jc_pad->rstick_y < 0xC00) - { - jc_cal_ctx.crx_max = jc_pad->rstick_x + 0x72; - jc_cal_ctx.crx_min = jc_pad->rstick_x - 0x72; - jc_cal_ctx.cry_max = jc_pad->rstick_y + 0x72; - jc_cal_ctx.cry_min = jc_pad->rstick_y - 0x72; - jc_cal_ctx.cr_done = true; - } - else - return false; - } - - return true; -} - -static bool _jc_poll(gamepad_report_t *rpt) -{ - // Poll Joy-Con. - jc_gamepad_rpt_t *jc_pad = joycon_poll(); - - if (!jc_pad) - return false; - - // Exit emulation if Left stick and Home are pressed. - if (jc_pad->l3 && jc_pad->home) - return true; - - if (!jc_cal_ctx.cl_done || !jc_cal_ctx.cr_done) - { - if (!_jc_calibration(jc_pad)) - return false; - } - - // Re-calibrate on disconnection. - if (!jc_pad->conn_l) - jc_cal_ctx.cl_done = false; - if (!jc_pad->conn_r) - jc_cal_ctx.cr_done = false; - - // Calculate left analog stick. - if (jc_pad->lstick_x <= jc_cal_ctx.clx_max && jc_pad->lstick_x >= jc_cal_ctx.clx_min) - rpt->x = 0x7F; - else if (jc_pad->lstick_x > jc_cal_ctx.clx_max) - { - u16 x_raw = (jc_pad->lstick_x - jc_cal_ctx.clx_max) / 7; - if (x_raw > 0x7F) - x_raw = 0x7F; - rpt->x = 0x7F + x_raw; - } - else - { - u16 x_raw = (jc_cal_ctx.clx_min - jc_pad->lstick_x) / 7; - if (x_raw > 0x7F) - x_raw = 0x7F; - rpt->x = 0x7F - x_raw; - } - - if (jc_pad->lstick_y <= jc_cal_ctx.cly_max && jc_pad->lstick_y >= jc_cal_ctx.cly_min) - rpt->y = 0x7F; - else if (jc_pad->lstick_y > jc_cal_ctx.cly_max) - { - u16 y_raw = (jc_pad->lstick_y - jc_cal_ctx.cly_max) / 7; - if (y_raw > 0x7F) - y_raw = 0x7F; - rpt->y = 0x7F - y_raw; - } - else - { - u16 y_raw = (jc_cal_ctx.cly_min - jc_pad->lstick_y) / 7; - if (y_raw > 0x7F) - y_raw = 0x7F; - rpt->y = 0x7F + y_raw; - } - - // Calculate right analog stick. - if (jc_pad->rstick_x <= jc_cal_ctx.crx_max && jc_pad->rstick_x >= jc_cal_ctx.crx_min) - rpt->z = 0x7F; - else if (jc_pad->rstick_x > jc_cal_ctx.crx_max) - { - u16 x_raw = (jc_pad->rstick_x - jc_cal_ctx.crx_max) / 7; - if (x_raw > 0x7F) - x_raw = 0x7F; - rpt->z = 0x7F + x_raw; - } - else - { - u16 x_raw = (jc_cal_ctx.crx_min - jc_pad->rstick_x) / 7; - if (x_raw > 0x7F) - x_raw = 0x7F; - rpt->z = 0x7F - x_raw; - } - - if (jc_pad->rstick_y <= jc_cal_ctx.cry_max && jc_pad->rstick_y >= jc_cal_ctx.cry_min) - rpt->rz = 0x7F; - else if (jc_pad->rstick_y > jc_cal_ctx.cry_max) - { - u16 y_raw = (jc_pad->rstick_y - jc_cal_ctx.cry_max) / 7; - if (y_raw > 0x7F) - y_raw = 0x7F; - rpt->rz = 0x7F - y_raw; - } - else - { - u16 y_raw = (jc_cal_ctx.cry_min - jc_pad->rstick_y) / 7; - if (y_raw > 0x7F) - y_raw = 0x7F; - rpt->rz = 0x7F + y_raw; - } - - // Set D-pad. - switch ((jc_pad->buttons >> 16) & 0xF) - { - case 0: // none - rpt->hat = 0xF; - break; - case 1: // down - rpt->hat = 4; - break; - case 2: // up - rpt->hat = 0; - break; - case 4: // right - rpt->hat = 2; - break; - case 5: // down + right - rpt->hat = 3; - break; - case 6: // up + right - rpt->hat = 1; - break; - case 8: // left - rpt->hat = 6; - break; - case 9: // down + left - rpt->hat = 5; - break; - case 10: // up + left - rpt->hat = 7; - break; - default: - rpt->hat = 0xF; - break; - } - - // Set buttons. - rpt->btn1 = jc_pad->b; // x. - rpt->btn2 = jc_pad->a; // a. - rpt->btn3 = jc_pad->y; // b. - rpt->btn4 = jc_pad->x; // y. - - rpt->btn5 = jc_pad->l; - rpt->btn6 = jc_pad->r; - rpt->btn7 = jc_pad->zl; - rpt->btn8 = jc_pad->zr; - rpt->btn9 = jc_pad->minus; - rpt->btn10 = jc_pad->plus; - rpt->btn11 = jc_pad->l3; - rpt->btn12 = jc_pad->r3; - - //rpt->btn13 = jc_pad->cap; - //rpt->btn14 = jc_pad->home; - - return false; -} - -typedef struct _touchpad_report_t -{ - u8 rpt_id; - u8 tip_switch:1; - u8 count:7; - - u8 id; - - //u16 z; - u16 x; - u16 y; -} __attribute__((packed)) touchpad_report_t; - -static bool _fts_touch_read(touchpad_report_t *rpt) -{ - static touch_event touchpad; - - touch_poll(&touchpad); - - rpt->rpt_id = 5; - rpt->count = 1; - - // Decide touch enable. - switch (touchpad.type & STMFTS_MASK_EVENT_ID) - { - //case STMFTS_EV_MULTI_TOUCH_ENTER: - case STMFTS_EV_MULTI_TOUCH_MOTION: - rpt->x = touchpad.x; - rpt->y = touchpad.y; - //rpt->z = touchpad.z; - rpt->id = touchpad.fingers ? touchpad.fingers - 1 : 0; - rpt->tip_switch = 1; - break; - case STMFTS_EV_MULTI_TOUCH_LEAVE: - rpt->x = touchpad.x; - rpt->y = touchpad.y; - //rpt->z = touchpad.z; - rpt->id = touchpad.fingers ? touchpad.fingers - 1 : 0; - rpt->tip_switch = 0; - break; - case STMFTS_EV_NO_EVENT: - return false; - } - - return true; -} - -static u8 _hid_transfer_start(usb_ctxt_t *usbs, u32 len) -{ - u8 status = usb_ops.usb_device_ep1_in_write((u8 *)USB_EP_BULK_IN_BUF_ADDR, len, NULL, USB_XFER_SYNCED_CMD); - if (status == USB_ERROR_XFER_ERROR) - { - usbs->set_text(usbs->label, "#FFDD00 Error:# EP IN transfer!"); - if (usb_ops.usbd_flush_endpoint) - usb_ops.usbd_flush_endpoint(USB_EP_BULK_IN); - } - - // Linux mitigation: If timed out, clear status. - if (status == USB_ERROR_TIMEOUT) - return 0; - - return status; -} - -static bool _hid_poll_jc(usb_ctxt_t *usbs) -{ - if (_jc_poll((gamepad_report_t *)USB_EP_BULK_IN_BUF_ADDR)) - return true; - - // Send HID report. - if (_hid_transfer_start(usbs, sizeof(gamepad_report_t))) - return true; // EP Error. - - return false; -} - -static bool _hid_poll_touch(usb_ctxt_t *usbs) -{ - _fts_touch_read((touchpad_report_t *)USB_EP_BULK_IN_BUF_ADDR); - - // Send HID report. - if (_hid_transfer_start(usbs, sizeof(touchpad_report_t))) - return true; // EP Error. - - return false; -} - -int usb_device_gadget_hid(usb_ctxt_t *usbs) -{ - int res = 0; - u32 gadget_type; - u32 polling_time; - - // Get USB Controller ops. - if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210) - usb_device_get_ops(&usb_ops); - else - xusb_device_get_ops(&usb_ops); - - if (usbs->type == USB_HID_GAMEPAD) - { - polling_time = 8000; - gadget_type = USB_GADGET_HID_GAMEPAD; - } - else - { - polling_time = 4000; - gadget_type = USB_GADGET_HID_TOUCHPAD; - } - - usbs->set_text(usbs->label, "#C7EA46 Status:# Started USB"); - - if (usb_ops.usb_device_init()) - { - usb_ops.usbd_end(false, true); - return 1; - } - - usbs->set_text(usbs->label, "#C7EA46 Status:# Waiting for connection"); - - // Initialize Control Endpoint. - if (usb_ops.usb_device_enumerate(gadget_type)) - goto error; - - usbs->set_text(usbs->label, "#C7EA46 Status:# Waiting for HID report request"); - - if (usb_ops.usb_device_class_send_hid_report()) - goto error; - - usbs->set_text(usbs->label, "#C7EA46 Status:# Started HID emulation"); - - u32 timer_sys = get_tmr_ms() + 5000; - while (true) - { - u32 timer = get_tmr_us(); - - // Parse input device. - if (usbs->type == USB_HID_GAMEPAD) - { - if (_hid_poll_jc(usbs)) - break; - } - else - { - if (_hid_poll_touch(usbs)) - break; - } - - // Check for suspended USB in case the cable was pulled. - if (usb_ops.usb_device_get_suspended()) - break; // Disconnected. - - // Handle control endpoint. - usb_ops.usbd_handle_ep0_ctrl_setup(); - - // Wait max gadget timing. - timer = get_tmr_us() - timer; - if (timer < polling_time) - usleep(polling_time - timer); - - if (timer_sys < get_tmr_ms()) - { - usbs->system_maintenance(true); - timer_sys = get_tmr_ms() + 5000; - } - } - - usbs->set_text(usbs->label, "#C7EA46 Status:# HID ended"); - goto exit; - -error: - usbs->set_text(usbs->label, "#FFDD00 Error:# Timed out or canceled"); - res = 1; - -exit: - usb_ops.usbd_end(true, false); - - return res; -} diff --git a/bdk/usb/usb_gadget_ums.c b/bdk/usb/usb_gadget_ums.c deleted file mode 100644 index 10bd56a..0000000 --- a/bdk/usb/usb_gadget_ums.c +++ /dev/null @@ -1,1926 +0,0 @@ -/* - * USB Gadget UMS driver for Tegra X1 - * - * Copyright (c) 2003-2008 Alan Stern - * Copyright (c) 2009 Samsung Electronics - * Author: Michal Nazarewicz - * Copyright (c) 2019-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 . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -//#define DPRINTF(...) gfx_printf(__VA_ARGS__) -#define DPRINTF(...) - -#define UMS_MAX_LUN 1 // Only 1 disk/partition for now. - -#define USB_BULK_CB_WRAP_LEN 31 -#define USB_BULK_CB_SIG 0x43425355 // USBC. -#define USB_BULK_IN_FLAG 0x80 - -#define USB_BULK_CS_WRAP_LEN 13 -#define USB_BULK_CS_SIG 0x53425355 // USBS. - -#define USB_STATUS_PASS 0 -#define USB_STATUS_FAIL 1 -#define USB_STATUS_PHASE_ERROR 2 - -#define UMS_DISK_LBA_SHIFT 9 -#define UMS_DISK_LBA_SIZE (1 << UMS_DISK_LBA_SHIFT) - -#define UMS_DISK_MAX_IO_TRANSFER_64K (USB_EP_BUFFER_MAX_SIZE >> UMS_DISK_LBA_SHIFT) -#define UMS_DISK_MAX_IO_TRANSFER_32K (UMS_DISK_MAX_IO_TRANSFER_64K / 2) - -#define UMS_SCSI_TRANSFER_512K (0x80000 >> UMS_DISK_LBA_SHIFT) - -#define UMS_EP_OUT_MAX_XFER (USB_EP_BULK_OUT_MAX_XFER) - -// Length of a SCSI Command Data Block. -#define SCSI_MAX_CMD_SZ 16 - -// SCSI device types -#define SCSI_TYPE_DISK 0x00 - -// SCSI commands. -#define SC_FORMAT_UNIT 0x04 -#define SC_INQUIRY 0x12 -#define SC_LOG_SENSE 0x4D -#define SC_MODE_SELECT_6 0x15 -#define SC_MODE_SELECT_10 0x55 -#define SC_MODE_SENSE_6 0x1A -#define SC_MODE_SENSE_10 0x5A -#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E -#define SC_READ_6 0x08 -#define SC_READ_10 0x28 -#define SC_READ_12 0xA8 -#define SC_READ_CAPACITY 0x25 -#define SC_READ_FORMAT_CAPACITIES 0x23 -#define SC_READ_HEADER 0x44 -#define SC_READ_TOC 0x43 -#define SC_RELEASE 0x17 -#define SC_REQUEST_SENSE 0x03 -#define SC_RESERVE 0x16 -#define SC_SEND_DIAGNOSTIC 0x1D -#define SC_START_STOP_UNIT 0x1B -#define SC_SYNCHRONIZE_CACHE 0x35 -#define SC_TEST_UNIT_READY 0x00 -#define SC_VERIFY 0x2F -#define SC_WRITE_6 0x0A -#define SC_WRITE_10 0x2A -#define SC_WRITE_12 0xAA - -// SCSI Sense Key/Additional Sense Code/ASC Qualifier values. -#define SS_NO_SENSE 0x0 -#define SS_COMMUNICATION_FAILURE 0x40800 -#define SS_INVALID_COMMAND 0x52000 -#define SS_INVALID_FIELD_IN_CDB 0x52400 -#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x52100 -#define SS_MEDIUM_NOT_PRESENT 0x23A00 -#define SS_MEDIUM_REMOVAL_PREVENTED 0x55302 -#define SS_NOT_READY_TO_READY_TRANSITION 0x62800 -#define SS_RESET_OCCURRED 0x62900 -#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x53900 -#define SS_UNRECOVERED_READ_ERROR 0x31100 -#define SS_WRITE_ERROR 0x30C02 -#define SS_WRITE_PROTECTED 0x72700 - -#define SK(x) ((u8) ((x) >> 16)) /* Sense Key byte, etc. */ -#define ASC(x) ((u8) ((x) >> 8)) -#define ASCQ(x) ((u8) (x)) - -enum ums_state { - UMS_STATE_NORMAL = 0, - UMS_STATE_ABORT_BULK_OUT, - UMS_STATE_PROTOCOL_RESET, - UMS_STATE_EXIT, - UMS_STATE_TERMINATED -}; - -enum ums_result { - UMS_RES_OK = 0, - UMS_RES_IO_ERROR = -5, - UMS_RES_TIMEOUT = -3, - UMS_RES_PROT_FATAL = -4, - UMS_RES_INVALID_ARG = -22 -}; - - -enum data_direction { - DATA_DIR_UNKNOWN = 0, - DATA_DIR_FROM_HOST, - DATA_DIR_TO_HOST, - DATA_DIR_NONE -}; - -enum buffer_state { - BUF_STATE_EMPTY = 0, - BUF_STATE_FULL, - BUF_STATE_BUSY -}; - -typedef struct _bulk_recv_pkt_t { - u32 Signature; // 'USBC'. - u32 Tag; // Unique per command id. - u32 DataTransferLength; // Size of the data. - u8 Flags; // Direction in bit 7. - u8 Lun; // LUN (normally 0). - u8 Length; // Of the CDB, <= SCSI_MAX_CMD_SZ. - u8 CDB[16]; // Command Data Block. -} bulk_recv_pkt_t; - -typedef struct _bulk_send_pkt_t { - u32 Signature; // 'USBS'. - u32 Tag; // Same as original command. - u32 Residue; // Amount not transferred. - u8 Status; -} bulk_send_pkt_t; - -typedef struct _logical_unit_t -{ - sdmmc_t *sdmmc; - sdmmc_storage_t *storage; - - u32 num_sectors; - u32 offset; - - int unmounted; - - u32 ro; - u32 type; - u32 partition; - u32 removable; - u32 prevent_medium_removal; - - u32 info_valid; - - u32 sense_data; - u32 sense_data_info; - u32 unit_attention_data; -} logical_unit_t; - -typedef struct _bulk_ctxt_t { - u32 bulk_in; - int bulk_in_status; - u32 bulk_in_length; - u32 bulk_in_length_actual; - u8 *bulk_in_buf; - enum buffer_state bulk_in_buf_state; - - u32 bulk_out; - int bulk_out_status; - u32 bulk_out_length; - u32 bulk_out_length_actual; - int bulk_out_ignore; - u8 *bulk_out_buf; - enum buffer_state bulk_out_buf_state; -} bulk_ctxt_t; - -typedef struct _usbd_gadget_ums_t { - bulk_ctxt_t bulk_ctxt; - - u32 cmnd_size; - u8 cmnd[SCSI_MAX_CMD_SZ]; - - u32 lun_idx; // lun index - logical_unit_t lun; - - enum ums_state state; // For exception handling. - - enum data_direction data_dir; - u32 data_size; - u32 data_size_from_cmnd; - u32 tag; - u32 residue; - u32 usb_amount_left; - - u32 phase_error; - u32 short_packet_received; - - int thread_wakeup_needed; - int can_stall; - - u32 timeouts; - bool xusb; - - void (*system_maintenance)(bool); - void *label; - void (*set_text)(void *, const char *); -} usbd_gadget_ums_t; - -static usb_ops_t usb_ops; - -static inline void put_array_le_to_be16(u16 val, void *p) -{ - u8 *_p = p; - _p[0] = val >> 8; - _p[1] = val; -} - -static inline void put_array_le_to_be32(u32 val, void *p) -{ - u8 *_p = p; - _p[0] = val >> 24; - _p[1] = val >> 16; - _p[2] = val >> 8; - _p[3] = val; -} - -static inline u16 get_array_be_to_le16(const void *p) -{ - const u8 *_p = p; - u16 val = _p[0] << 8 | _p[1]; - return val; -} - -static inline u32 get_array_be_to_le24(const void *p) -{ - const u8 *_p = p; - u32 val = (_p[0] << 16) | (_p[1] << 8) | _p[2]; - return val; -} - -static inline u32 get_array_be_to_le32(const void *p) -{ - const u8 *_p = p; - u32 val = (_p[0] << 24) | (_p[1] << 16) | (_p[2] << 8) | _p[3]; - return val; -} - -static void raise_exception(usbd_gadget_ums_t *ums, enum ums_state new_state) -{ - /* Do nothing if a higher-priority exception is already in progress. - * If a lower-or-equal priority exception is in progress, preempt it - * and notify the main thread by sending it a signal. */ - if (ums->state <= new_state) { - ums->state = new_state; - ums->thread_wakeup_needed = 1; - } -} - -static void ums_handle_ep0_ctrl(usbd_gadget_ums_t *ums) -{ - if (usb_ops.usbd_handle_ep0_ctrl_setup()) - raise_exception(ums, UMS_STATE_PROTOCOL_RESET); -} - -static int ums_wedge_bulk_in_endpoint(usbd_gadget_ums_t *ums) -{ - /* usbd_set_ep_wedge(bulk_ctxt->bulk_in); */ - - return UMS_RES_OK; -} - -static int ums_set_stall(u32 ep) -{ - usb_ops.usbd_set_ep_stall(ep, USB_EP_CFG_STALL); - - return UMS_RES_OK; -} - -static int ums_clear_stall(u32 ep) -{ - usb_ops.usbd_set_ep_stall(ep, USB_EP_CFG_CLEAR); - - return UMS_RES_OK; -} - -static void ums_flush_endpoint(u32 ep) -{ - if (usb_ops.usbd_flush_endpoint) - usb_ops.usbd_flush_endpoint(ep); -} - -static void _ums_transfer_start(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_write( - bulk_ctxt->bulk_in_buf, bulk_ctxt->bulk_in_length, - &bulk_ctxt->bulk_in_length_actual, sync_timeout); - - if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR) - { - ums->set_text(ums->label, "#FFDD00 Error:# EP IN transfer!"); - ums_flush_endpoint(bulk_ctxt->bulk_in); - } - else if (bulk_ctxt->bulk_in_status == USB2_ERROR_XFER_NOT_ALIGNED) - ums->set_text(ums->label, "#FFDD00 Error:# EP IN Buffer not aligned!"); - - if (sync_timeout) - bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY; - } - else - { - bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_read( - bulk_ctxt->bulk_out_buf, bulk_ctxt->bulk_out_length, - &bulk_ctxt->bulk_out_length_actual, sync_timeout); - - if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR) - { - ums->set_text(ums->label, "#FFDD00 Error:# EP OUT transfer!"); - ums_flush_endpoint(bulk_ctxt->bulk_out); - } - else if (bulk_ctxt->bulk_out_status == USB2_ERROR_XFER_NOT_ALIGNED) - ums->set_text(ums->label, "#FFDD00 Error:# EP OUT Buffer not aligned!"); - - if (sync_timeout) - bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL; - } -} - -static void _ums_transfer_out_big_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_read_big( - bulk_ctxt->bulk_out_buf, bulk_ctxt->bulk_out_length, - &bulk_ctxt->bulk_out_length_actual); - - if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR) - { - ums->set_text(ums->label, "#FFDD00 Error:# EP OUT transfer!"); - ums_flush_endpoint(bulk_ctxt->bulk_out); - } - - 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) -{ - 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); - - if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR) - { - ums->set_text(ums->label, "#FFDD00 Error:# EP IN transfer!"); - ums_flush_endpoint(bulk_ctxt->bulk_in); - } - - bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY; - } - else - { - bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_reading_finish( - &bulk_ctxt->bulk_out_length_actual); - - if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR) - { - ums->set_text(ums->label, "#FFDD00 Error:# EP OUT transfer!"); - ums_flush_endpoint(bulk_ctxt->bulk_out); - } - - bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL; - } -} - -static void _ums_reset_buffer(bulk_ctxt_t *bulk_ctxt, u32 ep) -{ - if (ep == bulk_ctxt->bulk_in) - bulk_ctxt->bulk_in_buf = (u8 *)USB_EP_BULK_IN_BUF_ADDR; - else - bulk_ctxt->bulk_out_buf = (u8 *)USB_EP_BULK_OUT_BUF_ADDR; -} - -/* - * The following are old data based on max 64KB SCSI transfers. - * The endpoint xfer is actually 41.2 MB/s and SD card max 39.2 MB/s, with higher SCSI - * transfers, but the concurrency still helps and increases speeds by 20%. - * - * Concurrency of the SDMMC and USB xfers is very important with no cache. - * The worst offender being the SD card. We are already limited by bus, so - * concurrency helps minimize the SDMMC overhead. - * Max achieved bulk endpoint rate on a Tegra X1 and USB2.0 is 39.4 MB/s. - * - * USB bulk endpoint raw max transfer rate: - * 39.4MB/S - SCSI 128KB. - * 38.2MB/s - SCSI 64KB. - * - * 128 KB, 64 KB, 32 KB, 16 KB, 8 KB - Internal SDMMC I\O Sizes - * ------------------------------------------------------------------------------------- - * eMMC - Toshiba - 4MB reads: 314.8 MB/s: - * 225.9 MB/s, 168.6 MB/s, 114.7 MB/s, 86.4 MB/s, 50.3 MB/s - RAW SDMMC. - * 33.5 MB/s, 31.9 MB/s, 29.3 MB/s, 27.1 MB/s, 22.1 MB/s - SCSI 128KB, No concurrency. - * 33.5 MB/s, 35.3 MB/s, 36.3 MB/s, 37.3 MB/s, 37.8 MB/s - SCSI 128KB, Concurrency. - * --.- --/-, 31.1 MB/s, 28.7 MB/s, 26.5 MB/s, 21.7 MB/s - SCSI 64KB, No concurrency. - * --.- --/-, 31.1 MB/s, 32.7 MB/s, 34.4 MB/s, 35.0 MB/s - SCSI 64KB, Concurrency. - * - * SD Card - Samsung Evo+ 128GB - 4MB reads: 91.6 MB/s: - * 72.6 MB/s, 62.8 MB/s, 47.4 MB/s, 31.1 MB/s, 18.5 MB/s - RAW SDMMC. - * 25.5 MB/s, 24.2 MB/s, 21.5 MB/s, 17.4 MB/s, 12.6 MB/s - SCSI 128KB, No concurrency. - * 25.5 MB/s, 30.0 MB/s, 32.6 MB/s, 28.3 MB/s, 18.0 MB/s - SCSI 128KB, Concurrency. - * --.- --/-, 23.8 MB/s, 21.2 MB/s, 17.1 MB/s, 12.5 MB/s - SCSI 64KB, No concurrency. - * --.- --/-, 23.8 MB/s, 27.2 MB/s, 25.8 MB/s, 17.5 MB/s - SCSI 64KB, Concurrency. - */ - -static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - u32 lba_offset; - bool first_read = true; - u8 *sdmmc_buf = (u8 *)SDXC_BUF_ALIGNED; - - // Get the starting LBA and check that it's not too big. - if (ums->cmnd[0] == SC_READ_6) - lba_offset = get_array_be_to_le24(&ums->cmnd[1]); - else - { - lba_offset = get_array_be_to_le32(&ums->cmnd[2]); - - // We allow DPO and FUA bypass cache bits, but we don't use them. - if ((ums->cmnd[1] & ~0x18) != 0) - { - ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB; - - return UMS_RES_INVALID_ARG; - } - } - if (lba_offset >= ums->lun.num_sectors) - { - ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - - return UMS_RES_INVALID_ARG; - } - - // Check that request data size is not 0. - u32 amount_left = ums->data_size_from_cmnd >> UMS_DISK_LBA_SHIFT; - if (!amount_left) - return UMS_RES_IO_ERROR; // No default reply. - - // Limit IO transfers based on request for faster concurrent reads. - u32 max_io_transfer = (amount_left >= UMS_SCSI_TRANSFER_512K) ? - UMS_DISK_MAX_IO_TRANSFER_64K : UMS_DISK_MAX_IO_TRANSFER_32K; - - while (true) - { - // Max io size and end sector limits. - u32 amount = MIN(amount_left, max_io_transfer); - amount = MIN(amount, ums->lun.num_sectors - lba_offset); - - // Check if it is a read past the end sector. - if (!amount) - { - ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - ums->lun.sense_data_info = lba_offset; - ums->lun.info_valid = 1; - bulk_ctxt->bulk_in_length = 0; - bulk_ctxt->bulk_in_buf_state = BUF_STATE_FULL; - break; - } - - // Do the SDMMC read. - if (!sdmmc_storage_read(ums->lun.storage, ums->lun.offset + lba_offset, amount, sdmmc_buf)) - amount = 0; - - // Wait for the async USB transfer to finish. - if (!first_read) - _ums_transfer_finish(ums, bulk_ctxt, bulk_ctxt->bulk_in); - - lba_offset += amount; - amount_left -= amount; - ums->residue -= amount << UMS_DISK_LBA_SHIFT; - - bulk_ctxt->bulk_in_length = amount << UMS_DISK_LBA_SHIFT; - bulk_ctxt->bulk_in_buf_state = BUF_STATE_FULL; - bulk_ctxt->bulk_in_buf = sdmmc_buf; - - // If an error occurred, report it and its position. - if (!amount) - { - ums->set_text(ums->label, "#FFDD00 Error:# SDMMC Read!"); - ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR; - ums->lun.sense_data_info = lba_offset; - ums->lun.info_valid = 1; - break; - } - - // Last SDMMC read. Last part will be sent by the finish reply function. - if (!amount_left) - break; - - // Start the USB transfer. - _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_START); - first_read = false; - - // Increment our buffer to read new data. - sdmmc_buf += amount << UMS_DISK_LBA_SHIFT; - } - - return UMS_RES_IO_ERROR; // No default reply. -} - -/* - * Writes are another story. - * Tests showed that big writes are faster than concurrent 32K usb reads + writes. - * The only thing that can help here is caching the writes. But for the simplicity - * of this implementation it will not be implemented yet. - */ - -static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - static char txt_buf[256]; - u32 amount_left_to_req, amount_left_to_write; - u32 usb_lba_offset, lba_offset; - u32 amount; - - if (ums->lun.ro) - { - ums->lun.sense_data = SS_WRITE_PROTECTED; - - return UMS_RES_INVALID_ARG; - } - - if (ums->cmnd[0] == SC_WRITE_6) - lba_offset = get_array_be_to_le24(&ums->cmnd[1]); - else - { - lba_offset = get_array_be_to_le32(&ums->cmnd[2]); - - // We allow DPO and FUA bypass cache bits. We only implement FUA by performing synchronous output. - if (ums->cmnd[1] & ~0x18) - { - ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB; - - return UMS_RES_INVALID_ARG; - } - } - - // Check that starting LBA is not past the end sector offset. - if (lba_offset >= ums->lun.num_sectors) - { - ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - - return UMS_RES_INVALID_ARG; - } - - /* 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 */ - if (amount_left_to_req > 0) - { - - // Limit write to max supported read from EP OUT. - amount = MIN(amount_left_to_req, UMS_EP_OUT_MAX_XFER); - - if (usb_lba_offset >= ums->lun.num_sectors) - { - ums->set_text(ums->label, "#FFDD00 Error:# Write - Past last sector!"); - ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - ums->lun.sense_data_info = usb_lba_offset; - ums->lun.info_valid = 1; - break; - } - - // Get the next buffer. - usb_lba_offset += amount >> UMS_DISK_LBA_SHIFT; - ums->usb_amount_left -= amount; - amount_left_to_req -= amount; - - bulk_ctxt->bulk_out_length = amount; - - _ums_transfer_out_big_read(ums, bulk_ctxt); - } - - if (bulk_ctxt->bulk_out_buf_state == BUF_STATE_FULL) - { - bulk_ctxt->bulk_out_buf_state = BUF_STATE_EMPTY; - - // Did something go wrong with the transfer?. - if (bulk_ctxt->bulk_out_status != 0) - { - ums->lun.sense_data = SS_COMMUNICATION_FAILURE; - ums->lun.sense_data_info = lba_offset; - ums->lun.info_valid = 1; - s_printf(txt_buf, "#FFDD00 Error:# Write - Comm failure %d!", bulk_ctxt->bulk_out_status); - ums->set_text(ums->label, txt_buf); - break; - } - - amount = bulk_ctxt->bulk_out_length_actual; - - if ((ums->lun.num_sectors - lba_offset) < (amount >> UMS_DISK_LBA_SHIFT)) - { - DPRINTF("write %X @ %X beyond end %X\n", amount, lba_offset, ums->lun.num_sectors); - amount = (ums->lun.num_sectors - lba_offset) << UMS_DISK_LBA_SHIFT; - } - - /* - * Don't accept excess data. The spec doesn't say - * what to do in this case. We'll ignore the error. - */ - amount = MIN(amount, bulk_ctxt->bulk_out_length); - - /* Don't write a partial block */ - amount -= (amount & 511); - if (amount == 0) - goto empty_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; - -DPRINTF("file write %X @ %X\n", amount, lba_offset); - - lba_offset += amount >> UMS_DISK_LBA_SHIFT; - amount_left_to_write -= amount; - ums->residue -= amount; - - /* If an error occurred, report it and its position */ - if (!amount) - { - ums->set_text(ums->label, "#FFDD00 Error:# SDMMC Write!"); - ums->lun.sense_data = SS_WRITE_ERROR; - ums->lun.sense_data_info = lba_offset; - ums->lun.info_valid = 1; - break; - } - - empty_write: - // Did the host decide to stop early? - if (bulk_ctxt->bulk_out_length_actual < bulk_ctxt->bulk_out_length) - { - ums->set_text(ums->label, "#FFDD00 Error:# Empty Write!"); - ums->short_packet_received = 1; - break; - } - } - } - - return UMS_RES_IO_ERROR; // No default reply. -} - -static int _scsi_verify(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - // Check that start LBA is past the end sector offset. - u32 lba_offset = get_array_be_to_le32(&ums->cmnd[2]); - if (lba_offset >= ums->lun.num_sectors) - { - ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - - return UMS_RES_INVALID_ARG; - } - - // We allow DPO but we don't implement it. Check that nothing else is enabled. - if (ums->cmnd[1] & ~0x10) - { - ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB; - - return UMS_RES_INVALID_ARG; - } - - u32 verification_length = get_array_be_to_le16(&ums->cmnd[7]); - if (verification_length == 0) - return UMS_RES_IO_ERROR; // No default reply. - - u32 amount; - while (verification_length > 0) - { - - // Limit to EP buffer size and end sector offset. - amount = MIN(verification_length, USB_EP_BUFFER_MAX_SIZE >> UMS_DISK_LBA_SHIFT); - amount = MIN(amount, ums->lun.num_sectors - lba_offset); - if (amount == 0) { - ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - ums->lun.sense_data_info = lba_offset; - ums->lun.info_valid = 1; - break; - } - - if (!sdmmc_storage_read(ums->lun.storage, ums->lun.offset + lba_offset, amount, bulk_ctxt->bulk_in_buf)) - amount = 0; - -DPRINTF("File read %X @ %X\n", amount, lba_offset); - - if (!amount) - { - ums->set_text(ums->label, "#FFDD00 Error:# File verify!"); - ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR; - ums->lun.sense_data_info = lba_offset; - ums->lun.info_valid = 1; - break; - } - lba_offset += amount; - verification_length -= amount; - } - return UMS_RES_OK; -} - -static int _scsi_inquiry(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - u8 *buf = (u8 *)bulk_ctxt->bulk_in_buf; - - memset(buf, 0, 36); - - // Enable Vital Product Data (EVPD) and Unit Serial Number. - if (ums->cmnd[1] == 1 && ums->cmnd[2] == 0x80) - { - buf[0] = 0; - buf[1] = ums->cmnd[2]; - buf[2] = 0; - buf[3] = 20; // Additional length. - - buf += 4; - s_printf((char *)buf, "%04X%s", - ums->lun.storage->cid.serial, ums->lun.type == MMC_SD ? " SD " : " eMMC "); - - switch (ums->lun.partition) - { - case 0: - strcpy((char *)buf + strlen((char *)buf), "RAW"); - break; - case EMMC_GPP + 1: - s_printf((char *)buf + strlen((char *)buf), "GPP"); - break; - case EMMC_BOOT0 + 1: - s_printf((char *)buf + strlen((char *)buf), "BOOT0"); - break; - case EMMC_BOOT1 + 1: - s_printf((char *)buf + strlen((char *)buf), "BOOT1"); - break; - } - - for (u32 i = strlen((char *)buf); i < 20; i++) - buf[i] = ' '; - - return 24; - } - else /* if (ums->cmnd[1] == 0 && ums->cmnd[2] == 0) */ // Standard inquiry. - { - buf[0] = SCSI_TYPE_DISK; - buf[1] = ums->lun.removable ? 0x80 : 0; - buf[2] = 6; // ANSI INCITS 351-2001 (SPC-2).////////SPC2: 4, SPC4: 6 - buf[3] = 2; // SCSI-2 INQUIRY data format. - buf[4] = 31; // Additional length. - // buf5-7: No special options. - - // Vendor ID. Max 8 chars. - buf += 8; - strcpy((char *)buf, "hekate"); - - // Product ID. Max 16 chars. - buf += 8; - switch (ums->lun.partition) - { - case 0: - s_printf((char *)buf, "%s", "SD RAW"); - break; - case EMMC_GPP + 1: - s_printf((char *)buf, "%s%s", - ums->lun.type == MMC_SD ? "SD " : "eMMC ", "GPP"); - break; - case EMMC_BOOT0 + 1: - s_printf((char *)buf, "%s%s", - ums->lun.type == MMC_SD ? "SD " : "eMMC ", "BOOT0"); - break; - case EMMC_BOOT1 + 1: - s_printf((char *)buf, "%s%s", - ums->lun.type == MMC_SD ? "SD " : "eMMC ", "BOOT1"); - break; - } - - // Rev ID. Max 4 chars. - buf += 16; - strcpy((char *)buf, "1.00"); - - return 36; - } -} - -static int _scsi_request_sense(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - u8 *buf = (u8 *)bulk_ctxt->bulk_in_buf; - u32 sd, sdinfo; - int valid; - - sd = ums->lun.sense_data; - sdinfo = ums->lun.sense_data_info; - valid = ums->lun.info_valid << 7; - ums->lun.sense_data = SS_NO_SENSE; - ums->lun.sense_data_info = 0; - ums->lun.info_valid = 0; - - memset(buf, 0, 18); - buf[0] = valid | 0x70; // Valid, current error. - buf[2] = SK(sd); - put_array_le_to_be32(sdinfo, &buf[3]); // Sense information. - buf[7] = 18 - 8; // Additional sense length. - buf[12] = ASC(sd); - buf[13] = ASCQ(sd); - - return 18; -} - -static int _scsi_read_capacity(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - u8 *buf = (u8 *)bulk_ctxt->bulk_in_buf; - u32 lba = get_array_be_to_le32(&ums->cmnd[2]); - int pmi = ums->cmnd[8]; - - // Check the PMI and LBA fields. - if (pmi > 1 || (pmi == 0 && lba != 0)) - { - ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB; - - return UMS_RES_INVALID_ARG; - } - - put_array_le_to_be32(ums->lun.num_sectors - 1, &buf[0]); // Max logical block. - put_array_le_to_be32(UMS_DISK_LBA_SIZE, &buf[4]); // Block length. - - return 8; -} - -static int _scsi_log_sense(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - u8 *buf = (u8 *)bulk_ctxt->bulk_in_buf; - u8 *buf0 = buf; - bool valid_page = false; - - u8 pc = ums->cmnd[2] >> 6; - u8 page_code = ums->cmnd[2] & 0x3F; - u8 sub_page_code = ums->cmnd[3]; - - if (ums->cmnd[1] & 1) - { - ums->lun.sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED; - - return UMS_RES_INVALID_ARG; - } - - if (pc != 1) // Current cumulative values. - { - ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB; - - return UMS_RES_INVALID_ARG; - } - - memset(buf, 0, 8); - if (page_code == 0x00 && !sub_page_code) // Supported pages. - { - valid_page = true; - buf[0] = 0x00; // Page code. - buf += 4; - - buf[0] = 0x00; // Page 0. - buf[1] = 0x0D; // Page 1. - - buf += 2; - } - else if (page_code == 0x0d && !sub_page_code) // Temperature. - { - valid_page = true; - buf[0] = 0x0D; - buf += 4; - - put_array_le_to_be16(0, &buf[0]); // Param code. - buf[2] = 1; // Param control byte. - buf[3] = 2; // Param length. - buf[4] = 0; // Reserved. - buf[5] = 35; // Temperature (C) current (PCB here). - - put_array_le_to_be16(0, &buf[6]); // PARAMETER CODE - buf[8] = 1; // Param control byte. - buf[9] = 2; // Param length. - buf[10] = 0; // Reserved. - buf[11] = 60; // Temperature (C) reference. - - buf += 12; - } - - // Check that a valid page mode data length was requested. - u32 len = buf - buf0; - if (!valid_page) - { - ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB; - - return UMS_RES_INVALID_ARG; - } - - put_array_le_to_be16(len - 4, &buf0[2]); - - return len; -} - -static int _scsi_mode_sense(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - u8 *buf = (u8 *)bulk_ctxt->bulk_in_buf; - u8 *buf0 = buf; - bool valid_page = false; - - u8 pc = ums->cmnd[2] >> 6; - u8 page_code = ums->cmnd[2] & 0x3F; - bool changeable_values = pc == 1; - bool all_pages = page_code == 0x3F; - - if ((ums->cmnd[1] & ~0x08) != 0) // Mask away DBD. - { - ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB; - - return UMS_RES_INVALID_ARG; - } - - if (pc == 3) - { - ums->lun.sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED; - - return UMS_RES_INVALID_ARG; - } - - /* Write the mode parameter header. Fixed values are: default - * medium type, no cache control (DPOFUA), and no block descriptors. - * The only variable value is the WriteProtect bit. We will fill in - * the mode data length later. */ - memset(buf, 0, 8); - if (ums->cmnd[0] == SC_MODE_SENSE_6) - { - buf[2] = (ums->lun.ro ? 0x80 : 0x00); // WP, DPOFUA. - buf += 4; - } - else // SC_MODE_SENSE_10. - { - buf[3] = (ums->lun.ro ? 0x80 : 0x00); // WP, DPOFUA. - buf += 8; - } - - // The only page we support is the Caching page. - // What about x1C - if (page_code == 0x08 || all_pages) - { - valid_page = true; - buf[0] = 0x08; // Page code. - buf[1] = 18; // Page length. - memset(buf + 2, 0, 18); // Set all parameters to 0. - - // None of the fields are changeable. - if (!changeable_values) - { - // Write Cache enable, Read Cache not disabled, Multiplication Factor off. - buf[2] = 0x04; - - // Multiplication Factor is disabled, so all values below are 1x LBA. - put_array_le_to_be16(0xFFFF, &buf[4]); // Disable Prefetch if >32MB. - put_array_le_to_be16(0x0000, &buf[6]); // Minimum Prefetch 0MB. - put_array_le_to_be16(0xFFFF, &buf[8]); // Maximum Prefetch 32MB. - put_array_le_to_be16(0xFFFF, &buf[10]); // Maximum Prefetch ceiling 32MB. - } - - buf += 20; - } - - // Check that a valid page mode data length was requested. - u32 len = buf - buf0; - if (!valid_page) - { - ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB; - - return UMS_RES_INVALID_ARG; - } - - /* Store the mode data length */ - if (ums->cmnd[0] == SC_MODE_SENSE_6) - buf0[0] = len - 1; - else - put_array_le_to_be16(len - 2, buf0); - - return len; -} - -static int _scsi_start_stop(usbd_gadget_ums_t *ums) -{ - int loej, start; - - if (!ums->lun.removable) - { - ums->lun.sense_data = SS_INVALID_COMMAND; - - return UMS_RES_INVALID_ARG; - } - else if ((ums->cmnd[1] & ~0x01) != 0 || // Mask away Immed. - (ums->cmnd[4] & ~0x03) != 0) // Mask LoEj, Start. - { - ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB; - - return UMS_RES_INVALID_ARG; - } - - loej = ums->cmnd[4] & 0x02; - start = ums->cmnd[4] & 0x01; - - // We do not support re-mounting. - if (start) - { - if (ums->lun.unmounted) - { - ums->lun.sense_data = SS_MEDIUM_NOT_PRESENT; - - return UMS_RES_INVALID_ARG; - } - - return UMS_RES_OK; - } - - // Check if we are allowed to unload the media. - if (ums->lun.prevent_medium_removal) - { - ums->set_text(ums->label, "#C7EA46 Status:# Unload attempt prevented"); - ums->lun.sense_data = SS_MEDIUM_REMOVAL_PREVENTED; - - return UMS_RES_INVALID_ARG; - } - - if (!loej) - return UMS_RES_OK; - - // Unmount means we exit UMS because of ejection. - ums->lun.unmounted = 1; - - return UMS_RES_OK; -} - -static int _scsi_prevent_allow_removal(usbd_gadget_ums_t *ums) -{ - int prevent; - - if (!ums->lun.removable) - { - ums->lun.sense_data = SS_INVALID_COMMAND; - - return UMS_RES_INVALID_ARG; - } - - prevent = ums->cmnd[4] & 0x01; - if ((ums->cmnd[4] & ~0x01) != 0) // Mask away Prevent. - { - ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB; - - return UMS_RES_INVALID_ARG; - } - - // Notify for possible unmounting? - // Normally we sync here but we do synced writes to SDMMC. - if (ums->lun.prevent_medium_removal && !prevent) - ; - - ums->lun.prevent_medium_removal = prevent; - - return UMS_RES_OK; -} - -static int _scsi_read_format_capacities(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - u8 *buf = (u8 *)bulk_ctxt->bulk_in_buf; - - buf[0] = buf[1] = buf[2] = 0; - buf[3] = 8; // Only the Current/Maximum Capacity Descriptor. - buf += 4; - - put_array_le_to_be32(ums->lun.num_sectors, &buf[0]); // Number of blocks. - put_array_le_to_be32(UMS_DISK_LBA_SIZE, &buf[4]); // Block length. - buf[4] = 0x02; // Current capacity. - - return 12; -} - -// Check whether the command is properly formed and whether its data size -// and direction agree with the values we already have. -static int _ums_check_scsi_cmd(usbd_gadget_ums_t *ums, u32 cmnd_size, - enum data_direction data_dir, u32 mask, int needs_medium) -{ -//const char dirletter[4] = {'u', 'o', 'i', 'n'}; -DPRINTF("SCSI command: %X; Dc=%d, D%c=%X; Hc=%d, H%c=%X\n", - ums->cmnd[0], cmnd_size, dirletter[(int)ums->data_dir], - ums->data_size_from_cmnd, ums->cmnd_size, - dirletter[(int)data_dir], ums->data_size); - - // We can't reply if we don't know the direction and size. - if (ums->data_size_from_cmnd == 0) - data_dir = DATA_DIR_NONE; - - // This is a phase error but we continue and only transfer as much we can. - if (ums->data_size < ums->data_size_from_cmnd) - { - ums->data_size_from_cmnd = ums->data_size; - ums->phase_error = 1; - } - - ums->residue = ums->data_size; - ums->usb_amount_left = ums->data_size; - - if (ums->data_dir != data_dir && ums->data_size_from_cmnd > 0) - { - ums->phase_error = 1; - - return UMS_RES_INVALID_ARG; - } - - // Cmd length verification. - if (cmnd_size != ums->cmnd_size) - { - - // Special case workaround for Windows and Xbox 360. - if (cmnd_size <= ums->cmnd_size) - cmnd_size = ums->cmnd_size; - else - { - ums->phase_error = 1; - - return UMS_RES_INVALID_ARG; - } - } - - // check that LUN ums->cmnd[1] >> 5 is 0 because of only one. - - if (ums->cmnd[0] != SC_REQUEST_SENSE) - { - ums->lun.sense_data = SS_NO_SENSE; - ums->lun.sense_data_info = 0; - ums->lun.info_valid = 0; - } - - // If a unit attention condition exists, only INQUIRY and REQUEST SENSE - // commands are allowed. - if (ums->lun.unit_attention_data != SS_NO_SENSE && ums->cmnd[0] != SC_INQUIRY && - ums->cmnd[0] != SC_REQUEST_SENSE) - { - ums->lun.sense_data = ums->lun.unit_attention_data; - ums->lun.unit_attention_data = SS_NO_SENSE; - - return UMS_RES_INVALID_ARG; - } - - // Check that only command bytes listed in the mask are set. - ums->cmnd[1] &= 0x1F; // Mask away the LUN. - for (u32 i = 1; i < cmnd_size; ++i) - { - if (ums->cmnd[i] && !(mask & BIT(i))) - { - ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB; - - return UMS_RES_INVALID_ARG; - } - } - - // If the medium isn't mounted and the command needs to access it, return an error. - if (ums->lun.unmounted && needs_medium) - { - ums->lun.sense_data = SS_MEDIUM_NOT_PRESENT; - - return UMS_RES_INVALID_ARG; - } - - return UMS_RES_OK; -} - -static int _ums_parse_scsi_cmd(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - u32 len; - int reply = UMS_RES_INVALID_ARG; - - ums->phase_error = 0; - ums->short_packet_received = 0; - - switch (ums->cmnd[0]) - { - case SC_INQUIRY: - ums->data_size_from_cmnd = ums->cmnd[4]; - u32 mask = (1<<4); - if (ums->cmnd[1] == 1 && ums->cmnd[2] == 0x80) // Inquiry S/N. - mask = (1<<1) | (1<<2) | (1<<4); - reply = _ums_check_scsi_cmd(ums, 6, DATA_DIR_TO_HOST, mask, 0); - if (reply == 0) - reply = _scsi_inquiry(ums, bulk_ctxt); - break; - - case SC_LOG_SENSE: - ums->data_size_from_cmnd = get_array_be_to_le16(&ums->cmnd[7]); - reply = _ums_check_scsi_cmd(ums, 10, DATA_DIR_TO_HOST, (1<<1) | (1<<2) | (3<<7), 0); - if (reply == 0) - reply = _scsi_log_sense(ums, bulk_ctxt); - break; - - case SC_MODE_SELECT_6: - ums->data_size_from_cmnd = ums->cmnd[4]; - reply = _ums_check_scsi_cmd(ums, 6, DATA_DIR_FROM_HOST, (1<<1) | (1<<4), 0); - if (reply == 0) - { - // We don't support MODE SELECT. - ums->lun.sense_data = SS_INVALID_COMMAND; - reply = UMS_RES_INVALID_ARG; - } - break; - - case SC_MODE_SELECT_10: - ums->data_size_from_cmnd = get_array_be_to_le16(&ums->cmnd[7]); - reply = _ums_check_scsi_cmd(ums, 10, DATA_DIR_FROM_HOST, (1<<1) | (3<<7), 0); - if (reply == 0) - { - // We don't support MODE SELECT. - ums->lun.sense_data = SS_INVALID_COMMAND; - reply = UMS_RES_INVALID_ARG; - } - break; - - case SC_MODE_SENSE_6: - ums->data_size_from_cmnd = ums->cmnd[4]; - reply = _ums_check_scsi_cmd(ums, 6, DATA_DIR_TO_HOST, (1<<1) | (1<<2) | (1<<4), 0); - if (reply == 0) - reply = _scsi_mode_sense(ums, bulk_ctxt); - break; - - case SC_MODE_SENSE_10: - ums->data_size_from_cmnd = get_array_be_to_le16(&ums->cmnd[7]); - reply = _ums_check_scsi_cmd(ums, 10, DATA_DIR_TO_HOST, (1<<1) | (1<<2) | (3<<7), 0); - if (reply == 0) - reply = _scsi_mode_sense(ums, bulk_ctxt); - break; - - case SC_PREVENT_ALLOW_MEDIUM_REMOVAL: - ums->data_size_from_cmnd = 0; - reply = _ums_check_scsi_cmd(ums, 6, DATA_DIR_NONE, (1<<4), 0); - if (reply == 0) - reply = _scsi_prevent_allow_removal(ums); - break; - - case SC_READ_6: - len = ums->cmnd[4]; - ums->data_size_from_cmnd = (len == 0 ? 256 : len) << UMS_DISK_LBA_SHIFT; - reply = _ums_check_scsi_cmd(ums, 6, DATA_DIR_TO_HOST, (7<<1) | (1<<4), 1); - if (reply == 0) - reply = _scsi_read(ums, bulk_ctxt); - break; - - case SC_READ_10: - ums->data_size_from_cmnd = get_array_be_to_le16(&ums->cmnd[7]) << UMS_DISK_LBA_SHIFT; - reply = _ums_check_scsi_cmd(ums, 10, DATA_DIR_TO_HOST, (1<<1) | (0xf<<2) | (3<<7), 1); - if (reply == 0) - reply = _scsi_read(ums, bulk_ctxt); - break; - - case SC_READ_12: - ums->data_size_from_cmnd = get_array_be_to_le32(&ums->cmnd[6]) << UMS_DISK_LBA_SHIFT; - reply = _ums_check_scsi_cmd(ums, 12, DATA_DIR_TO_HOST, (1<<1) | (0xf<<2) | (0xf<<6), 1); - if (reply == 0) - reply = _scsi_read(ums, bulk_ctxt); - break; - - case SC_READ_CAPACITY: - ums->data_size_from_cmnd = 8; - reply = _ums_check_scsi_cmd(ums, 10, DATA_DIR_TO_HOST, (0xf<<2) | (1<<8), 1); - if (reply == 0) - reply = _scsi_read_capacity(ums, bulk_ctxt); - break; - case SC_READ_FORMAT_CAPACITIES: - ums->data_size_from_cmnd = get_array_be_to_le16(&ums->cmnd[7]); - reply = _ums_check_scsi_cmd(ums, 10, DATA_DIR_TO_HOST, (3<<7), 1); - if (reply == 0) - reply = _scsi_read_format_capacities(ums, bulk_ctxt); - break; - - case SC_REQUEST_SENSE: - ums->data_size_from_cmnd = ums->cmnd[4]; - reply = _ums_check_scsi_cmd(ums, 6, DATA_DIR_TO_HOST, (1<<4), 0); - if (reply == 0) - reply = _scsi_request_sense(ums, bulk_ctxt); - break; - - case SC_START_STOP_UNIT: - ums->data_size_from_cmnd = 0; - reply = _ums_check_scsi_cmd(ums, 6, DATA_DIR_NONE, (1<<1) | (1<<4), 0); - if (reply == 0) - reply = _scsi_start_stop(ums); - break; - - case SC_SYNCHRONIZE_CACHE: - ums->data_size_from_cmnd = 0; - reply = _ums_check_scsi_cmd(ums, 10, DATA_DIR_NONE, (0xf<<2) | (3<<7), 1); - if (reply == 0) - reply = 0; // Don't bother - break; - - case SC_TEST_UNIT_READY: - ums->data_size_from_cmnd = 0; - reply = _ums_check_scsi_cmd(ums, 6, DATA_DIR_NONE, 0, 1); - break; - - // This command is used by Windows. We support a minimal version and BytChk must be 0. - case SC_VERIFY: - ums->data_size_from_cmnd = 0; - reply = _ums_check_scsi_cmd(ums, 10, DATA_DIR_NONE, (1<<1) | (0xf<<2) | (3<<7), 1); - if (reply == 0) - reply = _scsi_verify(ums, bulk_ctxt); - break; - - case SC_WRITE_6: - len = ums->cmnd[4]; - ums->data_size_from_cmnd = (len == 0 ? 256 : len) << UMS_DISK_LBA_SHIFT; - reply = _ums_check_scsi_cmd(ums, 6, DATA_DIR_FROM_HOST, (7<<1) | (1<<4), 1); - if (reply == 0) - reply = _scsi_write(ums, bulk_ctxt); - break; - - case SC_WRITE_10: - ums->data_size_from_cmnd = get_array_be_to_le16(&ums->cmnd[7]) << UMS_DISK_LBA_SHIFT; - reply = _ums_check_scsi_cmd(ums, 10, DATA_DIR_FROM_HOST, (1<<1) | (0xf<<2) | (3<<7), 1); - if (reply == 0) - reply = _scsi_write(ums, bulk_ctxt); - break; - - case SC_WRITE_12: - ums->data_size_from_cmnd = get_array_be_to_le32(&ums->cmnd[6]) << UMS_DISK_LBA_SHIFT; - reply = _ums_check_scsi_cmd(ums, 12, DATA_DIR_FROM_HOST, (1<<1) | (0xf<<2) | (0xf<<6), 1); - if (reply == 0) - reply = _scsi_write(ums, bulk_ctxt); - break; - - // Mandatory commands that we don't implement. No need. - case SC_READ_HEADER: - case SC_READ_TOC: - case SC_FORMAT_UNIT: - case SC_RELEASE: - case SC_RESERVE: - case SC_SEND_DIAGNOSTIC: - default: - ums->data_size_from_cmnd = 0; - reply = _ums_check_scsi_cmd(ums, ums->cmnd_size, DATA_DIR_UNKNOWN, 0xFF, 0); - if (reply == 0) - { - ums->lun.sense_data = SS_INVALID_COMMAND; - reply = UMS_RES_INVALID_ARG; - } - break; - } - - if (reply == UMS_RES_INVALID_ARG) - reply = 0; // Error reply length. - - // Set up reply buffer for finish_reply(). Otherwise it's already set. - if (reply >= 0 && ums->data_dir == DATA_DIR_TO_HOST) - { - reply = MIN((u32)reply, ums->data_size_from_cmnd); - bulk_ctxt->bulk_in_length = reply; - bulk_ctxt->bulk_in_buf_state = BUF_STATE_FULL; - ums->residue -= reply; - } - - return UMS_RES_OK; -} - -static int pad_with_zeros(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY; // For the first iteration. - u32 current_len_to_keep = bulk_ctxt->bulk_in_length; - ums->usb_amount_left = current_len_to_keep + ums->residue; - - while (ums->usb_amount_left > 0) - { - u32 nsend = MIN(ums->usb_amount_left, USB_EP_BUFFER_MAX_SIZE); - memset(bulk_ctxt->bulk_in_buf + current_len_to_keep, 0, nsend - current_len_to_keep); - bulk_ctxt->bulk_in_length = nsend; - _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED_DATA); - ums->usb_amount_left -= nsend; - current_len_to_keep = 0; - } - - return UMS_RES_OK; -} - -static int throw_away_data(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - if (bulk_ctxt->bulk_out_buf_state != BUF_STATE_EMPTY || ums->usb_amount_left > 0) - { - // Try to submit another request if we need one. - if (bulk_ctxt->bulk_out_buf_state == BUF_STATE_EMPTY && ums->usb_amount_left > 0) - { - u32 amount = MIN(ums->usb_amount_left, USB_EP_BUFFER_MAX_SIZE); - - bulk_ctxt->bulk_out_length = amount; - _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_DATA); - ums->usb_amount_left -= amount; - - return UMS_RES_OK; - } - - // Throw away the data in a filled buffer. - if (bulk_ctxt->bulk_out_buf_state == BUF_STATE_FULL) - bulk_ctxt->bulk_out_buf_state = BUF_STATE_EMPTY; - - // A short packet or an error ends everything. - if (bulk_ctxt->bulk_out_length_actual != bulk_ctxt->bulk_out_length || - bulk_ctxt->bulk_out_status != USB_RES_OK) - { - raise_exception(ums, UMS_STATE_ABORT_BULK_OUT); - return UMS_RES_PROT_FATAL; - } - } - return UMS_RES_OK; -} - -static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - int rc = UMS_RES_OK; - - switch (ums->data_dir) { - case DATA_DIR_NONE: - break; // Nothing to send. - - // If this is a CB or CBI with an unknown command, we mustn't - // try to send or receive any data. Stall if we can and wait reset. - case DATA_DIR_UNKNOWN: - if (ums->can_stall) - { - ums_set_stall(bulk_ctxt->bulk_out); - rc = ums_set_stall(bulk_ctxt->bulk_in); - ums->set_text(ums->label, "#FFDD00 Error:# Direction unknown. Stalled both EP!"); - } // Else do nothing. - break; - - // All but the last buffer of data have already been sent. - case DATA_DIR_TO_HOST: - if (ums->data_size) - { - // If there's no residue, simply send the last buffer. - if (!ums->residue) - { - _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED_DATA); - - /* For Bulk-only, if we're allowed to stall then send the - * short packet and halt the bulk-in endpoint. If we can't - * stall, pad out the remaining data with 0's. */ - } - else if (ums->can_stall) - { - _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED_DATA); - rc = ums_set_stall(bulk_ctxt->bulk_in); - ums->set_text(ums->label, "#FFDD00 Error:# Residue. Stalled EP IN!"); - } - else - rc = pad_with_zeros(ums, bulk_ctxt); - } - - // In case we used SDMMC transfer, reset the buffer address. - _ums_reset_buffer(bulk_ctxt, bulk_ctxt->bulk_in); - break; - - // We have processed all we want from the data the host has sent. - // There may still be outstanding bulk-out requests. - case DATA_DIR_FROM_HOST: - if (ums->residue) - { - if (ums->short_packet_received) // Did the host stop sending unexpectedly early? - { - raise_exception(ums, UMS_STATE_ABORT_BULK_OUT); - rc = UMS_RES_PROT_FATAL; - } - else // We can't stall. Read in the excess data and throw it away. - rc = throw_away_data(ums, bulk_ctxt); - } - - break; - } - - return rc; -} - -/* - * Medium ejection heuristics. - * - * Windows: - * Uses Start/Stop Unit. Only Stop with LoEj. Observed ONLY on very specific windows machines. - * Uses Prevent/Allow Medium Removal. (For big reads and ANY write.) //////Except trivial writes. Needs check with prefetch ON - * Sends Test Unit Ready every 1s at idle. (Needs 1 EP Timeout protection: 2s) - * Does not send data when ejects. In the case it does, - * it loops into Request Sense and Test Unit Ready when ejects. - * Line always at SE0 and only goes in J-State when it ejects. - * - * Linux: - * Uses Start/Stop Unit. Stops with LoEj when Media prevention is off. - * Uses Prevent/Allow Medium Removal. (For big read and any write.) - * Sends Test Unit Ready every 2s at idle. (Needs 2 EP Timeouts protection: 4s) - * Loops into Request Sense and Test Unit Ready when ejects. - * Line always at SE0. - * - * Mac OS: - * Uses Start/Stop. Stops with LoEj when Allow Medium Removal is enabled. - * Uses Prevent/Allow Medium Removal. (Properly. Enables at mount and only disables it when ejects.) - * Does not send Test Unit Ready at idle. But Prevent Medium Removal is enabled. - * Loops into Request Sense and Test Unit Ready when ejects. - * Line always at SE0. - */ - -static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - /* 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"); - // 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 || - (bulk_ctxt->bulk_out_status == USB_ERROR_TIMEOUT && ums->lun.removable && !ums->lun.prevent_medium_removal)) - { - if (bulk_ctxt->bulk_out_status == USB_ERROR_TIMEOUT) - { - if (usb_ops.usb_device_get_port_in_sleep()) - { - ums->set_text(ums->label, "#C7EA46 Status:# EP in sleep"); - ums->timeouts += 14; - } - else if (!ums->xusb) // Timeout only on USB2. - { - ums->timeouts += 4; - DPRINTF("USB: EP removable\n"); - } - } - else - { - gfx_printf("USB: EP disabled\n"); - msleep(500); - ums->timeouts += 4; - } - } - - if (ums->lun.unmounted) - { - ums->set_text(ums->label, "#C7EA46 Status:# Medium unmounted"); - ums->timeouts++; - } - - if (ums->timeouts > 20) - raise_exception(ums, UMS_STATE_EXIT); - } - - if (bulk_ctxt->bulk_out_status || bulk_ctxt->bulk_out_ignore) - return UMS_RES_INVALID_ARG; - } - - /* 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. - ums_wedge_bulk_in_endpoint(ums); - bulk_ctxt->bulk_out_ignore = 1; - return UMS_RES_INVALID_ARG; - } - - /* 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) - { - gfx_printf("USB: non-meaningful CBW: lun = %X, flags = 0x%X, cmdlen %X\n", - cbw->Lun, cbw->Flags, cbw->Length); - - /* We can do anything we want here, so let's stall the - * bulk pipes if we are allowed to. */ - if (ums->can_stall) - { - ums_set_stall(bulk_ctxt->bulk_out); - ums_set_stall(bulk_ctxt->bulk_in); - ums->set_text(ums->label, "#FFDD00 Error:# CBW unknown - Stalled both EP!"); - } - - return UMS_RES_INVALID_ARG; - } - - /* Save the command for later */ - ums->cmnd_size = cbw->Length; - memcpy(ums->cmnd, cbw->CDB, ums->cmnd_size); - - if (cbw->Flags & USB_BULK_IN_FLAG) - ums->data_dir = DATA_DIR_TO_HOST; - else - ums->data_dir = DATA_DIR_FROM_HOST; - - ums->data_size = cbw->DataTransferLength; - - if (ums->data_size == 0) - ums->data_dir = DATA_DIR_NONE; - - ums->lun_idx = cbw->Lun; - ums->tag = cbw->Tag; - - if (!ums->lun.unmounted) - ums->timeouts = 0; - - return UMS_RES_OK; -} - -static int get_next_command(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - int rc = UMS_RES_OK; - - /* Wait for the next buffer to become available */ - // while (bulk_ctxt->bulk_out_buf_state != BUF_STATE_EMPTY) - // { - // //wait irq. - // } - - 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); - - /* We will drain the buffer in software, which means we - * can reuse it for the next filling. No need to advance - * next_buffhd_to_fill. */ - - /* Wait for the CBW to arrive */ - // while (bulk_ctxt->bulk_out_buf_state != BUF_STATE_FULL) - // { - // //wait irq. - // } - - rc = received_cbw(ums, bulk_ctxt); - bulk_ctxt->bulk_out_buf_state = BUF_STATE_EMPTY; - - return rc; -} - -static void send_status(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) -{ - u8 status = USB_STATUS_PASS; - u32 sd = ums->lun.sense_data; - - if (ums->phase_error) - { - ums->set_text(ums->label, "#FFDD00 Error:# Phase-error!"); - status = USB_STATUS_PHASE_ERROR; - sd = SS_INVALID_COMMAND; - } - else if (sd != SS_NO_SENSE) - { - DPRINTF("USB: CMD fail\n"); - status = USB_STATUS_FAIL; - DPRINTF("USB: Sense: SK x%02X, ASC x%02X, ASCQ x%02X; info x%X\n", - SK(sd), ASC(sd), ASCQ(sd), ums->lun.sense_data_info); - } - - /* 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; - csw->Tag = ums->tag; - csw->Residue = ums->residue; - csw->Status = status; - - bulk_ctxt->bulk_in_length = USB_BULK_CS_WRAP_LEN; - _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED_CMD); -} - -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 */ - ums_flush_endpoint(bulk_ctxt->bulk_in); - ums_flush_endpoint(bulk_ctxt->bulk_out); - - /* Reset the I/O buffer states and pointers, the SCSI - * state, and the exception. Then invoke the handler. */ - - bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY; - bulk_ctxt->bulk_out_buf_state = BUF_STATE_EMPTY; - - old_state = ums->state; - - if (old_state != UMS_STATE_ABORT_BULK_OUT) - { - ums->lun.prevent_medium_removal = 0; - ums->lun.sense_data = SS_NO_SENSE; - ums->lun.unit_attention_data = SS_NO_SENSE; - ums->lun.sense_data_info = 0; - ums->lun.info_valid = 0; - } - - ums->state = UMS_STATE_NORMAL; - - /* Carry out any extra actions required for the exception */ - switch (old_state) - { - case UMS_STATE_NORMAL: - break; - case UMS_STATE_ABORT_BULK_OUT: - send_status(ums, bulk_ctxt); - break; - - case UMS_STATE_PROTOCOL_RESET: - /* In case we were forced against our will to halt a - * bulk endpoint, clear the halt now. (The SuperH UDC - * requires this.) */ - if (bulk_ctxt->bulk_out_ignore) - { - bulk_ctxt->bulk_out_ignore = 0; - ums_clear_stall(bulk_ctxt->bulk_in); - } - ums->lun.unit_attention_data = SS_RESET_OCCURRED; - break; - - case UMS_STATE_EXIT: - ums->state = UMS_STATE_TERMINATED; /* Stop the thread */ - break; - - default: - break; - } -} - -static inline void _system_maintainance(usbd_gadget_ums_t *ums) -{ - static u32 timer_dram = 0; - static u32 timer_status_bar = 0; - - u32 time = get_tmr_ms(); - - if (timer_status_bar < time) - { - ums->system_maintenance(true); - timer_status_bar = get_tmr_ms() + 30000; - } - else if (timer_dram < time) - { - minerva_periodic_training(); - timer_dram = get_tmr_ms() + EMC_PERIODIC_TRAIN_MS; - } -} - -int usb_device_gadget_ums(usb_ctxt_t *usbs) -{ - int res = 0; - sdmmc_t sdmmc; - sdmmc_storage_t storage; - usbd_gadget_ums_t ums = {0}; - - // Get USB Controller ops. - if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210) - usb_device_get_ops(&usb_ops); - else - { - ums.xusb = true; - xusb_device_get_ops(&usb_ops); - } - - usbs->set_text(usbs->label, "#C7EA46 Status:# Started USB"); - - if (usb_ops.usb_device_init()) - { - usb_ops.usbd_end(false, true); - return 1; - } - - ums.state = UMS_STATE_NORMAL; - ums.can_stall = 0; - - ums.bulk_ctxt.bulk_in = USB_EP_BULK_IN; - ums.bulk_ctxt.bulk_in_buf = (u8 *)USB_EP_BULK_IN_BUF_ADDR; - - ums.bulk_ctxt.bulk_out = USB_EP_BULK_OUT; - ums.bulk_ctxt.bulk_out_buf = (u8 *)USB_EP_BULK_OUT_BUF_ADDR; - - // Set LUN parameters. - ums.lun.ro = usbs->ro; - ums.lun.type = usbs->type; - ums.lun.partition = usbs->partition; - ums.lun.offset = usbs->offset; - ums.lun.removable = 1; // Always removable to force OSes to use prevent media removal. - ums.lun.unit_attention_data = SS_RESET_OCCURRED; - - // Set system functions - ums.label = usbs->label; - ums.set_text = usbs->set_text; - ums.system_maintenance = usbs->system_maintenance; - - ums.set_text(ums.label, "#C7EA46 Status:# Mounting disk"); - - // Initialize sdmmc. - if (usbs->type == MMC_SD) - { - sd_end(); - sd_mount(); - sd_unmount(); - ums.lun.sdmmc = &sd_sdmmc; - ums.lun.storage = &sd_storage; - } - else - { - ums.lun.sdmmc = &sdmmc; - ums.lun.storage = &storage; - sdmmc_storage_init_mmc(ums.lun.storage, ums.lun.sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400); - sdmmc_storage_set_mmc_partition(ums.lun.storage, ums.lun.partition - 1); - } - - ums.set_text(ums.label, "#C7EA46 Status:# Waiting for connection"); - - // Initialize Control Endpoint. - if (usb_ops.usb_device_enumerate(USB_GADGET_UMS)) - goto error; - - ums.set_text(ums.label, "#C7EA46 Status:# Waiting for LUN"); - - if (usb_ops.usb_device_class_send_max_lun(0)) // One device for now. - goto error; - - ums.set_text(ums.label, "#C7EA46 Status:# Started UMS"); - - if (usbs->sectors) - ums.lun.num_sectors = usbs->sectors; - else - ums.lun.num_sectors = ums.lun.storage->sec_cnt; - - do - { - // Do DRAM training and update system tasks. - _system_maintainance(&ums); - - // Check for force unmount button combo. - if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) - { - // Check if we are allowed to unload the media. - if (ums.lun.prevent_medium_removal) - ums.set_text(ums.label, "#C7EA46 Status:# Unload attempt prevented"); - else - break; - } - - if (ums.state != UMS_STATE_NORMAL) - { - handle_exception(&ums, &ums.bulk_ctxt); - continue; - } - - ums_handle_ep0_ctrl(&ums); - - if (get_next_command(&ums, &ums.bulk_ctxt) || (ums.state > UMS_STATE_NORMAL)) - continue; - - ums_handle_ep0_ctrl(&ums); - - if (_ums_parse_scsi_cmd(&ums, &ums.bulk_ctxt) || (ums.state > UMS_STATE_NORMAL)) - continue; - - ums_handle_ep0_ctrl(&ums); - - if (finish_reply(&ums, &ums.bulk_ctxt) || (ums.state > UMS_STATE_NORMAL)) - continue; - - send_status(&ums, &ums.bulk_ctxt); - } while (ums.state != UMS_STATE_TERMINATED); - - if (ums.lun.prevent_medium_removal) - ums.set_text(ums.label, "#FFDD00 Error:# Disk unsafely ejected"); - else - ums.set_text(ums.label, "#C7EA46 Status:# Disk ejected"); - goto exit; - -error: - ums.set_text(ums.label, "#FFDD00 Error:# Timed out or canceled!"); - res = 1; - -exit: - if (ums.lun.type == MMC_EMMC) - sdmmc_storage_end(ums.lun.storage); - - usb_ops.usbd_end(true, false); - - return res; -} diff --git a/bdk/usb/usb_t210.h b/bdk/usb/usb_t210.h deleted file mode 100644 index e677a5f..0000000 --- a/bdk/usb/usb_t210.h +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Enhanced & eXtensible USB device (EDCI & XDCI) driver for Tegra X1 - * - * Copyright (c) 2019-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 _USB_T210_H_ -#define _USB_T210_H_ - -#include - -/* EHCI USB */ - -/* General USB registers */ -#define USB1_IF_USB_SUSP_CTRL 0x400 -#define SUSP_CTRL_USB_WAKE_ON_CNNT_EN_DEV BIT(3) -#define SUSP_CTRL_USB_WAKE_ON_DISCON_EN_DEV BIT(4) -#define SUSP_CTRL_USB_PHY_CLK_VALID BIT(7) -#define SUSP_CTRL_UTMIP_RESET BIT(11) -#define SUSP_CTRL_UTMIP_PHY_ENB BIT(12) -#define SUSP_CTRL_UTMIP_UTMIP_SUSPL1_SET BIT(25) -#define USB1_IF_USB_PHY_VBUS_SENSORS 0x404 -#define USB1_UTMIP_XCVR_CFG0 0x808 -#define USB1_UTMIP_BIAS_CFG0 0x80C -#define USB1_UTMIP_HSRX_CFG0 0x810 -#define USB1_UTMIP_HSRX_CFG1 0x814 -#define USB1_UTMIP_TX_CFG0 0x820 -#define USB1_UTMIP_MISC_CFG1 0x828 -#define USB1_UTMIP_DEBOUNCE_CFG0 0x82C -#define USB1_UTMIP_BAT_CHRG_CFG0 0x830 -#define BAT_CHRG_CFG0_PWRDOWN_CHRG BIT(0) -#define BAT_CHRG_CFG0_OP_SRC_EN BIT(3) -#define USB1_UTMIP_SPARE_CFG0 0x834 -#define USB1_UTMIP_XCVR_CFG1 0x838 -#define USB1_UTMIP_BIAS_CFG1 0x83C -#define USB1_UTMIP_BIAS_CFG2 0x850 -#define USB1_UTMIP_XCVR_CFG2 0x854 -#define USB1_UTMIP_XCVR_CFG3 0x858 - -/* USB Queue Head Descriptor */ -#define USB2_QH_USB2D_QH_EP_BASE (USB_BASE + 0x1000) -#define USB_QHD_EP_CAP_IOS_ENABLE BIT(15) -#define USB_QHD_EP_CAP_MAX_PKT_LEN_MASK 0x7FF -#define USB_QHD_EP_CAP_ZERO_LEN_TERM_DIS BIT(29) -#define USB_QHD_EP_CAP_MULTI_NON_ISO (0 << 30) -#define USB_QHD_EP_CAP_MULTI_1 (1 << 30) -#define USB_QHD_EP_CAP_MULTI_2 (2 << 30) -#define USB_QHD_EP_CAP_MULTI_3 (3 << 30) - -#define USB_QHD_TOKEN_XFER_ERROR BIT(3) -#define USB_QHD_TOKEN_BUFFER_ERROR BIT(5) -#define USB_QHD_TOKEN_HALTED BIT(6) -#define USB_QHD_TOKEN_ACTIVE BIT(7) -#define USB_QHD_TOKEN_MULT_OVERR_MASK (2 << 10) -#define USB_QHD_TOKEN_IRQ_ON_COMPLETE BIT(15) -#define USB_QHD_TOKEN_TOTAL_BYTES_SHIFT 16 - -/* USB_OTG/USB_1 controllers register bits */ -#define USB2D_PORTSC1_SUSP BIT(7) - -#define USB2D_USBCMD_RUN BIT(0) -#define USB2D_USBCMD_RESET BIT(1) -#define USB2D_USBCMD_ITC_MASK (0xFF << 16) - -#define USB2D_USBSTS_UI BIT(0) -#define USB2D_USBSTS_UEI BIT(1) -#define USB2D_USBSTS_PCI BIT(2) -#define USB2D_USBSTS_FRI BIT(3) -#define USB2D_USBSTS_SEI BIT(4) -#define USB2D_USBSTS_AAI BIT(5) -#define USB2D_USBSTS_URI BIT(6) -#define USB2D_USBSTS_SRI BIT(7) -#define USB2D_USBSTS_SLI BIT(8) - -#define USB2D_USBMODE_CM_MASK (3 << 0) -#define USB2D_USBMODE_CM_IDLE 0 -#define USB2D_USBMODE_CM_RSVD 1 -#define USB2D_USBMODE_CM_DEVICE 2 -#define USB2D_USBMODE_CM_HOST 3 - -#define USB2D_ENDPT_STATUS_RX_OFFSET BIT(0) -#define USB2D_ENDPT_STATUS_TX_OFFSET BIT(16) - -#define USB2D_ENDPTCTRL_RX_EP_STALL BIT(0) -#define USB2D_ENDPTCTRL_RX_EP_TYPE_CTRL (0 << 2) -#define USB2D_ENDPTCTRL_RX_EP_TYPE_ISO (1 << 2) -#define USB2D_ENDPTCTRL_RX_EP_TYPE_BULK (2 << 2) -#define USB2D_ENDPTCTRL_RX_EP_TYPE_INTR (3 << 2) -#define USB2D_ENDPTCTRL_RX_EP_TYPE_MASK (3 << 2) -#define USB2D_ENDPTCTRL_RX_EP_INHIBIT BIT(5) -#define USB2D_ENDPTCTRL_RX_EP_RESET BIT(6) -#define USB2D_ENDPTCTRL_RX_EP_ENABLE BIT(7) -#define USB2D_ENDPTCTRL_TX_EP_STALL BIT(16) -#define USB2D_ENDPTCTRL_TX_EP_TYPE_CTRL (0 << 18) -#define USB2D_ENDPTCTRL_TX_EP_TYPE_ISO (1 << 18) -#define USB2D_ENDPTCTRL_TX_EP_TYPE_BULK (2 << 18) -#define USB2D_ENDPTCTRL_TX_EP_TYPE_INTR (3 << 18) -#define USB2D_ENDPTCTRL_TX_EP_TYPE_MASK (3 << 18) -#define USB2D_ENDPTCTRL_TX_EP_INHIBIT BIT(21) -#define USB2D_ENDPTCTRL_TX_EP_RESET BIT(22) -#define USB2D_ENDPTCTRL_TX_EP_ENABLE BIT(23) - -#define USB2D_HOSTPC1_DEVLC_ASUS BIT(17) -#define USB2D_HOSTPC1_DEVLC_PHCD BIT(22) -#define USB2D_HOSTPC1_DEVLC_PSPD_MASK (3 << 25) - -#define USB2D_OTGSC_USB_ID_PULLUP BIT(5) -#define USB2D_OTGSC_USB_IRQ_STS_MASK (0x7F << 16) - -/* USB_OTG/USB_1 controllers registers */ -typedef struct _t210_usb2d_t -{ - vu32 id; - vu32 unk0; - vu32 hw_host; - vu32 hw_device; - vu32 hw_txbuf; - vu32 hw_rxbuf; - vu32 unk1[26]; - vu32 gptimer0ld; - vu32 gptimer0ctrl; - vu32 gptimer1ld; - vu32 gptimer1ctrl; - vu32 unk2[28]; - vu16 caplength; - vu16 hciversion; - vu32 hcsparams; - vu32 hccparams; - vu32 unk3[5]; - vu32 dciversion; - vu32 dccparams; - vu32 extsts; - vu32 usbextintr; - vu32 usbcmd; - vu32 usbsts; - vu32 usbintr; - vu32 frindex; - vu32 unk4; - vu32 periodiclistbase; - vu32 asynclistaddr; - vu32 asyncttsts; - vu32 burstsize; - vu32 txfilltuning; - vu32 unk6; - vu32 icusb_ctrl; - vu32 ulpi_viewport; - vu32 rsvd0[4]; - vu32 portsc1; - vu32 rsvd1[15]; - vu32 hostpc1_devlc; - vu32 rsvd2[15]; - vu32 otgsc; - vu32 usbmode; - vu32 unk10; - vu32 endptnak; - vu32 endptnak_enable; - vu32 endptsetupstat; - vu32 endptprime; - vu32 endptflush; - vu32 endptstatus; - vu32 endptcomplete; - vu32 endptctrl[16]; -} t210_usb2d_t; - - -/* XHCI USB */ - -/* XUSB DEV XHCI registers */ -#define XUSB_DEV_XHCI_DB 0x4 -#define XUSB_DEV_XHCI_ERSTSZ 0x8 -#define XUSB_DEV_XHCI_ERST0BALO 0x10 -#define XUSB_DEV_XHCI_ERST0BAHI 0x14 -#define XUSB_DEV_XHCI_ERST1BALO 0x18 -#define XUSB_DEV_XHCI_ERST1BAHI 0x1C -#define XUSB_DEV_XHCI_ERDPLO 0x20 -#define XHCI_ERDPLO_EHB BIT(3) -#define XUSB_DEV_XHCI_ERDPHI 0x24 -#define XUSB_DEV_XHCI_EREPLO 0x28 -#define XCHI_ECS BIT(0) -#define XUSB_DEV_XHCI_EREPHI 0x2C -#define XUSB_DEV_XHCI_CTRL 0x30 -#define XHCI_CTRL_RUN BIT(0) -#define XHCI_CTRL_LSE BIT(1) -#define XHCI_CTRL_IE BIT(4) -#define XHCI_CTRL_ENABLE BIT(31) -#define XUSB_DEV_XHCI_ST 0x34 -#define XHCI_ST_RC BIT(0) -#define XHCI_ST_IP BIT(4) -#define XUSB_DEV_XHCI_RT_IMOD 0x38 -#define XUSB_DEV_XHCI_PORTSC 0x3C -#define XHCI_PORTSC_PR BIT(4) -#define XHCI_PORTSC_PLS_MASK (0xF << 5) -#define XHCI_PORTSC_PLS_U0 (0 << 5) -#define XHCI_PORTSC_PLS_U1 (1 << 5) -#define XHCI_PORTSC_PLS_U2 (2 << 5) -#define XHCI_PORTSC_PLS_U3 (3 << 5) -#define XHCI_PORTSC_PLS_DISABLED (4 << 5) -#define XHCI_PORTSC_PLS_RXDETECT (5 << 5) -#define XHCI_PORTSC_PLS_INACTIVE (6 << 5) -#define XHCI_PORTSC_PLS_POLLING (7 << 5) -#define XHCI_PORTSC_PLS_RECOVERY (8 << 5) -#define XHCI_PORTSC_PLS_HOTRESET (9 << 5) -#define XHCI_PORTSC_PLS_COMPLIANCE (10 << 5) -#define XHCI_PORTSC_PLS_LOOPBACK (11 << 5) -#define XHCI_PORTSC_PLS_RESUME (15 << 5) -#define XHCI_PORTSC_PS (0xF << 10) -#define XHCI_PORTSC_LWS BIT(16) -#define XHCI_PORTSC_CSC BIT(17) -#define XHCI_PORTSC_WRC BIT(19) -#define XHCI_PORTSC_PRC BIT(21) -#define XHCI_PORTSC_PLC BIT(22) -#define XHCI_PORTSC_CEC BIT(23) -#define XHCI_PORTSC_WPR BIT(30) -#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 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 XHCI_PORTHALT_HALT_LTSSM BIT(0) -#define XHCI_PORTHALT_STCHG_REQ BIT(20) -#define XUSB_DEV_XHCI_CFG_DEV_FE 0x85C -#define XHCI_CFG_DEV_FE_PORTREGSEL_MASK (3 << 0) -#define XHCI_CFG_DEV_FE_PORTREGSEL_SS (1 << 0) -#define XHCI_CFG_DEV_FE_PORTREGSEL_HSFS (2 << 0) - -/* XUSB DEV PCI registers */ -#define XUSB_CFG_1 0x4 -#define CFG_1_IO_SPACE BIT(0) -#define CFG_1_MEMORY_SPACE BIT(1) -#define CFG_1_BUS_MASTER BIT(2) -#define XUSB_CFG_4 0x10 -#define CFG_4_ADDRESS_TYPE_32_BIT (0 << 1) -#define CFG_4_ADDRESS_TYPE_64_BIT (2 << 1) - -/* XUSB DEV Device registers */ -#define XUSB_DEV_CONFIGURATION 0x180 -#define DEV_CONFIGURATION_EN_FPCI BIT(0) -#define XUSB_DEV_INTR_MASK 0x188 -#define DEV_INTR_MASK_IP_INT_MASK BIT(16) - -/* XUSB Pad Control registers */ -#define XUSB_PADCTL_USB2_PAD_MUX 0x4 -#define PADCTL_USB2_PAD_MUX_USB2_OTG_PAD_PORT0_USB2 (0 << 0) -#define PADCTL_USB2_PAD_MUX_USB2_OTG_PAD_PORT0_XUSB (1 << 0) -#define PADCTL_USB2_PAD_MUX_USB2_OTG_PAD_PORT0_MASK (3 << 0) -#define PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_USB2 (0 << 18) -#define PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_XUSB (1 << 18) -#define PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_MASK (3 << 18) -#define XUSB_PADCTL_USB2_PORT_CAP 0x8 -#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_DIS (0 << 0) -#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_HOST (1 << 0) -#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_DEV (2 << 0) -#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_OTG (3 << 0) -#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_MASK (3 << 0) -#define XUSB_PADCTL_SS_PORT_MAP 0x14 -#define PADCTL_SS_PORT_MAP_PORT0_MASK (0xF << 0) -#define XUSB_PADCTL_ELPG_PROGRAM_0 0x20 -#define XUSB_PADCTL_ELPG_PROGRAM_1 0x24 -#define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD0_CTL0 0x80 -#define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD0_CTL1 0x84 -#define XUSB_PADCTL_USB2_OTG_PAD0_CTL_0 0x88 -#define XUSB_PADCTL_USB2_OTG_PAD0_CTL_1 0x8C -#define XUSB_PADCTL_USB2_BIAS_PAD_CTL_0 0x284 -#define XUSB_PADCTL_USB2_BIAS_PAD_CTL_1 0x288 -#define XUSB_PADCTL_USB2_VBUS_ID 0xC60 -#define PADCTL_USB2_VBUS_ID_VBUS_OVR_EN (1 << 12) -#define PADCTL_USB2_VBUS_ID_VBUS_OVR_MASK (3 << 12) -#define PADCTL_USB2_VBUS_ID_VBUS_ON BIT(14) -#define PADCTL_USB2_VBUS_ID_SRC_ID_OVR_EN (1 << 16) -#define PADCTL_USB2_VBUS_ID_SRC_MASK (3 << 16) -#define PADCTL_USB2_VBUS_ID_OVR_GND (0 << 18) -#define PADCTL_USB2_VBUS_ID_OVR_C (1 << 18) -#define PADCTL_USB2_VBUS_ID_OVR_B (2 << 18) -#define PADCTL_USB2_VBUS_ID_OVR_A (4 << 18) -#define PADCTL_USB2_VBUS_ID_OVR_FLOAT (8 << 18) -#define PADCTL_USB2_VBUS_ID_OVR_MASK (0xF << 18) - -#endif diff --git a/bdk/usb/usbd.c b/bdk/usb/usbd.c deleted file mode 100644 index 95d1ed5..0000000 --- a/bdk/usb/usbd.c +++ /dev/null @@ -1,1595 +0,0 @@ -/* - * Enhanced USB Device (EDCI) driver for Tegra X1 - * - * Copyright (c) 2019-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 . - */ - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -typedef enum -{ - USB_HW_EP0 = 0, - USB_HW_EP1 = 1 -} usb_hw_ep_t; - -typedef enum -{ - USB_EP_STATUS_IDLE = 0, - USB_EP_STATUS_ACTIVE = 1, - USB_EP_STATUS_ERROR = 2, - USB_EP_STATUS_NO_CONFIG = 3, - USB_EP_STATUS_STALLED = 4, - USB_EP_STATUS_DISABLED = 5 -} usb_ep_status_t; - -typedef enum { - USB_LOW_SPEED = 0, - USB_FULL_SPEED = 1, - USB_HIGH_SPEED = 2, - USB_SUPER_SPEED = 3, -} usb_speed_t; - -typedef struct _dTD_t -{ - vu32 next_dTD; - vu32 info; - vu32 pages[5]; - vu32 reserved; -} dTD_t; - -typedef struct _dQH_t -{ - vu32 ep_capabilities; - vu32 curr_dTD_ptr; - vu32 next_dTD_ptr; - vu32 token; - vu32 buffers[5]; // hmmm. - vu32 reserved; - vu32 setup[2]; - vu32 gap[4]; -} dQH_t; - -typedef struct _usbd_t -{ - volatile dTD_t dtds[4 * 4]; // 4 dTD per endpoint. - volatile dQH_t *qhs; - int ep_configured[4]; - int ep_bytes_requested[4]; -} usbd_t; - -typedef struct _usbd_controller_t -{ - u32 port_speed; - t210_usb2d_t *regs; - usb_ctrl_setup_t control_setup; - usb_desc_t *desc; - usb_gadget_type gadget; - u8 config_num; - u8 interface_num; - u8 max_lun; - bool usb_phy_ready; - bool configuration_set; - bool max_lun_set; - bool bulk_reset_req; - bool hid_report_sent; - u32 charger_detect; -} usbd_controller_t; - -extern u8 hid_report_descriptor_jc[]; -extern u8 hid_report_descriptor_touch[]; -extern u32 hid_report_descriptor_jc_size; -extern u32 hid_report_descriptor_touch_size; - -extern usb_desc_t usb_gadget_hid_jc_descriptors; -extern usb_desc_t usb_gadget_hid_touch_descriptors; -extern usb_desc_t usb_gadget_ums_descriptors; - -usbd_t *usbdaemon; - -usbd_controller_t *usbd_otg; -usbd_controller_t usbd_usb_otg_controller_ctxt; - -bool usb_init_done = false; - -u8 *usb_ep0_ctrl_buf = (u8 *)USB_EP_CONTROL_BUF_ADDR; - -static int _usbd_reset_usb_otg_phy_device_mode() -{ - usbd_otg->usb_phy_ready = false; - - // Clear UTMIP reset. - USB(USB1_IF_USB_SUSP_CTRL) &= ~SUSP_CTRL_UTMIP_RESET; - - // Wait for PHY clock to get validated. - u32 retries = 100000; // 200ms timeout. - while (!(USB(USB1_IF_USB_SUSP_CTRL) & SUSP_CTRL_USB_PHY_CLK_VALID)) - { - retries--; - if (!retries) - return USB_ERROR_INIT; - usleep(1); - } - usbd_otg->usb_phy_ready = true; - - // Clear all device addresses, enabled setup requests and transmit events. - usbd_otg->regs->periodiclistbase = 0; - usbd_otg->regs->endptsetupstat = usbd_otg->regs->endptsetupstat; - usbd_otg->regs->endptcomplete = usbd_otg->regs->endptcomplete; - - // Stop device controller. - usbd_otg->regs->usbcmd &= ~USB2D_USBCMD_RUN; - - // Set controller mode to idle. - usbd_otg->regs->usbmode &= ~USB2D_USBMODE_CM_MASK; - - // Reset the controller. - usbd_otg->regs->usbcmd |= USB2D_USBCMD_RESET; - - // Wait for the reset to complete. - retries = 100000; // 200ms timeout. - while (usbd_otg->regs->usbcmd & USB2D_USBCMD_RESET) - { - retries--; - if (!retries) - return USB_ERROR_INIT; - usleep(1); - } - - // Wait for PHY clock to get validated after reset. - retries = 100000; // 200ms timeout. - while (!(USB(USB1_IF_USB_SUSP_CTRL) & SUSP_CTRL_USB_PHY_CLK_VALID)) - { - retries--; - if (!retries) - return USB_ERROR_INIT; - usleep(1); - } - - // Set controller to Device mode. - usbd_otg->regs->usbmode = (usbd_otg->regs->usbmode & ~USB2D_USBMODE_CM_MASK) | USB2D_USBMODE_CM_DEVICE; - - // Wait for the selected mode to be enabled. - retries = 100000; // 200ms timeout. - while ((usbd_otg->regs->usbmode & USB2D_USBMODE_CM_MASK) != USB2D_USBMODE_CM_DEVICE) - { - retries--; - if (!retries) - return USB_ERROR_INIT; - usleep(1); - } - - // Disable all interrupts. - usbd_otg->regs->usbintr = 0; - - // Set the ID pullup and disable all OTGSC interrupts. - usbd_otg->regs->otgsc = USB2D_OTGSC_USB_ID_PULLUP; - - // Clear all relevant interrupt statuses. - usbd_otg->regs->usbsts = - USB2D_USBSTS_UI | USB2D_USBSTS_UEI | USB2D_USBSTS_PCI | - USB2D_USBSTS_FRI | USB2D_USBSTS_SEI | USB2D_USBSTS_AAI | - USB2D_USBSTS_URI | USB2D_USBSTS_SRI | USB2D_USBSTS_SLI; - - // Disable and clear all OTGSC interrupts. - usbd_otg->regs->otgsc = USB2D_OTGSC_USB_IRQ_STS_MASK; - - // Clear EP0, EP1, EP2 setup requests. - usbd_otg->regs->endptsetupstat = 7; //TODO: Shouldn't this be endptsetupstat = endptsetupstat? - - // Set all interrupts to immediate. - usbd_otg->regs->usbcmd &= ~USB2D_USBCMD_ITC_MASK; - - return USB_RES_OK; -} - -static void _usb_charger_detect() -{ - // Charger detect init. - usbd_otg->charger_detect = 0; - bool charger_detect_enable = FUSE(FUSE_RESERVED_SW) & 0x10; // Disabled on Switch production. - if (charger_detect_enable) - { - usbd_otg->charger_detect |= 1; - // Configure detect pin. - PINMUX_AUX(PINMUX_AUX_LCD_GPIO1) &= ~(PINMUX_PARKED | PINMUX_TRISTATE | PINMUX_PULL_MASK); - gpio_config(GPIO_PORT_V, GPIO_PIN_3, GPIO_MODE_GPIO); - - // Configure charger pin. - PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN1) &= - ~(PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_TRISTATE | PINMUX_PULL_MASK); - gpio_config(GPIO_PORT_CC, GPIO_PIN_5, GPIO_MODE_GPIO); - gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_5, GPIO_OUTPUT_ENABLE); - - // Enable charger. - if (gpio_read(GPIO_PORT_V, GPIO_PIN_3)) - { - usbd_otg->charger_detect |= 2; - gpio_write(GPIO_PORT_CC, GPIO_PIN_5, GPIO_HIGH); - usbd_otg->charger_detect |= 0x100; - USB(USB1_UTMIP_BAT_CHRG_CFG0) = BAT_CHRG_CFG0_OP_SRC_EN; // Clears UTMIP_PD_CHRG and enables charger detect. - usleep(5000); - } - } -} - -static void _usb_init_phy() -{ - // Configure and enable PLLU. - clock_enable_pllu(); - - // Enable USBD clock. - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_USBD); - usleep(2); - CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_USBD); - usleep(2); - CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_USBD); - usleep(2); - - // Clear XUSB_PADCTL reset - CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_CLR) = BIT(CLK_W_XUSB_PADCTL); - - // Enable USB PHY and reset for programming. - u32 usb_susp_ctrl = USB(USB1_IF_USB_SUSP_CTRL); - USB(USB1_IF_USB_SUSP_CTRL) = usb_susp_ctrl | SUSP_CTRL_UTMIP_RESET; - USB(USB1_IF_USB_SUSP_CTRL) = usb_susp_ctrl | SUSP_CTRL_UTMIP_PHY_ENB | SUSP_CTRL_UTMIP_RESET; - - // Enable IDDQ control by software and disable UTMIPLL IDDQ. - CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) = (CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) & 0xFFFFFFFC) | 1; - usleep(10); - - // Disable crystal clock. - USB(USB1_UTMIP_MISC_CFG1) &= 0xBFFFFFFF; - CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) &= 0xBFFFFFFF; - - // Set B_SESS_VLD. - USB(USB1_IF_USB_PHY_VBUS_SENSORS) |= 0x1000; - USB(USB1_IF_USB_PHY_VBUS_SENSORS) |= 0x800; - - // Set UTMIPLL dividers and config based on OSC and enable it to 960 MHz. - clock_enable_utmipll(); - - // Configure UTMIP Transceiver Cells. - u32 fuse_usb_calib = FUSE(FUSE_USB_CALIB); - USB(USB1_UTMIP_XCVR_CFG0) = (((USB(USB1_UTMIP_XCVR_CFG0) & 0xFFFFFFF0) | (fuse_usb_calib & 0xF)) & 0xFE3FFFFF) | ((fuse_usb_calib & 0x3F) << 25 >> 29 << 22); - USB(USB1_UTMIP_XCVR_CFG1) = (USB(USB1_UTMIP_XCVR_CFG1) & 0xFFC3FFFF) | ((fuse_usb_calib << 21) >> 28 << 18); - USB(USB1_UTMIP_XCVR_CFG3) = (USB(USB1_UTMIP_XCVR_CFG3) & 0xFFFFC1FF) | ((FUSE(FUSE_USB_CALIB_EXT) & 0x1F) << 9); - USB(USB1_UTMIP_XCVR_CFG0) &= 0xFFDFFFFF; - USB(USB1_UTMIP_XCVR_CFG2) = (USB(USB1_UTMIP_XCVR_CFG2) & 0xFFFFF1FF) | 0x400; - usleep(1); - - // Configure misc UTMIP. - USB(USB1_UTMIP_DEBOUNCE_CFG0) = (USB(USB1_UTMIP_DEBOUNCE_CFG0) & 0xFFFF0000) | 0xBB80; - USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFFFFC0FF) | 0x100; // when osc is 38.4KHz - - //USB(USB1_UTMIP_SPARE_CFG0) &= 0xFFFFFEE7; unpatched0 - USB(USB1_UTMIP_BIAS_CFG2) |= 2; //patched0 - UTMIP_HSSQUELCH_LEVEL_NEW: 2. - USB(USB1_UTMIP_SPARE_CFG0) &= 0xFFFFFE67; //patched0 - FUSE_HS_IREF_CAP_CFG - USB(USB1_UTMIP_TX_CFG0) |= 0x80000; - - //USB(USB1_UTMIP_HSRX_CFG0) = (USB(USB1_UTMIP_HSRX_CFG0) & 0xFFF003FF) | 0x88000 | 0x4000; unpatched1 - USB(USB1_UTMIP_HSRX_CFG0) = (USB(USB1_UTMIP_HSRX_CFG0) & 0xF0F003FF) | 0x88000 | 0x4000; //patched1 - reset UTMIP_PCOUNT_UPDN_DIV: From 1 to 0. - USB(USB1_UTMIP_BIAS_CFG2) &= 0xFFFFFFF8; //patched1 - UTMIP_HSSQUELCH_LEVEL_NEW: 0 - - USB(USB1_UTMIP_HSRX_CFG1) = (USB(USB1_UTMIP_HSRX_CFG1) & 0xFFFFFFC1) | 0x12; - USB(USB1_UTMIP_MISC_CFG1) |= 0x40000000; - - // Enable crystal clock. - CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) |= 0x40000000; - - // Enable USB2 tracking clock. - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_SET) = BIT(CLK_Y_USB2_TRK); - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK) & 0xFFFFFF00) | 6; // Set trank divisor to 4. - - USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFFC03F07) | 0x78000 | 0x50; // Set delays. - USB(USB1_UTMIP_BIAS_CFG0) &= 0xFFFFFBFF; // Disable Power down bias circuit. - usleep(1); - - // Force PDTRK input into power up. - USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFFFFFFFE) | 2; - usleep(100); - - // TRK cycle done. Force PDTRK input into power down. - USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFF7FFFFF) | 1; - usleep(3); - - // Force PDTRK input into power up. - USB(USB1_UTMIP_BIAS_CFG1) = USB(USB1_UTMIP_BIAS_CFG1) & 0xFFFFFFFE; - usleep(100); - - // TRK cycle done. Force PDTRK input into power down. - USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFF7FFFFF) | 1; - - // Disable USB2 tracking clock and configure UTMIP misc. - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_CLR) = BIT(CLK_Y_USB2_TRK); - CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) = (CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) & 0xFEFFFFEA) | 0x2000000 | 0x28 | 2; - usleep(1); - - USB(USB1_UTMIP_BIAS_CFG0) &= 0xFF3FF7FF; - usleep(1); - - // Clear power downs on UTMIP ID and VBUS wake up, PD, PD2, PDZI, PDCHRP, PDDR. - PMC(APBDEV_PMC_USB_AO) &= 0xFFFFFFF3; // UTMIP ID and VBUS wake up. - usleep(1); - USB(USB1_UTMIP_XCVR_CFG0) &= 0xFFFFBFFF; // UTMIP_FORCE_PD_POWERDOWN. - usleep(1); - USB(USB1_UTMIP_XCVR_CFG0) &= 0xFFFEFFFF; // UTMIP_FORCE_PD2_POWERDOWN. - usleep(1); - USB(USB1_UTMIP_XCVR_CFG0) &= 0xFFFBFFFF; // UTMIP_FORCE_PDZI_POWERDOWN. - usleep(1); - USB(USB1_UTMIP_XCVR_CFG1) &= 0xFFFFFFFB; // UTMIP_FORCE_PDCHRP_POWERDOWN. - usleep(1); - USB(USB1_UTMIP_XCVR_CFG1) &= 0xFFFFFFEF; // UTMIP_FORCE_PDDR_POWERDOWN. - usleep(1); -} - -int usb_device_init() -{ - if (usb_init_done) - return USB_RES_OK; - - // Initialize USB2 controller PHY. - _usb_init_phy(); - - // AHB USB performance cfg. - AHB_GIZMO(AHB_GIZMO_AHB_MEM) |= AHB_MEM_DONT_SPLIT_AHB_WR | AHB_MEM_ENB_FAST_REARBITRATE; - AHB_GIZMO(AHB_GIZMO_USB) |= AHB_GIZMO_IMMEDIATE; - AHB_GIZMO(AHB_ARBITRATION_PRIORITY_CTRL) = PRIORITY_CTRL_WEIGHT(7) | PRIORITY_SELECT_USB; - AHB_GIZMO(AHB_AHB_MEM_PREFETCH_CFG1) = - MEM_PREFETCH_ENABLE | MEM_PREFETCH_USB_MST_ID | MEM_PREFETCH_ADDR_BNDRY(12) | 0x1000; // Addr boundary 64KB, Inactivity 4096 cycles. - - // Set software and hardware context storage and clear it. - usbdaemon = (usbd_t *)USBD_ADDR; // Depends on USB_TD_BUFFER_PAGE_SIZE aligned address. - usbd_otg = &usbd_usb_otg_controller_ctxt; - memset(usbd_otg, 0, sizeof(usbd_controller_t)); - memset(usbdaemon, 0, sizeof(usbd_t)); - - usbd_otg->regs = (t210_usb2d_t *)USB_OTG_BASE; - usbd_otg->usb_phy_ready = false; - - // Initialize USB PHY on the USB_OTG Controller (#1) in Device mode. - int res = _usbd_reset_usb_otg_phy_device_mode(); - usbd_otg->configuration_set = false; - - _usb_charger_detect(); - - if (!res) - usb_init_done = true; - - return res; -} - -static void _usb_device_power_down() -{ - // Enable PHY low power suspend. - usbd_otg->regs->hostpc1_devlc |= USB2D_HOSTPC1_DEVLC_PHCD; - // Do not use any controller regs after the above! - // A reset or clear of the PHCD suspend bit must happen. - - // Power down OTG and Bias circuits. - USB(USB1_UTMIP_BIAS_CFG0) |= BIT(11) | BIT(10); // UTMIP_OTGPD, UTMIP_BIASPD. - - // Power down ID detectors. - USB(USB1_UTMIP_BIAS_CFG0) |= BIT(23) | BIT(22); // UTMIP_IDPD_SEL, UTMIP_IDPD_VAL. - - if (usbd_otg->charger_detect) - { - USB(USB1_UTMIP_BAT_CHRG_CFG0) = 1; //UTMIP_PD_CHRG - usbd_otg->charger_detect = 0; - } - - // Power down the UTMIP transceivers. - // UTMIP_FORCE_PDZI_POWERDOWN, UTMIP_FORCE_PD2_POWERDOWN, UTMIP_FORCE_PD_POWERDOWN. - USB(USB1_UTMIP_XCVR_CFG0) |= BIT(18) | BIT(16) |BIT(14); - // UTMIP_FORCE_PDDR_POWERDOWN, UTMIP_FORCE_PDCHRP_POWERDOWN, UTMIP_FORCE_PDDISC_POWERDOWN. - USB(USB1_UTMIP_XCVR_CFG1) |= BIT(4) | BIT(2) | BIT(0); - - // Keep UTMIP in reset. - USB(USB1_IF_USB_SUSP_CTRL) |= SUSP_CTRL_UTMIP_RESET; - - // Power down PD trunk. - USB(USB1_UTMIP_BIAS_CFG1) |= BIT(0); //UTMIP_FORCE_PDTRK_POWERDOWN. - - // Force UTMIP_PLL power down. - CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG1) |= BIT(14); // UTMIP_FORCE_PLL_ENABLE_POWERDOWN. - CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG1) |= BIT(12); // UTMIP_FORCE_PLL_ACTIVE_POWERDOWN. - CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) |= BIT(4) | BIT(0); // UTMIP_FORCE_PD_SAMP_A/C_POWERDOWN. - CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG1) |= BIT(16); // UTMIP_FORCE_PLLU_POWERDOWN. - - // Disable crystal clock. - USB(USB1_UTMIP_MISC_CFG1) &= 0xBFFFFFFF; - - // Force enable UTMIPLL IDDQ. - CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) |= 3; - - // Set XUSB_PADCTL reset - CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB_PADCTL); - - // Disable USBD clock. - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_USBD); - - // Disable PLLU. - clock_disable_pllu(); - - usb_init_done = false; -} - -static void _usbd_stall_reset_ep1(usb_dir_t direction, usb_ep_cfg_t stall) -{ - stall &= 1; - if (direction == USB_DIR_IN) - { - usbd_otg->regs->endptctrl[1] = (usbd_otg->regs->endptctrl[1] & ~USB2D_ENDPTCTRL_TX_EP_STALL) | ((u32)stall << 16); - if (!stall) - usbd_otg->regs->endptctrl[1] |= USB2D_ENDPTCTRL_TX_EP_RESET; - } - else - { - usbd_otg->regs->endptctrl[1] = (usbd_otg->regs->endptctrl[1] & ~USB2D_ENDPTCTRL_RX_EP_STALL) | stall; - if (!stall) - usbd_otg->regs->endptctrl[1] |= USB2D_ENDPTCTRL_RX_EP_RESET; - } -} - -void usb_device_stall_ep1_bulk_out() -{ - _usbd_stall_reset_ep1(USB_DIR_OUT, USB_EP_CFG_STALL); -} - -void usb_device_stall_ep1_bulk_in() -{ - _usbd_stall_reset_ep1(USB_DIR_IN, USB_EP_CFG_STALL); -} - -static int _usbd_get_max_pkt_length(int endpoint) -{ - switch (endpoint) - { - case USB_EP_CTRL_OUT: - case USB_EP_CTRL_IN: - return 64; - case USB_EP_BULK_OUT: - case USB_EP_BULK_IN: - if (usbd_otg->port_speed == USB_HIGH_SPEED) - return 512; - else - return 64; - default: - return 64; - } -} - -static void _usbd_initialize_ep_ctrl(u32 endpoint) -{ - usb_hw_ep_t actual_ep = (endpoint & 2) >> 1; - usb_dir_t direction = endpoint & 1; - - memset((void *)&usbdaemon->qhs[endpoint], 0, sizeof(dQH_t)); - - if (!endpoint) - usbdaemon->qhs[endpoint].ep_capabilities = USB_QHD_EP_CAP_IOS_ENABLE; - - usbdaemon->qhs[endpoint].next_dTD_ptr = 1; // TERMINATE_SET - - u32 max_packet_len = _usbd_get_max_pkt_length(endpoint) & USB_QHD_EP_CAP_MAX_PKT_LEN_MASK; - usbdaemon->qhs[endpoint].ep_capabilities |= max_packet_len << 16; - - if (direction == USB_DIR_IN) - { - u32 endpoint_type = usbd_otg->regs->endptctrl[actual_ep] & ~USB2D_ENDPTCTRL_TX_EP_TYPE_MASK; - if (actual_ep) - endpoint_type |= usbd_otg->gadget ? USB2D_ENDPTCTRL_TX_EP_TYPE_INTR : USB2D_ENDPTCTRL_TX_EP_TYPE_BULK; - else - endpoint_type |= USB2D_ENDPTCTRL_TX_EP_TYPE_CTRL; - - usbd_otg->regs->endptctrl[actual_ep] = endpoint_type; - - usbd_otg->regs->endptctrl[actual_ep] &= ~USB2D_ENDPTCTRL_TX_EP_STALL; - - if (actual_ep == USB_HW_EP1) - usbd_otg->regs->endptctrl[1] |= USB2D_ENDPTCTRL_TX_EP_RESET; - - usbd_otg->regs->endptctrl[actual_ep] |= USB2D_ENDPTCTRL_TX_EP_ENABLE; - } - else // EP Bulk OUT. - { - u32 endpoint_type = usbd_otg->regs->endptctrl[actual_ep] & ~USB2D_ENDPTCTRL_RX_EP_TYPE_MASK; - if (actual_ep) - { - endpoint_type |= usbd_otg->gadget ? USB2D_ENDPTCTRL_RX_EP_TYPE_INTR : USB2D_ENDPTCTRL_RX_EP_TYPE_BULK; - } - else - endpoint_type |= USB2D_ENDPTCTRL_RX_EP_TYPE_CTRL; - - usbd_otg->regs->endptctrl[actual_ep] = endpoint_type; - usbd_otg->regs->endptctrl[actual_ep] &= ~USB2D_ENDPTCTRL_RX_EP_STALL; - - if (actual_ep == USB_HW_EP1) - usbd_otg->regs->endptctrl[1] |= USB2D_ENDPTCTRL_RX_EP_RESET; - - usbd_otg->regs->endptctrl[actual_ep] |= USB2D_ENDPTCTRL_RX_EP_ENABLE; - } -} - -static int _usbd_initialize_ep0() -{ - memset((void *)usbdaemon->qhs, 0, sizeof(dQH_t) * 4); // Clear all used EP queue heads. - memset((void *)usbdaemon->dtds, 0, sizeof(dTD_t) * 4); // Clear all used EP0 token heads. - - usbd_otg->regs->asynclistaddr = (u32)usbdaemon->qhs; - - _usbd_initialize_ep_ctrl(USB_EP_CTRL_OUT); - _usbd_initialize_ep_ctrl(USB_EP_CTRL_IN); - - // Disable Auto Low Power. - usbd_otg->regs->hostpc1_devlc &= ~USB2D_HOSTPC1_DEVLC_ASUS; - - // Initiate an attach event. - usbd_otg->regs->usbcmd |= USB2D_USBCMD_RUN; - - u32 retries = 100000; // 200ms timeout. - while (!(usbd_otg->regs->usbcmd & USB2D_USBCMD_RUN)) - { - retries--; - if (!retries) - return USB_ERROR_TIMEOUT; - usleep(1); - } - - return USB_RES_OK; -} - -// static void _disable_usb_wdt4() -// { -// if (TIMER_WDT4_STATUS & 1)// active -// { -// TIMER_TMR0_TMR_PTV &= 0x7FFFFFFF; // Disable timer -// TIMER_WDT4_UNLOCK_PATTERN = 0xC45A; // Alow writes to disable counter bit. -// TIMER_WDT4_COMMAND |= 2; // Disable counter -// TIMER_TMR0_TMR_PCR |= 0x40000000;// INTR_CLR -// } -// } - -int usbd_flush_endpoint(u32 endpoint) -{ - - usb_hw_ep_t actual_ep = (endpoint & 2) >> 1; - usb_dir_t direction = endpoint & 1; - u32 reg_mask = endpoint; - - // Flash all endpoints or 1. - if (endpoint != USB_EP_ALL) - { - if (direction == USB_DIR_IN) - reg_mask = USB2D_ENDPT_STATUS_TX_OFFSET << actual_ep; - else - reg_mask = USB2D_ENDPT_STATUS_RX_OFFSET << actual_ep; - } - usbd_otg->regs->endptflush = reg_mask; - - u32 retries = 100000; // 200ms timeout. - while (usbd_otg->regs->endptflush & reg_mask) - { - retries--; - if (!retries) - return USB_ERROR_TIMEOUT; - usleep(1); - } - - // Wait for the endpoint to finish all transactions (buffer not ready). - retries = 100000; // 200ms timeout. - while (usbd_otg->regs->endptstatus & reg_mask) - { - retries--; - if (!retries) - return USB_ERROR_TIMEOUT; - usleep(1); - } - - // Wait for the endpoint to clear the primed status. - retries = 100000; // 200ms timeout. - while (usbd_otg->regs->endptprime & reg_mask) - { - retries--; - if (!retries) - return USB_ERROR_TIMEOUT; - usleep(1); - } - - return USB_RES_OK; -} - -void usbd_end(bool reset_ep, bool only_controller) -{ - if (reset_ep) - { - usbd_flush_endpoint(USB_EP_ALL); - _usbd_stall_reset_ep1(USB_DIR_OUT, USB_EP_CFG_RESET); // EP1 Bulk OUT. - _usbd_stall_reset_ep1(USB_DIR_IN, USB_EP_CFG_RESET); // EP1 Bulk IN. - - usbd_otg->config_num = 0; - usbd_otg->interface_num = 0; - usbd_otg->configuration_set = false; - usbd_otg->max_lun_set = false; - } - - // Stop device controller. - usbd_otg->regs->usbcmd &= ~USB2D_USBCMD_RUN; - - // Enable PHY auto low power suspend. - usbd_otg->regs->hostpc1_devlc |= USB2D_HOSTPC1_DEVLC_ASUS; - - if (!only_controller) - _usb_device_power_down(); -} - -static void _usbd_mark_ep_complete(u32 endpoint) -{ - u32 complete_bit; - usb_hw_ep_t actual_ep = (endpoint & 2) >> 1; - usb_dir_t direction = endpoint & 1; - - usbd_flush_endpoint(endpoint); - memset((void *)&usbdaemon->dtds[endpoint * 4], 0, sizeof(dTD_t) * 4); - memset((void *)&usbdaemon->qhs[endpoint], 0, sizeof(dQH_t)); - usbdaemon->ep_configured[endpoint] = 0; - usbdaemon->ep_bytes_requested[endpoint] = 0; - - if (direction == USB_DIR_IN) - complete_bit = USB2D_ENDPT_STATUS_TX_OFFSET << actual_ep; - else - complete_bit = USB2D_ENDPT_STATUS_RX_OFFSET << actual_ep; - - usbd_otg->regs->endptcomplete |= complete_bit; -} - -static usb_ep_status_t _usbd_get_ep_status(usb_ep_t endpoint) -{ - bool status; - u32 reg_val; - u32 reg_mask; - u32 actual_ep = (endpoint & 2) >> 1; - usb_dir_t direction = endpoint & 1; - - if (direction == USB_DIR_IN) - reg_mask = USB2D_ENDPT_STATUS_TX_OFFSET << actual_ep; - else - reg_mask = USB2D_ENDPT_STATUS_RX_OFFSET << actual_ep; - - if (actual_ep == USB_HW_EP1) - reg_val = usbd_otg->regs->endptctrl[1]; - else - reg_val = usbd_otg->regs->endptctrl[0]; - - // Check stalled status. - if (direction == USB_DIR_IN) - status = reg_val & USB2D_ENDPTCTRL_TX_EP_STALL; - else - status = reg_val & USB2D_ENDPTCTRL_RX_EP_STALL; - - if (status) - return USB_EP_STATUS_STALLED; - - // Check enabled status. - if (direction == USB_DIR_IN) - status = reg_val & USB2D_ENDPTCTRL_TX_EP_ENABLE; - else - status = reg_val & USB2D_ENDPTCTRL_RX_EP_ENABLE; - - if (!status) - return USB_EP_STATUS_DISABLED; - - // CHeck qHD error status. - u32 token_error_mask = USB_QHD_TOKEN_HALTED | USB_QHD_TOKEN_BUFFER_ERROR | USB_QHD_TOKEN_XFER_ERROR; - if (usbdaemon->qhs[endpoint].token & token_error_mask) - return USB_EP_STATUS_ERROR; - - // Check if endpoint has a request or a ready buffer. - if ((usbd_otg->regs->endptprime & reg_mask) || (usbd_otg->regs->endptstatus & reg_mask)) - return USB_EP_STATUS_ACTIVE; // RX/TX active. - - // Return idle or not configured status. - if (!usbdaemon->ep_configured[endpoint]) - return USB_EP_STATUS_NO_CONFIG; - - return USB_EP_STATUS_IDLE; -} - -static int _usbd_ep_operation(usb_ep_t endpoint, u8 *buf, u32 len, u32 sync_timeout) -{ - if (!buf) - len = 0; - - u32 prime_bit; - usb_hw_ep_t actual_ep = (endpoint & 2) >> 1; - usb_dir_t direction = endpoint & 1; - u32 length_left = len; - u32 dtd_ep_idx = endpoint * 4; - - _usbd_mark_ep_complete(endpoint); - - if (endpoint == USB_EP_CTRL_OUT) - usbdaemon->qhs[endpoint].ep_capabilities = USB_QHD_EP_CAP_IOS_ENABLE; - - u32 max_packet_len = _usbd_get_max_pkt_length(endpoint) & USB_QHD_EP_CAP_MAX_PKT_LEN_MASK; - usbdaemon->qhs[endpoint].ep_capabilities |= (max_packet_len << 16) | USB_QHD_EP_CAP_ZERO_LEN_TERM_DIS; - usbdaemon->qhs[endpoint].next_dTD_ptr = 0; // Clear terminate bit. - //usbdaemon->qhs[endpoint].ep_capabilities |= USB_QHD_TOKEN_IRQ_ON_COMPLETE; - - usbdaemon->ep_configured[endpoint] = 1; - usbdaemon->ep_bytes_requested[endpoint] = len; - - // Configure dTD. - u32 dtd_idx = 0; - do - { - if (dtd_idx) - usbdaemon->dtds[dtd_ep_idx + dtd_idx - 1].next_dTD = (u32)&usbdaemon->dtds[dtd_ep_idx + dtd_idx]; - - u32 dtd_size = MIN(length_left, USB_TD_BUFFER_MAX_SIZE); // 16KB max per dTD. - usbdaemon->dtds[dtd_ep_idx + dtd_idx].info = (dtd_size << 16) | USB_QHD_TOKEN_ACTIVE; - // usbdaemon->dtds[dtd_ep_idx + dtd_idx].info |= USB_QHD_TOKEN_IRQ_ON_COMPLETE; - - // Set buffers addresses to all page pointers. - u32 dt_buffer_offset = dtd_idx * USB_TD_BUFFER_MAX_SIZE; - for (u32 i = 0; i < 4; i++) - usbdaemon->dtds[dtd_ep_idx + dtd_idx].pages[i] = - (u32)&buf[dt_buffer_offset + (USB_TD_BUFFER_PAGE_SIZE * i)]; - - //usbdaemon->dtds[dtd_ep_idx + dtd_idx].pages[5] = - // (u32)&buf[dt_buffer_offset + (USB_TD_BUFFER_PAGE_SIZE * 4)]; // Last buffer. Unused. - - length_left -= dtd_size; - if (length_left) - dtd_idx++; - } - while (length_left); - - // Last dTD, terminate it. - usbdaemon->dtds[dtd_ep_idx + dtd_idx].next_dTD = 1; - - // Set first dTD address to queue head next dTD. - usbdaemon->qhs[endpoint].next_dTD_ptr |= (u32)&usbdaemon->dtds[dtd_ep_idx] & 0xFFFFFFE0; - - // Flush AHB prefetcher. - AHB_GIZMO(AHB_AHB_MEM_PREFETCH_CFG1) &= ~MEM_PREFETCH_ENABLE; - AHB_GIZMO(AHB_AHB_MEM_PREFETCH_CFG1) |= MEM_PREFETCH_ENABLE; - - if (direction == USB_DIR_IN) - { - prime_bit = USB2D_ENDPT_STATUS_TX_OFFSET << actual_ep; - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); - } - else - prime_bit = USB2D_ENDPT_STATUS_RX_OFFSET << actual_ep; - - // Prime endpoint. - usbd_otg->regs->endptprime |= prime_bit; // USB2_CONTROLLER_USB2D_ENDPTPRIME. - - int res = USB_RES_OK; - usb_ep_status_t ep_status; - if (sync_timeout) - { - ep_status = _usbd_get_ep_status(endpoint); - if (ep_status == USB_EP_STATUS_ACTIVE) - { - u32 retries = sync_timeout; - while (retries) - { - ep_status = _usbd_get_ep_status(endpoint); - if (ep_status != USB_EP_STATUS_ACTIVE) - { - if (ep_status == USB_EP_STATUS_DISABLED) - res = USB2_ERROR_XFER_EP_DISABLED; - goto out; - } - retries--; - usleep(1); - } - res = USB_ERROR_TIMEOUT; - } - else if (ep_status == USB_EP_STATUS_DISABLED) - res = USB2_ERROR_XFER_EP_DISABLED; -out: - if (res) - _usbd_mark_ep_complete(endpoint); - else if (_usbd_get_ep_status(endpoint) != USB_EP_STATUS_IDLE) - res = USB_ERROR_XFER_ERROR; - - if (direction == USB_DIR_OUT) - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); - } - - return res; -} - -static int _usbd_ep_ack(usb_ep_t ep) -{ - return _usbd_ep_operation(ep, NULL, 0, USB_XFER_SYNCED_ENUM); -} - -static void _usbd_set_ep0_stall() -{ - // EP Control endpoints must be always stalled together. - usbd_otg->regs->endptctrl[0] = - USB2D_ENDPTCTRL_TX_EP_ENABLE | USB2D_ENDPTCTRL_TX_EP_STALL | - USB2D_ENDPTCTRL_RX_EP_ENABLE | USB2D_ENDPTCTRL_RX_EP_STALL; -} - -int usbd_set_ep_stall(u32 endpoint, int ep_stall) -{ - usb_hw_ep_t actual_ep = (endpoint & 2) >> 1; - usb_dir_t direction = endpoint & 1; - - if (ep_stall) - { - if (direction == USB_DIR_IN) - usbd_otg->regs->endptctrl[actual_ep] |= USB2D_ENDPTCTRL_TX_EP_STALL; // Stall EP Bulk IN. - else - usbd_otg->regs->endptctrl[actual_ep] |= USB2D_ENDPTCTRL_RX_EP_STALL; // Stall EP Bulk OUT. - } - else - { - if (direction == USB_DIR_IN) - usbd_otg->regs->endptctrl[actual_ep] &= ~USB2D_ENDPTCTRL_TX_EP_STALL; // Clear stall EP Bulk IN. - else - usbd_otg->regs->endptctrl[actual_ep] &= ~USB2D_ENDPTCTRL_RX_EP_STALL; // Clear stall EP Bulk OUT. - } - - return USB_RES_OK; -} - -static void _usbd_handle_get_class_request(bool *transmit_data, u8 *descriptor, int *size, bool *ep_stall) -{ - u8 _bRequest = usbd_otg->control_setup.bRequest; - u16 _wIndex = usbd_otg->control_setup.wIndex; - u16 _wValue = usbd_otg->control_setup.wValue; - u16 _wLength = usbd_otg->control_setup.wLength; - - bool valid_interface = _wIndex == usbd_otg->interface_num; - bool valid_len = (_bRequest == USB_REQUEST_BULK_GET_MAX_LUN) ? 1 : 0; - - if (!valid_interface || _wValue != 0 || _wLength != valid_len) - { - *ep_stall = true; - return; - } - - switch (_bRequest) - { - case USB_REQUEST_BULK_RESET: - _usbd_ep_ack(USB_EP_CTRL_IN); - usbd_otg->bulk_reset_req = true; - break; // DELAYED_STATUS; - case USB_REQUEST_BULK_GET_MAX_LUN: - *transmit_data = true; - *size = 1; - descriptor[0] = usbd_otg->max_lun; // Set 0 LUN for 1 drive supported. - usbd_otg->max_lun_set = true; - break; - default: - *ep_stall = true; - break; - } -} - -static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor, int *size, bool *ep_stall) -{ - u8 descriptor_type = usbd_otg->control_setup.wValue >> 8; - u8 descriptor_subtype = usbd_otg->control_setup.wValue & 0xFF; - - switch (descriptor_type) - { - case USB_DESCRIPTOR_DEVICE: - { -/* - u32 soc_rev = APB_MISC(APB_MISC_GP_HIDREV); - usb_device_descriptor.idProduct = (soc_rev >> 8) & 0xFF; // chip_id. - usb_device_descriptor.idProduct |= ((soc_rev << 4) | (FUSE(FUSE_SKU_INFO) & 0xF)) << 8; // HIDFAM. - usb_device_descriptor.bcdDevice = (soc_rev >> 16) & 0xF; // MINORREV. - usb_device_descriptor.bcdDevice |= ((soc_rev >> 4) & 0xF) << 8; // MAJORREV. -*/ - *descriptor = usbd_otg->desc->dev; - *size = usbd_otg->desc->dev->bLength; - *transmit_data = true; - return; - } - case USB_DESCRIPTOR_CONFIGURATION: - if (usbd_otg->gadget == USB_GADGET_UMS) - { - if (usbd_otg->port_speed == USB_HIGH_SPEED) // High speed. 512 bytes. - { - usbd_otg->desc->cfg->endpoint[0].wMaxPacketSize = 0x200; - usbd_otg->desc->cfg->endpoint[1].wMaxPacketSize = 0x200; - } - else // Full speed. 64 bytes. - { - usbd_otg->desc->cfg->endpoint[0].wMaxPacketSize = 0x40; - usbd_otg->desc->cfg->endpoint[1].wMaxPacketSize = 0x40; - } - } - else - { - usb_cfg_hid_descr_t *tmp = (usb_cfg_hid_descr_t *)usbd_otg->desc->cfg; - if (usbd_otg->port_speed == USB_HIGH_SPEED) // High speed. 512 bytes. - { - tmp->endpoint[0].wMaxPacketSize = 0x200; - tmp->endpoint[1].wMaxPacketSize = 0x200; - tmp->endpoint[0].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms. - tmp->endpoint[1].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms. - } - else // Full speed. 64 bytes. - { - tmp->endpoint[0].wMaxPacketSize = 0x40; - tmp->endpoint[1].wMaxPacketSize = 0x40; - tmp->endpoint[0].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms. - tmp->endpoint[1].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms. - } - } - *descriptor = usbd_otg->desc->cfg; - *size = usbd_otg->desc->cfg->config.wTotalLength; - *transmit_data = true; - return; - case USB_DESCRIPTOR_STRING: - switch (descriptor_subtype) - { - case 1: - *descriptor = usbd_otg->desc->vendor; - *size = usbd_otg->desc->vendor[0]; - break; - case 2: - *descriptor = usbd_otg->desc->product; - *size = usbd_otg->desc->product[0]; - break; - case 3: - *descriptor = usbd_otg->desc->serial; - *size = usbd_otg->desc->serial[0]; - break; - case 0xEE: - *descriptor = usbd_otg->desc->ms_os; - *size = usbd_otg->desc->ms_os->bLength; - break; - default: - *descriptor = usbd_otg->desc->lang_id; - *size = 4; - break; - } - *transmit_data = true; - return; - case USB_DESCRIPTOR_DEVICE_QUALIFIER: - if (!usbd_otg->desc->dev_qual) - goto exit; - usbd_otg->desc->dev_qual->bNumOtherConfigs = 1; - *descriptor = usbd_otg->desc->dev_qual; - *size = usbd_otg->desc->dev_qual->bLength; - *transmit_data = true; - return; - case USB_DESCRIPTOR_OTHER_SPEED_CONFIGURATION: - if (!usbd_otg->desc->cfg_other) - goto exit; - if (usbd_otg->port_speed == USB_HIGH_SPEED) - { - usbd_otg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x40; - usbd_otg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x40; - } - else - { - usbd_otg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x200; - usbd_otg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x200; - } - if ((usbd_otg->charger_detect & 1) && (usbd_otg->charger_detect & 2)) - usbd_otg->desc->cfg_other->config.bMaxPower = 500 / 2; - *descriptor = usbd_otg->desc->cfg_other; - *size = usbd_otg->desc->cfg_other->config.wTotalLength; - *transmit_data = true; - return; - case USB_DESCRIPTOR_DEVICE_BINARY_OBJECT: - *descriptor = usbd_otg->desc->dev_bot; - *size = usbd_otg->desc->dev_bot->wTotalLength; - *transmit_data = true; - return; - default: - *transmit_data = false; - *ep_stall = true; - return; - } -exit: - *transmit_data = false; - *ep_stall = true; - return; -} - -static int _usbd_handle_set_request(bool *ep_stall) -{ - int res = USB_RES_OK; - u8 bRequest = usbd_otg->control_setup.bRequest; - if (bRequest == USB_REQUEST_SET_ADDRESS) - { - res = _usbd_ep_ack(USB_EP_CTRL_IN); - - // Set USB address for device mode. - if (!res) - usbd_otg->regs->periodiclistbase = (usbd_otg->regs->periodiclistbase & 0x1FFFFFF) | ((usbd_otg->control_setup.wValue & 0xFF) << 25); - } - else if (bRequest == USB_REQUEST_SET_CONFIGURATION) - { - res = _usbd_ep_ack(USB_EP_CTRL_IN); - if (!res) - { - usbd_otg->config_num = usbd_otg->control_setup.wValue; - _usbd_initialize_ep_ctrl(USB_EP_BULK_OUT); - _usbd_initialize_ep_ctrl(USB_EP_BULK_IN); - usbd_otg->configuration_set = true; - } - } - else - *ep_stall = true; - - return res; -} - -static int _usbd_handle_ep0_control_transfer() -{ - int res = USB_RES_OK; - bool ep_stall = false; - bool transmit_data = false; - - u8 *descriptor = (u8 *)USB_DESCRIPTOR_ADDR; - int size = 0; - - u8 _bmRequestType = usbd_otg->control_setup.bmRequestType; - u8 _bRequest = usbd_otg->control_setup.bRequest; - u16 _wValue = usbd_otg->control_setup.wValue; - u16 _wIndex = usbd_otg->control_setup.wIndex; - u16 _wLength = usbd_otg->control_setup.wLength; - - //gfx_printf("%02X %02X %04X %04X %04X\n", _bmRequestType, _bRequest, _wValue, _wIndex, _wLength); - - switch (_bmRequestType) - { - case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): - res = _usbd_handle_set_request(&ep_stall); - break; - - case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): - res = _usbd_ep_ack(USB_EP_CTRL_IN); - if (!res) - usbd_otg->interface_num = _wValue; - break; - - case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): - switch (_bRequest) - { - case USB_REQUEST_CLEAR_FEATURE: - case USB_REQUEST_SET_FEATURE: - if ((_wValue & 0xFF) == USB_FEATURE_ENDPOINT_HALT) - { - int direction; - switch (_wIndex) // endpoint - { - case USB_EP_ADDR_CTRL_OUT: - direction = 2; - break; - case USB_EP_ADDR_CTRL_IN: - direction = 3; - break; - case USB_EP_ADDR_BULK_OUT: - direction = 0; - break; - case USB_EP_ADDR_BULK_IN: - direction = 1; - break; - default: - _usbd_stall_reset_ep1(3, USB_EP_CFG_STALL); - goto out; - } - - if (_bRequest == USB_REQUEST_CLEAR_FEATURE) - _usbd_stall_reset_ep1(direction, USB_EP_CFG_RESET); - else - _usbd_stall_reset_ep1(direction, USB_EP_CFG_STALL); - - res = _usbd_ep_ack(USB_EP_CTRL_IN); - } - else - _usbd_stall_reset_ep1(3, USB_EP_CFG_STALL); - - break; - default: - ep_stall = true; - break; - } - break; - - case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): - memset(descriptor, 0, _wLength); - _usbd_handle_get_class_request(&transmit_data, descriptor, &size, &ep_stall); - break; - - case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): - switch (_bRequest) - { - case USB_REQUEST_GET_STATUS: - descriptor[0] = USB_STATUS_DEV_SELF_POWERED; - descriptor[1] = 0; // No support for remove wake up. - transmit_data = true; - size = 2; - break; - case USB_REQUEST_GET_DESCRIPTOR: - _usbd_handle_get_descriptor(&transmit_data, (void **)&descriptor, &size, &ep_stall); - break; - case USB_REQUEST_GET_CONFIGURATION: - descriptor = (u8 *)&usbd_otg->config_num; - size = _wLength; - transmit_data = true; - break; - default: - ep_stall = true; - break; - } - break; - - case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): - if (_bRequest == USB_REQUEST_GET_INTERFACE) - { - memset(descriptor, 0, _wLength); - descriptor[0] = usbd_otg->interface_num; - size = _wLength; - } - else if (_bRequest == USB_REQUEST_GET_STATUS) - { - memset(descriptor, 0, _wLength); - size = _wLength; - } - else if (_bRequest == USB_REQUEST_GET_DESCRIPTOR && (_wValue >> 8) == USB_DESCRIPTOR_HID_REPORT && usbd_otg->gadget > USB_GADGET_UMS) - { - if (usbd_otg->gadget == USB_GADGET_HID_GAMEPAD) - { - descriptor = (u8 *)&hid_report_descriptor_jc; - size = hid_report_descriptor_jc_size; - } - else // USB_GADGET_HID_TOUCHPAD - { - descriptor = (u8 *)&hid_report_descriptor_touch; - size = hid_report_descriptor_touch_size; - } - - usbd_otg->hid_report_sent = true; - } - else - { - ep_stall = true; - break; - } - - if (_wLength < size) - size = _wLength; - transmit_data = true; - break; - - case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): - if (_bRequest == USB_REQUEST_GET_STATUS) - { - int ep_req; - switch (_wIndex) - { - case USB_EP_ADDR_CTRL_OUT: - ep_req = USB_EP_CTRL_OUT; - break; - case USB_EP_ADDR_BULK_OUT: - ep_req = USB_EP_BULK_OUT; - break; - case USB_EP_ADDR_CTRL_IN: - ep_req = USB_EP_CTRL_IN; - break; - case USB_EP_ADDR_BULK_IN: - ep_req = USB_EP_BULK_IN; - break; - default: - _usbd_stall_reset_ep1(3, USB_EP_CFG_STALL); - goto out; - } - - size = _wLength; - memset(descriptor, 0, size); - - if (_usbd_get_ep_status(ep_req) == USB_EP_STATUS_STALLED) - descriptor[0] = USB_STATUS_EP_HALTED; - else - descriptor[0] = USB_STATUS_EP_OK; - - transmit_data = true; - } - else - _usbd_stall_reset_ep1(3, USB_EP_CFG_STALL); - break; - - case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): - memset(descriptor, 0, _wLength); - _usbd_handle_get_class_request(&transmit_data, descriptor, &size, &ep_stall); - break; - - case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE): - case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE): - if (_bRequest == USB_REQUEST_GET_MS_DESCRIPTOR) - { - switch (_wIndex) - { - case USB_DESCRIPTOR_MS_COMPAT_ID: - descriptor = (u8 *)usbd_otg->desc->ms_cid; - size = usbd_otg->desc->ms_cid->dLength; - transmit_data = true; - break; - case USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES: - descriptor = (u8 *)usbd_otg->desc->mx_ext; - size = usbd_otg->desc->mx_ext->dLength; - transmit_data = true; - break; - default: - ep_stall = true; - break; - } - } - else - ep_stall = true; - break; - - default: - ep_stall = true; - break; - } - - // Transmit data to HOST if any. - if (transmit_data) - { - memcpy(usb_ep0_ctrl_buf, descriptor, size); - - if (_wLength < size) - size = _wLength; - res = _usbd_ep_operation(USB_EP_CTRL_IN, usb_ep0_ctrl_buf, size, USB_XFER_SYNCED_ENUM); - if (!res) - res = _usbd_ep_ack(USB_EP_CTRL_OUT); - } - -out: - if (ep_stall) - _usbd_set_ep0_stall(); - - return res; -} - -static int _usbd_ep0_initialize() -{ - bool enter = false; - if (usbd_otg->configuration_set) - enter = true; - else - { - usbdaemon->qhs = (volatile dQH_t *)USB2_QH_USB2D_QH_EP_BASE; - - if (!_usbd_initialize_ep0()) - enter = true; - } - - if (enter) - { - usbd_otg->configuration_set = false; - usbd_otg->max_lun_set = false; - - // Timeout if cable or communication isn't started in 1.5 minutes. - u32 timer = get_tmr_ms() + 90000; - while (true) - { - u32 usb_status_irqs = usbd_otg->regs->usbsts; - - // Clear all interrupt statuses. - usbd_otg->regs->usbsts = usb_status_irqs; - - // Check if a reset was received. - if (usb_status_irqs & USB2D_USBSTS_URI) - { - //_disable_usb_wdt4(); - - // Clear all device addresses, enabled setup requests, transmit events and flush all endpoints. - usbd_otg->regs->periodiclistbase = 0; - usbd_otg->regs->endptsetupstat = usbd_otg->regs->endptsetupstat; - usbd_otg->regs->endptcomplete = usbd_otg->regs->endptcomplete; - usbd_flush_endpoint(USB_EP_ALL); - } - - // Check if port change happened. - if (usb_status_irqs & USB2D_USBSTS_PCI) - usbd_otg->port_speed = (usbd_otg->regs->hostpc1_devlc & USB2D_HOSTPC1_DEVLC_PSPD_MASK) >> 25; - - // Acknowledge setup request for EP0 and copy its configuration. - u32 ep0_setup_req = usbd_otg->regs->endptsetupstat; - if (ep0_setup_req & 1) - { - usbd_otg->regs->endptsetupstat = ep0_setup_req; - memcpy(&usbd_otg->control_setup, (void *)usbdaemon->qhs->setup, 8); - if (_usbd_handle_ep0_control_transfer()) - break; - } - if (usbd_otg->configuration_set) - return USB_RES_OK; - - if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) - return USB_ERROR_USER_ABORT; - } - } - - return USB_ERROR_TIMEOUT; -} - -int usb_device_enumerate(usb_gadget_type gadget) -{ - switch (gadget) - { - case USB_GADGET_UMS: - usbd_otg->desc = &usb_gadget_ums_descriptors; - break; - case USB_GADGET_HID_GAMEPAD: - usbd_otg->desc = &usb_gadget_hid_jc_descriptors; - break; - case USB_GADGET_HID_TOUCHPAD: - usbd_otg->desc = &usb_gadget_hid_touch_descriptors; - break; - } - - usbd_otg->gadget = gadget; - - return _usbd_ep0_initialize(); -} - -int usbd_handle_ep0_ctrl_setup() -{ - // Acknowledge setup request for EP0 and copy its configuration. - u32 ep0_setup_req = usbd_otg->regs->endptsetupstat; - if (ep0_setup_req & 1) - { - usbd_otg->regs->endptsetupstat = ep0_setup_req; - memcpy(&usbd_otg->control_setup, (void *)usbdaemon->qhs->setup, 8); - _usbd_handle_ep0_control_transfer(); - memset(usb_ep0_ctrl_buf, 0, USB_TD_BUFFER_PAGE_SIZE); - } - - // Only return error if bulk reset was requested. - if (usbd_otg->bulk_reset_req) - { - usbd_otg->bulk_reset_req = false; - return USB_RES_BULK_RESET; - } - - return USB_RES_OK; -} - -static usb_ep_status_t _usbd_get_ep1_status(usb_dir_t dir) -{ - usb_ep_t ep; - if (dir == USB_DIR_OUT) - ep = USB_EP_BULK_OUT; - else - ep = USB_EP_BULK_IN; - return _usbd_get_ep_status(ep); -} - -int usb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, u32 sync_timeout) -{ - if ((u32)buf % USB_EP_BUFFER_ALIGN) - return USB2_ERROR_XFER_NOT_ALIGNED; - - if (len > USB_EP_BUFFER_MAX_SIZE) - len = USB_EP_BUFFER_MAX_SIZE; - - int res = _usbd_ep_operation(USB_EP_BULK_OUT, buf, len, sync_timeout); - - if (sync_timeout && bytes_read) - *bytes_read = res ? 0 : len; - - return res; -} - -int usb_device_ep1_out_read_big(u8 *buf, u32 len, u32 *bytes_read) -{ - if ((u32)buf % USB_EP_BUFFER_ALIGN) - return USB2_ERROR_XFER_NOT_ALIGNED; - - if (len > USB_EP_BULK_OUT_MAX_XFER) - len = USB_EP_BULK_OUT_MAX_XFER; - - int res; - u32 bytes = 0; - *bytes_read = 0; - u8 *buf_curr = buf; - - while (len) - { - u32 len_ep = MIN(len, USB_EP_BUFFER_MAX_SIZE); - - res = usb_device_ep1_out_read(buf_curr, len_ep, &bytes, USB_XFER_SYNCED_DATA); - if (res) - return res; - - len -= len_ep; - buf_curr += len_ep; - *bytes_read = *bytes_read + bytes; - } - - return USB_RES_OK; -} - -static int _usbd_get_ep1_out_bytes_read() -{ - if (_usbd_get_ep_status(USB_EP_BULK_OUT) != USB_EP_STATUS_IDLE) - return 0; - else - 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) -{ - usb_ep_status_t ep_status; - do - { - ep_status = _usbd_get_ep1_status(USB_DIR_OUT); - if ((ep_status == USB_EP_STATUS_IDLE) || (ep_status == USB_EP_STATUS_DISABLED)) - break; - - usbd_handle_ep0_ctrl_setup(); - } - while ((ep_status == USB_EP_STATUS_ACTIVE) || (ep_status == USB_EP_STATUS_STALLED)); - - *pending_bytes = _usbd_get_ep1_out_bytes_read(); - - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); - - if (ep_status == USB_EP_STATUS_IDLE) - return USB_RES_OK; - else if (ep_status == USB_EP_STATUS_DISABLED) - return USB2_ERROR_XFER_EP_DISABLED; - else - return USB_ERROR_XFER_ERROR; -} - -int usb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, u32 sync_timeout) -{ - if ((u32)buf % USB_EP_BUFFER_ALIGN) - return USB2_ERROR_XFER_NOT_ALIGNED; - - if (len > USB_EP_BUFFER_MAX_SIZE) - len = USB_EP_BUFFER_MAX_SIZE; - - int res = _usbd_ep_operation(USB_EP_BULK_IN, buf, len, sync_timeout); - - if (sync_timeout && bytes_written) - *bytes_written = res ? 0 : len; - - return res; -} - -static int _usbd_get_ep1_in_bytes_written() -{ - if (_usbd_get_ep_status(USB_EP_BULK_IN) != USB_EP_STATUS_IDLE) - return 0; - else - 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) -{ - usb_ep_status_t ep_status; - do - { - ep_status = _usbd_get_ep1_status(USB_DIR_IN); - if ((ep_status == USB_EP_STATUS_IDLE) || (ep_status == USB_EP_STATUS_DISABLED)) - break; - - usbd_handle_ep0_ctrl_setup(); - } - while ((ep_status == USB_EP_STATUS_ACTIVE) || (ep_status == USB_EP_STATUS_STALLED)); - - *pending_bytes = _usbd_get_ep1_in_bytes_written(); - - if (ep_status == USB_EP_STATUS_IDLE) - return USB_RES_OK; - else if (ep_status == USB_EP_STATUS_DISABLED) - return USB2_ERROR_XFER_EP_DISABLED; - - usb_device_stall_ep1_bulk_out(); - return USB_ERROR_XFER_ERROR; -} - -bool usb_device_get_suspended() -{ - bool suspended = (usbd_otg->regs->portsc1 & USB2D_PORTSC1_SUSP) == USB2D_PORTSC1_SUSP; - return suspended; -} - -bool usb_device_get_port_in_sleep() -{ - // Windows heuristic: Forces port into suspend, sleep and J-State. - return (usbd_otg->regs->portsc1) == 0x885; -} - -int usb_device_class_send_max_lun(u8 max_lun) -{ - // Timeout if get MAX_LUN request doesn't happen in 10s. - u32 timer = get_tmr_ms() + 10000; - - usbd_otg->max_lun = max_lun; - - while (!usbd_otg->max_lun_set) - { - usbd_handle_ep0_ctrl_setup(); - if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) - return USB_ERROR_USER_ABORT; - } - - return USB_RES_OK; -} - -int usb_device_class_send_hid_report() -{ - // Timeout if get GET_HID_REPORT request doesn't happen in 10s. - u32 timer = get_tmr_ms() + 10000; - - // Wait for request and transfer start. - while (!usbd_otg->hid_report_sent) - { - usbd_handle_ep0_ctrl_setup(); - if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) - return USB_ERROR_USER_ABORT; - } - - return USB_RES_OK; -} - -void usb_device_get_ops(usb_ops_t *ops) -{ - ops->usbd_flush_endpoint = usbd_flush_endpoint; - ops->usbd_set_ep_stall = usbd_set_ep_stall; - ops->usbd_handle_ep0_ctrl_setup = usbd_handle_ep0_ctrl_setup; - ops->usbd_end = usbd_end; - ops->usb_device_init = usb_device_init; - ops->usb_device_enumerate = usb_device_enumerate; - ops->usb_device_class_send_max_lun = usb_device_class_send_max_lun; - ops->usb_device_class_send_hid_report = usb_device_class_send_hid_report; - ops->usb_device_get_suspended = usb_device_get_suspended; - ops->usb_device_get_port_in_sleep = usb_device_get_port_in_sleep; - - ops->usb_device_ep1_out_read = usb_device_ep1_out_read; - ops->usb_device_ep1_out_read_big = usb_device_ep1_out_read_big; - ops->usb_device_ep1_out_reading_finish = usb_device_ep1_out_reading_finish; - ops->usb_device_ep1_in_write = usb_device_ep1_in_write; - ops->usb_device_ep1_in_writing_finish = usb_device_ep1_in_writing_finish; -} - diff --git a/bdk/usb/usbd.h b/bdk/usb/usbd.h deleted file mode 100644 index a0e4a63..0000000 --- a/bdk/usb/usbd.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Enhanced & eXtensible USB Device (EDCI & XDCI) driver for Tegra X1 - * - * Copyright (c) 2019 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 _USB_H_ -#define _USB_H_ - -#include - -#define USB_TD_BUFFER_PAGE_SIZE 0x1000 -#define USB_TD_BUFFER_MAX_SIZE (USB_TD_BUFFER_PAGE_SIZE * 4) -//#define USB_HW_BUFFER_5_PAGES 0x5000 -#define USB_EP_BUFFER_1_TD (USB_TD_BUFFER_MAX_SIZE) -#define USB_EP_BUFFER_2_TD (USB_TD_BUFFER_MAX_SIZE * 2) -#define USB_EP_BUFFER_4_TD (USB_TD_BUFFER_MAX_SIZE * 4) -#define USB_EP_BUFFER_MAX_SIZE (USB_EP_BUFFER_4_TD) -#define USB_EP_BUFFER_ALIGN (USB_TD_BUFFER_PAGE_SIZE) - -#define USB_XFER_START 0 -#define USB_XFER_SYNCED_ENUM 1000000 -#define USB_XFER_SYNCED_CMD 1000000 -#define USB_XFER_SYNCED_DATA 2000000 -#define USB_XFER_SYNCED_CLASS 5000000 -#define USB_XFER_SYNCED -1 - -typedef enum _usb_hid_type -{ - USB_HID_GAMEPAD, - USB_HID_TOUCHPAD -} usb_hid_type; - -typedef enum _usb_gadget_type -{ - USB_GADGET_UMS = 0, - USB_GADGET_HID_GAMEPAD = 1, - USB_GADGET_HID_TOUCHPAD = 2, -} usb_gadget_type; - -typedef enum { - USB_DIR_OUT = 0, - USB_DIR_IN = 1, -} usb_dir_t; - -typedef enum -{ - XUSB_EP_CTRL_IN = 0, // EP0. - XUSB_EP_CTRL_OUT = 1, // EP0. - - USB_EP_CTRL_OUT = 0, // EP0. - USB_EP_CTRL_IN = 1, // EP0. - - USB_EP_BULK_OUT = 2, // EP1. - USB_EP_BULK_IN = 3, // EP1. - USB_EP_ALL = 0xFFFFFFFF -} usb_ep_t; - -typedef enum -{ - USB_EP_ADDR_CTRL_OUT = 0x00, - USB_EP_ADDR_CTRL_IN = 0x80, - USB_EP_ADDR_BULK_OUT = 0x01, - USB_EP_ADDR_BULK_IN = 0x81, -} usb_ep_addr_t; - -typedef enum -{ - USB_EP_CFG_CLEAR = 0, - USB_EP_CFG_RESET = 0, - USB_EP_CFG_STALL = 1 -} usb_ep_cfg_t; - -typedef enum { - USB_STATUS_EP_OK = 0, - USB_STATUS_EP_HALTED = 1, - - USB_STATUS_DEV_SELF_POWERED = 1, - USB_STATUS_DEV_REMOTE_WAKE = 2, -} usb_set_clear_feature_req_t; - -typedef enum { - USB_SETUP_RECIPIENT_DEVICE = 0, - USB_SETUP_RECIPIENT_INTERFACE = 1, - USB_SETUP_RECIPIENT_ENDPOINT = 2, - USB_SETUP_RECIPIENT_OTHER = 3, - - USB_SETUP_TYPE_STANDARD = 0x00, - USB_SETUP_TYPE_CLASS = 0x20, - USB_SETUP_TYPE_VENDOR = 0x40, - USB_SETUP_TYPE_RESERVED = 0x60, - - USB_SETUP_HOST_TO_DEVICE = 0x00, - USB_SETUP_DEVICE_TO_HOST = 0x80, -} usb_setup_req_type_t; - -typedef enum { - USB_REQUEST_GET_STATUS = 0, - USB_REQUEST_CLEAR_FEATURE = 1, - USB_REQUEST_SET_FEATURE = 3, - USB_REQUEST_SET_ADDRESS = 5, - USB_REQUEST_GET_DESCRIPTOR = 6, - USB_REQUEST_SET_DESCRIPTOR = 7, - USB_REQUEST_GET_CONFIGURATION = 8, - USB_REQUEST_SET_CONFIGURATION = 9, - USB_REQUEST_GET_INTERFACE = 10, - USB_REQUEST_SET_INTERFACE = 11, - USB_REQUEST_SYNCH_FRAME = 12, - USB_REQUEST_SET_SEL = 13, - - USB_REQUEST_GET_MS_DESCRIPTOR = 0x99, - - USB_REQUEST_BULK_GET_MAX_LUN = 0xFE, - USB_REQUEST_BULK_RESET = 0xFF -} usb_standard_req_t; - -typedef enum { - USB_FEATURE_ENDPOINT_HALT = 0, - USB_FEATURE_DEVICE_REMOTE_WAKEUP = 1, - USB_FEATURE_TEST_MODE = 2, -} usb_get_status_req_t; - -typedef enum _usb_error_t -{ - USB_RES_OK = 0, - USB_RES_BULK_RESET = 1, - - USB_ERROR_USER_ABORT = 2, - USB_ERROR_TIMEOUT = 3, - USB_ERROR_INIT = 4, - USB_ERROR_XFER_ERROR = 5, - - USB2_ERROR_XFER_EP_DISABLED = 28, - USB2_ERROR_XFER_NOT_ALIGNED = 29, - - 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_SEQ_NUM = 51, - XUSB_ERROR_XFER_DIR = 52, - XUSB_ERROR_PORT_CFG = 54 -} usb_error_t; - -typedef struct _usb_ctrl_setup_t -{ - u8 bmRequestType; - u8 bRequest; - u16 wValue; - u16 wIndex; - u16 wLength; -} usb_ctrl_setup_t; - -typedef struct _usb_ops_t -{ - int (*usbd_flush_endpoint)(u32); - int (*usbd_set_ep_stall)(u32, int); - int (*usbd_handle_ep0_ctrl_setup)(); - void (*usbd_end)(bool, bool); - int (*usb_device_init)(); - int (*usb_device_enumerate)(usb_gadget_type gadget); - int (*usb_device_class_send_max_lun)(u8); - int (*usb_device_class_send_hid_report)(); - - 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_in_write)(u8 *, u32, u32 *, u32); - int (*usb_device_ep1_in_writing_finish)(u32 *); - bool (*usb_device_get_suspended)(); - bool (*usb_device_get_port_in_sleep)(); -} usb_ops_t; - -typedef struct _usb_ctxt_t -{ - u32 type; - u32 partition; - u32 offset; - u32 sectors; - u32 ro; - void (*system_maintenance)(bool); - void *label; - void (*set_text)(void *, const char *); -} usb_ctxt_t; - -void usb_device_get_ops(usb_ops_t *ops); -void xusb_device_get_ops(usb_ops_t *ops); - -int usb_device_gadget_ums(usb_ctxt_t *usbs); -int usb_device_gadget_hid(usb_ctxt_t *usbs); - -#endif \ No newline at end of file diff --git a/bdk/usb/xusbd.c b/bdk/usb/xusbd.c deleted file mode 100644 index 4beefcd..0000000 --- a/bdk/usb/xusbd.c +++ /dev/null @@ -1,2026 +0,0 @@ -/* - * eXtensible USB Device driver (XDCI) for Tegra X1 - * - * Copyright (c) 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 . - */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define XUSB_TRB_SLOTS 16 //! TODO: Consider upping it. -#define XUSB_LINK_TRB_IDX (XUSB_TRB_SLOTS - 1) -#define XUSB_LAST_TRB_IDX (XUSB_TRB_SLOTS - 1) - -#define EP_DONT_RING 0 -#define EP_RING_DOORBELL 1 - -typedef enum { - XUSB_FULL_SPEED = 1, - XUSB_HIGH_SPEED = 3, - XUSB_SUPER_SPEED = 4 -} xusb_speed_t; - -typedef enum { - EP_DISABLED = 0, - EP_RUNNING = 1, - EP_HALTED = 2, - EP_STOPPED = 3, - EP_ERROR = 4 -} xusb_ep_status_t; - -typedef enum { - EP_TYPE_ISOC_OUT = 1, - EP_TYPE_BULK_OUT = 2, - EP_TYPE_INTR_OUT = 3, - EP_TYPE_CNTRL = 4, - EP_TYPE_ISOC_IN = 5, - EP_TYPE_BULK_IN = 6, - EP_TYPE_INTR_IN = 7 -} xusb_ep_type_t; - -typedef enum { - XUSB_DEFAULT = 0, - XUSB_ADDRESSED_STS_WAIT = 1, - XUSB_ADDRESSED = 2, - XUSB_CONFIGURED_STS_WAIT = 3, - XUSB_CONFIGURED = 4, - - XUSB_LUN_CONFIGURED_STS_WAIT = 5, - XUSB_LUN_CONFIGURED = 6, - XUSB_HID_CONFIGURED_STS_WAIT = 7, - XUSB_HID_CONFIGURED = 8, - - // XUSB_CONNECTED = , - // XUSB_DISCONNECTED = , - // XUSB_RESET = , - // XUSB_SUSPENDED = , -} xusb_dev_state_t; - -typedef enum { - XUSB_TRB_NONE = 0, - XUSB_TRB_NORMAL = 1, - XUSB_TRB_DATA = 3, - XUSB_TRB_STATUS = 4, - XUSB_TRB_LINK = 6, - XUSB_TRB_TRANSFER = 32, - XUSB_TRB_PORT_CHANGE = 34, - XUSB_TRB_SETUP = 63, -} xusb_trb_type_t; - -typedef enum { - XUSB_COMP_INVALID = 0, - XUSB_COMP_SUCCESS = 1, - XUSB_COMP_DATA_BUFFER_ERROR = 2, - XUSB_COMP_BABBLE_DETECTED_ERROR = 3, - XUSB_COMP_USB_TRANSACTION_ERROR = 4, - XUSB_COMP_TRB_ERROR = 5, - XUSB_COMP_STALL_ERROR = 6, - XUSB_COMP_RESOURCE_ERROR = 7, - XUSB_COMP_BANDWIDTH_ERROR = 8, - XUSB_COMP_NO_SLOTS_AVAILABLE_ERROR = 9, - XUSB_COMP_INVALID_STREAM_TYPE_ERROR = 10, - XUSB_COMP_SLOT_NOT_ENABLED_ERROR = 11, - XUSB_COMP_EP_DISABLED_ERROR = 12, - XUSB_COMP_SHORT_PKT = 13, - XUSB_COMP_RING_UNDERRUN = 14, - XUSB_COMP_RING_OVERRUN = 15, - XUSB_COMP_VF_EVENT_RING_FULL_ERROR = 16, - XUSB_COMP_PARAMETER_ERROR = 17, - XUSB_COMP_BANDWIDTH_OVERRUN_ERROR = 18, - XUSB_COMP_CONTEXT_STATE_ERROR = 19, - XUSB_COMP_NO_PING_RESPONSE_ERROR = 20, - XUSB_COMP_EVENT_RING_FULL_ERROR = 21, - XUSB_COMP_INCOMPATIBLE_DEVICE_ERROR = 22, - XUSB_COMP_MISSED_SERVICE_ERROR = 23, - XUSB_COMP_COMMAND_RING_STOPPED = 24, - XUSB_COMP_COMMAND_ABORTED = 25, - XUSB_COMP_STOPPED = 26, - XUSB_COMP_STOPPED_LENGTH_INVALID = 27, - XUSB_COMP_STOPPED_SHORT_PACKET = 28, - XUSB_COMP_EXIT_LATENCY_LARGE_ERROR = 29, - XUSB_COMP_ISOCH_BUFFER_OVERRUN = 31, - XUSB_COMP_EVENT_LOST_ERROR = 32, - XUSB_COMP_UNDEFINED_ERROR = 33, - XUSB_COMP_INVALID_STREAM_ID_ERROR = 34, - XUSB_COMP_SECONDARY_BANDWIDTH_ERROR = 35, - XUSB_COMP_SPLIT_TRANSACTION_ERROR = 36, - - XUSB_COMP_CODE_STREAM_NUMP_ERROR = 219, - XUSB_COMP_PRIME_PIPE_RECEIVED = 220, - XUSB_COMP_HOST_REJECTED = 221, - XUSB_COMP_CTRL_DIR_ERROR = 222, - XUSB_COMP_CTRL_SEQ_NUM_ERROR = 223 -} xusb_comp_code_t; - -typedef struct _event_trb_t -{ - u32 rsvd0; - u32 rsvd1; - - u32 rsvd2:24; - u32 comp_code:8; - - u32 cycle:1; - u32 rsvd3:9; - u32 trb_type:6; - u32 ep_id:5; - u32 rsvd4:11; -} event_trb_t; - -typedef struct _transfer_event_trb_t { - u32 trb_pointer_lo; - u32 trb_pointer_hi; - - u32 trb_tx_len:24; - u32 comp_code:8; - - u32 cycle:1; - u32 rsvddw3_0:1; - u32 event_data:1; - u32 rsvddw3_1:7; - u32 trb_type:6; - u32 ep_id:5; - u32 rsvddw3_2:11; -} transfer_event_trb_t; - -typedef struct _setup_event_trb_t -{ - usb_ctrl_setup_t ctrl_setup_data; - - u32 ctrl_seq_num:16; - u32 rsvddw2_0:8; - u32 comp_code:8; - - u32 cycle:1; - u32 rsvddw3_0:9; - u32 trb_type:6; - u32 ep_id:5; - u32 rsvddw3_1:11; -} setup_event_trb_t; - -typedef struct _status_trb_t -{ - u32 rsvd0; - u32 rsvd1; - - u32 rsvd2:22; - u32 interrupt_target:10; - - u32 cycle:1; - u32 ent:1; - u32 rsvd3_0:2; - u32 chain:1; - u32 ioc:1; - u32 rsvd3_1:4; - u32 trb_type:6; - u32 dir:1; - u32 rsvd3_2:15; -} status_trb_t; - -typedef struct _normal_trb_t -{ - u32 databufptr_lo; - u32 databufptr_hi; - - u32 trb_tx_len:17; - u32 td_size:5; - u32 interrupt_target:10; - - u32 cycle:1; - u32 ent:1; - u32 isp:1; - u32 no_snoop:1; - u32 chain:1; - u32 ioc:1; - u32 idt:1; - u32 rsvd0_0:2; - u32 bei:1; - u32 trb_type:6; - u32 rsvd0_1:16; -} normal_trb_t; - -typedef struct _data_trb_t -{ - u32 databufptr_lo; - u32 databufptr_hi; - - u32 trb_tx_len:17; - u32 td_size:5; - u32 interrupt_target:10; - - u32 cycle:1; - u32 ent:1; - u32 isp:1; - u32 no_snoop:1; - u32 chain:1; - u32 ioc:1; - u32 rsvd0_0:4; - u32 trb_type:6; - u32 dir:1; - u32 rsvd0_1:15; -} data_trb_t; - -typedef struct _link_trb_t -{ - u32 rsvd0_0:4; - u32 ring_seg_ptrlo:28; - - u32 ring_seg_ptrhi; - - u32 rsvd1_0:22; - u32 interrupt_target:10; - - u32 cycle:1; - u32 toggle_cycle:1; - u32 rsvd3_0:2; - u32 chain:1; - u32 ioc:1; - u32 rsvd3_1:4; - u32 trb_type:6; - u32 rsvd3_2:16; -} link_trb_t; - -typedef struct _xusb_ep_ctx_t -{ - // Common context. - u32 ep_state:3; - u32 rsvddW0_0:5; - u32 mult:2; - u32 max_pstreams:5; - u32 lsa:1; - u32 interval:8; - u32 rsvddW0_1:8; - - u32 rsvddw1_0:1; - u32 cerr:2; - u32 ep_type:3; - u32 rsvddw1_1:1; - u32 hid:1; - u32 max_burst_size:8; - u32 max_packet_size:16; - - u32 dcs:1; - u32 rsvddw2_0:3; - u32 trd_dequeueptr_lo:28; - - u32 trd_dequeueptr_hi; - - u32 avg_trb_len:16; - u32 max_esit_payload:16; - - // Nvidia context. - u32 event_data_txlen_acc; - - u32 cprog:8; - u32 sbyte:7; - u32 tp:2; - u32 rec:1; - u32 cec:2; - u32 ced:1; - u32 hsp1:1; - u32 rty1:1; - u32 std:1; - u32 status:8; - - u32 data_offset; - - u32 scratch_pad0; - - u32 scratch_pad1; - - u32 cping:8; - u32 sping:8; - u32 toggle_cycle:2; - u32 no_snoop:1; - u32 ro:1; - u32 tlm:1; - u32 dlm:1; - u32 hsp2:1; - u32 rty2:1; - u32 stop_rec_req:8; - - u32 device_addr:8; - u32 hub_addr:8; - u32 root_port_num:8; - u32 slot_id:8; - - u32 routing_string:20; - u32 speed:4; - u32 lpu:1; - u32 mtt:1; - u32 hub:1; - u32 dci:5; - - u32 tthub_slot_id:8; - u32 ttport_num:8; - u32 ssf:4; - u32 sps:2; - u32 interrupt_target:10; - - u32 frz:1; - u32 end:1; - u32 elm:1; - u32 mrx:1; - u32 ep_linklo:28; - - u32 ep_linkhi; -} xusb_ep_ctx_t; - -typedef struct _xusbd_controller_t -{ - data_trb_t *cntrl_epenqueue_ptr; - data_trb_t *cntrl_epdequeue_ptr; - u32 cntrl_producer_cycle; - data_trb_t *bulkout_epenqueue_ptr; - data_trb_t *bulkout_epdequeue_ptr; - u32 bulkout_producer_cycle; - data_trb_t *bulkin_epenqueue_ptr; - data_trb_t *bulkin_epdequeue_ptr; - u32 bulkin_producer_cycle; - event_trb_t *event_enqueue_ptr; - event_trb_t *event_dequeue_ptr; - u32 event_ccs; - u32 device_state; - u32 bytes_remaining[2]; - u32 tx_count[2]; - u32 ctrl_seq_num; - u32 config_num; - u32 interface_num; - u32 wait_for_event_trb; - u32 port_speed; - - usb_desc_t *desc; - usb_gadget_type gadget; - - u8 max_lun; - bool max_lun_set; - bool bulk_reset_req; -} xusbd_controller_t; - -extern u32 hid_report_descriptor_jc_size; -extern u32 hid_report_descriptor_touch_size; -extern u8 hid_report_descriptor_jc[]; -extern u8 hid_report_descriptor_touch[]; -extern usb_desc_t usb_gadget_hid_jc_descriptors; -extern usb_desc_t usb_gadget_hid_touch_descriptors; -extern usb_desc_t usb_gadget_ums_descriptors; - -// All rings and EP context must be aligned to 0x10. -typedef struct _xusbd_event_queues_t -{ - event_trb_t xusb_event_ring_seg0[XUSB_TRB_SLOTS]; - event_trb_t xusb_event_ring_seg1[XUSB_TRB_SLOTS]; - data_trb_t xusb_cntrl_event_queue[XUSB_TRB_SLOTS]; - data_trb_t xusb_bulkin_event_queue[XUSB_TRB_SLOTS]; - data_trb_t xusb_bulkout_event_queue[XUSB_TRB_SLOTS]; - volatile xusb_ep_ctx_t xusb_ep_ctxt[4]; -} xusbd_event_queues_t; - -// Set event queues context to a 0x10 aligned address. -xusbd_event_queues_t *xusb_evtq = (xusbd_event_queues_t *)XUSB_RING_ADDR; - -xusbd_controller_t *usbd_xotg; -xusbd_controller_t usbd_xotg_controller_ctxt; - -static int _xusb_xhci_mask_wait(u32 reg, u32 mask, u32 val, u32 retries) -{ - do - { - if ((XUSB_DEV_XHCI(reg) & mask) == val) - return USB_RES_OK; - usleep(1); - --retries; - } - while (retries); - - return USB_ERROR_TIMEOUT; -} - -// Event rings aligned to 0x10 -static void _xusbd_ep_init_event_ring() -{ - memset(xusb_evtq->xusb_event_ring_seg0, 0, sizeof(xusb_evtq->xusb_event_ring_seg0)); - memset(xusb_evtq->xusb_event_ring_seg1, 0, sizeof(xusb_evtq->xusb_event_ring_seg1)); - - //! TODO USB3: enable pcie regulators. - - // Set Event Ring Segment 0 Base Address. - XUSB_DEV_XHCI(XUSB_DEV_XHCI_ERST0BALO) = (u32)xusb_evtq->xusb_event_ring_seg0; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_ERST0BAHI) = 0; - - // Set Event Ring Segment 1 Base Address. - XUSB_DEV_XHCI(XUSB_DEV_XHCI_ERST1BALO) = (u32)xusb_evtq->xusb_event_ring_seg1; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_ERST1BAHI) = 0; - - // Set Event Ring Segment sizes. - XUSB_DEV_XHCI(XUSB_DEV_XHCI_ERSTSZ) = (XUSB_TRB_SLOTS << 16) | XUSB_TRB_SLOTS; - - // Set Enqueue and Dequeue pointers. - usbd_xotg->event_enqueue_ptr = xusb_evtq->xusb_event_ring_seg0; - usbd_xotg->event_dequeue_ptr = xusb_evtq->xusb_event_ring_seg0; - usbd_xotg->event_ccs = 1; - - // Event Ring Enqueue Pointer. - u32 evt_ring_addr = (u32)xusb_evtq->xusb_event_ring_seg0 & 0xFFFFFFF0; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_EREPLO) = (XUSB_DEV_XHCI(XUSB_DEV_XHCI_EREPLO) & 0xE) | evt_ring_addr | XCHI_ECS; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_EREPHI) = 0; - - // Set Event Ring Dequeue Pointer. - XUSB_DEV_XHCI(XUSB_DEV_XHCI_ERDPLO) = (XUSB_DEV_XHCI(XUSB_DEV_XHCI_ERDPLO) & 0xF) | evt_ring_addr; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_ERDPHI) = 0; -} - -static void _xusb_ep_set_type_and_metrics(u32 ep_idx, volatile xusb_ep_ctx_t *ep_ctxt) -{ - usb_ep_descr_t *ep_desc = NULL; - usb_ep_descr_t *endpoints = usbd_xotg->desc->cfg->endpoint; - - switch (ep_idx) - { - case XUSB_EP_CTRL_IN: - // Set EP type. - ep_ctxt->ep_type = EP_TYPE_CNTRL; - - // Set max packet size based on port speed. - ep_ctxt->avg_trb_len = 8; - ep_ctxt->max_packet_size = 64; //! TODO USB3: max_packet_size = 512. - break; - - case USB_EP_BULK_OUT: - // Set default EP type. - ep_ctxt->ep_type = EP_TYPE_BULK_OUT; - - // Check configuration descriptor. - if (usbd_xotg->desc->cfg->interface.bInterfaceClass == 0x3) // HID Class. - endpoints = (usb_ep_descr_t *)((void *)endpoints + sizeof(usb_hid_descr_t)); - - for (u32 i = 0; i < usbd_xotg->desc->cfg->interface.bNumEndpoints; i++) - if (endpoints[i].bEndpointAddress == USB_EP_ADDR_BULK_OUT) - { - ep_desc = &endpoints[i]; - break; - } - - // Set actual EP type. - if (ep_desc) - { - switch (ep_desc->bmAttributes) - { - case USB_EP_TYPE_ISO: - ep_ctxt->ep_type = EP_TYPE_ISOC_OUT; - break; - case USB_EP_TYPE_BULK: - ep_ctxt->ep_type = EP_TYPE_BULK_OUT; - break; - case USB_EP_TYPE_INTR: - ep_ctxt->ep_type = EP_TYPE_INTR_OUT; - break; - } - } - - // Set average TRB length. - //TODO: Use ep type instead (we don't expect to calculate avg per gadget)? - switch (usbd_xotg->gadget) - { - case USB_GADGET_UMS: - ep_ctxt->avg_trb_len = 3072; - break; - case USB_GADGET_HID_GAMEPAD: - case USB_GADGET_HID_TOUCHPAD: - ep_ctxt->avg_trb_len = 1024; - break; - default: - switch (usbd_xotg->port_speed) - { - case XUSB_SUPER_SPEED: - ep_ctxt->avg_trb_len = 1024; - break; - case XUSB_HIGH_SPEED: - case XUSB_FULL_SPEED: - ep_ctxt->avg_trb_len = 512; - break; - } - break; - } - - // Set max burst rate. - ep_ctxt->max_burst_size = (ep_desc->wMaxPacketSize >> 11) & 3; - - // Set max packet size based on port speed. - if (usbd_xotg->port_speed == XUSB_SUPER_SPEED) - { - ep_ctxt->max_packet_size = 1024; - - //! TODO USB3: - // If ISO or INTR EP, set Max Esit Payload size. - // ep_ctxt->max_burst_size = bMaxBurst; - //if (ep_ctxt->ep_type == EP_TYPE_INTR_OUT || ep_ctxt->ep_type == EP_TYPE_ISOC_OUT) - // ep_ctxt->max_esit_payload = ep_ctxt->max_packet_size * (ep_ctxt->max_burst_size + 1); - } - else if (usbd_xotg->port_speed == XUSB_HIGH_SPEED) - { - ep_ctxt->max_packet_size = 512; - - // If ISO or INTR EP, set Max Esit Payload size. - if (ep_ctxt->ep_type == EP_TYPE_INTR_OUT || ep_ctxt->ep_type == EP_TYPE_ISOC_OUT) - ep_ctxt->max_esit_payload = ep_ctxt->max_packet_size * (ep_ctxt->max_burst_size + 1); - } - else - { - ep_ctxt->max_packet_size = 64; - - // If ISO or INTR EP, set Max Esit Payload size. - if (ep_ctxt->ep_type == EP_TYPE_INTR_OUT || ep_ctxt->ep_type == EP_TYPE_ISOC_OUT) - ep_ctxt->max_esit_payload = ep_ctxt->max_packet_size; - } - break; - - case USB_EP_BULK_IN: - // Set default EP type. - ep_ctxt->ep_type = EP_TYPE_BULK_IN; - - // Check configuration descriptor. - if (usbd_xotg->desc->cfg->interface.bInterfaceClass == 0x3) // HID Class. - endpoints = (usb_ep_descr_t *)((void *)endpoints + sizeof(usb_hid_descr_t)); - - for (u32 i = 0; i < usbd_xotg->desc->cfg->interface.bNumEndpoints; i++) - if (endpoints[i].bEndpointAddress == USB_EP_ADDR_BULK_IN) - { - ep_desc = &endpoints[i]; - break; - } - - // Set actual EP type. - if (ep_desc) - { - switch (ep_desc->bmAttributes) - { - case USB_EP_TYPE_ISO: - ep_ctxt->ep_type = EP_TYPE_ISOC_IN; - break; - case USB_EP_TYPE_BULK: - ep_ctxt->ep_type = EP_TYPE_BULK_IN; - break; - case USB_EP_TYPE_INTR: - ep_ctxt->ep_type = EP_TYPE_INTR_IN; - break; - } - } - - // Set average TRB length. - //TODO: Use ep type instead (we don't expect to calculate avg per gadget)? - switch (usbd_xotg->gadget) - { - case USB_GADGET_UMS: - ep_ctxt->avg_trb_len = 3072; - break; - case USB_GADGET_HID_GAMEPAD: - case USB_GADGET_HID_TOUCHPAD: - ep_ctxt->avg_trb_len = 16; // Normal interrupt avg is 1024KB. - break; - default: - switch (usbd_xotg->port_speed) - { - case XUSB_SUPER_SPEED: - ep_ctxt->avg_trb_len = 1024; - break; - case XUSB_HIGH_SPEED: - case XUSB_FULL_SPEED: - ep_ctxt->avg_trb_len = 512; - break; - } - break; - } - - // Set max burst rate. - ep_ctxt->max_burst_size = (ep_desc->wMaxPacketSize >> 11) & 3; - - // Set max packet size based on port speed. - if (usbd_xotg->port_speed == XUSB_SUPER_SPEED) - { - ep_ctxt->max_packet_size = 1024; - - //! TODO USB3: - // If ISO or INTR EP, set Max Esit Payload size. - // ep_ctxt->max_burst_size = bMaxBurst; - //if (ep_ctxt->ep_type == EP_TYPE_INTR_IN || ep_ctxt->ep_type == EP_TYPE_ISOC_IN) - // ep_ctxt->max_esit_payload = ep_ctxt->max_packet_size * (ep_ctxt->max_burst_size + 1); - } - else if (usbd_xotg->port_speed == XUSB_HIGH_SPEED) - { - ep_ctxt->max_packet_size = 512; - - // If ISO or INTR EP, set Max Esit Payload size. - if (ep_ctxt->ep_type == EP_TYPE_INTR_IN || ep_ctxt->ep_type == EP_TYPE_ISOC_IN) - ep_ctxt->max_esit_payload = ep_ctxt->max_packet_size * (ep_ctxt->max_burst_size + 1); - } - else - { - ep_ctxt->max_packet_size = 64; - - // If ISO or INTR EP, set Max Esit Payload size. - if (ep_ctxt->ep_type == EP_TYPE_INTR_IN || ep_ctxt->ep_type == EP_TYPE_ISOC_IN) - ep_ctxt->max_esit_payload = ep_ctxt->max_packet_size; - } - break; - } -} - -static int _xusb_ep_init_context(u32 ep_idx) -{ - link_trb_t *link_trb; - - if (ep_idx > USB_EP_BULK_IN) - return USB_ERROR_INIT; - - if (ep_idx == XUSB_EP_CTRL_OUT) - ep_idx = XUSB_EP_CTRL_IN; - - volatile xusb_ep_ctx_t *ep_ctxt = &xusb_evtq->xusb_ep_ctxt[ep_idx]; - memset((void *)ep_ctxt, 0, sizeof(xusb_ep_ctx_t)); - - ep_ctxt->ep_state = EP_RUNNING; - ep_ctxt->dcs = 1; - ep_ctxt->cec = 3; - ep_ctxt->cerr = 3; - ep_ctxt->max_burst_size = 0; - - switch (ep_idx) - { - case XUSB_EP_CTRL_IN: - usbd_xotg->cntrl_producer_cycle = 1; - usbd_xotg->cntrl_epenqueue_ptr = xusb_evtq->xusb_cntrl_event_queue; - usbd_xotg->cntrl_epdequeue_ptr = xusb_evtq->xusb_cntrl_event_queue; - - _xusb_ep_set_type_and_metrics(ep_idx, ep_ctxt); - - ep_ctxt->trd_dequeueptr_lo = (u32)xusb_evtq->xusb_cntrl_event_queue >> 4; - ep_ctxt->trd_dequeueptr_hi = 0; - - link_trb = (link_trb_t *)&xusb_evtq->xusb_cntrl_event_queue[XUSB_LINK_TRB_IDX]; - link_trb->toggle_cycle = 1; - link_trb->ring_seg_ptrlo = (u32)xusb_evtq->xusb_cntrl_event_queue >> 4; - link_trb->ring_seg_ptrhi = 0; - link_trb->trb_type = XUSB_TRB_LINK; - break; - - case USB_EP_BULK_OUT: - usbd_xotg->bulkout_producer_cycle = 1; - usbd_xotg->bulkout_epenqueue_ptr = xusb_evtq->xusb_bulkout_event_queue; - usbd_xotg->bulkout_epdequeue_ptr = xusb_evtq->xusb_bulkout_event_queue; - - _xusb_ep_set_type_and_metrics(ep_idx, ep_ctxt); - - ep_ctxt->trd_dequeueptr_lo = (u32)xusb_evtq->xusb_bulkout_event_queue >> 4; - ep_ctxt->trd_dequeueptr_hi = 0; - - link_trb = (link_trb_t *)&xusb_evtq->xusb_bulkout_event_queue[XUSB_LINK_TRB_IDX]; - link_trb->toggle_cycle = 1; - link_trb->ring_seg_ptrlo = (u32)xusb_evtq->xusb_bulkout_event_queue >> 4; - link_trb->ring_seg_ptrhi = 0; - link_trb->trb_type = XUSB_TRB_LINK; - break; - - case USB_EP_BULK_IN: - usbd_xotg->bulkin_producer_cycle = 1; - usbd_xotg->bulkin_epenqueue_ptr = xusb_evtq->xusb_bulkin_event_queue; - usbd_xotg->bulkin_epdequeue_ptr = xusb_evtq->xusb_bulkin_event_queue; - - _xusb_ep_set_type_and_metrics(ep_idx, ep_ctxt); - - ep_ctxt->trd_dequeueptr_lo = (u32)xusb_evtq->xusb_bulkin_event_queue >> 4; - ep_ctxt->trd_dequeueptr_hi = 0; - - link_trb = (link_trb_t *)&xusb_evtq->xusb_bulkin_event_queue[XUSB_LINK_TRB_IDX]; - link_trb->toggle_cycle = 1; - link_trb->ring_seg_ptrlo = (u32)xusb_evtq->xusb_bulkin_event_queue >> 4; - link_trb->ring_seg_ptrhi = 0; - link_trb->trb_type = XUSB_TRB_LINK; - break; - } - - return USB_RES_OK; -} - -static int _xusbd_ep_initialize(u32 ep_idx) -{ - switch (ep_idx) - { - case XUSB_EP_CTRL_IN: - case XUSB_EP_CTRL_OUT: - return _xusb_ep_init_context(XUSB_EP_CTRL_IN); - case USB_EP_BULK_OUT: - case USB_EP_BULK_IN: - _xusb_ep_init_context(ep_idx); - XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_RELOAD) = BIT(ep_idx); - int res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_EP_RELOAD, BIT(ep_idx), 0, 1000); - if (!res) - { - XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_PAUSE) &= ~BIT(ep_idx); - XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) &= ~BIT(ep_idx); - } - return res; - default: - return USB_ERROR_INIT; - } -} - -static void _xusb_init_phy() -{ - // Configure and enable PLLU. - clock_enable_pllu(); - - // Enable IDDQ control by software and disable UTMIPLL IDDQ. - CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) = (CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) & 0xFFFFFFFC) | 1; - - // Set UTMIPLL dividers and config based on OSC and enable it to 960 MHz. - clock_enable_utmipll(); - - // Set UTMIP misc config. - CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) = (CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) & 0xFEFFFFE8) | 0x2000008 | 0x20 | 2; - usleep(2); - - // Set OTG PAD0 calibration. - u32 fuse_usb_calib = FUSE(FUSE_USB_CALIB); - // Set HS_CURR_LEVEL. - XUSB_PADCTL(XUSB_PADCTL_USB2_OTG_PAD0_CTL_0) = (XUSB_PADCTL(XUSB_PADCTL_USB2_OTG_PAD0_CTL_0) & 0xFFFFFFC0) | (fuse_usb_calib & 0x3F); - // Set TERM_RANGE_ADJ and RPD_CTRL. - XUSB_PADCTL(XUSB_PADCTL_USB2_OTG_PAD0_CTL_1) = (XUSB_PADCTL(XUSB_PADCTL_USB2_OTG_PAD0_CTL_1) & 0x83FFFF87) | ((fuse_usb_calib & 0x780) >> 4) | ((u32)(FUSE(FUSE_USB_CALIB_EXT) << 27) >> 1); - - // Set VREG_LEV to 1. - XUSB_PADCTL(XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD0_CTL1) = (XUSB_PADCTL(XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD0_CTL1) & 0xFFFFFE3F) | 0x80; - - // Disable power down on usb2 ports pads. - XUSB_PADCTL(XUSB_PADCTL_USB2_OTG_PAD0_CTL_0) &= 0xDBFFFFFF; // Clear pad power down. - XUSB_PADCTL(XUSB_PADCTL_USB2_OTG_PAD0_CTL_1) &= 0xFFFFFFFB; // Clear pad dr power down. - XUSB_PADCTL(XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD0_CTL0) &= 0xFFFFFFFE; // Clear charging power down. - XUSB_PADCTL(XUSB_PADCTL_USB2_BIAS_PAD_CTL_0) &= 0xFFFFF7FF; // Clear bias power down. - (void)XUSB_PADCTL(XUSB_PADCTL_USB2_OTG_PAD0_CTL_1); // Commit write. - - // Enable USB2 tracking clock. - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_SET) = BIT(CLK_Y_USB2_TRK); - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK) & 0xFFFFFF00) | 6; // Set trank divisor to 4. - - // Set tracking parameters and trigger it. - XUSB_PADCTL(XUSB_PADCTL_USB2_BIAS_PAD_CTL_1) = 0x451E000; - XUSB_PADCTL(XUSB_PADCTL_USB2_BIAS_PAD_CTL_1) = 0x51E000; - usleep(100); - - // TRK cycle done. Force PDTRK input into power down. - XUSB_PADCTL(XUSB_PADCTL_USB2_BIAS_PAD_CTL_1) = 0x451E000; - usleep(3); - - // Re-trigger it. - XUSB_PADCTL(XUSB_PADCTL_USB2_BIAS_PAD_CTL_1) = 0x51E000; - usleep(100); - - // TRK cycle done. Force PDTRK input into power down. - XUSB_PADCTL(XUSB_PADCTL_USB2_BIAS_PAD_CTL_1) |= 0x4000000; - - // Disable USB2 tracking clock. - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_CLR) = BIT(CLK_Y_USB2_TRK); - - // Wait for XUSB PHY to stabilize. - usleep(30); -} - -static void _xusbd_init_device_clocks() -{ - // Disable reset to PLLU_OUT1 - CLOCK(CLK_RST_CONTROLLER_PLLU_OUTA) |= 1; - usleep(2); - - // Enable XUSB device clock. - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_SET) = BIT(CLK_U_XUSB_DEV); - - // Set XUSB device core clock source to PLLP for a 102MHz result. - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_CORE_DEV) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_CORE_DEV) & 0x1FFFFF00) | (1 << 29) | 6; - usleep(2); - - // Set XUSB Full-Speed logic clock source to FO 48MHz. - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_FS) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_FS) & 0x1FFFFFFF) | (2 << 29); - - // Enable XUSB Super-Speed logic clock. - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_XUSB_SS); - - // Set XUSB Super-Speed logic clock source to HSIC 480MHz for 120MHz result and source FS logic clock from Super-Speed. - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_SS) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_SS) & 0x1FFFFF00) | (3 << 29) | 6; - - // Clear reset to XUSB device and Super-Speed logic. - CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_CLR) = BIT(CLK_W_XUSB_SS); - CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_CLR) = BIT(CLK_U_XUSB_DEV); - usleep(2); -} - -int xusb_device_init() -{ - ///////////////////////////////////////////////// - CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_USBD); - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_USBD); - ///////////////////////////////////////////////// - - - // Enable XUSB clock and clear Reset to XUSB Pad Control. - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_XUSB); - CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB); - usleep(2); - CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_CLR) = BIT(CLK_W_XUSB); - CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_CLR) = BIT(CLK_W_XUSB_PADCTL); - usleep(2); - - // USB2 Pads to XUSB. - XUSB_PADCTL(XUSB_PADCTL_USB2_PAD_MUX) = - (XUSB_PADCTL(XUSB_PADCTL_USB2_PAD_MUX) & ~(PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_MASK | PADCTL_USB2_PAD_MUX_USB2_OTG_PAD_PORT0_MASK)) | - PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_XUSB | PADCTL_USB2_PAD_MUX_USB2_OTG_PAD_PORT0_XUSB; - - // Initialize XUSB controller PHY. - _xusb_init_phy(); - - // Set USB2.0 Port 0 to device mode. - XUSB_PADCTL(XUSB_PADCTL_USB2_PORT_CAP) = (XUSB_PADCTL(XUSB_PADCTL_USB2_PORT_CAP) & ~PADCTL_USB2_PORT_CAP_PORT_0_CAP_MASK) | PADCTL_USB2_PORT_CAP_PORT_0_CAP_DEV; - - //! TODO USB3 - // // Set USB3.0 Port 0 cap to device. - // XUSB_PADCTL(XUSB_PADCTL_SS_PORT_CAP) = (XUSB_PADCTL(XUSB_PADCTL_SS_PORT_CAP) & ~PADCTL_SS_PORT_CAP_0_PORT1_CAP_MASK) | PADCTL_SS_PORT_CAP_0_PORT1_CAP_DEVICE_ONLY; - - // Set Super Speed Port 0 to USB2 Port 0. - XUSB_PADCTL(XUSB_PADCTL_SS_PORT_MAP) &= ~PADCTL_SS_PORT_MAP_PORT0_MASK; // 0: USB2_PORT0 - - // Power Up ID Wake up and Vbus Wake Up for UTMIP - PMC(APBDEV_PMC_USB_AO) &= 0xFFFFFFF3; - usleep(1); - - // Initialize device clocks. - _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. - - // Enable XUSB device IPFS. - XUSB_DEV_DEV(XUSB_DEV_CONFIGURATION) |= DEV_CONFIGURATION_EN_FPCI; - - // Configure PCI and BAR0 address space. - XUSB_DEV_PCI(XUSB_CFG_1) |= CFG_1_BUS_MASTER | CFG_1_MEMORY_SPACE | CFG_1_IO_SPACE; - usleep(1); - XUSB_DEV_PCI(XUSB_CFG_4) = XUSB_DEV_BASE | CFG_4_ADDRESS_TYPE_32_BIT; - - // Mask SATA interrupt to MCORE. - XUSB_DEV_DEV(XUSB_DEV_INTR_MASK) |= DEV_INTR_MASK_IP_INT_MASK; - - // AHB USB performance cfg. - AHB_GIZMO(AHB_GIZMO_AHB_MEM) |= AHB_MEM_DONT_SPLIT_AHB_WR | AHB_MEM_ENB_FAST_REARBITRATE; - AHB_GIZMO(AHB_GIZMO_USB3) |= AHB_GIZMO_IMMEDIATE; - AHB_GIZMO(AHB_ARBITRATION_PRIORITY_CTRL) = PRIORITY_CTRL_WEIGHT(7) | PRIORITY_SELECT_USB3; - AHB_GIZMO(AHB_AHB_MEM_PREFETCH_CFG1) = - MEM_PREFETCH_ENABLE | MEM_PREFETCH_USB3_MST_ID | MEM_PREFETCH_ADDR_BNDRY(12) | 0x1000; // Addr boundary 64KB, Inactivity 4096 cycles. - - // Initialize context. - usbd_xotg = &usbd_xotg_controller_ctxt; - memset(usbd_xotg, 0, sizeof(xusbd_controller_t)); - - // Initialize event and EP rings. - _xusbd_ep_init_event_ring(); - memset(xusb_evtq->xusb_cntrl_event_queue, 0, sizeof(xusb_evtq->xusb_cntrl_event_queue)); - memset(xusb_evtq->xusb_bulkin_event_queue, 0, sizeof(xusb_evtq->xusb_bulkin_event_queue)); - memset(xusb_evtq->xusb_bulkout_event_queue, 0, sizeof(xusb_evtq->xusb_bulkout_event_queue)); - - // Initialize Control EP. - int res = _xusbd_ep_initialize(XUSB_EP_CTRL_IN); - if (res) - return USB_ERROR_INIT; - - // Enable events and interrupts. - XUSB_DEV_XHCI(XUSB_DEV_XHCI_CTRL) |= XHCI_CTRL_IE | XHCI_CTRL_LSE; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_ECPLO) = (u32)xusb_evtq->xusb_ep_ctxt & 0xFFFFFFF0; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_ECPHI) = 0; - - //! TODO USB3: - // XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT) |= DEV_XHCI_PORTHALT_STCHG_INTR_EN; - - return USB_RES_OK; -} - -static int _xusb_queue_trb(int ep_idx, void *trb, bool ring_doorbell) -{ - int res = USB_RES_OK; - data_trb_t *next_trb; - link_trb_t *link_trb; - - // Copy TRB and advance Enqueue list. - switch (ep_idx) - { - case XUSB_EP_CTRL_IN: - memcpy(usbd_xotg->cntrl_epenqueue_ptr, trb, sizeof(data_trb_t)); - - // Advance queue and if Link TRB set index to 0 and toggle cycle bit. - next_trb = &usbd_xotg->cntrl_epenqueue_ptr[1]; - if (next_trb->trb_type == XUSB_TRB_LINK) - { - link_trb = (link_trb_t *)next_trb; - link_trb->cycle = usbd_xotg->cntrl_producer_cycle & 1; - link_trb->toggle_cycle = 1; - next_trb = (data_trb_t *)(link_trb->ring_seg_ptrlo << 4); - usbd_xotg->cntrl_producer_cycle ^= 1; - } - usbd_xotg->cntrl_epenqueue_ptr = next_trb; - break; - - case USB_EP_BULK_OUT: - memcpy(usbd_xotg->bulkout_epenqueue_ptr, trb, sizeof(data_trb_t)); - - // Advance queue and if Link TRB set index to 0 and toggle cycle bit. - next_trb = &usbd_xotg->bulkout_epenqueue_ptr[1]; - if (next_trb->trb_type == XUSB_TRB_LINK) - { - link_trb = (link_trb_t *)next_trb; - link_trb->cycle = usbd_xotg->bulkout_producer_cycle & 1; - link_trb->toggle_cycle = 1; - next_trb = (data_trb_t *)(link_trb->ring_seg_ptrlo << 4); - usbd_xotg->bulkout_producer_cycle ^= 1; - } - usbd_xotg->bulkout_epenqueue_ptr = next_trb; - break; - - case USB_EP_BULK_IN: - memcpy(usbd_xotg->bulkin_epenqueue_ptr, trb, sizeof(data_trb_t)); - - // Advance queue and if Link TRB set index to 0 and toggle cycle bit. - next_trb = &usbd_xotg->bulkin_epenqueue_ptr[1]; - if (next_trb->trb_type == XUSB_TRB_LINK) - { - link_trb = (link_trb_t *)next_trb; - link_trb->cycle = usbd_xotg->bulkin_producer_cycle & 1; - link_trb->toggle_cycle = 1; - next_trb = (data_trb_t *)(link_trb->ring_seg_ptrlo << 4); - usbd_xotg->bulkin_producer_cycle ^= 1; - } - usbd_xotg->bulkin_epenqueue_ptr = next_trb; - break; - - case XUSB_EP_CTRL_OUT: - default: - res = XUSB_ERROR_INVALID_EP; - break; - } - - // Ring doorbell. - if (ring_doorbell) - { - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); - u32 target_id = (ep_idx << 8) & 0xFFFF; - if (ep_idx == XUSB_EP_CTRL_IN) - target_id |= usbd_xotg->ctrl_seq_num << 16; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_DB) = target_id; - } - - return res; -} - -static void _xusb_create_status_trb(status_trb_t *trb, usb_dir_t direction) -{ - trb->cycle = usbd_xotg->cntrl_producer_cycle & 1; - trb->ioc = 1; // Enable interrupt on completion. - trb->trb_type = XUSB_TRB_STATUS; - trb->dir = direction; -} - -static void _xusb_create_normal_trb(normal_trb_t *trb, u8 *buf, u32 len, usb_dir_t direction) -{ - u8 producer_cycle; - - trb->databufptr_lo = (u32)buf; - trb->databufptr_hi = 0; - - trb->trb_tx_len = len; - - // Single TRB transfer. - trb->td_size = 0; - trb->chain = 0; - - if (direction == USB_DIR_IN) - producer_cycle = usbd_xotg->bulkin_producer_cycle & 1; - else - producer_cycle = usbd_xotg->bulkout_producer_cycle & 1; - - trb->cycle = producer_cycle; - trb->isp = 1; // Enable interrupt on short packet. - trb->ioc = 1; // Enable interrupt on completion. - trb->trb_type = XUSB_TRB_NORMAL; -} - -static void _xusb_create_data_trb(data_trb_t *trb, u8 *buf, u32 len, usb_dir_t direction) -{ - trb->databufptr_lo = (u32)buf; - trb->databufptr_hi = 0; - - trb->trb_tx_len = len; - - // Single TRB transfer. - trb->td_size = 0; - trb->chain = 0; - - trb->cycle = usbd_xotg->cntrl_producer_cycle & 1; - trb->isp = 1; // Enable interrupt on short packet. - trb->ioc = 1; // Enable interrupt on completion. - trb->trb_type = XUSB_TRB_DATA; - trb->dir = direction; -} - -static int _xusb_issue_status_trb(usb_dir_t direction) -{ - int res = USB_RES_OK; - status_trb_t trb = {0}; - - if (usbd_xotg->cntrl_epenqueue_ptr == usbd_xotg->cntrl_epdequeue_ptr || direction == USB_DIR_OUT) - { - _xusb_create_status_trb(&trb, direction); - res = _xusb_queue_trb(XUSB_EP_CTRL_IN, &trb, EP_RING_DOORBELL); - usbd_xotg->wait_for_event_trb = XUSB_TRB_STATUS; - } - - return res; -} - -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; - if (direction == USB_DIR_OUT) - ep_idx = USB_EP_BULK_OUT; - int res = _xusb_queue_trb(ep_idx, &trb, EP_RING_DOORBELL); - if (!res) - usbd_xotg->wait_for_event_trb = XUSB_TRB_NORMAL; - - return res; -} - -static int _xusb_issue_data_trb(u8 *buf, u32 len, usb_dir_t direction) -{ - data_trb_t trb = {0}; - - int res = USB_RES_OK; - if (usbd_xotg->cntrl_epenqueue_ptr == usbd_xotg->cntrl_epdequeue_ptr) - { - _xusb_create_data_trb(&trb, buf, len, direction); - res = _xusb_queue_trb(XUSB_EP_CTRL_IN, &trb, EP_RING_DOORBELL); - if (!res) - usbd_xotg->wait_for_event_trb = XUSB_TRB_DATA; - } - return res; -} - -int xusb_set_ep_stall(u32 endpoint, int ep_stall) -{ - int ep_idx = BIT(endpoint); - if (ep_stall) - XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) |= ep_idx; - else - XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) &= ~ep_idx; - - // Wait for EP status to change. - int res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_EP_STCHG, ep_idx, ep_idx, 1000); - if (res) - return res; - - // Clear status change. - XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_STCHG) = ep_idx; - - return USB_RES_OK; -} - -static int _xusb_handle_transfer_event(transfer_event_trb_t *trb) -{ - // Advance dequeue list. - data_trb_t *next_trb; - switch (trb->ep_id) - { - case XUSB_EP_CTRL_IN: - next_trb = &usbd_xotg->cntrl_epdequeue_ptr[1]; - if (next_trb->trb_type == XUSB_TRB_LINK) - next_trb = (data_trb_t *)(next_trb->databufptr_lo & 0xFFFFFFF0); - usbd_xotg->cntrl_epdequeue_ptr = next_trb; - break; - case USB_EP_BULK_OUT: - next_trb = &usbd_xotg->bulkout_epdequeue_ptr[1]; - if (next_trb->trb_type == XUSB_TRB_LINK) - next_trb = (data_trb_t *)(next_trb->databufptr_lo & 0xFFFFFFF0); - usbd_xotg->bulkout_epdequeue_ptr = next_trb; - break; - case USB_EP_BULK_IN: - next_trb = &usbd_xotg->bulkin_epdequeue_ptr[1]; - if (next_trb->trb_type == XUSB_TRB_LINK) - next_trb = (data_trb_t *)(next_trb->databufptr_lo & 0xFFFFFFF0); - usbd_xotg->bulkin_epdequeue_ptr = next_trb; - break; - default: - // Should never happen. - break; - } - - // Handle completion code. - switch (trb->comp_code) - { - case XUSB_COMP_SUCCESS: - case XUSB_COMP_SHORT_PKT: - switch (trb->ep_id) - { - case XUSB_EP_CTRL_IN: - if (usbd_xotg->wait_for_event_trb == XUSB_TRB_DATA) - 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) - usbd_xotg->device_state = XUSB_ADDRESSED; - else if (usbd_xotg->device_state == XUSB_CONFIGURED_STS_WAIT) - usbd_xotg->device_state = XUSB_CONFIGURED; - else if (usbd_xotg->device_state == XUSB_LUN_CONFIGURED_STS_WAIT) - usbd_xotg->device_state = XUSB_LUN_CONFIGURED; - else if (usbd_xotg->device_state == XUSB_HID_CONFIGURED_STS_WAIT) - usbd_xotg->device_state = XUSB_HID_CONFIGURED; - } - 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_count[USB_DIR_IN]--; - - // If bytes remaining for a Bulk IN transfer, return error. - if (trb->trb_tx_len) - return XUSB_ERROR_XFER_BULK_IN_RESIDUE; - break; - - 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_count[USB_DIR_OUT]--; - break; - } - return USB_RES_OK; -/* - case XUSB_COMP_USB_TRANSACTION_ERROR: - case XUSB_COMP_TRB_ERROR: - case XUSB_COMP_RING_UNDERRUN: - case XUSB_COMP_RING_OVERRUN: - case XUSB_COMP_CTRL_DIR_ERROR: // Redefined. - xusb_set_ep_stall(trb->ep_id, USB_EP_CFG_STALL); - return USB_RES_OK; -*/ - case XUSB_COMP_CTRL_DIR_ERROR: - return XUSB_ERROR_XFER_DIR; - - case XUSB_COMP_CTRL_SEQ_NUM_ERROR: - return XUSB_ERROR_SEQ_NUM; //! TODO: Can mean a new setup packet was received. - - default: // Every other completion code. - return USB_ERROR_XFER_ERROR; - } -} - -/* - * Other XUSB impl: - * CBT: PR, PRC, WPR, WRC, CSC, REQ, PLC, CEC. - * LNX: REQ, PRC PR, PRC & !PR, WRC, CSC, PLC, CEC. - * BRO: CSC, PR | PRC, WPR | WRC, REQ, PLC, CEC. - */ - -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); - - // Connect status change (CSC). - if (status & XHCI_PORTSC_CSC) - { - //! TODO: Check CCS. - // CCS check seems to be - // XHCI_PORTSC_CCS 1: device_state = XUSB_CONNECTED - // XHCI_PORTSC_CCS 0: device_state = XUSB_DISCONNECTED - // Always do XHCI_PORTSC_CSC bit clear. - - // Set port speed. - usbd_xotg->port_speed = (status & XHCI_PORTSC_PS) >> 10; - - // In case host does not support Super Speed, revert the control EP packet size. - if (usbd_xotg->port_speed != XUSB_SUPER_SPEED) - { - 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; - } - - // Clear CSC bit. - 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; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT) &= ~XHCI_PORTHALT_HALT_LTSSM; - } - - // 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 - // device_state = XUSB_SUSPENDED - // else if 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; - } - - // 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; - } - - return res; -} - -static int _xusb_handle_get_ep_status(usb_ctrl_setup_t *ctrl_setup) -{ - 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; - return _xusb_issue_data_trb(xusb_ep_status_descriptor, 2, USB_DIR_IN); -} - -static int _xusb_handle_get_class_request(usb_ctrl_setup_t *ctrl_setup) -{ - u8 _bRequest = ctrl_setup->bRequest; - u16 _wIndex = ctrl_setup->wIndex; - u16 _wValue = ctrl_setup->wValue; - u16 _wLength = ctrl_setup->wLength; - - bool valid_interface = _wIndex == usbd_xotg->interface_num; - bool valid_len = (_bRequest == USB_REQUEST_BULK_GET_MAX_LUN) ? 1 : 0; - - if (!valid_interface || _wValue != 0 || _wLength != valid_len) - goto stall; - - switch (_bRequest) - { - case USB_REQUEST_BULK_RESET: - usbd_xotg->bulk_reset_req = true; - return _xusb_issue_status_trb(USB_DIR_IN); // DELAYED_STATUS; - case USB_REQUEST_BULK_GET_MAX_LUN: - if (!usbd_xotg->max_lun_set) - goto stall; - usbd_xotg->device_state = XUSB_LUN_CONFIGURED_STS_WAIT; - return _xusb_issue_data_trb(&usbd_xotg->max_lun, 1, USB_DIR_IN); - } - -stall: - xusb_set_ep_stall(XUSB_EP_CTRL_IN, USB_EP_CFG_STALL); - return USB_RES_OK; -} - -static int _xusb_handle_get_descriptor(usb_ctrl_setup_t *ctrl_setup) -{ - u32 size; - void *descriptor; - - u32 wLength = ctrl_setup->wLength; - - u8 descriptor_type = ctrl_setup->wValue >> 8; - u8 descriptor_subtype = ctrl_setup->wValue & 0xFF; - - switch (descriptor_type) - { - case USB_DESCRIPTOR_DEVICE: - //! TODO USB3: Provide a super speed descriptor. -/* - u32 soc_rev = APB_MISC(APB_MISC_GP_HIDREV); - usb_device_descriptor.idProduct = (soc_rev >> 8) & 0xFF; // chip_id. - usb_device_descriptor.idProduct |= ((soc_rev << 4) | (FUSE(FUSE_SKU_INFO) & 0xF)) << 8; // HIDFAM. - usb_device_descriptor.bcdDevice = (soc_rev >> 16) & 0xF; // MINORREV. - usb_device_descriptor.bcdDevice |= ((soc_rev >> 4) & 0xF) << 8; // MAJORREV. -*/ - descriptor = usbd_xotg->desc->dev; - size = usbd_xotg->desc->dev->bLength; - break; - case USB_DESCRIPTOR_CONFIGURATION: - //! TODO USB3: Provide a super speed descriptor. - if (usbd_xotg->gadget == USB_GADGET_UMS) - { - if (usbd_xotg->port_speed == XUSB_HIGH_SPEED) // High speed. 512 bytes. - { - usbd_xotg->desc->cfg->endpoint[0].wMaxPacketSize = 0x200; // No burst. - usbd_xotg->desc->cfg->endpoint[1].wMaxPacketSize = 0x200; // No burst. - } - else // Full speed. 64 bytes. - { - usbd_xotg->desc->cfg->endpoint[0].wMaxPacketSize = 0x40; - usbd_xotg->desc->cfg->endpoint[1].wMaxPacketSize = 0x40; - } - } - else - { - usb_cfg_hid_descr_t *tmp = (usb_cfg_hid_descr_t *)usbd_xotg->desc->cfg; - if (usbd_xotg->port_speed == XUSB_HIGH_SPEED) // High speed. 512 bytes. - { - tmp->endpoint[0].wMaxPacketSize = 0x200; - tmp->endpoint[1].wMaxPacketSize = 0x200; - tmp->endpoint[0].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms. - tmp->endpoint[1].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms. - } - else // Full speed. 64 bytes. - { - tmp->endpoint[0].wMaxPacketSize = 0x40; - tmp->endpoint[1].wMaxPacketSize = 0x40; - tmp->endpoint[0].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms. - tmp->endpoint[1].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms. - } - } - descriptor = usbd_xotg->desc->cfg; - size = usbd_xotg->desc->cfg->config.wTotalLength; - break; - case USB_DESCRIPTOR_STRING: - switch (descriptor_subtype) - { - case 1: - descriptor = usbd_xotg->desc->vendor; - size = usbd_xotg->desc->vendor[0]; - break; - case 2: - descriptor = usbd_xotg->desc->product; - size = usbd_xotg->desc->product[0]; - break; - case 3: - descriptor = usbd_xotg->desc->serial; - size = usbd_xotg->desc->serial[0]; - break; - case 0xEE: - descriptor = usbd_xotg->desc->ms_os; - size = usbd_xotg->desc->ms_os->bLength; - break; - default: - descriptor = usbd_xotg->desc->lang_id; - size = 4; - break; - } - break; - case USB_DESCRIPTOR_DEVICE_QUALIFIER: - if (!usbd_xotg->desc->dev_qual) - { - xusb_set_ep_stall(XUSB_EP_CTRL_IN, USB_EP_CFG_STALL); - return USB_RES_OK; - } - usbd_xotg->desc->dev_qual->bNumOtherConfigs = 0; - descriptor = usbd_xotg->desc->dev_qual; - size = usbd_xotg->desc->dev_qual->bLength; - break; - case USB_DESCRIPTOR_OTHER_SPEED_CONFIGURATION: - if (!usbd_xotg->desc->cfg_other) - { - xusb_set_ep_stall(XUSB_EP_CTRL_IN, USB_EP_CFG_STALL); - return USB_RES_OK; - } - if (usbd_xotg->port_speed == XUSB_HIGH_SPEED) - { - usbd_xotg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x40; - usbd_xotg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x40; - } - else - { - usbd_xotg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x200; - usbd_xotg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x200; - } - descriptor = usbd_xotg->desc->cfg_other; - size = usbd_xotg->desc->cfg_other->config.wTotalLength; - break; - case USB_DESCRIPTOR_DEVICE_BINARY_OBJECT: - descriptor = usbd_xotg->desc->dev_bot; - size = usbd_xotg->desc->dev_bot->wTotalLength; - break; - default: - xusb_set_ep_stall(XUSB_EP_CTRL_IN, USB_EP_CFG_STALL); - return USB_RES_OK; - } - - if (wLength < size) - size = wLength; - - return _xusb_issue_data_trb(descriptor, size, USB_DIR_IN); -} - -static void _xusb_handle_set_request_dev_address(usb_ctrl_setup_t *ctrl_setup) -{ - u32 addr = ctrl_setup->wValue & 0xFF; - - XUSB_DEV_XHCI(XUSB_DEV_XHCI_CTRL) = (XUSB_DEV_XHCI(XUSB_DEV_XHCI_CTRL) & 0x80FFFFFF) | (addr << 24); - xusb_evtq->xusb_ep_ctxt[XUSB_EP_CTRL_IN].device_addr = addr; - - _xusb_issue_status_trb(USB_DIR_IN); - - usbd_xotg->device_state = XUSB_ADDRESSED_STS_WAIT; -} - -static void _xusb_handle_set_request_configuration(usb_ctrl_setup_t *ctrl_setup) -{ - u32 config_num = ctrl_setup->wValue; - if (!config_num) //TODO! we can change device_state here. - return; - - // Initialize BULK EPs. - _xusbd_ep_initialize(USB_EP_BULK_OUT); - _xusbd_ep_initialize(USB_EP_BULK_IN); - - // Device mode start. - XUSB_DEV_XHCI(XUSB_DEV_XHCI_CTRL) |= XHCI_CTRL_RUN; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_ST) |= XHCI_ST_RC; - - _xusb_issue_status_trb(USB_DIR_IN); - - usbd_xotg->config_num = config_num; - usbd_xotg->device_state = XUSB_CONFIGURED_STS_WAIT; -} - -static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup) -{ - u32 size; - u8 *desc; - bool ep_stall = false; - bool transmit_data = false; - - u8 _bmRequestType = ctrl_setup->bmRequestType; - u8 _bRequest = ctrl_setup->bRequest; - u16 _wValue = ctrl_setup->wValue; - u16 _wIndex = ctrl_setup->wIndex; - u16 _wLength = ctrl_setup->wLength; - - static u8 xusb_dev_status_descriptor[2] = {USB_STATUS_DEV_SELF_POWERED, 0}; - static u8 xusb_interface_descriptor[4] = {0}; - static u8 xusb_configuration_descriptor[2] = {0}; - static u8 xusb_status_descriptor[2] = {0}; - - //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); - if (res) - return res; - - switch (_bmRequestType) - { - case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): - if (_bRequest == USB_REQUEST_SET_ADDRESS) - _xusb_handle_set_request_dev_address(ctrl_setup); - else if (_bRequest == USB_REQUEST_SET_CONFIGURATION) - _xusb_handle_set_request_configuration(ctrl_setup); - return USB_RES_OK; // What about others. - - case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): - usbd_xotg->interface_num = _wValue; - return _xusb_issue_status_trb(USB_DIR_IN); - - 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) - { - 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); - return _xusb_issue_status_trb(USB_DIR_IN); - } - } - ep_stall = true; - break; - - case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): - return _xusb_handle_get_class_request(ctrl_setup); - - case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): - switch (_bRequest) - { - case USB_REQUEST_GET_STATUS: - desc = xusb_dev_status_descriptor; - size = sizeof(xusb_dev_status_descriptor); - transmit_data = true; - break; - case USB_REQUEST_GET_DESCRIPTOR: - return _xusb_handle_get_descriptor(ctrl_setup); - case USB_REQUEST_GET_CONFIGURATION: - xusb_configuration_descriptor[0] = usbd_xotg->config_num; - desc = xusb_configuration_descriptor; - size = sizeof(xusb_configuration_descriptor); - transmit_data = true; - break; - default: - ep_stall = true; - break; - } - break; - - case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): - if (_bRequest == USB_REQUEST_GET_INTERFACE) - { - desc = xusb_interface_descriptor; - size = sizeof(xusb_interface_descriptor); - xusb_interface_descriptor[0] = usbd_xotg->interface_num; - transmit_data = true; - } - else if (_bRequest == USB_REQUEST_GET_STATUS) - { - desc = xusb_status_descriptor; - size = sizeof(xusb_status_descriptor); - transmit_data = true; - } - else if (_bRequest == USB_REQUEST_GET_DESCRIPTOR && (_wValue >> 8) == USB_DESCRIPTOR_HID_REPORT && usbd_xotg->gadget > USB_GADGET_UMS) - { - if (usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD) - { - desc = (u8 *)&hid_report_descriptor_jc; - size = hid_report_descriptor_jc_size; - } - else // USB_GADGET_HID_TOUCHPAD - { - desc = (u8 *)&hid_report_descriptor_touch; - size = hid_report_descriptor_touch_size; - } - transmit_data = true; - usbd_xotg->device_state = XUSB_HID_CONFIGURED_STS_WAIT; - } - else - ep_stall = true; - break; - - 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); - - ep_stall = true; - break; - - case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): - return _xusb_handle_get_class_request(ctrl_setup); - - case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE): - case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE): - if (_bRequest == USB_REQUEST_GET_MS_DESCRIPTOR) - { - switch (_wIndex) - { - case USB_DESCRIPTOR_MS_COMPAT_ID: - desc = (u8 *)usbd_xotg->desc->ms_cid; - size = usbd_xotg->desc->ms_cid->dLength; - transmit_data = true; - break; - case USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES: - desc = (u8 *)usbd_xotg->desc->mx_ext; - size = usbd_xotg->desc->mx_ext->dLength; - transmit_data = true; - break; - default: - ep_stall = true; - break; - } - } - else - ep_stall = true; - break; - - default: - ep_stall = true; - break; - } - - if (transmit_data) - { - memcpy((u8 *)USB_EP_CONTROL_BUF_ADDR, desc, size); - if (_wLength < size) - size = _wLength; - return _xusb_issue_data_trb((u8 *)USB_EP_CONTROL_BUF_ADDR, size, USB_DIR_IN); - } - - if (ep_stall) - xusb_set_ep_stall(XUSB_EP_CTRL_IN, USB_EP_CFG_STALL); - - return USB_RES_OK; -} - -static int _xusb_ep_operation(u32 tries) -{ - usb_ctrl_setup_t setup_event; - volatile event_trb_t *event_trb; - setup_event_trb_t *setup_event_trb; - - // Wait for an interrupt event. - int res = _xusb_xhci_mask_wait(XUSB_DEV_XHCI_ST, XHCI_ST_IP, XHCI_ST_IP, tries); - if (res) - return res; - - // Clear interrupt status. - XUSB_DEV_XHCI(XUSB_DEV_XHCI_ST) |= XHCI_ST_IP; - - usbd_xotg->event_enqueue_ptr = (event_trb_t *)(XUSB_DEV_XHCI(XUSB_DEV_XHCI_EREPLO) & 0xFFFFFFF0); - event_trb = usbd_xotg->event_dequeue_ptr; - - // Check if cycle matches. - if ((event_trb->cycle & 1) != usbd_xotg->event_ccs) - return XUSB_ERROR_INVALID_CYCLE; - - while ((event_trb->cycle & 1) == usbd_xotg->event_ccs) - { - switch (event_trb->trb_type) - { - case XUSB_TRB_TRANSFER: - res = _xusb_handle_transfer_event((transfer_event_trb_t *)event_trb); - break; - case XUSB_TRB_PORT_CHANGE: - res = _xusb_handle_port_change(); - break; - case XUSB_TRB_SETUP: - setup_event_trb = (setup_event_trb_t *)event_trb; - memcpy(&setup_event, &setup_event_trb->ctrl_setup_data, sizeof(usb_ctrl_setup_t)); - usbd_xotg->ctrl_seq_num = setup_event_trb->ctrl_seq_num; - res = _xusbd_handle_ep0_control_transfer(&setup_event); - break; - default: - // TRB not supported. - break; - } - - // Check if last event TRB and reset to first one. - if (usbd_xotg->event_dequeue_ptr == &xusb_evtq->xusb_event_ring_seg1[XUSB_LAST_TRB_IDX]) - { - usbd_xotg->event_dequeue_ptr = xusb_evtq->xusb_event_ring_seg0; - usbd_xotg->event_ccs ^= 1; - } - else // Advance dequeue to next event. - usbd_xotg->event_dequeue_ptr = &usbd_xotg->event_dequeue_ptr[1]; - - // Set next event. - event_trb = usbd_xotg->event_dequeue_ptr; - - // If events exceed the interrupt time, handle them next interrupt. - if (usbd_xotg->event_dequeue_ptr == usbd_xotg->event_enqueue_ptr) - break; - } - - // Clear Event Handler bit if enabled and set Dequeue pointer. - u32 erdp = XUSB_DEV_XHCI(XUSB_DEV_XHCI_ERDPLO) & 0xF; - if (erdp & XHCI_ERDPLO_EHB) - erdp |= XHCI_ERDPLO_EHB; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_ERDPLO) = ((u32)usbd_xotg->event_dequeue_ptr & 0xFFFFFFF0) | erdp; - - return res; -} - -int xusb_device_enumerate(usb_gadget_type gadget) -{ - switch (gadget) - { - case USB_GADGET_UMS: - usbd_xotg->desc = &usb_gadget_ums_descriptors; - break; - case USB_GADGET_HID_GAMEPAD: - usbd_xotg->desc = &usb_gadget_hid_jc_descriptors; - break; - case USB_GADGET_HID_TOUCHPAD: - usbd_xotg->desc = &usb_gadget_hid_touch_descriptors; - break; - } - - usbd_xotg->gadget = gadget; - - /* - * Set interrupt moderation to 0us. - * This is important because default value creates a 4.62ms latency. - * Effectively hurting transfers by having 15% to 96% performance loss. - */ - XUSB_DEV_XHCI(XUSB_DEV_XHCI_RT_IMOD) = 0; - - // Disable Wake events. - XUSB_PADCTL(XUSB_PADCTL_ELPG_PROGRAM_0) = 0; - XUSB_PADCTL(XUSB_PADCTL_ELPG_PROGRAM_1) = 0; - - // Enable overrides for VBUS and ID. - XUSB_PADCTL(XUSB_PADCTL_USB2_VBUS_ID) = (XUSB_PADCTL(XUSB_PADCTL_USB2_VBUS_ID) & ~(PADCTL_USB2_VBUS_ID_VBUS_OVR_MASK | PADCTL_USB2_VBUS_ID_SRC_MASK)) | - PADCTL_USB2_VBUS_ID_VBUS_OVR_EN | PADCTL_USB2_VBUS_ID_SRC_ID_OVR_EN; - - // Clear halt for LTSSM. - XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTHALT) &= ~XHCI_PORTHALT_HALT_LTSSM; - - // Enable device mode. - XUSB_DEV_XHCI(XUSB_DEV_XHCI_CTRL) |= XHCI_CTRL_ENABLE; - - // Override access to High/Full Speed. - XUSB_DEV_XHCI(XUSB_DEV_XHCI_CFG_DEV_FE) = (XUSB_DEV_XHCI(XUSB_DEV_XHCI_CFG_DEV_FE) & ~XHCI_CFG_DEV_FE_PORTREGSEL_MASK) | XHCI_CFG_DEV_FE_PORTREGSEL_HSFS; - - XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) = - (XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) & ~XHCI_PORTSC_PLS_MASK) | XHCI_PORTSC_LWS | XHCI_PORTSC_PLS_RXDETECT; - XUSB_DEV_XHCI(XUSB_DEV_XHCI_CFG_DEV_FE) &= ~XHCI_CFG_DEV_FE_PORTREGSEL_MASK; - - // Enable VBUS and set ID to Float. - XUSB_PADCTL(XUSB_PADCTL_USB2_VBUS_ID) = (XUSB_PADCTL(XUSB_PADCTL_USB2_VBUS_ID) & ~PADCTL_USB2_VBUS_ID_OVR_MASK) | - PADCTL_USB2_VBUS_ID_OVR_FLOAT | PADCTL_USB2_VBUS_ID_VBUS_ON; - - usbd_xotg->wait_for_event_trb = XUSB_TRB_SETUP; - usbd_xotg->device_state = XUSB_DEFAULT; - - // Timeout if cable or communication isn't started in 1.5 minutes. - u32 timer = get_tmr_ms() + 90000; - while (true) - { - int res = _xusb_ep_operation(USB_XFER_SYNCED_ENUM); // 2s timeout. - if (res && res != USB_ERROR_TIMEOUT) - return res; - - if (usbd_xotg->device_state == XUSB_CONFIGURED) - break; - - if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) - return USB_ERROR_USER_ABORT; - } - - return USB_RES_OK; -} - -void xusb_end(bool reset_ep, bool only_controller) -{ - CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB_SS); - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = BIT(CLK_W_XUSB_SS); - CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = BIT(CLK_U_XUSB_DEV); - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = BIT(CLK_U_XUSB_DEV); - CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB_PADCTL); - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = BIT(CLK_W_XUSB); - CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB); - mc_disable_ahb_redirect(); // Can be skipped if IRAM is not used. -} - -int xusb_handle_ep0_ctrl_setup() -{ - /* - * EP0 Control handling is done by normal ep operation in XUSB. - * Here we handle the bulk reset only. - */ - if (usbd_xotg->bulk_reset_req) - { - usbd_xotg->bulk_reset_req = false; - return USB_RES_BULK_RESET; - } - - return USB_RES_OK; -} - -int xusb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, u32 sync_tries) -{ - if (len > USB_EP_BUFFER_MAX_SIZE) - len = USB_EP_BUFFER_MAX_SIZE; - - int res = USB_RES_OK; - usbd_xotg->tx_count[USB_DIR_OUT] = 0; - usbd_xotg->bytes_remaining[USB_DIR_OUT] = len; - _xusb_issue_normal_trb(buf, len, USB_DIR_OUT); - usbd_xotg->tx_count[USB_DIR_OUT]++; - - if (sync_tries) - { - while (!res && usbd_xotg->tx_count[USB_DIR_OUT]) - res = _xusb_ep_operation(sync_tries); - - if (bytes_read) - *bytes_read = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_OUT]; - - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); - } - - return res; -} - -int xusb_device_ep1_out_read_big(u8 *buf, u32 len, u32 *bytes_read) -{ - if (len > USB_EP_BULK_OUT_MAX_XFER) - len = USB_EP_BULK_OUT_MAX_XFER; - - u32 bytes = 0; - *bytes_read = 0; - u8 *buf_curr = buf; - - while (len) - { - u32 len_ep = MIN(len, USB_EP_BUFFER_MAX_SIZE); - - int res = xusb_device_ep1_out_read(buf_curr, len_ep, &bytes, USB_XFER_SYNCED_DATA); - if (res) - return res; - - len -= len_ep; - buf_curr += len_ep; - *bytes_read = *bytes_read + bytes; - } - - return USB_RES_OK; -} - -int xusb_device_ep1_out_reading_finish(u32 *pending_bytes) -{ - int res = USB_RES_OK; - while (!res && usbd_xotg->tx_count[USB_DIR_OUT]) - res = _xusb_ep_operation(USB_XFER_SYNCED); // Infinite retries. - - if (pending_bytes) - *pending_bytes = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_OUT]; - - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); - - return res; -} - -int xusb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, u32 sync_tries) -{ - if (len > USB_EP_BUFFER_MAX_SIZE) - len = USB_EP_BUFFER_MAX_SIZE; - - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); - - int res = USB_RES_OK; - usbd_xotg->tx_count[USB_DIR_IN] = 0; - usbd_xotg->bytes_remaining[USB_DIR_IN] = len; - _xusb_issue_normal_trb(buf, len, USB_DIR_IN); - usbd_xotg->tx_count[USB_DIR_IN]++; - - if (sync_tries) - { - while (!res && usbd_xotg->tx_count[USB_DIR_IN]) - res = _xusb_ep_operation(sync_tries); - - if (bytes_written) - *bytes_written = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_IN]; - } - else - { - if ((usbd_xotg->port_speed == XUSB_FULL_SPEED && len == 64) || - (usbd_xotg->port_speed == XUSB_HIGH_SPEED && len == 512) || - (usbd_xotg->port_speed == XUSB_SUPER_SPEED && len == 1024)) - { - _xusb_issue_normal_trb(buf, 0, USB_DIR_IN); - usbd_xotg->tx_count[USB_DIR_IN]++; - } - } - - return res; -} - -int xusb_device_ep1_in_writing_finish(u32 *pending_bytes) -{ - int res = USB_RES_OK; - while (!res && usbd_xotg->tx_count[USB_DIR_IN]) - res = _xusb_ep_operation(USB_XFER_SYNCED); // Infinite retries. - - if (pending_bytes) - *pending_bytes = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_IN]; - - return res; -} - -bool xusb_device_get_port_in_sleep() -{ - // Ejection heuristic. - u32 link_mode = XUSB_DEV_XHCI(XUSB_DEV_XHCI_PORTSC) & XHCI_PORTSC_PLS_MASK; - return (link_mode == XHCI_PORTSC_PLS_U3); -} - -bool xusb_device_class_send_max_lun(u8 max_lun) -{ - // Timeout if get MAX_LUN request doesn't happen in 10s. - u32 timer = get_tmr_ms() + 10000; - - usbd_xotg->max_lun = max_lun; - usbd_xotg->max_lun_set = true; - - // Wait for request and transfer start. - while (usbd_xotg->device_state != XUSB_LUN_CONFIGURED) - { - _xusb_ep_operation(USB_XFER_SYNCED_CLASS); - if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) - return true; - } - - usbd_xotg->device_state = XUSB_CONFIGURED; - - return false; -} - -bool xusb_device_class_send_hid_report() -{ - // Timeout if get GET_HID_REPORT request doesn't happen in 10s. - u32 timer = get_tmr_ms() + 10000; - - // Wait for request and transfer start. - while (usbd_xotg->device_state != XUSB_HID_CONFIGURED) - { - _xusb_ep_operation(USB_XFER_SYNCED_CLASS); - if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) - return true; - } - - usbd_xotg->device_state = XUSB_CONFIGURED; - - return false; -} - -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->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; - ops->usb_device_class_send_hid_report = xusb_device_class_send_hid_report; - ops->usb_device_get_suspended = xusb_device_get_port_in_sleep; - ops->usb_device_get_port_in_sleep = xusb_device_get_port_in_sleep; - - ops->usb_device_ep1_out_read = xusb_device_ep1_out_read; - ops->usb_device_ep1_out_read_big = xusb_device_ep1_out_read_big; - ops->usb_device_ep1_out_reading_finish = xusb_device_ep1_out_reading_finish; - ops->usb_device_ep1_in_write = xusb_device_ep1_in_write; - ops->usb_device_ep1_in_writing_finish = xusb_device_ep1_in_writing_finish; -} diff --git a/bdk/utils/btn.c b/bdk/utils/btn.c index cc36573..ded903d 100644 --- a/bdk/utils/btn.c +++ b/bdk/utils/btn.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018 CTCaer + * Copyright (c) 2018-2022 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, @@ -44,6 +44,11 @@ u8 btn_read_vol() return res; } +u8 btn_read_home() +{ + return (!gpio_read(GPIO_PORT_Y, GPIO_PIN_1)) ? BTN_HOME : 0; +} + u8 btn_wait() { u8 res = 0, btn = btn_read(); diff --git a/bdk/utils/btn.h b/bdk/utils/btn.h index ac191fa..a1c91a3 100644 --- a/bdk/utils/btn.h +++ b/bdk/utils/btn.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018 CTCaer + * Copyright (c) 2018-2022 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,10 +23,12 @@ #define BTN_POWER BIT(0) #define BTN_VOL_DOWN BIT(1) #define BTN_VOL_UP BIT(2) +#define BTN_HOME BIT(3) #define BTN_SINGLE BIT(7) u8 btn_read(); u8 btn_read_vol(); +u8 btn_read_home(); u8 btn_wait(); u8 btn_wait_timeout(u32 time_ms, u8 mask); u8 btn_wait_timeout_single(u32 time_ms, u8 mask); diff --git a/bdk/utils/ini.c b/bdk/utils/ini.c index ff4d3a3..123c0d5 100644 --- a/bdk/utils/ini.c +++ b/bdk/utils/ini.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2020 CTCaer + * Copyright (c) 2018-2022 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, @@ -21,25 +21,7 @@ #include #include #include - -static char *_strdup(char *str) -{ - if (!str) - return NULL; - - // Remove starting space. - if (str[0] == ' ' && strlen(str)) - str++; - - char *res = (char *)malloc(strlen(str) + 1); - strcpy(res, str); - - // Remove trailing space. - if (strlen(res) && res[strlen(res) - 1] == ' ') - res[strlen(res) - 1] = 0; - - return res; -} +#include u32 _find_section_name(char *lbuf, u32 lblen, char schar) { @@ -57,8 +39,12 @@ ini_sec_t *_ini_create_section(link_t *dst, ini_sec_t *csec, char *name, u8 type if (csec) list_append(dst, &csec->link); - csec = (ini_sec_t *)calloc(sizeof(ini_sec_t), 1); - csec->name = _strdup(name); + // Calculate total allocation size. + u32 len = name ? strlen(name) + 1 : 0; + char *buf = calloc(sizeof(ini_sec_t) + len, 1); + + csec = (ini_sec_t *)buf; + csec->name = strcpy_ns(buf + sizeof(ini_sec_t), name); csec->type = type; return csec; @@ -66,14 +52,14 @@ ini_sec_t *_ini_create_section(link_t *dst, ini_sec_t *csec, char *name, u8 type int ini_parse(link_t *dst, char *ini_path, bool is_dir) { + FIL fp; u32 lblen; u32 pathlen = strlen(ini_path); u32 k = 0; - char lbuf[512]; - char *filelist = NULL; - FIL fp; ini_sec_t *csec = NULL; + char *lbuf = NULL; + char *filelist = NULL; char *filename = (char *)malloc(256); strcpy(filename, ini_path); @@ -114,8 +100,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir) return 0; } - csec = _ini_create_section(dst, csec, "Unknown", INI_CHOICE); - list_init(&csec->kvs); + lbuf = malloc(512); do { @@ -154,9 +139,16 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir) { u32 i = _find_section_name(lbuf, lblen, '='); - ini_kv_t *kv = (ini_kv_t *)calloc(sizeof(ini_kv_t), 1); - kv->key = _strdup(&lbuf[0]); - kv->val = _strdup(&lbuf[i + 1]); + // Calculate total allocation size. + u32 klen = strlen(&lbuf[0]) + 1; + u32 vlen = strlen(&lbuf[i + 1]) + 1; + char *buf = calloc(sizeof(ini_kv_t) + klen + vlen, 1); + + ini_kv_t *kv = (ini_kv_t *)buf; + buf += sizeof(ini_kv_t); + kv->key = strcpy_ns(buf, &lbuf[0]); + buf += klen; + kv->val = strcpy_ns(buf, &lbuf[i + 1]); list_append(&csec->kvs, &kv->link); } } while (!f_eof(&fp)); @@ -171,6 +163,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir) } } while (is_dir); + free(lbuf); free(filename); free(filelist); diff --git a/bdk/utils/sprintf.c b/bdk/utils/sprintf.c index 8fa2dec..a5b8cef 100644 --- a/bdk/utils/sprintf.c +++ b/bdk/utils/sprintf.c @@ -1,123 +1,201 @@ /* - * Copyright (c) 2019-2020 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, - * 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 "sprintf.h" +* Copyright (c) 2018 naehrwert +* Copyright (c) 2019-2022 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 . +*/ #include +#include -static void _putc(char *buffer, const char c) { - *buffer = c; +#include + +char **sout_buf; + +static void _s_putc(char c) +{ + **sout_buf = c; + *sout_buf += 1; } -static u32 _puts(char *buffer, const char *s) { - u32 count = 0; - for (; *s; s++, count++) - _putc(buffer + count, *s); - return count; +static void _s_puts(char *s) +{ + for (; *s; s++) + _s_putc(*s); } -static u32 _putn(char *buffer, u32 v, int base, char fill, int fcnt) { - char buf[0x121]; - static const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; - char *p; - int c = fcnt; +static void _s_putn(u32 v, int base, char fill, int fcnt) +{ + char buf[65]; + static const char digits[] = "0123456789ABCDEFghijklmnopqrstuvwxyz"; + char *p; + int c = fcnt; - if (base > 36) - return 0; + if (base > 36) + return; - p = buf + 0x120; - *p = 0; - do { - c--; - *--p = digits[v % base]; - v /= base; - } while (v); + p = buf + 64; + *p = 0; + do + { + c--; + *--p = digits[v % base]; + v /= base; + } while (v); - if (fill != 0) { - while (c > 0) { - *--p = fill; - c--; - } - } + if (fill != 0) + { + while (c > 0) + { + *--p = fill; + c--; + } + } - return _puts(buffer, p); + _s_puts(p); } -u32 s_printf(char *buffer, const char *fmt, ...) { - va_list ap; - int fill, fcnt; - u32 count = 0; +void s_printf(char *out_buf, const char *fmt, ...) +{ + va_list ap; + int fill, fcnt; - va_start(ap, fmt); - while(*fmt) { - if (*fmt == '%') { - fmt++; - fill = 0; - fcnt = 0; - if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ') { - fcnt = *fmt; - fmt++; - if (*fmt >= '0' && *fmt <= '9') { - fill = fcnt; - fcnt = *fmt - '0'; - fmt++; - } else { - fill = ' '; - fcnt -= '0'; - } - } - switch (*fmt) { - case 'c': - _putc(buffer + count, va_arg(ap, u32)); - count++; - break; - case 's': - count += _puts(buffer + count, va_arg(ap, char *)); - break; - case 'd': - count += _putn(buffer + count, va_arg(ap, u32), 10, fill, fcnt); - break; - case 'p': - case 'P': - case 'x': - case 'X': - count += _putn(buffer + count, va_arg(ap, u32), 16, fill, fcnt); - break; - case '%': - _putc(buffer + count, '%'); - count++; - break; - case '\0': - goto out; - default: - _putc(buffer + count, '%'); - count++; - _putc(buffer + count, *fmt); - count++; - break; - } - } else { - _putc(buffer + count, *fmt); - count++; - } - fmt++; - } + sout_buf = &out_buf; - out: - buffer[count] = 0; - va_end(ap); - return count; -} \ No newline at end of file + va_start(ap, fmt); + while(*fmt) + { + if(*fmt == '%') + { + fmt++; + fill = 0; + fcnt = 0; + if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ') + { + fcnt = *fmt; + fmt++; + if (*fmt >= '0' && *fmt <= '9') + { + fill = fcnt; + fcnt = *fmt - '0'; + fmt++; + } + else + { + fill = ' '; + fcnt -= '0'; + } + } + switch(*fmt) + { + case 'c': + _s_putc(va_arg(ap, u32)); + break; + case 's': + _s_puts(va_arg(ap, char *)); + break; + case 'd': + _s_putn(va_arg(ap, u32), 10, fill, fcnt); + break; + case 'p': + case 'P': + case 'x': + case 'X': + _s_putn(va_arg(ap, u32), 16, fill, fcnt); + break; + case '%': + _s_putc('%'); + break; + case '\0': + goto out; + default: + _s_putc('%'); + _s_putc(*fmt); + break; + } + } + else + _s_putc(*fmt); + fmt++; + } + +out: + **sout_buf = '\0'; + va_end(ap); +} + +void s_vprintf(char *out_buf, const char *fmt, va_list ap) +{ + int fill, fcnt; + + sout_buf = &out_buf; + + while(*fmt) + { + if(*fmt == '%') + { + fmt++; + fill = 0; + fcnt = 0; + if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ') + { + fcnt = *fmt; + fmt++; + if (*fmt >= '0' && *fmt <= '9') + { + fill = fcnt; + fcnt = *fmt - '0'; + fmt++; + } + else + { + fill = ' '; + fcnt -= '0'; + } + } + switch(*fmt) + { + case 'c': + _s_putc(va_arg(ap, u32)); + break; + case 's': + _s_puts(va_arg(ap, char *)); + break; + case 'd': + _s_putn(va_arg(ap, u32), 10, fill, fcnt); + break; + case 'p': + case 'P': + case 'x': + case 'X': + _s_putn(va_arg(ap, u32), 16, fill, fcnt); + break; + case '%': + _s_putc('%'); + break; + case '\0': + goto out; + default: + _s_putc('%'); + _s_putc(*fmt); + break; + } + } + else + _s_putc(*fmt); + fmt++; + } + +out: + **sout_buf = '\0'; +} diff --git a/bdk/utils/sprintf.h b/bdk/utils/sprintf.h index 35a8218..2fb863b 100644 --- a/bdk/utils/sprintf.h +++ b/bdk/utils/sprintf.h @@ -1,24 +1,27 @@ /* - * Copyright (c) 2019-2020 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, - * 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 . - */ +* Copyright (c) 2019 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 _SPRINTF_H_ #define _SPRINTF_H_ -#include "types.h" +#include -u32 s_printf(char *buffer, const char *fmt, ...); +#include -#endif +void s_printf(char *out_buf, const char *fmt, ...); +void s_vprintf(char *out_buf, const char *fmt, va_list ap); + +#endif \ No newline at end of file diff --git a/bdk/utils/types.h b/bdk/utils/types.h index 9e8e716..b1c2234 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, @@ -17,22 +18,10 @@ #ifndef _TYPES_H_ #define _TYPES_H_ -#define NULL ((void *)0) +#include #define ALWAYS_INLINE inline __attribute__((always_inline)) -#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) -#define ALIGN_DOWN(x, a) ((x) & ~((a) - 1)) -#define BIT(n) (1U << (n)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define DIV_ROUND_UP(a, b) ((a + b - 1) / b) - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) -#define LOG2(n) (32 - __builtin_clz(n) - 1) - -#define OFFSET_OF(t, m) ((u32)&((t *)NULL)->m) -#define CONTAINER_OF(mp, t, mn) ((t *)((u32)mp - OFFSET_OF(t, mn))) #define COLOR_RED 0xFFE70000 #define COLOR_ORANGE 0xFFFF8C00 @@ -41,13 +30,16 @@ #define COLOR_BLUE 0xFF00DDFF #define COLOR_VIOLET 0xFF8040FF +/* Types */ typedef signed char s8; typedef short s16; typedef short SHORT; typedef int s32; typedef int INT; +typedef int bool; typedef long LONG; typedef long long int s64; + typedef unsigned char u8; typedef unsigned char BYTE; typedef unsigned short u16; @@ -58,32 +50,94 @@ typedef unsigned int UINT; typedef unsigned long DWORD; typedef unsigned long long QWORD; typedef unsigned long long int u64; + typedef volatile unsigned char vu8; typedef volatile unsigned short vu16; typedef volatile unsigned int vu32; #ifdef __aarch64__ -typedef u64 uptr; +typedef unsigned long long uptr; #else /* __arm__ or __thumb__ */ -typedef u32 uptr; +typedef unsigned long uptr; #endif -static const u32 colors[6] = {COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_GREEN, COLOR_BLUE, COLOR_VIOLET}; - -typedef int bool; -#define true 1 +/* Important */ #define false 0 +#define true 1 +#define NULL ((void *)0) + +/* Misc */ #define DISABLE 0 #define ENABLE 1 +/* Sizes */ +#define SZ_1K 0x400 +#define SZ_2K 0x800 +#define SZ_4K 0x1000 +#define SZ_8K 0x2000 +#define SZ_16K 0x4000 +#define SZ_32K 0x8000 +#define SZ_64K 0x10000 +#define SZ_128K 0x20000 +#define SZ_256K 0x40000 +#define SZ_512K 0x80000 +#define SZ_1M 0x100000 +#define SZ_2M 0x200000 +#define SZ_4M 0x400000 +#define SZ_8M 0x800000 +#define SZ_16M 0x1000000 +#define SZ_32M 0x2000000 +#define SZ_64M 0x4000000 +#define SZ_128M 0x8000000 +#define SZ_256M 0x10000000 +#define SZ_512M 0x20000000 +#define SZ_1G 0x40000000 +#define SZ_2G 0x80000000 +#define SZ_PAGE SZ_4K + +/* Macros */ +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) +#define ALIGN_DOWN(x, a) ((x) & ~((a) - 1)) +#define BIT(n) (1U << (n)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define DIV_ROUND_UP(a, b) ((a + b - 1) / b) + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) +#define LOG2(n) (32 - __builtin_clz(n) - 1) + +#define OFFSET_OF(t, m) ((uptr)&((t *)NULL)->m) +#define CONTAINER_OF(mp, t, mn) ((t *)((uptr)mp - OFFSET_OF(t, mn))) + +#define byte_swap_16(num) ((((num) >> 8) & 0xff) | (((num) << 8) & 0xff00)) +#define byte_swap_32(num) ((((num) >> 24) & 0xff) | (((num) << 8) & 0xff0000) | \ + (((num) >> 8 )& 0xff00) | (((num) << 24) & 0xff000000)) + + +/* Bootloader/Nyx */ #define BOOT_CFG_AUTOBOOT_EN BIT(0) #define BOOT_CFG_FROM_LAUNCH BIT(1) #define BOOT_CFG_FROM_ID BIT(2) #define BOOT_CFG_TO_EMUMMC BIT(3) -#define BOOT_CFG_SEPT_RUN BIT(7) -#define EXTRA_CFG_DUMP_EMUMMC BIT(0) +#define EXTRA_CFG_KEYS BIT(0) +#define EXTRA_CFG_PAYLOAD BIT(1) +#define EXTRA_CFG_MODULE BIT(2) + +#define EXTRA_CFG_NYX_UMS BIT(5) +#define EXTRA_CFG_NYX_RELOAD BIT(6) + +typedef enum _nyx_ums_type +{ + NYX_UMS_SD_CARD = 0, + NYX_UMS_EMMC_BOOT0, + NYX_UMS_EMMC_BOOT1, + NYX_UMS_EMMC_GPP, + NYX_UMS_EMUMMC_BOOT0, + NYX_UMS_EMUMMC_BOOT1, + NYX_UMS_EMUMMC_GPP +} nyx_ums_type; typedef struct __attribute__((__packed__)) _boot_cfg_t { @@ -95,14 +149,24 @@ typedef struct __attribute__((__packed__)) _boot_cfg_t { struct { - char id[8]; // 7 char ASCII null teminated. - char emummc_path[0x78]; // emuMMC/XXX, ASCII null teminated. + char id[8]; // 7 char ASCII null terminated. + char emummc_path[0x78]; // emuMMC/XXX, ASCII null terminated. }; u8 ums; // nyx_ums_type. u8 xt_str[0x80]; }; } boot_cfg_t; +static_assert(sizeof(boot_cfg_t) == 0x84, "Boot cfg storage size is wrong!"); + +typedef struct __attribute__((__packed__)) _ipl_ver_meta_t +{ + u32 magic; + u32 version; + u16 rsvd0; + u16 rsvd1; +} ipl_ver_meta_t; + typedef struct __attribute__((__packed__)) _reloc_meta_t { u32 start; diff --git a/bdk/utils/util.c b/bdk/utils/util.c index f267236..b351038 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-2022 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,7 +15,8 @@ * along with this program. If not, see . */ -#include +#include + #include #include #include @@ -24,12 +25,56 @@ #include #include #include -#include +#include +#include #define USE_RTC_TIMER 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; +} + +char *strcpy_ns(char *dst, char *src) +{ + if (!src || !dst) + return NULL; + + // Remove starting space. + u32 len = strlen(src); + if (len && src[0] == ' ') + { + len--; + src++; + } + + strcpy(dst, src); + + // Remove trailing space. + if (len && dst[len - 1] == ' ') + dst[len - 1] = 0; + + return dst; +} + u32 get_tmr_s() { return RTC(APBDEV_RTC_SECONDS); diff --git a/bdk/utils/util.h b/bdk/utils/util.h index 3503e1e..c4d0bb0 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-2022 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, @@ -21,6 +21,8 @@ #include #include +#define NYX_NEW_INFO 0x3058594E + typedef enum { REBOOT_RCM, // PMC reset. Enter RCM mode. @@ -33,9 +35,9 @@ typedef enum typedef enum { - NYX_CFG_BIS = BIT(5), NYX_CFG_UMS = BIT(6), - NYX_CFG_DUMP = BIT(7), + + NYX_CFG_EXTRA = 0xFF << 24 } nyx_cfg_t; typedef enum @@ -44,15 +46,11 @@ typedef enum ERR_SYSOLD_NYX = BIT(1), ERR_LIBSYS_MTC = BIT(2), ERR_SD_BOOT_EN = BIT(3), + ERR_PANIC_CODE = BIT(4), ERR_L4T_KERNEL = BIT(24), ERR_EXCEPTION = BIT(31), } hekate_errors_t; -#define byte_swap_32(num) ((((num) >> 24) & 0xff) | (((num) << 8) & 0xff0000) | \ - (((num) >> 8 )& 0xff00) | (((num) << 24) & 0xff000000)) - -#define byte_swap_16(num) ((((num) >> 8) & 0xff) | (((num) << 8) & 0xff00)) - typedef struct _cfg_op_t { u32 off; @@ -75,18 +73,22 @@ typedef struct _nyx_storage_t u32 cfg; u8 irama[0x8000]; u8 hekate[0x30000]; - u8 rsvd[0x800000 - sizeof(nyx_info_t)]; + u8 rsvd[SZ_8M - sizeof(nyx_info_t)]; nyx_info_t info; mtc_config_t mtc_cfg; emc_table_t mtc_table[10]; } nyx_storage_t; +u8 bit_count(u32 val); +u32 bit_count_mask(u8 bits); +char *strcpy_ns(char *dst, char *src); + void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops); u32 crc32_calc(u32 crc, const u8 *buf, u32 len); -u32 get_tmr_us(); -u32 get_tmr_ms(); -u32 get_tmr_s(); +u32 get_tmr_us(); +u32 get_tmr_ms(); +u32 get_tmr_s(); void usleep(u32 us); void msleep(u32 ms); diff --git a/source/config.c b/source/config.c index fbe505e..f3a2b3d 100644 --- a/source/config.c +++ b/source/config.c @@ -18,17 +18,7 @@ #include #include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include extern hekate_config h_cfg; @@ -37,19 +27,13 @@ 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.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN; - h_cfg.aes_slots_new = false; h_cfg.rcm_patched = fuse_check_patched_rcm(); 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 894cdf9..a90e458 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 @@ -39,7 +38,6 @@ typedef struct _hekate_config bool emummc_force_disable; bool rcm_patched; u32 errors; - hos_eks_mbr_t *eks; } hekate_config; void set_default_configuration(); diff --git a/source/fs/fscopy.c b/source/fs/fscopy.c index 7857387..1a67a5e 100644 --- a/source/fs/fscopy.c +++ b/source/fs/fscopy.c @@ -1,14 +1,14 @@ #include "fscopy.h" #include -#include +#include +#include #include "../tegraexplorer/tconf.h" #include "../gfx/gfx.h" -#include -#include #include "../gfx/gfxutils.h" #include "fsutils.h" #include "readers/folderReader.h" + ErrCode_t FileCopy(const char *locin, const char *locout, u8 options){ FIL in, out; FILINFO in_info; diff --git a/source/fs/fsutils.c b/source/fs/fsutils.c index 6efa3aa..6a96149 100644 --- a/source/fs/fsutils.c +++ b/source/fs/fsutils.c @@ -1,8 +1,7 @@ -#include #include #include "fsutils.h" #include "../utils/utils.h" -#include +#include #include #include "readers/folderReader.h" diff --git a/source/fs/menus/filemenu.c b/source/fs/menus/filemenu.c index 820d0d5..bd08f0e 100644 --- a/source/fs/menus/filemenu.c +++ b/source/fs/menus/filemenu.c @@ -3,19 +3,17 @@ #include "../../gfx/menu.h" #include "../../gfx/gfxutils.h" #include "../fsutils.h" -#include -#include -#include #include "../../tegraexplorer/tconf.h" #include "../../hid/hid.h" -#include #include "../../utils/utils.h" #include "../../keys/nca.h" -#include #include "../../storage/emummc.h" #include "../../script/eval.h" #include "../../script/parser.h" #include "../../script/garbageCollector.h" +#include +#include +#include MenuEntry_t FileMenuEntries[] = { @@ -73,6 +71,7 @@ void DeleteFile(char *path, FSEntry_t entry){ } void RunScriptString(char *str, u32 size){ + return; TConf.scriptCWD = "sd:/"; gfx_clearscreen(); ParserRet_t ret = parseScript(str, size); @@ -87,6 +86,7 @@ void RunScriptString(char *str, u32 size){ } void RunScript(char *path, FSEntry_t entry){ + return; char *thing = CombinePaths(path, entry.name); u32 size; char *script = sd_file_read(thing, &size); diff --git a/source/fs/menus/foldermenu.c b/source/fs/menus/foldermenu.c index 74325a5..16b89ec 100644 --- a/source/fs/menus/foldermenu.c +++ b/source/fs/menus/foldermenu.c @@ -3,15 +3,13 @@ #include "../../gfx/menu.h" #include "../../gfx/gfxutils.h" #include "../fsutils.h" -#include #include -#include #include "../../tegraexplorer/tconf.h" #include "../../hid/hid.h" #include #include "../../utils/utils.h" #include "../../keys/nca.h" -#include +#include #include "../fscopy.h" MenuEntry_t FolderMenuEntries[] = { diff --git a/source/fs/readers/folderReader.c b/source/fs/readers/folderReader.c index 70b9d26..7da7dd3 100644 --- a/source/fs/readers/folderReader.c +++ b/source/fs/readers/folderReader.c @@ -1,7 +1,7 @@ #include "folderReader.h" #include #include "../../utils/utils.h" -#include +#include void clearFileVector(Vector_t *v){ vecPDefArray(FSEntry_t*, entries, v); diff --git a/source/hos/fss.c b/source/hos/fss.c index 09896f9..9bf3930 100644 --- a/source/hos/fss.c +++ b/source/hos/fss.c @@ -21,10 +21,9 @@ #include "fss.h" #include "hos.h" #include "../config.h" -#include -#include #include "../storage/emummc.h" -#include +#include +#include #include #define DPRINTF(...) diff --git a/source/hos/sept.c b/source/hos/sept.c deleted file mode 100644 index 24fef6d..0000000 --- a/source/hos/sept.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2019 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 . - */ - -#include - -#include "hos.h" -#include "fss.h" -#include "sept.h" -#include "../config.h" -#include -#include -#include -#include -#include -#include -#include -#include "../storage/nx_emmc.h" -#include -#include -#include -#include -#include - -#include - -#define PATCHED_RELOC_SZ 0x94 - -#define WB_RST_ADDR 0x40010ED0 -#define WB_RST_SIZE 0x30 - -u8 warmboot_reboot[] = { - 0x14, 0x00, 0x9F, 0xE5, // LDR R0, =0x7000E450 - 0x01, 0x10, 0xB0, 0xE3, // MOVS R1, #1 - 0x00, 0x10, 0x80, 0xE5, // STR R1, [R0] - 0x0C, 0x00, 0x9F, 0xE5, // LDR R0, =0x7000E400 - 0x10, 0x10, 0xB0, 0xE3, // MOVS R1, #0x10 - 0x00, 0x10, 0x80, 0xE5, // STR R1, [R0] - 0xFE, 0xFF, 0xFF, 0xEA, // LOOP - 0x50, 0xE4, 0x00, 0x70, // #0x7000E450 - 0x00, 0xE4, 0x00, 0x70 // #0x7000E400 -}; - -#define SEPT_PRI_ADDR 0x4003F000 - -#define SEPT_PK1T_ADDR 0xC0400000 -#define SEPT_PK1T_STACK 0x40008000 -#define SEPT_TCSZ_ADDR (SEPT_PK1T_ADDR - 0x4) -#define SEPT_STG1_ADDR (SEPT_PK1T_ADDR + 0x2E100) -#define SEPT_STG2_ADDR (SEPT_PK1T_ADDR + 0x60E0) -#define SEPT_PKG_SZ (0x2F100 + WB_RST_SIZE) - -extern u32 color_idx; -extern boot_cfg_t b_cfg; -extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size); - -int reboot_to_sept(const u8 *tsec_fw, const u32 tsec_size, const u32 kb) -{ - FIL fp; - bool fss0_sept_used = false; - - // Copy warmboot reboot code and TSEC fw. - memcpy((u8 *)(SEPT_PK1T_ADDR - WB_RST_SIZE), (u8 *)warmboot_reboot, sizeof(warmboot_reboot)); - memcpy((void *)SEPT_PK1T_ADDR, tsec_fw, tsec_size); - *(vu32 *)SEPT_TCSZ_ADDR = tsec_size; - - LIST_INIT(ini_sections); - if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false)) - { - bool found = false; - LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) - { - // Only parse non config sections. - if (ini_sec->type == INI_CHOICE && strcmp(ini_sec->name, "config")) - { - LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) - { - if (!strcmp("fss0", kv->key)) - { - fss0_sept_t sept_ctxt; - sept_ctxt.kb = kb; - sept_ctxt.sept_primary = (void *)SEPT_STG1_ADDR; - sept_ctxt.sept_secondary = (void *)SEPT_STG2_ADDR; - fss0_sept_used = parse_fss(NULL, kv->val, &sept_ctxt); - - found = true; - break; - } - } - } - if (found) - break; - } - } - - if (!fss0_sept_used) - { - // Copy sept-primary. - if (f_open(&fp, "sd:/sept/sept-primary.bin", FA_READ)) - goto error; - - if (f_read(&fp, (u8 *)SEPT_STG1_ADDR, f_size(&fp), NULL)) - { - f_close(&fp); - goto error; - } - f_close(&fp); - - // Copy sept-secondary. - if (kb < KB_FIRMWARE_VERSION_810) - { - if (f_open(&fp, "sd:/sept/sept-secondary_00.enc", FA_READ)) - if (f_open(&fp, "sd:/sept/sept-secondary.enc", FA_READ)) // Try the deprecated version. - goto error; - } - else - { - if (f_open(&fp, "sd:/sept/sept-secondary_01.enc", FA_READ)) - goto error; - } - - if (f_read(&fp, (u8 *)SEPT_STG2_ADDR, f_size(&fp), NULL)) - { - f_close(&fp); - goto error; - } - f_close(&fp); - } - - // Save auto boot config to sept payload, if any. - boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t)); - memcpy(tmp_cfg, &b_cfg, sizeof(boot_cfg_t)); - - tmp_cfg->boot_cfg |= BOOT_CFG_SEPT_RUN; - - if (f_open(&fp, "sd:/sept/payload.bin", FA_READ | FA_WRITE)) - { - free(tmp_cfg); - goto error; - } - - f_lseek(&fp, PATCHED_RELOC_SZ); - f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL); - - f_close(&fp); - - sd_unmount(); - gfx_printf("\n%kPress Power or Vol +/-\n to Reboot to Sept...", colors[(color_idx++) % 6]); - - u32 pk1t_sept = SEPT_PK1T_ADDR - (ALIGN(PATCHED_RELOC_SZ, 0x10) + WB_RST_SIZE); - - void (*sept)() = (void *)pk1t_sept; - - reloc_patcher(WB_RST_ADDR, pk1t_sept, SEPT_PKG_SZ); - - // Patch SDRAM init to perform an SVC immediately after second write. - PMC(APBDEV_PMC_SCRATCH45) = 0x2E38DFFF; - PMC(APBDEV_PMC_SCRATCH46) = 0x6001DC28; - // Set SVC handler to jump to sept-primary in IRAM. - PMC(APBDEV_PMC_SCRATCH33) = SEPT_PRI_ADDR; - PMC(APBDEV_PMC_SCRATCH40) = 0x6000F208; - - hw_reinit_workaround(false, 0); - - (*sept)(); - -error: - EPRINTF("\nSept files not found in sd:/sept!\nPlace appropriate files and try again."); - display_backlight_brightness(100, 1000); - - btn_wait(); - - return 0; -} \ No newline at end of file diff --git a/source/hos/sept.h b/source/hos/sept.h deleted file mode 100644 index 086d50d..0000000 --- a/source/hos/sept.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2019 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 _SEPT_H_ -#define _SEPT_H_ - -#include - -int reboot_to_sept(const u8 *tsec_fw, const u32 tsec_size, const u32 kb); - -#endif diff --git a/source/keys/key_sources.inl b/source/keys/key_sources.inl index 0ba95f9..91e640d 100644 --- a/source/keys/key_sources.inl +++ b/source/keys/key_sources.inl @@ -15,6 +15,9 @@ */ // Sha256 hash of the null string. +#include +#include "../hos/hos.h" + static const u8 null_hash[0x20] __attribute__((aligned(4))) = { 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55}; diff --git a/source/keys/keyfile.c b/source/keys/keyfile.c index 18755ec..4992d8e 100644 --- a/source/keys/keyfile.c +++ b/source/keys/keyfile.c @@ -1,11 +1,9 @@ #include "keys.h" #include "keyfile.h" -#include #include #include -#include +#include #include "../tegraexplorer/tconf.h" -#include #include "../gfx/gfx.h" #define GetHexFromChar(c) ((c & 0x0F) + (c >= 'A' ? 9 : 0)) diff --git a/source/keys/keys.c b/source/keys/keys.c index 05b8a98..b13041b 100644 --- a/source/keys/keys.c +++ b/source/keys/keys.c @@ -1,31 +1,10 @@ #include "keys.h" -#include "../config.h" -#include -#include -#include "../hos/pkg1.h" -#include "../hos/pkg2.h" -#include "../hos/sept.h" #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include "../config.h" +#include "../hos/pkg1.h" #include "../storage/emummc.h" -#include "../storage/nx_emmc.h" -#include "../storage/nx_emmc_bis.h" -#include -#include -#include -#include -#include -#include #include "../gfx/gfx.h" #include "../tegraexplorer/tconf.h" #include "../storage/mountmanager.h" @@ -37,6 +16,7 @@ extern hekate_config h_cfg; #define DPRINTF(x) +#define TSEC_KEY_DATA_OFFSET 0x300 static int _key_exists(const void *data) { return memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) != 0; }; @@ -125,7 +105,7 @@ static void _derive_bis_keys(key_derivation_ctx_t *keys) { } static int _derive_master_keys_from_keyblobs(key_derivation_ctx_t *keys) { - u8 *keyblob_block = (u8 *)calloc(KB_FIRMWARE_VERSION_600 + 1, NX_EMMC_BLOCKSIZE); + u8 *keyblob_block = (u8 *)calloc(KB_FIRMWARE_VERSION_600 + 1, EMMC_BLOCKSIZE); encrypted_keyblob_t *current_keyblob = (encrypted_keyblob_t *)keyblob_block; u32 keyblob_mac[AES_128_KEY_SIZE / 4] = {0}; @@ -144,7 +124,7 @@ static int _derive_master_keys_from_keyblobs(key_derivation_ctx_t *keys) { se_aes_key_set(8, keys->tsec_keys, sizeof(keys->tsec_keys) / 2); se_aes_key_set(9, keys->sbk, 0x10); - if (!emummc_storage_read(&emmc_storage, KEYBLOB_OFFSET / NX_EMMC_BLOCKSIZE, KB_FIRMWARE_VERSION_600 + 1, keyblob_block)) { + if (!emummc_storage_read(KEYBLOB_OFFSET / EMMC_BLOCKSIZE, KB_FIRMWARE_VERSION_600 + 1, keyblob_block)) { DPRINTF("Unable to read keyblobs."); } @@ -195,7 +175,7 @@ static bool _derive_tsec_keys(tsec_ctxt_t *tsec_ctxt, u32 kb, key_derivation_ctx mc_disable_ahb_redirect(); - while (tsec_query(keys->tsec_keys, kb, tsec_ctxt) < 0) { + while (tsec_query(keys->tsec_keys, tsec_ctxt) < 0) { memset(keys->tsec_keys, 0, sizeof(keys->tsec_keys)); retries++; if (retries > 15) { @@ -204,7 +184,7 @@ static bool _derive_tsec_keys(tsec_ctxt_t *tsec_ctxt, u32 kb, key_derivation_ctx } } - mc_enable_ahb_redirect(); + mc_enable_ahb_redirect(false); if (res < 0) { //EPRINTFARGS("ERROR %x dumping TSEC.\n", res); @@ -227,11 +207,11 @@ static ALWAYS_INLINE u8 *_read_pkg1(const pkg1_id_t **pkg1_id) { // Read package1. u8 *pkg1 = (u8 *)malloc(PKG1_MAX_SIZE); - if (!emummc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0)) { + if (!emummc_storage_set_mmc_partition(EMMC_BOOT0)) { DPRINTF("Unable to set partition."); return NULL; } - if (!emummc_storage_read(&emmc_storage, PKG1_OFFSET / NX_EMMC_BLOCKSIZE, PKG1_MAX_SIZE / NX_EMMC_BLOCKSIZE, pkg1)) { + if (!emummc_storage_read(PKG1_OFFSET / EMMC_BLOCKSIZE, PKG1_MAX_SIZE / EMMC_BLOCKSIZE, pkg1)) { DPRINTF("Unable to read pkg1."); return NULL; } diff --git a/source/keys/keys.h b/source/keys/keys.h index 5302047..07b4ba9 100644 --- a/source/keys/keys.h +++ b/source/keys/keys.h @@ -1,6 +1,8 @@ #pragma once #include -#include "../hos/hos.h" + +#define HOS_PKG11_MAGIC 0x31314B50 +#define HOS_EKS_MAGIC 0x30534B45 #define AES_128_KEY_SIZE 16 #define RSA_2048_KEY_SIZE 256 @@ -86,6 +88,23 @@ typedef struct { keyblob_t keyblob; } key_derivation_ctx_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 DumpKeys(); void PrintKey(u8 *key, u32 len); diff --git a/source/libs/fatfs/diskio.c b/source/libs/fatfs/diskio.c index 987266b..f66acea 100644 --- a/source/libs/fatfs/diskio.c +++ b/source/libs/fatfs/diskio.c @@ -24,12 +24,8 @@ /*-----------------------------------------------------------------------*/ #include - +#include #include /* FatFs lower layer API */ -#include -#include -#include "../../storage/nx_emmc_bis.h" -#include /*-----------------------------------------------------------------------*/ /* Get Drive Status */ diff --git a/source/libs/fatfs/ffconf.h b/source/libs/fatfs/ffconf.h index 9f021f0..a0745a8 100644 --- a/source/libs/fatfs/ffconf.h +++ b/source/libs/fatfs/ffconf.h @@ -41,15 +41,26 @@ #define FF_USE_MKFS 1 /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ -#define FF_FASTFS 0 - -#if FF_FASTFS -#define FF_USE_FASTSEEK 1 -#else -#define FF_USE_FASTSEEK 0 +#if FF_USE_MKFS +#define FF_MKFS_LABEL "SWITCH SD " #endif +/* This sets FAT/FAT32 label. Exactly 11 characters, all caps. */ + + +#define FF_USE_FASTSEEK 0 /* This option switches fast seek function. (0:Disable or 1:Enable) */ +#define FF_FASTFS 0 +#if FF_FASTFS +#undef FF_USE_FASTSEEK +#define FF_USE_FASTSEEK 1 +#endif +/* This option switches fast access to chained clusters. (0:Disable or 1:Enable) */ + + +#define FF_SIMPLE_GPT 1 +/* This option switches support for the first GPT partition. (0:Disable or 1:Enable) */ + #define FF_USE_EXPAND 0 /* This option switches f_expand function. (0:Disable or 1:Enable) */ @@ -245,7 +256,7 @@ #define FF_FS_NORTC 1 #define FF_NORTC_MON 1 #define FF_NORTC_MDAY 1 -#define FF_NORTC_YEAR 2020 +#define FF_NORTC_YEAR 2022 /* The option FF_FS_NORTC switches timestamp function. If the system does not have / any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable / the timestamp function. Every object modified by FatFs will have a fixed timestamp diff --git a/source/main.c b/source/main.c index 78c8507..e27284e 100644 --- a/source/main.c +++ b/source/main.c @@ -20,35 +20,15 @@ #include #include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include "storage/emummc.h" -#include "storage/nx_emmc.h" -#include -#include -#include -#include -#include -#include -#include #include "hid/hid.h" -#include #include "gfx/menu.h" #include "utils/vector.h" #include "gfx/gfxutils.h" #include "tegraexplorer/mainmenu.h" #include "tegraexplorer/tconf.h" #include "err.h" -#include #include "keys/keys.h" #include "keys/keyfile.h" #include "storage/mountmanager.h" diff --git a/source/script/parser.c b/source/script/parser.c index 9323ff2..935f990 100644 --- a/source/script/parser.c +++ b/source/script/parser.c @@ -15,7 +15,7 @@ #ifndef WIN32 #include "../tegraexplorer/tconf.h" -#include +#include #endif static inline int isValidWord(char c) { diff --git a/source/script/standardLibrary.c b/source/script/standardLibrary.c index fb16552..5f02efd 100644 --- a/source/script/standardLibrary.c +++ b/source/script/standardLibrary.c @@ -15,18 +15,15 @@ #include "../keys/keys.h" #include "../fs/readers/folderReader.h" #include "../fs/fscopy.h" -#include #include "../keys/nca.h" #include "../hid/hid.h" #include "../gfx/menu.h" #include "../gfx/gfxutils.h" #include "../tegraexplorer/tconf.h" #include "../storage/emummc.h" -#include #include "../fs/fsutils.h" -#include #include "../storage/emmcfile.h" -#include +#include #endif // Takes [int, function]. Returns elseable. ClassFunction(stdIf) { diff --git a/source/storage/emmcfile.c b/source/storage/emmcfile.c index 218db89..9f2423a 100644 --- a/source/storage/emmcfile.c +++ b/source/storage/emmcfile.c @@ -1,18 +1,15 @@ #include "emmcfile.h" +#include #include "../gfx/gfx.h" #include "emummc.h" #include "mountmanager.h" -#include -#include "nx_emmc.h" -#include #include "../err.h" #include "../tegraexplorer/tconf.h" #include "../gfx/gfxutils.h" #include "../hid/hid.h" -#include #include #include "../fs/fsutils.h" -#include "nx_emmc_bis.h" +#include // Uses default storage in nx_emmc.c // Expects the correct mmc & partition to be set @@ -41,20 +38,20 @@ ErrCode_t EmmcDumpToFile(const char *path, u32 lba_start, u32 lba_end, u8 force, gfx_con_getpos(&x, &y); while (totalSectors > 0){ - u32 num = MIN(totalSectors, TConf.FSBuffSize / NX_EMMC_BLOCKSIZE); + u32 num = MIN(totalSectors, TConf.FSBuffSize / EMMC_BLOCKSIZE); int readRes = 0; if (crypt) readRes = !nx_emmc_bis_read(curLba, num, buff); else - readRes = emummc_storage_read(&emmc_storage, curLba, num, buff); + readRes = emummc_storage_read(curLba, num, buff); if (!readRes){ err = newErrCode(TE_ERR_EMMC_READ_FAIL); break; } - if ((res = f_write(&fp, buff, num * NX_EMMC_BLOCKSIZE, NULL))){ + if ((res = f_write(&fp, buff, num * EMMC_BLOCKSIZE, NULL))){ err = newErrCode(res); break; } @@ -82,7 +79,7 @@ ErrCode_t EmmcRestoreFromFile(const char *path, u32 lba_start, u32 lba_end, u8 f return newErrCode(res); u64 totalSizeSrc = f_size(&fp); - u32 totalSectorsSrc = totalSizeSrc / NX_EMMC_BLOCKSIZE; + u32 totalSectorsSrc = totalSizeSrc / EMMC_BLOCKSIZE; if (totalSectorsSrc > totalSectorsDest) // We don't close the file here, oh well return newErrCode(TE_ERR_FILE_TOO_BIG_FOR_DEST); @@ -100,9 +97,9 @@ ErrCode_t EmmcRestoreFromFile(const char *path, u32 lba_start, u32 lba_end, u8 f gfx_con_getpos(&x, &y); while (totalSectorsSrc > 0){ - u32 num = MIN(totalSectorsSrc, TConf.FSBuffSize / NX_EMMC_BLOCKSIZE); + u32 num = MIN(totalSectorsSrc, TConf.FSBuffSize / EMMC_BLOCKSIZE); - if ((res = f_read(&fp, buff, num * NX_EMMC_BLOCKSIZE, NULL))){ + if ((res = f_read(&fp, buff, num * EMMC_BLOCKSIZE, NULL))){ err = newErrCode(res); break; } @@ -111,7 +108,7 @@ ErrCode_t EmmcRestoreFromFile(const char *path, u32 lba_start, u32 lba_end, u8 f if (crypt) writeRes = !nx_emmc_bis_write(curLba, num, buff); else - writeRes = emummc_storage_write(&emmc_storage, curLba, num, buff); + writeRes = emummc_storage_write(curLba, num, buff); if (!writeRes){ err = newErrCode(TE_ERR_EMMC_WRITE_FAIL); @@ -121,7 +118,7 @@ ErrCode_t EmmcRestoreFromFile(const char *path, u32 lba_start, u32 lba_end, u8 f curLba += num; totalSectorsSrc -= num; - u32 percent = ((curLba - lba_start) * 100) / ((totalSizeSrc / NX_EMMC_BLOCKSIZE)); + u32 percent = ((curLba - lba_start) * 100) / ((totalSizeSrc / EMMC_BLOCKSIZE)); gfx_printf("[%3d%%]", percent); gfx_con_setpos(x, y); } @@ -157,22 +154,22 @@ ErrCode_t DumpOrWriteEmmcPart(const char *path, const char *part, u8 write, u8 f return newErrCode(TE_ERR_PARTITION_NOT_FOUND); if (!memcmp(part, "BOOT0", 5)){ - emummc_storage_set_mmc_partition(&emmc_storage, 1); - lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1; + emummc_storage_set_mmc_partition(1); + lba_end = (BOOT_PART_SIZE / EMMC_BLOCKSIZE) - 1; } else if (!memcmp(part, "BOOT1", 5)){ - emummc_storage_set_mmc_partition(&emmc_storage, 2); - lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1; + emummc_storage_set_mmc_partition(2); + lba_end = (BOOT_PART_SIZE / EMMC_BLOCKSIZE) - 1; } else { - emummc_storage_set_mmc_partition(&emmc_storage, 0); + emummc_storage_set_mmc_partition(0); - emmc_part_t *system_part = nx_emmc_part_find(GetCurGPT(), part); + emmc_part_t *system_part = emmc_part_find(GetCurGPT(), part); if (!system_part) return newErrCode(TE_ERR_PARTITION_NOT_FOUND); if (isSystemPartCrypt(system_part) && TConf.keysDumped){ - nx_emmc_bis_init(system_part); + nx_emmc_bis_init(system_part, true, 0); crypt = true; lba_start = 0; lba_end = system_part->lba_end - system_part->lba_start; diff --git a/source/storage/emummc.c b/source/storage/emummc.c index 65953ed..a920fcf 100644 --- a/source/storage/emummc.c +++ b/source/storage/emummc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 CTCaer + * Copyright (c) 2019-2022 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, @@ -17,17 +17,11 @@ #include #include +#include + #include "emummc.h" -#include #include "../config.h" -#include -#include #include -#include -#include "../storage/nx_emmc.h" -#include -#include -#include extern hekate_config h_cfg; emummc_cfg_t emu_cfg = { 0 }; @@ -42,9 +36,9 @@ void emummc_load_cfg() emu_cfg.active_part = 0; emu_cfg.fs_ver = 0; if (!emu_cfg.nintendo_path) - emu_cfg.nintendo_path = (char *)malloc(0x80); + emu_cfg.nintendo_path = (char *)malloc(0x200); if (!emu_cfg.emummc_file_based_path) - emu_cfg.emummc_file_based_path = (char *)malloc(0x80); + emu_cfg.emummc_file_based_path = (char *)malloc(0x200); emu_cfg.nintendo_path[0] = 0; emu_cfg.emummc_file_based_path[0] = 0; @@ -109,7 +103,14 @@ bool emummc_set_path(char *path) if (found) { emu_cfg.enabled = 1; - emu_cfg.id = 0; + + // Get ID from path. + u32 id_from_path = 0; + u32 path_size = strlen(path); + if (path_size >= 4) + memcpy(&id_from_path, path + path_size - 4, 4); + emu_cfg.id = id_from_path; + strcpy(emu_cfg.nintendo_path, path); strcat(emu_cfg.nintendo_path, "/Nintendo"); } @@ -131,13 +132,13 @@ static int emummc_raw_get_part_off(int part_idx) return 2; } -int emummc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc) +int emummc_storage_init_mmc() { FILINFO fno; emu_cfg.active_part = 0; // Always init eMMC even when in emuMMC. eMMC is needed from the emuMMC driver anyway. - if (!sdmmc_storage_init_mmc(storage, sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400)) + if (!emmc_initialize(false)) return 2; if (!emu_cfg.enabled || h_cfg.emummc_force_disable) @@ -173,18 +174,21 @@ out: return 1; } -int emummc_storage_end(sdmmc_storage_t *storage) +int emummc_storage_end() { - sdmmc_storage_end(storage); + if (!emu_cfg.enabled || h_cfg.emummc_force_disable) + sdmmc_storage_end(&emmc_storage); + else + sd_end(); return 1; } -int emummc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf) +int emummc_storage_read(u32 sector, u32 num_sectors, void *buf) { FIL fp; if (!emu_cfg.enabled || h_cfg.emummc_force_disable) - return sdmmc_storage_read(storage, sector, num_sectors, buf); + return sdmmc_storage_read(&emmc_storage, sector, num_sectors, buf); else if (emu_cfg.sector) { sector += emu_cfg.sector; @@ -225,11 +229,11 @@ int emummc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, v return 1; } -int emummc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf) +int emummc_storage_write(u32 sector, u32 num_sectors, void *buf) { FIL fp; if (!emu_cfg.enabled || h_cfg.emummc_force_disable) - return sdmmc_storage_write(storage, sector, num_sectors, buf); + return sdmmc_storage_write(&emmc_storage, sector, num_sectors, buf); else if (emu_cfg.sector) { sector += emu_cfg.sector; @@ -250,15 +254,13 @@ int emummc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 1, 10); } } + if (f_open(&fp, emu_cfg.emummc_file_based_path, FA_WRITE)) - { - gfx_printf("e5\n"); return 0; - } + f_lseek(&fp, (u64)sector << 9); if (f_write(&fp, buf, (u64)num_sectors << 9, NULL)) { - gfx_printf("e6\n"); f_close(&fp); return 0; } @@ -268,13 +270,12 @@ int emummc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, } } -int emummc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition) +int emummc_storage_set_mmc_partition(u32 partition) { emu_cfg.active_part = partition; + sdmmc_storage_set_mmc_partition(&emmc_storage, partition); - if (!emu_cfg.enabled || h_cfg.emummc_force_disable) - sdmmc_storage_set_mmc_partition(storage, partition); - else if (emu_cfg.sector) + if (!emu_cfg.enabled || h_cfg.emummc_force_disable || emu_cfg.sector) return 1; else { diff --git a/source/storage/emummc.h b/source/storage/emummc.h index 81ad123..617b36b 100644 --- a/source/storage/emummc.h +++ b/source/storage/emummc.h @@ -1,5 +1,5 @@ /* - * 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, @@ -17,8 +17,7 @@ #ifndef EMUMMC_H #define EMUMMC_H -#include -#include +#include typedef enum { @@ -37,7 +36,7 @@ typedef struct _emummc_cfg_t { int enabled; u64 sector; - u16 id; + u32 id; char *path; char *nintendo_path; // Internal. @@ -51,10 +50,10 @@ extern emummc_cfg_t emu_cfg; void emummc_load_cfg(); bool emummc_set_path(char *path); -int emummc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc); -int emummc_storage_end(sdmmc_storage_t *storage); -int emummc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf); -int emummc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf); -int emummc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition); +int emummc_storage_init_mmc(); +int emummc_storage_end(); +int emummc_storage_read(u32 sector, u32 num_sectors, void *buf); +int emummc_storage_write(u32 sector, u32 num_sectors, void *buf); +int emummc_storage_set_mmc_partition(u32 partition); #endif \ No newline at end of file diff --git a/source/storage/gptmenu.c b/source/storage/gptmenu.c index 9c9198e..530dd5b 100644 --- a/source/storage/gptmenu.c +++ b/source/storage/gptmenu.c @@ -1,18 +1,15 @@ #include "gptmenu.h" +#include +#include #include "../gfx/gfx.h" #include "../gfx/menu.h" #include "../gfx/gfxutils.h" #include "../utils/vector.h" #include "mountmanager.h" -#include -#include -#include "nx_emmc.h" -#include #include "../fs/menus/explorer.h" #include "../err.h" #include "../tegraexplorer/tconf.h" #include "emmcfile.h" -#include #include "../fs/fsutils.h" #include "../utils/utils.h" diff --git a/source/storage/mountmanager.c b/source/storage/mountmanager.c index 5ee13e6..abd7b2f 100644 --- a/source/storage/mountmanager.c +++ b/source/storage/mountmanager.c @@ -1,11 +1,9 @@ #include "mountmanager.h" #include "emummc.h" #include "../tegraexplorer/tconf.h" -#include "nx_emmc.h" #include "../keys/keys.h" -#include #include -#include "nx_emmc_bis.h" +#include #include "../config.h" extern hekate_config h_cfg; @@ -39,8 +37,8 @@ void disconnectMMC(){ if (TConf.currentMMCConnected != MMC_CONN_None){ TConf.currentMMCConnected = MMC_CONN_None; - emummc_storage_end(&emmc_storage); - nx_emmc_gpt_free(&curGpt); + emummc_storage_end(); + emmc_gpt_free(&curGpt); } } @@ -51,11 +49,11 @@ int connectMMC(u8 mmcType){ disconnectMMC(); h_cfg.emummc_force_disable = (mmcType == MMC_CONN_EMMC) ? 1 : 0; - int res = emummc_storage_init_mmc(&emmc_storage, &emmc_sdmmc); + int res = emummc_storage_init_mmc(&emmc_sdmmc); if (!res){ TConf.currentMMCConnected = mmcType; - emummc_storage_set_mmc_partition(&emmc_storage, 0); - nx_emmc_gpt_parse(&curGpt, &emmc_storage); + emummc_storage_set_mmc_partition(0); + emmc_gpt_parse(&curGpt); } return res; // deal with the errors later lol @@ -67,13 +65,13 @@ ErrCode_t mountMMCPart(const char *partition){ unmountMMCPart(); - emummc_storage_set_mmc_partition(&emmc_storage, 0); // why i have to do this twice beats me + emummc_storage_set_mmc_partition(0); // why i have to do this twice beats me - emmc_part_t *system_part = nx_emmc_part_find(&curGpt, partition); + emmc_part_t *system_part = emmc_part_find(&curGpt, partition); if (!system_part) return newErrCode(TE_ERR_PARTITION_NOT_FOUND); - nx_emmc_bis_init(system_part); + nx_emmc_bis_init(system_part, true, 0); int res = 0; if ((res = f_mount(&emmc_fs, "bis:", 1))) diff --git a/source/storage/nx_emmc.c b/source/storage/nx_emmc.c deleted file mode 100644 index 328a95b..0000000 --- a/source/storage/nx_emmc.c +++ /dev/null @@ -1,86 +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 . - */ - -#include - -#include "nx_emmc.h" -#include "emummc.h" -#include -#include -#include - -sdmmc_t emmc_sdmmc; -sdmmc_storage_t emmc_storage; -FATFS emmc_fs; - -void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage) -{ - gpt_t *gpt_buf = (gpt_t *)calloc(NX_GPT_NUM_BLOCKS, NX_EMMC_BLOCKSIZE); - - emummc_storage_read(storage, NX_GPT_FIRST_LBA, NX_GPT_NUM_BLOCKS, gpt_buf); - - for (u32 i = 0; i < gpt_buf->header.num_part_ents; i++) - { - emmc_part_t *part = (emmc_part_t *)calloc(sizeof(emmc_part_t), 1); - - if (gpt_buf->entries[i].lba_start < gpt_buf->header.first_use_lba) - continue; - - part->index = i; - part->lba_start = gpt_buf->entries[i].lba_start; - part->lba_end = gpt_buf->entries[i].lba_end; - part->attrs = gpt_buf->entries[i].attrs; - - // ASCII conversion. Copy only the LSByte of the UTF-16LE name. - for (u32 j = 0; j < 36; j++) - part->name[j] = gpt_buf->entries[i].name[j]; - part->name[35] = 0; - - list_append(gpt, &part->link); - } - - free(gpt_buf); -} - -void nx_emmc_gpt_free(link_t *gpt) -{ - LIST_FOREACH_SAFE(iter, gpt) - free(CONTAINER_OF(iter, emmc_part_t, link)); -} - -emmc_part_t *nx_emmc_part_find(link_t *gpt, const char *name) -{ - LIST_FOREACH_ENTRY(emmc_part_t, part, gpt, link) - if (!strcmp(part->name, name)) - return part; - return NULL; -} - -int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf) -{ - // The last LBA is inclusive. - if (part->lba_start + sector_off > part->lba_end) - return 0; - return emummc_storage_read(storage, part->lba_start + sector_off, num_sectors, buf); -} - -int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf) -{ - // The last LBA is inclusive. - if (part->lba_start + sector_off > part->lba_end) - return 0; - return emummc_storage_write(storage, part->lba_start + sector_off, num_sectors, buf); -} diff --git a/source/storage/nx_emmc_bis.c b/source/storage/nx_emmc_bis.c deleted file mode 100644 index e551a13..0000000 --- a/source/storage/nx_emmc_bis.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * eMMC BIS driver for Nintendo Switch - * - * Copyright (c) 2019 shchmue - * Copyright (c) 2019-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 . - */ - -#include - -#include - -#include -#include -#include "../storage/nx_emmc.h" -#include "nx_emmc_bis.h" -#include -#include - -#define MAX_CLUSTER_CACHE_ENTRIES 32768 -#define CLUSTER_LOOKUP_EMPTY_ENTRY 0xFFFFFFFF -#define SECTORS_PER_CLUSTER 0x20 - -typedef struct -{ - u32 cluster_num; // index of the cluster in the partition - u32 visit_count; // used for debugging/access analysis - u8 dirty; // has been modified without writeback flag - u8 align[7]; - u8 cluster[XTS_CLUSTER_SIZE]; // the cached cluster itself -} cluster_cache_t; - -typedef struct -{ - u8 emmc_buffer[XTS_CLUSTER_SIZE]; - cluster_cache_t cluster_cache[]; -} bis_cache_t; - -static u8 ks_crypt = 0; -static u8 ks_tweak = 0; -static u8 cache_filled = 0; -static u32 dirty_cluster_count = 0; -static u32 cluster_cache_end_index = 0; -static emmc_part_t *system_part = NULL; -static bis_cache_t *bis_cache = (bis_cache_t *)NX_BIS_CACHE_ADDR; -static u32 *cluster_lookup_buf = NULL; -static u32 *cluster_lookup = NULL; -static bool lock_cluster_cache = false; - -static void _gf256_mul_x_le(void *block) -{ - u32 *pdata = (u32 *)block; - u32 carry = 0; - - for (u32 i = 0; i < 4; i++) - { - u32 b = pdata[i]; - pdata[i] = (b << 1) | carry; - carry = b >> 31; - } - - if (carry) - pdata[0x0] ^= 0x87; -} - -static int _nx_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u8 *tweak, bool regen_tweak, u32 tweak_exp, u32 sec, void *dst, const void *src, u32 sec_size) -{ - u32 *pdst = (u32 *)dst; - u32 *psrc = (u32 *)src; - u32 *ptweak = (u32 *)tweak; - - if (regen_tweak) - { - for (int i = 0xF; i >= 0; i--) - { - tweak[i] = sec & 0xFF; - sec >>= 8; - } - if (!se_aes_crypt_block_ecb(tweak_ks, 1, tweak, tweak)) - return 0; - } - - // tweak_exp allows us to use a saved tweak to reduce _gf256_mul_x_le calls. - for (u32 i = 0; i < (tweak_exp << 5); i++) - _gf256_mul_x_le(tweak); - - u8 orig_tweak[0x10] __attribute__((aligned(4))); - memcpy(orig_tweak, tweak, 0x10); - - // We are assuming a 0x10-aligned sector size in this implementation. - for (u32 i = 0; i < (sec_size >> 4); i++) - { - for (u32 j = 0; j < 4; j++) - pdst[j] = psrc[j] ^ ptweak[j]; - - _gf256_mul_x_le(tweak); - psrc += 4; - pdst += 4; - } - - if (!se_aes_crypt_ecb(crypt_ks, enc, dst, sec_size, dst, sec_size)) - return 0; - - pdst = (u32 *)dst; - ptweak = (u32 *)orig_tweak; - for (u32 i = 0; i < (sec_size >> 4); i++) - { - for (u32 j = 0; j < 4; j++) - pdst[j] = pdst[j] ^ ptweak[j]; - - _gf256_mul_x_le(orig_tweak); - pdst += 4; - } - - return 1; -} - -static int nx_emmc_bis_write_block(u32 sector, u32 count, void *buff, bool force_flush) -{ - if (!system_part) - return 3; // Not ready. - - u8 tweak[0x10] __attribute__((aligned(4))); - u32 cluster = sector / SECTORS_PER_CLUSTER; - u32 aligned_sector = cluster * SECTORS_PER_CLUSTER; - u32 sector_index_in_cluster = sector % SECTORS_PER_CLUSTER; - u32 cluster_lookup_index = cluster_lookup[cluster]; - bool is_cached = cluster_lookup_index != CLUSTER_LOOKUP_EMPTY_ENTRY; - - // Write to cached cluster. - if (is_cached) - { - if (buff) - memcpy(bis_cache->cluster_cache[cluster_lookup_index].cluster + sector_index_in_cluster * NX_EMMC_BLOCKSIZE, buff, count * NX_EMMC_BLOCKSIZE); - else - buff = bis_cache->cluster_cache[cluster_lookup_index].cluster; - bis_cache->cluster_cache[cluster_lookup_index].visit_count++; - if (bis_cache->cluster_cache[cluster_lookup_index].dirty == 0) - dirty_cluster_count++; - bis_cache->cluster_cache[cluster_lookup_index].dirty = 1; - if (!force_flush) - return 0; // Success. - - // Reset args to trigger a full cluster flush to emmc. - sector_index_in_cluster = 0; - sector = aligned_sector; - count = SECTORS_PER_CLUSTER; - } - - // 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) || - !nx_emmc_part_write(&emmc_storage, system_part, sector, count, bis_cache->emmc_buffer) - ) - return 1; // R/W error. - - // Mark cache entry not dirty if write succeeds. - if (is_cached) - { - bis_cache->cluster_cache[cluster_lookup_index].dirty = 0; - dirty_cluster_count--; - } - - return 0; // Success. -} - -static void _nx_emmc_bis_flush_cluster(cluster_cache_t *cache_entry) -{ - nx_emmc_bis_write_block(cache_entry->cluster_num * SECTORS_PER_CLUSTER, SECTORS_PER_CLUSTER, NULL, true); -} - -static int nx_emmc_bis_read_block(u32 sector, u32 count, void *buff) -{ - if (!system_part) - return 3; // Not ready. - - static u32 prev_cluster = -1; - static u32 prev_sector = 0; - static u8 tweak[0x10] __attribute__((aligned(4))); - u8 cache_tweak[0x10] __attribute__((aligned(4))); - - u32 tweak_exp = 0; - bool regen_tweak = true; - - u32 cluster = sector / SECTORS_PER_CLUSTER; - u32 aligned_sector = cluster * SECTORS_PER_CLUSTER; - u32 sector_index_in_cluster = sector % SECTORS_PER_CLUSTER; - u32 cluster_lookup_index = cluster_lookup[cluster]; - - // Read from cached cluster. - if (cluster_lookup_index != CLUSTER_LOOKUP_EMPTY_ENTRY) - { - memcpy(buff, bis_cache->cluster_cache[cluster_lookup_index].cluster + sector_index_in_cluster * NX_EMMC_BLOCKSIZE, count * NX_EMMC_BLOCKSIZE); - bis_cache->cluster_cache[cluster_lookup_index].visit_count++; - prev_sector = sector + count - 1; - prev_cluster = cluster; - return 0; // Success. - } - - // Cache cluster. - if (!lock_cluster_cache) - { - // Roll the cache index over and flush if full. - if (cluster_cache_end_index >= MAX_CLUSTER_CACHE_ENTRIES) - { - cluster_cache_end_index = 0; - cache_filled = 1; - } - // Check if cache entry was previously in use in case of cache loop. - if (cache_filled == 1 && bis_cache->cluster_cache[cluster_cache_end_index].dirty == 1) - _nx_emmc_bis_flush_cluster(&bis_cache->cluster_cache[cluster_cache_end_index]); - - if (cache_filled == 1) - cluster_lookup[bis_cache->cluster_cache[cluster_cache_end_index].cluster_num] = -1; - - bis_cache->cluster_cache[cluster_cache_end_index].cluster_num = cluster; - bis_cache->cluster_cache[cluster_cache_end_index].visit_count = 1; - bis_cache->cluster_cache[cluster_cache_end_index].dirty = 0; - cluster_lookup[cluster] = cluster_cache_end_index; - - // 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) - ) - return 1; // R/W error. - - // Copy to cluster cache. - memcpy(bis_cache->cluster_cache[cluster_cache_end_index].cluster, bis_cache->emmc_buffer, XTS_CLUSTER_SIZE); - memcpy(buff, bis_cache->emmc_buffer + sector_index_in_cluster * NX_EMMC_BLOCKSIZE, count * NX_EMMC_BLOCKSIZE); - cluster_cache_end_index++; - return 0; // Success. - } - - // If not reading from or writing to cache, do a regular read and decrypt. - if (!nx_emmc_part_read(&emmc_storage, system_part, sector, count, bis_cache->emmc_buffer)) - return 1; // R/W error. - - if (prev_cluster != cluster) // Sector in different cluster than last read. - { - prev_cluster = cluster; - tweak_exp = sector_index_in_cluster; - } - else if (sector > prev_sector) // Sector in same cluster and past last sector. - { - // Calculates the new tweak using the saved one, reducing expensive _gf256_mul_x_le calls. - tweak_exp = sector - prev_sector - 1; - regen_tweak = false; - } - else // Sector in same cluster and before or same as last sector. - 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)) - return 1; // R/W error. - prev_sector = sector + count - 1; - - return 0; // Success. -} - -int nx_emmc_bis_read(u32 sector, u32 count, void *buff) -{ - int res = 1; - u8 *buf = (u8 *)buff; - u32 curr_sct = sector; - - while (count) - { - u32 sct_cnt = MIN(count, 0x20); - res = nx_emmc_bis_read_block(curr_sct, sct_cnt, buf); - if (res) - return 1; - - count -= sct_cnt; - curr_sct += sct_cnt; - buf += NX_EMMC_BLOCKSIZE * sct_cnt; - } - - return res; -} - -int nx_emmc_bis_write(u32 sector, u32 count, void *buff) -{ - int res = 1; - u8 *buf = (u8 *)buff; - u32 curr_sct = sector; - - while (count) - { - u32 sct_cnt = MIN(count, 0x20); - res = nx_emmc_bis_write_block(curr_sct, sct_cnt, buf, false); - if (res) - return 1; - - count -= sct_cnt; - curr_sct += sct_cnt; - buf += NX_EMMC_BLOCKSIZE * sct_cnt; - } - - nx_emmc_bis_finalize(); - return res; -} - -void nx_emmc_bis_cluster_cache_init() -{ - u32 cluster_lookup_size = (system_part->lba_end - system_part->lba_start + 1) / SECTORS_PER_CLUSTER * sizeof(*cluster_lookup); - - if (cluster_lookup_buf) - free(cluster_lookup_buf); - - // Check if carveout protected, in case of old hwinit (pre 4.0.0) chainload. - *(vu32 *)NX_BIS_LOOKUP_ADR = 0; - if (*(vu32 *)NX_BIS_LOOKUP_ADR != 0) - { - cluster_lookup_buf = (u32 *)malloc(cluster_lookup_size + 0x2000); - cluster_lookup = (u32 *)ALIGN((u32)cluster_lookup_buf, 0x1000); - } - else - { - cluster_lookup_buf = NULL; - cluster_lookup = (u32 *)NX_BIS_LOOKUP_ADR; - } - - // Clear cluster lookup table and reset end index. - memset(cluster_lookup, -1, cluster_lookup_size); - cluster_cache_end_index = 0; - lock_cluster_cache = false; - - dirty_cluster_count = 0; - cache_filled = 0; -} - -void nx_emmc_bis_init(emmc_part_t *part) -{ - system_part = part; - - nx_emmc_bis_cluster_cache_init(); - - switch (part->index) - { - case 0: // PRODINFO. - case 1: // PRODINFOF. - ks_crypt = 0; - ks_tweak = 1; - break; - case 8: // SAFE. - ks_crypt = 2; - ks_tweak = 3; - break; - case 9: // SYSTEM. - case 10: // USER. - ks_crypt = 4; - ks_tweak = 5; - break; - } -} - -void nx_emmc_bis_finalize() -{ - if (dirty_cluster_count == 0) - return; - - u32 limit = cache_filled == 1 ? MAX_CLUSTER_CACHE_ENTRIES : cluster_cache_end_index; - u32 clusters_to_flush = dirty_cluster_count; - for (u32 i = 0; i < limit && clusters_to_flush; i++) - { - if (bis_cache->cluster_cache[i].dirty) { - _nx_emmc_bis_flush_cluster(&bis_cache->cluster_cache[i]); - clusters_to_flush--; - } - } -} - -// Set cluster cache lock according to arg. -void nx_emmc_bis_cache_lock(bool lock) -{ - lock_cluster_cache = lock; -} diff --git a/source/tegraexplorer/mainmenu.c b/source/tegraexplorer/mainmenu.c index 52337eb..73e30af 100644 --- a/source/tegraexplorer/mainmenu.c +++ b/source/tegraexplorer/mainmenu.c @@ -5,22 +5,18 @@ #include "tools.h" #include "../hid/hid.h" #include "../fs/menus/explorer.h" -#include -#include #include "tconf.h" #include "../keys/keys.h" #include "../storage/mountmanager.h" #include "../storage/gptmenu.h" #include "../storage/emummc.h" -#include #include "../fs/fsutils.h" -#include #include "../utils/utils.h" #include "../config.h" #include "../fs/readers/folderReader.h" #include -#include #include "../fs/menus/filemenu.h" +#include #define INCLUDE_BUILTIN_SCRIPTS 1 //#define SCRIPT_ONLY 1 @@ -131,8 +127,6 @@ void ViewCredits(){ hidWait(); } -extern bool sd_mounted; -extern bool is_sd_inited; extern int launch_payload(char *path); void RebootToAMS(){ @@ -145,7 +139,7 @@ void RebootToHekate(){ void MountOrUnmountSD(){ gfx_clearscreen(); - if (sd_mounted) + if (sd_get_card_mounted()) sd_unmount(); else if (!sd_mount()) hidWait(); @@ -176,24 +170,24 @@ void EnterMainMenu(){ #ifndef SCRIPT_ONLY // -- Explore -- - mainMenuEntries[MainBrowseSd].hide = !sd_mounted; - mainMenuEntries[MainMountSd].name = (sd_mounted) ? "Unmount SD" : "Mount SD"; - mainMenuEntries[MainBrowseEmummc].hide = (!emu_cfg.enabled || !sd_mounted); + mainMenuEntries[MainBrowseSd].hide = !sd_get_card_mounted(); + mainMenuEntries[MainMountSd].name = (sd_get_card_mounted()) ? "Unmount SD" : "Mount SD"; + mainMenuEntries[MainBrowseEmummc].hide = (!emu_cfg.enabled || !sd_get_card_mounted()); // -- Tools -- - mainMenuEntries[MainPartitionSd].hide = (!is_sd_inited || sd_get_card_removed()); + mainMenuEntries[MainPartitionSd].hide = (!sd_get_card_initialized() || sd_get_card_removed()); mainMenuEntries[MainViewKeys].hide = !TConf.keysDumped; // -- Exit -- - mainMenuEntries[MainRebootAMS].hide = (!sd_mounted || !FileExists("sd:/atmosphere/reboot_payload.bin")); - mainMenuEntries[MainRebootHekate].hide = (!sd_mounted || !FileExists("sd:/bootloader/update.bin")); + mainMenuEntries[MainRebootAMS].hide = (!sd_get_card_mounted() || !FileExists("sd:/atmosphere/reboot_payload.bin")); + mainMenuEntries[MainRebootHekate].hide = (!sd_get_card_mounted() || !FileExists("sd:/bootloader/update.bin")); mainMenuEntries[MainRebootRCM].hide = h_cfg.t210b01; #endif // -- Scripts -- #ifndef INCLUDE_BUILTIN_SCRIPTS - mainMenuEntries[MainScripts].hide = (!sd_mounted || !FileExists("sd:/tegraexplorer/scripts")); + mainMenuEntries[MainScripts].hide = (!sd_get_card_mounted() || !FileExists("sd:/tegraexplorer/scripts")); #else - mainMenuEntries[MainScripts].hide = ((!sd_mounted || !FileExists("sd:/tegraexplorer/scripts")) && !EMBEDDED_SCRIPTS_LEN); + mainMenuEntries[MainScripts].hide = ((!sd_get_card_mounted() || !FileExists("sd:/tegraexplorer/scripts")) && !EMBEDDED_SCRIPTS_LEN); #endif Vector_t ent = newVec(sizeof(MenuEntry_t), ARRAY_SIZE(mainMenuEntries)); @@ -209,7 +203,7 @@ void EnterMainMenu(){ } #endif - if (sd_mounted && FileExists("sd:/tegraexplorer/scripts")){ + if (sd_get_card_mounted() && FileExists("sd:/tegraexplorer/scripts")){ scriptFiles = ReadFolder("sd:/tegraexplorer/scripts", &res); if (!res){ if (!scriptFiles.count){ diff --git a/source/tegraexplorer/tools.c b/source/tegraexplorer/tools.c index 429fdba..b71a0bd 100644 --- a/source/tegraexplorer/tools.c +++ b/source/tegraexplorer/tools.c @@ -3,21 +3,18 @@ #include "../gfx/gfxutils.h" #include "../gfx/menu.h" #include "../hid/hid.h" -#include #include "../keys/keys.h" #include "../keys/nca.h" -#include #include "../fs/fsutils.h" -#include #include "../storage/mountmanager.h" #include "../err.h" -#include -#include #include "../tegraexplorer/tconf.h" #include "../fs/readers/folderReader.h" #include #include "../fs/fscopy.h" #include "../utils/utils.h" +#include +#include void DumpSysFw(){ char sysPath[25 + 36 + 3 + 1]; // 24 for "bis:/Contents/registered", 36 for ncaName.nca, 3 for /00, and 1 to make sure :) @@ -118,7 +115,6 @@ void DumpSysFw(){ } extern sdmmc_storage_t sd_storage; -extern bool is_sd_inited; MenuEntry_t FatAndEmu[] = { {.optionUnion = COLORTORGB(COLOR_ORANGE), .name = "Back to main menu"}, @@ -133,7 +129,7 @@ void FormatSD(){ bool emummc = 0; int res; - if (!is_sd_inited || sd_get_card_removed()) + if (!sd_get_card_initialized() || sd_get_card_removed()) return; gfx_printf("\nDo you want to partition for an emummc?\n"); @@ -198,12 +194,10 @@ void FormatSD(){ hidWait(); } -extern bool sd_mounted; - void TakeScreenshot(){ static u32 timer = 0; - if (!TConf.minervaEnabled || !sd_mounted) + if (!TConf.minervaEnabled || !sd_get_card_mounted()) return; if (timer + 3 < get_tmr_s())