diff --git a/bdk/bdk.h b/bdk/bdk.h new file mode 100644 index 00000000..1cb315c6 --- /dev/null +++ b/bdk/bdk.h @@ -0,0 +1,79 @@ +/* + * 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 +#include +#include + +#include + +#endif \ No newline at end of file diff --git a/bdk/display/di.c b/bdk/display/di.c index 9396e99a..39bcfe1d 100644 --- a/bdk/display/di.c +++ b/bdk/display/di.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2021 CTCaer + * Copyright (c) 2018-2023 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, @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -35,8 +36,9 @@ extern volatile nyx_storage_t *nyx_str; -static u32 _display_id = 0; -static bool nx_aula = false; +static u32 _display_id = 0; +static u32 _dsi_bl = -1; +static bool _nx_aula = false; static void _display_panel_and_hw_end(bool no_panel_deinit); @@ -57,9 +59,52 @@ static void _display_dsi_send_cmd(u8 cmd, u32 param, u32 wait) usleep(wait); } +static void _display_dsi_wait_vblank(bool enable) +{ + if (enable) + { + // 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)) + ; + } + else + { + // 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)) + ; + usleep(14); + + // 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; + } +} + static void _display_dsi_read_rx_fifo(u32 *data) { u32 fifo_count = DSI(_DSIREG(DSI_STATUS)) & DSI_STATUS_RX_FIFO_SIZE; + if (fifo_count) + DSI(_DSIREG(DSI_TRIGGER)) = 0; + for (u32 i = 0; i < fifo_count; i++) { // Read or Drain RX FIFO. @@ -70,44 +115,95 @@ static void _display_dsi_read_rx_fifo(u32 *data) } } -int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled) +int display_dsi_read(u8 cmd, u32 len, void *data) { int res = 0; - u32 host_control = 0; - u32 cmd_timeout = video_enabled ? 0 : 250000; u32 fifo[DSI_STATUS_RX_FIFO_SIZE] = {0}; // Drain RX FIFO. _display_dsi_read_rx_fifo(NULL); - // Save host control and enable host cmd packets during video. - if (video_enabled) + // Set reply size. + _display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 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, cmd, 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_IMM_BTA; + + // Wait for reply to complete. DSI_HOST_CONTROL_IMM_BTA bit acts as a DSI host read busy. + _display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA); + + // Wait a bit for the reply. + usleep(5000); + + // Read RX FIFO. + _display_dsi_read_rx_fifo(fifo); + + // Parse packet and copy over the data. + if ((fifo[0] & 0xFF) == DSI_ESCAPE_CMD) { - host_control = DSI(_DSIREG(DSI_HOST_CONTROL)); + // Act based on reply type. + switch (fifo[1] & 0xFF) + { + case GEN_LONG_RD_RES: + case DCS_LONG_RD_RES: + memcpy(data, &fifo[2], MIN((fifo[1] >> 8) & 0xFFFF, len)); + break; - // Enable vblank interrupt. - DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = DC_CMD_INT_FRAME_END_INT; + case GEN_1_BYTE_SHORT_RD_RES: + case DCS_1_BYTE_SHORT_RD_RES: + memcpy(data, &fifo[2], 1); + break; - // 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); + case GEN_2_BYTE_SHORT_RD_RES: + case DCS_2_BYTE_SHORT_RD_RES: + memcpy(data, &fifo[2], 2); + break; - // 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)) - ; + case ACK_ERROR_RES: + default: + res = 1; + break; + } } + else + res = 1; + + return res; +} + +int display_dsi_vblank_read(u8 cmd, u32 len, void *data) +{ + int res = 0; + u32 host_control = 0; + u32 fifo[DSI_STATUS_RX_FIFO_SIZE] = {0}; + + // Drain RX FIFO. + _display_dsi_read_rx_fifo(NULL); + + // Save host control and enable host cmd packets during video. + host_control = DSI(_DSIREG(DSI_HOST_CONTROL)); + + _display_dsi_wait_vblank(true); // Set reply size. _display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0); - _display_dsi_wait(cmd_timeout, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO); + _display_dsi_wait(0, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO); // Request register read. _display_dsi_send_cmd(MIPI_DSI_DCS_READ, cmd, 0); - _display_dsi_wait(cmd_timeout, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO); + _display_dsi_wait(0, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO); + + _display_dsi_wait_vblank(false); // Transfer bus control to device for transmitting the reply. - u32 high_speed = video_enabled ? DSI_HOST_CONTROL_HS : 0; - DSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC | high_speed; + DSI(_DSIREG(DSI_HOST_CONTROL)) |= DSI_HOST_CONTROL_IMM_BTA; + + // Wait for reply to complete. DSI_HOST_CONTROL_IMM_BTA bit acts as a DSI host read busy. _display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA); // Wait a bit for the reply. @@ -146,47 +242,38 @@ int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled) 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)) - ; - - // 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; - DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control; - - // 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; - } + // Restore host control. + DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control; return res; } -void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled) +void display_dsi_write(u8 cmd, u32 len, void *data) { - u8 *fifo8; - u32 *fifo32; + static u8 *fifo8 = NULL; + static u32 *fifo32 = NULL; u32 host_control; - // Enable host cmd packets during video and save host control. - if (video_enabled) - DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE; + // Allocate fifo buffer. + if (!fifo32) + { + fifo32 = malloc(DSI_STATUS_RX_FIFO_SIZE * 8 * sizeof(u32)); + fifo8 = (u8 *)fifo32; + } + + // Prepare data for long write. + if (len >= 2) + { + memcpy(&fifo8[5], data, len); + memset(&fifo8[5] + len, 0, len % sizeof(u32)); + len++; // Increase length by CMD. + } + + // Save host control. host_control = DSI(_DSIREG(DSI_HOST_CONTROL)); // Enable host transfer trigger. - DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control | DSI_HOST_CONTROL_TX_TRIG_HOST; + DSI(_DSIREG(DSI_HOST_CONTROL)) = (host_control & ~(DSI_HOST_CONTROL_TX_TRIG_MASK)) | DSI_HOST_CONTROL_TX_TRIG_HOST; switch (len) { @@ -199,43 +286,43 @@ void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled) break; default: - fifo32 = calloc(DSI_STATUS_RX_FIFO_SIZE * 8, 4); - fifo8 = (u8 *)fifo32; fifo32[0] = (len << 8) | MIPI_DSI_DCS_LONG_WRITE; fifo8[4] = cmd; - memcpy(&fifo8[5], data, len); - len += 4 + 1; // Increase length by CMD/length word and DCS CMD. - for (u32 i = 0; i < (ALIGN(len, 4) / 4); i++) + len += sizeof(u32); // Increase length by length word and DCS CMD. + for (u32 i = 0; i < (ALIGN(len, sizeof(u32)) / sizeof(u32)); i++) DSI(_DSIREG(DSI_WR_DATA)) = fifo32[i]; DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST; - free(fifo32); break; } // Wait for the write to happen. _display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST); - // Disable host cmd packets during video and restore host control. - if (video_enabled) - DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0; + // Restore host control. DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control; } void display_dsi_vblank_write(u8 cmd, u32 len, void *data) { - u8 *fifo8; - u32 *fifo32; + static u8 *fifo8 = NULL; + static u32 *fifo32 = NULL; - // Enable vblank interrupt. - DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = DC_CMD_INT_FRAME_END_INT; + // Allocate fifo buffer. + if (!fifo32) + { + fifo32 = malloc(DSI_STATUS_RX_FIFO_SIZE * 8 * sizeof(u32)); + fifo8 = (u8 *)fifo32; + } - // 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); + // Prepare data for long write. + if (len >= 2) + { + memcpy(&fifo8[5], data, len); + memset(&fifo8[5] + len, 0, len % sizeof(u32)); + len++; // Increase length by CMD. + } - // 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)) - ; + _display_dsi_wait_vblank(true); switch (len) { @@ -248,43 +335,21 @@ void display_dsi_vblank_write(u8 cmd, u32 len, void *data) break; default: - fifo32 = calloc(DSI_STATUS_RX_FIFO_SIZE * 8, 4); - fifo8 = (u8 *)fifo32; fifo32[0] = (len << 8) | MIPI_DSI_DCS_LONG_WRITE; fifo8[4] = cmd; - memcpy(&fifo8[5], data, len); - len += 4 + 1; // Increase length by CMD/length word and DCS CMD. - for (u32 i = 0; i < (ALIGN(len, 4) / 4); i++) + len += sizeof(u32); // Increase length by length word and DCS CMD. + for (u32 i = 0; i < (ALIGN(len, sizeof(u32)) / sizeof(u32)); i++) DSI(_DSIREG(DSI_WR_DATA)) = fifo32[i]; - free(fifo32); break; } - // Wait for vblank before reseting sync points. - DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt. - while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT)) - ; - - // Reset all states of syncpt block. - DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = DSI_INCR_SYNCPT_SOFT_RESET; - usleep(300); // Stabilization delay. - - // Clear syncpt block reset. - DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = 0; - usleep(300); // Stabilization delay. - - // Restore video mode and host control. - DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0; - - // Disable and clear vblank interrupt. - DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = 0; - DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; + _display_dsi_wait_vblank(false); } 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; + _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)) @@ -302,68 +367,57 @@ void display_init() // Set slew rate and enable SD2 regulator. i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD2_CFG, (1 << MAX77620_SD_SR_SHIFT) | MAX77620_SD_CFG1_FSRADE_SD_ENABLE); max7762x_regulator_enable(REGULATOR_SD2, true); - } - // Enable power to display panel controller. + // Enable LCD DVDD. max7762x_regulator_set_voltage(REGULATOR_LDO0, 1200000); max7762x_regulator_enable(REGULATOR_LDO0, true); if (tegra_t210) - max77620_config_gpio(7, MAX77620_GPIO_OUTPUT_ENABLE); // T210: LD0 -> GPIO7 -> Display panel. + max77620_config_gpio(7, MAX77620_GPIO_OUTPUT_ENABLE); // T210: LD0 -> GPIO7 -> LCD. // Enable Display Interface specific clocks. CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI); - - CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1); - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1); + CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_DISP1); + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_DISP1); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_UART_FST_MIPI_CAL); CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = 10; // Set PLLP_OUT3 and div 6 (17MHz). CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP); - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 10; // Set PLLP_OUT and div 6 (68MHz). + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 10; // Set PLLP_OUT and div 6 (68MHz). // Bring every IO rail out of deep power down. PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF; PMC(APBDEV_PMC_IO_DPD2_REQ) = PMC_IO_DPD_REQ_DPD_OFF; - // Configure LCD pins. - PINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN - PINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE; // PULL_DOWN - PINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE; // PULL_DOWN - - // Configure Backlight pins. - PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= ~PINMUX_TRISTATE; // PULL_DOWN | 1 - PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN - - if (nx_aula) + // Configure LCD/BL pins. + 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); + // Configure LCD pins. + PINMUX_AUX(PINMUX_AUX_NFC_EN) = PINMUX_PULL_DOWN; + PINMUX_AUX(PINMUX_AUX_NFC_INT) = PINMUX_PULL_DOWN; - // 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 pins. + PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = PINMUX_PULL_DOWN; + PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) = PINMUX_PULL_DOWN; + + // Enable LCD AVDD. + gpio_direction_output(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_HIGH); + usleep(10000); // Wait minimum 4.2ms to stabilize. - // 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 pins (BL PWM, BL EN). + gpio_direction_output(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1, GPIO_LOW); // Enable Backlight power. gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH); } + // Configure LCD RST pin. + PINMUX_AUX(PINMUX_AUX_LCD_RST) = PINMUX_PULL_DOWN; + gpio_direction_output(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); + // Power up supply regulator for display interface. MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0; @@ -373,39 +427,32 @@ void display_init() APB_MISC(APB_MISC_GP_DSI_PAD_CONTROL) = 0; } - // Set DISP1 clock source and parent clock. - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 0x40000000; // PLLD_OUT. - u32 plld_div = (3 << 20) | (20 << 11) | 1; // DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 97.5 MHz (offset). - CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div; - - if (tegra_t210) - { - CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0x20; // PLLD_SETUP. - CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2D0AAA; // PLLD_ENABLE_CLK. - } - else - { - CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0; - CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2DFC00; // PLLD_ENABLE_CLK. - } + // Set DISP1 clock source, parent clock and DSI/PCLK to low power mode. + // T210: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 100.0 MHz, PLLD_OUT0 (DSI-PCLK): 50.0 MHz. (PCLK: 16.66 MHz) + // T210B01: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 97.8 MHz, PLLD_OUT0 (DSI-PCLK): 48.9 MHz. (PCLK: 16.30 MHz) + clock_enable_plld(3, 20, true, tegra_t210); // Setup Display Interface initial window configuration. - exec_cfg((u32 *)DISPLAY_A_BASE, _display_dc_setup_win_config, 94); + exec_cfg((u32 *)DISPLAY_A_BASE, _di_dc_setup_win_config, CFG_SIZE(_di_dc_setup_win_config)); - // Setup display communication interfaces. - exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part1, 8); + // Setup dsi init sequence packets. + exec_cfg((u32 *)DSI_BASE, _di_dsi_init_irq_pkt_config0, CFG_SIZE(_di_dsi_init_irq_pkt_config0)); if (tegra_t210) DSI(_DSIREG(DSI_INIT_SEQ_DATA_15)) = 0; else DSI(_DSIREG(DSI_INIT_SEQ_DATA_15_B01)) = 0; - exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part2, 14); + exec_cfg((u32 *)DSI_BASE, _di_dsi_init_irq_pkt_config1, CFG_SIZE(_di_dsi_init_irq_pkt_config1)); + + // Reset pad trimmers for T210B01. if (!tegra_t210) - exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part3_t210b01, 7); - exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part4, 10); - DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603; - exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part5, 12); - DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603; - exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part6, 14); + exec_cfg((u32 *)DSI_BASE, _di_dsi_init_pads_t210b01, CFG_SIZE(_di_dsi_init_pads_t210b01)); + + // Setup init sequence packets and timings. + exec_cfg((u32 *)DSI_BASE, _di_dsi_init_timing_pkt_config2, CFG_SIZE(_di_dsi_init_timing_pkt_config2)); + DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603; // DSI_THSPREPR: 1 : 3. + exec_cfg((u32 *)DSI_BASE, _di_dsi_init_timing_pwrctrl_config, CFG_SIZE(_di_dsi_init_timing_pwrctrl_config)); + DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603; // DSI_THSPREPR: 1 : 3. + exec_cfg((u32 *)DSI_BASE, _di_dsi_init_timing_pkt_config3, CFG_SIZE(_di_dsi_init_timing_pkt_config3)); usleep(10000); // Enable LCD Reset. @@ -413,13 +460,13 @@ void display_init() usleep(60000); // Setup DSI device takeover timeout. - DSI(_DSIREG(DSI_BTA_TIMING)) = nx_aula ? 0x40103 : 0x50204; + DSI(_DSIREG(DSI_BTA_TIMING)) = _nx_aula ? 0x40103 : 0x50204; // Get Display ID. _display_id = 0xCCCCCC; for (u32 i = 0; i < 3; i++) { - if (!display_dsi_read(MIPI_DCS_GET_DISPLAY_ID, 3, &_display_id, DSI_VIDEO_DISABLED)) + if (!display_dsi_read(MIPI_DCS_GET_DISPLAY_ID, 3, &_display_id)) break; usleep(10000); @@ -435,7 +482,7 @@ void display_init() _display_id = PANEL_JDI_XXX062M; // For Aula ensure that we have a compatible panel id. - if (nx_aula && _display_id == 0xCCCC) + if (_nx_aula && _display_id == 0xCCCC) _display_id = PANEL_SAM_AMS699VC01; // Initialize display panel. @@ -443,16 +490,39 @@ void display_init() { 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. + // Set color mode to natural. Stock is Saturated (0x00). (Reset value is 0x20). + _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, + MIPI_DCS_PRIV_SM_SET_COLOR_MODE | (DCS_SM_COLOR_MODE_NATURAL << 8), 0); + // Enable backlight and smooth PWM. + _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, + MIPI_DCS_SET_CONTROL_DISPLAY | ((DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL | DCS_CONTROL_DISPLAY_DIMMING_CTRL) << 8), 0); + + // Unlock Level 2 registers. + DSI(_DSIREG(DSI_WR_DATA)) = 0x539; // MIPI_DSI_DCS_LONG_WRITE: 5 bytes. + DSI(_DSIREG(DSI_WR_DATA)) = 0x5A5A5AE2; // MIPI_DCS_PRIV_SM_SET_REGS_LOCK: Unlock Level 2 registers. + DSI(_DSIREG(DSI_WR_DATA)) = 0x5A; + DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST; + + // Set registers offset and set PWM transition to 6 frames (100ms). + _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, MIPI_DCS_PRIV_SM_SET_REG_OFFSET | (7 << 8), 0); + _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, MIPI_DCS_PRIV_SM_SET_ELVSS | (6 << 8), 0); + + // Relock Level 2 registers. + DSI(_DSIREG(DSI_WR_DATA)) = 0x539; // MIPI_DSI_DCS_LONG_WRITE: 5 bytes. + DSI(_DSIREG(DSI_WR_DATA)) = 0xA55A5AE2; // MIPI_DCS_PRIV_SM_SET_REGS_LOCK: Lock Level 2 registers. + DSI(_DSIREG(DSI_WR_DATA)) = 0xA5; + DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST; + + // Set backlight to 0%. 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); + _dsi_bl = 0; break; case PANEL_JDI_XXX062M: - exec_cfg((u32 *)DSI_BASE, _display_init_config_jdi, 43); + exec_cfg((u32 *)DSI_BASE, _di_dsi_panel_init_config_jdi, CFG_SIZE(_di_dsi_panel_init_config_jdi)); _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000); break; @@ -479,7 +549,7 @@ void display_init() case PANEL_INL_2J055IA_27A: case PANEL_AUO_A055TAN01: - case PANEL_V40_55_UNK: + case PANEL_SHP_LQ055T1SW10: default: // Allow spare part displays to work. _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 120000); break; @@ -488,28 +558,25 @@ void display_init() // Unblank display. _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, it's ddr btw, so normally div2). - CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div; - - if (tegra_t210) - CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0x20; // PLLD_SETUP. - else - CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0; - CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2DFC00; // Use new PLLD_SDM_DIN. + // Setup final dsi clock. + // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 468.0 MHz, PLLD_OUT0 (DSI): 234.0 MHz. + clock_enable_plld(1, 24, false, tegra_t210); - // Finalize DSI configuration. + // Finalize DSI init packet sequence configuration. DSI(_DSIREG(DSI_PAD_CONTROL_1)) = 0; DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603; - exec_cfg((u32 *)DSI_BASE, _display_dsi_packet_config, 19); - // Set pixel clock dividers: 234 / 3 / 1 = 78 MHz (offset) for 60 Hz. + exec_cfg((u32 *)DSI_BASE, _di_dsi_init_seq_pkt_final_config, CFG_SIZE(_di_dsi_init_seq_pkt_final_config)); + + // Set 1-by-1 pixel/clock and pixel clock to 234 / 3 = 78 MHz. For 60 Hz refresh rate. DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4); // 4: div3. - exec_cfg((u32 *)DSI_BASE, _display_dsi_mode_config, 10); + + // Set DSI mode. + exec_cfg((u32 *)DSI_BASE, _di_dsi_mode_config, CFG_SIZE(_di_dsi_mode_config)); usleep(10000); // Calibrate display communication pads. - u32 loops = tegra_t210 ? 1 : 2; // Find out why this is done 2 times on Mariko. - exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_pad_cal_config, 4); + u32 loops = tegra_t210 ? 1 : 2; // Calibrate pads 2 times on T210B01. + exec_cfg((u32 *)MIPI_CAL_BASE, _di_mipi_pad_cal_config, CFG_SIZE(_di_mipi_pad_cal_config)); for (u32 i = 0; i < loops; i++) { // Set MIPI bias pad config. @@ -519,22 +586,22 @@ void display_init() // Set pad trimmers and set MIPI DSI cal offsets. if (tegra_t210) { - exec_cfg((u32 *)DSI_BASE, _display_dsi_pad_cal_config_t210, 4); - exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_dsi_cal_offsets_config_t210, 4); + exec_cfg((u32 *)DSI_BASE, _di_dsi_pad_cal_config_t210, CFG_SIZE(_di_dsi_pad_cal_config_t210)); + exec_cfg((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_offsets_config_t210, CFG_SIZE(_di_mipi_dsi_cal_offsets_config_t210)); } else { - exec_cfg((u32 *)DSI_BASE, _display_dsi_pad_cal_config_t210b01, 7); - exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_dsi_cal_offsets_config_t210b01, 4); + exec_cfg((u32 *)DSI_BASE, _di_dsi_pad_cal_config_t210b01, CFG_SIZE(_di_dsi_pad_cal_config_t210b01)); + exec_cfg((u32 *)MIPI_CAL_BASE, _di_mipi_dsi_cal_offsets_config_t210b01, CFG_SIZE(_di_mipi_dsi_cal_offsets_config_t210b01)); } - // Set the rest of MIPI cal offsets and apply calibration. - exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_apply_dsi_cal_config, 12); + // Reset all MIPI cal offsets and start calibration. + exec_cfg((u32 *)MIPI_CAL_BASE, _di_mipi_start_dsi_cal_config, CFG_SIZE(_di_mipi_start_dsi_cal_config)); } usleep(10000); // Enable video display controller. - exec_cfg((u32 *)DISPLAY_A_BASE, _display_video_disp_controller_enable_config, 113); + exec_cfg((u32 *)DISPLAY_A_BASE, _di_dc_video_enable_config, CFG_SIZE(_di_dc_video_enable_config)); } void display_backlight_pwm_init() @@ -544,7 +611,8 @@ void display_backlight_pwm_init() clock_enable_pwm(); - PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN; // Enable PWM and set it to 25KHz PFM. 29.5KHz is stock. + // Enable PWM and set it to 25KHz PFM. 29.5KHz is stock. + PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN; PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode. gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode. @@ -552,28 +620,37 @@ void display_backlight_pwm_init() void display_backlight(bool enable) { - gpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW); // Backlight PWM GPIO. + // Backlight PWM GPIO. + gpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW); } -void display_dsi_backlight_brightness(u32 brightness) +static void _display_dsi_backlight_brightness(u32 duty) { - // Normalize brightness value by 82% and a base of 45 duty. - if (brightness) - brightness = (brightness * PANEL_OLED_BL_COEFF / 100) + PANEL_OLED_BL_OFFSET; + if (_dsi_bl == duty) + return; - u16 bl_ctrl = byte_swap_16((u16)(brightness * 8)); + // Convert duty to candela. + u32 candela = duty * PANEL_SM_BL_CANDELA_MAX / 255; + + u16 bl_ctrl = byte_swap_16((u16)candela); display_dsi_vblank_write(MIPI_DCS_SET_BRIGHTNESS, 2, &bl_ctrl); + + // Wait for backlight to completely turn off. 6+1 frames. + if (!duty) + usleep(120000); + + _dsi_bl = duty; } -void display_pwm_backlight_brightness(u32 brightness, u32 step_delay) +static void _display_pwm_backlight_brightness(u32 duty, u32 step_delay) { u32 old_value = (PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF; - if (brightness == old_value) + if (duty == old_value) return; - if (old_value < brightness) + if (old_value < duty) { - for (u32 i = old_value; i < brightness + 1; i++) + for (u32 i = old_value; i < duty + 1; i++) { PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); usleep(step_delay); @@ -581,13 +658,13 @@ void display_pwm_backlight_brightness(u32 brightness, u32 step_delay) } else { - for (u32 i = old_value; i > brightness; i--) + for (u32 i = old_value; i > duty; i--) { PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); usleep(step_delay); } } - if (!brightness) + if (!duty) PWM(PWM_CONTROLLER_PWM_CSR_0) = 0; } @@ -597,9 +674,9 @@ void display_backlight_brightness(u32 brightness, u32 step_delay) brightness = 255; if (_display_id != PANEL_SAM_AMS699VC01) - display_pwm_backlight_brightness(brightness, step_delay); + _display_pwm_backlight_brightness(brightness, step_delay); else - display_dsi_backlight_brightness(brightness); + _display_dsi_backlight_brightness(brightness); } u32 display_get_backlight_brightness() @@ -620,13 +697,23 @@ static void _display_panel_and_hw_end(bool no_panel_deinit) // Blank display. DSI(_DSIREG(DSI_WR_DATA)) = (MIPI_DCS_SET_DISPLAY_OFF << 8) | MIPI_DSI_DCS_SHORT_WRITE; + // Wait for 5 frames (HOST1X_CH0_SYNC_SYNCPT_9). + // Not here. + // Propagate changes to all register buffers and disable host cmd packets during video. DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX; DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0; // 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); + exec_cfg((u32 *)DISPLAY_A_BASE, _di_dc_video_disable_config, CFG_SIZE(_di_dc_video_disable_config)); + + // Set DISP1 clock source, parent clock and DSI/PCLK to low power mode. + // T210: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 100.0 MHz, PLLD_OUT0 (DSI-PCLK): 50.0 MHz. (PCLK: 16.66 MHz) + // T210B01: DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 97.8 MHz, PLLD_OUT0 (DSI-PCLK): 48.9 MHz. (PCLK: 16.30 MHz) + clock_enable_plld(3, 20, true, hw_get_chip_id() == GP_HIDREV_MAJOR_T210); + + // Set timings for lowpower clocks. + exec_cfg((u32 *)DSI_BASE, _di_dsi_timing_deinit_config, CFG_SIZE(_di_dsi_timing_deinit_config)); if (_display_id != PANEL_SAM_AMS699VC01) usleep(10000); @@ -635,16 +722,16 @@ static void _display_panel_and_hw_end(bool no_panel_deinit) switch (_display_id) { case PANEL_JDI_XXX062M: - exec_cfg((u32 *)DSI_BASE, _display_deinit_config_jdi, 22); + exec_cfg((u32 *)DSI_BASE, _di_dsi_panel_deinit_config_jdi, CFG_SIZE(_di_dsi_panel_deinit_config_jdi)); break; case PANEL_AUO_A062TAN01: - exec_cfg((u32 *)DSI_BASE, _display_deinit_config_auo, 37); + exec_cfg((u32 *)DSI_BASE, _di_dsi_panel_deinit_config_auo, CFG_SIZE(_di_dsi_panel_deinit_config_auo)); break; case PANEL_INL_2J055IA_27A: case PANEL_AUO_A055TAN01: - case PANEL_V40_55_UNK: + case PANEL_SHP_LQ055T1SW10: // Unlock extension cmds. DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes. DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94). @@ -657,7 +744,7 @@ static void _display_panel_and_hw_end(bool no_panel_deinit) DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40). else if (_display_id == PANEL_AUO_A055TAN01) DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40). - else // PANEL_V40_55_UNK. + else // PANEL_SHP_LQ055T1SW10. DSI(_DSIREG(DSI_WR_DATA)) = 0x731348B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT3 / XDK, VRH gamma volt adj 51 / x40). if (_display_id == PANEL_INL_2J055IA_27A || _display_id == PANEL_AUO_A055TAN01) { @@ -665,7 +752,7 @@ static void _display_panel_and_hw_end(bool no_panel_deinit) DSI(_DSIREG(DSI_WR_DATA)) = 0x71143209; DSI(_DSIREG(DSI_WR_DATA)) = 0x114D31; // (Unknown). } - else // PANEL_V40_55_UNK. + else // PANEL_SHP_LQ055T1SW10. { // (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/48, Enter standby / PON / VCOMG). DSI(_DSIREG(DSI_WR_DATA)) = 0x71243209; @@ -676,6 +763,7 @@ static void _display_panel_and_hw_end(bool no_panel_deinit) break; case PANEL_INL_P062CCA_AZ1: + case PANEL_SAM_AMS699VC01: default: break; } @@ -687,35 +775,35 @@ static void _display_panel_and_hw_end(bool no_panel_deinit) skip_panel_deinit: // Disable LCD power pins. gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); // LCD Reset disable. + usleep(10000); - if (!nx_aula) // HOS uses panel id. + 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); + gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); // LCD AVDD -5.4V disable. + gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); // LCD AVDD +5.4V disable. } - else - usleep(30000); // Aula Panel. + usleep(10000); // Disable Display Interface specific clocks. CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI); - CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1); - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1); + CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_DISP1); + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_DISP1); // Power down pads. - DSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF); + DSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | + DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF); DSI(_DSIREG(DSI_POWER_CONTROL)) = 0; // Switch LCD PWM backlight pin to special function mode and enable PWM0 mode. - if (!nx_aula) + 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. + PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = PINMUX_TRISTATE | PINMUX_PULL_DOWN | 1; // Set PWM0 mode. } + + // Disable LCD DVDD. + max7762x_regulator_enable(REGULATOR_LDO0, false); } void display_end() { _display_panel_and_hw_end(false); }; @@ -728,7 +816,7 @@ 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; + _nx_aula = fuse_read_hw_type() == FUSE_NX_HW_TYPE_AULA; // Decode Display ID. _display_id = ((id >> 8) & 0xFF00) | (id & 0xFF); @@ -737,13 +825,13 @@ void display_set_decoded_panel_id(u32 id) _display_id = PANEL_JDI_XXX062M; // For Aula ensure that we have a compatible panel id. - if (nx_aula && _display_id == 0xCCCC) + if (_nx_aula && _display_id == 0xCCCC) _display_id = PANEL_SAM_AMS699VC01; } void display_color_screen(u32 color) { - exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_one_color, 8); + exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_one_color, CFG_SIZE(_di_win_one_color)); // Configure display to show single color. DISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0; @@ -751,110 +839,151 @@ 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); // No need to wait on Aula. + usleep(35000); // Wait 2 frames. No need on Aula. if (_display_id != PANEL_SAM_AMS699VC01) display_backlight(true); else - display_backlight_brightness(255, 0); + display_backlight_brightness(150, 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 720x1280 (line stride 720). + exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_pitch, CFG_SIZE(_di_win_framebuffer_pitch)); + //usleep(35000); // Wait 2 frames. No need on Aula. + + return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR)); +} - // 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); // No need to wait on Aula. +u32 *display_init_framebuffer_pitch_vic() +{ + // This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280 (line stride 720). + if (_display_id != PANEL_SAM_AMS699VC01) + usleep(8000); // Wait half frame for PWM to apply. + exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_pitch_vic, CFG_SIZE(_di_win_framebuffer_pitch_vic)); + if (_display_id != PANEL_SAM_AMS699VC01) + usleep(35000); // Wait 2 frames. - 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. + // This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280 (line stride 720). + exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_pitch_inv, CFG_SIZE(_di_win_framebuffer_pitch_inv)); + usleep(35000); // Wait 2 frames. No need on Aula. - 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. + // This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280. + exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_block, CFG_SIZE(_di_win_framebuffer_block)); + usleep(35000); // Wait 2 frames. No need on Aula. - return (u32 *)NYX_FB_ADDRESS; + return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR)); } 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); + exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_log, CFG_SIZE(_di_win_framebuffer_log)); - return (u32 *)LOG_FB_ADDRESS; + return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR)); } void display_activate_console() { - DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window D. - DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = WIN_ENABLE; // Enable window DD. - DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0xFF80; - DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE; + // Select window D. + DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; + + // Enable and setup window D. + DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = WIN_ENABLE; + DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0xFF80; // X: -128. + + // Arm and activate changes. + DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE; DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ; + // Pull-down effect. for (u32 i = 0xFF80; i < 0x10000; i++) { + // Set window position. DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF; - DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE; + + // Arm and activate changes. + DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE; DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ; usleep(1000); } DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0; - DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE; + + // Arm and activate changes. + DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE; DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ; + + // Re-select window A. + DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_A_SELECT; } void display_deactivate_console() { - DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window D. + // Select window D. + DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; + // Pull-up effect. for (u32 i = 0xFFFF; i > 0xFF7F; i--) { + // Set window position. DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF; - DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE; + + // Arm and activate changes. + DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE; DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ; usleep(500); } + // Disable window D. DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0; - DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = 0; // Disable window DD. - DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE; + DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = 0; + + // Arm and activate changes. + DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE; DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ; + + // Re-select window A. + DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_A_SELECT; } void display_init_cursor(void *crs_fb, u32 size) { // Setup cursor. - DISPLAY_A(_DIREG(DC_DISP_CURSOR_START_ADDR)) = CURSOR_CLIPPING(CURSOR_CLIP_WIN_A) | size | ((u32)crs_fb >> 10); - DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) = - CURSOR_BLEND_R8G8B8A8 | CURSOR_BLEND_DST_FACTOR(CURSOR_BLEND_K1) | CURSOR_BLEND_SRC_FACTOR(CURSOR_BLEND_K1) | 0xFF; + DISPLAY_A(_DIREG(DC_DISP_CURSOR_START_ADDR)) = CURSOR_CLIPPING(CURSOR_CLIP_WIN_A) | size | ((u32)crs_fb >> 10); + DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) = CURSOR_BLEND_R8G8B8A8 | + CURSOR_BLEND_DST_FACTOR(CURSOR_BLEND_K1) | + CURSOR_BLEND_SRC_FACTOR(CURSOR_BLEND_K1) | 0xFF; + // Enable cursor window. DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) |= CURSOR_ENABLE; // Arm and activate changes. - DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE; + DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE; DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ; } void display_set_pos_cursor(u32 x, u32 y) { + // Set cursor position. DISPLAY_A(_DIREG(DC_DISP_CURSOR_POSITION)) = x | (y << 16); - DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE; + // Arm and activate changes. + DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE; DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ; } @@ -862,6 +991,7 @@ void display_deinit_cursor() { DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) = 0; DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) &= ~CURSOR_ENABLE; - DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE; + + DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE; DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ; } diff --git a/bdk/display/di.h b/bdk/display/di.h index 1e0f991e..4a19ecb9 100644 --- a/bdk/display/di.h +++ b/bdk/display/di.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2021 CTCaer + * Copyright (c) 2018-2023 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, @@ -43,13 +43,17 @@ // DC_CMD non-shadowed command/sync registers. #define DC_CMD_GENERAL_INCR_SYNCPT 0x00 +#define SYNCPT_GENERAL_INDX(x) (((x) & 0xff) << 0) +#define SYNCPT_GENERAL_COND(x) (((x) & 0xff) << 8) +#define COND_REG_WR_SAFE 3 #define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01 #define SYNCPT_CNTRL_SOFT_RESET BIT(0) #define SYNCPT_CNTRL_NO_STALL BIT(8) #define DC_CMD_CONT_SYNCPT_VSYNC 0x28 -#define SYNCPT_VSYNC_ENABLE BIT(8) +#define SYNCPT_VSYNC_INDX(x) (((x) & 0xff) << 0) +#define SYNCPT_VSYNC_ENABLE BIT(8) #define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031 @@ -72,6 +76,7 @@ #define DC_CMD_INT_MASK 0x38 #define DC_CMD_INT_ENABLE 0x39 #define DC_CMD_INT_FRAME_END_INT BIT(1) +#define DC_CMD_INT_V_BLANK_INT BIT(2) #define DC_CMD_STATE_ACCESS 0x40 #define READ_MUX BIT(0) @@ -98,7 +103,13 @@ #define WINDOW_C_SELECT BIT(6) #define WINDOW_D_SELECT BIT(7) -#define DC_CMD_REG_ACT_CONTROL 0x043 +#define DC_CMD_REG_ACT_CONTROL 0x43 +#define GENERAL_ACT_HCNTR_SEL BIT(0) +#define WIN_A_ACT_HCNTR_SEL BIT(2) +#define WIN_B_ACT_HCNTR_SEL BIT(4) +#define WIN_C_ACT_HCNTR_SEL BIT(6) +#define CURSOR_ACT_HCNTR_SEL BIT(7) +#define WIN_D_ACT_HCNTR_SEL BIT(10) // DC_D_WIN_DD window D instance of DC_WIN #define DC_D_WIN_DD_WIN_OPTIONS 0x80 @@ -124,6 +135,7 @@ #define DC_COM_CRC_CONTROL 0x300 #define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x)) #define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x)) +#define LSC0_OUTPUT_POLARITY_LOW BIT(24) #define DC_COM_DSC_TOP_CTL 0x33E @@ -139,12 +151,29 @@ #define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403 #define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404 + #define DC_DISP_DISP_TIMING_OPTIONS 0x405 +#define VSYNC_H_POSITION(x) (((x) & 0x1fff) << 0) + #define DC_DISP_REF_TO_SYNC 0x406 +#define H_REF_TO_SYNC(x) (((x) & 0x1fff) << 0) // Min 0 pixel clock. +#define V_REF_TO_SYNC(x) (((x) & 0x1fff) << 16) // Min 1 line clock. + #define DC_DISP_SYNC_WIDTH 0x407 +#define H_SYNC_WIDTH(x) (((x) & 0x1fff) << 0) // Min 1 pixel clock. +#define V_SYNC_WIDTH(x) (((x) & 0x1fff) << 16) // Min 1 line clock. + #define DC_DISP_BACK_PORCH 0x408 +#define H_BACK_PORCH(x) (((x) & 0x1fff) << 0) +#define V_BACK_PORCH(x) (((x) & 0x1fff) << 16) + #define DC_DISP_ACTIVE 0x409 +#define H_DISP_ACTIVE(x) (((x) & 0x1fff) << 0) // Min 16 pixel clock. +#define V_DISP_ACTIVE(x) (((x) & 0x1fff) << 16) // Min 16 line clock. + #define DC_DISP_FRONT_PORCH 0x40A +#define H_FRONT_PORCH(x) (((x) & 0x1fff) << 0) // Min -=PS_=-H_REF_TO_SYNC + 1 +#define V_FRONT_PORCH(x) (((x) & 0x1fff) << 16) // Min -=PS_=-V_REF_TO_SYNC + 1 #define DC_DISP_DISP_CLOCK_CONTROL 0x42E #define SHIFT_CLK_DIVIDER(x) ((x) & 0xff) @@ -239,6 +268,10 @@ #define DC_DISP_SD_BL_CONTROL 0x4DC #define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4 +#define DC_WINC_COLOR_PALETTE 0x500 +#define DC_WINC_COLOR_PALETTE_IDX(off) (DC_WINC_COLOR_PALETTE + (off)) +#define DC_WINC_PALETTE_COLOR_EXT 0x600 + #define DC_WIN_CSC_YOF 0x611 #define DC_WIN_CSC_KYRGB 0x612 #define DC_WIN_CSC_KUR 0x613 @@ -253,12 +286,13 @@ // The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER). #define DC_WIN_WIN_OPTIONS 0x700 -#define H_DIRECTION BIT(0) -#define V_DIRECTION BIT(2) -#define SCAN_COLUMN BIT(4) -#define COLOR_EXPAND BIT(6) -#define CSC_ENABLE BIT(18) -#define WIN_ENABLE BIT(30) +#define H_DIRECTION BIT(0) +#define V_DIRECTION BIT(2) +#define SCAN_COLUMN BIT(4) +#define COLOR_EXPAND BIT(6) +#define COLOR_PALETTE_ENABLE BIT(16) +#define CSC_ENABLE BIT(18) +#define WIN_ENABLE BIT(30) #define DC_WIN_BUFFER_CONTROL 0x702 #define BUFFER_CONTROL_HOST 0 @@ -290,10 +324,22 @@ #define WIN_COLOR_DEPTH_YUV422R 0x17 #define WIN_COLOR_DEPTH_YCbCr422RA 0x18 #define WIN_COLOR_DEPTH_YUV422RA 0x19 +#define WIN_COLOR_DEPTH_YCbCr444P 0x29 +#define WIN_COLOR_DEPTH_YCrCb420SP 0x2A +#define WIN_COLOR_DEPTH_YCbCr420SP 0x2B +#define WIN_COLOR_DEPTH_YCrCb422SP 0x2C +#define WIN_COLOR_DEPTH_YCbCr422SP 0x2D +#define WIN_COLOR_DEPTH_YUV444P 0x34 +#define WIN_COLOR_DEPTH_YVU420SP 0x35 +#define WIN_COLOR_DEPTH_YUV420SP 0x36 +#define WIN_COLOR_DEPTH_YVU422SP 0x37 +#define WIN_COLOR_DEPTH_YUV422SP 0x38 +#define WIN_COLOR_DEPTH_YVU444SP 0x3B +#define WIN_COLOR_DEPTH_YUV444SP 0x3C #define DC_WIN_POSITION 0x704 -#define H_POSITION(x) (((x) & 0xFfff) << 0) -#define V_POSITION(x) (((x) & 0x1fff) << 16) +#define H_POSITION(x) (((x) & 0xffff) << 0) // Support negative. +#define V_POSITION(x) (((x) & 0xffff) << 16) // Support negative. #define DC_WIN_SIZE 0x705 #define H_SIZE(x) (((x) & 0x1fff) << 0) @@ -316,6 +362,7 @@ #define DC_WIN_DV_CONTROL 0x70E #define DC_WINBUF_BLEND_LAYER_CONTROL 0x716 +#define WIN_BLEND_DEPTH(x) (((x) & 0xff) << 0) #define WIN_K1(x) (((x) & 0xff) << 8) #define WIN_K2(x) (((x) & 0xff) << 16) #define WIN_BLEND_ENABLE (0 << 24) @@ -386,6 +433,7 @@ #define DSI_HOST_CONTROL_FIFO_SEL BIT(4) #define DSI_HOST_CONTROL_HS BIT(5) #define DSI_HOST_CONTROL_RAW BIT(6) +#define DSI_HOST_CONTROL_TX_TRIG_MASK (3 << 12) #define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12) #define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12) #define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12) @@ -433,10 +481,14 @@ #define DSI_PKT_SEQ_5_LO 0x2D #define DSI_PKT_SEQ_5_HI 0x2E #define DSI_DCS_CMDS 0x33 + #define DSI_PKT_LEN_0_1 0x34 #define DSI_PKT_LEN_2_3 0x35 #define DSI_PKT_LEN_4_5 0x36 #define DSI_PKT_LEN_6_7 0x37 +#define PKT0_LEN(x) (((x) & 0xffff) << 0) +#define PKT1_LEN(x) (((x) & 0xffff) << 16) + #define DSI_PHY_TIMING_0 0x3C #define DSI_PHY_TIMING_1 0x3D #define DSI_PHY_TIMING_2 0x3E @@ -593,6 +645,7 @@ #define MIPI_DCS_GET_SCANLINE 0x45 #define MIPI_DCS_SET_TEAR_SCANLINE_WIDTH 0x46 #define MIPI_DCS_GET_SCANLINE_WIDTH 0x47 +#define MIPI_DSI_AREA_COLOR_MODE 0x4C #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. @@ -606,7 +659,9 @@ #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_SM_SET_COLOR_MODE 0xA0 +#define MIPI_DCS_PRIV_SM_SET_REG_OFFSET 0xB0 +#define MIPI_DCS_PRIV_SM_SET_ELVSS 0xB1 // OLED backlight tuning. Byte7: PWM transition time in frames. #define MIPI_DCS_PRIV_SET_POWER_CONTROL 0xB1 #define MIPI_DCS_PRIV_SET_EXTC 0xB9 // Enable extended commands. #define MIPI_DCS_PRIV_UNK_BD 0xBD @@ -614,6 +669,8 @@ #define MIPI_DCS_PRIV_UNK_D6 0xD6 #define MIPI_DCS_PRIV_UNK_D8 0xD8 #define MIPI_DCS_PRIV_UNK_D9 0xD9 + // LVL1 LVL2 LVL3 UNK0 UNK1 +#define MIPI_DCS_PRIV_SM_SET_REGS_LOCK 0xE2 // Samsung: Lock (default): 5A5A A5A5 A5A5 A500 A500. Unlock: A5A5 5A5A 5A5A UNK UNK. #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. @@ -648,32 +705,55 @@ #define DCS_GAMMA_CURVE_GC2_1_0 BIT(2) #define DCS_GAMMA_CURVE_GC3_1_0 BIT(3) // Are there more? +#define DCS_CONTROL_DISPLAY_SM_FLASHLIGHT BIT(2) #define DCS_CONTROL_DISPLAY_BACKLIGHT_CTRL BIT(2) #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. +#define DCS_SM_COLOR_MODE_SATURATED 0x00 // Disabled. Similar to vivid but over-saturated. Wide gamut? +#define DCS_SM_COLOR_MODE_WASHED 0x45 +#define DCS_SM_COLOR_MODE_BASIC 0x03 +#define DCS_SM_COLOR_MODE_POR_RESET 0x20 // Reset value on power on. +#define DCS_SM_COLOR_MODE_NATURAL 0x23 // Not actually natural.. +#define DCS_SM_COLOR_MODE_VIVID 0x65 +#define DCS_SM_COLOR_MODE_NIGHT0 0x43 // Based on washed out. +#define DCS_SM_COLOR_MODE_NIGHT1 0x15 // Based on basic. +#define DCS_SM_COLOR_MODE_NIGHT2 0x35 // Based on natural. +#define DCS_SM_COLOR_MODE_NIGHT3 0x75 // Based on vivid. + +#define DCS_SM_COLOR_MODE_ENABLE BIT(0) + +#define PANEL_SM_BL_CANDELA_MAX 2047 /* 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] 98 [0F]: InnoLux P062CCA-??? [UNCONFIRMED MODEL REV] + * [20] 96 [0F]: InnoLux P062CCA-AZ3 (Rev XX) [UNCONFIRMED MODEL+REV] + * [20] 97 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV] + * [20] 98 [0F]: InnoLux P062CCA-??? (Rev XX) [UNCONFIRMED MODEL+REV] + * [30] 93 [0F]: AUO A062TAN00 (59.06A33.000) * [30] 94 [0F]: AUO A062TAN01 (59.06A33.001) * [30] 95 [0F]: AUO A062TAN02 (59.06A33.002) + * [30] 97 [0F]: AUO A062TAN02 (59.06A33.002) [From photo of assumed same panel] + * [30] 98 [0F]: AUO A062TAN0? [UNCONFIRMED MODEL] * [30] XX [0F]: AUO A062TAN03 (59.06A33.003) [UNCONFIRMED ID] * - * 5.5" panels for Hoag skus: - * [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1) + * + * 5.5" panels for Hoag SKU: + * [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1) (6203B001P4000) + * [20] 95 [10]: InnoLux 2J055IA-27A (Rev XX) [UNCONFIRMED MODEL+REV] + * [20] 96 [10]: InnoLux 2J055IA-27A (Rev XX) [UNCONFIRMED MODEL+REV] * [30] 93 [10]: AUO A055TAN01 (59.05A30.001) - * [40] XX [10]: Vendor 40 [UNCONFIRMED ID] + * [30] 94 [10]: AUO A055TAN02 (59.05A30.002) + * [30] 95 [10]: AUO A055TAN03 (59.05A30.003) + * [40] 94 [10]: Sharp LQ055T1SW10 (Rev P) + * * - * 7.0" OLED panels for Aula skus: + * 7.0" OLED panels for Aula SKU: * [50] 9B [20]: Samsung AMS699VC01-0 (Rev 2.5) */ @@ -687,7 +767,7 @@ * 10h: Japan Display Inc. * 20h: InnoLux Corporation * 30h: AU Optronics - * 40h: Unknown0 + * 40h: Sharp * 50h: Samsung * * Boards, Panel Size: @@ -705,7 +785,7 @@ enum PANEL_AUO_A062TAN01 = 0x0F30, PANEL_INL_2J055IA_27A = 0x1020, PANEL_AUO_A055TAN01 = 0x1030, - PANEL_V40_55_UNK = 0x1040, + PANEL_SHP_LQ055T1SW10 = 0x1040, PANEL_SAM_AMS699VC01 = 0x2050 }; @@ -725,8 +805,9 @@ void display_backlight(bool enable); void display_backlight_brightness(u32 brightness, u32 step_delay); u32 display_get_backlight_brightness(); -/*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */ +/*! Init display in full 720x1280 resolution (B8G8R8A8, line stride 720, framebuffer size = 720*1280*4 bytes). */ u32 *display_init_framebuffer_pitch(); +u32 *display_init_framebuffer_pitch_vic(); u32 *display_init_framebuffer_pitch_inv(); u32 *display_init_framebuffer_block(); u32 *display_init_framebuffer_log(); @@ -736,7 +817,9 @@ void display_init_cursor(void *crs_fb, u32 size); void display_set_pos_cursor(u32 x, u32 y); void display_deinit_cursor(); -void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled); -int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled); +int display_dsi_read(u8 cmd, u32 len, void *data); +int display_dsi_vblank_read(u8 cmd, u32 len, void *data); +void display_dsi_write(u8 cmd, u32 len, void *data); +void display_dsi_vblank_write(u8 cmd, u32 len, void *data); #endif diff --git a/bdk/display/di.inl b/bdk/display/di.inl index c1e5d841..61569a73 100644 --- a/bdk/display/di.inl +++ b/bdk/display/di.inl @@ -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,67 +15,29 @@ * along with this program. If not, see . */ -//Display A config. -static const cfg_op_t _display_dc_setup_win_config[94] = { +// Display A config. +static const cfg_op_t _di_dc_setup_win_config[] = { {DC_CMD_STATE_ACCESS, 0}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ}, - {DC_CMD_REG_ACT_CONTROL, 0x54}, // Select H counter for win A/B/C. + {DC_CMD_REG_ACT_CONTROL, WIN_A_ACT_HCNTR_SEL | WIN_B_ACT_HCNTR_SEL | WIN_C_ACT_HCNTR_SEL}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT}, {DC_DISP_DC_MCCIF_FIFOCTRL, 0}, {DC_DISP_DISP_MEM_HIGH_PRIORITY, 0}, {DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER, 0}, {DC_CMD_DISPLAY_POWER_CONTROL, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE}, {DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL}, - {DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | 0x9}, // 9: SYNCPT + {DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE | SYNCPT_VSYNC_INDX(9)}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}, {DC_CMD_STATE_ACCESS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_WIN_DV_CONTROL, 0}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - /* Setup default YUV colorspace conversion coefficients */ - {DC_WIN_CSC_YOF, 0xF0}, - {DC_WIN_CSC_KYRGB, 0x12A}, - {DC_WIN_CSC_KUR, 0}, - {DC_WIN_CSC_KVR, 0x198}, - {DC_WIN_CSC_KUG, 0x39B}, - {DC_WIN_CSC_KVG, 0x32F}, - {DC_WIN_CSC_KUB, 0x204}, - {DC_WIN_CSC_KVB, 0}, - /* End of color coefficients */ - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_WIN_DV_CONTROL, 0}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - /* Setup default YUV colorspace conversion coefficients */ - {DC_WIN_CSC_YOF, 0xF0}, - {DC_WIN_CSC_KYRGB, 0x12A}, - {DC_WIN_CSC_KUR, 0}, - {DC_WIN_CSC_KVR, 0x198}, - {DC_WIN_CSC_KUG, 0x39B}, - {DC_WIN_CSC_KVG, 0x32F}, - {DC_WIN_CSC_KUB, 0x204}, - {DC_WIN_CSC_KVB, 0}, - /* End of color coefficients */ - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, - {DC_WIN_DV_CONTROL, 0}, + + /* Setup Windows A/B/C */ + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, + {DC_WIN_DV_CONTROL, 0}, /* Setup default YUV colorspace conversion coefficients */ {DC_WIN_CSC_YOF, 0xF0}, {DC_WIN_CSC_KYRGB, 0x12A}, @@ -86,32 +48,19 @@ static const cfg_op_t _display_dc_setup_win_config[94] = { {DC_WIN_CSC_KUB, 0x204}, {DC_WIN_CSC_KVB, 0}, /* End of color coefficients */ - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, + {DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888}, {DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C}, - {DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000}, + {DC_COM_PIN_OUTPUT_POLARITY(1), LSC0_OUTPUT_POLARITY_LOW}, {DC_COM_PIN_OUTPUT_POLARITY(3), 0}, {DC_DISP_BLEND_BACKGROUND_COLOR, 0}, {DC_COM_CRC_CONTROL, 0}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, - {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF}, + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT}, + {DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_BYPASS | WIN_BLEND_DEPTH(255)}, {DC_CMD_DISPLAY_COMMAND_OPTION0, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_DISP_DISP_WIN_OPTIONS, 0}, {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP}, @@ -119,18 +68,18 @@ static const cfg_op_t _display_dc_setup_win_config[94] = { {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ} }; -//DSI Init config. -static const cfg_op_t _display_dsi_init_config_part1[8] = { +// DSI Init config. +static const cfg_op_t _di_dsi_init_irq_pkt_config0[] = { {DSI_WR_DATA, 0}, {DSI_INT_ENABLE, 0}, {DSI_INT_STATUS, 0}, - {DSI_INT_MASK, 0}, + {DSI_INT_MASK, 0}, {DSI_INIT_SEQ_DATA_0, 0}, {DSI_INIT_SEQ_DATA_1, 0}, {DSI_INIT_SEQ_DATA_2, 0}, {DSI_INIT_SEQ_DATA_3, 0} }; -static const cfg_op_t _display_dsi_init_config_part2[14] = { +static const cfg_op_t _di_dsi_init_irq_pkt_config1[] = { {DSI_DCS_CMDS, 0}, {DSI_PKT_SEQ_0_LO, 0}, {DSI_PKT_SEQ_1_LO, 0}, @@ -146,7 +95,7 @@ static const cfg_op_t _display_dsi_init_config_part2[14] = { {DSI_PKT_SEQ_5_HI, 0}, {DSI_CONTROL, 0} }; -static const cfg_op_t _display_dsi_init_config_part3_t210b01[7] = { +static const cfg_op_t _di_dsi_init_pads_t210b01[] = { {DSI_PAD_CONTROL_1, 0}, {DSI_PAD_CONTROL_2, 0}, {DSI_PAD_CONTROL_3, 0}, @@ -155,10 +104,10 @@ static const cfg_op_t _display_dsi_init_config_part3_t210b01[7] = { {DSI_PAD_CONTROL_6_B01, 0}, {DSI_PAD_CONTROL_7_B01, 0} }; -static const cfg_op_t _display_dsi_init_config_part4[10] = { +static const cfg_op_t _di_dsi_init_timing_pkt_config2[] = { {DSI_PAD_CONTROL_CD, 0}, - {DSI_SOL_DELAY, 0x18}, - {DSI_MAX_THRESHOLD, 0x1E0}, + {DSI_SOL_DELAY, 24}, + {DSI_MAX_THRESHOLD, 480}, {DSI_TRIGGER, 0}, {DSI_INIT_SEQ_CONTROL, 0}, {DSI_PKT_LEN_0_1, 0}, @@ -167,12 +116,12 @@ static const cfg_op_t _display_dsi_init_config_part4[10] = { {DSI_PKT_LEN_6_7, 0}, {DSI_PAD_CONTROL_1, 0} }; -static const cfg_op_t _display_dsi_init_config_part5[12] = { +static const cfg_op_t _di_dsi_init_timing_pwrctrl_config[] = { {DSI_PHY_TIMING_1, 0x40A0E05}, {DSI_PHY_TIMING_2, 0x30109}, - {DSI_BTA_TIMING, 0x190A14}, + {DSI_BTA_TIMING, 0x190A14}, {DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)}, - {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)}, + {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x765) | DSI_TIMEOUT_TA(0x2000)}, {DSI_TO_TALLY, 0}, {DSI_PAD_CONTROL_0, DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0)}, // Enable {DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE}, @@ -181,25 +130,25 @@ static const cfg_op_t _display_dsi_init_config_part5[12] = { {DSI_POWER_CONTROL, 0}, {DSI_PAD_CONTROL_1, 0} }; -static const cfg_op_t _display_dsi_init_config_part6[14] = { +static const cfg_op_t _di_dsi_init_timing_pkt_config3[] = { {DSI_PHY_TIMING_1, 0x40A0E05}, {DSI_PHY_TIMING_2, 0x30118}, - {DSI_BTA_TIMING, 0x190A14}, + {DSI_BTA_TIMING, 0x190A14}, {DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF)}, - {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)}, + {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)}, {DSI_TO_TALLY, 0}, {DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}, {DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE}, {DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE}, {DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE}, - {DSI_MAX_THRESHOLD, 0x40}, + {DSI_MAX_THRESHOLD, 64}, {DSI_TRIGGER, 0}, {DSI_TX_CRC, 0}, {DSI_INIT_SEQ_CONTROL, 0} }; -//DSI panel config. -static const cfg_op_t _display_init_config_jdi[43] = { +// DSI panel JDI config. +static const cfg_op_t _di_dsi_panel_init_config_jdi[] = { {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}, @@ -245,13 +194,13 @@ static const cfg_op_t _display_init_config_jdi[43] = { {DSI_TRIGGER, DSI_TRIGGER_HOST} }; -//DSI packet config. -static const cfg_op_t _display_dsi_packet_config[19] = { +// DSI packet config. +static const cfg_op_t _di_dsi_init_seq_pkt_final_config[] = { {DSI_PHY_TIMING_1, 0x40A0E05}, {DSI_PHY_TIMING_2, 0x30172}, - {DSI_BTA_TIMING, 0x190A14}, + {DSI_BTA_TIMING, 0x190A14}, {DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xA40)}, - {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)}, + {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x5A2F) | DSI_TIMEOUT_TA(0x2000)}, {DSI_TO_TALLY, 0}, {DSI_PKT_SEQ_0_LO, 0x40000208}, {DSI_PKT_SEQ_2_LO, 0x40000308}, @@ -261,66 +210,66 @@ static const cfg_op_t _display_dsi_packet_config[19] = { {DSI_PKT_SEQ_3_HI, 0x2CC}, {DSI_PKT_SEQ_5_LO, 0x3F3B2B08}, {DSI_PKT_SEQ_5_HI, 0x2CC}, - {DSI_PKT_LEN_0_1, 0xCE0000}, - {DSI_PKT_LEN_2_3, 0x87001A2}, - {DSI_PKT_LEN_4_5, 0x190}, - {DSI_PKT_LEN_6_7, 0x190}, + {DSI_PKT_LEN_0_1, PKT1_LEN(206) | PKT0_LEN(0)}, + {DSI_PKT_LEN_2_3, PKT1_LEN(2160) | PKT0_LEN(418)}, + {DSI_PKT_LEN_4_5, PKT1_LEN(0) | PKT0_LEN(400)}, + {DSI_PKT_LEN_6_7, PKT1_LEN(0) | PKT0_LEN(400)}, {DSI_HOST_CONTROL, 0} }; -//DSI mode config. -static const cfg_op_t _display_dsi_mode_config[10] = { +// DSI mode config. +static const cfg_op_t _di_dsi_mode_config[] = { {DSI_TRIGGER, 0}, {DSI_CONTROL, 0}, {DSI_SOL_DELAY, 6}, - {DSI_MAX_THRESHOLD, 0x1E0}, + {DSI_MAX_THRESHOLD, 480}, {DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE}, {DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE}, - {DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL| DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}, + {DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_FIFO_SEL | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}, {DSI_CONTROL, DSI_CONTROL_HS_CLK_CTRL | DSI_CONTROL_FORMAT(3) | DSI_CONTROL_LANES(3) | DSI_CONTROL_VIDEO_ENABLE}, - {DSI_HOST_CONTROL, DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}, - {DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC} + {DSI_HOST_CONTROL, DSI_HOST_CONTROL_TX_TRIG_SOL | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}, + {DSI_HOST_CONTROL, DSI_HOST_CONTROL_HS | DSI_HOST_CONTROL_TX_TRIG_SOL | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC} }; -//MIPI CAL config. -static const cfg_op_t _display_mipi_pad_cal_config[4] = { +// MIPI CAL config. +static const cfg_op_t _di_mipi_pad_cal_config[] = { {MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0}, {MIPI_CAL_CIL_MIPI_CAL_STATUS, 0xF3F10000}, {MIPI_CAL_MIPI_BIAS_PAD_CFG0, 0}, {MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0} }; -//DSI config. -static const cfg_op_t _display_dsi_pad_cal_config_t210[4] = { +// DSI pad config. +static const cfg_op_t _di_dsi_pad_cal_config_t210[] = { {DSI_PAD_CONTROL_1, 0}, {DSI_PAD_CONTROL_2, 0}, {DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)}, {DSI_PAD_CONTROL_4, 0} }; -static const cfg_op_t _display_dsi_pad_cal_config_t210b01[7] = { - {DSI_PAD_CONTROL_1, 0}, - {DSI_PAD_CONTROL_2, 0}, - {DSI_PAD_CONTROL_3, 0}, - {DSI_PAD_CONTROL_4, 0x77777}, +static const cfg_op_t _di_dsi_pad_cal_config_t210b01[] = { + {DSI_PAD_CONTROL_1, 0}, + {DSI_PAD_CONTROL_2, 0}, + {DSI_PAD_CONTROL_3, 0}, + {DSI_PAD_CONTROL_4, 0x77777}, {DSI_PAD_CONTROL_5_B01, 0x77777}, - {DSI_PAD_CONTROL_6_B01, 0x1111}, + {DSI_PAD_CONTROL_6_B01, DSI_PAD_PREEMP_PD_CLK(0x1) | DSI_PAD_PREEMP_PU_CLK(0x1) | DSI_PAD_PREEMP_PD(0x01) | DSI_PAD_PREEMP_PU(0x1)}, {DSI_PAD_CONTROL_7_B01, 0} }; -//MIPI CAL config. -static const cfg_op_t _display_mipi_dsi_cal_offsets_config_t210[4] = { +// MIPI CAL config. +static const cfg_op_t _di_mipi_dsi_cal_offsets_config_t210[] = { {MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200200}, {MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200200}, {MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x200002}, {MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x200002} }; -static const cfg_op_t _display_mipi_dsi_cal_offsets_config_t210b01[4] = { +static const cfg_op_t _di_mipi_dsi_cal_offsets_config_t210b01[] = { {MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200006}, {MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200006}, {MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x260000}, {MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x260000} }; -static const cfg_op_t _display_mipi_apply_dsi_cal_config[12] = { +static const cfg_op_t _di_mipi_start_dsi_cal_config[] = { {MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0}, {MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0}, {MIPI_CAL_CILC_MIPI_CAL_CONFIG, 0}, @@ -332,53 +281,17 @@ static const cfg_op_t _display_mipi_apply_dsi_cal_config[12] = { {MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0}, {MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2, 0}, {MIPI_CAL_DSID_MIPI_CAL_CONFIG_2, 0}, - {MIPI_CAL_MIPI_CAL_CTRL, 0x2A000001} + {MIPI_CAL_MIPI_CAL_CTRL, 0x2A000001} // Set Prescale and filter and start calibration. }; -//Display A config. -static const cfg_op_t _display_video_disp_controller_enable_config[113] = { +// Display A enable config. +static const cfg_op_t _di_dc_video_enable_config[] = { {DC_CMD_STATE_ACCESS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_WIN_DV_CONTROL, 0}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - /* Setup default YUV colorspace conversion coefficients */ - {DC_WIN_CSC_YOF, 0xF0}, - {DC_WIN_CSC_KYRGB, 0x12A}, - {DC_WIN_CSC_KUR, 0}, - {DC_WIN_CSC_KVR, 0x198}, - {DC_WIN_CSC_KUG, 0x39B}, - {DC_WIN_CSC_KVG, 0x32F}, - {DC_WIN_CSC_KUB, 0x204}, - {DC_WIN_CSC_KVB, 0}, - /* End of color coefficients */ - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_WIN_DV_CONTROL, 0}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - /* Setup default YUV colorspace conversion coefficients */ - {DC_WIN_CSC_YOF, 0xF0}, - {DC_WIN_CSC_KYRGB, 0x12A}, - {DC_WIN_CSC_KUR, 0}, - {DC_WIN_CSC_KVR, 0x198}, - {DC_WIN_CSC_KUG, 0x39B}, - {DC_WIN_CSC_KVG, 0x32F}, - {DC_WIN_CSC_KUB, 0x204}, - {DC_WIN_CSC_KVB, 0}, - /* End of color coefficients */ - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, - {DC_WIN_DV_CONTROL, 0}, + + /* Setup Windows A/B/C */ + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, + {DC_WIN_DV_CONTROL, 0}, /* Setup default YUV colorspace conversion coefficients */ {DC_WIN_CSC_YOF, 0xF0}, {DC_WIN_CSC_KYRGB, 0x12A}, @@ -389,32 +302,19 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = { {DC_WIN_CSC_KUB, 0x204}, {DC_WIN_CSC_KVB, 0}, /* End of color coefficients */ - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, + {DC_DISP_DISP_COLOR_CONTROL, BASE_COLOR_SIZE_888}, {DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C}, - {DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000}, + {DC_COM_PIN_OUTPUT_POLARITY(1), LSC0_OUTPUT_POLARITY_LOW}, {DC_COM_PIN_OUTPUT_POLARITY(3), 0}, {DC_DISP_BLEND_BACKGROUND_COLOR, 0}, {DC_COM_CRC_CONTROL, 0}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, - {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF}, + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT}, + {DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_BYPASS | WIN_BLEND_DEPTH(255)}, {DC_CMD_DISPLAY_COMMAND_OPTION0, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_DISP_DISP_WIN_OPTIONS, 0}, {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP}, @@ -422,34 +322,13 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = { {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}, {DC_CMD_STATE_ACCESS, 0}, - /* Set Display timings - * - * DC_DISP_REF_TO_SYNC: - * V_REF_TO_SYNC - 1 - * H_REF_TO_SYNC - 0 - * - * DC_DISP_SYNC_WIDTH: - * V_SYNC_WIDTH - 1 - * H_SYNC_WIDTH - 72 - * - * DC_DISP_BACK_PORCH: - * V_BACK_PORCH - 9 - * H_BACK_PORCH - 72 - * - * DC_DISP_ACTIVE: - * V_DISP_ACTIVE - 1280 - * H_DISP_ACTIVE - 720 - * - * DC_DISP_FRONT_PORCH: - * V_FRONT_PORCH - 10 - * H_FRONT_PORCH - 136 - */ - {DC_DISP_DISP_TIMING_OPTIONS, 0}, - {DC_DISP_REF_TO_SYNC, 0x10000}, - {DC_DISP_SYNC_WIDTH, 0x10048}, - {DC_DISP_BACK_PORCH, 0x90048}, - {DC_DISP_ACTIVE, 0x50002D0}, - {DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should happen before DC_DISP_ACTIVE cmd. + /* Set panel timings */ + {DC_DISP_DISP_TIMING_OPTIONS, VSYNC_H_POSITION(0)}, + {DC_DISP_REF_TO_SYNC, V_REF_TO_SYNC(1) | H_REF_TO_SYNC(0)}, + {DC_DISP_SYNC_WIDTH, V_SYNC_WIDTH(1) | H_SYNC_WIDTH(72)}, + {DC_DISP_BACK_PORCH, V_BACK_PORCH(9) | H_BACK_PORCH(72)}, + {DC_DISP_FRONT_PORCH, V_FRONT_PORCH(10) | H_FRONT_PORCH(136)}, + {DC_DISP_ACTIVE, V_DISP_ACTIVE(1280) | H_DISP_ACTIVE(720)}, /* End of Display timings */ {DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE}, @@ -458,23 +337,18 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = { {DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C}, {DC_DISP_DISP_CLOCK_CONTROL, 0}, {DC_CMD_DISPLAY_COMMAND_OPTION0, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_DISP_DISP_WIN_OPTIONS, 0}, {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ}, {DC_CMD_STATE_ACCESS, READ_MUX | WRITE_MUX}, - {DC_DISP_FRONT_PORCH, 0xA0088}, + {DC_DISP_FRONT_PORCH, V_FRONT_PORCH(10) | H_FRONT_PORCH(136)}, {DC_CMD_STATE_ACCESS, 0}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ}, - {DC_CMD_GENERAL_INCR_SYNCPT, 0x301}, - {DC_CMD_GENERAL_INCR_SYNCPT, 0x301}, + {DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ}, {DC_CMD_STATE_ACCESS, 0}, @@ -483,9 +357,9 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = { {DC_CMD_DISPLAY_COMMAND_OPTION0, 0} }; -////Display A config. -static const cfg_op_t _display_video_disp_controller_disable_config[17] = { - {DC_DISP_FRONT_PORCH, 0xA0088}, +// Display A disable config. +static const cfg_op_t _di_dc_video_disable_config[] = { + {DC_DISP_FRONT_PORCH, V_FRONT_PORCH(10) | H_FRONT_PORCH(136)}, {DC_CMD_INT_MASK, 0}, {DC_CMD_STATE_ACCESS, 0}, {DC_CMD_INT_ENABLE, 0}, @@ -493,39 +367,37 @@ static const cfg_op_t _display_video_disp_controller_disable_config[17] = { {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ}, + {DC_CMD_GENERAL_INCR_SYNCPT, SYNCPT_GENERAL_COND(COND_REG_WR_SAFE) | SYNCPT_GENERAL_INDX(1)}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ}, - {DC_CMD_GENERAL_INCR_SYNCPT, 0x301}, - {DC_CMD_GENERAL_INCR_SYNCPT, 0x301}, - {DC_CMD_STATE_CONTROL, GENERAL_UPDATE}, - {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ}, + // LCD panels should sleep for 40ms here. {DC_CMD_DISPLAY_POWER_CONTROL, 0}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ}, }; -//DSI config. -static const cfg_op_t _display_dsi_timing_deinit_config[16] = { +// DSI deinit config. +static const cfg_op_t _di_dsi_timing_deinit_config[] = { {DSI_POWER_CONTROL, 0}, {DSI_PAD_CONTROL_1, 0}, - {DSI_PHY_TIMING_0, 0x6070601}, + {DSI_PHY_TIMING_0, 0x6070601}, //mariko changes {DSI_PHY_TIMING_1, 0x40A0E05}, {DSI_PHY_TIMING_2, 0x30118}, - {DSI_BTA_TIMING, 0x190A14}, + {DSI_BTA_TIMING, 0x190A14}, {DSI_TIMEOUT_0, DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(0xFFFF) }, - {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)}, + {DSI_TIMEOUT_1, DSI_TIMEOUT_PR(0x1343) | DSI_TIMEOUT_TA(0x2000)}, {DSI_TO_TALLY, 0}, {DSI_HOST_CONTROL, DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC}, {DSI_CONTROL, DSI_CONTROL_LANES(3) | DSI_CONTROL_HOST_ENABLE}, {DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE}, - {DSI_MAX_THRESHOLD, 0x40}, + {DSI_MAX_THRESHOLD, 64}, {DSI_TRIGGER, 0}, {DSI_TX_CRC, 0}, {DSI_INIT_SEQ_CONTROL, 0} }; -//DSI config (if ver == 0x10). -static const cfg_op_t _display_deinit_config_jdi[22] = { +// DSI panel JDI deinit config. +static const cfg_op_t _di_dsi_panel_deinit_config_jdi[] = { {DSI_WR_DATA, 0x439}, // 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}, @@ -550,7 +422,8 @@ static const cfg_op_t _display_deinit_config_jdi[22] = { {DSI_TRIGGER, DSI_TRIGGER_HOST} }; -static const cfg_op_t _display_deinit_config_auo[37] = { +// DSI panel AUO deinit config. +static const cfg_op_t _di_dsi_panel_deinit_config_auo[] = { {DSI_WR_DATA, 0x439}, // 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}, @@ -591,156 +464,143 @@ static const cfg_op_t _display_deinit_config_auo[37] = { {DSI_TRIGGER, DSI_TRIGGER_HOST} }; -static const cfg_op_t _display_init_config_invert[3] = { +static const cfg_op_t _di_init_config_invert[] = { {DSI_WR_DATA, 0x239}, {DSI_WR_DATA, 0x02C1}, // INV_EN. {DSI_TRIGGER, DSI_TRIGGER_HOST}, }; -//Display A config. -static const cfg_op_t cfg_display_one_color[8] = { - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, +// Display A Window A one color config. +static const cfg_op_t _di_win_one_color[] = { + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT | WINDOW_B_SELECT | WINDOW_C_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} // Continuous display. }; -//Display A config linear pitch. -static const cfg_op_t cfg_display_framebuffer_pitch[32] = { - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, +// Display A Window A linear pitch config. +static const cfg_op_t _di_win_framebuffer_pitch[] = { + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT | WINDOW_B_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, {DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8. - {DC_WIN_WIN_OPTIONS, 0}, - {DC_WIN_WIN_OPTIONS, 0}, {DC_WIN_POSITION, 0}, //(0,0) {DC_WIN_H_INITIAL_DDA, 0}, {DC_WIN_V_INITIAL_DDA, 0}, - {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)}, - {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x. - {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, - {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements. + {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)}, + {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x. + {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, + {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements. {DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST}, {DC_WINBUF_SURFACE_KIND, PITCH}, {DC_WINBUF_START_ADDR, IPL_FB_ADDRESS}, // Framebuffer address. {DC_WINBUF_ADDR_H_OFFSET, 0}, {DC_WINBUF_ADDR_V_OFFSET, 0}, + {DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD. + {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display. + {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, + {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} +}; + +// Display A Window A linear pitch + Win D support config. +static const cfg_op_t _di_win_framebuffer_pitch_vic[] = { + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT | WINDOW_C_SELECT | WINDOW_B_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, - {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, + {DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8. + {DC_WIN_POSITION, 0}, //(0,0) + {DC_WIN_H_INITIAL_DDA, 0}, + {DC_WIN_V_INITIAL_DDA, 0}, + {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)}, + {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x. + {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, + {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements. + {DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST}, + {DC_WINBUF_SURFACE_KIND, PITCH}, + {DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address. + {DC_WINBUF_ADDR_H_OFFSET, 0}, + {DC_WINBUF_ADDR_V_OFFSET, 0}, {DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD. {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display. {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} }; -//Display A config linear pitch inverse + Win D support. -static const cfg_op_t cfg_display_framebuffer_pitch_inv[34] = { - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, +// Display A Window A linear pitch inverse + Win D support config. +static const cfg_op_t _di_win_framebuffer_pitch_inv[] = { + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT | WINDOW_C_SELECT | WINDOW_B_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, {DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8. - {DC_WIN_WIN_OPTIONS, 0}, - {DC_WIN_WIN_OPTIONS, 0}, {DC_WIN_POSITION, 0}, //(0,0) {DC_WIN_H_INITIAL_DDA, 0}, {DC_WIN_V_INITIAL_DDA, 0}, - {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)}, - {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x. - {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, - {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements. + {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)}, + {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x. + {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, + {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements. {DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST}, {DC_WINBUF_SURFACE_KIND, PITCH}, {DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address. {DC_WINBUF_ADDR_H_OFFSET, 0}, // Linear: 0x383FFC, Block: 0x3813FC. {DC_WINBUF_ADDR_V_OFFSET, 1279}, // Linear: 1279, Block: 0. - {DC_WIN_WIN_OPTIONS, 0}, - {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, {DC_WIN_WIN_OPTIONS, WIN_ENABLE | V_DIRECTION}, // Enable window AD. {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display. {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} }; -//Display A config block linear. -static const cfg_op_t cfg_display_framebuffer_block[34] = { - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, +// Display A Window A block linear config. +static const cfg_op_t _di_win_framebuffer_block[] = { + {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT | WINDOW_C_SELECT | WINDOW_B_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, {DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8. - {DC_WIN_WIN_OPTIONS, 0}, - {DC_WIN_WIN_OPTIONS, 0}, {DC_WIN_POSITION, 0}, //(0,0) {DC_WIN_H_INITIAL_DDA, 0}, {DC_WIN_V_INITIAL_DDA, 0}, - {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)}, - {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x. - {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, - {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements. + {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)}, + {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x. + {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, + {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements. {DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST}, {DC_WINBUF_SURFACE_KIND, BLOCK_HEIGHT(4) | BLOCK}, {DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address. - {DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, // Linear: 0x383FFC, Block: 0x3813FC. + {DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, // Linear: 0x383FFC, Block: 0x3813FC. Block in HOS: 0x13FF. {DC_WINBUF_ADDR_V_OFFSET, 0}, // Linear: 1279, Block: 0. - {DC_WIN_WIN_OPTIONS, 0}, - {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, - {DC_WIN_WIN_OPTIONS, 0}, - {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, {DC_WIN_WIN_OPTIONS, WIN_ENABLE | SCAN_COLUMN | H_DIRECTION}, // Enable window AD. | SCAN_COLUMN | H_DIRECTION. {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display. {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} }; -//Display D config. -static const cfg_op_t cfg_display_framebuffer_log[20] = { +// Display A Window D config. +static const cfg_op_t _di_win_framebuffer_log[] = { {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, {DC_WIN_POSITION, 0}, //(0,0) {DC_WIN_H_INITIAL_DDA, 0}, {DC_WIN_V_INITIAL_DDA, 0}, - {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(656 * 4)}, - {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x. - {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(656)}, - {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(656 * 2) | LINE_STRIDE(656 * 4)}, //656*2x656*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements. + {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(656 * 4)}, + {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x. + {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(656)}, + {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(656 * 2) | LINE_STRIDE(656 * 4)}, //656*2x656*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements. {DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST}, {DC_WINBUF_SURFACE_KIND, PITCH}, {DC_WINBUF_START_ADDR, LOG_FB_ADDRESS}, // Framebuffer address. {DC_WINBUF_ADDR_H_OFFSET, 0}, {DC_WINBUF_ADDR_V_OFFSET, 0}, - {DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_ENABLE | WIN_K1(200)}, + {DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_ENABLE | WIN_K1(200) | WIN_BLEND_DEPTH(0)}, {DC_WINBUF_BLEND_MATCH_SELECT, WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_K1 | WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_NEG_K1}, - {DC_WIN_WIN_OPTIONS, 0}, // Enable window DD. {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_D_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_D_ACT_REQ} }; diff --git a/bdk/display/vic.c b/bdk/display/vic.c new file mode 100644 index 00000000..c9a0c597 --- /dev/null +++ b/bdk/display/vic.c @@ -0,0 +1,563 @@ +/* + * VIC driver for Tegra X1 + * + * Copyright (c) 2018-2023 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 "vic.h" +#include +#include +#include +#include +#include +#include + +/* VIC Private registers */ +#define PVIC_FALCON_PA_OFFSET 0x1000 +#define PVIC_FALCON_ADDR 0x10AC +#define PVIC_FALCON_IDLESTATE 0x104C + +/* VIC Control and Status registers. */ +/* Fetch Control registers. */ +#define VIC_FC_COMPOSE 0x10000 +#define COMPOSE_START BIT(0) + +#define VIC_FC_CFG_STRUCT_SLOT_INDEX 0x10B00 + +#define VIC_FC_CFG_STRUCT_SLOT_CFG0 0x10B04 +#define SLOT_ENABLE BIT(0) +#define FIELD_CURRENT_ENABLE BIT(8) + +#define VIC_FC_CFG_STRUCT_SLOT_CFG2 0x10B0C +#define CACHE_WIDTH(n) ((n) << 16) +#define CACHE_WIDTH_16BX16 0 // Block Linear. +#define CACHE_WIDTH_32BX8 1 // Block Linear. Recommended for Block Linear. +#define CACHE_WIDTH_64BX4 2 // Block Linear, Pitch. Recommended for Pitch. +#define CACHE_WIDTH_128BX2 3 // Block Linear, Pitch. +#define OUTPUT_FLIP_X BIT(20) +#define OUTPUT_FLIP_Y BIT(21) +#define OUTPUT_TRANSPOSE BIT(22) + +#define VIC_FC_CFG_STRUCT_SLOT_SFC_SIZE 0x10B10 +#define VIC_FC_CFG_STRUCT_SLOT_LUMA_SIZE 0x10B14 +#define VIC_FC_CFG_STRUCT_SLOT_CHROMA_SIZE 0x10B18 +#define VIC_FC_CFG_STRUCT_SLOT_SRC_RECT_LR 0x10B1C +#define VIC_FC_CFG_STRUCT_SLOT_SRC_RECT_TB 0x10B20 +#define VIC_FC_CFG_STRUCT_SLOT_DST_RECT_LR 0x10B30 +#define VIC_FC_CFG_STRUCT_SLOT_DST_RECT_TB 0x10B34 +#define VIC_FC_CFG_STRUCT_TGT_RECT_LR 0x10B38 +#define VIC_FC_CFG_STRUCT_TGT_RECT_TB 0x10B3C +#define VIC_FC_SLOT_MAP 0x10C00 + +#define VIC_FC_FCE_CTRL 0x11000 +#define START_TRIGGER BIT(0) +#define HALT_TRIGGER BIT(1) +#define CLEAR_ERROR BIT(8) + +#define VIC_FC_FCE_UCODE_ADDR 0x11200 +#define VIC_FC_FCE_UCODE_INST 0x11300 + +/* Surface List registers. */ +#define VIC_SL_CFG_STRUCT_SLOT_INDEX 0x12100 +#define VIC_SL_CFG_STRUCT_SLOT_DST_RECT_LR 0x12200 +#define VIC_SL_CFG_STRUCT_SLOT_DST_RECT_TB 0x12300 +#define VIC_SL_CFG_STRUCT_TGT_RECT_LR 0x12400 +#define VIC_SL_CFG_STRUCT_TGT_RECT_TB 0x12500 +#define VIC_SL_CFG_STRUCT_SLOT_CFG0 0x12600 + +/* Surface Cache registers. */ +#define VIC_SC_PRAMBASE 0x14000 +#define VIC_SC_PRAMSIZE 0x14100 +#define VIC_SC_SFC0_BASE_LUMA(n) (0x14300 + (n) * 0x100) + +/* Blending Output registers. */ +#define VIC_BL_TARGET_BASADR 0x22000 +#define VIC_BL_CONFIG 0x22800 +#define SUBPARTITION_MODE BIT(0) +#define PROCESS_CFG_STRUCT_TRIGGER BIT(2) +#define SLOTMASK(n) ((n) << 8) + +#define VIC_BL_CFG_STRUCT_CFG0 0x22C00 +#define VIC_BL_CFG_STRUCT_SFC_SIZE 0x22C04 +#define VIC_BL_CFG_STRUCT_LUMA_SIZE 0x22C08 +#define VIC_BL_CFG_STRUCT_CHROMA_SIZE 0x22C0C +#define VIC_BL_CFG_STRUCT_TGT_RECT_LR 0x22C10 +#define VIC_BL_CFG_STRUCT_TGT_RECT_TB 0x22C14 + +// VIC_FC_CFG_STRUCT_SLOT_CFG2 & VIC_BL_CFG_STRUCT_CFG0. +#define BLK_KIND(n) ((n) << 8) +#define BLK_KIND_PITCH 0 +#define BLK_KIND_GENERIC_16BX2 1 +#define BLK_HEIGHT(n) ((n) << 12) +#define BLK_HEIGHT_ONE_GOB 0 +#define BLK_HEIGHT_SIXTEEN_GOBS 4 + +// Generic size macros. +#define SIZE_WIDTH(n) (((n) - 1) << 0) +#define SIZE_HEIGHT(n) (((n) - 1) << 16) +#define RECT_LEFT(n) ((n) << 0) +#define RECT_RIGHT(n) (((n) - 1) << 16) +#define RECT_TOP(n) ((n) << 0) +#define RECT_BOTTOM(n) (((n) - 1) << 16) + +#define FORMAT_PROGRESSIVE 0 +#define SOFT_CLAMP_MIN 0 +#define SOFT_CLAMP_MAX 0x3FFu +#define ALPHA_1_0 0x3FFu + +typedef struct _OutputConfig { + u64 AlphaFillMode:3; + u64 AlphaFillSlot:3; + u64 BackgroundAlpha:10; + u64 BackgroundR:10; + u64 BackgroundG:10; + u64 BackgroundB:10; + u64 RegammaMode:2; + u64 OutputFlipX:1; + u64 OutputFlipY:1; + u64 OutputTranspose:1; + u64 rsvd1:1; + u64 rsvd2:12; + u64 TargetRectLeft:14; + u64 rsvd3:2; + u64 TargetRectRight:14; + u64 rsvd4:2; + u64 TargetRectTop:14; + u64 rsvd5:2; + u64 TargetRectBottom:14; + u64 rsvd6:2; +} OutputConfig; + +typedef struct _OutputSurfaceConfig { + u64 OutPixelFormat:7; + u64 OutChromaLocHoriz:2; + u64 OutChromaLocVert:2; + u64 OutBlkKind:4; + u64 OutBlkHeight:4; + u64 rsvd0:3; + u64 rsvd1:10; + u64 OutSurfaceWidth:14; + u64 OutSurfaceHeight:14; + u64 rsvd2:4; + u64 OutLumaWidth:14; + u64 OutLumaHeight:14; + u64 rsvd3:4; + u64 OutChromaWidth:14; + u64 OutChromaHeight:14; + u64 rsvd4:4; +} OutputSurfaceConfig; + +typedef struct _SlotConfig { + u64 SlotEnable:1; + u64 DeNoise:1; + u64 AdvancedDenoise:1; + u64 CadenceDetect:1; + u64 MotionMap:1; + u64 MMapCombine:1; + u64 IsEven:1; + u64 ChromaEven:1; + u64 CurrentFieldEnable:1; + u64 PrevFieldEnable:1; + u64 NextFieldEnable:1; + u64 NextNrFieldEnable:1; + u64 CurMotionFieldEnable:1; + u64 PrevMotionFieldEnable:1; + u64 PpMotionFieldEnable:1; + u64 CombMotionFieldEnable:1; + u64 FrameFormat:4; + u64 FilterLengthY:2; + u64 FilterLengthX:2; + u64 Panoramic:12; + u64 rsvd1:22; + u64 DetailFltClamp:6; + u64 FilterNoise:10; + u64 FilterDetail:10; + u64 ChromaNoise:10; + u64 ChromaDetail:10; + u64 DeinterlaceMode:4; + u64 MotionAccumWeight:3; + u64 NoiseIir:11; + u64 LightLevel:4; + u64 rsvd4:2; + u64 SoftClampLow:10; + u64 SoftClampHigh:10; + u64 rsvd5:3; + u64 rsvd6:9; + u64 PlanarAlpha:10; + u64 ConstantAlpha:1; + u64 StereoInterleave:3; + u64 ClipEnabled:1; + u64 ClearRectMask:8; + u64 DegammaMode:2; + u64 rsvd7:1; + u64 DecompressEnable:1; + u64 rsvd9:5; + u64 DecompressCtbCount:8; + u64 DecompressZbcColor:32; + u64 rsvd12:24; + u64 SourceRectLeft:30; + u64 rsvd14:2; + u64 SourceRectRight:30; + u64 rsvd15:2; + u64 SourceRectTop:30; + u64 rsvd16:2; + u64 SourceRectBottom:30; + u64 rsvd17:2; + u64 DestRectLeft:14; + u64 rsvd18:2; + u64 DestRectRight:14; + u64 rsvd19:2; + u64 DestRectTop:14; + u64 rsvd20:2; + u64 DestRectBottom:14; + u64 rsvd21:2; + u64 rsvd22:32; + u64 rsvd23:32; +} SlotConfig; + +typedef struct _SlotSurfaceConfig { + u64 SlotPixelFormat:7; + u64 SlotChromaLocHoriz:2; + u64 SlotChromaLocVert:2; + u64 SlotBlkKind:4; + u64 SlotBlkHeight:4; + u64 SlotCacheWidth:3; + u64 rsvd0:10; + u64 SlotSurfaceWidth:14; + u64 SlotSurfaceHeight:14; + u64 rsvd1:4; + u64 SlotLumaWidth:14; + u64 SlotLumaHeight:14; + u64 rsvd2:4; + u64 SlotChromaWidth:14; + u64 SlotChromaHeight:14; + u64 rsvd3:4; +} SlotSurfaceConfig; + +typedef struct _SlotStruct { + SlotConfig slot_cfg; + SlotSurfaceConfig slot_sfc_cfg; + + // No need to configure. Reset to zeros. + u8 lumaKeyStruct[0x10]; + u8 colorMatrixStruct[0x20]; + u8 gamutMatrixStruct[0x20]; + u8 blendingSlotStruct[0x10]; +} SlotStruct; + +typedef struct _vic_config_t { + // No need to configure. Reset to zeros. + u8 pipeConfig[0x10]; + + OutputConfig out_cfg; + OutputSurfaceConfig out_sfc_cfg; + + // No need to configure. Reset to zeros. + u8 out_color_matrix[0x20]; + u8 clear_rect[0x10 * 4]; + + SlotStruct slots[8]; +} vic_config_t; + +// VIC Fetch Control Engine microcode. Dumped from L4T r33. +u8 vic_fce_ucode[] = { + 0x66, 0x00, 0x00, 0x00, 0x60, 0x07, 0x00, 0x00, 0x42, 0x40, 0x10, 0x00, 0x4E, 0x01, 0x40, 0x00, + 0x6A, 0x07, 0x00, 0x00, 0x6E, 0x23, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x4E, 0x01, 0x04, 0x00, + 0x6A, 0x0B, 0x00, 0x00, 0x6E, 0x1F, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x4E, 0x01, 0x10, 0x00, + 0x6A, 0x0F, 0x00, 0x00, 0x6E, 0x1F, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x48, 0x80, 0x02, 0x00, + 0x0E, 0x11, 0x00, 0x00, 0x6A, 0x14, 0x00, 0x00, 0x6E, 0x08, 0x06, 0x00, 0x6C, 0x00, 0x00, 0x00, + 0x4E, 0x01, 0x08, 0x00, 0x6A, 0x18, 0x00, 0x00, 0x6E, 0x26, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, + 0x4E, 0x01, 0x20, 0x00, 0x6A, 0x1C, 0x00, 0x00, 0x6E, 0x26, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, + 0x4E, 0x01, 0x02, 0x00, 0x6A, 0x20, 0x00, 0x00, 0x6E, 0x24, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, + 0x56, 0x00, 0x10, 0x00, 0x56, 0x40, 0x10, 0x00, 0x22, 0x41, 0x01, 0x00, 0x6C, 0x00, 0x00, 0x00, + 0x62, 0x80, 0x01, 0x00, 0x60, 0x47, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00, 0x01, 0x4A, 0x00, 0x00, + 0x55, 0xC0, 0x20, 0x00, 0x00, 0x59, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00, + 0x01, 0x93, 0x00, 0x00, 0x40, 0x82, 0x02, 0x00, 0x4E, 0x02, 0x00, 0x00, 0x6B, 0x34, 0x00, 0x00, + 0x43, 0xC1, 0x10, 0x00, 0x42, 0x02, 0x03, 0x00, 0x00, 0x23, 0x01, 0x00, 0x24, 0xD4, 0x00, 0x00, + 0x56, 0x40, 0x3D, 0x00, 0x04, 0xEB, 0x00, 0x00, 0x60, 0x07, 0x01, 0x00, 0x60, 0x47, 0x00, 0x00, + 0x6A, 0x3E, 0x00, 0x00, 0x55, 0xC0, 0x30, 0x00, 0x48, 0x00, 0x01, 0x00, 0x48, 0x40, 0x01, 0x00, + 0x48, 0x80, 0x01, 0x00, 0x6B, 0x28, 0x02, 0x00, 0x56, 0x40, 0x09, 0x00, 0x04, 0x4D, 0x01, 0x00, + 0x06, 0x4D, 0x00, 0x00, 0x42, 0xC0, 0x03, 0x00, 0x56, 0x80, 0x09, 0x00, 0x04, 0xFE, 0x01, 0x00, + 0x00, 0xF9, 0x01, 0x00, 0x4E, 0x02, 0x00, 0x00, 0x6B, 0x32, 0x02, 0x00, 0x55, 0x40, 0x2F, 0x00, + 0x56, 0x80, 0x0D, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x6A, 0x0D, 0x02, 0x00, 0x55, 0x40, 0x31, 0x00, + 0x56, 0x80, 0x0B, 0x00, 0x0C, 0x2B, 0x00, 0x00, 0x6A, 0x13, 0x02, 0x00, 0x43, 0x45, 0x03, 0x00, + 0x42, 0x86, 0x03, 0x00, 0x4D, 0x06, 0x02, 0x00, 0x6A, 0x0D, 0x02, 0x00, 0x42, 0x86, 0x03, 0x00, + 0x22, 0x7E, 0x01, 0x00, 0x4E, 0x04, 0x00, 0x00, 0x6B, 0x32, 0x02, 0x00, 0x55, 0x40, 0x17, 0x00, + 0x0D, 0x2C, 0x00, 0x00, 0x56, 0xC0, 0x09, 0x00, 0x6A, 0x1E, 0x02, 0x00, 0x48, 0xC0, 0x01, 0x00, + 0x43, 0x04, 0x03, 0x00, 0x6C, 0x20, 0x02, 0x00, 0x55, 0x40, 0x19, 0x00, 0x01, 0x2C, 0x01, 0x00, + 0x65, 0x23, 0x01, 0x00, 0x42, 0x42, 0x03, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x24, 0x14, 0x01, 0x00, + 0x00, 0x2C, 0x01, 0x00, 0x24, 0x14, 0x01, 0x00, 0x00, 0x3C, 0x01, 0x00, 0x42, 0x04, 0x09, 0x00, + 0x42, 0xC3, 0x02, 0x00, 0x65, 0x54, 0x01, 0x00, 0x65, 0x55, 0x01, 0x00, 0x42, 0x45, 0x0D, 0x00, + 0x62, 0x03, 0x00, 0x00, 0x62, 0x44, 0x00, 0x00, 0x62, 0x85, 0x00, 0x00, 0x62, 0xC2, 0x00, 0x00, + 0x22, 0x48, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x48, 0x00, 0x01, 0x00, 0x6C, 0x28, 0x02, 0x00, + 0x62, 0x80, 0x01, 0x00, 0x60, 0x07, 0x00, 0x00, 0x60, 0x47, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00, + 0x01, 0x01, 0x00, 0x00, 0x43, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x01, 0xCA, 0x01, 0x00, + 0x60, 0x03, 0x01, 0x00, 0x01, 0xA0, 0x01, 0x00, 0x60, 0x40, 0x00, 0x00, 0x65, 0x01, 0x00, 0x00, + 0x55, 0xC0, 0x2E, 0x00, 0x01, 0x18, 0x00, 0x00, 0x43, 0x00, 0x04, 0x00, 0x43, 0x41, 0x06, 0x00, + 0x6F, 0x00, 0x00, 0x00, 0x61, 0xC1, 0x00, 0x00, 0x61, 0x42, 0x01, 0x00, 0x65, 0xB5, 0x00, 0x00, + 0x65, 0x73, 0x01, 0x00, 0x65, 0x35, 0x01, 0x00, 0x65, 0x34, 0x01, 0x00, 0x42, 0x04, 0x0D, 0x00, + 0x01, 0x14, 0x01, 0x00, 0x42, 0x04, 0x03, 0x00, 0x00, 0x20, 0x00, 0x00, 0x43, 0x03, 0x05, 0x00, + 0x43, 0x85, 0x02, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x48, 0x46, 0x01, 0x00, 0x65, 0xEB, 0x00, 0x00, + 0x00, 0x9A, 0x00, 0x00, 0x65, 0xB2, 0x01, 0x00, 0x00, 0xA6, 0x01, 0x00, 0x42, 0x86, 0x0D, 0x00, + 0x61, 0x42, 0x01, 0x00, 0x01, 0xAE, 0x01, 0x00, 0x00, 0x71, 0x00, 0x00, 0x42, 0x82, 0x08, 0x00, + 0x42, 0xC3, 0x08, 0x00, 0x48, 0x40, 0x01, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x6E, 0x34, 0x02, 0x00, + 0x65, 0x79, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x6C, 0x36, 0x04, 0x00, 0x6E, 0x34, 0x02, 0x00, + 0x48, 0x7F, 0x01, 0x00, 0x6C, 0x0A, 0x06, 0x00, 0x6E, 0x34, 0x02, 0x00, 0x6E, 0x05, 0x04, 0x00, + 0x65, 0x79, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x41, 0x87, 0x03, 0x00, 0x65, 0xBA, 0x00, 0x00, + 0x65, 0xB2, 0x00, 0x00, 0x42, 0x82, 0x02, 0x00, 0x00, 0x51, 0x00, 0x00, 0x61, 0xC1, 0x00, 0x00, + 0x65, 0xFB, 0x00, 0x00, 0x65, 0xF3, 0x00, 0x00, 0x41, 0x87, 0x05, 0x00, 0x65, 0xF3, 0x00, 0x00, + 0x42, 0xC3, 0x08, 0x00, 0x00, 0x59, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00, + 0x56, 0xC0, 0x21, 0x00, 0x04, 0xDF, 0x01, 0x00, 0x43, 0xC7, 0x15, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x00, 0x79, 0x00, 0x00, 0x42, 0xC3, 0x20, 0x00, 0x43, 0xC3, 0x04, 0x00, 0x42, 0x00, 0x30, 0x00, + 0x42, 0x41, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x60, 0xC7, 0x01, 0x00, + 0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00, 0x22, 0x7F, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00, + 0x6E, 0x34, 0x02, 0x00, 0x6E, 0x05, 0x04, 0x00, 0x4B, 0x41, 0x00, 0x00, 0x60, 0xC7, 0x01, 0x00, + 0x60, 0x87, 0x01, 0x00, 0x43, 0x86, 0x15, 0x00, 0x00, 0x30, 0x00, 0x00, 0x65, 0x39, 0x01, 0x00, + 0x42, 0x04, 0x05, 0x00, 0x4E, 0x05, 0x7E, 0x00, 0x6A, 0x1B, 0x06, 0x00, 0x55, 0xC0, 0x3D, 0x00, + 0x0A, 0x3C, 0x01, 0x00, 0x60, 0xC7, 0x01, 0x00, 0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00, + 0x22, 0x7C, 0x09, 0x00, 0x22, 0x7F, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x65, 0x7A, 0x01, 0x00, + 0x42, 0x45, 0x05, 0x00, 0x65, 0xBB, 0x01, 0x00, 0x42, 0x86, 0x05, 0x00, 0x55, 0xC0, 0x3D, 0x00, + 0x0A, 0x7D, 0x01, 0x00, 0x0A, 0xBE, 0x01, 0x00, 0x07, 0xC7, 0x01, 0x00, 0x0B, 0x7D, 0x01, 0x00, + 0x0B, 0xBE, 0x01, 0x00, 0x55, 0xC0, 0x3D, 0x00, 0x0A, 0x3C, 0x01, 0x00, 0x60, 0xC7, 0x01, 0x00, + 0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00, 0x22, 0x7A, 0x05, 0x00, 0x22, 0x7B, 0x07, 0x00, + 0x22, 0x7C, 0x09, 0x00, 0x22, 0x7D, 0x0B, 0x00, 0x22, 0x7E, 0x0D, 0x00, 0x22, 0x7F, 0x1F, 0x00, + 0x6F, 0x00, 0x00, 0x00 +}; + +vic_config_t __attribute__((aligned (0x100))) vic_cfg = {0}; + +u32 _vic_read_priv(u32 addr) +{ + u32 addr_lsb = addr & 0xFF; + + // Set address LSB. + if (addr_lsb) + VIC(PVIC_FALCON_ADDR) = addr_lsb >> 2; + + // Set address. + u32 val = VIC(PVIC_FALCON_PA_OFFSET + (addr >> 6)); + + // Unset address LSB. + if (addr_lsb) + VIC(PVIC_FALCON_ADDR) = 0; + + return val; +} + +static void _vic_write_priv(u32 addr, u32 data) +{ + u32 addr_lsb = addr & 0xFF; + + // Set address LSB. + if (addr_lsb) + VIC(PVIC_FALCON_ADDR) = addr_lsb >> 2; + + // Set address. + VIC(PVIC_FALCON_PA_OFFSET + (addr >> 6)) = data; + + // Unset address LSB. + if (addr_lsb) + VIC(PVIC_FALCON_ADDR) = 0; +} + +static int _vic_wait_idle() +{ + u32 timeout_count = 15000; // 150ms. + + while (VIC(PVIC_FALCON_IDLESTATE)) + { + usleep(10); + + timeout_count--; + if (!timeout_count) + return -1; + }; + + return 0; +} + +void vic_set_surface(vic_surface_t *sfc) +{ + u32 flip_x = 0; + u32 flip_y = 0; + u32 swap_xy = 0; + u32 const_alpha = 0; + + u32 width = sfc->width; + u32 height = sfc->height; + u32 pix_fmt = sfc->pix_fmt; + u32 src_buf = sfc->src_buf; + u32 dst_buf = sfc->dst_buf; + + // Get format alpha type. + switch (sfc->pix_fmt) + { + case VIC_PIX_FORMAT_X8B8G8R8: + case VIC_PIX_FORMAT_X8R8G8B8: + case VIC_PIX_FORMAT_B8G8R8X8: + case VIC_PIX_FORMAT_R8G8B8X8: + const_alpha = 1; + break; + + case VIC_PIX_FORMAT_A8B8G8R8: + case VIC_PIX_FORMAT_A8R8G8B8: + case VIC_PIX_FORMAT_B8G8R8A8: + case VIC_PIX_FORMAT_R8G8B8A8: + default: + break; + } + + // Get rotation parameters. + switch (sfc->rotation) + { + case VIC_ROTATION_90: + swap_xy = 1; + break; + + case VIC_ROTATION_180: + flip_x = 1; + flip_y = 1; + break; + + case VIC_ROTATION_270: + flip_x = 1; + swap_xy = 1; + break; + + case VIC_ROTATION_0: + default: + break; + } + + // Set output surface format. + vic_cfg.out_sfc_cfg.OutPixelFormat = pix_fmt; + vic_cfg.out_sfc_cfg.OutBlkKind = BLK_KIND_PITCH; + vic_cfg.out_sfc_cfg.OutBlkHeight = 0; + + // Set output rotation/flip. + vic_cfg.out_cfg.OutputFlipX = flip_x; + vic_cfg.out_cfg.OutputFlipY = flip_y; + vic_cfg.out_cfg.OutputTranspose = swap_xy; + + // Set output surface resolution. + vic_cfg.out_sfc_cfg.OutSurfaceWidth = width - 1; + vic_cfg.out_sfc_cfg.OutSurfaceHeight = height - 1; + vic_cfg.out_sfc_cfg.OutLumaWidth = width - 1; + vic_cfg.out_sfc_cfg.OutLumaHeight = height - 1; + + // Set output destination rectangle. Anything outside will not be touched at output buffer. + vic_cfg.out_cfg.TargetRectLeft = 0; + vic_cfg.out_cfg.TargetRectRight = width - 1; + vic_cfg.out_cfg.TargetRectTop = 0; + vic_cfg.out_cfg.TargetRectBottom = height - 1; + + // Initialize slot parameters. + vic_cfg.slots[0].slot_cfg.SlotEnable = 1; + vic_cfg.slots[0].slot_cfg.SoftClampLow = SOFT_CLAMP_MIN; + vic_cfg.slots[0].slot_cfg.SoftClampHigh = SOFT_CLAMP_MAX; + vic_cfg.slots[0].slot_cfg.PlanarAlpha = ALPHA_1_0; + vic_cfg.slots[0].slot_cfg.ConstantAlpha = const_alpha; + vic_cfg.slots[0].slot_cfg.FrameFormat = FORMAT_PROGRESSIVE; + + // Set input source rectangle. + vic_cfg.slots[0].slot_cfg.SourceRectLeft = 0; + vic_cfg.slots[0].slot_cfg.SourceRectRight = (width - 1) << 16; + vic_cfg.slots[0].slot_cfg.SourceRectTop = 0; + vic_cfg.slots[0].slot_cfg.SourceRectBottom = (height - 1) << 16; + + // Set input destination rectangle. + vic_cfg.slots[0].slot_cfg.DestRectLeft = 0; + vic_cfg.slots[0].slot_cfg.DestRectRight = (width - 1); + vic_cfg.slots[0].slot_cfg.DestRectTop = 0; + vic_cfg.slots[0].slot_cfg.DestRectBottom = (height - 1); + + // Set input surface format. + vic_cfg.slots[0].slot_sfc_cfg.SlotPixelFormat = pix_fmt; + vic_cfg.slots[0].slot_sfc_cfg.SlotBlkKind = BLK_KIND_PITCH; + vic_cfg.slots[0].slot_sfc_cfg.SlotBlkHeight = 0; + vic_cfg.slots[0].slot_sfc_cfg.SlotCacheWidth = CACHE_WIDTH_64BX4; + + // Set input surface resolution. + vic_cfg.slots[0].slot_sfc_cfg.SlotSurfaceWidth = width - 1; + vic_cfg.slots[0].slot_sfc_cfg.SlotSurfaceHeight = height - 1; + vic_cfg.slots[0].slot_sfc_cfg.SlotLumaWidth = width - 1; + vic_cfg.slots[0].slot_sfc_cfg.SlotLumaHeight = height - 1; + + // Flush data. + bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false); + + // Set parameters base and size. Causes a parse by surface cache. + _vic_write_priv(VIC_SC_PRAMBASE, (u32)&vic_cfg >> 8); + _vic_write_priv(VIC_SC_PRAMSIZE, sizeof(vic_config_t) >> 6); + + // Wait for surface cache to get ready. + _vic_wait_idle(); + + // Set slot mapping. + _vic_write_priv(VIC_FC_SLOT_MAP, 0xFFFFFFF0); + + // Set input surface buffer. + _vic_write_priv(VIC_SC_SFC0_BASE_LUMA(0), src_buf >> 8); + + // Set output surface buffer. + _vic_write_priv(VIC_BL_TARGET_BASADR, dst_buf >> 8); + + // Set blending config and push changes to surface cache. + _vic_write_priv(VIC_BL_CONFIG, SLOTMASK(0x1F) | PROCESS_CFG_STRUCT_TRIGGER | SUBPARTITION_MODE); + + // Wait for surface cache to get ready. + _vic_wait_idle(); +} + +int vic_compose() +{ + // Wait for surface cache to get ready. Otherwise VIC will hang. + int res = _vic_wait_idle(); + + // Start composition of a single frame. + _vic_write_priv(VIC_FC_COMPOSE, COMPOSE_START); + + return res; +} + +int vic_init() +{ + // Ease the stress to APB. + bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL); + + clock_enable_vic(); + + // Restore sys clock. + bpmp_clk_rate_set(prev_fid); + + // Load Fetch Control Engine microcode. + for (u32 i = 0; i < sizeof(vic_fce_ucode) / sizeof(u32); i++) + { + _vic_write_priv(VIC_FC_FCE_UCODE_ADDR, (i * sizeof(u32))); + _vic_write_priv(VIC_FC_FCE_UCODE_INST, *(u32 *)&vic_fce_ucode[i * sizeof(u32)]); + } + + // Start Fetch Control Engine. + _vic_write_priv(VIC_FC_FCE_CTRL, START_TRIGGER); + + return _vic_wait_idle(); +} + +void vic_end() +{ + clock_disable_vic(); +} diff --git a/bdk/display/vic.h b/bdk/display/vic.h new file mode 100644 index 00000000..0014926d --- /dev/null +++ b/bdk/display/vic.h @@ -0,0 +1,63 @@ +/* + * VIC driver for Tegra X1 + * + * Copyright (c) 2018-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 _VIC_H_ +#define _VIC_H_ + +#include + +#define VIC_THI_SLCG_OVERRIDE_LOW_A 0x8C + +typedef enum _vic_rotation_t +{ + VIC_ROTATION_0 = 0, + VIC_ROTATION_90 = 1, + VIC_ROTATION_180 = 2, + VIC_ROTATION_270 = 3, +} vic_rotation_t; + +typedef enum _vic_pix_format_t +{ + VIC_PIX_FORMAT_A8B8G8R8 = 31, // 32-bit ABGR. + VIC_PIX_FORMAT_A8R8G8B8 = 32, // 32-bit ARGB. + VIC_PIX_FORMAT_B8G8R8A8 = 33, // 32-bit BGRA. + VIC_PIX_FORMAT_R8G8B8A8 = 34, // 32-bit RGBA. + + VIC_PIX_FORMAT_X8B8G8R8 = 35, // 32-bit XBGR. + VIC_PIX_FORMAT_X8R8G8B8 = 36, // 32-bit XRGB. + VIC_PIX_FORMAT_B8G8R8X8 = 37, // 32-bit BGRX. + VIC_PIX_FORMAT_R8G8B8X8 = 38, // 32-bit RGBX. + +} vic_pix_format_t; + +typedef struct _vic_surface_t +{ + u32 src_buf; + u32 dst_buf; + u32 width; + u32 height; + u32 pix_fmt; + u32 rotation; +} vic_surface_t; + +void vic_set_surface(vic_surface_t *sfc); +int vic_compose(); +int vic_init(); +void vic_end(); + +#endif diff --git a/bdk/exception_handlers.S b/bdk/exception_handlers.S index 97d1ec67..2f38bb30 100644 --- a/bdk/exception_handlers.S +++ b/bdk/exception_handlers.S @@ -97,6 +97,10 @@ _irq_setup: MSR CPSR, #(MODE_IRQ | IRQ | FIQ) /* IRQ mode, IRQ/FIQ disabled */ LDR SP, =0x40040000 + /* Setup FIQ stack pointer */ + MSR CPSR, #(MODE_FIQ | IRQ | FIQ) /* FIQ mode, IRQ/FIQ disabled */ + LDR SP, =0x40040000 + /* Setup SYS stack pointer */ MSR CPSR, #(MODE_SYS | IRQ | FIQ) /* SYSTEM mode, IRQ/FIQ disabled */ LDR SP, =0x4003FF00 /* Will be changed later to DRAM */ @@ -111,7 +115,9 @@ _irq_setup: B ipl_main B . -_reset: +.globl excp_reset +.type excp_reset, %function +excp_reset: LDR R0, =EXCP_EN_ADDR LDR R1, =0x30505645 /* EVP0 */ STR R1, [R0] /* EVP0 in EXCP_EN_ADDR */ @@ -129,25 +135,25 @@ _reset_handler: LDR R0, =EXCP_TYPE_ADDR LDR R1, =0x545352 /* RST */ STR R1, [R0] /* RST in EXCP_TYPE_ADDR */ - B _reset + B excp_reset _undefined_handler: LDR R0, =EXCP_TYPE_ADDR LDR R1, =0x464455 /* UDF */ STR R1, [R0] /* UDF in EXCP_TYPE_ADDR */ - B _reset + B excp_reset _prefetch_abort_handler: LDR R0, =EXCP_TYPE_ADDR LDR R1, =0x54424150 /* PABT */ STR R1, [R0] /* PABT in EXCP_TYPE_ADDR */ - B _reset + B excp_reset _data_abort_handler: LDR R0, =EXCP_TYPE_ADDR LDR R1, =0x54424144 /* DABT */ STR R1, [R0] /* DABT in EXCP_TYPE_ADDR */ - B _reset + B excp_reset .globl irq_enable_cpu_irq_exceptions .type irq_enable_cpu_irq_exceptions, %function diff --git a/bdk/fatfs_cfg.h b/bdk/fatfs_cfg.h index a12585f6..77b26ddb 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 00000000..580aa31b --- /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 1 +/* 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 196cf87c..2a7111e6 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 */ @@ -444,7 +445,7 @@ typedef struct /* Dynamic structure */ typedef struct { - Elf32_Sword d_tag; /* controls meaning of d_val */ + Elf32_Word d_tag; /* controls meaning of d_val */ union { Elf32_Word d_val; /* Multiple meanings - see d_tag */ Elf32_Addr d_ptr; /* program virtual address */ diff --git a/bdk/ianos/elfload/elfload.c b/bdk/ianos/elfload/elfload.c index 16f8200f..daf561a4 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 2b9bb670..0a73e052 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 bbb0ce4f..736ad467 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 8b905cb2..77ce654d 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 8deca458..99a996df 100644 --- a/bdk/ianos/ianos.c +++ b/bdk/ianos/ianos.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -74,19 +74,16 @@ uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig) el_ctx ctx; uintptr_t epaddr = 0; - if (!sd_mount()) - goto elfLoadFinalOut; - // Read library. fileBuf = sd_file_read(path, NULL); if (!fileBuf) - goto elfLoadFinalOut; + goto out; ctx.pread = _ianos_read_cb; if (el_init(&ctx)) - goto elfLoadFinalOut; + goto out; // Set our relocated library's buffer. switch (type & 0xFFFF) @@ -100,15 +97,15 @@ uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig) } if (!elfBuf) - goto elfLoadFinalOut; + goto out; // Load and relocate library. ctx.base_load_vaddr = ctx.base_load_paddr = (uintptr_t)elfBuf; if (el_load(&ctx, _ianos_alloc_cb)) - goto elfFreeOut; + goto out_free; if (el_relocate(&ctx)) - goto elfFreeOut; + goto out_free; // Launch. epaddr = ctx.ehdr.e_entry + (uintptr_t)elfBuf; @@ -116,11 +113,11 @@ uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig) _ianos_call_ep(ep, moduleConfig); -elfFreeOut: +out_free: free(fileBuf); elfBuf = NULL; fileBuf = NULL; -elfLoadFinalOut: +out: return epaddr; } \ No newline at end of file diff --git a/bdk/input/als.c b/bdk/input/als.c index be554260..54e44644 100644 --- a/bdk/input/als.c +++ b/bdk/input/als.c @@ -73,7 +73,7 @@ void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle) 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_GAIN_REG), gain); i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - cycle)); als_ctxt->gain = gain; @@ -83,25 +83,25 @@ void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle) void get_als_lux(als_ctxt_t *als_ctxt) { u32 data[2]; - u32 visible_light; + u32 vi_light; u32 ir_light; u64 lux = 0; u32 itime_us = BH1730_ITIME_CYCLE_TO_US * als_ctxt->cycle; // 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); + (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); + (i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1HIGH_REG)) << 8); - visible_light = data[0]; + vi_light = data[0]; ir_light = data[1]; - als_ctxt->over_limit = visible_light > 65534 || ir_light > 65534; - als_ctxt->vi_light = visible_light; + als_ctxt->vi_light = vi_light; als_ctxt->ir_light = ir_light; + als_ctxt->over_limit = vi_light > 65534 || ir_light > 65534; - if (!visible_light) + if (!vi_light) { als_ctxt->lux = 0; @@ -116,7 +116,7 @@ void get_als_lux(als_ctxt_t *als_ctxt) // 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) + if (1000 * ir_light / vi_light < opt_win_cal[i].rc) { lux = ((u64)opt_win_cal[i].cv * data[0]) - (opt_win_cal[i].ci * data[1]); break; diff --git a/bdk/input/joycon.c b/bdk/input/joycon.c index 825e3470..a33a6adc 100644 --- a/bdk/input/joycon.c +++ b/bdk/input/joycon.c @@ -1,7 +1,7 @@ /* * Joy-Con UART driver for Nintendo Switch * - * Copyright (c) 2019-2021 CTCaer + * Copyright (c) 2019-2023 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,9 +27,9 @@ #include #include #include +#include #include #include -#include // For disabling driver when logging is enabled. #include @@ -42,8 +42,13 @@ #define JC_HORI_INPUT_RPT_CMD 0x9A #define JC_HORI_INPUT_RPT 0x00 -#define JC_WIRED_CMD_MAC 0x01 -#define JC_WIRED_CMD_10 0x10 +#define JC_WIRED_CMD_GET_INFO 0x01 +#define JC_WIRED_CMD_CHRG_CFG 0x02 +#define JC_WIRED_CMD_WAKE_REASON 0x07 +#define JC_WIRED_CMD_HID_CONN 0x10 +#define JC_WIRED_CMD_HID_DISC 0x11 +#define JC_WIRED_CMD_SET_HIDRATE 0x12 // Output report rate. +#define JC_WIRED_CMD_SET_BRATE 0x20 #define JC_HID_OUTPUT_RPT 0x01 #define JC_HID_RUMBLE_RPT 0x10 @@ -61,15 +66,38 @@ #define JC_HID_SUBCMD_RUMBLE_CTL 0x48 #define JC_HID_SUBCMD_SND_RUMBLE 0xFF +#define JC_SIO_OUTPUT_RPT 0x91 +#define JC_SIO_INPUT_RPT 0x92 +#define JC_SIO_CMD_ACK 0x80 + +#define JC_SIO_CMD_INIT 0x01 +#define JC_SIO_CMD_UNK02 0x02 +#define JC_SIO_CMD_VER_RPT 0x03 +#define JC_SIO_CMD_UNK20 0x20 // JC_WIRED_CMD_SET_BRATE +#define JC_SIO_CMD_UNK21 0x21 +#define JC_SIO_CMD_UNK22 0x22 +#define JC_SIO_CMD_UNK40 0x40 +#define JC_SIO_CMD_STATUS 0x41 +#define JC_SIO_CMD_IAP_VER 0x42 + + #define JC_BTN_MASK_L 0xFF2900 // 0xFFE900: with charge status. #define JC_BTN_MASK_R 0x0056FF -#define JC_ID_L 0x01 -#define JC_ID_R 0x02 -#define JC_ID_HORI 0x20 +#define JC_ID_L 0x01 // Joycon (L). Mask for Hori (L). +#define JC_ID_R 0x02 // Joycon (R). Mask for Hori (R). +#define JC_ID_HORI 0x20 // Mask for Hori. Actual ids: 0x21, 0x22. -#define JC_CRC8_INIT 0x00 -#define JC_CRC8_POLY 0x8D +#define JC_CRC8_POLY 0x8D + +enum +{ + JC_STATE_START = 0, + JC_STATE_HANDSHAKED = 1, + JC_STATE_BRATE_CHANGED = 2, + JC_STATE_BRATE_OK = 3, + JC_STATE_INIT_DONE = 4 +}; enum { @@ -80,7 +108,25 @@ enum JC_BATT_FULL = 8 }; -static const u8 init_jc[] = { +static const u8 sio_init[] = { + JC_SIO_OUTPUT_RPT, JC_SIO_CMD_INIT, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x95 +}; + +static const u8 sio_set_rpt_version[] = { + JC_SIO_OUTPUT_RPT, JC_SIO_CMD_VER_RPT, + // old fw: 0x00, 0x0D (0.13). New 3.4. + // force_update_en: 0x01 + 0x00, 0x00, 0x03, 0x04, 0x00, 0xDA +}; + +// Every 8ms. +static const u8 sio_pad_status[] = { + JC_SIO_OUTPUT_RPT, JC_SIO_CMD_STATUS, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0 +}; + +static const u8 init_wake[] = { 0xA1, 0xA2, 0xA3, 0xA4 }; @@ -91,21 +137,47 @@ static const u8 init_handshake[] = { }; static const u8 init_get_info[] = { - 0x19, 0x01, 0x03, 0x07, 0x00, // Uart header. - JC_WIRED_CMD, JC_WIRED_CMD_MAC, // Wired cmd and subcmd. - 0x00, 0x00, 0x00, 0x00, 0x24 // Wired subcmd data and crc. + 0x19, 0x01, 0x03, 0x07, 0x00, // Uart header. + JC_WIRED_CMD, JC_WIRED_CMD_GET_INFO, // Wired cmd and subcmd. + 0x00, 0x00, 0x00, 0x00, 0x24 // Wired subcmd data and crc. }; -static const u8 init_finalize[] = { - 0x19, 0x01, 0x03, 0x07, 0x00, // Uart header. - JC_WIRED_CMD, JC_WIRED_CMD_10, // Wired cmd and subcmd. - 0x00, 0x00, 0x00, 0x00, 0x3D // Wired subcmd data and crc. +static const u8 init_switch_brate[] = { + 0x19, 0x01, 0x03, 0x0F, 0x00, // Uart header. + JC_WIRED_CMD, JC_WIRED_CMD_SET_BRATE, // Wired cmd and subcmd. + 0x08, 0x00, 0x00, 0xBD, 0xB1, // Wired subcmd data, data crc and crc. + // Baudrate 3 megabaud. + 0xC0, 0xC6, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const u8 init_hid_disconnect[] = { + 0x19, 0x01, 0x03, 0x07, 0x00, // Uart header. + JC_WIRED_CMD, JC_WIRED_CMD_HID_DISC, // Wired cmd and subcmd. + 0x00, 0x00, 0x00, 0x00, 0x0E // Wired subcmd data and crc. +}; + +static const u8 init_set_hid_rate[] = { + 0x19, 0x01, 0x03, 0x0B, 0x00, // Uart header. + JC_WIRED_CMD, JC_WIRED_CMD_SET_HIDRATE, // Wired cmd and subcmd. + 0x04, 0x00, 0x00, 0x12, 0xA6, // Wired subcmd data, data crc and crc. + // Output report rate 15 ms. + 0x0F, 0x00, 0x00, 0x00 + + // 5 ms. + // 0x04, 0x00, 0x00, 0x0E, 0xD5, + // 0x05, 0x00, 0x00, 0x00 +}; + +static const u8 init_hid_connect[] = { + 0x19, 0x01, 0x03, 0x07, 0x00, // Uart header. + JC_WIRED_CMD, JC_WIRED_CMD_HID_CONN, // Wired cmd and subcmd. + 0x00, 0x00, 0x00, 0x00, 0x3D // Wired subcmd data and crc. }; static const u8 nx_pad_status[] = { 0x19, 0x01, 0x03, 0x08, 0x00, // Uart header. JC_WIRED_HID, 0x00, // Wired cmd and hid cmd. - 0x01, 0x00, 0x00, 0x69, 0x2D, 0x1F // hid data and crc. + 0x01, 0x00, 0x00, 0x69, 0x2D, 0x1F // hid data, data crc and crc. }; static const u8 hori_pad_status[] = { @@ -160,7 +232,7 @@ typedef struct _jc_hid_in_rpt_t u8 stick_h_right; u8 stick_m_right; u8 stick_v_right; - u8 vib_decider; + u8 vib_decider; // right:8, left:8. (bit3 en, bit2-0 buffer avail). u8 submcd_ack; u8 subcmd; u8 subcmd_data[]; @@ -185,17 +257,71 @@ typedef struct _jc_hid_in_pair_data_t u8 pad1; } jc_hid_in_pair_data_t; -typedef struct _joycon_ctxt_t +typedef struct _jc_sio_out_rpt_t +{ + u8 cmd; + u8 subcmd; + u16 payload_size; + u8 data[2]; + u8 crc_payload; + u8 crc_hdr; + u8 payload[]; +} jc_sio_out_rpt_t; + +typedef struct _jc_sio_in_rpt_t +{ + u8 cmd; + u8 ack; + u16 payload_size; + u8 status; + u8 unk; + u8 crc_payload; + u8 crc_hdr; + u8 payload[]; +} jc_sio_in_rpt_t; + +typedef struct _jc_hid_in_sixaxis_rpt_t +{ + s16 acc_x; + s16 acc_y; + s16 acc_z; + s16 gyr_x; + s16 gyr_y; + s16 gyr_z; +} __attribute__((packed)) jc_hid_in_sixaxis_rpt_t; + +typedef struct _jc_sio_hid_in_rpt_t { - u8 buf[0x100]; //FIXME: If heap is used, dumping breaks. - u8 uart; u8 type; - u8 mac[6]; - u32 hw_init_done; + u8 pkt_id; + u8 unk; + u8 btn_right; + u8 btn_shared; + u8 btn_left; + u8 stick_h_left; + u8 stick_m_left; + u8 stick_v_left; + u8 stick_h_right; + u8 stick_m_right; + u8 stick_v_right; + u8 siaxis_rpt_num; // Max 15. + // Each report is 800 us? + jc_hid_in_sixaxis_rpt_t sixaxis[15]; +} jc_sio_hid_in_rpt_t; + +typedef struct _joycon_ctxt_t +{ + u8 buf[0x100]; //FIXME: If heap is used, dumping breaks. + u8 uart; + u8 type; + u8 state; + u8 mac[6]; u32 last_received_time; u32 last_status_req_time; - u8 rumble_sent; - u8 connected; + u8 rumble_sent; + u8 connected; + u8 detected; + u8 sio_mode; } joycon_ctxt_t; static joycon_ctxt_t jc_l = {0}; @@ -206,15 +332,14 @@ static u32 hid_pkt_inc = 0; static jc_gamepad_rpt_t jc_gamepad; -void jc_power_supply(u8 uart, bool enable); - -static u8 jc_crc(u8 *data, u16 len) +static u8 _jc_crc(u8 *data, u16 len, u8 init) { - u8 crc = JC_CRC8_INIT; - u16 i, j; - for (i = 0; i < len; i++) { + u8 crc = init; + for (u16 i = 0; i < len; i++) + { crc ^= data[i]; - for (j = 0; j < 8; j++) { + for (u16 j = 0; j < 8; j++) + { if ((crc & 0x80) != 0) crc = (u8)((crc << 1) ^ JC_CRC8_POLY); else @@ -224,13 +349,136 @@ static u8 jc_crc(u8 *data, u16 len) return crc; } -void joycon_send_raw(u8 uart_port, const u8 *buf, u16 size) +static void _jc_power_supply(u8 uart, bool enable) +{ + if (enable) + { + if (regulator_5v_get_dev_enabled(1 << uart)) + return; + + regulator_5v_enable(1 << uart); + + if (jc_gamepad.sio_mode) + return; + + if (jc_init_done) + { + if (uart == UART_C) + gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_HIGH); + else + gpio_write(GPIO_PORT_K, GPIO_PIN_3, GPIO_HIGH); + return; + } + + if (uart == UART_C) + { + // Joy-Con(L) Charge Enable. + PINMUX_AUX(PINMUX_AUX_SPDIF_IN) = PINMUX_PULL_DOWN | 1; + gpio_direction_output(GPIO_PORT_CC, GPIO_PIN_3, GPIO_HIGH); + } + else + { + // Joy-Con(R) Charge Enable. + PINMUX_AUX(PINMUX_AUX_GPIO_PK3) = PINMUX_DRIVE_4X | PINMUX_PULL_DOWN | 2; + gpio_direction_output(GPIO_PORT_K, GPIO_PIN_3, GPIO_HIGH); + } + } + else + { + if (!regulator_5v_get_dev_enabled(1 << uart)) + return; + + regulator_5v_disable(1 << uart); + + if (jc_gamepad.sio_mode) + return; + + if (uart == UART_C) + gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_LOW); + else + gpio_write(GPIO_PORT_K, GPIO_PIN_3, GPIO_LOW); + } +} + +static void _jc_detect() +{ + if (!jc_gamepad.sio_mode) + { + // Turn on Joy-Con detect. (UARTB/C TX). UART CTS also if HW flow control and irq is enabled. + PINMUX_AUX(PINMUX_AUX_UART2_TX) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; + PINMUX_AUX(PINMUX_AUX_UART3_TX) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; + gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0); + gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1); + usleep(20); + + // Read H6/E6 which are shared with UART TX pins. + jc_r.detected = !gpio_read(GPIO_PORT_H, GPIO_PIN_6); + jc_l.detected = !gpio_read(GPIO_PORT_E, GPIO_PIN_6); + + // Turn off Joy-Con detect. (UARTB/C TX). + PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0; + PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0; + gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO); + gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO); + usleep(20); + } + else + { + //! TODO: Is there a way to detect a broken Sio? + jc_l.detected = true; + } +} + +static void _jc_conn_check() +{ + _jc_detect(); + + if (jc_gamepad.sio_mode) + return; + + // Check if a Joy-Con was disconnected. + if (!jc_l.detected) + { + if (jc_l.connected) + _jc_power_supply(UART_C, false); + + hid_pkt_inc = 0; + + jc_l.connected = false; + jc_l.rumble_sent = false; + + jc_gamepad.conn_l = false; + + jc_gamepad.batt_info_l = 0; + jc_gamepad.bt_conn_l.type = 0; + jc_gamepad.buttons &= ~JC_BTN_MASK_L; + } + + if (!jc_r.detected) + { + if (jc_r.connected) + _jc_power_supply(UART_B, false); + + hid_pkt_inc = 0; + + jc_r.connected = false; + jc_r.rumble_sent = false; + + jc_gamepad.conn_r = false; + + jc_gamepad.batt_info_r = 0; + jc_gamepad.bt_conn_r.type = 0; + jc_gamepad.buttons &= ~JC_BTN_MASK_R; + } +} + +static void _joycon_send_raw(u8 uart_port, const u8 *buf, u16 size) { uart_send(uart_port, buf, size); - uart_wait_idle(uart_port, UART_TX_IDLE); + uart_wait_xfer(uart_port, UART_TX_IDLE); } -static u16 jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data, u16 size, bool crc) +static u16 _jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data, u16 size, bool crc) { out->uart_hdr.magic[0] = 0x19; out->uart_hdr.magic[1] = 0x01; @@ -243,14 +491,16 @@ static u16 jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data, u if (data) memcpy(out->data, data, size); - out->crc = crc ? jc_crc(&out->uart_hdr.total_size_msb, sizeof(out->uart_hdr.total_size_msb) + sizeof(out->cmd) + sizeof(out->data)) : 0; + out->crc = crc ? _jc_crc(&out->uart_hdr.total_size_msb, + sizeof(out->uart_hdr.total_size_msb) + + sizeof(out->cmd) + sizeof(out->data), 0) : 0; return sizeof(jc_wired_hdr_t); } -static u16 jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, u8 *payload, u16 size, bool crc) +static u16 _jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, u8 *payload, u16 size, bool crc) { - u16 pkt_size = jc_packet_add_uart_hdr(rpt, JC_WIRED_HID, NULL, 0, crc); + u16 pkt_size = _jc_packet_add_uart_hdr(rpt, JC_WIRED_HID, NULL, 0, crc); pkt_size += size; rpt->uart_hdr.total_size_lsb += size; @@ -263,34 +513,29 @@ static u16 jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, u8 *payload, u16 size, b return pkt_size; } -void jc_send_hid_output_rpt(u8 uart, u8 *payload, u16 size, bool crc) +static void _jc_send_hid_output_rpt(u8 uart, u8 *payload, u16 size, bool crc) { u8 rpt[0x50]; memset(rpt, 0, sizeof(rpt)); - u32 rpt_size = jc_hid_output_rpt_craft((jc_wired_hdr_t *)rpt, payload, size, crc); + u32 rpt_size = _jc_hid_output_rpt_craft((jc_wired_hdr_t *)rpt, payload, size, crc); - joycon_send_raw(uart, rpt, rpt_size); + _joycon_send_raw(uart, rpt, rpt_size); } -static u8 jc_hid_pkt_id_incr() +static u8 _jc_hid_pkt_id_incr() { - u8 curr_id = hid_pkt_inc; - hid_pkt_inc++; - - return (curr_id & 0xF); + return (hid_pkt_inc++ & 0xF); } -void jc_send_hid_cmd(u8 uart, u8 subcmd, u8 *data, u16 size) +static void _jc_send_hid_cmd(u8 uart, u8 subcmd, u8 *data, u16 size) { - u8 temp[0x30]; - u8 rumble_neutral[8] = {0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40}; - u8 rumble_init[8] = {0xc2, 0xc8, 0x03, 0x72, 0xc2, 0xc8, 0x03, 0x72}; + const u8 rumble_neutral[8] = { 0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40 }; + const u8 rumble_init[8] = { 0xc2, 0xc8, 0x03, 0x72, 0xc2, 0xc8, 0x03, 0x72 }; - memset(temp, 0, sizeof(temp)); + u8 temp[0x30] = {0}; jc_hid_out_rpt_t *hid_pkt = (jc_hid_out_rpt_t *)temp; - memcpy(hid_pkt->rumble, rumble_neutral, sizeof(rumble_neutral)); if (subcmd == JC_HID_SUBCMD_SND_RUMBLE) @@ -299,63 +544,63 @@ void jc_send_hid_cmd(u8 uart, u8 subcmd, u8 *data, u16 size) bool send_l_rumble = jc_l.connected && !jc_l.rumble_sent; // Enable rumble. - hid_pkt->cmd = JC_HID_OUTPUT_RPT; - hid_pkt->pkt_id = jc_hid_pkt_id_incr(); + hid_pkt->cmd = JC_HID_OUTPUT_RPT; + hid_pkt->pkt_id = _jc_hid_pkt_id_incr(); hid_pkt->subcmd = JC_HID_SUBCMD_RUMBLE_CTL; hid_pkt->subcmd_data[0] = 1; if (send_r_rumble) - jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10, false); + _jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10, false); if (send_l_rumble) - jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10, false); + _jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10, false); // Send rumble. - hid_pkt->cmd = JC_HID_RUMBLE_RPT; - hid_pkt->pkt_id = jc_hid_pkt_id_incr(); + hid_pkt->cmd = JC_HID_RUMBLE_RPT; + hid_pkt->pkt_id = _jc_hid_pkt_id_incr(); memcpy(hid_pkt->rumble, rumble_init, sizeof(rumble_init)); if (send_r_rumble) - jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 10, false); + _jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 10, false); if (send_l_rumble) - jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 10, false); + _jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 10, false); msleep(15); // Disable rumble. - hid_pkt->cmd = JC_HID_OUTPUT_RPT; - hid_pkt->pkt_id = jc_hid_pkt_id_incr(); + hid_pkt->cmd = JC_HID_OUTPUT_RPT; + hid_pkt->pkt_id = _jc_hid_pkt_id_incr(); hid_pkt->subcmd = JC_HID_SUBCMD_RUMBLE_CTL; hid_pkt->subcmd_data[0] = 0; memcpy(hid_pkt->rumble, rumble_neutral, sizeof(rumble_neutral)); if (send_r_rumble) - jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10, false); + _jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10, false); if (send_l_rumble) - jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10, false); + _jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10, false); } else { bool crc_needed = (jc_l.uart == uart) ? (jc_l.type & JC_ID_HORI) : (jc_r.type & JC_ID_HORI); - hid_pkt->cmd = JC_HID_OUTPUT_RPT; - hid_pkt->pkt_id = jc_hid_pkt_id_incr(); + hid_pkt->cmd = JC_HID_OUTPUT_RPT; + hid_pkt->pkt_id = _jc_hid_pkt_id_incr(); hid_pkt->subcmd = subcmd; if (data) memcpy(hid_pkt->subcmd_data, data, size); - jc_send_hid_output_rpt(uart, (u8 *)hid_pkt, sizeof(jc_hid_out_rpt_t) + size, crc_needed); + _jc_send_hid_output_rpt(uart, (u8 *)hid_pkt, sizeof(jc_hid_out_rpt_t) + size, crc_needed); } } -static void jc_charging_decider(u8 batt, u8 uart) +static void _jc_charging_decider(u8 batt, u8 uart) { u32 system_batt_enough = max17050_get_cached_batt_volt() > 4000; // Power supply control based on battery levels and charging. if ((batt >> 1 << 1) < JC_BATT_LOW) // Level without checking charging. - jc_power_supply(uart, true); + _jc_power_supply(uart, true); else if (batt > (system_batt_enough ? JC_BATT_FULL : JC_BATT_MID)) // Addresses the charging bit. - jc_power_supply(uart, false); + _jc_power_supply(uart, false); } -static void jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size) +static void _jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size) { u32 btn_tmp; jc_hid_in_rpt_t *hid_pkt = (jc_hid_in_rpt_t *)packet; @@ -390,7 +635,8 @@ static void jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size) jc_gamepad.conn_l = jc_l.connected; jc_gamepad.conn_r = jc_r.connected; - jc_charging_decider(hid_pkt->batt_info, jc->uart); + if (hid_pkt->cmd == JC_HID_INPUT_RPT) + _jc_charging_decider(hid_pkt->batt_info, jc->uart); break; case JC_HID_SUBMCD_RPT: if (hid_pkt->subcmd == JC_HID_SUBCMD_SPI_READ) @@ -402,10 +648,10 @@ static void jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size) else bt_conn = &jc_gamepad.bt_conn_r; - jc_hid_in_spi_read_t *spi_info = (jc_hid_in_spi_read_t *)hid_pkt->subcmd_data; + jc_hid_in_spi_read_t *spi_info = (jc_hid_in_spi_read_t *)hid_pkt->subcmd_data; jc_hid_in_pair_data_t *pair_data = (jc_hid_in_pair_data_t *)spi_info->data; - // Check if we reply is pairing info. + // Check if the reply is pairing info. if (spi_info->size == 0x1A && pair_data->magic == 0x95 && pair_data->size == 0x22) { bt_conn->type = jc->type; @@ -420,120 +666,179 @@ static void jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size) default: break; } - jc->last_received_time = get_tmr_ms(); } -static void jc_parse_wired_init(joycon_ctxt_t *jc, const u8* data, u32 size) +static void _jc_parse_wired_init(joycon_ctxt_t *jc, const u8* data, u32 size) { switch (data[0]) { - case JC_WIRED_CMD_MAC: + case JC_WIRED_CMD_GET_INFO: for (int i = 12; i > 6; i--) jc->mac[12 - i] = data[i]; jc->type = data[6]; jc->connected = true; + break; + case JC_WIRED_CMD_SET_BRATE: + jc->state = JC_STATE_BRATE_CHANGED; + break; + case JC_WIRED_CMD_HID_DISC: + jc->state = JC_STATE_BRATE_OK; + break; + case JC_WIRED_CMD_HID_CONN: + case JC_WIRED_CMD_SET_HIDRATE: + // done. default: break; } } -static void jc_uart_pkt_parse(joycon_ctxt_t *jc, const u8* packet, size_t size) +static void _jc_uart_pkt_parse(joycon_ctxt_t *jc, const jc_wired_hdr_t *pkt, size_t size) { - jc_wired_hdr_t *pkt = (jc_wired_hdr_t *)packet; switch (pkt->cmd) { case JC_HORI_INPUT_RPT_CMD: case JC_WIRED_HID: - jc_parse_wired_hid(jc, pkt->payload, (pkt->data[0] << 8) | pkt->data[1]); + _jc_parse_wired_hid(jc, pkt->payload, (pkt->data[0] << 8) | pkt->data[1]); break; case JC_WIRED_INIT_REPLY: - jc_parse_wired_init(jc, pkt->data, size - sizeof(jc_uart_hdr_t) - 1); + _jc_parse_wired_init(jc, pkt->data, size - sizeof(jc_uart_hdr_t) - 1); + break; + case JC_INIT_HANDSHAKE: + jc->state = JC_STATE_HANDSHAKED; break; default: break; } + + jc->last_received_time = get_tmr_ms(); } -static void jc_rcv_pkt(joycon_ctxt_t *jc) +static void _jc_sio_parse_payload(joycon_ctxt_t *jc, u8 cmd, const u8* payload, u32 size) { - if (gpio_read(GPIO_PORT_E, GPIO_PIN_6) && jc->uart == UART_C) - return; - else if (gpio_read(GPIO_PORT_H, GPIO_PIN_6) && jc->uart == UART_B) + switch (cmd) + { + case JC_SIO_CMD_STATUS: + jc_sio_hid_in_rpt_t *hid_pkt = (jc_sio_hid_in_rpt_t *)payload; + jc_gamepad.buttons = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16; + jc_gamepad.home = !gpio_read(GPIO_PORT_V, GPIO_PIN_3); + + jc_gamepad.lstick_x = hid_pkt->stick_h_left | ((hid_pkt->stick_m_left & 0xF) << 8); + jc_gamepad.lstick_y = (hid_pkt->stick_m_left >> 4) | (hid_pkt->stick_v_left << 4); + jc_gamepad.rstick_x = hid_pkt->stick_h_right | ((hid_pkt->stick_m_right & 0xF) << 8); + jc_gamepad.rstick_y = (hid_pkt->stick_m_right >> 4) | (hid_pkt->stick_v_right << 4); + + jc_gamepad.batt_info_l = jc_l.connected; + jc_gamepad.batt_info_r = gpio_read(GPIO_PORT_E, GPIO_PIN_7); // Set IRQ status. + + jc_gamepad.conn_l = jc_l.connected; + jc_gamepad.conn_r = jc_l.connected; + break; + default: + break; + } +} + +static void _jc_sio_uart_pkt_parse(joycon_ctxt_t *jc, const jc_sio_in_rpt_t *pkt, u32 size) +{ + if (pkt->crc_hdr != _jc_crc((u8 *)pkt, sizeof(jc_sio_in_rpt_t) - 1, 0)) return; - // Check if device stopped sending data. - u32 uart_irq = uart_get_IIR(jc->uart); - if (uart_irq != UART_IIR_REDI) + u8 cmd = pkt->ack & (~JC_SIO_CMD_ACK); + switch (cmd) + { + case JC_SIO_CMD_INIT: + jc->connected = pkt->status == 0; + break; + case JC_SIO_CMD_VER_RPT: + if (jc->connected) + jc->connected = pkt->status == 0; + break; + case JC_SIO_CMD_IAP_VER: + case JC_SIO_CMD_STATUS: + _jc_sio_parse_payload(jc, cmd, pkt->payload, pkt->payload_size); + break; + case JC_SIO_CMD_UNK02: + case JC_SIO_CMD_UNK20: + case JC_SIO_CMD_UNK21: + case JC_SIO_CMD_UNK22: + case JC_SIO_CMD_UNK40: + default: + break; + } + + jc->last_received_time = get_tmr_ms(); +} + +static void _jc_rcv_pkt(joycon_ctxt_t *jc) +{ + if (!jc->detected) return; u32 len = uart_recv(jc->uart, (u8 *)jc->buf, 0x100); + if (len < 8) + return; - // Check valid size and uart reply magic. - if (len > 7 && !memcmp(jc->buf, "\x19\x81\x03", 3)) + // For Joycon, check uart reply magic. + jc_wired_hdr_t *jc_pkt = (jc_wired_hdr_t *)jc->buf; + if (!jc->sio_mode && !memcmp(jc_pkt->uart_hdr.magic, "\x19\x81\x03", 3)) { - jc_wired_hdr_t *pkt = (jc_wired_hdr_t *)(jc->buf); + _jc_uart_pkt_parse(jc, jc_pkt, jc_pkt->uart_hdr.total_size_lsb + sizeof(jc_uart_hdr_t)); - jc_uart_pkt_parse(jc, jc->buf, pkt->uart_hdr.total_size_lsb + sizeof(jc_uart_hdr_t)); + return; + } + + // For Sio, check uart output report and command ack. + jc_sio_in_rpt_t *sio_pkt = (jc_sio_in_rpt_t *)(jc->buf); + if (jc->sio_mode && sio_pkt->cmd == JC_SIO_INPUT_RPT && (sio_pkt->ack & JC_SIO_CMD_ACK) == JC_SIO_CMD_ACK) + { + _jc_sio_uart_pkt_parse(jc, sio_pkt, sio_pkt->payload_size + sizeof(jc_sio_in_rpt_t)); + + return; } } -static bool jc_send_init_rumble(joycon_ctxt_t *jc) +static bool _jc_send_init_rumble(joycon_ctxt_t *jc) { // Send init rumble or request nx pad status report. if ((jc_r.connected && !jc_r.rumble_sent) || (jc_l.connected && !jc_l.rumble_sent)) { - gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO); - gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO); - - jc_send_hid_cmd(jc->uart, JC_HID_SUBCMD_SND_RUMBLE, NULL, 0); + _jc_send_hid_cmd(jc->uart, JC_HID_SUBCMD_SND_RUMBLE, NULL, 0); if (jc_l.connected) jc_l.rumble_sent = true; if (jc_r.connected) jc_r.rumble_sent = true; - if (jc->uart != UART_B) - gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO); - else - gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO); - return 1; } return 0; } -static void jc_req_nx_pad_status(joycon_ctxt_t *jc) +static void _jc_req_nx_pad_status(joycon_ctxt_t *jc) { - bool is_nxpad = !(jc->type & JC_ID_HORI); + if (!jc->detected) + return; + + bool is_nxpad = !(jc->type & JC_ID_HORI) && !jc->sio_mode; + + if (jc->last_status_req_time > get_tmr_ms() || !jc->connected) + return; if (is_nxpad) { - bool sent_rumble = jc_send_init_rumble(jc); + bool sent_rumble = _jc_send_init_rumble(jc); if (sent_rumble) return; } - if (jc->last_status_req_time > get_tmr_ms() || !jc->connected) - return; - - // Turn off Joy-Con detect. - if (jc->uart == UART_B) - gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO); - else - gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO); - if (is_nxpad) - joycon_send_raw(jc->uart, nx_pad_status, sizeof(nx_pad_status)); - else - joycon_send_raw(jc->uart, hori_pad_status, sizeof(hori_pad_status)); - - // Turn Joy-Con detect on. - if (jc->uart == UART_B) - gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO); + _joycon_send_raw(jc->uart, nx_pad_status, sizeof(nx_pad_status)); + else if (jc->sio_mode) + _joycon_send_raw(jc->uart, sio_pad_status, sizeof(sio_pad_status)); else - gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO); + _joycon_send_raw(jc->uart, hori_pad_status, sizeof(hori_pad_status)); jc->last_status_req_time = get_tmr_ms() + 15; } @@ -563,21 +868,23 @@ jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos) u8 retries; jc_bt_conn_t *bt_conn; - if (!jc_init_done) + if (!jc_init_done || jc_gamepad.sio_mode) return NULL; bt_conn = &jc_gamepad.bt_conn_l; memset(bt_conn->host_mac, 0, 6); - memset(bt_conn->ltk, 0, 16); + memset(bt_conn->ltk, 0, 16); bt_conn = &jc_gamepad.bt_conn_r; memset(bt_conn->host_mac, 0, 6); - memset(bt_conn->ltk, 0, 16); + memset(bt_conn->ltk, 0, 16); + + _jc_conn_check(); while (jc_l.last_status_req_time > get_tmr_ms()) { - jc_rcv_pkt(&jc_r); - jc_rcv_pkt(&jc_l); + _jc_rcv_pkt(&jc_r); + _jc_rcv_pkt(&jc_l); } jc_hid_in_spi_read_t subcmd_data_l; @@ -588,13 +895,13 @@ jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos) subcmd_data_r.addr = 0x2000; subcmd_data_r.size = 0x1A; - // Turn off Joy-Con detect. - gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO); - gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO); - bool jc_r_found = jc_r.connected ? false : true; bool jc_l_found = jc_l.connected ? false : true; + // Set mode to HW controlled RTS. + uart_set_mode(jc_l.uart, UART_AO_TX_HW_RX); + uart_set_mode(jc_r.uart, UART_AO_TX_HW_RX); + u32 total_retries = 10; retry: retries = 10; @@ -605,23 +912,26 @@ jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos) { if (!jc_l_found) { - jc_send_hid_cmd(jc_l.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_l, 5); + _jc_send_hid_cmd(jc_l.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_l, 5); jc_l.last_status_req_time = get_tmr_ms() + 15; } if (!jc_r_found) { - jc_send_hid_cmd(jc_r.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_r, 5); + _jc_send_hid_cmd(jc_r.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_r, 5); jc_r.last_status_req_time = get_tmr_ms() + 15; } retries--; } + // Wait for the first 36 bytes to arrive. + msleep(5); + if (!jc_l_found) { memset(jc_l.buf, 0, 0x100); - jc_rcv_pkt(&jc_l); + _jc_rcv_pkt(&jc_l); bool is_hos = false; if (_jc_validate_pairing_info(&jc_l.buf[SPI_READ_OFFSET], &is_hos)) @@ -641,7 +951,7 @@ jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos) if (!jc_r_found) { memset(jc_r.buf, 0, 0x100); - jc_rcv_pkt(&jc_r); + _jc_rcv_pkt(&jc_r); bool is_hos = false; if (_jc_validate_pairing_info(&jc_r.buf[SPI_READ_OFFSET], &is_hos)) @@ -674,255 +984,285 @@ jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos) { bt_conn = &jc_gamepad.bt_conn_l; memset(bt_conn->host_mac, 0, 6); - memset(bt_conn->ltk, 0, 16); + memset(bt_conn->ltk, 0, 16); } if (!jc_r_found) { bt_conn = &jc_gamepad.bt_conn_r; memset(bt_conn->host_mac, 0, 6); - memset(bt_conn->ltk, 0, 16); + memset(bt_conn->ltk, 0, 16); } } - // Turn Joy-Con detect on. - gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO); - gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO); + // Restore mode to manual RTS. + uart_set_mode(jc_l.uart, UART_AO_TX_MN_RX); + uart_set_mode(jc_r.uart, UART_AO_TX_MN_RX); return &jc_gamepad; } -void jc_deinit() +static void _jc_init_conn(joycon_ctxt_t *jc) { - // Disable power. - jc_power_supply(UART_B, false); - jc_power_supply(UART_C, false); - - // Turn off Joy-Con detect. - gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO); - gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO); - - // Send sleep command. - u8 data = HCI_STATE_SLEEP; - - if (jc_r.connected && !(jc_r.type & JC_ID_HORI)) - { - jc_send_hid_cmd(UART_B, JC_HID_SUBCMD_HCI_STATE, &data, 1); - jc_rcv_pkt(&jc_r); - } - if (jc_l.connected && !(jc_l.type & JC_ID_HORI)) - { - jc_send_hid_cmd(UART_C, JC_HID_SUBCMD_HCI_STATE, &data, 1); - jc_rcv_pkt(&jc_l); - } - - // Disable UART B and C clocks. - clock_disable_uart(UART_B); - clock_disable_uart(UART_C); -} + if (!jc->detected) + return; -static void jc_init_conn(joycon_ctxt_t *jc) -{ if (((u32)get_tmr_ms() - jc->last_received_time) > 1000) { - jc_power_supply(jc->uart, true); + _jc_power_supply(jc->uart, true); - // Turn off Joy-Con detect. + // Mask out buttons and set connected to false. if (jc->uart == UART_B) { jc_gamepad.buttons &= ~JC_BTN_MASK_R; jc_gamepad.conn_r = false; - gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO); } else { jc_gamepad.buttons &= ~JC_BTN_MASK_L; jc_gamepad.conn_l = false; - gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO); } - uart_init(jc->uart, 1000000); - uart_invert(jc->uart, true, UART_INVERT_TXD); - uart_set_IIR(jc->uart); - - joycon_send_raw(jc->uart, init_jc, 4); - joycon_send_raw(jc->uart, init_handshake, sizeof(init_handshake)); - - msleep(5); - jc_rcv_pkt(jc); - - joycon_send_raw(jc->uart, init_get_info, sizeof(init_get_info)); - msleep(5); - jc_rcv_pkt(jc); + // Initialize uart to 1 megabaud and manual RTS. + uart_init(jc->uart, 1000000, UART_AO_TX_MN_RX); - if (!(jc->type & JC_ID_HORI)) + if (!jc->sio_mode) { - joycon_send_raw(jc->uart, init_finalize, sizeof(init_finalize)); - msleep(5); - jc_rcv_pkt(jc); - } - - // Turn Joy-Con detect on. - if (jc->uart == UART_B) - gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO); - else - gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO); + jc->state = JC_STATE_START; - jc->last_received_time = get_tmr_ms(); - - if (jc->connected) - jc_power_supply(jc->uart, false); - } -} + // Set TX and RTS inversion for Joycon. + uart_invert(jc->uart, true, UART_INVERT_TXD | UART_INVERT_RTS); -static void jc_conn_check() -{ - // Check if a Joy-Con was disconnected. - if (gpio_read(GPIO_PORT_E, GPIO_PIN_6)) - { - jc_power_supply(UART_C, false); + // Wake up the controller. + _joycon_send_raw(jc->uart, init_wake, sizeof(init_wake)); + _jc_rcv_pkt(jc); // Clear RX FIFO. - hid_pkt_inc = 0; + // Do a handshake. + u32 retries = 10; + while (retries && jc->state != JC_STATE_HANDSHAKED) + { + _joycon_send_raw(jc->uart, init_handshake, sizeof(init_handshake)); + msleep(5); + _jc_rcv_pkt(jc); + retries--; + } - jc_l.connected = false; - jc_l.rumble_sent = false; + if (jc->state != JC_STATE_HANDSHAKED) + goto out; - jc_gamepad.buttons &= ~JC_BTN_MASK_L; - jc_gamepad.conn_l = false; + // Get info about the controller. + _joycon_send_raw(jc->uart, init_get_info, sizeof(init_get_info)); + msleep(2); + _jc_rcv_pkt(jc); - jc_gamepad.batt_info_l = 0; - jc_gamepad.bt_conn_l.type = 0; - } + if (!(jc->type & JC_ID_HORI)) + { + // Request 3 megabaud change. + _joycon_send_raw(jc->uart, init_switch_brate, sizeof(init_switch_brate)); + msleep(2); + _jc_rcv_pkt(jc); + + if (jc->state == JC_STATE_BRATE_CHANGED) + { + // Reinitialize uart to 3 megabaud and manual RTS. + uart_init(jc->uart, 3000000, UART_AO_TX_MN_RX); + uart_invert(jc->uart, true, UART_INVERT_TXD | UART_INVERT_RTS); + + // Disconnect HID. + retries = 10; + while (retries && jc->state != JC_STATE_BRATE_OK) + { + _joycon_send_raw(jc->uart, init_hid_disconnect, sizeof(init_hid_disconnect)); + msleep(5); + _jc_rcv_pkt(jc); + retries--; + } + + if (jc->state != JC_STATE_BRATE_OK) + goto out; + } + + // Create HID connection with the new rate. + _joycon_send_raw(jc->uart, init_hid_connect, sizeof(init_hid_connect)); + msleep(2); + _jc_rcv_pkt(jc); + + // Set hid packet rate. + _joycon_send_raw(jc->uart, init_set_hid_rate, sizeof(init_set_hid_rate)); + msleep(2); + _jc_rcv_pkt(jc); + } + else // Hori. Unset RTS inversion. + uart_invert(jc->uart, false, UART_INVERT_RTS); + } + else + { + // Set Sio NPOR low to configure BOOT0 mode. + gpio_write(GPIO_PORT_CC, GPIO_PIN_5, GPIO_LOW); + usleep(300); + gpio_write(GPIO_PORT_T, GPIO_PIN_0, GPIO_LOW); + gpio_write(GPIO_PORT_CC, GPIO_PIN_5, GPIO_HIGH); + msleep(100); + + // Clear RX FIFO. + _jc_rcv_pkt(jc); + + // Initialize the controller. + u32 retries = 10; + while (!jc->connected) + { + _joycon_send_raw(jc->uart, sio_init, sizeof(sio_init)); + msleep(5); + _jc_rcv_pkt(jc); + retries--; + } - if (gpio_read(GPIO_PORT_H, GPIO_PIN_6)) - { - jc_power_supply(UART_B, false); + if (!jc->connected) + goto out; - hid_pkt_inc = 0; + // Set output report version. + _joycon_send_raw(jc->uart, sio_set_rpt_version, sizeof(sio_set_rpt_version)); + msleep(5); + _jc_rcv_pkt(jc); + } - jc_r.connected = false; - jc_r.rumble_sent = false; + // Initialization done. + jc->state = JC_STATE_INIT_DONE; - jc_gamepad.buttons &= ~JC_BTN_MASK_R; - jc_gamepad.conn_r = false; +out: + jc->last_received_time = get_tmr_ms(); - jc_gamepad.batt_info_r = 0; - jc_gamepad.bt_conn_r.type = 0; + if (!jc->sio_mode && jc->connected && !(jc->type & JC_ID_HORI)) + _jc_power_supply(jc->uart, false); } } -void jc_power_supply(u8 uart, bool enable) +void jc_init_hw() { - if (enable) - { - if (regulator_5v_get_dev_enabled(1 << uart)) - return; + jc_l.uart = UART_C; + jc_r.uart = UART_B; - regulator_5v_enable(1 << uart); + jc_l.sio_mode = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG; + jc_gamepad.sio_mode = jc_l.sio_mode; - if (jc_init_done) - { - if (uart == UART_C) - gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_HIGH); - else - gpio_write(GPIO_PORT_K, GPIO_PIN_3, GPIO_HIGH); - return; - } +#if !defined(DEBUG_UART_PORT) || !(DEBUG_UART_PORT) + _jc_power_supply(UART_C, true); + _jc_power_supply(UART_B, true); - if (uart == UART_C) - { - // Joy-Con(L) Charge Detect. - PINMUX_AUX(PINMUX_AUX_SPDIF_IN) = PINMUX_PULL_DOWN | 1; - gpio_config(GPIO_PORT_CC, GPIO_PIN_3, GPIO_MODE_GPIO); - gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_3, GPIO_OUTPUT_ENABLE); - gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_HIGH); - } - else - { - // Joy-Con(R) Charge Detect. - PINMUX_AUX(PINMUX_AUX_GPIO_PK3) = PINMUX_DRIVE_4X | PINMUX_PULL_DOWN | 2; - gpio_config(GPIO_PORT_K, GPIO_PIN_3, GPIO_MODE_GPIO); - gpio_output_enable(GPIO_PORT_K, GPIO_PIN_3, GPIO_OUTPUT_ENABLE); - gpio_write(GPIO_PORT_K, GPIO_PIN_3, GPIO_HIGH); - } - } - else + // Sio Initialization. + if (jc_gamepad.sio_mode) { - if (!regulator_5v_get_dev_enabled(1 << uart)) - return; + // Enable 4 MHz clock to Sio. + clock_enable_extperiph2(); + PINMUX_AUX(PINMUX_AUX_TOUCH_CLK) = PINMUX_PULL_DOWN; - regulator_5v_disable(1 << uart); + // Configure Sio HOME BUTTON. + PINMUX_AUX(PINMUX_AUX_LCD_GPIO1) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 1; + gpio_direction_input(GPIO_PORT_V, GPIO_PIN_3); - if (uart == UART_C) - gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_LOW); - else - gpio_write(GPIO_PORT_K, GPIO_PIN_3, GPIO_LOW); - } -} + // Configure Sio IRQ + PINMUX_AUX(PINMUX_AUX_GPIO_PE7) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP; + gpio_direction_input(GPIO_PORT_E, GPIO_PIN_7); -void jc_init_hw() -{ - jc_l.uart = UART_C; - jc_r.uart = UART_B; + // Configure Sio NRST and BOOT0. + PINMUX_AUX(PINMUX_AUX_CAM1_STROBE) = PINMUX_PULL_DOWN | 1; + PINMUX_AUX(PINMUX_AUX_CAM2_PWDN) = PINMUX_PULL_DOWN | 1; -#if !defined(DEBUG_UART_PORT) || !(DEBUG_UART_PORT) - if (fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG) - return; + // Set BOOT0 to flash mode. (output high is sram mode). + gpio_direction_output(GPIO_PORT_T, GPIO_PIN_0, GPIO_LOW); - jc_power_supply(UART_C, true); - jc_power_supply(UART_B, true); + // NRST to pull down. + gpio_direction_input(GPIO_PORT_T, GPIO_PIN_1); - // Joy-Con (R) IsAttached. - PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; - gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO); + // Configure Sio NPOR. + PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN1) = PINMUX_IO_HV | PINMUX_LPDR | 1; + gpio_direction_output(GPIO_PORT_CC, GPIO_PIN_5, GPIO_LOW); + } - // Joy-Con (L) IsAttached. +#if 0 // Already set by hw init. + // Set Joy-Con IsAttached pinmux. Shared with UARTB/UARTC TX. PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; + PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; + + // Set Joy-Con IsAttached mode. Shared with UARTB/UARTC TX. gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO); + gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO); +#endif // Configure pinmuxing for UART B and C. - pinmux_config_uart(UART_B); + if (!jc_gamepad.sio_mode) + pinmux_config_uart(UART_B); pinmux_config_uart(UART_C); // Ease the stress to APB. bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL); // Enable UART B and C clocks. - clock_enable_uart(UART_B); + if (!jc_gamepad.sio_mode) + clock_enable_uart(UART_B); clock_enable_uart(UART_C); // Restore OC. bpmp_clk_rate_set(prev_fid); - // Turn Joy-Con detect on. - gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO); - gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO); - jc_init_done = true; #endif } +void jc_deinit() +{ + if (!jc_init_done) + return; + + // Disable power. + _jc_power_supply(UART_B, false); + _jc_power_supply(UART_C, false); + + if (!jc_gamepad.sio_mode) + { + // Send sleep command. + u8 data = HCI_STATE_SLEEP; + if (jc_r.connected && !(jc_r.type & JC_ID_HORI)) + { + _jc_send_hid_cmd(UART_B, JC_HID_SUBCMD_HCI_STATE, &data, 1); + _jc_rcv_pkt(&jc_r); + } + if (jc_l.connected && !(jc_l.type & JC_ID_HORI)) + { + _jc_send_hid_cmd(UART_C, JC_HID_SUBCMD_HCI_STATE, &data, 1); + _jc_rcv_pkt(&jc_l); + } + } + else + { + // Disable Sio NPOR. + gpio_write(GPIO_PORT_CC, GPIO_PIN_5, GPIO_LOW); + + // Disable 4 MHz clock to Sio. + clock_disable_extperiph2(); + } + + // Disable UART B and C clocks. + if (!jc_gamepad.sio_mode) + clock_disable_uart(UART_B); + clock_disable_uart(UART_C); +} + jc_gamepad_rpt_t *joycon_poll() { if (!jc_init_done) return NULL; - if (!gpio_read(GPIO_PORT_H, GPIO_PIN_6)) - jc_init_conn(&jc_r); - if (!gpio_read(GPIO_PORT_E, GPIO_PIN_6)) - jc_init_conn(&jc_l); + _jc_conn_check(); - if (!gpio_read(GPIO_PORT_H, GPIO_PIN_6)) - jc_req_nx_pad_status(&jc_r); - if (!gpio_read(GPIO_PORT_E, GPIO_PIN_6)) - jc_req_nx_pad_status(&jc_l); + _jc_init_conn(&jc_r); + _jc_init_conn(&jc_l); - if (!gpio_read(GPIO_PORT_H, GPIO_PIN_6)) - jc_rcv_pkt(&jc_r); - if (!gpio_read(GPIO_PORT_E, GPIO_PIN_6)) - jc_rcv_pkt(&jc_l); + _jc_req_nx_pad_status(&jc_r); + _jc_req_nx_pad_status(&jc_l); - jc_conn_check(); + _jc_rcv_pkt(&jc_r); + _jc_rcv_pkt(&jc_l); return &jc_gamepad; } diff --git a/bdk/input/joycon.h b/bdk/input/joycon.h index 932c8369..6fa0881e 100644 --- a/bdk/input/joycon.h +++ b/bdk/input/joycon.h @@ -83,13 +83,13 @@ typedef struct _jc_gamepad_rpt_t bool center_stick_r; bool conn_l; bool conn_r; - u8 batt_info_l; - u8 batt_info_r; + bool sio_mode; + u8 batt_info_l; // Also Sio Connected status. + u8 batt_info_r; // Also Sio IRQ. jc_bt_conn_t bt_conn_l; jc_bt_conn_t bt_conn_r; } jc_gamepad_rpt_t; -void jc_power_supply(u8 uart, bool enable); void jc_init_hw(); void jc_deinit(); jc_gamepad_rpt_t *joycon_poll(); diff --git a/bdk/input/touch.c b/bdk/input/touch.c index 4c498375..2825ebd2 100644 --- a/bdk/input/touch.c +++ b/bdk/input/touch.c @@ -2,7 +2,7 @@ * Touch driver for Nintendo Switch's STM FingerTip S (4CD60D) touch controller * * Copyright (c) 2018 langerhans - * Copyright (c) 2018-2020 CTCaer + * Copyright (c) 2018-2023 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, @@ -24,9 +24,9 @@ #include #include #include +#include #include #include -#include #include "touch.h" @@ -35,12 +35,12 @@ static touch_panel_info_t _panels[] = { - { 0, 1, 1, 1, "NISSHA NFT-K12D" }, - { 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, "Samsung BH2109" }, - { -1, 1, 0, 1, "GiS VA 6.2\"" } + { 0, 1, 1, 1, "NISSHA NFT-K12D" },// 0. + { 1, 0, 1, 1, "GiS GGM6 B2X" },// 1. + { 2, 0, 0, 0, "NISSHA NBF-K9A" },// 3. + { 3, 1, 0, 0, "GiS 5.5\"" },// 4. + { 4, 0, 0, 1, "Samsung BH2109" },// 5? + { -1, 1, 0, 1, "GiS VA 6.2\"" } // 2. }; static int touch_command(u8 cmd, u8 *buf, u8 size) @@ -87,19 +87,19 @@ static int touch_wait_event(u8 event, u8 status, u32 timeout, u8 *buf) static void _touch_compensate_limits(touch_event *event, bool touching) { - event->x = MAX(event->x, EDGE_OFFSET); - event->x = MIN(event->x, X_REAL_MAX); + event->x = MAX(event->x, EDGE_OFFSET); + event->x = MIN(event->x, X_REAL_MAX); event->x -= EDGE_OFFSET; u32 x_adj = (1280 * 1000) / (X_REAL_MAX - EDGE_OFFSET); - event->x = ((u32)event->x * x_adj) / 1000; + event->x = ((u32)event->x * x_adj) / 1000; if (touching) { - event->y = MAX(event->y, EDGE_OFFSET); - event->y = MIN(event->y, Y_REAL_MAX); + event->y = MAX(event->y, EDGE_OFFSET); + event->y = MIN(event->y, Y_REAL_MAX); event->y -= EDGE_OFFSET; u32 y_adj = (720 * 1000) / (Y_REAL_MAX - EDGE_OFFSET); - event->y = ((u32)event->y * y_adj) / 1000; + event->y = ((u32)event->y * y_adj) / 1000; } } @@ -115,6 +115,7 @@ static void _touch_process_contact_event(touch_event *event, bool touching) event->z = event->raw[5] | (event->raw[6] << 8); event->z = event->z << 6; + u16 tmp = 0x40; if ((event->raw[7] & 0x3F) != 1 && (event->raw[7] & 0x3F) != 0x3F) tmp = event->raw[7] & 0x3F; @@ -245,7 +246,7 @@ int touch_get_fw_info(touch_fw_info_t *fw) res = touch_read_reg(cmd, 3, buf, 8); if (!res) { - fw->fw_id = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4]; + fw->fw_id = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4]; fw->ftb_ver = (buf[6] << 8) | buf[5]; } @@ -406,14 +407,7 @@ int touch_power_on() // Configure touchscreen VDD GPIO. PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1; - gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO); - 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. - // 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); + gpio_direction_output(GPIO_PORT_J, GPIO_PIN_7, GPIO_HIGH); // Configure Touscreen and GCAsic shared GPIO. PINMUX_AUX(PINMUX_AUX_CAM_I2C_SDA) = PINMUX_LPDR | PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 2; diff --git a/bdk/libs/fatfs/ff.c b/bdk/libs/fatfs/ff.c index 1d7e34b2..b61fa7d2 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,8 @@ #include "ff.h" /* Declarations of FatFs API */ #include "diskio.h" /* Declarations of device I/O functions */ +#include #include -#include "../../storage/nx_sd.h" #define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF); //#define EFSPRINTF(...) @@ -3274,7 +3274,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 +3284,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 +3317,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 +4061,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 +4709,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,13 +5873,13 @@ 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); if (stat & STA_NOINIT) return FR_NOT_READY; if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; - if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK || !sz_blk || sz_blk > 32768 || (sz_blk & (sz_blk - 1))) sz_blk = 1; /* Erase block to align data area */ + if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK || !sz_blk || sz_blk > 131072 || (sz_blk & (sz_blk - 1))) sz_blk = 2048; /* Erase block to align data area. 1MB minimum */ #if FF_MAX_SS != FF_MIN_SS /* Get sector size of the medium if variable sector size cfg. */ if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR; if (ss > FF_MAX_SS || ss < FF_MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR; @@ -5893,7 +5904,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 */ @@ -5904,7 +5915,7 @@ FRESULT f_mkfs ( } else { /* Create a single-partition in this function */ if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - b_vol = (opt & FM_SFD) ? 0 : 32768; /* Volume start sector. Align to 16MB */ + b_vol = (opt & FM_SFD) ? 0 : sz_blk; /* Volume start sector */ if (sz_vol < b_vol) LEAVE_MKFS(FR_MKFS_ABORTED); sz_vol -= b_vol; /* Volume size */ } @@ -5929,7 +5940,6 @@ FRESULT f_mkfs ( #if FF_FS_EXFAT if (fmt == FS_EXFAT) { /* Create an exFAT volume */ - LEAVE_MKFS(FR_NO_FILESYSTEM); // Muh frii bytes DWORD szb_bit, szb_case, sum, nb, cl; WCHAR ch, si; UINT j, st; @@ -6172,7 +6182,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 +6197,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 */ @@ -6212,13 +6228,35 @@ FRESULT f_mkfs ( mem_set(buf, 0, ss); st_dword(buf + FSI_LeadSig, 0x41615252); st_dword(buf + FSI_StrucSig, 0x61417272); - st_dword(buf + FSI_Free_Count, n_clst - 1); /* Number of free clusters */ - st_dword(buf + FSI_Nxt_Free, 2); /* Last allocated cluster# */ + if (opt & FM_PRF2) { + st_dword(buf + FSI_Free_Count, 0xFFFFFFFF); /* Invalidate free count */ + st_dword(buf + FSI_Nxt_Free, 0xFFFFFFFF); /* Invalidate last allocated cluster */ + } else { + st_dword(buf + FSI_Free_Count, n_clst - 1); /* Number of free clusters */ + st_dword(buf + FSI_Nxt_Free, 2); /* Last allocated cluster# */ + } st_word(buf + BS_55AA, 0xAA55); disk_write(pdrv, buf, b_vol + 7, 1); /* Write backup FSINFO (VBR + 7) */ 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); + st_dword(buf + 0, 0x32465250); /* Magic PRF2 */ + st_dword(buf + 4, 0x45464153); /* Magic SAFE */ + buf[16] = 0x64; /* Record type */ + st_dword(buf + 32, 0x03); /* Unknown. SYSTEM: 0x3F00. USER: 0x03. Volatile. */ + if (sz_vol < 0x1000000) { + st_dword(buf + 36, 21 + 1); /* 22 Entries. */ + st_dword(buf + 508, 0x90BB2F39); /* Sector CRC32 */ + } else { + st_dword(buf + 36, 21 + 2); /* 23 Entries. */ + st_dword(buf + 508, 0x5EA8AFC8); /* Sector CRC32 */ + } + 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 +6302,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 */ @@ -6373,81 +6411,7 @@ FRESULT f_fdisk ( #endif /* FF_MULTI_PARTITION */ #endif /* FF_USE_MKFS && !FF_FS_READONLY */ -extern sdmmc_storage_t sd_storage; - -FRESULT f_fdisk_mod ( - BYTE pdrv, /* Physical drive number */ - const DWORD* szt, /* Pointer to the size table for each partitions */ - void* work -) -{ - UINT i, n, sz_cyl, tot_cyl, e_cyl; - BYTE s_hd, e_hd, *p, *buf = (BYTE*)work; - DSTATUS stat; - DWORD sz_disk, p_sect, b_cyl, b_sect; - FRESULT res; - - stat = disk_initialize(pdrv); - if (stat & STA_NOINIT) return FR_NOT_READY; - if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; - sz_disk = sd_storage.csd.capacity; - if (!buf) return FR_NOT_ENOUGH_CORE; - - /* Determine the CHS without any consideration of the drive geometry */ - for (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ; - if (n == 256) n--; - e_hd = (BYTE)(n - 1); - sz_cyl = 63 * n; - tot_cyl = sz_disk / sz_cyl; - - /* Create partition table */ - mem_set(buf, 0, 0x10000); - p = buf + MBR_Table; b_cyl = 0, b_sect = 0; - for (i = 0; i < 4; i++, p += SZ_PTE) { - p_sect = szt[i]; /* Number of sectors */ - - if (p_sect == 0) - continue; - - if (i == 0) { /* Exclude first 16MiB of sd */ - s_hd = 1; - b_sect += 32768; p_sect -= 32768; - } - else - s_hd = 0; - - b_cyl = b_sect / sz_cyl; - e_cyl = ((b_sect + p_sect) / sz_cyl) - 1; /* End cylinder */ - - if (e_cyl >= tot_cyl) - LEAVE_MKFS(FR_INVALID_PARAMETER); - - - /* Set partition table */ - p[1] = s_hd; /* Start head */ - p[2] = (BYTE)(((b_cyl >> 2) & 0xC0) | 1); /* Start sector */ - p[3] = (BYTE)b_cyl; /* Start cylinder */ - p[4] = 0x07; /* System type (temporary setting) */ - p[5] = e_hd; /* End head */ - p[6] = (BYTE)(((e_cyl >> 2) & 0xC0) | 63); /* End sector */ - p[7] = (BYTE)e_cyl; /* End cylinder */ - st_dword(p + 8, b_sect); /* Start sector in LBA */ - st_dword(p + 12, p_sect); /* Number of sectors */ - /* Next partition */ - - for (u32 cursect = 0; cursect < 512; cursect++){ - disk_write(pdrv, buf + 0x4000, b_sect + (64 * cursect), 64); - } - - b_sect += p_sect; - } - st_word(p, 0xAA55); /* MBR signature (always at offset 510) */ - - /* Write it to the MBR */ - res = (disk_write(pdrv, buf, 0, 1) == RES_OK && disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR; - LEAVE_MKFS(res); -} #if FF_USE_STRFUNC @@ -6782,6 +6746,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 +6774,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 29b1ba23..3a6c4238 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,6 @@ 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_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 +366,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 b7fea652..8b0256eb 100644 --- a/bdk/libs/nx_savedata/save.c +++ b/bdk/libs/nx_savedata/save.c @@ -38,7 +38,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include +#include #include #include diff --git a/bdk/mem/heap.c b/bdk/mem/heap.c index d249140b..9c5b4065 100644 --- a/bdk/mem/heap.c +++ b/bdk/mem/heap.c @@ -19,33 +19,44 @@ #include "heap.h" #include -static void _heap_create(heap_t *heap, u32 start) +heap_t _heap; + +static void _heap_create(void *start) { - heap->start = start; - heap->first = NULL; + _heap.start = start; + _heap.first = NULL; + _heap.last = NULL; } // Node info is before node address. -static u32 _heap_alloc(heap_t *heap, u32 size) +static void *_heap_alloc(u32 size) { hnode_t *node, *new_node; // Align to cache line size. size = ALIGN(size, sizeof(hnode_t)); - if (!heap->first) + // First allocation. + if (!_heap.first) { - node = (hnode_t *)heap->start; + node = (hnode_t *)_heap.start; node->used = 1; node->size = size; node->prev = NULL; node->next = NULL; - heap->first = node; - return (u32)node + sizeof(hnode_t); + _heap.first = node; + _heap.last = node; + + return (void *)node + sizeof(hnode_t); } - node = heap->first; +#ifdef BDK_MALLOC_NO_DEFRAG + // Get the last allocated block. + node = _heap.last; +#else + // Get first block and find the first available one. + node = _heap.first; while (true) { // Check if there's available unused node. @@ -53,7 +64,7 @@ static u32 _heap_alloc(heap_t *heap, u32 size) { // Size and offset of the new unused node. u32 new_size = node->size - size; - new_node = (hnode_t *)((u32)node + sizeof(hnode_t) + size); + new_node = (hnode_t *)((void *)node + sizeof(hnode_t) + size); // If there's aligned unused space from the old node, // create a new one and set the leftover size. @@ -76,7 +87,7 @@ static u32 _heap_alloc(heap_t *heap, u32 size) node->size = size; node->used = 1; - return (u32)node + sizeof(hnode_t); + return (void *)node + sizeof(hnode_t); } // No unused node found, try the next one. @@ -85,23 +96,29 @@ static u32 _heap_alloc(heap_t *heap, u32 size) else break; } +#endif // No unused node found, create a new one. - new_node = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size); + new_node = (hnode_t *)((void *)node + sizeof(hnode_t) + node->size); new_node->used = 1; new_node->size = size; new_node->prev = node; new_node->next = NULL; + node->next = new_node; + _heap.last = new_node; - return (u32)new_node + sizeof(hnode_t); + return (void *)new_node + sizeof(hnode_t); } -static void _heap_free(heap_t *heap, u32 addr) +static void _heap_free(void *addr) { hnode_t *node = (hnode_t *)(addr - sizeof(hnode_t)); node->used = 0; - node = heap->first; + node = _heap.first; + +#ifndef BDK_MALLOC_NO_DEFRAG + // Do simple defragmentation on next blocks. while (node) { if (!node->used) @@ -117,36 +134,35 @@ static void _heap_free(heap_t *heap, u32 addr) } node = node->next; } +#endif } -heap_t _heap; - -void heap_init(u32 base) +void heap_init(void *base) { - _heap_create(&_heap, base); + _heap_create(base); } -void heap_copy(heap_t *heap) +void heap_set(heap_t *heap) { memcpy(&_heap, heap, sizeof(heap_t)); } void *malloc(u32 size) { - return (void *)_heap_alloc(&_heap, size); + return _heap_alloc(size); } void *calloc(u32 num, u32 size) { - void *res = (void *)_heap_alloc(&_heap, num * size); + void *res = (void *)_heap_alloc(num * size); memset(res, 0, ALIGN(num * size, sizeof(hnode_t))); // Clear the aligned size. return res; } void free(void *buf) { - if ((u32)buf >= _heap.start) - _heap_free(&_heap, (u32)buf); + if (buf >= _heap.start) + _heap_free(buf); } void heap_monitor(heap_monitor_t *mon, bool print_node_stats) @@ -158,7 +174,10 @@ void heap_monitor(heap_monitor_t *mon, bool print_node_stats) while (true) { if (node->used) + { + mon->nodes_used++; mon->used += node->size + sizeof(hnode_t); + } else mon->total += node->size + sizeof(hnode_t); @@ -174,4 +193,5 @@ void heap_monitor(heap_monitor_t *mon, bool print_node_stats) break; } mon->total += mon->used; + mon->nodes_total = count; } diff --git a/bdk/mem/heap.h b/bdk/mem/heap.h index 811f13d3..91501042 100644 --- a/bdk/mem/heap.h +++ b/bdk/mem/heap.h @@ -31,18 +31,21 @@ typedef struct _hnode typedef struct _heap { - u32 start; + void *start; hnode_t *first; + hnode_t *last; } heap_t; typedef struct { - u32 total; - u32 used; + u32 total; + u32 used; + u32 nodes_total; + u32 nodes_used; } heap_monitor_t; -void heap_init(u32 base); -void heap_copy(heap_t *heap); +void heap_init(void *base); +void heap_set(heap_t *heap); void *malloc(u32 size); void *calloc(u32 num, u32 size); void free(void *buf); diff --git a/bdk/mem/mc.c b/bdk/mem/mc.c index d577bd73..d8949bc6 100644 --- a/bdk/mem/mc.c +++ b/bdk/mem/mc.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, @@ -17,11 +17,9 @@ #include #include +#include #include #include -#include - -//#define CONFIG_ENABLE_AHB_REDIRECT void mc_config_tsec_carveout(u32 bom, u32 size1mb, bool lock) { @@ -125,13 +123,13 @@ void mc_config_carveout() MC(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F; } -void mc_enable_ahb_redirect(bool full_aperture) +void mc_enable_ahb_redirect() { // 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) = full_aperture ? DRAM_START : 0x4003F000; + CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) |= BIT(19); + //MC(MC_IRAM_REG_CTRL) &= ~BIT(0); + MC(MC_IRAM_BOM) = IRAM_BASE; + MC(MC_IRAM_TOM) = DRAM_START; // Default is only IRAM: 0x4003F000. } void mc_disable_ahb_redirect() @@ -139,15 +137,27 @@ void mc_disable_ahb_redirect() MC(MC_IRAM_BOM) = 0xFFFFF000; MC(MC_IRAM_TOM) = 0; // Disable IRAM_CFG_WRITE_ACCESS (sticky). - //MC(MC_IRAM_REG_CTRL) = MC(MC_IRAM_REG_CTRL) & 0xFFFFFFFE | 1; + //MC(MC_IRAM_REG_CTRL) |= BIT(0); // Disable ARC_CLK_OVR_ON. - CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= 0xFFF7FFFF; + CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) &= ~BIT(19); +} + +bool mc_client_has_access(void *address) +{ + // Check if address is in DRAM or if arbitration for IRAM is enabled. + if ((u32)address >= DRAM_START) + return true; // Access by default. + else if ((u32)address >= IRAM_BASE && MC(MC_IRAM_BOM) == IRAM_BASE) + return true; // Access by AHB arbitration. + + // No access to address space. + return false; } void mc_enable() { // Reset EMC source to PLLP. - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | 0x40000000; + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | (2 << 29); // Enable memory clocks. CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MEM); @@ -156,7 +166,7 @@ void mc_enable() CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM); usleep(5); -#ifdef CONFIG_ENABLE_AHB_REDIRECT +#ifdef BDK_MC_ENABLE_AHB_REDIRECT mc_enable_ahb_redirect(); #else mc_disable_ahb_redirect(); diff --git a/bdk/mem/mc.h b/bdk/mem/mc.h index d873c7d1..300bbfdc 100644 --- a/bdk/mem/mc.h +++ b/bdk/mem/mc.h @@ -23,8 +23,9 @@ 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(bool full_aperture); +void mc_enable_ahb_redirect(); void mc_disable_ahb_redirect(); +bool mc_client_has_access(void *address); void mc_enable(); #endif diff --git a/bdk/mem/mc_t210.h b/bdk/mem/mc_t210.h index a7a98778..ed968523 100644 --- a/bdk/mem/mc_t210.h +++ b/bdk/mem/mc_t210.h @@ -464,11 +464,111 @@ #define MC_UNTRANSLATED_REGION_CHECK 0x948 #define MC_DA_CONFIG0 0x9dc +/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS0 */ +#define SEC_CARVEOUT_CA0_R_PTCR BIT(0) +#define SEC_CARVEOUT_CA0_R_DISPLAY0A BIT(1) +#define SEC_CARVEOUT_CA0_R_DISPLAY0AB BIT(2) +#define SEC_CARVEOUT_CA0_R_DISPLAY0B BIT(3) +#define SEC_CARVEOUT_CA0_R_DISPLAY0BB BIT(4) +#define SEC_CARVEOUT_CA0_R_DISPLAY0C BIT(5) +#define SEC_CARVEOUT_CA0_R_DISPLAY0CB BIT(6) +#define SEC_CARVEOUT_CA0_R_AFI BIT(14) +#define SEC_CARVEOUT_CA0_R_BPMP_C BIT(15) +#define SEC_CARVEOUT_CA0_R_DISPLAYHC BIT(16) +#define SEC_CARVEOUT_CA0_R_DISPLAYHCB BIT(17) +#define SEC_CARVEOUT_CA0_R_HDA BIT(21) +#define SEC_CARVEOUT_CA0_R_HOST1XDMA BIT(22) +#define SEC_CARVEOUT_CA0_R_HOST1X BIT(23) +#define SEC_CARVEOUT_CA0_R_NVENC BIT(28) +#define SEC_CARVEOUT_CA0_R_PPCSAHBDMA BIT(29) +#define SEC_CARVEOUT_CA0_R_PPCSAHBSLV BIT(30) +#define SEC_CARVEOUT_CA0_R_SATAR BIT(31) + +/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS1 */ +#define SEC_CARVEOUT_CA1_R_VDEBSEV BIT(2) +#define SEC_CARVEOUT_CA1_R_VDEMBE BIT(3) +#define SEC_CARVEOUT_CA1_R_VDEMCE BIT(4) +#define SEC_CARVEOUT_CA1_R_VDETPE BIT(5) +#define SEC_CARVEOUT_CA1_R_CCPLEXLP_C BIT(6) +#define SEC_CARVEOUT_CA1_R_CCPLEX_C BIT(7) +#define SEC_CARVEOUT_CA1_W_NVENC BIT(11) +#define SEC_CARVEOUT_CA1_W_AFI BIT(17) +#define SEC_CARVEOUT_CA1_W_BPMP_C BIT(18) +#define SEC_CARVEOUT_CA1_W_HDA BIT(21) +#define SEC_CARVEOUT_CA1_W_HOST1X BIT(22) +#define SEC_CARVEOUT_CA1_W_CCPLEXLP_C BIT(24) +#define SEC_CARVEOUT_CA1_W_CCPLEX_C BIT(25) +#define SEC_CARVEOUT_CA1_W_PPCSAHBDMA BIT(27) +#define SEC_CARVEOUT_CA1_W_PPCSAHBSLV BIT(28) +#define SEC_CARVEOUT_CA1_W_SATA BIT(29) +#define SEC_CARVEOUT_CA1_W_VDEBSEV BIT(30) +#define SEC_CARVEOUT_CA1_W_VDEDBG BIT(31) + +/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS2 */ +#define SEC_CARVEOUT_CA2_W_VDEMBE BIT(0) +#define SEC_CARVEOUT_CA2_W_VDETPM BIT(1) +#define SEC_CARVEOUT_CA2_R_ISPRA BIT(4) +#define SEC_CARVEOUT_CA2_W_ISPWA BIT(6) +#define SEC_CARVEOUT_CA2_W_ISPWB BIT(7) +#define SEC_CARVEOUT_CA2_R_XUSB_HOST BIT(10) +#define SEC_CARVEOUT_CA2_W_XUSB_HOST BIT(11) +#define SEC_CARVEOUT_CA2_R_XUSB_DEV BIT(12) +#define SEC_CARVEOUT_CA2_W_XUSB_DEV BIT(13) +#define SEC_CARVEOUT_CA2_R_SE2 BIT(14) +#define SEC_CARVEOUT_CA2_W_SE2 BIT(16) +#define SEC_CARVEOUT_CA2_R_TSEC BIT(20) +#define SEC_CARVEOUT_CA2_W_TSEC BIT(21) +#define SEC_CARVEOUT_CA2_R_ADSP_SC BIT(22) +#define SEC_CARVEOUT_CA2_W_ADSP_SC BIT(23) +#define SEC_CARVEOUT_CA2_R_GPU BIT(24) +#define SEC_CARVEOUT_CA2_W_GPU BIT(25) +#define SEC_CARVEOUT_CA2_R_DISPLAYT BIT(26) + +/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS3 */ +#define SEC_CARVEOUT_CA3_R_SDMMCA BIT(0) +#define SEC_CARVEOUT_CA3_R_SDMMCAA BIT(1) +#define SEC_CARVEOUT_CA3_R_SDMMC BIT(2) +#define SEC_CARVEOUT_CA3_R_SDMMCAB BIT(3) +#define SEC_CARVEOUT_CA3_W_SDMMCA BIT(4) +#define SEC_CARVEOUT_CA3_W_SDMMCAA BIT(5) +#define SEC_CARVEOUT_CA3_W_SDMMC BIT(6) +#define SEC_CARVEOUT_CA3_W_SDMMCAB BIT(7) +#define SEC_CARVEOUT_CA3_R_VIC BIT(12) +#define SEC_CARVEOUT_CA3_W_VIC BIT(13) +#define SEC_CARVEOUT_CA3_W_VIW BIT(18) +#define SEC_CARVEOUT_CA3_R_DISPLAYD BIT(19) +#define SEC_CARVEOUT_CA3_R_NVDEC BIT(24) +#define SEC_CARVEOUT_CA3_W_NVDEC BIT(25) +#define SEC_CARVEOUT_CA3_R_APE BIT(26) +#define SEC_CARVEOUT_CA3_W_APE BIT(27) +#define SEC_CARVEOUT_CA3_R_NVJPG BIT(30) +#define SEC_CARVEOUT_CA3_W_NVJPG BIT(31) + +/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS4 */ +#define SEC_CARVEOUT_CA4_R_SE BIT(0) +#define SEC_CARVEOUT_CA4_W_SE BIT(1) +#define SEC_CARVEOUT_CA4_R_AXIAP BIT(2) +#define SEC_CARVEOUT_CA4_W_AXIAP BIT(3) +#define SEC_CARVEOUT_CA4_R_ETR BIT(4) +#define SEC_CARVEOUT_CA4_W_ETR BIT(5) +#define SEC_CARVEOUT_CA4_R_TSECB BIT(6) +#define SEC_CARVEOUT_CA4_W_TSECB BIT(7) +#define SEC_CARVEOUT_CA4_R_GPU2 BIT(8) +#define SEC_CARVEOUT_CA4_W_GPU2 BIT(9) + +// 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_ALL_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) @@ -479,30 +579,31 @@ #define SEC_CARVEOUT_CFG_UNTRANSLATED_ONLY (1 << ADDRESS_TYPE_SHIFT) #define READ_ACCESS_LEVEL_SHIFT 3 -#define SEC_CARVEOUT_CFG_RD_ALL (1 << READ_ACCESS_LEVEL_SHIFT) -#define SEC_CARVEOUT_CFG_RD_UNK (2 << READ_ACCESS_LEVEL_SHIFT) +#define SEC_CARVEOUT_CFG_RD_NS (1 << READ_ACCESS_LEVEL_SHIFT) +#define SEC_CARVEOUT_CFG_RD_SEC (2 << READ_ACCESS_LEVEL_SHIFT) #define SEC_CARVEOUT_CFG_RD_FALCON_LS (4 << READ_ACCESS_LEVEL_SHIFT) #define SEC_CARVEOUT_CFG_RD_FALCON_HS (8 << READ_ACCESS_LEVEL_SHIFT) #define WRITE_ACCESS_LEVEL_SHIFT 7 -#define SEC_CARVEOUT_CFG_WR_ALL (1 << WRITE_ACCESS_LEVEL_SHIFT) -#define SEC_CARVEOUT_CFG_WR_UNK (2 << WRITE_ACCESS_LEVEL_SHIFT) +#define SEC_CARVEOUT_CFG_WR_NS (1 << WRITE_ACCESS_LEVEL_SHIFT) +#define SEC_CARVEOUT_CFG_WR_SEC (2 << WRITE_ACCESS_LEVEL_SHIFT) #define SEC_CARVEOUT_CFG_WR_FALCON_LS (4 << WRITE_ACCESS_LEVEL_SHIFT) #define SEC_CARVEOUT_CFG_WR_FALCON_HS (8 << WRITE_ACCESS_LEVEL_SHIFT) #define SEC_CARVEOUT_CFG_APERTURE_ID_MASK (3 << 11) +#define SEC_CARVEOUT_CFG_APERTURE_ID(id) ((id) << 11) #define DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT 14 -#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L0 (1 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT) -#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L1 (2 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT) -#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L2 (4 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT) -#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_L3 (8 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT) +#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_NS (1 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT) +#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_SEC (2 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT) +#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_FLCN_LS (4 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT) +#define SEC_CARVEOUT_CFG_DIS_RD_CHECK_FLCN_HS (8 << DISABLE_READ_CHECK_ACCESS_LEVEL_SHIFT) #define DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT 18 -#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L0 (1 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT) -#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L1 (2 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT) -#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L2 (4 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT) -#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L3 (8 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT) +#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_NS (1 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT) +#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_SEC (2 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT) +#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_FLCN_LS (4 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT) +#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_FLCN_HS (8 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT) #define SEC_CARVEOUT_CFG_SEND_CFG_TO_GPU BIT(22) diff --git a/bdk/mem/minerva.c b/bdk/mem/minerva.c index 2560dfe7..e4f11305 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,63 @@ void minerva_prep_boot_freq() minerva_change_freq(FREQ_800); } +void minerva_prep_boot_l4t(int oc_freq) +{ + if (!minerva_cfg) + return; + + mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg; + + // Add OC frequency. + if (oc_freq && mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600) + { + memcpy(&mtc_cfg->mtc_table[mtc_cfg->table_entries], + &mtc_cfg->mtc_table[mtc_cfg->table_entries - 1], + sizeof(emc_table_t)); + mtc_cfg->mtc_table[mtc_cfg->table_entries].rate_khz = oc_freq; + mtc_cfg->table_entries++; + } + + // 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_disabled = !(EMC(EMC_MRW3) & 0xC0); + if (fsp_opwr_disabled) + minerva_change_freq(FREQ_666); + minerva_change_freq(FREQ_800); + + // Trim table. + int entries = 0; + for (u32 i = 0; i < mtc_cfg->table_entries; i++) + { + // Copy freqs from 204 MHz to 800 MHz and 1600 MHz and above. + int rate = mtc_cfg->mtc_table[i].rate_khz; + if ((rate >= FREQ_204 && rate <= FREQ_800) || rate >= FREQ_1600) + { + memcpy(&mtc_cfg->mtc_table[entries], &mtc_cfg->mtc_table[i], sizeof(emc_table_t)); + entries++; + } + } + mtc_cfg->table_entries = entries; + + // Do not let other mtc ops. + mtc_cfg->init_done = 0; +} + void minerva_periodic_training() { if (!minerva_cfg) @@ -167,4 +225,22 @@ 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; +} + +int minerva_get_mtc_table_entries() +{ + if (!minerva_cfg) + return 0; + + mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg; + return mtc_cfg->table_entries; +} diff --git a/bdk/mem/minerva.h b/bdk/mem/minerva.h index a81cdc86..9320ecbe 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, @@ -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,9 @@ 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(int oc_freq); void minerva_periodic_training(); +emc_table_t *minerva_get_mtc_table(); +int minerva_get_mtc_table_entries(); #endif diff --git a/bdk/mem/sdram.c b/bdk/mem/sdram.c index 00ec3559..299f3b2d 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-2021 CTCaer + * Copyright (c) 2019-2023 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, @@ -31,11 +31,14 @@ #include #include #include +#include #include -#include #define CONFIG_SDRAM_KEEP_ALIVE +#define DRAM_ID(x) BIT(x) +#define DRAM_CC(x) BIT(x) + typedef struct _sdram_vendor_patch_t { u32 val; @@ -44,35 +47,41 @@ typedef struct _sdram_vendor_patch_t } sdram_vendor_patch_t; 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, +/* 00 */ LPDDR4X_UNUSED, +/* 01 */ LPDDR4X_UNUSED, +/* 02 */ LPDDR4X_UNUSED, +/* 03 */ LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, +/* 04 */ LPDDR4X_UNUSED, +/* 05 */ LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, +/* 06 */ LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, +/* 07 */ LPDDR4X_UNUSED, +/* 08 */ LPDDR4X_NO_PATCH, +/* 09 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ, +/* 10 */ LPDDR4X_NO_PATCH, +/* 11 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE, +/* 12 */ LPDDR4X_NO_PATCH, +/* 13 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ, +/* 14 */ LPDDR4X_NO_PATCH, +/* 15 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE, +/* 16 */ LPDDR4X_UNUSED, +/* 17 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL, +/* 18 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL, +/* 19 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL, +/* 20 */ LPDDR4X_4GB_SAMSUNG_1Z, +/* 21 */ LPDDR4X_4GB_SAMSUNG_1Z, +/* 22 */ LPDDR4X_4GB_SAMSUNG_1Z, +/* 23 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL, +/* 24 */ LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL, +/* 25 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF, +/* 26 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF, +/* 27 */ LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF, +/* 28 */ LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL, +/* 29 */ LPDDR4X_4GB_HYNIX_1A, +/* 30 */ LPDDR4X_4GB_HYNIX_1A, +/* 31 */ LPDDR4X_4GB_HYNIX_1A, +/* 32 */ LPDDR4X_4GB_MICRON_1A, +/* 33 */ LPDDR4X_4GB_MICRON_1A, +/* 34 */ LPDDR4X_4GB_MICRON_1A, }; #include "sdram_config.inl" @@ -118,6 +127,14 @@ static void _sdram_req_mrr_data(u32 data, bool dual_channel) emc_mr_data_t sdram_read_mrx(emc_mr_t mrx) { emc_mr_data_t data; + u32 dual_channel = (EMC(EMC_FBIO_CFG7) >> 2) & 1; + + // Clear left overs. + for (u32 i = 0; i < 32; i++) + { + (void)EMC(EMC_MRR); + usleep(1); + } /* * When a dram chip has only one rank, then the info from the 2 ranks differs. @@ -125,14 +142,23 @@ emc_mr_data_t sdram_read_mrx(emc_mr_t mrx) */ // Get Device 0 (Rank 0) info from both dram chips (channels). - _sdram_req_mrr_data(BIT(31) | (mrx << 16), EMC_CHAN0); + _sdram_req_mrr_data((2u << 30) | (mrx << 16), dual_channel); data.rank0_ch0 = EMC(EMC_MRR) & 0xFF; data.rank0_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8); - // Get Device 1 (Rank 1) info from both dram chips (channels). - _sdram_req_mrr_data(BIT(30) | (mrx << 16), EMC_CHAN1); - data.rank1_ch0 = EMC(EMC_MRR) & 0xFF; - data.rank1_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8); + // If Rank 1 exists, get info. + if (EMC(EMC_ADR_CFG) & 1) + { + // Get Device 1 (Rank 1) info from both dram chips (channels). + _sdram_req_mrr_data((1u << 30) | (mrx << 16), dual_channel); + data.rank1_ch0 = EMC(EMC_MRR) & 0xFF; + data.rank1_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8); + } + else + { + data.rank1_ch0 = 0xFF; + data.rank1_ch1 = 0xFF; + } return data; } @@ -250,7 +276,7 @@ static void _sdram_config_t210(const sdram_params_t210_t *params) *(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7; // Set pad controls. - EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl; + EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl; EMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2; EMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3; @@ -263,70 +289,70 @@ static void _sdram_config_t210(const sdram_params_t210_t *params) EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7; EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8; - EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term; - EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive; - EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive; + EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term; + EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive; + EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive; EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive; EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common; - EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel; - EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl; + EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel; + EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl; - EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0; - EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1; + EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0; + EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1; EMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1; EMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0; EMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1; - EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0; - EMC(EMC_DQS_BRLSHFT_1) = params->emc_dqs_brlshft1; - EMC(EMC_CMD_BRLSHFT_0) = params->emc_cmd_brlshft0; - EMC(EMC_CMD_BRLSHFT_1) = params->emc_cmd_brlshft1; - EMC(EMC_CMD_BRLSHFT_2) = params->emc_cmd_brlshft2; - EMC(EMC_CMD_BRLSHFT_3) = params->emc_cmd_brlshft3; + EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0; + EMC(EMC_DQS_BRLSHFT_1) = params->emc_dqs_brlshft1; + EMC(EMC_CMD_BRLSHFT_0) = params->emc_cmd_brlshft0; + EMC(EMC_CMD_BRLSHFT_1) = params->emc_cmd_brlshft1; + EMC(EMC_CMD_BRLSHFT_2) = params->emc_cmd_brlshft2; + EMC(EMC_CMD_BRLSHFT_3) = params->emc_cmd_brlshft3; EMC(EMC_QUSE_BRLSHFT_0) = params->emc_quse_brlshft0; EMC(EMC_QUSE_BRLSHFT_1) = params->emc_quse_brlshft1; EMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2; EMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3; EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1BF01BF) | 0x1E401E40; - EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl; + EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl; - EMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd; - EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2 & 0xFF7FFF7F; + EMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd; + EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2 & 0xFF7FFF7F; EMC(EMC_PMACRO_DATA_BRICK_CTRL_FDPD) = params->emc_pmacro_data_brick_ctrl_fdpd; - EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = params->emc_pmacro_bg_bias_ctrl0; - EMC(EMC_PMACRO_DATA_PAD_RX_CTRL) = params->emc_pmacro_data_pad_rx_ctrl; - EMC(EMC_PMACRO_CMD_PAD_RX_CTRL) = params->emc_pmacro_cmd_pad_rx_ctrl; - EMC(EMC_PMACRO_DATA_PAD_TX_CTRL) = params->emc_pmacro_data_pad_tx_ctrl; - EMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode; - EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode; - EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl; + EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = params->emc_pmacro_bg_bias_ctrl0; + EMC(EMC_PMACRO_DATA_PAD_RX_CTRL) = params->emc_pmacro_data_pad_rx_ctrl; + EMC(EMC_PMACRO_CMD_PAD_RX_CTRL) = params->emc_pmacro_cmd_pad_rx_ctrl; + EMC(EMC_PMACRO_DATA_PAD_TX_CTRL) = params->emc_pmacro_data_pad_tx_ctrl; + EMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode; + EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode; + EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl; EMC(EMC_CFG_3) = params->emc_cfg3; - EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0; - EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1; - EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2; - EMC(EMC_PMACRO_TX_PWRD_3) = params->emc_pmacro_tx_pwrd3; - EMC(EMC_PMACRO_TX_PWRD_4) = params->emc_pmacro_tx_pwrd4; - EMC(EMC_PMACRO_TX_PWRD_5) = params->emc_pmacro_tx_pwrd5; + EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0; + EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1; + EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2; + EMC(EMC_PMACRO_TX_PWRD_3) = params->emc_pmacro_tx_pwrd3; + EMC(EMC_PMACRO_TX_PWRD_4) = params->emc_pmacro_tx_pwrd4; + EMC(EMC_PMACRO_TX_PWRD_5) = params->emc_pmacro_tx_pwrd5; EMC(EMC_PMACRO_TX_SEL_CLK_SRC_0) = params->emc_pmacro_tx_sel_clk_src0; EMC(EMC_PMACRO_TX_SEL_CLK_SRC_1) = params->emc_pmacro_tx_sel_clk_src1; EMC(EMC_PMACRO_TX_SEL_CLK_SRC_2) = params->emc_pmacro_tx_sel_clk_src2; EMC(EMC_PMACRO_TX_SEL_CLK_SRC_3) = params->emc_pmacro_tx_sel_clk_src3; EMC(EMC_PMACRO_TX_SEL_CLK_SRC_4) = params->emc_pmacro_tx_sel_clk_src4; EMC(EMC_PMACRO_TX_SEL_CLK_SRC_5) = params->emc_pmacro_tx_sel_clk_src5; - EMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass; - EMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0; - EMC(EMC_PMACRO_DDLL_PWRD_1) = params->emc_pmacro_ddll_pwrd1; - EMC(EMC_PMACRO_DDLL_PWRD_2) = params->emc_pmacro_ddll_pwrd2; - EMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0; - EMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1; - EMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2; - EMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0; - EMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1; - EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0; - EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1; - EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt; + EMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass; + EMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0; + EMC(EMC_PMACRO_DDLL_PWRD_1) = params->emc_pmacro_ddll_pwrd1; + EMC(EMC_PMACRO_DDLL_PWRD_2) = params->emc_pmacro_ddll_pwrd2; + EMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0; + EMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1; + EMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2; + EMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0; + EMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1; + EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0; + EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1; + EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt; EMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0; EMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1; @@ -340,7 +366,7 @@ static void _sdram_config_t210(const sdram_params_t210_t *params) EMC(EMC_PMACRO_QUSE_DDLL_RANK1_3) = params->emc_pmacro_quse_ddll_rank1_3; EMC(EMC_PMACRO_QUSE_DDLL_RANK1_4) = params->emc_pmacro_quse_ddll_rank1_4; EMC(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5; - EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1; + EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1; EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0; EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1; @@ -376,11 +402,11 @@ static void _sdram_config_t210(const sdram_params_t210_t *params) EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2; EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3; - EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0; - EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1; - EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2; - EMC(EMC_PMACRO_DDLL_LONG_CMD_3) = params->emc_pmacro_ddll_long_cmd_3; - EMC(EMC_PMACRO_DDLL_LONG_CMD_4) = params->emc_pmacro_ddll_long_cmd_4; + EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0; + EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1; + EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2; + EMC(EMC_PMACRO_DDLL_LONG_CMD_3) = params->emc_pmacro_ddll_long_cmd_3; + EMC(EMC_PMACRO_DDLL_LONG_CMD_4) = params->emc_pmacro_ddll_long_cmd_4; EMC(EMC_PMACRO_DDLL_SHORT_CMD_0) = params->emc_pmacro_ddll_short_cmd_0; EMC(EMC_PMACRO_DDLL_SHORT_CMD_1) = params->emc_pmacro_ddll_short_cmd_1; EMC(EMC_PMACRO_DDLL_SHORT_CMD_2) = params->emc_pmacro_ddll_short_cmd_2; @@ -395,18 +421,18 @@ static void _sdram_config_t210(const sdram_params_t210_t *params) EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place. // Initialize MC VPR settings. - MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom; - MC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi; - MC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb; - MC(MC_VIDEO_PROTECT_VPR_OVERRIDE) = params->mc_video_protect_vpr_override; - MC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1; + MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom; + MC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi; + MC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb; + MC(MC_VIDEO_PROTECT_VPR_OVERRIDE) = params->mc_video_protect_vpr_override; + MC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1; MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = params->mc_video_protect_gpu_override0; MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = params->mc_video_protect_gpu_override1; // Program SDRAM geometry parameters. - MC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg; - MC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0; - MC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1; + MC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg; + MC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0; + MC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1; MC(MC_EMEM_ADR_CFG_CHANNEL_MASK) = params->mc_emem_adr_cfg_channel_mask; // Program bank swizzling. @@ -418,44 +444,44 @@ static void _sdram_config_t210(const sdram_params_t210_t *params) MC(MC_EMEM_CFG) = params->mc_emem_cfg; // Program SEC carveout (base and size). - MC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom; - MC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi; + MC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom; + MC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi; MC(MC_SEC_CARVEOUT_SIZE_MB) = params->mc_sec_carveout_size_mb; // Program MTS carveout (base and size). - MC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom; - MC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi; + MC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom; + MC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi; MC(MC_MTS_CARVEOUT_SIZE_MB) = params->mc_mts_carveout_size_mb; // Program the memory arbiter. - MC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg; + MC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg; MC(MC_EMEM_ARB_OUTSTANDING_REQ) = params->mc_emem_arb_outstanding_req; - MC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl; + MC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl; MC(MC_EMEM_ARB_REFPB_BANK_CTRL) = params->emc_emem_arb_refpb_bank_ctrl; - MC(MC_EMEM_ARB_TIMING_RCD) = params->mc_emem_arb_timing_rcd; - MC(MC_EMEM_ARB_TIMING_RP) = params->mc_emem_arb_timing_rp; - MC(MC_EMEM_ARB_TIMING_RC) = params->mc_emem_arb_timing_rc; - MC(MC_EMEM_ARB_TIMING_RAS) = params->mc_emem_arb_timing_ras; - MC(MC_EMEM_ARB_TIMING_FAW) = params->mc_emem_arb_timing_faw; - MC(MC_EMEM_ARB_TIMING_RRD) = params->mc_emem_arb_timing_rrd; - MC(MC_EMEM_ARB_TIMING_RAP2PRE) = params->mc_emem_arb_timing_rap2pre; - MC(MC_EMEM_ARB_TIMING_WAP2PRE) = params->mc_emem_arb_timing_wap2pre; - MC(MC_EMEM_ARB_TIMING_R2R) = params->mc_emem_arb_timing_r2r; - MC(MC_EMEM_ARB_TIMING_W2W) = params->mc_emem_arb_timing_w2w; - MC(MC_EMEM_ARB_TIMING_CCDMW) = params->mc_emem_arb_timing_ccdmw; - MC(MC_EMEM_ARB_TIMING_R2W) = params->mc_emem_arb_timing_r2w; - MC(MC_EMEM_ARB_TIMING_W2R) = params->mc_emem_arb_timing_w2r; - MC(MC_EMEM_ARB_TIMING_RFCPB) = params->mc_emem_arb_timing_rfcpb; - MC(MC_EMEM_ARB_DA_TURNS) = params->mc_emem_arb_da_turns; - MC(MC_EMEM_ARB_DA_COVERS) = params->mc_emem_arb_da_covers; - MC(MC_EMEM_ARB_MISC0) = params->mc_emem_arb_misc0; - MC(MC_EMEM_ARB_MISC1) = params->mc_emem_arb_misc1; - MC(MC_EMEM_ARB_MISC2) = params->mc_emem_arb_misc2; - MC(MC_EMEM_ARB_RING1_THROTTLE) = params->mc_emem_arb_ring1_throttle; - MC(MC_EMEM_ARB_OVERRIDE) = params->mc_emem_arb_override; - MC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1; - MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv; - MC(MC_DA_CONFIG0) = params->mc_da_cfg0; + MC(MC_EMEM_ARB_TIMING_RCD) = params->mc_emem_arb_timing_rcd; + MC(MC_EMEM_ARB_TIMING_RP) = params->mc_emem_arb_timing_rp; + MC(MC_EMEM_ARB_TIMING_RC) = params->mc_emem_arb_timing_rc; + MC(MC_EMEM_ARB_TIMING_RAS) = params->mc_emem_arb_timing_ras; + MC(MC_EMEM_ARB_TIMING_FAW) = params->mc_emem_arb_timing_faw; + MC(MC_EMEM_ARB_TIMING_RRD) = params->mc_emem_arb_timing_rrd; + MC(MC_EMEM_ARB_TIMING_RAP2PRE) = params->mc_emem_arb_timing_rap2pre; + MC(MC_EMEM_ARB_TIMING_WAP2PRE) = params->mc_emem_arb_timing_wap2pre; + MC(MC_EMEM_ARB_TIMING_R2R) = params->mc_emem_arb_timing_r2r; + MC(MC_EMEM_ARB_TIMING_W2W) = params->mc_emem_arb_timing_w2w; + MC(MC_EMEM_ARB_TIMING_CCDMW) = params->mc_emem_arb_timing_ccdmw; + MC(MC_EMEM_ARB_TIMING_R2W) = params->mc_emem_arb_timing_r2w; + MC(MC_EMEM_ARB_TIMING_W2R) = params->mc_emem_arb_timing_w2r; + MC(MC_EMEM_ARB_TIMING_RFCPB) = params->mc_emem_arb_timing_rfcpb; + MC(MC_EMEM_ARB_DA_TURNS) = params->mc_emem_arb_da_turns; + MC(MC_EMEM_ARB_DA_COVERS) = params->mc_emem_arb_da_covers; + MC(MC_EMEM_ARB_MISC0) = params->mc_emem_arb_misc0; + MC(MC_EMEM_ARB_MISC1) = params->mc_emem_arb_misc1; + MC(MC_EMEM_ARB_MISC2) = params->mc_emem_arb_misc2; + MC(MC_EMEM_ARB_RING1_THROTTLE) = params->mc_emem_arb_ring1_throttle; + MC(MC_EMEM_ARB_OVERRIDE) = params->mc_emem_arb_override; + MC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1; + MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv; + MC(MC_DA_CONFIG0) = params->mc_da_cfg0; MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update. @@ -480,7 +506,7 @@ static void _sdram_config_t210(const sdram_params_t210_t *params) EMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1; EMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval; - EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config; + EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config; usleep(params->emc_auto_cal_wait); // Patch 5 using BCT spare variables. @@ -488,96 +514,96 @@ static void _sdram_config_t210(const sdram_params_t210_t *params) *(vu32 *)params->emc_bct_spare8 = params->emc_bct_spare9; // Program EMC timing configuration. - EMC(EMC_CFG_2) = params->emc_cfg2; - EMC(EMC_CFG_PIPE) = params->emc_cfg_pipe; - EMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1; - EMC(EMC_CFG_PIPE_2) = params->emc_cfg_pipe2; - EMC(EMC_CMDQ) = params->emc_cmd_q; - EMC(EMC_MC2EMCQ) = params->emc_mc2emc_q; - EMC(EMC_MRS_WAIT_CNT) = params->emc_mrs_wait_cnt; - EMC(EMC_MRS_WAIT_CNT2) = params->emc_mrs_wait_cnt2; - EMC(EMC_FBIO_CFG5) = params->emc_fbio_cfg5; - EMC(EMC_RC) = params->emc_rc; - EMC(EMC_RFC) = params->emc_rfc; - EMC(EMC_RFCPB) = params->emc_rfc_pb; - EMC(EMC_REFCTRL2) = params->emc_ref_ctrl2; - EMC(EMC_RFC_SLR) = params->emc_rfc_slr; - EMC(EMC_RAS) = params->emc_ras; - EMC(EMC_RP) = params->emc_rp; - EMC(EMC_TPPD) = params->emc_tppd; - EMC(EMC_R2R) = params->emc_r2r; - EMC(EMC_W2W) = params->emc_w2w; - EMC(EMC_R2W) = params->emc_r2w; - EMC(EMC_W2R) = params->emc_w2r; - EMC(EMC_R2P) = params->emc_r2p; - EMC(EMC_W2P) = params->emc_w2p; - EMC(EMC_CCDMW) = params->emc_ccdmw; - EMC(EMC_RD_RCD) = params->emc_rd_rcd; - EMC(EMC_WR_RCD) = params->emc_wr_rcd; - EMC(EMC_RRD) = params->emc_rrd; - EMC(EMC_REXT) = params->emc_rext; - EMC(EMC_WEXT) = params->emc_wext; - EMC(EMC_WDV) = params->emc_wdv; - EMC(EMC_WDV_CHK) = params->emc_wdv_chk; - EMC(EMC_WSV) = params->emc_wsv; - EMC(EMC_WEV) = params->emc_wev; - EMC(EMC_WDV_MASK) = params->emc_wdv_mask; - EMC(EMC_WS_DURATION) = params->emc_ws_duration; - EMC(EMC_WE_DURATION) = params->emc_we_duration; - EMC(EMC_QUSE) = params->emc_quse; - EMC(EMC_QUSE_WIDTH) = params->emc_quse_width; - EMC(EMC_IBDLY) = params->emc_ibdly; - EMC(EMC_OBDLY) = params->emc_obdly; - EMC(EMC_EINPUT) = params->emc_einput; + EMC(EMC_CFG_2) = params->emc_cfg2; + EMC(EMC_CFG_PIPE) = params->emc_cfg_pipe; + EMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1; + EMC(EMC_CFG_PIPE_2) = params->emc_cfg_pipe2; + EMC(EMC_CMDQ) = params->emc_cmd_q; + EMC(EMC_MC2EMCQ) = params->emc_mc2emc_q; + EMC(EMC_MRS_WAIT_CNT) = params->emc_mrs_wait_cnt; + EMC(EMC_MRS_WAIT_CNT2) = params->emc_mrs_wait_cnt2; + EMC(EMC_FBIO_CFG5) = params->emc_fbio_cfg5; + EMC(EMC_RC) = params->emc_rc; + EMC(EMC_RFC) = params->emc_rfc; + EMC(EMC_RFCPB) = params->emc_rfc_pb; + EMC(EMC_REFCTRL2) = params->emc_ref_ctrl2; + EMC(EMC_RFC_SLR) = params->emc_rfc_slr; + EMC(EMC_RAS) = params->emc_ras; + EMC(EMC_RP) = params->emc_rp; + EMC(EMC_TPPD) = params->emc_tppd; + EMC(EMC_R2R) = params->emc_r2r; + EMC(EMC_W2W) = params->emc_w2w; + EMC(EMC_R2W) = params->emc_r2w; + EMC(EMC_W2R) = params->emc_w2r; + EMC(EMC_R2P) = params->emc_r2p; + EMC(EMC_W2P) = params->emc_w2p; + EMC(EMC_CCDMW) = params->emc_ccdmw; + EMC(EMC_RD_RCD) = params->emc_rd_rcd; + EMC(EMC_WR_RCD) = params->emc_wr_rcd; + EMC(EMC_RRD) = params->emc_rrd; + EMC(EMC_REXT) = params->emc_rext; + EMC(EMC_WEXT) = params->emc_wext; + EMC(EMC_WDV) = params->emc_wdv; + EMC(EMC_WDV_CHK) = params->emc_wdv_chk; + EMC(EMC_WSV) = params->emc_wsv; + EMC(EMC_WEV) = params->emc_wev; + EMC(EMC_WDV_MASK) = params->emc_wdv_mask; + EMC(EMC_WS_DURATION) = params->emc_ws_duration; + EMC(EMC_WE_DURATION) = params->emc_we_duration; + EMC(EMC_QUSE) = params->emc_quse; + EMC(EMC_QUSE_WIDTH) = params->emc_quse_width; + EMC(EMC_IBDLY) = params->emc_ibdly; + EMC(EMC_OBDLY) = params->emc_obdly; + EMC(EMC_EINPUT) = params->emc_einput; EMC(EMC_EINPUT_DURATION) = params->emc_einput_duration; - EMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra; - EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width; + EMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra; + EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width; EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl; - EMC(EMC_DBG) = params->emc_dbg; - EMC(EMC_QRST) = params->emc_qrst; - EMC(EMC_ISSUE_QRST) = 1; - EMC(EMC_ISSUE_QRST) = 0; - EMC(EMC_QSAFE) = params->emc_qsafe; - EMC(EMC_RDV) = params->emc_rdv; - EMC(EMC_RDV_MASK) = params->emc_rdv_mask; - EMC(EMC_RDV_EARLY) = params->emc_rdv_early; - EMC(EMC_RDV_EARLY_MASK) = params->emc_rdv_early_mask; - EMC(EMC_QPOP) = params->emc_qpop; - EMC(EMC_REFRESH) = params->emc_refresh; - EMC(EMC_BURST_REFRESH_NUM) = params->emc_burst_refresh_num; + EMC(EMC_DBG) = params->emc_dbg; + EMC(EMC_QRST) = params->emc_qrst; + EMC(EMC_ISSUE_QRST) = 1; + EMC(EMC_ISSUE_QRST) = 0; + EMC(EMC_QSAFE) = params->emc_qsafe; + EMC(EMC_RDV) = params->emc_rdv; + EMC(EMC_RDV_MASK) = params->emc_rdv_mask; + EMC(EMC_RDV_EARLY) = params->emc_rdv_early; + EMC(EMC_RDV_EARLY_MASK) = params->emc_rdv_early_mask; + EMC(EMC_QPOP) = params->emc_qpop; + EMC(EMC_REFRESH) = params->emc_refresh; + EMC(EMC_BURST_REFRESH_NUM) = params->emc_burst_refresh_num; EMC(EMC_PRE_REFRESH_REQ_CNT) = params->emc_prerefresh_req_cnt; - EMC(EMC_PDEX2WR) = params->emc_pdex2wr; - EMC(EMC_PDEX2RD) = params->emc_pdex2rd; - EMC(EMC_PCHG2PDEN) = params->emc_pchg2pden; - EMC(EMC_ACT2PDEN) = params->emc_act2pden; - EMC(EMC_AR2PDEN) = params->emc_ar2pden; - EMC(EMC_RW2PDEN) = params->emc_rw2pden; - EMC(EMC_CKE2PDEN) = params->emc_cke2pden; - EMC(EMC_PDEX2CKE) = params->emc_pdex2che; - EMC(EMC_PDEX2MRR) = params->emc_pdex2mrr; - EMC(EMC_TXSR) = params->emc_txsr; - EMC(EMC_TXSRDLL) = params->emc_txsr_dll; - EMC(EMC_TCKE) = params->emc_tcke; - EMC(EMC_TCKESR) = params->emc_tckesr; - EMC(EMC_TPD) = params->emc_tpd; - EMC(EMC_TFAW) = params->emc_tfaw; - EMC(EMC_TRPAB) = params->emc_trpab; - EMC(EMC_TCLKSTABLE) = params->emc_tclkstable; - EMC(EMC_TCLKSTOP) = params->emc_tclkstop; - EMC(EMC_TREFBW) = params->emc_trefbw; - EMC(EMC_ODT_WRITE) = params->emc_odt_write; - EMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll; - EMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period; + EMC(EMC_PDEX2WR) = params->emc_pdex2wr; + EMC(EMC_PDEX2RD) = params->emc_pdex2rd; + EMC(EMC_PCHG2PDEN) = params->emc_pchg2pden; + EMC(EMC_ACT2PDEN) = params->emc_act2pden; + EMC(EMC_AR2PDEN) = params->emc_ar2pden; + EMC(EMC_RW2PDEN) = params->emc_rw2pden; + EMC(EMC_CKE2PDEN) = params->emc_cke2pden; + EMC(EMC_PDEX2CKE) = params->emc_pdex2che; + EMC(EMC_PDEX2MRR) = params->emc_pdex2mrr; + EMC(EMC_TXSR) = params->emc_txsr; + EMC(EMC_TXSRDLL) = params->emc_txsr_dll; + EMC(EMC_TCKE) = params->emc_tcke; + EMC(EMC_TCKESR) = params->emc_tckesr; + EMC(EMC_TPD) = params->emc_tpd; + EMC(EMC_TFAW) = params->emc_tfaw; + EMC(EMC_TRPAB) = params->emc_trpab; + EMC(EMC_TCLKSTABLE) = params->emc_tclkstable; + EMC(EMC_TCLKSTOP) = params->emc_tclkstop; + EMC(EMC_TREFBW) = params->emc_trefbw; + EMC(EMC_ODT_WRITE) = params->emc_odt_write; + EMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll; + EMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period; // Don't write CFG_ADR_EN (bit 1) here - lock bit written later. - EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD; - EMC(EMC_CFG_RSV) = params->emc_cfg_rsv; + EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD; + EMC(EMC_CFG_RSV) = params->emc_cfg_rsv; EMC(EMC_PMC_SCRATCH1) = params->emc_pmc_scratch1; EMC(EMC_PMC_SCRATCH2) = params->emc_pmc_scratch2; EMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3; EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control; - EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen; + EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen; // Set pipe bypass enable bits before sending any DRAM commands. EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000; @@ -602,13 +628,8 @@ static void _sdram_config_t210(const sdram_params_t210_t *params) // ZQ CAL setup (not actually issuing ZQ CAL now). if (params->emc_zcal_warm_cold_boot_enables & 1) { - if (params->memory_type == MEMORY_TYPE_DDR3L) - EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt << 3; - if (params->memory_type == MEMORY_TYPE_LPDDR4) - { - EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt; - EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd; - } + EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt; + EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd; } EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place. @@ -620,68 +641,51 @@ static void _sdram_config_t210(const sdram_params_t210_t *params) // Set clock enable signal. u32 pin_gpio_cfg = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12); - if (params->memory_type == MEMORY_TYPE_DDR3L || params->memory_type == MEMORY_TYPE_LPDDR4) - { - EMC(EMC_PIN) = pin_gpio_cfg; - (void)EMC(EMC_PIN); - usleep(params->emc_pin_extra_wait + 200); - EMC(EMC_PIN) = pin_gpio_cfg | 0x100; - (void)EMC(EMC_PIN); - } + EMC(EMC_PIN) = pin_gpio_cfg; + (void)EMC(EMC_PIN); + usleep(params->emc_pin_extra_wait + 200); + EMC(EMC_PIN) = pin_gpio_cfg | 0x100; + (void)EMC(EMC_PIN); - if (params->memory_type == MEMORY_TYPE_LPDDR4) - usleep(params->emc_pin_extra_wait + 2000); - else if (params->memory_type == MEMORY_TYPE_DDR3L) - usleep(params->emc_pin_extra_wait + 500); + usleep(params->emc_pin_extra_wait + 2000); // Enable clock enable signal. EMC(EMC_PIN) = pin_gpio_cfg | 0x101; (void)EMC(EMC_PIN); usleep(params->emc_pin_program_wait); - // Send NOP (trigger just needs to be non-zero). - if (params->memory_type != MEMORY_TYPE_LPDDR4) - EMC(EMC_NOP) = (params->emc_dev_select << 30) + 1; - - // On coldboot w/LPDDR2/3, wait 200 uSec after asserting CKE high. - if (params->memory_type == MEMORY_TYPE_LPDDR2) - usleep(params->emc_pin_extra_wait + 200); - // Init zq calibration, - if (params->memory_type == MEMORY_TYPE_LPDDR4) + // Patch 6 using BCT spare variables. + if (params->emc_bct_spare10) + *(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11; + + // Write mode registers. + EMC(EMC_MRW2) = params->emc_mrw2; + EMC(EMC_MRW) = params->emc_mrw1; + EMC(EMC_MRW3) = params->emc_mrw3; + EMC(EMC_MRW4) = params->emc_mrw4; + EMC(EMC_MRW6) = params->emc_mrw6; + EMC(EMC_MRW14) = params->emc_mrw14; + + EMC(EMC_MRW8) = params->emc_mrw8; + EMC(EMC_MRW12) = params->emc_mrw12; + EMC(EMC_MRW9) = params->emc_mrw9; + EMC(EMC_MRW13) = params->emc_mrw13; + + if (params->emc_zcal_warm_cold_boot_enables & 1) { - // Patch 6 using BCT spare variables. - if (params->emc_bct_spare10) - *(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11; - - // Write mode registers. - EMC(EMC_MRW2) = params->emc_mrw2; - EMC(EMC_MRW) = params->emc_mrw1; - EMC(EMC_MRW3) = params->emc_mrw3; - EMC(EMC_MRW4) = params->emc_mrw4; - EMC(EMC_MRW6) = params->emc_mrw6; - EMC(EMC_MRW14) = params->emc_mrw14; - - EMC(EMC_MRW8) = params->emc_mrw8; - EMC(EMC_MRW12) = params->emc_mrw12; - EMC(EMC_MRW9) = params->emc_mrw9; - EMC(EMC_MRW13) = params->emc_mrw13; - - if (params->emc_zcal_warm_cold_boot_enables & 1) + // Issue ZQCAL start, device 0. + EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0; + usleep(params->emc_zcal_init_wait); + + // Issue ZQCAL latch. + EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3; + // Same for device 1. + if (!(params->emc_dev_select & 2)) { - // Issue ZQCAL start, device 0. - EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0; + EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1; usleep(params->emc_zcal_init_wait); - - // Issue ZQCAL latch. - EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3; - // Same for device 1. - if (!(params->emc_dev_select & 2)) - { - EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1; - usleep(params->emc_zcal_init_wait); - EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1 ^ 3; - } + EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1 ^ 3; } } @@ -689,12 +693,9 @@ static void _sdram_config_t210(const sdram_params_t210_t *params) PMC(APBDEV_PMC_DDR_CFG) = params->pmc_ddr_cfg; // Start periodic ZQ calibration (LPDDRx only). - if (params->memory_type && params->memory_type <= MEMORY_TYPE_LPDDR4) - { - EMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval; - EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt; - EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd; - } + EMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval; + EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt; + EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd; // Patch 7 using BCT spare variables. if (params->emc_bct_spare12) @@ -709,11 +710,11 @@ static void _sdram_config_t210(const sdram_params_t210_t *params) EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000; EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control; - EMC(EMC_CFG_UPDATE) = params->emc_cfg_update; - EMC(EMC_CFG) = params->emc_cfg; - EMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq; + EMC(EMC_CFG_UPDATE) = params->emc_cfg_update; + EMC(EMC_CFG) = params->emc_cfg; + EMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq; EMC(EMC_FDPD_CTRL_CMD) = params->emc_fdpd_ctrl_cmd; - EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl; + EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl; // Write addr swizzle lock bit. EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2; @@ -731,8 +732,8 @@ static void _sdram_config_t210(const sdram_params_t210_t *params) // Lock carveouts per BCT cfg. MC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access; - MC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access; - MC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl; + MC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access; + MC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl; // Disable write access to a bunch of EMC registers. MC(MC_EMEM_CFG_ACCESS_CTRL) = 1; @@ -749,7 +750,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) // Program DPD3/DPD4 regs (coldboot path). // Enable sel_dpd on unused pins. - PMC(APBDEV_PMC_WEAK_BIAS) = (pmc_scratch1 & 0x1000) << 19 | (pmc_scratch1 & 0xFFF) << 18 | (pmc_scratch1 & 0x8000) << 15; + PMC(APBDEV_PMC_WEAK_BIAS) = (pmc_scratch1 & 0x1000) << 19 | (pmc_scratch1 & 0xFFF) << 18 | (pmc_scratch1 & 0x8000) << 15; PMC(APBDEV_PMC_IO_DPD3_REQ) = (pmc_scratch1 & 0x9FFF) + 0x80000000; usleep(params->pmc_io_dpd3_req_wait); @@ -763,7 +764,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) // Program CMD mapping. Required before brick mapping, else // we can't guarantee CK will be differential at all times. - EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7; + EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7; EMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0; EMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1; EMC(EMC_CMD_MAPPING_CMD0_2) = params->emc_cmd_mapping_cmd0_2; @@ -776,7 +777,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) EMC(EMC_CMD_MAPPING_CMD3_0) = params->emc_cmd_mapping_cmd3_0; EMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1; EMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2; - EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte; + EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte; // Program brick mapping. EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0; @@ -803,7 +804,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) usleep(params->pmc_vddp_sel_wait + 2); // Ensure the regulators settle. // Set clock sources. - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = params->emc_clock_source; + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = params->emc_clock_source; CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll; // Select EMC write mux. @@ -834,7 +835,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) *(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7; // Set pad controls. - EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl; + EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl; EMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2; EMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3; @@ -847,51 +848,51 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7; EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8; - EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term; - EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive; - EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive; - EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive; + EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term; + EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive; + EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive; + EMC(EMC_PMACRO_CMD_TX_DRV) = params->emc_pmacro_cmd_tx_drive; EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common; - EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel; - EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl; + EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel; + EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl; - EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0; - EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1; + EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0; + EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1; EMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1; EMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0; EMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1; - EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0; - EMC(EMC_DQS_BRLSHFT_1) = params->emc_dqs_brlshft1; - EMC(EMC_CMD_BRLSHFT_0) = params->emc_cmd_brlshft0; - EMC(EMC_CMD_BRLSHFT_1) = params->emc_cmd_brlshft1; - EMC(EMC_CMD_BRLSHFT_2) = params->emc_cmd_brlshft2; - EMC(EMC_CMD_BRLSHFT_3) = params->emc_cmd_brlshft3; + EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0; + EMC(EMC_DQS_BRLSHFT_1) = params->emc_dqs_brlshft1; + EMC(EMC_CMD_BRLSHFT_0) = params->emc_cmd_brlshft0; + EMC(EMC_CMD_BRLSHFT_1) = params->emc_cmd_brlshft1; + EMC(EMC_CMD_BRLSHFT_2) = params->emc_cmd_brlshft2; + EMC(EMC_CMD_BRLSHFT_3) = params->emc_cmd_brlshft3; EMC(EMC_QUSE_BRLSHFT_0) = params->emc_quse_brlshft0; EMC(EMC_QUSE_BRLSHFT_1) = params->emc_quse_brlshft1; EMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2; EMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3; EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1; - EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl; + EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl; - EMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd; - EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2; + EMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd; + EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2; EMC(EMC_PMACRO_DATA_BRICK_CTRL_FDPD) = params->emc_pmacro_data_brick_ctrl_fdpd; - EMC(EMC_PMACRO_DATA_PAD_RX_CTRL) = params->emc_pmacro_data_pad_rx_ctrl; - EMC(EMC_PMACRO_CMD_PAD_RX_CTRL) = params->emc_pmacro_cmd_pad_rx_ctrl; - EMC(EMC_PMACRO_DATA_PAD_TX_CTRL) = params->emc_pmacro_data_pad_tx_ctrl; - EMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode; - EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode; - EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl & 0xEFFFFFFF; - - EMC(EMC_CFG_3) = params->emc_cfg3; - EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0; - EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1; - EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2; - EMC(EMC_PMACRO_TX_PWRD_3) = params->emc_pmacro_tx_pwrd3; - EMC(EMC_PMACRO_TX_PWRD_4) = params->emc_pmacro_tx_pwrd4; - EMC(EMC_PMACRO_TX_PWRD_5) = params->emc_pmacro_tx_pwrd5; + EMC(EMC_PMACRO_DATA_PAD_RX_CTRL) = params->emc_pmacro_data_pad_rx_ctrl; + EMC(EMC_PMACRO_CMD_PAD_RX_CTRL) = params->emc_pmacro_cmd_pad_rx_ctrl; + EMC(EMC_PMACRO_DATA_PAD_TX_CTRL) = params->emc_pmacro_data_pad_tx_ctrl; + EMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode; + EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode; + EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl & 0xEFFFFFFF; + + EMC(EMC_CFG_3) = params->emc_cfg3; + EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0; + EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1; + EMC(EMC_PMACRO_TX_PWRD_2) = params->emc_pmacro_tx_pwrd2; + EMC(EMC_PMACRO_TX_PWRD_3) = params->emc_pmacro_tx_pwrd3; + EMC(EMC_PMACRO_TX_PWRD_4) = params->emc_pmacro_tx_pwrd4; + EMC(EMC_PMACRO_TX_PWRD_5) = params->emc_pmacro_tx_pwrd5; EMC(EMC_PMACRO_TX_SEL_CLK_SRC_0) = params->emc_pmacro_tx_sel_clk_src0; EMC(EMC_PMACRO_TX_SEL_CLK_SRC_1) = params->emc_pmacro_tx_sel_clk_src1; EMC(EMC_PMACRO_TX_SEL_CLK_SRC_2) = params->emc_pmacro_tx_sel_clk_src2; @@ -906,33 +907,33 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_3) = params->emc_pmacro_perbit_fgcg_ctrl3; EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_4) = params->emc_pmacro_perbit_fgcg_ctrl4; EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_5) = params->emc_pmacro_perbit_fgcg_ctrl5; - EMC(EMC_PMACRO_PERBIT_RFU_CTRL_0) = params->emc_pmacro_perbit_rfu_ctrl0; - EMC(EMC_PMACRO_PERBIT_RFU_CTRL_1) = params->emc_pmacro_perbit_rfu_ctrl1; - EMC(EMC_PMACRO_PERBIT_RFU_CTRL_2) = params->emc_pmacro_perbit_rfu_ctrl2; - EMC(EMC_PMACRO_PERBIT_RFU_CTRL_3) = params->emc_pmacro_perbit_rfu_ctrl3; - EMC(EMC_PMACRO_PERBIT_RFU_CTRL_4) = params->emc_pmacro_perbit_rfu_ctrl4; - EMC(EMC_PMACRO_PERBIT_RFU_CTRL_5) = params->emc_pmacro_perbit_rfu_ctrl5; + EMC(EMC_PMACRO_PERBIT_RFU_CTRL_0) = params->emc_pmacro_perbit_rfu_ctrl0; + EMC(EMC_PMACRO_PERBIT_RFU_CTRL_1) = params->emc_pmacro_perbit_rfu_ctrl1; + EMC(EMC_PMACRO_PERBIT_RFU_CTRL_2) = params->emc_pmacro_perbit_rfu_ctrl2; + EMC(EMC_PMACRO_PERBIT_RFU_CTRL_3) = params->emc_pmacro_perbit_rfu_ctrl3; + EMC(EMC_PMACRO_PERBIT_RFU_CTRL_4) = params->emc_pmacro_perbit_rfu_ctrl4; + EMC(EMC_PMACRO_PERBIT_RFU_CTRL_5) = params->emc_pmacro_perbit_rfu_ctrl5; EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_0) = params->emc_pmacro_perbit_rfu1_ctrl0; EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_1) = params->emc_pmacro_perbit_rfu1_ctrl1; EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_2) = params->emc_pmacro_perbit_rfu1_ctrl2; EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_3) = params->emc_pmacro_perbit_rfu1_ctrl3; EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_4) = params->emc_pmacro_perbit_rfu1_ctrl4; EMC(EMC_PMACRO_PERBIT_RFU1_CTRL_5) = params->emc_pmacro_perbit_rfu1_ctrl5; - EMC(EMC_PMACRO_DATA_PI_CTRL) = params->emc_pmacro_data_pi_ctrl; - EMC(EMC_PMACRO_CMD_PI_CTRL) = params->emc_pmacro_cmd_pi_ctrl; - - EMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass; - EMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0; - EMC(EMC_PMACRO_DDLL_PWRD_1) = params->emc_pmacro_ddll_pwrd1; - EMC(EMC_PMACRO_DDLL_PWRD_2) = params->emc_pmacro_ddll_pwrd2; - EMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0; - EMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1; - EMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2; - EMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0; - EMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1; + EMC(EMC_PMACRO_DATA_PI_CTRL) = params->emc_pmacro_data_pi_ctrl; + EMC(EMC_PMACRO_CMD_PI_CTRL) = params->emc_pmacro_cmd_pi_ctrl; + + EMC(EMC_PMACRO_DDLL_BYPASS) = params->emc_pmacro_ddll_bypass; + EMC(EMC_PMACRO_DDLL_PWRD_0) = params->emc_pmacro_ddll_pwrd0; + EMC(EMC_PMACRO_DDLL_PWRD_1) = params->emc_pmacro_ddll_pwrd1; + EMC(EMC_PMACRO_DDLL_PWRD_2) = params->emc_pmacro_ddll_pwrd2; + EMC(EMC_PMACRO_CMD_CTRL_0) = params->emc_pmacro_cmd_ctrl0; + EMC(EMC_PMACRO_CMD_CTRL_1) = params->emc_pmacro_cmd_ctrl1; + EMC(EMC_PMACRO_CMD_CTRL_2) = params->emc_pmacro_cmd_ctrl2; + EMC(EMC_PMACRO_IB_VREF_DQ_0) = params->emc_pmacro_ib_vref_dq_0; + EMC(EMC_PMACRO_IB_VREF_DQ_1) = params->emc_pmacro_ib_vref_dq_1; EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0; EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1; - EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt; + EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt; EMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0; EMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1; @@ -981,11 +982,11 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2; EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3; - EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0; - EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1; - EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2; - EMC(EMC_PMACRO_DDLL_LONG_CMD_3) = params->emc_pmacro_ddll_long_cmd_3; - EMC(EMC_PMACRO_DDLL_LONG_CMD_4) = params->emc_pmacro_ddll_long_cmd_4; + EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0; + EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1; + EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2; + EMC(EMC_PMACRO_DDLL_LONG_CMD_3) = params->emc_pmacro_ddll_long_cmd_3; + EMC(EMC_PMACRO_DDLL_LONG_CMD_4) = params->emc_pmacro_ddll_long_cmd_4; EMC(EMC_PMACRO_DDLL_SHORT_CMD_0) = params->emc_pmacro_ddll_short_cmd_0; EMC(EMC_PMACRO_DDLL_SHORT_CMD_1) = params->emc_pmacro_ddll_short_cmd_1; EMC(EMC_PMACRO_DDLL_SHORT_CMD_2) = params->emc_pmacro_ddll_short_cmd_2; @@ -999,27 +1000,27 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) // Patch 4 to 6 using BCT spare secure variables. if (params->emc_bct_spare_secure6) - *(vu32 *)params->emc_bct_spare_secure6 = params->emc_bct_spare_secure7; + *(vu32 *)params->emc_bct_spare_secure6 = params->emc_bct_spare_secure7; if (params->emc_bct_spare_secure8) - *(vu32 *)params->emc_bct_spare_secure8 = params->emc_bct_spare_secure9; + *(vu32 *)params->emc_bct_spare_secure8 = params->emc_bct_spare_secure9; if (params->emc_bct_spare_secure10) *(vu32 *)params->emc_bct_spare_secure10 = params->emc_bct_spare_secure11; EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place. // Initialize MC VPR settings. - MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom; - MC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi; - MC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb; - MC(MC_VIDEO_PROTECT_VPR_OVERRIDE) = params->mc_video_protect_vpr_override; - MC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1; + MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom; + MC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi; + MC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb; + MC(MC_VIDEO_PROTECT_VPR_OVERRIDE) = params->mc_video_protect_vpr_override; + MC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1; MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = params->mc_video_protect_gpu_override0; MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = params->mc_video_protect_gpu_override1; // Program SDRAM geometry parameters. - MC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg; - MC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0; - MC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1; + MC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg; + MC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0; + MC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1; MC(MC_EMEM_ADR_CFG_CHANNEL_MASK) = params->mc_emem_adr_cfg_channel_mask; // Program bank swizzling. @@ -1031,44 +1032,44 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) MC(MC_EMEM_CFG) = params->mc_emem_cfg; // Program SEC carveout (base and size). - MC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom; - MC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi; + MC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom; + MC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi; MC(MC_SEC_CARVEOUT_SIZE_MB) = params->mc_sec_carveout_size_mb; // Program MTS carveout (base and size). - MC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom; - MC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi; + MC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom; + MC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi; MC(MC_MTS_CARVEOUT_SIZE_MB) = params->mc_mts_carveout_size_mb; // Program the memory arbiter. - MC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg; + MC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg; MC(MC_EMEM_ARB_OUTSTANDING_REQ) = params->mc_emem_arb_outstanding_req; - MC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl; + MC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl; MC(MC_EMEM_ARB_REFPB_BANK_CTRL) = params->emc_emem_arb_refpb_bank_ctrl; - MC(MC_EMEM_ARB_TIMING_RCD) = params->mc_emem_arb_timing_rcd; - MC(MC_EMEM_ARB_TIMING_RP) = params->mc_emem_arb_timing_rp; - MC(MC_EMEM_ARB_TIMING_RC) = params->mc_emem_arb_timing_rc; - MC(MC_EMEM_ARB_TIMING_RAS) = params->mc_emem_arb_timing_ras; - MC(MC_EMEM_ARB_TIMING_FAW) = params->mc_emem_arb_timing_faw; - MC(MC_EMEM_ARB_TIMING_RRD) = params->mc_emem_arb_timing_rrd; - MC(MC_EMEM_ARB_TIMING_RAP2PRE) = params->mc_emem_arb_timing_rap2pre; - MC(MC_EMEM_ARB_TIMING_WAP2PRE) = params->mc_emem_arb_timing_wap2pre; - MC(MC_EMEM_ARB_TIMING_R2R) = params->mc_emem_arb_timing_r2r; - MC(MC_EMEM_ARB_TIMING_W2W) = params->mc_emem_arb_timing_w2w; - MC(MC_EMEM_ARB_TIMING_CCDMW) = params->mc_emem_arb_timing_ccdmw; - MC(MC_EMEM_ARB_TIMING_R2W) = params->mc_emem_arb_timing_r2w; - MC(MC_EMEM_ARB_TIMING_W2R) = params->mc_emem_arb_timing_w2r; - MC(MC_EMEM_ARB_TIMING_RFCPB) = params->mc_emem_arb_timing_rfcpb; - MC(MC_EMEM_ARB_DA_TURNS) = params->mc_emem_arb_da_turns; - MC(MC_EMEM_ARB_DA_COVERS) = params->mc_emem_arb_da_covers; - MC(MC_EMEM_ARB_MISC0) = params->mc_emem_arb_misc0; - MC(MC_EMEM_ARB_MISC1) = params->mc_emem_arb_misc1; - MC(MC_EMEM_ARB_MISC2) = params->mc_emem_arb_misc2; - MC(MC_EMEM_ARB_RING1_THROTTLE) = params->mc_emem_arb_ring1_throttle; - MC(MC_EMEM_ARB_OVERRIDE) = params->mc_emem_arb_override; - MC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1; - MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv; - MC(MC_DA_CONFIG0) = params->mc_da_cfg0; + MC(MC_EMEM_ARB_TIMING_RCD) = params->mc_emem_arb_timing_rcd; + MC(MC_EMEM_ARB_TIMING_RP) = params->mc_emem_arb_timing_rp; + MC(MC_EMEM_ARB_TIMING_RC) = params->mc_emem_arb_timing_rc; + MC(MC_EMEM_ARB_TIMING_RAS) = params->mc_emem_arb_timing_ras; + MC(MC_EMEM_ARB_TIMING_FAW) = params->mc_emem_arb_timing_faw; + MC(MC_EMEM_ARB_TIMING_RRD) = params->mc_emem_arb_timing_rrd; + MC(MC_EMEM_ARB_TIMING_RAP2PRE) = params->mc_emem_arb_timing_rap2pre; + MC(MC_EMEM_ARB_TIMING_WAP2PRE) = params->mc_emem_arb_timing_wap2pre; + MC(MC_EMEM_ARB_TIMING_R2R) = params->mc_emem_arb_timing_r2r; + MC(MC_EMEM_ARB_TIMING_W2W) = params->mc_emem_arb_timing_w2w; + MC(MC_EMEM_ARB_TIMING_CCDMW) = params->mc_emem_arb_timing_ccdmw; + MC(MC_EMEM_ARB_TIMING_R2W) = params->mc_emem_arb_timing_r2w; + MC(MC_EMEM_ARB_TIMING_W2R) = params->mc_emem_arb_timing_w2r; + MC(MC_EMEM_ARB_TIMING_RFCPB) = params->mc_emem_arb_timing_rfcpb; + MC(MC_EMEM_ARB_DA_TURNS) = params->mc_emem_arb_da_turns; + MC(MC_EMEM_ARB_DA_COVERS) = params->mc_emem_arb_da_covers; + MC(MC_EMEM_ARB_MISC0) = params->mc_emem_arb_misc0; + MC(MC_EMEM_ARB_MISC1) = params->mc_emem_arb_misc1; + MC(MC_EMEM_ARB_MISC2) = params->mc_emem_arb_misc2; + MC(MC_EMEM_ARB_RING1_THROTTLE) = params->mc_emem_arb_ring1_throttle; + MC(MC_EMEM_ARB_OVERRIDE) = params->mc_emem_arb_override; + MC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1; + MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv; + MC(MC_DA_CONFIG0) = params->mc_da_cfg0; MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update. @@ -1093,7 +1094,7 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) EMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1; EMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval; - EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config; + EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config; usleep(params->emc_auto_cal_wait); // Patch 5 using BCT spare variables. @@ -1103,99 +1104,100 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) EMC(EMC_AUTO_CAL_CONFIG9) = params->emc_auto_cal_config9; // Program EMC timing configuration. - EMC(EMC_CFG_2) = params->emc_cfg2; - EMC(EMC_CFG_PIPE) = params->emc_cfg_pipe; - EMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1; - EMC(EMC_CFG_PIPE_2) = params->emc_cfg_pipe2; - EMC(EMC_CMDQ) = params->emc_cmd_q; - EMC(EMC_MC2EMCQ) = params->emc_mc2emc_q; - EMC(EMC_MRS_WAIT_CNT) = params->emc_mrs_wait_cnt; - EMC(EMC_MRS_WAIT_CNT2) = params->emc_mrs_wait_cnt2; - EMC(EMC_FBIO_CFG5) = params->emc_fbio_cfg5; - EMC(EMC_RC) = params->emc_rc; - EMC(EMC_RFC) = params->emc_rfc; - EMC(EMC_RFCPB) = params->emc_rfc_pb; - EMC(EMC_REFCTRL2) = params->emc_ref_ctrl2; - EMC(EMC_RFC_SLR) = params->emc_rfc_slr; - EMC(EMC_RAS) = params->emc_ras; - EMC(EMC_RP) = params->emc_rp; - EMC(EMC_TPPD) = params->emc_tppd; - EMC(EMC_CTT) = params->emc_trtm; - EMC(EMC_FBIO_TWTM) = params->emc_twtm; - EMC(EMC_FBIO_TRATM) = params->emc_tratm; - EMC(EMC_FBIO_TWATM) = params->emc_twatm; - EMC(EMC_FBIO_TR2REF) = params->emc_tr2ref; - EMC(EMC_R2R) = params->emc_r2r; - EMC(EMC_W2W) = params->emc_w2w; - EMC(EMC_R2W) = params->emc_r2w; - EMC(EMC_W2R) = params->emc_w2r; - EMC(EMC_R2P) = params->emc_r2p; - EMC(EMC_W2P) = params->emc_w2p; - EMC(EMC_CCDMW) = params->emc_ccdmw; - EMC(EMC_RD_RCD) = params->emc_rd_rcd; - EMC(EMC_WR_RCD) = params->emc_wr_rcd; - EMC(EMC_RRD) = params->emc_rrd; - EMC(EMC_REXT) = params->emc_rext; - EMC(EMC_WEXT) = params->emc_wext; - EMC(EMC_WDV) = params->emc_wdv; - EMC(EMC_WDV_CHK) = params->emc_wdv_chk; - EMC(EMC_WSV) = params->emc_wsv; - EMC(EMC_WEV) = params->emc_wev; - EMC(EMC_WDV_MASK) = params->emc_wdv_mask; - EMC(EMC_WS_DURATION) = params->emc_ws_duration; - EMC(EMC_WE_DURATION) = params->emc_we_duration; - EMC(EMC_QUSE) = params->emc_quse; - EMC(EMC_QUSE_WIDTH) = params->emc_quse_width; - EMC(EMC_IBDLY) = params->emc_ibdly; - EMC(EMC_OBDLY) = params->emc_obdly; - EMC(EMC_EINPUT) = params->emc_einput; + EMC(EMC_CFG_2) = params->emc_cfg2; + EMC(EMC_CFG_PIPE) = params->emc_cfg_pipe; + EMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1; + EMC(EMC_CFG_PIPE_2) = params->emc_cfg_pipe2; + EMC(EMC_CMDQ) = params->emc_cmd_q; + EMC(EMC_MC2EMCQ) = params->emc_mc2emc_q; + EMC(EMC_MRS_WAIT_CNT) = params->emc_mrs_wait_cnt; + EMC(EMC_MRS_WAIT_CNT2) = params->emc_mrs_wait_cnt2; + EMC(EMC_FBIO_CFG5) = params->emc_fbio_cfg5; + EMC(EMC_RC) = params->emc_rc; + EMC(EMC_RFC) = params->emc_rfc; + EMC(EMC_RFCPB) = params->emc_rfc_pb; + EMC(EMC_REFCTRL2) = params->emc_ref_ctrl2; + EMC(EMC_RFC_SLR) = params->emc_rfc_slr; + EMC(EMC_RAS) = params->emc_ras; + EMC(EMC_RP) = params->emc_rp; + EMC(EMC_TPPD) = params->emc_tppd; + EMC(EMC_CTT) = params->emc_trtm; + EMC(EMC_FBIO_TWTM) = params->emc_twtm; + EMC(EMC_FBIO_TRATM) = params->emc_tratm; + EMC(EMC_FBIO_TWATM) = params->emc_twatm; + EMC(EMC_FBIO_TR2REF) = params->emc_tr2ref; + EMC(EMC_R2R) = params->emc_r2r; + EMC(EMC_W2W) = params->emc_w2w; + EMC(EMC_R2W) = params->emc_r2w; + EMC(EMC_W2R) = params->emc_w2r; + EMC(EMC_R2P) = params->emc_r2p; + EMC(EMC_W2P) = params->emc_w2p; + EMC(EMC_CCDMW) = params->emc_ccdmw; + EMC(EMC_RD_RCD) = params->emc_rd_rcd; + EMC(EMC_WR_RCD) = params->emc_wr_rcd; + EMC(EMC_RRD) = params->emc_rrd; + EMC(EMC_REXT) = params->emc_rext; + EMC(EMC_WEXT) = params->emc_wext; + EMC(EMC_WDV) = params->emc_wdv; + EMC(EMC_WDV_CHK) = params->emc_wdv_chk; + EMC(EMC_WSV) = params->emc_wsv; + EMC(EMC_WEV) = params->emc_wev; + EMC(EMC_WDV_MASK) = params->emc_wdv_mask; + EMC(EMC_WS_DURATION) = params->emc_ws_duration; + EMC(EMC_WE_DURATION) = params->emc_we_duration; + EMC(EMC_QUSE) = params->emc_quse; + EMC(EMC_QUSE_WIDTH) = params->emc_quse_width; + EMC(EMC_IBDLY) = params->emc_ibdly; + EMC(EMC_OBDLY) = params->emc_obdly; + EMC(EMC_EINPUT) = params->emc_einput; EMC(EMC_EINPUT_DURATION) = params->emc_einput_duration; - EMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra; - EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width; - EMC(EMC_DBG) = params->emc_dbg; - EMC(EMC_QRST) = params->emc_qrst; - EMC(EMC_ISSUE_QRST) = 1; - EMC(EMC_ISSUE_QRST) = 0; - EMC(EMC_QSAFE) = params->emc_qsafe; - EMC(EMC_RDV) = params->emc_rdv; - EMC(EMC_RDV_MASK) = params->emc_rdv_mask; - EMC(EMC_RDV_EARLY) = params->emc_rdv_early; - EMC(EMC_RDV_EARLY_MASK) = params->emc_rdv_early_mask; - EMC(EMC_QPOP) = params->emc_qpop; - EMC(EMC_REFRESH) = params->emc_refresh; - EMC(EMC_BURST_REFRESH_NUM) = params->emc_burst_refresh_num; + EMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra; + EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width; + + EMC(EMC_DBG) = params->emc_dbg; + EMC(EMC_QRST) = params->emc_qrst; + EMC(EMC_ISSUE_QRST) = 1; + EMC(EMC_ISSUE_QRST) = 0; + EMC(EMC_QSAFE) = params->emc_qsafe; + EMC(EMC_RDV) = params->emc_rdv; + EMC(EMC_RDV_MASK) = params->emc_rdv_mask; + EMC(EMC_RDV_EARLY) = params->emc_rdv_early; + EMC(EMC_RDV_EARLY_MASK) = params->emc_rdv_early_mask; + EMC(EMC_QPOP) = params->emc_qpop; + EMC(EMC_REFRESH) = params->emc_refresh; + EMC(EMC_BURST_REFRESH_NUM) = params->emc_burst_refresh_num; EMC(EMC_PRE_REFRESH_REQ_CNT) = params->emc_prerefresh_req_cnt; - EMC(EMC_PDEX2WR) = params->emc_pdex2wr; - EMC(EMC_PDEX2RD) = params->emc_pdex2rd; - EMC(EMC_PCHG2PDEN) = params->emc_pchg2pden; - EMC(EMC_ACT2PDEN) = params->emc_act2pden; - EMC(EMC_AR2PDEN) = params->emc_ar2pden; - EMC(EMC_RW2PDEN) = params->emc_rw2pden; - EMC(EMC_CKE2PDEN) = params->emc_cke2pden; - EMC(EMC_PDEX2CKE) = params->emc_pdex2che; - EMC(EMC_PDEX2MRR) = params->emc_pdex2mrr; - EMC(EMC_TXSR) = params->emc_txsr; - EMC(EMC_TXSRDLL) = params->emc_txsr_dll; - EMC(EMC_TCKE) = params->emc_tcke; - EMC(EMC_TCKESR) = params->emc_tckesr; - EMC(EMC_TPD) = params->emc_tpd; - EMC(EMC_TFAW) = params->emc_tfaw; - EMC(EMC_TRPAB) = params->emc_trpab; - EMC(EMC_TCLKSTABLE) = params->emc_tclkstable; - EMC(EMC_TCLKSTOP) = params->emc_tclkstop; - EMC(EMC_TREFBW) = params->emc_trefbw; - EMC(EMC_ODT_WRITE) = params->emc_odt_write; - EMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll; - EMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period; + EMC(EMC_PDEX2WR) = params->emc_pdex2wr; + EMC(EMC_PDEX2RD) = params->emc_pdex2rd; + EMC(EMC_PCHG2PDEN) = params->emc_pchg2pden; + EMC(EMC_ACT2PDEN) = params->emc_act2pden; + EMC(EMC_AR2PDEN) = params->emc_ar2pden; + EMC(EMC_RW2PDEN) = params->emc_rw2pden; + EMC(EMC_CKE2PDEN) = params->emc_cke2pden; + EMC(EMC_PDEX2CKE) = params->emc_pdex2che; + EMC(EMC_PDEX2MRR) = params->emc_pdex2mrr; + EMC(EMC_TXSR) = params->emc_txsr; + EMC(EMC_TXSRDLL) = params->emc_txsr_dll; + EMC(EMC_TCKE) = params->emc_tcke; + EMC(EMC_TCKESR) = params->emc_tckesr; + EMC(EMC_TPD) = params->emc_tpd; + EMC(EMC_TFAW) = params->emc_tfaw; + EMC(EMC_TRPAB) = params->emc_trpab; + EMC(EMC_TCLKSTABLE) = params->emc_tclkstable; + EMC(EMC_TCLKSTOP) = params->emc_tclkstop; + EMC(EMC_TREFBW) = params->emc_trefbw; + EMC(EMC_ODT_WRITE) = params->emc_odt_write; + EMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll; + EMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period; // Don't write CFG_ADR_EN (bit 1) here - lock bit written later. - EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD; - EMC(EMC_CFG_RSV) = params->emc_cfg_rsv; + EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD; + EMC(EMC_CFG_RSV) = params->emc_cfg_rsv; EMC(EMC_PMC_SCRATCH1) = params->emc_pmc_scratch1; EMC(EMC_PMC_SCRATCH2) = params->emc_pmc_scratch2; EMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3; EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control; - EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen; + EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen; EMC(EMC_PMACRO_DSR_VTTGEN_CTRL0) = params->emc_pmacro_dsr_vttgen_ctrl0; // Set pipe bypass enable bits before sending any DRAM commands. @@ -1226,13 +1228,8 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) // ZQ CAL setup (not actually issuing ZQ CAL now). if (params->emc_zcal_warm_cold_boot_enables & 1) { - if (params->memory_type == MEMORY_TYPE_DDR3L) - EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt << 3; - if (params->memory_type == MEMORY_TYPE_LPDDR4) - { - EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt; - EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd; - } + EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt; + EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd; } EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place. @@ -1244,68 +1241,51 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) // Set clock enable signal. u32 pin_gpio_cfg = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12); - if (params->memory_type == MEMORY_TYPE_DDR3L || params->memory_type == MEMORY_TYPE_LPDDR4) - { - EMC(EMC_PIN) = pin_gpio_cfg; - (void)EMC(EMC_PIN); - usleep(params->emc_pin_extra_wait + 200); - EMC(EMC_PIN) = pin_gpio_cfg | 0x100; - (void)EMC(EMC_PIN); - } + EMC(EMC_PIN) = pin_gpio_cfg; + (void)EMC(EMC_PIN); + usleep(params->emc_pin_extra_wait + 200); + EMC(EMC_PIN) = pin_gpio_cfg | 0x100; + (void)EMC(EMC_PIN); - if (params->memory_type == MEMORY_TYPE_LPDDR4) - usleep(params->emc_pin_extra_wait + 2000); - else if (params->memory_type == MEMORY_TYPE_DDR3L) - usleep(params->emc_pin_extra_wait + 500); + usleep(params->emc_pin_extra_wait + 2000); // Enable clock enable signal. EMC(EMC_PIN) = pin_gpio_cfg | 0x101; (void)EMC(EMC_PIN); usleep(params->emc_pin_program_wait); - // Send NOP (trigger just needs to be non-zero). - if (params->memory_type != MEMORY_TYPE_LPDDR4) - EMC(EMC_NOP) = (params->emc_dev_select << 30) + 1; - - // On coldboot w/LPDDR2/3, wait 200 uSec after asserting CKE high. - if (params->memory_type == MEMORY_TYPE_LPDDR2) - usleep(params->emc_pin_extra_wait + 200); - // Init zq calibration, - if (params->memory_type == MEMORY_TYPE_LPDDR4) + // Patch 6 using BCT spare variables. + if (params->emc_bct_spare10) + *(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11; + + // Write mode registers. + EMC(EMC_MRW2) = params->emc_mrw2; + EMC(EMC_MRW) = params->emc_mrw1; + EMC(EMC_MRW3) = params->emc_mrw3; + EMC(EMC_MRW4) = params->emc_mrw4; + EMC(EMC_MRW6) = params->emc_mrw6; + EMC(EMC_MRW14) = params->emc_mrw14; + + EMC(EMC_MRW8) = params->emc_mrw8; + EMC(EMC_MRW12) = params->emc_mrw12; + EMC(EMC_MRW9) = params->emc_mrw9; + EMC(EMC_MRW13) = params->emc_mrw13; + + if (params->emc_zcal_warm_cold_boot_enables & 1) { - // Patch 6 using BCT spare variables. - if (params->emc_bct_spare10) - *(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11; - - // Write mode registers. - EMC(EMC_MRW2) = params->emc_mrw2; - EMC(EMC_MRW) = params->emc_mrw1; - EMC(EMC_MRW3) = params->emc_mrw3; - EMC(EMC_MRW4) = params->emc_mrw4; - EMC(EMC_MRW6) = params->emc_mrw6; - EMC(EMC_MRW14) = params->emc_mrw14; - - EMC(EMC_MRW8) = params->emc_mrw8; - EMC(EMC_MRW12) = params->emc_mrw12; - EMC(EMC_MRW9) = params->emc_mrw9; - EMC(EMC_MRW13) = params->emc_mrw13; - - if (params->emc_zcal_warm_cold_boot_enables & 1) + // Issue ZQCAL start, device 0. + EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0; + usleep(params->emc_zcal_init_wait); + + // Issue ZQCAL latch. + EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3; + // Same for device 1. + if (!(params->emc_dev_select & 2)) { - // Issue ZQCAL start, device 0. - EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0; + EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1; usleep(params->emc_zcal_init_wait); - - // Issue ZQCAL latch. - EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3; - // Same for device 1. - if (!(params->emc_dev_select & 2)) - { - EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1; - usleep(params->emc_zcal_init_wait); - EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1 ^ 3; - } + EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1 ^ 3; } } @@ -1321,12 +1301,9 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) PMC(APBDEV_PMC_DDR_CFG) = params->pmc_ddr_cfg; // Start periodic ZQ calibration (LPDDRx only). - if (params->memory_type == MEMORY_TYPE_LPDDR2 || params->memory_type == MEMORY_TYPE_DDR3L || params->memory_type == MEMORY_TYPE_LPDDR4) - { - EMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval; - EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt; - EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd; - } + EMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval; + EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt; + EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd; // Patch 7 using BCT spare variables. if (params->emc_bct_spare12) @@ -1341,10 +1318,10 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000; EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control; - EMC(EMC_CFG) = params->emc_cfg; - EMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq; + EMC(EMC_CFG) = params->emc_cfg; + EMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq; EMC(EMC_FDPD_CTRL_CMD) = params->emc_fdpd_ctrl_cmd; - EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl; + EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl; // Write addr swizzle lock bit. EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2; @@ -1364,8 +1341,8 @@ static void _sdram_config_t210b01(const sdram_params_t210b01_t *params) // Lock carveouts per BCT cfg. MC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access; - MC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access; - MC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl; + MC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access; + MC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl; // Disable write access to a bunch of EMC registers. MC(MC_EMEM_CFG_ACCESS_CTRL) = 1; @@ -1406,7 +1383,7 @@ void *sdram_get_params_t210b01() return (void *)params; for (u32 i = 0; i < ARRAY_SIZE(sdram_cfg_vendor_patches_t210b01); i++) - if (sdram_cfg_vendor_patches_t210b01[i].dramcf == dram_code) + if (sdram_cfg_vendor_patches_t210b01[i].dramcf & DRAM_CC(dram_code)) params[sdram_cfg_vendor_patches_t210b01[i].offset] = sdram_cfg_vendor_patches_t210b01[i].val; return (void *)params; @@ -1453,22 +1430,24 @@ void *sdram_get_params_patched() static void _sdram_init_t210() { const sdram_params_t210_t *params = (const sdram_params_t210_t *)_sdram_get_params_t210(); + if (params->memory_type != MEMORY_TYPE_LPDDR4) + return; // Set DRAM voltage. - max7762x_regulator_set_voltage(REGULATOR_SD1, 1100000); // HOS uses 1.125V + max7762x_regulator_set_voltage(REGULATOR_SD1, 1125000); // HOS: 1.125V. Bootloader: 1.1V. // VDDP Select. PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel; usleep(params->pmc_vddp_sel_wait); // Set DDR pad voltage. - PMC(APBDEV_PMC_DDR_PWR) = PMC(APBDEV_PMC_DDR_PWR); + PMC(APBDEV_PMC_DDR_PWR) = PMC(APBDEV_PMC_DDR_PWR); // Normally params->pmc_ddr_pwr. // Turn on MEM IO Power. PMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power; - PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short; + PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short; - PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl; + PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl; // Patch 1 using BCT spare variables if (params->emc_bct_spare0) @@ -1480,6 +1459,8 @@ static void _sdram_init_t210() static void _sdram_init_t210b01() { const sdram_params_t210b01_t *params = (const sdram_params_t210b01_t *)sdram_get_params_t210b01(); + if (params->memory_type != MEMORY_TYPE_LPDDR4) + return; // VDDP Select. PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel; @@ -1487,9 +1468,9 @@ static void _sdram_init_t210b01() // Turn on MEM IO Power. PMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power; - PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short; + PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short; - PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl; + PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl; // Patch 1 using BCT spare variables if (params->emc_bct_spare0) diff --git a/bdk/mem/sdram.h b/bdk/mem/sdram.h index 42907f9d..785dbee8 100644 --- a/bdk/mem/sdram.h +++ b/bdk/mem/sdram.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2020-2021 CTCaer + * Copyright (c) 2020-2023 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, @@ -51,73 +51,73 @@ enum sdram_ids_erista LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0, LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1, LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT = 2, // 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, // 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_HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 3, // Replaced from Copper. Die-M. (1y-01). + LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 5, // Replaced from Copper. Die-M. (1y-01). + LPDDR4X_AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 6, // Replaced from Copper. Die-M. (1y-01). // LPDDR4X 3733Mbps. - LPDDR4X_IOWA_4GB_SAMSUNG_X1X2 = 7, - - LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. + LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8, // Die-M. 1st gen. 8 banks. 3733Mbps. 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, // Die-M. + LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12, // Die-M. 1st gen. 8 banks. 3733Mbps. 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_IOWA_4GB_SAMSUNG_Y = 16, + LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 17, // Die-A. (1y-X03). 2nd gen. 8 banks. 4266Mbps. + LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 18, // Die-A. (1y-X03). + LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 19, // Die-A. (1y-X03). 2nd gen. 8 banks. 4266Mbps. - 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_1Z = 20, // 1z nm. 40% lower power usage. (1z-01). + LPDDR4X_HOAG_4GB_SAMSUNG_1Z = 21, // 1z nm. 40% lower power usage. (1z-01). + LPDDR4X_AULA_4GB_SAMSUNG_1Z = 22, // 1z nm. 40% lower power usage. (1z-01). - LPDDR4X_IOWA_4GB_SAMSUNG_1Y_Y = 20, - LPDDR4X_IOWA_8GB_SAMSUNG_1Y_Y = 21, + LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23, // Die-A. (1y-X03). + LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A. (1y-X03). 2nd gen. 8 banks. 4266Mbps. - // LPDDR4X_AULA_8GB_SAMSUNG_1Y_A = 22, // Unused. + LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 25, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01). + LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WTF = 26, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01). + LPDDR4X_AULA_4GB_MICRON_MT53E512M32D2NP_046_WTF = 27, // 4266Mbps. Die-F. D9XRR. 10nm-class (1y-01). - LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 23, // Die-A. - LPDDR4X_AULA_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 24, // Die-A. + LPDDR4X_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A. - 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_UNK0_4GB_HYNIX_1A = 29, // 1a nm. 61% lower power usage. (1a-01). + LPDDR4X_UNK1_4GB_HYNIX_1A = 30, // 1a nm. 61% lower power usage. (1a-01). + LPDDR4X_UNK2_4GB_HYNIX_1A = 31, // 1a nm. 61% lower power usage. (1a-01). - LPDDR4X_AULA_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 28, // Die-A. + LPDDR4X_UNK0_4GB_MICRON_1A = 32, // 1a nm. 61% lower power usage. (1a-01). + LPDDR4X_UNK1_4GB_MICRON_1A = 33, // 1a nm. 61% lower power usage. (1a-01). + LPDDR4X_UNK2_4GB_MICRON_1A = 34, // 1a nm. 61% lower power usage. (1a-01). }; enum sdram_codes_mariko { - LPDDR4X_NO_PATCH = 0, - LPDDR4X_UNUSED = 0, + 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. + LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 1, // DRAM IDs: 09, 13. + LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE = 2, // DRAM IDs: 11, 15. + LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL = 3, // DRAM IDs: 17, 19, 24. + LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL = 4, // DRAM IDs: 18, 23, 28. + LPDDR4X_4GB_SAMSUNG_1Z = 5, // DRAM IDs: 20, 21, 22. + LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF = 6, // DRAM IDs: 25, 26, 27. + LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE = 7, // DRAM IDs: 03, 05, 06. + + LPDDR4X_4GB_HYNIX_1A = 8, // DRAM IDs: 29, 30, 31. + LPDDR4X_4GB_MICRON_1A = 9, // DRAM IDs: 32, 33, 34. }; void sdram_init(); diff --git a/bdk/mem/sdram_config.inl b/bdk/mem/sdram_config.inl index 4548981f..19e84940 100644 --- a/bdk/mem/sdram_config.inl +++ b/bdk/mem/sdram_config.inl @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2020-2021 CTCaer + * Copyright (c) 2020-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,8 +17,6 @@ #define DRAM_CFG_T210_SIZE 1896 -#define DRAM_ID(x) BIT(x) - static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = { /* Specifies the type of memory device */ .memory_type = MEMORY_TYPE_LPDDR4, @@ -543,8 +541,12 @@ static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = { .mc_video_protect_bom = 0xFFF00000, .mc_video_protect_bom_adr_hi = 0x00000000, .mc_video_protect_size_mb = 0x00000000, + + // AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A. .mc_video_protect_vpr_override = 0xE4BAC343, + // SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. .mc_video_protect_vpr_override1 = 0x00001ED3, + .mc_video_protect_gpu_override0 = 0x00000000, .mc_video_protect_gpu_override1 = 0x00000000, .mc_sec_carveout_bom = 0xFFF00000, diff --git a/bdk/mem/sdram_config_t210b01.inl b/bdk/mem/sdram_config_t210b01.inl index 28cc0637..e764ca63 100644 --- a/bdk/mem/sdram_config_t210b01.inl +++ b/bdk/mem/sdram_config_t210b01.inl @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 CTCaer + * Copyright (c) 2020-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, @@ -594,10 +594,15 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = { .mc_video_protect_bom = 0xFFF00000, .mc_video_protect_bom_adr_hi = 0x00000000, .mc_video_protect_size_mb = 0x00000000, + + // AFI, BPMP, HC, ISP2, CCPLEX, PPCS (AHB), SATA, VI, XUSB_HOST, XUSB_DEV, ADSP, PPCS1 (AHB), DC1, SDMMC1A, SDMMC2A, SDMMC3A. .mc_video_protect_vpr_override = 0xE4BAC343, - .mc_video_protect_vpr_override1 = 0x06001ED3, // Add SE2, SE2B. + // SDMMC4A, ISP2B, PPCS2 (AHB), APE, SE, HC1, SE1, AXIAP, ETR. Plus SE2, SE2B. + .mc_video_protect_vpr_override1 = 0x06001ED3, + .mc_video_protect_gpu_override0 = 0x00000000, .mc_video_protect_gpu_override1 = 0x00000000, + .mc_sec_carveout_bom = 0xFFF00000, .mc_sec_carveout_adr_hi = 0x00000000, .mc_sec_carveout_size_mb = 0x00000000, @@ -701,292 +706,102 @@ static const sdram_params_t210b01_t _dram_cfg_08_10_12_14_samsung_hynix_4gb = { .bct_na = 0x00000000, }; -//!TODO Find out what mc_video_protect_gpu_override0 and mc_video_protect_gpu_override1 new bits are. +#define DRAM_CC_LPDDR4X_PMACRO_IB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ)) + +#define DRAM_CC_LPDDR4X_AUTOCAL_VPR (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \ + DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \ + DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \ + DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \ + DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \ + DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \ + DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \ + DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \ + DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z)) + +#define DRAM_CC_LPDDR4X_DYN_SELF_CTRL (DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTE) | \ + DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \ + DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \ + DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \ + DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \ + DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \ + DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z)) + +#define DRAM_CC_LPDDR4X_QUSE_EINPUT (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \ + DRAM_CC(LPDDR4X_4GB_SAMSUNG_K4U6E3S4AA_MGCL) | \ + DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \ + DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \ + DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \ + DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \ + DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \ + DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z)) + +#define DRAM_CC_LPDDR4X_FAW (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL) | \ + DRAM_CC(LPDDR4X_4GB_MICRON_MT53E512M32D2NP_046_WTF) | \ + DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \ + DRAM_CC(LPDDR4X_4GB_MICRON_1A)) + +#define DRAM_CC_LPDDR4X_VPR (DRAM_CC(LPDDR4X_4GB_HYNIX_H9HCNNNBKMMLXR_NEE) | \ + DRAM_CC(LPDDR4X_4GB_HYNIX_1A) | \ + DRAM_CC(LPDDR4X_4GB_MICRON_1A) | \ + DRAM_CC(LPDDR4X_4GB_SAMSUNG_1Z)) + +#define DRAM_CC_LPDDR4X_SAMSUNG_8GB (DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AM_MGCJ) | \ + DRAM_CC(LPDDR4X_8GB_SAMSUNG_K4UBE3D4AA_MGCL)) static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210b01[] = { - // Samsung LPDDR4X 4GB X1X2 for prototype Iowa. - { 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 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: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 (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 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 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-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-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 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 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. + { 0x35353535, 0x350 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_vref_dq_0. + { 0x35353535, 0x354 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_vref_dq_1. + { 0x00100010, 0x3FC / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_0. + { 0x00100010, 0x400 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_1. + { 0x00100010, 0x404 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_2. + { 0x00100010, 0x408 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank0_3. + { 0x00100010, 0x40C / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_0. + { 0x00100010, 0x410 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_1. + { 0x00100010, 0x414 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_2. + { 0x00100010, 0x418 / 4, DRAM_CC_LPDDR4X_PMACRO_IB }, // emc_pmacro_ib_ddll_long_dqs_rank1_3. + + /*! Shared patched between DRAM Codes. */ + { 0x05500000, 0x0D4 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // emc_auto_cal_config2. + { 0xC9AFBCBC, 0x0F4 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // emc_auto_cal_vref_sel0. + { 0x2A800000, 0x6DC / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // mc_video_protect_gpu_override0. + { 0x00000002, 0x6E0 / 4, DRAM_CC_LPDDR4X_AUTOCAL_VPR }, // mc_video_protect_gpu_override1. + //!TODO Find out what mc_video_protect_gpu_override0 and mc_video_protect_gpu_override1 new bits are. + + { 0x88161414, 0x2E0 / 4, DRAM_CC_LPDDR4X_DYN_SELF_CTRL }, // emc_mrw14. + { 0x80000713, 0x32C / 4, DRAM_CC_LPDDR4X_DYN_SELF_CTRL }, // emc_dyn_self_ref_control. + + { 0x00000006, 0x1CC / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_quse. + { 0x00000005, 0x1D0 / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_quse_width. + { 0x00000003, 0x1DC / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_einput. + { 0x0000000C, 0x1E0 / 4, DRAM_CC_LPDDR4X_QUSE_EINPUT }, // emc_einput_duration. + + { 0x00000008, 0x24C / 4, DRAM_CC_LPDDR4X_FAW }, // emc_tfaw. + { 0x00000001, 0x670 / 4, DRAM_CC_LPDDR4X_FAW }, // mc_emem_arb_timing_faw. + + { 0xE4FACB43, 0x6D4 / 4, DRAM_CC_LPDDR4X_VPR }, // mc_video_protect_vpr_override. + TSEC, NVENC. + { 0x0600FED3, 0x6D8 / 4, DRAM_CC_LPDDR4X_VPR }, // mc_video_protect_vpr_override1. + TSECB, TSEC1, TSECB1. + + { 0x00000001, 0x134 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_adr_cfg. 2 Ranks. + { 0x08010004, 0x2B8 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw1. + { 0x08020000, 0x2BC / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw2. + { 0x080D0000, 0x2C0 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw3. + { 0x08033131, 0x2C8 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw6. + { 0x080B0000, 0x2CC / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw8. + { 0x0C0E5D5D, 0x2D0 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw9. + { 0x080C5D5D, 0x2D4 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw10. + { 0x0C0D0808, 0x2D8 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw12. + { 0x0C0D0000, 0x2DC / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw13. + { 0x08161414, 0x2E0 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw14. + { 0x08010004, 0x2E4 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_mrw_extra. + { 0x00000000, 0x340 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_dev_select. Both devices. + { 0x0051004F, 0x450 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_zcal_mrw_cmd. + { 0x40000001, 0x45C / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_zcal_init_dev1. + { 0x00000000, 0x594 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_pmacro_tx_pwrd4. + { 0x00001000, 0x598 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // emc_pmacro_tx_pwrd5. + { 0x00000001, 0x630 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_adr_cfg. 2 Ranks. + { 0x00002000, 0x64C / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_cfg. 8GB total density. + { 0x00000002, 0x680 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_arb_timing_r2r. + { 0x02020001, 0x694 / 4, DRAM_CC_LPDDR4X_SAMSUNG_8GB }, // mc_emem_arb_da_turns. }; diff --git a/bdk/mem/sdram_lp0.c b/bdk/mem/sdram_lp0.c index 1c6e7e38..1e50103f 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 f2f20fbc..8bc9aac8 100644 --- a/bdk/mem/smmu.c +++ b/bdk/mem/smmu.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2018 naehrwert * Copyright (c) 2018 balika011 + * 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, @@ -18,10 +19,10 @@ #include #include +#include #include #include #include -#include #include bool smmu_used = false; @@ -70,18 +71,19 @@ void smmu_flush_all() { MC(MC_SMMU_PTC_FLUSH) = 0; smmu_flush_regs(); + MC(MC_SMMU_TLB_FLUSH) = 0; smmu_flush_regs(); } void smmu_init(u32 secmon_base) { - MC(MC_SMMU_PTB_ASID) = 0; - MC(MC_SMMU_PTB_DATA) = 0; + MC(MC_SMMU_PTB_ASID) = 0; + MC(MC_SMMU_PTB_DATA) = 0; MC(MC_SMMU_TLB_CONFIG) = 0x30000030; MC(MC_SMMU_PTC_CONFIG) = 0x28000F3F; - MC(MC_SMMU_PTC_FLUSH) = 0; - MC(MC_SMMU_TLB_FLUSH) = 0; + MC(MC_SMMU_PTC_FLUSH) = 0; + MC(MC_SMMU_TLB_FLUSH) = 0; // Set the secmon address *(u32 *)(smmu_payload + 0x30) = secmon_base; @@ -163,8 +165,8 @@ u32 *smmu_init_for_tsec() void smmu_deinit_for_tsec() { - MC(MC_SMMU_PTB_ASID) = 1; - MC(MC_SMMU_PTB_DATA) = 0; + MC(MC_SMMU_PTB_ASID) = 1; + MC(MC_SMMU_PTB_DATA) = 0; MC(MC_SMMU_TSEC_ASID) = 0; smmu_flush_regs(); } diff --git a/bdk/mem/smmu.h b/bdk/mem/smmu.h index 7846253f..97cd9d5b 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 8b0644a8..67ffa1fe 100644 --- a/bdk/memory_map.h +++ b/bdk/memory_map.h @@ -17,7 +17,6 @@ #ifndef _MEMORY_MAP_H_ #define _MEMORY_MAP_H_ -//#define IPL_STACK_TOP 0x4003FF00 /* --- BIT/BCT: 0x40000000 - 0x40003000 --- */ /* --- IPL: 0x40008000 - 0x40028000 --- */ #define LDR_LOAD_ADDR 0x40007000 @@ -25,14 +24,22 @@ #define IPL_LOAD_ADDR 0x40008000 #define IPL_SZ_MAX SZ_128K -/* --- XUSB EP context and TRB ring buffers --- */ -#define XUSB_RING_ADDR 0x40020000 +#define XUSB_RING_ADDR 0x40020000 // XUSB EP context and TRB ring buffers. -#define SECMON_MIN_START 0x4002B000 +#define SECMON_MIN_START 0x4002B000 // Minimum reserved address for secmon. #define SDRAM_PARAMS_ADDR 0x40030000 // SDRAM extraction buffer during sdram init. #define CBFS_DRAM_EN_ADDR 0x4003e000 // u32. +/* start.S / exception_handlers.S */ +#define SYS_STACK_TOP_INIT 0x4003FF00 +#define FIQ_STACK_TOP 0x40040000 +#define IRQ_STACK_TOP 0x40040000 +#define IPL_RELOC_ADDR 0x4003FF00 +#define IPL_RELOC_SZ 0x10 +#define EXCP_STORAGE_ADDR 0x4003FFF0 +#define EXCP_STORAGE_SZ 0x10 + /* --- DRAM START --- */ #define DRAM_START 0x80000000 #define HOS_RSVD SZ_16M // Do not write anything in this area. @@ -96,16 +103,13 @@ #define NYX_FB2_ADDRESS 0xF6600000 #define NYX_FB_SZ 0x384000 // 1280 x 720 x 4. +/* OBSOLETE: Very old hwinit based payloads were setting a carveout here. */ #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 diff --git a/bdk/power/bm92t36.c b/bdk/power/bm92t36.c index d1496f7a..faa1db54 100644 --- a/bdk/power/bm92t36.c +++ b/bdk/power/bm92t36.c @@ -1,7 +1,7 @@ /* * USB-PD driver for Nintendo Switch's TI BM92T36 * - * Copyright (c) 2020 CTCaer + * Copyright (c) 2020-2023 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, @@ -73,18 +73,23 @@ void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd) if (inserted) { + memset(buf, 0, sizeof(buf)); _bm92t36_read_reg(buf, 2, STATUS1_REG); *inserted = buf[0] & STATUS1_INSERT ? true : false; } if (usb_pd) { + memset(buf, 0, sizeof(buf)); _bm92t36_read_reg(buf, 29, READ_PDOS_SRC_REG); memcpy(pdos, &buf[1], 28); memset(usb_pd, 0, sizeof(usb_pd_objects_t)); usb_pd->pdo_no = buf[0] / sizeof(pd_object_t); + if (usb_pd->pdo_no > 7) + usb_pd->pdo_no = 7; + for (u32 i = 0; i < usb_pd->pdo_no; i++) { usb_pd->pdos[i].amperage = pdos[i].amp * 10; diff --git a/bdk/power/bq24193.h b/bdk/power/bq24193.h index 1b6e7174..399e2253 100644 --- a/bdk/power/bq24193.h +++ b/bdk/power/bq24193.h @@ -28,7 +28,7 @@ // REG 1 masks. #define BQ24193_PORCONFIG_BOOST_MASK (1<<0) -#define BQ24193_PORCONFIG_SYSMIN_MASK (7<<1) +#define BQ24193_PORCONFIG_SYSMIN_MASK (7<<1) // 3000uV HOS default. #define BQ24193_PORCONFIG_CHGCONFIG_MASK (3<<4) #define BQ24193_PORCONFIG_CHGCONFIG_CHARGER_EN (1<<4) #define BQ24193_PORCONFIG_I2CWATCHDOG_MASK (1<<6) diff --git a/bdk/power/max17050.c b/bdk/power/max17050.c index a5617245..c718d2bf 100644 --- a/bdk/power/max17050.c +++ b/bdk/power/max17050.c @@ -24,7 +24,7 @@ #include "max17050.h" #include -#include +#include #define BASE_SNS_UOHM 5000 diff --git a/bdk/power/max77620.h b/bdk/power/max77620.h index d54909f0..3d41459d 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 @@ -318,7 +318,7 @@ #define MAX77620_REG_CID2 0x5A #define MAX77620_REG_CID3 0x5B #define MAX77620_REG_CID4 0x5C // OTP version. -#define MAX77620_REG_CID5 0x5D +#define MAX77620_REG_CID5 0x5D // ES version. #define MAX77620_CID_DIDO_MASK 0xF #define MAX77620_CID_DIDO_SHIFT 0 #define MAX77620_CID_DIDM_MASK 0xF0 diff --git a/bdk/power/max7762x.c b/bdk/power/max7762x.c index a7d30cee..c2a267e3 100644 --- a/bdk/power/max7762x.c +++ b/bdk/power/max7762x.c @@ -20,8 +20,8 @@ #include #include #include +#include #include -#include #define REGULATOR_SD 0 #define REGULATOR_LDO 1 @@ -88,11 +88,11 @@ static const max77620_regulator_t _pmic_regulators[] = { { "ldo7", 50000, 800000, 1050000, 1050000, REGULATOR_LDO, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO7, 1, 4, 3 }} }, { "ldo8", 50000, 800000, 1050000, 2800000, REGULATOR_LDO, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, {{ MAX77620_REG_FPS_LDO8, 3, 7, 0 }} }, - { "max77621_CPU", 6250, 606250, 1000000, 1400000, REGULATOR_BC0, MAX77621_VOUT_REG, MAX77621_VOUT_DVS_REG, MAX77621_DVC_DVS_VOLT_MASK, {{ MAX77621_CPU_CTRL1_POR_DEFAULT, MAX77621_CPU_CTRL1_HOS_DEFAULT, MAX77621_CPU_CTRL2_POR_DEFAULT, MAX77621_CPU_CTRL2_HOS_DEFAULT }} }, - { "max77621_GPU", 6250, 606250, 1200000, 1400000, REGULATOR_BC0, MAX77621_VOUT_REG, MAX77621_VOUT_DVS_REG, MAX77621_DVC_DVS_VOLT_MASK, {{ MAX77621_CPU_CTRL1_POR_DEFAULT, MAX77621_CPU_CTRL1_HOS_DEFAULT, MAX77621_CPU_CTRL2_POR_DEFAULT, MAX77621_CPU_CTRL2_HOS_DEFAULT }} }, + { "max77621_CPU", 6250, 606250, 1000000, 1400000, REGULATOR_BC0, MAX77621_REG_VOUT, MAX77621_REG_VOUT_DVS, MAX77621_DVC_DVS_VOLT_MASK, {{ MAX77621_CPU_CTRL1_POR_DEFAULT, MAX77621_CPU_CTRL1_HOS_DEFAULT, MAX77621_CPU_CTRL2_POR_DEFAULT, MAX77621_CPU_CTRL2_HOS_DEFAULT }} }, + { "max77621_GPU", 6250, 606250, 1200000, 1400000, REGULATOR_BC0, MAX77621_REG_VOUT, MAX77621_REG_VOUT_DVS, MAX77621_DVC_DVS_VOLT_MASK, {{ MAX77621_CPU_CTRL1_POR_DEFAULT, MAX77621_CPU_CTRL1_HOS_DEFAULT, MAX77621_CPU_CTRL2_POR_DEFAULT, MAX77621_CPU_CTRL2_HOS_DEFAULT }} }, { "max77812_CPU", 5000, 250000, 600000, 1525000, REGULATOR_BC1, MAX77812_REG_M4_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M4_MASK, MAX77812_EN_CTRL_EN_M4_SHIFT, 0, 0 }} }, + { "max77812_RAM", 5000, 250000, 600000, 650000, REGULATOR_BC1, MAX77812_REG_M3_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M3_MASK, MAX77812_EN_CTRL_EN_M3_SHIFT, 0, 0 }} } // Only on PHASE211 configuration. //{ "max77812_GPU", 5000, 250000, 600000, 1525000, REGULATOR_BC1, MAX77812_REG_M1_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M1_MASK, MAX77812_EN_CTRL_EN_M1_SHIFT, 0, 0 }} }, - //{ "max77812_RAM", 5000, 250000, 600000, 1525000, REGULATOR_BC1, MAX77812_REG_M3_VOUT, MAX77812_REG_EN_CTRL, MAX77812_BUCK_VOLT_MASK, {{ MAX77812_EN_CTRL_EN_M3_MASK, MAX77812_EN_CTRL_EN_M3_SHIFT, 0, 0 }} } // Only on PHASE211 configuration. }; static u8 _max77812_get_address() @@ -121,7 +121,12 @@ static u8 _max7762x_get_i2c_address(u32 id) case REGULATOR_BC0: return (id == REGULATOR_CPU0 ? MAX77621_CPU_I2C_ADDR : MAX77621_GPU_I2C_ADDR); case REGULATOR_BC1: - return _max77812_get_address(); + { + u8 reg_addr = _max77812_get_address(); + if (id == REGULATOR_RAM1 && reg_addr == MAX77812_PHASE31_CPU_I2C_ADDR) + reg_addr = 0; + return reg_addr; + } default: return 0; } @@ -175,20 +180,22 @@ int max77620_regulator_config_fps(u32 id) return 1; } -int max7762x_regulator_set_voltage(u32 id, u32 mv) +int max7762x_regulator_set_voltage(u32 id, u32 uv) { if (id > REGULATOR_MAX) return 0; const max77620_regulator_t *reg = &_pmic_regulators[id]; - if (mv < reg->uv_min || mv > reg->uv_max) + if (uv < reg->uv_min || uv > reg->uv_max) return 0; u8 addr = _max7762x_get_i2c_address(id); + if (!addr) + return 0; // Calculate voltage multiplier. - u32 mult = (mv + reg->uv_step - 1 - reg->uv_min) / reg->uv_step; + u32 mult = (uv + reg->uv_step - 1 - reg->uv_min) / reg->uv_step; u8 val = i2c_recv_byte(I2C_5, addr, reg->volt_addr); val = (val & ~reg->volt_mask) | (mult & reg->volt_mask); @@ -249,6 +256,8 @@ int max7762x_regulator_enable(u32 id, bool enable) } u8 addr = _max7762x_get_i2c_address(id); + if (!addr) + return 0; // Read and enable/disable. u8 val = i2c_recv_byte(I2C_5, addr, reg_addr); @@ -291,6 +300,8 @@ void max77621_config_default(u32 id, bool por) return; u8 addr = _max7762x_get_i2c_address(id); + if (!addr) + return; if (por) { @@ -299,13 +310,13 @@ void max77621_config_default(u32 id, bool por) max7762x_regulator_enable(id, false); // Configure to default. - i2c_send_byte(I2C_5, addr, MAX77621_CONTROL1_REG, reg->ctrl.ctrl1_por); - i2c_send_byte(I2C_5, addr, MAX77621_CONTROL2_REG, reg->ctrl.ctrl2_por); + i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL1, reg->ctrl.ctrl1_por); + i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL2, reg->ctrl.ctrl2_por); } else { - i2c_send_byte(I2C_5, addr, MAX77621_CONTROL1_REG, reg->ctrl.ctrl1_hos); - i2c_send_byte(I2C_5, addr, MAX77621_CONTROL2_REG, reg->ctrl.ctrl2_hos); + i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL1, reg->ctrl.ctrl1_hos); + i2c_send_byte(I2C_5, addr, MAX77621_REG_CONTROL2, reg->ctrl.ctrl2_hos); } } diff --git a/bdk/power/max7762x.h b/bdk/power/max7762x.h index 3478530d..a9a6ba9e 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 @@ -58,22 +66,22 @@ #define REGULATOR_LDO6 10 #define REGULATOR_LDO7 11 #define REGULATOR_LDO8 12 -#define REGULATOR_CPU0 13 -#define REGULATOR_GPU0 14 -#define REGULATOR_CPU1 15 -//#define REGULATOR_GPU1 16 -//#define REGULATOR_GPU1 17 -#define REGULATOR_MAX 15 +#define REGULATOR_CPU0 13 // T210 CPU. +#define REGULATOR_GPU0 14 // T210 CPU. +#define REGULATOR_CPU1 15 // T210B01 CPU. +#define REGULATOR_RAM1 16 // T210B01 RAM for PHASE211. +//#define REGULATOR_GPU1 17 // T210B01 CPU. +#define REGULATOR_MAX REGULATOR_RAM1 #define MAX77621_CPU_I2C_ADDR 0x1B #define MAX77621_GPU_I2C_ADDR 0x1C -#define MAX77621_VOUT_REG 0x00 -#define MAX77621_VOUT_DVS_REG 0x01 -#define MAX77621_CONTROL1_REG 0x02 -#define MAX77621_CONTROL2_REG 0x03 -#define MAX77621_CHIPID1_REG 0x04 -#define MAX77621_CHIPID2_REG 0x05 +#define MAX77621_REG_VOUT 0x00 +#define MAX77621_REG_VOUT_DVS 0x01 +#define MAX77621_REG_CONTROL1 0x02 +#define MAX77621_REG_CONTROL2 0x03 +#define MAX77621_REG_CHIPID1 0x04 +#define MAX77621_REG_CHIPID2 0x05 /* MAX77621_VOUT_DVC_DVS */ #define MAX77621_DVC_DVS_VOLT_MASK 0x7F @@ -106,11 +114,10 @@ #define MAX77621_INDUCTOR_PLUS_60_PER 3 #define MAX77621_INDUCTOR_MASK 3 -#define MAX77621_CKKADV_TRIP_75mV_PER_US 0x0 -#define MAX77621_CKKADV_TRIP_150mV_PER_US BIT(2) -#define MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS BIT(3) -#define MAX77621_CKKADV_TRIP_DISABLE (BIT(2) | BIT(3)) -#define MAX77621_CKKADV_TRIP_MASK (BIT(2) | BIT(3)) +#define MAX77621_CKKADV_TRIP_75mV_PER_US (0 << 2) +#define MAX77621_CKKADV_TRIP_150mV_PER_US (1u << 2) +#define MAX77621_CKKADV_TRIP_DISABLE (3u << 2) +#define MAX77621_CKKADV_TRIP_MASK (3u << 2) #define MAX77621_FT_ENABLE BIT(4) #define MAX77621_DISCH_ENABLE BIT(5) @@ -118,18 +125,17 @@ #define MAX77621_T_JUNCTION_120 BIT(7) #define MAX77621_CPU_CTRL1_POR_DEFAULT (MAX77621_RAMP_50mV_PER_US) -#define MAX77621_CPU_CTRL1_HOS_DEFAULT (MAX77621_AD_ENABLE | \ - MAX77621_NFSR_ENABLE | \ - MAX77621_SNS_ENABLE | \ +#define MAX77621_CPU_CTRL1_HOS_DEFAULT (MAX77621_AD_ENABLE | \ + MAX77621_NFSR_ENABLE | \ + MAX77621_SNS_ENABLE | \ MAX77621_RAMP_12mV_PER_US) -#define MAX77621_CPU_CTRL2_POR_DEFAULT (MAX77621_T_JUNCTION_120 | \ - MAX77621_FT_ENABLE | \ - MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS | \ - MAX77621_CKKADV_TRIP_150mV_PER_US | \ +#define MAX77621_CPU_CTRL2_POR_DEFAULT (MAX77621_T_JUNCTION_120 | \ + MAX77621_FT_ENABLE | \ + MAX77621_CKKADV_TRIP_DISABLE | \ MAX77621_INDUCTOR_NOMINAL) -#define MAX77621_CPU_CTRL2_HOS_DEFAULT (MAX77621_T_JUNCTION_120 | \ - MAX77621_WDTMR_ENABLE | \ - MAX77621_CKKADV_TRIP_75mV_PER_US | \ +#define MAX77621_CPU_CTRL2_HOS_DEFAULT (MAX77621_T_JUNCTION_120 | \ + MAX77621_WDTMR_ENABLE | \ + MAX77621_CKKADV_TRIP_75mV_PER_US | \ MAX77621_INDUCTOR_NOMINAL) #define MAX77621_CTRL_HOS_CFG 0 @@ -137,7 +143,7 @@ int max77620_regulator_get_status(u32 id); int max77620_regulator_config_fps(u32 id); -int max7762x_regulator_set_voltage(u32 id, u32 mv); +int max7762x_regulator_set_voltage(u32 id, u32 uv); int max7762x_regulator_enable(u32 id, bool enable); void max77620_config_gpio(u32 id, bool enable); void max77620_config_default(); diff --git a/bdk/power/max77812.h b/bdk/power/max77812.h index 89c3baf4..cdd28998 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 @@ -66,22 +66,23 @@ #define MAX77812_REG_M2_VOUT_S 0x2C #define MAX77812_REG_M3_VOUT_S 0x2D #define MAX77812_REG_M4_VOUT_S 0x2E -#define MAX77812_REG_M1_CFG 0x2F -#define MAX77812_REG_M2_CFG 0x30 -#define MAX77812_REG_M3_CFG 0x31 -#define MAX77812_REG_M4_CFG 0x32 -#define MAX77812_REG_GLB_CFG1 0x33 -#define MAX77812_REG_GLB_CFG2 0x34 +#define MAX77812_REG_M1_CFG 0x2F // HOS: M1_ILIM - 7.2A/4.8A. +#define MAX77812_REG_M2_CFG 0x30 // HOS: M2_ILIM - 7.2A/4.8A. +#define MAX77812_REG_M3_CFG 0x31 // HOS: M3_ILIM - 7.2A/4.8A. +#define MAX77812_REG_M4_CFG 0x32 // HOS: M4_ILIM - 7.2A/4.8A. +#define MAX77812_REG_GLB_CFG1 0x33 // HOS: B_SD_SR/B_SS_SR - 5mV/us. +#define MAX77812_REG_GLB_CFG2 0x34 // HOS: B_RD_SR/B_RU_SR - 5mV/us #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_CFG5 0x37 // HOS: 0x3E. Unmasked write. +#define MAX77812_REG_GLB_CFG6 0x38 // HOS: 0x90. Unmasked write. #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_GLB_CFG8 0x3A // HOS: 0x3A. Unmasked write. + +#define MAX77812_REG_PROT_ACCESS 0xFD // 0x00: Lock, 0x5A: Unlock. +#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 379f7a61..557dae98 100644 --- a/bdk/power/regulator_5v.c +++ b/bdk/power/regulator_5v.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2021 CTCaer + * Copyright (c) 2019-2023 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,38 +27,31 @@ static bool usb_src = false; void regulator_5v_enable(u8 dev) { + bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210; + // The power supply selection from battery or USB is automatic. if (!reg_5v_dev) { // 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); - - // 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) + gpio_direction_output(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH); + + // Only Icosa has USB 5V VBUS rails. + if (tegra_t210) { // 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); + gpio_direction_output(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW); } - // 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. + // Make sure GPIO IO 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. - // 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; @@ -66,36 +59,23 @@ void regulator_5v_enable(u8 dev) void regulator_5v_disable(u8 dev) { + bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210; + reg_5v_dev &= ~dev; if (!reg_5v_dev) { // 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; - - // 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) + + // Only Icosa has USB 5V VBUS rails. + if (tegra_t210) { // 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. - 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. - } } } @@ -106,10 +86,8 @@ bool regulator_5v_get_dev_enabled(u8 dev) void regulator_5v_usb_src_enable(bool enable) { - // 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) + // Only for Icosa. + if (hw_get_chip_id() != GP_HIDREV_MAJOR_T210) return; if (enable && !usb_src) diff --git a/bdk/rtc/max77620-rtc.c b/bdk/rtc/max77620-rtc.c index 164df754..ab01b408 100644 --- a/bdk/rtc/max77620-rtc.c +++ b/bdk/rtc/max77620-rtc.c @@ -1,7 +1,7 @@ /* * PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC * - * Copyright (c) 2018-2019 CTCaer + * Copyright (c) 2018-2022 CTCaer * Copyright (c) 2019 shchmue * * This program is free software; you can redistribute it and/or modify it @@ -19,7 +19,14 @@ #include #include -#include +#include +#include +#include + +void max77620_rtc_prep_read() +{ + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE); +} void max77620_rtc_get_time(rtc_time_t *time) { @@ -35,7 +42,7 @@ void max77620_rtc_get_time(rtc_time_t *time) // Get time. time->sec = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_SEC_REG) & 0x7F; time->min = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MIN_REG) & 0x7F; - u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG); + u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG); time->hour = hour & 0x1F; if (!(val & MAX77620_RTC_24H) && (hour & MAX77620_RTC_HOUR_PM_MASK)) @@ -53,7 +60,7 @@ void max77620_rtc_get_time(rtc_time_t *time) } // Get date. - time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f; + time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f; time->month = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MONTH_REG) & 0xF) - 1; time->year = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_YEAR_REG) & 0x7F) + 2000; } @@ -64,6 +71,7 @@ void max77620_rtc_stop_alarm() // Update RTC regs from RTC clock. i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE); + msleep(16); // Stop alarm for both ALARM1 and ALARM2. Horizon uses ALARM2. for (int i = 0; i < (MAX77620_RTC_NR_TIME_REGS * 2); i++) @@ -82,9 +90,9 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time) u32 tmp, edays, year, month, day; // Set time. - time->sec = epoch % 60; + time->sec = epoch % 60; epoch /= 60; - time->min = epoch % 60; + time->min = epoch % 60; epoch /= 60; time->hour = epoch % 24; epoch /= 24; @@ -99,14 +107,14 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time) day = edays - month * 30 - month * 601 / 1000; // Month/Year offset. - if(month < 14) + if (month < 14) { year -= 4716; month--; } else { - year -= 4715; + year -= 4715; month -= 13; } @@ -129,13 +137,13 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time) month = time->month; // Month/Year offset. - if(month < 3) + if (month < 3) { month += 12; year--; } - epoch = (365 * year) + (year >> 2) - (year / 100) + (year / 400); // Years to days. + epoch = (365 * year) + (year >> 2) - (year / 100) + (year / 400); // Years to days. epoch += (30 * month) + (3 * (month + 1) / 5) + time->day; // Months to days. epoch -= 719561; // Epoch time is 1/1/1970. @@ -145,3 +153,45 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time) return epoch; } + +void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr) +{ + max77620_rtc_stop_alarm(); + + // Set reboot reason. + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_YEAR_REG, rr->enc.val1); + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_YEAR_REG, rr->enc.val2); + + // Set reboot reason magic. + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG, RTC_REBOOT_REASON_MAGIC); + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG, RTC_REBOOT_REASON_MAGIC); + + // Update RTC clock from RTC regs. + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE); + msleep(16); +} + +bool max77620_rtc_get_reboot_reason(rtc_reboot_reason_t *rr) +{ + u8 magic[2]; + + // Get reboot reason magic. + magic[0] = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG); + magic[1] = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG); + + // Magic must be correct and match on both registers. + if (magic[0] != RTC_REBOOT_REASON_MAGIC || magic[0] != magic[1]) + return false; + + // Reboot reason setter is expected to have updated the actual regs already. + rr->enc.val1 = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_YEAR_REG); + rr->enc.val2 = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_YEAR_REG); + + // Clear magic and update actual regs. + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_WEEKDAY_REG, 0); + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM2_WEEKDAY_REG, 0); + i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE); + + // Return reboot reason. False if [config] was selected. + return true; +} diff --git a/bdk/rtc/max77620-rtc.h b/bdk/rtc/max77620-rtc.h index 93b24c40..b0d616dc 100644 --- a/bdk/rtc/max77620-rtc.h +++ b/bdk/rtc/max77620-rtc.h @@ -1,7 +1,7 @@ /* * PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC * - * 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, @@ -25,6 +25,8 @@ #define MAX77620_RTC_NR_TIME_REGS 7 +#define MAX77620_RTC_RTCINT_REG 0x00 +#define MAX77620_RTC_RTCINTM_REG 0x01 #define MAX77620_RTC_CONTROLM_REG 0x02 #define MAX77620_RTC_CONTROL_REG 0x03 #define MAX77620_RTC_BIN_FORMAT BIT(0) @@ -34,6 +36,9 @@ #define MAX77620_RTC_WRITE_UPDATE BIT(0) #define MAX77620_RTC_READ_UPDATE BIT(4) +#define MAX77620_RTC_UPDATE1_REG 0x05 +#define MAX77620_RTC_RTCSMPL_REG 0x06 + #define MAX77620_RTC_SEC_REG 0x07 #define MAX77620_RTC_MIN_REG 0x08 #define MAX77620_RTC_HOUR_REG 0x09 @@ -69,9 +74,45 @@ typedef struct _rtc_time_t { u16 year; } rtc_time_t; +#define RTC_REBOOT_REASON_MAGIC 0x77 // 7-bit reg. + +enum { + REBOOT_REASON_NOP = 0, // Use [config]. + REBOOT_REASON_SELF = 1, // Use autoboot_idx/autoboot_list. + REBOOT_REASON_MENU = 2, // Force menu. + REBOOT_REASON_UMS = 3, // Force selected UMS partition. + REBOOT_REASON_REC = 4, // Set PMC_SCRATCH0_MODE_RECOVERY and reboot to self. + REBOOT_REASON_PANIC = 5 // Inform bootloader that panic occured if T210B01. +}; + +typedef struct _rtc_rr_decoded_t +{ + u16 reason:4; + u16 autoboot_idx:4; + u16 autoboot_list:1; + u16 ums_idx:3; +} rtc_rr_decoded_t; + +typedef struct _rtc_rr_encoded_t +{ + u16 val1:6; // 6-bit reg. + u16 val2:6; // 6-bit reg. +} rtc_rr_encoded_t; + +typedef struct _rtc_reboot_reason_t +{ + union { + rtc_rr_decoded_t dec; + rtc_rr_encoded_t enc; + }; +} rtc_reboot_reason_t; + +void max77620_rtc_prep_read(); void max77620_rtc_get_time(rtc_time_t *time); void max77620_rtc_stop_alarm(); void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time); -u32 max77620_rtc_date_to_epoch(const rtc_time_t *time); +u32 max77620_rtc_date_to_epoch(const rtc_time_t *time); +void max77620_rtc_set_reboot_reason(rtc_reboot_reason_t *rr); +bool max77620_rtc_get_reboot_reason(rtc_reboot_reason_t *rr); #endif /* _MFD_MAX77620_RTC_H_ */ diff --git a/bdk/sec/se.c b/bdk/sec/se.c index 92767b9a..4286282c 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,13 +18,13 @@ #include #include "se.h" -#include "se_t210.h" #include #include #include +#include #include +#include #include -#include typedef struct _se_ll_t { @@ -35,8 +33,8 @@ 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_src, ll_dst; +se_ll_t *ll_src_ptr, *ll_dst_ptr; // Must be u32 aligned. static void _gf256_mul_x(void *block) { @@ -72,92 +70,108 @@ static void _gf256_mul_x_le(void *block) static void _se_ll_init(se_ll_t *ll, u32 addr, u32 size) { - ll->num = 0; + ll->num = 0; ll->addr = addr; ll->size = size; } -static void _se_ll_set(se_ll_t *dst, se_ll_t *src) +static void _se_ll_set(se_ll_t *src, se_ll_t *dst) { - 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_ptr) + { + 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_ptr->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_finalize() +{ + int res = _se_wait(); + + // Invalidate data after OP is done. + bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false); + + ll_src_ptr = NULL; + ll_dst_ptr = NULL; + + return res; +} + static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot) { - ll_dst = NULL; - ll_src = NULL; + ll_src_ptr = NULL; + ll_dst_ptr = NULL; - if (dst) + if (src) { - ll_dst = (se_ll_t *)malloc(sizeof(se_ll_t)); - _se_ll_init(ll_dst, (u32)dst, dst_size); + ll_src_ptr = &ll_src; + _se_ll_init(ll_src_ptr, (u32)src, src_size); } - if (src) + if (dst) { - ll_src = (se_ll_t *)malloc(sizeof(se_ll_t)); - _se_ll_init(ll_src, (u32)src, src_size); + ll_dst_ptr = &ll_dst; + _se_ll_init(ll_dst_ptr, (u32)dst, dst_size); } - _se_ll_set(ll_dst, ll_src); + _se_ll_set(ll_src_ptr, ll_dst_ptr); SE(SE_ERR_STATUS_REG) = SE(SE_ERR_STATUS_REG); SE(SE_INT_STATUS_REG) = SE(SE_INT_STATUS_REG); - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); + // Flush data before starting OP. + bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false); SE(SE_OPERATION_REG) = op; if (is_oneshot) - { - int res = _se_wait(); - - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); - - if (src) - free(ll_src); - if (dst) - free(ll_dst); - - return res; - } + return _se_execute_finalize(); return 1; } -static int _se_execute_finalize() -{ - int res = _se_wait(); - - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); - - if (ll_src) - { - free(ll_src); - ll_src = NULL; - } - if (ll_dst) - { - free(ll_dst); - ll_dst = NULL; - } - - return res; -} - static int _se_execute_oneshot(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size) { return _se_execute(op, dst, dst_size, src, src_size, true); @@ -168,8 +182,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr if (!src || !dst) return 0; - u8 *block = (u8 *)malloc(SE_AES_BLOCK_SIZE); - memset(block, 0, SE_AES_BLOCK_SIZE); + u8 *block = (u8 *)calloc(1, SE_AES_BLOCK_SIZE); SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1; @@ -194,72 +207,12 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags) { if (flags & SE_RSA_KEY_TBL_DIS_KEY_ACCESS_FLAG) SE(SE_RSA_KEYTABLE_ACCESS_REG + 4 * rs) = - (((flags >> 4) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) |(flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG)) ^ + (((flags >> 4) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) | (flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG)) ^ SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_USE_FLAG; if (flags & SE_RSA_KEY_LOCK_FLAG) 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 +226,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 +238,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,10 +281,11 @@ 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); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); + SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1; SE(SE_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst) | SE_KEYTABLE_DST_WORD_QUAD(KEYS_0_3); @@ -365,14 +313,14 @@ int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, if (enc) { SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | - SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | + SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP); } else { SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) | - SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) | + SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM); } SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1; return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size); @@ -387,8 +335,9 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s { SE(SE_SPARE_REG) = SE_ECO(SE_ERRATA_FIX_ENABLE); SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | - SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_CNTN(1); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | + SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | + SE_CRYPTO_CTR_CNTN(1); _se_aes_ctr_set(ctr); u32 src_size_aligned = src_size & 0xFFFFFFF0; @@ -409,89 +358,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() -{ - static bool initialized = false; - - 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) +int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize) { - 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); + int res = 0; + u8 *tweak = (u8 *)malloc(SE_AES_BLOCK_SIZE); + u8 *pdst = (u8 *)dst; + u8 *psrc = (u8 *)src; - u32 num_blocks = size >> 4; - u32 aligned_size = num_blocks << 4; - if (num_blocks) + // Generate tweak. + for (int i = 0xF; i >= 0; i--) { - SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 1; - if (!_se_execute_oneshot(SE_OP_START, dst, aligned_size, NULL, 0)) - return 0; + tweak[i] = sec & 0xFF; + sec >>= 8; } - if (size > aligned_size) - return _se_execute_one_block(SE_OP_START, dst + aligned_size, size - aligned_size, NULL, 0); - return 1; -} + if (!se_aes_crypt_block_ecb(tweak_ks, CORE_ENCRYPT, tweak, tweak)) + goto out; -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); + // We are assuming a 0x10-aligned sector size in this implementation. + 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; + } - 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; + res = 1; - return 1; +out:; + free(tweak); + return res; } -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_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) { - u8 tweak[0x10]; - u8 orig_tweak[0x10]; u32 *pdst = (u32 *)dst; u32 *psrc = (u32 *)src; u32 *ptweak = (u32 *)tweak; - //Generate tweak. - for (int i = 0xF; i >= 0; i--) + if (regen_tweak) { - tweak[i] = sec & 0xFF; - sec >>= 8; + for (int i = 0xF; i >= 0; i--) + { + tweak[i] = sec & 0xFF; + sec >>= 8; + } + if (!se_aes_crypt_block_ecb(tweak_ks, CORE_ENCRYPT, tweak, tweak)) + return 0; } - if (!se_aes_crypt_block_ecb(tweak_ks, 1, tweak, tweak)) - return 0; - memcpy(orig_tweak, tweak, 0x10); + // 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); - // We are assuming a 0x10-aligned sector size in this implementation. - for (u32 i = 0; i < sec_size / 0x10; i++) + 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 +435,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,13 +447,13 @@ 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; @@ -668,7 +597,7 @@ int se_calc_sha256_finalize(void *hash, u32 *msg_left) // Copy output hash. for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++) - hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i << 2))); + hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4))); memcpy(hash, hash32, SE_SHA_256_SIZE); return res; @@ -718,74 +647,20 @@ out:; 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) +int se_gen_prng128(void *dst) { - if (dst_size <= 0 || buf_size < 0x43 || label_digest_size != 0x20) - return 0; - - bool is_valid = buf[0] == 0; + // 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; - 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); + SE(SE_CRYPTO_BLOCK_COUNT_REG) = (16 >> 4) - 1; - 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) @@ -793,9 +668,9 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize) u8 *aligned_buf = (u8 *)ALIGN((u32)buf, 0x40); // Set Secure Random Key. - SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); - SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_FORCE_RESEED); + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); + SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_FORCE_RESEED); SE(SE_CRYPTO_LAST_BLOCK) = 0; _se_execute_oneshot(SE_OP_START, NULL, 0, NULL, 0); @@ -805,7 +680,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize) for (u32 i = 0; i < SE_AES_KEYSLOT_COUNT; i++) { SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) | - SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_0_3); + SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_0_3); SE(SE_CRYPTO_LAST_BLOCK) = 0; _se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0); @@ -814,7 +689,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize) if (keysize > SE_KEY_128_SIZE) { SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) | - SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_4_7); + SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_4_7); SE(SE_CRYPTO_LAST_BLOCK) = 0; _se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0); @@ -841,6 +716,6 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize) // Decrypt context. se_aes_key_clear(3); se_aes_key_set(3, srk, SE_KEY_128_SIZE); - se_aes_crypt_cbc(3, 0, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize); + se_aes_crypt_cbc(3, CORE_DECRYPT, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize); se_aes_key_clear(3); } diff --git a/bdk/sec/se.h b/bdk/sec/se.h index a52fd534..8787a292 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_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); +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_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); +int se_gen_prng128(void *dst); #endif diff --git a/bdk/sec/se_t210.h b/bdk/sec/se_t210.h index 0233e1d0..fa7b0fb1 100644 --- a/bdk/sec/se_t210.h +++ b/bdk/sec/se_t210.h @@ -301,6 +301,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 adf5ac20..306f9dcb 100644 --- a/bdk/sec/tsec.c +++ b/bdk/sec/tsec.c @@ -20,20 +20,23 @@ #include "tsec.h" #include "tsec_t210.h" +#include +#include +#include +#include #include #include #include #include +#include #include -#include -#include -#include -#include +#include // #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() { @@ -55,17 +58,18 @@ static int _tsec_dma_pa_to_internal_100(int not_imem, int i_offset, int pa_offse else cmd = TSEC_DMATRFCMD_IMEM; // DMA IMEM (Instruction memmory) - TSEC(TSEC_DMATRFMOFFS) = i_offset; + TSEC(TSEC_DMATRFMOFFS) = i_offset; TSEC(TSEC_DMATRFFBOFFS) = pa_offset; - TSEC(TSEC_DMATRFCMD) = cmd; + TSEC(TSEC_DMATRFCMD) = cmd; 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; @@ -73,30 +77,42 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL); // Enable clocks. - clock_enable_host1x(); - usleep(2); clock_enable_tsec(); clock_enable_sor_safe(); clock_enable_sor0(); clock_enable_sor1(); clock_enable_kfuse(); - kfuse_wait_ready(); - //Configure Falcon. + // Disable AHB aperture. + mc_disable_ahb_redirect(); + + 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(); + } + + // Configure Falcon. TSEC(TSEC_DMACTL) = 0; TSEC(TSEC_IRQMSET) = TSEC_IRQMSET_EXT(0xFF) | - TSEC_IRQMSET_WDTMR | - TSEC_IRQMSET_HALT | - TSEC_IRQMSET_EXTERR | - TSEC_IRQMSET_SWGEN0 | + TSEC_IRQMSET_WDTMR | + TSEC_IRQMSET_HALT | + TSEC_IRQMSET_EXTERR | + TSEC_IRQMSET_SWGEN0 | TSEC_IRQMSET_SWGEN1; TSEC(TSEC_IRQDEST) = TSEC_IRQDEST_EXT(0xFF) | - TSEC_IRQDEST_HALT | - TSEC_IRQDEST_EXTERR | - TSEC_IRQDEST_SWGEN0 | + TSEC_IRQDEST_HALT | + TSEC_IRQDEST_EXTERR | + TSEC_IRQDEST_SWGEN0 | TSEC_IRQDEST_SWGEN1; TSEC(TSEC_ITFEN) = TSEC_ITFEN_CTXEN | TSEC_ITFEN_MTHDEN; if (!_tsec_dma_wait_idle()) @@ -105,14 +121,15 @@ 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 +142,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,21 +175,21 @@ 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; + mc[MC_IRAM_TOM / 4] = DRAM_START; smmu_map(pdir, MC_BASE, (u32)mc, 1, _READABLE | _NONSECURE); // IRAM iram = page_alloc(0x30); memcpy(iram, tsec_ctxt->pkg1, 0x30000); // PKG1.1 magic offset. - pkg11_magic_off = (u32 *)(iram + (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,17 +197,17 @@ 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_STATUS) = 0; TSEC(TSEC_BOOTKEYVER) = 1; // HOS uses key version 1. - TSEC(TSEC_BOOTVEC) = 0; - TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU; + 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]; + u32 timeout = get_tmr_us() + 125000; u32 key[16] = {0}; u32 kidx = 0; @@ -205,7 +222,7 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) } // Failsafe. - if ((u32)get_tmr_us() - start > 125000) + if ((u32)get_tmr_us() > timeout) break; } @@ -257,27 +274,26 @@ 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); buf[1] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB); buf[2] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB); buf[3] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB); - SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB) = 0; + SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB) = 0; SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB) = 0; - SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB) = 0; - SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 0; + SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB) = 0; + SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 0; memcpy(tsec_keys, &buf, SE_KEY_128_SIZE); } -out_free:; +out_free: free(fwbuf); -out:; - - //Disable clocks. +out: + // Disable clocks. clock_disable_kfuse(); clock_disable_sor1(); clock_disable_sor0(); @@ -286,5 +302,10 @@ out:; bpmp_mmu_enable(); bpmp_clk_rate_set(prev_fid); +#ifdef BDK_MC_ENABLE_AHB_REDIRECT + // Re-enable AHB aperture. + mc_enable_ahb_redirect(); +#endif + return res; } diff --git a/bdk/sec/tsec.h b/bdk/sec/tsec.h index 274b6e72..c9851a5a 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, @@ -22,30 +22,41 @@ #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]; + 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 00000000..4df80ebe --- /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 00000000..dc9d0c58 --- /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/bpmp.c b/bdk/soc/bpmp.c index fc0e4128..5a33f4b1 100644 --- a/bdk/soc/bpmp.c +++ b/bdk/soc/bpmp.c @@ -1,7 +1,7 @@ /* * BPMP-Lite Cache/MMU and Frequency driver for Tegra X1 * - * Copyright (c) 2019-2021 CTCaer + * Copyright (c) 2019-2023 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,9 +18,9 @@ #include #include +#include #include #include -#include #define BPMP_MMU_CACHE_LINE_SIZE 0x20 @@ -134,7 +134,7 @@ void bpmp_mmu_maintenance(u32 op, bool force) // This is a blocking operation. BPMP_CACHE_CTRL(BPMP_CACHE_MAINT_REQ) = MAINT_REQ_WAY_BITMAP(0xF) | op; - while(!(BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT) & INT_MAINT_DONE)) + while (!(BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT) & INT_MAINT_DONE)) ; BPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT); @@ -150,8 +150,8 @@ void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply) if (entry->enable) { mmu_entry->start_addr = ALIGN(entry->start_addr, BPMP_MMU_CACHE_LINE_SIZE); - mmu_entry->end_addr = ALIGN_DOWN(entry->end_addr, BPMP_MMU_CACHE_LINE_SIZE); - mmu_entry->attr = entry->attr; + mmu_entry->end_addr = ALIGN_DOWN(entry->end_addr, BPMP_MMU_CACHE_LINE_SIZE); + mmu_entry->attr = entry->attr; BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) |= BIT(idx); @@ -166,9 +166,9 @@ void bpmp_mmu_enable() return; // Init BPMP MMU. - BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_INIT; + BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_INIT; BPMP_CACHE_CTRL(BPMP_CACHE_MMU_FALLBACK_ENTRY) = MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC; // RWX for non-defined regions. - BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CFG) = MMU_CFG_SEQ_EN | MMU_CFG_TLB_EN | MMU_CFG_ABORT_STORE_LAST; + BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CFG) = MMU_CFG_SEQ_EN | MMU_CFG_TLB_EN | MMU_CFG_ABORT_STORE_LAST; // Init BPMP MMU entries. BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) = 0; @@ -206,6 +206,7 @@ void bpmp_mmu_disable() const u8 pll_divn[] = { 0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB. 85, // BPMP_CLK_HIGH_BOOST: 544MHz 33% - 136MHz APB. + 88, // BPMP_CLK_HIGH2_BOOST: 563MHz 38% - 141MHz APB. 90, // BPMP_CLK_SUPER_BOOST: 576MHz 41% - 144MHz APB. 92 // BPMP_CLK_HYPER_BOOST: 589MHz 44% - 147MHz APB. // Do not use for public releases! diff --git a/bdk/soc/bpmp.h b/bdk/soc/bpmp.h index 0f80150b..0c55147c 100644 --- a/bdk/soc/bpmp.h +++ b/bdk/soc/bpmp.h @@ -1,7 +1,7 @@ /* * BPMP-Lite Cache/MMU and Frequency driver for Tegra X1 * - * Copyright (c) 2019-2021 CTCaer + * Copyright (c) 2019-2023 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, @@ -47,12 +47,14 @@ typedef enum { BPMP_CLK_NORMAL, // 408MHz 0% - 136MHz APB. BPMP_CLK_HIGH_BOOST, // 544MHz 33% - 136MHz APB. + BPMP_CLK_HIGH2_BOOST, // 563MHz 38% - 141MHz APB. BPMP_CLK_SUPER_BOOST, // 576MHz 41% - 144MHz APB. BPMP_CLK_HYPER_BOOST, // 589MHz 44% - 147MHz APB. //BPMP_CLK_DEV_BOOST, // 608MHz 49% - 152MHz APB. BPMP_CLK_MAX } bpmp_freq_t; +#define BPMP_CLK_LOWEST_BOOST BPMP_CLK_HIGH2_BOOST #define BPMP_CLK_LOWER_BOOST BPMP_CLK_SUPER_BOOST #define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST diff --git a/bdk/soc/ccplex.c b/bdk/soc/ccplex.c index 7d2f4b63..37ce73d5 100644 --- a/bdk/soc/ccplex.c +++ b/bdk/soc/ccplex.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,6 +15,7 @@ * along with this program. If not, see . */ +#include #include #include #include @@ -51,7 +52,7 @@ void _ccplex_enable_power_t210b01() void ccplex_boot_cpu0(u32 entry) { // Set ACTIVE_CLUSER to FAST. - FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE; + FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= ~CLUSTER_CTRL_ACTIVE_SLOW; if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210) _ccplex_enable_power_t210(); @@ -62,12 +63,12 @@ void ccplex_boot_cpu0(u32 entry) // Configure MSELECT source and enable clock to 102MHz. CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_MSELECT); + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_MSELECT); // Configure initial CPU clock frequency and enable clock. CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888; // PLLX_OUT0_LJ. CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG); + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG); clock_enable_coresight(); @@ -81,9 +82,9 @@ void ccplex_boot_cpu0(u32 entry) // Enable CPU0 rail. pmc_enable_partition(POWER_RAIL_CE0, ENABLE); - // Request and wait for RAM repair. - FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1; - while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & 2)) + // Request and wait for RAM repair. Needed for the Fast cluster. + FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = RAM_REPAIR_REQ; + while (!(FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) & RAM_REPAIR_STS)) ; EXCP_VEC(EVP_CPU_RESET_VECTOR) = 0; @@ -91,6 +92,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); @@ -99,7 +101,7 @@ void ccplex_boot_cpu0(u32 entry) // MC(MC_TZ_SECURITY_CTRL) = 1; // Clear MSELECT reset. - CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT); + CLOCK(CLK_RST_CONTROLLER_RST_DEV_V_CLR) = BIT(CLK_V_MSELECT); // Clear NONCPU reset. CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000; // Clear CPU0 reset. diff --git a/bdk/soc/clock.c b/bdk/soc/clock.c index f4d9e92c..520bdd6a 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-2023 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,9 +17,10 @@ #include #include +#include +#include #include #include -#include typedef struct _clock_osc_t { @@ -59,46 +60,65 @@ static const clock_t _clock_i2c[] = { }; static clock_t _clock_se = { - CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, 0 // 408MHz. + CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, 0 // 408MHz. Default: 408MHz. Max: 627.2 MHz. }; - static clock_t _clock_tzram = { - CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, 0 + CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, 0 }; - static clock_t _clock_host1x = { - CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, 3 // 163.2MHz. + CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, 3 // 163.2MHz. Max: 408MHz. }; static clock_t _clock_tsec = { - CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, 2 // 204MHz. + CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, 2 // 204MHz. Max: 408MHz. +}; +static clock_t _clock_nvdec = { + CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC, CLK_Y_NVDEC, 4, 0 // 408 MHz. Max: 716.8/979.2MHz. +}; +static clock_t _clock_nvjpg = { + CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, 0 // 408 MHz. Max: 627.2/652.8MHz. +}; +static clock_t _clock_vic = { + CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, 0 // 408 MHz. Max: 627.2/652.8MHz. }; static clock_t _clock_sor_safe = { - CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, 0 + CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, 0 }; 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 + 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 + CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, 0 }; - static clock_t _clock_cl_dvfs = { - CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, 0 + CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, 0 }; static clock_t _clock_coresight = { - CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, 4 // 136MHz. + CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, 4 // 136MHz. }; - static clock_t _clock_pwm = { - CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, 4 // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz. + CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, 4 // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz. }; - 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 // Max: 204MHz. +}; +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. +}; +static clock_t _clock_extperiph1 = { + CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1, CLK_V_EXTPERIPH1, 0, 0 +}; +static clock_t _clock_extperiph2 = { + CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2, CLK_V_EXTPERIPH2, 2, 202 // 4.0MHz +}; void clock_enable(const clock_t *clk) { @@ -147,7 +167,9 @@ int clock_uart_use_src_div(u32 idx, u32 baud) { u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000; - if (baud == 1000000) + if (baud == 3000000) + CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 15; + else if (baud == 1000000) CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | 49; else { @@ -203,6 +225,36 @@ void clock_disable_tsec() clock_disable(&_clock_tsec); } +void clock_enable_nvdec() +{ + clock_enable(&_clock_nvdec); +} + +void clock_disable_nvdec() +{ + clock_disable(&_clock_nvdec); +} + +void clock_enable_nvjpg() +{ + clock_enable(&_clock_nvjpg); +} + +void clock_disable_nvjpg() +{ + clock_disable(&_clock_nvjpg); +} + +void clock_enable_vic() +{ + clock_enable(&_clock_vic); +} + +void clock_disable_vic() +{ + clock_disable(&_clock_vic); +} + void clock_enable_sor_safe() { clock_enable(&_clock_sor_safe); @@ -279,6 +331,86 @@ 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_extperiph1() +{ + clock_enable(&_clock_extperiph1); + + PMC(APBDEV_PMC_CLK_OUT_CNTRL) |= PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(OSC_CAR) | PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN; + usleep(5); +} + +void clock_disable_extperiph1() +{ + PMC(APBDEV_PMC_CLK_OUT_CNTRL) &= ~((PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(OSC_CAR)) | PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN); + clock_disable(&_clock_extperiph1); +} + +void clock_enable_extperiph2() +{ + clock_enable(&_clock_extperiph2); + + PMC(APBDEV_PMC_CLK_OUT_CNTRL) |= PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(OSC_CAR) | PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN; + usleep(5); +} + +void clock_disable_extperiph2() +{ + PMC(APBDEV_PMC_CLK_OUT_CNTRL) &= ~((PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(OSC_CAR)) | PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN); + clock_disable(&_clock_extperiph2); +} + +void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210) +{ + u32 plld_div = (divp << 20) | (divn << 11) | 1; + + // N divider is fractional, so N = DIVN + 1/2 + PLLD_SDM_DIN/8192. + u32 misc = 0x2D0000 | 0xFC00; // Clock enable and PLLD_SDM_DIN: -1024 -> DIVN + 0.375. + if (lowpower && tegra_t210) + misc = 0x2D0000 | 0x0AAA; // Clock enable and PLLD_SDM_DIN: 2730 -> DIVN + 0.833. + + + // Set DISP1 clock source and parent clock. + if (lowpower) + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 0x40000000; // PLLD_OUT0. + + // Set dividers and enable PLLD. + CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div; + CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = tegra_t210 ? 0x20 : 0; // Keep default PLLD_SETUP. + + // Set PLLD_SDM_DIN and enable PLLD to DSI pads. + CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = misc; +} + void clock_enable_pllx() { // Configure and enable PLLX if disabled. @@ -315,7 +447,7 @@ void clock_enable_pllc(u32 divn) // Take PLLC out of reset and set basic misc parameters. CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) = - ((CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) & 0xFFF0000F) & ~PLLC_MISC_RESET) | (0x80000 << 4); // PLLC_EXT_FRU. + ((CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) & 0xFFF0000F) & ~PLLC_MISC_RESET) | (0x8000 << 4); // PLLC_EXT_FRU. CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) |= 0xF0 << 8; // PLLC_FLL_LD_MEM. // Disable PLL and IDDQ in case they are on. @@ -342,11 +474,11 @@ void clock_enable_pllc(u32 divn) void clock_disable_pllc() { // Disable PLLC and PLLC_OUT1. - CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) &= ~(PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR); + CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) &= ~PLLC_OUT1_RSTN_CLR; + CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) = PLLC_MISC_RESET; CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) &= ~PLLCX_BASE_ENABLE; - CLOCK(CLK_RST_CONTROLLER_PLLC_BASE) |= PLLCX_BASE_REF_DIS; CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_1) |= PLLC_MISC1_IDDQ; - CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) |= PLLC_MISC_RESET; + CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) &= ~(0xFF << 8); // PLLC_FLL_LD_MEM. usleep(10); } @@ -409,9 +541,9 @@ void clock_enable_pllu() CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | PLLCX_BASE_ENABLE; // Enable. // Wait for PLL to stabilize. - u32 timeout = (u32)TMR(TIMERUS_CNTR_1US) + 1300; + u32 timeout = get_tmr_us() + 1300; while (!(CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & PLLCX_BASE_LOCK)) // PLL_LOCK. - if ((u32)TMR(TIMERUS_CNTR_1US) > timeout) + if (get_tmr_us() > timeout) break; usleep(10); @@ -421,9 +553,9 @@ void clock_enable_pllu() void clock_disable_pllu() { - CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x2E00000; // Disable PLLU USB/HSIC/ICUSB/48M. - CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x40000000; // Disable PLLU. - CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) &= ~0x20000000; // Enable reference clock. + CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x2E00000; // Disable PLLU USB/HSIC/ICUSB/48M. + CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~BIT(30); // Disable PLLU. + CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) &= ~BIT(29); // Enable reference clock. } void clock_enable_utmipll() @@ -588,10 +720,6 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val) *pclock = 25500; divisor = 30; // 16 div. break; - case 40800: - *pclock = 40800; - divisor = 18; // 10 div. - break; case 50000: *pclock = 48000; divisor = 15; // 8.5 div. @@ -600,6 +728,10 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val) *pclock = 51000; divisor = 14; // 8 div. break; + case 81600: // Originally MMC_HS50 for GC FPGA at 40800 KHz, div 18 (real 10). + *pclock = 81600; + divisor = 8; // 5 div. + break; case 100000: source = SDMMC_CLOCK_SRC_PLLC4_OUT2; *pclock = 99840; @@ -727,10 +859,10 @@ void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type) *pdivisor = 1; break; case SDHCI_TIMING_UHS_DDR50: - *pclock = 40800; - *pdivisor = 1; + *pclock = 81600; // Originally MMC_HS50 for GC FPGA at 40800 KHz, div 1. + *pdivisor = 2; break; - case SDHCI_TIMING_MMC_HS102: // Actual IO Freq: 99.84 MHz. + case SDHCI_TIMING_MMC_DDR100: // Actual IO Freq: 99.84 MHz. *pclock = 200000; *pdivisor = 2; break; diff --git a/bdk/soc/clock.h b/bdk/soc/clock.h index 32afe8dd..fa3f2419 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,7 +117,10 @@ #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_AHUB 0x3D0 +#define CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON 0x3E8 #define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1 0x3EC +#define CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2 0x3F0 #define CLK_RST_CONTROLLER_CLK_SOURCE_SYS 0x400 #define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410 #define CLK_RST_CONTROLLER_CLK_SOURCE_SE 0x42C @@ -153,8 +156,12 @@ #define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 0x65C #define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664 #define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL 0x66C +#define CLK_RST_CONTROLLER_CLK_SOURCE_VIC 0x678 #define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694 +#define CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC 0x698 +#define CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG 0x69C #define CLK_RST_CONTROLLER_CLK_SOURCE_NVENC 0x6A0 +#define CLK_RST_CONTROLLER_CLK_SOURCE_APE 0x6C0 #define CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK 0x6CC #define CLK_RST_CONTROLLER_SE_SUPER_CLK_DIVIDER 0x704 #define CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE 0x710 @@ -645,6 +652,12 @@ void clock_enable_host1x(); void clock_disable_host1x(); void clock_enable_tsec(); void clock_disable_tsec(); +void clock_enable_nvdec(); +void clock_disable_nvdec(); +void clock_enable_nvjpg(); +void clock_disable_nvjpg(); +void clock_enable_vic(); +void clock_disable_vic(); void clock_enable_sor_safe(); void clock_disable_sor_safe(); void clock_enable_sor0(); @@ -659,12 +672,25 @@ 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_extperiph1(); +void clock_disable_extperiph1(); +void clock_enable_extperiph2(); +void clock_disable_extperiph2(); + +void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210); void clock_enable_pllx(); void clock_enable_pllc(u32 divn); void clock_disable_pllc(); void clock_enable_pllu(); void clock_disable_pllu(); void clock_enable_utmipll(); + void clock_sdmmc_config_clock_source(u32 *pclock, u32 id, u32 val); void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type); int clock_sdmmc_is_not_reset_and_enabled(u32 id); diff --git a/bdk/soc/fuse.c b/bdk/soc/fuse.c index 6200f8a0..5b43d538 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-2021 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,6 +19,7 @@ #include +#include #include #include #include @@ -26,8 +27,6 @@ #include #include -extern boot_cfg_t b_cfg; - static const u32 evp_thunk_template[] = { 0xe92d0007, // STMFD SP!, {R0-R2} 0xe1a0200e, // MOV R2, LR @@ -44,12 +43,19 @@ static const u32 evp_thunk_template[] = { 0xe3822001, // ORR R2, R2, #1 0xe8bd0003, // LDMFD SP!, {R0,R1} 0xe12fff12, // BX R2 + // idx: 15: 0x001007b0, // off_1007EC DCD evp_thunk_template 0x001007f8, // off_1007F0 DCD thunk_end 0x40004c30, // off_1007F4 DCD iram_evp_thunks // thunk_end is here }; -static const u32 evp_thunk_template_len = sizeof(evp_thunk_template); + +static const u32 evp_thunk_func_offsets_t210b01[] = { + 0x0010022c, // off_100268 DCD evp_thunk_template + 0x00100174, // off_10026C DCD thunk_end + 0x40004164, // off_100270 DCD iram_evp_thunks + // thunk_end is here +}; // treated as 12bit values static const u32 hash_vals[] = {1, 2, 4, 8, 0, 3, 5, 6, 7, 9, 10, 11}; @@ -82,19 +88,26 @@ u32 fuse_read_odm_keygen_rev() u32 fuse_read_dramid(bool raw_id) { - u32 dramid = (fuse_read_odm(4) & 0xF8) >> 3; + bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210; + u32 odm4 = fuse_read_odm(4); + + u32 dramid = (odm4 & 0xF8) >> 3; + + // Get extended dram id info. + if (!tegra_t210) + dramid |= (odm4 & 0x7000) >> 7; if (raw_id) return dramid; - if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210) + if (tegra_t210) { if (dramid > 6) dramid = 0; } else { - if (dramid > 28) + if (dramid > 34) dramid = 8; } @@ -130,9 +143,7 @@ u32 fuse_read_hw_type() int fuse_set_sbk() { - // 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) + if (FUSE(FUSE_PRIVATE_KEY0) != 0xFFFFFFFF) { // Read SBK from fuses. u32 sbk[4] = { @@ -174,7 +185,8 @@ u32 fuse_read(u32 addr) void fuse_read_array(u32 *words) { - u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ? 256 : 192; + u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ? + FUSE_ARRAY_WORDS_NUM_T210B01 : FUSE_ARRAY_WORDS_NUM; for (u32 i = 0; i < array_size; i++) words[i] = fuse_read(i); @@ -184,9 +196,8 @@ static u32 _parity32_even(u32 *words, u32 count) { u32 acc = words[0]; for (u32 i = 1; i < count; i++) - { acc ^= words[i]; - } + u32 lo = ((acc & 0xffff) ^ (acc >> 16)) & 0xff; u32 hi = ((acc & 0xffff) ^ (acc >> 16)) >> 8; u32 x = hi ^ lo; @@ -202,26 +213,26 @@ static int _patch_hash_one(u32 *word) u32 bits20_31 = *word & 0xfff00000; u32 parity_bit = _parity32_even(&bits20_31, 1); u32 hash = 0; + for (u32 i = 0; i < 12; i++) { if (*word & (1 << (20 + i))) - { hash ^= hash_vals[i]; - } } + if (hash == 0) { if (parity_bit == 0) - { return 0; - } + *word ^= 1 << 24; + return 1; } + if (parity_bit == 0) - { return 3; - } + for (u32 i = 0; i < ARRAY_SIZE(hash_vals); i++) { if (hash_vals[i] == hash) @@ -230,6 +241,7 @@ static int _patch_hash_one(u32 *word) return 1; } } + return 2; } @@ -250,9 +262,7 @@ static int _patch_hash_multi(u32 *words, u32 count) for (u32 bitpos = 0; bitpos < 32; bitpos++) { if ((w >> bitpos) & 1) - { hash ^= 0x4000 + i * 32 + bitpos; - } } } } @@ -264,16 +274,14 @@ static int _patch_hash_multi(u32 *words, u32 count) if (hash == 0) { if (parity_bit == 0) - { return 0; - } + words[0] ^= 0x8000; return 1; } if (parity_bit == 0) - { return 3; - } + u32 bitcount = hash - 0x4000; if (bitcount < 16 || bitcount >= count * 32) { @@ -281,14 +289,11 @@ static int _patch_hash_multi(u32 *words, u32 count) for (u32 bitpos = 0; bitpos < 15; bitpos++) { if ((hash >> bitpos) & 1) - { num_set++; - } } if (num_set != 1) - { return 2; - } + words[0] ^= hash; return 1; } @@ -306,24 +311,30 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value)) word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE); word_count &= 0x7F; - word_addr = 191; + word_addr = FUSE_ARRAY_WORDS_NUM - 1; while (word_count) { total_read += word_count; if (total_read >= ARRAY_SIZE(words)) - { break; - } for (u32 i = 0; i < word_count; i++) + { words[i] = fuse_read(word_addr--); + // Parse extra T210B01 fuses when the difference is reached. + if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 && + word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) - + (FUSE_ARRAY_WORDS_NUM_T210B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32))) + { + word_addr = FUSE_ARRAY_WORDS_NUM_T210B01 - 1; + } + } word0 = words[0]; if (_patch_hash_multi(words, word_count) >= 2) - { return 1; - } + u32 ipatch_count = (words[0] >> 16) & 0xF; if (ipatch_count) { @@ -336,13 +347,14 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value)) ipatch(addr, data); } } + words[0] = word0; if ((word0 >> 25) == 0) break; + if (_patch_hash_one(&word0) >= 2) - { return 3; - } + word_count = word0 >> 25; } @@ -358,29 +370,44 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len) u32 total_read = 0; int evp_thunk_written = 0; void *evp_thunk_dst_addr = 0; + bool t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01; + u32 *evp_thunk_tmp = (u32 *)malloc(sizeof(evp_thunk_template)); + memcpy(evp_thunk_tmp, evp_thunk_template, sizeof(evp_thunk_template)); memset(iram_evp_thunks, 0, *iram_evp_thunks_len); + if (t210b01) + memcpy(&evp_thunk_tmp[15], evp_thunk_func_offsets_t210b01, sizeof(evp_thunk_func_offsets_t210b01)); + word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE); word_count &= 0x7F; - word_addr = 191; + word_addr = FUSE_ARRAY_WORDS_NUM - 1; while (word_count) { total_read += word_count; if (total_read >= ARRAY_SIZE(words)) - { break; - } for (u32 i = 0; i < word_count; i++) + { words[i] = fuse_read(word_addr--); + // Parse extra T210B01 fuses when the difference is reached. + if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01 && + word_addr == ((FUSE_ARRAY_WORDS_NUM - 1) - + (FUSE_ARRAY_WORDS_NUM_T210B01 - FUSE_ARRAY_WORDS_NUM) / sizeof(u32))) + { + word_addr = FUSE_ARRAY_WORDS_NUM_T210B01 - 1; + } + } word0 = words[0]; if (_patch_hash_multi(words, word_count) >= 2) { + free(evp_thunk_tmp); return 1; } + u32 ipatch_count = (words[0] >> 16) & 0xF; u32 insn_count = word_count - ipatch_count - 1; if (insn_count) @@ -389,10 +416,10 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len) { evp_thunk_dst_addr = (void *)iram_evp_thunks; - memcpy(evp_thunk_dst_addr, (void *)evp_thunk_template, evp_thunk_template_len); - evp_thunk_dst_addr += evp_thunk_template_len; + memcpy(evp_thunk_dst_addr, (void *)evp_thunk_tmp, sizeof(evp_thunk_template)); + evp_thunk_dst_addr += sizeof(evp_thunk_template); evp_thunk_written = 1; - *iram_evp_thunks_len = evp_thunk_template_len; + *iram_evp_thunks_len = sizeof(evp_thunk_template); //write32(TEGRA_EXCEPTION_VECTORS_BASE + 0x208, iram_evp_thunks); } @@ -402,16 +429,22 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len) evp_thunk_dst_addr += thunk_patch_len; *iram_evp_thunks_len += thunk_patch_len; } + words[0] = word0; if ((word0 >> 25) == 0) break; + if (_patch_hash_one(&word0) >= 2) { + free(evp_thunk_tmp); return 3; } + word_count = word0 >> 25; } + free(evp_thunk_tmp); + return 0; } @@ -423,7 +456,7 @@ bool fuse_check_patched_rcm() // Check if RCM is ipatched. u32 word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE) & 0x7F; - u32 word_addr = 191; + u32 word_addr = FUSE_ARRAY_WORDS_NUM - 1; while (word_count) { diff --git a/bdk/soc/fuse.h b/bdk/soc/fuse.h index 62fa1ff1..1b2f0432 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-2021 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, @@ -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 @@ -78,12 +82,15 @@ /*! Fuse cache registers. */ #define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x)) +#define FUSE_ARRAY_WORDS_NUM 192 +#define FUSE_ARRAY_WORDS_NUM_T210B01 256 + enum { FUSE_NX_HW_TYPE_ICOSA, FUSE_NX_HW_TYPE_IOWA, FUSE_NX_HW_TYPE_HOAG, - FUSE_NX_HW_TYPE_AULA + FUSE_NX_HW_TYPE_AULA }; enum diff --git a/bdk/soc/gpio.c b/bdk/soc/gpio.c index 5cd2ccd9..cdd61910 100644 --- a/bdk/soc/gpio.c +++ b/bdk/soc/gpio.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2019 CTCaer + * Copyright (c) 2019-2023 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, @@ -86,6 +86,19 @@ void gpio_write(u32 port, u32 pins, int high) (void)GPIO(port_offset); // Commit the write. } +void gpio_direction_input(u32 port, u32 pins) +{ + gpio_output_enable(port, pins, GPIO_OUTPUT_DISABLE); + gpio_config(port, pins, GPIO_MODE_GPIO); +} + +void gpio_direction_output(u32 port, u32 pins, int high) +{ + gpio_output_enable(port, pins, GPIO_OUTPUT_ENABLE); + gpio_config(port, pins, GPIO_MODE_GPIO); + gpio_write(port, pins, high); +} + int gpio_read(u32 port, u32 pins) { u32 port_offset = GPIO_IN_OFFSET(port); diff --git a/bdk/soc/gpio.h b/bdk/soc/gpio.h index 0c92b147..09c29cfb 100644 --- a/bdk/soc/gpio.h +++ b/bdk/soc/gpio.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2019 CTCaer + * Copyright (c) 2019-2023 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, @@ -85,6 +85,8 @@ void gpio_config(u32 port, u32 pins, int mode); void gpio_output_enable(u32 port, u32 pins, int enable); +void gpio_direction_input(u32 port, u32 pins); +void gpio_direction_output(u32 port, u32 pins, int high); void gpio_write(u32 port, u32 pins, int high); int gpio_read(u32 port, u32 pins); int gpio_interrupt_status(u32 port, u32 pins); diff --git a/bdk/soc/hw_init.c b/bdk/soc/hw_init.c index c86dc3ab..91160d08 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-2023 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,7 @@ #include #include +#include #include #include #include @@ -31,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +41,7 @@ #include #include #include -#include +#include #include #include #include @@ -71,24 +73,24 @@ u32 hw_get_chip_id() static void _config_oscillators() { CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4; // Set CLK_M_DIVISOR to 2. - SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency. - TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m. - CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength. + SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency. + TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m. + CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength. 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(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN; + 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. + 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. PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz) - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1. - CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz). + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1. + CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz). CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000; // Enable SUPER_SDIV to 1. - CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3. + CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3. } // The uart is skipped for Copper, Hoag and Calcio. Used in Icosa, Iowa and Aula. @@ -99,53 +101,39 @@ static void _config_gpios(bool nx_hoag) if (!nx_hoag) { + // Turn Joy-Con detect on. (GPIO mode and input logic for UARTB/C TX pins.) PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0; PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0; - - // Set pin mode for UARTB/C TX pins. -#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B - gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO); -#endif -#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_C - gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO); -#endif - - // Enable input logic for UARTB/C TX pins. - gpio_output_enable(GPIO_PORT_G, GPIO_PIN_0, GPIO_OUTPUT_DISABLE); - gpio_output_enable(GPIO_PORT_D, GPIO_PIN_1, GPIO_OUTPUT_DISABLE); + gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0); + gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1); } - // Set Joy-Con IsAttached direction. + // Set Joy-Con IsAttached pinmux. Shared with UARTB/UARTC TX. PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; - // Set Joy-Con IsAttached mode. - gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO); - gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO); - - // Enable input logic for Joy-Con IsAttached pins. - gpio_output_enable(GPIO_PORT_E, GPIO_PIN_6, GPIO_OUTPUT_DISABLE); - gpio_output_enable(GPIO_PORT_H, GPIO_PIN_6, GPIO_OUTPUT_DISABLE); + // Configure Joy-Con IsAttached pins. Shared with UARTB/UARTC TX. + gpio_direction_input(GPIO_PORT_E, GPIO_PIN_6); + gpio_direction_input(GPIO_PORT_H, GPIO_PIN_6); pinmux_config_i2c(I2C_1); pinmux_config_i2c(I2C_5); pinmux_config_uart(UART_A); // Configure volume up/down as inputs. - gpio_config(GPIO_PORT_X, GPIO_PIN_6, GPIO_MODE_GPIO); - gpio_config(GPIO_PORT_X, GPIO_PIN_7, GPIO_MODE_GPIO); - gpio_output_enable(GPIO_PORT_X, GPIO_PIN_6, GPIO_OUTPUT_DISABLE); - 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); + gpio_direction_input(GPIO_PORT_X, GPIO_PIN_6 | GPIO_PIN_7); + + // Configure HOME as input. (Shared with UARTB RTS). + PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; + gpio_direction_input(GPIO_PORT_Y, GPIO_PIN_1); + + // Power button can be configured for hoag here. Only SKU where it's connected. } static void _config_pmc_scratch() { PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; // Unset Debug console from Customer Option. - PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset DATA_DQ_E_IVREF EMC_PMACRO_DATA_PAD_TX_CTRL + PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset WDT_DURING_BR. PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT; } @@ -178,8 +166,9 @@ static void _mbist_workaround() I2S(I2S5_CTRL) |= I2S_CTRL_MASTER_EN; I2S(I2S5_CG) &= ~I2S_CG_SLCG_ENABLE; + // Set SLCG overrides. DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= 4; // DSC_SLCG_OVERRIDE. - VIC(0x8C) = 0xFFFFFFFF; + VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0xFFFFFFFF; usleep(2); // Set per-clock reset for APE/VIC/HOST1X/DISP1. @@ -246,9 +235,9 @@ static void _mbist_workaround() // Set child clock sources. CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF; // Disable PLLD and set reference clock and csi clock. CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= 0xFFFF3FFF; // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch. - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT. + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT. CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT. - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT. + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT. } static void _config_se_brom() @@ -263,7 +252,7 @@ static void _config_se_brom() // 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, SZ_64K); + memset((void *)TZRAM_BASE, 0, TZRAM_SIZE); PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE; SE(SE_INT_STATUS_REG) = 0x1F; // Clear all SE interrupts. @@ -291,6 +280,9 @@ static void _config_regulators(bool tegra_t210) max7762x_regulator_enable(REGULATOR_LDO2, false); sd_power_cycle_time_start = get_tmr_ms(); + // Disable LCD DVDD. + max7762x_regulator_enable(REGULATOR_LDO0, false); + i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K); i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_RSVD | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off. @@ -327,7 +319,7 @@ static void _config_regulators(bool tegra_t210) void hw_init() { - // Get Chip ID. + // Get Chip ID and SKU. bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210; bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG; @@ -360,8 +352,14 @@ void hw_init() _config_gpios(nx_hoag); #ifdef DEBUG_UART_PORT + #if (DEBUG_UART_PORT == UART_B) + gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO); + #elif (DEBUG_UART_PORT == UART_C) + gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO); + #endif + pinmux_config_uart(DEBUG_UART_PORT); clock_enable_uart(DEBUG_UART_PORT); - uart_init(DEBUG_UART_PORT, DEBUG_UART_BAUDRATE); + uart_init(DEBUG_UART_PORT, DEBUG_UART_BAUDRATE, UART_AO_TX_AO_RX); uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD); #endif @@ -378,7 +376,7 @@ void hw_init() // Initialize I2C5, mandatory for PMIC. i2c_init(I2C_5); - //! TODO: Why? Device is NFC MCU on Lite. + // Enable LDO8 on HOAG as it also powers I2C1 IO pads. if (nx_hoag) { max7762x_regulator_set_voltage(REGULATOR_LDO8, 2800000); @@ -391,35 +389,38 @@ void hw_init() // Initialize various regulators based on Erista/Mariko platform. _config_regulators(tegra_t210); - // Enable charger in case it's disabled. - bq24193_enable_charger(); - _config_pmc_scratch(); // Missing from 4.x+ // Set BPMP/SCLK to PLLP_OUT (408MHz). CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; - // Disable TZRAM shutdown control and lock the regs. + // 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. sdram_init(); bpmp_mmu_enable(); + + // Enable HOST1X used by every display module (DC, VIC, NVDEC, NVENC, TSEC, etc). + clock_enable_host1x(); } void hw_reinit_workaround(bool coreboot, u32 bl_magic) { - // Disable BPMP max clock. + bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210; + + // Scale down BPMP clock. bpmp_clk_rate_set(BPMP_CLK_NORMAL); -#ifdef NYX - // Disable temperature sensor, touchscreen, 5V regulators and Joy-Con. +#ifdef BDK_HW_EXTRA_DEINIT + // Disable temperature sensor, touchscreen, 5V regulators, Joy-Con and VIC. + vic_end(); tmp451_end(); set_fan_duty(0); touch_power_off(); @@ -427,14 +428,19 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic) regulator_5v_disable(REGULATOR_5V_ALL); #endif - // Flush/disable MMU cache and set DRAM clock to 204MHz. - bpmp_mmu_disable(); + // set DRAM clock to 204MHz. minerva_change_freq(FREQ_204); nyx_str->mtc_cfg.init_done = 0; + // Flush/disable MMU cache. + bpmp_mmu_disable(); + // Re-enable clocks to Audio Processing Engine as a workaround to hanging. - CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB); - CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE); + if (tegra_t210) + { + CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB); + CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE); + } // Do coreboot mitigations. if (coreboot) @@ -443,11 +449,9 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic) clock_disable_cl_dvfs(); - // Disable Joy-con GPIOs. + // Disable Joy-con detect in order to restore UART TX. gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO); gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO); - gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_SPIO); - gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_SPIO); // Reinstate SD controller power. PMC(APBDEV_PMC_NO_IOPOWER) &= ~(PMC_NO_IOPOWER_SDMMC1_IO_EN); @@ -463,17 +467,11 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic) gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_GPIO); display_backlight_brightness(brightness, 0); break; + case BL_MAGIC_L4TLDR_SLD: + // Do not disable display or backlight at all. + break; default: display_end(); - } - - // Enable clock to USBD and init SDMMC1 to avoid hangs with bad hw inits. - if (bl_magic == BL_MAGIC_BROKEN_HWI) - { - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_USBD); - sdmmc_init(&sd_sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, 0); - clock_disable_cl_dvfs(); - - msleep(200); + clock_disable_host1x(); } } diff --git a/bdk/soc/hw_init.h b/bdk/soc/hw_init.h index 4a24c335..aebb021b 100644 --- a/bdk/soc/hw_init.h +++ b/bdk/soc/hw_init.h @@ -21,7 +21,7 @@ #include #define BL_MAGIC_CRBOOT_SLD 0x30444C53 // SLD0, seamless display type 0. -#define BL_MAGIC_BROKEN_HWI 0xBAADF00D // Broken hwinit. +#define BL_MAGIC_L4TLDR_SLD 0x31444C53 // SLD1, seamless display type 1. extern u32 hw_rst_status; extern u32 hw_rst_reason; diff --git a/bdk/soc/i2c.c b/bdk/soc/i2c.c index 0906adc4..34aa666f 100644 --- a/bdk/soc/i2c.c +++ b/bdk/soc/i2c.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, @@ -18,7 +18,7 @@ #include #include -#include +#include #define I2C_PACKET_PROT_I2C BIT(4) #define I2C_HEADER_CONT_XFER BIT(15) @@ -95,9 +95,9 @@ static void _i2c_load_cfg_wait(vu32 *base) base[I2C_CONFIG_LOAD] = BIT(5) | TIMEOUT_CONFIG_LOAD | MSTR_CONFIG_LOAD; for (u32 i = 0; i < 20; i++) { - usleep(1); if (!(base[I2C_CONFIG_LOAD] & MSTR_CONFIG_LOAD)) break; + usleep(1); } } @@ -205,8 +205,8 @@ static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr) ARB_LOST | TX_FIFO_OVER | RX_FIFO_UNDER | TX_FIFO_DATA_REQ; base[I2C_INT_STATUS] = base[I2C_INT_STATUS]; - // Set device address and recv mode. - base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ; + // Set device address and send mode. + base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_WRITE; // Set recv mode. base[I2C_CNFG] = DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_WRITE; @@ -362,9 +362,9 @@ void i2c_init(u32 i2c_idx) for (u32 i = 0; i < 10; i++) { - usleep(20000); if (base[I2C_INT_STATUS] & BUS_CLEAR_DONE) break; + usleep(25); } (vu32)base[I2C_BUS_CLEAR_STATUS]; diff --git a/bdk/soc/irq.c b/bdk/soc/irq.c index e2f925ca..380cfe15 100644 --- a/bdk/soc/irq.c +++ b/bdk/soc/irq.c @@ -19,6 +19,7 @@ #include #include "irq.h" +#include #include #include #include @@ -26,6 +27,7 @@ //#define DPRINTF(...) gfx_printf(__VA_ARGS__) #define DPRINTF(...) +extern void excp_reset(); extern void irq_disable(); extern void irq_enable_cpu_irq_exceptions(); extern void irq_disable_cpu_irq_exceptions(); @@ -69,7 +71,7 @@ static void _irq_disable_and_ack_all() { u32 enabled_irqs = ICTLR(ctrl_idx, PRI_ICTLR_COP_IER); ICTLR(ctrl_idx, PRI_ICTLR_COP_IER_CLR) = enabled_irqs; - ICTLR(ctrl_idx, PRI_ICTLR_FIR_CLR) = enabled_irqs; + ICTLR(ctrl_idx, PRI_ICTLR_FIR_CLR) = enabled_irqs; } } @@ -88,10 +90,10 @@ void irq_free(u32 irq) { if (irqs[idx].irq == irq && irqs[idx].handler) { - irqs[idx].irq = 0; + irqs[idx].irq = 0; irqs[idx].handler = NULL; - irqs[idx].data = NULL; - irqs[idx].flags = 0; + irqs[idx].data = NULL; + irqs[idx].flags = 0; _irq_disable_source(irq); } @@ -106,10 +108,10 @@ static void _irq_free_all() { _irq_disable_source(irqs[idx].irq); - irqs[idx].irq = 0; + irqs[idx].irq = 0; irqs[idx].handler = NULL; - irqs[idx].data = NULL; - irqs[idx].flags = 0; + irqs[idx].data = NULL; + irqs[idx].flags = 0; } } } @@ -218,10 +220,10 @@ irq_status_t irq_request(u32 irq, irq_handler_t handler, void *data, irq_flags_t DPRINTF("Registered handler, IRQ: %d, Slot: %d\n", irq, idx); DPRINTF("Handler: %08p, Flags: %x\n", (u32)handler, flags); - irqs[idx].irq = irq; + irqs[idx].irq = irq; irqs[idx].handler = handler; - irqs[idx].data = data; - irqs[idx].flags = flags; + irqs[idx].data = data; + irqs[idx].flags = flags; _irq_enable_source(irq); @@ -270,4 +272,14 @@ void __attribute__ ((target("arm"), interrupt ("FIQ"))) fiq_handler() len--; } */ +#ifdef BDK_WATCHDOG_FIQ_ENABLE + // Set watchdog timeout status and disable WDT and its FIQ signal. + watchdog_handle(); + +#ifdef BDK_RESTART_BL_ON_WDT + // Restart bootloader. + excp_reset(); +#endif + +#endif } diff --git a/bdk/soc/pinmux.c b/bdk/soc/pinmux.c index 2601cdfe..288a4f70 100644 --- a/bdk/soc/pinmux.c +++ b/bdk/soc/pinmux.c @@ -19,10 +19,10 @@ void pinmux_config_uart(u32 idx) { - PINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0; - PINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP; + PINMUX_AUX(PINMUX_AUX_UARTX_TX(idx)) = 0; + PINMUX_AUX(PINMUX_AUX_UARTX_RX(idx)) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; PINMUX_AUX(PINMUX_AUX_UARTX_RTS(idx)) = 0; - PINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN; + PINMUX_AUX(PINMUX_AUX_UARTX_CTS(idx)) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; } void pinmux_config_i2c(u32 idx) diff --git a/bdk/soc/pinmux.h b/bdk/soc/pinmux.h index 48fcab38..070ce1e1 100644 --- a/bdk/soc/pinmux.h +++ b/bdk/soc/pinmux.h @@ -39,6 +39,7 @@ #define PINMUX_AUX_SDMMC3_DAT2 0x2C #define PINMUX_AUX_SDMMC3_DAT3 0x30 #define PINMUX_AUX_SATA_LED_ACTIVE 0x4C +#define PINMUX_AUX_GPIO_PA5_T210B01 PINMUX_AUX_SATA_LED_ACTIVE #define PINMUX_AUX_DMIC3_CLK 0xB4 #define PINMUX_AUX_DMIC3_DAT 0xB8 #define PINMUX_AUX_CAM_I2C_SCL 0xD4 @@ -46,7 +47,9 @@ #define PINMUX_AUX_UART2_TX 0xF4 #define PINMUX_AUX_UART3_TX 0x104 #define PINMUX_AUX_DAP4_DIN 0x148 +#define PINMUX_AUX_DAP4_DOUT 0x14C #define PINMUX_AUX_DAP4_SCLK 0x150 +#define PINMUX_AUX_CLK_32K_OUT 0x164 #define PINMUX_AUX_GPIO_X1_AUD 0x18C #define PINMUX_AUX_GPIO_X3_AUD 0x190 #define PINMUX_AUX_SPDIF_IN 0x1A4 @@ -57,19 +60,26 @@ #define PINMUX_AUX_AP_WAKE_NFC 0x1CC #define PINMUX_AUX_NFC_EN 0x1D0 #define PINMUX_AUX_NFC_INT 0x1D4 +#define PINMUX_AUX_CAM_RST 0x1E0 #define PINMUX_AUX_CAM1_PWDN 0x1EC #define PINMUX_AUX_CAM2_PWDN 0x1F0 +#define PINMUX_AUX_CAM1_STROBE 0x1F4 #define PINMUX_AUX_LCD_BL_PWM 0x1FC #define PINMUX_AUX_LCD_BL_EN 0x200 #define PINMUX_AUX_LCD_RST 0x204 #define PINMUX_AUX_LCD_GPIO1 0x208 #define PINMUX_AUX_LCD_GPIO2 0x20C +#define PINMUX_AUX_TOUCH_CLK 0x218 #define PINMUX_AUX_TOUCH_INT 0x220 #define PINMUX_AUX_MOTION_INT 0x224 +#define PINMUX_AUX_ALS_PROX_INT 0x228 +#define PINMUX_AUX_BUTTON_POWER_ON 0x230 #define PINMUX_AUX_BUTTON_HOME 0x240 #define PINMUX_AUX_GPIO_PE6 0x248 +#define PINMUX_AUX_GPIO_PE7 0x24C #define PINMUX_AUX_GPIO_PH6 0x250 #define PINMUX_AUX_GPIO_PK3 0x260 +#define PINMUX_AUX_GPIO_PK7 0x270 #define PINMUX_AUX_GPIO_PZ1 0x280 /* Only in T210B01 */ #define PINMUX_AUX_SDMMC2_DAT0 0x294 @@ -116,6 +126,8 @@ #define PINMUX_DRIVE_3X (2 << 13) #define PINMUX_DRIVE_4X (3 << 13) +#define PINMUX_PREEMP BIT(15) + void pinmux_config_uart(u32 idx); void pinmux_config_i2c(u32 idx); diff --git a/bdk/soc/pmc.c b/bdk/soc/pmc.c index aa86cb7e..472b22cd 100644 --- a/bdk/soc/pmc.c +++ b/bdk/soc/pmc.c @@ -16,31 +16,28 @@ #include #include +#include #include -#include void pmc_scratch_lock(pmc_sec_lock_t lock_mask) { // Lock Private key disable, Fuse write enable, MC carveout, Warmboot PA id and Warmboot address. + + // Happens on T210B01 LP0 always. if (lock_mask & PMC_SEC_LOCK_MISC) { PMC(APBDEV_PMC_SEC_DISABLE) |= 0x700FF0; // RW lock: 0-3. PMC(APBDEV_PMC_SEC_DISABLE2) |= 0xFC000000; // RW lock: 21-23. PMC(APBDEV_PMC_SEC_DISABLE3) |= 0x3F0FFF00; // RW lock: 28-33, 36-38. PMC(APBDEV_PMC_SEC_DISABLE6) |= 0xC000000; // RW lock: 85. - PMC(APBDEV_PMC_SEC_DISABLE8) |= 0xFF00FF00; // RW lock: 108-111, 116-119. - - // SE2 context. - if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) - { - PMC(APBDEV_PMC_SEC_DISABLE9) |= 0x3FF; // RW lock: 120-124. (0xB38) - PMC(APBDEV_PMC_SEC_DISABLE10) = 0xFFFFFFFF; // RW lock: 135-150. - } + // Default: 0xFF00FF00: RW lock: 108-111, 116-119. Gets locked in LP0. + PMC(APBDEV_PMC_SEC_DISABLE8) |= 0xFF005500; // W lock: 108-111, RW lock: 116-119. } + // Happens on T210B01 LP0 always. if (lock_mask & PMC_SEC_LOCK_LP0_PARAMS) { - PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF; // RW lock: 8-15, 17-20. + PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF; // RW lock: 8-15, 17-20. L4T expects 8-15 as write locked only. PMC(APBDEV_PMC_SEC_DISABLE4) |= 0x3F3FFFFF; // RW lock: 40-50, 52-54. PMC(APBDEV_PMC_SEC_DISABLE5) = 0xFFFFFFFF; // RW lock: 56-71. PMC(APBDEV_PMC_SEC_DISABLE6) |= 0xF3FFC00F; // RW lock: 72-73, 79-84, 86-87. @@ -60,6 +57,7 @@ void pmc_scratch_lock(pmc_sec_lock_t lock_mask) PMC(APBDEV_PMC_SEC_DISABLE7) |= 0xFFC00000; // RW lock: 99-103. } + // HOS specific. if (lock_mask & PMC_SEC_LOCK_TZ_CMAC_W) PMC(APBDEV_PMC_SEC_DISABLE8) |= 0x550000; // W lock: 112-115. @@ -71,9 +69,34 @@ void pmc_scratch_lock(pmc_sec_lock_t lock_mask) if (lock_mask & PMC_SEC_LOCK_TZ_KEK_R) PMC(APBDEV_PMC_SEC_DISABLE3) |= 0xAA; // R lock: 24-27. + // End of HOS specific. if (lock_mask & PMC_SEC_LOCK_SE_SRK) PMC(APBDEV_PMC_SEC_DISABLE) |= 0xFF000; // RW lock: 4-7 + + if (lock_mask & PMC_SEC_LOCK_SE2_SRK_B01) + PMC(APBDEV_PMC_SEC_DISABLE9) |= 0x3FC; // RW lock: 120-123 (T210B01). LP0 also sets global bits (b0-1). + + if (lock_mask & PMC_SEC_LOCK_MISC_B01) + PMC(APBDEV_PMC_SEC_DISABLE10) = 0xFFFFFFFF; // RW lock: 135-150. Happens on T210B01 LP0 always. + + if (lock_mask & PMC_SEC_LOCK_CARVEOUTS_L4T) + PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x5555; // W: 8-15 LP0 and Carveouts. Superseded by LP0 lock. + + // NVTBOOT misses APBDEV_PMC_SCRATCH_WRITE_LOCK_DISABLE_STICKY. bit0: SCRATCH_WR_DIS_ON. + // They could also use the NS write disable registers instead. + if (lock_mask & PMC_SEC_LOCK_LP0_PARAMS_B01) + { + PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE0) |= 0xCBCFE0; // W lock: 5-11, 14-17, 19, 22-23. + PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE1) |= 0x583FF; // W lock: 24-33, 39-40, 42. + PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE2) |= 0x1BE; // W lock: 44-48, 50-51. + PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE3) = 0xFFFFFFFF; // W lock: 56-87. + PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE4) |= 0xFFFFFFF; // W lock: 88-115. + PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE5) |= 0xFFFFFFF8; // W lock: 123-151. + PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE6) = 0xFFFFFFFF; // W lock: 152-183. + PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE7) |= 0xFC00FFFF; // W lock: 184-199, 210-215. + PMC(APBDEV_PMC_SCRATCH_WRITE_DISABLE8) |= 0xF; // W lock: 216-219. + } } int pmc_enable_partition(pmc_power_rail_t part, u32 enable) diff --git a/bdk/soc/pmc.h b/bdk/soc/pmc.h index 937786a1..e983447d 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, @@ -22,102 +22,183 @@ #include /*! PMC registers. */ -#define APBDEV_PMC_CNTRL 0x0 -#define PMC_CNTRL_MAIN_RST BIT(4) -#define APBDEV_PMC_SEC_DISABLE 0x4 -#define APBDEV_PMC_PWRGATE_TOGGLE 0x30 -#define APBDEV_PMC_PWRGATE_STATUS 0x38 -#define APBDEV_PMC_NO_IOPOWER 0x44 -#define PMC_NO_IOPOWER_SDMMC1_IO_EN BIT(12) -#define PMC_NO_IOPOWER_AUDIO_HV BIT(18) -#define PMC_NO_IOPOWER_GPIO_IO_EN BIT(21) -#define APBDEV_PMC_SCRATCH0 0x50 -#define PMC_SCRATCH0_MODE_WARMBOOT BIT(0) -#define PMC_SCRATCH0_MODE_RCM BIT(1) -#define PMC_SCRATCH0_MODE_PAYLOAD BIT(29) -#define PMC_SCRATCH0_MODE_FASTBOOT BIT(30) -#define PMC_SCRATCH0_MODE_RECOVERY BIT(31) -#define PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | PMC_SCRATCH0_MODE_FASTBOOT | PMC_SCRATCH0_MODE_PAYLOAD) -#define APBDEV_PMC_SCRATCH1 0x54 -#define APBDEV_PMC_SCRATCH20 0xA0 -#define APBDEV_PMC_SECURE_SCRATCH4 0xC0 -#define APBDEV_PMC_SECURE_SCRATCH5 0xC4 -#define APBDEV_PMC_PWR_DET_VAL 0xE4 -#define PMC_PWR_DET_SDMMC1_IO_EN BIT(12) -#define PMC_PWR_DET_AUDIO_HV BIT(18) -#define PMC_PWR_DET_GPIO_IO_EN BIT(21) -#define APBDEV_PMC_DDR_PWR 0xE8 -#define APBDEV_PMC_USB_AO 0xF0 -#define APBDEV_PMC_CRYPTO_OP 0xF4 -#define PMC_CRYPTO_OP_SE_ENABLE 0 -#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 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 -#define APBDEV_PMC_VDDP_SEL 0x1CC -#define APBDEV_PMC_DDR_CFG 0x1D0 -#define APBDEV_PMC_SECURE_SCRATCH6 0x224 -#define APBDEV_PMC_SECURE_SCRATCH7 0x228 -#define APBDEV_PMC_SCRATCH45 0x234 -#define APBDEV_PMC_SCRATCH46 0x238 -#define APBDEV_PMC_SCRATCH49 0x244 -#define APBDEV_PMC_TSC_MULT 0x2B4 -#define APBDEV_PMC_SEC_DISABLE2 0x2C4 -#define APBDEV_PMC_WEAK_BIAS 0x2C8 -#define APBDEV_PMC_REG_SHORT 0x2CC -#define APBDEV_PMC_SEC_DISABLE3 0x2D8 -#define APBDEV_PMC_SECURE_SCRATCH21 0x334 -#define PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT 0x10 -#define APBDEV_PMC_SECURE_SCRATCH32 0x360 -#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4 -#define APBDEV_PMC_CNTRL2 0x440 -#define PMC_CNTRL2_HOLD_CKE_LOW_EN 0x1000 -#define APBDEV_PMC_IO_DPD3_REQ 0x45C -#define APBDEV_PMC_IO_DPD4_REQ 0x464 -#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4 -#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC -#define APBDEV_PMC_DDR_CNTRL 0x4E4 -#define APBDEV_PMC_SEC_DISABLE4 0x5B0 -#define APBDEV_PMC_SEC_DISABLE5 0x5B4 -#define APBDEV_PMC_SEC_DISABLE6 0x5B8 -#define APBDEV_PMC_SEC_DISABLE7 0x5BC -#define APBDEV_PMC_SEC_DISABLE8 0x5C0 -#define APBDEV_PMC_SEC_DISABLE9 0x5C4 -#define APBDEV_PMC_SEC_DISABLE10 0x5C8 -#define APBDEV_PMC_SCRATCH188 0x810 -#define APBDEV_PMC_SCRATCH190 0x818 -#define APBDEV_PMC_SCRATCH200 0x840 -#define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8 -#define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC -#define APBDEV_PMC_TZRAM_NON_SEC_DISABLE 0xBF0 +#define APBDEV_PMC_CNTRL 0x0 +#define PMC_CNTRL_RTC_CLK_DIS BIT(1) +#define PMC_CNTRL_RTC_RST BIT(2) +#define PMC_CNTRL_MAIN_RST BIT(4) +#define PMC_CNTRL_LATCHWAKE_EN BIT(5) +#define PMC_CNTRL_BLINK_EN BIT(7) +#define PMC_CNTRL_PWRREQ_OE BIT(9) +#define PMC_CNTRL_SYSCLK_OE BIT(11) +#define PMC_CNTRL_PWRGATE_DIS BIT(12) +#define PMC_CNTRL_SIDE_EFFECT_LP0 BIT(14) +#define PMC_CNTRL_CPUPWRREQ_OE BIT(16) +#define PMC_CNTRL_FUSE_OVERRIDE BIT(18) +#define PMC_CNTRL_SHUTDOWN_OE BIT(22) +#define APBDEV_PMC_SEC_DISABLE 0x4 +#define APBDEV_PMC_PWRGATE_TOGGLE 0x30 +#define APBDEV_PMC_PWRGATE_STATUS 0x38 +#define APBDEV_PMC_NO_IOPOWER 0x44 +#define PMC_NO_IOPOWER_SDMMC1_IO_EN BIT(12) +#define PMC_NO_IOPOWER_SDMMC4_IO_EN BIT(14) +#define PMC_NO_IOPOWER_AUDIO_HV BIT(18) +#define PMC_NO_IOPOWER_GPIO_IO_EN BIT(21) +#define APBDEV_PMC_SCRATCH0 0x50 +#define PMC_SCRATCH0_MODE_WARMBOOT BIT(0) +#define PMC_SCRATCH0_MODE_RCM BIT(1) +#define PMC_SCRATCH0_MODE_PAYLOAD BIT(29) +#define PMC_SCRATCH0_MODE_BOOTLOADER BIT(30) +#define PMC_SCRATCH0_MODE_RECOVERY BIT(31) +#define PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | \ + PMC_SCRATCH0_MODE_BOOTLOADER | \ + PMC_SCRATCH0_MODE_PAYLOAD) +#define APBDEV_PMC_BLINK_TIMER 0x40 +#define PMC_BLINK_ON(n) ((n & 0x7FFF)) +#define PMC_BLINK_FORCE BIT(15) +#define PMC_BLINK_OFF(n) ((u32)(n & 0xFFFF) << 16) +#define APBDEV_PMC_SCRATCH1 0x54 +#define APBDEV_PMC_SCRATCH20 0xA0 // ODM data/config scratch. +#define APBDEV_PMC_SECURE_SCRATCH4 0xC0 +#define APBDEV_PMC_SECURE_SCRATCH5 0xC4 +#define APBDEV_PMC_PWR_DET_VAL 0xE4 +#define PMC_PWR_DET_SDMMC1_IO_EN BIT(12) +#define PMC_PWR_DET_AUDIO_HV BIT(18) +#define PMC_PWR_DET_GPIO_IO_EN BIT(21) +#define APBDEV_PMC_DDR_PWR 0xE8 +#define APBDEV_PMC_USB_AO 0xF0 +#define APBDEV_PMC_CRYPTO_OP 0xF4 +#define PMC_CRYPTO_OP_SE_ENABLE 0 +#define PMC_CRYPTO_OP_SE_DISABLE 1 +#define APBDEV_PMC_PLLP_WB0_OVERRIDE 0xF8 +#define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE_ENABLE BIT(11) +#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE BIT(12) +#define APBDEV_PMC_SCRATCH33 0x120 +#define APBDEV_PMC_SCRATCH37 0x130 +#define PMC_SCRATCH37_KERNEL_PANIC_MAGIC 0x4E415054 // "TPAN" +#define APBDEV_PMC_SCRATCH39 0x138 +#define APBDEV_PMC_SCRATCH40 0x13C +#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4 +#define PMC_OSC_EDPD_OVER_OSC_CTRL_OVER BIT(22) +#define APBDEV_PMC_CLK_OUT_CNTRL 0x1A8 +#define PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN BIT(2) +#define PMC_CLK_OUT_CNTRL_CLK2_FORCE_EN BIT(10) +#define PMC_CLK_OUT_CNTRL_CLK3_FORCE_EN BIT(18) +#define PMC_CLK_OUT_CNTRL_CLK1_SRC_SEL(src) (((src) & 3) << 6) +#define PMC_CLK_OUT_CNTRL_CLK2_SRC_SEL(src) (((src) & 3) << 14) +#define PMC_CLK_OUT_CNTRL_CLK3_SRC_SEL(src) (((src) & 3) << 22) +#define OSC_DIV1 0 +#define OSC_DIV2 1 +#define OSC_DIV4 2 +#define OSC_CAR 3 +#define APBDEV_PMC_RST_STATUS 0x1B4 +#define PMC_RST_STATUS_MASK 7 +#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 +#define APBDEV_PMC_VDDP_SEL 0x1CC +#define APBDEV_PMC_DDR_CFG 0x1D0 +#define APBDEV_PMC_SECURE_SCRATCH6 0x224 +#define APBDEV_PMC_SECURE_SCRATCH7 0x228 +#define APBDEV_PMC_SCRATCH45 0x234 +#define APBDEV_PMC_SCRATCH46 0x238 +#define APBDEV_PMC_SCRATCH49 0x244 +#define APBDEV_PMC_SCRATCH52 0x250 +#define APBDEV_PMC_SCRATCH53 0x254 +#define APBDEV_PMC_SCRATCH54 0x258 +#define APBDEV_PMC_SCRATCH55 0x25C +#define APBDEV_PMC_TSC_MULT 0x2B4 +#define APBDEV_PMC_STICKY_BITS 0x2C0 +#define PMC_STICKY_BITS_HDA_LPBK_DIS BIT(0) +#define APBDEV_PMC_SEC_DISABLE2 0x2C4 +#define APBDEV_PMC_WEAK_BIAS 0x2C8 +#define APBDEV_PMC_REG_SHORT 0x2CC +#define APBDEV_PMC_SEC_DISABLE3 0x2D8 +#define APBDEV_PMC_SECURE_SCRATCH21 0x334 +#define PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT BIT(4) +#define APBDEV_PMC_SECURE_SCRATCH22 0x338 // AArch32 reset address. +#define APBDEV_PMC_SECURE_SCRATCH32 0x360 +#define APBDEV_PMC_SECURE_SCRATCH34 0x368 // AArch64 reset address. +#define APBDEV_PMC_SECURE_SCRATCH35 0x36C // AArch64 reset hi-address. +#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4 +#define APBDEV_PMC_CNTRL2 0x440 +#define PMC_CNTRL2_WAKE_INT_EN BIT(0) +#define PMC_CNTRL2_WAKE_DET_EN BIT(9) +#define PMC_CNTRL2_SYSCLK_ORRIDE BIT(10) +#define PMC_CNTRL2_HOLD_CKE_LOW_EN BIT(12) +#define PMC_CNTRL2_ALLOW_PULSE_WAKE BIT(14) +#define APBDEV_PMC_IO_DPD3_REQ 0x45C +#define APBDEV_PMC_IO_DPD4_REQ 0x464 +#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4 +#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC +#define APBDEV_PMC_DDR_CNTRL 0x4E4 +#define APBDEV_PMC_SEC_DISABLE4 0x5B0 +#define APBDEV_PMC_SEC_DISABLE5 0x5B4 +#define APBDEV_PMC_SEC_DISABLE6 0x5B8 +#define APBDEV_PMC_SEC_DISABLE7 0x5BC +#define APBDEV_PMC_SEC_DISABLE8 0x5C0 +#define APBDEV_PMC_SEC_DISABLE9 0x5C4 +#define APBDEV_PMC_SEC_DISABLE10 0x5C8 +#define APBDEV_PMC_SCRATCH188 0x810 +#define APBDEV_PMC_SCRATCH190 0x818 +#define APBDEV_PMC_SCRATCH200 0x840 +#define APBDEV_PMC_SCRATCH201 0x844 +#define APBDEV_PMC_SCRATCH250 0x908 +#define APBDEV_PMC_SECURE_SCRATCH108 0xB08 +#define APBDEV_PMC_SECURE_SCRATCH109 0xB0C +#define APBDEV_PMC_SECURE_SCRATCH110 0xB10 +#define APBDEV_PMC_SECURE_SCRATCH112 0xB18 +#define APBDEV_PMC_SECURE_SCRATCH113 0xB1C +#define APBDEV_PMC_SECURE_SCRATCH114 0xB20 +#define APBDEV_PMC_SECURE_SCRATCH119 0xB34 + +// Only in T210B01. +#define APBDEV_PMC_SCRATCH_WRITE_DISABLE0 0xA48 +#define APBDEV_PMC_SCRATCH_WRITE_DISABLE1 0xA4C +#define APBDEV_PMC_SCRATCH_WRITE_DISABLE2 0xA50 +#define APBDEV_PMC_SCRATCH_WRITE_DISABLE3 0xA54 +#define APBDEV_PMC_SCRATCH_WRITE_DISABLE4 0xA58 +#define APBDEV_PMC_SCRATCH_WRITE_DISABLE5 0xA5C +#define APBDEV_PMC_SCRATCH_WRITE_DISABLE6 0xA60 +#define APBDEV_PMC_SCRATCH_WRITE_DISABLE7 0xA64 +#define APBDEV_PMC_SCRATCH_WRITE_DISABLE8 0xA68 +#define APBDEV_PMC_LED_BREATHING_CTRL 0xB48 +#define PMC_LED_BREATHING_CTRL_ENABLE BIT(0) +#define PMC_LED_BREATHING_CTRL_COUNTER1_EN BIT(1) +#define APBDEV_PMC_LED_BREATHING_SLOPE_STEPS 0xB4C +#define APBDEV_PMC_LED_BREATHING_ON_COUNTER 0xB50 +#define APBDEV_PMC_LED_BREATHING_OFF_COUNTER1 0xB54 +#define APBDEV_PMC_LED_BREATHING_OFF_COUNTER0 0xB58 +#define PMC_LED_BREATHING_COUNTER_HZ 32768 +#define APBDEV_PMC_LED_BREATHING_STATUS 0xB5C +#define PMC_LED_BREATHING_FSM_STATUS_MASK 0x7 +#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 { - PMC_SEC_LOCK_MISC = BIT(0), - PMC_SEC_LOCK_LP0_PARAMS = BIT(1), - PMC_SEC_LOCK_RST_VECTOR = BIT(2), - PMC_SEC_LOCK_CARVEOUTS = BIT(3), - PMC_SEC_LOCK_TZ_CMAC_W = BIT(4), - PMC_SEC_LOCK_TZ_CMAC_R = BIT(5), - PMC_SEC_LOCK_TZ_KEK_W = BIT(6), - PMC_SEC_LOCK_TZ_KEK_R = BIT(7), - PMC_SEC_LOCK_SE_SRK = BIT(8), + PMC_SEC_LOCK_MISC = BIT(0), + PMC_SEC_LOCK_LP0_PARAMS = BIT(1), + PMC_SEC_LOCK_RST_VECTOR = BIT(2), + PMC_SEC_LOCK_CARVEOUTS = BIT(3), + PMC_SEC_LOCK_TZ_CMAC_W = BIT(4), + PMC_SEC_LOCK_TZ_CMAC_R = BIT(5), + PMC_SEC_LOCK_TZ_KEK_W = BIT(6), + PMC_SEC_LOCK_TZ_KEK_R = BIT(7), + PMC_SEC_LOCK_SE_SRK = BIT(8), + PMC_SEC_LOCK_SE2_SRK_B01 = BIT(9), + PMC_SEC_LOCK_MISC_B01 = BIT(10), + PMC_SEC_LOCK_CARVEOUTS_L4T = BIT(11), + PMC_SEC_LOCK_LP0_PARAMS_B01 = BIT(12), } pmc_sec_lock_t; typedef enum _pmc_power_rail_t diff --git a/bdk/soc/t210.h b/bdk/soc/t210.h index e48f53a2..f04465c8 100644 --- a/bdk/soc/t210.h +++ b/bdk/soc/t210.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 naehrwert +* 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, @@ -26,8 +27,10 @@ #define DISPLAY_A_BASE 0x54200000 #define DSI_BASE 0x54300000 #define VIC_BASE 0x54340000 +#define NVDEC_BASE 0x54480000 #define TSEC_BASE 0x54500000 #define SOR1_BASE 0x54580000 +#define MSELECT_BASE 0x50060000 #define ICTLR_BASE 0x60004000 #define TMR_BASE 0x60005000 #define CLOCK_BASE 0x60006000 @@ -35,6 +38,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) @@ -69,6 +73,8 @@ #define I2S_BASE 0x702D1000 #define ADMA_BASE 0x702E2000 #define TZRAM_BASE 0x7C010000 +#define TZRAM_SIZE 0x10000 +#define TZRAM_T210B01_SIZE 0x3C000 #define USB_BASE 0x7D000000 #define USB_OTG_BASE USB_BASE #define USB1_BASE 0x7D004000 @@ -80,8 +86,10 @@ #define DISPLAY_A(off) _REG(DISPLAY_A_BASE, off) #define DSI(off) _REG(DSI_BASE, off) #define VIC(off) _REG(VIC_BASE, off) +#define NVDEC(off) _REG(NVDEC_BASE, off) #define TSEC(off) _REG(TSEC_BASE, off) #define SOR1(off) _REG(SOR1_BASE, off) +#define MSELECT(off) _REG(MSELECT_BASE, off) #define ICTLR(cidx, off) _REG(ICTLR_BASE + (0x100 * (cidx)), off) #define TMR(off) _REG(TMR_BASE, off) #define CLOCK(off) _REG(CLOCK_BASE, off) @@ -89,6 +97,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) @@ -127,88 +136,91 @@ #define TEST_REG(off) _REG(0x0, off) /* HOST1X registers. */ -#define HOST1X_CH0_SYNC_BASE 0x2100 +#define HOST1X_CH0_SYNC_BASE 0x2100 #define HOST1X_CH0_SYNC_SYNCPT_9 (HOST1X_CH0_SYNC_BASE + 0xFA4) #define HOST1X_CH0_SYNC_SYNCPT_160 (HOST1X_CH0_SYNC_BASE + 0x1200) /*! EVP registers. */ -#define EVP_CPU_RESET_VECTOR 0x100 -#define EVP_COP_RESET_VECTOR 0x200 -#define EVP_COP_UNDEF_VECTOR 0x204 -#define EVP_COP_SWI_VECTOR 0x208 +#define EVP_CPU_RESET_VECTOR 0x100 +#define EVP_COP_RESET_VECTOR 0x200 +#define EVP_COP_UNDEF_VECTOR 0x204 +#define EVP_COP_SWI_VECTOR 0x208 #define EVP_COP_PREFETCH_ABORT_VECTOR 0x20C -#define EVP_COP_DATA_ABORT_VECTOR 0x210 -#define EVP_COP_RSVD_VECTOR 0x214 -#define EVP_COP_IRQ_VECTOR 0x218 -#define EVP_COP_FIQ_VECTOR 0x21C -#define EVP_COP_IRQ_STS 0x220 +#define EVP_COP_DATA_ABORT_VECTOR 0x210 +#define EVP_COP_RSVD_VECTOR 0x214 +#define EVP_COP_IRQ_VECTOR 0x218 +#define EVP_COP_FIQ_VECTOR 0x21C +#define EVP_COP_IRQ_STS 0x220 /*! Primary Interrupt Controller registers. */ -#define PRI_ICTLR_FIR 0x14 -#define PRI_ICTLR_FIR_SET 0x18 -#define PRI_ICTLR_FIR_CLR 0x1C -#define PRI_ICTLR_CPU_IER 0x20 -#define PRI_ICTLR_CPU_IER_SET 0x24 -#define PRI_ICTLR_CPU_IER_CLR 0x28 +#define PRI_ICTLR_FIR 0x14 +#define PRI_ICTLR_FIR_SET 0x18 +#define PRI_ICTLR_FIR_CLR 0x1C +#define PRI_ICTLR_CPU_IER 0x20 +#define PRI_ICTLR_CPU_IER_SET 0x24 +#define PRI_ICTLR_CPU_IER_CLR 0x28 #define PRI_ICTLR_CPU_IEP_CLASS 0x2C -#define PRI_ICTLR_COP_IER 0x30 -#define PRI_ICTLR_COP_IER_SET 0x34 -#define PRI_ICTLR_COP_IER_CLR 0x38 +#define PRI_ICTLR_COP_IER 0x30 +#define PRI_ICTLR_COP_IER_SET 0x34 +#define PRI_ICTLR_COP_IER_CLR 0x38 #define PRI_ICTLR_COP_IEP_CLASS 0x3C /*! AHB Gizmo registers. */ -#define AHB_ARBITRATION_PRIORITY_CTRL 0x8 -#define PRIORITY_CTRL_WEIGHT(x) (((x) & 7) << 29) -#define PRIORITY_SELECT_USB BIT(6) // USB-OTG. -#define PRIORITY_SELECT_USB2 BIT(18) // USB-HSIC. -#define PRIORITY_SELECT_USB3 BIT(17) // XUSB. -#define AHB_GIZMO_AHB_MEM 0x10 -#define AHB_MEM_ENB_FAST_REARBITRATE BIT(2) -#define AHB_MEM_DONT_SPLIT_AHB_WR BIT(7) -#define AHB_MEM_IMMEDIATE BIT(18) -#define AHB_GIZMO_APB_DMA 0x14 -#define AHB_GIZMO_USB 0x20 -#define AHB_GIZMO_SDMMC4 0x48 -#define AHB_GIZMO_USB2 0x7C -#define AHB_GIZMO_USB3 0x80 -#define AHB_GIZMO_IMMEDIATE BIT(18) -#define AHB_ARBITRATION_XBAR_CTRL 0xE0 -#define AHB_AHB_MEM_PREFETCH_CFG3 0xE4 -#define AHB_AHB_MEM_PREFETCH_CFG4 0xE8 -#define AHB_AHB_MEM_PREFETCH_CFG1 0xF0 -#define AHB_AHB_MEM_PREFETCH_CFG2 0xF4 -#define MST_ID(x) (((x) & 0x1F) << 26) -#define MEM_PREFETCH_AHBDMA_MST_ID MST_ID(5) -#define MEM_PREFETCH_USB_MST_ID MST_ID(6) // USB-OTG. -#define MEM_PREFETCH_USB2_MST_ID MST_ID(18) // USB-HSIC. -#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_AHB_SPARE_REG 0x110 +#define AHB_ARBITRATION_PRIORITY_CTRL 0x8 +#define PRIORITY_CTRL_WEIGHT(x) (((x) & 7) << 29) +#define PRIORITY_SELECT_USB BIT(6) // USB-OTG. +#define PRIORITY_SELECT_USB2 BIT(18) // USB-HSIC. +#define PRIORITY_SELECT_USB3 BIT(17) // XUSB. +#define AHB_GIZMO_AHB_MEM 0x10 +#define AHB_MEM_ENB_FAST_REARBITRATE BIT(2) +#define AHB_MEM_DONT_SPLIT_AHB_WR BIT(7) +#define AHB_MEM_IMMEDIATE BIT(18) +#define AHB_GIZMO_APB_DMA 0x14 +#define AHB_GIZMO_USB 0x20 +#define AHB_GIZMO_SDMMC4 0x48 +#define AHB_GIZMO_USB2 0x7C +#define AHB_GIZMO_USB3 0x80 +#define AHB_GIZMO_IMMEDIATE BIT(18) +#define AHB_ARBITRATION_XBAR_CTRL 0xE0 +#define AHB_AHB_MEM_PREFETCH_CFG3 0xE4 +#define AHB_AHB_MEM_PREFETCH_CFG4 0xE8 +#define AHB_AHB_MEM_PREFETCH_CFG1 0xF0 +#define AHB_AHB_MEM_PREFETCH_CFG2 0xF4 +#define MST_ID(x) (((x) & 0x1F) << 26) +#define MEM_PREFETCH_AHBDMA_MST_ID MST_ID(5) +#define MEM_PREFETCH_USB_MST_ID MST_ID(6) // USB-OTG. +#define MEM_PREFETCH_USB2_MST_ID MST_ID(18) // USB-HSIC. +#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. */ -#define APB_MISC_PP_STRAPPING_OPT_A 0x08 -#define APB_MISC_PP_PINMUX_GLOBAL 0x40 -#define APB_MISC_GP_HIDREV 0x804 -#define GP_HIDREV_MAJOR_T210 0x1 -#define GP_HIDREV_MAJOR_T210B01 0x2 -#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 -#define APB_MISC_GP_EMMC2_PAD_CFGPADCTRL 0xA9C -#define APB_MISC_GP_EMMC4_PAD_CFGPADCTRL 0xAB4 +#define APB_MISC_PP_STRAPPING_OPT_A 0x8 +#define APB_MISC_PP_PINMUX_GLOBAL 0x40 +#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 +#define APB_MISC_GP_EMMC2_PAD_CFGPADCTRL 0xA9C +#define APB_MISC_GP_EMMC4_PAD_CFGPADCTRL 0xAB4 #define APB_MISC_GP_EMMC4_PAD_PUPD_CFGPADCTRL 0xABC -#define APB_MISC_GP_DSI_PAD_CONTROL 0xAC0 -#define APB_MISC_GP_WIFI_EN_CFGPADCTRL 0xB64 -#define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68 +#define APB_MISC_GP_DSI_PAD_CONTROL 0xAC0 +#define APB_MISC_GP_WIFI_EN_CFGPADCTRL 0xB64 +#define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68 /*! Secure boot registers. */ -#define SB_CSR 0x0 -#define SB_CSR_NS_RST_VEC_WR_DIS BIT(1) -#define SB_CSR_PIROM_DISABLE BIT(4) -#define SB_AA64_RESET_LOW 0x30 -#define SB_AA64_RST_AARCH64_MODE_EN BIT(0) -#define SB_AA64_RESET_HIGH 0x34 +#define SB_CSR 0x0 +#define SB_CSR_NS_RST_VEC_WR_DIS BIT(1) +#define SB_CSR_PIROM_DISABLE BIT(4) +#define SB_AA64_RESET_LOW 0x30 +#define SB_AA64_RST_AARCH64_MODE_EN BIT(0) +#define SB_AA64_RESET_HIGH 0x34 /*! SOR registers. */ #define SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB 0x1E8 @@ -222,42 +234,22 @@ #define APBDEV_RTC_MILLI_SECONDS 0x10 /*! SYSCTR0 registers. */ -#define SYSCTR0_CNTFID0 0x20 -#define SYSCTR0_CNTCR 0x00 -#define SYSCTR0_COUNTERID0 0xFE0 -#define SYSCTR0_COUNTERID1 0xFE4 -#define SYSCTR0_COUNTERID2 0xFE8 -#define SYSCTR0_COUNTERID3 0xFEC -#define SYSCTR0_COUNTERID4 0xFD0 -#define SYSCTR0_COUNTERID5 0xFD4 -#define SYSCTR0_COUNTERID6 0xFD8 -#define SYSCTR0_COUNTERID7 0xFDC -#define SYSCTR0_COUNTERID8 0xFF0 -#define SYSCTR0_COUNTERID9 0xFF4 -#define SYSCTR0_COUNTERID10 0xFF8 -#define SYSCTR0_COUNTERID11 0xFFC - -/*! TMR registers. */ -#define TIMERUS_CNTR_1US (0x10 + 0x0) -#define TIMERUS_USEC_CFG (0x10 + 0x4) -#define TIMER_TMR8_TMR_PTV 0x78 -#define TIMER_TMR9_TMR_PTV 0x80 -#define TIMER_PER_EN BIT(30) -#define TIMER_EN BIT(31) -#define TIMER_TMR8_TMR_PCR 0x7C -#define TIMER_TMR9_TMR_PCR 0x8C -#define TIMER_INTR_CLR BIT(30) - -#define TIMER_WDT4_CONFIG (0x100 + 0x80) -#define TIMER_SRC(TMR) ((TMR) & 0xF) -#define TIMER_PER(PER) (((PER) & 0xFF) << 4) -#define TIMER_SYSRESET_EN BIT(14) -#define TIMER_PMCRESET_EN BIT(15) -#define TIMER_WDT4_COMMAND (0x108 + 0x80) -#define TIMER_START_CNT BIT(0) -#define TIMER_CNT_DISABLE BIT(1) -#define TIMER_WDT4_UNLOCK_PATTERN (0x10C + 0x80) -#define TIMER_MAGIC_PTRN 0xC45A +#define SYSCTR0_CNTCR 0x00 +#define SYSCTR0_CNTFID0 0x20 +#define SYSCTR0_COUNTERS_BASE 0xFD0 +#define SYSCTR0_COUNTERS 12 +#define SYSCTR0_COUNTERID0 0xFE0 +#define SYSCTR0_COUNTERID1 0xFE4 +#define SYSCTR0_COUNTERID2 0xFE8 +#define SYSCTR0_COUNTERID3 0xFEC +#define SYSCTR0_COUNTERID4 0xFD0 +#define SYSCTR0_COUNTERID5 0xFD4 +#define SYSCTR0_COUNTERID6 0xFD8 +#define SYSCTR0_COUNTERID7 0xFDC +#define SYSCTR0_COUNTERID8 0xFF0 +#define SYSCTR0_COUNTERID9 0xFF4 +#define SYSCTR0_COUNTERID10 0xFF8 +#define SYSCTR0_COUNTERID11 0xFFC /*! I2S registers. */ #define I2S1_CG 0x88 @@ -284,25 +276,42 @@ #define EMC_SEPT_RUN BIT(31) /*! Flow controller registers. */ -#define FLOW_CTLR_HALT_COP_EVENTS 0x4 -#define HALT_COP_GIC_IRQ BIT(9) -#define HALT_COP_LIC_IRQ BIT(11) -#define HALT_COP_SEC BIT(23) -#define HALT_COP_MSEC BIT(24) -#define HALT_COP_USEC BIT(25) -#define HALT_COP_JTAG BIT(28) -#define HALT_COP_WAIT_EVENT BIT(30) -#define HALT_COP_STOP_UNTIL_IRQ BIT(31) -#define HALT_COP_MAX_CNT 0xFF -#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0 -#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14 -#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C -#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24 -#define FLOW_CTLR_CPU0_CSR 0x8 -#define FLOW_CTLR_CPU1_CSR 0x18 -#define FLOW_CTLR_CPU2_CSR 0x20 -#define FLOW_CTLR_CPU3_CSR 0x28 -#define FLOW_CTLR_RAM_REPAIR 0x40 +#define FLOW_CTLR_HALT_COP_EVENTS 0x4 +#define HALT_COP_GIC_IRQ BIT(9) +#define HALT_COP_LIC_IRQ BIT(11) +#define HALT_COP_SEC BIT(23) +#define HALT_COP_MSEC BIT(24) +#define HALT_COP_USEC BIT(25) +#define HALT_COP_JTAG BIT(28) +#define HALT_COP_WAIT_EVENT BIT(30) +#define HALT_COP_STOP_UNTIL_IRQ BIT(31) +#define HALT_COP_MAX_CNT 0xFF +#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0 +#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14 +#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C +#define FLOW_CTLR_HALT_CPU3_EVENTS 0x24 +#define FLOW_CTLR_CPU0_CSR 0x8 +#define FLOW_CTLR_CPU1_CSR 0x18 +#define FLOW_CTLR_CPU2_CSR 0x20 +#define FLOW_CTLR_CPU3_CSR 0x28 +#define FLOW_CTLR_RAM_REPAIR 0x40 +#define RAM_REPAIR_REQ BIT(0) +#define RAM_REPAIR_STS BIT(1) #define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98 +#define CLUSTER_CTRL_ACTIVE_SLOW BIT(0) + +/* MSelect registers */ +#define MSELECT_CONFIG 0x00 +#define MSELECT_CFG_ERR_RESP_EN_PCIE BIT(24) +#define MSELECT_CFG_ERR_RESP_EN_GPU BIT(25) +#define MSELECT_CFG_WRAP_TO_INCR_BPMP BIT(27) +#define MSELECT_CFG_WRAP_TO_INCR_PCIE BIT(28) +#define MSELECT_CFG_WRAP_TO_INCR_GPU BIT(29) +/* NVDEC registers */ +#define NVDEC_SA_KEYSLOT_FALCON 0x2100 +#define NVDEC_SA_KEYSLOT_TZ 0x2104 +#define NVDEC_SA_KEYSLOT_OTF 0x210C +#define NVDEC_SA_KEYSLOT_GLOBAL_RW 0x2118 +#define NVDEC_VPR_ALL_OTF_GOTO_VPR 0x211C #endif diff --git a/bdk/soc/timer.c b/bdk/soc/timer.c new file mode 100644 index 00000000..2f25380b --- /dev/null +++ b/bdk/soc/timer.c @@ -0,0 +1,115 @@ +/* + * Timer/Watchdog 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 . + */ + +#include +#include +#include +#include +#include + +#define EXCP_TYPE_ADDR 0x4003FFF8 +#define EXCP_TYPE_WDT 0x544457 // "WDT". + +u32 get_tmr_s() +{ + (void)RTC(APBDEV_RTC_MILLI_SECONDS); + return (u32)RTC(APBDEV_RTC_SECONDS); +} + +u32 get_tmr_ms() +{ + // The registers must be read with the following order: + // RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC) + return (u32)(RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000)); +} + +u32 get_tmr_us() +{ + return (u32)TMR(TIMERUS_CNTR_1US); +} + +void msleep(u32 ms) +{ +#ifdef USE_RTC_TIMER + u32 start = (u32)RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000); + // Casting to u32 is important! + while (((u32)(RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000)) - start) <= ms) + ; +#else + bpmp_msleep(ms); +#endif +} + +void usleep(u32 us) +{ +#ifdef USE_RTC_TIMER + u32 start = (u32)TMR(TIMERUS_CNTR_1US); + + // Check if timer is at upper limits and use BPMP sleep so it doesn't wake up immediately. + if ((start + us) < start) + bpmp_usleep(us); + else + while ((u32)(TMR(TIMERUS_CNTR_1US) - start) <= us) // Casting to u32 is important! + ; +#else + bpmp_usleep(us); +#endif +} + +void timer_usleep(u32 us) +{ + TMR(TIMER_TMR8_TMR_PTV) = TIMER_EN | us; + + irq_wait_event(IRQ_TMR8); + + TMR(TIMER_TMR8_TMR_PCR) = TIMER_INTR_CLR; +} + +void watchdog_start(u32 us, u32 mode) +{ + // WDT4 is for BPMP. + TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN; + TMR(TIMER_TMR9_TMR_PTV) = TIMER_EN | TIMER_PER_EN | us; + TMR(TIMER_WDT4_CONFIG) = TIMER_SRC(9) | TIMER_PER(1) | mode; + TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT; +} + +void watchdog_end() +{ + // WDT4 is for BPMP. + TMR(TIMER_TMR9_TMR_PTV) = 0; + TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN; + TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT; // Re-arm to clear any interrupts. + TMR(TIMER_WDT4_COMMAND) = TIMER_CNT_DISABLE; + TMR(TIMER_TMR9_TMR_PCR) = TIMER_INTR_CLR; +} + +void watchdog_handle() +{ + // Disable watchdog and clear its interrupts. + watchdog_end(); + + // Set watchdog magic. + *(u32 *)EXCP_TYPE_ADDR = EXCP_TYPE_WDT; +} + +bool watchdog_fired() +{ + // Return if watchdog got fired. User handles clearing. + return (*(u32 *)EXCP_TYPE_ADDR == EXCP_TYPE_WDT); +} \ No newline at end of file diff --git a/bdk/soc/timer.h b/bdk/soc/timer.h new file mode 100644 index 00000000..6fcdb368 --- /dev/null +++ b/bdk/soc/timer.h @@ -0,0 +1,62 @@ +/* + * Timer/Watchdog 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 _TIMER_H_ +#define _TIMER_H_ + +#include + +// TMR registers. +#define TIMERUS_CNTR_1US (0x10 + 0x0) +#define TIMERUS_USEC_CFG (0x10 + 0x4) +#define TIMER_TMR8_TMR_PTV 0x78 +#define TIMER_TMR9_TMR_PTV 0x80 +#define TIMER_PER_EN BIT(30) +#define TIMER_EN BIT(31) +#define TIMER_TMR8_TMR_PCR 0x7C +#define TIMER_TMR9_TMR_PCR 0x8C +#define TIMER_INTR_CLR BIT(30) + +// WDT registers. +#define TIMER_WDT4_CONFIG (0x100 + 0x80) +#define TIMER_SRC(TMR) ((TMR) & 0xF) +#define TIMER_PER(PER) (((PER) & 0xFF) << 4) +#define TIMER_IRQENABL_EN BIT(12) +#define TIMER_FIQENABL_EN BIT(13) +#define TIMER_SYSRESET_EN BIT(14) +#define TIMER_PMCRESET_EN BIT(15) +#define TIMER_WDT4_COMMAND (0x108 + 0x80) +#define TIMER_START_CNT BIT(0) +#define TIMER_CNT_DISABLE BIT(1) +#define TIMER_WDT4_UNLOCK_PATTERN (0x10C + 0x80) +#define TIMER_MAGIC_PTRN 0xC45A + +u32 get_tmr_us(); +u32 get_tmr_ms(); +u32 get_tmr_s(); +void usleep(u32 us); +void msleep(u32 ms); + +void timer_usleep(u32 us); + +void watchdog_start(u32 us, u32 mode); +void watchdog_end(); +void watchdog_handle(); +bool watchdog_fired(); + +#endif diff --git a/bdk/soc/uart.c b/bdk/soc/uart.c index 582bca1e..228ac01a 100644 --- a/bdk/soc/uart.c +++ b/bdk/soc/uart.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert -* Copyright (c) 2019-2020 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,45 +17,58 @@ #include #include +#include #include -#include /* UART A, B, C, D and E. */ static const u32 uart_baseoff[5] = { 0, 0x40, 0x200, 0x300, 0x400 }; -void uart_init(u32 idx, u32 baud) +void uart_init(u32 idx, u32 baud, u32 mode) { uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); // Make sure no data is being sent. - uart_wait_idle(idx, UART_TX_IDLE); + if (!(mode & (UART_MCR_CTS_EN | UART_MCR_DTR))) + uart_wait_xfer(idx, UART_TX_IDLE); // Set clock. bool clk_type = clock_uart_use_src_div(idx, baud); + // 2 STOP bits for rates > 1M. (Reduced efficiency but less errors on high baudrates). + u32 uart_lcr_stop = baud > 1000000 ? UART_LCR_STOP : 0; + // Misc settings. u32 div = clk_type ? ((8 * baud + 408000000) / (16 * baud)) : 1; // DIV_ROUND_CLOSEST. uart->UART_IER_DLAB = 0; // Disable interrupts. - uart->UART_LCR = UART_LCR_DLAB | UART_LCR_WORD_LENGTH_8; // Enable DLAB & set 8n1 mode. - uart->UART_THR_DLAB = (u8)div; // Divisor latch LSB. + uart->UART_LCR = UART_LCR_DLAB | UART_LCR_WORD_LENGTH_8; // Enable DLAB & set 8n1 mode. + uart->UART_THR_DLAB = (u8)div; // Divisor latch LSB. uart->UART_IER_DLAB = (u8)(div >> 8); // Divisor latch MSB. - uart->UART_LCR = UART_LCR_WORD_LENGTH_8; // Disable DLAB. + + // Disable DLAB and set STOP bits setting if applicable. + uart->UART_LCR = uart_lcr_stop | UART_LCR_WORD_LENGTH_8; (void)uart->UART_SPR; - // Setup and flush fifo. + // Enable fifo. uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO; (void)uart->UART_SPR; usleep(20); - uart->UART_MCR = 0; // Disable hardware flow control. + + // Disable hardware flow control. + uart->UART_MCR = 0; usleep(96); + + // Clear tx/rx fifos. uart->UART_IIR_FCR = UART_IIR_FCR_EN_FIFO | UART_IIR_FCR_TX_CLR | UART_IIR_FCR_RX_CLR; + // Set hardware flow control. + uart->UART_MCR = mode; + // Wait 3 symbols for baudrate change. usleep(3 * ((baud + 999999) / baud)); - uart_wait_idle(idx, UART_TX_IDLE | UART_RX_IDLE); + uart_wait_xfer(idx, UART_TX_IDLE | UART_RX_RDYR); } -void uart_wait_idle(u32 idx, u32 which) +void uart_wait_xfer(u32 idx, u32 which) { uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); if (UART_TX_IDLE & which) @@ -63,10 +76,10 @@ void uart_wait_idle(u32 idx, u32 which) while (!(uart->UART_LSR & UART_LSR_TMTY)) ; } - if (UART_RX_IDLE & which) + if (UART_RX_RDYR & which) { while (uart->UART_LSR & UART_LSR_RDR) - ; + (void)uart->UART_THR_DLAB; } } @@ -85,26 +98,31 @@ void uart_send(u32 idx, const u8 *buf, u32 len) u32 uart_recv(u32 idx, u8 *buf, u32 len) { uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + bool manual_mode = uart->UART_MCR & UART_MCR_RTS; u32 timeout = get_tmr_us() + 250; u32 i; + if (manual_mode) + uart->UART_MCR &= ~UART_MCR_RTS; + for (i = 0; ; i++) { + if (len && len <= i) + break; + while (!(uart->UART_LSR & UART_LSR_RDR)) - { if (timeout < get_tmr_us()) - break; - if (len && len < i) - break; - } - if (timeout < get_tmr_us()) - break; + goto out; buf[i] = uart->UART_THR_DLAB; timeout = get_tmr_us() + 250; } - return i ? (len ? (i - 1) : i) : 0; +out: + if (manual_mode) + uart->UART_MCR |= UART_MCR_RTS; + + return i; } void uart_invert(u32 idx, bool enable, u32 invert_mask) @@ -118,6 +136,14 @@ void uart_invert(u32 idx, bool enable, u32 invert_mask) (void)uart->UART_SPR; } +void uart_set_mode(u32 idx, u32 mode) +{ + uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); + + uart->UART_MCR = mode; + (void)uart->UART_SPR; +} + u32 uart_get_IIR(u32 idx) { uart_t *uart = (uart_t *)(UART_BASE + uart_baseoff[idx]); @@ -172,3 +198,24 @@ void uart_empty_fifo(u32 idx, u32 which) } } } + +#ifdef DEBUG_UART_PORT +#include +#include + +#include + +void uart_printf(const char *fmt, ...) +{ + va_list ap; + + //! NOTE: Anything more and it will hang. Heap usage is out of the question. + 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 6a4c073b..c25973cc 100644 --- a/bdk/soc/uart.h +++ b/bdk/soc/uart.h @@ -28,33 +28,33 @@ #define BAUD_115200 115200 -#define UART_TX_IDLE 0x1 -#define UART_RX_IDLE 0x2 +#define UART_TX_IDLE BIT(0) +#define UART_RX_RDYR BIT(1) -#define UART_TX_FIFO_FULL 0x100 -#define UART_RX_FIFO_EMPTY 0x200 +#define UART_TX_FIFO_FULL BIT(8) +#define UART_RX_FIFO_EMPTY BIT(9) -#define UART_INVERT_RXD 0x01 -#define UART_INVERT_TXD 0x02 -#define UART_INVERT_CTS 0x04 -#define UART_INVERT_RTS 0x08 +#define UART_INVERT_RXD BIT(0) +#define UART_INVERT_TXD BIT(1) +#define UART_INVERT_CTS BIT(2) +#define UART_INVERT_RTS BIT(3) -#define UART_IER_DLAB_IE_EORD 0x20 +#define UART_IER_DLAB_IE_EORD BIT(5) -#define UART_LCR_DLAB 0x80 -#define UART_LCR_STOP 0x4 #define UART_LCR_WORD_LENGTH_8 0x3 +#define UART_LCR_STOP BIT(2) +#define UART_LCR_DLAB BIT(7) -#define UART_LSR_RDR 0x1 -#define UART_LSR_THRE 0x20 -#define UART_LSR_TMTY 0x40 -#define UART_LSR_FIFOE 0x80 +#define UART_LSR_RDR BIT(0) +#define UART_LSR_THRE BIT(5) +#define UART_LSR_TMTY BIT(6) +#define UART_LSR_FIFOE BIT(7) -#define UART_IIR_FCR_TX_CLR 0x4 -#define UART_IIR_FCR_RX_CLR 0x2 -#define UART_IIR_FCR_EN_FIFO 0x1 +#define UART_IIR_FCR_EN_FIFO BIT(0) +#define UART_IIR_FCR_RX_CLR BIT(1) +#define UART_IIR_FCR_TX_CLR BIT(2) -#define UART_IIR_NO_INT BIT(0) +#define UART_IIR_NO_INT BIT(0) #define UART_IIR_INT_MASK 0xF /* Custom returned interrupt results. Actual interrupts are -1 */ #define UART_IIR_NOI 0 // No interrupt. @@ -65,8 +65,10 @@ #define UART_IIR_REDI 5 // Receiver end of data interrupt. #define UART_IIR_RDTI 7 // Receiver data timeout interrupt. -#define UART_MCR_RTS 0x2 -#define UART_MCR_DTR 0x1 +#define UART_MCR_DTR BIT(0) +#define UART_MCR_RTS BIT(1) +#define UART_MCR_CTS_EN BIT(5) +#define UART_MCR_RTS_EN BIT(6) typedef struct _uart_t { @@ -86,13 +88,29 @@ typedef struct _uart_t /* 0x3C */ vu32 UART_ASR; } uart_t; -void uart_init(u32 idx, u32 baud); -void uart_wait_idle(u32 idx, u32 which); +//! TODO: Commented out modes are not supported yet. +typedef enum _uart_mode_t +{ + UART_AO_TX_AO_RX = 0, + //UART_MN_TX_AO_RX = UART_MCR_RTS | UART_MCR_DTR, + UART_AO_TX_MN_RX = UART_MCR_RTS, // Up to 36 bytes read. + //UART_MN_TX_AO_RX = UART_MCR_DTR, + //UART_HW_TX_HW_RX = UART_MCR_RTS_EN | UART_MCR_CTS_EN, + UART_AO_TX_HW_RX = UART_MCR_RTS_EN, + //UART_HW_TX_AO_RX = UART_MCR_CTS_EN, +} uart_mode_t; + +void uart_init(u32 idx, u32 baud, u32 mode); +void uart_wait_xfer(u32 idx, u32 which); void uart_send(u32 idx, const u8 *buf, u32 len); u32 uart_recv(u32 idx, u8 *buf, u32 len); void uart_invert(u32 idx, bool enable, u32 invert_mask); +void uart_set_mode(u32 idx, u32 mode); 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_printf(const char *fmt, ...); +#endif #endif diff --git a/bdk/storage/emmc.c b/bdk/storage/emmc.c new file mode 100644 index 00000000..5412fb59 --- /dev/null +++ b/bdk/storage/emmc.c @@ -0,0 +1,227 @@ +/* + * 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; +} + +void emmc_end() { sdmmc_storage_end(&emmc_storage); } + +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--; + emmc_end(); + } + + // 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) + emmc_end(); + + 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); + } + } + + emmc_end(); + + return false; +} + +int emmc_set_partition(u32 partition) { return sdmmc_storage_set_mmc_partition(&emmc_storage, partition); } + +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 50% rename from source/storage/nx_emmc.h rename to bdk/storage/emmc.h index 5db6a1f8..f2010bf2 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,20 @@ 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); +int emmc_set_partition(u32 partition); +void emmc_end(); + +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 ee81e695..c7d6106f 100644 --- a/bdk/storage/mmc.h +++ b/bdk/storage/mmc.h @@ -408,7 +408,10 @@ /* * BKOPS status level */ -#define EXT_CSD_BKOPS_LEVEL_2 0x2 +#define EXT_CSD_BKOPS_OK 0x0 +#define EXT_CSD_BKOPS_NON_CRITICAL 0x1 +#define EXT_CSD_BKOPS_PERF_IMPACTED 0x2 +#define EXT_CSD_BKOPS_CRITICAL 0x3 /* * BKOPS modes diff --git a/bdk/storage/nx_emmc_bis.c b/bdk/storage/nx_emmc_bis.c new file mode 100644 index 00000000..4267f948 --- /dev/null +++ b/bdk/storage/nx_emmc_bis.c @@ -0,0 +1,325 @@ +/* + * 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, CORE_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, CORE_ENCRYPT, 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, CORE_ENCRYPT, 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) + { + // Get sector index in cluster and use it as boundary check. + u32 cnt_max = (curr_sct % BIS_CLUSTER_SECTORS); + cnt_max = BIS_CLUSTER_SECTORS - cnt_max; + + u32 sct_cnt = MIN(count, cnt_max); // Only allow cluster sized access. + + 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) + { + // Get sector index in cluster and use it as boundary check. + u32 cnt_max = (curr_sct % BIS_CLUSTER_SECTORS); + cnt_max = BIS_CLUSTER_SECTORS - cnt_max; + + u32 sct_cnt = MIN(count, cnt_max); // Only allow cluster sized access. + + 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 4eb5d824..8b070089 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 e2b703ff..00000000 --- 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 315075d3..3a86ebf9 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 e6252354..67bc0a5c 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 70% rename from source/storage/nx_sd.c rename to bdk/storage/sd.c index 8e4eb561..ce7e078c 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-2023 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,18 @@ * 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 bool insertion_event = 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 +55,22 @@ u16 *sd_get_error_count() bool sd_get_card_removed() { - if (!sdmmc_get_sd_inserted()) + if (insertion_event && !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 +79,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,11 +103,23 @@ 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; + } + + int res = sdmmc_storage_init_sd(&sd_storage, &sd_sdmmc, bus_width, type); + if (res) + { + sd_init_done = true; + insertion_event = true; } + else + sd_init_done = false; - return sdmmc_storage_init_sd(&sd_storage, &sd_sdmmc, bus_width, type); + return res; } bool sd_initialize(bool power_cycle) @@ -111,7 +135,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 +154,15 @@ bool sd_initialize(bool power_cycle) return false; } -bool is_sd_inited = false; - bool sd_mount() { - if (sd_mounted) + if (sd_init_done && 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 +175,8 @@ bool sd_mount() } else { - res = f_mount(&sd_fs, "", 1); + if (!sd_mounted) + res = f_mount(&sd_fs, "0:", 1); // Volume 0 is SD. if (res == FR_OK) { sd_mounted = true; @@ -167,26 +192,40 @@ 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) { - f_mount(NULL, "", 1); - sdmmc_storage_end(&sd_storage); - sd_mounted = false; - is_sd_inited = false; + if (sd_mounted) + f_mount(NULL, "0:", 1); // Volume 0 is SD. + + if (deinit) + { + sdmmc_storage_end(&sd_storage); + sd_init_done = false; + insertion_event = false; + } } + sd_mounted = 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) { FIL fp; + if (!sd_get_card_mounted()) + return NULL; + if (f_open(&fp, path, FA_READ) != FR_OK) return NULL; @@ -213,6 +252,9 @@ int sd_save_to_file(void *buf, u32 size, const char *filename) { FIL fp; u32 res = 0; + if (!sd_get_card_mounted()) + return FR_DISK_ERR; + res = f_open(&fp, filename, FA_CREATE_ALWAYS | FA_WRITE); if (res) { diff --git a/bdk/storage/sd.h b/bdk/storage/sd.h index 22d3359d..863fb3ce 100644 --- a/bdk/storage/sd.h +++ b/bdk/storage/sd.h @@ -1,150 +1,62 @@ /* - * 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: - * - * [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 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:12] Reserved (0) - * [11:8] Host Voltage Supply Flags - * [7:0] Check Pattern (0xAA) - */ - -/* - * SD_APP_GET_MKB 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: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 /* LINUX_MMC_SD_H */ + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef SD_H +#define SD_H + +#include +#include +#include + +#define SD_BLOCKSIZE 512 + +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/sd_def.h b/bdk/storage/sd_def.h new file mode 100644 index 00000000..5895b157 --- /dev/null +++ b/bdk/storage/sd_def.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved. + * Copyright (c) 2018-2023 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_POWER_LIMIT_0_72 0 +#define SD_SET_POWER_LIMIT_1_44 1 +#define SD_SET_POWER_LIMIT_2_16 2 +#define SD_SET_POWER_LIMIT_2_88 3 + +#define SD_MAX_POWER_0_72 (1 << SD_SET_POWER_LIMIT_0_72) +#define SD_MAX_POWER_1_44 (1 << SD_SET_POWER_LIMIT_1_44) +#define SD_MAX_POWER_2_16 (1 << SD_SET_POWER_LIMIT_2_16) +#define SD_MAX_POWER_2_88 (1 << SD_SET_POWER_LIMIT_2_88) + +/* + * SD_SWITCH mode + */ +#define SD_SWITCH_CHECK 0 +#define SD_SWITCH_SET 1 + +/* + * SD_SWITCH function groups + */ +#define SD_SWITCH_GRP_ACCESS 0 +#define SD_SWITCH_GRP_CMDSYS 1 +#define SD_SWITCH_GRP_DRVSTR 2 +#define SD_SWITCH_GRP_PWRLIM 3 + +/* + * 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 c87db833..7c5b12bf 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-2023 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,14 +16,16 @@ */ #include + +#include +#include +#include #include #include -#include #include +#include #include #include -#include -#include //#define DPRINTF(...) gfx_printf(__VA_ARGS__) #define DPRINTF(...) @@ -151,12 +153,16 @@ int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg) resp = -1; u32 timeout = get_tmr_ms() + 1500; - while (resp != (R1_READY_FOR_DATA | R1_STATE(R1_STATE_TRAN))) + while (true) { _sdmmc_storage_get_status(storage, &resp, 0); + if (resp == (R1_READY_FOR_DATA | R1_STATE(R1_STATE_TRAN))) + break; + if (get_tmr_ms() > timeout) break; + msleep(10); } return _sdmmc_storage_check_card_status(resp); @@ -174,11 +180,11 @@ int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf) 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.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; @@ -205,11 +211,11 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out sdmmc_init_cmd(&cmdbuf, is_write ? MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK, sector, SDMMC_RSP_TYPE_1, 0); - reqbuf.buf = buf; - reqbuf.num_sectors = num_sectors; - reqbuf.blksize = 512; - reqbuf.is_write = is_write; - reqbuf.is_multi_block = 1; + reqbuf.buf = buf; + reqbuf.num_sectors = num_sectors; + reqbuf.blksize = 512; + reqbuf.is_write = is_write; + reqbuf.is_multi_block = 1; reqbuf.is_auto_stop_trn = 1; if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, blkcnt_out)) @@ -264,20 +270,36 @@ static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 nu 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 (storage->sdmmc->id == SDMMC_1) + { + sd_error_count_increment(SD_ERROR_RW_FAIL); - if (first_reinit) - res = sd_initialize(true); - else + 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) { - res = sd_init_retry(true); - if (!res) - sd_error_count_increment(SD_ERROR_INIT_FAIL); + 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. @@ -285,7 +307,7 @@ static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 nu retries = 3; first_reinit = false; - // If succesful reinit, restart xfer. + // If successful reinit, restart xfer. if (res) { bbuf = (u8 *)buf; @@ -310,8 +332,8 @@ static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 nu int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf) { - // Ensure that buffer resides in DRAM and it's DMA aligned. - if (((u32)buf >= DRAM_START) && !((u32)buf % 8)) + // Ensure that SDMMC has access to buffer and it's SDMMC DMA aligned. + if (mc_client_has_access(buf) && !((u32)buf % 8)) return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 0); if (num_sectors > (SDMMC_UP_BUF_SZ / 512)) @@ -328,8 +350,8 @@ int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, vo int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf) { - // Ensure that buffer resides in DRAM and it's DMA aligned. - if (((u32)buf >= DRAM_START) && !((u32)buf % 8)) + // Ensure that SDMMC has access to buffer and it's SDMMC DMA aligned. + if (mc_client_has_access(buf) && !((u32)buf % 8)) return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 1); if (num_sectors > (SDMMC_UP_BUF_SZ / 512)) @@ -412,19 +434,19 @@ static void _mmc_storage_parse_cid(sdmmc_storage_t *storage) case 0: /* MMC v1.0 - v1.2 */ case 1: /* MMC v1.4 */ storage->cid.prod_name[6] = unstuff_bits(raw_cid, 48, 8); - storage->cid.manfid = unstuff_bits(raw_cid, 104, 24); - storage->cid.hwrev = unstuff_bits(raw_cid, 44, 4); - storage->cid.fwrev = unstuff_bits(raw_cid, 40, 4); - storage->cid.serial = unstuff_bits(raw_cid, 16, 24); + storage->cid.manfid = unstuff_bits(raw_cid, 104, 24); + storage->cid.hwrev = unstuff_bits(raw_cid, 44, 4); + storage->cid.fwrev = unstuff_bits(raw_cid, 40, 4); + storage->cid.serial = unstuff_bits(raw_cid, 16, 24); break; case 2: /* MMC v2.0 - v2.2 */ case 3: /* MMC v3.1 - v3.3 */ case 4: /* MMC v4 */ - storage->cid.manfid = unstuff_bits(raw_cid, 120, 8); - storage->cid.oemid = unstuff_bits(raw_cid, 104, 8); - storage->cid.prv = unstuff_bits(raw_cid, 48, 8); - storage->cid.serial = unstuff_bits(raw_cid, 16, 32); + storage->cid.manfid = unstuff_bits(raw_cid, 120, 8); + storage->cid.oemid = unstuff_bits(raw_cid, 104, 8); + storage->cid.prv = unstuff_bits(raw_cid, 48, 8); + storage->cid.serial = unstuff_bits(raw_cid, 16, 32); break; default: @@ -461,35 +483,34 @@ static void _mmc_storage_parse_csd(sdmmc_storage_t *storage) static void _mmc_storage_parse_ext_csd(sdmmc_storage_t *storage, u8 *buf) { - storage->ext_csd.rev = buf[EXT_CSD_REV]; - storage->ext_csd.ext_struct = buf[EXT_CSD_STRUCTURE]; - storage->ext_csd.card_type = buf[EXT_CSD_CARD_TYPE]; - storage->ext_csd.dev_version = *(u16 *)&buf[EXT_CSD_DEVICE_VERSION]; - storage->ext_csd.boot_mult = buf[EXT_CSD_BOOT_MULT]; - storage->ext_csd.rpmb_mult = buf[EXT_CSD_RPMB_MULT]; - //storage->ext_csd.bkops = buf[EXT_CSD_BKOPS_SUPPORT]; - //storage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN]; + storage->ext_csd.rev = buf[EXT_CSD_REV]; + storage->ext_csd.ext_struct = buf[EXT_CSD_STRUCTURE]; + storage->ext_csd.card_type = buf[EXT_CSD_CARD_TYPE]; + storage->ext_csd.dev_version = *(u16 *)&buf[EXT_CSD_DEVICE_VERSION]; + storage->ext_csd.boot_mult = buf[EXT_CSD_BOOT_MULT]; + storage->ext_csd.rpmb_mult = buf[EXT_CSD_RPMB_MULT]; + //storage->ext_csd.bkops = buf[EXT_CSD_BKOPS_SUPPORT]; + //storage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN]; //storage->ext_csd.bkops_status = buf[EXT_CSD_BKOPS_STATUS]; - storage->ext_csd.pre_eol_info = buf[EXT_CSD_PRE_EOL_INFO]; + storage->ext_csd.pre_eol_info = buf[EXT_CSD_PRE_EOL_INFO]; storage->ext_csd.dev_life_est_a = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]; storage->ext_csd.dev_life_est_b = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]; - storage->ext_csd.cache_size = - buf[EXT_CSD_CACHE_SIZE] | - (buf[EXT_CSD_CACHE_SIZE + 1] << 8) | - (buf[EXT_CSD_CACHE_SIZE + 2] << 16) | - (buf[EXT_CSD_CACHE_SIZE + 3] << 24); - storage->ext_csd.max_enh_mult = - (buf[EXT_CSD_MAX_ENH_SIZE_MULT] | - (buf[EXT_CSD_MAX_ENH_SIZE_MULT + 1] << 8) | - (buf[EXT_CSD_MAX_ENH_SIZE_MULT + 2] << 16)) * - buf[EXT_CSD_HC_WP_GRP_SIZE] * buf[EXT_CSD_HC_ERASE_GRP_SIZE]; + storage->ext_csd.cache_size = buf[EXT_CSD_CACHE_SIZE] | + (buf[EXT_CSD_CACHE_SIZE + 1] << 8) | + (buf[EXT_CSD_CACHE_SIZE + 2] << 16) | + (buf[EXT_CSD_CACHE_SIZE + 3] << 24); + + storage->ext_csd.max_enh_mult = (buf[EXT_CSD_MAX_ENH_SIZE_MULT] | + (buf[EXT_CSD_MAX_ENH_SIZE_MULT + 1] << 8) | + (buf[EXT_CSD_MAX_ENH_SIZE_MULT + 2] << 16)) * + buf[EXT_CSD_HC_WP_GRP_SIZE] * buf[EXT_CSD_HC_ERASE_GRP_SIZE]; storage->sec_cnt = *(u32 *)&buf[EXT_CSD_SEC_CNT]; } -static int _mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf) +int mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf) { sdmmc_cmd_t cmdbuf; sdmmc_init_cmd(&cmdbuf, MMC_SEND_EXT_CSD, 0, SDMMC_RSP_TYPE_1, 0); @@ -545,21 +566,21 @@ static int _mmc_storage_switch_buswidth(sdmmc_storage_t *storage, u32 bus_width) return 0; } -static int _mmc_storage_enable_HS(sdmmc_storage_t *storage, int check) +static int _mmc_storage_enable_HS(sdmmc_storage_t *storage, bool check_sts_before_clk_setup) { if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS))) return 0; - if (check && !_sdmmc_storage_check_status(storage)) + if (check_sts_before_clk_setup && !_sdmmc_storage_check_status(storage)) return 0; if (!sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_MMC_HS52)) return 0; -DPRINTF("[MMC] switched to HS\n"); +DPRINTF("[MMC] switched to HS52\n"); storage->csd.busspeed = 52; - if (check || _sdmmc_storage_check_status(storage)) + if (check_sts_before_clk_setup || _sdmmc_storage_check_status(storage)) return 1; return 0; @@ -589,7 +610,7 @@ static int _mmc_storage_enable_HS400(sdmmc_storage_t *storage) sdmmc_save_tap_value(storage->sdmmc); - if (!_mmc_storage_enable_HS(storage, 0)) + if (!_mmc_storage_enable_HS(storage, false)) return 0; if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_DDR_BUS_WIDTH_8))) @@ -610,27 +631,29 @@ DPRINTF("[MMC] switched to HS400\n"); static int _mmc_storage_enable_highspeed(sdmmc_storage_t *storage, u32 card_type, u32 type) { if (sdmmc_get_io_power(storage->sdmmc) != SDMMC_POWER_1_8) - goto out; + goto hs52_mode; + // HS400 needs 8-bit bus width mode. if (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 && card_type & EXT_CSD_CARD_TYPE_HS400_1_8V && type == SDHCI_TIMING_MMC_HS400) return _mmc_storage_enable_HS400(storage); - if (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 || - (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_4 - && card_type & EXT_CSD_CARD_TYPE_HS200_1_8V - && (type == SDHCI_TIMING_MMC_HS400 || type == SDHCI_TIMING_MMC_HS200))) + // Try HS200 if HS400 and 4-bit width bus or just HS200. + if ((sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 || + sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_4) && + card_type & EXT_CSD_CARD_TYPE_HS200_1_8V && + (type == SDHCI_TIMING_MMC_HS400 || type == SDHCI_TIMING_MMC_HS200)) return _mmc_storage_enable_HS200(storage); -out: +hs52_mode: if (card_type & EXT_CSD_CARD_TYPE_HS_52) - return _mmc_storage_enable_HS(storage, 1); + return _mmc_storage_enable_HS(storage, true); return 1; } /* -static int _mmc_storage_enable_bkops(sdmmc_storage_t *storage) +static int _mmc_storage_enable_auto_bkops(sdmmc_storage_t *storage) { if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_SET_BITS, EXT_CSD_BKOPS_EN, EXT_CSD_AUTO_BKOPS_MASK))) return 0; @@ -686,23 +709,22 @@ DPRINTF("[MMC] set blocklen to 512\n"); // Check system specification version, only version 4.0 and later support below features. if (storage->csd.mmca_vsn < CSD_SPEC_VER_4) - return 1; + goto done; if (!_mmc_storage_switch_buswidth(storage, bus_width)) return 0; DPRINTF("[MMC] switched buswidth\n"); - if (!_mmc_storage_get_ext_csd(storage, (u8 *)SDMMC_UPPER_BUFFER)) + if (!mmc_storage_get_ext_csd(storage, (u8 *)SDMMC_UPPER_BUFFER)) return 0; DPRINTF("[MMC] got ext_csd\n"); _mmc_storage_parse_cid(storage); // This needs to be after csd and ext_csd. - //gfx_hexdump(0, ext_csd, 512); /* if (storage->ext_csd.bkops & 0x1 && !(storage->ext_csd.bkops_en & EXT_CSD_AUTO_BKOPS_MASK)) { - _mmc_storage_enable_bkops(storage); + _mmc_storage_enable_auto_bkops(storage); DPRINTF("[MMC] BKOPS enabled\n"); } */ @@ -713,6 +735,7 @@ DPRINTF("[MMC] successfully switched to HS mode\n"); sdmmc_card_clock_powersave(storage->sdmmc, SDMMC_POWER_SAVE_ENABLE); +done: storage->initialized = 1; return 1; @@ -887,17 +910,17 @@ static void _sd_storage_parse_scr(sdmmc_storage_t *storage) storage->scr.cmds = unstuff_bits(resp, 32, 2); } -int _sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf) +int sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf) { sdmmc_cmd_t cmdbuf; sdmmc_init_cmd(&cmdbuf, SD_APP_SEND_SCR, 0, SDMMC_RSP_TYPE_1, 0); sdmmc_req_t reqbuf; - reqbuf.buf = buf; - reqbuf.blksize = 8; - reqbuf.num_sectors = 1; - reqbuf.is_write = 0; - reqbuf.is_multi_block = 0; + reqbuf.buf = buf; + reqbuf.blksize = 8; + reqbuf.num_sectors = 1; + reqbuf.is_write = 0; + reqbuf.is_multi_block = 0; reqbuf.is_auto_stop_trn = 0; if (!_sd_storage_execute_app_cmd(storage, R1_STATE_TRAN, 0, &cmdbuf, &reqbuf, NULL)) @@ -914,33 +937,34 @@ int _sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf) storage->raw_scr[i] = buf[i + 3]; } _sd_storage_parse_scr(storage); - //gfx_hexdump(0, storage->raw_scr, 8); return _sdmmc_storage_check_card_status(tmp); } -int _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf) +static int _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf) { sdmmc_cmd_t cmdbuf; sdmmc_init_cmd(&cmdbuf, SD_SWITCH, 0xFFFFFF, SDMMC_RSP_TYPE_1, 0); sdmmc_req_t reqbuf; - reqbuf.buf = buf; - reqbuf.blksize = 64; - reqbuf.num_sectors = 1; - reqbuf.is_write = 0; - reqbuf.is_multi_block = 0; + reqbuf.buf = buf; + reqbuf.blksize = 64; + reqbuf.num_sectors = 1; + reqbuf.is_write = 0; + reqbuf.is_multi_block = 0; reqbuf.is_auto_stop_trn = 0; if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL)) return 0; + //gfx_hexdump(0, (u8 *)buf, 64); + u32 tmp = 0; sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1); return _sdmmc_storage_check_card_status(tmp); } -int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int group, u32 arg) +static int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int group, u32 arg) { sdmmc_cmd_t cmdbuf; u32 switchcmd = mode << 31 | 0x00FFFFFF; @@ -949,11 +973,11 @@ int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int group, sdmmc_init_cmd(&cmdbuf, SD_SWITCH, switchcmd, SDMMC_RSP_TYPE_1, 0); sdmmc_req_t reqbuf; - reqbuf.buf = buf; - reqbuf.blksize = 64; - reqbuf.num_sectors = 1; - reqbuf.is_write = 0; - reqbuf.is_multi_block = 0; + reqbuf.buf = buf; + reqbuf.blksize = 64; + reqbuf.num_sectors = 1; + reqbuf.is_write = 0; + reqbuf.is_multi_block = 0; reqbuf.is_auto_stop_trn = 0; if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL)) @@ -964,46 +988,53 @@ int _sd_storage_switch(sdmmc_storage_t *storage, void *buf, int mode, int group, return _sdmmc_storage_check_card_status(tmp); } -void _sd_storage_set_current_limit(sdmmc_storage_t *storage, u16 current_limit, u8 *buf) +static void _sd_storage_set_power_limit(sdmmc_storage_t *storage, u16 power_limit, u8 *buf) { - u32 pwr = SD_SET_CURRENT_LIMIT_200; - - if (current_limit & SD_MAX_CURRENT_800) - pwr = SD_SET_CURRENT_LIMIT_800; - else if (current_limit & SD_MAX_CURRENT_600) - pwr = SD_SET_CURRENT_LIMIT_600; - else if (current_limit & SD_MAX_CURRENT_400) - pwr = SD_SET_CURRENT_LIMIT_400; - - _sd_storage_switch(storage, buf, SD_SWITCH_SET, 3, pwr); + u32 pwr = SD_SET_POWER_LIMIT_0_72; + +// If UHS-I only, anything above 1.44W defaults to 1.44W. +#if SDMMC_UHS2_SUPPORT + if (power_limit & SD_MAX_POWER_2_88) + pwr = SD_SET_POWER_LIMIT_2_88; + else if (power_limit & SD_MAX_POWER_2_16) + pwr = SD_SET_POWER_LIMIT_2_16; + else if (power_limit & SD_MAX_POWER_1_44) + pwr = SD_SET_POWER_LIMIT_1_44; +#else + if (power_limit & SD_MAX_POWER_1_44) + pwr = SD_SET_POWER_LIMIT_1_44; +#endif + + _sd_storage_switch(storage, buf, SD_SWITCH_SET, SD_SWITCH_GRP_PWRLIM, pwr); if (((buf[15] >> 4) & 0x0F) == pwr) { switch (pwr) { - case SD_SET_CURRENT_LIMIT_800: -DPRINTF("[SD] power limit raised to 800mA\n"); +#if SDMMC_UHS2_SUPPORT + case SD_SET_POWER_LIMIT_2_88: +DPRINTF("[SD] power limit raised to 2880 mW\n"); break; - case SD_SET_CURRENT_LIMIT_600: -DPRINTF("[SD] power limit raised to 600mA\n"); + case SD_SET_POWER_LIMIT_2_16: +DPRINTF("[SD] power limit raised to 2160 mW\n"); break; - - case SD_SET_CURRENT_LIMIT_400: -DPRINTF("[SD] power limit raised to 400mA\n"); +#endif + case SD_SET_POWER_LIMIT_1_44: +DPRINTF("[SD] power limit raised to 1440 mW\n"); break; default: - case SD_SET_CURRENT_LIMIT_200: -DPRINTF("[SD] power limit defaulted to 200mA\n"); + case SD_SET_POWER_LIMIT_0_72: +DPRINTF("[SD] power limit defaulted to 720 mW\n"); break; } } } -int _sd_storage_enable_highspeed(sdmmc_storage_t *storage, u32 hs_type, u8 *buf) +static int _sd_storage_enable_highspeed(sdmmc_storage_t *storage, u32 hs_type, u8 *buf) { - if (!_sd_storage_switch(storage, buf, SD_SWITCH_CHECK, 0, hs_type)) + if (!_sd_storage_switch(storage, buf, SD_SWITCH_CHECK, SD_SWITCH_GRP_ACCESS, hs_type)) return 0; DPRINTF("[SD] supports (U)HS mode: %d\n", buf[16] & 0xF); @@ -1013,11 +1044,12 @@ DPRINTF("[SD] supports (U)HS mode: %d\n", buf[16] & 0xF); DPRINTF("[SD] supports selected (U)HS mode\n"); u16 total_pwr_consumption = ((u16)buf[0] << 8) | buf[1]; -DPRINTF("[SD] total max current: %d\n", total_pwr_consumption); +DPRINTF("[SD] max power: %d mW\n", total_pwr_consumption * 3600 / 1000); + storage->card_power_limit = total_pwr_consumption; if (total_pwr_consumption <= 800) { - if (!_sd_storage_switch(storage, buf, SD_SWITCH_SET, 0, hs_type)) + if (!_sd_storage_switch(storage, buf, SD_SWITCH_SET, SD_SWITCH_GRP_ACCESS, hs_type)) return 0; if (type_out != (buf[16] & 0xF)) @@ -1025,26 +1057,25 @@ DPRINTF("[SD] total max current: %d\n", total_pwr_consumption); return 1; } -DPRINTF("[SD] card max current over limit\n"); +DPRINTF("[SD] card max power over limit\n"); return 0; } -int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf) +static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf) { if (sdmmc_get_bus_width(storage->sdmmc) != SDMMC_BUS_WIDTH_4) return 0; if (!_sd_storage_switch_get(storage, buf)) return 0; - //gfx_hexdump(0, (u8 *)buf, 64); u8 access_mode = buf[13]; - u16 current_limit = buf[7] | buf[6] << 8; -DPRINTF("[SD] access: %02X, current: %02X\n", access_mode, current_limit); + u16 power_limit = buf[7] | buf[6] << 8; +DPRINTF("[SD] access: %02X, power: %02X\n", access_mode, power_limit); - // Try to raise the current limit to let the card perform better. - _sd_storage_set_current_limit(storage, current_limit, buf); + // Try to raise the power limit to let the card perform better. + _sd_storage_set_power_limit(storage, power_limit, buf); u32 hs_type = 0; switch (type) @@ -1076,6 +1107,7 @@ DPRINTF("[SD] bus speed set to SDR50\n"); storage->csd.busspeed = 50; break; } +/* case SDHCI_TIMING_UHS_SDR25: if (access_mode & SD_MODE_UHS_SDR25) { @@ -1085,6 +1117,7 @@ DPRINTF("[SD] bus speed set to SDR25\n"); storage->csd.busspeed = 25; break; } +*/ case SDHCI_TIMING_UHS_SDR12: if (!(access_mode & SD_MODE_UHS_SDR12)) return 0; @@ -1111,17 +1144,17 @@ DPRINTF("[SD] after tuning\n"); return _sdmmc_storage_check_status(storage); } -int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage, u8 *buf) +static int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage, u8 *buf) { if (!_sd_storage_switch_get(storage, buf)) return 0; - //gfx_hexdump(0, (u8 *)buf, 64); u8 access_mode = buf[13]; - u16 current_limit = buf[7] | buf[6] << 8; + u16 power_limit = buf[7] | buf[6] << 8; +DPRINTF("[SD] access: %02X, power: %02X\n", access_mode, power_limit); - // Try to raise the current limit to let the card perform better. - _sd_storage_set_current_limit(storage, current_limit, buf); + // Try to raise the power limit to let the card perform better. + _sd_storage_set_power_limit(storage, power_limit, buf); if (!(access_mode & SD_MODE_HIGH_SPEED)) return 1; @@ -1146,7 +1179,7 @@ u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage) { u32 shift = au_size; au_size = shift ? 8 : 0; - au_size <<= shift; + au_size <<= shift; } else { @@ -1176,8 +1209,8 @@ u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage) static void _sd_storage_parse_ssr(sdmmc_storage_t *storage) { // unstuff_bits supports only 4 u32 so break into 2 x u32x4 groups. - u32 raw_ssr1[4]; - u32 raw_ssr2[4]; + u32 raw_ssr1[4]; // 511:384. + u32 raw_ssr2[4]; // 383:256. memcpy(raw_ssr1, &storage->raw_ssr[0], 16); memcpy(raw_ssr2, &storage->raw_ssr[16], 16); @@ -1203,11 +1236,11 @@ static void _sd_storage_parse_ssr(sdmmc_storage_t *storage) storage->ssr.speed_class = speed_class; break; } - storage->ssr.uhs_grade = unstuff_bits(raw_ssr1, 396 - 384, 4); + storage->ssr.uhs_grade = unstuff_bits(raw_ssr1, 396 - 384, 4); storage->ssr.video_class = unstuff_bits(raw_ssr1, 384 - 384, 8); - storage->ssr.app_class = unstuff_bits(raw_ssr2, 336 - 256, 4); + storage->ssr.app_class = unstuff_bits(raw_ssr2, 336 - 256, 4); - storage->ssr.au_size = unstuff_bits(raw_ssr1, 428 - 384, 4); + storage->ssr.au_size = unstuff_bits(raw_ssr1, 428 - 384, 4); storage->ssr.uhs_au_size = unstuff_bits(raw_ssr1, 392 - 384, 4); } @@ -1217,11 +1250,11 @@ int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf) sdmmc_init_cmd(&cmdbuf, SD_APP_SD_STATUS, 0, SDMMC_RSP_TYPE_1, 0); sdmmc_req_t reqbuf; - reqbuf.buf = buf; - reqbuf.blksize = 64; - reqbuf.num_sectors = 1; - reqbuf.is_write = 0; - reqbuf.is_multi_block = 0; + reqbuf.buf = buf; + reqbuf.blksize = 64; + reqbuf.num_sectors = 1; + reqbuf.is_write = 0; + reqbuf.is_multi_block = 0; reqbuf.is_auto_stop_trn = 0; if (!(storage->csd.cmdclass & CCC_APP_SPEC)) @@ -1246,7 +1279,6 @@ DPRINTF("[SD] ssr: Not supported\n"); } _sd_storage_parse_ssr(storage); - //gfx_hexdump(0, storage->raw_ssr, 64); return _sdmmc_storage_check_card_status(tmp); } @@ -1255,26 +1287,26 @@ static void _sd_storage_parse_cid(sdmmc_storage_t *storage) { u32 *raw_cid = (u32 *)&(storage->raw_cid); - storage->cid.manfid = unstuff_bits(raw_cid, 120, 8); - storage->cid.oemid = unstuff_bits(raw_cid, 104, 16); + storage->cid.manfid = unstuff_bits(raw_cid, 120, 8); + storage->cid.oemid = unstuff_bits(raw_cid, 104, 16); storage->cid.prod_name[0] = unstuff_bits(raw_cid, 96, 8); storage->cid.prod_name[1] = unstuff_bits(raw_cid, 88, 8); storage->cid.prod_name[2] = unstuff_bits(raw_cid, 80, 8); storage->cid.prod_name[3] = unstuff_bits(raw_cid, 72, 8); storage->cid.prod_name[4] = unstuff_bits(raw_cid, 64, 8); - storage->cid.hwrev = unstuff_bits(raw_cid, 60, 4); - storage->cid.fwrev = unstuff_bits(raw_cid, 56, 4); - storage->cid.serial = unstuff_bits(raw_cid, 24, 32); - storage->cid.year = unstuff_bits(raw_cid, 12, 8) + 2000; - storage->cid.month = unstuff_bits(raw_cid, 8, 4); + storage->cid.hwrev = unstuff_bits(raw_cid, 60, 4); + storage->cid.fwrev = unstuff_bits(raw_cid, 56, 4); + storage->cid.serial = unstuff_bits(raw_cid, 24, 32); + storage->cid.year = unstuff_bits(raw_cid, 12, 8) + 2000; + storage->cid.month = unstuff_bits(raw_cid, 8, 4); } static void _sd_storage_parse_csd(sdmmc_storage_t *storage) { u32 *raw_csd = (u32 *)&(storage->raw_csd); - storage->csd.structure = unstuff_bits(raw_csd, 126, 2); - storage->csd.cmdclass = unstuff_bits(raw_csd, 84, 12); + storage->csd.structure = unstuff_bits(raw_csd, 126, 2); + storage->csd.cmdclass = unstuff_bits(raw_csd, 84, 12); storage->csd.read_blkbits = unstuff_bits(raw_csd, 80, 4); storage->csd.write_protect = unstuff_bits(raw_csd, 12, 2); switch(storage->csd.structure) @@ -1285,8 +1317,8 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage) break; case 1: - storage->csd.c_size = (1 + unstuff_bits(raw_csd, 48, 22)); - storage->csd.capacity = storage->csd.c_size << 10; + storage->csd.c_size = (1 + unstuff_bits(raw_csd, 48, 22)); + storage->csd.capacity = storage->csd.c_size << 10; storage->csd.read_blkbits = 9; break; @@ -1390,7 +1422,7 @@ DPRINTF("[SD] set blocklen to 512\n"); return 0; DPRINTF("[SD] cleared card detect\n"); - if (!_sd_storage_get_scr(storage, buf)) + if (!sd_storage_get_scr(storage, buf)) return 0; DPRINTF("[SD] got scr\n"); @@ -1457,11 +1489,11 @@ int _gc_storage_custom_cmd(sdmmc_storage_t *storage, void *buf) sdmmc_init_cmd(&cmdbuf, MMC_VENDOR_60_CMD, 0, SDMMC_RSP_TYPE_1, 1); sdmmc_req_t reqbuf; - reqbuf.buf = buf; - reqbuf.blksize = 64; - reqbuf.num_sectors = 1; - reqbuf.is_write = 1; - reqbuf.is_multi_block = 0; + reqbuf.buf = buf; + reqbuf.blksize = 64; + reqbuf.num_sectors = 1; + reqbuf.is_write = 1; + reqbuf.is_multi_block = 0; reqbuf.is_auto_stop_trn = 0; if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, &reqbuf, NULL)) @@ -1482,13 +1514,13 @@ int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc) memset(storage, 0, sizeof(sdmmc_storage_t)); storage->sdmmc = sdmmc; - if (!sdmmc_init(sdmmc, SDMMC_2, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS102, SDMMC_POWER_SAVE_DISABLE)) + if (!sdmmc_init(sdmmc, SDMMC_2, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_DDR100, SDMMC_POWER_SAVE_DISABLE)) return 0; DPRINTF("[gc] after init\n"); usleep(1000 + (10000 + sdmmc->divisor - 1) / sdmmc->divisor); - if (!sdmmc_tuning_execute(storage->sdmmc, SDHCI_TIMING_MMC_HS102, MMC_SEND_TUNING_BLOCK_HS200)) + if (!sdmmc_tuning_execute(storage->sdmmc, SDHCI_TIMING_MMC_DDR100, MMC_SEND_TUNING_BLOCK_HS200)) return 0; DPRINTF("[gc] after tuning\n"); diff --git a/bdk/storage/sdmmc.h b/bdk/storage/sdmmc.h index 5dcd10f0..283e0d4b 100644 --- a/bdk/storage/sdmmc.h +++ b/bdk/storage/sdmmc.h @@ -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, @@ -129,10 +129,7 @@ typedef struct _mmc_csd u16 cmdclass; u32 c_size; u32 r2w_factor; - u32 max_dtr; - u32 erase_size; /* In sectors */ u32 read_blkbits; - u32 write_blkbits; u32 capacity; u8 write_protect; u16 busspeed; @@ -186,6 +183,7 @@ typedef struct _sdmmc_storage_t int is_low_voltage; u32 partition; int initialized; + u32 card_power_limit; u8 raw_cid[0x10]; u8 raw_csd[0x10]; u8 raw_scr[8]; @@ -209,6 +207,9 @@ 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 mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf); + +int sd_storage_get_scr(sdmmc_storage_t *storage, u8 *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 4e4ebc95..e153805c 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-2023 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,14 +27,14 @@ #include #include #include +#include #include -#include //#define DPRINTF(...) gfx_printf(__VA_ARGS__) //#define ERROR_EXTRA_PRINTING #define DPRINTF(...) -#ifdef NYX +#ifdef BDK_SDMMC_OC_AND_EXTRA_PRINT #define ERROR_EXTRA_PRINTING #define SDMMC_EMMC_OC #endif @@ -88,9 +88,9 @@ static int _sdmmc_set_io_power(sdmmc_t *sdmmc, u32 power) u32 sdmmc_get_bus_width(sdmmc_t *sdmmc) { u32 h = sdmmc->regs->hostctl; - if (h & SDHCI_CTRL_8BITBUS) + if (h & SDHCI_CTRL_8BITBUS) // eMMC only (or UHS-II). return SDMMC_BUS_WIDTH_8; - if (h & SDHCI_CTRL_4BITBUS) + if (h & SDHCI_CTRL_4BITBUS) // SD only. return SDMMC_BUS_WIDTH_4; return SDMMC_BUS_WIDTH_1; } @@ -102,9 +102,9 @@ void sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width) if (bus_width == SDMMC_BUS_WIDTH_1) sdmmc->regs->hostctl = host_control; else if (bus_width == SDMMC_BUS_WIDTH_4) - sdmmc->regs->hostctl = host_control | SDHCI_CTRL_4BITBUS; + sdmmc->regs->hostctl = host_control | SDHCI_CTRL_4BITBUS; // SD only. else if (bus_width == SDMMC_BUS_WIDTH_8) - sdmmc->regs->hostctl = host_control | SDHCI_CTRL_8BITBUS; + sdmmc->regs->hostctl = host_control | SDHCI_CTRL_8BITBUS; // eMMC only (or UHS-II). } void sdmmc_save_tap_value(sdmmc_t *sdmmc) @@ -116,7 +116,7 @@ void sdmmc_save_tap_value(sdmmc_t *sdmmc) static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type) { const u32 dqs_trim_val = 0x28; - const u32 tap_values_t210[] = { 4, 0, 3, 0 }; + const u8 tap_values_t210[4] = { 4, 0, 3, 0 }; u32 tap_val = 0; @@ -140,9 +140,9 @@ static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type) return 1; } -static int _sdmmc_commit_changes(sdmmc_t *sdmmc) +static void _sdmmc_commit_changes(sdmmc_t *sdmmc) { - return sdmmc->regs->clkcon; + (void)sdmmc->regs->clkcon; } static void _sdmmc_pad_config_fallback(sdmmc_t *sdmmc, u32 power) @@ -173,8 +173,8 @@ static void _sdmmc_pad_config_fallback(sdmmc_t *sdmmc, u32 power) break; case SDMMC_4: // 50 Ohm 2X Driver. PU:16, PD:16, B01: PU:10, PD:10. - APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) = - (APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0xFFFFC003) | (sdmmc->t210b01 ? 0xA28 : 0x1040); + APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0xFFFFC003) | + (sdmmc->t210b01 ? 0xA28 : 0x1040); (void)APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL); // Commit write. break; } @@ -218,9 +218,9 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power) u8 code_mask = (sdmmc->t210b01 || sdmmc->id != SDMMC_1) ? 0x1F : 0x7F; u8 autocal_pu_status = sdmmc->regs->autocalsts & code_mask; if (!autocal_pu_status) - EPRINTF("SDMMC: Comp Pad short to gnd!"); + EPRINTFARGS("SDMMC%d: Comp Pad short to gnd!", sdmmc->id + 1); else if (autocal_pu_status == code_mask) - EPRINTF("SDMMC: Comp Pad open!"); + EPRINTFARGS("SDMMC%d: Comp Pad open!", sdmmc->id + 1); #endif // In case auto calibration fails, we load suggested standard values. @@ -233,7 +233,7 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power) // Disable E_INPUT to conserve power. sdmmc->regs->sdmemcmppadctl &= ~TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD; - if(should_enable_sd_clock) + if (should_enable_sd_clock) sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN; } @@ -330,7 +330,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) case SDHCI_TIMING_MMC_HS52: case SDHCI_TIMING_SD_HS25: - sdmmc->regs->hostctl |= SDHCI_CTRL_HISPD; + sdmmc->regs->hostctl |= SDHCI_CTRL_HISPD; // SD only? sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_VDD_180; break; @@ -339,24 +339,24 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) case SDHCI_TIMING_UHS_SDR104: case SDHCI_TIMING_UHS_SDR82: case SDHCI_TIMING_UHS_DDR50: - case SDHCI_TIMING_MMC_HS102: - sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR104_BUS_SPEED; + case SDHCI_TIMING_MMC_DDR100: + sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_SDR104_BUS_SPEED; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; break; case SDHCI_TIMING_MMC_HS400: // Non standard. - sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | HS400_BUS_SPEED; + sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | HS400_BUS_SPEED; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; break; case SDHCI_TIMING_UHS_SDR25: - sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR25_BUS_SPEED; + sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_SDR25_BUS_SPEED; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; break; case SDHCI_TIMING_UHS_SDR12: - sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR12_BUS_SPEED; + sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_SDR12_BUS_SPEED; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; break; } @@ -521,7 +521,7 @@ static int _sdmmc_wait_cmd_data_inhibit(sdmmc_t *sdmmc, bool wait_dat) _sdmmc_commit_changes(sdmmc); u32 timeout = get_tmr_ms() + 2000; - while(sdmmc->regs->prnsts & SDHCI_CMD_INHIBIT) + while (sdmmc->regs->prnsts & SDHCI_CMD_INHIBIT) if (get_tmr_ms() > timeout) { _sdmmc_reset(sdmmc); @@ -547,7 +547,7 @@ static int _sdmmc_wait_card_busy(sdmmc_t *sdmmc) _sdmmc_commit_changes(sdmmc); u32 timeout = get_tmr_ms() + 2000; - while (!(sdmmc->regs->prnsts & SDHCI_DATA_0_LVL_MASK)) + while (!(sdmmc->regs->prnsts & SDHCI_DATA_0_LVL)) if (get_tmr_ms() > timeout) { _sdmmc_reset(sdmmc); @@ -687,7 +687,7 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd) case SDHCI_TIMING_UHS_SDR50: case SDHCI_TIMING_UHS_DDR50: - case SDHCI_TIMING_MMC_HS102: + case SDHCI_TIMING_MMC_DDR100: max = 256; flag = (4 << 13); // 256 iterations. break; @@ -734,6 +734,7 @@ static int _sdmmc_enable_internal_clock(sdmmc_t *sdmmc) sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_PRESET_VAL_EN; sdmmc->regs->clkcon &= ~SDHCI_PROG_CLOCK_MODE; + // Enable 32bit addressing if used (sysad. if blkcnt it fallbacks to 16bit). sdmmc->regs->hostctl2 |= SDHCI_HOST_VERSION_4_EN; if (!(sdmmc->regs->capareg & SDHCI_CAN_64BIT)) @@ -741,7 +742,7 @@ static int _sdmmc_enable_internal_clock(sdmmc_t *sdmmc) sdmmc->regs->hostctl2 |= SDHCI_ADDRESSING_64BIT_EN; sdmmc->regs->hostctl &= ~SDHCI_CTRL_DMA_MASK; - sdmmc->regs->timeoutcon = (sdmmc->regs->timeoutcon & 0xF0) | 0xE; + sdmmc->regs->timeoutcon = (sdmmc->regs->timeoutcon & 0xF0) | 14; // TMCLK * 2^27. return 1; } @@ -806,7 +807,7 @@ static void _sdmmc_mask_interrupts(sdmmc_t *sdmmc) sdmmc->regs->norintstsen &= ~(SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE); } -static int _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask) +static u32 _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask) { u16 norintsts = sdmmc->regs->norintsts; u16 errintsts = sdmmc->regs->errintsts; @@ -820,7 +821,7 @@ DPRINTF("norintsts %08X, errintsts %08X\n", norintsts, errintsts); if (norintsts & SDHCI_INT_ERROR) { #ifdef ERROR_EXTRA_PRINTING - EPRINTFARGS("SDMMC: norintsts %08X, errintsts %08X\n", norintsts, errintsts); + EPRINTFARGS("SDMMC%d: norintsts %08X, errintsts %08X\n", sdmmc->id + 1, norintsts, errintsts); #endif sdmmc->regs->errintsts = errintsts; return SDMMC_MASKINT_ERROR; @@ -841,7 +842,7 @@ static int _sdmmc_wait_response(sdmmc_t *sdmmc) u32 timeout = get_tmr_ms() + 2000; while (true) { - int result = _sdmmc_check_mask_interrupt(sdmmc, NULL, SDHCI_INT_RESPONSE); + u32 result = _sdmmc_check_mask_interrupt(sdmmc, NULL, SDHCI_INT_RESPONSE); if (result == SDMMC_MASKINT_MASKED) break; if (result != SDMMC_MASKINT_NOERROR || get_tmr_ms() > timeout) @@ -937,7 +938,7 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req) // Set mulitblock request. if (req->is_multi_block) - trnmode = SDHCI_TRNS_MULTI | SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_DMA; + trnmode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_BLK_CNT_EN; // Set request direction. if (!req->is_write) @@ -963,13 +964,13 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc) u32 timeout = get_tmr_ms() + 1500; do { - int result = 0; + u32 result = SDMMC_MASKINT_MASKED; while (true) { u16 intr = 0; result = _sdmmc_check_mask_interrupt(sdmmc, &intr, SDHCI_INT_DATA_END | SDHCI_INT_DMA_END); - if (result < 0) + if (result != SDMMC_MASKINT_MASKED) break; if (intr & SDHCI_INT_DATA_END) @@ -983,10 +984,11 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc) sdmmc->dma_addr_next += 0x80000; } } + if (result != SDMMC_MASKINT_NOERROR) { #ifdef ERROR_EXTRA_PRINTING - EPRINTFARGS("%08X!", result); + EPRINTFARGS("SDMMC%d: %08X!", sdmmc->id + 1, result); #endif _sdmmc_reset(sdmmc); return 0; @@ -1011,13 +1013,13 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_ if (!_sdmmc_config_dma(sdmmc, &blkcnt, req)) { #ifdef ERROR_EXTRA_PRINTING - EPRINTF("SDMMC: DMA Wrong cfg!"); + EPRINTFARGS("SDMMC%d: DMA Wrong cfg!", sdmmc->id + 1); #endif return 0; } // Flush cache before starting the transfer. - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); + bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false); is_data_present = true; } @@ -1027,7 +1029,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_ if (!_sdmmc_send_cmd(sdmmc, cmd, is_data_present)) { #ifdef ERROR_EXTRA_PRINTING - EPRINTFARGS("SDMMC: Wrong Response type %08X!", cmd->rsp_type); + EPRINTFARGS("SDMMC%d: Wrong Response type %08X!", sdmmc->id + 1, cmd->rsp_type); #endif return 0; } @@ -1035,7 +1037,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_ int result = _sdmmc_wait_response(sdmmc); #ifdef ERROR_EXTRA_PRINTING if (!result) - EPRINTF("SDMMC: Transfer timeout!"); + EPRINTFARGS("SDMMC%d: Transfer timeout!", sdmmc->id + 1); #endif DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result, sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3); @@ -1047,7 +1049,7 @@ DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result, result = _sdmmc_cache_rsp(sdmmc, sdmmc->rsp, 0x10, cmd->rsp_type); #ifdef ERROR_EXTRA_PRINTING if (!result) - EPRINTF("SDMMC: Unknown response type!"); + EPRINTFARGS("SDMMC%d: Unknown response type!", sdmmc->id + 1); #endif } if (req && result) @@ -1055,7 +1057,7 @@ DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result, result = _sdmmc_update_dma(sdmmc); #ifdef ERROR_EXTRA_PRINTING if (!result) - EPRINTF("SDMMC: DMA Update failed!"); + EPRINTFARGS("SDMMC%d: DMA Update failed!", sdmmc->id + 1); #endif } } @@ -1066,8 +1068,8 @@ DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result, { if (req) { - // Flush cache after transfer. - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); + // Invalidate cache after transfer. + bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false); if (blkcnt_out) *blkcnt_out = blkcnt; @@ -1081,7 +1083,7 @@ DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result, result = _sdmmc_wait_card_busy(sdmmc); #ifdef ERROR_EXTRA_PRINTING if (!result) - EPRINTF("SDMMC: Busy timeout!"); + EPRINTFARGS("SDMMC%d: Busy timeout!", sdmmc->id + 1); #endif return result; } @@ -1149,12 +1151,11 @@ static int _sdmmc_config_sdmmc1(bool t210b01) // Configure SD card detect. PINMUX_AUX(PINMUX_AUX_GPIO_PZ1) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | 2; // GPIO control, pull up. APB_MISC(APB_MISC_GP_VGPIO_GPIO_MUX_SEL) = 0; - gpio_config(GPIO_PORT_Z, GPIO_PIN_1, GPIO_MODE_GPIO); - gpio_output_enable(GPIO_PORT_Z, GPIO_PIN_1, GPIO_OUTPUT_DISABLE); + gpio_direction_input(GPIO_PORT_Z, GPIO_PIN_1); usleep(100); // Check if SD card is inserted. - if(!sdmmc_get_sd_inserted()) + if (!sdmmc_get_sd_inserted()) return 0; /* @@ -1185,20 +1186,20 @@ static int _sdmmc_config_sdmmc1(bool t210b01) _sdmmc_config_sdmmc1_schmitt(); // Make sure the SDMMC1 controller is powered. + PMC(APBDEV_PMC_NO_IOPOWER) |= PMC_NO_IOPOWER_SDMMC1_IO_EN; + usleep(1000); PMC(APBDEV_PMC_NO_IOPOWER) &= ~(PMC_NO_IOPOWER_SDMMC1_IO_EN); (void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write. + // Set enable SD card power. + PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_PULL_DOWN | 2; + gpio_direction_output(GPIO_PORT_E, GPIO_PIN_4, GPIO_HIGH); + usleep(10000); + // Inform IO pads that voltage is gonna be 3.3V. PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_SDMMC1_IO_EN; (void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write. - // Set enable SD card power. - PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_PULL_DOWN | 2; // Pull down. - gpio_config(GPIO_PORT_E, GPIO_PIN_4, GPIO_MODE_GPIO); - gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_HIGH); - gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_ENABLE); - usleep(10000); - // Enable SD card IO power. max7762x_regulator_set_voltage(REGULATOR_LDO2, 3300000); max7762x_regulator_enable(REGULATOR_LDO2, true); @@ -1235,7 +1236,7 @@ static void _sdmmc_config_emmc(u32 id, bool t210b01) APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) &= 0xF8003FFF; // Set default pad cfg. if (t210b01) - APB_MISC(APB_MISC_GP_EMMC4_PAD_PUPD_CFGPADCTRL) &= 0xFFBFFFF9; // Unset CMD/CLK/DQS powedown. + APB_MISC(APB_MISC_GP_EMMC4_PAD_PUPD_CFGPADCTRL) &= 0xFFBFFFF9; // Unset CMD/CLK/DQS weak pull up/down. // Enable schmitt trigger. APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) |= 1; (void)APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL); // Commit write. @@ -1249,9 +1250,9 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int p u16 divisor; u8 vref_sel = 7; - const u32 trim_values_t210[] = { 2, 8, 3, 8 }; - const u32 trim_values_t210b01[] = { 14, 13, 15, 13 }; - const u32 *trim_values = sdmmc->t210b01 ? trim_values_t210b01 : trim_values_t210; + const u8 trim_values_t210[4] = { 2, 8, 3, 8 }; + const u8 trim_values_t210b01[4] = { 14, 13, 15, 13 }; + const u8 *trim_values; if (id > SDMMC_4 || id == SDMMC_3) return 0; @@ -1263,6 +1264,8 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int p sdmmc->clock_stopped = 1; sdmmc->t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01; + trim_values = sdmmc->t210b01 ? trim_values_t210b01 : trim_values_t210; + // Do specific SDMMC HW configuration. switch (id) { @@ -1300,7 +1303,7 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int p // Set default pad IO trimming configuration. sdmmc->regs->iospare |= 0x80000; // Enable muxing. sdmmc->regs->veniotrimctl &= 0xFFFFFFFB; // Set Band Gap VREG to supply DLL. - sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xE0FFFFFB) | (trim_values[sdmmc->id] << 24); + sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xE0FFFFFB) | ((u32)trim_values[sdmmc->id] << 24); sdmmc->regs->sdmemcmppadctl = (sdmmc->regs->sdmemcmppadctl & TEGRA_MMC_SDMEMCOMPPADCTRL_COMP_VREF_SEL_MASK) | vref_sel; @@ -1419,7 +1422,7 @@ int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *b int sdmmc_enable_low_voltage(sdmmc_t *sdmmc) { - if(sdmmc->id != SDMMC_1) + if (sdmmc->id != SDMMC_1) return 0; if (!sdmmc_setup_clock(sdmmc, SDHCI_TIMING_UHS_SDR12)) diff --git a/bdk/storage/sdmmc_driver.h b/bdk/storage/sdmmc_driver.h index 696ce4d8..43263b8c 100644 --- a/bdk/storage/sdmmc_driver.h +++ b/bdk/storage/sdmmc_driver.h @@ -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, @@ -22,10 +22,10 @@ #include /*! SDMMC controller IDs. */ -#define SDMMC_1 0 -#define SDMMC_2 1 -#define SDMMC_3 2 -#define SDMMC_4 3 +#define SDMMC_1 0 // Version 4.00. +#define SDMMC_2 1 // Version 5.1. +#define SDMMC_3 2 // Version 4.00. +#define SDMMC_4 3 // Version 5.1. /*! SDMMC power types. */ #define SDMMC_POWER_OFF 0 @@ -47,33 +47,43 @@ /*! SDMMC mask interrupt status. */ #define SDMMC_MASKINT_MASKED 0 -#define SDMMC_MASKINT_NOERROR -1 -#define SDMMC_MASKINT_ERROR -2 +#define SDMMC_MASKINT_NOERROR 1 +#define SDMMC_MASKINT_ERROR 2 /*! SDMMC present state. */ -#define SDHCI_CMD_INHIBIT 0x1 -#define SDHCI_DATA_INHIBIT 0x2 -#define SDHCI_DOING_WRITE 0x100 -#define SDHCI_DOING_READ 0x200 -#define SDHCI_SPACE_AVAILABLE 0x400 -#define SDHCI_DATA_AVAILABLE 0x800 -#define SDHCI_CARD_PRESENT 0x10000 -#define SDHCI_CD_STABLE 0x20000 -#define SDHCI_CD_LVL 0x40000 -#define SDHCI_WRITE_PROTECT 0x80000 +#define SDHCI_CMD_INHIBIT BIT(0) +#define SDHCI_DATA_INHIBIT BIT(1) +#define SDHCI_DAT_LINE_ACTIVE BIT(2) +#define SDHCI_RETUNING_REQUEST BIT(3) +#define SDHCI_EMMC_LINE_LVL_MASK 0xF0 +#define SDHCI_DATA_4_LVL BIT(4) // eMMC only. +#define SDHCI_DATA_5_LVL BIT(5) // eMMC only. +#define SDHCI_DATA_6_LVL BIT(6) // eMMC only. +#define SDHCI_DATA_7_LVL BIT(7) // eMMC only. +#define SDHCI_DOING_WRITE BIT(8) +#define SDHCI_DOING_READ BIT(9) // SD only. +#define SDHCI_SPACE_AVAILABLE BIT(10) +#define SDHCI_DATA_AVAILABLE BIT(11) +#define SDHCI_CARD_PRESENT BIT(16) +#define SDHCI_CD_STABLE BIT(17) +#define SDHCI_CD_LVL BIT(18) +#define SDHCI_WRITE_PROTECT BIT(19) #define SDHCI_DATA_LVL_MASK 0xF00000 -#define SDHCI_DATA_0_LVL_MASK 0x100000 -#define SDHCI_CMD_LVL 0x1000000 +#define SDHCI_DATA_0_LVL BIT(20) +#define SDHCI_DATA_1_LVL BIT(21) +#define SDHCI_DATA_2_LVL BIT(22) +#define SDHCI_DATA_3_LVL BIT(23) +#define SDHCI_CMD_LVL BIT(24) +#define SDHCI_CMD_NOT_ISSUED BIT(27) /*! SDMMC transfer mode. */ -#define SDHCI_TRNS_DMA 0x01 -#define SDHCI_TRNS_BLK_CNT_EN 0x02 -#define SDHCI_TRNS_AUTO_CMD12 0x04 -#define SDHCI_TRNS_AUTO_CMD23 0x08 -#define SDHCI_TRNS_AUTO_SEL 0x0C -#define SDHCI_TRNS_WRITE 0x00 -#define SDHCI_TRNS_READ 0x10 -#define SDHCI_TRNS_MULTI 0x20 +#define SDHCI_TRNS_DMA BIT(0) +#define SDHCI_TRNS_BLK_CNT_EN BIT(1) +#define SDHCI_TRNS_AUTO_CMD12 BIT(2) +#define SDHCI_TRNS_AUTO_CMD23 BIT(3) +#define SDHCI_TRNS_WRITE 0x00 // Bit4. +#define SDHCI_TRNS_READ BIT(4) +#define SDHCI_TRNS_MULTI BIT(5) /*! SDMMC command. */ #define SDHCI_CMD_RESP_MASK 0x3 @@ -81,43 +91,43 @@ #define SDHCI_CMD_RESP_LEN136 0x1 #define SDHCI_CMD_RESP_LEN48 0x2 #define SDHCI_CMD_RESP_LEN48_BUSY 0x3 -#define SDHCI_CMD_CRC 0x08 -#define SDHCI_CMD_INDEX 0x10 -#define SDHCI_CMD_DATA 0x20 -#define SDHCI_CMD_ABORTCMD 0xC0 +#define SDHCI_CMD_CRC BIT(3) +#define SDHCI_CMD_INDEX BIT(4) +#define SDHCI_CMD_DATA BIT(5) +#define SDHCI_CMD_ABORTCMD 0xC0 /*! SDMMC host control. */ -#define SDHCI_CTRL_LED 0x01 -#define SDHCI_CTRL_4BITBUS 0x02 -#define SDHCI_CTRL_HISPD 0x04 +#define SDHCI_CTRL_LED BIT(0) +#define SDHCI_CTRL_4BITBUS BIT(1) // SD only. +#define SDHCI_CTRL_HISPD BIT(2) // SD only. #define SDHCI_CTRL_DMA_MASK 0x18 #define SDHCI_CTRL_SDMA 0x00 #define SDHCI_CTRL_ADMA1 0x08 #define SDHCI_CTRL_ADMA32 0x10 #define SDHCI_CTRL_ADMA64 0x18 -#define SDHCI_CTRL_8BITBUS 0x20 -#define SDHCI_CTRL_CDTEST_INS 0x40 -#define SDHCI_CTRL_CDTEST_EN 0x80 +#define SDHCI_CTRL_8BITBUS BIT(5) // eMMC only (or UHS-II). +#define SDHCI_CTRL_CDTEST_INS BIT(6) +#define SDHCI_CTRL_CDTEST_EN BIT(7) /*! SDMMC host control 2. */ -#define SDHCI_CTRL_UHS_MASK 0xFFF8 -#define SDHCI_CTRL_VDD_180 8 -#define SDHCI_CTRL_DRV_TYPE_B 0x00 -#define SDHCI_CTRL_DRV_TYPE_A 0x10 -#define SDHCI_CTRL_DRV_TYPE_C 0x20 -#define SDHCI_CTRL_DRV_TYPE_D 0x30 -#define SDHCI_CTRL_EXEC_TUNING 0x40 -#define SDHCI_CTRL_TUNED_CLK 0x80 -#define SDHCI_HOST_VERSION_4_EN 0x1000 -#define SDHCI_ADDRESSING_64BIT_EN 0x2000 -#define SDHCI_CTRL_PRESET_VAL_EN 0x8000 +#define SDHCI_CTRL_UHS_MASK 0x7 +#define SDHCI_CTRL_VDD_180 BIT(3) +#define SDHCI_CTRL_DRV_TYPE_B (0U << 4) +#define SDHCI_CTRL_DRV_TYPE_A (1U << 4) +#define SDHCI_CTRL_DRV_TYPE_C (2U << 4) +#define SDHCI_CTRL_DRV_TYPE_D (3U << 4) +#define SDHCI_CTRL_EXEC_TUNING BIT(6) +#define SDHCI_CTRL_TUNED_CLK BIT(7) +#define SDHCI_HOST_VERSION_4_EN BIT(12) +#define SDHCI_ADDRESSING_64BIT_EN BIT(13) +#define SDHCI_CTRL_PRESET_VAL_EN BIT(15) /*! SDMMC power control. */ -#define SDHCI_POWER_ON 0x01 +#define SDHCI_POWER_ON BIT(0) #define SDHCI_POWER_180 0x0A #define SDHCI_POWER_300 0x0C #define SDHCI_POWER_330 0x0E -#define SDHCI_POWER_MASK 0xF1 +#define SDHCI_POWER_MASK 0xF1 // UHS-II only. // /*! SDMMC max current. */ // #define SDHCI_MAX_CURRENT_330_MASK 0xFF @@ -125,45 +135,48 @@ // #define SDHCI_MAX_CURRENT_MULTIPLIER 4 /*! SDMMC clock control. */ -#define SDHCI_DIVIDER_SHIFT 8 +#define SDHCI_CLOCK_INT_EN BIT(0) +#define SDHCI_CLOCK_INT_STABLE BIT(1) +#define SDHCI_CLOCK_CARD_EN BIT(2) +#define SDHCI_PROG_CLOCK_MODE BIT(5) #define SDHCI_DIVIDER_HI_SHIFT 6 -#define SDHCI_DIV_MASK 0xFF00 -#define SDHCI_DIV_HI_MASK 0xC0 -#define SDHCI_PROG_CLOCK_MODE 0x20 -#define SDHCI_CLOCK_CARD_EN 0x4 -#define SDHCI_CLOCK_INT_STABLE 0x2 -#define SDHCI_CLOCK_INT_EN 0x1 +#define SDHCI_DIV_HI_MASK (3U << SDHCI_DIVIDER_HI_SHIFT) +#define SDHCI_DIVIDER_SHIFT 8 +#define SDHCI_DIV_MASK (0xFFU << SDHCI_DIVIDER_SHIFT) + /*! SDMMC software reset. */ -#define SDHCI_RESET_ALL 0x01 -#define SDHCI_RESET_CMD 0x02 -#define SDHCI_RESET_DATA 0x04 +#define SDHCI_RESET_ALL BIT(0) +#define SDHCI_RESET_CMD BIT(1) +#define SDHCI_RESET_DATA BIT(2) /*! SDMMC interrupt status and control. */ -#define SDHCI_INT_RESPONSE 0x1 -#define SDHCI_INT_DATA_END 0x2 -#define SDHCI_INT_BLK_GAP 0x4 -#define SDHCI_INT_DMA_END 0x8 -#define SDHCI_INT_SPACE_AVAIL 0x10 -#define SDHCI_INT_DATA_AVAIL 0x20 -#define SDHCI_INT_CARD_INSERT 0x40 -#define SDHCI_INT_CARD_REMOVE 0x80 -#define SDHCI_INT_CARD_INT 0x100 -#define SDHCI_INT_RETUNE 0x1000 -#define SDHCI_INT_CQE 0x4000 -#define SDHCI_INT_ERROR 0x8000 +#define SDHCI_INT_RESPONSE BIT(0) +#define SDHCI_INT_DATA_END BIT(1) +#define SDHCI_INT_BLK_GAP BIT(2) +#define SDHCI_INT_DMA_END BIT(3) +#define SDHCI_INT_SPACE_AVAIL BIT(4) +#define SDHCI_INT_DATA_AVAIL BIT(5) +#define SDHCI_INT_CARD_INSERT BIT(6) +#define SDHCI_INT_CARD_REMOVE BIT(7) +#define SDHCI_INT_CARD_INT BIT(8) +#define SDHCI_INT_RETUNE BIT(12) +#define SDHCI_INT_CQE BIT(14) +#define SDHCI_INT_ERROR BIT(15) /*! SDMMC error interrupt status and control. */ -#define SDHCI_ERR_INT_TIMEOUT 0x1 -#define SDHCI_ERR_INT_CRC 0x2 -#define SDHCI_ERR_INT_END_BIT 0x4 -#define SDHCI_ERR_INT_INDEX 0x8 -#define SDHCI_ERR_INT_DATA_TIMEOUT 0x10 -#define SDHCI_ERR_INT_DATA_CRC 0x20 -#define SDHCI_ERR_INT_DATA_END_BIT 0x40 -#define SDHCI_ERR_INT_BUS_POWER 0x80 -#define SDHCI_ERR_INT_AUTO_CMD_ERR 0x100 -#define SDHCI_ERR_INT_ADMA_ERROR 0x200 +#define SDHCI_ERR_INT_TIMEOUT BIT(0) +#define SDHCI_ERR_INT_CRC BIT(1) +#define SDHCI_ERR_INT_END_BIT BIT(2) +#define SDHCI_ERR_INT_INDEX BIT(3) +#define SDHCI_ERR_INT_DATA_TIMEOUT BIT(4) +#define SDHCI_ERR_INT_DATA_CRC BIT(5) +#define SDHCI_ERR_INT_DATA_END_BIT BIT(6) +#define SDHCI_ERR_INT_BUS_POWER BIT(7) +#define SDHCI_ERR_INT_AUTO_CMD_ERR BIT(8) +#define SDHCI_ERR_INT_ADMA_ERROR BIT(9) +#define SDHCI_ERR_INT_TUNE_ERROR BIT(10) +#define SDHCI_ERR_INT_RSP_ERROR BIT(11) #define SDHCI_ERR_INT_ALL_EXCEPT_ADMA_BUSPWR \ (SDHCI_ERR_INT_AUTO_CMD_ERR | SDHCI_ERR_INT_DATA_END_BIT | \ @@ -193,11 +206,12 @@ #define SDHCI_TIMING_UHS_SDR25 9 #define SDHCI_TIMING_UHS_SDR50 10 #define SDHCI_TIMING_UHS_SDR104 11 -#define SDHCI_TIMING_UHS_SDR82 12 // SDR104 with a 163.2MHz -> 81.6MHz clock. -#define SDHCI_TIMING_UHS_DDR50 13 -#define SDHCI_TIMING_MMC_HS102 14 +#define SDHCI_TIMING_UHS_DDR50 12 +// SDR104 with a 163.2MHz -> 81.6MHz clock. +#define SDHCI_TIMING_UHS_SDR82 13 // GC FPGA. Obsolete and Repurposed. MMC_HS50 -> SDR82. +#define SDHCI_TIMING_MMC_DDR100 14 // GC ASIC. -#define SDHCI_CAN_64BIT 0x10000000 +#define SDHCI_CAN_64BIT BIT(28) /*! SDMMC Low power features. */ #define SDMMC_POWER_SAVE_DISABLE 0 diff --git a/bdk/storage/sdmmc_t210.h b/bdk/storage/sdmmc_t210.h index 2c1b3a51..50686e43 100644 --- a/bdk/storage/sdmmc_t210.h +++ b/bdk/storage/sdmmc_t210.h @@ -18,6 +18,7 @@ #ifndef _SDMMC_T210_H_ #define _SDMMC_T210_H_ +#include #include #define TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW 0x20000 @@ -31,79 +32,97 @@ typedef struct _t210_sdmmc_t { - vu32 sysad; - vu16 blksize; - vu16 blkcnt; - vu32 argument; - vu16 trnmod; - vu16 cmdreg; - vu32 rspreg0; - vu32 rspreg1; - vu32 rspreg2; - vu32 rspreg3; - vu32 bdata; - vu32 prnsts; - vu8 hostctl; - vu8 pwrcon; - vu8 blkgap; - vu8 wakcon; - vu16 clkcon; - vu8 timeoutcon; - vu8 swrst; - vu16 norintsts; - vu16 errintsts; - vu16 norintstsen; // Enable irq status. - vu16 errintstsen; // Enable irq status. - vu16 norintsigen; // Enable irq signal to LIC/GIC. - vu16 errintsigen; // Enable irq signal to LIC/GIC. - vu16 acmd12errsts; - vu16 hostctl2; - vu32 capareg; - vu32 capareg_1; - vu32 maxcurr; - vu8 rsvd0[4]; // 4C-4F reserved for more max current. - vu16 setacmd12err; - vu16 setinterr; - vu8 admaerr; - vu8 rsvd1[3]; // 55-57 reserved. - vu32 admaaddr; - vu32 admaaddr_hi; - vu8 rsvd2[156]; // 60-FB reserved. - vu16 slotintsts; - vu16 hcver; - vu32 venclkctl; - vu32 vensysswctl; - vu32 venerrintsts; - vu32 vencapover; - vu32 venbootctl; - vu32 venbootacktout; - vu32 venbootdattout; - vu32 vendebouncecnt; - vu32 venmiscctl; - vu32 maxcurrover; - vu32 maxcurrover_hi; - vu32 unk0[32]; // 0x12C - vu32 veniotrimctl; - vu32 vendllcalcfg; - vu32 vendllctl0; - vu32 vendllctl1; - vu32 vendllcalcfgsts; - vu32 ventunctl0; - vu32 ventunctl1; - vu32 ventunsts0; - vu32 ventunsts1; - vu32 venclkgatehystcnt; - vu32 venpresetval0; - vu32 venpresetval1; - vu32 venpresetval2; - vu32 sdmemcmppadctl; - vu32 autocalcfg; - vu32 autocalintval; - vu32 autocalsts; - vu32 iospare; - vu32 mcciffifoctl; - vu32 timeoutwcoal; - vu32 unk1; +/* 0x00 */ vu32 sysad; // sdma system address. +/* 0x04 */ vu16 blksize; +/* 0x06 */ vu16 blkcnt; +/* 0x08 */ vu32 argument; +/* 0x0C */ vu16 trnmod; +/* 0x0E */ vu16 cmdreg; +/* 0x10 */ vu32 rspreg0; +/* 0x14 */ vu32 rspreg1; +/* 0x18 */ vu32 rspreg2; +/* 0x1C */ vu32 rspreg3; +/* 0x20 */ vu32 bdata; // Buffer data port. +/* 0x24 */ vu32 prnsts; +/* 0x28 */ vu8 hostctl; +/* 0x29 */ vu8 pwrcon; +/* 0x2A */ vu8 blkgap; +/* 0x2B */ vu8 wakcon; +/* 0x2C */ vu16 clkcon; +/* 0x2E */ vu8 timeoutcon; +/* 0x2F */ vu8 swrst; +/* 0x30 */ vu16 norintsts; // Normal interrupt status. +/* 0x32 */ vu16 errintsts; // Error interrupt status. +/* 0x34 */ vu16 norintstsen; // Enable irq status. +/* 0x36 */ vu16 errintstsen; // Enable irq status. +/* 0x38 */ vu16 norintsigen; // Enable irq signal to LIC/GIC. +/* 0x3A */ vu16 errintsigen; // Enable irq signal to LIC/GIC. +/* 0x3C */ vu16 acmd12errsts; +/* 0x3E */ vu16 hostctl2; + +// CAP0: 0x376CD08C. +// 12 MHz timeout clock. 208 MHz max base clock. 512B max block length. 8-bit support. +// ADMA2 support. HS25 support. SDMA support. No suspend/resume support. 3.3/3.0/1.8V support. +// 64bit addressing for V3/V4 support. Async IRQ support. All report as removable. +/* 0x40 */ vu32 capareg; +// CAP1: 0x10002F73. +// SDR50/SDR104 support. No DDR50 support. Drive A/B/C/D support. +// Timer re-tuning info from other source. SDR50 requires re-tuning. +// Tuning uses timer and transfers should be 4MB limited. +// ADMA3 not supported. 1.8V VDD2 supported. +/* 0x44 */ vu32 capareg_hi; + +/* 0x48 */ vu32 maxcurr; // Get information by another method. Can be overriden via maxcurrover and maxcurrover_hi. +/* 0x4C */ vu8 rsvd0[4]; // 4C-4F reserved for more max current. +/* 0x50 */ vu16 setacmd12err; +/* 0x52 */ vu16 setinterr; +/* 0x54 */ vu8 admaerr; +/* 0x55 */ vu8 rsvd1[3]; // 55-57 reserved. +/* 0x58 */ vu32 admaaddr; +/* 0x5C */ vu32 admaaddr_hi; +/* 0x60 */ vu16 presets[11]; +/* 0x76 */ vu16 rsvd2; +/* 0x78 */ vu32 adma3addr; +/* 0x7C */ vu32 adma3addr_hi; +/* 0x80 */ vu8 uhs2[124]; // 80-FB UHS-II. +/* 0xFC */ vu16 slotintsts; +/* 0xFE */ vu16 hcver; // 0x303 (4.00). + +/* UHS-II range. Used for Vendor registers here */ +/* 0x100 */ vu32 venclkctl; +/* 0x104 */ vu32 vensysswctl; +/* 0x108 */ vu32 venerrintsts; +/* 0x10C */ vu32 vencapover; +/* 0x110 */ vu32 venbootctl; +/* 0x114 */ vu32 venbootacktout; +/* 0x118 */ vu32 venbootdattout; +/* 0x11C */ vu32 vendebouncecnt; +/* 0x120 */ vu32 venmiscctl; +/* 0x124 */ vu32 maxcurrover; +/* 0x128 */ vu32 maxcurrover_hi; +/* 0x12C */ vu32 unk0[32]; // 0x12C +/* 0x1AC */ vu32 veniotrimctl; +/* 0x1B0 */ vu32 vendllcalcfg; +/* 0x1B4 */ vu32 vendllctl0; +/* 0x1B8 */ vu32 vendllctl1; +/* 0x1BC */ vu32 vendllcalcfgsts; +/* 0x1C0 */ vu32 ventunctl0; +/* 0x1C4 */ vu32 ventunctl1; +/* 0x1C8 */ vu32 ventunsts0; +/* 0x1CC */ vu32 ventunsts1; +/* 0x1D0 */ vu32 venclkgatehystcnt; +/* 0x1D4 */ vu32 venpresetval0; +/* 0x1D8 */ vu32 venpresetval1; +/* 0x1DC */ vu32 venpresetval2; +/* 0x1E0 */ vu32 sdmemcmppadctl; +/* 0x1E4 */ vu32 autocalcfg; +/* 0x1E8 */ vu32 autocalintval; +/* 0x1EC */ vu32 autocalsts; +/* 0x1F0 */ vu32 iospare; +/* 0x1F4 */ vu32 mcciffifoctl; +/* 0x1F8 */ vu32 timeoutwcoal; } t210_sdmmc_t; +static_assert(sizeof(t210_sdmmc_t) == 0x1FC, "T210 SDMMC REG size is wrong!"); + #endif diff --git a/bdk/thermal/fan.c b/bdk/thermal/fan.c index 9e7a65e8..6927fe4e 100644 --- a/bdk/thermal/fan.c +++ b/bdk/thermal/fan.c @@ -1,7 +1,7 @@ /* * Fan driver for Nintendo Switch * - * Copyright (c) 2018-2021 CTCaer + * Copyright (c) 2018-2023 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,11 +18,14 @@ #include #include +#include +#include #include #include +#include #include +#include #include -#include void set_fan_duty(u32 duty) { @@ -37,18 +40,24 @@ void set_fan_duty(u32 duty) 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. - PINMUX_AUX(PINMUX_AUX_CAM1_PWDN) = PINMUX_TRISTATE | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | 1; - gpio_config(GPIO_PORT_S, GPIO_PIN_7, GPIO_MODE_GPIO); - gpio_output_enable(GPIO_PORT_S, GPIO_PIN_7, GPIO_OUTPUT_DISABLE); + u32 pull_resistor = hw_get_chip_id() == GP_HIDREV_MAJOR_T210 ? PINMUX_PULL_UP : 0; + PINMUX_AUX(PINMUX_AUX_CAM1_PWDN) = PINMUX_TRISTATE | PINMUX_INPUT_ENABLE | pull_resistor | 1; + gpio_direction_input(GPIO_PORT_S, GPIO_PIN_7); + + // Enable PWM if disabled. + if (fuse_read_hw_type() == FUSE_NX_HW_TYPE_AULA) + { + // Ease the stress to APB. + bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL); + + clock_enable_pwm(); + + // Restore OC. + bpmp_clk_rate_set(prev_fid); + } PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (0x100 << 16); // Max PWM to disable fan. @@ -68,8 +77,8 @@ void set_fan_duty(u32 duty) regulator_5v_disable(REGULATOR_5V_FAN); // Disable fan. - PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = - PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_TRISTATE | PINMUX_PULL_DOWN; // Set source to PWM1. + PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = PINMUX_INPUT_ENABLE | PINMUX_PARKED | + PINMUX_TRISTATE | PINMUX_PULL_DOWN; // Set source to PWM1. } else // Set PWM duty. { diff --git a/bdk/usb/usb_gadget_hid.c b/bdk/usb/usb_gadget_hid.c index b7c2e24d..d9105ae7 100644 --- a/bdk/usb/usb_gadget_hid.c +++ b/bdk/usb/usb_gadget_hid.c @@ -1,7 +1,7 @@ /* * USB Gadget HID driver for Tegra X1 * - * Copyright (c) 2019-2020 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, @@ -23,8 +23,8 @@ #include #include #include +#include #include -#include #include @@ -159,14 +159,22 @@ static bool _jc_poll(gamepad_report_t *rpt) 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; + // Hoag has inverted Y axis. + if (!jc_pad->sio_mode) + rpt->y = 0x7F - y_raw; + else + 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; + // Hoag has inverted Y axis. + if (!jc_pad->sio_mode) + rpt->y = 0x7F + y_raw; + else + rpt->y = 0x7F - y_raw; } // Calculate right analog stick. @@ -194,14 +202,22 @@ static bool _jc_poll(gamepad_report_t *rpt) 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; + // Hoag has inverted Y axis. + if (!jc_pad->sio_mode) + rpt->rz = 0x7F - y_raw; + else + 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; + // Hoag has inverted Y axis. + if (!jc_pad->sio_mode) + rpt->rz = 0x7F + y_raw; + else + rpt->rz = 0x7F - y_raw; } // Set D-pad. @@ -312,7 +328,7 @@ 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!"); + usbs->set_text(usbs->label, "#FFDD00 错误:#EP IN传输!"); if (usb_ops.usbd_flush_endpoint) usb_ops.usbd_flush_endpoint(USB_EP_BULK_IN); } @@ -361,7 +377,7 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs) if (usbs->type == USB_HID_GAMEPAD) { - polling_time = 8000; + polling_time = 15000; gadget_type = USB_GADGET_HID_GAMEPAD; } else @@ -370,7 +386,7 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs) gadget_type = USB_GADGET_HID_TOUCHPAD; } - usbs->set_text(usbs->label, "#C7EA46 Status:# Started USB"); + usbs->set_text(usbs->label, "#C7EA46 状态:#开启USB"); if (usb_ops.usb_device_init()) { @@ -378,18 +394,18 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs) return 1; } - usbs->set_text(usbs->label, "#C7EA46 Status:# Waiting for connection"); + usbs->set_text(usbs->label, "#C7EA46 状态:#等待连接"); // 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"); + usbs->set_text(usbs->label, "#C7EA46 状态:#等待HID上报请求"); if (usb_ops.usb_device_class_send_hid_report()) goto error; - usbs->set_text(usbs->label, "#C7EA46 Status:# Started HID emulation"); + usbs->set_text(usbs->label, "#C7EA46 状态:#开始HID模拟"); u32 timer_sys = get_tmr_ms() + 5000; while (true) @@ -427,11 +443,11 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs) } } - usbs->set_text(usbs->label, "#C7EA46 Status:# HID ended"); + usbs->set_text(usbs->label, "#C7EA46 状态:#HID结束"); goto exit; error: - usbs->set_text(usbs->label, "#FFDD00 Error:# Timed out or canceled"); + usbs->set_text(usbs->label, "#FFDD00 错误:#超时或取消"); res = 1; exit: diff --git a/bdk/usb/usb_gadget_ums.c b/bdk/usb/usb_gadget_ums.c index 2b90439d..e4d80715 100644 --- a/bdk/usb/usb_gadget_ums.c +++ b/bdk/usb/usb_gadget_ums.c @@ -4,7 +4,7 @@ * Copyright (c) 2003-2008 Alan Stern * Copyright (c) 2009 Samsung Electronics * Author: Michal Nazarewicz - * Copyright (c) 2019-2021 CTCaer + * Copyright (c) 2019-2023 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, @@ -24,13 +24,14 @@ #include #include #include +#include #include -#include +#include #include +#include #include #include #include -#include #include @@ -283,40 +284,40 @@ static void raise_exception(usbd_gadget_ums_t *ums, enum ums_state new_state) } } -static void ums_handle_ep0_ctrl(usbd_gadget_ums_t *ums) +static void _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) +static int _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) +static int _set_ep_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) +static int _clear_ep_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) +static void _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) +static void _transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32 ep, u32 sync_timeout) { if (ep == bulk_ctxt->bulk_in) { @@ -326,11 +327,11 @@ static void _ums_transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, 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); + ums->set_text(ums->label, "#FFDD00 错误:#EP IN传输!"); + _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!"); + ums->set_text(ums->label, "#FFDD00 错误:#EP IN缓冲区未对齐!"); if (sync_timeout) bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY; @@ -343,18 +344,18 @@ static void _ums_transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, 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); + ums->set_text(ums->label, "#FFDD00 错误:#EP OUT传输!"); + _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!"); + ums->set_text(ums->label, "#FFDD00 错误:#EP OUT缓冲区未对齐!"); 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) +static void _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, @@ -362,14 +363,14 @@ static void _ums_transfer_out_big_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk 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); + ums->set_text(ums->label, "#FFDD00 错误:#EP OUT传输!"); + _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, u32 sync_timeout) +static void _transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32 ep, u32 sync_timeout) { if (ep == bulk_ctxt->bulk_in) { @@ -378,8 +379,8 @@ static void _ums_transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, 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); + ums->set_text(ums->label, "#FFDD00 错误:#EP IN传输!"); + _flush_endpoint(bulk_ctxt->bulk_in); } bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY; @@ -391,15 +392,15 @@ static void _ums_transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, 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); + ums->set_text(ums->label, "#FFDD00 错误:#EP OUT传输!"); + _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) +static void _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; @@ -461,7 +462,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) } if (lba_offset >= ums->lun.num_sectors) { - ums->set_text(ums->label, "#FF8000 Warn:# Read - Out of range! Host notified."); + ums->set_text(ums->label, "#FF8000 警告:#读 - 超出范围!主机通知。"); ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; return UMS_RES_INVALID_ARG; @@ -474,20 +475,21 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) // 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; + 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); + 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 = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; ums->lun.sense_data_info = lba_offset; - ums->lun.info_valid = 1; + ums->lun.info_valid = 1; + bulk_ctxt->bulk_in_length = 0; bulk_ctxt->bulk_in_buf_state = BUF_STATE_FULL; break; @@ -499,7 +501,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) // Wait for the async USB transfer to finish. if (!first_read) - _ums_transfer_finish(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED); + _transfer_finish(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED); lba_offset += amount; amount_left -= amount; @@ -512,10 +514,10 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) // 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->set_text(ums->label, "#FFDD00 错误:# SDMMC读!"); + ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR; ums->lun.sense_data_info = lba_offset; - ums->lun.info_valid = 1; + ums->lun.info_valid = 1; break; } @@ -524,7 +526,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) break; // Start the USB transfer. - _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_START); + _transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_START); first_read = false; // Increment our buffer to read new data. @@ -550,7 +552,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) if (ums->lun.ro) { - ums->set_text(ums->label, "#FF8000 Warn:# Write - Read only! Host notified."); + ums->set_text(ums->label, "#FF8000 警告:#写 - 只读!主机通知。"); ums->lun.sense_data = SS_WRITE_PROTECTED; return UMS_RES_INVALID_ARG; @@ -574,15 +576,15 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) // Check that starting LBA is not past the end sector offset. if (lba_offset >= ums->lun.num_sectors) { - ums->set_text(ums->label, "#FF8000 Warn:# Write - Out of range! Host notified."); + ums->set_text(ums->label, "#FF8000 警告:#写 - 超出范围!主机通知。"); 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; + 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) @@ -596,21 +598,21 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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->set_text(ums->label, "#FFDD00 错误:#写 - 超出最后扇区!"); + ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; ums->lun.sense_data_info = usb_lba_offset; - ums->lun.info_valid = 1; + ums->lun.info_valid = 1; break; } // Get the next buffer. - usb_lba_offset += amount >> UMS_DISK_LBA_SHIFT; + usb_lba_offset += amount >> UMS_DISK_LBA_SHIFT; ums->usb_amount_left -= amount; - amount_left_to_req -= amount; + amount_left_to_req -= amount; bulk_ctxt->bulk_out_length = amount; - _ums_transfer_out_big_read(ums, bulk_ctxt); + _transfer_out_big_read(ums, bulk_ctxt); } if (bulk_ctxt->bulk_out_buf_state == BUF_STATE_FULL) @@ -620,10 +622,11 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) // 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 = 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->lun.info_valid = 1; + + s_printf(txt_buf, "#FFDD00 错误:#写 - 通讯失败 %d!", bulk_ctxt->bulk_out_status); ums->set_text(ums->label, txt_buf); break; } @@ -661,10 +664,10 @@ DPRINTF("file write %X @ %X\n", amount, lba_offset); // 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->set_text(ums->label, "#FFDD00 错误:#SDMMC写!"); + ums->lun.sense_data = SS_WRITE_ERROR; ums->lun.sense_data_info = lba_offset; - ums->lun.info_valid = 1; + ums->lun.info_valid = 1; break; } @@ -672,7 +675,7 @@ DPRINTF("file write %X @ %X\n", amount, lba_offset); // 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->set_text(ums->label, "#FFDD00 错误:#写空!"); ums->short_packet_received = 1; break; } @@ -688,7 +691,7 @@ static int _scsi_verify(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) u32 lba_offset = get_array_be_to_le32(&ums->cmnd[2]); if (lba_offset >= ums->lun.num_sectors) { - ums->set_text(ums->label, "#FF8000 Warn:# Verif - Out of range! Host notified."); + ums->set_text(ums->label, "#FF8000 警告:#验证 - 超出范围!主机通知。"); ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; return UMS_RES_INVALID_ARG; @@ -714,9 +717,9 @@ static int _scsi_verify(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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 = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; ums->lun.sense_data_info = lba_offset; - ums->lun.info_valid = 1; + ums->lun.info_valid = 1; break; } @@ -727,10 +730,10 @@ 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->set_text(ums->label, "#FFDD00 错误:#文件检验!"); + ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR; ums->lun.sense_data_info = lba_offset; - ums->lun.info_valid = 1; + ums->lun.info_valid = 1; break; } lba_offset += amount; @@ -755,12 +758,12 @@ static int _scsi_inquiry(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) buf += 4; s_printf((char *)buf, "%04X%s", - ums->lun.storage->cid.serial, ums->lun.type == MMC_SD ? " SD " : " eMMC "); + 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"); + strcpy((char *)buf + strlen((char *)buf), "原始"); break; case EMMC_GPP + 1: s_printf((char *)buf + strlen((char *)buf), "GPP"); @@ -796,19 +799,19 @@ static int _scsi_inquiry(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) switch (ums->lun.partition) { case 0: - s_printf((char *)buf, "%s", "SD RAW"); + s_printf((char *)buf, "%s", "SD卡原始分区"); break; case EMMC_GPP + 1: s_printf((char *)buf, "%s%s", - ums->lun.type == MMC_SD ? "SD " : "eMMC ", "GPP"); + 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"); + 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"); + ums->lun.type == MMC_SD ? "SD卡 " : "eMMC ", "BOOT1"); break; } @@ -1056,7 +1059,7 @@ static int _scsi_start_stop(usbd_gadget_ums_t *ums) // 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->set_text(ums->label, "#C7EA46 状态:#卸载尝试被阻止"); ums->lun.sense_data = SS_MEDIUM_REMOVAL_PREVENTED; return UMS_RES_INVALID_ARG; @@ -1116,8 +1119,9 @@ static int _scsi_read_format_capacities(usbd_gadget_ums_t *ums, bulk_ctxt_t *bul // 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) +static int _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", @@ -1165,9 +1169,9 @@ DPRINTF("SCSI command: %X; Dc=%d, D%c=%X; Hc=%d, H%c=%X\n", if (ums->cmnd[0] != SC_REQUEST_SENSE) { - ums->lun.sense_data = SS_NO_SENSE; + ums->lun.sense_data = SS_NO_SENSE; ums->lun.sense_data_info = 0; - ums->lun.info_valid = 0; + ums->lun.info_valid = 0; } // If a unit attention condition exists, only INQUIRY and REQUEST SENSE @@ -1204,7 +1208,7 @@ DPRINTF("SCSI command: %X; Dc=%d, D%c=%X; Hc=%d, H%c=%X\n", return UMS_RES_OK; } -static int _ums_parse_scsi_cmd(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) +static int _parse_scsi_cmd(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) { u32 len; int reply = UMS_RES_INVALID_ARG; @@ -1219,21 +1223,21 @@ static int _ums_parse_scsi_cmd(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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); + reply = _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); + reply = _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); + reply = _check_scsi_cmd(ums, 6, DATA_DIR_FROM_HOST, (1<<1) | (1<<4), 0); if (reply == 0) { // We don't support MODE SELECT. @@ -1244,7 +1248,7 @@ static int _ums_parse_scsi_cmd(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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); + reply = _check_scsi_cmd(ums, 10, DATA_DIR_FROM_HOST, (1<<1) | (3<<7), 0); if (reply == 0) { // We don't support MODE SELECT. @@ -1255,21 +1259,21 @@ static int _ums_parse_scsi_cmd(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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); + reply = _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); + reply = _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); + reply = _check_scsi_cmd(ums, 6, DATA_DIR_NONE, (1<<4), 0); if (reply == 0) reply = _scsi_prevent_allow_removal(ums); break; @@ -1277,68 +1281,68 @@ static int _ums_parse_scsi_cmd(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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); + reply = _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); + reply = _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); + reply = _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); + reply = _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); + reply = _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); + reply = _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); + reply = _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); + reply = _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); + reply = _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); + reply = _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; @@ -1346,21 +1350,21 @@ static int _ums_parse_scsi_cmd(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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); + reply = _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); + reply = _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); + reply = _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; @@ -1374,7 +1378,7 @@ static int _ums_parse_scsi_cmd(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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); + reply = _check_scsi_cmd(ums, ums->cmnd_size, DATA_DIR_UNKNOWN, 0xFF, 0); if (reply == 0) { ums->lun.sense_data = SS_INVALID_COMMAND; @@ -1386,7 +1390,7 @@ static int _ums_parse_scsi_cmd(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) if (reply == UMS_RES_INVALID_ARG) reply = 0; // Error reply length. - // Set up reply buffer for finish_reply(). Otherwise it's already set. + // 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); @@ -1398,7 +1402,7 @@ static int _ums_parse_scsi_cmd(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) return UMS_RES_OK; } -static int pad_with_zeros(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) +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; @@ -1409,7 +1413,7 @@ static int pad_with_zeros(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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); + _transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED_DATA); ums->usb_amount_left -= nsend; current_len_to_keep = 0; } @@ -1417,7 +1421,7 @@ static int pad_with_zeros(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) return UMS_RES_OK; } -static int throw_away_data(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) +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) { @@ -1427,7 +1431,7 @@ static int throw_away_data(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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); + _transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_DATA); ums->usb_amount_left -= amount; return UMS_RES_OK; @@ -1448,7 +1452,7 @@ static int throw_away_data(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) return UMS_RES_OK; } -static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) +static int _finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) { int rc = UMS_RES_OK; @@ -1461,9 +1465,9 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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!"); + _set_ep_stall(bulk_ctxt->bulk_out); + rc = _set_ep_stall(bulk_ctxt->bulk_in); + ums->set_text(ums->label, "#FFDD00 错误:#方向不明。两端EP都停了!"); } // Else do nothing. break; @@ -1474,7 +1478,7 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) // 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); + _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 @@ -1482,16 +1486,16 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) } 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!"); + _transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED_DATA); + rc = _set_ep_stall(bulk_ctxt->bulk_in); + ums->set_text(ums->label, "#FFDD00 错误:#数据残留。EP IN停止!"); } else - rc = pad_with_zeros(ums, bulk_ctxt); + 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); + _reset_buffer(bulk_ctxt, bulk_ctxt->bulk_in); break; // We have processed all we want from the data the host has sent. @@ -1505,7 +1509,7 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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); + rc = _throw_away_data(ums, bulk_ctxt); } break; @@ -1540,7 +1544,7 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) * Line always at SE0. */ -static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) +static int _received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) { // Was this a real packet? Should it be ignored? if (bulk_ctxt->bulk_out_status || bulk_ctxt->bulk_out_ignore || ums->lun.unmounted) @@ -1557,7 +1561,7 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) { if (usb_ops.usb_device_get_port_in_sleep()) { - ums->set_text(ums->label, "#C7EA46 Status:# EP in sleep"); + ums->set_text(ums->label, "#C7EA46 状态:#EP已休眠"); ums->timeouts += 14; } else if (!ums->xusb) // Timeout only on USB2. @@ -1576,7 +1580,7 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) if (ums->lun.unmounted) { - ums->set_text(ums->label, "#C7EA46 Status:# Medium unmounted"); + ums->set_text(ums->label, "#C7EA46 状态:#介质未挂载"); ums->timeouts++; if (!bulk_ctxt->bulk_out_status) ums->timeouts += 3; @@ -1610,7 +1614,7 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) * we can simply accept and discard any data received * until the next reset. */ - ums_wedge_bulk_in_endpoint(ums); + _wedge_bulk_in_endpoint(ums); bulk_ctxt->bulk_out_ignore = 1; return UMS_RES_INVALID_ARG; } @@ -1626,9 +1630,9 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) * 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!"); + _set_ep_stall(bulk_ctxt->bulk_out); + _set_ep_stall(bulk_ctxt->bulk_in); + ums->set_text(ums->label, "#FFDD00 错误:#CBW未知 - 两端EP都停了!"); } return UMS_RES_INVALID_ARG; @@ -1657,7 +1661,7 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) return UMS_RES_OK; } -static int get_next_command(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) +static int _get_next_command(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) { int rc = UMS_RES_OK; @@ -1671,9 +1675,9 @@ static int get_next_command(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) // Queue a request to read a Bulk-only CBW. if (!ums->cbw_req_queued) - _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_CMD); + _transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_CMD); else - _ums_transfer_finish(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_CMD); + _transfer_finish(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_CMD); /* * On XUSB do not allow multiple requests for CBW to be done. @@ -1694,20 +1698,20 @@ static int get_next_command(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) // //wait irq. // } - rc = received_cbw(ums, bulk_ctxt); + 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) +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!"); + ums->set_text(ums->label, "#FFDD00 错误:#相位错误!"); status = USB_STATUS_PHASE_ERROR; sd = SS_INVALID_COMMAND; } @@ -1723,26 +1727,26 @@ static void send_status(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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; + 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); + _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) +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); + _flush_endpoint(bulk_ctxt->bulk_in); + _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_in_buf_state = BUF_STATE_EMPTY; bulk_ctxt->bulk_out_buf_state = BUF_STATE_EMPTY; old_state = ums->state; @@ -1750,10 +1754,10 @@ static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) 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->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; @@ -1764,7 +1768,7 @@ static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) case UMS_STATE_NORMAL: break; case UMS_STATE_ABORT_BULK_OUT: - send_status(ums, bulk_ctxt); + _send_status(ums, bulk_ctxt); break; case UMS_STATE_PROTOCOL_RESET: @@ -1774,7 +1778,7 @@ static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) if (bulk_ctxt->bulk_out_ignore) { bulk_ctxt->bulk_out_ignore = 0; - ums_clear_stall(bulk_ctxt->bulk_in); + _clear_ep_stall(bulk_ctxt->bulk_in); } ums->lun.unit_attention_data = SS_RESET_OCCURRED; break; @@ -1810,8 +1814,6 @@ static inline void _system_maintainance(usbd_gadget_ums_t *ums) 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. @@ -1823,7 +1825,7 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs) xusb_device_get_ops(&usb_ops); } - usbs->set_text(usbs->label, "#C7EA46 Status:# Started USB"); + usbs->set_text(usbs->label, "#C7EA46 状态:#开启USB"); if (usb_ops.usb_device_init()) { @@ -1834,17 +1836,17 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs) ums.state = UMS_STATE_NORMAL; ums.can_stall = 0; - ums.bulk_ctxt.bulk_in = USB_EP_BULK_IN; + 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 = 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.ro = usbs->ro; + ums.lun.type = usbs->type; ums.lun.partition = usbs->partition; - ums.lun.offset = usbs->offset; + 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; @@ -1853,37 +1855,49 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs) ums.set_text = usbs->set_text; ums.system_maintenance = usbs->system_maintenance; - ums.set_text(ums.label, "#C7EA46 Status:# Mounting disk"); + ums.set_text(ums.label, "#C7EA46 状态:#挂载磁盘"); // Initialize sdmmc. if (usbs->type == MMC_SD) { sd_end(); - sd_mount(); + if (!sd_mount()) + { + ums.set_text(ums.label, "#FFDD00 初始化SD卡失败!#"); + res = 1; + goto init_fail; + } sd_unmount(); - ums.lun.sdmmc = &sd_sdmmc; + + 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); + if (!emmc_initialize(false)) + { + ums.set_text(ums.label, "#FFDD00 初始化eMMC失败!#"); + res = 1; + goto init_fail; + } + emmc_set_partition(ums.lun.partition - 1); + + ums.lun.sdmmc = &emmc_sdmmc; + ums.lun.storage = &emmc_storage; } - ums.set_text(ums.label, "#C7EA46 Status:# Waiting for connection"); + ums.set_text(ums.label, "#C7EA46 状态:#等待连接"); // Initialize Control Endpoint. if (usb_ops.usb_device_enumerate(USB_GADGET_UMS)) - goto error; + goto usb_enum_error; - ums.set_text(ums.label, "#C7EA46 Status:# Waiting for LUN"); + ums.set_text(ums.label, "#C7EA46 状态:#等待LUN"); if (usb_ops.usb_device_class_send_max_lun(0)) // One device for now. - goto error; + goto usb_enum_error; - ums.set_text(ums.label, "#C7EA46 Status:# Started UMS"); + ums.set_text(ums.label, "#C7EA46 状态:#开启UMS"); if (usbs->sectors) ums.lun.num_sectors = usbs->sectors; @@ -1900,49 +1914,50 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs) { // 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.set_text(ums.label, "#C7EA46 状态:#卸载尝试被阻止"); else break; } if (ums.state != UMS_STATE_NORMAL) { - handle_exception(&ums, &ums.bulk_ctxt); + _handle_exception(&ums, &ums.bulk_ctxt); continue; } - ums_handle_ep0_ctrl(&ums); + _handle_ep0_ctrl(&ums); - if (get_next_command(&ums, &ums.bulk_ctxt) || (ums.state > UMS_STATE_NORMAL)) + if (_get_next_command(&ums, &ums.bulk_ctxt) || (ums.state > UMS_STATE_NORMAL)) continue; - ums_handle_ep0_ctrl(&ums); + _handle_ep0_ctrl(&ums); - if (_ums_parse_scsi_cmd(&ums, &ums.bulk_ctxt) || (ums.state > UMS_STATE_NORMAL)) + if (_parse_scsi_cmd(&ums, &ums.bulk_ctxt) || (ums.state > UMS_STATE_NORMAL)) continue; - ums_handle_ep0_ctrl(&ums); + _handle_ep0_ctrl(&ums); - if (finish_reply(&ums, &ums.bulk_ctxt) || (ums.state > UMS_STATE_NORMAL)) + if (_finish_reply(&ums, &ums.bulk_ctxt) || (ums.state > UMS_STATE_NORMAL)) continue; - send_status(&ums, &ums.bulk_ctxt); + _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"); + ums.set_text(ums.label, "#FFDD00 错误:#磁盘不安全弹出"); else - ums.set_text(ums.label, "#C7EA46 Status:# Disk ejected"); + ums.set_text(ums.label, "#C7EA46 状态:#磁盘弹出"); goto exit; -error: - ums.set_text(ums.label, "#FFDD00 Error:# Timed out or canceled!"); +usb_enum_error: + ums.set_text(ums.label, "#FFDD00 错误:#超时或取消!"); res = 1; exit: if (ums.lun.type == MMC_EMMC) - sdmmc_storage_end(ums.lun.storage); + emmc_end(); +init_fail: usb_ops.usbd_end(true, false); return res; diff --git a/bdk/usb/usbd.c b/bdk/usb/usbd.c index 81d719a3..83f9ce7e 100644 --- a/bdk/usb/usbd.c +++ b/bdk/usb/usbd.c @@ -1,7 +1,7 @@ /* * Enhanced USB Device (EDCI) driver for Tegra X1 * - * Copyright (c) 2019-2021 CTCaer + * Copyright (c) 2019-2023 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -30,16 +30,16 @@ #include #include #include +#include #include #include -#include #include typedef enum { - USB_HW_EP0 = 0, - USB_HW_EP1 = 1 + USB_HW_EP0 = 0, + USB_HW_EP1 = 1 } usb_hw_ep_t; typedef enum @@ -143,11 +143,11 @@ static int _usbd_reset_usb_otg_phy_device_mode() // 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; + 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; + usbd_otg->regs->usbcmd &= ~USB2D_USBCMD_RUN; // Set controller mode to idle. usbd_otg->regs->usbmode &= ~USB2D_USBMODE_CM_MASK; @@ -192,16 +192,15 @@ static int _usbd_reset_usb_otg_phy_device_mode() usbd_otg->regs->usbintr = 0; // Set the ID pullup and disable all OTGSC interrupts. - usbd_otg->regs->otgsc = USB2D_OTGSC_USB_ID_PULLUP; + 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; + 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; + 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? @@ -222,11 +221,10 @@ static void _usb_charger_detect() 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); + gpio_direction_input(GPIO_PORT_V, GPIO_PIN_3); // Configure charger pin. - PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN1) &= - ~(PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_TRISTATE | PINMUX_PULL_MASK); + 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); @@ -289,12 +287,12 @@ static void _usb_init_phy() // 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_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_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_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. @@ -307,7 +305,7 @@ static void _usb_init_phy() 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_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. @@ -338,7 +336,7 @@ static void _usb_init_phy() 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. + 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); @@ -362,14 +360,14 @@ int usb_device_init() // 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_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. + 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; + usbd_otg = &usbd_usb_otg_controller_ctxt; memset(usbd_otg, 0, sizeof(usbd_controller_t)); memset(usbdaemon, 0, sizeof(usbd_t)); @@ -443,6 +441,11 @@ static void _usb_device_power_down() usb_init_done = false; } +static void _usbd_disable_ep1() +{ + usbd_otg->regs->endptctrl[1] = 0; +} + static void _usbd_stall_reset_ep1(usb_dir_t direction, usb_ep_cfg_t stall) { stall &= 1; @@ -524,13 +527,11 @@ static void _usbd_initialize_ep_ctrl(u32 endpoint) { 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] = endpoint_type; usbd_otg->regs->endptctrl[actual_ep] &= ~USB2D_ENDPTCTRL_RX_EP_STALL; if (actual_ep == USB_HW_EP1) @@ -542,7 +543,7 @@ static void _usbd_initialize_ep_ctrl(u32 endpoint) static int _usbd_initialize_ep0() { - memset((void *)usbdaemon->qhs, 0, sizeof(dQH_t) * 4); // Clear all used EP queue heads. + 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; @@ -583,8 +584,8 @@ 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; + usb_dir_t direction = endpoint & 1; + u32 reg_mask = endpoint; // Flash all endpoints or 1. if (endpoint != USB_EP_ALL) @@ -628,19 +629,23 @@ int usbd_flush_endpoint(u32 endpoint) return USB_RES_OK; } +static void _usb_reset_disable_ep1() +{ + 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_disable_ep1(); + + usbd_otg->config_num = 0; + usbd_otg->interface_num = 0; + usbd_otg->configuration_set = false; + usbd_otg->max_lun_set = false; +} + 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; - } + _usb_reset_disable_ep1(); // Stop device controller. usbd_otg->regs->usbcmd &= ~USB2D_USBCMD_RUN; @@ -659,9 +664,11 @@ static void _usbd_mark_ep_complete(u32 endpoint) 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; + 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) @@ -762,7 +769,7 @@ static int _usbd_ep_operation(usb_ep_t endpoint, u8 *buf, u32 len, u32 sync_time // 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] = + usbdaemon->dtds[dtd_ep_idx + dtd_idx].pages[i] = !buf ? 0 : (u32)&buf[dt_buffer_offset + (USB_TD_BUFFER_PAGE_SIZE * i)]; //usbdaemon->dtds[dtd_ep_idx + dtd_idx].pages[5] = @@ -785,13 +792,13 @@ static int _usbd_ep_operation(usb_ep_t endpoint, u8 *buf, u32 len, u32 sync_time 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; + // Flush data before priming EP. + bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false); + // Prime endpoint. usbd_otg->regs->endptprime |= prime_bit; // USB2_CONTROLLER_USB2D_ENDPTPRIME. @@ -825,8 +832,9 @@ static int _usbd_ep_operation(usb_ep_t endpoint, u8 *buf, u32 len, u32 sync_time else if (_usbd_get_ep_status(endpoint) != USB_EP_STATUS_IDLE) res = USB_ERROR_XFER_ERROR; + // Invalidate data after OP is done. if (direction == USB_DIR_OUT) - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); + bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false); } return res; @@ -840,9 +848,8 @@ static int _usbd_ep_ack(usb_ep_t ep) 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; + 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) @@ -1046,6 +1053,16 @@ static int _usbd_handle_set_request(bool *ep_stall) if (!res) { usbd_otg->config_num = usbd_otg->control_setup.wValue; + + // Remove configuration. + if (!usbd_otg->config_num) + { + //! TODO: Signal that to userspace. + _usb_reset_disable_ep1(); + return res; + } + + // Initialize configuration. _usbd_initialize_ep_ctrl(USB_EP_BULK_OUT); _usbd_initialize_ep_ctrl(USB_EP_BULK_IN); usbd_otg->configuration_set = true; @@ -1321,8 +1338,8 @@ static int _usbd_ep0_initialize() // 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_otg->regs->endptsetupstat = usbd_otg->regs->endptsetupstat; + usbd_otg->regs->endptcomplete = usbd_otg->regs->endptcomplete; usbd_flush_endpoint(USB_EP_ALL); } @@ -1470,7 +1487,7 @@ int usb_device_ep1_out_reading_finish(u32 *pending_bytes, u32 sync_timeout) *pending_bytes = _usbd_get_ep1_out_bytes_read(); - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); + bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false); if (ep_status == USB_EP_STATUS_IDLE) return USB_RES_OK; diff --git a/bdk/usb/xusbd.c b/bdk/usb/xusbd.c index 0f68ec7c..c14816d4 100644 --- a/bdk/usb/xusbd.c +++ b/bdk/usb/xusbd.c @@ -1,7 +1,7 @@ /* * eXtensible USB Device driver (XDCI) for Tegra X1 * - * Copyright (c) 2020-2021 CTCaer + * Copyright (c) 2020-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, @@ -28,9 +28,9 @@ #include #include #include +#include #include #include -#include #include @@ -397,9 +397,9 @@ 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]; + 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; @@ -676,8 +676,8 @@ static int _xusb_ep_init_context(u32 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; + 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); @@ -685,16 +685,16 @@ static int _xusb_ep_init_context(u32 ep_idx) 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->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; + 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; + 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); @@ -702,16 +702,16 @@ static int _xusb_ep_init_context(u32 ep_idx) 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->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; + 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; + 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); @@ -719,10 +719,10 @@ static int _xusb_ep_init_context(u32 ep_idx) 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->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; + link_trb->trb_type = XUSB_TRB_LINK; break; } @@ -744,7 +744,7 @@ static int _xusbd_ep_initialize(u32 ep_idx) if (!res) { XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_PAUSE) &= ~BIT(ep_idx); - XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) &= ~BIT(ep_idx); + XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) &= ~BIT(ep_idx); } return res; default: @@ -752,6 +752,48 @@ static int _xusbd_ep_initialize(u32 ep_idx) } } +static void _xusbd_ep1_disable(u32 ep_idx) +{ + volatile xusb_ep_ctx_t *ep_ctxt = &xusb_evtq->xusb_ep_ctxt[ep_idx]; + u32 ep_mask = BIT(ep_idx); + + switch (ep_idx) + { + case USB_EP_BULK_OUT: + case USB_EP_BULK_IN: + // Skip if already disabled. + if (!ep_ctxt->ep_state) + return; + + XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) |= ep_mask; + + // Set EP state to disabled. + ep_ctxt->ep_state = EP_DISABLED; + + // Wait for EP status to change. + _xusb_xhci_mask_wait(XUSB_DEV_XHCI_EP_STCHG, ep_mask, ep_mask, 1000); + + // Clear status change. + XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_STCHG) = ep_mask; + break; + } +} + +static void _xusb_disable_ep1() +{ + _xusbd_ep1_disable(USB_EP_BULK_OUT); + _xusbd_ep1_disable(USB_EP_BULK_IN); + + // Device mode stop. + XUSB_DEV_XHCI(XUSB_DEV_XHCI_CTRL) &= ~XHCI_CTRL_RUN; + XUSB_DEV_XHCI(XUSB_DEV_XHCI_ST) |= XHCI_ST_RC; + + usbd_xotg->config_num = 0; + usbd_xotg->interface_num = 0; + usbd_xotg->max_lun_set = false; + usbd_xotg->device_state = XUSB_DEFAULT; +} + static void _xusb_init_phy() { // Configure and enable PLLU. @@ -785,7 +827,7 @@ static void _xusb_init_phy() (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_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. @@ -841,11 +883,9 @@ static void _xusbd_init_device_clocks() int xusb_device_init() { - ///////////////////////////////////////////////// + // Disable USB2 device controller clocks. 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); @@ -881,7 +921,7 @@ int xusb_device_init() _xusbd_init_device_clocks(); // Enable AHB redirect for access to IRAM for Event/EP ring buffers. - mc_enable_ahb_redirect(false); // Can be skipped if IRAM is not used. + mc_enable_ahb_redirect(); // Enable XUSB device IPFS. XUSB_DEV_DEV(XUSB_DEV_CONFIGURATION) |= DEV_CONFIGURATION_EN_FPCI; @@ -896,10 +936,10 @@ int xusb_device_init() // 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. + 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; @@ -907,8 +947,8 @@ int xusb_device_init() // 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_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. @@ -927,6 +967,44 @@ int xusb_device_init() return USB_RES_OK; } +//! TODO: Power down more stuff. +static void _xusb_device_power_down() +{ + // Disable clock for XUSB Super-Speed and set source to CLK_M. + CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB_SS); + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_SS) &= 0x1FFFFF00; + usleep(2); + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = BIT(CLK_W_XUSB_SS); + + // Put XUSB device into reset. + CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = BIT(CLK_U_XUSB_DEV); + usleep(2); + + // Reset Full-Speed clock source to CLK_M and div1. + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_FS) = 0; + usleep(2); + + // Disable XUSB device clock. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = BIT(CLK_U_XUSB_DEV); + + // Force UTMIP_PLL power down. + CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG1) &= (~BIT(15)); + CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) |= BIT(4) | BIT(0); // UTMIP_FORCE_PD_SAMP_A/C_POWERDOWN. + + // Force enable UTMIPLL IDDQ. + CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) |= 3; + + // Disable PLLU. + clock_disable_pllu(); + + // Set XUSB_PADCTL clock reset. + CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB_PADCTL); + + // Disable XUSB clock. + CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB); + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = BIT(CLK_W_XUSB); +} + static int _xusb_queue_trb(u32 ep_idx, void *trb, bool ring_doorbell) { int res = USB_RES_OK; @@ -946,7 +1024,9 @@ static int _xusb_queue_trb(u32 ep_idx, void *trb, bool ring_doorbell) 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; @@ -962,7 +1042,9 @@ static int _xusb_queue_trb(u32 ep_idx, void *trb, bool ring_doorbell) 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; @@ -978,7 +1060,9 @@ static int _xusb_queue_trb(u32 ep_idx, void *trb, bool ring_doorbell) 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; @@ -993,10 +1077,13 @@ static int _xusb_queue_trb(u32 ep_idx, void *trb, bool ring_doorbell) // Ring doorbell. if (ring_doorbell) { - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); + // Flush data before transfer. + bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_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; } @@ -1005,10 +1092,10 @@ static int _xusb_queue_trb(u32 ep_idx, void *trb, bool ring_doorbell) 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->cycle = usbd_xotg->cntrl_producer_cycle & 1; + trb->ioc = 1; // Enable interrupt on completion. trb->trb_type = XUSB_TRB_STATUS; - trb->dir = direction; + trb->dir = direction; } static void _xusb_create_normal_trb(normal_trb_t *trb, u8 *buf, u32 len, usb_dir_t direction) @@ -1022,16 +1109,16 @@ static void _xusb_create_normal_trb(normal_trb_t *trb, u8 *buf, u32 len, usb_dir // Single TRB transfer. trb->td_size = 0; - trb->chain = 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->cycle = producer_cycle; + trb->isp = 1; // Enable interrupt on short packet. + trb->ioc = 1; // Enable interrupt on completion. trb->trb_type = XUSB_TRB_NORMAL; } @@ -1044,13 +1131,13 @@ static void _xusb_create_data_trb(data_trb_t *trb, u8 *buf, u32 len, usb_dir_t d // Single TRB transfer. trb->td_size = 0; - trb->chain = 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->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; + trb->dir = direction; } static int _xusb_issue_status_trb(usb_dir_t direction) @@ -1061,6 +1148,7 @@ static int _xusb_issue_status_trb(usb_dir_t direction) 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; } @@ -1076,6 +1164,7 @@ static int _xusb_issue_normal_trb(u8 *buf, u32 len, usb_dir_t direction) u32 ep_idx = USB_EP_BULK_IN; if (direction == USB_DIR_OUT) ep_idx = USB_EP_BULK_OUT; + int res = _xusb_queue_trb(ep_idx, &trb, EP_RING_DOORBELL); if (!res) usbd_xotg->wait_for_event_trb = XUSB_TRB_NORMAL; @@ -1091,6 +1180,7 @@ static int _xusb_issue_data_trb(u8 *buf, u32 len, usb_dir_t direction) 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; @@ -1360,8 +1450,8 @@ static int _xusb_handle_get_ep_status(u32 ep_idx) u32 ep_mask = BIT(ep_idx); static u8 xusb_ep_status_descriptor[2] = {0}; - xusb_ep_status_descriptor[0] = - (XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) & ep_mask) ? USB_STATUS_EP_HALTED : USB_STATUS_EP_OK; + xusb_ep_status_descriptor[0] = (XUSB_DEV_XHCI(XUSB_DEV_XHCI_EP_HALT) & ep_mask) ? USB_STATUS_EP_HALTED : USB_STATUS_EP_OK; + return _xusb_issue_data_trb(xusb_ep_status_descriptor, 2, USB_DIR_IN); } @@ -1383,6 +1473,7 @@ static int _xusb_handle_get_class_request(usb_ctrl_setup_t *ctrl_setup) 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; @@ -1538,9 +1629,18 @@ static void _xusb_handle_set_request_dev_address(usb_ctrl_setup_t *ctrl_setup) 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. + usbd_xotg->config_num = ctrl_setup->wValue; + + // Remove configuration. + if (!usbd_xotg->config_num) + { + //! TODO: Signal that to userspace. + _xusb_disable_ep1(); + + _xusb_issue_status_trb(USB_DIR_IN); + return; + } // Initialize BULK EPs. _xusbd_ep_initialize(USB_EP_BULK_OUT); @@ -1551,8 +1651,6 @@ static void _xusb_handle_set_request_configuration(usb_ctrl_setup_t *ctrl_setup) 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; } @@ -1862,7 +1960,7 @@ int xusb_device_enumerate(usb_gadget_type gadget) // 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; + 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; @@ -1873,16 +1971,15 @@ int xusb_device_enumerate(usb_gadget_type gadget) // 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_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; + 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; + usbd_xotg->device_state = XUSB_DEFAULT; // Timeout if cable or communication isn't started in 1.5 minutes. u32 timer = get_tmr_ms() + 90000; @@ -1902,17 +1999,16 @@ int xusb_device_enumerate(usb_gadget_type gadget) return USB_RES_OK; } -//! TODO: Do a full deinit. void xusb_end(bool reset_ep, bool only_controller) { - CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB_SS); - 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. + // Disable endpoints and stop device mode operation. + _xusb_disable_ep1(); + + // Disable device mode. + XUSB_DEV_XHCI(XUSB_DEV_XHCI_CTRL) = 0; + + //! TODO: Add only controller support? + _xusb_device_power_down(); } int xusb_handle_ep0_ctrl_setup() @@ -1938,6 +2034,7 @@ int xusb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, u32 sync_tries) int res = USB_RES_OK; usbd_xotg->tx_count[USB_DIR_OUT] = 0; usbd_xotg->tx_bytes[USB_DIR_OUT] = len; + _xusb_issue_normal_trb(buf, len, USB_DIR_OUT); usbd_xotg->tx_count[USB_DIR_OUT]++; @@ -1948,10 +2045,11 @@ int xusb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, u32 sync_tries) if (bytes_read) *bytes_read = res ? 0 : usbd_xotg->tx_bytes[USB_DIR_OUT]; - - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); } + // Invalidate data after transfer. + bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false); + return res; } @@ -1989,7 +2087,8 @@ int xusb_device_ep1_out_reading_finish(u32 *pending_bytes, u32 sync_tries) if (pending_bytes) *pending_bytes = res ? 0 : usbd_xotg->tx_bytes[USB_DIR_OUT]; - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); + // Invalidate data after transfer. + bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false); return res; } @@ -1999,11 +2098,13 @@ int xusb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, u32 sync_trie if (len > USB_EP_BUFFER_MAX_SIZE) len = USB_EP_BUFFER_MAX_SIZE; - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); + // Flush data before transfer. + bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false); int res = USB_RES_OK; usbd_xotg->tx_count[USB_DIR_IN] = 0; usbd_xotg->tx_bytes[USB_DIR_IN] = len; + _xusb_issue_normal_trb(buf, len, USB_DIR_IN); usbd_xotg->tx_count[USB_DIR_IN]++; @@ -2053,7 +2154,7 @@ 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 = max_lun; usbd_xotg->max_lun_set = true; // Wait for request and transfer start. diff --git a/bdk/utils/btn.c b/bdk/utils/btn.c index cc365734..55ca67b6 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, @@ -18,8 +18,8 @@ #include "btn.h" #include #include +#include #include -#include #include u8 btn_read() @@ -29,6 +29,7 @@ u8 btn_read() res |= BTN_VOL_DOWN; if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6)) res |= BTN_VOL_UP; + // HOAG can use the GPIO. Icosa/Iowa/AULA cannot. Traces are there but they miss a resistor. if (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFSTAT) & MAX77620_ONOFFSTAT_EN0) res |= BTN_POWER; return res; @@ -44,6 +45,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 ac191fa9..a1c91a33 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 ff4d3a31..7e13ff37 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,23 +39,30 @@ 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; + // Initialize list. + list_init(&csec->kvs); + return csec; } 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; + u32 pathlen = strlen(ini_path); ini_sec_t *csec = NULL; + char *lbuf = NULL; + char *filelist = NULL; char *filename = (char *)malloc(256); strcpy(filename, ini_path); @@ -114,8 +103,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 { @@ -133,7 +121,6 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir) _find_section_name(lbuf, lblen, ']'); csec = _ini_create_section(dst, csec, &lbuf[1], INI_CHOICE); - list_init(&csec->kvs); } else if (lblen > 1 && lbuf[0] == '{') // Create new caption. Support empty caption '{}'. { @@ -154,13 +141,22 @@ 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)); + free(lbuf); + f_close(&fp); if (csec) @@ -177,16 +173,55 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir) return 1; } -char *ini_check_payload_section(ini_sec_t *cfg) +char *ini_check_special_section(ini_sec_t *cfg) { if (cfg == NULL) return NULL; LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link) { - if (!strcmp("payload", kv->key)) + if (!strcmp("l4t", kv->key)) + return ((kv->val[0] == '1') ? (char *)-1 : NULL); + else if (!strcmp("payload", kv->key)) return kv->val; } return NULL; } + +void ini_free(link_t *src) +{ + ini_sec_t *prev_sec = NULL; + + // Parse and free all ini sections. + LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, src, link) + { + ini_kv_t *prev_kv = NULL; + + // Free all ini key allocations if they exist. + LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) + { + // Free previous key. + if (prev_kv) + free(prev_kv); + + // Set next key to free. + prev_kv = kv; + } + + // Free last key. + if (prev_kv) + free(prev_kv); + + // Free previous section. + if (prev_sec) + free(prev_sec); + + // Set next section to free. + prev_sec = ini_sec; + } + + // Free last section. + if (prev_sec) + free(prev_sec); +} diff --git a/bdk/utils/ini.h b/bdk/utils/ini.h index 571d19d2..929a850d 100644 --- a/bdk/utils/ini.h +++ b/bdk/utils/ini.h @@ -43,8 +43,9 @@ typedef struct _ini_sec_t u32 color; } ini_sec_t; -int ini_parse(link_t *dst, char *ini_path, bool is_dir); -char *ini_check_payload_section(ini_sec_t *cfg); +int ini_parse(link_t *dst, char *ini_path, bool is_dir); +char *ini_check_special_section(ini_sec_t *cfg); +void ini_free(link_t *src); #endif diff --git a/bdk/utils/list.h b/bdk/utils/list.h index ece5402f..4d172619 100644 --- a/bdk/utils/list.h +++ b/bdk/utils/list.h @@ -28,16 +28,25 @@ /*! Iterate over all list links. */ #define LIST_FOREACH(iter, list) \ - for(link_t *iter = (list)->next; iter != (list); iter = iter->next) + for (link_t *iter = (list)->next; iter != (list); iter = iter->next) + +/*! Iterate over all list links backwards. */ +#define LIST_FOREACH_INVERSE(iter, list) \ + for (link_t *iter = (list)->prev; iter != (list); iter = iter->prev) /*! Safely iterate over all list links. */ #define LIST_FOREACH_SAFE(iter, list) \ - for(link_t *iter = (list)->next, *safe = iter->next; iter != (list); iter = safe, safe = iter->next) + for (link_t *iter = (list)->next, *safe = iter->next; iter != (list); iter = safe, safe = iter->next) /*! Iterate over all list members and make sure that the list has at least one entry. */ #define LIST_FOREACH_ENTRY(etype, iter, list, mn) \ if ((list)->next != (list)) \ - for(etype *iter = CONTAINER_OF((list)->next, etype, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.next, etype, mn)) + for (etype *iter = CONTAINER_OF((list)->next, etype, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.next, etype, mn)) + +/* Iterate over all list members backwards and make sure that the list has at least one entry. */ +#define LIST_FOREACH_ENTRY_INVERSE(type, iter, list, mn) \ + if ((list)->prev != (list)) \ + for (type *iter = CONTAINER_OF((list)->prev, type, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.prev, type, mn)) typedef struct _link_t { @@ -53,7 +62,7 @@ static inline void link_init(link_t *l) static inline int link_used(link_t *l) { - if(l->next == NULL) + if (l->next == NULL) return 1; return 0; } @@ -89,7 +98,7 @@ static inline void list_remove(link_t *l) static inline int list_empty(link_t *lh) { - if(lh->next == lh) + if (lh->next == lh) return 1; return 0; } diff --git a/bdk/utils/sprintf.c b/bdk/utils/sprintf.c index 8fa2decd..87f1526a 100644 --- a/bdk/utils/sprintf.c +++ b/bdk/utils/sprintf.c @@ -1,123 +1,214 @@ /* - * 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 void _s_putn(u32 v, int base, char fill, int fcnt) +{ + static const char digits[] = "0123456789ABCDEF"; + + char *p; + char buf[65]; + int c = fcnt; + bool negative = false; + + if (base != 10 && base != 16) + return; + + // Account for negative numbers. + if (base == 10 && v & 0x80000000) + { + negative = true; + v = (int)v * -1; + c--; + } + + p = buf + 64; + *p = 0; + do + { + c--; + *--p = digits[v % base]; + v /= base; + } while (v); + + if (negative) + *--p = '-'; + + if (fill != 0) + { + while (c > 0 && p > buf) + { + *--p = fill; + c--; + } + } + + _s_puts(p); } -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; - - if (base > 36) - return 0; - - p = buf + 0x120; - *p = 0; - do { - c--; - *--p = digits[v % base]; - v /= base; - } while (v); - - if (fill != 0) { - while (c > 0) { - *--p = fill; - c--; - } - } - - return _puts(buffer, p); +void s_printf(char *out_buf, const char *fmt, ...) +{ + va_list ap; + int fill, fcnt; + + sout_buf = &out_buf; + + 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); } -u32 s_printf(char *buffer, const char *fmt, ...) { - va_list ap; - int fill, fcnt; - u32 count = 0; - - 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++; - } - - out: - buffer[count] = 0; - va_end(ap); - return count; -} \ No newline at end of file +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 35a82187..c5232674 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, ...) __attribute__((format(printf, 2, 3))); +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 7c56806e..e15addd2 100644 --- a/bdk/utils/types.h +++ b/bdk/utils/types.h @@ -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, @@ -56,9 +56,9 @@ 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}; @@ -113,7 +113,7 @@ static const u32 colors[6] = {COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_GREEN #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)) + (((num) >> 8 ) & 0xff00) | (((num) << 24) & 0xff000000)) /* Bootloader/Nyx */ @@ -153,8 +153,8 @@ 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]; diff --git a/bdk/utils/util.c b/bdk/utils/util.c index 146c404e..e88232a6 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 @@ -23,13 +24,13 @@ #include #include #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; @@ -51,54 +52,153 @@ u32 bit_count_mask(u8 bits) return val; } -u32 get_tmr_s() +char *strcpy_ns(char *dst, char *src) { - return RTC(APBDEV_RTC_SECONDS); -} + if (!src || !dst) + return NULL; -u32 get_tmr_ms() -{ - // The registers must be read with the following order: - // RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC) - return (RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000)); + // 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_us() +// Approximate square root finder for a 64-bit number. +u64 sqrt64(u64 num) { - return TMR(TIMERUS_CNTR_1US); + u64 base = 0; + u64 limit = num; + u64 square_root = 0; + + while (base <= limit) + { + u64 tmp_sqrt = (base + limit) / 2; + + if (tmp_sqrt * tmp_sqrt == num) { + square_root = tmp_sqrt; + break; + } + + if (tmp_sqrt * tmp_sqrt < num) + { + square_root = base; + base = tmp_sqrt + 1; + } + else + limit = tmp_sqrt - 1; + } + + return square_root; } -void msleep(u32 ms) +#define TLONG_MAX ((long)(((unsigned long)(~0L)) >> 1)) +#define TLONG_MIN ((long)(~TLONG_MAX)) +#define ISSPACE(ch) ((ch >= '\t' && ch <= '\r') || (ch == ' ')) +#define ISDIGIT(ch) ( ch >= '0' && ch <= '9' ) +#define ISALPHA(ch) ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) +#define ISUPPER(ch) ( ch >= 'A' && ch <= 'Z' ) + +/* + * Avoid using reentrant newlib version of strol. It's only used for errno. + * + * strol/atoi: + * Copyright (c) 1990 The Regents of the University of California. + */ +long strtol(const char *nptr, char **endptr, register int base) { -#ifdef USE_RTC_TIMER - u32 start = RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000); - // Casting to u32 is important! - while (((u32)(RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000)) - start) <= ms) - ; -#else - bpmp_msleep(ms); -#endif + register const char *s = nptr; + register unsigned long acc; + register int c; + register unsigned long cutoff; + register int neg = 0, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + do { + c = *s++; + } while (ISSPACE(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else if (c == '+') + c = *s++; + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? -(unsigned long)TLONG_MIN : TLONG_MAX; + cutlim = cutoff % (unsigned long)base; + cutoff /= (unsigned long)base; + for (acc = 0, any = 0;; c = *s++) { + if (ISDIGIT(c)) + c -= '0'; + else if (ISALPHA(c)) + c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? TLONG_MIN : TLONG_MAX; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (char *) (any ? s - 1 : nptr); + return (acc); } -void usleep(u32 us) +int atoi(const char *nptr) { -#ifdef USE_RTC_TIMER - u32 start = TMR(TIMERUS_CNTR_1US); - - // Check if timer is at upper limits and use BPMP sleep so it doesn't wake up immediately. - if ((start + us) < start) - bpmp_usleep(us); - else - while ((u32)(TMR(TIMERUS_CNTR_1US) - start) <= us) // Casting to u32 is important! - ; -#else - bpmp_usleep(us); -#endif + return (int)strtol(nptr, (char **)NULL, 10); } void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops) { - for(u32 i = 0; i < num_ops; i++) + for (u32 i = 0; i < num_ops; i++) base[ops[i].off] = ops[i].val; } @@ -143,14 +243,14 @@ void panic(u32 val) { // Set panic code. PMC(APBDEV_PMC_SCRATCH200) = val; + + // Disable SE. //PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_DISABLE; - TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN; - TMR(TIMER_TMR9_TMR_PTV) = TIMER_EN | TIMER_PER_EN; - TMR(TIMER_WDT4_CONFIG) = TIMER_SRC(9) | TIMER_PER(1) | TIMER_PMCRESET_EN; - TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT; - while (true) - usleep(1); + // Immediately cause a full system reset. + watchdog_start(0, TIMER_PMCRESET_EN); + + while (true); } void power_set_state(power_state_t state) @@ -179,7 +279,7 @@ void power_set_state(power_state_t state) break; case POWER_OFF: - // Initiate power down sequence and do not generate a reset (regulators retain state). + // Initiate power down sequence and do not generate a reset (regulators retain state after POR). i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF); break; @@ -194,7 +294,7 @@ void power_set_state(power_state_t state) reg |= MAX77620_ONOFFCNFG2_SFT_RST_WK; i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2, reg); - // Initiate power down sequence and generate a reset (regulators' state resets). + // Initiate power down sequence and generate a reset (regulators' state resets after POR). i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_SFT_RST); break; } diff --git a/bdk/utils/util.h b/bdk/utils/util.h index 66201f61..2ba268ab 100644 --- a/bdk/utils/util.h +++ b/bdk/utils/util.h @@ -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, @@ -21,6 +21,8 @@ #include #include +#define CFG_SIZE(array) (sizeof(array) / sizeof(cfg_op_t)) + #define NYX_NEW_INFO 0x3058594E typedef enum @@ -35,9 +37,8 @@ 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; @@ -52,11 +53,6 @@ typedef enum 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; @@ -82,21 +78,19 @@ typedef struct _nyx_storage_t u8 rsvd[SZ_8M - sizeof(nyx_info_t)]; nyx_info_t info; mtc_config_t mtc_cfg; - emc_table_t mtc_table[10]; + emc_table_t mtc_table[11]; // 10 + 1. } nyx_storage_t; u8 bit_count(u32 val); u32 bit_count_mask(u8 bits); +char *strcpy_ns(char *dst, char *src); +u64 sqrt64(u64 num); +long strtol(const char *nptr, char **endptr, register int base); +int atoi(const char *nptr); 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(); -void usleep(u32 us); -void msleep(u32 ms); - void panic(u32 val); void power_set_state(power_state_t state); void power_set_state_ex(void *param); diff --git a/source/config.c b/source/config.c index fbe505ec..a7eb66e7 100644 --- a/source/config.c +++ b/source/config.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/source/cpr/cpr.c b/source/cpr/cpr.c index 35514fa3..cede5314 100644 --- a/source/cpr/cpr.c +++ b/source/cpr/cpr.c @@ -1,6 +1,6 @@ // #include // #include "tools.h" -#include +#include #include "../fs/readers/folderReader.h" #include "../fs/fstypes.h" #include "../fs/fscopy.h" diff --git a/source/fs/menus/filemenu.c b/source/fs/menus/filemenu.c index 8cbcbeeb..4564eb25 100644 --- a/source/fs/menus/filemenu.c +++ b/source/fs/menus/filemenu.c @@ -14,7 +14,7 @@ #include "../../script/lexer.h" #include "../../script/parser.h" #include "../../script/variables.h" -#include +#include #include "../../storage/emummc.h" MenuEntry_t FileMenuEntries[] = { diff --git a/source/fs/menus/foldermenu.c b/source/fs/menus/foldermenu.c index 1d8b4d36..abf14b1a 100644 --- a/source/fs/menus/foldermenu.c +++ b/source/fs/menus/foldermenu.c @@ -14,7 +14,7 @@ #include "../../script/lexer.h" #include "../../script/parser.h" #include "../../script/variables.h" -#include +#include #include "../fscopy.h" MenuEntry_t FolderMenuEntries[] = { diff --git a/source/gfx/gfx.c b/source/gfx/gfx.c index a6bce342..93514c01 100644 --- a/source/gfx/gfx.c +++ b/source/gfx/gfx.c @@ -495,6 +495,17 @@ void gfx_putc_small(char c){ #define hexDumpLen 0x20 +static void _gfx_cputs(u32 color, const char *s) +{ + gfx_con.fgcol = color; + gfx_puts(s); + gfx_putc('\n'); + gfx_con.fgcol = TXT_CLR_DEFAULT; +} + +void gfx_wputs(const char *s) { _gfx_cputs(TXT_CLR_WARNING, s); } +void gfx_eputs(const char *s) { _gfx_cputs(TXT_CLR_ERROR, s); } + void gfx_hexdump(u32 base, const u8 *buf, u32 len) { if (gfx_con.mute) diff --git a/source/gfx/gfx.h b/source/gfx/gfx.h index a8f82df3..8b6c3545 100644 --- a/source/gfx/gfx.h +++ b/source/gfx/gfx.h @@ -21,11 +21,28 @@ #include #include +#include +#include -#define EPRINTF(text) gfx_printf("%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC) -#define EPRINTFARGS(text, args...) gfx_printf("%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC) -#define WPRINTF(text) gfx_printf("%k"text"%k\n", 0xFFFFDD00, 0xFFCCCCCC) -#define WPRINTFARGS(text, args...) gfx_printf("%k"text"%k\n", 0xFFFFDD00, args, 0xFFCCCCCC) +#define TXT_CLR_BG 0xFF1B1B1B // Dark Grey. +#define TXT_CLR_DEFAULT 0xFFCCCCCC // Light Grey. +#define TXT_CLR_WARNING 0xFFFFDD00 // Yellow. +#define TXT_CLR_ERROR 0xFFFF0000 // Red. +#define TXT_CLR_CYAN_L 0xFF00CCFF // Light Cyan. +#define TXT_CLR_TURQUOISE 0xFF00FFCC // Turquoise. +#define TXT_CLR_ORANGE 0xFFFFBA00 // Orange. +#define TXT_CLR_GREENISH 0xFF96FF00 // Toxic Green. +#define TXT_CLR_GREEN_D 0xFF008800 // Dark Green. +#define TXT_CLR_RED_D 0xFF880000 // Dark Red. +#define TXT_CLR_GREY_D 0xFF303030 // Darkest Grey. +#define TXT_CLR_GREY_DM 0xFF444444 // Darker Grey. +#define TXT_CLR_GREY_M 0xFF555555 // Dark Grey. +#define TXT_CLR_GREY 0xFF888888 // Grey. + +#define EPRINTF(text) gfx_eputs(text) +#define EPRINTFARGS(text, args...) gfx_printf("%k"text"%k\n", TXT_CLR_ERROR, args, TXT_CLR_DEFAULT) +#define WPRINTF(text) gfx_wputs(text) +#define WPRINTFARGS(text, args...) gfx_printf("%k"text"%k\n", TXT_CLR_WARNING, args, TXT_CLR_DEFAULT) typedef struct _gfx_ctxt_t { @@ -63,6 +80,8 @@ void gfx_con_getpos(u32 *x, u32 *y); void gfx_con_setpos(u32 x, u32 y); void gfx_putc(char c); void gfx_puts(const char *s); +void gfx_wputs(const char *s); +void gfx_eputs(const char *s); void gfx_printf(const char *fmt, ...); void gfx_vprintf(const char *fmt, va_list ap); void gfx_hexdump(u32 base, const u8 *buf, u32 len); diff --git a/source/hos/fss.c b/source/hos/fss.c index 09896f9e..a0a09cd2 100644 --- a/source/hos/fss.c +++ b/source/hos/fss.c @@ -24,7 +24,7 @@ #include #include #include "../storage/emummc.h" -#include +#include #include #define DPRINTF(...) diff --git a/source/hos/sept.c b/source/hos/sept.c index 24fef6d1..d3e56b21 100644 --- a/source/hos/sept.c +++ b/source/hos/sept.c @@ -27,8 +27,8 @@ #include #include #include -#include "../storage/nx_emmc.h" -#include +#include +#include #include #include #include diff --git a/source/keys/keyfile.c b/source/keys/keyfile.c index 18755ecb..a06ce950 100644 --- a/source/keys/keyfile.c +++ b/source/keys/keyfile.c @@ -5,7 +5,7 @@ #include #include #include "../tegraexplorer/tconf.h" -#include +#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 4009342b..c35cd932 100644 --- a/source/keys/keys.c +++ b/source/keys/keys.c @@ -18,9 +18,9 @@ #include #include #include "../storage/emummc.h" -#include "../storage/nx_emmc.h" -#include "../storage/nx_emmc_bis.h" -#include +#include +#include +#include #include #include #include @@ -125,7 +125,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 +144,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(&emmc_storage, KEYBLOB_OFFSET / EMMC_BLOCKSIZE, KB_FIRMWARE_VERSION_600 + 1, keyblob_block)) { DPRINTF("Unable to read keyblobs."); } @@ -195,7 +195,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) { @@ -231,7 +231,7 @@ static ALWAYS_INLINE u8 *_read_pkg1(const pkg1_id_t **pkg1_id) { 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(&emmc_storage, PKG1_OFFSET / EMMC_BLOCKSIZE, PKG1_MAX_SIZE / EMMC_BLOCKSIZE, pkg1)) { DPRINTF("Unable to read pkg1."); return NULL; } diff --git a/source/libs/fatfs/diskio.c b/source/libs/fatfs/diskio.c index 987266b7..5419d3cb 100644 --- a/source/libs/fatfs/diskio.c +++ b/source/libs/fatfs/diskio.c @@ -27,8 +27,8 @@ #include /* FatFs lower layer API */ #include -#include -#include "../../storage/nx_emmc_bis.h" +#include +#include #include /*-----------------------------------------------------------------------*/ diff --git a/source/libs/fatfs/ffconf.h b/source/libs/fatfs/ffconf.h index 9f021f0f..875f4ec7 100644 --- a/source/libs/fatfs/ffconf.h +++ b/source/libs/fatfs/ffconf.h @@ -41,14 +41,24 @@ #define FF_USE_MKFS 1 /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ -#define FF_FASTFS 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 -#else -#define FF_USE_FASTSEEK 0 #endif -/* This option switches fast seek function. (0:Disable or 1:Enable) */ +/* 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 @@ -245,7 +255,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 8f9b6e72..d9712a28 100644 --- a/source/main.c +++ b/source/main.c @@ -32,8 +32,8 @@ #include #include #include "storage/emummc.h" -#include "storage/nx_emmc.h" -#include +#include "storage/emmc.h" +#include #include #include #include diff --git a/source/script/functions.c b/source/script/functions.c index c2b7d75f..ac6ae878 100644 --- a/source/script/functions.c +++ b/source/script/functions.c @@ -6,7 +6,7 @@ #include #include "lexer.h" -#include +#include #include "../fs/fsutils.h" #include "../gfx/gfxutils.h" #include "../hid/hid.h" diff --git a/source/storage/emmcfile.c b/source/storage/emmcfile.c index 218db89d..09068c45 100644 --- a/source/storage/emmcfile.c +++ b/source/storage/emmcfile.c @@ -3,16 +3,16 @@ #include "emummc.h" #include "mountmanager.h" #include -#include "nx_emmc.h" +#include #include #include "../err.h" #include "../tegraexplorer/tconf.h" #include "../gfx/gfxutils.h" #include "../hid/hid.h" -#include +#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,7 +41,7 @@ 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) @@ -54,7 +54,7 @@ ErrCode_t EmmcDumpToFile(const char *path, u32 lba_start, u32 lba_end, u8 force, 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 +82,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 +100,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; } @@ -121,7 +121,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); } @@ -158,11 +158,11 @@ ErrCode_t DumpOrWriteEmmcPart(const char *path, const char *part, u8 write, u8 f if (!memcmp(part, "BOOT0", 5)){ emummc_storage_set_mmc_partition(&emmc_storage, 1); - lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 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; + lba_end = (BOOT_PART_SIZE / EMMC_BLOCKSIZE) - 1; } else { emummc_storage_set_mmc_partition(&emmc_storage, 0); @@ -172,7 +172,7 @@ ErrCode_t DumpOrWriteEmmcPart(const char *path, const char *part, u8 write, u8 f 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, false, 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 65953ed4..35b05efc 100644 --- a/source/storage/emummc.c +++ b/source/storage/emummc.c @@ -24,8 +24,8 @@ #include #include #include -#include "../storage/nx_emmc.h" -#include +#include +#include #include #include diff --git a/source/storage/gptmenu.c b/source/storage/gptmenu.c index 9c9198e7..dddac40e 100644 --- a/source/storage/gptmenu.c +++ b/source/storage/gptmenu.c @@ -6,13 +6,13 @@ #include "mountmanager.h" #include #include -#include "nx_emmc.h" +#include #include #include "../fs/menus/explorer.h" #include "../err.h" #include "../tegraexplorer/tconf.h" #include "emmcfile.h" -#include +#include #include "../fs/fsutils.h" #include "../utils/utils.h" diff --git a/source/storage/mountmanager.c b/source/storage/mountmanager.c index 5ee13e6f..17403028 100644 --- a/source/storage/mountmanager.c +++ b/source/storage/mountmanager.c @@ -1,11 +1,11 @@ #include "mountmanager.h" #include "emummc.h" #include "../tegraexplorer/tconf.h" -#include "nx_emmc.h" +#include #include "../keys/keys.h" #include #include -#include "nx_emmc_bis.h" +#include #include "../config.h" extern hekate_config h_cfg; @@ -73,7 +73,7 @@ ErrCode_t mountMMCPart(const char *partition){ if (!system_part) return newErrCode(TE_ERR_PARTITION_NOT_FOUND); - nx_emmc_bis_init(system_part); + nx_emmc_bis_init(system_part, false, 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 328a95b9..00000000 --- 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 e551a135..00000000 --- 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 bcafa69a..1bb479ec 100644 --- a/source/tegraexplorer/mainmenu.c +++ b/source/tegraexplorer/mainmenu.c @@ -6,7 +6,7 @@ #include "../hid/hid.h" #include "../fs/menus/explorer.h" #include -#include +#include #include "tconf.h" #include "../keys/keys.h" #include "../storage/mountmanager.h" @@ -99,7 +99,6 @@ void HandleSD(){ } -extern bool sd_mounted; extern bool is_sd_inited; extern int launch_payload(char *path); @@ -113,7 +112,7 @@ void RebootToHekate(){ void MountOrUnmountSD(){ gfx_clearscreen(); - if (sd_mounted) + if (sd_get_card_mounted()) sd_unmount(); else if (!sd_mount()) hidWait(); @@ -152,8 +151,8 @@ void EnterMainMenu(){ sd_unmount(); // // -- 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; gfx_clearscreen(); diff --git a/source/tegraexplorer/tools.c b/source/tegraexplorer/tools.c index 429fdbaf..2c979858 100644 --- a/source/tegraexplorer/tools.c +++ b/source/tegraexplorer/tools.c @@ -6,9 +6,10 @@ #include #include "../keys/keys.h" #include "../keys/nca.h" -#include +#include #include "../fs/fsutils.h" #include +#include #include "../storage/mountmanager.h" #include "../err.h" #include @@ -176,7 +177,7 @@ void FormatSD(){ } u8 *work = malloc(TConf.FSBuffSize); - res = f_fdisk_mod(0, plist, work); + res = f_fdisk(0, plist, work); if (!res){ res = f_mkfs("sd:", FM_FAT32, 32768, work, TConf.FSBuffSize); @@ -198,12 +199,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())