Merge from dev

This commit is contained in:
shchmue 2020-12-10 18:17:32 -07:00
commit 557aa84e2c
110 changed files with 13978 additions and 3029 deletions

View File

@ -10,8 +10,8 @@ include $(DEVKITARM)/base_rules
IPL_LOAD_ADDR := 0x40003000 IPL_LOAD_ADDR := 0x40003000
LPVERSION_MAJOR := 1 LPVERSION_MAJOR := 1
LPVERSION_MINOR := 8 LPVERSION_MINOR := 9
LPVERSION_BUGFX := 5 LPVERSION_BUGFX := 0
################################################################################ ################################################################################
@ -40,8 +40,13 @@ CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
CUSTOMDEFINES += -DLP_VER_MJ=$(LPVERSION_MAJOR) -DLP_VER_MN=$(LPVERSION_MINOR) -DLP_VER_BF=$(LPVERSION_BUGFX) CUSTOMDEFINES += -DLP_VER_MJ=$(LPVERSION_MAJOR) -DLP_VER_MN=$(LPVERSION_MINOR) -DLP_VER_BF=$(LPVERSION_BUGFX)
CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC) CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
# 0: UART_A, 1: UART_B.
#CUSTOMDEFINES += -DDEBUG_UART_PORT=0
#CUSTOMDEFINES += -DDEBUG
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fno-inline -fdata-sections -fomit-frame-pointer -std=gnu11 -Wall $(CUSTOMDEFINES) CFLAGS = $(ARCH) -Os -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall $(CUSTOMDEFINES)
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR) LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
################################################################################ ################################################################################

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer * Copyright (c) 2018-2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -22,6 +22,7 @@
#include <power/max7762x.h> #include <power/max7762x.h>
#include <soc/clock.h> #include <soc/clock.h>
#include <soc/gpio.h> #include <soc/gpio.h>
#include <soc/hw_init.h>
#include <soc/i2c.h> #include <soc/i2c.h>
#include <soc/pinmux.h> #include <soc/pinmux.h>
#include <soc/pmc.h> #include <soc/pmc.h>
@ -34,7 +35,7 @@ extern volatile nyx_storage_t *nyx_str;
static u32 _display_id = 0; static u32 _display_id = 0;
void display_end(); static void _display_panel_and_hw_end(bool no_panel_deinit);
static void _display_dsi_wait(u32 timeout, u32 off, u32 mask) static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
{ {
@ -53,91 +54,309 @@ static void _display_dsi_send_cmd(u8 cmd, u32 param, u32 wait)
usleep(wait); usleep(wait);
} }
static void _display_dsi_read_rx_fifo(u32 *data)
{
u32 fifo_count = DSI(_DSIREG(DSI_STATUS)) & DSI_STATUS_RX_FIFO_SIZE;
for (u32 i = 0; i < fifo_count; i++)
{
// Read or Drain RX FIFO.
if (data)
data[i] = DSI(_DSIREG(DSI_RD_DATA));
else
(void)DSI(_DSIREG(DSI_RD_DATA));
}
}
int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled)
{
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)
{
host_control = DSI(_DSIREG(DSI_HOST_CONTROL));
// 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)
;
}
// 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);
// 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);
// 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;
_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)
{
// 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;
case GEN_1_BYTE_SHORT_RD_RES:
case DCS_1_BYTE_SHORT_RD_RES:
memcpy(data, &fifo[2], 1);
break;
case GEN_2_BYTE_SHORT_RD_RES:
case DCS_2_BYTE_SHORT_RD_RES:
memcpy(data, &fifo[2], 2);
break;
case ACK_ERROR_RES:
default:
res = 1;
break;
}
}
// 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;
}
return res;
}
void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled)
{
u32 host_control;
u32 fifo32[DSI_STATUS_RX_FIFO_SIZE] = {0};
u8 *fifo8 = (u8 *)fifo32;
// Enable host cmd packets during video and save host control.
if (video_enabled)
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE;
host_control = DSI(_DSIREG(DSI_HOST_CONTROL));
// Enable host transfer trigger.
DSI(_DSIREG(DSI_HOST_CONTROL)) |= DSI_HOST_CONTROL_TX_TRIG_HOST;
switch (len)
{
case 0:
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, cmd, 0);
break;
case 1:
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd | (*(u8 *)data << 8), 0);
break;
default:
fifo32[0] = (len << 8) | MIPI_DSI_DCS_LONG_WRITE;
fifo8[4] = cmd;
memcpy(&fifo8[5], data, len);
len += 4 + 1; // Increase length by CMD/length word and DCS CMD.
for (u32 i = 0; i < (ALIGN(len, 4) / 4); i++)
DSI(_DSIREG(DSI_WR_DATA)) = fifo32[i];
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
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;
DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control;
}
void display_init() void display_init()
{ {
// Check if display is already initialized. // Check if display is already initialized.
if (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) & 0x18000000) if (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) & BIT(CLK_L_DISP1))
display_end(); _display_panel_and_hw_end(true);
// Power on. // Get Chip ID.
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
// T210B01: Power on SD2 regulator for supplying LD0.
if (!tegra_t210)
{
// Set SD2 regulator voltage.
max77620_regulator_set_voltage(REGULATOR_SD2, 1325000);
// 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);
max77620_regulator_enable(REGULATOR_SD2, 1);
}
// Enable power to display panel controller.
max77620_regulator_set_volt_and_flags(REGULATOR_LDO0, 1200000, MAX77620_POWER_MODE_NORMAL); // Configure to 1.2V. max77620_regulator_set_volt_and_flags(REGULATOR_LDO0, 1200000, MAX77620_POWER_MODE_NORMAL); // Configure to 1.2V.
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO7, MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH | MAX77620_CNFG_GPIO_DRV_PUSHPULL); if (tegra_t210)
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO7,
MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH | MAX77620_CNFG_GPIO_DRV_PUSHPULL); // T210: LD0 -> GPIO7 -> Display panel.
// Enable Display Interface specific clocks. // Enable Display Interface specific clocks.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x1010000; // Clear reset DSI, MIPI_CAL. 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) = 0x1010000; // Set enable clock DSI, MIPI_CAL. 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) = 0x18000000; // Clear reset DISP1, HOST1X. CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = 0x18000000; // Set enable clock DISP1, HOST1X. CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x20000; // Set enable clock UART_FST_MIPI_CAL. 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_SOURCE_UART_FST_MIPI_CAL) = 10; // Set PLLP_OUT3 and div 6 (17MHz).
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = 0x80000; // Set enable clock DSIA_LP. 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).
// Disable deep power down. // Bring every IO rail out of deep power down.
PMC(APBDEV_PMC_IO_DPD_REQ) = 0x40000000; PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
PMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000; PMC(APBDEV_PMC_IO_DPD2_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
// Config LCD and Backlight pins. // Configure LCD pins.
PINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN PINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
PINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE; // PULL_DOWN PINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE; // PULL_DOWN
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= ~PINMUX_TRISTATE; // PULL_DOWN | 1
PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
PINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE; // PULL_DOWN PINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE; // PULL_DOWN
// Set Backlight +-5V pins mode and direction // 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
// Set LCD +-5V pins mode and direction
gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO); 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); gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE);
// Enable Backlight power. // Enable LCD power.
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); // Backlight +5V enable. gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); // LCD +5V enable.
usleep(10000); usleep(10000);
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); // Backlight -5V enable. gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); // LCD -5V enable.
usleep(10000); usleep(10000);
// Configure Backlight pins (PWM, EN, RST). // 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_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); gpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE);
gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH); // Enable Backlight EN.
// Enable Backlight power.
gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH);
// Power up supply regulator for display interface. // Power up supply regulator for display interface.
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0; MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0;
if (!tegra_t210)
{
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG0)) = 0;
APB_MISC(APB_MISC_GP_DSI_PAD_CONTROL) = 0;
}
// Set DISP1 clock source and parent clock. // Set DISP1 clock source and parent clock.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 0x40000000; // PLLD_OUT. 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): 96 MHz. u32 plld_div = (3 << 20) | (20 << 11) | 1; // DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 96 MHz.
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div; 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_MISC1) = 0x20; // PLLD_SETUP.
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2D0AAA; // PLLD_ENABLE_CLK. 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.
}
// Setup Display Interface initial window configuration.
exec_cfg((u32 *)DISPLAY_A_BASE, _display_dc_setup_win_config, 94);
// Setup display communication interfaces. // Setup display communication interfaces.
exec_cfg((u32 *)DISPLAY_A_BASE, _display_dc_setup_win_config, 94); exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part1, 8);
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config, 61); 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);
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);
usleep(10000); usleep(10000);
// Enable Backlight Reset. // Enable LCD Reset.
gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH); gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH);
usleep(60000); usleep(60000);
// Setups DSI packet configuration and request display id. // Setup DSI device takeover timeout.
DSI(_DSIREG(DSI_BTA_TIMING)) = 0x50204; DSI(_DSIREG(DSI_BTA_TIMING)) = 0x50204;
#if 0
// Get Display ID.
_display_id = 0xCCCCCC;
display_dsi_read(MIPI_DCS_GET_DISPLAY_ID, 3, &_display_id, DSI_VIDEO_DISABLED);
#else
// Set reply size.
_display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, 3, 0); _display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, 3, 0);
_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO); _display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
// Request register read.
_display_dsi_send_cmd(MIPI_DSI_DCS_READ, MIPI_DCS_GET_DISPLAY_ID, 0); _display_dsi_send_cmd(MIPI_DSI_DCS_READ, MIPI_DCS_GET_DISPLAY_ID, 0);
_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO); _display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
// Transfer bus control to device for transmitting the reply.
DSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC; DSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;
_display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA); _display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);
// Wait a bit for the reply.
usleep(5000); usleep(5000);
// MIPI_DCS_GET_DISPLAY_ID reply is a long read, size 3 u32. // MIPI_DCS_GET_DISPLAY_ID reply is a long read, size 3 x u32.
for (u32 i = 0; i < 3; i++) for (u32 i = 0; i < 3; i++)
_display_id = DSI(_DSIREG(DSI_RD_DATA)); // Skip ack and msg type info and get the payload (display id). _display_id = DSI(_DSIREG(DSI_RD_DATA)) & 0xFFFFFF; // Skip ack and msg type info and get the payload (display id).
#endif
// Save raw Display ID to Nyx storage. // Save raw Display ID to Nyx storage.
nyx_str->info.disp_id = _display_id; nyx_str->info.disp_id = _display_id;
@ -154,47 +373,82 @@ void display_init()
exec_cfg((u32 *)DSI_BASE, _display_init_config_jdi, 43); exec_cfg((u32 *)DSI_BASE, _display_init_config_jdi, 43);
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000); _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
break; break;
case PANEL_INL_P062CCA_AZ1: case PANEL_INL_P062CCA_AZ1:
case PANEL_AUO_A062TAN01: case PANEL_AUO_A062TAN01:
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000); _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
// Unlock extension cmds.
DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes. DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // Enable extension cmd. (Pass: FF 83 94). DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST; DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
usleep(5000); usleep(5000);
// Set Power control.
DSI(_DSIREG(DSI_WR_DATA)) = 0x739; // MIPI_DSI_DCS_LONG_WRITE: 7 bytes. DSI(_DSIREG(DSI_WR_DATA)) = 0x739; // MIPI_DSI_DCS_LONG_WRITE: 7 bytes.
if (_display_id == PANEL_INL_P062CCA_AZ1) if (_display_id == PANEL_INL_P062CCA_AZ1)
DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // Set Power control. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40). DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40).
else else // PANEL_AUO_A062TAN01.
DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // Set Power control. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40). DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
DSI(_DSIREG(DSI_WR_DATA)) = 0x143209; // (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32). DSI(_DSIREG(DSI_WR_DATA)) = 0x143209; // (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32).
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST; DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
usleep(5000); usleep(5000);
break; break;
case PANEL_INL_P062CCA_AZ2:
case PANEL_AUO_A062TAN02: case PANEL_INL_2J055IA_27A:
case PANEL_AUO_A055TAN01:
case PANEL_V40_55_UNK:
default: // Allow spare part displays to work. default: // Allow spare part displays to work.
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 120000); _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 120000);
break; break;
} }
// Unblank display.
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_SET_DISPLAY_ON, 20000); _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_SET_DISPLAY_ON, 20000);
// Configure PLLD for DISP1. // Configure PLLD for DISP1.
plld_div = (1 << 20) | (24 << 11) | 1; // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 460.8 MHz. plld_div = (1 << 20) | (24 << 11) | 1; // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 230.4 MHz.
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div; CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0x20;
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. CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2DFC00; // Use new PLLD_SDM_DIN.
// Finalize DSI configuration. // Finalize DSI configuration.
exec_cfg((u32 *)DSI_BASE, _display_dsi_packet_config, 21); DSI(_DSIREG(DSI_PAD_CONTROL_1)) = 0;
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = 4; // PCD1 | div3. DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
exec_cfg((u32 *)DSI_BASE, _display_dsi_packet_config, 19);
// Set pixel clock dividers: 230.4 / 3 / 1 = 76.8 MHz. 60 Hz.
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); exec_cfg((u32 *)DSI_BASE, _display_dsi_mode_config, 10);
usleep(10000); usleep(10000);
// Calibrate display communication pads. // Calibrate display communication pads.
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_pad_cal_config, 6); u32 loops = tegra_t210 ? 1 : 2; // Find out why this is done 2 times on Mariko.
exec_cfg((u32 *)DSI_BASE, _display_dsi_pad_cal_config, 4); exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_pad_cal_config, 4);
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_apply_dsi_cal_config, 16); for (u32 i = 0; i < loops; i++)
{
// Set MIPI bias pad config.
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0x10010;
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG1)) = tegra_t210 ? 0x300 : 0;
// 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);
}
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);
}
// Set the rest of MIPI cal offsets and apply calibration.
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_apply_dsi_cal_config, 12);
}
usleep(10000); usleep(10000);
// Enable video display controller. // Enable video display controller.
@ -205,9 +459,9 @@ void display_backlight_pwm_init()
{ {
clock_enable_pwm(); clock_enable_pwm();
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN; // Enable PWM and set it to 25KHz PFM. PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN; // Enable PWM and set it to 25KHz PFM. 29.5KHz is stock.
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & 0xFFFFFFFC) | 1; // PWM clock source. 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. gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode.
} }
@ -245,15 +499,22 @@ void display_backlight_brightness(u32 brightness, u32 step_delay)
PWM(PWM_CONTROLLER_PWM_CSR_0) = 0; PWM(PWM_CONTROLLER_PWM_CSR_0) = 0;
} }
void display_end() static void _display_panel_and_hw_end(bool no_panel_deinit)
{ {
if (no_panel_deinit)
goto skip_panel_deinit;
display_backlight_brightness(0, 1000); display_backlight_brightness(0, 1000);
// Enable host cmd packets during video.
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE; DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE;
DSI(_DSIREG(DSI_WR_DATA)) = 0x2805; // MIPI_DCS_SET_DISPLAY_OFF
// Blank display.
DSI(_DSIREG(DSI_WR_DATA)) = (MIPI_DCS_SET_DISPLAY_OFF << 8) | MIPI_DSI_DCS_SHORT_WRITE;
// Propagate changes to all register buffers and disable host cmd packets during video.
DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX; DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX;
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0; // Disable host cmd packet. DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
// De-initialize video controller. // De-initialize video controller.
exec_cfg((u32 *)DISPLAY_A_BASE, _display_video_disp_controller_disable_config, 17); exec_cfg((u32 *)DISPLAY_A_BASE, _display_video_disp_controller_disable_config, 17);
@ -266,59 +527,82 @@ void display_end()
case PANEL_JDI_XXX062M: case PANEL_JDI_XXX062M:
exec_cfg((u32 *)DSI_BASE, _display_deinit_config_jdi, 22); exec_cfg((u32 *)DSI_BASE, _display_deinit_config_jdi, 22);
break; break;
case PANEL_AUO_A062TAN01: case PANEL_AUO_A062TAN01:
exec_cfg((u32 *)DSI_BASE, _display_deinit_config_auo, 37); exec_cfg((u32 *)DSI_BASE, _display_deinit_config_auo, 37);
break; break;
case PANEL_INL_P062CCA_AZ2:
case PANEL_AUO_A062TAN02: case PANEL_INL_2J055IA_27A:
case PANEL_AUO_A055TAN01:
case PANEL_V40_55_UNK:
// Unlock extension cmds.
DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes. DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // Enable extension cmd. (Pass: FF 83 94). DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST; DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
usleep(5000); usleep(5000);
// Set Power.
// Set Power control.
DSI(_DSIREG(DSI_WR_DATA)) = 0xB39; // MIPI_DSI_DCS_LONG_WRITE: 11 bytes. DSI(_DSIREG(DSI_WR_DATA)) = 0xB39; // MIPI_DSI_DCS_LONG_WRITE: 11 bytes.
if (_display_id == PANEL_INL_P062CCA_AZ2) if (_display_id == PANEL_INL_2J055IA_27A)
DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // Set Power control. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40). DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40).
else else if (_display_id == PANEL_AUO_A055TAN01)
DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // Set Power control. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40). DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
// Set Power control. (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32, Enter standby / PON / VCOMG). else // PANEL_V40_55_UNK.
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)
{
// (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32, Enter standby / PON / VCOMG).
DSI(_DSIREG(DSI_WR_DATA)) = 0x71143209; DSI(_DSIREG(DSI_WR_DATA)) = 0x71143209;
DSI(_DSIREG(DSI_WR_DATA)) = 0x114D31; // Set Power control. (Unknown). DSI(_DSIREG(DSI_WR_DATA)) = 0x114D31; // (Unknown).
}
else // PANEL_V40_55_UNK.
{
// (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;
DSI(_DSIREG(DSI_WR_DATA)) = 0x004C31; // (Unknown).
}
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST; DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
usleep(5000); usleep(5000);
break; break;
case PANEL_INL_P062CCA_AZ1: case PANEL_INL_P062CCA_AZ1:
default: default:
break; break;
} }
// Blank - powerdown.
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_ENTER_SLEEP_MODE, 50000); _display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_ENTER_SLEEP_MODE, 50000);
// Disable display and backlight pins. skip_panel_deinit:
gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); //Backlight Reset disable. // Disable LCD power pins.
gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); // LCD Reset disable.
usleep(10000); usleep(10000);
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); // LCD -5V disable.
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); //Backlight -5V disable.
usleep(10000); usleep(10000);
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); // LCD +5V disable.
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); //Backlight +5V disable.
usleep(10000); usleep(10000);
// Disable Display Interface specific clocks. // Disable Display Interface specific clocks.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x1010000; // Set reset clock DSI, MIPI_CAL. 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) = 0x1010000; // Clear enable clock DSI, MIPI_CAL. 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) = 0x18000000; // Set reset DISP1, HOST1X. CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = 0x18000000; // Clear enable DISP1, HOST1X. CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
// Power down pads. // 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; DSI(_DSIREG(DSI_POWER_CONTROL)) = 0;
// Switch to automatic function mode. // Switch LCD PWM backlight pin to special function mode and enable PWM0 mode.
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM. 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_TRISTATE) | PINMUX_TRISTATE;
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & 0xFFFFFFFC)| 1; PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode.
}
void display_end() { _display_panel_and_hw_end(false); };
u16 display_get_decoded_lcd_id()
{
return _display_id;
} }
void display_color_screen(u32 color) void display_color_screen(u32 color)
@ -378,7 +662,7 @@ u32 *display_init_framebuffer_log()
void display_activate_console() void display_activate_console()
{ {
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window C. 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_WIN_OPTIONS)) = WIN_ENABLE; // Enable window DD.
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0xFF80; DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0xFF80;
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE; DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
@ -399,7 +683,7 @@ void display_activate_console()
void display_deactivate_console() void display_deactivate_console()
{ {
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window C. DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window D.
for (u32 i = 0xFFFF; i > 0xFF7F; i--) for (u32 i = 0xFFFF; i > 0xFF7F; i--)
{ {

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer * Copyright (c) 2018-2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -21,6 +21,9 @@
#include <memory_map.h> #include <memory_map.h>
#include <utils/types.h> #include <utils/types.h>
#define DSI_VIDEO_DISABLED 0
#define DSI_VIDEO_ENABLED 1
/*! Display registers. */ /*! Display registers. */
#define _DIREG(reg) ((reg) * 4) #define _DIREG(reg) ((reg) * 4)
@ -42,11 +45,11 @@
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00 #define DC_CMD_GENERAL_INCR_SYNCPT 0x00
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01 #define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
#define SYNCPT_CNTRL_NO_STALL (1 << 8) #define SYNCPT_CNTRL_SOFT_RESET BIT(0)
#define SYNCPT_CNTRL_SOFT_RESET (1 << 0) #define SYNCPT_CNTRL_NO_STALL BIT(8)
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28 #define DC_CMD_CONT_SYNCPT_VSYNC 0x28
#define SYNCPT_VSYNC_ENABLE (1 << 8) #define SYNCPT_VSYNC_ENABLE BIT(8)
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031 #define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
@ -57,42 +60,43 @@
#define DISP_CTRL_MODE_MASK (3 << 5) #define DISP_CTRL_MODE_MASK (3 << 5)
#define DC_CMD_DISPLAY_POWER_CONTROL 0x36 #define DC_CMD_DISPLAY_POWER_CONTROL 0x36
#define PW0_ENABLE (1 << 0) #define PW0_ENABLE BIT(0)
#define PW1_ENABLE (1 << 2) #define PW1_ENABLE BIT(2)
#define PW2_ENABLE (1 << 4) #define PW2_ENABLE BIT(4)
#define PW3_ENABLE (1 << 6) #define PW3_ENABLE BIT(6)
#define PW4_ENABLE (1 << 8) #define PW4_ENABLE BIT(8)
#define PM0_ENABLE (1 << 16) #define PM0_ENABLE BIT(16)
#define PM1_ENABLE (1 << 18) #define PM1_ENABLE BIT(18)
#define DC_CMD_INT_STATUS 0x37 #define DC_CMD_INT_STATUS 0x37
#define DC_CMD_INT_MASK 0x38 #define DC_CMD_INT_MASK 0x38
#define DC_CMD_INT_ENABLE 0x39 #define DC_CMD_INT_ENABLE 0x39
#define DC_CMD_INT_FRAME_END_INT BIT(1)
#define DC_CMD_STATE_ACCESS 0x40 #define DC_CMD_STATE_ACCESS 0x40
#define READ_MUX (1 << 0) #define READ_MUX BIT(0)
#define WRITE_MUX (1 << 2) #define WRITE_MUX BIT(2)
#define DC_CMD_STATE_CONTROL 0x41 #define DC_CMD_STATE_CONTROL 0x41
#define GENERAL_ACT_REQ (1 << 0) #define GENERAL_ACT_REQ BIT(0)
#define WIN_A_ACT_REQ (1 << 1) #define WIN_A_ACT_REQ BIT(1)
#define WIN_B_ACT_REQ (1 << 2) #define WIN_B_ACT_REQ BIT(2)
#define WIN_C_ACT_REQ (1 << 3) #define WIN_C_ACT_REQ BIT(3)
#define WIN_D_ACT_REQ (1 << 4) #define WIN_D_ACT_REQ BIT(4)
#define CURSOR_ACT_REQ (1 << 7) #define CURSOR_ACT_REQ BIT(7)
#define GENERAL_UPDATE (1 << 8) #define GENERAL_UPDATE BIT(8)
#define WIN_A_UPDATE (1 << 9) #define WIN_A_UPDATE BIT(9)
#define WIN_B_UPDATE (1 << 10) #define WIN_B_UPDATE BIT(10)
#define WIN_C_UPDATE (1 << 11) #define WIN_C_UPDATE BIT(11)
#define WIN_D_UPDATE (1 << 12) #define WIN_D_UPDATE BIT(12)
#define CURSOR_UPDATE (1 << 15) #define CURSOR_UPDATE BIT(15)
#define NC_HOST_TRIG (1 << 24) #define NC_HOST_TRIG BIT(24)
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42 #define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
#define WINDOW_A_SELECT (1 << 4) #define WINDOW_A_SELECT BIT(4)
#define WINDOW_B_SELECT (1 << 5) #define WINDOW_B_SELECT BIT(5)
#define WINDOW_C_SELECT (1 << 6) #define WINDOW_C_SELECT BIT(6)
#define WINDOW_D_SELECT (1 << 7) #define WINDOW_D_SELECT BIT(7)
#define DC_CMD_REG_ACT_CONTROL 0x043 #define DC_CMD_REG_ACT_CONTROL 0x043
@ -125,12 +129,13 @@
// DC_DISP shadowed registers. // DC_DISP shadowed registers.
#define DC_DISP_DISP_WIN_OPTIONS 0x402 #define DC_DISP_DISP_WIN_OPTIONS 0x402
#define HDMI_ENABLE (1 << 30) #define CURSOR_ENABLE BIT(16)
#define DSI_ENABLE (1 << 29) #define SOR_ENABLE BIT(25)
#define SOR1_TIMING_CYA (1 << 27) #define SOR1_ENABLE BIT(26)
#define SOR1_ENABLE (1 << 26) #define SOR1_TIMING_CYA BIT(27)
#define SOR_ENABLE (1 << 25) #define DSI_ENABLE BIT(29)
#define CURSOR_ENABLE (1 << 16) #define HDMI_ENABLE BIT(30)
#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403 #define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404 #define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
@ -142,6 +147,7 @@
#define DC_DISP_FRONT_PORCH 0x40A #define DC_DISP_FRONT_PORCH 0x40A
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E #define DC_DISP_DISP_CLOCK_CONTROL 0x42E
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8) #define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8) #define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8) #define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
@ -155,7 +161,6 @@
#define PIXEL_CLK_DIVIDER_PCD18 (10 << 8) #define PIXEL_CLK_DIVIDER_PCD18 (10 << 8)
#define PIXEL_CLK_DIVIDER_PCD24 (11 << 8) #define PIXEL_CLK_DIVIDER_PCD24 (11 << 8)
#define PIXEL_CLK_DIVIDER_PCD13 (12 << 8) #define PIXEL_CLK_DIVIDER_PCD13 (12 << 8)
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
#define DC_DISP_DISP_INTERFACE_CONTROL 0x42F #define DC_DISP_DISP_INTERFACE_CONTROL 0x42F
#define DISP_DATA_FORMAT_DF1P1C (0 << 0) #define DISP_DATA_FORMAT_DF1P1C (0 << 0)
@ -189,8 +194,8 @@
#define BASE_COLOR_SIZE_888 (8 << 0) #define BASE_COLOR_SIZE_888 (8 << 0)
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431 #define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
#define SC1_H_QUALIFIER_NONE (1 << 16) #define SC0_H_QUALIFIER_NONE BIT(0)
#define SC0_H_QUALIFIER_NONE (1 << 0) #define SC1_H_QUALIFIER_NONE BIT(16)
#define DC_DISP_DATA_ENABLE_OPTIONS 0x432 #define DC_DISP_DATA_ENABLE_OPTIONS 0x432
#define DE_SELECT_ACTIVE_BLANK (0 << 0) #define DE_SELECT_ACTIVE_BLANK (0 << 0)
@ -217,6 +222,7 @@
#define CURSOR_SIZE_128 (2 << 24) #define CURSOR_SIZE_128 (2 << 24)
#define CURSOR_SIZE_256 (3 << 24) #define CURSOR_SIZE_256 (3 << 24)
#define DC_DISP_CURSOR_POSITION 0x440 #define DC_DISP_CURSOR_POSITION 0x440
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
#define DC_DISP_CURSOR_START_ADDR_HI 0x4EC #define DC_DISP_CURSOR_START_ADDR_HI 0x4EC
#define DC_DISP_BLEND_CURSOR_CONTROL 0x4F1 #define DC_DISP_BLEND_CURSOR_CONTROL 0x4F1
#define CURSOR_BLEND_2BIT (0 << 24) #define CURSOR_BLEND_2BIT (0 << 24)
@ -247,12 +253,12 @@
// The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER). // 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 DC_WIN_WIN_OPTIONS 0x700
#define H_DIRECTION (1 << 0) #define H_DIRECTION BIT(0)
#define V_DIRECTION (1 << 2) #define V_DIRECTION BIT(2)
#define SCAN_COLUMN (1 << 4) #define SCAN_COLUMN BIT(4)
#define COLOR_EXPAND (1 << 6) #define COLOR_EXPAND BIT(6)
#define CSC_ENABLE (1 << 18) #define CSC_ENABLE BIT(18)
#define WIN_ENABLE (1 << 30) #define WIN_ENABLE BIT(30)
#define DC_WIN_BUFFER_CONTROL 0x702 #define DC_WIN_BUFFER_CONTROL 0x702
#define BUFFER_CONTROL_HOST 0 #define BUFFER_CONTROL_HOST 0
@ -358,6 +364,10 @@
/*! Display serial interface registers. */ /*! Display serial interface registers. */
#define _DSIREG(reg) ((reg) * 4) #define _DSIREG(reg) ((reg) * 4)
#define DSI_INCR_SYNCPT_CNTRL 0x1
#define DSI_INCR_SYNCPT_SOFT_RESET BIT(0)
#define DSI_INCR_SYNCPT_NO_STALL BIT(8)
#define DSI_RD_DATA 0x9 #define DSI_RD_DATA 0x9
#define DSI_WR_DATA 0xA #define DSI_WR_DATA 0xA
@ -369,39 +379,42 @@
#define DSI_INT_MASK 0xE #define DSI_INT_MASK 0xE
#define DSI_HOST_CONTROL 0xF #define DSI_HOST_CONTROL 0xF
#define DSI_HOST_CONTROL_FIFO_RESET (1 << 21) #define DSI_HOST_CONTROL_ECC BIT(0)
#define DSI_HOST_CONTROL_CRC_RESET (1 << 20) #define DSI_HOST_CONTROL_CS BIT(1)
#define DSI_HOST_CONTROL_PKT_BTA BIT(2)
#define DSI_HOST_CONTROL_IMM_BTA BIT(3)
#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_SOL (0 << 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_FIFO (1 << 12)
#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12) #define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
#define DSI_HOST_CONTROL_RAW (1 << 6) #define DSI_HOST_CONTROL_CRC_RESET BIT(20)
#define DSI_HOST_CONTROL_HS (1 << 5) #define DSI_HOST_CONTROL_FIFO_RESET BIT(21)
#define DSI_HOST_CONTROL_FIFO_SEL (1 << 4)
#define DSI_HOST_CONTROL_IMM_BTA (1 << 3)
#define DSI_HOST_CONTROL_PKT_BTA (1 << 2)
#define DSI_HOST_CONTROL_CS (1 << 1)
#define DSI_HOST_CONTROL_ECC (1 << 0)
#define DSI_CONTROL 0x10 #define DSI_CONTROL 0x10
#define DSI_CONTROL_HS_CLK_CTRL (1 << 20) #define DSI_CONTROL_HOST_ENABLE BIT(0)
#define DSI_CONTROL_CHANNEL(c) (((c) & 0x3) << 16) #define DSI_CONTROL_VIDEO_ENABLE BIT(1)
#define DSI_CONTROL_FORMAT(f) (((f) & 0x3) << 12)
#define DSI_CONTROL_TX_TRIG(x) (((x) & 0x3) << 8)
#define DSI_CONTROL_LANES(n) (((n) & 0x3) << 4)
#define DSI_CONTROL_DCS_ENABLE (1 << 3)
#define DSI_CONTROL_SOURCE(s) (((s) & 0x1) << 2) #define DSI_CONTROL_SOURCE(s) (((s) & 0x1) << 2)
#define DSI_CONTROL_VIDEO_ENABLE (1 << 1) #define DSI_CONTROL_DCS_ENABLE BIT(3)
#define DSI_CONTROL_HOST_ENABLE (1 << 0) #define DSI_CONTROL_LANES(n) (((n) & 0x3) << 4)
#define DSI_CONTROL_TX_TRIG(x) (((x) & 0x3) << 8)
#define DSI_CONTROL_FORMAT(f) (((f) & 0x3) << 12)
#define DSI_CONTROL_CHANNEL(c) (((c) & 0x3) << 16)
#define DSI_CONTROL_HS_CLK_CTRL BIT(20)
#define DSI_SOL_DELAY 0x11 #define DSI_SOL_DELAY 0x11
#define DSI_MAX_THRESHOLD 0x12 #define DSI_MAX_THRESHOLD 0x12
#define DSI_TRIGGER 0x13 #define DSI_TRIGGER 0x13
#define DSI_TRIGGER_HOST (1 << 1) #define DSI_TRIGGER_VIDEO BIT(0)
#define DSI_TRIGGER_VIDEO (1 << 0) #define DSI_TRIGGER_HOST BIT(1)
#define DSI_TX_CRC 0x14 #define DSI_TX_CRC 0x14
#define DSI_STATUS 0x15 #define DSI_STATUS 0x15
#define DSI_STATUS_RX_FIFO_SIZE 0x1F
#define DSI_INIT_SEQ_CONTROL 0x1A #define DSI_INIT_SEQ_CONTROL 0x1A
#define DSI_INIT_SEQ_DATA_0 0x1B #define DSI_INIT_SEQ_DATA_0 0x1B
#define DSI_INIT_SEQ_DATA_1 0x1C #define DSI_INIT_SEQ_DATA_1 0x1C
@ -430,36 +443,53 @@
#define DSI_BTA_TIMING 0x3F #define DSI_BTA_TIMING 0x3F
#define DSI_TIMEOUT_0 0x44 #define DSI_TIMEOUT_0 0x44
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0) #define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
#define DSI_TIMEOUT_1 0x45 #define DSI_TIMEOUT_1 0x45
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0) #define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
#define DSI_TO_TALLY 0x46 #define DSI_TO_TALLY 0x46
#define DSI_PAD_CONTROL_0 0x4B #define DSI_PAD_CONTROL_0 0x4B
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK (1 << 24) #define DSI_PAD_CONTROL_VS1_PDIO_CLK BIT(8)
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
#define DSI_PAD_CONTROL_VS1_PDIO_CLK (1 << 8)
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0) #define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK BIT(24)
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
#define DSI_PAD_CONTROL_CD 0x4C #define DSI_PAD_CONTROL_CD 0x4C
#define DSI_VIDEO_MODE_CONTROL 0x4E #define DSI_VIDEO_MODE_CONTROL 0x4E
#define DSI_CMD_PKT_VID_ENABLE 1 #define DSI_CMD_PKT_VID_ENABLE 1
#define DSI_DSI_LINE_TYPE(x) ((x) << 1)
#define DSI_PAD_CONTROL_1 0x4F #define DSI_PAD_CONTROL_1 0x4F
#define DSI_PAD_CONTROL_2 0x50 #define DSI_PAD_CONTROL_2 0x50
#define DSI_PAD_CONTROL_3 0x51 #define DSI_PAD_CONTROL_3 0x51
#define DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)
#define DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)
#define DSI_PAD_PREEMP_PD(x) (((x) & 0x3) << 4)
#define DSI_PAD_PREEMP_PU(x) (((x) & 0x3) << 0) #define DSI_PAD_PREEMP_PU(x) (((x) & 0x3) << 0)
#define DSI_PAD_PREEMP_PD(x) (((x) & 0x3) << 4)
#define DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)
#define DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)
#define DSI_PAD_CONTROL_4 0x52 #define DSI_PAD_CONTROL_4 0x52
#define DSI_PAD_CONTROL_5_B01 0x53
#define DSI_PAD_CONTROL_6_B01 0x54
#define DSI_PAD_CONTROL_7_B01 0x55
#define DSI_INIT_SEQ_DATA_15 0x5F #define DSI_INIT_SEQ_DATA_15 0x5F
#define DSI_INIT_SEQ_DATA_15_B01 0x62
/*! DSI packet defines */
#define DSI_ESCAPE_CMD 0x87
#define DSI_ACK_NO_ERR 0x84
#define ACK_ERROR_RES 0x02
#define GEN_LONG_RD_RES 0x1A
#define DCS_LONG_RD_RES 0x1C
#define GEN_1_BYTE_SHORT_RD_RES 0x11
#define DCS_1_BYTE_SHORT_RD_RES 0x21
#define GEN_2_BYTE_SHORT_RD_RES 0x12
#define DCS_2_BYTE_SHORT_RD_RES 0x22
/*! MIPI registers. */ /*! MIPI registers. */
#define MIPI_CAL_MIPI_CAL_CTRL (0x00 / 0x4) #define MIPI_CAL_MIPI_CAL_CTRL (0x00 / 0x4)
@ -483,25 +513,168 @@
#define MIPI_CAL_DSID_MIPI_CAL_CONFIG_2 (0x74 / 0x4) #define MIPI_CAL_DSID_MIPI_CAL_CONFIG_2 (0x74 / 0x4)
/*! MIPI CMDs. */ /*! MIPI CMDs. */
#define MIPI_DSI_V_SYNC_START 0x01
#define MIPI_DSI_COLOR_MODE_OFF 0x02
#define MIPI_DSI_END_OF_TRANSMISSION 0x08
#define MIPI_DSI_NULL_PACKET 0x09
#define MIPI_DSI_V_SYNC_END 0x11
#define MIPI_DSI_COLOR_MODE_ON 0x12
#define MIPI_DSI_BLANKING_PACKET 0x19
#define MIPI_DSI_H_SYNC_START 0x21
#define MIPI_DSI_SHUTDOWN_PERIPHERAL 0x22
#define MIPI_DSI_H_SYNC_END 0x31
#define MIPI_DSI_TURN_ON_PERIPHERAL 0x32
#define MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE 0x37
#define MIPI_DSI_DCS_SHORT_WRITE 0x05 #define MIPI_DSI_DCS_SHORT_WRITE 0x05
#define MIPI_DSI_DCS_READ 0x06 #define MIPI_DSI_DCS_READ 0x06
#define MIPI_DSI_DCS_SHORT_WRITE_PARAM 0x15 #define MIPI_DSI_DCS_SHORT_WRITE_PARAM 0x15
#define MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE 0x37
#define MIPI_DSI_DCS_LONG_WRITE 0x39 #define MIPI_DSI_DCS_LONG_WRITE 0x39
#define MIPI_DSI_GENERIC_LONG_WRITE 0x29
#define MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM 0x03
#define MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM 0x13
#define MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM 0x23
#define MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM 0x04
#define MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM 0x14
#define MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM 0x24
/*! MIPI DCS CMDs. */ /*! MIPI DCS CMDs. */
#define MIPI_DCS_NOP 0x00
#define MIPI_DCS_SOFT_RESET 0x01
#define MIPI_DCS_GET_COMPRESSION_MODE 0x03
#define MIPI_DCS_GET_DISPLAY_ID 0x04 #define MIPI_DCS_GET_DISPLAY_ID 0x04
#define MIPI_DCS_GET_DISPLAY_ID1 0xDA // GET_DISPLAY_ID Byte0, Module Manufacturer ID.
#define MIPI_DCS_GET_DISPLAY_ID2 0xDB // GET_DISPLAY_ID Byte1, Module/Driver Version ID.
#define MIPI_DCS_GET_DISPLAY_ID3 0xDC // GET_DISPLAY_ID Byte2, Module/Driver ID.
#define MIPI_DCS_GET_NUM_ERRORS 0x05
#define MIPI_DCS_GET_RED_CHANNEL 0x06
#define MIPI_DCS_GET_GREEN_CHANNEL 0x07
#define MIPI_DCS_GET_BLUE_CHANNEL 0x08
#define MIPI_DCS_GET_DISPLAY_STATUS 0x09
#define MIPI_DCS_GET_POWER_MODE 0x0A
#define MIPI_DCS_GET_ADDRESS_MODE 0x0B
#define MIPI_DCS_GET_PIXEL_FORMAT 0x0C
#define MIPI_DCS_GET_DISPLAY_MODE 0x0D
#define MIPI_DCS_GET_SIGNAL_MODE 0x0E
#define MIPI_DCS_GET_DIAGNOSTIC_RESULT 0x0F
#define MIPI_DCS_ENTER_SLEEP_MODE 0x10 #define MIPI_DCS_ENTER_SLEEP_MODE 0x10
#define MIPI_DCS_EXIT_SLEEP_MODE 0x11 #define MIPI_DCS_EXIT_SLEEP_MODE 0x11
#define MIPI_DCS_ENTER_PARTIAL_MODE 0x12
#define MIPI_DCS_ENTER_NORMAL_MODE 0x13
#define MIPI_DCS_EXIT_INVERT_MODE 0x20
#define MIPI_DCS_ENTER_INVERT_MODE 0x21
#define MIPI_DCS_ALL_PIXELS_OFF 0x22
#define MIPI_DCS_ALL_PIXELS_ON 0x23
#define MIPI_DCS_SET_CONTRAST 0x25 // VCON in 40mV steps. 7-bit integer.
#define MIPI_DCS_SET_GAMMA_CURVE 0x26
#define MIPI_DCS_SET_DISPLAY_OFF 0x28
#define MIPI_DCS_SET_DISPLAY_ON 0x29 #define MIPI_DCS_SET_DISPLAY_ON 0x29
#define MIPI_DCS_SET_COLUMN_ADDRESS 0x2A
#define MIPI_DCS_SET_PAGE_ADDRESS 0x2B
#define MIPI_DCS_WRITE_MEMORY_START 0x2C
#define MIPI_DCS_WRITE_LUT 0x2D // 24-bit: 192 bytes.
#define MIPI_DCS_READ_MEMORY_START 0x2E
#define MIPI_DCS_SET_PARTIAL_ROWS 0x30
#define MIPI_DCS_SET_PARTIAL_COLUMNS 0x31
#define MIPI_DCS_SET_SCROLL_AREA 0x33
#define MIPI_DCS_SET_TEAR_OFF 0x34
#define MIPI_DCS_SET_TEAR_ON 0x35
#define MIPI_DCS_SET_ADDRESS_MODE 0x36
#define MIPI_DCS_SET_SCROLL_START 0x37
#define MIPI_DCS_EXIT_IDLE_MODE 0x38
#define MIPI_DCS_ENTER_IDLE_MODE 0x39
#define MIPI_DCS_SET_PIXEL_FORMAT 0x3A
#define MIPI_DCS_WRITE_MEMORY_CONTINUE 0x3C
#define MIPI_DCS_READ_MEMORY_CONTINUE 0x3E
#define MIPI_DCS_GET_3D_CONTROL 0x3F
#define MIPI_DCS_SET_VSYNC_TIMING 0x40
#define MIPI_DCS_SET_TEAR_SCANLINE 0x44
#define MIPI_DCS_GET_SCANLINE 0x45
#define MIPI_DCS_SET_TEAR_SCANLINE_WIDTH 0x46
#define MIPI_DCS_GET_SCANLINE_WIDTH 0x47
#define MIPI_DCS_SET_BRIGHTNESS 0x51 // DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL.
#define MIPI_DCS_GET_BRIGHTNESS 0x52
#define MIPI_DCS_SET_CONTROL_DISPLAY 0x53
#define MIPI_DCS_GET_CONTROL_DISPLAY 0x54
#define MIPI_DCS_SET_CABC_VALUE 0x55
#define MIPI_DCS_GET_CABC_VALUE 0x56
#define MIPI_DCS_SET_CABC_MIN_BRI 0x5E
#define MIPI_DCS_GET_CABC_MIN_BRI 0x5F
#define MIPI_DCS_READ_DDB_START 0xA1
#define MIPI_DCS_READ_DDB_CONTINUE 0xA8
/*! MIPI DCS Panel Private CMDs. */
#define MIPI_DCS_PRIV_UNK_A0 0xA0
#define MIPI_DCS_PRIV_SET_POWER_CONTROL 0xB1
#define MIPI_DCS_PRIV_SET_EXTC 0xB9
#define MIPI_DCS_PRIV_UNK_BD 0xBD
#define MIPI_DCS_PRIV_UNK_D5 0xD5
#define MIPI_DCS_PRIV_UNK_D6 0xD6
#define MIPI_DCS_PRIV_UNK_D8 0xD8
#define MIPI_DCS_PRIV_UNK_D9 0xD9
/*! MIPI DCS CMD Defines. */
#define DCS_POWER_MODE_DISPLAY_ON BIT(2)
#define DCS_POWER_MODE_NORMAL_MODE BIT(3)
#define DCS_POWER_MODE_SLEEP_MODE BIT(4)
#define DCS_POWER_MODE_PARTIAL_MODE BIT(5)
#define DCS_POWER_MODE_IDLE_MODE BIT(6)
#define DCS_ADDRESS_MODE_V_FLIP BIT(0)
#define DCS_ADDRESS_MODE_H_FLIP BIT(1)
#define DCS_ADDRESS_MODE_LATCH_RL BIT(2) // Latch Data Order.
#define DCS_ADDRESS_MODE_BGR_COLOR BIT(3)
#define DCS_ADDRESS_MODE_LINE_ORDER BIT(4) // Line Refresh Order.
#define DCS_ADDRESS_MODE_SWAP_XY BIT(5) // Page/Column Addressing Reverse Order.
#define DCS_ADDRESS_MODE_MIRROR_X BIT(6) // Column Address Order.
#define DCS_ADDRESS_MODE_MIRROR_Y BIT(7) // Page Address Order.
#define DCS_ADDRESS_MODE_ROTATION_MASK (0xF << 4)
#define DCS_ADDRESS_MODE_ROTATION_90 (DCS_ADDRESS_MODE_SWAP_XY | DCS_ADDRESS_MODE_LINE_ORDER)
#define DCS_ADDRESS_MODE_ROTATION_180 (DCS_ADDRESS_MODE_MIRROR_X | DCS_ADDRESS_MODE_LINE_ORDER)
#define DCS_ADDRESS_MODE_ROTATION_270 (DCS_ADDRESS_MODE_SWAP_XY)
#define DCS_GAMMA_CURVE_NONE 0
#define DCS_GAMMA_CURVE_GC0_1_8 BIT(0)
#define DCS_GAMMA_CURVE_GC1_2_5 BIT(1)
#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_BACKLIGHT_CTRL BIT(2)
#define DCS_CONTROL_DISPLAY_DIMMING_CTRL BIT(3)
#define DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL BIT(5)
/* Switch Panels: /* Switch Panels:
*
* 6.2" panels for Icosa and Iowa skus:
* [10] 81 [26]: JDI LPM062M326A * [10] 81 [26]: JDI LPM062M326A
* [10] 96 [09]: JDI LAM062M109A * [10] 96 [09]: JDI LAM062M109A
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1) * [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
* [20] XX [10]: InnoLux P062CCA-AZ2 [UNCONFIRMED ID] * [20] 95 [0F]: InnoLux P062CCA-AZ2
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001) * [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
* [30] XX [10]: AUO A062TAN02 (59.06A33.002) [UNCONFIRMED ID] * [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
*
* 5.5" panels for Hoag skus:
* [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1)
* [30] XX [10]: AUO A055TAN01 (59.05A30.001) [UNCONFIRMED ID]
* [40] XX [10]: Vendor 40 [UNCONFIRMED ID]
*/
/* Display ID Decoding:
*
* byte0: Vendor
* byte1: Model
* byte2: Board
*
* Vendors:
* 10h: Japan Display Inc.
* 20h: InnoLux Corporation
* 30h: AU Optronics
* 40h: Unknown1
*
* Boards, Panel Size:
* 0Fh: Icosa/Iowa, 6.2"
* 10h: Hoag, 5.5"
*/ */
enum enum
@ -511,14 +684,18 @@ enum
PANEL_JDI_LPM062M326A = 0x2610, PANEL_JDI_LPM062M326A = 0x2610,
PANEL_INL_P062CCA_AZ1 = 0x0F20, PANEL_INL_P062CCA_AZ1 = 0x0F20,
PANEL_AUO_A062TAN01 = 0x0F30, PANEL_AUO_A062TAN01 = 0x0F30,
PANEL_INL_P062CCA_AZ2 = 0x1020, PANEL_INL_2J055IA_27A = 0x1020,
PANEL_AUO_A062TAN02 = 0x1030 PANEL_AUO_A055TAN01 = 0x1030,
PANEL_V40_55_UNK = 0x1040
}; };
void display_init(); void display_init();
void display_backlight_pwm_init(); void display_backlight_pwm_init();
void display_end(); void display_end();
/*! Get Display panel ID. */
u16 display_get_decoded_lcd_id();
/*! Show one single color on the display. */ /*! Show one single color on the display. */
void display_color_screen(u32 color); void display_color_screen(u32 color);
@ -537,4 +714,7 @@ void display_init_cursor(void *crs_fb, u32 size);
void display_set_pos_cursor(u32 x, u32 y); void display_set_pos_cursor(u32 x, u32 y);
void display_deinit_cursor(); 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);
#endif #endif

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer * Copyright (c) 2018-2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -20,7 +20,7 @@ static const cfg_op_t _display_dc_setup_win_config[94] = {
{DC_CMD_STATE_ACCESS, 0}, {DC_CMD_STATE_ACCESS, 0},
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_REG_ACT_CONTROL, 0x54}, {DC_CMD_REG_ACT_CONTROL, 0x54}, // Select H counter for win A/B/C.
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
@ -96,16 +96,16 @@ static const cfg_op_t _display_dc_setup_win_config[94] = {
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C}, {DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000}, {DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
{DC_COM_PIN_OUTPUT_POLARITY(3), 0}, {DC_COM_PIN_OUTPUT_POLARITY(3), 0},
{0x4E4, 0}, {DC_DISP_BLEND_BACKGROUND_COLOR, 0},
{DC_COM_CRC_CONTROL, 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_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_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_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{0x716, 0x10000FF}, {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{0x716, 0x10000FF}, {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{0x716, 0x10000FF}, {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0}, {DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0}, {DC_WIN_WIN_OPTIONS, 0},
@ -120,7 +120,7 @@ static const cfg_op_t _display_dc_setup_win_config[94] = {
}; };
//DSI Init config. //DSI Init config.
static const cfg_op_t _display_dsi_init_config[61] = { static const cfg_op_t _display_dsi_init_config_part1[8] = {
{DSI_WR_DATA, 0}, {DSI_WR_DATA, 0},
{DSI_INT_ENABLE, 0}, {DSI_INT_ENABLE, 0},
{DSI_INT_STATUS, 0}, {DSI_INT_STATUS, 0},
@ -128,8 +128,9 @@ static const cfg_op_t _display_dsi_init_config[61] = {
{DSI_INIT_SEQ_DATA_0, 0}, {DSI_INIT_SEQ_DATA_0, 0},
{DSI_INIT_SEQ_DATA_1, 0}, {DSI_INIT_SEQ_DATA_1, 0},
{DSI_INIT_SEQ_DATA_2, 0}, {DSI_INIT_SEQ_DATA_2, 0},
{DSI_INIT_SEQ_DATA_3, 0}, {DSI_INIT_SEQ_DATA_3, 0}
{DSI_INIT_SEQ_DATA_15, 0}, };
static const cfg_op_t _display_dsi_init_config_part2[14] = {
{DSI_DCS_CMDS, 0}, {DSI_DCS_CMDS, 0},
{DSI_PKT_SEQ_0_LO, 0}, {DSI_PKT_SEQ_0_LO, 0},
{DSI_PKT_SEQ_1_LO, 0}, {DSI_PKT_SEQ_1_LO, 0},
@ -143,7 +144,18 @@ static const cfg_op_t _display_dsi_init_config[61] = {
{DSI_PKT_SEQ_3_HI, 0}, {DSI_PKT_SEQ_3_HI, 0},
{DSI_PKT_SEQ_4_HI, 0}, {DSI_PKT_SEQ_4_HI, 0},
{DSI_PKT_SEQ_5_HI, 0}, {DSI_PKT_SEQ_5_HI, 0},
{DSI_CONTROL, 0}, {DSI_CONTROL, 0}
};
static const cfg_op_t _display_dsi_init_config_part3_t210b01[7] = {
{DSI_PAD_CONTROL_1, 0},
{DSI_PAD_CONTROL_2, 0},
{DSI_PAD_CONTROL_3, 0},
{DSI_PAD_CONTROL_4, 0},
{DSI_PAD_CONTROL_5_B01, 0},
{DSI_PAD_CONTROL_6_B01, 0},
{DSI_PAD_CONTROL_7_B01, 0}
};
static const cfg_op_t _display_dsi_init_config_part4[10] = {
{DSI_PAD_CONTROL_CD, 0}, {DSI_PAD_CONTROL_CD, 0},
{DSI_SOL_DELAY, 0x18}, {DSI_SOL_DELAY, 0x18},
{DSI_MAX_THRESHOLD, 0x1E0}, {DSI_MAX_THRESHOLD, 0x1E0},
@ -153,8 +165,9 @@ static const cfg_op_t _display_dsi_init_config[61] = {
{DSI_PKT_LEN_2_3, 0}, {DSI_PKT_LEN_2_3, 0},
{DSI_PKT_LEN_4_5, 0}, {DSI_PKT_LEN_4_5, 0},
{DSI_PKT_LEN_6_7, 0}, {DSI_PKT_LEN_6_7, 0},
{DSI_PAD_CONTROL_1, 0}, {DSI_PAD_CONTROL_1, 0}
{DSI_PHY_TIMING_0, 0x6070601}, };
static const cfg_op_t _display_dsi_init_config_part5[12] = {
{DSI_PHY_TIMING_1, 0x40A0E05}, {DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30109}, {DSI_PHY_TIMING_2, 0x30109},
{DSI_BTA_TIMING, 0x190A14}, {DSI_BTA_TIMING, 0x190A14},
@ -166,8 +179,9 @@ static const cfg_op_t _display_dsi_init_config[61] = {
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE}, {DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
{DSI_POWER_CONTROL, 0}, {DSI_POWER_CONTROL, 0},
{DSI_POWER_CONTROL, 0}, {DSI_POWER_CONTROL, 0},
{DSI_PAD_CONTROL_1, 0}, {DSI_PAD_CONTROL_1, 0}
{DSI_PHY_TIMING_0, 0x6070601}, };
static const cfg_op_t _display_dsi_init_config_part6[14] = {
{DSI_PHY_TIMING_1, 0x40A0E05}, {DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30118}, {DSI_PHY_TIMING_2, 0x30118},
{DSI_BTA_TIMING, 0x190A14}, {DSI_BTA_TIMING, 0x190A14},
@ -187,12 +201,12 @@ static const cfg_op_t _display_dsi_init_config[61] = {
//DSI panel config. //DSI panel config.
static const cfg_op_t _display_init_config_jdi[43] = { static const cfg_op_t _display_init_config_jdi[43] = {
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes. {DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
{DSI_WR_DATA, 0x9483FFB9}, // Enable extension cmd. (Pass: FF 83 94). {DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x00BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0x0BD. {DSI_WR_DATA, 0x00BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0 to 0xBD.
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x1939}, // MIPI_DSI_DCS_LONG_WRITE: 25 bytes. {DSI_WR_DATA, 0x1939}, // MIPI_DSI_DCS_LONG_WRITE: 25 bytes.
{DSI_WR_DATA, 0xAAAAAAD8}, {DSI_WR_DATA, 0xAAAAAAD8}, // Register: 0xD8.
{DSI_WR_DATA, 0xAAAAAAEB}, {DSI_WR_DATA, 0xAAAAAAEB},
{DSI_WR_DATA, 0xAAEBAAAA}, {DSI_WR_DATA, 0xAAEBAAAA},
{DSI_WR_DATA, 0xAAAAAAAA}, {DSI_WR_DATA, 0xAAAAAAAA},
@ -200,10 +214,10 @@ static const cfg_op_t _display_init_config_jdi[43] = {
{DSI_WR_DATA, 0xAAEBAAAA}, {DSI_WR_DATA, 0xAAEBAAAA},
{DSI_WR_DATA, 0xAA}, {DSI_WR_DATA, 0xAA},
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x01BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0x1BD. {DSI_WR_DATA, 0x01BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 1 to 0xBD.
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x2739}, // MIPI_DSI_DCS_LONG_WRITE: 39 bytes. {DSI_WR_DATA, 0x2739}, // MIPI_DSI_DCS_LONG_WRITE: 39 bytes.
{DSI_WR_DATA, 0xFFFFFFD8}, {DSI_WR_DATA, 0xFFFFFFD8}, // Register: 0xD8.
{DSI_WR_DATA, 0xFFFFFFFF}, {DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF}, {DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF}, {DSI_WR_DATA, 0xFFFFFFFF},
@ -214,27 +228,25 @@ static const cfg_op_t _display_init_config_jdi[43] = {
{DSI_WR_DATA, 0xFFFFFFFF}, {DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFF}, {DSI_WR_DATA, 0xFFFFFF},
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x02BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0x2BD. {DSI_WR_DATA, 0x02BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 2 to 0xBD.
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0xF39}, // MIPI_DSI_DCS_LONG_WRITE: 15 bytes. {DSI_WR_DATA, 0xF39}, // MIPI_DSI_DCS_LONG_WRITE: 15 bytes.
{DSI_WR_DATA, 0xFFFFFFD8}, {DSI_WR_DATA, 0xFFFFFFD8}, // Register: 0xD8.
{DSI_WR_DATA, 0xFFFFFFFF}, {DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFFFF}, {DSI_WR_DATA, 0xFFFFFFFF},
{DSI_WR_DATA, 0xFFFFFF}, {DSI_WR_DATA, 0xFFFFFF},
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x00BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0x0BD. {DSI_WR_DATA, 0x00BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0 to 0xBD.
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x06D915}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0x6D9. {DSI_WR_DATA, 0x06D915}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 6 to 0xD9.
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes. {DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
{DSI_WR_DATA, 0x000000B9}, // Disable extension cmd. {DSI_WR_DATA, 0x000000B9}, // MIPI_DCS_PRIV_SET_EXTC. Disable.
{DSI_TRIGGER, DSI_TRIGGER_HOST} {DSI_TRIGGER, DSI_TRIGGER_HOST}
}; };
//DSI packet config. //DSI packet config.
static const cfg_op_t _display_dsi_packet_config[21] = { static const cfg_op_t _display_dsi_packet_config[19] = {
{DSI_PAD_CONTROL_1, 0},
{DSI_PHY_TIMING_0, 0x6070601},
{DSI_PHY_TIMING_1, 0x40A0E05}, {DSI_PHY_TIMING_1, 0x40A0E05},
{DSI_PHY_TIMING_2, 0x30172}, {DSI_PHY_TIMING_2, 0x30172},
{DSI_BTA_TIMING, 0x190A14}, {DSI_BTA_TIMING, 0x190A14},
@ -253,7 +265,7 @@ static const cfg_op_t _display_dsi_packet_config[21] = {
{DSI_PKT_LEN_2_3, 0x87001A2}, {DSI_PKT_LEN_2_3, 0x87001A2},
{DSI_PKT_LEN_4_5, 0x190}, {DSI_PKT_LEN_4_5, 0x190},
{DSI_PKT_LEN_6_7, 0x190}, {DSI_PKT_LEN_6_7, 0x190},
{DSI_HOST_CONTROL, 0}, {DSI_HOST_CONTROL, 0}
}; };
//DSI mode config. //DSI mode config.
@ -271,29 +283,44 @@ static const cfg_op_t _display_dsi_mode_config[10] = {
}; };
//MIPI CAL config. //MIPI CAL config.
static const cfg_op_t _display_mipi_pad_cal_config[6] = { static const cfg_op_t _display_mipi_pad_cal_config[4] = {
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0}, {MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0},
{MIPI_CAL_CIL_MIPI_CAL_STATUS, 0xF3F10000}, {MIPI_CAL_CIL_MIPI_CAL_STATUS, 0xF3F10000},
{MIPI_CAL_MIPI_BIAS_PAD_CFG0, 0}, {MIPI_CAL_MIPI_BIAS_PAD_CFG0, 0},
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0}, {MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0}
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0x10010},
{MIPI_CAL_MIPI_BIAS_PAD_CFG1, 0x300}
}; };
//DSI config. //DSI config.
static const cfg_op_t _display_dsi_pad_cal_config[4] = { static const cfg_op_t _display_dsi_pad_cal_config_t210[4] = {
{DSI_PAD_CONTROL_1, 0}, {DSI_PAD_CONTROL_1, 0},
{DSI_PAD_CONTROL_2, 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_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} {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},
{DSI_PAD_CONTROL_5_B01, 0x77777},
{DSI_PAD_CONTROL_6_B01, 0x1111},
{DSI_PAD_CONTROL_7_B01, 0}
};
//MIPI CAL config. //MIPI CAL config.
static const cfg_op_t _display_mipi_apply_dsi_cal_config[16] = { static const cfg_op_t _display_mipi_dsi_cal_offsets_config_t210[4] = {
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200200}, {MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200200},
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200200}, {MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200200},
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x200002}, {MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x200002},
{MIPI_CAL_DSIB_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] = {
{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] = {
{MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0}, {MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0},
{MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0}, {MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0},
{MIPI_CAL_CILC_MIPI_CAL_CONFIG, 0}, {MIPI_CAL_CILC_MIPI_CAL_CONFIG, 0},
@ -372,16 +399,16 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C}, {DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000}, {DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
{DC_COM_PIN_OUTPUT_POLARITY(3), 0}, {DC_COM_PIN_OUTPUT_POLARITY(3), 0},
{0x4E4, 0}, {DC_DISP_BLEND_BACKGROUND_COLOR, 0},
{DC_COM_CRC_CONTROL, 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_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_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_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{0x716, 0x10000FF}, {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
{0x716, 0x10000FF}, {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{0x716, 0x10000FF}, {DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0}, {DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0}, {DC_WIN_WIN_OPTIONS, 0},
@ -394,14 +421,37 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE}, {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_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
{DC_CMD_STATE_ACCESS, 0}, {DC_CMD_STATE_ACCESS, 0},
/* Set Display timings */
/* 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_DISP_TIMING_OPTIONS, 0},
{DC_DISP_REF_TO_SYNC, (1 << 16)}, // h_ref_to_sync = 0, v_ref_to_sync = 1. {DC_DISP_REF_TO_SYNC, 0x10000},
{DC_DISP_SYNC_WIDTH, 0x10048}, {DC_DISP_SYNC_WIDTH, 0x10048},
{DC_DISP_BACK_PORCH, 0x90048}, {DC_DISP_BACK_PORCH, 0x90048},
{DC_DISP_ACTIVE, 0x50002D0}, {DC_DISP_ACTIVE, 0x50002D0},
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd. {DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should happen before DC_DISP_ACTIVE cmd.
/* End of Display timings */ /* End of Display timings */
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE}, {DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
{DC_COM_PIN_OUTPUT_ENABLE(1), 0}, {DC_COM_PIN_OUTPUT_ENABLE(1), 0},
{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL}, {DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
@ -477,10 +527,10 @@ static const cfg_op_t _display_dsi_timing_deinit_config[16] = {
//DSI config (if ver == 0x10). //DSI config (if ver == 0x10).
static const cfg_op_t _display_deinit_config_jdi[22] = { static const cfg_op_t _display_deinit_config_jdi[22] = {
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes. {DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
{DSI_WR_DATA, 0x9483FFB9}, // Enable extension cmd. (Pass: FF 83 94). {DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x2139}, // MIPI_DSI_DCS_LONG_WRITE: 33 bytes. {DSI_WR_DATA, 0x2139}, // MIPI_DSI_DCS_LONG_WRITE: 33 bytes.
{DSI_WR_DATA, 0x191919D5}, {DSI_WR_DATA, 0x191919D5}, // Register: 0xD5.
{DSI_WR_DATA, 0x19191919}, {DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919}, {DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919}, {DSI_WR_DATA, 0x19191919},
@ -491,21 +541,21 @@ static const cfg_op_t _display_deinit_config_jdi[22] = {
{DSI_WR_DATA, 0x19}, {DSI_WR_DATA, 0x19},
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0xB39}, // MIPI_DSI_DCS_LONG_WRITE: 11 bytes. {DSI_WR_DATA, 0xB39}, // MIPI_DSI_DCS_LONG_WRITE: 11 bytes.
{DSI_WR_DATA, 0x4F0F41B1}, // Set Power control. {DSI_WR_DATA, 0x4F0F41B1}, // MIPI_DCS_PRIV_SET_POWER_CONTROL.
{DSI_WR_DATA, 0xF179A433}, {DSI_WR_DATA, 0xF179A433},
{DSI_WR_DATA, 0x002D81}, {DSI_WR_DATA, 0x002D81},
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes. {DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
{DSI_WR_DATA, 0x000000B9}, // Disable extension cmd. {DSI_WR_DATA, 0x000000B9}, // MIPI_DCS_PRIV_SET_EXTC. Disable.
{DSI_TRIGGER, DSI_TRIGGER_HOST} {DSI_TRIGGER, DSI_TRIGGER_HOST}
}; };
static const cfg_op_t _display_deinit_config_auo[37] = { static const cfg_op_t _display_deinit_config_auo[37] = {
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes. {DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
{DSI_WR_DATA, 0x9483FFB9}, // Enable extension cmd. (Pass: FF 83 94). {DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x2C39}, // MIPI_DSI_DCS_LONG_WRITE: 44 bytes. {DSI_WR_DATA, 0x2C39}, // MIPI_DSI_DCS_LONG_WRITE: 44 bytes.
{DSI_WR_DATA, 0x191919D5}, {DSI_WR_DATA, 0x191919D5}, // Register: 0xD5.
{DSI_WR_DATA, 0x19191919}, {DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919}, {DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919}, {DSI_WR_DATA, 0x19191919},
@ -518,7 +568,7 @@ static const cfg_op_t _display_deinit_config_auo[37] = {
{DSI_WR_DATA, 0x19191919}, {DSI_WR_DATA, 0x19191919},
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x2C39}, // MIPI_DSI_DCS_LONG_WRITE: 44 bytes. {DSI_WR_DATA, 0x2C39}, // MIPI_DSI_DCS_LONG_WRITE: 44 bytes.
{DSI_WR_DATA, 0x191919D6}, {DSI_WR_DATA, 0x191919D6}, // Register: 0xD6.
{DSI_WR_DATA, 0x19191919}, {DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919}, {DSI_WR_DATA, 0x19191919},
{DSI_WR_DATA, 0x19191919}, {DSI_WR_DATA, 0x19191919},
@ -531,13 +581,13 @@ static const cfg_op_t _display_deinit_config_auo[37] = {
{DSI_WR_DATA, 0x19191919}, {DSI_WR_DATA, 0x19191919},
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0xB39}, // MIPI_DSI_DCS_LONG_WRITE: 11 bytes. {DSI_WR_DATA, 0xB39}, // MIPI_DSI_DCS_LONG_WRITE: 11 bytes.
{DSI_WR_DATA, 0x711148B1}, // Set Power control. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40). {DSI_WR_DATA, 0x711148B1}, // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
// Set Power control. (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32, Enter standby / PON / VCOMG). // (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32, Enter standby / PON / VCOMG).
{DSI_WR_DATA, 0x71143209}, {DSI_WR_DATA, 0x71143209},
{DSI_WR_DATA, 0x114D31}, // Set Power control. (Unknown). {DSI_WR_DATA, 0x114D31}, // (Unknown).
{DSI_TRIGGER, DSI_TRIGGER_HOST}, {DSI_TRIGGER, DSI_TRIGGER_HOST},
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes. {DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
{DSI_WR_DATA, 0x000000B9}, // Disable extension cmd. {DSI_WR_DATA, 0x000000B9}, // MIPI_DCS_PRIV_SET_EXTC. Disable.
{DSI_TRIGGER, DSI_TRIGGER_HOST} {DSI_TRIGGER, DSI_TRIGGER_HOST}
}; };

View File

@ -103,7 +103,8 @@ u8 als_init(als_table_t *als_val)
i2c_init(I2C_2); i2c_init(I2C_2);
max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL); max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2, 0xD8 | MAX77620_LDO_CFG2_ADE_MASK); i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
(MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT | (3 << 3) | MAX77620_LDO_CFG2_ADE_ENABLE));
u8 id = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(0x12)); u8 id = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(0x12));
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_SPEC(BH1730_SPECCMD_RESET), 0); i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_SPEC(BH1730_SPECCMD_RESET), 0);

View File

@ -45,8 +45,8 @@
#define BH1730_DATA1LOW_REG 0x16 #define BH1730_DATA1LOW_REG 0x16
#define BH1730_DATA1HIGH_REG 0x17 #define BH1730_DATA1HIGH_REG 0x17
#define BH1730_ADDR(reg) (BH1730_CMD_MAGIC | BH1730_CMD_SETADDR | reg) #define BH1730_ADDR(reg) (BH1730_CMD_MAGIC | BH1730_CMD_SETADDR | (reg))
#define BH1730_SPEC(cmd) (BH1730_CMD_MAGIC | BH1730_CMD_SPECCMD | cmd) #define BH1730_SPEC(cmd) (BH1730_CMD_MAGIC | BH1730_CMD_SPECCMD | (cmd))
typedef struct _als_table_t typedef struct _als_table_t
{ {

View File

@ -24,6 +24,7 @@
#include <power/regulator_5v.h> #include <power/regulator_5v.h>
#include <soc/bpmp.h> #include <soc/bpmp.h>
#include <soc/clock.h> #include <soc/clock.h>
#include <soc/fuse.h>
#include <soc/gpio.h> #include <soc/gpio.h>
#include <soc/pinmux.h> #include <soc/pinmux.h>
#include <soc/uart.h> #include <soc/uart.h>
@ -58,7 +59,7 @@
#define JC_HID_SUBCMD_SND_RUMBLE 0xFF #define JC_HID_SUBCMD_SND_RUMBLE 0xFF
#define JC_BTN_MASK_L 0xFF2900 // 0xFFE900: with charge status. #define JC_BTN_MASK_L 0xFF2900 // 0xFFE900: with charge status.
#define JC_BTN_MASK_R 0x76FF #define JC_BTN_MASK_R 0x0056FF
#define JC_ID_L 1 #define JC_ID_L 1
#define JC_ID_R 2 #define JC_ID_R 2
@ -206,7 +207,7 @@ static u16 jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data, u
out->uart_hdr.magic[1] = 0x01; out->uart_hdr.magic[1] = 0x01;
out->uart_hdr.magic[2] = 0x3; out->uart_hdr.magic[2] = 0x3;
out->uart_hdr.total_size_lsb = 7; out->uart_hdr.total_size_lsb = sizeof(jc_wired_hdr_t) - sizeof(jc_uart_hdr_t);
out->uart_hdr.total_size_msb = 0; out->uart_hdr.total_size_msb = 0;
out->cmd = wired_cmd; out->cmd = wired_cmd;
@ -523,6 +524,9 @@ jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos)
u8 retries; u8 retries;
jc_bt_conn_t *bt_conn; jc_bt_conn_t *bt_conn;
if (!jc_init_done)
return NULL;
bt_conn = &jc_gamepad.bt_conn_l; bt_conn = &jc_gamepad.bt_conn_l;
memset(bt_conn->host_mac, 0, 6); memset(bt_conn->host_mac, 0, 6);
memset(bt_conn->ltk, 0, 16); memset(bt_conn->ltk, 0, 16);
@ -812,7 +816,10 @@ void jc_init_hw()
jc_l.uart = UART_C; jc_l.uart = UART_C;
jc_r.uart = UART_B; jc_r.uart = UART_B;
#if (LV_LOG_PRINTF != 1) if (fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG)
return;
#ifndef DEBUG_UART_PORT
jc_power_supply(UART_C, true); jc_power_supply(UART_C, true);
jc_power_supply(UART_B, true); jc_power_supply(UART_B, true);

View File

@ -361,7 +361,7 @@ int touch_power_on()
// Enables LDO6 for touchscreen VDD/AVDD supply // Enables LDO6 for touchscreen VDD/AVDD supply
max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL); max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2, i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
MAX77620_LDO_CFG2_ADE_ENABLE | (3 << 3) | (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT)); (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT | (3 << 3) | MAX77620_LDO_CFG2_ADE_ENABLE));
// Configure touchscreen GPIO. // Configure touchscreen GPIO.
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1; PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;

View File

@ -125,7 +125,7 @@ static int _LZ_ReadVarSize( unsigned int * x, const unsigned char * buf )
* insize - Number of input bytes. * insize - Number of input bytes.
*************************************************************************/ *************************************************************************/
void LZ_Uncompress( const unsigned char *in, unsigned char *out, unsigned int LZ_Uncompress( const unsigned char *in, unsigned char *out,
unsigned int insize ) unsigned int insize )
{ {
unsigned char marker, symbol; unsigned char marker, symbol;
@ -134,7 +134,7 @@ void LZ_Uncompress( const unsigned char *in, unsigned char *out,
/* Do we have anything to uncompress? */ /* Do we have anything to uncompress? */
if( insize < 1 ) if( insize < 1 )
{ {
return; return 0;
} }
/* Get marker symbol from input stream */ /* Get marker symbol from input stream */
@ -176,4 +176,6 @@ void LZ_Uncompress( const unsigned char *in, unsigned char *out,
} }
} }
while( inpos < insize ); while( inpos < insize );
return outpos;
} }

View File

@ -41,7 +41,7 @@ extern "C" {
* Function prototypes * Function prototypes
*************************************************************************/ *************************************************************************/
void LZ_Uncompress( const unsigned char *in, unsigned char *out, unsigned int LZ_Uncompress( const unsigned char *in, unsigned char *out,
unsigned int insize ); unsigned int insize );

1672
bdk/libs/compr/lz4.c Normal file

File diff suppressed because it is too large Load Diff

569
bdk/libs/compr/lz4.h Normal file
View File

@ -0,0 +1,569 @@
/*
* LZ4 - Fast LZ compression algorithm
* Header File
* Copyright (C) 2011-2017, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at :
- LZ4 homepage : http://www.lz4.org
- LZ4 source repository : https://github.com/lz4/lz4
*/
#if defined (__cplusplus)
extern "C" {
#endif
#ifndef LZ4_H_2983827168210
#define LZ4_H_2983827168210
/* --- Dependency --- */
#include <stddef.h> /* size_t */
/**
Introduction
LZ4 is lossless compression algorithm, providing compression speed at 400 MB/s per core,
scalable with multi-cores CPU. It features an extremely fast decoder, with speed in
multiple GB/s per core, typically reaching RAM speed limits on multi-core systems.
The LZ4 compression library provides in-memory compression and decompression functions.
Compression can be done in:
- a single step (described as Simple Functions)
- a single step, reusing a context (described in Advanced Functions)
- unbounded multiple steps (described as Streaming compression)
lz4.h provides block compression functions. It gives full buffer control to user.
Decompressing an lz4-compressed block also requires metadata (such as compressed size).
Each application is free to encode such metadata in whichever way it wants.
An additional format, called LZ4 frame specification (doc/lz4_Frame_format.md),
take care of encoding standard metadata alongside LZ4-compressed blocks.
If your application requires interoperability, it's recommended to use it.
A library is provided to take care of it, see lz4frame.h.
*/
/*^***************************************************************
* Export parameters
*****************************************************************/
/*
* LZ4_DLL_EXPORT :
* Enable exporting of functions when building a Windows DLL
* LZ4LIB_VISIBILITY :
* Control library symbols visibility.
*/
#ifndef LZ4LIB_VISIBILITY
# if defined(__GNUC__) && (__GNUC__ >= 4)
# define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default")))
# else
# define LZ4LIB_VISIBILITY
# endif
#endif
#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1)
# define LZ4LIB_API __declspec(dllexport) LZ4LIB_VISIBILITY
#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1)
# define LZ4LIB_API __declspec(dllimport) LZ4LIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
#else
# define LZ4LIB_API LZ4LIB_VISIBILITY
#endif
/*------ Version ------*/
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
#define LZ4_VERSION_MINOR 8 /* for new (non-breaking) interface capabilities */
#define LZ4_VERSION_RELEASE 2 /* for tweaks, bug-fixes, or development */
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE
#define LZ4_QUOTE(str) #str
#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str)
#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION)
LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version */
LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; unseful to check dll version */
/*-************************************
* Tuning parameter
**************************************/
/*!
* LZ4_MEMORY_USAGE :
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
* Increasing memory usage improves compression ratio
* Reduced memory usage may improve speed, thanks to cache effect
* Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
*/
#ifndef LZ4_MEMORY_USAGE
# define LZ4_MEMORY_USAGE 14
#endif
/*-************************************
* Simple Functions
**************************************/
/*! LZ4_compress_default() :
Compresses 'srcSize' bytes from buffer 'src'
into already allocated 'dst' buffer of size 'dstCapacity'.
Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize).
It also runs faster, so it's a recommended setting.
If the function cannot compress 'src' into a more limited 'dst' budget,
compression stops *immediately*, and the function result is zero.
Note : as a consequence, 'dst' content is not valid.
Note 2 : This function is protected against buffer overflow scenarios (never writes outside 'dst' buffer, nor read outside 'source' buffer).
srcSize : max supported value is LZ4_MAX_INPUT_SIZE.
dstCapacity : size of buffer 'dst' (which must be already allocated)
return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity)
or 0 if compression fails */
LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity);
/*! LZ4_decompress_safe() :
compressedSize : is the exact complete size of the compressed block.
dstCapacity : is the size of destination buffer, which must be already allocated.
return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity)
If destination buffer is not large enough, decoding will stop and output an error code (negative value).
If the source stream is detected malformed, the function will stop decoding and return a negative result.
This function is protected against malicious data packets.
*/
LZ4LIB_API int LZ4_decompress_safe (const char* src, char* dst, int compressedSize, int dstCapacity);
/*-************************************
* Advanced Functions
**************************************/
#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
/*!
LZ4_compressBound() :
Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
This function is primarily useful for memory allocation purposes (destination buffer size).
Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
Note that LZ4_compress_default() compresses faster when dstCapacity is >= LZ4_compressBound(srcSize)
inputSize : max supported value is LZ4_MAX_INPUT_SIZE
return : maximum output size in a "worst case" scenario
or 0, if input size is incorrect (too large or negative)
*/
LZ4LIB_API int LZ4_compressBound(int inputSize);
/*!
LZ4_compress_fast() :
Same as LZ4_compress_default(), but allows selection of "acceleration" factor.
The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
An acceleration value of "1" is the same as regular LZ4_compress_default()
Values <= 0 will be replaced by ACCELERATION_DEFAULT (currently == 1, see lz4.c).
*/
LZ4LIB_API int LZ4_compress_fast (const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
/*!
LZ4_compress_fast_extState() :
Same compression function, just using an externally allocated memory space to store compression state.
Use LZ4_sizeofState() to know how much memory must be allocated,
and allocate it on 8-bytes boundaries (using malloc() typically).
Then, provide it as 'void* state' to compression function.
*/
LZ4LIB_API int LZ4_sizeofState(void);
LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
/*!
LZ4_compress_destSize() :
Reverse the logic : compresses as much data as possible from 'src' buffer
into already allocated buffer 'dst' of size 'targetDestSize'.
This function either compresses the entire 'src' content into 'dst' if it's large enough,
or fill 'dst' buffer completely with as much data as possible from 'src'.
*srcSizePtr : will be modified to indicate how many bytes where read from 'src' to fill 'dst'.
New value is necessarily <= old value.
return : Nb bytes written into 'dst' (necessarily <= targetDestSize)
or 0 if compression fails
*/
LZ4LIB_API int LZ4_compress_destSize (const char* src, char* dst, int* srcSizePtr, int targetDstSize);
/*!
LZ4_decompress_fast() : **unsafe!**
This function is a bit faster than LZ4_decompress_safe(),
but doesn't provide any security guarantee.
originalSize : is the uncompressed size to regenerate
Destination buffer must be already allocated, and its size must be >= 'originalSize' bytes.
return : number of bytes read from source buffer (== compressed size).
If the source stream is detected malformed, the function stops decoding and return a negative result.
note : This function respects memory boundaries for *properly formed* compressed data.
However, it does not provide any protection against malicious input.
It also doesn't know 'src' size, and implies it's >= compressed size.
Use this function in trusted environment **only**.
*/
LZ4LIB_API int LZ4_decompress_fast (const char* src, char* dst, int originalSize);
/*!
LZ4_decompress_safe_partial() :
This function decompress a compressed block of size 'srcSize' at position 'src'
into destination buffer 'dst' of size 'dstCapacity'.
The function will decompress a minimum of 'targetOutputSize' bytes, and stop after that.
However, it's not accurate, and may write more than 'targetOutputSize' (but always <= dstCapacity).
@return : the number of bytes decoded in the destination buffer (necessarily <= dstCapacity)
Note : this number can also be < targetOutputSize, if compressed block contains less data.
Therefore, always control how many bytes were decoded.
If source stream is detected malformed, function returns a negative result.
This function is protected against malicious data packets.
*/
LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcSize, int targetOutputSize, int dstCapacity);
/*-*********************************************
* Streaming Compression Functions
***********************************************/
typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */
/*! LZ4_createStream() and LZ4_freeStream() :
* LZ4_createStream() will allocate and initialize an `LZ4_stream_t` structure.
* LZ4_freeStream() releases its memory.
*/
LZ4LIB_API LZ4_stream_t* LZ4_createStream(void);
LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr);
/*! LZ4_resetStream() :
* An LZ4_stream_t structure can be allocated once and re-used multiple times.
* Use this function to start compressing a new stream.
*/
LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr);
/*! LZ4_loadDict() :
* Use this function to load a static dictionary into LZ4_stream_t.
* Any previous data will be forgotten, only 'dictionary' will remain in memory.
* Loading a size of 0 is allowed, and is the same as reset.
* @return : dictionary size, in bytes (necessarily <= 64 KB)
*/
LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
/*! LZ4_compress_fast_continue() :
* Compress 'src' content using data from previously compressed blocks, for better compression ratio.
* 'dst' buffer must be already allocated.
* If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
*
* Important : The previous 64KB of compressed data is assumed to remain present and unmodified in memory!
*
* Special 1 : When input is a double-buffer, they can have any size, including < 64 KB.
* Make sure that buffers are separated by at least one byte.
* This way, each block only depends on previous block.
* Special 2 : If input buffer is a ring-buffer, it can have any size, including < 64 KB.
*
* @return : size of compressed block
* or 0 if there is an error (typically, cannot fit into 'dst').
* After an error, the stream status is invalid, it can only be reset or freed.
*/
LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
/*! LZ4_saveDict() :
* If last 64KB data cannot be guaranteed to remain available at its current memory location,
* save it into a safer place (char* safeBuffer).
* This is schematically equivalent to a memcpy() followed by LZ4_loadDict(),
* but is much faster, because LZ4_saveDict() doesn't need to rebuild tables.
* @return : saved dictionary size in bytes (necessarily <= maxDictSize), or 0 if error.
*/
LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int maxDictSize);
/*-**********************************************
* Streaming Decompression Functions
* Bufferless synchronous API
************************************************/
typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* incomplete type (defined later) */
/*! LZ4_createStreamDecode() and LZ4_freeStreamDecode() :
* creation / destruction of streaming decompression tracking structure.
* A tracking structure can be re-used multiple times sequentially. */
LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void);
LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
/*! LZ4_setStreamDecode() :
* An LZ4_streamDecode_t structure can be allocated once and re-used multiple times.
* Use this function to start decompression of a new stream of blocks.
* A dictionary can optionnally be set. Use NULL or size 0 for a reset order.
* @return : 1 if OK, 0 if error
*/
LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
/*! LZ4_decompress_*_continue() :
* These decoding functions allow decompression of consecutive blocks in "streaming" mode.
* A block is an unsplittable entity, it must be presented entirely to a decompression function.
* Decompression functions only accept one block at a time.
* The last 64KB of previously decoded data *must* remain available and unmodified at the memory position where they were decoded.
* If less than 64KB of data has been decoded all the data must be present.
*
* Special : if application sets a ring buffer for decompression, it must respect one of the following conditions :
* - Exactly same size as encoding buffer, with same update rule (block boundaries at same positions)
* In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB).
* - Larger than encoding buffer, by a minimum of maxBlockSize more bytes.
* maxBlockSize is implementation dependent. It's the maximum size of any single block.
* In which case, encoding and decoding buffers do not need to be synchronized,
* and encoding ring buffer can have any size, including small ones ( < 64 KB).
* - _At least_ 64 KB + 8 bytes + maxBlockSize.
* In which case, encoding and decoding buffers do not need to be synchronized,
* and encoding ring buffer can have any size, including larger than decoding buffer.
* Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer,
* and indicate where it is saved using LZ4_setStreamDecode() before decompressing next block.
*/
LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int srcSize, int dstCapacity);
LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int originalSize);
/*! LZ4_decompress_*_usingDict() :
* These decoding functions work the same as
* a combination of LZ4_setStreamDecode() followed by LZ4_decompress_*_continue()
* They are stand-alone, and don't need an LZ4_streamDecode_t structure.
*/
LZ4LIB_API int LZ4_decompress_safe_usingDict (const char* src, char* dst, int srcSize, int dstCapcity, const char* dictStart, int dictSize);
LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int originalSize, const char* dictStart, int dictSize);
/*^**********************************************
* !!!!!! STATIC LINKING ONLY !!!!!!
***********************************************/
/*-************************************
* Unstable declarations
**************************************
* Declarations in this section should be considered unstable.
* Use at your own peril, etc., etc.
* They may be removed in the future.
* Their signatures may change.
**************************************/
#ifdef LZ4_STATIC_LINKING_ONLY
/*! LZ4_resetStream_fast() :
* When an LZ4_stream_t is known to be in a internally coherent state,
* it can often be prepared for a new compression with almost no work, only
* sometimes falling back to the full, expensive reset that is always required
* when the stream is in an indeterminate state (i.e., the reset performed by
* LZ4_resetStream()).
*
* LZ4_streams are guaranteed to be in a valid state when:
* - returned from LZ4_createStream()
* - reset by LZ4_resetStream()
* - memset(stream, 0, sizeof(LZ4_stream_t))
* - the stream was in a valid state and was reset by LZ4_resetStream_fast()
* - the stream was in a valid state and was then used in any compression call
* that returned success
* - the stream was in an indeterminate state and was used in a compression
* call that fully reset the state (LZ4_compress_fast_extState()) and that
* returned success
*/
LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr);
/*! LZ4_compress_fast_extState_fastReset() :
* A variant of LZ4_compress_fast_extState().
*
* Using this variant avoids an expensive initialization step. It is only safe
* to call if the state buffer is known to be correctly initialized already
* (see above comment on LZ4_resetStream_fast() for a definition of "correctly
* initialized"). From a high level, the difference is that this function
* initializes the provided state with a call to LZ4_resetStream_fast() while
* LZ4_compress_fast_extState() starts with a call to LZ4_resetStream().
*/
LZ4LIB_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
/*! LZ4_attach_dictionary() :
* This is an experimental API that allows for the efficient use of a
* static dictionary many times.
*
* Rather than re-loading the dictionary buffer into a working context before
* each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a
* working LZ4_stream_t, this function introduces a no-copy setup mechanism,
* in which the working stream references the dictionary stream in-place.
*
* Several assumptions are made about the state of the dictionary stream.
* Currently, only streams which have been prepared by LZ4_loadDict() should
* be expected to work.
*
* Alternatively, the provided dictionary stream pointer may be NULL, in which
* case any existing dictionary stream is unset.
*
* If a dictionary is provided, it replaces any pre-existing stream history.
* The dictionary contents are the only history that can be referenced and
* logically immediately precede the data compressed in the first subsequent
* compression call.
*
* The dictionary will only remain attached to the working stream through the
* first compression call, at the end of which it is cleared. The dictionary
* stream (and source buffer) must remain in-place / accessible / unchanged
* through the completion of the first compression call on the stream.
*/
LZ4LIB_API void LZ4_attach_dictionary(LZ4_stream_t *working_stream, const LZ4_stream_t *dictionary_stream);
#endif
/*-************************************
* Private definitions
**************************************
* Do not use these definitions.
* They are exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`.
* Using these definitions will expose code to API and/or ABI break in future versions of the library.
**************************************/
#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2)
#define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE)
#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */
#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
#include <stdint.h>
typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
struct LZ4_stream_t_internal {
uint32_t hashTable[LZ4_HASH_SIZE_U32];
uint32_t currentOffset;
uint16_t initCheck;
uint16_t tableType;
const uint8_t* dictionary;
const LZ4_stream_t_internal* dictCtx;
uint32_t dictSize;
};
typedef struct {
const uint8_t* externalDict;
size_t extDictSize;
const uint8_t* prefixEnd;
size_t prefixSize;
} LZ4_streamDecode_t_internal;
#else
typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
struct LZ4_stream_t_internal {
unsigned int hashTable[LZ4_HASH_SIZE_U32];
unsigned int currentOffset;
unsigned short initCheck;
unsigned short tableType;
const unsigned char* dictionary;
const LZ4_stream_t_internal* dictCtx;
unsigned int dictSize;
};
typedef struct {
const unsigned char* externalDict;
size_t extDictSize;
const unsigned char* prefixEnd;
size_t prefixSize;
} LZ4_streamDecode_t_internal;
#endif
/*!
* LZ4_stream_t :
* information structure to track an LZ4 stream.
* init this structure before first use.
* note : only use in association with static linking !
* this definition is not API/ABI safe,
* it may change in a future version !
*/
#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4)
#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(unsigned long long))
union LZ4_stream_u {
unsigned long long table[LZ4_STREAMSIZE_U64];
LZ4_stream_t_internal internal_donotuse;
} ; /* previously typedef'd to LZ4_stream_t */
/*!
* LZ4_streamDecode_t :
* information structure to track an LZ4 stream during decompression.
* init this structure using LZ4_setStreamDecode (or memset()) before first use
* note : only use in association with static linking !
* this definition is not API/ABI safe,
* and may change in a future version !
*/
#define LZ4_STREAMDECODESIZE_U64 4
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
union LZ4_streamDecode_u {
unsigned long long table[LZ4_STREAMDECODESIZE_U64];
LZ4_streamDecode_t_internal internal_donotuse;
} ; /* previously typedef'd to LZ4_streamDecode_t */
/*-************************************
* Obsolete Functions
**************************************/
/*! Deprecation warnings
Should deprecation warnings be a problem,
it is generally possible to disable them,
typically with -Wno-deprecated-declarations for gcc
or _CRT_SECURE_NO_WARNINGS in Visual.
Otherwise, it's also possible to define LZ4_DISABLE_DEPRECATE_WARNINGS */
#ifdef LZ4_DISABLE_DEPRECATE_WARNINGS
# define LZ4_DEPRECATED(message) /* disable deprecation warnings */
#else
# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */
# define LZ4_DEPRECATED(message) [[deprecated(message)]]
# elif (LZ4_GCC_VERSION >= 405) || defined(__clang__)
# define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
# elif (LZ4_GCC_VERSION >= 301)
# define LZ4_DEPRECATED(message) __attribute__((deprecated))
# elif defined(_MSC_VER)
# define LZ4_DEPRECATED(message) __declspec(deprecated(message))
# else
# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler")
# define LZ4_DEPRECATED(message)
# endif
#endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */
/* Obsolete compression functions */
LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress (const char* source, char* dest, int sourceSize);
LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize);
LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
/* Obsolete decompression functions */
LZ4_DEPRECATED("use LZ4_decompress_fast() instead") LZ4LIB_API int LZ4_uncompress (const char* source, char* dest, int outputSize);
LZ4_DEPRECATED("use LZ4_decompress_safe() instead") LZ4LIB_API int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize);
/* Obsolete streaming functions; degraded functionality; do not use!
*
* In order to perform streaming compression, these functions depended on data
* that is no longer tracked in the state. They have been preserved as well as
* possible: using them will still produce a correct output. However, they don't
* actually retain any history between compression calls. The compression ratio
* achieved will therefore be no better than compressing each chunk
* independently.
*/
LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API void* LZ4_create (char* inputBuffer);
LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API int LZ4_sizeofStreamState(void);
LZ4_DEPRECATED("Use LZ4_resetStream() instead") LZ4LIB_API int LZ4_resetStreamState(void* state, char* inputBuffer);
LZ4_DEPRECATED("Use LZ4_saveDict() instead") LZ4LIB_API char* LZ4_slideInputBuffer (void* state);
/* Obsolete streaming decoding functions */
LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") LZ4LIB_API int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize);
LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize);
#endif /* LZ4_H_2983827168210 */
#if defined (__cplusplus)
}
#endif

View File

@ -40,6 +40,7 @@ DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
DRESULT disk_set_info (BYTE pdrv, BYTE cmd, void *buff);
/* Disk Status Bits (DSTATUS) */ /* Disk Status Bits (DSTATUS) */
@ -54,6 +55,7 @@ DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
/* Generic command (Used by FatFs) */ /* Generic command (Used by FatFs) */
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */ #define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */ #define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
#define SET_SECTOR_COUNT 1 /* Set media size (needed at FF_USE_MKFS == 1) */
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ #define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */

View File

@ -38,8 +38,10 @@
#include "ff.h" /* Declarations of FatFs API */ #include "ff.h" /* Declarations of FatFs API */
#include "diskio.h" /* Declarations of device I/O functions */ #include "diskio.h" /* Declarations of device I/O functions */
#include <gfx_utils.h>
#define EFSPRINTF(text, ...) #define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
//#define EFSPRINTF(...)
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
@ -530,7 +532,7 @@ static WCHAR LfnBuf[FF_MAX_LFN + 1]; /* LFN working buffer */
#define FREE_NAMBUF() ff_memfree(lfn) #define FREE_NAMBUF() ff_memfree(lfn)
#endif #endif
#define LEAVE_MKFS(res) { if (!work) ff_memfree(buf); return res; } #define LEAVE_MKFS(res) { if (!work) ff_memfree(buf); return res; }
#define MAX_MALLOC 0x4000 /* Must be >=FF_MAX_SS */ #define MAX_MALLOC 0x8000 /* Must be >=FF_MAX_SS */
#else #else
#error Wrong setting of FF_USE_LFN #error Wrong setting of FF_USE_LFN
@ -590,6 +592,16 @@ static const BYTE DbcTbl[] = MKCVTBL(TBL_DC, FF_CODE_PAGE);
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/* Print error header */
/*-----------------------------------------------------------------------*/
void print_error()
{
gfx_printf("\n\n\n%k[FatFS] Error: %k", 0xFFFFFF00, 0xFFFFFFFF);
}
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Load/Store multi-byte word in the FAT structure */ /* Load/Store multi-byte word in the FAT structure */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -3894,11 +3906,11 @@ FRESULT f_read (
#ifdef FF_FASTFS #if FF_FASTFS && FF_USE_FASTSEEK
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Fast Read Aligned Sized File Without a Cache */ /* Fast Read Aligned Sized File Without a Cache */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
#if FF_USE_FASTSEEK
FRESULT f_read_fast ( FRESULT f_read_fast (
FIL* fp, /* Pointer to the file object */ FIL* fp, /* Pointer to the file object */
const void* buff, /* Pointer to the data to be written */ const void* buff, /* Pointer to the data to be written */
@ -3909,12 +3921,13 @@ FRESULT f_read_fast (
FATFS *fs; FATFS *fs;
UINT csize_bytes; UINT csize_bytes;
DWORD clst; DWORD clst;
DWORD wbytes; UINT count = 0;
UINT count;
FSIZE_t work_sector = 0; FSIZE_t work_sector = 0;
FSIZE_t sector_base = 0; FSIZE_t sector_base = 0;
BYTE *wbuff = (BYTE*)buff; BYTE *wbuff = (BYTE*)buff;
// TODO support sector reading inside a cluster
res = validate(&fp->obj, &fs); /* Check validity of the file object */ res = validate(&fp->obj, &fs); /* Check validity of the file object */
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) { if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
EFSPRINTF("FOV"); EFSPRINTF("FOV");
@ -3926,17 +3939,6 @@ FRESULT f_read_fast (
if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */
csize_bytes = fs->csize * SS(fs); csize_bytes = fs->csize * SS(fs);
DWORD csect = (UINT)((fp->fptr / SS(fs)) & (fs->csize - 1)); /* Sector offset in the cluster */
/* If inside a cluster, read the sectors and align to cluster. */
if (csect) {
wbytes = MIN(btr, (fs->csize - csect) * SS(fs));
f_read(fp, wbuff, wbytes, (void *)0);
wbuff += wbytes;
btr -= wbytes;
if (!btr)
goto out;
}
if (!fp->fptr) { /* On the top of the file? */ if (!fp->fptr) { /* On the top of the file? */
clst = fp->obj.sclust; /* Follow from the origin */ clst = fp->obj.sclust; /* Follow from the origin */
@ -3944,22 +3946,15 @@ FRESULT f_read_fast (
if (fp->cltbl) clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ if (fp->cltbl) clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
else { EFSPRINTF("CLTBL"); ABORT(fs, FR_CLTBL_NO_INIT); } else { EFSPRINTF("CLTBL"); ABORT(fs, FR_CLTBL_NO_INIT); }
} }
if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); } if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); }
else if (clst == 0xFFFFFFFF) { EFSPRINTF("DSKC"); ABORT(fs, FR_DISK_ERR); } else if (clst == 0xFFFFFFFF) { EFSPRINTF("DSKC"); ABORT(fs, FR_DISK_ERR); }
fp->clust = clst; /* Set working cluster */ fp->clust = clst; /* Set working cluster */
wbytes = MIN(btr, csize_bytes);
sector_base = clst2sect(fs, fp->clust); sector_base = clst2sect(fs, fp->clust);
count = wbytes / SS(fs); count += fs->csize;
fp->fptr += wbytes; btr -= csize_bytes;
btr -= wbytes; fp->fptr += csize_bytes;
if (!btr) { /* Final cluster/sectors read. */
if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
goto out;
}
while (btr) { while (btr) {
clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
@ -3970,29 +3965,29 @@ FRESULT f_read_fast (
fp->clust = clst; fp->clust = clst;
work_sector = clst2sect(fs, fp->clust); work_sector = clst2sect(fs, fp->clust);
wbytes = MIN(btr, csize_bytes); if ((work_sector - sector_base) == count) count += fs->csize;
if ((work_sector - sector_base) == count) count += wbytes / SS(fs);
else { else {
if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR); if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
wbuff += count * SS(fs); wbuff += count * SS(fs);
sector_base = work_sector; sector_base = work_sector;
count = wbytes / SS(fs); count = fs->csize;
} }
fp->fptr += wbytes; fp->fptr += MIN(btr, csize_bytes);
btr -= wbytes; btr -= MIN(btr, csize_bytes);
// TODO: what about if data is smaller than cluster?
// Must read-write back that cluster.
if (!btr) { /* Final cluster/sectors read. */ if (!btr) { /* Final cluster/sectors read. */
if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR); if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
} }
} }
out:
LEAVE_FF(fs, FR_OK); LEAVE_FF(fs, FR_OK);
} }
#endif #endif
#endif
@ -4136,11 +4131,11 @@ FRESULT f_write (
#ifdef FF_FASTFS #if FF_FASTFS && FF_USE_FASTSEEK
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Fast Write Aligned Sized File Without a Cache */ /* Fast Write Aligned Sized File Without a Cache */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
#if FF_USE_FASTSEEK
FRESULT f_write_fast ( FRESULT f_write_fast (
FIL* fp, /* Pointer to the file object */ FIL* fp, /* Pointer to the file object */
const void* buff, /* Pointer to the data to be written */ const void* buff, /* Pointer to the data to be written */
@ -4151,11 +4146,12 @@ FRESULT f_write_fast (
FATFS *fs; FATFS *fs;
UINT csize_bytes; UINT csize_bytes;
DWORD clst; DWORD clst;
DWORD wbytes; UINT count = 0;
UINT count;
FSIZE_t work_sector = 0; FSIZE_t work_sector = 0;
FSIZE_t sector_base = 0; FSIZE_t sector_base = 0;
BYTE *wbuff = (BYTE*)buff; const BYTE *wbuff = (const BYTE*)buff;
// TODO support sector writing inside a cluster
res = validate(&fp->obj, &fs); /* Check validity of the file object */ res = validate(&fp->obj, &fs); /* Check validity of the file object */
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) { if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
@ -4170,19 +4166,6 @@ FRESULT f_write_fast (
} }
csize_bytes = fs->csize * SS(fs); csize_bytes = fs->csize * SS(fs);
DWORD csect = (UINT)((fp->fptr / SS(fs)) & (fs->csize - 1)); /* Sector offset in the cluster */
/* If inside a cluster, write the sectors and align to cluster. */
if (csect) {
wbytes = MIN(btw, (fs->csize - csect) * SS(fs));
f_write(fp, wbuff, wbytes, (void *)0);
/* Ensure flushing of it. FatFS is not notified for next write if raw. */
f_sync(fp);
wbuff += wbytes;
btw -= wbytes;
if (!btw)
goto out;
}
if (!fp->fptr) { /* On the top of the file? */ if (!fp->fptr) { /* On the top of the file? */
clst = fp->obj.sclust; /* Follow from the origin */ clst = fp->obj.sclust; /* Follow from the origin */
@ -4192,57 +4175,49 @@ FRESULT f_write_fast (
} }
if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); } if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); }
else if (clst == 0xFFFFFFFF) { EFSPRINTF("DSKC"); ABORT(fs, FR_DISK_ERR); } else if (clst == 0xFFFFFFFF) { EFSPRINTF("DERR"); ABORT(fs, FR_DISK_ERR); }
fp->clust = clst; /* Set working cluster */ fp->clust = clst; /* Set working cluster */
wbytes = MIN(btw, csize_bytes);
sector_base = clst2sect(fs, fp->clust); sector_base = clst2sect(fs, fp->clust);
count = wbytes / SS(fs); count += fs->csize;
fp->fptr += wbytes; btw -= csize_bytes;
btw -= wbytes; fp->fptr += csize_bytes;
if (!btw) { /* Final cluster/sectors write. */
if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
fp->flag &= (BYTE)~FA_DIRTY;
goto out;
}
while (btw) { while (btw) {
clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
if (clst < 2) { EFSPRINTF("CCHK2"); ABORT(fs, FR_INT_ERR); } if (clst < 2) { EFSPRINTF("CCHK2"); ABORT(fs, FR_INT_ERR); }
else if (clst == 0xFFFFFFFF) { EFSPRINTF("DSKC"); ABORT(fs, FR_DISK_ERR); } else if (clst == 0xFFFFFFFF) { EFSPRINTF("DERR"); ABORT(fs, FR_DISK_ERR); }
fp->clust = clst; fp->clust = clst;
work_sector = clst2sect(fs, fp->clust); work_sector = clst2sect(fs, fp->clust);
wbytes = MIN(btw, csize_bytes); if ((work_sector - sector_base) == count) count += fs->csize;
if ((work_sector - sector_base) == count) count += wbytes / SS(fs);
else { else {
if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR); if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
wbuff += count * SS(fs); wbuff += count * SS(fs);
sector_base = work_sector; sector_base = work_sector;
count = wbytes / SS(fs); count = fs->csize;
} }
fp->fptr += wbytes; fp->fptr += MIN(btw, csize_bytes);
btw -= wbytes; btw -= MIN(btw, csize_bytes);
// what about if data is smaller than cluster?
// Probably must read-write back that cluster.
if (!btw) { /* Final cluster/sectors write. */ if (!btw) { /* Final cluster/sectors write. */
if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR); if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
fp->flag &= (BYTE)~FA_DIRTY; fp->flag &= (BYTE)~FA_DIRTY;
} }
} }
out:
fp->flag |= FA_MODIFIED; /* Set file change flag */ fp->flag |= FA_MODIFIED; /* Set file change flag */
LEAVE_FF(fs, FR_OK); LEAVE_FF(fs, FR_OK);
} }
#endif #endif
#endif
@ -4703,8 +4678,7 @@ FRESULT f_lseek (
#ifdef FF_FASTFS #if FF_FASTFS && FF_USE_FASTSEEK
#if FF_USE_FASTSEEK
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Seek File Read/Write Pointer */ /* Seek File Read/Write Pointer */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -4712,24 +4686,25 @@ FRESULT f_lseek (
DWORD *f_expand_cltbl ( DWORD *f_expand_cltbl (
FIL* fp, /* Pointer to the file object */ FIL* fp, /* Pointer to the file object */
UINT tblsz, /* Size of table */ UINT tblsz, /* Size of table */
DWORD *tbl, /* Table pointer */
FSIZE_t ofs /* File pointer from top of file */ FSIZE_t ofs /* File pointer from top of file */
) )
{ {
if (fp->flag & FA_WRITE) f_lseek(fp, ofs); /* Expand file if write is enabled */ if (fp->flag & FA_WRITE) f_lseek(fp, ofs); /* Expand file if write is enabled */
fp->cltbl = (DWORD *)tbl; if (!fp->cltbl) { /* Allocate memory for cluster link table */
fp->cltbl = (DWORD *)ff_memalloc(tblsz);
fp->cltbl[0] = tblsz; fp->cltbl[0] = tblsz;
}
if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */ if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */
fp->cltbl = (void *)0; ff_memfree(fp->cltbl);
fp->cltbl = NULL;
EFSPRINTF("CLTBLSZ"); EFSPRINTF("CLTBLSZ");
return (void *)0; return NULL;
} }
f_lseek(fp, 0); f_lseek(fp, 0);
return fp->cltbl; return fp->cltbl;
} }
#endif #endif
#endif
@ -5863,7 +5838,7 @@ FRESULT f_mkfs (
UINT len /* Size of working buffer [byte] */ UINT len /* Size of working buffer [byte] */
) )
{ {
const UINT n_fats = 1; /* Number of FATs for FAT/FAT32 volume (1 or 2) */ const UINT n_fats = 2; /* Number of FATs for FAT/FAT32 volume (1 or 2) */
const UINT n_rootdir = 512; /* Number of root directory entries for FAT volume */ const UINT n_rootdir = 512; /* Number of root directory entries for FAT volume */
static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT volume (4Ks unit) */ static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT volume (4Ks unit) */
static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */ static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */
@ -5927,7 +5902,7 @@ FRESULT f_mkfs (
} else { } else {
/* Create a single-partition in this function */ /* Create a single-partition in this function */
if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
b_vol = (opt & FM_SFD) ? 0 : 63; /* Volume start sector */ b_vol = (opt & FM_SFD) ? 0 : 32768; /* Volume start sector. Align to 16MB */
if (sz_vol < b_vol) LEAVE_MKFS(FR_MKFS_ABORTED); if (sz_vol < b_vol) LEAVE_MKFS(FR_MKFS_ABORTED);
sz_vol -= b_vol; /* Volume size */ sz_vol -= b_vol; /* Volume size */
} }
@ -6151,6 +6126,9 @@ FRESULT f_mkfs (
if (fmt == FS_FAT32) { /* FAT32: Move FAT base */ if (fmt == FS_FAT32) { /* FAT32: Move FAT base */
sz_rsv += n; b_fat += n; sz_rsv += n; b_fat += n;
} else { /* FAT: Expand FAT size */ } else { /* FAT: Expand FAT size */
if (n % n_fats) { /* Adjust fractional error if needed */
n--; sz_rsv++; b_fat++;
}
sz_fat += n / n_fats; sz_fat += n / n_fats;
} }
@ -6214,13 +6192,13 @@ FRESULT f_mkfs (
st_word(buf + BPB_BkBootSec32, 6); /* Offset of backup VBR (VBR + 6) */ st_word(buf + BPB_BkBootSec32, 6); /* Offset of backup VBR (VBR + 6) */
buf[BS_DrvNum32] = 0x80; /* Drive number (for int13) */ buf[BS_DrvNum32] = 0x80; /* Drive number (for int13) */
buf[BS_BootSig32] = 0x29; /* Extended boot signature */ buf[BS_BootSig32] = 0x29; /* Extended boot signature */
mem_cpy(buf + BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */ mem_cpy(buf + BS_VolLab32, "SWITCH SD " "FAT32 ", 19); /* Volume label, FAT signature */
} else { } else {
st_dword(buf + BS_VolID, GET_FATTIME()); /* VSN */ st_dword(buf + BS_VolID, GET_FATTIME()); /* VSN */
st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */ st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */
buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */ buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */
buf[BS_BootSig] = 0x29; /* Extended boot signature */ buf[BS_BootSig] = 0x29; /* Extended boot signature */
mem_cpy(buf + BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */ mem_cpy(buf + BS_VolLab, "SWITCH SD " "FAT ", 19); /* Volume label, FAT signature */
} }
st_word(buf + BS_55AA, 0xAA55); /* Signature (offset is fixed here regardless of sector size) */ 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 */ if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */

View File

@ -263,10 +263,8 @@ FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a f
FRESULT f_close (FIL* fp); /* Close an open file object */ FRESULT f_close (FIL* fp); /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */ FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */ FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
#ifdef FF_FASTFS
FRESULT f_read_fast (FIL* fp, const void* buff, UINT btr); /* Fast read data from the file */ FRESULT f_read_fast (FIL* fp, const void* buff, UINT btr); /* Fast read data from the file */
FRESULT f_write_fast (FIL* fp, const void* buff, UINT btw); /* Fast write data to the file */ FRESULT f_write_fast (FIL* fp, const void* buff, UINT btw); /* Fast write data to the file */
#endif
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */ FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
FRESULT f_truncate (FIL* fp); /* Truncate the file */ FRESULT f_truncate (FIL* fp); /* Truncate the file */
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */ FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
@ -288,9 +286,7 @@ FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get numbe
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */ FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
#ifdef FF_FASTFS DWORD *f_expand_cltbl (FIL* fp, UINT tblsz, FSIZE_t ofs); /* Expand file and populate cluster table */
DWORD *f_expand_cltbl (FIL* fp, UINT tblsz, DWORD *tbl, FSIZE_t ofs); /* Expand file and populate cluster table */
#endif
FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */ FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ 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_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */

View File

@ -155,7 +155,11 @@
/*Log settings*/ /*Log settings*/
#define USE_LV_LOG 0 /*Enable/disable the log module*/ #ifdef DEBUG_UART_PORT
# define USE_LV_LOG 1 /*Enable/disable the log module*/
#else
# define USE_LV_LOG 0 /*Enable/disable the log module*/
#endif
#if USE_LV_LOG #if USE_LV_LOG
/* How important log should be added: /* How important log should be added:
* LV_LOG_LEVEL_TRACE A lot of logs to give detailed information * LV_LOG_LEVEL_TRACE A lot of logs to give detailed information

View File

@ -67,7 +67,7 @@ void lv_log_add(lv_log_level_t level, const char * file, int line, const char *
static const char * lvl_prefix[] = {"Trace", "Info", "Warn", "Error"}; static const char * lvl_prefix[] = {"Trace", "Info", "Warn", "Error"};
char *log = (char *)malloc(0x1000); char *log = (char *)malloc(0x1000);
s_printf(log, "%s: %s \t(%s #%d)\r\n", lvl_prefix[level], dsc, file, line); s_printf(log, "%s: %s \t(%s #%d)\r\n", lvl_prefix[level], dsc, file, line);
uart_send(UART_B, (u8 *)log, strlen(log) + 1); uart_send(DEBUG_UART_PORT, (u8 *)log, strlen(log) + 1);
//gfx_printf("%s: %s \t(%s #%d)\n", lvl_prefix[level], dsc, file, line); //gfx_printf("%s: %s \t(%s #%d)\n", lvl_prefix[level], dsc, file, line);
#else #else
if(print_cb) print_cb(level, file, line, dsc); if(print_cb) print_cb(level, file, line, dsc);

View File

@ -38,12 +38,21 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <gfx_utils.h> #include <gfx_utils.h>
void save_allocation_table_storage_init(allocation_table_storage_ctx_t *ctx, substorage *data, allocation_table_ctx_t *table, uint32_t block_size, uint32_t initial_block) { bool save_allocation_table_storage_init(allocation_table_storage_ctx_t *ctx, substorage *data, allocation_table_ctx_t *table, uint32_t block_size, uint32_t initial_block) {
ctx->base_storage = data; ctx->base_storage = data;
ctx->block_size = block_size; ctx->block_size = block_size;
ctx->fat = table; ctx->fat = table;
ctx->initial_block = initial_block; ctx->initial_block = initial_block;
ctx->_length = initial_block == 0xFFFFFFFF ? 0 : save_allocation_table_get_list_length(table, initial_block) * block_size; ctx->_length = 0;
if (initial_block != 0xFFFFFFFF) {
uint32_t list_length = save_allocation_table_get_list_length(table, initial_block);
if (list_length == 0) {
EPRINTF("Allocation table storage init failed!");
return false;
};
ctx->_length = list_length * block_size;
}
return true;
} }
uint32_t save_allocation_table_storage_read(allocation_table_storage_ctx_t *ctx, void *buffer, uint64_t offset, uint64_t count) { uint32_t save_allocation_table_storage_read(allocation_table_storage_ctx_t *ctx, void *buffer, uint64_t offset, uint64_t count) {

View File

@ -52,7 +52,7 @@ static ALWAYS_INLINE void save_allocation_table_storage_get_size(allocation_tabl
*out_size = ctx->_length; *out_size = ctx->_length;
} }
void save_allocation_table_storage_init(allocation_table_storage_ctx_t *ctx, substorage *data, allocation_table_ctx_t *table, uint32_t block_size, uint32_t initial_block); bool save_allocation_table_storage_init(allocation_table_storage_ctx_t *ctx, substorage *data, allocation_table_ctx_t *table, uint32_t block_size, uint32_t initial_block);
uint32_t save_allocation_table_storage_read(allocation_table_storage_ctx_t *ctx, void *buffer, uint64_t offset, uint64_t count); uint32_t save_allocation_table_storage_read(allocation_table_storage_ctx_t *ctx, void *buffer, uint64_t offset, uint64_t count);
uint32_t save_allocation_table_storage_write(allocation_table_storage_ctx_t *ctx, const void *buffer, uint64_t offset, uint64_t count); uint32_t save_allocation_table_storage_write(allocation_table_storage_ctx_t *ctx, const void *buffer, uint64_t offset, uint64_t count);
bool save_allocation_table_storage_set_size(allocation_table_storage_ctx_t *ctx, uint64_t size); bool save_allocation_table_storage_set_size(allocation_table_storage_ctx_t *ctx, uint64_t size);

View File

@ -49,7 +49,7 @@ static ALWAYS_INLINE cache_block_t *cache_block_init(cached_storage_ctx_t *ctx)
void save_cached_storage_init(cached_storage_ctx_t *ctx, substorage *base_storage, uint32_t block_size, uint32_t cache_size) { void save_cached_storage_init(cached_storage_ctx_t *ctx, substorage *base_storage, uint32_t block_size, uint32_t cache_size) {
memcpy(&ctx->base_storage, base_storage, sizeof(substorage)); memcpy(&ctx->base_storage, base_storage, sizeof(substorage));
ctx->block_size = block_size; ctx->block_size = block_size;
substorage_get_size(base_storage, &ctx->length); ctx->length = base_storage->length;
ctx->cache_size = cache_size; ctx->cache_size = cache_size;
list_init(&ctx->blocks); list_init(&ctx->blocks);
@ -69,6 +69,8 @@ static void cache_block_finalize(cache_block_t **block) {
} }
void save_cached_storage_finalize(cached_storage_ctx_t *ctx) { void save_cached_storage_finalize(cached_storage_ctx_t *ctx) {
if (!ctx->blocks.next)
return;
LIST_FOREACH_SAFE(curr_block, &ctx->blocks) { LIST_FOREACH_SAFE(curr_block, &ctx->blocks) {
cache_block_t *block = CONTAINER_OF(curr_block, cache_block_t, link) ; cache_block_t *block = CONTAINER_OF(curr_block, cache_block_t, link) ;
cache_block_finalize(&block); cache_block_finalize(&block);
@ -76,6 +78,8 @@ void save_cached_storage_finalize(cached_storage_ctx_t *ctx) {
} }
static bool try_get_block_by_value(cached_storage_ctx_t *ctx, uint64_t index, cache_block_t **out_block) { static bool try_get_block_by_value(cached_storage_ctx_t *ctx, uint64_t index, cache_block_t **out_block) {
if (!ctx->blocks.next)
return false;
LIST_FOREACH_ENTRY(cache_block_t, block, &ctx->blocks, link) { LIST_FOREACH_ENTRY(cache_block_t, block, &ctx->blocks, link) {
if (block->index == index) { if (block->index == index) {
*out_block = block; *out_block = block;

View File

@ -135,7 +135,7 @@ validity_t save_hierarchical_integrity_verification_storage_validate(hierarchica
validity_t result = VALIDITY_VALID; validity_t result = VALIDITY_VALID;
integrity_verification_storage_ctx_t *storage = &ctx->integrity_storages[3]; integrity_verification_storage_ctx_t *storage = &ctx->integrity_storages[3];
uint64_t block_size = storage->base_storage.sector_size; uint32_t block_size = storage->base_storage.sector_size;
uint32_t block_count = (uint32_t)(DIV_ROUND_UP(ctx->length, block_size)); uint32_t block_count = (uint32_t)(DIV_ROUND_UP(ctx->length, block_size));
uint8_t *buffer = malloc(block_size); uint8_t *buffer = malloc(block_size);
@ -143,7 +143,7 @@ validity_t save_hierarchical_integrity_verification_storage_validate(hierarchica
for (unsigned int i = 0; i < block_count; i++) { for (unsigned int i = 0; i < block_count; i++) {
if (ctx->level_validities[3][i] == VALIDITY_UNCHECKED) { if (ctx->level_validities[3][i] == VALIDITY_UNCHECKED) {
uint64_t storage_size = storage->base_storage.length; uint64_t storage_size = storage->base_storage.length;
uint32_t to_read = MIN((uint32_t)(storage_size - block_size * i), (uint32_t)block_size); uint32_t to_read = MIN((uint32_t)(storage_size - block_size * i), block_size);
substorage_read(&ctx->data_level->base_storage, buffer, block_size * i, to_read); substorage_read(&ctx->data_level->base_storage, buffer, block_size * i, to_read);
} }
if (ctx->level_validities[3][i] == VALIDITY_INVALID) { if (ctx->level_validities[3][i] == VALIDITY_INVALID) {

View File

@ -207,7 +207,7 @@ void save_hierarchical_file_table_unlink_file_from_parent(hierarchical_save_file
return; return;
} }
prev_index = cur_index; prev_index = cur_index;
memcpy(&prev_entry, &cur_entry, sizeof(prev_entry)); memcpy(&prev_entry, &cur_entry, sizeof(save_table_entry_t));
cur_index = prev_entry.next_sibling; cur_index = prev_entry.next_sibling;
} }
} }
@ -236,7 +236,7 @@ void save_hierarchical_file_table_unlink_directory_from_parent(hierarchical_save
return; return;
} }
prev_index = cur_index; prev_index = cur_index;
memcpy(&prev_entry, &cur_entry, sizeof(prev_entry)); memcpy(&prev_entry, &cur_entry, sizeof(save_table_entry_t));
cur_index = prev_entry.next_sibling; cur_index = prev_entry.next_sibling;
} }
} }

View File

@ -52,7 +52,7 @@ void save_ivfc_storage_init(integrity_verification_storage_ctx_t *ctx, integrity
/* buffer must have size count + 0x20 for salt to by copied in at offset 0. */ /* buffer must have size count + 0x20 for salt to by copied in at offset 0. */
static ALWAYS_INLINE void save_ivfc_storage_do_hash(integrity_verification_storage_ctx_t *ctx, uint8_t *out_hash, void *buffer, uint64_t count) { static ALWAYS_INLINE void save_ivfc_storage_do_hash(integrity_verification_storage_ctx_t *ctx, uint8_t *out_hash, void *buffer, uint64_t count) {
memcpy(buffer, ctx->salt, sizeof(ctx->salt)); memcpy(buffer, ctx->salt, sizeof(ctx->salt));
se_calc_sha256(out_hash, buffer, count + sizeof(ctx->salt)); se_calc_sha256_oneshot(out_hash, buffer, count + sizeof(ctx->salt));
out_hash[0x1F] |= 0x80; out_hash[0x1F] |= 0x80;
} }
@ -81,7 +81,7 @@ bool save_ivfc_storage_read(integrity_verification_storage_ctx_t *ctx, void *buf
return false; return false;
} }
uint8_t hash_buffer[0x20] = {0}; uint8_t hash_buffer[0x20] __attribute__((aligned(4))) = {0};
uint64_t hash_pos = block_index * sizeof(hash_buffer); uint64_t hash_pos = block_index * sizeof(hash_buffer);
if (substorage_read(&ctx->hash_storage, hash_buffer, hash_pos, sizeof(hash_buffer)) != sizeof(hash_buffer)) if (substorage_read(&ctx->hash_storage, hash_buffer, hash_pos, sizeof(hash_buffer)) != sizeof(hash_buffer))
@ -99,17 +99,16 @@ bool save_ivfc_storage_read(integrity_verification_storage_ctx_t *ctx, void *buf
return false; return false;
} }
if (ctx->integrity_check_level && ctx->block_validities[block_index] != VALIDITY_UNCHECKED) {
memcpy(buffer, data_buffer + 0x20 + (offset % ctx->base_storage.sector_size), count); memcpy(buffer, data_buffer + 0x20 + (offset % ctx->base_storage.sector_size), count);
if (ctx->integrity_check_level && ctx->block_validities[block_index] != VALIDITY_UNCHECKED) {
free(data_buffer); free(data_buffer);
return true; return true;
} }
uint8_t hash[0x20] = {0}; uint8_t hash[0x20] __attribute__((aligned(4))) = {0};
save_ivfc_storage_do_hash(ctx, hash, data_buffer, ctx->base_storage.sector_size); save_ivfc_storage_do_hash(ctx, hash, data_buffer, ctx->base_storage.sector_size);
memcpy(buffer, data_buffer + 0x20 + (offset % ctx->base_storage.sector_size), count);
free(data_buffer); free(data_buffer);
if (memcmp(hash_buffer, hash, sizeof(hash_buffer)) == 0) { if (memcmp(hash_buffer, hash, sizeof(hash_buffer)) == 0) {
ctx->block_validities[block_index] = VALIDITY_VALID; ctx->block_validities[block_index] = VALIDITY_VALID;
} else { } else {
@ -127,7 +126,7 @@ bool save_ivfc_storage_write(integrity_verification_storage_ctx_t *ctx, const vo
uint64_t block_index = offset / ctx->base_storage.sector_size; uint64_t block_index = offset / ctx->base_storage.sector_size;
uint64_t hash_pos = block_index * 0x20; uint64_t hash_pos = block_index * 0x20;
uint8_t hash[0x20] = {0}; uint8_t hash[0x20] __attribute__((aligned(4))) = {0};
uint8_t *data_buffer = calloc(1, ctx->base_storage.sector_size + 0x20); uint8_t *data_buffer = calloc(1, ctx->base_storage.sector_size + 0x20);
if (count < ctx->base_storage.sector_size) { if (count < ctx->base_storage.sector_size) {
if (substorage_read(&ctx->base_storage.base_storage, data_buffer + 0x20, offset - (offset % ctx->base_storage.sector_size), ctx->base_storage.sector_size) != ctx->base_storage.sector_size) { if (substorage_read(&ctx->base_storage.base_storage, data_buffer + 0x20, offset - (offset % ctx->base_storage.sector_size), ctx->base_storage.sector_size) != ctx->base_storage.sector_size) {

View File

@ -102,7 +102,7 @@ uint32_t save_remap_storage_read(remap_storage_ctx_t *ctx, void *buffer, uint64_
} }
uint64_t in_pos = offset; uint64_t in_pos = offset;
uint32_t out_pos = 0; uint32_t out_pos = 0;
uint32_t remaining = count; uint32_t remaining = (u32)count;
while (remaining) { while (remaining) {
uint64_t entry_pos = in_pos - entry->entry.virtual_offset; uint64_t entry_pos = in_pos - entry->entry.virtual_offset;
@ -135,7 +135,7 @@ uint32_t save_remap_storage_write(remap_storage_ctx_t *ctx, const void *buffer,
} }
uint64_t in_pos = offset; uint64_t in_pos = offset;
uint32_t out_pos = 0; uint32_t out_pos = 0;
uint32_t remaining = count; uint32_t remaining = (u32)count;
while (remaining) { while (remaining) {
uint64_t entry_pos = in_pos - entry->entry.virtual_offset; uint64_t entry_pos = in_pos - entry->entry.virtual_offset;

View File

@ -98,13 +98,13 @@ static bool save_process_header(save_ctx_t *ctx) {
ctx->data_ivfc_master = (uint8_t *)&ctx->header + ctx->header.layout.ivfc_master_hash_offset_a; ctx->data_ivfc_master = (uint8_t *)&ctx->header + ctx->header.layout.ivfc_master_hash_offset_a;
ctx->fat_ivfc_master = (uint8_t *)&ctx->header + ctx->header.layout.fat_ivfc_master_hash_a; ctx->fat_ivfc_master = (uint8_t *)&ctx->header + ctx->header.layout.fat_ivfc_master_hash_a;
uint8_t hash[0x20]; uint8_t hash[0x20] __attribute__((aligned(4)));
uint32_t hashed_data_offset = sizeof(ctx->header.layout) + sizeof(ctx->header.cmac) + sizeof(ctx->header._0x10); uint32_t hashed_data_offset = sizeof(ctx->header.layout) + sizeof(ctx->header.cmac) + sizeof(ctx->header._0x10);
uint32_t hashed_data_size = sizeof(ctx->header) - hashed_data_offset; uint32_t hashed_data_size = sizeof(ctx->header) - hashed_data_offset;
se_calc_sha256(hash, (uint8_t *)&ctx->header + hashed_data_offset, hashed_data_size); se_calc_sha256_oneshot(hash, (uint8_t *)&ctx->header + hashed_data_offset, hashed_data_size);
ctx->header_hash_validity = memcmp(hash, ctx->header.layout.hash, 0x20) == 0 ? VALIDITY_VALID : VALIDITY_INVALID; ctx->header_hash_validity = memcmp(hash, ctx->header.layout.hash, sizeof(hash)) == 0 ? VALIDITY_VALID : VALIDITY_INVALID;
unsigned char cmac[0x10] = {}; uint8_t cmac[0x10] __attribute__((aligned(4)));
se_aes_key_set(10, ctx->save_mac_key, 0x10); se_aes_key_set(10, ctx->save_mac_key, 0x10);
se_aes_cmac(10, cmac, 0x10, &ctx->header.layout, sizeof(ctx->header.layout)); se_aes_cmac(10, cmac, 0x10, &ctx->header.layout, sizeof(ctx->header.layout));
if (memcmp(cmac, &ctx->header.cmac, 0x10) == 0) { if (memcmp(cmac, &ctx->header.cmac, 0x10) == 0) {
@ -126,14 +126,14 @@ bool save_process(save_ctx_t *ctx) {
substorage_init(&ctx->base_storage, &file_storage_vt, ctx->file, 0, f_size(ctx->file)); substorage_init(&ctx->base_storage, &file_storage_vt, ctx->file, 0, f_size(ctx->file));
/* Try to parse Header A. */ /* Try to parse Header A. */
if (substorage_read(&ctx->base_storage, &ctx->header, 0, sizeof(ctx->header)) != sizeof(ctx->header)) { if (substorage_read(&ctx->base_storage, &ctx->header, 0, sizeof(ctx->header)) != sizeof(ctx->header)) {
EPRINTF("Failed to read save header!\n"); EPRINTF("Failed to read save header A!\n");
return false; return false;
} }
if (!save_process_header(ctx) || (ctx->header_hash_validity == VALIDITY_INVALID)) { if (!save_process_header(ctx) || (ctx->header_hash_validity == VALIDITY_INVALID)) {
/* Try to parse Header B. */ /* Try to parse Header B. */
if (substorage_read(&ctx->base_storage, &ctx->header, sizeof(ctx->header), sizeof(ctx->header)) != sizeof(ctx->header)) { if (substorage_read(&ctx->base_storage, &ctx->header, sizeof(ctx->header), sizeof(ctx->header)) != sizeof(ctx->header)) {
EPRINTF("Failed to read save header!\n"); EPRINTF("Failed to read save header B!\n");
return false; return false;
} }
@ -143,14 +143,22 @@ bool save_process(save_ctx_t *ctx) {
} }
} }
if (ctx->header.layout.version > VERSION_DISF_5) {
EPRINTF("Unsupported save version.\nLibrary must be updated.");
return false;
}
/* Initialize remap storages. */ /* Initialize remap storages. */
ctx->data_remap_storage.header = &ctx->header.main_remap_header; ctx->data_remap_storage.header = &ctx->header.main_remap_header;
ctx->meta_remap_storage.header = &ctx->header.meta_remap_header; ctx->meta_remap_storage.header = &ctx->header.meta_remap_header;
u32 data_remap_entry_size = sizeof(remap_entry_t) * ctx->data_remap_storage.header->map_entry_count;
u32 meta_remap_entry_size = sizeof(remap_entry_t) * ctx->meta_remap_storage.header->map_entry_count;
substorage_init(&ctx->data_remap_storage.base_storage, &file_storage_vt, ctx->file, ctx->header.layout.file_map_data_offset, ctx->header.layout.file_map_data_size); substorage_init(&ctx->data_remap_storage.base_storage, &file_storage_vt, ctx->file, ctx->header.layout.file_map_data_offset, ctx->header.layout.file_map_data_size);
ctx->data_remap_storage.map_entries = calloc(1, sizeof(remap_entry_ctx_t) * ctx->data_remap_storage.header->map_entry_count); ctx->data_remap_storage.map_entries = calloc(1, sizeof(remap_entry_ctx_t) * ctx->data_remap_storage.header->map_entry_count);
uint8_t *remap_buffer = malloc(MAX(ctx->data_remap_storage.header->map_entry_count, ctx->meta_remap_storage.header->map_entry_count) * sizeof(remap_entry_t)); uint8_t *remap_buffer = malloc(MAX(data_remap_entry_size, meta_remap_entry_size));
if (substorage_read(&ctx->base_storage, remap_buffer, ctx->header.layout.file_map_entry_offset, sizeof(remap_entry_t) * ctx->data_remap_storage.header->map_entry_count) != sizeof(remap_entry_t) * ctx->data_remap_storage.header->map_entry_count) { if (substorage_read(&ctx->base_storage, remap_buffer, ctx->header.layout.file_map_entry_offset, data_remap_entry_size) != data_remap_entry_size) {
EPRINTF("Failed to read data remap table!"); EPRINTF("Failed to read data remap table!");
free(remap_buffer); free(remap_buffer);
return false; return false;
@ -177,7 +185,7 @@ bool save_process(save_ctx_t *ctx) {
/* Initialize meta remap storage. */ /* Initialize meta remap storage. */
substorage_init(&ctx->meta_remap_storage.base_storage, &hierarchical_duplex_storage_vt, &ctx->duplex_storage, 0, ctx->duplex_storage.data_layer->_length); substorage_init(&ctx->meta_remap_storage.base_storage, &hierarchical_duplex_storage_vt, &ctx->duplex_storage, 0, ctx->duplex_storage.data_layer->_length);
ctx->meta_remap_storage.map_entries = calloc(1, sizeof(remap_entry_ctx_t) * ctx->meta_remap_storage.header->map_entry_count); ctx->meta_remap_storage.map_entries = calloc(1, sizeof(remap_entry_ctx_t) * ctx->meta_remap_storage.header->map_entry_count);
if (substorage_read(&ctx->base_storage, remap_buffer, ctx->header.layout.meta_map_entry_offset, sizeof(remap_entry_t) * ctx->meta_remap_storage.header->map_entry_count) != sizeof(remap_entry_t) * ctx->meta_remap_storage.header->map_entry_count) { if (substorage_read(&ctx->base_storage, remap_buffer, ctx->header.layout.meta_map_entry_offset, meta_remap_entry_size) != meta_remap_entry_size) {
EPRINTF("Failed to read meta remap table!"); EPRINTF("Failed to read meta remap table!");
free(remap_buffer); free(remap_buffer);
return false; return false;
@ -225,42 +233,68 @@ bool save_process(save_ctx_t *ctx) {
} }
/* Initialize core save filesystem. */ /* Initialize core save filesystem. */
save_data_file_system_core_init(&ctx->save_filesystem_core, &ctx->core_data_ivfc_storage.base_storage, ctx->fat_storage, &ctx->header.save_header); return save_data_file_system_core_init(&ctx->save_filesystem_core, &ctx->core_data_ivfc_storage.base_storage, ctx->fat_storage, &ctx->header.save_header);
return true;
} }
void save_free_contexts(save_ctx_t *ctx) { void save_free_contexts(save_ctx_t *ctx) {
if (ctx->data_remap_storage.header) {
for (unsigned int i = 0; i < ctx->data_remap_storage.header->map_segment_count; i++) { for (unsigned int i = 0; i < ctx->data_remap_storage.header->map_segment_count; i++) {
if (ctx->data_remap_storage.segments && ctx->data_remap_storage.segments[i].entries)
free(ctx->data_remap_storage.segments[i].entries); free(ctx->data_remap_storage.segments[i].entries);
} }
}
if (ctx->data_remap_storage.segments)
free(ctx->data_remap_storage.segments); free(ctx->data_remap_storage.segments);
if (ctx->meta_remap_storage.header) {
for (unsigned int i = 0; i < ctx->meta_remap_storage.header->map_segment_count; i++) { for (unsigned int i = 0; i < ctx->meta_remap_storage.header->map_segment_count; i++) {
if (ctx->meta_remap_storage.segments && ctx->meta_remap_storage.segments[i].entries)
free(ctx->meta_remap_storage.segments[i].entries); free(ctx->meta_remap_storage.segments[i].entries);
} }
}
if (ctx->meta_remap_storage.segments)
free(ctx->meta_remap_storage.segments); free(ctx->meta_remap_storage.segments);
if (ctx->data_remap_storage.map_entries)
free(ctx->data_remap_storage.map_entries); free(ctx->data_remap_storage.map_entries);
if (ctx->meta_remap_storage.map_entries)
free(ctx->meta_remap_storage.map_entries); free(ctx->meta_remap_storage.map_entries);
for (unsigned int i = 0; i < 2; i++) { for (unsigned int i = 0; i < 2; i++) {
if (ctx->duplex_storage.layers[i].bitmap.bitmap)
free(ctx->duplex_storage.layers[i].bitmap.bitmap); free(ctx->duplex_storage.layers[i].bitmap.bitmap);
if (ctx->duplex_storage.layers[i].data_a.base_storage.ctx)
free(ctx->duplex_storage.layers[i].data_a.base_storage.ctx); free(ctx->duplex_storage.layers[i].data_a.base_storage.ctx);
if (ctx->duplex_storage.layers[i].data_b.base_storage.ctx)
free(ctx->duplex_storage.layers[i].data_b.base_storage.ctx); free(ctx->duplex_storage.layers[i].data_b.base_storage.ctx);
} }
if (ctx->duplex_storage.layers[1].bitmap_storage.base_storage.ctx)
free(ctx->duplex_storage.layers[1].bitmap_storage.base_storage.ctx); free(ctx->duplex_storage.layers[1].bitmap_storage.base_storage.ctx);
if (ctx->journal_storage.map.map_storage)
free(ctx->journal_storage.map.map_storage); free(ctx->journal_storage.map.map_storage);
if (ctx->journal_storage.map.entries)
free(ctx->journal_storage.map.entries); free(ctx->journal_storage.map.entries);
for (unsigned int i = 0; i < 4; i++) { for (unsigned int i = 0; i < 4; i++) {
if (ctx->core_data_ivfc_storage.integrity_storages[i].block_validities)
free(ctx->core_data_ivfc_storage.integrity_storages[i].block_validities); free(ctx->core_data_ivfc_storage.integrity_storages[i].block_validities);
save_cached_storage_finalize(&ctx->core_data_ivfc_storage.levels[i + 1]); save_cached_storage_finalize(&ctx->core_data_ivfc_storage.levels[i + 1]);
} }
if (ctx->core_data_ivfc_storage.level_validities)
free(ctx->core_data_ivfc_storage.level_validities); free(ctx->core_data_ivfc_storage.level_validities);
if (ctx->header.layout.version >= VERSION_DISF_5) { if (ctx->header.layout.version >= VERSION_DISF_5) {
for (unsigned int i = 0; i < 3; i++) { for (unsigned int i = 0; i < 3; i++) {
if (ctx->fat_ivfc_storage.integrity_storages[i].block_validities)
free(ctx->fat_ivfc_storage.integrity_storages[i].block_validities); free(ctx->fat_ivfc_storage.integrity_storages[i].block_validities);
save_cached_storage_finalize(&ctx->fat_ivfc_storage.levels[i + 1]); save_cached_storage_finalize(&ctx->fat_ivfc_storage.levels[i + 1]);
} }
} }
if (ctx->fat_ivfc_storage.level_validities)
free(ctx->fat_ivfc_storage.level_validities); free(ctx->fat_ivfc_storage.level_validities);
if (ctx->fat_storage)
free(ctx->fat_storage); free(ctx->fat_storage);
} }
@ -292,7 +326,7 @@ bool save_commit(save_ctx_t *ctx) {
uint32_t hashed_data_offset = sizeof(ctx->header.layout) + sizeof(ctx->header.cmac) + sizeof(ctx->header._0x10); uint32_t hashed_data_offset = sizeof(ctx->header.layout) + sizeof(ctx->header.cmac) + sizeof(ctx->header._0x10);
uint32_t hashed_data_size = sizeof(ctx->header) - hashed_data_offset; uint32_t hashed_data_size = sizeof(ctx->header) - hashed_data_offset;
uint8_t *header = (uint8_t *)&ctx->header; uint8_t *header = (uint8_t *)&ctx->header;
se_calc_sha256(ctx->header.layout.hash, header + hashed_data_offset, hashed_data_size); se_calc_sha256_oneshot(ctx->header.layout.hash, header + hashed_data_offset, hashed_data_size);
se_aes_key_set(10, ctx->save_mac_key, 0x10); se_aes_key_set(10, ctx->save_mac_key, 0x10);
se_aes_cmac(10, ctx->header.cmac, 0x10, &ctx->header.layout, sizeof(ctx->header.layout)); se_aes_cmac(10, ctx->header.cmac, 0x10, &ctx->header.layout, sizeof(ctx->header.layout));

View File

@ -38,7 +38,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
void save_data_file_init(save_data_file_ctx_t *ctx, allocation_table_storage_ctx_t *base_storage, const char *path, hierarchical_save_file_table_ctx_t *file_table, uint64_t size, open_mode_t mode) { void save_data_file_init(save_data_file_ctx_t *ctx, allocation_table_storage_ctx_t *base_storage, const char *path, hierarchical_save_file_table_ctx_t *file_table, uint64_t size, open_mode_t mode) {
ctx->mode = mode; ctx->mode = mode;
memcpy(&ctx->base_storage, base_storage, sizeof(ctx->base_storage)); memcpy(&ctx->base_storage, base_storage, sizeof(allocation_table_storage_ctx_t));
ctx->path = path; ctx->path = path;
ctx->file_table = file_table; ctx->file_table = file_table;
ctx->size = size; ctx->size = size;

View File

@ -41,21 +41,29 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <gfx_utils.h> #include <gfx_utils.h>
#include <mem/heap.h> #include <mem/heap.h>
static ALWAYS_INLINE void save_data_file_system_core_open_fat_storage(save_data_file_system_core_ctx_t *ctx, allocation_table_storage_ctx_t *storage_ctx, uint32_t block_index) { static ALWAYS_INLINE bool save_data_file_system_core_open_fat_storage(save_data_file_system_core_ctx_t *ctx, allocation_table_storage_ctx_t *storage_ctx, uint32_t block_index) {
save_allocation_table_storage_init(storage_ctx, ctx->base_storage, &ctx->allocation_table, (uint32_t)ctx->header->block_size, block_index); return save_allocation_table_storage_init(storage_ctx, ctx->base_storage, &ctx->allocation_table, (uint32_t)ctx->header->block_size, block_index);
} }
void save_data_file_system_core_init(save_data_file_system_core_ctx_t *ctx, substorage *storage, void *allocation_table, save_fs_header_t *save_fs_header) { bool save_data_file_system_core_init(save_data_file_system_core_ctx_t *ctx, substorage *storage, void *allocation_table, save_fs_header_t *save_fs_header) {
save_allocation_table_init(&ctx->allocation_table, allocation_table, &save_fs_header->fat_header); save_allocation_table_init(&ctx->allocation_table, allocation_table, &save_fs_header->fat_header);
ctx->header = save_fs_header; ctx->header = save_fs_header;
ctx->base_storage = storage; ctx->base_storage = storage;
save_filesystem_list_ctx_t *dir_table = &ctx->file_table.directory_table; save_filesystem_list_ctx_t *dir_table = &ctx->file_table.directory_table;
save_filesystem_list_ctx_t *file_table = &ctx->file_table.file_table; save_filesystem_list_ctx_t *file_table = &ctx->file_table.file_table;
save_data_file_system_core_open_fat_storage(ctx, &dir_table->storage, save_fs_header->fat_header.directory_table_block); if (!save_data_file_system_core_open_fat_storage(ctx, &dir_table->storage, save_fs_header->fat_header.directory_table_block)) {
save_data_file_system_core_open_fat_storage(ctx, &file_table->storage, save_fs_header->fat_header.file_table_block); EPRINTF("Failed to init dir table for fs core!");
return false;
}
if (!save_data_file_system_core_open_fat_storage(ctx, &file_table->storage, save_fs_header->fat_header.file_table_block)) {
EPRINTF("Failed to init file table for fs core!");
return false;
}
save_fs_list_init(dir_table); save_fs_list_init(dir_table);
save_fs_list_init(file_table); save_fs_list_init(file_table);
return true;
} }
bool save_data_file_system_core_create_directory(save_data_file_system_core_ctx_t *ctx, const char *path) { bool save_data_file_system_core_create_directory(save_data_file_system_core_ctx_t *ctx, const char *path) {

View File

@ -66,7 +66,7 @@ static ALWAYS_INLINE void save_data_file_system_core_get_total_space_size(save_d
*out_total_space = ctx->header->block_size * ctx->header->block_count; *out_total_space = ctx->header->block_size * ctx->header->block_count;
} }
void save_data_file_system_core_init(save_data_file_system_core_ctx_t *ctx, substorage *storage, void *allocation_table, save_fs_header_t *save_fs_header); bool save_data_file_system_core_init(save_data_file_system_core_ctx_t *ctx, substorage *storage, void *allocation_table, save_fs_header_t *save_fs_header);
bool save_data_file_system_core_create_directory(save_data_file_system_core_ctx_t *ctx, const char *path); bool save_data_file_system_core_create_directory(save_data_file_system_core_ctx_t *ctx, const char *path);
bool save_data_file_system_core_create_file(save_data_file_system_core_ctx_t *ctx, const char *path, uint64_t size); bool save_data_file_system_core_create_file(save_data_file_system_core_ctx_t *ctx, const char *path, uint64_t size);

View File

@ -45,11 +45,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <string.h> #include <string.h>
void storage_init(storage *this, const storage_vt *vt, void *ctx) {
this->vt = vt;
this->ctx = ctx;
}
void substorage_init(substorage *this, const storage_vt *vt, void *ctx, uint64_t offset, uint64_t length) { void substorage_init(substorage *this, const storage_vt *vt, void *ctx, uint64_t offset, uint64_t length) {
storage_init(&this->base_storage, vt, ctx); storage_init(&this->base_storage, vt, ctx);
this->offset = offset; this->offset = offset;

View File

@ -51,7 +51,10 @@ typedef struct {
void *ctx; void *ctx;
} storage; } storage;
void storage_init(storage *this, const storage_vt *vt, void *ctx); static void ALWAYS_INLINE storage_init(storage *this, const storage_vt *vt, void *ctx) {
this->vt = vt;
this->ctx = ctx;
}
typedef struct { typedef struct {
uint64_t offset; uint64_t offset;

View File

@ -72,6 +72,7 @@
#define EMC_PDEX2MRR 0xb4 #define EMC_PDEX2MRR 0xb4
#define EMC_ODT_WRITE 0xb0 #define EMC_ODT_WRITE 0xb0
#define EMC_WEXT 0xb8 #define EMC_WEXT 0xb8
#define EMC_CTT 0xBC
#define EMC_RFC_SLR 0xc0 #define EMC_RFC_SLR 0xc0
#define EMC_MRS_WAIT_CNT2 0xc4 #define EMC_MRS_WAIT_CNT2 0xc4
#define EMC_MRS_WAIT_CNT 0xc8 #define EMC_MRS_WAIT_CNT 0xc8
@ -86,8 +87,13 @@
#define EMC_MRR 0xec #define EMC_MRR 0xec
#define EMC_CMDQ 0xf0 #define EMC_CMDQ 0xf0
#define EMC_MC2EMCQ 0xf4 #define EMC_MC2EMCQ 0xf4
#define EMC_FBIO_TWTM 0xF8
#define EMC_FBIO_TRATM 0xFC
#define EMC_FBIO_TWATM 0x108
#define EMC_FBIO_TR2REF 0x10C
#define EMC_FBIO_SPARE 0x100 #define EMC_FBIO_SPARE 0x100
#define EMC_FBIO_CFG5 0x104 #define EMC_FBIO_CFG5 0x104
#define EMC_FBIO_CFG6 0x114
#define EMC_CFG_RSV 0x120 #define EMC_CFG_RSV 0x120
#define EMC_ACPD_CONTROL 0x124 #define EMC_ACPD_CONTROL 0x124
#define EMC_MPC 0x128 #define EMC_MPC 0x128
@ -211,6 +217,7 @@
#define EMC_AUTO_CAL_CONFIG6 0x5cc #define EMC_AUTO_CAL_CONFIG6 0x5cc
#define EMC_AUTO_CAL_CONFIG7 0x574 #define EMC_AUTO_CAL_CONFIG7 0x574
#define EMC_AUTO_CAL_CONFIG8 0x2dc #define EMC_AUTO_CAL_CONFIG8 0x2dc
#define EMC_AUTO_CAL_CONFIG9 0x42C
#define EMC_AUTO_CAL_VREF_SEL_0 0x2f8 #define EMC_AUTO_CAL_VREF_SEL_0 0x2f8
#define EMC_AUTO_CAL_VREF_SEL_1 0x300 #define EMC_AUTO_CAL_VREF_SEL_1 0x300
#define EMC_AUTO_CAL_INTERVAL 0x2a8 #define EMC_AUTO_CAL_INTERVAL 0x2a8
@ -232,7 +239,7 @@
#define EMC_COMP_PAD_SW_CTRL 0x57c #define EMC_COMP_PAD_SW_CTRL 0x57c
#define EMC_REQ_CTRL 0x2b0 #define EMC_REQ_CTRL 0x2b0
#define EMC_EMC_STATUS 0x2b4 #define EMC_EMC_STATUS 0x2b4
#define EMC_STATUS_MRR_DIVLD (1 << 20) #define EMC_STATUS_MRR_DIVLD BIT(20)
#define EMC_CFG_2 0x2b8 #define EMC_CFG_2 0x2b8
#define EMC_CFG_DIG_DLL 0x2bc #define EMC_CFG_DIG_DLL 0x2bc
#define EMC_CFG_DIG_DLL_PERIOD 0x2c0 #define EMC_CFG_DIG_DLL_PERIOD 0x2c0
@ -386,6 +393,8 @@
#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK0 0xed4 #define EMC_TRAINING_OPT_DQS_IB_VREF_RANK0 0xed4
#define EMC_TRAINING_OPT_DQS_IB_VREF_RANK1 0xed8 #define EMC_TRAINING_OPT_DQS_IB_VREF_RANK1 0xed8
#define EMC_TRAINING_DRAMC_TIMING 0xedc #define EMC_TRAINING_DRAMC_TIMING 0xedc
#define EMC_PMACRO_DATA_PI_CTRL 0x110
#define EMC_PMACRO_CMD_PI_CTRL 0x114
#define EMC_PMACRO_QUSE_DDLL_RANK0_0 0x600 #define EMC_PMACRO_QUSE_DDLL_RANK0_0 0x600
#define EMC_PMACRO_QUSE_DDLL_RANK0_1 0x604 #define EMC_PMACRO_QUSE_DDLL_RANK0_1 0x604
#define EMC_PMACRO_QUSE_DDLL_RANK0_2 0x608 #define EMC_PMACRO_QUSE_DDLL_RANK0_2 0x608
@ -650,6 +659,7 @@
#define EMC_PMACRO_CMD_PAD_TX_CTRL 0xc60 #define EMC_PMACRO_CMD_PAD_TX_CTRL 0xc60
#define EMC_PMACRO_DATA_PAD_TX_CTRL 0xc64 #define EMC_PMACRO_DATA_PAD_TX_CTRL 0xc64
#define EMC_PMACRO_COMMON_PAD_TX_CTRL 0xc68 #define EMC_PMACRO_COMMON_PAD_TX_CTRL 0xc68
#define EMC_PMACRO_DSR_VTTGEN_CTRL0 0xC6C
#define EMC_PMACRO_BRICK_MAPPING_0 0xc80 #define EMC_PMACRO_BRICK_MAPPING_0 0xc80
#define EMC_PMACRO_BRICK_MAPPING_1 0xc84 #define EMC_PMACRO_BRICK_MAPPING_1 0xc84
#define EMC_PMACRO_BRICK_MAPPING_2 0xc88 #define EMC_PMACRO_BRICK_MAPPING_2 0xc88
@ -662,6 +672,24 @@
#define EMC_PMACRO_DATA_BRICK_CTRL_FDPD 0x31c #define EMC_PMACRO_DATA_BRICK_CTRL_FDPD 0x31c
#define EMC_PMACRO_TRAINING_CTRL_0 0xcf8 #define EMC_PMACRO_TRAINING_CTRL_0 0xcf8
#define EMC_PMACRO_TRAINING_CTRL_1 0xcfc #define EMC_PMACRO_TRAINING_CTRL_1 0xcfc
#define EMC_PMACRO_PERBIT_FGCG_CTRL_0 0xD40
#define EMC_PMACRO_PERBIT_FGCG_CTRL_1 0xD44
#define EMC_PMACRO_PERBIT_FGCG_CTRL_2 0xD48
#define EMC_PMACRO_PERBIT_FGCG_CTRL_3 0xD4C
#define EMC_PMACRO_PERBIT_FGCG_CTRL_4 0xD50
#define EMC_PMACRO_PERBIT_FGCG_CTRL_5 0xD54
#define EMC_PMACRO_PERBIT_RFU_CTRL_0 0xD60
#define EMC_PMACRO_PERBIT_RFU_CTRL_1 0xD64
#define EMC_PMACRO_PERBIT_RFU_CTRL_2 0xD68
#define EMC_PMACRO_PERBIT_RFU_CTRL_3 0xD6C
#define EMC_PMACRO_PERBIT_RFU_CTRL_4 0xD70
#define EMC_PMACRO_PERBIT_RFU_CTRL_5 0xD74
#define EMC_PMACRO_PERBIT_RFU1_CTRL_0 0xD80
#define EMC_PMACRO_PERBIT_RFU1_CTRL_1 0xD84
#define EMC_PMACRO_PERBIT_RFU1_CTRL_2 0xD88
#define EMC_PMACRO_PERBIT_RFU1_CTRL_3 0xD8C
#define EMC_PMACRO_PERBIT_RFU1_CTRL_4 0xD90
#define EMC_PMACRO_PERBIT_RFU1_CTRL_5 0xD94
#define EMC_PMC_SCRATCH1 0x440 #define EMC_PMC_SCRATCH1 0x440
#define EMC_PMC_SCRATCH2 0x444 #define EMC_PMC_SCRATCH2 0x444
#define EMC_PMC_SCRATCH3 0x448 #define EMC_PMC_SCRATCH3 0x448
@ -684,10 +712,13 @@ enum
typedef struct _emc_mr_data_t typedef struct _emc_mr_data_t
{ {
u8 dev0_ch0; // Device 0.
u8 dev0_ch1; u8 rank0_ch0;
u8 dev1_ch0; u8 rank0_ch1;
u8 dev1_ch1;
// Device 1.
u8 rank1_ch0;
u8 rank1_ch1;
} emc_mr_data_t; } emc_mr_data_t;
#endif #endif

View File

@ -144,13 +144,12 @@ void mc_disable_ahb_redirect()
void mc_enable() void mc_enable()
{ {
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) | 0x40000000;
// Enable EMC clock. // Enable memory clocks.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFDFFFFFF) | 0x2000000; CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & ~BIT(CLK_H_EMC)) | BIT(CLK_H_EMC);
// Enable MC clock. CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & ~BIT(CLK_H_MEM)) | BIT(CLK_H_MEM);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFFFFFFFE) | 1; CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & ~BIT(CLK_X_EMC_DLL)) | BIT(CLK_X_EMC_DLL);
// Enable EMC DLL clock. // Clear clock resets for memory.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & 0xFFFFBFFF) | 0x4000; CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x2000001; //Clear EMC and MC reset.
usleep(5); usleep(5);
//#ifdef CONFIG_ENABLE_AHB_REDIRECT //#ifdef CONFIG_ENABLE_AHB_REDIRECT

View File

@ -461,6 +461,7 @@
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 0xc6c #define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 0xc6c
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 0xd08 #define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 0xd08
#define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0 #define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0
#define MC_UNTRANSLATED_REGION_CHECK 0x948
#define MC_DA_CONFIG0 0x9dc #define MC_DA_CONFIG0 0x9dc
// MC_SECURITY_CARVEOUTX_CFG0 // MC_SECURITY_CARVEOUTX_CFG0
@ -503,14 +504,14 @@
#define SEC_CARVEOUT_CFG_DIS_WR_CHECK_L2 (4 << 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_L3 (8 << DISABLE_WRITE_CHECK_ACCESS_LEVEL_SHIFT)
#define SEC_CARVEOUT_CFG_SEND_CFG_TO_GPU (1 << 22) #define SEC_CARVEOUT_CFG_SEND_CFG_TO_GPU BIT(22)
#define SEC_CARVEOUT_CFG_TZ_GLOBAL_WR_EN_BYPASS_CHECK (1 << 23) #define SEC_CARVEOUT_CFG_TZ_GLOBAL_WR_EN_BYPASS_CHECK BIT(23)
#define SEC_CARVEOUT_CFG_TZ_GLOBAL_RD_EN_BYPASS_CHECK (1 << 24) #define SEC_CARVEOUT_CFG_TZ_GLOBAL_RD_EN_BYPASS_CHECK BIT(24)
#define SEC_CARVEOUT_CFG_ALLOW_APERTURE_ID_MISMATCH (1 << 25) #define SEC_CARVEOUT_CFG_ALLOW_APERTURE_ID_MISMATCH BIT(25)
#define SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH (1 << 26) #define SEC_CARVEOUT_CFG_FORCE_APERTURE_ID_MATCH BIT(26)
#define SEC_CARVEOUT_CFG_IS_WPR (1 << 27) #define SEC_CARVEOUT_CFG_IS_WPR BIT(27)
#endif #endif

View File

@ -23,6 +23,7 @@
#include <ianos/ianos.h> #include <ianos/ianos.h>
#include <soc/clock.h> #include <soc/clock.h>
#include <soc/fuse.h> #include <soc/fuse.h>
#include <soc/hw_init.h>
#include <soc/t210.h> #include <soc/t210.h>
#include <utils/util.h> #include <utils/util.h>
@ -37,6 +38,10 @@ u32 minerva_init()
minerva_cfg = NULL; minerva_cfg = NULL;
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg; mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
//!TODO: Not supported on T210B01 yet.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
return 0;
#ifdef NYX #ifdef NYX
// Set table to nyx storage. // Set table to nyx storage.
mtc_cfg->mtc_table = (emc_table_t *)nyx_str->mtc_table; mtc_cfg->mtc_table = (emc_table_t *)nyx_str->mtc_table;
@ -48,7 +53,7 @@ u32 minerva_init()
u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg); u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg);
minerva_cfg = (void *)ep_addr; minerva_cfg = (void *)ep_addr;
return 0; return !minerva_cfg ? 1 : 0;
} }
else else
{ {

View File

@ -20,12 +20,15 @@
#include <mem/mc.h> #include <mem/mc.h>
#include <mem/emc.h> #include <mem/emc.h>
#include <mem/sdram.h>
#include <mem/sdram_param_t210.h> #include <mem/sdram_param_t210.h>
#include <mem/sdram_param_t210b01.h>
#include <memory_map.h> #include <memory_map.h>
#include <power/max77620.h> #include <power/max77620.h>
#include <power/max7762x.h> #include <power/max7762x.h>
#include <soc/clock.h> #include <soc/clock.h>
#include <soc/fuse.h> #include <soc/fuse.h>
#include <soc/hw_init.h>
#include <soc/i2c.h> #include <soc/i2c.h>
#include <soc/pmc.h> #include <soc/pmc.h>
#include <soc/t210.h> #include <soc/t210.h>
@ -33,14 +36,25 @@
#define CONFIG_SDRAM_KEEP_ALIVE #define CONFIG_SDRAM_KEEP_ALIVE
//#define CONFIG_SDRAM_COMPRESS_CFG
typedef struct _sdram_vendor_patch_t
{
u32 val;
u32 addr:10;
u32 dramid:22;
} sdram_vendor_patch_t;
#ifdef CONFIG_SDRAM_COMPRESS_CFG #ifdef CONFIG_SDRAM_COMPRESS_CFG
#include <libs/compr/lz.h> #include <libs/compr/lz.h>
#include "sdram_config_lz.inl" #include "sdram_config_lz.inl"
#else #else
#include "sdram_config.inl" #include "sdram_config.inl"
#endif #endif
static u32 _get_sdram_id() #include "sdram_config_t210b01.inl"
static u32 _sdram_get_id()
{ {
return ((fuse_read_odm(4) & 0xF8) >> 3); return ((fuse_read_odm(4) & 0xF8) >> 3);
} }
@ -85,17 +99,26 @@ 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 sdram_read_mrx(emc_mr_t mrx)
{ {
emc_mr_data_t data; emc_mr_data_t data;
_sdram_req_mrr_data((1 << 31) | (mrx << 16), EMC_CHAN0);
data.dev0_ch0 = EMC(EMC_MRR) & 0xFF; /*
data.dev0_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8); * When a dram chip has only one rank, then the info from the 2 ranks differs.
_sdram_req_mrr_data((1 << 30) | (mrx << 16), EMC_CHAN1); * Info not matching is only allowed on different channels.
data.dev1_ch0 = EMC(EMC_MRR) & 0xFF; */
data.dev1_ch1 = (EMC(EMC_MRR) & 0xFF00 >> 8);
// Get Device 0 (Rank 0) info from both dram chips (channels).
_sdram_req_mrr_data(BIT(31) | (mrx << 16), EMC_CHAN0);
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);
return data; return data;
} }
static void _sdram_config(const sdram_params_t *params) static void _sdram_config_t210(const sdram_params_t210_t *params)
{ {
// Program DPD3/DPD4 regs (coldboot path). // Program DPD3/DPD4 regs (coldboot path).
// Enable sel_dpd on unused pins. // Enable sel_dpd on unused pins.
@ -143,9 +166,10 @@ break_nosleep:
if (params->clear_clock2_mc1) if (params->clear_clock2_mc1)
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000; // Clear Reset to MC1. CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000; // Clear Reset to MC1.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x2000001; // Enable EMC and MEM clocks. // Enable and clear reset for memory clocks.
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x4000; // Enable EMC_DLL clock. CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x2000001; // Clear EMC and MEM resets. CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_EMC_DLL);
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_EMC) | BIT(CLK_H_MEM);
// Set pad macros. // Set pad macros.
EMC(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0; EMC(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0;
@ -540,7 +564,7 @@ break_nosleep:
EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000; EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;
// Patch BootROM. // Patch BootROM.
if (params->boot_rom_patch_control & (1 << 31)) if (params->boot_rom_patch_control & BIT(31))
{ {
*(vu32 *)(APB_MISC_BASE + params->boot_rom_patch_control * 4) = params->boot_rom_patch_data; *(vu32 *)(APB_MISC_BASE + params->boot_rom_patch_control * 4) = params->boot_rom_patch_data;
MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update. MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
@ -695,49 +719,738 @@ break_nosleep:
MC(MC_EMEM_CFG_ACCESS_CTRL) = 1; MC(MC_EMEM_CFG_ACCESS_CTRL) = 1;
} }
#ifndef CONFIG_SDRAM_COMPRESS_CFG static void _sdram_config_t210b01(const sdram_params_t210b01_t *params)
static void _sdram_patch_model_params(u32 dramid, u32 *params)
{ {
for (u32 i = 0; i < sizeof(sdram_cfg_vendor_patches) / sizeof(sdram_vendor_patch_t); i++) u32 pmc_scratch1 = ~params->emc_pmc_scratch1;
if (sdram_cfg_vendor_patches[i].dramid & DRAM_ID(dramid)) u32 pmc_scratch2 = ~params->emc_pmc_scratch2;
params[sdram_cfg_vendor_patches[i].addr] = sdram_cfg_vendor_patches[i].val;
// Override HW FSM if needed.
if (params->clk_rst_pllm_misc20_override_enable)
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC2) = params->clk_rst_pllm_misc20_override;
// 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_IO_DPD3_REQ) = (pmc_scratch1 & 0x9FFF) + 0x80000000;
usleep(params->pmc_io_dpd3_req_wait);
// Disable e_dpd_vttgen.
PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x3FFF0000) | 0x80000000;
usleep(params->pmc_io_dpd4_req_wait);
// Disable e_dpd_bg.
PMC(APBDEV_PMC_IO_DPD4_REQ) = (pmc_scratch2 & 0x1FFF) | 0x80000000;
usleep(1);
// 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_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;
EMC(EMC_CMD_MAPPING_CMD1_0) = params->emc_cmd_mapping_cmd1_0;
EMC(EMC_CMD_MAPPING_CMD1_1) = params->emc_cmd_mapping_cmd1_1;
EMC(EMC_CMD_MAPPING_CMD1_2) = params->emc_cmd_mapping_cmd1_2;
EMC(EMC_CMD_MAPPING_CMD2_0) = params->emc_cmd_mapping_cmd2_0;
EMC(EMC_CMD_MAPPING_CMD2_1) = params->emc_cmd_mapping_cmd2_1;
EMC(EMC_CMD_MAPPING_CMD2_2) = params->emc_cmd_mapping_cmd2_2;
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;
// Program brick mapping.
EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
EMC(EMC_PMACRO_BRICK_MAPPING_1) = params->emc_pmacro_brick_mapping1;
EMC(EMC_PMACRO_BRICK_MAPPING_2) = params->emc_pmacro_brick_mapping2;
// Set pad macros.
EMC(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0;
EMC(EMC_PMACRO_VTTGEN_CTRL_1) = params->emc_pmacro_vttgen_ctrl1;
EMC(EMC_PMACRO_VTTGEN_CTRL_2) = params->emc_pmacro_vttgen_ctrl2;
// Set pad macros bias.
EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = params->emc_pmacro_bg_bias_ctrl0;
// Patch 1 to 3 using BCT spare secure variables.
if (params->emc_bct_spare_secure0)
*(vu32 *)params->emc_bct_spare_secure0 = params->emc_bct_spare_secure1;
if (params->emc_bct_spare_secure2)
*(vu32 *)params->emc_bct_spare_secure2 = params->emc_bct_spare_secure3;
if (params->emc_bct_spare_secure4)
*(vu32 *)params->emc_bct_spare_secure4 = params->emc_bct_spare_secure5;
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
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_DLL) = params->emc_clock_source_dll;
// Select EMC write mux.
EMC(EMC_DBG) = (params->emc_dbg_write_mux << 1) | params->emc_dbg;
// Patch 2 using BCT spare variables.
if (params->emc_bct_spare2)
*(vu32 *)params->emc_bct_spare2 = params->emc_bct_spare3;
// This is required to do any reads from the pad macros.
EMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;
EMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;
// Set swizzle for Rank 0.
EMC(EMC_SWIZZLE_RANK0_BYTE0) = params->emc_swizzle_rank0_byte0;
EMC(EMC_SWIZZLE_RANK0_BYTE1) = params->emc_swizzle_rank0_byte1;
EMC(EMC_SWIZZLE_RANK0_BYTE2) = params->emc_swizzle_rank0_byte2;
EMC(EMC_SWIZZLE_RANK0_BYTE3) = params->emc_swizzle_rank0_byte3;
// Set swizzle for Rank 1.
EMC(EMC_SWIZZLE_RANK1_BYTE0) = params->emc_swizzle_rank1_byte0;
EMC(EMC_SWIZZLE_RANK1_BYTE1) = params->emc_swizzle_rank1_byte1;
EMC(EMC_SWIZZLE_RANK1_BYTE2) = params->emc_swizzle_rank1_byte2;
EMC(EMC_SWIZZLE_RANK1_BYTE3) = params->emc_swizzle_rank1_byte3;
// Patch 3 using BCT spare variables.
if (params->emc_bct_spare6)
*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;
// Set pad controls.
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;
// Program Autocal controls with shadowed register fields.
EMC(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;
EMC(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;
EMC(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;
EMC(EMC_AUTO_CAL_CONFIG5) = params->emc_auto_cal_config5;
EMC(EMC_AUTO_CAL_CONFIG6) = params->emc_auto_cal_config6;
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_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_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_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_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_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;
// Program per bit pad macros.
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_0) = params->emc_pmacro_perbit_fgcg_ctrl0;
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_1) = params->emc_pmacro_perbit_fgcg_ctrl1;
EMC(EMC_PMACRO_PERBIT_FGCG_CTRL_2) = params->emc_pmacro_perbit_fgcg_ctrl2;
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_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_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;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_3) = params->emc_pmacro_quse_ddll_rank0_3;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_4) = params->emc_pmacro_quse_ddll_rank0_4;
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_5) = params->emc_pmacro_quse_ddll_rank0_5;
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_0) = params->emc_pmacro_quse_ddll_rank1_0;
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_1) = params->emc_pmacro_quse_ddll_rank1_1;
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_2) = params->emc_pmacro_quse_ddll_rank1_2;
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_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;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3) = params->emc_pmacro_ob_ddll_long_dq_rank0_3;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4) = params->emc_pmacro_ob_ddll_long_dq_rank0_4;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5) = params->emc_pmacro_ob_ddll_long_dq_rank0_5;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0) = params->emc_pmacro_ob_ddll_long_dq_rank1_0;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1) = params->emc_pmacro_ob_ddll_long_dq_rank1_1;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2) = params->emc_pmacro_ob_ddll_long_dq_rank1_2;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3) = params->emc_pmacro_ob_ddll_long_dq_rank1_3;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4) = params->emc_pmacro_ob_ddll_long_dq_rank1_4;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5) = params->emc_pmacro_ob_ddll_long_dq_rank1_5;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0) = params->emc_pmacro_ob_ddll_long_dqs_rank0_0;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1) = params->emc_pmacro_ob_ddll_long_dqs_rank0_1;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2) = params->emc_pmacro_ob_ddll_long_dqs_rank0_2;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3) = params->emc_pmacro_ob_ddll_long_dqs_rank0_3;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4) = params->emc_pmacro_ob_ddll_long_dqs_rank0_4;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5) = params->emc_pmacro_ob_ddll_long_dqs_rank0_5;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0) = params->emc_pmacro_ob_ddll_long_dqs_rank1_0;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1) = params->emc_pmacro_ob_ddll_long_dqs_rank1_1;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ob_ddll_long_dqs_rank1_2;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ob_ddll_long_dqs_rank1_3;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4) = params->emc_pmacro_ob_ddll_long_dqs_rank1_4;
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5) = params->emc_pmacro_ob_ddll_long_dqs_rank1_5;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0) = params->emc_pmacro_ib_ddll_long_dqs_rank0_0;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1) = params->emc_pmacro_ib_ddll_long_dqs_rank0_1;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2) = params->emc_pmacro_ib_ddll_long_dqs_rank0_2;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3) = params->emc_pmacro_ib_ddll_long_dqs_rank0_3;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0) = params->emc_pmacro_ib_ddll_long_dqs_rank1_0;
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1) = params->emc_pmacro_ib_ddll_long_dqs_rank1_1;
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_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;
// Set DLL periodic offset.
EMC(EMC_PMACRO_DDLL_PERIODIC_OFFSET) = params->emc_pmacro_ddll_periodic_offset;
// Patch 4 using BCT spare variables.
if (params->emc_bct_spare4)
*(vu32 *)params->emc_bct_spare4 = params->emc_bct_spare5;
// 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;
if (params->emc_bct_spare_secure8)
*(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_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_CHANNEL_MASK) = params->mc_emem_adr_cfg_channel_mask;
// Program bank swizzling.
MC(MC_EMEM_ADR_CFG_BANK_MASK_0) = params->mc_emem_adr_cfg_bank_mask0;
MC(MC_EMEM_ADR_CFG_BANK_MASK_1) = params->mc_emem_adr_cfg_bank_mask1;
MC(MC_EMEM_ADR_CFG_BANK_MASK_2) = params->mc_emem_adr_cfg_bank_mask2;
// Program external memory aperture (base and size).
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_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_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_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_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_TIMING_CONTROL) = 1; // Trigger MC timing update.
// Program second-level clock enable overrides.
MC(MC_CLKEN_OVERRIDE) = params->mc_clken_override;
// Program statistics gathering.
MC(MC_STAT_CONTROL) = params->mc_stat_control;
// Program SDRAM geometry parameters.
EMC(EMC_ADR_CFG) = params->emc_adr_cfg;
// Program second-level clock enable overrides.
EMC(EMC_CLKEN_OVERRIDE) = params->emc_clken_override;
// Program EMC pad auto calibration.
EMC(EMC_PMACRO_AUTOCAL_CFG_0) = params->emc_pmacro_auto_cal_cfg0;
EMC(EMC_PMACRO_AUTOCAL_CFG_1) = params->emc_pmacro_auto_cal_cfg1;
EMC(EMC_PMACRO_AUTOCAL_CFG_2) = params->emc_pmacro_auto_cal_cfg2;
EMC(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;
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;
usleep(params->emc_auto_cal_wait);
// Patch 5 using BCT spare variables.
if (params->emc_bct_spare8)
*(vu32 *)params->emc_bct_spare8 = params->emc_bct_spare9;
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_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_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;
// 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_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_PMACRO_DSR_VTTGEN_CTRL0) = params->emc_pmacro_dsr_vttgen_ctrl0;
// Set pipe bypass enable bits before sending any DRAM commands.
EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;
// BootROM patching is used as a generic patch here.
if (params->boot_rom_patch_control)
{
*(vu32 *)params->boot_rom_patch_control = params->boot_rom_patch_data;
MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
}
// Patch 7 to 9 using BCT spare secure variables.
if (params->emc_bct_spare_secure12)
*(vu32 *)params->emc_bct_spare_secure12 = params->emc_bct_spare_secure13;
if (params->emc_bct_spare_secure14)
*(vu32 *)params->emc_bct_spare_secure14 = params->emc_bct_spare_secure15;
if (params->emc_bct_spare_secure16)
*(vu32 *)params->emc_bct_spare_secure16 = params->emc_bct_spare_secure17;
// Release SEL_DPD_CMD.
PMC(APBDEV_PMC_IO_DPD3_REQ) = ((params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x40000000) & 0xCFFF0000;
usleep(params->pmc_io_dpd3_req_wait);
// Set transmission pad control parameters.
EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;
// 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_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
usleep(params->emc_timing_control_wait);
// Deassert HOLD_CKE_LOW.
PMC(APBDEV_PMC_DDR_CNTRL) &= 0xFF78007F;
usleep(params->pmc_ddr_ctrl_wait);
// 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);
}
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);
// 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)
{
// 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))
{
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;
}
}
}
// Patch 10 to 12 using BCT spare secure variables.
if (params->emc_bct_spare_secure18)
*(vu32 *)params->emc_bct_spare_secure18 = params->emc_bct_spare_secure19;
if (params->emc_bct_spare_secure20)
*(vu32 *)params->emc_bct_spare_secure20 = params->emc_bct_spare_secure21;
if (params->emc_bct_spare_secure22)
*(vu32 *)params->emc_bct_spare_secure22 = params->emc_bct_spare_secure23;
// Set package and DPD pad control.
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;
}
// Patch 7 using BCT spare variables.
if (params->emc_bct_spare12)
*(vu32 *)params->emc_bct_spare12 = params->emc_bct_spare13;
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
if (params->emc_extra_refresh_num)
EMC(EMC_REF) = ((1 << params->emc_extra_refresh_num << 8) - 253) | (params->emc_dev_select << 30);
// Enable refresh.
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_FDPD_CTRL_CMD) = params->emc_fdpd_ctrl_cmd;
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
// Write addr swizzle lock bit.
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;
EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions.
EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
// Enable EMC pipe clock gating.
EMC(EMC_CFG_PIPE_CLK) = params->emc_cfg_pipe_clk;
// Depending on freqency, enable CMD/CLK fdpd.
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = params->emc_fdpd_ctrl_cmd_no_ramp;
// Set untranslated region requirements.
MC(MC_UNTRANSLATED_REGION_CHECK) = params->mc_untranslated_region_check;
// 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;
// Disable write access to a bunch of EMC registers.
MC(MC_EMEM_CFG_ACCESS_CTRL) = 1;
// Enable arbiter.
SYSREG(AHB_ARBITRATION_XBAR_CTRL) = (SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF) | (params->ahb_arbitration_xbar_ctrl_meminit_done << 16);
}
#ifndef CONFIG_SDRAM_COMPRESS_CFG
static void _sdram_patch_model_params_t210(u32 dramid, u32 *params)
{
for (u32 i = 0; i < ARRAY_SIZE(sdram_cfg_vendor_patches_t210); i++)
if (sdram_cfg_vendor_patches_t210[i].dramid & DRAM_ID(dramid))
params[sdram_cfg_vendor_patches_t210[i].addr] = sdram_cfg_vendor_patches_t210[i].val;
} }
#endif #endif
sdram_params_t *sdram_get_params() static void _sdram_patch_model_params_t210b01(u32 dramid, u32 *params)
{
for (u32 i = 0; i < ARRAY_SIZE(sdram_cfg_vendor_patches_t210b01); i++)
if (sdram_cfg_vendor_patches_t210b01[i].dramid & DRAM_ID2(dramid))
params[sdram_cfg_vendor_patches_t210b01[i].addr] = sdram_cfg_vendor_patches_t210b01[i].val;
}
static void *_sdram_get_params_t210()
{ {
// Check if id is proper. // Check if id is proper.
u32 dramid = _get_sdram_id(); u32 dramid = _sdram_get_id();
if (dramid > 6) if (dramid > 6)
dramid = 0; dramid = 0;
#ifdef CONFIG_SDRAM_COMPRESS_CFG #ifdef CONFIG_SDRAM_COMPRESS_CFG
u8 *buf = (u8 *)SDRAM_PARAMS_ADDR; u8 *buf = (u8 *)SDRAM_PARAMS_ADDR;
LZ_Uncompress(_dram_cfg_lz, buf, sizeof(_dram_cfg_lz)); LZ_Uncompress(_dram_cfg_lz, buf, sizeof(_dram_cfg_lz));
return (sdram_params_t *)&buf[sizeof(sdram_params_t) * dramid]; return (void *)&buf[sizeof(sdram_params_t210_t) * dramid];
#else #else
sdram_params_t *buf = (sdram_params_t *)SDRAM_PARAMS_ADDR;
memcpy(buf, &_dram_cfg_0_samsung_4gb, sizeof(sdram_params_t)); u32 *buf = (u32 *)SDRAM_PARAMS_ADDR;
memcpy(buf, &_dram_cfg_0_samsung_4gb, sizeof(sdram_params_t210_t));
switch (dramid) switch (dramid)
{ {
case DRAM_4GB_SAMSUNG_K4F6E304HB_MGCH: case LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH:
case DRAM_4GB_MICRON_MT53B512M32D2NP_062_WT: case LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT:
break; break;
case DRAM_4GB_HYNIX_H9HCNNNBPUMLHR_NLN: case LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE:
case DRAM_6GB_SAMSUNG_K4FHE3D4HM_MFCH: case LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH:
#ifdef CONFIG_SDRAM_COPPER_SUPPORT #ifdef CONFIG_SDRAM_COPPER_SUPPORT
case DRAM_4GB_COPPER_SAMSUNG: case LPDDR4_COPPER_4GB_SAMSUNG_K4F6E304HB_MGCH:
case DRAM_4GB_COPPER_HYNIX: case LPDDR4_COPPER_4GB_HYNIX_H9HCNNNBPUMLHR_NLE:
case DRAM_4GB_COPPER_MICRON: case LPDDR4_COPPER_4GB_MICRON_MT53B512M32D2NP_062_WT:
#endif #endif
_sdram_patch_model_params(dramid, (u32 *)buf); _sdram_patch_model_params_t210(dramid, (u32 *)buf);
break; break;
} }
return buf; return (void *)buf;
#endif #endif
} }
void *sdram_get_params_t210b01()
{
// Check if id is proper.
u32 dramid = _sdram_get_id();
if (dramid > 27)
dramid = 8;
u32 *buf = (u32 *)SDRAM_PARAMS_ADDR;
memcpy(buf, &_dram_cfg_08_10_12_14_samsung_hynix_4gb, sizeof(sdram_params_t210b01_t));
switch (dramid)
{
case LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ:
case LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME:
case LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ:
case LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME:
break;
case LPDDR4X_IOWA_4GB_SAMSUNG_X1X2:
case LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ:
case LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WT:
case LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ:
case LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WT:
case LPDDR4X_IOWA_4GB_SAMSUNG_Y:
case LPDDR4X_IOWA_4GB_SAMSUNG_1Y_X:
case LPDDR4X_IOWA_8GB_SAMSUNG_1Y_X:
case LPDDR4X_HOAG_4GB_SAMSUNG_1Y_X:
case LPDDR4X_IOWA_4GB_SAMSUNG_1Y_Y:
case LPDDR4X_IOWA_8GB_SAMSUNG_1Y_Y:
case LPDDR4X_SDS_4GB_SAMSUNG_1Y_A:
case LPDDR4X_SDS_8GB_SAMSUNG_1Y_X:
case LPDDR4X_SDS_4GB_SAMSUNG_1Y_X:
case LPDDR4X_IOWA_4GB_MICRON_1Y_A:
case LPDDR4X_HOAG_4GB_MICRON_1Y_A:
case LPDDR4X_SDS_4GB_MICRON_1Y_A:
_sdram_patch_model_params_t210b01(dramid, (u32 *)buf);
break;
}
return (void *)buf;
}
/* /*
* Function: sdram_get_params_patched * Function: sdram_get_params_patched
* *
@ -754,13 +1467,13 @@ sdram_params_t *sdram_get_params()
* Note: The modulus in the header must match and validated. * Note: The modulus in the header must match and validated.
*/ */
sdram_params_t *sdram_get_params_patched() void *sdram_get_params_patched()
{ {
#define IPATCH_CONFIG(addr, data) (((addr - 0x100000) / 2) << 16 | (data & 0xffff)) #define IPATCH_CONFIG(addr, data) ((((addr) - 0x100000) / 2) << 16 | ((data) & 0xffff))
sdram_params_t *sdram_params = sdram_get_params(); sdram_params_t210_t *sdram_params = _sdram_get_params_t210();
// Disable Warmboot signature check. // Disable Warmboot signature check.
sdram_params->boot_rom_patch_control = (1 << 31) | (((IPATCH_BASE + 4) - APB_MISC_BASE) / 4); sdram_params->boot_rom_patch_control = BIT(31) | (((IPATCH_BASE + 4) - APB_MISC_BASE) / 4);
sdram_params->boot_rom_patch_data = IPATCH_CONFIG(0x10459E, 0x2000); sdram_params->boot_rom_patch_data = IPATCH_CONFIG(0x10459E, 0x2000);
/* /*
// Disable SBK lock. // Disable SBK lock.
@ -773,15 +1486,14 @@ sdram_params_t *sdram_get_params_patched()
sdram_params->emc_bct_spare12 = (IPATCH_BASE + 11 * 4); sdram_params->emc_bct_spare12 = (IPATCH_BASE + 11 * 4);
sdram_params->emc_bct_spare13 = IPATCH_CONFIG(0x100FDE, 0xE320); sdram_params->emc_bct_spare13 = IPATCH_CONFIG(0x100FDE, 0xE320);
*/ */
return sdram_params; return (void *)sdram_params;
} }
void sdram_init() static void _sdram_init_t210()
{ {
const sdram_params_t *params = (const sdram_params_t *)sdram_get_params(); const sdram_params_t210_t *params = (const sdram_params_t210_t *)_sdram_get_params_t210();
// Set DRAM voltage. // Set DRAM voltage.
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 0x05);
max77620_regulator_set_voltage(REGULATOR_SD1, 1100000); max77620_regulator_set_voltage(REGULATOR_SD1, 1100000);
// VDDP Select. // VDDP Select.
@ -801,5 +1513,37 @@ void sdram_init()
if (params->emc_bct_spare0) if (params->emc_bct_spare0)
*(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1; *(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
_sdram_config(params); _sdram_config_t210(params);
}
static void _sdram_init_t210b01()
{
const sdram_params_t210b01_t *params = (const sdram_params_t210b01_t *)sdram_get_params_t210b01();
// VDDP Select.
PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
usleep(params->pmc_vddp_sel_wait);
// 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_DDR_CNTRL) = params->pmc_ddr_ctrl;
// Patch 1 using BCT spare variables
if (params->emc_bct_spare0)
*(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
_sdram_config_t210b01(params);
}
void sdram_init()
{
// Configure SD regulator for DRAM.
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 0x05);
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
_sdram_init_t210();
else
_sdram_init_t210b01();
} }

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -18,11 +19,76 @@
#define _SDRAM_H_ #define _SDRAM_H_
#include <mem/emc.h> #include <mem/emc.h>
#include <mem/sdram_param_t210.h>
/*
* Tegra X1/X1+ EMC/DRAM Bandwidth Chart:
*
* 40.8 MHz: 0.61 GiB/s
* 68.0 MHz: 1.01 GiB/s
* 102.0 MHz: 1.52 GiB/s
* 204.0 MHz: 3.04 GiB/s <-- Tegra X1/X1+ Init/SC7 Frequency
* 408.0 MHz: 6.08 GiB/s
* 665.6 MHz: 9.92 GiB/s
* 800.0 MHz: 11.92 GiB/s <-- Tegra X1/X1+ Nvidia OS Boot Frequency
* 1065.6 MHz: 15.89 GiB/s
* 1331.2 MHz: 19.84 GiB/s
* 1600.0 MHz: 23.84 GiB/s <-- Tegra X1 Official Max Frequency
* 1862.4 MHz: 27.75 GiB/s <-- Tegra X1+ Official Max Frequency
* 2131.2 MHz: 31.76 GiB/s
*
* Note: BWbits = Hz x bus width x channels = Hz x 64 x 2.
*/
enum sdram_ids_erista
{
// LPDDR4 3200Mbps.
LPDDR4_ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0,
LPDDR4_ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1,
LPDDR4_ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WT = 2,
LPDDR4_COPPER_4GB_SAMSUNG_K4F6E304HB_MGCH = 3,
LPDDR4_ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4,
LPDDR4_COPPER_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 5,
LPDDR4_COPPER_4GB_MICRON_MT53B512M32D2NP_062_WT = 6,
};
enum sdram_ids_mariko
{
// LPDDR4X 3733Mbps.
LPDDR4X_IOWA_4GB_SAMSUNG_X1X2 = 7,
LPDDR4X_IOWA_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 8,
LPDDR4X_IOWA_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 9,
LPDDR4X_IOWA_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 10,
LPDDR4X_IOWA_4GB_MICRON_MT53E512M32D2NP_046_WT = 11, // 4266Mbps.
LPDDR4X_HOAG_4GB_SAMSUNG_K4U6E3S4AM_MGCJ = 12,
LPDDR4X_HOAG_8GB_SAMSUNG_K4UBE3D4AM_MGCJ = 13,
LPDDR4X_HOAG_4GB_HYNIX_H9HCNNNBKMMLHR_NME = 14,
LPDDR4X_HOAG_4GB_MICRON_MT53E512M32D2NP_046_WT = 15, // 4266Mbps.
// LPDDR4X 4266Mbps?
LPDDR4X_IOWA_4GB_SAMSUNG_Y = 16,
LPDDR4X_IOWA_4GB_SAMSUNG_1Y_X = 17,
LPDDR4X_IOWA_8GB_SAMSUNG_1Y_X = 18,
LPDDR4X_HOAG_4GB_SAMSUNG_1Y_X = 19,
LPDDR4X_IOWA_4GB_SAMSUNG_1Y_Y = 20,
LPDDR4X_IOWA_8GB_SAMSUNG_1Y_Y = 21,
LPDDR4X_SDS_4GB_SAMSUNG_1Y_A = 22,
LPDDR4X_SDS_8GB_SAMSUNG_1Y_X = 23,
LPDDR4X_SDS_4GB_SAMSUNG_1Y_X = 24,
LPDDR4X_IOWA_4GB_MICRON_1Y_A = 25,
LPDDR4X_HOAG_4GB_MICRON_1Y_A = 26,
LPDDR4X_SDS_4GB_MICRON_1Y_A = 27
};
void sdram_init(); void sdram_init();
sdram_params_t *sdram_get_params(); void *sdram_get_params_patched();
sdram_params_t *sdram_get_params_patched(); void *sdram_get_params_t210b01();
void sdram_lp0_save_params(const void *params); void sdram_lp0_save_params(const void *params);
emc_mr_data_t sdram_read_mrx(emc_mr_t mrx); emc_mr_data_t sdram_read_mrx(emc_mr_t mrx);

View File

@ -15,26 +15,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define DRAM_CFG_SIZE 1896 #define DRAM_CFG_T210_SIZE 1896
#define DRAM_ID(x) (1 << (x)) #define DRAM_ID(x) BIT(x)
#define DRAM_4GB_SAMSUNG_K4F6E304HB_MGCH 0 static const sdram_params_t210_t _dram_cfg_0_samsung_4gb = {
#define DRAM_4GB_HYNIX_H9HCNNNBPUMLHR_NLN 1
#define DRAM_4GB_MICRON_MT53B512M32D2NP_062_WT 2
#define DRAM_4GB_COPPER_SAMSUNG 3
#define DRAM_6GB_SAMSUNG_K4FHE3D4HM_MFCH 4
#define DRAM_4GB_COPPER_HYNIX 5
#define DRAM_4GB_COPPER_MICRON 6
typedef struct _sdram_vendor_patch_t
{
u32 val;
u16 addr:9;
u16 dramid:7;
} sdram_vendor_patch_t;
static const sdram_params_t _dram_cfg_0_samsung_4gb = {
/* Specifies the type of memory device */ /* Specifies the type of memory device */
.memory_type = MEMORY_TYPE_LPDDR4, .memory_type = MEMORY_TYPE_LPDDR4,
@ -112,7 +97,7 @@ static const sdram_params_t _dram_cfg_0_samsung_4gb = {
* DRAM size information * DRAM size information
* Specifies the value for EMC_ADR_CFG * Specifies the value for EMC_ADR_CFG
*/ */
.emc_adr_cfg = 0x00000001, .emc_adr_cfg = 0x00000001, // 2 populated DRAM Devices.
/* /*
* Specifies the time to wait after asserting pin * Specifies the time to wait after asserting pin
@ -258,7 +243,7 @@ static const sdram_params_t _dram_cfg_0_samsung_4gb = {
.emc_cfg_dig_dll = 0x002C00A0, .emc_cfg_dig_dll = 0x002C00A0,
.emc_cfg_dig_dll_1 = 0x00003701, .emc_cfg_dig_dll_1 = 0x00003701,
.emc_cfg_dig_dll_period = 0x00008000, .emc_cfg_dig_dll_period = 0x00008000,
.emc_dev_select = 0x00000000, .emc_dev_select = 0x00000000, // Both devices.
.emc_sel_dpd_ctrl = 0x00040008, .emc_sel_dpd_ctrl = 0x00040008,
/* Pads trimmer delays */ /* Pads trimmer delays */
@ -505,9 +490,9 @@ static const sdram_params_t _dram_cfg_0_samsung_4gb = {
.emc_pmacro_cmd_ctrl2 = 0x0A0A0A0A, .emc_pmacro_cmd_ctrl2 = 0x0A0A0A0A,
/* DRAM size information */ /* DRAM size information */
.mc_emem_adr_cfg = 0x00000001, .mc_emem_adr_cfg = 0x00000001, // 2 populated DRAM Devices.
.mc_emem_adr_cfg_dev0 = 0x00070302, .mc_emem_adr_cfg_dev0 = 0x00070302, // Density 512MB.
.mc_emem_adr_cfg_dev1 = 0x00070302, .mc_emem_adr_cfg_dev1 = 0x00070302, // Density 512MB.
.mc_emem_adr_cfg_channel_mask = 0xFFFF2400, .mc_emem_adr_cfg_channel_mask = 0xFFFF2400,
.mc_emem_adr_cfg_bank_mask0 = 0x6E574400, .mc_emem_adr_cfg_bank_mask0 = 0x6E574400,
.mc_emem_adr_cfg_bank_mask1 = 0x39722800, .mc_emem_adr_cfg_bank_mask1 = 0x39722800,
@ -516,7 +501,7 @@ static const sdram_params_t _dram_cfg_0_samsung_4gb = {
* Specifies the value for MC_EMEM_CFG which holds the external memory * Specifies the value for MC_EMEM_CFG which holds the external memory
* size (in KBytes) * size (in KBytes)
*/ */
.mc_emem_cfg = 0x00001000, .mc_emem_cfg = 0x00001000, // 4GB total density.
/* MC arbitration configuration */ /* MC arbitration configuration */
.mc_emem_arb_cfg = 0x08000001, .mc_emem_arb_cfg = 0x08000001,
@ -659,7 +644,7 @@ static const sdram_params_t _dram_cfg_0_samsung_4gb = {
.mc_mts_carveout_reg_ctrl = 0x00000000 .mc_mts_carveout_reg_ctrl = 0x00000000
}; };
static const sdram_vendor_patch_t sdram_cfg_vendor_patches[] = { static const sdram_vendor_patch_t sdram_cfg_vendor_patches_t210[] = {
// Hynix timing config. // Hynix timing config.
{ 0x0000000D, 67, DRAM_ID(1) | DRAM_ID(5) }, // emc_r2w. { 0x0000000D, 67, DRAM_ID(1) | DRAM_ID(5) }, // emc_r2w.
{ 0x00000001, 91, DRAM_ID(1) | DRAM_ID(5) }, // emc_puterm_extra. { 0x00000001, 91, DRAM_ID(1) | DRAM_ID(5) }, // emc_puterm_extra.

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
* Copyright 2014 Google Inc. * Copyright 2014 Google Inc.
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 CTCaer * Copyright (c) 2018-2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -17,16 +17,7 @@
#include <soc/t210.h> #include <soc/t210.h>
#include <soc/pmc_lp0_t210.h> #include <soc/pmc_lp0_t210.h>
#include <mem/sdram_lp0_param_t210.h> #include <mem/sdram_lp0_param_t210.h>
#include <mem/sdram_lp0_param_t210b01.h>
/*
* This function reads SDRAM parameters from the common BCT format and
* writes them into PMC scratch registers (where the BootROM expects them
* on LP0 resume).
*/
void sdram_lp0_save_params(const void *params)
{
struct sdram_params *sdram = (struct sdram_params *)params;
struct tegra_pmc_regs *pmc = (struct tegra_pmc_regs *)PMC_BASE;
#define pack(src, src_bits, dst, dst_bits) { \ #define pack(src, src_bits, dst, dst_bits) { \
u32 mask = 0xffffffff >> (31 - ((1 ? src_bits) - (0 ? src_bits))); \ u32 mask = 0xffffffff >> (31 - ((1 ? src_bits) - (0 ? src_bits))); \
@ -46,6 +37,16 @@ void sdram_lp0_save_params(const void *params)
/* 32 bits version c macro */ /* 32 bits version c macro */
#define c32(value, pmcreg) pmc->pmcreg = value #define c32(value, pmcreg) pmc->pmcreg = value
/*
* This function reads SDRAM parameters from the common BCT format and
* writes them into PMC scratch registers (where the BootROM expects them
* on LP0 resume).
*/
static void _sdram_lp0_save_params_t210(const void *params)
{
struct sdram_params_t210 *sdram = (struct sdram_params_t210 *)params;
struct tegra_pmc_regs *pmc = (struct tegra_pmc_regs *)PMC_BASE;
//TODO: pkg1.1 (1.X - 3.X) reads them from MC. //TODO: pkg1.1 (1.X - 3.X) reads them from MC.
// Patch carveout parameters. // Patch carveout parameters.
/*sdram->McGeneralizedCarveout1Bom = 0; /*sdram->McGeneralizedCarveout1Bom = 0;
@ -1124,3 +1125,414 @@ void sdram_lp0_save_params(const void *params)
c32(0, scratch4); c32(0, scratch4);
s(PllMStableTime, 9:0, scratch4, 9:0); s(PllMStableTime, 9:0, scratch4, 9:0);
} }
// #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;
// 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;
// // 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_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);
// 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;
// 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, 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, 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;
// if (chip_id != GP_HIDREV_MAJOR_T210B01)
_sdram_lp0_save_params_t210(params);
// else
// _sdram_lp0_save_params_t210b01(params);
}

View File

@ -20,8 +20,8 @@
* directly converting BCT config files (*.cfg) into C structure. * directly converting BCT config files (*.cfg) into C structure.
*/ */
#ifndef __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__ #ifndef __TEGRA210_SDRAM_PARAM_H__
#define __SOC_NVIDIA_TEGRA210_SDRAM_PARAM_H__ #define __TEGRA210_SDRAM_PARAM_H__
#include <utils/types.h> #include <utils/types.h>
@ -57,7 +57,7 @@ enum
/** /**
* Defines the SDRAM parameter structure * Defines the SDRAM parameter structure
*/ */
struct sdram_params struct sdram_params_t210
{ {
/* Specifies the type of memory device */ /* Specifies the type of memory device */

View File

@ -0,0 +1,990 @@
/*
* Copyright (c) 2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef __TEGRA210B01_SDRAM_PARAM_H__
#define __TEGRA210B01_SDRAM_PARAM_H__
#include <utils/types.h>
struct sdram_params_t210b01
{
/* Specifies the type of memory device */
u32 memory_type;
/* MC/EMC clock source configuration */
/* Specifies the M value for PllM */
u32 pllm_input_divider;
/* Specifies the N value for PllM */
u32 pllm_feedback_divider;
/* Specifies the time to wait for PLLM to lock (in microseconds) */
u32 pllm_stable_time;
/* Specifies misc. control bits */
u32 pllm_setup_control;
/* Specifies the P value for PLLM */
u32 pllm_post_divider;
/* Specifies value for Charge Pump Gain Control */
u32 pllm_kcp;
/* Specifies VCO gain */
u32 pllm_kvco;
/* Spare BCT param */
u32 emc_bct_spare0;
/* Spare BCT param */
u32 emc_bct_spare1;
/* Spare BCT param */
u32 emc_bct_spare2;
/* Spare BCT param */
u32 emc_bct_spare3;
/* Spare BCT param */
u32 emc_bct_spare4;
/* Spare BCT param */
u32 emc_bct_spare5;
/* Spare BCT param */
u32 emc_bct_spare6;
/* Spare BCT param */
u32 emc_bct_spare7;
/* Spare BCT param */
u32 emc_bct_spare8;
/* Spare BCT param */
u32 emc_bct_spare9;
/* Spare BCT param */
u32 emc_bct_spare10;
/* Spare BCT param */
u32 emc_bct_spare11;
/* Spare BCT param */
u32 emc_bct_spare12;
/* Spare BCT param */
u32 emc_bct_spare13;
/* Spare BCT param */
u32 emc_bct_spare_secure0;
/* Spare BCT param */
u32 emc_bct_spare_secure1;
/* Spare BCT param */
u32 emc_bct_spare_secure2;
/* Spare BCT param */
u32 emc_bct_spare_secure3;
/* Spare BCT param */
u32 emc_bct_spare_secure4;
/* Spare BCT param */
u32 emc_bct_spare_secure5;
/* Spare BCT param */
u32 emc_bct_spare_secure6;
/* Spare BCT param */
u32 emc_bct_spare_secure7;
/* Spare BCT param */
u32 emc_bct_spare_secure8;
/* Spare BCT param */
u32 emc_bct_spare_secure9;
/* Spare BCT param */
u32 emc_bct_spare_secure10;
/* Spare BCT param */
u32 emc_bct_spare_secure11;
/* Spare BCT param */
u32 emc_bct_spare_secure12;
/* Spare BCT param */
u32 emc_bct_spare_secure13;
/* Spare BCT param */
u32 emc_bct_spare_secure14;
/* Spare BCT param */
u32 emc_bct_spare_secure15;
/* Spare BCT param */
u32 emc_bct_spare_secure16;
/* Spare BCT param */
u32 emc_bct_spare_secure17;
/* Spare BCT param */
u32 emc_bct_spare_secure18;
/* Spare BCT param */
u32 emc_bct_spare_secure19;
/* Spare BCT param */
u32 emc_bct_spare_secure20;
/* Spare BCT param */
u32 emc_bct_spare_secure21;
/* Spare BCT param */
u32 emc_bct_spare_secure22;
/* Spare BCT param */
u32 emc_bct_spare_secure23;
/* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */
u32 emc_clock_source;
u32 emc_clock_source_dll;
/* Defines possible override for PLLLM_MISC2 */
u32 clk_rst_pllm_misc20_override;
/* enables override for PLLLM_MISC2 */
u32 clk_rst_pllm_misc20_override_enable;
/* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */
u32 clear_clock2_mc1;
/* Auto-calibration of EMC pads */
/* Specifies the value for EMC_AUTO_CAL_INTERVAL */
u32 emc_auto_cal_interval;
/*
* Specifies the value for EMC_AUTO_CAL_CONFIG
* Note: Trigger bits are set by the SDRAM code.
*/
u32 emc_auto_cal_config;
/* Specifies the value for EMC_AUTO_CAL_CONFIG2 */
u32 emc_auto_cal_config2;
/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
u32 emc_auto_cal_config3;
u32 emc_auto_cal_config4;
u32 emc_auto_cal_config5;
u32 emc_auto_cal_config6;
u32 emc_auto_cal_config7;
u32 emc_auto_cal_config8;
u32 emc_auto_cal_config9;
/* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */
u32 emc_auto_cal_vref_sel0;
u32 emc_auto_cal_vref_sel1;
/* Specifies the value for EMC_AUTO_CAL_CHANNEL */
u32 emc_auto_cal_channel;
/* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */
u32 emc_pmacro_auto_cal_cfg0;
u32 emc_pmacro_auto_cal_cfg1;
u32 emc_pmacro_auto_cal_cfg2;
u32 emc_pmacro_rx_term;
u32 emc_pmacro_dq_tx_drive;
u32 emc_pmacro_ca_tx_drive;
u32 emc_pmacro_cmd_tx_drive;
u32 emc_pmacro_auto_cal_common;
u32 emc_pmacro_zcrtl;
/*
* Specifies the time for the calibration
* to stabilize (in microseconds)
*/
u32 emc_auto_cal_wait;
u32 emc_xm2_comp_pad_ctrl;
u32 emc_xm2_comp_pad_ctrl2;
u32 emc_xm2_comp_pad_ctrl3;
/*
* DRAM size information
* Specifies the value for EMC_ADR_CFG
*/
u32 emc_adr_cfg;
/*
* Specifies the time to wait after asserting pin
* CKE (in microseconds)
*/
u32 emc_pin_program_wait;
/* Specifies the extra delay before/after pin RESET/CKE command */
u32 emc_pin_extra_wait;
u32 emc_pin_gpio_enable;
u32 emc_pin_gpio;
/*
* Specifies the extra delay after the first writing
* of EMC_TIMING_CONTROL
*/
u32 emc_timing_control_wait;
/* Timing parameters required for the SDRAM */
/* Specifies the value for EMC_RC */
u32 emc_rc;
/* Specifies the value for EMC_RFC */
u32 emc_rfc;
u32 emc_rfc_pb;
u32 emc_ref_ctrl2;
/* Specifies the value for EMC_RFC_SLR */
u32 emc_rfc_slr;
/* Specifies the value for EMC_RAS */
u32 emc_ras;
/* Specifies the value for EMC_RP */
u32 emc_rp;
/* Specifies the value for EMC_R2R */
u32 emc_r2r;
/* Specifies the value for EMC_W2W */
u32 emc_w2w;
/* Specifies the value for EMC_R2W */
u32 emc_r2w;
/* Specifies the value for EMC_W2R */
u32 emc_w2r;
/* Specifies the value for EMC_R2P */
u32 emc_r2p;
/* Specifies the value for EMC_W2P */
u32 emc_w2p;
/* Specifies the value for EMC_RD_RCD */
u32 emc_tppd;
u32 emc_trtm;
u32 emc_twtm;
u32 emc_tratm;
u32 emc_twatm;
u32 emc_tr2ref;
u32 emc_ccdmw;
u32 emc_rd_rcd;
/* Specifies the value for EMC_WR_RCD */
u32 emc_wr_rcd;
/* Specifies the value for EMC_RRD */
u32 emc_rrd;
/* Specifies the value for EMC_REXT */
u32 emc_rext;
/* Specifies the value for EMC_WEXT */
u32 emc_wext;
/* Specifies the value for EMC_WDV */
u32 emc_wdv;
u32 emc_wdv_chk;
u32 emc_wsv;
u32 emc_wev;
/* Specifies the value for EMC_WDV_MASK */
u32 emc_wdv_mask;
u32 emc_ws_duration;
u32 emc_we_duration;
/* Specifies the value for EMC_QUSE */
u32 emc_quse;
/* Specifies the value for EMC_QUSE_WIDTH */
u32 emc_quse_width;
/* Specifies the value for EMC_IBDLY */
u32 emc_ibdly;
u32 emc_obdly;
/* Specifies the value for EMC_EINPUT */
u32 emc_einput;
/* Specifies the value for EMC_EINPUT_DURATION */
u32 emc_einput_duration;
/* Specifies the value for EMC_PUTERM_EXTRA */
u32 emc_puterm_extra;
/* Specifies the value for EMC_PUTERM_WIDTH */
u32 emc_puterm_width;
u32 emc_qrst;
u32 emc_qsafe;
u32 emc_rdv;
u32 emc_rdv_mask;
u32 emc_rdv_early;
u32 emc_rdv_early_mask;
/* Specifies the value for EMC_QPOP */
u32 emc_qpop;
/* Specifies the value for EMC_REFRESH */
u32 emc_refresh;
/* Specifies the value for EMC_BURST_REFRESH_NUM */
u32 emc_burst_refresh_num;
/* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */
u32 emc_prerefresh_req_cnt;
/* Specifies the value for EMC_PDEX2WR */
u32 emc_pdex2wr;
/* Specifies the value for EMC_PDEX2RD */
u32 emc_pdex2rd;
/* Specifies the value for EMC_PCHG2PDEN */
u32 emc_pchg2pden;
/* Specifies the value for EMC_ACT2PDEN */
u32 emc_act2pden;
/* Specifies the value for EMC_AR2PDEN */
u32 emc_ar2pden;
/* Specifies the value for EMC_RW2PDEN */
u32 emc_rw2pden;
u32 emc_cke2pden;
u32 emc_pdex2che;
u32 emc_pdex2mrr;
/* Specifies the value for EMC_TXSR */
u32 emc_txsr;
/* Specifies the value for EMC_TXSRDLL */
u32 emc_txsr_dll;
/* Specifies the value for EMC_TCKE */
u32 emc_tcke;
/* Specifies the value for EMC_TCKESR */
u32 emc_tckesr;
/* Specifies the value for EMC_TPD */
u32 emc_tpd;
/* Specifies the value for EMC_TFAW */
u32 emc_tfaw;
/* Specifies the value for EMC_TRPAB */
u32 emc_trpab;
/* Specifies the value for EMC_TCLKSTABLE */
u32 emc_tclkstable;
/* Specifies the value for EMC_TCLKSTOP */
u32 emc_tclkstop;
/* Specifies the value for EMC_TREFBW */
u32 emc_trefbw;
/* FBIO configuration values */
/* Specifies the value for EMC_FBIO_CFG5 */
u32 emc_fbio_cfg5;
/* Specifies the value for EMC_FBIO_CFG7 */
u32 emc_fbio_cfg7;
u32 emc_fbio_cfg8;
/* Command mapping for CMD brick 0 */
u32 emc_cmd_mapping_cmd0_0;
u32 emc_cmd_mapping_cmd0_1;
u32 emc_cmd_mapping_cmd0_2;
u32 emc_cmd_mapping_cmd1_0;
u32 emc_cmd_mapping_cmd1_1;
u32 emc_cmd_mapping_cmd1_2;
u32 emc_cmd_mapping_cmd2_0;
u32 emc_cmd_mapping_cmd2_1;
u32 emc_cmd_mapping_cmd2_2;
u32 emc_cmd_mapping_cmd3_0;
u32 emc_cmd_mapping_cmd3_1;
u32 emc_cmd_mapping_cmd3_2;
u32 emc_cmd_mapping_byte;
/* Specifies the value for EMC_FBIO_SPARE */
u32 emc_fbio_spare;
/* Specifies the value for EMC_CFG_RSV */
u32 emc_cfg_rsv;
/* MRS command values */
/* Specifies the value for EMC_MRS */
u32 emc_mrs;
/* Specifies the MP0 command to initialize mode registers */
u32 emc_emrs;
/* Specifies the MP2 command to initialize mode registers */
u32 emc_emrs2;
/* Specifies the MP3 command to initialize mode registers */
u32 emc_emrs3;
/* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */
u32 emc_mrw1;
/* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */
u32 emc_mrw2;
/* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */
u32 emc_mrw3;
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
u32 emc_mrw4;
/* Specifies the programming to LPDDR4 Mode Register 3 at cold boot */
u32 emc_mrw6;
/* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */
u32 emc_mrw8;
/* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */
u32 emc_mrw9;
/* Specifies the programming to LPDDR4 Mode Register 12 at cold boot */
u32 emc_mrw10;
/* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */
u32 emc_mrw12;
/* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */
u32 emc_mrw13;
/* Specifies the programming to LPDDR4 Mode Register 22 at cold boot */
u32 emc_mrw14;
/*
* Specifies the programming to extra LPDDR2 Mode Register
* at cold boot
*/
u32 emc_mrw_extra;
/*
* Specifies the programming to extra LPDDR2 Mode Register
* at warm boot
*/
u32 emc_warm_boot_mrw_extra;
/*
* Specify the enable of extra Mode Register programming at
* warm boot
*/
u32 emc_warm_boot_extramode_reg_write_enable;
/*
* Specify the enable of extra Mode Register programming at
* cold boot
*/
u32 emc_extramode_reg_write_enable;
/* Specifies the EMC_MRW reset command value */
u32 emc_mrw_reset_command;
/* Specifies the EMC Reset wait time (in microseconds) */
u32 emc_mrw_reset_ninit_wait;
/* Specifies the value for EMC_MRS_WAIT_CNT */
u32 emc_mrs_wait_cnt;
/* Specifies the value for EMC_MRS_WAIT_CNT2 */
u32 emc_mrs_wait_cnt2;
/* EMC miscellaneous configurations */
/* Specifies the value for EMC_CFG */
u32 emc_cfg;
/* Specifies the value for EMC_CFG_2 */
u32 emc_cfg2;
/* Specifies the pipe bypass controls */
u32 emc_cfg_pipe;
u32 emc_cfg_pipe_clk;
u32 emc_fdpd_ctrl_cmd_no_ramp;
u32 emc_cfg_update;
/* Specifies the value for EMC_DBG */
u32 emc_dbg;
u32 emc_dbg_write_mux;
/* Specifies the value for EMC_CMDQ */
u32 emc_cmd_q;
/* Specifies the value for EMC_MC2EMCQ */
u32 emc_mc2emc_q;
/* Specifies the value for EMC_DYN_SELF_REF_CONTROL */
u32 emc_dyn_self_ref_control;
/* Specifies the value for MEM_INIT_DONE */
u32 ahb_arbitration_xbar_ctrl_meminit_done;
/* Specifies the value for EMC_CFG_DIG_DLL */
u32 emc_cfg_dig_dll;
u32 emc_cfg_dig_dll_1;
/* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */
u32 emc_cfg_dig_dll_period;
/* Specifies the value of *DEV_SELECTN of various EMC registers */
u32 emc_dev_select;
/* Specifies the value for EMC_SEL_DPD_CTRL */
u32 emc_sel_dpd_ctrl;
/* Pads trimmer delays */
u32 emc_fdpd_ctrl_dq;
u32 emc_fdpd_ctrl_cmd;
u32 emc_pmacro_ib_vref_dq_0;
u32 emc_pmacro_ib_vref_dq_1;
u32 emc_pmacro_ib_vref_dqs_0;
u32 emc_pmacro_ib_vref_dqs_1;
u32 emc_pmacro_ib_rxrt;
u32 emc_cfg_pipe1;
u32 emc_cfg_pipe2;
/* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */
u32 emc_pmacro_quse_ddll_rank0_0;
u32 emc_pmacro_quse_ddll_rank0_1;
u32 emc_pmacro_quse_ddll_rank0_2;
u32 emc_pmacro_quse_ddll_rank0_3;
u32 emc_pmacro_quse_ddll_rank0_4;
u32 emc_pmacro_quse_ddll_rank0_5;
u32 emc_pmacro_quse_ddll_rank1_0;
u32 emc_pmacro_quse_ddll_rank1_1;
u32 emc_pmacro_quse_ddll_rank1_2;
u32 emc_pmacro_quse_ddll_rank1_3;
u32 emc_pmacro_quse_ddll_rank1_4;
u32 emc_pmacro_quse_ddll_rank1_5;
u32 emc_pmacro_ob_ddll_long_dq_rank0_0;
u32 emc_pmacro_ob_ddll_long_dq_rank0_1;
u32 emc_pmacro_ob_ddll_long_dq_rank0_2;
u32 emc_pmacro_ob_ddll_long_dq_rank0_3;
u32 emc_pmacro_ob_ddll_long_dq_rank0_4;
u32 emc_pmacro_ob_ddll_long_dq_rank0_5;
u32 emc_pmacro_ob_ddll_long_dq_rank1_0;
u32 emc_pmacro_ob_ddll_long_dq_rank1_1;
u32 emc_pmacro_ob_ddll_long_dq_rank1_2;
u32 emc_pmacro_ob_ddll_long_dq_rank1_3;
u32 emc_pmacro_ob_ddll_long_dq_rank1_4;
u32 emc_pmacro_ob_ddll_long_dq_rank1_5;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_0;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_1;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_2;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_3;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_4;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_5;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_0;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_1;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_2;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_3;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_4;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_5;
u32 emc_pmacro_ib_ddll_long_dqs_rank0_0;
u32 emc_pmacro_ib_ddll_long_dqs_rank0_1;
u32 emc_pmacro_ib_ddll_long_dqs_rank0_2;
u32 emc_pmacro_ib_ddll_long_dqs_rank0_3;
u32 emc_pmacro_ib_ddll_long_dqs_rank1_0;
u32 emc_pmacro_ib_ddll_long_dqs_rank1_1;
u32 emc_pmacro_ib_ddll_long_dqs_rank1_2;
u32 emc_pmacro_ib_ddll_long_dqs_rank1_3;
u32 emc_pmacro_ddll_long_cmd_0;
u32 emc_pmacro_ddll_long_cmd_1;
u32 emc_pmacro_ddll_long_cmd_2;
u32 emc_pmacro_ddll_long_cmd_3;
u32 emc_pmacro_ddll_long_cmd_4;
u32 emc_pmacro_ddll_short_cmd_0;
u32 emc_pmacro_ddll_short_cmd_1;
u32 emc_pmacro_ddll_short_cmd_2;
u32 emc_pmacro_ddll_periodic_offset;
/*
* Specifies the delay after asserting CKE pin during a WarmBoot0
* sequence (in microseconds)
*/
u32 warm_boot_wait;
/* Specifies the value for EMC_ODT_WRITE */
u32 emc_odt_write;
/* Periodic ZQ calibration */
/*
* Specifies the value for EMC_ZCAL_INTERVAL
* Value 0 disables ZQ calibration
*/
u32 emc_zcal_interval;
/* Specifies the value for EMC_ZCAL_WAIT_CNT */
u32 emc_zcal_wait_cnt;
/* Specifies the value for EMC_ZCAL_MRW_CMD */
u32 emc_zcal_mrw_cmd;
/* DRAM initialization sequence flow control */
/* Specifies the MRS command value for resetting DLL */
u32 emc_mrs_reset_dll;
/* Specifies the command for ZQ initialization of device 0 */
u32 emc_zcal_init_dev0;
/* Specifies the command for ZQ initialization of device 1 */
u32 emc_zcal_init_dev1;
/*
* Specifies the wait time after programming a ZQ initialization
* command (in microseconds)
*/
u32 emc_zcal_init_wait;
/*
* Specifies the enable for ZQ calibration at cold boot [bit 0]
* and warm boot [bit 1]
*/
u32 emc_zcal_warm_cold_boot_enables;
/*
* Specifies the MRW command to LPDDR2 for ZQ calibration
* on warmboot
*/
/* Is issued to both devices separately */
u32 emc_mrw_lpddr2zcal_warm_boot;
/*
* Specifies the ZQ command to DDR3 for ZQ calibration on warmboot
* Is issued to both devices separately
*/
u32 emc_zqcal_ddr3_warm_boot;
u32 emc_zqcal_lpddr4_warm_boot;
/*
* Specifies the wait time for ZQ calibration on warmboot
* (in microseconds)
*/
u32 emc_zcal_warm_boot_wait;
/*
* Specifies the enable for DRAM Mode Register programming
* at warm boot
*/
u32 emc_mrs_warm_boot_enable;
/*
* Specifies the wait time after sending an MRS DLL reset command
* in microseconds)
*/
u32 emc_mrs_reset_dll_wait;
/* Specifies the extra MRS command to initialize mode registers */
u32 emc_mrs_extra;
/* Specifies the extra MRS command at warm boot */
u32 emc_warm_boot_mrs_extra;
/* Specifies the EMRS command to enable the DDR2 DLL */
u32 emc_emrs_ddr2_dll_enable;
/* Specifies the MRS command to reset the DDR2 DLL */
u32 emc_mrs_ddr2_dll_reset;
/* Specifies the EMRS command to set OCD calibration */
u32 emc_emrs_ddr2_ocd_calib;
/*
* Specifies the wait between initializing DDR and setting OCD
* calibration (in microseconds)
*/
u32 emc_ddr2_wait;
/* Specifies the value for EMC_CLKEN_OVERRIDE */
u32 emc_clken_override;
/*
* Specifies LOG2 of the extra refresh numbers after booting
* Program 0 to disable
*/
u32 emc_extra_refresh_num;
/* Specifies the master override for all EMC clocks */
u32 emc_clken_override_allwarm_boot;
/* Specifies the master override for all MC clocks */
u32 mc_clken_override_allwarm_boot;
/* Specifies digital dll period, choosing between 4 to 64 ms */
u32 emc_cfg_dig_dll_period_warm_boot;
/* Pad controls */
/* Specifies the value for PMC_VDDP_SEL */
u32 pmc_vddp_sel;
/* Specifies the wait time after programming PMC_VDDP_SEL */
u32 pmc_vddp_sel_wait;
/* Specifies the value for PMC_DDR_CFG */
u32 pmc_ddr_cfg;
/* Specifies the value for PMC_IO_DPD3_REQ */
u32 pmc_io_dpd3_req;
/* Specifies the wait time after programming PMC_IO_DPD3_REQ */
u32 pmc_io_dpd3_req_wait;
u32 pmc_io_dpd4_req_wait;
/* Specifies the value for PMC_REG_SHORT */
u32 pmc_reg_short;
/* Specifies the value for PMC_NO_IOPOWER */
u32 pmc_no_io_power;
u32 pmc_ddr_ctrl_wait;
u32 pmc_ddr_ctrl;
/* Specifies the value for EMC_ACPD_CONTROL */
u32 emc_acpd_control;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */
u32 emc_swizzle_rank0_byte0;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */
u32 emc_swizzle_rank0_byte1;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */
u32 emc_swizzle_rank0_byte2;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */
u32 emc_swizzle_rank0_byte3;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */
u32 emc_swizzle_rank1_byte0;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */
u32 emc_swizzle_rank1_byte1;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */
u32 emc_swizzle_rank1_byte2;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */
u32 emc_swizzle_rank1_byte3;
/* Specifies the value for EMC_TXDSRVTTGEN */
u32 emc_txdsrvttgen;
/* Specifies the value for EMC_DATA_BRLSHFT_0 */
u32 emc_data_brlshft0;
u32 emc_data_brlshft1;
u32 emc_dqs_brlshft0;
u32 emc_dqs_brlshft1;
u32 emc_cmd_brlshft0;
u32 emc_cmd_brlshft1;
u32 emc_cmd_brlshft2;
u32 emc_cmd_brlshft3;
u32 emc_quse_brlshft0;
u32 emc_quse_brlshft1;
u32 emc_quse_brlshft2;
u32 emc_quse_brlshft3;
u32 emc_dll_cfg0;
u32 emc_dll_cfg1;
u32 emc_pmc_scratch1;
u32 emc_pmc_scratch2;
u32 emc_pmc_scratch3;
u32 emc_pmacro_pad_cfg_ctrl;
u32 emc_pmacro_vttgen_ctrl0;
u32 emc_pmacro_vttgen_ctrl1;
u32 emc_pmacro_vttgen_ctrl2;
u32 emc_pmacro_dsr_vttgen_ctrl0;
u32 emc_pmacro_brick_ctrl_rfu1;
u32 emc_pmacro_cmd_brick_ctrl_fdpd;
u32 emc_pmacro_brick_ctrl_rfu2;
u32 emc_pmacro_data_brick_ctrl_fdpd;
u32 emc_pmacro_bg_bias_ctrl0;
u32 emc_pmacro_data_pad_rx_ctrl;
u32 emc_pmacro_cmd_pad_rx_ctrl;
u32 emc_pmacro_data_rx_term_mode;
u32 emc_pmacro_cmd_rx_term_mode;
u32 emc_pmacro_data_pad_tx_ctrl;
u32 emc_pmacro_cmd_pad_tx_ctrl;
u32 emc_cfg3;
u32 emc_pmacro_tx_pwrd0;
u32 emc_pmacro_tx_pwrd1;
u32 emc_pmacro_tx_pwrd2;
u32 emc_pmacro_tx_pwrd3;
u32 emc_pmacro_tx_pwrd4;
u32 emc_pmacro_tx_pwrd5;
u32 emc_config_sample_delay;
u32 emc_pmacro_brick_mapping0;
u32 emc_pmacro_brick_mapping1;
u32 emc_pmacro_brick_mapping2;
u32 emc_pmacro_tx_sel_clk_src0;
u32 emc_pmacro_tx_sel_clk_src1;
u32 emc_pmacro_tx_sel_clk_src2;
u32 emc_pmacro_tx_sel_clk_src3;
u32 emc_pmacro_tx_sel_clk_src4;
u32 emc_pmacro_tx_sel_clk_src5;
u32 emc_pmacro_perbit_fgcg_ctrl0;
u32 emc_pmacro_perbit_fgcg_ctrl1;
u32 emc_pmacro_perbit_fgcg_ctrl2;
u32 emc_pmacro_perbit_fgcg_ctrl3;
u32 emc_pmacro_perbit_fgcg_ctrl4;
u32 emc_pmacro_perbit_fgcg_ctrl5;
u32 emc_pmacro_perbit_rfu_ctrl0;
u32 emc_pmacro_perbit_rfu_ctrl1;
u32 emc_pmacro_perbit_rfu_ctrl2;
u32 emc_pmacro_perbit_rfu_ctrl3;
u32 emc_pmacro_perbit_rfu_ctrl4;
u32 emc_pmacro_perbit_rfu_ctrl5;
u32 emc_pmacro_perbit_rfu1_ctrl0;
u32 emc_pmacro_perbit_rfu1_ctrl1;
u32 emc_pmacro_perbit_rfu1_ctrl2;
u32 emc_pmacro_perbit_rfu1_ctrl3;
u32 emc_pmacro_perbit_rfu1_ctrl4;
u32 emc_pmacro_perbit_rfu1_ctrl5;
u32 emc_pmacro_data_pi_ctrl;
u32 emc_pmacro_cmd_pi_ctrl;
u32 emc_pmacro_ddll_bypass;
u32 emc_pmacro_ddll_pwrd0;
u32 emc_pmacro_ddll_pwrd1;
u32 emc_pmacro_ddll_pwrd2;
u32 emc_pmacro_cmd_ctrl0;
u32 emc_pmacro_cmd_ctrl1;
u32 emc_pmacro_cmd_ctrl2;
/* DRAM size information */
/* Specifies the value for MC_EMEM_ADR_CFG */
u32 mc_emem_adr_cfg;
/* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */
u32 mc_emem_adr_cfg_dev0;
/* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */
u32 mc_emem_adr_cfg_dev1;
u32 mc_emem_adr_cfg_channel_mask;
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG0 */
u32 mc_emem_adr_cfg_bank_mask0;
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */
u32 mc_emem_adr_cfg_bank_mask1;
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */
u32 mc_emem_adr_cfg_bank_mask2;
/*
* Specifies the value for MC_EMEM_CFG which holds the external memory
* size (in KBytes)
*/
u32 mc_emem_cfg;
/* MC arbitration configuration */
/* Specifies the value for MC_EMEM_ARB_CFG */
u32 mc_emem_arb_cfg;
/* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */
u32 mc_emem_arb_outstanding_req;
u32 emc_emem_arb_refpb_hp_ctrl;
u32 emc_emem_arb_refpb_bank_ctrl;
/* Specifies the value for MC_EMEM_ARB_TIMING_RCD */
u32 mc_emem_arb_timing_rcd;
/* Specifies the value for MC_EMEM_ARB_TIMING_RP */
u32 mc_emem_arb_timing_rp;
/* Specifies the value for MC_EMEM_ARB_TIMING_RC */
u32 mc_emem_arb_timing_rc;
/* Specifies the value for MC_EMEM_ARB_TIMING_RAS */
u32 mc_emem_arb_timing_ras;
/* Specifies the value for MC_EMEM_ARB_TIMING_FAW */
u32 mc_emem_arb_timing_faw;
/* Specifies the value for MC_EMEM_ARB_TIMING_RRD */
u32 mc_emem_arb_timing_rrd;
/* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */
u32 mc_emem_arb_timing_rap2pre;
/* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */
u32 mc_emem_arb_timing_wap2pre;
/* Specifies the value for MC_EMEM_ARB_TIMING_R2R */
u32 mc_emem_arb_timing_r2r;
/* Specifies the value for MC_EMEM_ARB_TIMING_W2W */
u32 mc_emem_arb_timing_w2w;
/* Specifies the value for MC_EMEM_ARB_TIMING_R2W */
u32 mc_emem_arb_timing_r2w;
/* Specifies the value for MC_EMEM_ARB_TIMING_W2R */
u32 mc_emem_arb_timing_w2r;
u32 mc_emem_arb_timing_rfcpb;
/* Specifies the value for MC_EMEM_ARB_DA_TURNS */
u32 mc_emem_arb_da_turns;
/* Specifies the value for MC_EMEM_ARB_DA_COVERS */
u32 mc_emem_arb_da_covers;
/* Specifies the value for MC_EMEM_ARB_MISC0 */
u32 mc_emem_arb_misc0;
/* Specifies the value for MC_EMEM_ARB_MISC1 */
u32 mc_emem_arb_misc1;
u32 mc_emem_arb_misc2;
/* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */
u32 mc_emem_arb_ring1_throttle;
/* Specifies the value for MC_EMEM_ARB_OVERRIDE */
u32 mc_emem_arb_override;
/* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */
u32 mc_emem_arb_override1;
/* Specifies the value for MC_EMEM_ARB_RSV */
u32 mc_emem_arb_rsv;
u32 mc_da_cfg0;
u32 mc_emem_arb_timing_ccdmw;
/* Specifies the value for MC_CLKEN_OVERRIDE */
u32 mc_clken_override;
/* Specifies the value for MC_STAT_CONTROL */
u32 mc_stat_control;
/* Specifies the value for MC_VIDEO_PROTECT_BOM */
u32 mc_video_protect_bom;
/* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */
u32 mc_video_protect_bom_adr_hi;
/* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */
u32 mc_video_protect_size_mb;
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */
u32 mc_video_protect_vpr_override;
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */
u32 mc_video_protect_vpr_override1;
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */
u32 mc_video_protect_gpu_override0;
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */
u32 mc_video_protect_gpu_override1;
/* Specifies the value for MC_SEC_CARVEOUT_BOM */
u32 mc_sec_carveout_bom;
/* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */
u32 mc_sec_carveout_adr_hi;
/* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */
u32 mc_sec_carveout_size_mb;
/* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.VIDEO_PROTECT_WRITE_ACCESS */
u32 mc_video_protect_write_access;
/* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.SEC_CARVEOUT_WRITE_ACCESS */
u32 mc_sec_carveout_protect_write_access;
u32 mc_generalized_carveout1_bom;
u32 mc_generalized_carveout1_bom_hi;
u32 mc_generalized_carveout1_size_128kb;
u32 mc_generalized_carveout1_access0;
u32 mc_generalized_carveout1_access1;
u32 mc_generalized_carveout1_access2;
u32 mc_generalized_carveout1_access3;
u32 mc_generalized_carveout1_access4;
u32 mc_generalized_carveout1_force_internal_access0;
u32 mc_generalized_carveout1_force_internal_access1;
u32 mc_generalized_carveout1_force_internal_access2;
u32 mc_generalized_carveout1_force_internal_access3;
u32 mc_generalized_carveout1_force_internal_access4;
u32 mc_generalized_carveout1_cfg0;
u32 mc_generalized_carveout2_bom;
u32 mc_generalized_carveout2_bom_hi;
u32 mc_generalized_carveout2_size_128kb;
u32 mc_generalized_carveout2_access0;
u32 mc_generalized_carveout2_access1;
u32 mc_generalized_carveout2_access2;
u32 mc_generalized_carveout2_access3;
u32 mc_generalized_carveout2_access4;
u32 mc_generalized_carveout2_force_internal_access0;
u32 mc_generalized_carveout2_force_internal_access1;
u32 mc_generalized_carveout2_force_internal_access2;
u32 mc_generalized_carveout2_force_internal_access3;
u32 mc_generalized_carveout2_force_internal_access4;
u32 mc_generalized_carveout2_cfg0;
u32 mc_generalized_carveout3_bom;
u32 mc_generalized_carveout3_bom_hi;
u32 mc_generalized_carveout3_size_128kb;
u32 mc_generalized_carveout3_access0;
u32 mc_generalized_carveout3_access1;
u32 mc_generalized_carveout3_access2;
u32 mc_generalized_carveout3_access3;
u32 mc_generalized_carveout3_access4;
u32 mc_generalized_carveout3_force_internal_access0;
u32 mc_generalized_carveout3_force_internal_access1;
u32 mc_generalized_carveout3_force_internal_access2;
u32 mc_generalized_carveout3_force_internal_access3;
u32 mc_generalized_carveout3_force_internal_access4;
u32 mc_generalized_carveout3_cfg0;
u32 mc_generalized_carveout4_bom;
u32 mc_generalized_carveout4_bom_hi;
u32 mc_generalized_carveout4_size_128kb;
u32 mc_generalized_carveout4_access0;
u32 mc_generalized_carveout4_access1;
u32 mc_generalized_carveout4_access2;
u32 mc_generalized_carveout4_access3;
u32 mc_generalized_carveout4_access4;
u32 mc_generalized_carveout4_force_internal_access0;
u32 mc_generalized_carveout4_force_internal_access1;
u32 mc_generalized_carveout4_force_internal_access2;
u32 mc_generalized_carveout4_force_internal_access3;
u32 mc_generalized_carveout4_force_internal_access4;
u32 mc_generalized_carveout4_cfg0;
u32 mc_generalized_carveout5_bom;
u32 mc_generalized_carveout5_bom_hi;
u32 mc_generalized_carveout5_size_128kb;
u32 mc_generalized_carveout5_access0;
u32 mc_generalized_carveout5_access1;
u32 mc_generalized_carveout5_access2;
u32 mc_generalized_carveout5_access3;
u32 mc_generalized_carveout5_access4;
u32 mc_generalized_carveout5_force_internal_access0;
u32 mc_generalized_carveout5_force_internal_access1;
u32 mc_generalized_carveout5_force_internal_access2;
u32 mc_generalized_carveout5_force_internal_access3;
u32 mc_generalized_carveout5_force_internal_access4;
u32 mc_generalized_carveout5_cfg0;
/* Specifies enable for CA training */
u32 emc_ca_training_enable;
/* Set if bit 6 select is greater than bit 7 select; uses aremc.spec packet SWIZZLE_BIT6_GT_BIT7 */
u32 swizzle_rank_byte_encode;
/* Specifies enable and offset for patched boot rom write */
u32 boot_rom_patch_control;
/* Specifies data for patched boot rom write */
u32 boot_rom_patch_data;
/* Specifies the value for MC_MTS_CARVEOUT_BOM */
u32 mc_mts_carveout_bom;
/* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */
u32 mc_mts_carveout_adr_hi;
/* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */
u32 mc_mts_carveout_size_mb;
/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
u32 mc_mts_carveout_reg_ctrl;
u32 mc_untranslated_region_check;
/* Just a place holder for special usage when there is no BCT for certain registers */
u32 bct_na;
};
#endif

View File

@ -37,7 +37,7 @@
/** /**
* Defines the SDRAM parameter structure * Defines the SDRAM parameter structure
*/ */
typedef struct _sdram_params typedef struct _sdram_params_t210_t
{ {
/* Specifies the type of memory device */ /* Specifies the type of memory device */
u32 memory_type; u32 memory_type;
@ -925,6 +925,6 @@ typedef struct _sdram_params
u32 mc_mts_carveout_size_mb; u32 mc_mts_carveout_size_mb;
/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */ /* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
u32 mc_mts_carveout_reg_ctrl; u32 mc_mts_carveout_reg_ctrl;
} sdram_params_t; } sdram_params_t210_t;
#endif #endif

View File

@ -0,0 +1,989 @@
/*
* Copyright (c) 2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef _SDRAM_PARAM_T210B01_H_
#define _SDRAM_PARAM_T210B01_H_
typedef struct _sdram_params_t210b01_t
{
/* Specifies the type of memory device */
u32 memory_type;
/* MC/EMC clock source configuration */
/* Specifies the M value for PllM */
u32 pllm_input_divider;
/* Specifies the N value for PllM */
u32 pllm_feedback_divider;
/* Specifies the time to wait for PLLM to lock (in microseconds) */
u32 pllm_stable_time;
/* Specifies misc. control bits */
u32 pllm_setup_control;
/* Specifies the P value for PLLM */
u32 pllm_post_divider;
/* Specifies value for Charge Pump Gain Control */
u32 pllm_kcp;
/* Specifies VCO gain */
u32 pllm_kvco;
/* Spare BCT param */
u32 emc_bct_spare0;
/* Spare BCT param */
u32 emc_bct_spare1;
/* Spare BCT param */
u32 emc_bct_spare2;
/* Spare BCT param */
u32 emc_bct_spare3;
/* Spare BCT param */
u32 emc_bct_spare4;
/* Spare BCT param */
u32 emc_bct_spare5;
/* Spare BCT param */
u32 emc_bct_spare6;
/* Spare BCT param */
u32 emc_bct_spare7;
/* Spare BCT param */
u32 emc_bct_spare8;
/* Spare BCT param */
u32 emc_bct_spare9;
/* Spare BCT param */
u32 emc_bct_spare10;
/* Spare BCT param */
u32 emc_bct_spare11;
/* Spare BCT param */
u32 emc_bct_spare12;
/* Spare BCT param */
u32 emc_bct_spare13;
/* Spare BCT param */
u32 emc_bct_spare_secure0;
/* Spare BCT param */
u32 emc_bct_spare_secure1;
/* Spare BCT param */
u32 emc_bct_spare_secure2;
/* Spare BCT param */
u32 emc_bct_spare_secure3;
/* Spare BCT param */
u32 emc_bct_spare_secure4;
/* Spare BCT param */
u32 emc_bct_spare_secure5;
/* Spare BCT param */
u32 emc_bct_spare_secure6;
/* Spare BCT param */
u32 emc_bct_spare_secure7;
/* Spare BCT param */
u32 emc_bct_spare_secure8;
/* Spare BCT param */
u32 emc_bct_spare_secure9;
/* Spare BCT param */
u32 emc_bct_spare_secure10;
/* Spare BCT param */
u32 emc_bct_spare_secure11;
/* Spare BCT param */
u32 emc_bct_spare_secure12;
/* Spare BCT param */
u32 emc_bct_spare_secure13;
/* Spare BCT param */
u32 emc_bct_spare_secure14;
/* Spare BCT param */
u32 emc_bct_spare_secure15;
/* Spare BCT param */
u32 emc_bct_spare_secure16;
/* Spare BCT param */
u32 emc_bct_spare_secure17;
/* Spare BCT param */
u32 emc_bct_spare_secure18;
/* Spare BCT param */
u32 emc_bct_spare_secure19;
/* Spare BCT param */
u32 emc_bct_spare_secure20;
/* Spare BCT param */
u32 emc_bct_spare_secure21;
/* Spare BCT param */
u32 emc_bct_spare_secure22;
/* Spare BCT param */
u32 emc_bct_spare_secure23;
/* Defines EMC_2X_CLK_SRC, EMC_2X_CLK_DIVISOR, EMC_INVERT_DCD */
u32 emc_clock_source;
u32 emc_clock_source_dll;
/* Defines possible override for PLLLM_MISC2 */
u32 clk_rst_pllm_misc20_override;
/* enables override for PLLLM_MISC2 */
u32 clk_rst_pllm_misc20_override_enable;
/* defines CLK_ENB_MC1 in register clk_rst_controller_clk_enb_w_clr */
u32 clear_clock2_mc1;
/* Auto-calibration of EMC pads */
/* Specifies the value for EMC_AUTO_CAL_INTERVAL */
u32 emc_auto_cal_interval;
/*
* Specifies the value for EMC_AUTO_CAL_CONFIG
* Note: Trigger bits are set by the SDRAM code.
*/
u32 emc_auto_cal_config;
/* Specifies the value for EMC_AUTO_CAL_CONFIG2 */
u32 emc_auto_cal_config2;
/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
u32 emc_auto_cal_config3;
u32 emc_auto_cal_config4;
u32 emc_auto_cal_config5;
u32 emc_auto_cal_config6;
u32 emc_auto_cal_config7;
u32 emc_auto_cal_config8;
u32 emc_auto_cal_config9;
/* Specifies the value for EMC_AUTO_CAL_VREF_SEL_0 */
u32 emc_auto_cal_vref_sel0;
u32 emc_auto_cal_vref_sel1;
/* Specifies the value for EMC_AUTO_CAL_CHANNEL */
u32 emc_auto_cal_channel;
/* Specifies the value for EMC_PMACRO_AUTOCAL_CFG_0 */
u32 emc_pmacro_auto_cal_cfg0;
u32 emc_pmacro_auto_cal_cfg1;
u32 emc_pmacro_auto_cal_cfg2;
u32 emc_pmacro_rx_term;
u32 emc_pmacro_dq_tx_drive;
u32 emc_pmacro_ca_tx_drive;
u32 emc_pmacro_cmd_tx_drive;
u32 emc_pmacro_auto_cal_common;
u32 emc_pmacro_zcrtl;
/*
* Specifies the time for the calibration
* to stabilize (in microseconds)
*/
u32 emc_auto_cal_wait;
u32 emc_xm2_comp_pad_ctrl;
u32 emc_xm2_comp_pad_ctrl2;
u32 emc_xm2_comp_pad_ctrl3;
/*
* DRAM size information
* Specifies the value for EMC_ADR_CFG
*/
u32 emc_adr_cfg;
/*
* Specifies the time to wait after asserting pin
* CKE (in microseconds)
*/
u32 emc_pin_program_wait;
/* Specifies the extra delay before/after pin RESET/CKE command */
u32 emc_pin_extra_wait;
u32 emc_pin_gpio_enable;
u32 emc_pin_gpio;
/*
* Specifies the extra delay after the first writing
* of EMC_TIMING_CONTROL
*/
u32 emc_timing_control_wait;
/* Timing parameters required for the SDRAM */
/* Specifies the value for EMC_RC */
u32 emc_rc;
/* Specifies the value for EMC_RFC */
u32 emc_rfc;
u32 emc_rfc_pb;
u32 emc_ref_ctrl2;
/* Specifies the value for EMC_RFC_SLR */
u32 emc_rfc_slr;
/* Specifies the value for EMC_RAS */
u32 emc_ras;
/* Specifies the value for EMC_RP */
u32 emc_rp;
/* Specifies the value for EMC_R2R */
u32 emc_r2r;
/* Specifies the value for EMC_W2W */
u32 emc_w2w;
/* Specifies the value for EMC_R2W */
u32 emc_r2w;
/* Specifies the value for EMC_W2R */
u32 emc_w2r;
/* Specifies the value for EMC_R2P */
u32 emc_r2p;
/* Specifies the value for EMC_W2P */
u32 emc_w2p;
/* Specifies the value for EMC_RD_RCD */
u32 emc_tppd;
u32 emc_trtm;
u32 emc_twtm;
u32 emc_tratm;
u32 emc_twatm;
u32 emc_tr2ref;
u32 emc_ccdmw;
u32 emc_rd_rcd;
/* Specifies the value for EMC_WR_RCD */
u32 emc_wr_rcd;
/* Specifies the value for EMC_RRD */
u32 emc_rrd;
/* Specifies the value for EMC_REXT */
u32 emc_rext;
/* Specifies the value for EMC_WEXT */
u32 emc_wext;
/* Specifies the value for EMC_WDV */
u32 emc_wdv;
u32 emc_wdv_chk;
u32 emc_wsv;
u32 emc_wev;
/* Specifies the value for EMC_WDV_MASK */
u32 emc_wdv_mask;
u32 emc_ws_duration;
u32 emc_we_duration;
/* Specifies the value for EMC_QUSE */
u32 emc_quse;
/* Specifies the value for EMC_QUSE_WIDTH */
u32 emc_quse_width;
/* Specifies the value for EMC_IBDLY */
u32 emc_ibdly;
u32 emc_obdly;
/* Specifies the value for EMC_EINPUT */
u32 emc_einput;
/* Specifies the value for EMC_EINPUT_DURATION */
u32 emc_einput_duration;
/* Specifies the value for EMC_PUTERM_EXTRA */
u32 emc_puterm_extra;
/* Specifies the value for EMC_PUTERM_WIDTH */
u32 emc_puterm_width;
u32 emc_qrst;
u32 emc_qsafe;
u32 emc_rdv;
u32 emc_rdv_mask;
u32 emc_rdv_early;
u32 emc_rdv_early_mask;
/* Specifies the value for EMC_QPOP */
u32 emc_qpop;
/* Specifies the value for EMC_REFRESH */
u32 emc_refresh;
/* Specifies the value for EMC_BURST_REFRESH_NUM */
u32 emc_burst_refresh_num;
/* Specifies the value for EMC_PRE_REFRESH_REQ_CNT */
u32 emc_prerefresh_req_cnt;
/* Specifies the value for EMC_PDEX2WR */
u32 emc_pdex2wr;
/* Specifies the value for EMC_PDEX2RD */
u32 emc_pdex2rd;
/* Specifies the value for EMC_PCHG2PDEN */
u32 emc_pchg2pden;
/* Specifies the value for EMC_ACT2PDEN */
u32 emc_act2pden;
/* Specifies the value for EMC_AR2PDEN */
u32 emc_ar2pden;
/* Specifies the value for EMC_RW2PDEN */
u32 emc_rw2pden;
u32 emc_cke2pden;
u32 emc_pdex2che;
u32 emc_pdex2mrr;
/* Specifies the value for EMC_TXSR */
u32 emc_txsr;
/* Specifies the value for EMC_TXSRDLL */
u32 emc_txsr_dll;
/* Specifies the value for EMC_TCKE */
u32 emc_tcke;
/* Specifies the value for EMC_TCKESR */
u32 emc_tckesr;
/* Specifies the value for EMC_TPD */
u32 emc_tpd;
/* Specifies the value for EMC_TFAW */
u32 emc_tfaw;
/* Specifies the value for EMC_TRPAB */
u32 emc_trpab;
/* Specifies the value for EMC_TCLKSTABLE */
u32 emc_tclkstable;
/* Specifies the value for EMC_TCLKSTOP */
u32 emc_tclkstop;
/* Specifies the value for EMC_TREFBW */
u32 emc_trefbw;
/* FBIO configuration values */
/* Specifies the value for EMC_FBIO_CFG5 */
u32 emc_fbio_cfg5;
/* Specifies the value for EMC_FBIO_CFG7 */
u32 emc_fbio_cfg7;
u32 emc_fbio_cfg8;
/* Command mapping for CMD brick 0 */
u32 emc_cmd_mapping_cmd0_0;
u32 emc_cmd_mapping_cmd0_1;
u32 emc_cmd_mapping_cmd0_2;
u32 emc_cmd_mapping_cmd1_0;
u32 emc_cmd_mapping_cmd1_1;
u32 emc_cmd_mapping_cmd1_2;
u32 emc_cmd_mapping_cmd2_0;
u32 emc_cmd_mapping_cmd2_1;
u32 emc_cmd_mapping_cmd2_2;
u32 emc_cmd_mapping_cmd3_0;
u32 emc_cmd_mapping_cmd3_1;
u32 emc_cmd_mapping_cmd3_2;
u32 emc_cmd_mapping_byte;
/* Specifies the value for EMC_FBIO_SPARE */
u32 emc_fbio_spare;
/* Specifies the value for EMC_CFG_RSV */
u32 emc_cfg_rsv;
/* MRS command values */
/* Specifies the value for EMC_MRS */
u32 emc_mrs;
/* Specifies the MP0 command to initialize mode registers */
u32 emc_emrs;
/* Specifies the MP2 command to initialize mode registers */
u32 emc_emrs2;
/* Specifies the MP3 command to initialize mode registers */
u32 emc_emrs3;
/* Specifies the programming to LPDDR2 Mode Register 1 at cold boot */
u32 emc_mrw1;
/* Specifies the programming to LPDDR2 Mode Register 2 at cold boot */
u32 emc_mrw2;
/* Specifies the programming to LPDDR2 Mode Register 3 at cold boot */
u32 emc_mrw3;
/* Specifies the programming to LPDDR2 Mode Register 11 at cold boot */
u32 emc_mrw4;
/* Specifies the programming to LPDDR4 Mode Register 3 at cold boot */
u32 emc_mrw6;
/* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */
u32 emc_mrw8;
/* Specifies the programming to LPDDR4 Mode Register 11 at cold boot */
u32 emc_mrw9;
/* Specifies the programming to LPDDR4 Mode Register 12 at cold boot */
u32 emc_mrw10;
/* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */
u32 emc_mrw12;
/* Specifies the programming to LPDDR4 Mode Register 14 at cold boot */
u32 emc_mrw13;
/* Specifies the programming to LPDDR4 Mode Register 22 at cold boot */
u32 emc_mrw14;
/*
* Specifies the programming to extra LPDDR2 Mode Register
* at cold boot
*/
u32 emc_mrw_extra;
/*
* Specifies the programming to extra LPDDR2 Mode Register
* at warm boot
*/
u32 emc_warm_boot_mrw_extra;
/*
* Specify the enable of extra Mode Register programming at
* warm boot
*/
u32 emc_warm_boot_extramode_reg_write_enable;
/*
* Specify the enable of extra Mode Register programming at
* cold boot
*/
u32 emc_extramode_reg_write_enable;
/* Specifies the EMC_MRW reset command value */
u32 emc_mrw_reset_command;
/* Specifies the EMC Reset wait time (in microseconds) */
u32 emc_mrw_reset_ninit_wait;
/* Specifies the value for EMC_MRS_WAIT_CNT */
u32 emc_mrs_wait_cnt;
/* Specifies the value for EMC_MRS_WAIT_CNT2 */
u32 emc_mrs_wait_cnt2;
/* EMC miscellaneous configurations */
/* Specifies the value for EMC_CFG */
u32 emc_cfg;
/* Specifies the value for EMC_CFG_2 */
u32 emc_cfg2;
/* Specifies the pipe bypass controls */
u32 emc_cfg_pipe;
u32 emc_cfg_pipe_clk;
u32 emc_fdpd_ctrl_cmd_no_ramp;
u32 emc_cfg_update;
/* Specifies the value for EMC_DBG */
u32 emc_dbg;
u32 emc_dbg_write_mux;
/* Specifies the value for EMC_CMDQ */
u32 emc_cmd_q;
/* Specifies the value for EMC_MC2EMCQ */
u32 emc_mc2emc_q;
/* Specifies the value for EMC_DYN_SELF_REF_CONTROL */
u32 emc_dyn_self_ref_control;
/* Specifies the value for MEM_INIT_DONE */
u32 ahb_arbitration_xbar_ctrl_meminit_done;
/* Specifies the value for EMC_CFG_DIG_DLL */
u32 emc_cfg_dig_dll;
u32 emc_cfg_dig_dll_1;
/* Specifies the value for EMC_CFG_DIG_DLL_PERIOD */
u32 emc_cfg_dig_dll_period;
/* Specifies the value of *DEV_SELECTN of various EMC registers */
u32 emc_dev_select;
/* Specifies the value for EMC_SEL_DPD_CTRL */
u32 emc_sel_dpd_ctrl;
/* Pads trimmer delays */
u32 emc_fdpd_ctrl_dq;
u32 emc_fdpd_ctrl_cmd;
u32 emc_pmacro_ib_vref_dq_0;
u32 emc_pmacro_ib_vref_dq_1;
u32 emc_pmacro_ib_vref_dqs_0;
u32 emc_pmacro_ib_vref_dqs_1;
u32 emc_pmacro_ib_rxrt;
u32 emc_cfg_pipe1;
u32 emc_cfg_pipe2;
/* Specifies the value for EMC_PMACRO_QUSE_DDLL_RANK0_0 */
u32 emc_pmacro_quse_ddll_rank0_0;
u32 emc_pmacro_quse_ddll_rank0_1;
u32 emc_pmacro_quse_ddll_rank0_2;
u32 emc_pmacro_quse_ddll_rank0_3;
u32 emc_pmacro_quse_ddll_rank0_4;
u32 emc_pmacro_quse_ddll_rank0_5;
u32 emc_pmacro_quse_ddll_rank1_0;
u32 emc_pmacro_quse_ddll_rank1_1;
u32 emc_pmacro_quse_ddll_rank1_2;
u32 emc_pmacro_quse_ddll_rank1_3;
u32 emc_pmacro_quse_ddll_rank1_4;
u32 emc_pmacro_quse_ddll_rank1_5;
u32 emc_pmacro_ob_ddll_long_dq_rank0_0;
u32 emc_pmacro_ob_ddll_long_dq_rank0_1;
u32 emc_pmacro_ob_ddll_long_dq_rank0_2;
u32 emc_pmacro_ob_ddll_long_dq_rank0_3;
u32 emc_pmacro_ob_ddll_long_dq_rank0_4;
u32 emc_pmacro_ob_ddll_long_dq_rank0_5;
u32 emc_pmacro_ob_ddll_long_dq_rank1_0;
u32 emc_pmacro_ob_ddll_long_dq_rank1_1;
u32 emc_pmacro_ob_ddll_long_dq_rank1_2;
u32 emc_pmacro_ob_ddll_long_dq_rank1_3;
u32 emc_pmacro_ob_ddll_long_dq_rank1_4;
u32 emc_pmacro_ob_ddll_long_dq_rank1_5;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_0;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_1;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_2;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_3;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_4;
u32 emc_pmacro_ob_ddll_long_dqs_rank0_5;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_0;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_1;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_2;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_3;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_4;
u32 emc_pmacro_ob_ddll_long_dqs_rank1_5;
u32 emc_pmacro_ib_ddll_long_dqs_rank0_0;
u32 emc_pmacro_ib_ddll_long_dqs_rank0_1;
u32 emc_pmacro_ib_ddll_long_dqs_rank0_2;
u32 emc_pmacro_ib_ddll_long_dqs_rank0_3;
u32 emc_pmacro_ib_ddll_long_dqs_rank1_0;
u32 emc_pmacro_ib_ddll_long_dqs_rank1_1;
u32 emc_pmacro_ib_ddll_long_dqs_rank1_2;
u32 emc_pmacro_ib_ddll_long_dqs_rank1_3;
u32 emc_pmacro_ddll_long_cmd_0;
u32 emc_pmacro_ddll_long_cmd_1;
u32 emc_pmacro_ddll_long_cmd_2;
u32 emc_pmacro_ddll_long_cmd_3;
u32 emc_pmacro_ddll_long_cmd_4;
u32 emc_pmacro_ddll_short_cmd_0;
u32 emc_pmacro_ddll_short_cmd_1;
u32 emc_pmacro_ddll_short_cmd_2;
u32 emc_pmacro_ddll_periodic_offset;
/*
* Specifies the delay after asserting CKE pin during a WarmBoot0
* sequence (in microseconds)
*/
u32 warm_boot_wait;
/* Specifies the value for EMC_ODT_WRITE */
u32 emc_odt_write;
/* Periodic ZQ calibration */
/*
* Specifies the value for EMC_ZCAL_INTERVAL
* Value 0 disables ZQ calibration
*/
u32 emc_zcal_interval;
/* Specifies the value for EMC_ZCAL_WAIT_CNT */
u32 emc_zcal_wait_cnt;
/* Specifies the value for EMC_ZCAL_MRW_CMD */
u32 emc_zcal_mrw_cmd;
/* DRAM initialization sequence flow control */
/* Specifies the MRS command value for resetting DLL */
u32 emc_mrs_reset_dll;
/* Specifies the command for ZQ initialization of device 0 */
u32 emc_zcal_init_dev0;
/* Specifies the command for ZQ initialization of device 1 */
u32 emc_zcal_init_dev1;
/*
* Specifies the wait time after programming a ZQ initialization
* command (in microseconds)
*/
u32 emc_zcal_init_wait;
/*
* Specifies the enable for ZQ calibration at cold boot [bit 0]
* and warm boot [bit 1]
*/
u32 emc_zcal_warm_cold_boot_enables;
/*
* Specifies the MRW command to LPDDR2 for ZQ calibration
* on warmboot
*/
/* Is issued to both devices separately */
u32 emc_mrw_lpddr2zcal_warm_boot;
/*
* Specifies the ZQ command to DDR3 for ZQ calibration on warmboot
* Is issued to both devices separately
*/
u32 emc_zqcal_ddr3_warm_boot;
u32 emc_zqcal_lpddr4_warm_boot;
/*
* Specifies the wait time for ZQ calibration on warmboot
* (in microseconds)
*/
u32 emc_zcal_warm_boot_wait;
/*
* Specifies the enable for DRAM Mode Register programming
* at warm boot
*/
u32 emc_mrs_warm_boot_enable;
/*
* Specifies the wait time after sending an MRS DLL reset command
* in microseconds)
*/
u32 emc_mrs_reset_dll_wait;
/* Specifies the extra MRS command to initialize mode registers */
u32 emc_mrs_extra;
/* Specifies the extra MRS command at warm boot */
u32 emc_warm_boot_mrs_extra;
/* Specifies the EMRS command to enable the DDR2 DLL */
u32 emc_emrs_ddr2_dll_enable;
/* Specifies the MRS command to reset the DDR2 DLL */
u32 emc_mrs_ddr2_dll_reset;
/* Specifies the EMRS command to set OCD calibration */
u32 emc_emrs_ddr2_ocd_calib;
/*
* Specifies the wait between initializing DDR and setting OCD
* calibration (in microseconds)
*/
u32 emc_ddr2_wait;
/* Specifies the value for EMC_CLKEN_OVERRIDE */
u32 emc_clken_override;
/*
* Specifies LOG2 of the extra refresh numbers after booting
* Program 0 to disable
*/
u32 emc_extra_refresh_num;
/* Specifies the master override for all EMC clocks */
u32 emc_clken_override_allwarm_boot;
/* Specifies the master override for all MC clocks */
u32 mc_clken_override_allwarm_boot;
/* Specifies digital dll period, choosing between 4 to 64 ms */
u32 emc_cfg_dig_dll_period_warm_boot;
/* Pad controls */
/* Specifies the value for PMC_VDDP_SEL */
u32 pmc_vddp_sel;
/* Specifies the wait time after programming PMC_VDDP_SEL */
u32 pmc_vddp_sel_wait;
/* Specifies the value for PMC_DDR_CFG */
u32 pmc_ddr_cfg;
/* Specifies the value for PMC_IO_DPD3_REQ */
u32 pmc_io_dpd3_req;
/* Specifies the wait time after programming PMC_IO_DPD3_REQ */
u32 pmc_io_dpd3_req_wait;
u32 pmc_io_dpd4_req_wait;
/* Specifies the value for PMC_REG_SHORT */
u32 pmc_reg_short;
/* Specifies the value for PMC_NO_IOPOWER */
u32 pmc_no_io_power;
u32 pmc_ddr_ctrl_wait;
u32 pmc_ddr_ctrl;
/* Specifies the value for EMC_ACPD_CONTROL */
u32 emc_acpd_control;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE0 */
u32 emc_swizzle_rank0_byte0;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE1 */
u32 emc_swizzle_rank0_byte1;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE2 */
u32 emc_swizzle_rank0_byte2;
/* Specifies the value for EMC_SWIZZLE_RANK0_BYTE3 */
u32 emc_swizzle_rank0_byte3;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE0 */
u32 emc_swizzle_rank1_byte0;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE1 */
u32 emc_swizzle_rank1_byte1;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE2 */
u32 emc_swizzle_rank1_byte2;
/* Specifies the value for EMC_SWIZZLE_RANK1_BYTE3 */
u32 emc_swizzle_rank1_byte3;
/* Specifies the value for EMC_TXDSRVTTGEN */
u32 emc_txdsrvttgen;
/* Specifies the value for EMC_DATA_BRLSHFT_0 */
u32 emc_data_brlshft0;
u32 emc_data_brlshft1;
u32 emc_dqs_brlshft0;
u32 emc_dqs_brlshft1;
u32 emc_cmd_brlshft0;
u32 emc_cmd_brlshft1;
u32 emc_cmd_brlshft2;
u32 emc_cmd_brlshft3;
u32 emc_quse_brlshft0;
u32 emc_quse_brlshft1;
u32 emc_quse_brlshft2;
u32 emc_quse_brlshft3;
u32 emc_dll_cfg0;
u32 emc_dll_cfg1;
u32 emc_pmc_scratch1;
u32 emc_pmc_scratch2;
u32 emc_pmc_scratch3;
u32 emc_pmacro_pad_cfg_ctrl;
u32 emc_pmacro_vttgen_ctrl0;
u32 emc_pmacro_vttgen_ctrl1;
u32 emc_pmacro_vttgen_ctrl2;
u32 emc_pmacro_dsr_vttgen_ctrl0;
u32 emc_pmacro_brick_ctrl_rfu1;
u32 emc_pmacro_cmd_brick_ctrl_fdpd;
u32 emc_pmacro_brick_ctrl_rfu2;
u32 emc_pmacro_data_brick_ctrl_fdpd;
u32 emc_pmacro_bg_bias_ctrl0;
u32 emc_pmacro_data_pad_rx_ctrl;
u32 emc_pmacro_cmd_pad_rx_ctrl;
u32 emc_pmacro_data_rx_term_mode;
u32 emc_pmacro_cmd_rx_term_mode;
u32 emc_pmacro_data_pad_tx_ctrl;
u32 emc_pmacro_cmd_pad_tx_ctrl;
u32 emc_cfg3;
u32 emc_pmacro_tx_pwrd0;
u32 emc_pmacro_tx_pwrd1;
u32 emc_pmacro_tx_pwrd2;
u32 emc_pmacro_tx_pwrd3;
u32 emc_pmacro_tx_pwrd4;
u32 emc_pmacro_tx_pwrd5;
u32 emc_config_sample_delay;
u32 emc_pmacro_brick_mapping0;
u32 emc_pmacro_brick_mapping1;
u32 emc_pmacro_brick_mapping2;
u32 emc_pmacro_tx_sel_clk_src0;
u32 emc_pmacro_tx_sel_clk_src1;
u32 emc_pmacro_tx_sel_clk_src2;
u32 emc_pmacro_tx_sel_clk_src3;
u32 emc_pmacro_tx_sel_clk_src4;
u32 emc_pmacro_tx_sel_clk_src5;
u32 emc_pmacro_perbit_fgcg_ctrl0;
u32 emc_pmacro_perbit_fgcg_ctrl1;
u32 emc_pmacro_perbit_fgcg_ctrl2;
u32 emc_pmacro_perbit_fgcg_ctrl3;
u32 emc_pmacro_perbit_fgcg_ctrl4;
u32 emc_pmacro_perbit_fgcg_ctrl5;
u32 emc_pmacro_perbit_rfu_ctrl0;
u32 emc_pmacro_perbit_rfu_ctrl1;
u32 emc_pmacro_perbit_rfu_ctrl2;
u32 emc_pmacro_perbit_rfu_ctrl3;
u32 emc_pmacro_perbit_rfu_ctrl4;
u32 emc_pmacro_perbit_rfu_ctrl5;
u32 emc_pmacro_perbit_rfu1_ctrl0;
u32 emc_pmacro_perbit_rfu1_ctrl1;
u32 emc_pmacro_perbit_rfu1_ctrl2;
u32 emc_pmacro_perbit_rfu1_ctrl3;
u32 emc_pmacro_perbit_rfu1_ctrl4;
u32 emc_pmacro_perbit_rfu1_ctrl5;
u32 emc_pmacro_data_pi_ctrl;
u32 emc_pmacro_cmd_pi_ctrl;
u32 emc_pmacro_ddll_bypass;
u32 emc_pmacro_ddll_pwrd0;
u32 emc_pmacro_ddll_pwrd1;
u32 emc_pmacro_ddll_pwrd2;
u32 emc_pmacro_cmd_ctrl0;
u32 emc_pmacro_cmd_ctrl1;
u32 emc_pmacro_cmd_ctrl2;
/* DRAM size information */
/* Specifies the value for MC_EMEM_ADR_CFG */
u32 mc_emem_adr_cfg;
/* Specifies the value for MC_EMEM_ADR_CFG_DEV0 */
u32 mc_emem_adr_cfg_dev0;
/* Specifies the value for MC_EMEM_ADR_CFG_DEV1 */
u32 mc_emem_adr_cfg_dev1;
u32 mc_emem_adr_cfg_channel_mask;
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG0 */
u32 mc_emem_adr_cfg_bank_mask0;
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG1 */
u32 mc_emem_adr_cfg_bank_mask1;
/* Specifies the value for MC_EMEM_BANK_SWIZZLE_CFG2 */
u32 mc_emem_adr_cfg_bank_mask2;
/*
* Specifies the value for MC_EMEM_CFG which holds the external memory
* size (in KBytes)
*/
u32 mc_emem_cfg;
/* MC arbitration configuration */
/* Specifies the value for MC_EMEM_ARB_CFG */
u32 mc_emem_arb_cfg;
/* Specifies the value for MC_EMEM_ARB_OUTSTANDING_REQ */
u32 mc_emem_arb_outstanding_req;
u32 emc_emem_arb_refpb_hp_ctrl;
u32 emc_emem_arb_refpb_bank_ctrl;
/* Specifies the value for MC_EMEM_ARB_TIMING_RCD */
u32 mc_emem_arb_timing_rcd;
/* Specifies the value for MC_EMEM_ARB_TIMING_RP */
u32 mc_emem_arb_timing_rp;
/* Specifies the value for MC_EMEM_ARB_TIMING_RC */
u32 mc_emem_arb_timing_rc;
/* Specifies the value for MC_EMEM_ARB_TIMING_RAS */
u32 mc_emem_arb_timing_ras;
/* Specifies the value for MC_EMEM_ARB_TIMING_FAW */
u32 mc_emem_arb_timing_faw;
/* Specifies the value for MC_EMEM_ARB_TIMING_RRD */
u32 mc_emem_arb_timing_rrd;
/* Specifies the value for MC_EMEM_ARB_TIMING_RAP2PRE */
u32 mc_emem_arb_timing_rap2pre;
/* Specifies the value for MC_EMEM_ARB_TIMING_WAP2PRE */
u32 mc_emem_arb_timing_wap2pre;
/* Specifies the value for MC_EMEM_ARB_TIMING_R2R */
u32 mc_emem_arb_timing_r2r;
/* Specifies the value for MC_EMEM_ARB_TIMING_W2W */
u32 mc_emem_arb_timing_w2w;
/* Specifies the value for MC_EMEM_ARB_TIMING_R2W */
u32 mc_emem_arb_timing_r2w;
/* Specifies the value for MC_EMEM_ARB_TIMING_W2R */
u32 mc_emem_arb_timing_w2r;
u32 mc_emem_arb_timing_rfcpb;
/* Specifies the value for MC_EMEM_ARB_DA_TURNS */
u32 mc_emem_arb_da_turns;
/* Specifies the value for MC_EMEM_ARB_DA_COVERS */
u32 mc_emem_arb_da_covers;
/* Specifies the value for MC_EMEM_ARB_MISC0 */
u32 mc_emem_arb_misc0;
/* Specifies the value for MC_EMEM_ARB_MISC1 */
u32 mc_emem_arb_misc1;
u32 mc_emem_arb_misc2;
/* Specifies the value for MC_EMEM_ARB_RING1_THROTTLE */
u32 mc_emem_arb_ring1_throttle;
/* Specifies the value for MC_EMEM_ARB_OVERRIDE */
u32 mc_emem_arb_override;
/* Specifies the value for MC_EMEM_ARB_OVERRIDE_1 */
u32 mc_emem_arb_override1;
/* Specifies the value for MC_EMEM_ARB_RSV */
u32 mc_emem_arb_rsv;
u32 mc_da_cfg0;
u32 mc_emem_arb_timing_ccdmw;
/* Specifies the value for MC_CLKEN_OVERRIDE */
u32 mc_clken_override;
/* Specifies the value for MC_STAT_CONTROL */
u32 mc_stat_control;
/* Specifies the value for MC_VIDEO_PROTECT_BOM */
u32 mc_video_protect_bom;
/* Specifies the value for MC_VIDEO_PROTECT_BOM_ADR_HI */
u32 mc_video_protect_bom_adr_hi;
/* Specifies the value for MC_VIDEO_PROTECT_SIZE_MB */
u32 mc_video_protect_size_mb;
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE */
u32 mc_video_protect_vpr_override;
/* Specifies the value for MC_VIDEO_PROTECT_VPR_OVERRIDE1 */
u32 mc_video_protect_vpr_override1;
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_0 */
u32 mc_video_protect_gpu_override0;
/* Specifies the value for MC_VIDEO_PROTECT_GPU_OVERRIDE_1 */
u32 mc_video_protect_gpu_override1;
/* Specifies the value for MC_SEC_CARVEOUT_BOM */
u32 mc_sec_carveout_bom;
/* Specifies the value for MC_SEC_CARVEOUT_ADR_HI */
u32 mc_sec_carveout_adr_hi;
/* Specifies the value for MC_SEC_CARVEOUT_SIZE_MB */
u32 mc_sec_carveout_size_mb;
/* Specifies the value for MC_VIDEO_PROTECT_REG_CTRL.VIDEO_PROTECT_WRITE_ACCESS */
u32 mc_video_protect_write_access;
/* Specifies the value for MC_SEC_CARVEOUT_REG_CTRL.SEC_CARVEOUT_WRITE_ACCESS */
u32 mc_sec_carveout_protect_write_access;
u32 mc_generalized_carveout1_bom;
u32 mc_generalized_carveout1_bom_hi;
u32 mc_generalized_carveout1_size_128kb;
u32 mc_generalized_carveout1_access0;
u32 mc_generalized_carveout1_access1;
u32 mc_generalized_carveout1_access2;
u32 mc_generalized_carveout1_access3;
u32 mc_generalized_carveout1_access4;
u32 mc_generalized_carveout1_force_internal_access0;
u32 mc_generalized_carveout1_force_internal_access1;
u32 mc_generalized_carveout1_force_internal_access2;
u32 mc_generalized_carveout1_force_internal_access3;
u32 mc_generalized_carveout1_force_internal_access4;
u32 mc_generalized_carveout1_cfg0;
u32 mc_generalized_carveout2_bom;
u32 mc_generalized_carveout2_bom_hi;
u32 mc_generalized_carveout2_size_128kb;
u32 mc_generalized_carveout2_access0;
u32 mc_generalized_carveout2_access1;
u32 mc_generalized_carveout2_access2;
u32 mc_generalized_carveout2_access3;
u32 mc_generalized_carveout2_access4;
u32 mc_generalized_carveout2_force_internal_access0;
u32 mc_generalized_carveout2_force_internal_access1;
u32 mc_generalized_carveout2_force_internal_access2;
u32 mc_generalized_carveout2_force_internal_access3;
u32 mc_generalized_carveout2_force_internal_access4;
u32 mc_generalized_carveout2_cfg0;
u32 mc_generalized_carveout3_bom;
u32 mc_generalized_carveout3_bom_hi;
u32 mc_generalized_carveout3_size_128kb;
u32 mc_generalized_carveout3_access0;
u32 mc_generalized_carveout3_access1;
u32 mc_generalized_carveout3_access2;
u32 mc_generalized_carveout3_access3;
u32 mc_generalized_carveout3_access4;
u32 mc_generalized_carveout3_force_internal_access0;
u32 mc_generalized_carveout3_force_internal_access1;
u32 mc_generalized_carveout3_force_internal_access2;
u32 mc_generalized_carveout3_force_internal_access3;
u32 mc_generalized_carveout3_force_internal_access4;
u32 mc_generalized_carveout3_cfg0;
u32 mc_generalized_carveout4_bom;
u32 mc_generalized_carveout4_bom_hi;
u32 mc_generalized_carveout4_size_128kb;
u32 mc_generalized_carveout4_access0;
u32 mc_generalized_carveout4_access1;
u32 mc_generalized_carveout4_access2;
u32 mc_generalized_carveout4_access3;
u32 mc_generalized_carveout4_access4;
u32 mc_generalized_carveout4_force_internal_access0;
u32 mc_generalized_carveout4_force_internal_access1;
u32 mc_generalized_carveout4_force_internal_access2;
u32 mc_generalized_carveout4_force_internal_access3;
u32 mc_generalized_carveout4_force_internal_access4;
u32 mc_generalized_carveout4_cfg0;
u32 mc_generalized_carveout5_bom;
u32 mc_generalized_carveout5_bom_hi;
u32 mc_generalized_carveout5_size_128kb;
u32 mc_generalized_carveout5_access0;
u32 mc_generalized_carveout5_access1;
u32 mc_generalized_carveout5_access2;
u32 mc_generalized_carveout5_access3;
u32 mc_generalized_carveout5_access4;
u32 mc_generalized_carveout5_force_internal_access0;
u32 mc_generalized_carveout5_force_internal_access1;
u32 mc_generalized_carveout5_force_internal_access2;
u32 mc_generalized_carveout5_force_internal_access3;
u32 mc_generalized_carveout5_force_internal_access4;
u32 mc_generalized_carveout5_cfg0;
/* Specifies enable for CA training */
u32 emc_ca_training_enable;
/* Set if bit 6 select is greater than bit 7 select; uses aremc.spec packet SWIZZLE_BIT6_GT_BIT7 */
u32 swizzle_rank_byte_encode;
/* Specifies enable and offset for patched boot rom write */
u32 boot_rom_patch_control;
/* Specifies data for patched boot rom write */
u32 boot_rom_patch_data;
/* Specifies the value for MC_MTS_CARVEOUT_BOM */
u32 mc_mts_carveout_bom;
/* Specifies the value for MC_MTS_CARVEOUT_ADR_HI */
u32 mc_mts_carveout_adr_hi;
/* Specifies the value for MC_MTS_CARVEOUT_SIZE_MB */
u32 mc_mts_carveout_size_mb;
/* Specifies the value for MC_MTS_CARVEOUT_REG_CTRL */
u32 mc_mts_carveout_reg_ctrl;
/* Specifies the clients that are allowed to access untranslated memory */
u32 mc_untranslated_region_check;
/* Just a place holder for special usage when there is no BCT for certain registers */
u32 bct_na;
} sdram_params_t210b01_t;
#endif

View File

@ -20,9 +20,16 @@
//#define IPL_STACK_TOP 0x4003FF00 //#define IPL_STACK_TOP 0x4003FF00
/* --- BIT/BCT: 0x40000000 - 0x40003000 --- */ /* --- BIT/BCT: 0x40000000 - 0x40003000 --- */
/* --- IPL: 0x40003000 - 0x40028000 --- */ /* --- IPL: 0x40003000 - 0x40028000 --- */
#define LDR_LOAD_ADDR 0x40007000
#define IPL_LOAD_ADDR 0x40003000 #define IPL_LOAD_ADDR 0x40003000
#define IPL_SZ_MAX 0x20000 // 128KB. #define IPL_SZ_MAX 0x20000 // 128KB.
//#define IRAM_LIB_ADDR 0x4002B000
/* --- XUSB EP context and TRB ring buffers --- */
#define XUSB_RING_ADDR 0x40020000
#define SECMON_MIN_START 0x4002B000
#define SDRAM_PARAMS_ADDR 0x40030000 // SDRAM extraction buffer during sdram init. #define SDRAM_PARAMS_ADDR 0x40030000 // SDRAM extraction buffer during sdram init.
#define CBFS_DRAM_EN_ADDR 0x4003e000 // u32. #define CBFS_DRAM_EN_ADDR 0x4003e000 // u32.
@ -45,6 +52,10 @@
#define NX_BIS_CACHE_ADDR RAM_DISK_ADDR #define NX_BIS_CACHE_ADDR RAM_DISK_ADDR
#define RAM_DISK_SZ 0x41000000 // 1040MB. #define RAM_DISK_SZ 0x41000000 // 1040MB.
// L4T Kernel Panic Storage (PSTORE).
#define PSTORE_ADDR 0xB0000000
#define PSTORE_SZ 0x200000 // 2MB.
//#define DRAM_LIB_ADDR 0xE0000000 //#define DRAM_LIB_ADDR 0xE0000000
/* --- Chnldr: 252MB 0xC03C0000 - 0xCFFFFFFF --- */ //! Only used when chainloading. /* --- Chnldr: 252MB 0xC03C0000 - 0xCFFFFFFF --- */ //! Only used when chainloading.

99
bdk/power/bm92t36.c Normal file
View File

@ -0,0 +1,99 @@
/*
* USB-PD driver for Nintendo Switch's TI BM92T36
*
* Copyright (c) 2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "bm92t36.h"
#include <soc/i2c.h>
#include <utils/util.h>
#define ALERT_STATUS_REG 0x2
#define STATUS1_REG 0x3
#define STATUS2_REG 0x4
#define COMMAND_REG 0x5
#define CONFIG1_REG 0x6
#define DEV_CAPS_REG 0x7
#define READ_PDOS_SRC_REG 0x8
#define CONFIG2_REG 0x17
#define DP_STATUS_REG 0x18
#define DP_ALERT_EN_REG 0x19
#define VENDOR_CONFIG_REG 0x1A
#define AUTO_NGT_FIXED_REG 0x20
#define AUTO_NGT_BATT_REG 0x23
#define SYS_CONFIG1_REG 0x26
#define SYS_CONFIG2_REG 0x27
#define CURRENT_PDO_REG 0x28
#define CURRENT_RDO_REG 0x2B
#define ALERT_ENABLE_REG 0x2E
#define SYS_CONFIG3_REG 0x2F
#define SET_RDO_REG 0x30
#define PDOS_SNK_REG 0x33
#define PDOS_SRC_PROV_REG 0x3C
#define FW_TYPE_REG 0x4B
#define FW_REVISION_REG 0x4C
#define MAN_ID_REG 0x4D
#define DEV_ID_REG 0x4E
#define REV_ID_REG 0x4F
#define INCOMING_VDM_REG 0x50
#define OUTGOING_VDM_REG 0x60
#define STATUS1_INSERT BIT(7) // Cable inserted.
typedef struct _pd_object_t {
unsigned int amp:10;
unsigned int volt:10;
unsigned int info:10;
unsigned int type:2;
} __attribute__((packed)) pd_object_t;
static int _bm92t36_read_reg(u8 *buf, u32 size, u32 reg)
{
return i2c_recv_buf_big(buf, size, I2C_1, BM92T36_I2C_ADDR, reg);
}
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd)
{
u8 buf[32];
pd_object_t pdos[7];
if (inserted)
{
_bm92t36_read_reg(buf, 2, STATUS1_REG);
*inserted = buf[0] & STATUS1_INSERT ? true : false;
}
if (usb_pd)
{
_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);
for (u32 i = 0; i < usb_pd->pdo_no; i++)
{
usb_pd->pdos[i].amperage = pdos[i].amp * 10;
usb_pd->pdos[i].voltage = (pdos[i].volt * 50) / 1000;
}
_bm92t36_read_reg(buf, 5, CURRENT_PDO_REG);
memcpy(pdos, &buf[1], 4);
usb_pd->selected_pdo.amperage = pdos[0].amp * 10;
usb_pd->selected_pdo.voltage = (pdos[0].volt * 50) / 1000;
}
}

41
bdk/power/bm92t36.h Normal file
View File

@ -0,0 +1,41 @@
/*
* USB-PD driver for Nintendo Switch's TI BM92T36
*
* Copyright (c) 2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BM92T36_H_
#define __BM92T36_H_
#include <utils/types.h>
#define BM92T36_I2C_ADDR 0x18
typedef struct _usb_pd_object_t
{
u32 amperage;
u32 voltage;
} usb_pd_object_t;
typedef struct _usb_pd_objects_t
{
u32 pdo_no;
usb_pd_object_t pdos[7];
usb_pd_object_t selected_pdo;
} usb_pd_objects_t;
void bm92t36_get_sink_info(bool *inserted, usb_pd_objects_t *usb_pd);
#endif

View File

@ -26,17 +26,19 @@
#include <soc/i2c.h> #include <soc/i2c.h>
#include <utils/util.h> #include <utils/util.h>
#define BASE_SNS_UOHM 5000
/* Status register bits */ /* Status register bits */
#define STATUS_POR_BIT (1 << 1) #define STATUS_POR_BIT BIT(1)
#define STATUS_BST_BIT (1 << 3) #define STATUS_BST_BIT BIT(3)
#define STATUS_VMN_BIT (1 << 8) #define STATUS_VMN_BIT BIT(8)
#define STATUS_TMN_BIT (1 << 9) #define STATUS_TMN_BIT BIT(9)
#define STATUS_SMN_BIT (1 << 10) #define STATUS_SMN_BIT BIT(10)
#define STATUS_BI_BIT (1 << 11) #define STATUS_BI_BIT BIT(11)
#define STATUS_VMX_BIT (1 << 12) #define STATUS_VMX_BIT BIT(12)
#define STATUS_TMX_BIT (1 << 13) #define STATUS_TMX_BIT BIT(13)
#define STATUS_SMX_BIT (1 << 14) #define STATUS_SMX_BIT BIT(14)
#define STATUS_BR_BIT (1 << 15) #define STATUS_BR_BIT BIT(15)
#define VFSOC0_LOCK 0x0000 #define VFSOC0_LOCK 0x0000
#define VFSOC0_UNLOCK 0x0080 #define VFSOC0_UNLOCK 0x0080
@ -85,31 +87,31 @@ int max17050_get_property(enum MAX17050_reg reg, int *value)
break; break;
case MAX17050_VCELL: // Voltage now. case MAX17050_VCELL: // Voltage now.
data = max17050_get_reg(MAX17050_VCELL); data = max17050_get_reg(MAX17050_VCELL);
*value = data * 625 / 8 / 1000; *value = (data >> 3) * 625 / 1000; /* Units of LSB = 0.625mV */
battery_voltage = *value; battery_voltage = *value;
break; break;
case MAX17050_AvgVCELL: // Voltage avg. case MAX17050_AvgVCELL: // Voltage avg.
data = max17050_get_reg(MAX17050_AvgVCELL); data = max17050_get_reg(MAX17050_AvgVCELL);
*value = data * 625 / 8 / 1000; *value = (data >> 3) * 625 / 1000; /* Units of LSB = 0.625mV */
break; break;
case MAX17050_OCVInternal: // Voltage ocv. case MAX17050_OCVInternal: // Voltage ocv.
data = max17050_get_reg(MAX17050_OCVInternal); data = max17050_get_reg(MAX17050_OCVInternal);
*value = data * 625 / 8 / 1000; *value = (data >> 3) * 625 / 1000; /* Units of LSB = 0.625mV */
break; break;
case MAX17050_RepSOC: // Capacity %. case MAX17050_RepSOC: // Capacity %.
*value = max17050_get_reg(MAX17050_RepSOC); *value = max17050_get_reg(MAX17050_RepSOC);
break; break;
case MAX17050_DesignCap: // Charge full design. case MAX17050_DesignCap: // Charge full design.
data = max17050_get_reg(MAX17050_DesignCap); data = max17050_get_reg(MAX17050_DesignCap);
*value = data * 5 / 10; *value = data * (BASE_SNS_UOHM / MAX17050_BOARD_SNS_RESISTOR_UOHM) / MAX17050_BOARD_CGAIN;
break; break;
case MAX17050_FullCAP: // Charge full. case MAX17050_FullCAP: // Charge full.
data = max17050_get_reg(MAX17050_FullCAP); data = max17050_get_reg(MAX17050_FullCAP);
*value = data * 5 / 10; *value = data * (BASE_SNS_UOHM / MAX17050_BOARD_SNS_RESISTOR_UOHM) / MAX17050_BOARD_CGAIN;
break; break;
case MAX17050_RepCap: // Charge now. case MAX17050_RepCap: // Charge now.
data = max17050_get_reg(MAX17050_RepCap); data = max17050_get_reg(MAX17050_RepCap);
*value = data * 5 / 10; *value = data * (BASE_SNS_UOHM / MAX17050_BOARD_SNS_RESISTOR_UOHM) / MAX17050_BOARD_CGAIN;
break; break;
case MAX17050_TEMP: // Temp. case MAX17050_TEMP: // Temp.
data = max17050_get_reg(MAX17050_TEMP); data = max17050_get_reg(MAX17050_TEMP);
@ -119,12 +121,12 @@ int max17050_get_property(enum MAX17050_reg reg, int *value)
case MAX17050_Current: // Current now. case MAX17050_Current: // Current now.
data = max17050_get_reg(MAX17050_Current); data = max17050_get_reg(MAX17050_Current);
*value = (s16)data; *value = (s16)data;
*value *= 1562500 / MAX17050_DEFAULT_SNS_RESISTOR; *value *= 1562500 / (MAX17050_BOARD_SNS_RESISTOR_UOHM * MAX17050_BOARD_CGAIN);
break; break;
case MAX17050_AvgCurrent: // Current avg. case MAX17050_AvgCurrent: // Current avg.
data = max17050_get_reg(MAX17050_AvgCurrent); data = max17050_get_reg(MAX17050_AvgCurrent);
*value = (s16)data; *value = (s16)data;
*value *= 1562500 / MAX17050_DEFAULT_SNS_RESISTOR; *value *= 1562500 / (MAX17050_BOARD_SNS_RESISTOR_UOHM * MAX17050_BOARD_CGAIN);
break; break;
default: default:
return -1; return -1;

View File

@ -1,6 +1,5 @@
/* /*
* Fuel gauge driver for Nintendo Switch's Maxim 17050 * Fuel gauge driver for Nintendo Switch's Maxim 17050
* Note that Maxim 8966 and 8997 are mfd and this is its subdevice.
* *
* Copyright (c) 2011 Samsung Electronics * Copyright (c) 2011 Samsung Electronics
* MyungJoo Ham <myungjoo.ham@samsung.com> * MyungJoo Ham <myungjoo.ham@samsung.com>
@ -26,8 +25,11 @@
#include <utils/types.h> #include <utils/types.h>
#define MAX17050_STATUS_BattAbsent (1 << 3) /* Board default values */
#define MAX17050_DEFAULT_SNS_RESISTOR 10000 #define MAX17050_BOARD_CGAIN 2 /* Actual: 1.99993 */
#define MAX17050_BOARD_SNS_RESISTOR_UOHM 5000 /* 0.005 Ohm */
#define MAX17050_STATUS_BattAbsent BIT(3)
/* Consider RepCap which is less then 10 units below FullCAP full */ /* Consider RepCap which is less then 10 units below FullCAP full */
#define MAX17050_FULL_THRESHOLD 10 #define MAX17050_FULL_THRESHOLD 10

View File

@ -16,13 +16,7 @@
/* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */ /* GLOBAL, PMIC, GPIO, FPS, ONOFFC, CID Registers */
#define MAX77620_REG_CNFGGLBL1 0x00 #define MAX77620_REG_CNFGGLBL1 0x00
#define MAX77620_CNFGGLBL1_LBDAC_EN (1 << 7) #define MAX77620_CNFGGLBL1_LBRSTEN BIT(0)
#define MAX77620_CNFGGLBL1_MPPLD (1 << 6)
#define MAX77620_CNFGGLBL1_LBHYST ((1 << 5) | (1 << 4))
#define MAX77620_CNFGGLBL1_LBHYST_100 (0 << 4)
#define MAX77620_CNFGGLBL1_LBHYST_200 (1 << 4)
#define MAX77620_CNFGGLBL1_LBHYST_300 (2 << 4)
#define MAX77620_CNFGGLBL1_LBHYST_400 (3 << 4)
#define MAX77620_CNFGGLBL1_LBDAC_MASK 0x0E #define MAX77620_CNFGGLBL1_LBDAC_MASK 0x0E
#define MAX77620_CNFGGLBL1_LBDAC_2700 (0 << 1) #define MAX77620_CNFGGLBL1_LBDAC_2700 (0 << 1)
#define MAX77620_CNFGGLBL1_LBDAC_2800 (1 << 1) #define MAX77620_CNFGGLBL1_LBDAC_2800 (1 << 1)
@ -32,14 +26,20 @@
#define MAX77620_CNFGGLBL1_LBDAC_3200 (5 << 1) #define MAX77620_CNFGGLBL1_LBDAC_3200 (5 << 1)
#define MAX77620_CNFGGLBL1_LBDAC_3300 (6 << 1) #define MAX77620_CNFGGLBL1_LBDAC_3300 (6 << 1)
#define MAX77620_CNFGGLBL1_LBDAC_3400 (7 << 1) #define MAX77620_CNFGGLBL1_LBDAC_3400 (7 << 1)
#define MAX77620_CNFGGLBL1_LBRSTEN (1 << 0) #define MAX77620_CNFGGLBL1_LBHYST_100 (0 << 4)
#define MAX77620_CNFGGLBL1_LBHYST_200 (1 << 4)
#define MAX77620_CNFGGLBL1_LBHYST_300 (2 << 4)
#define MAX77620_CNFGGLBL1_LBHYST_400 (3 << 4)
#define MAX77620_CNFGGLBL1_LBHYST (BIT(5) | BIT(4))
#define MAX77620_CNFGGLBL1_MPPLD BIT(6)
#define MAX77620_CNFGGLBL1_LBDAC_EN BIT(7)
#define MAX77620_REG_CNFGGLBL2 0x01 #define MAX77620_REG_CNFGGLBL2 0x01
#define MAX77620_REG_CNFGGLBL3 0x02 #define MAX77620_REG_CNFGGLBL3 0x02
#define MAX77620_WDTC_MASK 0x3 #define MAX77620_WDTC_MASK 0x3
#define MAX77620_WDTOFFC (1 << 4) #define MAX77620_WDTEN BIT(2)
#define MAX77620_WDTSLPC (1 << 3) #define MAX77620_WDTSLPC BIT(3)
#define MAX77620_WDTEN (1 << 2) #define MAX77620_WDTOFFC BIT(4)
#define MAX77620_TWD_MASK 0x3 #define MAX77620_TWD_MASK 0x3
#define MAX77620_TWD_2s 0x0 #define MAX77620_TWD_2s 0x0
#define MAX77620_TWD_16s 0x1 #define MAX77620_TWD_16s 0x1
@ -47,15 +47,15 @@
#define MAX77620_TWD_128s 0x3 #define MAX77620_TWD_128s 0x3
#define MAX77620_REG_CNFG1_32K 0x03 #define MAX77620_REG_CNFG1_32K 0x03
#define MAX77620_CNFG1_32K_OUT0_EN (1 << 2) #define MAX77620_CNFG1_32K_OUT0_EN BIT(2)
#define MAX77620_REG_CNFGBBC 0x04 #define MAX77620_REG_CNFGBBC 0x04
#define MAX77620_CNFGBBC_ENABLE (1 << 0) #define MAX77620_CNFGBBC_ENABLE BIT(0)
#define MAX77620_CNFGBBC_CURRENT_MASK 0x06 #define MAX77620_CNFGBBC_CURRENT_MASK 0x06
#define MAX77620_CNFGBBC_CURRENT_SHIFT 1 #define MAX77620_CNFGBBC_CURRENT_SHIFT 1
#define MAX77620_CNFGBBC_VOLTAGE_MASK 0x18 #define MAX77620_CNFGBBC_VOLTAGE_MASK 0x18
#define MAX77620_CNFGBBC_VOLTAGE_SHIFT 3 #define MAX77620_CNFGBBC_VOLTAGE_SHIFT 3
#define MAX77620_CNFGBBC_LOW_CURRENT_DISABLE (1 << 5) #define MAX77620_CNFGBBC_LOW_CURRENT_DISABLE BIT(5)
#define MAX77620_CNFGBBC_RESISTOR_MASK 0xC0 #define MAX77620_CNFGBBC_RESISTOR_MASK 0xC0
#define MAX77620_CNFGBBC_RESISTOR_SHIFT 6 #define MAX77620_CNFGBBC_RESISTOR_SHIFT 6
#define MAX77620_CNFGBBC_RESISTOR_100 (0 << MAX77620_CNFGBBC_RESISTOR_SHIFT) #define MAX77620_CNFGBBC_RESISTOR_100 (0 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
@ -64,19 +64,19 @@
#define MAX77620_CNFGBBC_RESISTOR_6K (3 << MAX77620_CNFGBBC_RESISTOR_SHIFT) #define MAX77620_CNFGBBC_RESISTOR_6K (3 << MAX77620_CNFGBBC_RESISTOR_SHIFT)
#define MAX77620_REG_IRQTOP 0x05 #define MAX77620_REG_IRQTOP 0x05
#define MAX77620_IRQ_TOP_GLBL_MASK (1 << 7) #define MAX77620_IRQ_TOP_ONOFF_MASK BIT(1)
#define MAX77620_IRQ_TOP_SD_MASK (1 << 6) #define MAX77620_IRQ_TOP_32K_MASK BIT(2)
#define MAX77620_IRQ_TOP_LDO_MASK (1 << 5) #define MAX77620_IRQ_TOP_RTC_MASK BIT(3)
#define MAX77620_IRQ_TOP_GPIO_MASK (1 << 4) #define MAX77620_IRQ_TOP_GPIO_MASK BIT(4)
#define MAX77620_IRQ_TOP_RTC_MASK (1 << 3) #define MAX77620_IRQ_TOP_LDO_MASK BIT(5)
#define MAX77620_IRQ_TOP_32K_MASK (1 << 2) #define MAX77620_IRQ_TOP_SD_MASK BIT(6)
#define MAX77620_IRQ_TOP_ONOFF_MASK (1 << 1) #define MAX77620_IRQ_TOP_GLBL_MASK BIT(7)
#define MAX77620_REG_INTLBT 0x06 #define MAX77620_REG_INTLBT 0x06
#define MAX77620_REG_IRQTOPM 0x0D #define MAX77620_REG_IRQTOPM 0x0D
#define MAX77620_IRQ_LBM_MASK (1 << 3) #define MAX77620_IRQ_TJALRM2_MASK BIT(1)
#define MAX77620_IRQ_TJALRM1_MASK (1 << 2) #define MAX77620_IRQ_TJALRM1_MASK BIT(2)
#define MAX77620_IRQ_TJALRM2_MASK (1 << 1) #define MAX77620_IRQ_LBM_MASK BIT(3)
#define MAX77620_REG_IRQSD 0x07 #define MAX77620_REG_IRQSD 0x07
#define MAX77620_REG_IRQ_LVL2_L0_7 0x08 #define MAX77620_REG_IRQ_LVL2_L0_7 0x08
@ -86,7 +86,7 @@
#define MAX77620_REG_NVERC 0x0C #define MAX77620_REG_NVERC 0x0C
#define MAX77620_REG_INTENLBT 0x0E #define MAX77620_REG_INTENLBT 0x0E
#define MAX77620_GLBLM_MASK (1 << 0) #define MAX77620_GLBLM_MASK BIT(0)
#define MAX77620_REG_IRQMASKSD 0x0F #define MAX77620_REG_IRQMASKSD 0x0F
#define MAX77620_REG_IRQ_MSK_L0_7 0x10 #define MAX77620_REG_IRQ_MSK_L0_7 0x10
@ -108,11 +108,11 @@
#define MAX77620_LDO_VOLT_MASK 0x3F #define MAX77620_LDO_VOLT_MASK 0x3F
#define MAX77620_REG_DVSSD0 0x1B #define MAX77620_REG_DVSSD0 0x1B
#define MAX77620_REG_DVSSD1 0x1C #define MAX77620_REG_DVSSD1 0x1C
#define MAX77620_REG_SD0_CFG 0x1D #define MAX77620_REG_SD0_CFG 0x1D // SD CNFG1.
#define MAX77620_REG_SD1_CFG 0x1E #define MAX77620_REG_SD1_CFG 0x1E // SD CNFG1.
#define MAX77620_REG_SD2_CFG 0x1F #define MAX77620_REG_SD2_CFG 0x1F // SD CNFG1.
#define MAX77620_REG_SD3_CFG 0x20 #define MAX77620_REG_SD3_CFG 0x20 // SD CNFG1.
#define MAX77620_REG_SD4_CFG 0x21 #define MAX77620_REG_SD4_CFG 0x21 // SD CNFG1.
#define MAX77620_REG_SD_CFG2 0x22 #define MAX77620_REG_SD_CFG2 0x22
#define MAX77620_REG_LDO0_CFG 0x23 #define MAX77620_REG_LDO0_CFG 0x23
#define MAX77620_REG_LDO0_CFG2 0x24 #define MAX77620_REG_LDO0_CFG2 0x24
@ -132,23 +132,23 @@
#define MAX77620_REG_LDO7_CFG2 0x32 #define MAX77620_REG_LDO7_CFG2 0x32
#define MAX77620_REG_LDO8_CFG 0x33 #define MAX77620_REG_LDO8_CFG 0x33
#define MAX77620_REG_LDO8_CFG2 0x34 #define MAX77620_REG_LDO8_CFG2 0x34
#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
#define MAX77620_LDO_CFG2_SS_FAST (1 << 0)
#define MAX77620_LDO_CFG2_SS_SLOW 0
#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
#define MAX77620_LDO_CFG2_ADE_DISABLE (0 << 1)
#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
#define MAX20024_LDO_CFG2_MPOK_MASK BIT(2)
#define MAX77620_LDO_POWER_MODE_MASK 0xC0 #define MAX77620_LDO_POWER_MODE_MASK 0xC0
#define MAX77620_LDO_POWER_MODE_SHIFT 6 #define MAX77620_LDO_POWER_MODE_SHIFT 6
#define MAX77620_POWER_MODE_NORMAL 3 #define MAX77620_POWER_MODE_NORMAL 3
#define MAX77620_POWER_MODE_LPM 2 #define MAX77620_POWER_MODE_LPM 2
#define MAX77620_POWER_MODE_GLPM 1 #define MAX77620_POWER_MODE_GLPM 1
#define MAX77620_POWER_MODE_DISABLE 0 #define MAX77620_POWER_MODE_DISABLE 0
#define MAX20024_LDO_CFG2_MPOK_MASK (1 << 2)
#define MAX77620_LDO_CFG2_ADE_MASK (1 << 1)
#define MAX77620_LDO_CFG2_ADE_DISABLE (0 << 1)
#define MAX77620_LDO_CFG2_ADE_ENABLE (1 << 1)
#define MAX77620_LDO_CFG2_SS_MASK (1 << 0)
#define MAX77620_LDO_CFG2_SS_FAST (1 << 0)
#define MAX77620_LDO_CFG2_SS_SLOW 0
#define MAX77620_REG_LDO_CFG3 0x35 #define MAX77620_REG_LDO_CFG3 0x35
#define MAX77620_TRACK4_MASK (1 << 5)
#define MAX77620_TRACK4_SHIFT 5 #define MAX77620_TRACK4_SHIFT 5
#define MAX77620_TRACK4_MASK (1 << MAX77620_TRACK4_SHIFT)
#define MAX77620_LDO_SLEW_RATE_MASK 0x1 #define MAX77620_LDO_SLEW_RATE_MASK 0x1
@ -183,19 +183,19 @@
#define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6) #define MAX77620_CNFG_GPIO_DBNC_32ms (0x3 << 6)
#define MAX77620_REG_ONOFFCNFG1 0x41 #define MAX77620_REG_ONOFFCNFG1 0x41
#define MAX77620_ONOFFCNFG1_SFT_RST (1 << 7)
#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
#define MAX77620_ONOFFCNFG1_SLPEN (1 << 2)
#define MAX77620_ONOFFCNFG1_PWR_OFF (1 << 1)
#define MAX20024_ONOFFCNFG1_CLRSE 0x18 #define MAX20024_ONOFFCNFG1_CLRSE 0x18
#define MAX77620_ONOFFCNFG1_PWR_OFF BIT(1)
#define MAX77620_ONOFFCNFG1_SLPEN BIT(2)
#define MAX77620_ONOFFCNFG1_MRT_SHIFT 0x3
#define MAX77620_ONOFFCNFG1_MRT_MASK 0x38
#define MAX77620_ONOFFCNFG1_SFT_RST BIT(7)
#define MAX77620_REG_ONOFFCNFG2 0x42 #define MAX77620_REG_ONOFFCNFG2 0x42
#define MAX77620_ONOFFCNFG2_SFT_RST_WK (1 << 7) #define MAX77620_ONOFFCNFG2_WK_EN0 BIT(0)
#define MAX77620_ONOFFCNFG2_WD_RST_WK (1 << 6) #define MAX77620_ONOFFCNFG2_WK_ALARM1 BIT(2)
#define MAX77620_ONOFFCNFG2_SLP_LPM_MSK (1 << 5) #define MAX77620_ONOFFCNFG2_SLP_LPM_MSK BIT(5)
#define MAX77620_ONOFFCNFG2_WK_ALARM1 (1 << 2) #define MAX77620_ONOFFCNFG2_WD_RST_WK BIT(6)
#define MAX77620_ONOFFCNFG2_WK_EN0 (1 << 0) #define MAX77620_ONOFFCNFG2_SFT_RST_WK BIT(7)
/* FPS Registers */ /* FPS Registers */
#define MAX77620_REG_FPS_CFG0 0x43 #define MAX77620_REG_FPS_CFG0 0x43
@ -259,8 +259,8 @@
#define MAX77620_CID_DIDM_SHIFT 4 #define MAX77620_CID_DIDM_SHIFT 4
/* CNCG2SD */ /* CNCG2SD */
#define MAX77620_SD_CNF2_ROVS_EN_SD1 (1 << 1) #define MAX77620_SD_CNF2_ROVS_EN_SD1 BIT(1)
#define MAX77620_SD_CNF2_ROVS_EN_SD0 (1 << 2) #define MAX77620_SD_CNF2_ROVS_EN_SD0 BIT(2)
/* Device Identification Metal */ /* Device Identification Metal */
#define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF) #define MAX77620_CID5_DIDM(n) (((n) >> 4) & 0xF)
@ -272,29 +272,29 @@
#define MAX77620_SD_SR_SHIFT 6 #define MAX77620_SD_SR_SHIFT 6
#define MAX77620_SD_POWER_MODE_MASK 0x30 #define MAX77620_SD_POWER_MODE_MASK 0x30
#define MAX77620_SD_POWER_MODE_SHIFT 4 #define MAX77620_SD_POWER_MODE_SHIFT 4
#define MAX77620_SD_CFG1_ADE_MASK (1 << 3) #define MAX77620_SD_CFG1_ADE_MASK BIT(3)
#define MAX77620_SD_CFG1_ADE_DISABLE 0 #define MAX77620_SD_CFG1_ADE_DISABLE 0
#define MAX77620_SD_CFG1_ADE_ENABLE (1 << 3) #define MAX77620_SD_CFG1_ADE_ENABLE BIT(3)
#define MAX77620_SD_FPWM_MASK 0x04 #define MAX77620_SD_FPWM_MASK 0x04
#define MAX77620_SD_FPWM_SHIFT 2 #define MAX77620_SD_FPWM_SHIFT 2
#define MAX77620_SD_FSRADE_MASK 0x01 #define MAX77620_SD_FSRADE_MASK 0x01
#define MAX77620_SD_FSRADE_SHIFT 0 #define MAX77620_SD_FSRADE_SHIFT 0
#define MAX77620_SD_CFG1_FPWM_SD_MASK (1 << 2) #define MAX77620_SD_CFG1_FPWM_SD_MASK BIT(2)
#define MAX77620_SD_CFG1_FPWM_SD_SKIP 0 #define MAX77620_SD_CFG1_FPWM_SD_SKIP 0
#define MAX77620_SD_CFG1_FPWM_SD_FPWM (1 << 2) #define MAX77620_SD_CFG1_FPWM_SD_FPWM BIT(2)
#define MAX20024_SD_CFG1_MPOK_MASK (1 << 1) #define MAX20024_SD_CFG1_MPOK_MASK BIT(1)
#define MAX77620_SD_CFG1_FSRADE_SD_MASK (1 << 0) #define MAX77620_SD_CFG1_FSRADE_SD_MASK BIT(0)
#define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0 #define MAX77620_SD_CFG1_FSRADE_SD_DISABLE 0
#define MAX77620_SD_CFG1_FSRADE_SD_ENABLE (1 << 0) #define MAX77620_SD_CFG1_FSRADE_SD_ENABLE BIT(0)
#define MAX77620_IRQ_LVL2_GPIO_EDGE0 (1 << 0) #define MAX77620_IRQ_LVL2_GPIO_EDGE0 BIT(0)
#define MAX77620_IRQ_LVL2_GPIO_EDGE1 (1 << 1) #define MAX77620_IRQ_LVL2_GPIO_EDGE1 BIT(1)
#define MAX77620_IRQ_LVL2_GPIO_EDGE2 (1 << 2) #define MAX77620_IRQ_LVL2_GPIO_EDGE2 BIT(2)
#define MAX77620_IRQ_LVL2_GPIO_EDGE3 (1 << 3) #define MAX77620_IRQ_LVL2_GPIO_EDGE3 BIT(3)
#define MAX77620_IRQ_LVL2_GPIO_EDGE4 (1 << 4) #define MAX77620_IRQ_LVL2_GPIO_EDGE4 BIT(4)
#define MAX77620_IRQ_LVL2_GPIO_EDGE5 (1 << 5) #define MAX77620_IRQ_LVL2_GPIO_EDGE5 BIT(5)
#define MAX77620_IRQ_LVL2_GPIO_EDGE6 (1 << 6) #define MAX77620_IRQ_LVL2_GPIO_EDGE6 BIT(6)
#define MAX77620_IRQ_LVL2_GPIO_EDGE7 (1 << 7) #define MAX77620_IRQ_LVL2_GPIO_EDGE7 BIT(7)
/* Interrupts */ /* Interrupts */
enum { enum {

View File

@ -61,17 +61,19 @@ static const max77620_regulator_t _pmic_regulators[] = {
{ REGULATOR_LDO, "ldo5", 0x00, 50000, 800000, 1800000, 1800000, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO5, 3, 7, 0 }, { REGULATOR_LDO, "ldo5", 0x00, 50000, 800000, 1800000, 1800000, MAX77620_REG_LDO5_CFG, MAX77620_REG_LDO5_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO5, 3, 7, 0 },
{ REGULATOR_LDO, "ldo6", 0x00, 50000, 800000, 2900000, 2900000, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO6, 3, 7, 0 }, { REGULATOR_LDO, "ldo6", 0x00, 50000, 800000, 2900000, 2900000, MAX77620_REG_LDO6_CFG, MAX77620_REG_LDO6_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO6, 3, 7, 0 },
{ REGULATOR_LDO, "ldo7", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO7, 1, 4, 3 }, { REGULATOR_LDO, "ldo7", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO7_CFG, MAX77620_REG_LDO7_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO7, 1, 4, 3 },
{ REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO8, 3, 7, 0 } { REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 2800000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO8, 3, 7, 0 }
}; };
static void _max77620_try_set_reg(u8 reg, u8 val) static void _max77620_set_reg(u8 reg, u8 val)
{ {
u8 tmp; u32 retries = 100;
do while (retries)
{ {
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg, val); if (i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg, val))
tmp = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg); break;
} while (val != tmp); usleep(100);
retries--;
}
} }
int max77620_regulator_get_status(u32 id) int max77620_regulator_get_status(u32 id)
@ -93,7 +95,7 @@ int max77620_regulator_config_fps(u32 id)
const max77620_regulator_t *reg = &_pmic_regulators[id]; const max77620_regulator_t *reg = &_pmic_regulators[id];
_max77620_try_set_reg(reg->fps_addr, _max77620_set_reg(reg->fps_addr,
(reg->fps_src << MAX77620_FPS_SRC_SHIFT) | (reg->pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) | (reg->pd_period)); (reg->fps_src << MAX77620_FPS_SRC_SHIFT) | (reg->pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) | (reg->pd_period));
return 1; return 1;
@ -112,7 +114,7 @@ int max77620_regulator_set_voltage(u32 id, u32 mv)
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step; u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr); u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr);
val = (val & ~reg->volt_mask) | (mult & reg->volt_mask); val = (val & ~reg->volt_mask) | (mult & reg->volt_mask);
_max77620_try_set_reg(reg->volt_addr, val); _max77620_set_reg(reg->volt_addr, val);
usleep(1000); usleep(1000);
return 1; return 1;
@ -131,7 +133,7 @@ int max77620_regulator_enable(u32 id, int enable)
val = (val & ~reg->enable_mask) | ((MAX77620_POWER_MODE_NORMAL << reg->enable_shift) & reg->enable_mask); val = (val & ~reg->enable_mask) | ((MAX77620_POWER_MODE_NORMAL << reg->enable_shift) & reg->enable_mask);
else else
val &= ~reg->enable_mask; val &= ~reg->enable_mask;
_max77620_try_set_reg(addr, val); _max77620_set_reg(addr, val);
usleep(1000); usleep(1000);
return 1; return 1;
@ -150,7 +152,7 @@ int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags)
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step; u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
u8 val = ((flags << reg->enable_shift) & ~reg->volt_mask) | (mult & reg->volt_mask); u8 val = ((flags << reg->enable_shift) & ~reg->volt_mask) | (mult & reg->volt_mask);
_max77620_try_set_reg(reg->volt_addr, val); _max77620_set_reg(reg->volt_addr, val);
usleep(1000); usleep(1000);
return 1; return 1;
@ -166,12 +168,12 @@ void max77620_config_default()
if (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE) if (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE)
max77620_regulator_enable(i, 1); max77620_regulator_enable(i, 1);
} }
_max77620_try_set_reg(MAX77620_REG_SD_CFG2, 4); _max77620_set_reg(MAX77620_REG_SD_CFG2, 4);
} }
void max77620_low_battery_monitor_config(bool enable) void max77620_low_battery_monitor_config(bool enable)
{ {
_max77620_try_set_reg(MAX77620_REG_CNFGGLBL1, _max77620_set_reg(MAX77620_REG_CNFGGLBL1,
MAX77620_CNFGGLBL1_LBDAC_EN | (enable ? MAX77620_CNFGGLBL1_MPPLD : 0) | MAX77620_CNFGGLBL1_LBDAC_EN | (enable ? MAX77620_CNFGGLBL1_MPPLD : 0) |
MAX77620_CNFGGLBL1_LBHYST_200 | MAX77620_CNFGGLBL1_LBDAC_2800); MAX77620_CNFGGLBL1_LBHYST_200 | MAX77620_CNFGGLBL1_LBDAC_2800);
} }

View File

@ -69,7 +69,7 @@
#define MAX77621_CONTROL2_REG 3 #define MAX77621_CONTROL2_REG 3
/* MAX77621_VOUT */ /* MAX77621_VOUT */
#define MAX77621_VOUT_ENABLE (1 << 7) #define MAX77621_VOUT_ENABLE BIT(7)
#define MAX77621_VOUT_MASK 0x7F #define MAX77621_VOUT_MASK 0x7F
#define MAX77621_VOUT_0_95V 0x37 #define MAX77621_VOUT_0_95V 0x37
#define MAX77621_VOUT_1_09V 0x4F #define MAX77621_VOUT_1_09V 0x4F
@ -78,12 +78,12 @@
#define MAX77621_DVS_VOUT_MASK 0x7F #define MAX77621_DVS_VOUT_MASK 0x7F
/* MAX77621_CONTROL1 */ /* MAX77621_CONTROL1 */
#define MAX77621_SNS_ENABLE (1 << 7) #define MAX77621_FREQSHIFT_9PER BIT(2)
#define MAX77621_FPWM_EN_M (1 << 6) #define MAX77621_BIAS_ENABLE BIT(3)
#define MAX77621_NFSR_ENABLE (1 << 5) #define MAX77621_AD_ENABLE BIT(4)
#define MAX77621_AD_ENABLE (1 << 4) #define MAX77621_NFSR_ENABLE BIT(5)
#define MAX77621_BIAS_ENABLE (1 << 3) #define MAX77621_FPWM_EN_M BIT(6)
#define MAX77621_FREQSHIFT_9PER (1 << 2) #define MAX77621_SNS_ENABLE BIT(7)
#define MAX77621_RAMP_12mV_PER_US 0x0 #define MAX77621_RAMP_12mV_PER_US 0x0
#define MAX77621_RAMP_25mV_PER_US 0x1 #define MAX77621_RAMP_25mV_PER_US 0x1
@ -92,10 +92,10 @@
#define MAX77621_RAMP_MASK 0x3 #define MAX77621_RAMP_MASK 0x3
/* MAX77621_CONTROL2 */ /* MAX77621_CONTROL2 */
#define MAX77621_WDTMR_ENABLE (1 << 6) #define MAX77621_FT_ENABLE BIT(4)
#define MAX77621_DISCH_ENBABLE (1 << 5) #define MAX77621_DISCH_ENBABLE BIT(5)
#define MAX77621_FT_ENABLE (1 << 4) #define MAX77621_WDTMR_ENABLE BIT(6)
#define MAX77621_T_JUNCTION_120 (1 << 7) #define MAX77621_T_JUNCTION_120 BIT(7)
#define MAX77621_CKKADV_TRIP_DISABLE 0xC #define MAX77621_CKKADV_TRIP_DISABLE 0xC
#define MAX77621_CKKADV_TRIP_75mV_PER_US 0x0 #define MAX77621_CKKADV_TRIP_75mV_PER_US 0x0

100
bdk/power/max77812.h Normal file
View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MAX77812_H_
#define _MAX77812_H_
#define MAX77812_PHASE31_CPU_I2C_ADDR 0x31
#define MAX77812_PHASE211_CPU_I2C_ADDR 0x33
#define MAX77812_REG_RSET 0x00
#define MAX77812_REG_INT_SRC 0x01
#define MAX77812_REG_INT_SRC_M 0x02
#define MAX77812_REG_TOPSYS_INT 0x03
#define MAX77812_REG_TOPSYS_INT_M 0x04
#define MAX77812_REG_TOPSYS_STAT 0x05
#define MAX77812_REG_EN_CTRL 0x06
#define MAX77812_EN_CTRL_EN_M4 BIT(6)
#define MAX77812_REG_STUP_DLY2 0x07
#define MAX77812_REG_STUP_DLY3 0x08
#define MAX77812_REG_STUP_DLY4 0x09
#define MAX77812_REG_SHDN_DLY1 0x0A
#define MAX77812_REG_SHDN_DLY2 0x0B
#define MAX77812_REG_SHDN_DLY3 0x0C
#define MAX77812_REG_SHDN_DLY4 0x0D
#define MAX77812_REG_WDTRSTB_DEB 0x0E
#define MAX77812_REG_GPI_FUNC 0x0F
#define MAX77812_REG_GPI_DEB1 0x10
#define MAX77812_REG_GPI_DEB2 0x11
#define MAX77812_REG_GPI_PD_CTRL 0x12
#define MAX77812_REG_PROT_CFG 0x13
#define MAX77812_REG_VERSION 0x14
#define MAX77812_REG_I2C_CFG 0x15
#define MAX77812_REG_BUCK_INT 0x20
#define MAX77812_REG_BUCK_INT_M 0x21
#define MAX77812_REG_BUCK_STAT 0x22
#define MAX77812_REG_M1_VOUT 0x23
#define MAX77812_REG_M2_VOUT 0x24
#define MAX77812_REG_M3_VOUT 0x25
#define MAX77812_REG_M4_VOUT 0x26
#define MAX77812_M4_VOUT_0_80V 0x6E
#define MAX77812_REG_M1_VOUT_D 0x27
#define MAX77812_REG_M2_VOUT_D 0x28
#define MAX77812_REG_M3_VOUT_D 0x29
#define MAX77812_REG_M4_VOUT_D 0x2A
#define MAX77812_REG_M1_VOUT_S 0x2B
#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_GLB_CFG3 0x35
#define MAX77812_REG_GLB_CFG4 0x36
#define MAX77812_REG_GLB_CFG5 0x37
#define MAX77812_REG_GLB_CFG6 0x38
#define MAX77812_REG_GLB_CFG7 0x39
#define MAX77812_REG_GLB_CFG8 0x3A
#define MAX77812_REG_PROT_ACCESS 0xFD
#define MAX77812_REG_MAX 0xFE
#define MAX77812_REG_EN_CTRL_MASK(n) BIT(n)
#define MAX77812_START_SLEW_RATE_MASK 0x07
#define MAX77812_SHDN_SLEW_RATE_MASK 0x70
#define MAX77812_RAMPUP_SLEW_RATE_MASK 0x07
#define MAX77812_RAMPDOWN_SLEW_RATE_MASK 0x70
#define MAX77812_SLEW_RATE_SHIFT 4
#define MAX77812_OP_ACTIVE_DISCHARGE_MASK BIT(7)
#define MAX77812_PEAK_CURRENT_LMT_MASK 0x70
#define MAX77812_SWITCH_FREQ_MASK 0x0C
#define MAX77812_FORCED_PWM_MASK BIT(1)
#define MAX77812_SLEW_RATE_CNTRL_MASK BIT(0)
#define MAX77812_START_SHD_DELAY_MASK 0x1F
#define MAX77812_VERSION_MASK 0x07
#define MAX77812_ES2_VERSION 0x04
#define MAX77812_QS_VERSION 0x05
#define MAX77812_VOUT_MASK 0xFF
#define MAX77812_VOUT_N_VOLTAGE 0xFF
#define MAX77812_VOUT_VMIN 250000
#define MAX77812_VOUT_VMAX 1525000
#define MAX77812_VOUT_STEP 5000
#endif

View File

@ -21,9 +21,9 @@
enum enum
{ {
REGULATOR_5V_FAN = (1 << 0), REGULATOR_5V_FAN = BIT(0),
REGULATOR_5V_JC_R = (1 << 1), REGULATOR_5V_JC_R = BIT(1),
REGULATOR_5V_JC_L = (1 << 2), REGULATOR_5V_JC_L = BIT(2),
REGULATOR_5V_ALL = 0xFF REGULATOR_5V_ALL = 0xFF
}; };

View File

@ -27,17 +27,17 @@
#define MAX77620_RTC_CONTROLM_REG 0x02 #define MAX77620_RTC_CONTROLM_REG 0x02
#define MAX77620_RTC_CONTROL_REG 0x03 #define MAX77620_RTC_CONTROL_REG 0x03
#define MAX77620_RTC_BIN_FORMAT (1 << 0) #define MAX77620_RTC_BIN_FORMAT BIT(0)
#define MAX77620_RTC_24H (1 << 1) #define MAX77620_RTC_24H BIT(1)
#define MAX77620_RTC_UPDATE0_REG 0x04 #define MAX77620_RTC_UPDATE0_REG 0x04
#define MAX77620_RTC_WRITE_UPDATE (1 << 0) #define MAX77620_RTC_WRITE_UPDATE BIT(0)
#define MAX77620_RTC_READ_UPDATE (1 << 4) #define MAX77620_RTC_READ_UPDATE BIT(4)
#define MAX77620_RTC_SEC_REG 0x07 #define MAX77620_RTC_SEC_REG 0x07
#define MAX77620_RTC_MIN_REG 0x08 #define MAX77620_RTC_MIN_REG 0x08
#define MAX77620_RTC_HOUR_REG 0x09 #define MAX77620_RTC_HOUR_REG 0x09
#define MAX77620_RTC_HOUR_PM_MASK (1 << 6) #define MAX77620_RTC_HOUR_PM_MASK BIT(6)
#define MAX77620_RTC_WEEKDAY_REG 0x0A #define MAX77620_RTC_WEEKDAY_REG 0x0A
#define MAX77620_RTC_MONTH_REG 0x0B #define MAX77620_RTC_MONTH_REG 0x0B
#define MAX77620_RTC_YEAR_REG 0x0C #define MAX77620_RTC_YEAR_REG 0x0C
@ -57,7 +57,7 @@
#define MAX77620_ALARM2_MONTH_REG 0x19 #define MAX77620_ALARM2_MONTH_REG 0x19
#define MAX77620_ALARM2_YEAR_REG 0x1A #define MAX77620_ALARM2_YEAR_REG 0x1A
#define MAX77620_ALARM2_DATE_REG 0x1B #define MAX77620_ALARM2_DATE_REG 0x1B
#define MAX77620_RTC_ALARM_EN_MASK (1 << 7) #define MAX77620_RTC_ALARM_EN_MASK BIT(7)
typedef struct _rtc_time_t { typedef struct _rtc_time_t {
u8 weekday; u8 weekday;

View File

@ -24,6 +24,7 @@
#include <memory_map.h> #include <memory_map.h>
#include <mem/heap.h> #include <mem/heap.h>
#include <soc/bpmp.h> #include <soc/bpmp.h>
#include <soc/pmc.h>
#include <soc/t210.h> #include <soc/t210.h>
#include <utils/util.h> #include <utils/util.h>
@ -93,22 +94,21 @@ static int _se_wait()
return 1; return 1;
} }
static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size) se_ll_t *ll_dst, *ll_src;
static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot)
{ {
static se_ll_t *ll_dst = NULL, *ll_src = NULL; ll_dst = NULL;
if (!ll_dst) ll_src = NULL;
{
ll_dst = (se_ll_t *)malloc(sizeof(se_ll_t));
ll_src = (se_ll_t *)malloc(sizeof(se_ll_t));
}
if (dst) if (dst)
{ {
ll_dst = (se_ll_t *)malloc(sizeof(se_ll_t));
_se_ll_init(ll_dst, (u32)dst, dst_size); _se_ll_init(ll_dst, (u32)dst, dst_size);
} }
if (src) if (src)
{ {
ll_src = (se_ll_t *)malloc(sizeof(se_ll_t));
_se_ll_init(ll_src, (u32)src, src_size); _se_ll_init(ll_src, (u32)src, src_size);
} }
@ -120,11 +120,47 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op); SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op);
if (is_oneshot)
{
int res = _se_wait(); int res = _se_wait();
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
if (src)
free(ll_src);
if (dst)
free(ll_dst);
return res; return res;
}
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);
} }
static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size) static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)
@ -138,7 +174,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
memcpy(block, src, src_size); memcpy(block, src, src_size);
int res = _se_execute(op, block, 0x10, block, 0x10); int res = _se_execute_oneshot(op, block, 0x10, block, 0x10);
memcpy(dst, block, dst_size); memcpy(dst, block, dst_size);
free(block); free(block);
@ -147,9 +183,11 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
static void _se_aes_ctr_set(void *ctr) static void _se_aes_ctr_set(void *ctr)
{ {
u32 *data = (u32 *)ctr; u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4];
for (u32 i = 0; i < 4; i++) memcpy(data, ctr, TEGRA_SE_AES_BLOCK_SIZE);
SE(SE_CRYPTO_CTR_REG_OFFSET + 4 * i) = data[i];
for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++)
SE(SE_CRYPTO_CTR_REG_OFFSET + (4 * i)) = data[i];
} }
void se_rsa_acc_ctrl(u32 rs, u32 flags) void se_rsa_acc_ctrl(u32 rs, u32 flags)
@ -159,7 +197,7 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags)
((flags >> SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) | ((flags >> SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) |
((flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG) ^ SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG); ((flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG) ^ SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG);
if (flags & SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG) if (flags & SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG)
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~(1 << rs); SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~BIT(rs);
} }
// se_rsa_key_set() was derived from Atmosphère's set_rsa_keyslot // se_rsa_key_set() was derived from Atmosphère's set_rsa_keyslot
@ -212,7 +250,7 @@ int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_siz
SE(SE_RSA_KEY_SIZE_REG_OFFSET) = (_se_rsa_mod_sizes[ks] >> 6) - 1; SE(SE_RSA_KEY_SIZE_REG_OFFSET) = (_se_rsa_mod_sizes[ks] >> 6) - 1;
SE(SE_RSA_EXP_SIZE_REG_OFFSET) = _se_rsa_exp_sizes[ks] >> 2; SE(SE_RSA_EXP_SIZE_REG_OFFSET) = _se_rsa_exp_sizes[ks] >> 2;
res = _se_execute(OP_START, NULL, 0, stack_buf, src_size); res = _se_execute_oneshot(OP_START, NULL, 0, stack_buf, src_size);
// Copy output hash. // Copy output hash.
u32 *dst32 = (u32 *)dst; u32 *dst32 = (u32 *)dst;
@ -227,7 +265,7 @@ void se_key_acc_ctrl(u32 ks, u32 flags)
if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG) if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG)
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags; SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags;
if (flags & SE_KEY_TBL_DIS_KEY_LOCK_FLAG) if (flags & SE_KEY_TBL_DIS_KEY_LOCK_FLAG)
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~(1 << ks); SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~BIT(ks);
} }
u32 se_key_acc_ctrl_get(u32 ks) u32 se_key_acc_ctrl_get(u32 ks)
@ -237,48 +275,61 @@ u32 se_key_acc_ctrl_get(u32 ks)
void se_aes_key_set(u32 ks, const void *key, u32 size) void se_aes_key_set(u32 ks, const void *key, u32 size)
{ {
u32 *data = (u32 *)key; u32 data[TEGRA_SE_AES_MAX_KEY_SIZE / 4];
for (u32 i = 0; i < size / 4; i++) memcpy(data, key, size);
for (u32 i = 0; i < (size / 4); i++)
{ {
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i]; SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];
} }
} }
void se_aes_iv_set(u32 ks, const void *iv, u32 size) void se_aes_key_partial_set(u32 ks, u32 index, u32 data)
{ {
u32 *data = (u32 *)iv; SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | index;
for (u32 i = 0; i < size / 4; i++) SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data;
}
void se_aes_iv_set(u32 ks, const void *iv)
{
u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4];
memcpy(data, iv, TEGRA_SE_AES_BLOCK_SIZE);
for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++)
{ {
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | 8 | i; SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i;
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i]; SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];
} }
} }
void se_aes_key_read(u32 ks, void *key, u32 size) void se_aes_key_get(u32 ks, void *key, u32 size)
{ {
u32 *data = (u32 *)key; u32 data[TEGRA_SE_AES_MAX_KEY_SIZE / 4];
for (u32 i = 0; i < size / 4; i++)
for (u32 i = 0; i < (size / 4); i++)
{ {
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
data[i] = SE(SE_KEYTABLE_DATA0_REG_OFFSET); data[i] = SE(SE_KEYTABLE_DATA0_REG_OFFSET);
} }
memcpy(key, data, size);
} }
void se_aes_key_clear(u32 ks) void se_aes_key_clear(u32 ks)
{ {
for (u32 i = 0; i < TEGRA_SE_AES_MAX_KEY_SIZE / 4; i++) for (u32 i = 0; i < (TEGRA_SE_AES_MAX_KEY_SIZE / 4); i++)
{ {
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0; SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;
} }
} }
void se_aes_key_iv_clear(u32 ks) void se_aes_iv_clear(u32 ks)
{ {
for (u32 i = 0; i < TEGRA_SE_AES_MAX_KEY_SIZE / 4; i++) for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++)
{ {
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | 8 | i; SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i;
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0; SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;
} }
} }
@ -290,7 +341,7 @@ int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst); SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst);
return _se_execute(OP_START, NULL, 0, input, 0x10); return _se_execute_oneshot(OP_START, NULL, 0, input, 0x10);
} }
int se_aes_crypt_ecb(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)
@ -306,7 +357,25 @@ int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src,
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
} }
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1; SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
return _se_execute(OP_START, dst, dst_size, src, src_size); return _se_execute_oneshot(OP_START, dst, dst_size, src, src_size);
}
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
{
if (enc)
{
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_REG_OFFSET) = 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_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVAHB) |
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
}
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
return _se_execute_oneshot(OP_START, dst, dst_size, src, src_size);
} }
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src) int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src)
@ -319,8 +388,7 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
SE(SE_SPARE_0_REG_OFFSET) = 1; SE(SE_SPARE_0_REG_OFFSET) = 1;
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE(SE_CRYPTO_REG_OFFSET) = 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_VAL(1) | SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_VAL(1);
SE_CRYPTO_VCTRAM_SEL(VCTRAM_AHB);
_se_aes_ctr_set(ctr); _se_aes_ctr_set(ctr);
u32 src_size_aligned = src_size & 0xFFFFFFF0; u32 src_size_aligned = src_size & 0xFFFFFFF0;
@ -329,7 +397,7 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
if (src_size_aligned) if (src_size_aligned)
{ {
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1; SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
if (!_se_execute(OP_START, dst, dst_size, src, src_size_aligned)) if (!_se_execute_oneshot(OP_START, dst, dst_size, src, src_size_aligned))
return 0; return 0;
} }
@ -359,7 +427,7 @@ int se_initialize_rng()
SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(RNG_SRC_RO_ENT_LOCK_ENABLE); SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(RNG_SRC_RO_ENT_LOCK_ENABLE);
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
int res =_se_execute(OP_START, output_buf, 0x10, NULL, 0); int res =_se_execute_oneshot(OP_START, output_buf, 0x10, NULL, 0);
free(output_buf); free(output_buf);
if (res) if (res)
@ -378,7 +446,7 @@ int se_generate_random(void *dst, u32 size)
if (num_blocks) if (num_blocks)
{ {
SE(SE_BLOCK_COUNT_REG_OFFSET) = num_blocks - 1; SE(SE_BLOCK_COUNT_REG_OFFSET) = num_blocks - 1;
if (!_se_execute(OP_START, dst, aligned_size, NULL, 0)) if (!_se_execute_oneshot(OP_START, dst, aligned_size, NULL, 0))
return 0; return 0;
} }
if (size > aligned_size) if (size > aligned_size)
@ -394,35 +462,15 @@ int se_generate_random_key(u32 ks_dst, u32 ks_src)
SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_MODE(RNG_MODE_NORMAL) | SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY); SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_MODE(RNG_MODE_NORMAL) | SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY);
SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst); SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst);
if (!_se_execute(OP_START, NULL, 0, NULL, 0)) if (!_se_execute_oneshot(OP_START, NULL, 0, NULL, 0))
return 0; return 0;
SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst) | 1; SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst) | 1;
if (!_se_execute(OP_START, NULL, 0, NULL, 0)) if (!_se_execute_oneshot(OP_START, NULL, 0, NULL, 0))
return 0; return 0;
return 1; return 1;
} }
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
{
if (enc)
{
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_INPUT_SEL(INPUT_AHB) |
SE_CRYPTO_IV_SEL(IV_ORIGINAL);
}
else
{
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVAHB) |
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_AHB) |
SE_CRYPTO_IV_SEL(IV_ORIGINAL);
}
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
return _se_execute(OP_START, dst, dst_size, src, src_size);
}
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(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, const void *src, u32 sec_size)
{ {
u8 tweak[0x10]; u8 tweak[0x10];
@ -500,13 +548,13 @@ int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size)
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_AHB) | SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_AHB) |
SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) | SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT); SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
se_aes_key_iv_clear(ks); se_aes_iv_clear(ks);
u32 num_blocks = (src_size + 0xf) >> 4; u32 num_blocks = (src_size + 0xf) >> 4;
if (num_blocks > 1) if (num_blocks > 1)
{ {
SE(SE_BLOCK_COUNT_REG_OFFSET) = num_blocks - 2; SE(SE_BLOCK_COUNT_REG_OFFSET) = num_blocks - 2;
if (!_se_execute(OP_START, NULL, 0, src, src_size)) if (!_se_execute_oneshot(OP_START, NULL, 0, src, src_size))
goto out; goto out;
SE(SE_CRYPTO_REG_OFFSET) |= SE_CRYPTO_IV_SEL(IV_UPDATED); SE(SE_CRYPTO_REG_OFFSET) |= SE_CRYPTO_IV_SEL(IV_UPDATED);
} }
@ -525,7 +573,7 @@ int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size)
last_block[i] ^= key[i]; last_block[i] ^= key[i];
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
res = _se_execute(OP_START, NULL, 0, last_block, 0x10); res = _se_execute_oneshot(OP_START, NULL, 0, last_block, 0x10);
u32 *dst32 = (u32 *)dst; u32 *dst32 = (u32 *)dst;
for (u32 i = 0; i < (dst_size >> 2); i++) for (u32 i = 0; i < (dst_size >> 2); i++)
@ -537,29 +585,91 @@ out:;
return res; return res;
} }
// se_calc_sha256() was derived from Atmosphère's se_calculate_sha256. 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(void *dst, const void *src, u32 src_size)
{ {
int res; int res;
// Setup config for SHA256, size = BITS(src_size). u32 hash32[TEGRA_SE_SHA_256_SIZE / 4];
//! TODO: src_size must be 512 bit aligned if continuing and not last block for SHA256.
if (src_size > 0xFFFFFF || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer.
return 0;
// Setup config for SHA256.
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG); SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_INIT_HASH; SE(SE_SHA_CONFIG_REG_OFFSET) = sha_cfg;
SE(SE_SHA_MSG_LENGTH_0_REG_OFFSET) = (u32)(src_size << 3); SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = 0;
// Set total size to current buffer size if empty.
if (!total_size)
total_size = src_size;
// Set total size: BITS(src_size), up to 2 EB.
SE(SE_SHA_MSG_LENGTH_0_REG_OFFSET) = (u32)(total_size << 3);
SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = (u32)(total_size >> 29);
SE(SE_SHA_MSG_LENGTH_2_REG_OFFSET) = 0; SE(SE_SHA_MSG_LENGTH_2_REG_OFFSET) = 0;
SE(SE_SHA_MSG_LENGTH_3_REG_OFFSET) = 0; SE(SE_SHA_MSG_LENGTH_3_REG_OFFSET) = 0;
SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = (u32)(src_size << 3);
SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = 0; // Set size left to hash.
SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = (u32)(total_size << 3);
SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = (u32)(total_size >> 29);
SE(SE_SHA_MSG_LEFT_2_REG_OFFSET) = 0; SE(SE_SHA_MSG_LEFT_2_REG_OFFSET) = 0;
SE(SE_SHA_MSG_LEFT_3_REG_OFFSET) = 0; SE(SE_SHA_MSG_LEFT_3_REG_OFFSET) = 0;
// If we hash in chunks, copy over the intermediate.
if (sha_cfg == SHA_CONTINUE && msg_left)
{
// Restore message left to process.
SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = msg_left[0];
SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = msg_left[1];
// Restore hash reg.
memcpy(hash32, hash, TEGRA_SE_SHA_256_SIZE);
for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)) = byte_swap_32(hash32[i]);
}
// Trigger the operation. // Trigger the operation.
res = _se_execute(OP_START, NULL, 0, src, src_size); res = _se_execute(OP_START, NULL, 0, src, src_size, is_oneshot);
if (is_oneshot)
{
// Backup message left.
if (msg_left)
{
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET);
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET);
}
// Copy output hash. // Copy output hash.
u32 *dst32 = (u32 *)dst; for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
for (u32 i = 0; i < 8; i++) hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));
dst32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2))); memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE);
}
return res;
}
int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size)
{
return se_calc_sha256(hash, NULL, src, src_size, 0, SHA_INIT_HASH, true);
}
int se_calc_sha256_finalize(void *hash, u32 *msg_left)
{
u32 hash32[TEGRA_SE_SHA_256_SIZE / 4];
int res = _se_execute_finalize();
// Backup message left.
if (msg_left)
{
msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET);
msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET);
}
// Copy output hash.
for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));
memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE);
return res; return res;
} }
@ -573,7 +683,7 @@ int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *ke
if (key_size > 0x40) if (key_size > 0x40)
{ {
if (!se_calc_sha256(secret, key, key_size)) if (!se_calc_sha256_oneshot(secret, key, key_size))
goto out; goto out;
memset(secret + 0x20, 0, 0x20); memset(secret + 0x20, 0, 0x20);
} }
@ -593,10 +703,10 @@ int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *ke
} }
memcpy(ipad + 0x40, src, src_size); memcpy(ipad + 0x40, src, src_size);
if (!se_calc_sha256(dst, ipad, 0x40 + src_size)) if (!se_calc_sha256_oneshot(dst, ipad, 0x40 + src_size))
goto out; goto out;
memcpy(opad + 0x40, dst, 0x20); memcpy(opad + 0x40, dst, 0x20);
if (!se_calc_sha256(dst, opad, 0x60)) if (!se_calc_sha256_oneshot(dst, opad, 0x60))
goto out; goto out;
res = 1; res = 1;
@ -611,8 +721,8 @@ out:;
// _mgf1_xor() and rsa_oaep_decode were derived from Atmosphère // _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) static void _mgf1_xor(void *masked, u32 masked_size, const void *seed, u32 seed_size)
{ {
u8 cur_hash[0x20]; u8 cur_hash[0x20] __attribute__((aligned(4)));
u8 hash_buf[0xe4]; u8 hash_buf[0xe4] __attribute__((aligned(4)));
u32 hash_buf_size = seed_size + 4; u32 hash_buf_size = seed_size + 4;
memcpy(hash_buf, seed, seed_size); memcpy(hash_buf, seed, seed_size);
@ -627,7 +737,7 @@ static void _mgf1_xor(void *masked, u32 masked_size, const void *seed, u32 seed_
hash_buf[seed_size + 3 - i] = (round_num >> (8 * i)) & 0xff; hash_buf[seed_size + 3 - i] = (round_num >> (8 * i)) & 0xff;
round_num++; round_num++;
se_calc_sha256(cur_hash, hash_buf, hash_buf_size); se_calc_sha256_oneshot(cur_hash, hash_buf, hash_buf_size);
for (unsigned int i = 0; i < cur_size; i++) { for (unsigned int i = 0; i < cur_size; i++) {
*p_out ^= cur_hash[i]; *p_out ^= cur_hash[i];
@ -678,3 +788,59 @@ u32 se_rsa_oaep_decode(void *dst, u32 dst_size, const void *label_digest, u32 la
return msg_size; return msg_size;
} }
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_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK);
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY) | SE_RNG_CONFIG_MODE(RNG_MODE_FORCE_RESEED);
SE(SE_CRYPTO_LAST_BLOCK) = 0;
_se_execute_oneshot(OP_START, NULL, 0, NULL, 0);
// Save AES keys.
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
for (u32 i = 0; i < TEGRA_SE_KEYSLOT_COUNT; i++)
{
SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(AES_KEYTABLE) |
(i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_0_3);
SE(SE_CRYPTO_LAST_BLOCK) = 0;
_se_execute_oneshot(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0);
memcpy(keys + i * keysize, aligned_buf, 0x10);
if (keysize > 0x10)
{
SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(AES_KEYTABLE) |
(i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_4_7);
SE(SE_CRYPTO_LAST_BLOCK) = 0;
_se_execute_oneshot(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0);
memcpy(keys + i * keysize + 0x10, aligned_buf, 0x10);
}
}
// Save SRK to PMC secure scratches.
SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(SRK);
SE(SE_CRYPTO_LAST_BLOCK) = 0;
_se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0);
// End context save.
SE(SE_CONFIG_REG_OFFSET) = 0;
_se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0);
// Get SRK.
u32 srk[4];
srk[0] = PMC(APBDEV_PMC_SECURE_SCRATCH4);
srk[1] = PMC(APBDEV_PMC_SECURE_SCRATCH5);
srk[2] = PMC(APBDEV_PMC_SECURE_SCRATCH6);
srk[3] = PMC(APBDEV_PMC_SECURE_SCRATCH7);
// Decrypt context.
se_aes_key_clear(3);
se_aes_key_set(3, srk, 0x10);
se_aes_crypt_cbc(3, 0, keys, TEGRA_SE_KEYSLOT_COUNT * keysize, keys, TEGRA_SE_KEYSLOT_COUNT * keysize);
se_aes_key_clear(3);
}

View File

@ -26,9 +26,11 @@ int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_siz
void se_key_acc_ctrl(u32 ks, u32 flags); void se_key_acc_ctrl(u32 ks, u32 flags);
u32 se_key_acc_ctrl_get(u32 ks); u32 se_key_acc_ctrl_get(u32 ks);
void se_aes_key_set(u32 ks, const void *key, u32 size); void se_aes_key_set(u32 ks, const void *key, u32 size);
void se_aes_iv_set(u32 ks, const void *iv, u32 size); void se_aes_iv_set(u32 ks, const void *iv);
void se_aes_key_read(u32 ks, void *key, u32 size); void se_aes_key_partial_set(u32 ks, u32 index, u32 data);
void se_aes_key_get(u32 ks, void *key, u32 size);
void se_aes_key_clear(u32 ks); void se_aes_key_clear(u32 ks);
void se_aes_iv_clear(u32 ks);
int se_initialize_rng(); int se_initialize_rng();
int se_generate_random(void *dst, u32 size); int se_generate_random(void *dst, u32 size);
int se_generate_random_key(u32 ks_dst, u32 ks_src); int se_generate_random_key(u32 ks_dst, u32 ks_src);
@ -40,8 +42,11 @@ int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src,
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(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_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_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_calc_sha256(void *dst, 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_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); u32 se_rsa_oaep_decode(void *dst, u32 dst_size, const void *label_digest, u32 label_digest_size, u8 *buf, u32 buf_size);
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize);
#endif #endif

View File

@ -47,15 +47,15 @@
#define ALG_RSA 4 #define ALG_RSA 4
#define ALG_NOP 0 #define ALG_NOP 0
#define ALG_AES_DEC 1 #define ALG_AES_DEC 1
#define SE_CONFIG_ENC_ALG(x) (x << SE_CONFIG_ENC_ALG_SHIFT) #define SE_CONFIG_ENC_ALG(x) ((x) << SE_CONFIG_ENC_ALG_SHIFT)
#define SE_CONFIG_DEC_ALG(x) (x << SE_CONFIG_DEC_ALG_SHIFT) #define SE_CONFIG_DEC_ALG(x) ((x) << SE_CONFIG_DEC_ALG_SHIFT)
#define SE_CONFIG_DST_SHIFT 2 #define SE_CONFIG_DST_SHIFT 2
#define DST_MEMORY 0 #define DST_MEMORY 0
#define DST_HASHREG 1 #define DST_HASHREG 1
#define DST_KEYTAB 2 #define DST_KEYTAB 2
#define DST_SRK 3 #define DST_SRK 3
#define DST_RSAREG 4 #define DST_RSAREG 4
#define SE_CONFIG_DST(x) (x << SE_CONFIG_DST_SHIFT) #define SE_CONFIG_DST(x) ((x) << SE_CONFIG_DST_SHIFT)
#define SE_CONFIG_ENC_MODE_SHIFT 24 #define SE_CONFIG_ENC_MODE_SHIFT 24
#define SE_CONFIG_DEC_MODE_SHIFT 16 #define SE_CONFIG_DEC_MODE_SHIFT 16
#define MODE_KEY128 0 #define MODE_KEY128 0
@ -66,57 +66,57 @@
#define MODE_SHA256 5 #define MODE_SHA256 5
#define MODE_SHA384 6 #define MODE_SHA384 6
#define MODE_SHA512 7 #define MODE_SHA512 7
#define SE_CONFIG_ENC_MODE(x) (x << SE_CONFIG_ENC_MODE_SHIFT) #define SE_CONFIG_ENC_MODE(x) ((x) << SE_CONFIG_ENC_MODE_SHIFT)
#define SE_CONFIG_DEC_MODE(x) (x << SE_CONFIG_DEC_MODE_SHIFT) #define SE_CONFIG_DEC_MODE(x) ((x) << SE_CONFIG_DEC_MODE_SHIFT)
#define SE_RNG_CONFIG_REG_OFFSET 0x340 #define SE_RNG_CONFIG_REG_OFFSET 0x340
#define RNG_MODE_SHIFT 0 #define RNG_MODE_SHIFT 0
#define RNG_MODE_NORMAL 0 #define RNG_MODE_NORMAL 0
#define RNG_MODE_FORCE_INSTANTION 1 #define RNG_MODE_FORCE_INSTANTION 1
#define RNG_MODE_FORCE_RESEED 2 #define RNG_MODE_FORCE_RESEED 2
#define SE_RNG_CONFIG_MODE(x) (x << RNG_MODE_SHIFT) #define SE_RNG_CONFIG_MODE(x) ((x) << RNG_MODE_SHIFT)
#define RNG_SRC_SHIFT 2 #define RNG_SRC_SHIFT 2
#define RNG_SRC_NONE 0 #define RNG_SRC_NONE 0
#define RNG_SRC_ENTROPY 1 #define RNG_SRC_ENTROPY 1
#define RNG_SRC_LFSR 2 #define RNG_SRC_LFSR 2
#define SE_RNG_CONFIG_SRC(x) (x << RNG_SRC_SHIFT) #define SE_RNG_CONFIG_SRC(x) ((x) << RNG_SRC_SHIFT)
#define SE_RNG_SRC_CONFIG_REG_OFFSET 0x344 #define SE_RNG_SRC_CONFIG_REG_OFFSET 0x344
#define RNG_SRC_RO_ENT_SHIFT 1 #define RNG_SRC_RO_ENT_SHIFT 1
#define RNG_SRC_RO_ENT_ENABLE 1 #define RNG_SRC_RO_ENT_ENABLE 1
#define RNG_SRC_RO_ENT_DISABLE 0 #define RNG_SRC_RO_ENT_DISABLE 0
#define SE_RNG_SRC_CONFIG_ENT_SRC(x) (x << RNG_SRC_RO_ENT_SHIFT) #define SE_RNG_SRC_CONFIG_ENT_SRC(x) ((x) << RNG_SRC_RO_ENT_SHIFT)
#define RNG_SRC_RO_ENT_LOCK_SHIFT 0 #define RNG_SRC_RO_ENT_LOCK_SHIFT 0
#define RNG_SRC_RO_ENT_LOCK_ENABLE 1 #define RNG_SRC_RO_ENT_LOCK_ENABLE 1
#define RNG_SRC_RO_ENT_LOCK_DISABLE 0 #define RNG_SRC_RO_ENT_LOCK_DISABLE 0
#define SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(x) (x << RNG_SRC_RO_ENT_LOCK_SHIFT) #define SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(x) ((x) << RNG_SRC_RO_ENT_LOCK_SHIFT)
#define SE_RNG_RESEED_INTERVAL_REG_OFFSET 0x348 #define SE_RNG_RESEED_INTERVAL_REG_OFFSET 0x348
#define SE_KEYTABLE_REG_OFFSET 0x31c #define SE_KEYTABLE_REG_OFFSET 0x31c
#define SE_KEYTABLE_SLOT_SHIFT 4 #define SE_KEYTABLE_SLOT_SHIFT 4
#define SE_KEYTABLE_SLOT(x) (x << SE_KEYTABLE_SLOT_SHIFT) #define SE_KEYTABLE_SLOT(x) ((x) << SE_KEYTABLE_SLOT_SHIFT)
#define SE_KEYTABLE_QUAD_SHIFT 2 #define SE_KEYTABLE_QUAD_SHIFT 2
#define QUAD_KEYS_128 0 #define QUAD_KEYS_128 0
#define QUAD_KEYS_192 1 #define QUAD_KEYS_192 1
#define QUAD_KEYS_256 1 #define QUAD_KEYS_256 1
#define QUAD_ORG_IV 2 #define QUAD_ORG_IV 2
#define QUAD_UPDTD_IV 3 #define QUAD_UPDTD_IV 3
#define SE_KEYTABLE_QUAD(x) (x << SE_KEYTABLE_QUAD_SHIFT) #define SE_KEYTABLE_QUAD(x) ((x) << SE_KEYTABLE_QUAD_SHIFT)
#define SE_KEYTABLE_OP_TYPE_SHIFT 9 #define SE_KEYTABLE_OP_TYPE_SHIFT 9
#define OP_READ 0 #define OP_READ 0
#define OP_WRITE 1 #define OP_WRITE 1
#define SE_KEYTABLE_OP_TYPE(x) (x << SE_KEYTABLE_OP_TYPE_SHIFT) #define SE_KEYTABLE_OP_TYPE(x) ((x) << SE_KEYTABLE_OP_TYPE_SHIFT)
#define SE_KEYTABLE_TABLE_SEL_SHIFT 8 #define SE_KEYTABLE_TABLE_SEL_SHIFT 8
#define TABLE_KEYIV 0 #define TABLE_KEYIV 0
#define TABLE_SCHEDULE 1 #define TABLE_SCHEDULE 1
#define SE_KEYTABLE_TABLE_SEL(x) (x << SE_KEYTABLE_TABLE_SEL_SHIFT) #define SE_KEYTABLE_TABLE_SEL(x) ((x) << SE_KEYTABLE_TABLE_SEL_SHIFT)
#define SE_KEYTABLE_PKT_SHIFT 0 #define SE_KEYTABLE_PKT_SHIFT 0
#define SE_KEYTABLE_PKT(x) (x << SE_KEYTABLE_PKT_SHIFT) #define SE_KEYTABLE_PKT(x) ((x) << SE_KEYTABLE_PKT_SHIFT)
#define SE_OP_DONE_SHIFT 4 #define SE_OP_DONE_SHIFT 4
#define OP_DONE 1 #define OP_DONE 1
#define SE_OP_DONE(x, y) ((x) && (y << SE_OP_DONE_SHIFT)) #define SE_OP_DONE(x, y) ((x) && ((y) << SE_OP_DONE_SHIFT))
#define SE_CRYPTO_LAST_BLOCK 0x080 #define SE_CRYPTO_LAST_BLOCK 0x080
@ -124,37 +124,37 @@
#define SE_CRYPTO_HASH_SHIFT 0 #define SE_CRYPTO_HASH_SHIFT 0
#define HASH_DISABLE 0 #define HASH_DISABLE 0
#define HASH_ENABLE 1 #define HASH_ENABLE 1
#define SE_CRYPTO_HASH(x) (x << SE_CRYPTO_HASH_SHIFT) #define SE_CRYPTO_HASH(x) ((x) << SE_CRYPTO_HASH_SHIFT)
#define SE_CRYPTO_XOR_POS_SHIFT 1 #define SE_CRYPTO_XOR_POS_SHIFT 1
#define XOR_BYPASS 0 #define XOR_BYPASS 0
#define XOR_TOP 2 #define XOR_TOP 2
#define XOR_BOTTOM 3 #define XOR_BOTTOM 3
#define SE_CRYPTO_XOR_POS(x) (x << SE_CRYPTO_XOR_POS_SHIFT) #define SE_CRYPTO_XOR_POS(x) ((x) << SE_CRYPTO_XOR_POS_SHIFT)
#define SE_CRYPTO_INPUT_SEL_SHIFT 3 #define SE_CRYPTO_INPUT_SEL_SHIFT 3
#define INPUT_AHB 0 #define INPUT_AHB 0
#define INPUT_RANDOM 1 #define INPUT_RANDOM 1
#define INPUT_AESOUT 2 #define INPUT_AESOUT 2
#define INPUT_LNR_CTR 3 #define INPUT_LNR_CTR 3
#define SE_CRYPTO_INPUT_SEL(x) (x << SE_CRYPTO_INPUT_SEL_SHIFT) #define SE_CRYPTO_INPUT_SEL(x) ((x) << SE_CRYPTO_INPUT_SEL_SHIFT)
#define SE_CRYPTO_VCTRAM_SEL_SHIFT 5 #define SE_CRYPTO_VCTRAM_SEL_SHIFT 5
#define VCTRAM_AHB 0 #define VCTRAM_AHB 0
#define VCTRAM_AESOUT 2 #define VCTRAM_AESOUT 2
#define VCTRAM_PREVAHB 3 #define VCTRAM_PREVAHB 3
#define SE_CRYPTO_VCTRAM_SEL(x) (x << SE_CRYPTO_VCTRAM_SEL_SHIFT) #define SE_CRYPTO_VCTRAM_SEL(x) ((x) << SE_CRYPTO_VCTRAM_SEL_SHIFT)
#define SE_CRYPTO_IV_SEL_SHIFT 7 #define SE_CRYPTO_IV_SEL_SHIFT 7
#define IV_ORIGINAL 0 #define IV_ORIGINAL 0
#define IV_UPDATED 1 #define IV_UPDATED 1
#define SE_CRYPTO_IV_SEL(x) (x << SE_CRYPTO_IV_SEL_SHIFT) #define SE_CRYPTO_IV_SEL(x) ((x) << SE_CRYPTO_IV_SEL_SHIFT)
#define SE_CRYPTO_CORE_SEL_SHIFT 8 #define SE_CRYPTO_CORE_SEL_SHIFT 8
#define CORE_DECRYPT 0 #define CORE_DECRYPT 0
#define CORE_ENCRYPT 1 #define CORE_ENCRYPT 1
#define SE_CRYPTO_CORE_SEL(x) (x << SE_CRYPTO_CORE_SEL_SHIFT) #define SE_CRYPTO_CORE_SEL(x) ((x) << SE_CRYPTO_CORE_SEL_SHIFT)
#define SE_CRYPTO_CTR_VAL_SHIFT 11 #define SE_CRYPTO_CTR_VAL_SHIFT 11
#define SE_CRYPTO_CTR_VAL(x) (x << SE_CRYPTO_CTR_VAL_SHIFT) #define SE_CRYPTO_CTR_VAL(x) ((x) << SE_CRYPTO_CTR_VAL_SHIFT)
#define SE_CRYPTO_KEY_INDEX_SHIFT 24 #define SE_CRYPTO_KEY_INDEX_SHIFT 24
#define SE_CRYPTO_KEY_INDEX(x) (x << SE_CRYPTO_KEY_INDEX_SHIFT) #define SE_CRYPTO_KEY_INDEX(x) ((x) << SE_CRYPTO_KEY_INDEX_SHIFT)
#define SE_CRYPTO_CTR_CNTN_SHIFT 11 #define SE_CRYPTO_CTR_CNTN_SHIFT 11
#define SE_CRYPTO_CTR_CNTN(x) (x << SE_CRYPTO_CTR_CNTN_SHIFT) #define SE_CRYPTO_CTR_CNTN(x) ((x) << SE_CRYPTO_CTR_CNTN_SHIFT)
#define SE_CRYPTO_CTR_REG_COUNT 4 #define SE_CRYPTO_CTR_REG_COUNT 4
#define SE_CRYPTO_CTR_REG_OFFSET 0x308 #define SE_CRYPTO_CTR_REG_OFFSET 0x308
@ -166,7 +166,7 @@
#define OP_RESTART 2 #define OP_RESTART 2
#define OP_CTX_SAVE 3 #define OP_CTX_SAVE 3
#define OP_RESTART_IN 4 #define OP_RESTART_IN 4
#define SE_OPERATION(x) (x << SE_OPERATION_SHIFT) #define SE_OPERATION(x) ((x) << SE_OPERATION_SHIFT)
#define SE_CONTEXT_SAVE_CONFIG_REG_OFFSET 0x070 #define SE_CONTEXT_SAVE_CONFIG_REG_OFFSET 0x070
#define SE_CONTEXT_SAVE_WORD_QUAD_SHIFT 0 #define SE_CONTEXT_SAVE_WORD_QUAD_SHIFT 0
@ -174,16 +174,16 @@
#define KEYS_4_7 1 #define KEYS_4_7 1
#define ORIG_IV 2 #define ORIG_IV 2
#define UPD_IV 3 #define UPD_IV 3
#define SE_CONTEXT_SAVE_WORD_QUAD(x) (x << SE_CONTEXT_SAVE_WORD_QUAD_SHIFT) #define SE_CONTEXT_SAVE_WORD_QUAD(x) ((x) << SE_CONTEXT_SAVE_WORD_QUAD_SHIFT)
#define SE_CONTEXT_SAVE_KEY_INDEX_SHIFT 8 #define SE_CONTEXT_SAVE_KEY_INDEX_SHIFT 8
#define SE_CONTEXT_SAVE_KEY_INDEX(x) (x << SE_CONTEXT_SAVE_KEY_INDEX_SHIFT) #define SE_CONTEXT_SAVE_KEY_INDEX(x) ((x) << SE_CONTEXT_SAVE_KEY_INDEX_SHIFT)
#define SE_CONTEXT_SAVAE_STICKY_WORD_QUAD_SHIFT 24 #define SE_CONTEXT_SAVE_STICKY_WORD_QUAD_SHIFT 24
#define STICKY_0_3 0 #define STICKY_0_3 0
#define STICKY_4_7 1 #define STICKY_4_7 1
#define SE_CONTEXT_SAVE_STICKY_WORD_QUAD(x) \ #define SE_CONTEXT_SAVE_STICKY_WORD_QUAD(x) \
(x << SE_CONTEXT_SAVAE_STICKY_WORD_QUAD_SHIFT) ((x) << SE_CONTEXT_SAVE_STICKY_WORD_QUAD_SHIFT)
#define SE_CONTEXT_SAVE_SRC_SHIFT 29 #define SE_CONTEXT_SAVE_SRC_SHIFT 29
#define STICKY_BITS 0 #define STICKY_BITS 0
@ -193,15 +193,20 @@
#define RSA_KEYTABLE 1 #define RSA_KEYTABLE 1
#define AES_KEYTABLE 2 #define AES_KEYTABLE 2
#define SE_CONTEXT_SAVE_SRC(x) (x << SE_CONTEXT_SAVE_SRC_SHIFT) #define SE_CONTEXT_SAVE_SRC(x) ((x) << SE_CONTEXT_SAVE_SRC_SHIFT)
#define SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT 16 #define SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT 16
#define SE_CONTEXT_SAVE_RSA_KEY_INDEX(x) \ #define SE_CONTEXT_SAVE_RSA_KEY_INDEX(x) \
(x << SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT) ((x) << SE_CONTEXT_SAVE_RSA_KEY_INDEX_SHIFT)
#define SE_CONTEXT_RSA_WORD_QUAD_SHIFT 12 #define SE_CONTEXT_RSA_WORD_QUAD_SHIFT 12
#define SE_CONTEXT_RSA_WORD_QUAD(x) \ #define SE_CONTEXT_RSA_WORD_QUAD(x) \
(x << SE_CONTEXT_RSA_WORD_QUAD_SHIFT) ((x) << SE_CONTEXT_RSA_WORD_QUAD_SHIFT)
#define SE_CTX_SAVE_AUTO 0x074
#define CTX_SAVE_AUTO_ENABLE BIT(0)
#define CTX_SAVE_AUTO_LOCK BIT(8)
#define CTX_SAVE_AUTO_CURR_CNT_MASK (0x3FF << 16)
#define SE_INT_ENABLE_REG_OFFSET 0x00c #define SE_INT_ENABLE_REG_OFFSET 0x00c
#define SE_INT_STATUS_REG_OFFSET 0x010 #define SE_INT_STATUS_REG_OFFSET 0x010
@ -210,9 +215,9 @@
#define INT_UNSET 0 #define INT_UNSET 0
#define INT_SET 1 #define INT_SET 1
#define SE_INT_OP_DONE_SHIFT 4 #define SE_INT_OP_DONE_SHIFT 4
#define SE_INT_OP_DONE(x) (x << SE_INT_OP_DONE_SHIFT) #define SE_INT_OP_DONE(x) ((x) << SE_INT_OP_DONE_SHIFT)
#define SE_INT_ERROR_SHIFT 16 #define SE_INT_ERROR_SHIFT 16
#define SE_INT_ERROR(x) (x << SE_INT_ERROR_SHIFT) #define SE_INT_ERROR(x) ((x) << SE_INT_ERROR_SHIFT)
#define SE_STATUS_0 0x800 #define SE_STATUS_0 0x800
#define SE_STATUS_0_STATE_WAIT_IN 3 #define SE_STATUS_0_STATE_WAIT_IN 3
@ -223,10 +228,10 @@
#define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET 0X330 #define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET 0X330
#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT 0 #define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT 0
#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD(x) \ #define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD(x) \
(x << SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT) ((x) << SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT)
#define SE_KEY_INDEX_SHIFT 8 #define SE_KEY_INDEX_SHIFT 8
#define SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(x) (x << SE_KEY_INDEX_SHIFT) #define SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(x) ((x) << SE_KEY_INDEX_SHIFT)
#define SE_IN_LL_ADDR_REG_OFFSET 0x018 #define SE_IN_LL_ADDR_REG_OFFSET 0x018
#define SE_OUT_LL_ADDR_REG_OFFSET 0x024 #define SE_OUT_LL_ADDR_REG_OFFSET 0x024
@ -260,6 +265,10 @@
#define TEGRA_SE_AES_MIN_KEY_SIZE 16 #define TEGRA_SE_AES_MIN_KEY_SIZE 16
#define TEGRA_SE_AES_MAX_KEY_SIZE 32 #define TEGRA_SE_AES_MAX_KEY_SIZE 32
#define TEGRA_SE_AES_IV_SIZE 16 #define TEGRA_SE_AES_IV_SIZE 16
#define TEGRA_SE_SHA_512_SIZE 64
#define TEGRA_SE_SHA_384_SIZE 48
#define TEGRA_SE_SHA_256_SIZE 32
#define TEGRA_SE_SHA_192_SIZE 24
#define TEGRA_SE_RNG_IV_SIZE 16 #define TEGRA_SE_RNG_IV_SIZE 16
#define TEGRA_SE_RNG_DT_SIZE 16 #define TEGRA_SE_RNG_DT_SIZE 16
#define TEGRA_SE_RNG_KEY_SIZE 16 #define TEGRA_SE_RNG_KEY_SIZE 16
@ -277,13 +286,13 @@
#define SE_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80 #define SE_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80
#define SE_KEY_TABLE_ACCESS_REG_OFFSET 0x284 #define SE_KEY_TABLE_ACCESS_REG_OFFSET 0x284
#define SE_KEY_TBL_DIS_KEYREAD_FLAG (1 << 0) #define SE_KEY_TBL_DIS_KEYREAD_FLAG BIT(0)
#define SE_KEY_TBL_DIS_KEYUPDATE_FLAG (1 << 1) #define SE_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1)
#define SE_KEY_TBL_DIS_OIVREAD_FLAG (1 << 2) #define SE_KEY_TBL_DIS_OIVREAD_FLAG BIT(2)
#define SE_KEY_TBL_DIS_OIVUPDATE_FLAG (1 << 3) #define SE_KEY_TBL_DIS_OIVUPDATE_FLAG BIT(3)
#define SE_KEY_TBL_DIS_UIVREAD_FLAG (1 << 4) #define SE_KEY_TBL_DIS_UIVREAD_FLAG BIT(4)
#define SE_KEY_TBL_DIS_UIVUPDATE_FLAG (1 << 5) #define SE_KEY_TBL_DIS_UIVUPDATE_FLAG BIT(5)
#define SE_KEY_TBL_DIS_KEYUSE_FLAG (1 << 6) #define SE_KEY_TBL_DIS_KEYUSE_FLAG BIT(6)
#define SE_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F #define SE_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F
#define SE_KEY_READ_DISABLE_SHIFT 0 #define SE_KEY_READ_DISABLE_SHIFT 0
@ -340,11 +349,11 @@
#define SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80 #define SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80
#define SE_RSA_KEYTABLE_ACCESS_REG_OFFSET 0x410 #define SE_RSA_KEYTABLE_ACCESS_REG_OFFSET 0x410
#define SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG (1 << 0) #define SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG BIT(0)
#define SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG (1 << 1) #define SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG BIT(1)
#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG) #define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG)
#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG (1 << 2) #define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG BIT(2)
#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT (1 << 2) #define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT BIT(2)
#define SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG 7 #define SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG 7
#define SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG 0x7F #define SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG 0x7F
@ -355,37 +364,37 @@
#define RSA_KEY_READ 0 #define RSA_KEY_READ 0
#define RSA_KEY_WRITE 1 #define RSA_KEY_WRITE 1
#define SE_RSA_KEY_OP_SHIFT 10 #define SE_RSA_KEY_OP_SHIFT 10
#define SE_RSA_KEY_OP(x) (x << SE_RSA_KEY_OP_SHIFT) #define SE_RSA_KEY_OP(x) ((x) << SE_RSA_KEY_OP_SHIFT)
#define RSA_KEY_INPUT_MODE_REG 0 #define RSA_KEY_INPUT_MODE_REG 0
#define RSA_KEY_INPUT_MODE_DMA 1 #define RSA_KEY_INPUT_MODE_DMA 1
#define RSA_KEY_INPUT_MODE_SHIFT 8 #define RSA_KEY_INPUT_MODE_SHIFT 8
#define RSA_KEY_INPUT_MODE(x) (x << RSA_KEY_INPUT_MODE_SHIFT) #define RSA_KEY_INPUT_MODE(x) ((x) << RSA_KEY_INPUT_MODE_SHIFT)
#define RSA_KEY_SLOT_ONE 0 #define RSA_KEY_SLOT_ONE 0
#define RSA_KEY_SLOT_TW0 1 #define RSA_KEY_SLOT_TW0 1
#define RSA_KEY_NUM_SHIFT 7 #define RSA_KEY_NUM_SHIFT 7
#define RSA_KEY_NUM(x) (x << RSA_KEY_NUM_SHIFT) #define RSA_KEY_NUM(x) ((x) << RSA_KEY_NUM_SHIFT)
#define RSA_KEY_TYPE_EXP 0 #define RSA_KEY_TYPE_EXP 0
#define RSA_KEY_TYPE_MOD 1 #define RSA_KEY_TYPE_MOD 1
#define RSA_KEY_TYPE_SHIFT 6 #define RSA_KEY_TYPE_SHIFT 6
#define RSA_KEY_TYPE(x) (x << RSA_KEY_TYPE_SHIFT) #define RSA_KEY_TYPE(x) ((x) << RSA_KEY_TYPE_SHIFT)
#define SE_RSA_KEY_SIZE_REG_OFFSET 0x404 #define SE_RSA_KEY_SIZE_REG_OFFSET 0x404
#define SE_RSA_EXP_SIZE_REG_OFFSET 0x408 #define SE_RSA_EXP_SIZE_REG_OFFSET 0x408
#define RSA_KEY_SLOT_SHIFT 24 #define RSA_KEY_SLOT_SHIFT 24
#define RSA_KEY_SLOT(x) (x << RSA_KEY_SLOT_SHIFT) #define RSA_KEY_SLOT(x) ((x) << RSA_KEY_SLOT_SHIFT)
#define SE_RSA_CONFIG 0x400 #define SE_RSA_CONFIG 0x400
#define RSA_KEY_PKT_WORD_ADDR_SHIFT 0 #define RSA_KEY_PKT_WORD_ADDR_SHIFT 0
#define RSA_KEY_PKT_WORD_ADDR(x) (x << RSA_KEY_PKT_WORD_ADDR_SHIFT) #define RSA_KEY_PKT_WORD_ADDR(x) ((x) << RSA_KEY_PKT_WORD_ADDR_SHIFT)
#define RSA_KEY_WORD_ADDR_SHIFT 0 #define RSA_KEY_WORD_ADDR_SHIFT 0
#define RSA_KEY_WORD_ADDR(x) (x << RSA_KEY_WORD_ADDR_SHIFT) #define RSA_KEY_WORD_ADDR(x) ((x) << RSA_KEY_WORD_ADDR_SHIFT)
#define SE_RSA_KEYTABLE_PKT_SHIFT 0 #define SE_RSA_KEYTABLE_PKT_SHIFT 0
#define SE_RSA_KEYTABLE_PKT(x) (x << SE_RSA_KEYTABLE_PKT_SHIFT) #define SE_RSA_KEYTABLE_PKT(x) ((x) << SE_RSA_KEYTABLE_PKT_SHIFT)
#endif /* _CRYPTO_TEGRA_SE_H */ #endif /* _CRYPTO_TEGRA_SE_H */

View File

@ -20,30 +20,30 @@
#define TSEC_BOOTKEYVER 0x1040 #define TSEC_BOOTKEYVER 0x1040
#define TSEC_STATUS 0x1044 #define TSEC_STATUS 0x1044
#define TSEC_ITFEN 0x1048 #define TSEC_ITFEN 0x1048
#define TSEC_ITFEN_CTXEN (1 << 0) #define TSEC_ITFEN_CTXEN BIT(0)
#define TSEC_ITFEN_MTHDEN (1 << 1) #define TSEC_ITFEN_MTHDEN BIT(1)
#define TSEC_IRQMSET 0x1010 #define TSEC_IRQMSET 0x1010
#define TSEC_IRQMSET_WDTMR (1 << 1) #define TSEC_IRQMSET_WDTMR BIT(1)
#define TSEC_IRQMSET_HALT (1 << 4) #define TSEC_IRQMSET_HALT BIT(4)
#define TSEC_IRQMSET_EXTERR (1 << 5) #define TSEC_IRQMSET_EXTERR BIT(5)
#define TSEC_IRQMSET_SWGEN0 (1 << 6) #define TSEC_IRQMSET_SWGEN0 BIT(6)
#define TSEC_IRQMSET_SWGEN1 (1 << 7) #define TSEC_IRQMSET_SWGEN1 BIT(7)
#define TSEC_IRQMSET_EXT(val) (((val) & 0xFF) << 8) #define TSEC_IRQMSET_EXT(val) (((val) & 0xFF) << 8)
#define TSEC_IRQDEST 0x101C #define TSEC_IRQDEST 0x101C
#define TSEC_IRQDEST_HALT (1 << 4) #define TSEC_IRQDEST_HALT BIT(4)
#define TSEC_IRQDEST_EXTERR (1 << 5) #define TSEC_IRQDEST_EXTERR BIT(5)
#define TSEC_IRQDEST_SWGEN0 (1 << 6) #define TSEC_IRQDEST_SWGEN0 BIT(6)
#define TSEC_IRQDEST_SWGEN1 (1 << 7) #define TSEC_IRQDEST_SWGEN1 BIT(7)
#define TSEC_IRQDEST_EXT(val) (((val) & 0xFF) << 8) #define TSEC_IRQDEST_EXT(val) (((val) & 0xFF) << 8)
#define TSEC_CPUCTL 0x1100 #define TSEC_CPUCTL 0x1100
#define TSEC_CPUCTL_STARTCPU (1 << 1) #define TSEC_CPUCTL_STARTCPU BIT(1)
#define TSEC_BOOTVEC 0x1104 #define TSEC_BOOTVEC 0x1104
#define TSEC_DMACTL 0x110C #define TSEC_DMACTL 0x110C
#define TSEC_DMATRFBASE 0x1110 #define TSEC_DMATRFBASE 0x1110
#define TSEC_DMATRFMOFFS 0x1114 #define TSEC_DMATRFMOFFS 0x1114
#define TSEC_DMATRFCMD 0x1118 #define TSEC_DMATRFCMD 0x1118
#define TSEC_DMATRFCMD_IDLE (1 << 1) #define TSEC_DMATRFCMD_IDLE BIT(1)
#define TSEC_DMATRFCMD_IMEM (1 << 4) #define TSEC_DMATRFCMD_IMEM BIT(4)
#define TSEC_DMATRFCMD_SIZE_256B (6 << 8) #define TSEC_DMATRFCMD_SIZE_256B (6 << 8)
#define TSEC_DMATRFFBOFFS 0x111C #define TSEC_DMATRFFBOFFS 0x111C

View File

@ -25,38 +25,38 @@
#define BPMP_MMU_CACHE_LINE_SIZE 0x20 #define BPMP_MMU_CACHE_LINE_SIZE 0x20
#define BPMP_CACHE_CONFIG 0x0 #define BPMP_CACHE_CONFIG 0x0
#define CFG_ENABLE_CACHE (1 << 0) #define CFG_ENABLE_CACHE BIT(0)
#define CFG_ENABLE_SKEW_ASSOC (1 << 1) #define CFG_ENABLE_SKEW_ASSOC BIT(1)
#define CFG_DISABLE_RANDOM_ALLOC (1 << 2) #define CFG_DISABLE_RANDOM_ALLOC BIT(2)
#define CFG_FORCE_WRITE_THROUGH (1 << 3) #define CFG_FORCE_WRITE_THROUGH BIT(3)
#define CFG_NEVER_ALLOCATE (1 << 6) #define CFG_NEVER_ALLOCATE BIT(6)
#define CFG_ENABLE_INTERRUPT (1 << 7) #define CFG_ENABLE_INTERRUPT BIT(7)
#define CFG_MMU_TAG_MODE(x) (x << 8) #define CFG_MMU_TAG_MODE(x) ((x) << 8)
#define TAG_MODE_PARALLEL 0 #define TAG_MODE_PARALLEL 0
#define TAG_MODE_TAG_FIRST 1 #define TAG_MODE_TAG_FIRST 1
#define TAG_MODE_MMU_FIRST 2 #define TAG_MODE_MMU_FIRST 2
#define CFG_DISABLE_WRITE_BUFFER (1 << 10) #define CFG_DISABLE_WRITE_BUFFER BIT(10)
#define CFG_DISABLE_READ_BUFFER (1 << 11) #define CFG_DISABLE_READ_BUFFER BIT(11)
#define CFG_ENABLE_HANG_DETECT (1 << 12) #define CFG_ENABLE_HANG_DETECT BIT(12)
#define CFG_FULL_LINE_DIRTY (1 << 13) #define CFG_FULL_LINE_DIRTY BIT(13)
#define CFG_TAG_CHK_ABRT_ON_ERR (1 << 14) #define CFG_TAG_CHK_ABRT_ON_ERR BIT(14)
#define CFG_TAG_CHK_CLR_ERR (1 << 15) #define CFG_TAG_CHK_CLR_ERR BIT(15)
#define CFG_DISABLE_SAMELINE (1 << 16) #define CFG_DISABLE_SAMELINE BIT(16)
#define CFG_OBS_BUS_EN (1 << 31) #define CFG_OBS_BUS_EN BIT(31)
#define BPMP_CACHE_LOCK 0x4 #define BPMP_CACHE_LOCK 0x4
#define LOCK_LINE(x) (1 << x) #define LOCK_LINE(x) BIT((x))
#define BPMP_CACHE_SIZE 0xC #define BPMP_CACHE_SIZE 0xC
#define BPMP_CACHE_LFSR 0x10 #define BPMP_CACHE_LFSR 0x10
#define BPMP_CACHE_TAG_STATUS 0x14 #define BPMP_CACHE_TAG_STATUS 0x14
#define TAG_STATUS_TAG_CHECK_ERROR (1 << 0) #define TAG_STATUS_TAG_CHECK_ERROR BIT(0)
#define TAG_STATUS_CONFLICT_ADDR_MASK 0xFFFFFFE0 #define TAG_STATUS_CONFLICT_ADDR_MASK 0xFFFFFFE0
#define BPMP_CACHE_CLKEN_OVERRIDE 0x18 #define BPMP_CACHE_CLKEN_OVERRIDE 0x18
#define CLKEN_OVERRIDE_WR_MCCIF_CLKEN (1 << 0) #define CLKEN_OVERRIDE_WR_MCCIF_CLKEN BIT(0)
#define CLKEN_OVERRIDE_RD_MCCIF_CLKEN (1 << 1) #define CLKEN_OVERRIDE_RD_MCCIF_CLKEN BIT(1)
#define BPMP_CACHE_MAINT_ADDR 0x20 #define BPMP_CACHE_MAINT_ADDR 0x20
#define BPMP_CACHE_MAINT_DATA 0x24 #define BPMP_CACHE_MAINT_DATA 0x24
@ -68,8 +68,8 @@
#define BPMP_CACHE_INT_CLEAR 0x44 #define BPMP_CACHE_INT_CLEAR 0x44
#define BPMP_CACHE_INT_RAW_EVENT 0x48 #define BPMP_CACHE_INT_RAW_EVENT 0x48
#define BPMP_CACHE_INT_STATUS 0x4C #define BPMP_CACHE_INT_STATUS 0x4C
#define INT_MAINT_DONE (1 << 0) #define INT_MAINT_DONE BIT(0)
#define INT_MAINT_ERROR (1 << 1) #define INT_MAINT_ERROR BIT(1)
#define BPMP_CACHE_RB_CFG 0x80 #define BPMP_CACHE_RB_CFG 0x80
#define BPMP_CACHE_WB_CFG 0x84 #define BPMP_CACHE_WB_CFG 0x84
@ -78,12 +78,12 @@
#define BPMP_CACHE_MMU_SHADOW_COPY_MASK 0xA4 #define BPMP_CACHE_MMU_SHADOW_COPY_MASK 0xA4
#define BPMP_CACHE_MMU_CFG 0xAC #define BPMP_CACHE_MMU_CFG 0xAC
#define MMU_CFG_BLOCK_MAIN_ENTRY_WR (1 << 0) #define MMU_CFG_BLOCK_MAIN_ENTRY_WR BIT(0)
#define MMU_CFG_SEQ_EN (1 << 1) #define MMU_CFG_SEQ_EN BIT(1)
#define MMU_CFG_TLB_EN (1 << 2) #define MMU_CFG_TLB_EN BIT(2)
#define MMU_CFG_SEG_CHECK_ALL_ENTRIES (1 << 3) #define MMU_CFG_SEG_CHECK_ALL_ENTRIES BIT(3)
#define MMU_CFG_ABORT_STORE_LAST (1 << 4) #define MMU_CFG_ABORT_STORE_LAST BIT(4)
#define MMU_CFG_CLR_ABORT (1 << 5) #define MMU_CFG_CLR_ABORT BIT(5)
#define BPMP_CACHE_MMU_CMD 0xB0 #define BPMP_CACHE_MMU_CMD 0xB0
#define MMU_CMD_NOP 0 #define MMU_CMD_NOP 0
@ -98,25 +98,25 @@
#define ABORT_STAT_UNIT_TLB 3 #define ABORT_STAT_UNIT_TLB 3
#define ABORT_STAT_UNIT_SEG 4 #define ABORT_STAT_UNIT_SEG 4
#define ABORT_STAT_UNIT_FALLBACK 5 #define ABORT_STAT_UNIT_FALLBACK 5
#define ABORT_STAT_OVERLAP (1 << 3) #define ABORT_STAT_OVERLAP BIT(3)
#define ABORT_STAT_ENTRY (0x1F << 4) #define ABORT_STAT_ENTRY (0x1F << 4)
#define ABORT_STAT_TYPE_MASK (3 << 16) #define ABORT_STAT_TYPE_MASK (3 << 16)
#define ABORT_STAT_TYPE_EXE (0 << 16) #define ABORT_STAT_TYPE_EXE (0 << 16)
#define ABORT_STAT_TYPE_RD (1 << 16) #define ABORT_STAT_TYPE_RD (1 << 16)
#define ABORT_STAT_TYPE_WR (2 << 16) #define ABORT_STAT_TYPE_WR (2 << 16)
#define ABORT_STAT_SIZE (3 << 18) #define ABORT_STAT_SIZE (3 << 18)
#define ABORT_STAT_SEQ (1 << 20) #define ABORT_STAT_SEQ BIT(20)
#define ABORT_STAT_PROT (1 << 21) #define ABORT_STAT_PROT BIT(21)
#define BPMP_CACHE_MMU_ABORT_ADDR 0xB8 #define BPMP_CACHE_MMU_ABORT_ADDR 0xB8
#define BPMP_CACHE_MMU_ACTIVE_ENTRIES 0xBC #define BPMP_CACHE_MMU_ACTIVE_ENTRIES 0xBC
#define BPMP_MMU_SHADOW_ENTRY_BASE (BPMP_CACHE_BASE + 0x400) #define BPMP_MMU_SHADOW_ENTRY_BASE (BPMP_CACHE_BASE + 0x400)
#define BPMP_MMU_MAIN_ENTRY_BASE (BPMP_CACHE_BASE + 0x800) #define BPMP_MMU_MAIN_ENTRY_BASE (BPMP_CACHE_BASE + 0x800)
#define MMU_EN_CACHED (1 << 0) #define MMU_EN_CACHED BIT(0)
#define MMU_EN_EXEC (1 << 1) #define MMU_EN_EXEC BIT(1)
#define MMU_EN_READ (1 << 2) #define MMU_EN_READ BIT(2)
#define MMU_EN_WRITE (1 << 3) #define MMU_EN_WRITE BIT(3)
bpmp_mmu_entry_t mmu_entries[] = bpmp_mmu_entry_t mmu_entries[] =
{ {
@ -153,7 +153,7 @@ void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply)
mmu_entry->end_addr = ALIGN_DOWN(entry->end_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->attr = entry->attr;
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) |= (1 << idx); BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) |= BIT(idx);
if (apply) if (apply)
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_COPY_SHADOW; BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_COPY_SHADOW;
@ -172,7 +172,7 @@ void bpmp_mmu_enable()
// Init BPMP MMU entries. // Init BPMP MMU entries.
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) = 0; BPMP_CACHE_CTRL(BPMP_CACHE_MMU_SHADOW_COPY_MASK) = 0;
for (u32 idx = 0; idx < (sizeof(mmu_entries) / sizeof(bpmp_mmu_entry_t)); idx++) for (u32 idx = 0; idx < ARRAY_SIZE(mmu_entries); idx++)
bpmp_mmu_set_entry(idx, &mmu_entries[idx], false); bpmp_mmu_set_entry(idx, &mmu_entries[idx], false);
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_COPY_SHADOW; BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_COPY_SHADOW;

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -15,18 +16,21 @@
*/ */
#include <soc/ccplex.h> #include <soc/ccplex.h>
#include <soc/fuse.h>
#include <soc/hw_init.h>
#include <soc/i2c.h> #include <soc/i2c.h>
#include <soc/clock.h> #include <soc/clock.h>
#include <utils/util.h>
#include <soc/pmc.h> #include <soc/pmc.h>
#include <soc/t210.h> #include <soc/t210.h>
#include <power/max77620.h> #include <power/max77620.h>
#include <power/max7762x.h> #include <power/max7762x.h>
#include <power/max77812.h>
#include <utils/util.h>
void _ccplex_enable_power() void _ccplex_enable_power_t210()
{ {
u8 tmp = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO); // Get current pinmuxing u8 tmp = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO); // Get current pinmuxing
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO, tmp & ~(1 << 5)); // Disable GPIO5 pinmuxing. i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_AME_GPIO, tmp & ~BIT(5)); // Disable GPIO5 pinmuxing.
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, MAX77620_CNFG_GPIO_DRV_PUSHPULL | MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH); i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, MAX77620_CNFG_GPIO_DRV_PUSHPULL | MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH);
// Enable cores power. // Enable cores power.
@ -40,37 +44,12 @@ void _ccplex_enable_power()
i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVS_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_0_95V); i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVS_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_0_95V);
} }
int _ccplex_pmc_enable_partition(u32 part, int enable) void _ccplex_enable_power_t210b01()
{ {
u32 part_mask = 1 << part; u8 pmic_cpu_addr = !(FUSE(FUSE_RESERVED_ODM28) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR;
u32 desired_state = enable << part; u8 tmp = i2c_recv_byte(I2C_5, pmic_cpu_addr, MAX77812_REG_EN_CTRL);
i2c_send_byte(I2C_5, pmic_cpu_addr, MAX77812_REG_EN_CTRL, tmp | MAX77812_EN_CTRL_EN_M4);
// Check if the partition has the state we want. i2c_send_byte(I2C_5, pmic_cpu_addr, MAX77812_REG_M4_VOUT, MAX77812_M4_VOUT_0_80V);
if ((PMC(APBDEV_PMC_PWRGATE_STATUS) & part_mask) == desired_state)
return 1;
u32 i = 5001;
while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100)
{
usleep(1);
i--;
if (i < 1)
return 0;
}
// Toggle power gating.
PMC(APBDEV_PMC_PWRGATE_TOGGLE) = part | 0x100;
i = 5001;
while (i > 0)
{
if ((PMC(APBDEV_PMC_PWRGATE_STATUS) & part_mask) == desired_state)
break;
usleep(1);
i--;
}
return 1;
} }
void ccplex_boot_cpu0(u32 entry) void ccplex_boot_cpu0(u32 entry)
@ -78,7 +57,10 @@ void ccplex_boot_cpu0(u32 entry)
// Set ACTIVE_CLUSER to FAST. // Set ACTIVE_CLUSER to FAST.
FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE; FLOW_CTLR(FLOW_CTLR_BPMP_CLUSTER_CONTROL) &= 0xFFFFFFFE;
_ccplex_enable_power(); if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
_ccplex_enable_power_t210();
else
_ccplex_enable_power_t210b01();
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x40000000)) // PLLX_ENABLE. if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x40000000)) // PLLX_ENABLE.
{ {
@ -94,12 +76,12 @@ void ccplex_boot_cpu0(u32 entry)
// Configure MSELECT source and enable clock. // Configure MSELECT source and enable clock.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6; CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT) & 0x1FFFFF00) | 6;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) & 0xFFFFFFF7) | 8; CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) & ~BIT(CLK_V_MSELECT)) | BIT(CLK_V_MSELECT);
// Configure initial CPU clock frequency and enable clock. // Configure initial CPU clock frequency and enable clock.
CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888; CLOCK(CLK_RST_CONTROLLER_CCLK_BURST_POLICY) = 0x20008888;
CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000; CLOCK(CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER) = 0x80000000;
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = 1; CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_CPUG);
clock_enable_coresight(); clock_enable_coresight();
@ -107,11 +89,11 @@ void ccplex_boot_cpu0(u32 entry)
CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000; CLOCK(CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2) &= 0xFFFFF000;
// Enable CPU rail. // Enable CPU rail.
_ccplex_pmc_enable_partition(0, 1); pmc_enable_partition(0, 1);
// Enable cluster 0 non-CPU. // Enable cluster 0 non-CPU rail.
_ccplex_pmc_enable_partition(15, 1); pmc_enable_partition(15, 1);
// Enable CE0. // Enable CE0 rail.
_ccplex_pmc_enable_partition(14, 1); pmc_enable_partition(14, 1);
// Request and wait for RAM repair. // Request and wait for RAM repair.
FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1; FLOW_CTLR(FLOW_CTLR_RAM_REPAIR) = 1;
@ -131,7 +113,7 @@ void ccplex_boot_cpu0(u32 entry)
// MC(MC_TZ_SECURITY_CTRL) = 1; // MC(MC_TZ_SECURITY_CTRL) = 1;
// Clear MSELECT reset. // Clear MSELECT reset.
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= 0xFFFFFFF7; CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= ~BIT(CLK_V_MSELECT);
// Clear NONCPU reset. // Clear NONCPU reset.
CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000; CLOCK(CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR) = 0x20000000;
// Clear CPU0 reset. // Clear CPU0 reset.

View File

@ -16,110 +16,101 @@
*/ */
#include <soc/clock.h> #include <soc/clock.h>
#include <soc/hw_init.h>
#include <soc/t210.h> #include <soc/t210.h>
#include <storage/sdmmc.h> #include <storage/sdmmc.h>
#include <utils/util.h> #include <utils/util.h>
/*
* CLOCK Peripherals:
* L 0 - 31
* H 32 - 63
* U 64 - 95
* V 96 - 127
* W 128 - 159
* X 160 - 191
* Y 192 - 223
*/
/* clock_t: reset, enable, source, index, clk_src, clk_div */ /* clock_t: reset, enable, source, index, clk_src, clk_div */
static const clock_t _clock_uart[] = { static const clock_t _clock_uart[] = {
/* UART A */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, 6, 0, 2 }, { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, 2 },
/* UART B */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, 7, 0, 2 }, { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, 2 },
/* UART C */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, 23, 0, 2 }, { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, 2 },
/* UART D */ { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, 1, 0, 2 }, { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, 2 },
/* UART E */ { CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, 20, 0, 2 } { CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, 2 }
}; };
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26. //I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
static const clock_t _clock_i2c[] = { static const clock_t _clock_i2c[] = {
/* I2C1 */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, 12, 0, 19 }, //20.4MHz -> 100KHz { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, 19 }, //20.4MHz -> 100KHz
/* I2C2 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, 22, 0, 4 }, //81.6MHz -> 400KHz { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, 4 }, //81.6MHz -> 400KHz
/* I2C3 */ { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, 3, 0, 4 }, //81.6MHz -> 400KHz { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, 4 }, //81.6MHz -> 400KHz
/* I2C4 */ { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, 7, 0, 19 }, //20.4MHz -> 100KHz { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, 19 }, //20.4MHz -> 100KHz
/* I2C5 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, 15, 0, 4 }, //81.6MHz -> 400KHz { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, 4 }, //81.6MHz -> 400KHz
/* I2C6 */ { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, 6, 0, 19 } //20.4MHz -> 100KHz { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, 19 } //20.4MHz -> 100KHz
}; };
static clock_t _clock_se = { static clock_t _clock_se = {
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, 31, 0, 0 CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, 0
}; };
static clock_t _clock_tzram = { static clock_t _clock_tzram = {
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, 30, 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 = { static clock_t _clock_host1x = {
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, 28, 4, 3 CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, 3
}; };
static clock_t _clock_tsec = { static clock_t _clock_tsec = {
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, 19, 0, 2 CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, 2
}; };
static clock_t _clock_sor_safe = { static clock_t _clock_sor_safe = {
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, 30, 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 = { static clock_t _clock_sor0 = {
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NO_SOURCE, 22, 0, 0 CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NO_SOURCE, CLK_X_SOR0, 0, 0
}; };
static clock_t _clock_sor1 = { static clock_t _clock_sor1 = {
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, 23, 0, 2 CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, 2
}; };
static clock_t _clock_kfuse = { static clock_t _clock_kfuse = {
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, 8, 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 = { static clock_t _clock_cl_dvfs = {
CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, 27, 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 = { static clock_t _clock_coresight = {
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, 9, 0, 4 CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, 4
}; };
static clock_t _clock_pwm = { static clock_t _clock_pwm = {
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, 17, 6, 4 // Fref: 6.2MHz. 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. Stock PLLP / 54: 7.55MHz.
}; };
static clock_t _clock_sdmmc_legacy_tm = { 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, 1, 4, 66 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
}; };
void clock_enable(const clock_t *clk) void clock_enable(const clock_t *clk)
{ {
// Put clock into reset. // Put clock into reset.
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~(1 << clk->index)) | (1 << clk->index); CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
// Disable. // Disable.
CLOCK(clk->enable) &= ~(1 << clk->index); CLOCK(clk->enable) &= ~BIT(clk->index);
// Configure clock source if required. // Configure clock source if required.
if (clk->source) if (clk->source)
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29); CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
// Enable. // Enable.
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~(1 << clk->index)) | (1 << clk->index); CLOCK(clk->enable) = (CLOCK(clk->enable) & ~BIT(clk->index)) | BIT(clk->index);
usleep(2); usleep(2);
// Take clock off reset. // Take clock off reset.
CLOCK(clk->reset) &= ~(1 << clk->index); CLOCK(clk->reset) &= ~BIT(clk->index);
} }
void clock_disable(const clock_t *clk) void clock_disable(const clock_t *clk)
{ {
// Put clock into reset. // Put clock into reset.
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~(1 << clk->index)) | (1 << clk->index); CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
// Disable. // Disable.
CLOCK(clk->enable) &= ~(1 << clk->index); CLOCK(clk->enable) &= ~BIT(clk->index);
} }
void clock_enable_fuse(bool enable) void clock_enable_fuse(bool enable)
{ {
// Enable Fuse registers visibility.
CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) = (CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) & 0xEFFFFFFF) | ((enable & 1) << 28); CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) = (CLOCK(CLK_RST_CONTROLLER_MISC_CLK_ENB) & 0xEFFFFFFF) | ((enable & 1) << 28);
} }
@ -133,7 +124,7 @@ void clock_disable_uart(u32 idx)
clock_disable(&_clock_uart[idx]); clock_disable(&_clock_uart[idx]);
} }
#define UART_SRC_CLK_DIV_EN (1 << 24) #define UART_SRC_CLK_DIV_EN BIT(24)
int clock_uart_use_src_div(u32 idx, u32 baud) int clock_uart_use_src_div(u32 idx, u32 baud)
{ {
@ -164,6 +155,10 @@ void clock_disable_i2c(u32 idx)
void clock_enable_se() void clock_enable_se()
{ {
clock_enable(&_clock_se); clock_enable(&_clock_se);
// Lock clock to always enabled if T210B01.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SE) |= 0x100;
} }
void clock_enable_tzram() void clock_enable_tzram()
@ -223,12 +218,12 @@ void clock_disable_sor1()
void clock_enable_kfuse() void clock_enable_kfuse()
{ {
//clock_enable(&_clock_kfuse); u32 kfuse_clk_unmask = ~BIT(CLK_H_KFUSE);
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) = (CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) & 0xFFFFFEFF) | 0x100; CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) = (CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) & kfuse_clk_unmask) | BIT(CLK_H_KFUSE);
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) &= 0xFFFFFEFF; CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) &= kfuse_clk_unmask;
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) & 0xFFFFFEFF) | 0x100; CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) & kfuse_clk_unmask) | BIT(CLK_H_KFUSE);
usleep(10); usleep(10);
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) &= 0xFFFFFEFF; CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) &= kfuse_clk_unmask;
usleep(20); usleep(20);
} }
@ -294,7 +289,7 @@ void clock_enable_pllc(u32 divn)
; ;
// Disable PLLC_OUT1, enable reset and set div to 1.5. // Disable PLLC_OUT1, enable reset and set div to 1.5.
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) = (1 << 8); CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) = BIT(8);
// Enable PLLC_OUT1 and bring it out of reset. // Enable PLLC_OUT1 and bring it out of reset.
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) |= (PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR); CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) |= (PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR);
@ -312,7 +307,7 @@ void clock_disable_pllc()
usleep(10); usleep(10);
} }
#define PLLC4_ENABLED (1 << 31) #define PLLC4_ENABLED BIT(31)
#define PLLC4_IN_USE (~PLLC4_ENABLED) #define PLLC4_IN_USE (~PLLC4_ENABLED)
u32 pllc4_enabled = 0; u32 pllc4_enabled = 0;
@ -362,48 +357,60 @@ static void _clock_disable_pllc4(u32 mask)
pllc4_enabled = 0; pllc4_enabled = 0;
} }
#define L_SWR_SDMMC1_RST (1 << 14) void clock_enable_pllu()
#define L_SWR_SDMMC2_RST (1 << 9) {
#define L_SWR_SDMMC4_RST (1 << 15) // Configure PLLU.
#define U_SWR_SDMMC3_RST (1 << 5) CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) |= BIT(29); // Disable reference clock.
u32 pllu_cfg = (CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & 0xFFE00000) | BIT(24) | (1 << 16) | (0x19 << 8) | 2;
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg;
CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) = pllu_cfg | PLLCX_BASE_ENABLE; // Enable.
#define L_CLK_ENB_SDMMC1 (1 << 14) // Wait for PLL to stabilize.
#define L_CLK_ENB_SDMMC2 (1 << 9) u32 timeout = (u32)TMR(TIMERUS_CNTR_1US) + 1300;
#define L_CLK_ENB_SDMMC4 (1 << 15) while (!(CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) & PLLCX_BASE_LOCK)) // PLL_LOCK.
#define U_CLK_ENB_SDMMC3 (1 << 5) if ((u32)TMR(TIMERUS_CNTR_1US) > timeout)
break;
usleep(10);
#define L_SET_SDMMC1_RST (1 << 14) // Enable PLLU USB/HSIC/ICUSB/48M.
#define L_SET_SDMMC2_RST (1 << 9) CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) |= 0x2E00000;
#define L_SET_SDMMC4_RST (1 << 15) }
#define U_SET_SDMMC3_RST (1 << 5)
#define L_CLR_SDMMC1_RST (1 << 14) void clock_disable_pllu()
#define L_CLR_SDMMC2_RST (1 << 9) {
#define L_CLR_SDMMC4_RST (1 << 15) CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x2E00000; // Disable PLLU USB/HSIC/ICUSB/48M.
#define U_CLR_SDMMC3_RST (1 << 5) CLOCK(CLK_RST_CONTROLLER_PLLU_BASE) &= ~0x40000000; // Disable PLLU.
CLOCK(CLK_RST_CONTROLLER_PLLU_MISC) &= ~0x20000000; // Enable reference clock.
}
#define L_SET_CLK_ENB_SDMMC1 (1 << 14) void clock_enable_utmipll()
#define L_SET_CLK_ENB_SDMMC2 (1 << 9) {
#define L_SET_CLK_ENB_SDMMC4 (1 << 15) // Set UTMIPLL dividers and config based on OSC and enable it to 960 MHz.
#define U_SET_CLK_ENB_SDMMC3 (1 << 5) CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG0) = (CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG0) & 0xFF0000FF) | (25 << 16) | (1 << 8); // 38.4Mhz * (25 / 1) = 960 MHz.
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) = (CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) & 0xFF00003F) | (24 << 18); // Set delay count for 38.4Mhz osc crystal.
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG1) = (CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG1) & 0x7FFA000) | (1 << 15) | 375;
#define L_CLR_CLK_ENB_SDMMC1 (1 << 14) // Wait for UTMIPLL to stabilize.
#define L_CLR_CLK_ENB_SDMMC2 (1 << 9) u32 retries = 10; // Wait 20us
#define L_CLR_CLK_ENB_SDMMC4 (1 << 15) while (!(CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) & UTMIPLL_LOCK) && retries)
#define U_CLR_CLK_ENB_SDMMC3 (1 << 5) {
usleep(1);
retries--;
}
}
static int _clock_sdmmc_is_reset(u32 id) static int _clock_sdmmc_is_reset(u32 id)
{ {
switch (id) switch (id)
{ {
case SDMMC_1: case SDMMC_1:
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC1_RST; return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC1);
case SDMMC_2: case SDMMC_2:
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC2_RST; return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC2);
case SDMMC_3: case SDMMC_3:
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_U) & U_SWR_SDMMC3_RST; return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_U) & BIT(CLK_U_SDMMC3);
case SDMMC_4: case SDMMC_4:
return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & L_SWR_SDMMC4_RST; return CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_L) & BIT(CLK_L_SDMMC4);
} }
return 0; return 0;
} }
@ -413,16 +420,16 @@ static void _clock_sdmmc_set_reset(u32 id)
switch (id) switch (id)
{ {
case SDMMC_1: case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC1_RST; CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC1);
break; break;
case SDMMC_2: case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC2_RST; CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC2);
break; break;
case SDMMC_3: case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = U_SET_SDMMC3_RST; CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_SET) = BIT(CLK_U_SDMMC3);
break; break;
case SDMMC_4: case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = L_SET_SDMMC4_RST; CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_SDMMC4);
break; break;
} }
} }
@ -432,16 +439,16 @@ static void _clock_sdmmc_clear_reset(u32 id)
switch (id) switch (id)
{ {
case SDMMC_1: case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC1_RST; CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC1);
break; break;
case SDMMC_2: case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC2_RST; CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC2);
break; break;
case SDMMC_3: case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_CLR) = U_CLR_SDMMC3_RST; CLOCK(CLK_RST_CONTROLLER_RST_DEV_U_CLR) = BIT(CLK_U_SDMMC3);
break; break;
case SDMMC_4: case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = L_CLR_SDMMC4_RST; CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_SDMMC4);
break; break;
} }
} }
@ -451,13 +458,13 @@ static int _clock_sdmmc_is_enabled(u32 id)
switch (id) switch (id)
{ {
case SDMMC_1: case SDMMC_1:
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC1; return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC1);
case SDMMC_2: case SDMMC_2:
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC2; return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC2);
case SDMMC_3: case SDMMC_3:
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) & U_CLK_ENB_SDMMC3; return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) & BIT(CLK_U_SDMMC3);
case SDMMC_4: case SDMMC_4:
return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & L_CLK_ENB_SDMMC4; return CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_SDMMC4);
} }
return 0; return 0;
} }
@ -467,16 +474,16 @@ static void _clock_sdmmc_set_enable(u32 id)
switch (id) switch (id)
{ {
case SDMMC_1: case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC1; CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC1);
break; break;
case SDMMC_2: case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC2; CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC2);
break; break;
case SDMMC_3: case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_SET) = U_SET_CLK_ENB_SDMMC3; CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_SET) = BIT(CLK_U_SDMMC3);
break; break;
case SDMMC_4: case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = L_SET_CLK_ENB_SDMMC4; CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_SDMMC4);
break; break;
} }
} }
@ -486,16 +493,16 @@ static void _clock_sdmmc_clear_enable(u32 id)
switch (id) switch (id)
{ {
case SDMMC_1: case SDMMC_1:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC1; CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC1);
break; break;
case SDMMC_2: case SDMMC_2:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC2; CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC2);
break; break;
case SDMMC_3: case SDMMC_3:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = U_CLR_CLK_ENB_SDMMC3; CLOCK(CLK_RST_CONTROLLER_CLK_ENB_U_CLR) = BIT(CLK_U_SDMMC3);
break; break;
case SDMMC_4: case SDMMC_4:
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = L_CLR_CLK_ENB_SDMMC4; CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_SDMMC4);
break; break;
} }
} }
@ -503,7 +510,7 @@ static void _clock_sdmmc_clear_enable(u32 id)
static void _clock_sdmmc_config_legacy_tm() static void _clock_sdmmc_config_legacy_tm()
{ {
clock_t *clk = &_clock_sdmmc_legacy_tm; clock_t *clk = &_clock_sdmmc_legacy_tm;
if (!(CLOCK(clk->enable) & (1 << clk->index))) if (!(CLOCK(clk->enable) & BIT(clk->index)))
clock_enable(clk); clock_enable(clk);
} }
@ -588,7 +595,7 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
// Enable PLLC4 if in use by any SDMMC. // Enable PLLC4 if in use by any SDMMC.
if (source) if (source)
_clock_enable_pllc4(1 << id); _clock_enable_pllc4(BIT(id));
// Set SDMMC legacy timeout clock. // Set SDMMC legacy timeout clock.
_clock_sdmmc_config_legacy_tm(); _clock_sdmmc_config_legacy_tm();
@ -680,7 +687,7 @@ void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type)
*pclock = 40800; *pclock = 40800;
*pdivisor = 1; *pdivisor = 1;
break; break;
case SDHCI_TIMING_MMC_DDR52: // Actual IO Freq: 49.92 MHz. case SDHCI_TIMING_MMC_HS102: // Actual IO Freq: 99.84 MHz.
*pclock = 200000; *pclock = 200000;
*pdivisor = 2; *pdivisor = 2;
break; break;
@ -712,5 +719,5 @@ void clock_sdmmc_disable(u32 id)
_clock_sdmmc_set_reset(id); _clock_sdmmc_set_reset(id);
_clock_sdmmc_clear_enable(id); _clock_sdmmc_clear_enable(id);
_clock_sdmmc_is_reset(id); _clock_sdmmc_is_reset(id);
_clock_disable_pllc4(1 << id); _clock_disable_pllc4(BIT(id));
} }

View File

@ -48,6 +48,7 @@
#define CLK_RST_CONTROLLER_PLLA_MISC1 0xB8 #define CLK_RST_CONTROLLER_PLLA_MISC1 0xB8
#define CLK_RST_CONTROLLER_PLLA_MISC 0xBC #define CLK_RST_CONTROLLER_PLLA_MISC 0xBC
#define CLK_RST_CONTROLLER_PLLU_BASE 0xC0 #define CLK_RST_CONTROLLER_PLLU_BASE 0xC0
#define CLK_RST_CONTROLLER_PLLU_OUTA 0xC4
#define CLK_RST_CONTROLLER_PLLU_MISC 0xCC #define CLK_RST_CONTROLLER_PLLU_MISC 0xCC
#define CLK_RST_CONTROLLER_PLLD_BASE 0xD0 #define CLK_RST_CONTROLLER_PLLD_BASE 0xD0
#define CLK_RST_CONTROLLER_PLLD_MISC1 0xD8 #define CLK_RST_CONTROLLER_PLLD_MISC1 0xD8
@ -131,6 +132,7 @@
#define CLK_RST_CONTROLLER_UTMIP_PLL_CFG2 0x488 #define CLK_RST_CONTROLLER_UTMIP_PLL_CFG2 0x488
#define CLK_RST_CONTROLLER_PLLE_AUX 0x48C #define CLK_RST_CONTROLLER_PLLE_AUX 0x48C
#define CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S0 0x4A0 #define CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S0 0x4A0
#define CLK_RST_CONTROLLER_UTMIP_PLL_CFG3 0x4C0
#define CLK_RST_CONTROLLER_PLLX_MISC_3 0x518 #define CLK_RST_CONTROLLER_PLLX_MISC_3 0x518
#define CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0 0x52C #define CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0 0x52C
#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE 0x554 #define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE 0x554
@ -140,6 +142,9 @@
#define CLK_RST_CONTROLLER_PLLC_MISC_2 0x5D0 #define CLK_RST_CONTROLLER_PLLC_MISC_2 0x5D0
#define CLK_RST_CONTROLLER_PLLC4_OUT 0x5E4 #define CLK_RST_CONTROLLER_PLLC4_OUT 0x5E4
#define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8 #define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_FS 0x608
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_CORE_DEV 0x60C
#define CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_SS 0x610
#define CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP 0x620 #define CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP 0x620
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 0x65C #define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 0x65C
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664 #define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664
@ -153,23 +158,288 @@
#define CLK_NO_SOURCE 0x0 #define CLK_NO_SOURCE 0x0
/*! PLL control and status bits */ /*! PLL control and status bits */
#define PLLCX_BASE_ENABLE (1 << 30) #define PLLCX_BASE_LOCK BIT(27)
#define PLLCX_BASE_REF_DIS (1 << 29) #define PLLCX_BASE_REF_DIS BIT(29)
#define PLLCX_BASE_LOCK (1 << 27) #define PLLCX_BASE_ENABLE BIT(30)
#define PLLA_BASE_IDDQ (1 << 25) #define PLLA_OUT0_RSTN_CLR BIT(0)
#define PLLA_OUT0_CLKEN (1 << 1) #define PLLA_OUT0_CLKEN BIT(1)
#define PLLA_OUT0_RSTN_CLR (1 << 0) #define PLLA_BASE_IDDQ BIT(25)
#define PLLC_MISC_RESET (1 << 30) #define PLLC_OUT1_RSTN_CLR BIT(0)
#define PLLC_MISC1_IDDQ (1 << 27) #define PLLC_OUT1_CLKEN BIT(1)
#define PLLC_OUT1_CLKEN (1 << 1) #define PLLC_MISC1_IDDQ BIT(27)
#define PLLC_OUT1_RSTN_CLR (1 << 0) #define PLLC_MISC_RESET BIT(30)
#define PLLC4_MISC_EN_LCKDET (1 << 30) #define PLLC4_OUT3_RSTN_CLR BIT(0)
#define PLLC4_BASE_IDDQ (1 << 18) #define PLLC4_OUT3_CLKEN BIT(1)
#define PLLC4_OUT3_CLKEN (1 << 1) #define PLLC4_BASE_IDDQ BIT(18)
#define PLLC4_OUT3_RSTN_CLR (1 << 0) #define PLLC4_MISC_EN_LCKDET BIT(30)
#define UTMIPLL_LOCK BIT(31)
/*
* CLOCK Peripherals:
* L 0 - 31
* H 32 - 63
* U 64 - 95
* V 96 - 127
* W 128 - 159
* X 160 - 191
* Y 192 - 223
*/
enum CLK_L_DEV
{
CLK_L_CPU = 0, // Only reset. Deprecated.
CLK_L_BPMP = 1, // Only reset.
CLK_L_SYS = 2, // Only reset.
CLK_L_ISPB = 3,
CLK_L_RTC = 4,
CLK_L_TMR = 5,
CLK_L_UARTA = 6,
CLK_L_UARTB = 7,
CLK_L_GPIO = 8,
CLK_L_SDMMC2 = 9,
CLK_L_SPDIF = 10,
CLK_L_I2S2 = 11, // I2S1
CLK_L_I2C1 = 12,
CLK_L_NDFLASH = 13, // HIDDEN.
CLK_L_SDMMC1 = 14,
CLK_L_SDMMC4 = 15,
CLK_L_TWC = 16, // HIDDEN.
CLK_L_PWM = 17,
CLK_L_I2S3 = 18,
CLK_L_EPP = 19, // HIDDEN.
CLK_L_VI = 20,
CLK_L_2D = 21, // HIDDEN.
CLK_L_USBD = 22,
CLK_L_ISP = 23,
CLK_L_3D = 24, // HIDDEN.
//CLK_L_ = 25,
CLK_L_DISP2 = 26,
CLK_L_DISP1 = 27,
CLK_L_HOST1X = 28,
CLK_L_VCP = 29, // HIDDEN.
CLK_L_I2S1 = 30, // I2S0
CLK_L_BPMP_CACHE_CTRL = 31, // CONTROLLER
};
enum CLK_H_DEV
{
CLK_H_MEM = 0, // MC.
CLK_H_AHBDMA = 1,
CLK_H_APBDMA = 2,
//CLK_H_ = 3,
CLK_H_KBC = 4, // HIDDEN.
CLK_H_STAT_MON = 5,
CLK_H_PMC = 6,
CLK_H_FUSE = 7,
CLK_H_KFUSE = 8,
CLK_H_SPI1 = 9,
CLK_H_SNOR = 10, // HIDDEN.
CLK_H_JTAG2TBC = 11,
CLK_H_SPI2 = 12,
CLK_H_XIO = 13, // HIDDEN.
CLK_H_SPI3 = 14,
CLK_H_I2C5 = 15,
CLK_H_DSI = 16,
//CLK_H_ = 17,
CLK_H_HSI = 18, // HIDDEN.
CLK_H_HDMI = 19, // HIDDEN.
CLK_H_CSI = 20,
//CLK_H_ = 21,
CLK_H_I2C2 = 22,
CLK_H_UARTC = 23,
CLK_H_MIPI_CAL = 24,
CLK_H_EMC = 25,
CLK_H_USB2 = 26,
CLK_H_USB3 = 27, // HIDDEN.
CLK_H_MPE = 28, // HIDDEN.
CLK_H_VDE = 29, // HIDDEN.
CLK_H_BSEA = 30, // HIDDEN.
CLK_H_BSEV = 31,
};
enum CLK_U_DEV
{
//CLK_U_ = 0,
CLK_U_UARTD = 1,
CLK_U_UARTE = 2, // HIDDEN.
CLK_U_I2C3 = 3,
CLK_U_SPI4 = 4,
CLK_U_SDMMC3 = 5,
CLK_U_PCIE = 6,
CLK_U_UNUSED = 7, // RESERVED
CLK_U_AFI = 8,
CLK_U_CSITE = 9,
CLK_U_PCIEXCLK = 10, // Only reset.
CLK_U_BPMPUCQ = 11, // HIDDEN.
CLK_U_LA = 12,
CLK_U_TRACECLKIN = 13, // HIDDEN.
CLK_U_SOC_THERM = 14,
CLK_U_DTV = 15,
CLK_U_NAND_SPEED = 16, // HIDDEN.
CLK_U_I2C_SLOW = 17,
CLK_U_DSIB = 18,
CLK_U_TSEC = 19,
CLK_U_IRAMA = 20,
CLK_U_IRAMB = 21,
CLK_U_IRAMC = 22,
CLK_U_IRAMD = 23, // EMUCIF ON RESET
CLK_U_BPMP_CACHE_RAM = 24,
CLK_U_XUSB_HOST = 25,
CLK_U_CLK_M_DOUBLER = 26,
CLK_U_MSENC = 27, // HIDDEN.
CLK_U_SUS_OUT = 28,
CLK_U_DEV2_OUT = 29,
CLK_U_DEV1_OUT = 30,
CLK_U_XUSB_DEV = 31,
};
enum CLK_V_DEV
{
CLK_V_CPUG = 0,
CLK_V_CPULP = 1, // Reserved.
CLK_V_3D2 = 2, // HIDDEN.
CLK_V_MSELECT = 3,
CLK_V_TSENSOR = 4,
CLK_V_I2S4 = 5,
CLK_V_I2S5 = 6,
CLK_V_I2C4 = 7,
CLK_V_SPI5 = 8, // HIDDEN.
CLK_V_SPI6 = 9, // HIDDEN.
CLK_V_AHUB = 10, // AUDIO.
CLK_V_APB2APE = 11, // APBIF.
CLK_V_DAM0 = 12, // HIDDEN.
CLK_V_DAM1 = 13, // HIDDEN.
CLK_V_DAM2 = 14, // HIDDEN.
CLK_V_HDA2CODEC_2X = 15,
CLK_V_ATOMICS = 16,
//CLK_V_ = 17,
//CLK_V_ = 18,
//CLK_V_ = 19,
//CLK_V_ = 20,
//CLK_V_ = 21,
CLK_V_SPDIF_DOUBLER = 22,
CLK_V_ACTMON = 23,
CLK_V_EXTPERIPH1 = 24,
CLK_V_EXTPERIPH2 = 25,
CLK_V_EXTPERIPH3 = 26,
CLK_V_SATA_OOB = 27,
CLK_V_SATA = 28,
CLK_V_HDA = 29,
CLK_V_TZRAM = 30, // HIDDEN.
CLK_V_SE = 31, // HIDDEN.
};
enum CLK_W_DEV
{
CLK_W_HDA2HDMICODEC = 0,
CLK_W_RESERVED0 = 1, //satacoldrstn
CLK_W_PCIERX0 = 2,
CLK_W_PCIERX1 = 3,
CLK_W_PCIERX2 = 4,
CLK_W_PCIERX3 = 5,
CLK_W_PCIERX4 = 6,
CLK_W_PCIERX5 = 7,
CLK_W_CEC = 8,
CLK_W_PCIE2_IOBIST = 9,
CLK_W_EMC_IOBIST = 10,
CLK_W_HDMI_IOBIST = 11, // HIDDEN.
CLK_W_SATA_IOBIST = 12,
CLK_W_MIPI_IOBIST = 13,
CLK_W_XUSB_PADCTL = 14, // Only reset.
CLK_W_XUSB = 15,
CLK_W_CILAB = 16,
CLK_W_CILCD = 17,
CLK_W_CILEF = 18,
CLK_W_DSIA_LP = 19,
CLK_W_DSIB_LP = 20,
CLK_W_ENTROPY = 21,
CLK_W_DDS = 22, // HIDDEN.
//CLK_W_ = 23,
CLK_W_DP2 = 24, // HIDDEN.
CLK_W_AMX0 = 25, // HIDDEN.
CLK_W_ADX0 = 26, // HIDDEN.
CLK_W_DVFS = 27,
CLK_W_XUSB_SS = 28,
CLK_W_EMC_LATENCY = 29,
CLK_W_MC1 = 30,
//CLK_W_ = 31,
};
enum CLK_X_DEV
{
CLK_X_SPARE = 0,
CLK_X_DMIC1 = 1,
CLK_X_DMIC2 = 2,
CLK_X_ETR = 3,
CLK_X_CAM_MCLK = 4,
CLK_X_CAM_MCLK2 = 5,
CLK_X_I2C6 = 6,
CLK_X_MC_CAPA = 7, // MC DAISY CHAIN1
CLK_X_MC_CBPA = 8, // MC DAISY CHAIN2
CLK_X_MC_CPU = 9,
CLK_X_MC_BBC = 10,
CLK_X_VIM2_CLK = 11,
//CLK_X_ = 12,
CLK_X_MIPIBIF = 13, //RESERVED
CLK_X_EMC_DLL = 14,
//CLK_X_ = 15,
CLK_X_HDMI_AUDIO = 16, // HIDDEN.
CLK_X_UART_FST_MIPI_CAL = 17,
CLK_X_VIC = 18,
//CLK_X_ = 19,
CLK_X_ADX1 = 20, // HIDDEN.
CLK_X_DPAUX = 21,
CLK_X_SOR0 = 22,
CLK_X_SOR1 = 23,
CLK_X_GPU = 24,
CLK_X_DBGAPB = 25,
CLK_X_HPLL_ADSP = 26,
CLK_X_PLLP_ADSP = 27,
CLK_X_PLLA_ADSP = 28,
CLK_X_PLLG_REF = 29,
//CLK_X_ = 30,
//CLK_X_ = 31,
};
enum CLK_Y_DEV
{
CLK_Y_SPARE1 = 0,
CLK_Y_SDMMC_LEGACY_TM = 1,
CLK_Y_NVDEC = 2,
CLK_Y_NVJPG = 3,
CLK_Y_AXIAP = 4,
CLK_Y_DMIC3 = 5,
CLK_Y_APE = 6,
CLK_Y_ADSP = 7,
CLK_Y_MC_CDPA = 8, // MC DAISY CHAIN4
CLK_Y_MC_CCPA = 9, // MC DAISY CHAIN3
CLK_Y_MAUD = 10,
//CLK_Y_ = 11,
CLK_Y_SATA_USB_UPHY = 12, // Only reset.
CLK_Y_PEX_USB_UPHY = 13, // Only reset.
CLK_Y_TSECB = 14,
CLK_Y_DPAUX1 = 15,
CLK_Y_VI_I2C = 16,
CLK_Y_HSIC_TRK = 17,
CLK_Y_USB2_TRK = 18,
CLK_Y_QSPI = 19,
CLK_Y_UARTAPE = 20,
CLK_Y_ADSPINTF = 21, // Only reset.
CLK_Y_ADSPPERIPH = 22, // Only reset.
CLK_Y_ADSPDBG = 23, // Only reset.
CLK_Y_ADSPWDT = 24, // Only reset.
CLK_Y_ADSPSCU = 25, // Only reset.
CLK_Y_ADSPNEON = 26,
CLK_Y_NVENC = 27,
CLK_Y_IQC2 = 28,
CLK_Y_IQC1 = 29,
CLK_Y_SOR_SAFE = 30,
CLK_Y_PLLP_OUT_CPU = 31,
};
/*! Generic clock descriptor. */ /*! Generic clock descriptor. */
typedef struct _clock_t typedef struct _clock_t
@ -215,6 +485,9 @@ void clock_enable_pwm();
void clock_disable_pwm(); void clock_disable_pwm();
void clock_enable_pllc(u32 divn); void clock_enable_pllc(u32 divn);
void clock_disable_pllc(); 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_config_clock_source(u32 *pclock, u32 id, u32 val);
void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type); void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type);
int clock_sdmmc_is_not_reset_and_enabled(u32 id); int clock_sdmmc_is_not_reset_and_enabled(u32 id);

View File

@ -20,9 +20,9 @@
#include <string.h> #include <string.h>
#include <soc/fuse.h> #include <soc/fuse.h>
#include <soc/hw_init.h>
#include <soc/t210.h> #include <soc/t210.h>
#include <utils/types.h>
#define ARRAYSIZE(x) (sizeof(x) / sizeof(*x))
static const u32 evp_thunk_template[] = { static const u32 evp_thunk_template[] = {
0xe92d0007, // STMFD SP!, {R0-R2} 0xe92d0007, // STMFD SP!, {R0-R2}
@ -62,12 +62,48 @@ u32 fuse_read_odm(u32 idx)
u32 fuse_read_odm_keygen_rev() u32 fuse_read_odm_keygen_rev()
{ {
if ((fuse_read_odm(4) & 0x800) && fuse_read_odm(0) == 0x8E61ECAE && fuse_read_odm(1) == 0xF2BA3BB2) bool has_new_keygen;
// Check if it has new keygen.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
has_new_keygen = true;
else
has_new_keygen = (fuse_read_odm(4) & 0x800) && fuse_read_odm(0) == 0x8E61ECAE && fuse_read_odm(1) == 0xF2BA3BB2;
if (has_new_keygen)
return (fuse_read_odm(2) & 0x1F); return (fuse_read_odm(2) & 0x1F);
return 0; return 0;
} }
u32 fuse_read_hw_type()
{
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
{
switch ((fuse_read_odm(4) & 0xF0000) >> 16)
{
case 1:
return FUSE_NX_HW_TYPE_IOWA;
case 2:
return FUSE_NX_HW_TYPE_HOAG;
}
}
return FUSE_NX_HW_TYPE_ICOSA;
}
u8 fuse_count_burnt(u32 val)
{
u8 burnt_fuses = 0;
for (u32 i = 0; i < 32; i++)
{
if ((val >> i) & 1)
burnt_fuses++;
}
return burnt_fuses;
}
void fuse_wait_idle() void fuse_wait_idle()
{ {
u32 ctrl; u32 ctrl;
@ -87,7 +123,9 @@ u32 fuse_read(u32 addr)
void fuse_read_array(u32 *words) void fuse_read_array(u32 *words)
{ {
for (u32 i = 0; i < 192; i++) u32 array_size = (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) ? 256 : 192;
for (u32 i = 0; i < array_size; i++)
words[i] = fuse_read(i); words[i] = fuse_read(i);
} }
@ -133,7 +171,7 @@ static int _patch_hash_one(u32 *word)
{ {
return 3; return 3;
} }
for (u32 i = 0; i < ARRAYSIZE(hash_vals); i++) for (u32 i = 0; i < ARRAY_SIZE(hash_vals); i++)
{ {
if (hash_vals[i] == hash) if (hash_vals[i] == hash)
{ {
@ -222,7 +260,7 @@ int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
while (word_count) while (word_count)
{ {
total_read += word_count; total_read += word_count;
if (total_read >= ARRAYSIZE(words)) if (total_read >= ARRAY_SIZE(words))
{ {
break; break;
} }
@ -279,7 +317,7 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
while (word_count) while (word_count)
{ {
total_read += word_count; total_read += word_count;
if (total_read >= ARRAYSIZE(words)) if (total_read >= ARRAY_SIZE(words))
{ {
break; break;
} }
@ -328,8 +366,8 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
bool fuse_check_patched_rcm() bool fuse_check_patched_rcm()
{ {
// Check if XUSB in use. // Check if XUSB in use or Tegra X1+.
if (FUSE(FUSE_RESERVED_SW) & (1<<7)) if (FUSE(FUSE_RESERVED_SW) & (1<<7) || hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
return true; return true;
// Check if RCM is ipatched. // Check if RCM is ipatched.

View File

@ -64,6 +64,7 @@
#define FUSE_OPT_X_COORDINATE 0x214 #define FUSE_OPT_X_COORDINATE 0x214
#define FUSE_OPT_Y_COORDINATE 0x218 #define FUSE_OPT_Y_COORDINATE 0x218
#define FUSE_GPU_IDDQ_CALIB 0x228 #define FUSE_GPU_IDDQ_CALIB 0x228
#define FUSE_RESERVED_ODM28 0x240
#define FUSE_USB_CALIB_EXT 0x350 #define FUSE_USB_CALIB_EXT 0x350
/*! Fuse commands. */ /*! Fuse commands. */
@ -75,9 +76,18 @@
/*! Fuse cache registers. */ /*! Fuse cache registers. */
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x)) #define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
enum
{
FUSE_NX_HW_TYPE_ICOSA,
FUSE_NX_HW_TYPE_IOWA,
FUSE_NX_HW_TYPE_HOAG
};
void fuse_disable_program(); void fuse_disable_program();
u32 fuse_read_odm(u32 idx); u32 fuse_read_odm(u32 idx);
u32 fuse_read_odm_keygen_rev(); u32 fuse_read_odm_keygen_rev();
u32 fuse_read_hw_type();
u8 fuse_count_burnt(u32 val);
void fuse_wait_idle(); void fuse_wait_idle();
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value)); int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len); int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);

View File

@ -18,23 +18,23 @@
#include <soc/gpio.h> #include <soc/gpio.h>
#include <soc/t210.h> #include <soc/t210.h>
#define GPIO_BANK_IDX(port) (port >> 2) #define GPIO_BANK_IDX(port) ((port) >> 2)
#define GPIO_CNF_OFFSET(port) (0x00 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_CNF_OFFSET(port) (0x00 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_OE_OFFSET(port) (0x10 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_OE_OFFSET(port) (0x10 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_OUT_OFFSET(port) (0x20 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_OUT_OFFSET(port) (0x20 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_IN_OFFSET(port) (0x30 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_IN_OFFSET(port) (0x30 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_INT_STA_OFFSET(port) (0x40 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_INT_STA_OFFSET(port) (0x40 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_INT_ENB_OFFSET(port) (0x50 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_INT_ENB_OFFSET(port) (0x50 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_INT_LVL_OFFSET(port) (0x60 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_INT_LVL_OFFSET(port) (0x60 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_INT_CLR_OFFSET(port) (0x70 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_INT_CLR_OFFSET(port) (0x70 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_CNF_MASKED_OFFSET(port) (0x80 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_CNF_MASKED_OFFSET(port) (0x80 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_OE_MASKED_OFFSET(port) (0x90 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_OE_MASKED_OFFSET(port) (0x90 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_OUT_MASKED_OFFSET(port) (0xA0 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_OUT_MASKED_OFFSET(port) (0xA0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_INT_STA_MASKED_OFFSET(port) (0xC0 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_INT_STA_MASKED_OFFSET(port) (0xC0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_INT_ENB_MASKED_OFFSET(port) (0xD0 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_INT_ENB_MASKED_OFFSET(port) (0xD0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_INT_LVL_MASKED_OFFSET(port) (0xE0 + ((port >> 2) << 8) + ((port % 4) << 2)) #define GPIO_INT_LVL_MASKED_OFFSET(port) (0xE0 + (((port) >> 2) << 8) + (((port) % 4) << 2))
#define GPIO_IRQ_BANK1 32 #define GPIO_IRQ_BANK1 32
#define GPIO_IRQ_BANK2 33 #define GPIO_IRQ_BANK2 33

View File

@ -41,14 +41,14 @@
#define GPIO_ANY_EDGE_CHANGE 1 #define GPIO_ANY_EDGE_CHANGE 1
/*! GPIO pins (0-7 for each port). */ /*! GPIO pins (0-7 for each port). */
#define GPIO_PIN_0 (1 << 0) #define GPIO_PIN_0 BIT(0)
#define GPIO_PIN_1 (1 << 1) #define GPIO_PIN_1 BIT(1)
#define GPIO_PIN_2 (1 << 2) #define GPIO_PIN_2 BIT(2)
#define GPIO_PIN_3 (1 << 3) #define GPIO_PIN_3 BIT(3)
#define GPIO_PIN_4 (1 << 4) #define GPIO_PIN_4 BIT(4)
#define GPIO_PIN_5 (1 << 5) #define GPIO_PIN_5 BIT(5)
#define GPIO_PIN_6 (1 << 6) #define GPIO_PIN_6 BIT(6)
#define GPIO_PIN_7 (1 << 7) #define GPIO_PIN_7 BIT(7)
/*! GPIO ports (A-EE). */ /*! GPIO ports (A-EE). */
#define GPIO_PORT_A 0 #define GPIO_PORT_A 0

View File

@ -56,7 +56,15 @@ extern volatile nyx_storage_t *nyx_str;
* PCLK - 68MHz init (-> 136MHz -> OC/4). * PCLK - 68MHz init (-> 136MHz -> OC/4).
*/ */
void _config_oscillators() u32 hw_get_chip_id()
{
if (((APB_MISC(APB_MISC_GP_HIDREV) >> 4) & 0xF) >= GP_HIDREV_MAJOR_T210B01)
return GP_HIDREV_MAJOR_T210B01;
else
return GP_HIDREV_MAJOR_T210;
}
static void _config_oscillators()
{ {
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4; // Set CLK_M_DIVISOR to 2. 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. SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
@ -73,35 +81,44 @@ void _config_oscillators()
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz) 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 SCLK div to 1. CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1.
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set clk source to Run and PLLP_OUT2 (204MHz). 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_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.
} }
void _config_gpios() static void _config_gpios(bool nx_hoag)
{ {
// Clamp inputs when tristated.
APB_MISC(APB_MISC_PP_PINMUX_GLOBAL) = 0;
if (!nx_hoag)
{
PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0; PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0; PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
// Set Joy-Con IsAttached direction. // Set pin mode for UARTB/C TX pins.
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
// Set pin mode for Joy-Con IsAttached and UARTB/C TX pins.
#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B #if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO); gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
#endif #endif
#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_C #if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_C
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO); gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
#endif #endif
// Enable input logic for UARTB/C TX pins.
gpio_output_enable(GPIO_PORT_G, GPIO_PIN_0, GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_PORT_D, GPIO_PIN_1, GPIO_OUTPUT_DISABLE);
}
// Set Joy-Con IsAttached direction.
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
// Set Joy-Con IsAttached mode. // Set Joy-Con IsAttached mode.
gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO); gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO);
gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO); gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO);
// Enable input logic for Joy-Con IsAttached and UARTB/C TX pins. // Enable input logic for Joy-Con IsAttached 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_output_enable(GPIO_PORT_E, GPIO_PIN_6, GPIO_OUTPUT_DISABLE); gpio_output_enable(GPIO_PORT_E, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
gpio_output_enable(GPIO_PORT_H, GPIO_PIN_6, GPIO_OUTPUT_DISABLE); gpio_output_enable(GPIO_PORT_H, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
@ -120,27 +137,28 @@ void _config_gpios()
// gpio_config(GPIO_PORT_Y, GPIO_PIN_1, GPIO_MODE_GPIO); // gpio_config(GPIO_PORT_Y, GPIO_PIN_1, GPIO_MODE_GPIO);
} }
void _config_pmc_scratch() static void _config_pmc_scratch()
{ {
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; // Unset Debug console from Customer Option. 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 DATA_DQ_E_IVREF EMC_PMACRO_DATA_PAD_TX_CTRL
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT; PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
} }
void _mbist_workaround() static void _mbist_workaround()
{ {
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= (1 << 10); // Enable AHUB clock. // Make sure Audio clocks are enabled before accessing I2S.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= (1 << 6); // Enable APE clock. CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
// Set mux output to SOR1 clock switch. // Set mux output to SOR1 clock switch.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) | 0x8000) & 0xFFFFBFFF; CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) | 0x8000) & 0xFFFFBFFF;
// Enabled PLLD and set csi to PLLD for test pattern generation. // Enabled PLLD and set csi to PLLD for test pattern generation.
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= 0x40800000; CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= 0x40800000;
// Clear per-clock resets. // Clear per-clock resets for APE/VIC/HOST1X/DISP1.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = 0x40; // Clear reset APE. CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = BIT(CLK_Y_APE);
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_CLR) = 0x40000; // Clear reset VIC. CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_CLR) = BIT(CLK_X_VIC);
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = 0x18000000; // Clear reset DISP1, HOST1X. CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
usleep(2); usleep(2);
// I2S channels to master and disable SLCG. // I2S channels to master and disable SLCG.
@ -159,20 +177,59 @@ void _mbist_workaround()
VIC(0x8C) = 0xFFFFFFFF; VIC(0x8C) = 0xFFFFFFFF;
usleep(2); usleep(2);
// Set per-clock reset. // Set per-clock reset for APE/VIC/HOST1X/DISP1.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_SET) = 0x40; // Set reset APE. CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_SET) = BIT(CLK_Y_APE);
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = 0x18000000; // Set reset DISP1, HOST1x. CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_SET) = 0x40000; // Set reset VIC. CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_SET) = BIT(CLK_X_VIC);
// Enable specific clocks and disable all others. // Enable specific clocks and disable all others.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = 0xC0; // Enable clock PMC, FUSE. // CLK L Devices.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80000130; // Enable clock RTC, TMR, GPIO, BPMP_CACHE. CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) =
//CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80400130; // Keep USBD ON. BIT(CLK_H_PMC) |
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) = 0x1F00200; // Enable clock CSITE, IRAMA, IRAMB, IRAMC, IRAMD, BPMP_CACHE_RAM. BIT(CLK_H_FUSE);
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = 0x80400808; // Enable clock MSELECT, APB2APE, SPDIF_DOUBLER, SE. // CLK H Devices.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) = 0x402000FC; // Enable clock PCIERX0, PCIERX1, PCIERX2, PCIERX3, PCIERX4, PCIERX5, ENTROPY, MC1. CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) =
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) = 0x23000780; // Enable clock MC_CAPA, MC_CAPB, MC_CPU, MC_BBC, DBGAPB, HPLL_ADSP, PLLG_REF. BIT(CLK_L_RTC) |
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) = 0x300; // Enable clock MC_CDPA, MC_CCPA. BIT(CLK_L_TMR) |
BIT(CLK_L_GPIO) |
BIT(CLK_L_BPMP_CACHE_CTRL);
// CLK U Devices.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) =
BIT(CLK_U_CSITE) |
BIT(CLK_U_IRAMA) |
BIT(CLK_U_IRAMB) |
BIT(CLK_U_IRAMC) |
BIT(CLK_U_IRAMD) |
BIT(CLK_U_BPMP_CACHE_RAM);
// CLK V Devices.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) =
BIT(CLK_V_MSELECT) |
BIT(CLK_V_APB2APE) |
BIT(CLK_V_SPDIF_DOUBLER) |
BIT(CLK_V_SE);
// CLK W Devices.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) =
BIT(CLK_W_PCIERX0) |
BIT(CLK_W_PCIERX1) |
BIT(CLK_W_PCIERX2) |
BIT(CLK_W_PCIERX3) |
BIT(CLK_W_PCIERX4) |
BIT(CLK_W_PCIERX5) |
BIT(CLK_W_ENTROPY) |
BIT(CLK_W_MC1);
// CLK X Devices.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) =
BIT(CLK_X_MC_CAPA) |
BIT(CLK_X_MC_CBPA) |
BIT(CLK_X_MC_CPU) |
BIT(CLK_X_MC_BBC) |
BIT(CLK_X_GPU) |
BIT(CLK_X_DBGAPB) |
BIT(CLK_X_PLLG_REF);
// CLK Y Devices.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) =
BIT(CLK_Y_MC_CDPA) |
BIT(CLK_Y_MC_CCPA);
// Disable clock gate overrides. // Disable clock gate overrides.
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA) = 0; CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA) = 0;
@ -189,13 +246,14 @@ void _mbist_workaround()
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.
} }
void _config_se_brom() static void _config_se_brom()
{ {
// Enable fuse clock. // Enable fuse clock.
clock_enable_fuse(true); clock_enable_fuse(true);
// Skip SBK/SSK if sept was run. // Skip SBK/SSK if sept was run.
if (!(b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN)) bool sbk_skip = b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN || FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF;
if (!sbk_skip)
{ {
// Bootrom part we skipped. // Bootrom part we skipped.
u32 sbk[4] = { u32 sbk[4] = {
@ -225,27 +283,26 @@ void _config_se_brom()
APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10); APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10);
} }
void _config_regulators() static void _config_regulators(bool tegra_t210)
{ {
// Disable low battery shutdown monitor. // Disable low battery shutdown monitor.
max77620_low_battery_monitor_config(false); max77620_low_battery_monitor_config(false);
// Disable SDMMC1 IO power. // Disable SDMMC1 IO power.
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE); gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
max77620_regulator_enable(REGULATOR_LDO2, 0); max77620_regulator_enable(REGULATOR_LDO2, 0);
sd_power_cycle_time_start = get_tmr_ms(); sd_power_cycle_time_start = get_tmr_ms();
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_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,
(1 << 6) | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off. BIT(6) | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.
// Configure all Flexible Power Sequencers. if (tegra_t210)
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0, {
(7 << MAX77620_FPS_TIME_PERIOD_SHIFT)); // Configure all Flexible Power Sequencers for MAX77620.
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1, i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
(7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (1 << MAX77620_FPS_EN_SRC_SHIFT)); i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (1 << MAX77620_FPS_EN_SRC_SHIFT));
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2, i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
(7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
max77620_regulator_config_fps(REGULATOR_LDO4); max77620_regulator_config_fps(REGULATOR_LDO4);
max77620_regulator_config_fps(REGULATOR_LDO8); max77620_regulator_config_fps(REGULATOR_LDO8);
max77620_regulator_config_fps(REGULATOR_SD0); max77620_regulator_config_fps(REGULATOR_SD0);
@ -275,65 +332,96 @@ void _config_regulators()
i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL2_REG, i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL2_REG,
MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS | MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL); MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
}
else // Tegra X1+ set vdd_core voltage to 1.05V.
max77620_regulator_set_voltage(REGULATOR_SD0, 1050000);
} }
void config_hw() void hw_init()
{ {
// Get Chip ID.
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
// Bootrom stuff we skipped by going through rcm. // Bootrom stuff we skipped by going through rcm.
_config_se_brom(); _config_se_brom();
//FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11; //FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11;
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F; // Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN. SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F; // Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
PMC(APBDEV_PMC_SCRATCH49) = PMC(APBDEV_PMC_SCRATCH49) & 0xFFFFFFFC; PMC(APBDEV_PMC_SCRATCH49) = PMC(APBDEV_PMC_SCRATCH49) & 0xFFFFFFFC;
// Perform Memory Built-In Self Test WAR if T210.
if (tegra_t210)
_mbist_workaround(); _mbist_workaround();
// Enable Security Engine clock.
clock_enable_se(); clock_enable_se();
// Enable fuse clock. // Enable Fuse clock.
clock_enable_fuse(true); clock_enable_fuse(true);
// Disable fuse programming. // Disable Fuse programming.
fuse_disable_program(); fuse_disable_program();
// Enable clocks to Memory controllers and disable AHB redirect.
mc_enable(); mc_enable();
// Initialize counters, CLKM, BPMP and other clocks based on 38.4MHz oscillator.
_config_oscillators(); _config_oscillators();
APB_MISC(APB_MISC_PP_PINMUX_GLOBAL) = 0;
_config_gpios(); // Initialize pin configuration.
_config_gpios(nx_hoag);
#ifdef DEBUG_UART_PORT #ifdef DEBUG_UART_PORT
clock_enable_uart(DEBUG_UART_PORT); clock_enable_uart(DEBUG_UART_PORT);
uart_init(DEBUG_UART_PORT, 115200); uart_init(DEBUG_UART_PORT, 115200);
#endif #endif
// Enable Dynamic Voltage and Frequency Scaling device clock.
clock_enable_cl_dvfs(); clock_enable_cl_dvfs();
// Enable clocks to I2C1 and I2CPWR.
clock_enable_i2c(I2C_1); clock_enable_i2c(I2C_1);
clock_enable_i2c(I2C_5); clock_enable_i2c(I2C_5);
// Enable clock to TZRAM.
clock_enable_tzram(); clock_enable_tzram();
i2c_init(I2C_1); // Initialize I2C5, mandatory for PMIC.
i2c_init(I2C_5); i2c_init(I2C_5);
//! TODO: Why? Device is NFC MCU on Lite.
if (nx_hoag)
max77620_regulator_set_volt_and_flags(REGULATOR_LDO8, 2800000, MAX77620_POWER_MODE_NORMAL);
// Initialize I2C1 for various power related devices.
i2c_init(I2C_1);
// Enable charger in case it's disabled. // Enable charger in case it's disabled.
bq24193_enable_charger(); bq24193_enable_charger();
_config_regulators(); // Initialize various regulators based on Erista/Mariko platform.
_config_regulators(tegra_t210);
_config_pmc_scratch(); // Missing from 4.x+ _config_pmc_scratch(); // Missing from 4.x+
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // Set SCLK to PLLP_OUT (408MHz). // Set BPMP/SCLK to PLLP_OUT (408MHz).
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333;
// Disable TZRAM shutdown control and lock the regs.
if (!tegra_t210)
{
PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= 0xFFFFFFFE;
PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = 3;
PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = 3;
}
// Initialize External memory controller and configure DRAM parameters.
sdram_init(); sdram_init();
bpmp_mmu_enable(); bpmp_mmu_enable();
mc_enable_ahb_redirect();
// Clear flags from PMC_SCRATCH0
PMC(APBDEV_PMC_SCRATCH0) &= ~PMC_SCRATCH0_MODE_PAYLOAD;
} }
void reconfig_hw_workaround(bool extra_reconfig, u32 magic) void hw_reinit_workaround(bool extra_reconfig, u32 magic)
{ {
// Disable BPMP max clock. // Disable BPMP max clock.
bpmp_clk_rate_set(BPMP_CLK_NORMAL); bpmp_clk_rate_set(BPMP_CLK_NORMAL);
@ -354,8 +442,8 @@ void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
nyx_str->mtc_cfg.init_done = 0; nyx_str->mtc_cfg.init_done = 0;
// Re-enable clocks to Audio Processing Engine as a workaround to hanging. // Re-enable clocks to Audio Processing Engine as a workaround to hanging.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= (1 << 10); // Enable AHUB clock. CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= (1 << 6); // Enable APE clock. CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
if (extra_reconfig) if (extra_reconfig)
{ {
@ -377,7 +465,7 @@ void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
// Enable clock to USBD and init SDMMC1 to avoid hangs with bad hw inits. // Enable clock to USBD and init SDMMC1 to avoid hangs with bad hw inits.
if (magic == 0xBAADF00D) if (magic == 0xBAADF00D)
{ {
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) |= (1 << 22); 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); sdmmc_init(&sd_sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, 0);
clock_disable_cl_dvfs(); clock_disable_cl_dvfs();

View File

@ -20,7 +20,8 @@
#include <utils/types.h> #include <utils/types.h>
void config_hw(); void hw_init();
void reconfig_hw_workaround(bool extra_reconfig, u32 magic); void hw_reinit_workaround(bool extra_reconfig, u32 magic);
u32 hw_get_chip_id();
#endif #endif

View File

@ -20,31 +20,98 @@
#include <soc/i2c.h> #include <soc/i2c.h>
#include <utils/util.h> #include <utils/util.h>
#define I2C_PACKET_PROT_I2C BIT(4)
#define I2C_HEADER_CONT_XFER BIT(15)
#define I2C_HEADER_REP_START BIT(16)
#define I2C_HEADER_IE_ENABLE BIT(17)
#define I2C_HEADER_READ BIT(19)
#define I2C_CNFG (0x00 / 4)
#define CMD1_WRITE (0 << 6)
#define CMD1_READ BIT(6)
#define NORMAL_MODE_GO BIT(9)
#define PACKET_MODE_GO BIT(10)
#define NEW_MASTER_FSM BIT(11)
#define DEBOUNCE_CNT_4T (2 << 12)
#define I2C_CMD_ADDR0 (0x04 / 4)
#define ADDR0_WRITE 0
#define ADDR0_READ 1
#define I2C_CMD_DATA1 (0x0C / 4)
#define I2C_CMD_DATA2 (0x10 / 4)
#define I2C_STATUS (0x1C / 4)
#define I2C_STATUS_NOACK (0xF << 0)
#define I2C_STATUS_BUSY BIT(8)
#define I2C_TX_FIFO (0x50 / 4)
#define I2C_RX_FIFO (0x54 / 4)
#define I2C_FIFO_CONTROL (0x5C / 4)
#define RX_FIFO_FLUSH BIT(0)
#define TX_FIFO_FLUSH BIT(1)
#define I2C_FIFO_STATUS (0x60 / 4)
#define RX_FIFO_FULL_CNT (0xF << 0)
#define TX_FIFO_EMPTY_CNT (0xF << 4)
#define I2C_INT_EN (0x64 / 4)
#define I2C_INT_STATUS (0x68 / 4)
#define I2C_INT_SOURCE (0x70 / 4)
#define RX_FIFO_DATA_REQ BIT(0)
#define TX_FIFO_DATA_REQ BIT(1)
#define ARB_LOST BIT(2)
#define NO_ACK BIT(3)
#define RX_FIFO_UNDER BIT(4)
#define TX_FIFO_OVER BIT(5)
#define ALL_PACKETS_COMPLETE BIT(6)
#define PACKET_COMPLETE BIT(7)
#define BUS_CLEAR_DONE BIT(11)
#define I2C_CLK_DIVISOR (0x6C / 4)
#define I2C_BUS_CLEAR_CONFIG (0x84 / 4)
#define BC_ENABLE BIT(0)
#define BC_TERMINATE BIT(1)
#define I2C_BUS_CLEAR_STATUS (0x88 / 4)
#define I2C_CONFIG_LOAD (0x8C / 4)
#define MSTR_CONFIG_LOAD BIT(0)
#define TIMEOUT_CONFIG_LOAD BIT(2)
static const u32 i2c_addrs[] = { static const u32 i2c_addrs[] = {
0x7000C000, 0x7000C400, 0x7000C500, 0x7000C000, // I2C_1.
0x7000C700, 0x7000D000, 0x7000D100 0x7000C400, // I2C_2.
0x7000C500, // I2C_3.
0x7000C700, // I2C_4.
0x7000D000, // I2C_5.
0x7000D100 // I2C_6.
}; };
static void _i2c_wait(vu32 *base) static void _i2c_load_cfg_wait(vu32 *base)
{ {
base[I2C_CONFIG_LOAD] = 0x25; base[I2C_CONFIG_LOAD] = BIT(5) | TIMEOUT_CONFIG_LOAD | MSTR_CONFIG_LOAD;
for (u32 i = 0; i < 20; i++) for (u32 i = 0; i < 20; i++)
{ {
usleep(1); usleep(1);
if (!(base[I2C_CONFIG_LOAD] & 1)) if (!(base[I2C_CONFIG_LOAD] & MSTR_CONFIG_LOAD))
break; break;
} }
} }
static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size) static int _i2c_send_single(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
{ {
if (size > 8) if (size > 8)
return 0; return 0;
u32 tmp = 0; u32 tmp = 0;
vu32 *base = (vu32 *)i2c_addrs[idx]; vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
base[I2C_CMD_ADDR0] = x << 1; //Set x (send mode).
// Set device address and send mode.
base[I2C_CMD_ADDR0] = dev_addr << 1 | ADDR0_WRITE;
if (size > 4) if (size > 4)
{ {
@ -60,44 +127,55 @@ static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
base[I2C_CMD_DATA1] = tmp; //Set value. base[I2C_CMD_DATA1] = tmp; //Set value.
} }
base[I2C_CNFG] = ((size - 1) << 1) | 0x2800; //Set size and send mode. // Set size and send mode.
_i2c_wait(base); //Kick transaction. base[I2C_CNFG] = ((size - 1) << 1) | DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_WRITE;
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200; // Load configuration.
_i2c_load_cfg_wait(base);
u32 timeout = get_tmr_ms() + 1500; // Initiate transaction on normal mode.
while (base[I2C_STATUS] & 0x100) base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | NORMAL_MODE_GO;
u32 timeout = get_tmr_ms() + 400; // Actual for max 8 bytes at 100KHz is 0.74ms.
while (base[I2C_STATUS] & I2C_STATUS_BUSY)
{ {
if (get_tmr_ms() > timeout) if (get_tmr_ms() > timeout)
return 0; return 0;
} }
if (base[I2C_STATUS] << 28) if (base[I2C_STATUS] & I2C_STATUS_NOACK)
return 0; return 0;
return 1; return 1;
} }
static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x) static int _i2c_recv_single(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
{ {
if (size > 8) if (size > 8)
return 0; return 0;
vu32 *base = (vu32 *)i2c_addrs[idx]; vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
base[I2C_CMD_ADDR0] = (x << 1) | 1; // Set x (recv mode).
base[I2C_CNFG] = ((size - 1) << 1) | 0x2840; // Set size and recv mode.
_i2c_wait(base); // Kick transaction.
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200; // Set device address and recv mode.
base[I2C_CMD_ADDR0] = (dev_addr << 1) | ADDR0_READ;
u32 timeout = get_tmr_ms() + 1500; // Set size and recv mode.
while (base[I2C_STATUS] & 0x100) base[I2C_CNFG] = ((size - 1) << 1) | DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_READ;
// Load configuration.
_i2c_load_cfg_wait(base);
// Initiate transaction on normal mode.
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | NORMAL_MODE_GO;
u32 timeout = get_tmr_ms() + 400; // Actual for max 8 bytes at 100KHz is 0.74ms.
while (base[I2C_STATUS] & I2C_STATUS_BUSY)
{ {
if (get_tmr_ms() > timeout) if (get_tmr_ms() > timeout)
return 0; return 0;
} }
if (base[I2C_STATUS] << 28) if (base[I2C_STATUS] & I2C_STATUS_NOACK)
return 0; return 0;
u32 tmp = base[I2C_CMD_DATA1]; // Get LS value. u32 tmp = base[I2C_CMD_DATA1]; // Get LS value.
@ -113,60 +191,234 @@ static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
return 1; return 1;
} }
void i2c_init(u32 idx) static int _i2c_send_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr)
{ {
vu32 *base = (vu32 *)i2c_addrs[idx]; if (size > 32)
return 0;
base[I2C_CLK_DIVISOR_REGISTER] = 0x50001; int res = 0;
base[I2C_BUS_CLEAR_CONFIG] = 0x90003;
_i2c_wait(base); vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
// Enable interrupts.
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
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 recv mode.
base[I2C_CNFG] = DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_WRITE;
// Set and flush FIFO.
base[I2C_FIFO_CONTROL] = RX_FIFO_FLUSH | TX_FIFO_FLUSH;
// Load configuration.
_i2c_load_cfg_wait(base);
// Initiate transaction on packet mode.
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | PACKET_MODE_GO;
u32 hdr[3];
hdr[0] = I2C_PACKET_PROT_I2C;
hdr[1] = size - 1;
hdr[2] = I2C_HEADER_IE_ENABLE | I2C_HEADER_CONT_XFER | (dev_addr << 1);
// Send header with request.
base[I2C_TX_FIFO] = hdr[0];
base[I2C_TX_FIFO] = hdr[1];
base[I2C_TX_FIFO] = hdr[2];
u32 timeout = get_tmr_ms() + 400;
while (size)
{
if (base[I2C_FIFO_STATUS] & TX_FIFO_EMPTY_CNT)
{
u32 tmp = 0;
u32 snd_size = MIN(size, 4);
memcpy(&tmp, buf, snd_size);
base[I2C_TX_FIFO] = tmp;
buf += snd_size;
size -= snd_size;
}
if (get_tmr_ms() > timeout)
{
res = 1;
break;
}
}
if (base[I2C_STATUS] & I2C_STATUS_NOACK || base[I2C_INT_STATUS] & NO_ACK)
res = 1;
// Disable packet mode.
usleep(20);
base[I2C_CNFG] &= 0xFFFFF9FF;
// Disable interrupts.
base[I2C_INT_EN] = 0;
return res;
}
static int _i2c_recv_pkt(u32 i2c_idx, u8 *buf, u32 size, u32 dev_addr, u32 reg)
{
if (size > 32)
return 0;
int res = 0;
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
// Enable interrupts.
base[I2C_INT_EN] = ALL_PACKETS_COMPLETE | PACKET_COMPLETE | NO_ACK |
ARB_LOST | TX_FIFO_OVER | RX_FIFO_UNDER | RX_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 recv mode.
base[I2C_CNFG] = DEBOUNCE_CNT_4T | NEW_MASTER_FSM | CMD1_READ;
// Set and flush FIFO.
base[I2C_FIFO_CONTROL] = RX_FIFO_FLUSH | TX_FIFO_FLUSH;
// Load configuration.
_i2c_load_cfg_wait(base);
// Initiate transaction on packet mode.
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFF9FF) | PACKET_MODE_GO;
// Send reg request.
u32 hdr[3];
hdr[0] = I2C_PACKET_PROT_I2C;
hdr[1] = 1 - 1;
hdr[2] = I2C_HEADER_REP_START | (dev_addr << 1);
// Send header with reg request.
base[I2C_TX_FIFO] = hdr[0];
base[I2C_TX_FIFO] = hdr[1];
base[I2C_TX_FIFO] = hdr[2];
base[I2C_TX_FIFO] = reg;
u32 timeout = get_tmr_ms() + 400;
while (!(base[I2C_FIFO_STATUS] & TX_FIFO_EMPTY_CNT))
if (get_tmr_ms() > timeout)
break;
// Send read request.
hdr[1] = size - 1;
hdr[2] = I2C_HEADER_READ | (dev_addr << 1);
// Send header with read request.
base[I2C_TX_FIFO] = hdr[0];
base[I2C_TX_FIFO] = hdr[1];
base[I2C_TX_FIFO] = hdr[2];
timeout = get_tmr_ms() + 400;
while (size)
{
if (base[I2C_FIFO_STATUS] & RX_FIFO_FULL_CNT)
{
u32 rcv_size = MIN(size, 4);
u32 tmp = base[I2C_RX_FIFO];
memcpy(buf, &tmp, rcv_size);
buf += rcv_size;
size -= rcv_size;
}
if (get_tmr_ms() > timeout)
{
res = 1;
break;
}
}
if (base[I2C_STATUS] & I2C_STATUS_NOACK || base[I2C_INT_STATUS] & NO_ACK)
res = 1;
// Disable packet mode.
usleep(20);
base[I2C_CNFG] &= 0xFFFFF9FF;
// Disable interrupts.
base[I2C_INT_EN] = 0;
return res;
}
void i2c_init(u32 i2c_idx)
{
vu32 *base = (vu32 *)i2c_addrs[i2c_idx];
base[I2C_CLK_DIVISOR] = (5 << 16) | 1; // SF mode Div: 6, HS mode div: 2.
base[I2C_BUS_CLEAR_CONFIG] = (9 << 16) | BC_TERMINATE | BC_ENABLE;
// Load configuration.
_i2c_load_cfg_wait(base);
for (u32 i = 0; i < 10; i++) for (u32 i = 0; i < 10; i++)
{ {
usleep(20000); usleep(20000);
if (base[INTERRUPT_STATUS_REGISTER] & 0x800) if (base[I2C_INT_STATUS] & BUS_CLEAR_DONE)
break; break;
} }
(vu32)base[I2C_BUS_CLEAR_STATUS]; (vu32)base[I2C_BUS_CLEAR_STATUS];
base[INTERRUPT_STATUS_REGISTER] = base[INTERRUPT_STATUS_REGISTER]; base[I2C_INT_STATUS] = base[I2C_INT_STATUS];
} }
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size) int i2c_recv_buf(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr)
{
return _i2c_recv_single(i2c_idx, buf, size, dev_addr);
}
int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size)
{
if (size > 32)
return 0;
return _i2c_send_pkt(i2c_idx, buf, size, dev_addr);
}
int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
{
return _i2c_recv_pkt(i2c_idx, buf, size, dev_addr, reg);
}
int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size)
{ {
u8 tmp[4]; u8 tmp[4];
if (size > 7) if (size > 7)
return 0; return 0;
tmp[0] = y; tmp[0] = reg;
memcpy(tmp + 1, buf, size); memcpy(tmp + 1, buf, size);
return _i2c_send_pkt(idx, x, tmp, size + 1); return _i2c_send_single(i2c_idx, dev_addr, tmp, size + 1);
} }
int i2c_recv_buf(u8 *buf, u32 size, u32 idx, u32 x) int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg)
{ {
return _i2c_recv_pkt(idx, buf, size, x); int res = _i2c_send_single(i2c_idx, dev_addr, (u8 *)&reg, 1);
}
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
{
int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);
if (res) if (res)
res = _i2c_recv_pkt(idx, buf, size, x); res = _i2c_recv_single(i2c_idx, buf, size, dev_addr);
return res; return res;
} }
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b) int i2c_send_byte(u32 i2c_idx, u32 dev_addr, u32 reg, u8 val)
{ {
return i2c_send_buf_small(idx, x, y, &b, 1); return i2c_send_buf_small(i2c_idx, dev_addr, reg, &val, 1);
} }
u8 i2c_recv_byte(u32 idx, u32 x, u32 y) u8 i2c_recv_byte(u32 i2c_idx, u32 dev_addr, u32 reg)
{ {
u8 tmp = 0; u8 tmp = 0;
i2c_recv_buf_small(&tmp, 1, idx, x, y); i2c_recv_buf_small(&tmp, 1, i2c_idx, dev_addr, reg);
return tmp; return tmp;
} }

View File

@ -27,22 +27,13 @@
#define I2C_5 4 #define I2C_5 4
#define I2C_6 5 #define I2C_6 5
#define I2C_CNFG 0x00 void i2c_init(u32 i2c_idx);
#define I2C_CMD_ADDR0 0x01 int i2c_recv_buf(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr);
#define I2C_CMD_DATA1 0x03 int i2c_send_buf_big(u32 i2c_idx, u32 dev_addr, u8 *buf, u32 size);
#define I2C_CMD_DATA2 0x04 int i2c_recv_buf_big(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
#define I2C_STATUS 0x07 int i2c_send_buf_small(u32 i2c_idx, u32 dev_addr, u32 reg, u8 *buf, u32 size);
#define INTERRUPT_STATUS_REGISTER 0x1A int i2c_recv_buf_small(u8 *buf, u32 size, u32 i2c_idx, u32 dev_addr, u32 reg);
#define I2C_CLK_DIVISOR_REGISTER 0x1B int i2c_send_byte(u32 i2c_idx, u32 dev_addr, u32 reg, u8 val);
#define I2C_BUS_CLEAR_CONFIG 0x21 u8 i2c_recv_byte(u32 i2c_idx, u32 dev_addr, u32 reg);
#define I2C_BUS_CLEAR_STATUS 0x22
#define I2C_CONFIG_LOAD 0x23
void i2c_init(u32 idx);
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);
int i2c_recv_buf(u8 *buf, u32 size, u32 idx, u32 x);
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y);
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);
u8 i2c_recv_byte(u32 idx, u32 x, u32 y);
#endif #endif

View File

@ -47,10 +47,10 @@ static void _irq_enable_source(u32 irq)
u32 bit = irq % 32; u32 bit = irq % 32;
// Set as normal IRQ. // Set as normal IRQ.
ICTLR(ctrl_idx, PRI_ICTLR_COP_IEP_CLASS) &= ~(1 << bit); ICTLR(ctrl_idx, PRI_ICTLR_COP_IEP_CLASS) &= ~BIT(bit);
// Enable IRQ source. // Enable IRQ source.
ICTLR(ctrl_idx, PRI_ICTLR_COP_IER_SET) = 1 << bit; ICTLR(ctrl_idx, PRI_ICTLR_COP_IER_SET) = BIT(bit);
} }
static void _irq_disable_source(u32 irq) static void _irq_disable_source(u32 irq)
@ -59,7 +59,7 @@ static void _irq_disable_source(u32 irq)
u32 bit = irq % 32; u32 bit = irq % 32;
// Disable IRQ source. // Disable IRQ source.
ICTLR(ctrl_idx, PRI_ICTLR_COP_IER_CLR) = 1 << bit; ICTLR(ctrl_idx, PRI_ICTLR_COP_IER_CLR) = BIT(bit);
} }
static void _irq_disable_and_ack_all() static void _irq_disable_and_ack_all()
@ -79,7 +79,7 @@ static void _irq_ack_source(u32 irq)
u32 bit = irq % 32; u32 bit = irq % 32;
// Force stop the interrupt as it's serviced here. // Force stop the interrupt as it's serviced here.
ICTLR(ctrl_idx, PRI_ICTLR_FIR_CLR) = 1 << bit; ICTLR(ctrl_idx, PRI_ICTLR_FIR_CLR) = BIT(bit);
} }
void irq_free(u32 irq) void irq_free(u32 irq)

View File

@ -209,8 +209,8 @@ typedef enum _irq_status_t
typedef enum _irq_flags_t typedef enum _irq_flags_t
{ {
IRQ_FLAG_NONE = 0, IRQ_FLAG_NONE = 0,
IRQ_FLAG_ONE_OFF = (1 << 0), IRQ_FLAG_ONE_OFF = BIT(0),
IRQ_FLAG_REPLACEABLE = (1 << 1) IRQ_FLAG_REPLACEABLE = BIT(1)
} irq_flags_t; } irq_flags_t;
void irq_end(); void irq_end();

View File

@ -19,16 +19,16 @@
#include <utils/types.h> #include <utils/types.h>
#define KFUSE_STATE_SOFTRESET (1 << 31)
#define KFUSE_STATE_STOP (1 << 25)
#define KFUSE_STATE_RESTART (1 << 24)
#define KFUSE_STATE_CRCPASS (1 << 17)
#define KFUSE_STATE_DONE (1 << 16)
#define KFUSE_STATE_ERRBLOCK_MASK 0x3F00
#define KFUSE_STATE_ERRBLOCK_SHIFT 8
#define KFUSE_STATE_CURBLOCK_MASK 0x3F #define KFUSE_STATE_CURBLOCK_MASK 0x3F
#define KFUSE_STATE_ERRBLOCK_SHIFT 8
#define KFUSE_STATE_ERRBLOCK_MASK 0x3F00
#define KFUSE_STATE_DONE BIT(16)
#define KFUSE_STATE_CRCPASS BIT(17)
#define KFUSE_STATE_RESTART BIT(24)
#define KFUSE_STATE_STOP BIT(25)
#define KFUSE_STATE_SOFTRESET BIT(31)
#define KFUSE_KEYADDR_AUTOINC (1<<16) #define KFUSE_KEYADDR_AUTOINC BIT(16)
#define KFUSE_STATE 0x80 #define KFUSE_STATE 0x80
#define KFUSE_KEYADDR 0x88 #define KFUSE_KEYADDR 0x88

View File

@ -71,6 +71,18 @@
#define PINMUX_AUX_GPIO_PH6 0x250 #define PINMUX_AUX_GPIO_PH6 0x250
#define PINMUX_AUX_GPIO_PK3 0x260 #define PINMUX_AUX_GPIO_PK3 0x260
#define PINMUX_AUX_GPIO_PZ1 0x280 #define PINMUX_AUX_GPIO_PZ1 0x280
/* Only in T210B01 */
#define PINMUX_AUX_SDMMC2_DAT0 0x294
#define PINMUX_AUX_SDMMC2_DAT1 0x298
#define PINMUX_AUX_SDMMC2_DAT2 0x29C
#define PINMUX_AUX_SDMMC2_DAT3 0x2A0
#define PINMUX_AUX_SDMMC2_DAT4 0x2A4
#define PINMUX_AUX_SDMMC2_DAT5 0x2A8
#define PINMUX_AUX_SDMMC2_DAT6 0x2AC
#define PINMUX_AUX_SDMMC2_DAT7 0x2B0
#define PINMUX_AUX_SDMMC2_CLK 0x2B4
#define PINMUX_AUX_SDMMC2_CMD 0x2BC
/*! 0:UART-A, 1:UART-B, 3:UART-C, 3:UART-D */ /*! 0:UART-A, 1:UART-B, 3:UART-C, 3:UART-D */
#define PINMUX_AUX_UARTX_TX(x) (0xE4 + 0x10 * (x)) #define PINMUX_AUX_UARTX_TX(x) (0xE4 + 0x10 * (x))
#define PINMUX_AUX_UARTX_RX(x) (0xE8 + 0x10 * (x)) #define PINMUX_AUX_UARTX_RX(x) (0xE8 + 0x10 * (x))
@ -87,17 +99,18 @@
#define PINMUX_PULL_DOWN (1 << 2) #define PINMUX_PULL_DOWN (1 << 2)
#define PINMUX_PULL_UP (2 << 2) #define PINMUX_PULL_UP (2 << 2)
#define PINMUX_TRISTATE (1 << 4) #define PINMUX_TRISTATE BIT(4)
#define PINMUX_PARKED (1 << 5) #define PINMUX_PARKED BIT(5)
#define PINMUX_INPUT_ENABLE (1 << 6) #define PINMUX_INPUT_ENABLE BIT(6)
#define PINMUX_LOCK (1 << 7) #define PINMUX_LOCK BIT(7)
#define PINMUX_LPDR (1 << 8) #define PINMUX_LPDR BIT(8)
#define PINMUX_HSM (1 << 9) #define PINMUX_HSM BIT(9)
#define PINMUX_IO_HV (1 << 10) #define PINMUX_IO_HV BIT(10)
#define PINMUX_OPEN_DRAIN (1 << 11) #define PINMUX_OPEN_DRAIN BIT(11)
#define PINMUX_SCHMT (1 << 12) #define PINMUX_SCHMT BIT(12)
#define PINMUX_DRIVE_MASK (3 << 13)
#define PINMUX_DRIVE_1X (0 << 13) #define PINMUX_DRIVE_1X (0 << 13)
#define PINMUX_DRIVE_2X (1 << 13) #define PINMUX_DRIVE_2X (1 << 13)
#define PINMUX_DRIVE_3X (2 << 13) #define PINMUX_DRIVE_3X (2 << 13)

52
bdk/soc/pmc.c Normal file
View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <soc/pmc.h>
#include <soc/t210.h>
#include <utils/util.h>
int pmc_enable_partition(u32 part, int enable)
{
u32 part_mask = BIT(part);
u32 desired_state = enable << part;
// Check if the partition has the state we want.
if ((PMC(APBDEV_PMC_PWRGATE_STATUS) & part_mask) == desired_state)
return 1;
u32 i = 5001;
while (PMC(APBDEV_PMC_PWRGATE_TOGGLE) & 0x100)
{
usleep(1);
i--;
if (i < 1)
return 0;
}
// Toggle power gating.
PMC(APBDEV_PMC_PWRGATE_TOGGLE) = part | 0x100;
i = 5001;
while (i > 0)
{
if ((PMC(APBDEV_PMC_PWRGATE_STATUS) & part_mask) == desired_state)
break;
usleep(1);
i--;
}
return 1;
}

View File

@ -1,6 +1,7 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 st4rk * Copyright (c) 2018 st4rk
* Copyright (c) 2018-2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -18,44 +19,54 @@
#ifndef _PMC_H_ #ifndef _PMC_H_
#define _PMC_H_ #define _PMC_H_
#include <utils/types.h>
/*! PMC registers. */ /*! PMC registers. */
#define APBDEV_PMC_CNTRL 0x0 #define APBDEV_PMC_CNTRL 0x0
#define PMC_CNTRL_MAIN_RST (1 << 4) #define PMC_CNTRL_MAIN_RST BIT(4)
#define APBDEV_PMC_SEC_DISABLE 0x4 #define APBDEV_PMC_SEC_DISABLE 0x4
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30 #define APBDEV_PMC_PWRGATE_TOGGLE 0x30
#define APBDEV_PMC_PWRGATE_STATUS 0x38 #define APBDEV_PMC_PWRGATE_STATUS 0x38
#define APBDEV_PMC_NO_IOPOWER 0x44 #define APBDEV_PMC_NO_IOPOWER 0x44
#define PMC_NO_IOPOWER_GPIO_IO_EN (1 << 21) #define PMC_NO_IOPOWER_SDMMC1_IO_EN BIT(12)
#define PMC_NO_IOPOWER_AUDIO_HV (1 << 18) #define PMC_NO_IOPOWER_AUDIO_HV BIT(18)
#define PMC_NO_IOPOWER_SDMMC1_IO_EN (1 << 12) #define PMC_NO_IOPOWER_GPIO_IO_EN BIT(21)
#define APBDEV_PMC_SCRATCH0 0x50 #define APBDEV_PMC_SCRATCH0 0x50
#define PMC_SCRATCH0_MODE_RECOVERY (1 << 31) #define PMC_SCRATCH0_MODE_WARMBOOT BIT(0)
#define PMC_SCRATCH0_MODE_FASTBOOT (1 << 30) #define PMC_SCRATCH0_MODE_RCM BIT(1)
#define PMC_SCRATCH0_MODE_PAYLOAD (1 << 29) #define PMC_SCRATCH0_MODE_PAYLOAD BIT(29)
#define PMC_SCRATCH0_MODE_RCM (1 << 1) #define PMC_SCRATCH0_MODE_FASTBOOT BIT(30)
#define PMC_SCRATCH0_MODE_WARMBOOT (1 << 0) #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_SCRATCH1 0x54
#define APBDEV_PMC_SCRATCH20 0xA0 #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 APBDEV_PMC_PWR_DET_VAL 0xE4
#define PMC_PWR_DET_GPIO_IO_EN (1 << 21) #define PMC_PWR_DET_SDMMC1_IO_EN BIT(12)
#define PMC_PWR_DET_AUDIO_HV (1 << 18) #define PMC_PWR_DET_AUDIO_HV BIT(18)
#define PMC_PWR_DET_SDMMC1_IO_EN (1 << 12) #define PMC_PWR_DET_GPIO_IO_EN BIT(21)
#define APBDEV_PMC_DDR_PWR 0xE8 #define APBDEV_PMC_DDR_PWR 0xE8
#define APBDEV_PMC_USB_AO 0xF0 #define APBDEV_PMC_USB_AO 0xF0
#define APBDEV_PMC_CRYPTO_OP 0xF4 #define APBDEV_PMC_CRYPTO_OP 0xF4
#define PMC_CRYPTO_OP_SE_ENABLE 0 #define PMC_CRYPTO_OP_SE_ENABLE 0
#define PMC_CRYPTO_OP_SE_DISABLE 1 #define PMC_CRYPTO_OP_SE_DISABLE 1
#define APBDEV_PMC_SCRATCH33 0x120 #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_SCRATCH40 0x13C
#define APBDEV_PMC_OSC_EDPD_OVER 0x1A4 #define APBDEV_PMC_OSC_EDPD_OVER 0x1A4
#define PMC_OSC_EDPD_OVER_OSC_CTRL_OVER 0x400000 #define PMC_OSC_EDPD_OVER_OSC_CTRL_OVER 0x400000
#define APBDEV_PMC_CLK_OUT_CNTRL 0x1A8 #define APBDEV_PMC_CLK_OUT_CNTRL 0x1A8
#define PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN (1 << 2) #define PMC_CLK_OUT_CNTRL_CLK1_FORCE_EN BIT(2)
#define APBDEV_PMC_RST_STATUS 0x1B4 #define APBDEV_PMC_RST_STATUS 0x1B4
#define APBDEV_PMC_IO_DPD_REQ 0x1B8 #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_IO_DPD2_REQ 0x1C0
#define APBDEV_PMC_VDDP_SEL 0x1CC #define APBDEV_PMC_VDDP_SEL 0x1CC
#define APBDEV_PMC_DDR_CFG 0x1D0 #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_SCRATCH45 0x234
#define APBDEV_PMC_SCRATCH46 0x238 #define APBDEV_PMC_SCRATCH46 0x238
#define APBDEV_PMC_SCRATCH49 0x244 #define APBDEV_PMC_SCRATCH49 0x244
@ -83,5 +94,10 @@
#define APBDEV_PMC_SCRATCH188 0x810 #define APBDEV_PMC_SCRATCH188 0x810
#define APBDEV_PMC_SCRATCH190 0x818 #define APBDEV_PMC_SCRATCH190 0x818
#define APBDEV_PMC_SCRATCH200 0x840 #define APBDEV_PMC_SCRATCH200 0x840
#define APBDEV_PMC_TZRAM_PWR_CNTRL 0xBE8
#define APBDEV_PMC_TZRAM_SEC_DISABLE 0xBEC
#define APBDEV_PMC_TZRAM_NON_SEC_DISABLE 0xBF0
int pmc_enable_partition(u32 part, int enable);
#endif #endif

View File

@ -61,6 +61,9 @@
#define EMC_BASE 0x7001B000 #define EMC_BASE 0x7001B000
#define EMC0_BASE 0x7001E000 #define EMC0_BASE 0x7001E000
#define EMC1_BASE 0x7001F000 #define EMC1_BASE 0x7001F000
#define XUSB_HOST_BASE 0x70090000
#define XUSB_PADCTL_BASE 0x7009F000
#define XUSB_DEV_BASE 0x700D0000
#define MIPI_CAL_BASE 0x700E3000 #define MIPI_CAL_BASE 0x700E3000
#define CL_DVFS_BASE 0x70110000 #define CL_DVFS_BASE 0x70110000
#define I2S_BASE 0x702D1000 #define I2S_BASE 0x702D1000
@ -79,7 +82,7 @@
#define VIC(off) _REG(VIC_BASE, off) #define VIC(off) _REG(VIC_BASE, off)
#define TSEC(off) _REG(TSEC_BASE, off) #define TSEC(off) _REG(TSEC_BASE, off)
#define SOR1(off) _REG(SOR1_BASE, off) #define SOR1(off) _REG(SOR1_BASE, off)
#define ICTLR(cidx, off) _REG(ICTLR_BASE + (0x100 * cidx), off) #define ICTLR(cidx, off) _REG(ICTLR_BASE + (0x100 * (cidx)), off)
#define TMR(off) _REG(TMR_BASE, off) #define TMR(off) _REG(TMR_BASE, off)
#define CLOCK(off) _REG(CLOCK_BASE, off) #define CLOCK(off) _REG(CLOCK_BASE, off)
#define FLOW_CTLR(off) _REG(FLOW_CTLR_BASE, off) #define FLOW_CTLR(off) _REG(FLOW_CTLR_BASE, off)
@ -109,6 +112,12 @@
#define EMC(off) _REG(EMC_BASE, off) #define EMC(off) _REG(EMC_BASE, off)
#define EMC_CH0(off) _REG(EMC0_BASE, off) #define EMC_CH0(off) _REG(EMC0_BASE, off)
#define EMC_CH1(off) _REG(EMC1_BASE, off) #define EMC_CH1(off) _REG(EMC1_BASE, off)
#define XUSB_HOST(off) _REG(XUSB_HOST_BASE, off)
#define XUSB_PADCTL(off) _REG(XUSB_PADCTL_BASE, off)
#define XUSB_DEV(off) _REG(XUSB_DEV_BASE, off)
#define XUSB_DEV_XHCI(off) _REG(XUSB_DEV_BASE, off)
#define XUSB_DEV_PCI(off) _REG(XUSB_DEV_BASE + 0x8000, off)
#define XUSB_DEV_DEV(off) _REG(XUSB_DEV_BASE + 0x9000, off)
#define MIPI_CAL(off) _REG(MIPI_CAL_BASE, off) #define MIPI_CAL(off) _REG(MIPI_CAL_BASE, off)
#define CL_DVFS(off) _REG(CL_DVFS_BASE, off) #define CL_DVFS(off) _REG(CL_DVFS_BASE, off)
#define I2S(off) _REG(I2S_BASE, off) #define I2S(off) _REG(I2S_BASE, off)
@ -149,14 +158,33 @@
/*! AHB Gizmo registers. */ /*! AHB Gizmo registers. */
#define AHB_ARBITRATION_PRIORITY_CTRL 0x8 #define AHB_ARBITRATION_PRIORITY_CTRL 0x8
#define ARBITRATION_PRIORITY_CTRL_ENB_FAST_REARBITRATE (1 << 6) #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_GIZMO_AHB_MEM 0x10
#define AHB_MEM_ENB_FAST_REARBITRATE (1 << 2) #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_USB 0x20
#define AHB_GIZMO_USB_IMMEDIATE (1 << 18) #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_CFG1 0xF0
#define MEM_PREFETCH_ENABLE (1 << 31) #define AHB_AHB_MEM_PREFETCH_CFG2 0xF4
#define MEM_PREFETCH_AHB_MST_USB 6 #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
/*! Misc registers. */ /*! Misc registers. */
#define APB_MISC_PP_STRAPPING_OPT_A 0x08 #define APB_MISC_PP_STRAPPING_OPT_A 0x08
@ -170,19 +198,16 @@
#define APB_MISC_GP_EMMC2_PAD_CFGPADCTRL 0xA9C #define APB_MISC_GP_EMMC2_PAD_CFGPADCTRL 0xA9C
#define APB_MISC_GP_EMMC4_PAD_CFGPADCTRL 0xAB4 #define APB_MISC_GP_EMMC4_PAD_CFGPADCTRL 0xAB4
#define APB_MISC_GP_EMMC4_PAD_PUPD_CFGPADCTRL 0xABC #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_EN_CFGPADCTRL 0xB64
#define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68 #define APB_MISC_GP_WIFI_RST_CFGPADCTRL 0xB68
/*! System registers. */
#define AHB_ARBITRATION_XBAR_CTRL 0xE0
#define AHB_AHB_SPARE_REG 0x110
/*! Secure boot registers. */ /*! Secure boot registers. */
#define SB_CSR 0x0 #define SB_CSR 0x0
#define SB_CSR_NS_RST_VEC_WR_DIS (1 << 1) #define SB_CSR_NS_RST_VEC_WR_DIS BIT(1)
#define SB_CSR_PIROM_DISABLE (1 << 4) #define SB_CSR_PIROM_DISABLE BIT(4)
#define SB_AA64_RESET_LOW 0x30 #define SB_AA64_RESET_LOW 0x30
#define SB_AA64_RST_AARCH64_MODE_EN (1 << 0) #define SB_AA64_RST_AARCH64_MODE_EN BIT(0)
#define SB_AA64_RESET_HIGH 0x34 #define SB_AA64_RESET_HIGH 0x34
/*! SOR registers. */ /*! SOR registers. */
@ -217,20 +242,20 @@
#define TIMERUS_USEC_CFG (0x10 + 0x4) #define TIMERUS_USEC_CFG (0x10 + 0x4)
#define TIMER_TMR8_TMR_PTV 0x78 #define TIMER_TMR8_TMR_PTV 0x78
#define TIMER_TMR9_TMR_PTV 0x80 #define TIMER_TMR9_TMR_PTV 0x80
#define TIMER_EN (1 << 31) #define TIMER_PER_EN BIT(30)
#define TIMER_PER_EN (1 << 30) #define TIMER_EN BIT(31)
#define TIMER_TMR8_TMR_PCR 0x7C #define TIMER_TMR8_TMR_PCR 0x7C
#define TIMER_TMR9_TMR_PCR 0x8C #define TIMER_TMR9_TMR_PCR 0x8C
#define TIMER_INTR_CLR (1 << 30) #define TIMER_INTR_CLR BIT(30)
#define TIMER_WDT4_CONFIG (0x100 + 0x80) #define TIMER_WDT4_CONFIG (0x100 + 0x80)
#define TIMER_SRC(TMR) (TMR & 0xF) #define TIMER_SRC(TMR) ((TMR) & 0xF)
#define TIMER_PER(PER) ((PER & 0xFF) << 4) #define TIMER_PER(PER) (((PER) & 0xFF) << 4)
#define TIMER_SYSRESET_EN (1 << 14) #define TIMER_SYSRESET_EN BIT(14)
#define TIMER_PMCRESET_EN (1 << 15) #define TIMER_PMCRESET_EN BIT(15)
#define TIMER_WDT4_COMMAND (0x108 + 0x80) #define TIMER_WDT4_COMMAND (0x108 + 0x80)
#define TIMER_START_CNT (1 << 0) #define TIMER_START_CNT BIT(0)
#define TIMER_CNT_DISABLE (1 << 1) #define TIMER_CNT_DISABLE BIT(1)
#define TIMER_WDT4_UNLOCK_PATTERN (0x10C + 0x80) #define TIMER_WDT4_UNLOCK_PATTERN (0x10C + 0x80)
#define TIMER_MAGIC_PTRN 0xC45A #define TIMER_MAGIC_PTRN 0xC45A
@ -245,29 +270,29 @@
#define I2S4_CTRL 0x3A0 #define I2S4_CTRL 0x3A0
#define I2S5_CG 0x488 #define I2S5_CG 0x488
#define I2S5_CTRL 0x4A0 #define I2S5_CTRL 0x4A0
#define I2S_CG_SLCG_ENABLE (1 << 0) #define I2S_CG_SLCG_ENABLE BIT(0)
#define I2S_CTRL_MASTER_EN (1 << 10) #define I2S_CTRL_MASTER_EN BIT(10)
/*! PWM registers. */ /*! PWM registers. */
#define PWM_CONTROLLER_PWM_CSR_0 0x00 #define PWM_CONTROLLER_PWM_CSR_0 0x00
#define PWM_CONTROLLER_PWM_CSR_1 0x10 #define PWM_CONTROLLER_PWM_CSR_1 0x10
#define PWM_CSR_EN (1 << 31) #define PWM_CSR_EN BIT(31)
/*! Special registers. */ /*! Special registers. */
#define EMC_SCRATCH0 0x324 #define EMC_SCRATCH0 0x324
#define EMC_HEKA_UPD (1 << 30) #define EMC_HEKA_UPD BIT(30)
#define EMC_SEPT_RUN (1 << 31) #define EMC_SEPT_RUN BIT(31)
/*! Flow controller registers. */ /*! Flow controller registers. */
#define FLOW_CTLR_HALT_COP_EVENTS 0x4 #define FLOW_CTLR_HALT_COP_EVENTS 0x4
#define HALT_COP_GIC_IRQ (1 << 9) #define HALT_COP_GIC_IRQ BIT(9)
#define HALT_COP_LIC_IRQ (1 << 11) #define HALT_COP_LIC_IRQ BIT(11)
#define HALT_COP_SEC (1 << 23) #define HALT_COP_SEC BIT(23)
#define HALT_COP_MSEC (1 << 24) #define HALT_COP_MSEC BIT(24)
#define HALT_COP_USEC (1 << 25) #define HALT_COP_USEC BIT(25)
#define HALT_COP_JTAG (1 << 28) #define HALT_COP_JTAG BIT(28)
#define HALT_COP_WAIT_EVENT (1 << 30) #define HALT_COP_WAIT_EVENT BIT(30)
#define HALT_COP_STOP_UNTIL_IRQ (1 << 31) #define HALT_COP_STOP_UNTIL_IRQ BIT(31)
#define HALT_COP_MAX_CNT 0xFF #define HALT_COP_MAX_CNT 0xFF
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0 #define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14 #define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
@ -280,9 +305,4 @@
#define FLOW_CTLR_RAM_REPAIR 0x40 #define FLOW_CTLR_RAM_REPAIR 0x40
#define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98 #define FLOW_CTLR_BPMP_CLUSTER_CONTROL 0x98
/*! USB controller registers. */
#define USB1_UTMIP_BAT_CHRG_CFG0 0x830
#define BAT_CHRG_CFG0_OP_SRC_EN (1 << 3)
#define BAT_CHRG_CFG0_PWRDOWN_CHRG (1 << 0)
#endif #endif

View File

@ -136,8 +136,8 @@ c : clear by read
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */ #define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */ #define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
#define R1_ERASE_RESET (1 << 13) /* sr, c */ #define R1_ERASE_RESET (1 << 13) /* sr, c */
#define R1_STATUS(x) (x & 0xFFFFE000) #define R1_STATUS(x) ((x) & 0xFFFFE000)
#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ #define R1_CURRENT_STATE(x) (((x) & 0x00001E00) >> 9) /* sx, b (4 bits) */
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */ #define R1_READY_FOR_DATA (1 << 8) /* sx, a */
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */ #define R1_SWITCH_ERROR (1 << 7) /* sx, c */
#define R1_EXCEPTION_EVENT (1 << 6) /* sr, a */ #define R1_EXCEPTION_EVENT (1 << 6) /* sr, a */

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer * Copyright (c) 2018-2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -48,15 +48,18 @@ static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)
static int _sdmmc_storage_check_result(u32 res) static int _sdmmc_storage_check_result(u32 res)
{ {
//Error mask: //Error mask:
//R1_OUT_OF_RANGE, R1_ADDRESS_ERROR, R1_BLOCK_LEN_ERROR, //TODO: R1_SWITCH_ERROR can be skipped for certain card types.
//R1_ERASE_SEQ_ERROR, R1_ERASE_PARAM, R1_WP_VIOLATION, if (res &
//R1_LOCK_UNLOCK_FAILED, R1_COM_CRC_ERROR, R1_ILLEGAL_COMMAND, (R1_OUT_OF_RANGE | R1_ADDRESS_ERROR | R1_BLOCK_LEN_ERROR |
//R1_CARD_ECC_FAILED, R1_CC_ERROR, R1_ERROR, R1_CID_CSD_OVERWRITE, R1_ERASE_SEQ_ERROR | R1_ERASE_PARAM | R1_WP_VIOLATION |
//R1_WP_ERASE_SKIP, R1_ERASE_RESET, R1_SWITCH_ERROR R1_LOCK_UNLOCK_FAILED | R1_COM_CRC_ERROR | R1_ILLEGAL_COMMAND |
if (!(res & 0xFDF9A080)) R1_CARD_ECC_FAILED | R1_CC_ERROR | R1_ERROR |
return 1; R1_CID_CSD_OVERWRITE | R1_WP_ERASE_SKIP | R1_ERASE_RESET |
//TODO: R1_SWITCH_ERROR we can skip for certain card types. R1_SWITCH_ERROR))
return 0; return 0;
// No errors.
return 1;
} }
static int _sdmmc_storage_execute_cmd_type1_ex(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state, u32 mask) static int _sdmmc_storage_execute_cmd_type1_ex(sdmmc_storage_t *storage, u32 *resp, u32 cmd, u32 arg, u32 check_busy, u32 expected_state, u32 mask)
@ -169,14 +172,23 @@ int sdmmc_storage_end(sdmmc_storage_t *storage)
sdmmc_end(storage->sdmmc); sdmmc_end(storage->sdmmc);
storage->initialized = 0;
return 1; return 1;
} }
static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf, u32 is_write) static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf, u32 is_write)
{ {
u8 *bbuf = (u8 *)buf; u8 *bbuf = (u8 *)buf;
bool first_reinit = false; u32 sct_off = sector;
while (num_sectors) u32 sct_total = num_sectors;
bool first_reinit = true;
// Exit if not initialized.
if (!storage->initialized)
return 0;
while (sct_total)
{ {
u32 blkcnt = 0; u32 blkcnt = 0;
// Retry 5 times if failed. // Retry 5 times if failed.
@ -184,7 +196,7 @@ static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 nu
do do
{ {
reinit_try: reinit_try:
if (_sdmmc_storage_readwrite_ex(storage, &blkcnt, sector, MIN(num_sectors, 0xFFFF), bbuf, is_write)) if (_sdmmc_storage_readwrite_ex(storage, &blkcnt, sct_off, MIN(sct_total, 0xFFFF), bbuf, is_write))
goto out; goto out;
else else
retries--; retries--;
@ -201,7 +213,7 @@ reinit_try:
sd_error_count_increment(SD_ERROR_RW_FAIL); sd_error_count_increment(SD_ERROR_RW_FAIL);
if (!first_reinit) if (first_reinit)
res = sd_initialize(true); res = sd_initialize(true);
else else
{ {
@ -210,19 +222,28 @@ reinit_try:
sd_error_count_increment(SD_ERROR_INIT_FAIL); sd_error_count_increment(SD_ERROR_INIT_FAIL);
} }
// Reset values for a retry.
blkcnt = 0;
retries = 3; retries = 3;
first_reinit = true; first_reinit = false;
// If succesful reinit, restart xfer.
if (res) if (res)
{
bbuf = (u8 *)buf;
sct_off = sector;
sct_total = num_sectors;
goto reinit_try; goto reinit_try;
} }
}
// Failed.
return 0; return 0;
out: out:
DPRINTF("readwrite: %08X\n", blkcnt); sct_off += blkcnt;
sector += blkcnt; sct_total -= blkcnt;
num_sectors -= blkcnt;
bbuf += 512 * blkcnt; bbuf += 512 * blkcnt;
} }
@ -275,9 +296,11 @@ static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u
case SDMMC_POWER_1_8: case SDMMC_POWER_1_8:
arg = SD_OCR_CCS | SD_OCR_VDD_18; arg = SD_OCR_CCS | SD_OCR_VDD_18;
break; break;
case SDMMC_POWER_3_3: case SDMMC_POWER_3_3:
arg = SD_OCR_CCS | SD_OCR_VDD_27_34; arg = SD_OCR_CCS | SD_OCR_VDD_27_34;
break; break;
default: default:
return 0; return 0;
} }
@ -334,6 +357,7 @@ static void _mmc_storage_parse_cid(sdmmc_storage_t *storage)
storage->cid.fwrev = unstuff_bits(raw_cid, 40, 4); storage->cid.fwrev = unstuff_bits(raw_cid, 40, 4);
storage->cid.serial = unstuff_bits(raw_cid, 16, 24); storage->cid.serial = unstuff_bits(raw_cid, 16, 24);
break; break;
case 2: /* MMC v2.0 - v2.2 */ case 2: /* MMC v2.0 - v2.2 */
case 3: /* MMC v3.1 - v3.3 */ case 3: /* MMC v3.1 - v3.3 */
case 4: /* MMC v4 */ case 4: /* MMC v4 */
@ -343,6 +367,7 @@ static void _mmc_storage_parse_cid(sdmmc_storage_t *storage)
storage->cid.prv = unstuff_bits(raw_cid, 48, 8); storage->cid.prv = unstuff_bits(raw_cid, 48, 8);
storage->cid.serial = unstuff_bits(raw_cid, 16, 32); storage->cid.serial = unstuff_bits(raw_cid, 16, 32);
break; break;
default: default:
break; break;
} }
@ -387,6 +412,10 @@ static void _mmc_storage_parse_ext_csd(sdmmc_storage_t *storage, u8 *buf)
storage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN]; storage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN];
storage->ext_csd.bkops_status = buf[EXT_CSD_BKOPS_STATUS]; 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.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->sec_cnt = *(u32 *)&buf[EXT_CSD_SEC_CNT]; storage->sec_cnt = *(u32 *)&buf[EXT_CSD_SEC_CNT];
} }
@ -429,6 +458,7 @@ static int _mmc_storage_switch_buswidth(sdmmc_storage_t *storage, u32 bus_width)
case SDMMC_BUS_WIDTH_4: case SDMMC_BUS_WIDTH_4:
arg = SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); arg = SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
break; break;
case SDMMC_BUS_WIDTH_8: case SDMMC_BUS_WIDTH_8:
arg = SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8); arg = SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8);
break; break;
@ -487,7 +517,7 @@ static int _mmc_storage_enable_HS400(sdmmc_storage_t *storage)
if (!_mmc_storage_enable_HS200(storage)) if (!_mmc_storage_enable_HS200(storage))
return 0; return 0;
sdmmc_set_tap_value(storage->sdmmc); sdmmc_save_tap_value(storage->sdmmc);
if (!_mmc_storage_enable_HS(storage, 0)) if (!_mmc_storage_enable_HS(storage, 0))
return 0; return 0;
@ -543,7 +573,7 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_wid
storage->sdmmc = sdmmc; storage->sdmmc = sdmmc;
storage->rca = 2; //TODO: this could be a config item. storage->rca = 2; //TODO: this could be a config item.
if (!sdmmc_init(sdmmc, SDMMC_4, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_MMC_ID, SDMMC_AUTO_CAL_DISABLE)) if (!sdmmc_init(sdmmc, SDMMC_4, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_MMC_ID, SDMMC_POWER_SAVE_DISABLE))
return 0; return 0;
DPRINTF("[MMC] after init\n"); DPRINTF("[MMC] after init\n");
@ -614,7 +644,9 @@ DPRINTF("[MMC] BKOPS enabled\n");
return 0; return 0;
DPRINTF("[MMC] succesfully switched to HS mode\n"); DPRINTF("[MMC] succesfully switched to HS mode\n");
sdmmc_card_clock_ctrl(storage->sdmmc, SDMMC_AUTO_CAL_ENABLE); sdmmc_card_clock_powersave(storage->sdmmc, SDMMC_POWER_SAVE_ENABLE);
storage->initialized = 1;
return 1; return 1;
} }
@ -628,6 +660,7 @@ int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition)
return 0; return 0;
storage->partition = partition; storage->partition = partition;
return 1; return 1;
} }
@ -666,7 +699,7 @@ static int _sd_storage_send_if_cond(sdmmc_storage_t *storage)
return (resp & 0xFF) == 0xAA ? 0 : 2; return (resp & 0xFF) == 0xAA ? 0 : 2;
} }
static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int is_version_1, int supports_low_voltage) static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int is_version_1, int bus_low_voltage_support)
{ {
sdmmc_cmd_t cmdbuf; sdmmc_cmd_t cmdbuf;
// Support for Current > 150mA // Support for Current > 150mA
@ -674,7 +707,7 @@ static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int
// Support for handling block-addressed SDHC cards // Support for handling block-addressed SDHC cards
arg |= (~is_version_1 & 1) ? SD_OCR_CCS : 0; arg |= (~is_version_1 & 1) ? SD_OCR_CCS : 0;
// Support for 1.8V // Support for 1.8V
arg |= (supports_low_voltage & ~is_version_1 & 1) ? SD_OCR_S18R : 0; arg |= (bus_low_voltage_support & ~is_version_1 & 1) ? SD_OCR_S18R : 0;
// This is needed for most cards. Do not set bit7 even if 1.8V is supported. // This is needed for most cards. Do not set bit7 even if 1.8V is supported.
arg |= SD_OCR_VDD_32_33; arg |= SD_OCR_VDD_32_33;
sdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0); sdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);
@ -684,22 +717,24 @@ static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int
return sdmmc_get_rsp(storage->sdmmc, cond, 4, SDMMC_RSP_TYPE_3); return sdmmc_get_rsp(storage->sdmmc, cond, 4, SDMMC_RSP_TYPE_3);
} }
static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, int supports_low_voltage) static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, int bus_low_voltage_support)
{ {
u32 timeout = get_tmr_ms() + 1500; u32 timeout = get_tmr_ms() + 1500;
while (1) while (1)
{ {
u32 cond = 0; u32 cond = 0;
if (!_sd_storage_get_op_cond_once(storage, &cond, is_version_1, supports_low_voltage)) if (!_sd_storage_get_op_cond_once(storage, &cond, is_version_1, bus_low_voltage_support))
break; break;
if (cond & MMC_CARD_BUSY) if (cond & MMC_CARD_BUSY)
{ {
DPRINTF("[SD] cond: %08X, lv: %d\n", cond, bus_low_voltage_support);
if (cond & SD_OCR_CCS) if (cond & SD_OCR_CCS)
storage->has_sector_access = 1; storage->has_sector_access = 1;
// Check if card supports 1.8V signaling. // Check if card supports 1.8V signaling.
if (cond & SD_ROCR_S18A && supports_low_voltage) if (cond & SD_ROCR_S18A && bus_low_voltage_support)
{ {
//The low voltage regulator configuration is valid for SDMMC1 only. //The low voltage regulator configuration is valid for SDMMC1 only.
if (storage->sdmmc->id == SDMMC_1 && if (storage->sdmmc->id == SDMMC_1 &&
@ -712,6 +747,10 @@ static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, i
DPRINTF("-> switched to low voltage\n"); DPRINTF("-> switched to low voltage\n");
} }
} }
else
{
DPRINTF("[SD] no low voltage support\n");
}
return 1; return 1;
} }
@ -867,12 +906,15 @@ void _sd_storage_set_current_limit(sdmmc_storage_t *storage, u16 current_limit,
case SD_SET_CURRENT_LIMIT_800: case SD_SET_CURRENT_LIMIT_800:
DPRINTF("[SD] power limit raised to 800mA\n"); DPRINTF("[SD] power limit raised to 800mA\n");
break; break;
case SD_SET_CURRENT_LIMIT_600: case SD_SET_CURRENT_LIMIT_600:
DPRINTF("[SD] power limit raised to 600mA\n"); DPRINTF("[SD] power limit raised to 600mA\n");
break; break;
case SD_SET_CURRENT_LIMIT_400: case SD_SET_CURRENT_LIMIT_400:
DPRINTF("[SD] power limit raised to 400mA\n"); DPRINTF("[SD] power limit raised to 400mA\n");
break; break;
default: default:
case SD_SET_CURRENT_LIMIT_200: case SD_SET_CURRENT_LIMIT_200:
DPRINTF("[SD] power limit defaulted to 200mA\n"); DPRINTF("[SD] power limit defaulted to 200mA\n");
@ -885,7 +927,7 @@ 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, 0, hs_type))
return 0; return 0;
DPRINTF("[SD] supports switch to (U)HS mode\n"); DPRINTF("[SD] supports (U)HS mode: %d\n", buf[16] & 0xF);
u32 type_out = buf[16] & 0xF; u32 type_out = buf[16] & 0xF;
if (type_out != hs_type) if (type_out != hs_type)
@ -921,6 +963,7 @@ int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf)
u8 access_mode = buf[13]; u8 access_mode = buf[13];
u16 current_limit = buf[7] | buf[6] << 8; u16 current_limit = buf[7] | buf[6] << 8;
DPRINTF("[SD] access: %02X, current: %02X\n", access_mode, current_limit);
// Try to raise the current limit to let the card perform better. // Try to raise the current limit to let the card perform better.
_sd_storage_set_current_limit(storage, current_limit, buf); _sd_storage_set_current_limit(storage, current_limit, buf);
@ -959,7 +1002,7 @@ DPRINTF("[SD] bus speed set to SDR50\n");
if (access_mode & SD_MODE_UHS_SDR25) if (access_mode & SD_MODE_UHS_SDR25)
{ {
type = SDHCI_TIMING_UHS_SDR25; type = SDHCI_TIMING_UHS_SDR25;
hs_type = UHS_SDR50_BUS_SPEED; hs_type = UHS_SDR25_BUS_SPEED;
DPRINTF("[SD] bus speed set to SDR25\n"); DPRINTF("[SD] bus speed set to SDR25\n");
storage->csd.busspeed = 25; storage->csd.busspeed = 25;
break; break;
@ -972,6 +1015,7 @@ DPRINTF("[SD] bus speed set to SDR25\n");
DPRINTF("[SD] bus speed set to SDR12\n"); DPRINTF("[SD] bus speed set to SDR12\n");
storage->csd.busspeed = 12; storage->csd.busspeed = 12;
break; break;
default: default:
return 0; return 0;
break; break;
@ -982,10 +1026,10 @@ DPRINTF("[SD] bus speed set to SDR12\n");
DPRINTF("[SD] card accepted UHS\n"); DPRINTF("[SD] card accepted UHS\n");
if (!sdmmc_setup_clock(storage->sdmmc, type)) if (!sdmmc_setup_clock(storage->sdmmc, type))
return 0; return 0;
DPRINTF("[SD] setup clock\n"); DPRINTF("[SD] after setup clock\n");
if (!sdmmc_tuning_execute(storage->sdmmc, type, MMC_SEND_TUNING_BLOCK)) if (!sdmmc_tuning_execute(storage->sdmmc, type, MMC_SEND_TUNING_BLOCK))
return 0; return 0;
DPRINTF("[SD] config tuning\n"); DPRINTF("[SD] after tuning\n");
return _sdmmc_storage_check_status(storage); return _sdmmc_storage_check_status(storage);
} }
@ -1030,23 +1074,30 @@ static void _sd_storage_parse_ssr(sdmmc_storage_t *storage)
raw_ssr2[0] = *(u32 *)&storage->raw_ssr[16]; raw_ssr2[0] = *(u32 *)&storage->raw_ssr[16];
storage->ssr.bus_width = (unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4) ? 4 : 1; storage->ssr.bus_width = (unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4) ? 4 : 1;
storage->ssr.protected_size = unstuff_bits(raw_ssr1, 448 - 384, 32);
switch(unstuff_bits(raw_ssr1, 440 - 384, 8)) switch(unstuff_bits(raw_ssr1, 440 - 384, 8))
{ {
case 0: case 0:
storage->ssr.speed_class = 0; storage->ssr.speed_class = 0;
break; break;
case 1: case 1:
storage->ssr.speed_class = 2; storage->ssr.speed_class = 2;
break; break;
case 2: case 2:
storage->ssr.speed_class = 4; storage->ssr.speed_class = 4;
break; break;
case 3: case 3:
storage->ssr.speed_class = 6; storage->ssr.speed_class = 6;
break; break;
case 4: case 4:
storage->ssr.speed_class = 10; storage->ssr.speed_class = 10;
break; break;
default: default:
storage->ssr.speed_class = unstuff_bits(raw_ssr1, 440 - 384, 8); storage->ssr.speed_class = unstuff_bits(raw_ssr1, 440 - 384, 8);
break; break;
@ -1126,6 +1177,7 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage)
case 0: case 0:
storage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2); storage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2);
break; break;
case 1: case 1:
storage->csd.c_size = (1 + unstuff_bits(raw_csd, 48, 22)); storage->csd.c_size = (1 + unstuff_bits(raw_csd, 48, 22));
storage->csd.capacity = storage->csd.c_size << 10; storage->csd.capacity = storage->csd.c_size << 10;
@ -1134,7 +1186,7 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage)
} }
} }
static bool _sdmmc_storage_supports_low_voltage(u32 bus_width, u32 type) static bool _sdmmc_storage_get_low_voltage_support(u32 bus_width, u32 type)
{ {
switch (type) switch (type)
{ {
@ -1153,9 +1205,10 @@ static bool _sdmmc_storage_supports_low_voltage(u32 bus_width, u32 type)
void sdmmc_storage_init_wait_sd() void sdmmc_storage_init_wait_sd()
{ {
// T210/T210B01 WAR: Wait exactly 239ms for IO and Controller power to discharge.
u32 sd_poweroff_time = (u32)get_tmr_ms() - sd_power_cycle_time_start; u32 sd_poweroff_time = (u32)get_tmr_ms() - sd_power_cycle_time_start;
if (sd_poweroff_time < 100) if (sd_poweroff_time < 239)
msleep(100 - sd_poweroff_time); msleep(239 - sd_poweroff_time);
} }
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type) int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type)
@ -1163,13 +1216,15 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
int is_version_1 = 0; int is_version_1 = 0;
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; u8 *buf = (u8 *)SDMMC_UPPER_BUFFER;
DPRINTF("[SD] init: bus: %d, type: %d\n", bus_width, type);
// Some cards (SanDisk U1), do not like a fast power cycle. Wait min 100ms. // Some cards (SanDisk U1), do not like a fast power cycle. Wait min 100ms.
sdmmc_storage_init_wait_sd(); sdmmc_storage_init_wait_sd();
memset(storage, 0, sizeof(sdmmc_storage_t)); memset(storage, 0, sizeof(sdmmc_storage_t));
storage->sdmmc = sdmmc; storage->sdmmc = sdmmc;
if (!sdmmc_init(sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, SDMMC_AUTO_CAL_DISABLE)) if (!sdmmc_init(sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, SDHCI_TIMING_SD_ID, SDMMC_POWER_SAVE_DISABLE))
return 0; return 0;
DPRINTF("[SD] after init\n"); DPRINTF("[SD] after init\n");
@ -1184,9 +1239,9 @@ DPRINTF("[SD] went to idle state\n");
return 0; return 0;
DPRINTF("[SD] after send if cond\n"); DPRINTF("[SD] after send if cond\n");
bool supports_low_voltage = _sdmmc_storage_supports_low_voltage(bus_width, type); bool bus_low_voltage_support = _sdmmc_storage_get_low_voltage_support(bus_width, type);
if (!_sd_storage_get_op_cond(storage, is_version_1, supports_low_voltage)) if (!_sd_storage_get_op_cond(storage, is_version_1, bus_low_voltage_support))
return 0; return 0;
DPRINTF("[SD] got op cond\n"); DPRINTF("[SD] got op cond\n");
@ -1264,7 +1319,7 @@ DPRINTF("[SD] SD does not support wide bus width\n");
return 0; return 0;
DPRINTF("[SD] enabled UHS\n"); DPRINTF("[SD] enabled UHS\n");
sdmmc_card_clock_ctrl(sdmmc, SDMMC_AUTO_CAL_ENABLE); sdmmc_card_clock_powersave(sdmmc, SDMMC_POWER_SAVE_ENABLE);
} }
else if (type != SDHCI_TIMING_SD_DS12 && (storage->scr.sda_vsn & 0xF) != 0) else if (type != SDHCI_TIMING_SD_DS12 && (storage->scr.sda_vsn & 0xF) != 0)
{ {
@ -1277,6 +1332,7 @@ DPRINTF("[SD] enabled HS\n");
case SDMMC_BUS_WIDTH_4: case SDMMC_BUS_WIDTH_4:
storage->csd.busspeed = 25; storage->csd.busspeed = 25;
break; break;
case SDMMC_BUS_WIDTH_1: case SDMMC_BUS_WIDTH_1:
storage->csd.busspeed = 6; storage->csd.busspeed = 6;
break; break;
@ -1289,6 +1345,8 @@ DPRINTF("[SD] enabled HS\n");
DPRINTF("[SD] got sd status\n"); DPRINTF("[SD] got sd status\n");
} }
storage->initialized = 1;
return 1; return 1;
} }
@ -1328,17 +1386,19 @@ int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc)
memset(storage, 0, sizeof(sdmmc_storage_t)); memset(storage, 0, sizeof(sdmmc_storage_t));
storage->sdmmc = sdmmc; storage->sdmmc = sdmmc;
if (!sdmmc_init(sdmmc, SDMMC_2, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_DDR52, SDMMC_AUTO_CAL_DISABLE)) if (!sdmmc_init(sdmmc, SDMMC_2, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS102, SDMMC_POWER_SAVE_DISABLE))
return 0; return 0;
DPRINTF("[gc] after init\n"); DPRINTF("[gc] after init\n");
usleep(1000 + (10000 + sdmmc->divisor - 1) / sdmmc->divisor); usleep(1000 + (10000 + sdmmc->divisor - 1) / sdmmc->divisor);
if (!sdmmc_tuning_execute(storage->sdmmc, SDHCI_TIMING_MMC_DDR52, MMC_SEND_TUNING_BLOCK_HS200)) if (!sdmmc_tuning_execute(storage->sdmmc, SDHCI_TIMING_MMC_HS102, MMC_SEND_TUNING_BLOCK_HS200))
return 0; return 0;
DPRINTF("[gc] after tuning\n"); DPRINTF("[gc] after tuning\n");
sdmmc_card_clock_ctrl(sdmmc, SDMMC_AUTO_CAL_ENABLE); sdmmc_card_clock_powersave(sdmmc, SDMMC_POWER_SAVE_ENABLE);
storage->initialized = 1;
return 1; return 1;
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 CTCaer * Copyright (c) 2018-2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -65,16 +65,19 @@ typedef struct _mmc_csd
typedef struct _mmc_ext_csd typedef struct _mmc_ext_csd
{ {
u8 rev;
u32 sectors; u32 sectors;
int bkops; /* background support bit */ int bkops; /* background support bit */
int bkops_en; /* manual bkops enable bit */ int bkops_en; /* manual bkops enable bit */
u8 rev;
u8 ext_struct; /* 194 */ u8 ext_struct; /* 194 */
u8 card_type; /* 196 */ u8 card_type; /* 196 */
u8 bkops_status; /* 246 */ u8 bkops_status; /* 246 */
u16 dev_version; u8 pre_eol_info;
u8 dev_life_est_a;
u8 dev_life_est_b;
u8 boot_mult; u8 boot_mult;
u8 rpmb_mult; u8 rpmb_mult;
u16 dev_version;
} mmc_ext_csd_t; } mmc_ext_csd_t;
typedef struct _sd_scr typedef struct _sd_scr
@ -92,6 +95,7 @@ typedef struct _sd_ssr
u8 uhs_grade; u8 uhs_grade;
u8 video_class; u8 video_class;
u8 app_class; u8 app_class;
u32 protected_size;
} sd_ssr_t; } sd_ssr_t;
/*! SDMMC storage context. */ /*! SDMMC storage context. */
@ -112,6 +116,7 @@ typedef struct _sdmmc_storage_t
mmc_ext_csd_t ext_csd; mmc_ext_csd_t ext_csd;
sd_scr_t scr; sd_scr_t scr;
sd_ssr_t ssr; sd_ssr_t ssr;
int initialized;
} sdmmc_storage_t; } sdmmc_storage_t;
int sdmmc_storage_end(sdmmc_storage_t *storage); int sdmmc_storage_end(sdmmc_storage_t *storage);

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer * Copyright (c) 2018-2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -24,6 +24,7 @@
#include <soc/bpmp.h> #include <soc/bpmp.h>
#include <soc/clock.h> #include <soc/clock.h>
#include <soc/gpio.h> #include <soc/gpio.h>
#include <soc/hw_init.h>
#include <soc/pinmux.h> #include <soc/pinmux.h>
#include <soc/pmc.h> #include <soc/pmc.h>
#include <soc/t210.h> #include <soc/t210.h>
@ -65,12 +66,15 @@ static int _sdmmc_set_io_power(sdmmc_t *sdmmc, u32 power)
case SDMMC_POWER_OFF: case SDMMC_POWER_OFF:
sdmmc->regs->pwrcon &= ~SDHCI_POWER_ON; sdmmc->regs->pwrcon &= ~SDHCI_POWER_ON;
break; break;
case SDMMC_POWER_1_8: case SDMMC_POWER_1_8:
sdmmc->regs->pwrcon = SDHCI_POWER_180; sdmmc->regs->pwrcon = SDHCI_POWER_180;
break; break;
case SDMMC_POWER_3_3: case SDMMC_POWER_3_3:
sdmmc->regs->pwrcon = SDHCI_POWER_330; sdmmc->regs->pwrcon = SDHCI_POWER_330;
break; break;
default: default:
return 0; return 0;
} }
@ -103,7 +107,7 @@ void sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width)
sdmmc->regs->hostctl = host_control | SDHCI_CTRL_8BITBUS; sdmmc->regs->hostctl = host_control | SDHCI_CTRL_8BITBUS;
} }
void sdmmc_set_tap_value(sdmmc_t *sdmmc) void sdmmc_save_tap_value(sdmmc_t *sdmmc)
{ {
sdmmc->venclkctl_tap = sdmmc->regs->venclkctl >> 16; sdmmc->venclkctl_tap = sdmmc->regs->venclkctl >> 16;
sdmmc->venclkctl_set = 1; sdmmc->venclkctl_set = 1;
@ -112,7 +116,7 @@ void sdmmc_set_tap_value(sdmmc_t *sdmmc)
static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type) static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
{ {
const u32 dqs_trim_val = 0x28; const u32 dqs_trim_val = 0x28;
const u32 tap_values[] = { 4, 0, 3, 0 }; const u32 tap_values_t210[] = { 4, 0, 3, 0 };
u32 tap_val = 0; u32 tap_val = 0;
@ -129,36 +133,49 @@ static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
tap_val = sdmmc->venclkctl_tap; tap_val = sdmmc->venclkctl_tap;
} }
else else
{ tap_val = sdmmc->t210b01 ? 11 : tap_values_t210[sdmmc->id];
tap_val = tap_values[sdmmc->id];
}
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap_val << 16); sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap_val << 16);
return 1; return 1;
} }
static int _sdmmc_get_clkcon(sdmmc_t *sdmmc) static int _sdmmc_commit_changes(sdmmc_t *sdmmc)
{ {
return sdmmc->regs->clkcon; return sdmmc->regs->clkcon;
} }
static void _sdmmc_pad_config_fallback(sdmmc_t *sdmmc, u32 power) static void _sdmmc_pad_config_fallback(sdmmc_t *sdmmc, u32 power)
{ {
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
switch (sdmmc->id) switch (sdmmc->id)
{ {
case SDMMC_1: // 33 Ohm 2X Driver. case SDMMC_1: // 33 Ohm 2X Driver.
if (power == SDMMC_POWER_OFF) if (power == SDMMC_POWER_OFF)
break; break;
u32 sdmmc1_pad_cfg = APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) & 0xF8080FFF; u32 sdmmc1_pad_cfg = APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) & 0xF8080FFF;
if (power == SDMMC_POWER_1_8) if (sdmmc->t210b01)
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = sdmmc1_pad_cfg | (0xB0F << 12); // Up: 11, Dn: 15. For 33 ohm. sdmmc1_pad_cfg |= (0x808 << 12); // Up: 8, Dn: 8. For 33 ohm.
else if (power == SDMMC_POWER_1_8)
sdmmc1_pad_cfg |= (0xB0F << 12); // Up: 11, Dn: 15. For 33 ohm.
else if (power == SDMMC_POWER_3_3) else if (power == SDMMC_POWER_3_3)
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = sdmmc1_pad_cfg | (0xC0C << 12); // Up: 12, Dn: 12. For 33 ohm. sdmmc1_pad_cfg |= (0xC0C << 12); // Up: 12, Dn: 12. For 33 ohm.
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = sdmmc1_pad_cfg;
(void)APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL); // Commit write.
break; break;
case SDMMC_2: case SDMMC_2:
case SDMMC_4: // 50 Ohm 2X Driver. PU:16, PD:16. if (sdmmc->t210b01)
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0xFFFFC003) | 0x1040; APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) & 0xF8080FFF) | 0xA0A000;
else
APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) & 0xFFFFC003) | 0x1040; // PU:16, PD:16.
(void)APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL);
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);
(void)APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL); // Commit write.
break; break;
} }
} }
@ -176,13 +193,13 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
if (!(sdmmc->regs->sdmemcmppadctl & TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD)) if (!(sdmmc->regs->sdmemcmppadctl & TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD))
{ {
sdmmc->regs->sdmemcmppadctl |= TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD; sdmmc->regs->sdmemcmppadctl |= TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD;
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
usleep(1); usleep(1);
} }
// Enable auto calibration and start auto configuration. // Enable auto calibration and start auto configuration.
sdmmc->regs->autocalcfg |= TEGRA_MMC_AUTOCALCFG_AUTO_CAL_ENABLE | TEGRA_MMC_AUTOCALCFG_AUTO_CAL_START; sdmmc->regs->autocalcfg |= TEGRA_MMC_AUTOCALCFG_AUTO_CAL_ENABLE | TEGRA_MMC_AUTOCALCFG_AUTO_CAL_START;
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
usleep(2); usleep(2);
u32 timeout = get_tmr_ms() + 10; u32 timeout = get_tmr_ms() + 10;
@ -194,24 +211,18 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
break; break;
} }
} }
/*
// Check if PU results are inside limits. #ifdef ERROR_EXTRA_PRINTING
// SDMMC1: CZ pads - 7-bit PU. SDMMC2/4: LV_CZ pads - 5-bit PU. // Check if Comp pad is open or short to ground.
u8 autocal_pu_status = sdmmc->regs->autocalsts & 0x7F; // SDMMC1: CZ pads - T210/T210B01: 7-bit/5-bit. SDMMC2/4: LV_CZ pads - 5-bit.
switch (sdmmc->id) u8 code_mask = (sdmmc->t210b01 || sdmmc->id != SDMMC_1) ? 0x1F : 0x7F;
{ u8 autocal_pu_status = sdmmc->regs->autocalsts & code_mask;
case SDMMC_1: if (!autocal_pu_status)
if (!autocal_pu_status || autocal_pu_status == 0x7F) EPRINTF("SDMMC: Comp Pad short to gnd!");
timeout = 0; else if (autocal_pu_status == code_mask)
break; EPRINTF("SDMMC: Comp Pad open!");
case SDMMC_2: #endif
case SDMMC_4:
autocal_pu_status &= 0x1F;
if (!autocal_pu_status || autocal_pu_status == 0x1F)
timeout = 0;
break;
}
*/
// In case auto calibration fails, we load suggested standard values. // In case auto calibration fails, we load suggested standard values.
if (!timeout) if (!timeout)
{ {
@ -241,12 +252,13 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
} }
#ifdef SDMMC_EMMC_OC #ifdef SDMMC_EMMC_OC
// Add -4 TX_DLY_CODE_OFFSET if HS533.
if (sdmmc->id == SDMMC_4 && overclock) if (sdmmc->id == SDMMC_4 && overclock)
sdmmc->regs->vendllcalcfg = sdmmc->regs->vendllcalcfg &= 0xFFFFC07F | (0x7C << 7); // Add -4 TX_DLY_CODE_OFFSET if HS533. sdmmc->regs->vendllcalcfg = sdmmc->regs->vendllcalcfg &= 0xFFFFC07F | (0x7C << 7);
#endif #endif
sdmmc->regs->vendllcalcfg |= TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE; sdmmc->regs->vendllcalcfg |= TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE;
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
u32 timeout = get_tmr_ms() + 5; u32 timeout = get_tmr_ms() + 5;
while (sdmmc->regs->vendllcalcfg & TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE) while (sdmmc->regs->vendllcalcfg & TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE)
@ -277,12 +289,21 @@ out:;
static void _sdmmc_reset(sdmmc_t *sdmmc) static void _sdmmc_reset(sdmmc_t *sdmmc)
{ {
sdmmc->regs->swrst |= SDHCI_RESET_CMD | SDHCI_RESET_DATA; sdmmc->regs->swrst |= SDHCI_RESET_CMD | SDHCI_RESET_DATA;
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
u32 timeout = get_tmr_ms() + 2000; u32 timeout = get_tmr_ms() + 2000;
while ((sdmmc->regs->swrst & (SDHCI_RESET_CMD | SDHCI_RESET_DATA)) && get_tmr_ms() < timeout) while ((sdmmc->regs->swrst & (SDHCI_RESET_CMD | SDHCI_RESET_DATA)) && get_tmr_ms() < timeout)
; ;
} }
static void _sdmmc_reset_all(sdmmc_t *sdmmc)
{
sdmmc->regs->swrst |= SDHCI_RESET_ALL;
_sdmmc_commit_changes(sdmmc);
u32 timeout = get_tmr_ms() + 2000;//100ms
while ((sdmmc->regs->swrst & SDHCI_RESET_ALL) && get_tmr_ms() < timeout)
;
}
int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
{ {
// Disable the SD clock if it was enabled, and reenable it later. // Disable the SD clock if it was enabled, and reenable it later.
@ -306,36 +327,41 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
sdmmc->regs->hostctl &= ~SDHCI_CTRL_HISPD; sdmmc->regs->hostctl &= ~SDHCI_CTRL_HISPD;
sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_VDD_180; sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_VDD_180;
break; break;
case SDHCI_TIMING_MMC_HS52: case SDHCI_TIMING_MMC_HS52:
case SDHCI_TIMING_SD_HS25: case SDHCI_TIMING_SD_HS25:
sdmmc->regs->hostctl |= SDHCI_CTRL_HISPD; sdmmc->regs->hostctl |= SDHCI_CTRL_HISPD;
sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_VDD_180; sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_VDD_180;
break; break;
case SDHCI_TIMING_MMC_HS200: case SDHCI_TIMING_MMC_HS200:
case SDHCI_TIMING_UHS_SDR50: // T210 Errata for SDR50, the host must be set to SDR104. case SDHCI_TIMING_UHS_SDR50: // T210 Errata for SDR50, the host must be set to SDR104.
case SDHCI_TIMING_UHS_SDR104: case SDHCI_TIMING_UHS_SDR104:
case SDHCI_TIMING_UHS_SDR82: case SDHCI_TIMING_UHS_SDR82:
case SDHCI_TIMING_UHS_DDR50: case SDHCI_TIMING_UHS_DDR50:
case SDHCI_TIMING_MMC_DDR52: case SDHCI_TIMING_MMC_HS102:
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR104_BUS_SPEED; sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR104_BUS_SPEED;
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
break; break;
case SDHCI_TIMING_MMC_HS400: case SDHCI_TIMING_MMC_HS400:
// Non standard. // 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; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
break; break;
case SDHCI_TIMING_UHS_SDR25: 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; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
break; break;
case SDHCI_TIMING_UHS_SDR12: 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; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
break; break;
} }
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
u32 clock; u32 clock;
u16 divisor; u16 divisor;
@ -373,10 +399,10 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
static void _sdmmc_card_clock_enable(sdmmc_t *sdmmc) static void _sdmmc_card_clock_enable(sdmmc_t *sdmmc)
{ {
// Recalibrate conditionally. // Recalibrate conditionally.
if ((sdmmc->id == SDMMC_1) && !sdmmc->auto_cal_enabled) if (sdmmc->manual_cal && !sdmmc->powersave_enabled)
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc)); _sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
if (!sdmmc->auto_cal_enabled) if (!sdmmc->powersave_enabled)
{ {
if (!(sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN)) if (!(sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN))
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN; sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
@ -390,17 +416,16 @@ static void _sdmmc_sd_clock_disable(sdmmc_t *sdmmc)
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN; sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
} }
void sdmmc_card_clock_ctrl(sdmmc_t *sdmmc, int auto_cal_enable) void sdmmc_card_clock_powersave(sdmmc_t *sdmmc, int powersave_enable)
{ {
// Recalibrate periodically for SDMMC1. // Recalibrate periodically for SDMMC1.
if ((sdmmc->id == SDMMC_1) && !auto_cal_enable && sdmmc->card_clock_enabled) if (sdmmc->manual_cal && !powersave_enable && sdmmc->card_clock_enabled)
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc)); _sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
sdmmc->auto_cal_enabled = auto_cal_enable; sdmmc->powersave_enabled = powersave_enable;
if (auto_cal_enable) if (powersave_enable)
{ {
if (!(sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN)) if (sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN)
return;
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN; sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
return; return;
} }
@ -422,6 +447,7 @@ static int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
return 0; return 0;
rsp[0] = sdmmc->regs->rspreg0; rsp[0] = sdmmc->regs->rspreg0;
break; break;
case SDMMC_RSP_TYPE_2: case SDMMC_RSP_TYPE_2:
if (size < 0x10) if (size < 0x10)
return 0; return 0;
@ -450,9 +476,9 @@ static int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
rsp[i - 1] |= (tempreg >> 24) & 0xFF; rsp[i - 1] |= (tempreg >> 24) & 0xFF;
} }
break; break;
default: default:
return 0; return 0;
break;
} }
return 1; return 1;
@ -473,6 +499,7 @@ int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
return 0; return 0;
rsp[0] = sdmmc->rsp[0]; rsp[0] = sdmmc->rsp[0];
break; break;
case SDMMC_RSP_TYPE_2: case SDMMC_RSP_TYPE_2:
if (size < 0x10) if (size < 0x10)
return 0; return 0;
@ -481,9 +508,9 @@ int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
rsp[2] = sdmmc->rsp[2]; rsp[2] = sdmmc->rsp[2];
rsp[3] = sdmmc->rsp[3]; rsp[3] = sdmmc->rsp[3];
break; break;
default: default:
return 0; return 0;
break;
} }
return 1; return 1;
@ -491,7 +518,7 @@ int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type)
static int _sdmmc_wait_cmd_data_inhibit(sdmmc_t *sdmmc, bool wait_dat) static int _sdmmc_wait_cmd_data_inhibit(sdmmc_t *sdmmc, bool wait_dat)
{ {
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
u32 timeout = get_tmr_ms() + 2000; u32 timeout = get_tmr_ms() + 2000;
while(sdmmc->regs->prnsts & SDHCI_CMD_INHIBIT) while(sdmmc->regs->prnsts & SDHCI_CMD_INHIBIT)
@ -517,7 +544,7 @@ static int _sdmmc_wait_cmd_data_inhibit(sdmmc_t *sdmmc, bool wait_dat)
static int _sdmmc_wait_card_busy(sdmmc_t *sdmmc) static int _sdmmc_wait_card_busy(sdmmc_t *sdmmc)
{ {
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
u32 timeout = get_tmr_ms() + 2000; u32 timeout = get_tmr_ms() + 2000;
while (!(sdmmc->regs->prnsts & SDHCI_DATA_0_LVL_MASK)) while (!(sdmmc->regs->prnsts & SDHCI_DATA_0_LVL_MASK))
@ -536,16 +563,19 @@ static int _sdmmc_setup_read_small_block(sdmmc_t *sdmmc)
{ {
case SDMMC_BUS_WIDTH_1: case SDMMC_BUS_WIDTH_1:
return 0; return 0;
break;
case SDMMC_BUS_WIDTH_4: case SDMMC_BUS_WIDTH_4:
sdmmc->regs->blksize = 64; sdmmc->regs->blksize = 64;
break; break;
case SDMMC_BUS_WIDTH_8: case SDMMC_BUS_WIDTH_8:
sdmmc->regs->blksize = 128; sdmmc->regs->blksize = 128;
break; break;
} }
sdmmc->regs->blkcnt = 1; sdmmc->regs->blkcnt = 1;
sdmmc->regs->trnmod = SDHCI_TRNS_READ; sdmmc->regs->trnmod = SDHCI_TRNS_READ;
return 1; return 1;
} }
@ -557,6 +587,7 @@ static int _sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, bool is_data_presen
{ {
case SDMMC_RSP_TYPE_0: case SDMMC_RSP_TYPE_0:
break; break;
case SDMMC_RSP_TYPE_1: case SDMMC_RSP_TYPE_1:
case SDMMC_RSP_TYPE_4: case SDMMC_RSP_TYPE_4:
case SDMMC_RSP_TYPE_5: case SDMMC_RSP_TYPE_5:
@ -565,15 +596,17 @@ static int _sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, bool is_data_presen
else else
cmdflags = SDHCI_CMD_RESP_LEN48 | SDHCI_CMD_INDEX | SDHCI_CMD_CRC; cmdflags = SDHCI_CMD_RESP_LEN48 | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
break; break;
case SDMMC_RSP_TYPE_2: case SDMMC_RSP_TYPE_2:
cmdflags = SDHCI_CMD_RESP_LEN136 | SDHCI_CMD_CRC; cmdflags = SDHCI_CMD_RESP_LEN136 | SDHCI_CMD_CRC;
break; break;
case SDMMC_RSP_TYPE_3: case SDMMC_RSP_TYPE_3:
cmdflags = SDHCI_CMD_RESP_LEN48; cmdflags = SDHCI_CMD_RESP_LEN48;
break; break;
default: default:
return 0; return 0;
break;
} }
if (is_data_present) if (is_data_present)
@ -596,7 +629,7 @@ static void _sdmmc_send_tuning_cmd(sdmmc_t *sdmmc, u32 cmd)
static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd) static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd)
{ {
if (sdmmc->auto_cal_enabled) if (sdmmc->powersave_enabled)
return 0; return 0;
if (!_sdmmc_wait_cmd_data_inhibit(sdmmc, true)) if (!_sdmmc_wait_cmd_data_inhibit(sdmmc, true))
return 0; return 0;
@ -608,13 +641,13 @@ static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd)
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN; sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
_sdmmc_send_tuning_cmd(sdmmc, cmd); _sdmmc_send_tuning_cmd(sdmmc, cmd);
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
usleep(1); usleep(1);
_sdmmc_reset(sdmmc); _sdmmc_reset(sdmmc);
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN; sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
u32 timeout = get_tmr_us() + 5000; u32 timeout = get_tmr_us() + 5000;
while (get_tmr_us() < timeout) while (get_tmr_us() < timeout)
@ -623,7 +656,7 @@ static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd)
{ {
sdmmc->regs->norintsts = SDHCI_INT_DATA_AVAIL; sdmmc->regs->norintsts = SDHCI_INT_DATA_AVAIL;
sdmmc->regs->norintstsen &= ~SDHCI_INT_DATA_AVAIL; sdmmc->regs->norintstsen &= ~SDHCI_INT_DATA_AVAIL;
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
usleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor); usleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor);
return 1; return 1;
} }
@ -632,7 +665,7 @@ static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd)
_sdmmc_reset(sdmmc); _sdmmc_reset(sdmmc);
sdmmc->regs->norintstsen &= ~SDHCI_INT_DATA_AVAIL; sdmmc->regs->norintstsen &= ~SDHCI_INT_DATA_AVAIL;
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
usleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor); usleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor);
return 0; return 0;
@ -651,15 +684,18 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd)
max = 128; max = 128;
flag = (2 << 13); // 128 iterations. flag = (2 << 13); // 128 iterations.
break; break;
case SDHCI_TIMING_UHS_SDR50: case SDHCI_TIMING_UHS_SDR50:
case SDHCI_TIMING_UHS_DDR50: case SDHCI_TIMING_UHS_DDR50:
case SDHCI_TIMING_MMC_DDR52: case SDHCI_TIMING_MMC_HS102:
max = 256; max = 256;
flag = (4 << 13); // 256 iterations. flag = (4 << 13); // 256 iterations.
break; break;
case SDHCI_TIMING_UHS_SDR12: case SDHCI_TIMING_UHS_SDR12:
case SDHCI_TIMING_UHS_SDR25: case SDHCI_TIMING_UHS_SDR25:
return 1; return 1;
default: default:
return 0; return 0;
} }
@ -688,7 +724,7 @@ static int _sdmmc_enable_internal_clock(sdmmc_t *sdmmc)
{ {
//Enable internal clock and wait till it is stable. //Enable internal clock and wait till it is stable.
sdmmc->regs->clkcon |= SDHCI_CLOCK_INT_EN; sdmmc->regs->clkcon |= SDHCI_CLOCK_INT_EN;
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
u32 timeout = get_tmr_ms() + 2000; u32 timeout = get_tmr_ms() + 2000;
while (!(sdmmc->regs->clkcon & SDHCI_CLOCK_INT_STABLE)) while (!(sdmmc->regs->clkcon & SDHCI_CLOCK_INT_STABLE))
{ {
@ -724,18 +760,29 @@ static int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power)
off_pd = 5; off_pd = 5;
off_pu = 5; off_pu = 5;
break; break;
case SDMMC_1: case SDMMC_1:
case SDMMC_3:
if (power == SDMMC_POWER_1_8) if (power == SDMMC_POWER_1_8)
{
if (!sdmmc->t210b01)
{ {
off_pd = 123; off_pd = 123;
off_pu = 123; off_pu = 123;
} }
else
{
off_pd = 6;
off_pu = 6;
}
}
else if (power == SDMMC_POWER_3_3) else if (power == SDMMC_POWER_3_3)
{
if (!sdmmc->t210b01)
{ {
off_pd = 125; off_pd = 125;
off_pu = 0; off_pu = 0;
} }
}
else else
return 0; return 0;
break; break;
@ -764,7 +811,7 @@ static int _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
u16 norintsts = sdmmc->regs->norintsts; u16 norintsts = sdmmc->regs->norintsts;
u16 errintsts = sdmmc->regs->errintsts; u16 errintsts = sdmmc->regs->errintsts;
DPRINTF("norintsts %08X; errintsts %08X\n", norintsts, errintsts); DPRINTF("norintsts %08X, errintsts %08X\n", norintsts, errintsts);
if (pout) if (pout)
*pout = norintsts; *pout = norintsts;
@ -772,6 +819,9 @@ DPRINTF("norintsts %08X; errintsts %08X\n", norintsts, errintsts);
// Check for error interrupt. // Check for error interrupt.
if (norintsts & SDHCI_INT_ERROR) if (norintsts & SDHCI_INT_ERROR)
{ {
#ifdef ERROR_EXTRA_PRINTING
EPRINTFARGS("SDMMC: norintsts %08X, errintsts %08X\n", norintsts, errintsts);
#endif
sdmmc->regs->errintsts = errintsts; sdmmc->regs->errintsts = errintsts;
return SDMMC_MASKINT_ERROR; return SDMMC_MASKINT_ERROR;
} }
@ -786,7 +836,7 @@ DPRINTF("norintsts %08X; errintsts %08X\n", norintsts, errintsts);
static int _sdmmc_wait_response(sdmmc_t *sdmmc) static int _sdmmc_wait_response(sdmmc_t *sdmmc)
{ {
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
u32 timeout = get_tmr_ms() + 2000; u32 timeout = get_tmr_ms() + 2000;
while (true) while (true)
@ -837,7 +887,7 @@ int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)
return 0; return 0;
// Recalibrate periodically for SDMMC1. // Recalibrate periodically for SDMMC1.
if ((sdmmc->id == SDMMC_1) && sdmmc->auto_cal_enabled) if (sdmmc->manual_cal && sdmmc->powersave_enabled)
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc)); _sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
bool should_disable_sd_clock = false; bool should_disable_sd_clock = false;
@ -845,7 +895,7 @@ int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)
{ {
should_disable_sd_clock = true; should_disable_sd_clock = true;
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN; sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor); usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);
} }
@ -963,8 +1013,6 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
is_data_present = true; is_data_present = true;
} }
else
is_data_present = false;
_sdmmc_enable_interrupts(sdmmc); _sdmmc_enable_interrupts(sdmmc);
@ -983,7 +1031,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
EPRINTF("SDMMC: Transfer timeout!"); EPRINTF("SDMMC: Transfer timeout!");
#endif #endif
} }
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result, DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3); sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);
if (result) if (result)
{ {
@ -994,7 +1042,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
if (!result) if (!result)
{ {
#ifdef ERROR_EXTRA_PRINTING #ifdef ERROR_EXTRA_PRINTING
EPRINTFARGS("SDMMC: Unknown response %08X!", sdmmc->rsp[0]); EPRINTF("SDMMC: Unknown response type!");
#endif #endif
} }
} }
@ -1004,7 +1052,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
if (!result) if (!result)
{ {
#ifdef ERROR_EXTRA_PRINTING #ifdef ERROR_EXTRA_PRINTING
EPRINTF("SDMMC: DMA Update failed!"); EPRINTFARGS("SDMMC: DMA Update failed (%08X)!", result);
#endif #endif
} }
} }
@ -1047,7 +1095,56 @@ bool sdmmc_get_sd_inserted()
return (!gpio_read(GPIO_PORT_Z, GPIO_PIN_1)); return (!gpio_read(GPIO_PORT_Z, GPIO_PIN_1));
} }
static int _sdmmc_config_sdmmc1() static void _sdmmc_config_sdmmc1_schmitt()
{
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) |= PINMUX_SCHMT;
}
static void _sdmmc_config_sdmmc2_schmitt()
{
PINMUX_AUX(PINMUX_AUX_SDMMC2_CLK) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC2_CMD) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT7) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT6) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT5) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT4) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT3) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT2) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT1) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT0) |= PINMUX_SCHMT;
}
static void _sdmmc_config_sdmmc1_pads(bool discharge)
{
u32 sdmmc1_pin_mask = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
// Set values for Reset state.
u32 function = GPIO_MODE_SPIO;
u32 level = GPIO_LOW;
u32 output = GPIO_OUTPUT_DISABLE;
// Set values for dicharging.
if (discharge)
{
function = GPIO_MODE_GPIO;
level = GPIO_HIGH;
output = GPIO_OUTPUT_ENABLE;
}
// Set all pads function.
gpio_config(GPIO_PORT_M, sdmmc1_pin_mask, function);
// Set all pads output level.
gpio_write(GPIO_PORT_M, sdmmc1_pin_mask, level);
// Set all pads output.
gpio_output_enable(GPIO_PORT_M, sdmmc1_pin_mask, output);
}
static int _sdmmc_config_sdmmc1(bool t210b01)
{ {
// Configure SD card detect. // Configure SD card detect.
PINMUX_AUX(PINMUX_AUX_GPIO_PZ1) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | 2; // GPIO control, pull up. PINMUX_AUX(PINMUX_AUX_GPIO_PZ1) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | 2; // GPIO control, pull up.
@ -1062,74 +1159,101 @@ static int _sdmmc_config_sdmmc1()
/* /*
* Pinmux config: * Pinmux config:
* DRV_TYPE = DRIVE_2X * DRV_TYPE = DRIVE_2X (for 33 Ohm driver)
* E_SCHMT = ENABLE (for 1.8V), DISABLE (for 3.3V) * E_SCHMT = ENABLE (for 1.8V), DISABLE (for 3.3V)
* E_INPUT = ENABLE * E_INPUT = ENABLE
* TRISTATE = PASSTHROUGH * TRISTATE = PASSTHROUGH
* APB_MISC_GP_SDMMCx_CLK_LPBK_CONTROL = SDMMCx_CLK_PAD_E_LPBK for CLK * APB_MISC_GP_SDMMCx_CLK_LPBK_CONTROL = SDMMCx_CLK_PAD_E_LPBK for CLK
*/ */
// Configure SDMMC1 pinmux. // Enable deep loopback for SDMMC1 CLK pad.
APB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1; // Enable deep loopback for SDMMC1 CLK pad. APB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1;
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED;
PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP; // Configure SDMMC1 CLK pinmux, based on state and SoC type.
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP; if (PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) != (PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN)) // Check if CLK pad is already configured.
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP; PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | (t210b01 ? PINMUX_PULL_NONE : PINMUX_PULL_DOWN);
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP; // Configure reset state of SDMMC1 pins pinmux.
PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
// Force schmitt trigger for T210B01.
if (t210b01)
_sdmmc_config_sdmmc1_schmitt();
// Make sure the SDMMC1 controller is powered. // 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); PMC(APBDEV_PMC_NO_IOPOWER) &= ~(PMC_NO_IOPOWER_SDMMC1_IO_EN);
(void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write.
// Inform IO pads that voltage is gonna be 3.3V. // Inform IO pads that voltage is gonna be 3.3V.
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_SDMMC1_IO_EN; 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. // Set enable SD card power.
PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_PULL_DOWN | 2; // Pull down. PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_PULL_DOWN | 2; // Pull down.
gpio_config(GPIO_PORT_E, GPIO_PIN_4, GPIO_MODE_GPIO); gpio_config(GPIO_PORT_E, GPIO_PIN_4, GPIO_MODE_GPIO);
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_HIGH); gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_HIGH);
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_ENABLE); gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_ENABLE);
usleep(1000); usleep(10000);
// Enable SD card power. // Enable SD card IO power.
max77620_regulator_set_voltage(REGULATOR_LDO2, 3300000); max77620_regulator_set_voltage(REGULATOR_LDO2, 3300000);
max77620_regulator_enable(REGULATOR_LDO2, 1); max77620_regulator_enable(REGULATOR_LDO2, 1);
usleep(1000); usleep(1000);
// Set pad slew codes to get good quality clock. // Set pad slew codes to get good quality clock.
if (!t210b01)
{
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) & 0xFFFFFFF) | 0x50000000; APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) & 0xFFFFFFF) | 0x50000000;
(void)APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL); // Commit write.
usleep(1000); usleep(1000);
}
return 1; return 1;
} }
static void _sdmmc_config_emmc(u32 id) static void _sdmmc_config_emmc(u32 id, bool t210b01)
{ {
switch (id) switch (id)
{ {
case SDMMC_2: case SDMMC_2:
if (!t210b01)
{
// Unset park for pads. // Unset park for pads.
APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) &= 0xF8003FFF; APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) &= 0xF8003FFF;
(void)APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL); // Commit write.
}
else // Enable schmitt trigger for T210B01.
_sdmmc_config_sdmmc2_schmitt();
break; break;
case SDMMC_4: case SDMMC_4:
// Unset park for pads. // Unset park for pads.
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) &= 0xF8003FFF; APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) &= 0xF8003FFF;
// Set default pad cfg. // Set default pad cfg.
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0xFFFFC003) | 0x1040; if (t210b01)
APB_MISC(APB_MISC_GP_EMMC4_PAD_PUPD_CFGPADCTRL) &= 0xFFBFFFF9; // Unset CMD/CLK/DQS powedown.
// Enabled schmitt trigger. // Enable schmitt trigger.
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) |= 1; // Enable Schmitt trigger. APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) |= 1;
(void)APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL); // Commit write.
break; break;
} }
} }
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int auto_cal_enable) int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int powersave_enable)
{ {
const u32 trim_values[] = { 2, 8, 3, 8 }; u32 clock;
u16 divisor;
u8 vref_sel = 7;
if (id > SDMMC_4) 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;
if (id > SDMMC_4 || id == SDMMC_3)
return 0; return 0;
memset(sdmmc, 0, sizeof(sdmmc_t)); memset(sdmmc, 0, sizeof(sdmmc_t));
@ -1137,45 +1261,57 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int a
sdmmc->regs = (t210_sdmmc_t *)_sdmmc_bases[id]; sdmmc->regs = (t210_sdmmc_t *)_sdmmc_bases[id];
sdmmc->id = id; sdmmc->id = id;
sdmmc->clock_stopped = 1; sdmmc->clock_stopped = 1;
sdmmc->t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01;
// Do specific SDMMC HW configuration. // Do specific SDMMC HW configuration.
switch (id) switch (id)
{ {
case SDMMC_1: case SDMMC_1:
if (!_sdmmc_config_sdmmc1()) if (!_sdmmc_config_sdmmc1(sdmmc->t210b01))
return 0; return 0;
if (sdmmc->t210b01)
vref_sel = 0;
else
sdmmc->manual_cal = 1;
break; break;
case SDMMC_2: case SDMMC_2:
case SDMMC_4: case SDMMC_4:
_sdmmc_config_emmc(id); _sdmmc_config_emmc(id, sdmmc->t210b01);
break; break;
} }
// Disable clock if enabled.
if (clock_sdmmc_is_not_reset_and_enabled(id)) if (clock_sdmmc_is_not_reset_and_enabled(id))
{ {
_sdmmc_sd_clock_disable(sdmmc); _sdmmc_sd_clock_disable(sdmmc);
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
} }
u32 clock; // Configure and enable selected clock.
u16 divisor;
clock_sdmmc_get_card_clock_div(&clock, &divisor, type); clock_sdmmc_get_card_clock_div(&clock, &divisor, type);
clock_sdmmc_enable(id, clock); clock_sdmmc_enable(id, clock);
// Make sure all sdmmc registers are reset.
_sdmmc_reset_all(sdmmc);
sdmmc->clock_stopped = 0; sdmmc->clock_stopped = 0;
//TODO: make this skip-able. // Set default pad IO trimming configuration.
sdmmc->regs->iospare |= 0x80000; // Enable muxing. sdmmc->regs->iospare |= 0x80000; // Enable muxing.
sdmmc->regs->veniotrimctl &= 0xFFFFFFFB; // Set Band Gap VREG to supply DLL. 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) | (trim_values[sdmmc->id] << 24);
sdmmc->regs->sdmemcmppadctl = sdmmc->regs->sdmemcmppadctl =
(sdmmc->regs->sdmemcmppadctl & TEGRA_MMC_SDMEMCOMPPADCTRL_COMP_VREF_SEL_MASK) | 7; (sdmmc->regs->sdmemcmppadctl & TEGRA_MMC_SDMEMCOMPPADCTRL_COMP_VREF_SEL_MASK) | vref_sel;
// Configure auto calibration values.
if (!_sdmmc_autocal_config_offset(sdmmc, power)) if (!_sdmmc_autocal_config_offset(sdmmc, power))
return 0; return 0;
// Calibrate pads.
_sdmmc_autocal_execute(sdmmc, power); _sdmmc_autocal_execute(sdmmc, power);
// Enable internal clock and power.
if (_sdmmc_enable_internal_clock(sdmmc)) if (_sdmmc_enable_internal_clock(sdmmc))
{ {
sdmmc_set_bus_width(sdmmc, bus_width); sdmmc_set_bus_width(sdmmc, bus_width);
@ -1183,16 +1319,61 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int a
if (sdmmc_setup_clock(sdmmc, type)) if (sdmmc_setup_clock(sdmmc, type))
{ {
sdmmc_card_clock_ctrl(sdmmc, auto_cal_enable); sdmmc_card_clock_powersave(sdmmc, powersave_enable);
_sdmmc_card_clock_enable(sdmmc); _sdmmc_card_clock_enable(sdmmc);
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
return 1; return 1;
} }
}
return 0; return 0;
}
void sdmmc1_disable_power()
{
// Ensure regulator is into default voltage.
if (PMC(APBDEV_PMC_PWR_DET_VAL) & PMC_PWR_DET_SDMMC1_IO_EN)
{
// Switch to 1.8V and wait for regulator to stabilize.
max77620_regulator_set_voltage(REGULATOR_LDO2, 1800000);
usleep(150);
// Inform IO pads that we switched to 1.8V.
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~(PMC_PWR_DET_SDMMC1_IO_EN);
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
} }
return 0;
// T210B01 WAR: Clear pull down from CLK pad.
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) &= ~PINMUX_PULL_MASK;
// T210B01 WAR: Set pads to discharge state.
_sdmmc_config_sdmmc1_pads(true);
// Disable SD card IO power regulator.
max77620_regulator_enable(REGULATOR_LDO2, 0);
usleep(4000);
// Disable SD card IO power pin.
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
// T210/T210B01 WAR: Set start timer for IO and Controller power discharge.
sd_power_cycle_time_start = get_tmr_ms();
usleep(1000); // To power cycle, min 1ms without power is needed.
// Disable SDMMC1 controller power.
PMC(APBDEV_PMC_NO_IOPOWER) |= PMC_NO_IOPOWER_SDMMC1_IO_EN;
(void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write.
// Inform IO pads that next voltage might be 3.3V.
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_SDMMC1_IO_EN;
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
// T210B01 WAR: Restore pads to reset state.
_sdmmc_config_sdmmc1_pads(false);
// T210B01 WAR: Restore pull down to CLK pad.
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) |= PINMUX_PULL_DOWN;
} }
void sdmmc_end(sdmmc_t *sdmmc) void sdmmc_end(sdmmc_t *sdmmc)
@ -1205,18 +1386,9 @@ void sdmmc_end(sdmmc_t *sdmmc)
// Disable SD card power. // Disable SD card power.
if (sdmmc->id == SDMMC_1) if (sdmmc->id == SDMMC_1)
{ sdmmc1_disable_power();
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
max77620_regulator_enable(REGULATOR_LDO2, 0);
// Inform IO pads that next voltage might be 3.3V. _sdmmc_commit_changes(sdmmc);
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_SDMMC1_IO_EN;
sd_power_cycle_time_start = get_tmr_ms(); // Some SanDisk U1 cards need 100ms for a power cycle.
usleep(1000); // To power cycle, min 1ms without power is needed.
}
_sdmmc_get_clkcon(sdmmc);
clock_sdmmc_disable(sdmmc->id); clock_sdmmc_disable(sdmmc->id);
sdmmc->clock_stopped = 1; sdmmc->clock_stopped = 1;
} }
@ -1236,7 +1408,7 @@ int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *b
return 0; return 0;
// Recalibrate periodically for SDMMC1. // Recalibrate periodically for SDMMC1.
if (sdmmc->id == SDMMC_1 && sdmmc->auto_cal_enabled) if (sdmmc->manual_cal && sdmmc->powersave_enabled)
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc)); _sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
int should_disable_sd_clock = 0; int should_disable_sd_clock = 0;
@ -1244,7 +1416,7 @@ int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *b
{ {
should_disable_sd_clock = 1; should_disable_sd_clock = 1;
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN; sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor); usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor);
} }
@ -1265,36 +1437,32 @@ int sdmmc_enable_low_voltage(sdmmc_t *sdmmc)
if (!sdmmc_setup_clock(sdmmc, SDHCI_TIMING_UHS_SDR12)) if (!sdmmc_setup_clock(sdmmc, SDHCI_TIMING_UHS_SDR12))
return 0; return 0;
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
// Switch to 1.8V and wait for regulator to stabilize. Assume max possible wait needed. // Switch to 1.8V and wait for regulator to stabilize. Assume max possible wait needed.
max77620_regulator_set_voltage(REGULATOR_LDO2, 1800000); max77620_regulator_set_voltage(REGULATOR_LDO2, 1800000);
usleep(300); usleep(150);
// Inform IO pads that we switched to 1.8V. // Inform IO pads that we switched to 1.8V.
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~(PMC_PWR_DET_SDMMC1_IO_EN); PMC(APBDEV_PMC_PWR_DET_VAL) &= ~(PMC_PWR_DET_SDMMC1_IO_EN);
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
// Enable schmitt trigger for better duty cycle and low jitter clock. // Enable schmitt trigger for better duty cycle and low jitter clock.
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) |= PINMUX_SCHMT; _sdmmc_config_sdmmc1_schmitt();
PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) |= PINMUX_SCHMT;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) |= PINMUX_SCHMT;
_sdmmc_autocal_config_offset(sdmmc, SDMMC_POWER_1_8); _sdmmc_autocal_config_offset(sdmmc, SDMMC_POWER_1_8);
_sdmmc_autocal_execute(sdmmc, SDMMC_POWER_1_8); _sdmmc_autocal_execute(sdmmc, SDMMC_POWER_1_8);
_sdmmc_set_io_power(sdmmc, SDMMC_POWER_1_8); _sdmmc_set_io_power(sdmmc, SDMMC_POWER_1_8);
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
msleep(5); // Wait minimum 5ms before turning on the card clock. msleep(5); // Wait minimum 5ms before turning on the card clock.
// Turn on SDCLK. // Turn on SDCLK.
if (sdmmc->regs->hostctl2 & SDHCI_CTRL_VDD_180) if (sdmmc->regs->hostctl2 & SDHCI_CTRL_VDD_180)
{ {
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN; sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
_sdmmc_get_clkcon(sdmmc); _sdmmc_commit_changes(sdmmc);
usleep(1000); usleep(1000);
if ((sdmmc->regs->prnsts & 0xF00000) == 0xF00000) if ((sdmmc->regs->prnsts & SDHCI_DATA_LVL_MASK) == SDHCI_DATA_LVL_MASK)
return 1; return 1;
} }

View File

@ -195,13 +195,13 @@
#define SDHCI_TIMING_UHS_SDR104 11 #define SDHCI_TIMING_UHS_SDR104 11
#define SDHCI_TIMING_UHS_SDR82 12 // SDR104 with a 163.2MHz -> 81.6MHz clock. #define SDHCI_TIMING_UHS_SDR82 12 // SDR104 with a 163.2MHz -> 81.6MHz clock.
#define SDHCI_TIMING_UHS_DDR50 13 #define SDHCI_TIMING_UHS_DDR50 13
#define SDHCI_TIMING_MMC_DDR52 14 #define SDHCI_TIMING_MMC_HS102 14
#define SDHCI_CAN_64BIT 0x10000000 #define SDHCI_CAN_64BIT 0x10000000
/*! SDMMC Low power features. */ /*! SDMMC Low power features. */
#define SDMMC_AUTO_CAL_DISABLE 0 #define SDMMC_POWER_SAVE_DISABLE 0
#define SDMMC_AUTO_CAL_ENABLE 1 #define SDMMC_POWER_SAVE_ENABLE 1
/*! Helper for SWITCH command argument. */ /*! Helper for SWITCH command argument. */
#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8)) #define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))
@ -213,7 +213,8 @@ typedef struct _sdmmc_t
u32 id; u32 id;
u32 divisor; u32 divisor;
u32 clock_stopped; u32 clock_stopped;
int auto_cal_enabled; int powersave_enabled;
int manual_cal;
int card_clock_enabled; int card_clock_enabled;
int venclkctl_set; int venclkctl_set;
u32 venclkctl_tap; u32 venclkctl_tap;
@ -221,6 +222,7 @@ typedef struct _sdmmc_t
u32 dma_addr_next; u32 dma_addr_next;
u32 rsp[4]; u32 rsp[4];
u32 rsp3; u32 rsp3;
int t210b01;
} sdmmc_t; } sdmmc_t;
/*! SDMMC command. */ /*! SDMMC command. */
@ -246,14 +248,14 @@ typedef struct _sdmmc_req_t
int sdmmc_get_io_power(sdmmc_t *sdmmc); int sdmmc_get_io_power(sdmmc_t *sdmmc);
u32 sdmmc_get_bus_width(sdmmc_t *sdmmc); u32 sdmmc_get_bus_width(sdmmc_t *sdmmc);
void sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width); void sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width);
void sdmmc_set_tap_value(sdmmc_t *sdmmc); void sdmmc_save_tap_value(sdmmc_t *sdmmc);
int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type); int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type);
void sdmmc_card_clock_ctrl(sdmmc_t *sdmmc, int auto_cal_enable); void sdmmc_card_clock_powersave(sdmmc_t *sdmmc, int powersave_enable);
int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type); int sdmmc_get_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 size, u32 type);
int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd); int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd);
int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp); int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp);
bool sdmmc_get_sd_inserted(); bool sdmmc_get_sd_inserted();
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int auto_cal_enable); int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int powersave_enable);
void sdmmc_end(sdmmc_t *sdmmc); void sdmmc_end(sdmmc_t *sdmmc);
void sdmmc_init_cmd(sdmmc_cmd_t *cmdbuf, u16 cmd, u32 arg, u32 rsp_type, u32 check_busy); void sdmmc_init_cmd(sdmmc_cmd_t *cmdbuf, u16 cmd, u32 arg, u32 rsp_type, u32 check_busy);
int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out); int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *blkcnt_out);

View File

@ -103,6 +103,7 @@ typedef struct _t210_sdmmc_t
vu32 iospare; vu32 iospare;
vu32 mcciffifoctl; vu32 mcciffifoctl;
vu32 timeoutwcoal; vu32 timeoutwcoal;
vu32 unk1;
} t210_sdmmc_t; } t210_sdmmc_t;
#endif #endif

View File

@ -38,7 +38,7 @@ void set_fan_duty(u32 duty)
gpio_config(GPIO_PORT_S, GPIO_PIN_7, GPIO_MODE_GPIO); gpio_config(GPIO_PORT_S, GPIO_PIN_7, GPIO_MODE_GPIO);
gpio_output_enable(GPIO_PORT_S, GPIO_PIN_7, GPIO_OUTPUT_DISABLE); gpio_output_enable(GPIO_PORT_S, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (1 << 24); // Max PWM to disable fan. PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (0x100 << 16); // Max PWM to disable fan.
PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = 1; // Set source to PWM1. PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = 1; // Set source to PWM1.
gpio_config(GPIO_PORT_V, GPIO_PIN_4, GPIO_MODE_SPIO); // Fan power mode. gpio_config(GPIO_PORT_V, GPIO_PIN_4, GPIO_MODE_SPIO); // Fan power mode.
@ -55,7 +55,7 @@ void set_fan_duty(u32 duty)
// If disabled send a 0 duty. // If disabled send a 0 duty.
if (inv_duty == 236) if (inv_duty == 236)
{ {
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (1 << 24); // Bit 24 is absolute 0%. PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (0x100 << 16); // Bit 24 is absolute 0%.
regulator_disable_5v(REGULATOR_5V_FAN); regulator_disable_5v(REGULATOR_5V_FAN);
// Disable fan. // Disable fan.

View File

@ -0,0 +1,238 @@
/*
* USB driver for Tegra X1
*
* Copyright (c) 2019-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _USB_DESCRIPTORS_TYPES_H_
#define _USB_DESCRIPTORS_TYPES_H_
#include <utils/types.h>
typedef enum {
USB_DESCRIPTOR_DEVICE = 1,
USB_DESCRIPTOR_CONFIGURATION = 2,
USB_DESCRIPTOR_STRING = 3,
USB_DESCRIPTOR_INTERFACE = 4,
USB_DESCRIPTOR_ENDPOINT = 5,
USB_DESCRIPTOR_DEVICE_QUALIFIER = 6,
USB_DESCRIPTOR_OTHER_SPEED_CONFIGURATION = 7,
USB_DESCRIPTOR_INTERFACE_POWER = 8,
USB_DESCRIPTOR_INTERFACE_OTG = 9,
USB_DESCRIPTOR_DEVICE_BINARY_OBJECT = 15,
USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP = 16,
USB_DESCRIPTOR_HID = 33,
USB_DESCRIPTOR_HID_REPORT = 34
} usb_desc_type_t;
typedef enum {
USB_DESCRIPTOR_MS_COMPAT_ID = 4,
USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES = 5
} usb_vendor_desc_type_t;
typedef enum {
USB_ATTR_REMOTE_WAKE_UP = 0x20,
USB_ATTR_SELF_POWERED = 0x40,
USB_ATTR_BUS_POWERED_RSVD = 0x80
} usb_cfg_attr_type_t;
typedef enum
{
USB_EP_TYPE_CTRL = 0,
USB_EP_TYPE_ISO = 1,
USB_EP_TYPE_BULK = 2,
USB_EP_TYPE_INTR = 3
} usb_cfg_ep_type_t;
/* Device descriptor structure */
typedef struct _usb_dev_descr_t
{
u8 bLength; // Size of this descriptor in bytes.
u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE)
u16 bcdUSB; // USB Spec. Release number (2.1).
u8 bDeviceClass; // Class is specified in the interface descriptor.
u8 bDeviceSubClass; // SubClass is specified in the interface descriptor.
u8 bDeviceProtocol; // Protocol is specified in the interface descriptor.
u8 bMaxPacketSize; // Maximum packet size for EP0.
u16 idVendor; // Vendor ID assigned by USB forum.
u16 idProduct; // Product ID assigned by Organization.
u16 bcdDevice; // Device Release number in BCD.
u8 iManufacturer; // Index of String descriptor describing Manufacturer.
u8 iProduct; // Index of String descriptor describing Product.
u8 iSerialNumber; // Index of String descriptor describing Serial number.
u8 bNumConfigs; // Number of possible configuration.
} __attribute__((packed)) usb_dev_descr_t;
/* Device Qualifier descriptor structure */
typedef struct _usb_dev_qual_descr_t
{
u8 bLength; // Size of this descriptor in bytes.
u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE_QUALIFIER)
u16 bcdUSB; // USB Spec. Release number (2.1).
u8 bDeviceClass; // Class is specified in the interface descriptor.
u8 bDeviceSubClass; // SubClass is specified in the interface descriptor.
u8 bDeviceProtocol; // Protocol is specified in the interface descriptor.
u8 bMaxPacketSize; // Maximum packet size for EP0.
u8 bNumOtherConfigs; // Number of possible other-speed configurations.
u8 bReserved; // Reserved for future use, must be zero
} __attribute__((packed)) usb_dev_qual_descr_t;
/* Configuration descriptor structure */
typedef struct _usb_cfg_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION).
u16 wTotalLength; // Total length of all descriptors for this configuration.
u8 bNumInterfaces; // Number of interfaces in this configuration.
u8 bConfigurationValue; // Value of this configuration (1 based).
u8 iConfiguration; // Index of String Descriptor describing the configuration.
u8 bmAttributes; // Configuration characteristics.
u8 bMaxPower; // Maximum power consumed by this configuration.
} __attribute__((packed)) usb_cfg_descr_t;
/* Interface descriptor structure */
typedef struct _usb_inter_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE).
u8 bInterfaceNumber; // Number of this interface (0 based).
u8 bAlternateSetting; // Value of this alternate interface setting.
u8 bNumEndpoints; // Number of endpoints in this interface.
u8 bInterfaceClass; // Class code (assigned by the USB-IF).
u8 bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
u8 bInterfaceProtocol; // Protocol code (assigned by the USB-IF).
u8 iInterface; // Index of String Descriptor describing the interface.
} __attribute__((packed)) usb_inter_descr_t;
/* HID descriptor structure */
typedef struct _usb_hid_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_HID).
u16 bcdHID; // HID class specification release
u8 bCountryCode; // Country code.
u8 bNumDescriptors; // Number of descriptors.
u8 bClassDescriptorType; // Type of class descriptor (USB_DESCRIPTOR_HID_REPORT).
u16 bDescriptorLength; // Report descriptor length.
} __attribute__((packed)) usb_hid_descr_t;
/* Endpoint descriptor structure */
typedef struct _usb_ep_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT).
u8 bEndpointAddress; // Endpoint address. bit7 indicates direction (0=OUT, 1=IN).
u8 bmAttributes; // Endpoint transfer type.
u16 wMaxPacketSize; // Maximum packet size.
u8 bInterval; // Polling interval in frames. For Interrupt and Isochronous data transfer only.
} __attribute__((packed)) usb_ep_descr_t;
typedef struct _usb_cfg_simple_descr_t
{
usb_cfg_descr_t config;
usb_inter_descr_t interface;
usb_ep_descr_t endpoint[2];
} __attribute__((packed)) usb_cfg_simple_descr_t;
typedef struct _usb_cfg_hid_descr_t
{
usb_cfg_descr_t config;
usb_inter_descr_t interface;
usb_hid_descr_t hid;
usb_ep_descr_t endpoint[2];
} __attribute__((packed)) usb_cfg_hid_descr_t;
typedef struct _usb_dev_bot_t
{
u8 bLength; // Size of this descriptor in bytes.
u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT)
u16 wTotalLength; // Size of this descriptor in bytes.
u8 bNumDeviceCaps; // Number of device capabilities in this descriptor.
/* Device Capability USB 2.0 Extension Descriptor */
/* Needed for a USB2.10 device. */
u8 bLengthCap0; // Size of this capability descriptor in bytes.
u8 bDescriptorTypeCap0; // Device Capability Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP)
u8 bDevCapabilityTypeCap0; // USB2: 2.
u32 bmAttributesCap0; // bit1: Link Power Management (LPM).
u8 bLengthCap1; // Size of this capability descriptor in bytes.
u8 bDescriptorTypeCap1; // Device Capability Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP)
u8 bDevCapabilityTypeCap1; // USB3: 3.
u8 bmAttributesCap1; // bit1: Latency Tolerance Messaging (LTM).
u16 wSpeedsSupported; // Supported bus speeds. 1: Low Speed, 2: Full Speed, 4: High Speed, 8: Super Speed.
u8 bFunctionalitySupport; // Lowest speed at which all the functionality is available. 1: Full speed and above.
u8 bU1DevExitLat; // USB3.0 U1 exit latency.
u16 wU2DevExitLat; // USB3.0 U2 exit latency.
} __attribute__((packed)) usb_dev_bot_t;
/* Microsoft OS String descriptor structure */
typedef struct _usb_ms_os_descr_t
{
u8 bLength; // 0x12
u8 bDescriptorType; // 3
u16 wSignature[7]; // "MSFT100" UTF16 LE
u8 bVendorCode; //
u8 bPadding;
} __attribute__((packed)) usb_ms_os_descr_t;
/* Microsoft Compatible ID Feature descriptor structure */
typedef struct _usb_ms_cid_descr_t
{
u32 dLength;
u16 wVersion;
u16 wCompatibilityId;
u8 bSections;
u8 bReserved0[7];
u8 bInterfaceNumber;
u8 bReserved1;
u8 bCompatibleId[8];
u8 bSubCompatibleId[8];
u8 bReserved2[6];
} __attribute__((packed)) usb_ms_cid_descr_t;
/* Microsoft Extended Properties Feature descriptor structure */
typedef struct _usb_ms_ext_prop_descr_t
{
u32 dLength;
u16 wVersion;
u16 wExtendedProperty;
u16 wSections;
u32 dPropertySize;
u32 dPropertyType;
u16 wPropertyNameLength;
u16 wPropertyName[22]; // UTF16 LE
u32 dPropertyDataLength;
u16 wPropertyData[2]; // UTF16 LE
} __attribute__((packed)) usb_ms_ext_prop_descr_t;
typedef struct _usb_desc_t
{
usb_dev_descr_t *dev;
usb_dev_qual_descr_t *dev_qual;
usb_cfg_simple_descr_t *cfg;
usb_cfg_simple_descr_t *cfg_other;
usb_dev_bot_t *dev_bot;
u8 *vendor;
u8 *product;
u8 *serial;
u8 *lang_id;
usb_ms_os_descr_t *ms_os;
usb_ms_cid_descr_t *ms_cid;
usb_ms_ext_prop_descr_t *mx_ext;
} usb_desc_t;
#endif

View File

@ -1,7 +1,7 @@
/* /*
* USB driver for Tegra X1 * USB driver for Tegra X1
* *
* Copyright (c) 2019 CTCaer * Copyright (c) 2019-2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -16,224 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _USB_DESCRIPTORS_H_ #include <usb/usb_descriptor_types.h>
#define _USB_DESCRIPTORS_H_
#include <utils/types.h> #include <utils/types.h>
typedef enum { static usb_dev_descr_t usb_device_descriptor_ums =
USB_DESCRIPTOR_DEVICE = 1,
USB_DESCRIPTOR_CONFIGURATION = 2,
USB_DESCRIPTOR_STRING = 3,
USB_DESCRIPTOR_INTERFACE = 4,
USB_DESCRIPTOR_ENDPOINT = 5,
USB_DESCRIPTOR_DEVICE_QUALIFIER = 6,
USB_DESCRIPTOR_OTHER_SPEED_CONFIGURATION = 7,
USB_DESCRIPTOR_INTERFACE_POWER = 8,
USB_DESCRIPTOR_INTERFACE_OTG = 9,
USB_DESCRIPTOR_DEVICE_BINARY_OBJECT = 15,
USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP = 16,
USB_DESCRIPTOR_HID = 33,
USB_DESCRIPTOR_HID_REPORT = 34
} usb_desc_type_t;
typedef enum {
USB_DESCRIPTOR_MS_COMPAT_ID = 4,
USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES = 5
} usb_vendor_desc_type_t;
typedef enum {
USB_ATTR_REMOTE_WAKE_UP = 0x20,
USB_ATTR_SELF_POWERED = 0x40,
USB_ATTR_BUS_POWERED_RSVD = 0x80
} usb_cfg_attr_type_t;
typedef enum
{
USB_EP_TYPE_CTRL = 0,
USB_EP_TYPE_ISO = 1,
USB_EP_TYPE_BULK = 2,
USB_EP_TYPE_INTR = 3
} usb_cfg_ep_type_t;
/* Device descriptor structure */
typedef struct _usb_dev_descr_t
{
u8 bLength; // Size of this descriptor in bytes.
u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE)
u16 bcdUSB; // USB Spec. Release number (2.1).
u8 bDeviceClass; // Class is specified in the interface descriptor.
u8 bDeviceSubClass; // SubClass is specified in the interface descriptor.
u8 bDeviceProtocol; // Protocol is specified in the interface descriptor.
u8 bMaxPacketSize; // Maximum packet size for EP0.
u16 idVendor; // Vendor ID assigned by USB forum.
u16 idProduct; // Product ID assigned by Organization.
u16 bcdDevice; // Device Release number in BCD.
u8 iManufacturer; // Index of String descriptor describing Manufacturer.
u8 iProduct; // Index of String descriptor describing Product.
u8 iSerialNumber; // Index of String descriptor describing Serial number.
u8 bNumConfigs; // Number of possible configuration.
} __attribute__((packed)) usb_dev_descr_t;
/* Device Qualigier descriptor structure */
typedef struct _usb_dev_qual_descr_t
{
u8 bLength; // Size of this descriptor in bytes.
u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE_QUALIFIER)
u16 bcdUSB; // USB Spec. Release number (2.1).
u8 bDeviceClass; // Class is specified in the interface descriptor.
u8 bDeviceSubClass; // SubClass is specified in the interface descriptor.
u8 bDeviceProtocol; // Protocol is specified in the interface descriptor.
u8 bMaxPacketSize; // Maximum packet size for EP0.
u8 bNumOtherConfigs; // Number of possible other-speed configurations.
u8 bReserved; // Reserved for future use, must be zero
} __attribute__((packed)) usb_dev_qual_descr_t;
/* Configuration descriptor structure */
typedef struct _usb_cfg_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION).
u16 wTotalLength; // Total length of all descriptors for this configuration.
u8 bNumInterfaces; // Number of interfaces in this configuration.
u8 bConfigurationValue; // Value of this configuration (1 based).
u8 iConfiguration; // Index of String Descriptor describing the configuration.
u8 bmAttributes; // Configuration characteristics.
u8 bMaxPower; // Maximum power consumed by this configuration.
} __attribute__((packed)) usb_cfg_descr_t;
/* Interface descriptor structure */
typedef struct _usb_inter_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE).
u8 bInterfaceNumber; // Number of this interface (0 based).
u8 bAlternateSetting; // Value of this alternate interface setting.
u8 bNumEndpoints; // Number of endpoints in this interface.
u8 bInterfaceClass; // Class code (assigned by the USB-IF).
u8 bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
u8 bInterfaceProtocol; // Protocol code (assigned by the USB-IF).
u8 iInterface; // Index of String Descriptor describing the interface.
} __attribute__((packed)) usb_inter_descr_t;
/* HID descriptor structure */
typedef struct _usb_hid_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_HID).
u16 bcdHID; // HID class specification release
u8 bCountryCode; // Country code.
u8 bNumDescriptors; // Number of descriptors.
u8 bClassDescriptorType; // Type of class descriptor (USB_DESCRIPTOR_HID_REPORT).
u16 bDescriptorLength; // Report descriptor length.
} __attribute__((packed)) usb_hid_descr_t;
/* Endpoint descriptor structure */
typedef struct _usb_ep_descr_t
{
u8 bLength; // Length of this descriptor.
u8 bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT).
u8 bEndpointAddress; // Endpoint address. bit7 indicates direction (0=OUT, 1=IN).
u8 bmAttributes; // Endpoint transfer type.
u16 wMaxPacketSize; // Maximum packet size.
u8 bInterval; // Polling interval in frames. For Interrupt and Isochronous data transfer only.
} __attribute__((packed)) usb_ep_descr_t;
typedef struct _usb_cfg_simple_descr_t
{
usb_cfg_descr_t config;
usb_inter_descr_t interface;
usb_ep_descr_t endpoint[2];
} __attribute__((packed)) usb_cfg_simple_descr_t;
typedef struct _usb_cfg_hid_descr_t
{
usb_cfg_descr_t config;
usb_inter_descr_t interface;
usb_hid_descr_t hid;
usb_ep_descr_t endpoint[2];
} __attribute__((packed)) usb_cfg_hid_descr_t;
typedef struct _usb_dev_bot_t
{
u8 bLength; // Size of this descriptor in bytes.
u8 bDescriptorType; // Device Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT)
u16 wTotalLength; // Size of this descriptor in bytes.
u8 bNumDeviceCaps; // Number of device capabilities in this descriptor.
/* Device Capability USB 2.0 Extension Descriptor */
/* Needed for a USB2.10 device. */
u8 bLengthCap0; // Size of this capability descriptor in bytes.
u8 bDescriptorTypeCap0; // Device Capability Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP)
u8 bDevCapabilityTypeCap0; // USB2: 2.
u32 bmAttributesCap0; // bit1: Link Power Management (LPM).
u8 bLengthCap1; // Size of this capability descriptor in bytes.
u8 bDescriptorTypeCap1; // Device Capability Descriptor Type. (USB_DESCRIPTOR_DEVICE_BINARY_OBJECT_CAP)
u8 bDevCapabilityTypeCap1; // USB3: 3.
u8 bmAttributesCap1; // bit1: Latency Tolerance Messaging (LTM).
u16 wSpeedsSupported; // Supported bus speeds. 1: Low Speed, 2: Full Speed, 4: High Speed, 8: Super Speed.
u8 bFunctionalitySupport; // Lowest speed at which all the functionality is available. 1: Full speed and above.
u8 bU1DevExitLat; // USB3.0 U1 exit latency.
u16 wU2DevExitLat; // USB3.0 U2 exit latency.
} __attribute__((packed)) usb_dev_bot_t;
/* Microsoft OS String descriptor structure */
typedef struct _usb_ms_os_descr_t
{
u8 bLength; // 0x12
u8 bDescriptorType; // 3
u16 wSignature[7]; // "MSFT100" UTF16 LE
u8 bVendorCode; //
u8 bPadding;
} __attribute__((packed)) usb_ms_os_descr_t;
/* Microsoft Compatible ID Feature descriptor structure */
typedef struct _usb_ms_cid_descr_t
{
u32 dLength;
u16 wVersion;
u16 wCompatibilityId;
u8 bSections;
u8 bReserved0[7];
u8 bInterfaceNumber;
u8 bReserved1;
u8 bCompatibleId[8];
u8 bSubCompatibleId[8];
u8 bReserved2[6];
} __attribute__((packed)) usb_ms_cid_descr_t;
/* Microsoft Extended Properties Feature descriptor structure */
typedef struct _usb_ms_ext_prop_descr_t
{
u32 dLength;
u16 wVersion;
u16 wExtendedProperty;
u16 wSections;
u32 dPropertySize;
u32 dPropertyType;
u16 wPropertyNameLength;
u16 wPropertyName[22]; // UTF16 LE
u32 dPropertyDataLength;
u16 wPropertyData[2]; // UTF16 LE
} __attribute__((packed)) usb_ms_ext_prop_descr_t;
typedef struct _usb_desc_t
{
usb_dev_descr_t *dev;
usb_dev_qual_descr_t *dev_qual;
usb_cfg_simple_descr_t *cfg;
usb_cfg_simple_descr_t *cfg_other;
usb_dev_bot_t *dev_bot;
u8 *vendor;
u8 *product;
usb_ms_os_descr_t *ms_os;
usb_ms_cid_descr_t *ms_cid;
usb_ms_ext_prop_descr_t *mx_ext;
} usb_desc_t;
usb_dev_descr_t usb_device_descriptor_ums =
{ {
.bLength = 18, .bLength = 18,
.bDescriptorType = USB_DESCRIPTOR_DEVICE, .bDescriptorType = USB_DESCRIPTOR_DEVICE,
@ -251,7 +37,7 @@ usb_dev_descr_t usb_device_descriptor_ums =
.bNumConfigs = 1 .bNumConfigs = 1
}; };
usb_dev_qual_descr_t usb_device_qualifier_descriptor = static usb_dev_qual_descr_t usb_device_qualifier_descriptor =
{ {
.bLength = 10, .bLength = 10,
.bDescriptorType = USB_DESCRIPTOR_DEVICE_QUALIFIER, .bDescriptorType = USB_DESCRIPTOR_DEVICE_QUALIFIER,
@ -264,7 +50,7 @@ usb_dev_qual_descr_t usb_device_qualifier_descriptor =
.bReserved = 0x00 .bReserved = 0x00
}; };
usb_cfg_simple_descr_t usb_configuration_descriptor_ums = static usb_cfg_simple_descr_t usb_configuration_descriptor_ums =
{ {
/* Configuration descriptor structure */ /* Configuration descriptor structure */
.config.bLength = 9, .config.bLength = 9,
@ -304,7 +90,7 @@ usb_cfg_simple_descr_t usb_configuration_descriptor_ums =
.endpoint[1].bInterval = 0x00 .endpoint[1].bInterval = 0x00
}; };
usb_cfg_simple_descr_t usb_other_speed_config_descriptor_ums = static usb_cfg_simple_descr_t usb_other_speed_config_descriptor_ums =
{ {
/* Other Speed Configuration descriptor structure */ /* Other Speed Configuration descriptor structure */
.config.bLength = 9, .config.bLength = 9,
@ -344,7 +130,7 @@ usb_cfg_simple_descr_t usb_other_speed_config_descriptor_ums =
.endpoint[1].bInterval = 0 .endpoint[1].bInterval = 0
}; };
usb_dev_bot_t usb_device_binary_object_descriptor = static usb_dev_bot_t usb_device_binary_object_descriptor =
{ {
.bLength = 5, .bLength = 5,
.bDescriptorType = USB_DESCRIPTOR_DEVICE_BINARY_OBJECT, .bDescriptorType = USB_DESCRIPTOR_DEVICE_BINARY_OBJECT,
@ -369,20 +155,33 @@ usb_dev_bot_t usb_device_binary_object_descriptor =
.wU2DevExitLat = 0 .wU2DevExitLat = 0
}; };
u8 usb_vendor_string_descriptor_ums[32] = static u8 usb_lang_id_string_descriptor[4] =
{
4, 3,
0x09, 0x04
};
static u8 usb_serial_string_descriptor[26] =
{
26, 0x03,
'C', 0x00, '7', 0x00, 'C', 0x00, '0', 0x00,
'9', 0x00, '2', 0x00, '4', 0x00, '2', 0x00, 'F', 0x00, '7', 0x00, '0', 0x00, '3', 0x00
};
static u8 usb_vendor_string_descriptor_ums[32] =
{ {
26, 0x03, 26, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0, ' ', 0, 'N', 0, 'y', 0, 'x', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0, ' ', 0,
'D', 0, 'i', 0, 's', 0, 'k', 0 'D', 0, 'i', 0, 's', 0, 'k', 0
}; };
u8 usb_product_string_descriptor_ums[22] = static u8 usb_product_string_descriptor_ums[22] =
{ {
8, 0x03, 8, 0x03,
'U', 0, 'M', 0, 'S', 0 'U', 0, 'M', 0, 'S', 0
}; };
usb_ms_os_descr_t usb_ms_os_descriptor = static usb_ms_os_descr_t usb_ms_os_descriptor =
{ {
.bLength = 0x28, .bLength = 0x28,
.bDescriptorType = 0x03, .bDescriptorType = 0x03,
@ -396,7 +195,7 @@ usb_ms_os_descr_t usb_ms_os_descriptor =
.bVendorCode = 0x99, .bVendorCode = 0x99,
}; };
usb_ms_cid_descr_t usb_ms_cid_descriptor = static usb_ms_cid_descr_t usb_ms_cid_descriptor =
{ {
.dLength = 0x28, .dLength = 0x28,
.wVersion = 0x100, .wVersion = 0x100,
@ -413,7 +212,7 @@ usb_ms_cid_descr_t usb_ms_cid_descriptor =
.bCompatibleId[5] = 'B', .bCompatibleId[5] = 'B',
}; };
usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_ums = static usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_ums =
{ {
.dLength = 0x48, .dLength = 0x48,
.wVersion = 0x100, .wVersion = 0x100,
@ -452,7 +251,7 @@ usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_ums =
.wPropertyData[1] = 0x10, .wPropertyData[1] = 0x10,
}; };
usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_hid = static usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_hid =
{ {
.dLength = 7, .dLength = 7,
.wVersion = 0x100, .wVersion = 0x100,
@ -460,7 +259,7 @@ usb_ms_ext_prop_descr_t usb_ms_ext_prop_descriptor_hid =
.wSections = 0, .wSections = 0,
}; };
usb_dev_descr_t usb_device_descriptor_hid_jc = static usb_dev_descr_t usb_device_descriptor_hid_jc =
{ {
.bLength = 18, .bLength = 18,
.bDescriptorType = USB_DESCRIPTOR_DEVICE, .bDescriptorType = USB_DESCRIPTOR_DEVICE,
@ -478,7 +277,7 @@ usb_dev_descr_t usb_device_descriptor_hid_jc =
.bNumConfigs = 1 .bNumConfigs = 1
}; };
usb_dev_descr_t usb_device_descriptor_hid_touch = static usb_dev_descr_t usb_device_descriptor_hid_touch =
{ {
.bLength = 18, .bLength = 18,
.bDescriptorType = USB_DESCRIPTOR_DEVICE, .bDescriptorType = USB_DESCRIPTOR_DEVICE,
@ -496,75 +295,6 @@ usb_dev_descr_t usb_device_descriptor_hid_touch =
.bNumConfigs = 1 .bNumConfigs = 1
}; };
usb_cfg_hid_descr_t usb_configuration_descriptor_hid_jc =
{
/* Configuration descriptor structure */
.config.bLength = 9,
.config.bDescriptorType = USB_DESCRIPTOR_CONFIGURATION,
.config.wTotalLength = sizeof(usb_cfg_hid_descr_t),
.config.bNumInterfaces = 0x01,
.config.bConfigurationValue = 0x01,
.config.iConfiguration = 0x00,
.config.bmAttributes = USB_ATTR_SELF_POWERED | USB_ATTR_BUS_POWERED_RSVD,
.config.bMaxPower = 32 / 2,
/* Interface descriptor structure */
.interface.bLength = 9,
.interface.bDescriptorType = USB_DESCRIPTOR_INTERFACE,
.interface.bInterfaceNumber = 0,
.interface.bAlternateSetting = 0,
.interface.bNumEndpoints = 2,
.interface.bInterfaceClass = 0x03, // Human Interface Device Class.
.interface.bInterfaceSubClass = 0x00, // SCSI Transparent Command Set.
.interface.bInterfaceProtocol = 0x00, // Bulk-Only Transport.
.interface.iInterface = 0x00,
.hid.bLength = 9,
.hid.bDescriptorType = USB_DESCRIPTOR_HID,
.hid.bcdHID = 0x110,
.hid.bCountryCode = 0,
.hid.bNumDescriptors = 1,
.hid.bClassDescriptorType = USB_DESCRIPTOR_HID_REPORT,
.hid.bDescriptorLength = 0x43,
/* Endpoint descriptor structure EP1 IN */
.endpoint[0].bLength = 7,
.endpoint[0].bDescriptorType = USB_DESCRIPTOR_ENDPOINT,
.endpoint[0].bEndpointAddress = 0x81, // USB_EP_ADDR_BULK_IN.
.endpoint[0].bmAttributes = USB_EP_TYPE_INTR,
.endpoint[0].wMaxPacketSize = 0x200,
.endpoint[0].bInterval = 4, // 4ms on FS, 8ms on HS.
/* Endpoint descriptor structure EP1 OUT */
.endpoint[1].bLength = 7,
.endpoint[1].bDescriptorType = USB_DESCRIPTOR_ENDPOINT,
.endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT.
.endpoint[1].bmAttributes = USB_EP_TYPE_INTR,
.endpoint[1].wMaxPacketSize = 0x200,
.endpoint[1].bInterval = 4 // 4ms on FS, 8ms on HS.
};
u8 usb_vendor_string_descriptor_hid[22] =
{
16, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0,
'U', 0, 'S', 0, 'B', 0
};
u8 usb_product_string_descriptor_hid_jc[24] =
{
24, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0,
'J', 0, 'o', 0, 'y', 0, '-', 0, 'C', 0, 'o', 0, 'n', 0
};
u8 usb_product_string_descriptor_hid_touch[26] =
{
26, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0,
'T', 0, 'o', 0, 'u', 0, 'c', 0, 'h', 0, 'p', 0, 'a', 0, 'd', 0
};
u8 hid_report_descriptor_jc[] = u8 hid_report_descriptor_jc[] =
{ {
0x05, 0x01, // USAGE_PAGE (Generic Desktop), 0x05, 0x01, // USAGE_PAGE (Generic Desktop),
@ -602,6 +332,8 @@ u8 hid_report_descriptor_jc[] =
0xc0 // END_COLLECTION(), 0xc0 // END_COLLECTION(),
}; };
u32 hid_report_descriptor_jc_size = sizeof(hid_report_descriptor_jc);
u8 hid_report_descriptor_touch[] = u8 hid_report_descriptor_touch[] =
{ {
0x05, 0x0d, // USAGE_PAGE (Digitizers) 0x05, 0x0d, // USAGE_PAGE (Digitizers)
@ -658,8 +390,78 @@ u8 hid_report_descriptor_touch[] =
0xc0, // END_COLLECTION 0xc0, // END_COLLECTION
0xc0, // END_COLLECTION 0xc0, // END_COLLECTION
}; };
u32 hid_report_descriptor_touch_size = sizeof(hid_report_descriptor_touch);
usb_cfg_hid_descr_t usb_configuration_descriptor_hid_touch = static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_jc =
{
/* Configuration descriptor structure */
.config.bLength = 9,
.config.bDescriptorType = USB_DESCRIPTOR_CONFIGURATION,
.config.wTotalLength = sizeof(usb_cfg_hid_descr_t),
.config.bNumInterfaces = 0x01,
.config.bConfigurationValue = 0x01,
.config.iConfiguration = 0x00,
.config.bmAttributes = USB_ATTR_SELF_POWERED | USB_ATTR_BUS_POWERED_RSVD,
.config.bMaxPower = 32 / 2,
/* Interface descriptor structure */
.interface.bLength = 9,
.interface.bDescriptorType = USB_DESCRIPTOR_INTERFACE,
.interface.bInterfaceNumber = 0,
.interface.bAlternateSetting = 0,
.interface.bNumEndpoints = 2,
.interface.bInterfaceClass = 0x03, // Human Interface Device Class.
.interface.bInterfaceSubClass = 0x00, // SCSI Transparent Command Set.
.interface.bInterfaceProtocol = 0x00, // Bulk-Only Transport.
.interface.iInterface = 0x00,
.hid.bLength = 9,
.hid.bDescriptorType = USB_DESCRIPTOR_HID,
.hid.bcdHID = 0x110,
.hid.bCountryCode = 0,
.hid.bNumDescriptors = 1,
.hid.bClassDescriptorType = USB_DESCRIPTOR_HID_REPORT,
.hid.bDescriptorLength = sizeof(hid_report_descriptor_jc),
/* Endpoint descriptor structure EP1 IN */
.endpoint[0].bLength = 7,
.endpoint[0].bDescriptorType = USB_DESCRIPTOR_ENDPOINT,
.endpoint[0].bEndpointAddress = 0x81, // USB_EP_ADDR_BULK_IN.
.endpoint[0].bmAttributes = USB_EP_TYPE_INTR,
.endpoint[0].wMaxPacketSize = 0x200,
.endpoint[0].bInterval = 4, // 8ms on HS.
/* Endpoint descriptor structure EP1 OUT */
.endpoint[1].bLength = 7,
.endpoint[1].bDescriptorType = USB_DESCRIPTOR_ENDPOINT,
.endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT.
.endpoint[1].bmAttributes = USB_EP_TYPE_INTR,
.endpoint[1].wMaxPacketSize = 0x200,
.endpoint[1].bInterval = 4 // 8ms on HS.
};
static u8 usb_vendor_string_descriptor_hid[22] =
{
16, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0,
'U', 0, 'S', 0, 'B', 0
};
static u8 usb_product_string_descriptor_hid_jc[24] =
{
24, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0,
'J', 0, 'o', 0, 'y', 0, '-', 0, 'C', 0, 'o', 0, 'n', 0
};
static u8 usb_product_string_descriptor_hid_touch[26] =
{
26, 0x03,
'N', 0, 'y', 0, 'x', 0, ' ', 0,
'T', 0, 'o', 0, 'u', 0, 'c', 0, 'h', 0, 'p', 0, 'a', 0, 'd', 0
};
static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_touch =
{ {
/* Configuration descriptor structure */ /* Configuration descriptor structure */
.config.bLength = 9, .config.bLength = 9,
@ -696,7 +498,7 @@ usb_cfg_hid_descr_t usb_configuration_descriptor_hid_touch =
.endpoint[0].bEndpointAddress = 0x81, // USB_EP_ADDR_BULK_IN. .endpoint[0].bEndpointAddress = 0x81, // USB_EP_ADDR_BULK_IN.
.endpoint[0].bmAttributes = USB_EP_TYPE_INTR, .endpoint[0].bmAttributes = USB_EP_TYPE_INTR,
.endpoint[0].wMaxPacketSize = 0x200, .endpoint[0].wMaxPacketSize = 0x200,
.endpoint[0].bInterval = 4, // 4ms on FS, 8ms on HS. .endpoint[0].bInterval = 3, // 4ms on HS.
/* Endpoint descriptor structure EP1 OUT */ /* Endpoint descriptor structure EP1 OUT */
.endpoint[1].bLength = 7, .endpoint[1].bLength = 7,
@ -704,7 +506,7 @@ usb_cfg_hid_descr_t usb_configuration_descriptor_hid_touch =
.endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT. .endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT.
.endpoint[1].bmAttributes = USB_EP_TYPE_INTR, .endpoint[1].bmAttributes = USB_EP_TYPE_INTR,
.endpoint[1].wMaxPacketSize = 0x200, .endpoint[1].wMaxPacketSize = 0x200,
.endpoint[1].bInterval = 4 // 4ms on FS, 8ms on HS. .endpoint[1].bInterval = 3 // 4ms on HS.
}; };
usb_desc_t usb_gadget_ums_descriptors = usb_desc_t usb_gadget_ums_descriptors =
@ -716,6 +518,8 @@ usb_desc_t usb_gadget_ums_descriptors =
.dev_bot = &usb_device_binary_object_descriptor, .dev_bot = &usb_device_binary_object_descriptor,
.vendor = usb_vendor_string_descriptor_ums, .vendor = usb_vendor_string_descriptor_ums,
.product = usb_product_string_descriptor_ums, .product = usb_product_string_descriptor_ums,
.serial = usb_serial_string_descriptor,
.lang_id = usb_lang_id_string_descriptor,
.ms_os = &usb_ms_os_descriptor, .ms_os = &usb_ms_os_descriptor,
.ms_cid = &usb_ms_cid_descriptor, .ms_cid = &usb_ms_cid_descriptor,
.mx_ext = &usb_ms_ext_prop_descriptor_ums .mx_ext = &usb_ms_ext_prop_descriptor_ums
@ -730,6 +534,8 @@ usb_desc_t usb_gadget_hid_jc_descriptors =
.dev_bot = &usb_device_binary_object_descriptor, .dev_bot = &usb_device_binary_object_descriptor,
.vendor = usb_vendor_string_descriptor_hid, .vendor = usb_vendor_string_descriptor_hid,
.product = usb_product_string_descriptor_hid_jc, .product = usb_product_string_descriptor_hid_jc,
.serial = usb_serial_string_descriptor,
.lang_id = usb_lang_id_string_descriptor,
.ms_os = &usb_ms_os_descriptor, .ms_os = &usb_ms_os_descriptor,
.ms_cid = &usb_ms_cid_descriptor, .ms_cid = &usb_ms_cid_descriptor,
.mx_ext = &usb_ms_ext_prop_descriptor_hid .mx_ext = &usb_ms_ext_prop_descriptor_hid
@ -744,9 +550,9 @@ usb_desc_t usb_gadget_hid_touch_descriptors =
.dev_bot = &usb_device_binary_object_descriptor, .dev_bot = &usb_device_binary_object_descriptor,
.vendor = usb_vendor_string_descriptor_hid, .vendor = usb_vendor_string_descriptor_hid,
.product = usb_product_string_descriptor_hid_touch, .product = usb_product_string_descriptor_hid_touch,
.serial = usb_serial_string_descriptor,
.lang_id = usb_lang_id_string_descriptor,
.ms_os = &usb_ms_os_descriptor, .ms_os = &usb_ms_os_descriptor,
.ms_cid = &usb_ms_cid_descriptor, .ms_cid = &usb_ms_cid_descriptor,
.mx_ext = &usb_ms_ext_prop_descriptor_hid .mx_ext = &usb_ms_ext_prop_descriptor_hid
}; };
#endif

View File

@ -22,6 +22,8 @@
#include <gfx_utils.h> #include <gfx_utils.h>
#include <input/joycon.h> #include <input/joycon.h>
#include <input/touch.h> #include <input/touch.h>
#include <soc/hw_init.h>
#include <soc/t210.h>
#include <utils/util.h> #include <utils/util.h>
#include <memory_map.h> #include <memory_map.h>
@ -67,6 +69,7 @@ typedef struct _jc_cal_t
} jc_cal_t; } jc_cal_t;
static jc_cal_t jc_cal_ctx; static jc_cal_t jc_cal_ctx;
static usb_ops_t usb_ops;
static bool _jc_calibration(jc_gamepad_rpt_t *jc_pad) static bool _jc_calibration(jc_gamepad_rpt_t *jc_pad)
{ {
@ -306,16 +309,16 @@ static bool _fts_touch_read(touchpad_report_t *rpt)
static u8 _hid_transfer_start(usb_ctxt_t *usbs, u32 len) static u8 _hid_transfer_start(usb_ctxt_t *usbs, u32 len)
{ {
u8 status = usb_device_write_ep1_in((u8 *)USB_EP_BULK_IN_BUF_ADDR, len, NULL, true); u8 status = usb_ops.usb_device_ep1_in_write((u8 *)USB_EP_BULK_IN_BUF_ADDR, len, NULL, USB_XFER_SYNCED);
if (status == USB_ERROR_XFER_ERROR)
if (status == 26)
{ {
usbs->set_text(usbs->label, "#C7EA46 Status:# Error EP IN"); usbs->set_text(usbs->label, "#FFDD00 Error:# EP IN transfer!");
usbd_flush_endpoint(3); if (usb_ops.usbd_flush_endpoint)
usb_ops.usbd_flush_endpoint(USB_EP_BULK_IN);
} }
// Linux mitigation: If timed out, clear status. // Linux mitigation: If timed out, clear status.
if (status == 3) if (status == USB_ERROR_TIMEOUT)
return 0; return 0;
return status; return status;
@ -350,6 +353,12 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
u32 gadget_type; u32 gadget_type;
u32 polling_time; u32 polling_time;
// Get USB Controller ops.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
usb_device_get_ops(&usb_ops);
else
xusb_device_get_ops(&usb_ops);
if (usbs->type == USB_HID_GAMEPAD) if (usbs->type == USB_HID_GAMEPAD)
{ {
polling_time = 8000; polling_time = 8000;
@ -363,21 +372,21 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
usbs->set_text(usbs->label, "#C7EA46 Status:# Started USB"); usbs->set_text(usbs->label, "#C7EA46 Status:# Started USB");
if (usb_device_init()) if (usb_ops.usb_device_init())
{ {
usbd_end(false, true); usb_ops.usbd_end(false, true);
return 1; return 1;
} }
usbs->set_text(usbs->label, "#C7EA46 Status:# Waiting for connection"); usbs->set_text(usbs->label, "#C7EA46 Status:# Waiting for connection");
// Initialize Control Endpoint. // Initialize Control Endpoint.
if (usb_device_ep0_initialize(gadget_type)) if (usb_ops.usb_device_enumerate(gadget_type))
goto error; goto error;
usbs->set_text(usbs->label, "#C7EA46 Status:# Waiting for HID report request"); usbs->set_text(usbs->label, "#C7EA46 Status:# Waiting for HID report request");
if (usb_device_get_hid_report()) if (usb_ops.usb_device_class_send_hid_report())
goto error; goto error;
usbs->set_text(usbs->label, "#C7EA46 Status:# Started HID emulation"); usbs->set_text(usbs->label, "#C7EA46 Status:# Started HID emulation");
@ -400,11 +409,11 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
} }
// Check for suspended USB in case the cable was pulled. // Check for suspended USB in case the cable was pulled.
if (usb_device_get_suspended()) if (usb_ops.usb_device_get_suspended())
break; // Disconnected. break; // Disconnected.
// Handle control endpoint. // Handle control endpoint.
usbd_handle_ep0_pending_control_transfer(); usb_ops.usbd_handle_ep0_ctrl_setup();
// Wait max gadget timing. // Wait max gadget timing.
timer = get_tmr_us() - timer; timer = get_tmr_us() - timer;
@ -422,11 +431,11 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
goto exit; goto exit;
error: error:
usbs->set_text(usbs->label, "#C7EA46 Status:# Timed out or canceled"); usbs->set_text(usbs->label, "#FFDD00 Error:# Timed out or canceled");
res = 1; res = 1;
exit: exit:
usbd_end(true, false); usb_ops.usbd_end(true, false);
return res; return res;
} }

View File

@ -23,6 +23,8 @@
#include <usb/usbd.h> #include <usb/usbd.h>
#include <gfx_utils.h> #include <gfx_utils.h>
#include <soc/hw_init.h>
#include <soc/t210.h>
#include <storage/nx_sd.h> #include <storage/nx_sd.h>
#include <storage/sdmmc.h> #include <storage/sdmmc.h>
#include <storage/sdmmc_driver.h> #include <storage/sdmmc_driver.h>
@ -198,7 +200,6 @@ typedef struct _usbd_gadget_ums_t {
u32 lun_idx; // lun index u32 lun_idx; // lun index
logical_unit_t lun; logical_unit_t lun;
u32 bulk_out_maxpacket; // 512
enum ums_state state; // For exception handling. enum ums_state state; // For exception handling.
enum data_direction data_dir; enum data_direction data_dir;
@ -215,12 +216,15 @@ typedef struct _usbd_gadget_ums_t {
int can_stall; int can_stall;
u32 timeouts; u32 timeouts;
bool xusb;
void (*system_maintenance)(bool); void (*system_maintenance)(bool);
void *label; void *label;
void (*set_text)(void *, const char *); void (*set_text)(void *, const char *);
} usbd_gadget_ums_t; } usbd_gadget_ums_t;
static usb_ops_t usb_ops;
static inline void put_array_le_to_be16(u16 val, void *p) static inline void put_array_le_to_be16(u16 val, void *p)
{ {
u8 *_p = p; u8 *_p = p;
@ -271,7 +275,7 @@ 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 ums_handle_ep0_ctrl(usbd_gadget_ums_t *ums)
{ {
if (usbd_handle_ep0_pending_control_transfer()) if (usb_ops.usbd_handle_ep0_ctrl_setup())
raise_exception(ums, UMS_STATE_PROTOCOL_RESET); raise_exception(ums, UMS_STATE_PROTOCOL_RESET);
} }
@ -284,46 +288,56 @@ static int ums_wedge_bulk_in_endpoint(usbd_gadget_ums_t *ums)
static int ums_set_stall(u32 ep) static int ums_set_stall(u32 ep)
{ {
usbd_set_ep_stall(ep, 1); usb_ops.usbd_set_ep_stall(ep, USB_EP_CFG_STALL);
return 0; return 0;
} }
static int ums_clear_stall(u32 ep) static int ums_clear_stall(u32 ep)
{ {
usbd_set_ep_stall(ep, 0); usb_ops.usbd_set_ep_stall(ep, USB_EP_CFG_CLEAR);
return 0; return 0;
} }
static void ums_flush_endpoint(u32 ep)
{
if (usb_ops.usbd_flush_endpoint)
usb_ops.usbd_flush_endpoint(ep);
}
static void _ums_transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32 ep, bool sync) static void _ums_transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32 ep, bool sync)
{ {
if (ep == bulk_ctxt->bulk_in) if (ep == bulk_ctxt->bulk_in)
{ {
bulk_ctxt->bulk_in_status = usb_device_write_ep1_in( bulk_ctxt->bulk_in_status = usb_ops.usb_device_ep1_in_write(
bulk_ctxt->bulk_in_buf, bulk_ctxt->bulk_in_length, bulk_ctxt->bulk_in_buf, bulk_ctxt->bulk_in_length,
&bulk_ctxt->bulk_in_length_actual, sync); &bulk_ctxt->bulk_in_length_actual, sync);
if (bulk_ctxt->bulk_in_status == 26) if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR)
{ {
ums->set_text(ums->label, "#C7EA46 Status:# Error EP IN"); ums->set_text(ums->label, "#FFDD00 Error:# EP IN transfer!");
usbd_flush_endpoint(bulk_ctxt->bulk_in); ums_flush_endpoint(bulk_ctxt->bulk_in);
} }
else if (bulk_ctxt->bulk_in_status == USB2_ERROR_XFER_NOT_ALIGNED)
ums->set_text(ums->label, "#FFDD00 Error:# EP IN Buffer not aligned!");
if (sync) if (sync)
bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY; bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY;
} }
else else
{ {
bulk_ctxt->bulk_out_status = usb_device_read_ep1_out( bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_read(
bulk_ctxt->bulk_out_buf, bulk_ctxt->bulk_out_length, bulk_ctxt->bulk_out_buf, bulk_ctxt->bulk_out_length,
&bulk_ctxt->bulk_out_length_actual, sync); &bulk_ctxt->bulk_out_length_actual, sync);
if (bulk_ctxt->bulk_out_status == 26) if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
{ {
ums->set_text(ums->label, "#C7EA46 Status:# Error EP OUT"); ums->set_text(ums->label, "#FFDD00 Error:# EP OUT transfer!");
usbd_flush_endpoint(bulk_ctxt->bulk_out); ums_flush_endpoint(bulk_ctxt->bulk_out);
} }
else if (bulk_ctxt->bulk_out_status == USB2_ERROR_XFER_NOT_ALIGNED)
ums->set_text(ums->label, "#FFDD00 Error:# EP OUT Buffer not aligned!");
if (sync) if (sync)
bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL; bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL;
@ -332,14 +346,14 @@ static void _ums_transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt,
static void _ums_transfer_out_big_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) static void _ums_transfer_out_big_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
{ {
bulk_ctxt->bulk_out_status = usb_device_read_ep1_out_big_reads( bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_read_big(
bulk_ctxt->bulk_out_buf, bulk_ctxt->bulk_out_length, bulk_ctxt->bulk_out_buf, bulk_ctxt->bulk_out_length,
&bulk_ctxt->bulk_out_length_actual); &bulk_ctxt->bulk_out_length_actual);
if (bulk_ctxt->bulk_out_status == 26) if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
{ {
ums->set_text(ums->label, "#C7EA46 Status:# Error EP OUT"); ums->set_text(ums->label, "#FFDD00 Error:# EP OUT transfer!");
usbd_flush_endpoint(bulk_ctxt->bulk_out); ums_flush_endpoint(bulk_ctxt->bulk_out);
} }
bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL; bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL;
@ -349,24 +363,26 @@ static void _ums_transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt,
{ {
if (ep == bulk_ctxt->bulk_in) if (ep == bulk_ctxt->bulk_in)
{ {
bulk_ctxt->bulk_in_status = usb_device_ep1_in_writing_finish(&bulk_ctxt->bulk_in_length_actual); bulk_ctxt->bulk_in_status = usb_ops.usb_device_ep1_in_writing_finish(
&bulk_ctxt->bulk_in_length_actual);
if (bulk_ctxt->bulk_in_status == 26) if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR)
{ {
ums->set_text(ums->label, "#C7EA46 Status:# Error EP IN"); ums->set_text(ums->label, "#FFDD00 Error:# EP IN transfer!");
usbd_flush_endpoint(bulk_ctxt->bulk_in); ums_flush_endpoint(bulk_ctxt->bulk_in);
} }
bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY; bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY;
} }
else else
{ {
bulk_ctxt->bulk_out_status = usb_device_ep1_out_reading_finish(&bulk_ctxt->bulk_out_length_actual); bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_reading_finish(
&bulk_ctxt->bulk_out_length_actual, 1000000);
if (bulk_ctxt->bulk_out_status == 26) if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
{ {
ums->set_text(ums->label, "#C7EA46 Status:# Error EP OUT"); ums->set_text(ums->label, "#FFDD00 Error:# EP OUT transfer!");
usbd_flush_endpoint(bulk_ctxt->bulk_out); ums_flush_endpoint(bulk_ctxt->bulk_out);
} }
bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL; bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL;
@ -485,7 +501,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
// If an error occurred, report it and its position. // If an error occurred, report it and its position.
if (!amount) if (!amount)
{ {
ums->set_text(ums->label, "#C7EA46 Status:# Error SDMMC Read"); ums->set_text(ums->label, "#FFDD00 Error:# SDMMC Read!");
ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR; ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR;
ums->lun.sense_data_info = lba_offset; ums->lun.sense_data_info = lba_offset;
ums->lun.info_valid = 1; ums->lun.info_valid = 1;
@ -497,7 +513,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
break; break;
// Start the USB transfer. // Start the USB transfer.
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, false); _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_START);
first_read = false; first_read = false;
// Increment our buffer to read new data. // Increment our buffer to read new data.
@ -568,7 +584,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
if (usb_lba_offset >= ums->lun.num_sectors) //////////Check if it works with concurrency if (usb_lba_offset >= ums->lun.num_sectors) //////////Check if it works with concurrency
{ {
ums->set_text(ums->label, "#C7EA46 Status:# Write Error - Past last sector"); ums->set_text(ums->label, "#FFDD00 Error:# Write - Past last sector!");
amount_left_to_req = 0; amount_left_to_req = 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 = usb_lba_offset; ums->lun.sense_data_info = usb_lba_offset;
@ -596,7 +612,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
ums->lun.sense_data = SS_COMMUNICATION_FAILURE; ums->lun.sense_data = SS_COMMUNICATION_FAILURE;
ums->lun.sense_data_info = lba_offset; ums->lun.sense_data_info = lba_offset;
ums->lun.info_valid = 1; ums->lun.info_valid = 1;
sprintf(txt_buf, "#C7EA46 Status:# Write Error - Comm failure %d", bulk_ctxt->bulk_out_status); sprintf(txt_buf, "#FFDD00 Error:# Write - Comm failure %d!", bulk_ctxt->bulk_out_status);
ums->set_text(ums->label, txt_buf); ums->set_text(ums->label, txt_buf);
break; break;
} }
@ -634,7 +650,7 @@ DPRINTF("file write %X @ %X\n", amount, lba_offset);
/* If an error occurred, report it and its position */ /* If an error occurred, report it and its position */
if (!amount) if (!amount)
{ {
ums->set_text(ums->label, "#C7EA46 Status:# Error SDMMC Write"); ums->set_text(ums->label, "#FFDD00 Error:# SDMMC Write!");
ums->lun.sense_data = SS_WRITE_ERROR; ums->lun.sense_data = SS_WRITE_ERROR;
ums->lun.sense_data_info = lba_offset; ums->lun.sense_data_info = lba_offset;
ums->lun.info_valid = 1; ums->lun.info_valid = 1;
@ -645,7 +661,7 @@ DPRINTF("file write %X @ %X\n", amount, lba_offset);
// Did the host decide to stop early? // Did the host decide to stop early?
if (bulk_ctxt->bulk_out_length_actual < bulk_ctxt->bulk_out_length) if (bulk_ctxt->bulk_out_length_actual < bulk_ctxt->bulk_out_length)
{ {
ums->set_text(ums->label, "#C7EA46 Status:# Empty Write"); ums->set_text(ums->label, "#FFDD00 Error:# Empty Write!");
ums->short_packet_received = 1; ums->short_packet_received = 1;
break; break;
} }
@ -699,7 +715,7 @@ DPRINTF("File read %X @ %X\n", amount, lba_offset);
if (!amount) if (!amount)
{ {
ums->set_text(ums->label, "#C7EA46 Status:# Error file verify"); ums->set_text(ums->label, "#FFDD00 Error:# File verify!");
ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR; ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR;
ums->lun.sense_data_info = lba_offset; ums->lun.sense_data_info = lba_offset;
ums->lun.info_valid = 1; ums->lun.info_valid = 1;
@ -1158,7 +1174,7 @@ DPRINTF("SCSI command: %X; Dc=%d, D%c=%X; Hc=%d, H%c=%X\n",
ums->cmnd[1] &= 0x1F; // Mask away the LUN. ums->cmnd[1] &= 0x1F; // Mask away the LUN.
for (u32 i = 1; i < cmnd_size; ++i) for (u32 i = 1; i < cmnd_size; ++i)
{ {
if (ums->cmnd[i] && !(mask & (1 << i))) if (ums->cmnd[i] && !(mask & BIT(i)))
{ {
ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB; ums->lun.sense_data = SS_INVALID_FIELD_IN_CDB;
@ -1382,7 +1398,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); 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); memset(bulk_ctxt->bulk_in_buf + current_len_to_keep, 0, nsend - current_len_to_keep);
bulk_ctxt->bulk_in_length = nsend; bulk_ctxt->bulk_in_length = nsend;
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, true); _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED);
ums->usb_amount_left -= nsend; ums->usb_amount_left -= nsend;
current_len_to_keep = 0; current_len_to_keep = 0;
} }
@ -1400,7 +1416,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); u32 amount = MIN(ums->usb_amount_left, USB_EP_BUFFER_MAX_SIZE);
bulk_ctxt->bulk_out_length = amount; bulk_ctxt->bulk_out_length = amount;
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, true); _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED);
ums->usb_amount_left -= amount; ums->usb_amount_left -= amount;
return 0; return 0;
@ -1412,7 +1428,7 @@ static int throw_away_data(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
// A short packet or an error ends everything. // A short packet or an error ends everything.
if (bulk_ctxt->bulk_out_length_actual != bulk_ctxt->bulk_out_length || if (bulk_ctxt->bulk_out_length_actual != bulk_ctxt->bulk_out_length ||
bulk_ctxt->bulk_out_status != 0) bulk_ctxt->bulk_out_status != USB_RES_OK)
{ {
raise_exception(ums, UMS_STATE_ABORT_BULK_OUT); raise_exception(ums, UMS_STATE_ABORT_BULK_OUT);
return -4; // Interrupted system call return -4; // Interrupted system call
@ -1436,7 +1452,7 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
{ {
ums_set_stall(bulk_ctxt->bulk_out); ums_set_stall(bulk_ctxt->bulk_out);
rc = ums_set_stall(bulk_ctxt->bulk_in); rc = ums_set_stall(bulk_ctxt->bulk_in);
ums->set_text(ums->label, "#C7EA46 Status:# Direction unknown. Stalled both EP"); ums->set_text(ums->label, "#FFDD00 Error:# Direction unknown. Stalled both EP!");
} // Else do nothing. } // Else do nothing.
break; break;
@ -1447,7 +1463,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 there's no residue, simply send the last buffer.
if (!ums->residue) if (!ums->residue)
{ {
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, true); _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED);
/* For Bulk-only, if we're allowed to stall then send the /* For Bulk-only, if we're allowed to stall then send the
* short packet and halt the bulk-in endpoint. If we can't * short packet and halt the bulk-in endpoint. If we can't
@ -1455,9 +1471,9 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
} }
else if (ums->can_stall) else if (ums->can_stall)
{ {
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, true); _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED);
rc = ums_set_stall(bulk_ctxt->bulk_in); rc = ums_set_stall(bulk_ctxt->bulk_in);
ums->set_text(ums->label, "#C7EA46 Status:# Residue. Stalled EP IN"); ums->set_text(ums->label, "#FFDD00 Error:# Residue. Stalled EP IN!");
} }
else else
rc = pad_with_zeros(ums, bulk_ctxt); rc = pad_with_zeros(ums, bulk_ctxt);
@ -1523,27 +1539,29 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
DPRINTF("USB: EP timeout\n"); DPRINTF("USB: EP timeout\n");
// In case we disconnected, exit UMS. // In case we disconnected, exit UMS.
// Raise timeout if removable and didn't got a unit ready command inside 4s. // Raise timeout if removable and didn't got a unit ready command inside 4s.
if (bulk_ctxt->bulk_out_status == 28 || if (bulk_ctxt->bulk_out_status == USB2_ERROR_XFER_EP_DISABLED ||
(bulk_ctxt->bulk_out_status == 3 && ums->lun.removable && !ums->lun.prevent_medium_removal)) (bulk_ctxt->bulk_out_status == USB_ERROR_TIMEOUT && ums->lun.removable && !ums->lun.prevent_medium_removal))
{ {
if (bulk_ctxt->bulk_out_status == 3) if (bulk_ctxt->bulk_out_status == USB_ERROR_TIMEOUT)
{ {
if (usb_device_get_port_status() == 0x885) 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 Status:# EP in sleep");
ums->timeouts += 10; ums->timeouts += 14;
} }
else else if (!ums->xusb) // Timeout only on USB2.
{
ums->timeouts += 4;
DPRINTF("USB: EP removable\n"); DPRINTF("USB: EP removable\n");
} }
}
else else
{ {
gfx_printf("USB: EP disabled\n"); gfx_printf("USB: EP disabled\n");
msleep(500); msleep(500);
}
ums->timeouts += 4; ums->timeouts += 4;
} }
}
if (ums->lun.unmounted) if (ums->lun.unmounted)
{ {
@ -1592,7 +1610,7 @@ static int received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
{ {
ums_set_stall(bulk_ctxt->bulk_out); ums_set_stall(bulk_ctxt->bulk_out);
ums_set_stall(bulk_ctxt->bulk_in); ums_set_stall(bulk_ctxt->bulk_in);
ums->set_text(ums->label, "#C7EA46 Status:# CBW unknown - Stalled both EP"); ums->set_text(ums->label, "#FFDD00 Error:# CBW unknown - Stalled both EP!");
} }
return -22; // Invalid argument. return -22; // Invalid argument.
@ -1634,7 +1652,7 @@ static int get_next_command(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
bulk_ctxt->bulk_out_length = USB_BULK_CB_WRAP_LEN; bulk_ctxt->bulk_out_length = USB_BULK_CB_WRAP_LEN;
/* Queue a request to read a Bulk-only CBW */ /* Queue a request to read a Bulk-only CBW */
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, true); _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED);
/* We will drain the buffer in software, which means we /* We will drain the buffer in software, which means we
* can reuse it for the next filling. No need to advance * can reuse it for the next filling. No need to advance
@ -1659,7 +1677,7 @@ static void send_status(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
if (ums->phase_error) if (ums->phase_error)
{ {
ums->set_text(ums->label, "#C7EA46 Status:# Phase-error"); ums->set_text(ums->label, "#FFDD00 Error:# Phase-error!");
status = USB_STATUS_PHASE_ERROR; status = USB_STATUS_PHASE_ERROR;
sd = SS_INVALID_COMMAND; sd = SS_INVALID_COMMAND;
} }
@ -1680,7 +1698,7 @@ static void send_status(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
csw->Status = status; csw->Status = status;
bulk_ctxt->bulk_in_length = USB_BULK_CS_WRAP_LEN; bulk_ctxt->bulk_in_length = USB_BULK_CS_WRAP_LEN;
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, true); _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED);
} }
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)
@ -1688,8 +1706,8 @@ static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
enum ums_state old_state; enum ums_state old_state;
/* Clear out the controller's fifos */ /* Clear out the controller's fifos */
usbd_flush_endpoint(bulk_ctxt->bulk_in); ums_flush_endpoint(bulk_ctxt->bulk_in);
usbd_flush_endpoint(bulk_ctxt->bulk_out); ums_flush_endpoint(bulk_ctxt->bulk_out);
/* Reset the I/O buffer states and pointers, the SCSI /* Reset the I/O buffer states and pointers, the SCSI
* state, and the exception. Then invoke the handler. */ * state, and the exception. Then invoke the handler. */
@ -1764,26 +1782,32 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
int res = 0; int res = 0;
sdmmc_t sdmmc; sdmmc_t sdmmc;
sdmmc_storage_t storage; sdmmc_storage_t storage;
usbd_gadget_ums_t ums = {0};
// Get USB Controller ops.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
usb_device_get_ops(&usb_ops);
else
{
ums.xusb = true;
xusb_device_get_ops(&usb_ops);
}
usbs->set_text(usbs->label, "#C7EA46 Status:# Started USB"); usbs->set_text(usbs->label, "#C7EA46 Status:# Started USB");
if (usb_device_init()) if (usb_ops.usb_device_init())
{ {
usbd_end(false, true); usb_ops.usbd_end(false, true);
return 1; return 1;
} }
usbd_gadget_ums_t ums;
memset(&ums, 0, sizeof(usbd_gadget_ums_t));
ums.bulk_out_maxpacket = usbd_get_max_pkt_length(USB_EP_BULK_IN);
ums.state = UMS_STATE_NORMAL; ums.state = UMS_STATE_NORMAL;
ums.can_stall = 0; ums.can_stall = 0;
ums.bulk_ctxt.bulk_in = 3; 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_in_buf = (u8 *)USB_EP_BULK_IN_BUF_ADDR;
ums.bulk_ctxt.bulk_out = 2; ums.bulk_ctxt.bulk_out = USB_EP_BULK_OUT;
ums.bulk_ctxt.bulk_out_buf = (u8 *)USB_EP_BULK_OUT_BUF_ADDR; ums.bulk_ctxt.bulk_out_buf = (u8 *)USB_EP_BULK_OUT_BUF_ADDR;
// Set LUN parameters. // Set LUN parameters.
@ -1820,12 +1844,12 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
ums.set_text(ums.label, "#C7EA46 Status:# Waiting for connection"); ums.set_text(ums.label, "#C7EA46 Status:# Waiting for connection");
// Initialize Control Endpoint. // Initialize Control Endpoint.
if (usb_device_ep0_initialize(USB_GADGET_UMS)) if (usb_ops.usb_device_enumerate(USB_GADGET_UMS))
goto error; goto error;
ums.set_text(ums.label, "#C7EA46 Status:# Waiting for LUN"); ums.set_text(ums.label, "#C7EA46 Status:# Waiting for LUN");
if (usb_device_get_max_lun(0)) // One device for now. if (usb_ops.usb_device_class_send_max_lun(0)) // One device for now.
goto error; goto error;
ums.set_text(ums.label, "#C7EA46 Status:# Started UMS"); ums.set_text(ums.label, "#C7EA46 Status:# Started UMS");
@ -1878,14 +1902,14 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
goto exit; goto exit;
error: error:
ums.set_text(ums.label, "#C7EA46 Status:# Timed out or canceled"); ums.set_text(ums.label, "#FFDD00 Error:# Timed out or canceled!");
res = 1; res = 1;
exit: exit:
if (ums.lun.type == MMC_EMMC) if (ums.lun.type == MMC_EMMC)
sdmmc_storage_end(ums.lun.storage); sdmmc_storage_end(ums.lun.storage);
usbd_end(true, false); usb_ops.usbd_end(true, false);
return res; return res;
} }

View File

@ -1,7 +1,7 @@
/* /*
* USB driver for Tegra X1 * Enhanced & eXtensible USB device (EDCI & XDCI) driver for Tegra X1
* *
* Copyright (c) 2019 CTCaer * Copyright (c) 2019-2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -21,14 +21,16 @@
#include <utils/types.h> #include <utils/types.h>
/* EHCI USB */
/* General USB registers */ /* General USB registers */
#define USB1_IF_USB_SUSP_CTRL 0x400 #define USB1_IF_USB_SUSP_CTRL 0x400
#define SUSP_CTRL_USB_WAKE_ON_CNNT_EN_DEV (1 << 3) #define SUSP_CTRL_USB_WAKE_ON_CNNT_EN_DEV BIT(3)
#define SUSP_CTRL_USB_WAKE_ON_DISCON_EN_DEV (1 << 4) #define SUSP_CTRL_USB_WAKE_ON_DISCON_EN_DEV BIT(4)
#define SUSP_CTRL_USB_PHY_CLK_VALID (1 << 7) #define SUSP_CTRL_USB_PHY_CLK_VALID BIT(7)
#define SUSP_CTRL_UTMIP_RESET (1 << 11) #define SUSP_CTRL_UTMIP_RESET BIT(11)
#define SUSP_CTRL_UTMIP_PHY_ENB (1 << 12) #define SUSP_CTRL_UTMIP_PHY_ENB BIT(12)
#define SUSP_CTRL_UTMIP_UTMIP_SUSPL1_SET (1 << 25) #define SUSP_CTRL_UTMIP_UTMIP_SUSPL1_SET BIT(25)
#define USB1_IF_USB_PHY_VBUS_SENSORS 0x404 #define USB1_IF_USB_PHY_VBUS_SENSORS 0x404
#define USB1_UTMIP_XCVR_CFG0 0x808 #define USB1_UTMIP_XCVR_CFG0 0x808
#define USB1_UTMIP_BIAS_CFG0 0x80C #define USB1_UTMIP_BIAS_CFG0 0x80C
@ -37,6 +39,9 @@
#define USB1_UTMIP_TX_CFG0 0x820 #define USB1_UTMIP_TX_CFG0 0x820
#define USB1_UTMIP_MISC_CFG1 0x828 #define USB1_UTMIP_MISC_CFG1 0x828
#define USB1_UTMIP_DEBOUNCE_CFG0 0x82C #define USB1_UTMIP_DEBOUNCE_CFG0 0x82C
#define USB1_UTMIP_BAT_CHRG_CFG0 0x830
#define BAT_CHRG_CFG0_PWRDOWN_CHRG BIT(0)
#define BAT_CHRG_CFG0_OP_SRC_EN BIT(3)
#define USB1_UTMIP_SPARE_CFG0 0x834 #define USB1_UTMIP_SPARE_CFG0 0x834
#define USB1_UTMIP_XCVR_CFG1 0x838 #define USB1_UTMIP_XCVR_CFG1 0x838
#define USB1_UTMIP_BIAS_CFG1 0x83C #define USB1_UTMIP_BIAS_CFG1 0x83C
@ -46,38 +51,38 @@
/* USB Queue Head Descriptor */ /* USB Queue Head Descriptor */
#define USB2_QH_USB2D_QH_EP_BASE (USB_BASE + 0x1000) #define USB2_QH_USB2D_QH_EP_BASE (USB_BASE + 0x1000)
#define USB_QHD_EP_CAP_IOS_ENABLE (1 << 15) #define USB_QHD_EP_CAP_IOS_ENABLE BIT(15)
#define USB_QHD_EP_CAP_MAX_PKT_LEN_MASK 0x7FF #define USB_QHD_EP_CAP_MAX_PKT_LEN_MASK 0x7FF
#define USB_QHD_EP_CAP_ZERO_LEN_TERM_DIS (1 << 29) #define USB_QHD_EP_CAP_ZERO_LEN_TERM_DIS BIT(29)
#define USB_QHD_EP_CAP_MULTI_NON_ISO (0 << 30) #define USB_QHD_EP_CAP_MULTI_NON_ISO (0 << 30)
#define USB_QHD_EP_CAP_MULTI_1 (1 << 30) #define USB_QHD_EP_CAP_MULTI_1 (1 << 30)
#define USB_QHD_EP_CAP_MULTI_2 (2 << 30) #define USB_QHD_EP_CAP_MULTI_2 (2 << 30)
#define USB_QHD_EP_CAP_MULTI_3 (3 << 30) #define USB_QHD_EP_CAP_MULTI_3 (3 << 30)
#define USB_QHD_TOKEN_XFER_ERROR (1 << 3) #define USB_QHD_TOKEN_XFER_ERROR BIT(3)
#define USB_QHD_TOKEN_BUFFER_ERROR (1 << 5) #define USB_QHD_TOKEN_BUFFER_ERROR BIT(5)
#define USB_QHD_TOKEN_HALTED (1 << 6) #define USB_QHD_TOKEN_HALTED BIT(6)
#define USB_QHD_TOKEN_ACTIVE (1 << 7) #define USB_QHD_TOKEN_ACTIVE BIT(7)
#define USB_QHD_TOKEN_MULT_OVERR_MASK (2 << 10) #define USB_QHD_TOKEN_MULT_OVERR_MASK (2 << 10)
#define USB_QHD_TOKEN_IRQ_ON_COMPLETE (1 << 15) #define USB_QHD_TOKEN_IRQ_ON_COMPLETE BIT(15)
#define USB_QHD_TOKEN_TOTAL_BYTES_SHIFT 16 #define USB_QHD_TOKEN_TOTAL_BYTES_SHIFT 16
/* USB_OTG/USB_1 controllers register bits */ /* USB_OTG/USB_1 controllers register bits */
#define USB2D_PORTSC1_SUSP (1 << 7) #define USB2D_PORTSC1_SUSP BIT(7)
#define USB2D_USBCMD_RUN (1 << 0) #define USB2D_USBCMD_RUN BIT(0)
#define USB2D_USBCMD_RESET (1 << 1) #define USB2D_USBCMD_RESET BIT(1)
#define USB2D_USBCMD_ITC_MASK (0xFF << 16) #define USB2D_USBCMD_ITC_MASK (0xFF << 16)
#define USB2D_USBSTS_UI (1 << 0) #define USB2D_USBSTS_UI BIT(0)
#define USB2D_USBSTS_UEI (1 << 1) #define USB2D_USBSTS_UEI BIT(1)
#define USB2D_USBSTS_PCI (1 << 2) #define USB2D_USBSTS_PCI BIT(2)
#define USB2D_USBSTS_FRI (1 << 3) #define USB2D_USBSTS_FRI BIT(3)
#define USB2D_USBSTS_SEI (1 << 4) #define USB2D_USBSTS_SEI BIT(4)
#define USB2D_USBSTS_AAI (1 << 5) #define USB2D_USBSTS_AAI BIT(5)
#define USB2D_USBSTS_URI (1 << 6) #define USB2D_USBSTS_URI BIT(6)
#define USB2D_USBSTS_SRI (1 << 7) #define USB2D_USBSTS_SRI BIT(7)
#define USB2D_USBSTS_SLI (1 << 8) #define USB2D_USBSTS_SLI BIT(8)
#define USB2D_USBMODE_CM_MASK (3 << 0) #define USB2D_USBMODE_CM_MASK (3 << 0)
#define USB2D_USBMODE_CM_IDLE 0 #define USB2D_USBMODE_CM_IDLE 0
@ -85,33 +90,33 @@
#define USB2D_USBMODE_CM_DEVICE 2 #define USB2D_USBMODE_CM_DEVICE 2
#define USB2D_USBMODE_CM_HOST 3 #define USB2D_USBMODE_CM_HOST 3
#define USB2D_ENDPT_STATUS_RX_OFFSET (1 << 0) #define USB2D_ENDPT_STATUS_RX_OFFSET BIT(0)
#define USB2D_ENDPT_STATUS_TX_OFFSET (1 << 16) #define USB2D_ENDPT_STATUS_TX_OFFSET BIT(16)
#define USB2D_ENDPTCTRL_RX_EP_STALL (1 << 0) #define USB2D_ENDPTCTRL_RX_EP_STALL BIT(0)
#define USB2D_ENDPTCTRL_RX_EP_TYPE_CTRL (0 << 2) #define USB2D_ENDPTCTRL_RX_EP_TYPE_CTRL (0 << 2)
#define USB2D_ENDPTCTRL_RX_EP_TYPE_ISO (1 << 2) #define USB2D_ENDPTCTRL_RX_EP_TYPE_ISO (1 << 2)
#define USB2D_ENDPTCTRL_RX_EP_TYPE_BULK (2 << 2) #define USB2D_ENDPTCTRL_RX_EP_TYPE_BULK (2 << 2)
#define USB2D_ENDPTCTRL_RX_EP_TYPE_INTR (3 << 2) #define USB2D_ENDPTCTRL_RX_EP_TYPE_INTR (3 << 2)
#define USB2D_ENDPTCTRL_RX_EP_TYPE_MASK (3 << 2) #define USB2D_ENDPTCTRL_RX_EP_TYPE_MASK (3 << 2)
#define USB2D_ENDPTCTRL_RX_EP_INHIBIT (1 << 5) #define USB2D_ENDPTCTRL_RX_EP_INHIBIT BIT(5)
#define USB2D_ENDPTCTRL_RX_EP_RESET (1 << 6) #define USB2D_ENDPTCTRL_RX_EP_RESET BIT(6)
#define USB2D_ENDPTCTRL_RX_EP_ENABLE (1 << 7) #define USB2D_ENDPTCTRL_RX_EP_ENABLE BIT(7)
#define USB2D_ENDPTCTRL_TX_EP_STALL (1 << 16) #define USB2D_ENDPTCTRL_TX_EP_STALL BIT(16)
#define USB2D_ENDPTCTRL_TX_EP_TYPE_CTRL (0 << 18) #define USB2D_ENDPTCTRL_TX_EP_TYPE_CTRL (0 << 18)
#define USB2D_ENDPTCTRL_TX_EP_TYPE_ISO (1 << 18) #define USB2D_ENDPTCTRL_TX_EP_TYPE_ISO (1 << 18)
#define USB2D_ENDPTCTRL_TX_EP_TYPE_BULK (2 << 18) #define USB2D_ENDPTCTRL_TX_EP_TYPE_BULK (2 << 18)
#define USB2D_ENDPTCTRL_TX_EP_TYPE_INTR (3 << 18) #define USB2D_ENDPTCTRL_TX_EP_TYPE_INTR (3 << 18)
#define USB2D_ENDPTCTRL_TX_EP_TYPE_MASK (3 << 18) #define USB2D_ENDPTCTRL_TX_EP_TYPE_MASK (3 << 18)
#define USB2D_ENDPTCTRL_TX_EP_INHIBIT (1 << 21) #define USB2D_ENDPTCTRL_TX_EP_INHIBIT BIT(21)
#define USB2D_ENDPTCTRL_TX_EP_RESET (1 << 22) #define USB2D_ENDPTCTRL_TX_EP_RESET BIT(22)
#define USB2D_ENDPTCTRL_TX_EP_ENABLE (1 << 23) #define USB2D_ENDPTCTRL_TX_EP_ENABLE BIT(23)
#define USB2D_HOSTPC1_DEVLC_ASUS (1 << 17) #define USB2D_HOSTPC1_DEVLC_ASUS BIT(17)
#define USB2D_HOSTPC1_DEVLC_PHCD (1 << 22) #define USB2D_HOSTPC1_DEVLC_PHCD BIT(22)
#define USB2D_HOSTPC1_DEVLC_PSPD_MASK (3 << 25) #define USB2D_HOSTPC1_DEVLC_PSPD_MASK (3 << 25)
#define USB2D_OTGSC_USB_ID_PULLUP (1 << 5) #define USB2D_OTGSC_USB_ID_PULLUP BIT(5)
#define USB2D_OTGSC_USB_IRQ_STS_MASK (0x7F << 16) #define USB2D_OTGSC_USB_IRQ_STS_MASK (0x7F << 16)
/* USB_OTG/USB_1 controllers registers */ /* USB_OTG/USB_1 controllers registers */
@ -169,4 +174,119 @@ typedef struct _t210_usb2d_t
vu32 endptctrl[16]; vu32 endptctrl[16];
} t210_usb2d_t; } t210_usb2d_t;
/* XHCI USB */
/* XUSB DEV XHCI registers */
#define XUSB_DEV_XHCI_DB 0x4
#define XUSB_DEV_XHCI_ERSTSZ 0x8
#define XUSB_DEV_XHCI_ERST0BALO 0x10
#define XUSB_DEV_XHCI_ERST0BAHI 0x14
#define XUSB_DEV_XHCI_ERST1BALO 0x18
#define XUSB_DEV_XHCI_ERST1BAHI 0x1C
#define XUSB_DEV_XHCI_ERDPLO 0x20
#define XHCI_ERDPLO_EHB BIT(3)
#define XUSB_DEV_XHCI_ERDPHI 0x24
#define XUSB_DEV_XHCI_EREPLO 0x28
#define XCHI_ECS BIT(0)
#define XUSB_DEV_XHCI_EREPHI 0x2C
#define XUSB_DEV_XHCI_CTRL 0x30
#define XHCI_CTRL_RUN BIT(0)
#define XHCI_CTRL_LSE BIT(1)
#define XHCI_CTRL_IE BIT(4)
#define XHCI_CTRL_ENABLE BIT(31)
#define XUSB_DEV_XHCI_ST 0x34
#define XHCI_ST_RC BIT(0)
#define XHCI_ST_IP BIT(4)
#define XUSB_DEV_XHCI_PORTSC 0x3C
#define XHCI_PORTSC_PR BIT(4)
#define XHCI_PORTSC_PLS_MASK (0xF << 5)
#define XHCI_PORTSC_PLS_U0 (0 << 5)
#define XHCI_PORTSC_PLS_U1 (1 << 5)
#define XHCI_PORTSC_PLS_U2 (2 << 5)
#define XHCI_PORTSC_PLS_U3 (3 << 5)
#define XHCI_PORTSC_PLS_DISABLED (4 << 5)
#define XHCI_PORTSC_PLS_RXDETECT (5 << 5)
#define XHCI_PORTSC_PLS_INACTIVE (6 << 5)
#define XHCI_PORTSC_PLS_POLLING (7 << 5)
#define XHCI_PORTSC_PLS_RECOVERY (8 << 5)
#define XHCI_PORTSC_PLS_HOTRESET (9 << 5)
#define XHCI_PORTSC_PLS_COMPLIANCE (10 << 5)
#define XHCI_PORTSC_PLS_LOOPBACK (11 << 5)
#define XHCI_PORTSC_PLS_RESUME (15 << 5)
#define XHCI_PORTSC_PS (0xF << 10)
#define XHCI_PORTSC_LWS BIT(16)
#define XHCI_PORTSC_CSC BIT(17)
#define XHCI_PORTSC_WRC BIT(19)
#define XHCI_PORTSC_PRC BIT(21)
#define XHCI_PORTSC_PLC BIT(22)
#define XHCI_PORTSC_CEC BIT(23)
#define XHCI_PORTSC_WPR BIT(30)
#define XUSB_DEV_XHCI_ECPLO 0x40
#define XUSB_DEV_XHCI_ECPHI 0x44
#define XUSB_DEV_XHCI_EP_HALT 0x50
#define XHCI_EP_HALT_DCI BIT(0)
#define XUSB_DEV_XHCI_EP_PAUSE 0x54
#define XUSB_DEV_XHCI_EP_RELOAD 0x58
#define XUSB_DEV_XHCI_EP_STCHG 0x5C
#define XUSB_DEV_XHCI_PORTHALT 0x6C
#define XHCI_PORTHALT_HALT_LTSSM BIT(0)
#define XHCI_PORTHALT_STCHG_REQ BIT(20)
#define XUSB_DEV_XHCI_CFG_DEV_FE 0x85C
#define XHCI_CFG_DEV_FE_PORTREGSEL_MASK (3 << 0)
#define XHCI_CFG_DEV_FE_PORTREGSEL_SS (1 << 0)
#define XHCI_CFG_DEV_FE_PORTREGSEL_HSFS (2 << 0)
/* XUSB DEV PCI registers */
#define XUSB_CFG_1 0x4
#define CFG_1_IO_SPACE BIT(0)
#define CFG_1_MEMORY_SPACE BIT(1)
#define CFG_1_BUS_MASTER BIT(2)
#define XUSB_CFG_4 0x10
#define CFG_4_ADDRESS_TYPE_32_BIT (0 << 1)
#define CFG_4_ADDRESS_TYPE_64_BIT (2 << 1)
/* XUSB DEV Device registers */
#define XUSB_DEV_CONFIGURATION 0x180
#define DEV_CONFIGURATION_EN_FPCI BIT(0)
#define XUSB_DEV_INTR_MASK 0x188
#define DEV_INTR_MASK_IP_INT_MASK BIT(16)
/* XUSB Pad Control registers */
#define XUSB_PADCTL_USB2_PAD_MUX 0x4
#define PADCTL_USB2_PAD_MUX_USB2_OTG_PAD_PORT0_USB2 (0 << 0)
#define PADCTL_USB2_PAD_MUX_USB2_OTG_PAD_PORT0_XUSB (1 << 0)
#define PADCTL_USB2_PAD_MUX_USB2_OTG_PAD_PORT0_MASK (3 << 0)
#define PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_USB2 (0 << 18)
#define PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_XUSB (1 << 18)
#define PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_MASK (3 << 18)
#define XUSB_PADCTL_USB2_PORT_CAP 0x8
#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_DIS (0 << 0)
#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_HOST (1 << 0)
#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_DEV (2 << 0)
#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_OTG (3 << 0)
#define PADCTL_USB2_PORT_CAP_PORT_0_CAP_MASK (3 << 0)
#define XUSB_PADCTL_SS_PORT_MAP 0x14
#define PADCTL_SS_PORT_MAP_PORT0_MASK (0xF << 0)
#define XUSB_PADCTL_ELPG_PROGRAM_0 0x20
#define XUSB_PADCTL_ELPG_PROGRAM_1 0x24
#define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD0_CTL0 0x80
#define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD0_CTL1 0x84
#define XUSB_PADCTL_USB2_OTG_PAD0_CTL_0 0x88
#define XUSB_PADCTL_USB2_OTG_PAD0_CTL_1 0x8C
#define XUSB_PADCTL_USB2_BIAS_PAD_CTL_0 0x284
#define XUSB_PADCTL_USB2_BIAS_PAD_CTL_1 0x288
#define XUSB_PADCTL_USB2_VBUS_ID 0xC60
#define PADCTL_USB2_VBUS_ID_VBUS_OVR_EN (1 << 12)
#define PADCTL_USB2_VBUS_ID_VBUS_OVR_MASK (3 << 12)
#define PADCTL_USB2_VBUS_ID_VBUS_ON BIT(14)
#define PADCTL_USB2_VBUS_ID_SRC_ID_OVR_EN (1 << 16)
#define PADCTL_USB2_VBUS_ID_SRC_MASK (3 << 16)
#define PADCTL_USB2_VBUS_ID_OVR_GND (0 << 18)
#define PADCTL_USB2_VBUS_ID_OVR_C (1 << 18)
#define PADCTL_USB2_VBUS_ID_OVR_B (2 << 18)
#define PADCTL_USB2_VBUS_ID_OVR_A (4 << 18)
#define PADCTL_USB2_VBUS_ID_OVR_FLOAT (8 << 18)
#define PADCTL_USB2_VBUS_ID_OVR_MASK (0xF << 18)
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
* USB Device driver for Tegra X1 * Enhanced & eXtensible USB Device (EDCI & XDCI) driver for Tegra X1
* *
* Copyright (c) 2019 CTCaer * Copyright (c) 2019 CTCaer
* *
@ -28,6 +28,155 @@
#define USB_EP_BUFFER_2_TD (USB_TD_BUFFER_MAX_SIZE * 2) #define USB_EP_BUFFER_2_TD (USB_TD_BUFFER_MAX_SIZE * 2)
#define USB_EP_BUFFER_4_TD (USB_TD_BUFFER_MAX_SIZE * 4) #define USB_EP_BUFFER_4_TD (USB_TD_BUFFER_MAX_SIZE * 4)
#define USB_EP_BUFFER_MAX_SIZE (USB_EP_BUFFER_4_TD) #define USB_EP_BUFFER_MAX_SIZE (USB_EP_BUFFER_4_TD)
#define USB_EP_BUFFER_ALIGN (USB_TD_BUFFER_PAGE_SIZE)
#define USB_XFER_START false
#define USB_XFER_SYNCED true
typedef enum _usb_hid_type
{
USB_HID_GAMEPAD,
USB_HID_TOUCHPAD
} usb_hid_type;
typedef enum _usb_gadget_type
{
USB_GADGET_UMS = 0,
USB_GADGET_HID_GAMEPAD = 1,
USB_GADGET_HID_TOUCHPAD = 2,
} usb_gadget_type;
typedef enum {
USB_DIR_OUT = 0,
USB_DIR_IN = 1,
} usb_dir_t;
typedef enum
{
XUSB_EP_CTRL_IN = 0, // EP0.
XUSB_EP_CTRL_OUT = 1, // EP0.
USB_EP_CTRL_OUT = 0, // EP0.
USB_EP_CTRL_IN = 1, // EP0.
USB_EP_BULK_OUT = 2, // EP1.
USB_EP_BULK_IN = 3, // EP1.
USB_EP_ALL = 0xFFFFFFFF
} usb_ep_t;
typedef enum
{
USB_EP_ADDR_CTRL_OUT = 0x00,
USB_EP_ADDR_CTRL_IN = 0x80,
USB_EP_ADDR_BULK_OUT = 0x01,
USB_EP_ADDR_BULK_IN = 0x81,
} usb_ep_addr_t;
typedef enum
{
USB_EP_CFG_CLEAR = 0,
USB_EP_CFG_RESET = 0,
USB_EP_CFG_STALL = 1
} usb_ep_cfg_t;
typedef enum {
USB_STATUS_EP_OK = 0,
USB_STATUS_EP_HALTED = 1,
USB_STATUS_DEV_SELF_POWERED = 1,
USB_STATUS_DEV_REMOTE_WAKE = 2,
} usb_set_clear_feature_req_t;
typedef enum {
USB_SETUP_RECIPIENT_DEVICE = 0,
USB_SETUP_RECIPIENT_INTERFACE = 1,
USB_SETUP_RECIPIENT_ENDPOINT = 2,
USB_SETUP_RECIPIENT_OTHER = 3,
USB_SETUP_TYPE_STANDARD = 0x00,
USB_SETUP_TYPE_CLASS = 0x20,
USB_SETUP_TYPE_VENDOR = 0x40,
USB_SETUP_TYPE_RESERVED = 0x60,
USB_SETUP_HOST_TO_DEVICE = 0x00,
USB_SETUP_DEVICE_TO_HOST = 0x80,
} usb_setup_req_type_t;
typedef enum {
USB_REQUEST_GET_STATUS = 0,
USB_REQUEST_CLEAR_FEATURE = 1,
USB_REQUEST_SET_FEATURE = 3,
USB_REQUEST_SET_ADDRESS = 5,
USB_REQUEST_GET_DESCRIPTOR = 6,
USB_REQUEST_SET_DESCRIPTOR = 7,
USB_REQUEST_GET_CONFIGURATION = 8,
USB_REQUEST_SET_CONFIGURATION = 9,
USB_REQUEST_GET_INTERFACE = 10,
USB_REQUEST_SET_INTERFACE = 11,
USB_REQUEST_SYNCH_FRAME = 12,
USB_REQUEST_SET_SEL = 13,
USB_REQUEST_GET_MS_DESCRIPTOR = 0x99,
USB_REQUEST_BULK_GET_MAX_LUN = 0xFE,
USB_REQUEST_BULK_RESET = 0xFF
} usb_standard_req_t;
typedef enum {
USB_FEATURE_ENDPOINT_HALT = 0,
USB_FEATURE_DEVICE_REMOTE_WAKEUP = 1,
USB_FEATURE_TEST_MODE = 2,
} usb_get_status_req_t;
typedef enum _usb_error_t
{
USB_RES_OK = 0,
USB_RES_BULK_RESET = 1,
USB_ERROR_USER_ABORT = 2,
USB_ERROR_TIMEOUT = 3,
USB_ERROR_INIT = 4,
USB_ERROR_XFER_ERROR = 5,
USB2_ERROR_XFER_EP_DISABLED = 28,
USB2_ERROR_XFER_NOT_ALIGNED = 29,
XUSB_ERROR_INVALID_EP = USB_ERROR_XFER_ERROR, // From 2.
XUSB_ERROR_XFER_BULK_IN_RESIDUE = 7,
XUSB_ERROR_INVALID_CYCLE = USB2_ERROR_XFER_EP_DISABLED, // From 8.
XUSB_ERROR_SEQ_NUM = 51,
XUSB_ERROR_XFER_DIR = 52,
XUSB_ERROR_PORT_CFG = 54
} usb_error_t;
typedef struct _usb_ctrl_setup_t
{
u8 bmRequestType;
u8 bRequest;
u16 wValue;
u16 wIndex;
u16 wLength;
} usb_ctrl_setup_t;
typedef struct _usb_ops_t
{
int (*usbd_flush_endpoint)(u32);
int (*usbd_set_ep_stall)(u32, int);
int (*usbd_handle_ep0_ctrl_setup)();
void (*usbd_end)(bool, bool);
int (*usb_device_init)();
int (*usb_device_enumerate)(usb_gadget_type gadget);
int (*usb_device_class_send_max_lun)(u8);
int (*usb_device_class_send_hid_report)();
int (*usb_device_ep1_out_read)(u8 *, u32, u32 *, bool);
int (*usb_device_ep1_out_read_big)(u8 *, u32, u32 *);
int (*usb_device_ep1_out_reading_finish)(u32 *, int);
int (*usb_device_ep1_in_write)(u8 *, u32, u32 *, bool);
int (*usb_device_ep1_in_writing_finish)(u32 *);
bool (*usb_device_get_suspended)();
bool (*usb_device_get_port_in_sleep)();
} usb_ops_t;
typedef struct _usb_ctxt_t typedef struct _usb_ctxt_t
{ {
@ -41,46 +190,10 @@ typedef struct _usb_ctxt_t
void (*set_text)(void *, const char *); void (*set_text)(void *, const char *);
} usb_ctxt_t; } usb_ctxt_t;
typedef enum _usb_hid_type void usb_device_get_ops(usb_ops_t *ops);
{ void xusb_device_get_ops(usb_ops_t *ops);
USB_HID_GAMEPAD,
USB_HID_TOUCHPAD
} usb_hid_type;
typedef enum _usb_gadget_type
{
USB_GADGET_UMS,
USB_GADGET_HID_GAMEPAD,
USB_GADGET_HID_TOUCHPAD
} usb_gadget_type;
typedef enum
{
USB_EP_CTRL_OUT = 0, // EP0.
USB_EP_CTRL_IN = 1, // EP0.
USB_EP_BULK_OUT = 2, // EP1.
USB_EP_BULK_IN = 3, // EP1.
USB_EP_ALL = 0xFFFFFFFF
} usb_ep_t;
int usbd_flush_endpoint(u32 ep);
void usbd_set_ep_stall(u32 endpoint, int ep_stall);
int usbd_get_max_pkt_length(int endpoint);
int usbd_handle_ep0_pending_control_transfer();
void usbd_end(bool reset_ep, bool only_controller);
int usb_device_init();
int usb_device_ep0_initialize(usb_gadget_type type);
int usb_device_read_ep1_out(u8 *buf, u32 len, u32 *bytes_read, bool sync);
int usb_device_read_ep1_out_big_reads(u8 *buf, u32 len, u32 *bytes_read);
int usb_device_ep1_out_reading_finish(u32 *pending_bytes);
int usb_device_write_ep1_in(u8 *buf, u32 len, u32 *bytes_written, bool sync);
int usb_device_ep1_in_writing_finish(u32 *pending_bytes);
bool usb_device_get_suspended();
int usb_device_gadget_ums(usb_ctxt_t *usbs); int usb_device_gadget_ums(usb_ctxt_t *usbs);
int usb_device_gadget_hid(usb_ctxt_t *usbs); int usb_device_gadget_hid(usb_ctxt_t *usbs);
bool usb_device_get_max_lun(u8 max_lun);
bool usb_device_get_hid_report();
u32 usb_device_get_port_status();
#endif #endif

2022
bdk/usb/xusbd.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -20,10 +20,10 @@
#include <utils/types.h> #include <utils/types.h>
#define BTN_POWER (1 << 0) #define BTN_POWER BIT(0)
#define BTN_VOL_DOWN (1 << 1) #define BTN_VOL_DOWN BIT(1)
#define BTN_VOL_UP (1 << 2) #define BTN_VOL_UP BIT(2)
#define BTN_SINGLE (1 << 7) #define BTN_SINGLE BIT(7)
u8 btn_read(); u8 btn_read();
u8 btn_read_vol(); u8 btn_read_vol();

View File

@ -23,10 +23,12 @@
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define ALIGN_DOWN(x, a) (((x) - ((a) - 1)) & ~((a) - 1)) #define ALIGN_DOWN(x, a) (((x) - ((a) - 1)) & ~((a) - 1))
#define BIT(n) (1U << (n))
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b))
#define DIV_ROUND_UP(a, b) ((a + b - 1) / b) #define DIV_ROUND_UP(a, b) ((a + b - 1) / b)
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
#define LOG2(n) (32 - __builtin_clz(n) - 1) #define LOG2(n) (32 - __builtin_clz(n) - 1)
#define OFFSET_OF(t, m) ((u32)&((t *)NULL)->m) #define OFFSET_OF(t, m) ((u32)&((t *)NULL)->m)
@ -60,17 +62,25 @@ typedef volatile unsigned char vu8;
typedef volatile unsigned short vu16; typedef volatile unsigned short vu16;
typedef volatile unsigned int vu32; typedef volatile unsigned int vu32;
#ifdef __aarch64__
typedef u64 uptr;
#else /* __arm__ or __thumb__ */
typedef u32 uptr;
#endif
static const u32 colors[6] = {COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_GREEN, COLOR_BLUE, COLOR_VIOLET}; static const u32 colors[6] = {COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_GREEN, COLOR_BLUE, COLOR_VIOLET};
typedef int bool; typedef int bool;
#define true 1 #define true 1
#define false 0 #define false 0
#define BOOT_CFG_AUTOBOOT_EN (1 << 0) #define BOOT_CFG_AUTOBOOT_EN BIT(0)
#define BOOT_CFG_FROM_LAUNCH (1 << 1) #define BOOT_CFG_FROM_LAUNCH BIT(1)
#define BOOT_CFG_SEPT_RUN (1 << 7) #define BOOT_CFG_FROM_ID BIT(2)
#define BOOT_CFG_TO_EMUMMC BIT(3)
#define BOOT_CFG_SEPT_RUN BIT(7)
#define EXTRA_CFG_DUMP_EMUMMC (1 << 0) #define EXTRA_CFG_DUMP_EMUMMC BIT(0)
typedef struct __attribute__((__packed__)) _boot_cfg_t typedef struct __attribute__((__packed__)) _boot_cfg_t
{ {
@ -82,8 +92,10 @@ typedef struct __attribute__((__packed__)) _boot_cfg_t
{ {
struct struct
{ {
char id[8]; char id[8]; // 7 char ASCII null teminated.
char emummc_path[0x78]; // emuMMC/XXX, ASCII null teminated.
}; };
u8 ums; // nyx_ums_type.
u8 xt_str[0x80]; u8 xt_str[0x80];
}; };
} boot_cfg_t; } boot_cfg_t;

View File

@ -135,7 +135,7 @@ void panic(u32 val)
void reboot_normal() void reboot_normal()
{ {
sd_end(); sd_end();
reconfig_hw_workaround(false, 0); hw_reinit_workaround(false, 0);
panic(0x21); // Bypass fuse programming in package1. panic(0x21); // Bypass fuse programming in package1.
} }
@ -143,7 +143,7 @@ void reboot_normal()
void reboot_rcm() void reboot_rcm()
{ {
sd_end(); sd_end();
reconfig_hw_workaround(false, 0); hw_reinit_workaround(false, 0);
PMC(APBDEV_PMC_SCRATCH0) = PMC_SCRATCH0_MODE_RCM; PMC(APBDEV_PMC_SCRATCH0) = PMC_SCRATCH0_MODE_RCM;
PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST; PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST;
@ -152,10 +152,27 @@ void reboot_rcm()
bpmp_halt(); bpmp_halt();
} }
void reboot_full()
{
sd_end();
hw_reinit_workaround(false, 0);
// Enable soft reset wake event.
u8 reg = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2);
reg |= MAX77620_ONOFFCNFG2_SFT_RST_WK;
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2, reg);
// Do a soft reset.
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_SFT_RST);
while (true)
bpmp_halt();
}
void power_off() void power_off()
{ {
sd_end(); sd_end();
reconfig_hw_workaround(false, 0); hw_reinit_workaround(false, 0);
// Stop the alarm, in case we injected and powered off too fast. // Stop the alarm, in case we injected and powered off too fast.
max77620_rtc_stop_alarm(); max77620_rtc_stop_alarm();

View File

@ -23,21 +23,23 @@
typedef enum typedef enum
{ {
NYX_CFG_BIS = (1 << 5), NYX_CFG_BIS = BIT(5),
NYX_CFG_UMS = (1 << 6), NYX_CFG_UMS = BIT(6),
NYX_CFG_DUMP = (1 << 7), NYX_CFG_DUMP = BIT(7),
} nyx_cfg_t; } nyx_cfg_t;
typedef enum typedef enum
{ {
ERR_LIBSYS_LP0 = (1 << 0), ERR_LIBSYS_LP0 = BIT(0),
ERR_SYSOLD_NYX = (1 << 1), ERR_SYSOLD_NYX = BIT(1),
ERR_SYSOLD_MTC = (1 << 2), ERR_LIBSYS_MTC = BIT(2),
ERR_EXCEPT_ENB = (1 << 31), ERR_SD_BOOT_EN = BIT(3),
ERR_L4T_KERNEL = BIT(24),
ERR_EXCEPTION = BIT(31),
} hekate_errors_t; } hekate_errors_t;
#define byte_swap_32(num) (((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \ #define byte_swap_32(num) ((((num) >> 24) & 0xff) | (((num) << 8) & 0xff0000) | \
((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000)) (((num) >> 8 )& 0xff00) | (((num) << 24) & 0xff000000))
typedef struct _cfg_op_t typedef struct _cfg_op_t
{ {
@ -71,6 +73,7 @@ void msleep(u32 ms);
void panic(u32 val); void panic(u32 val);
void reboot_normal(); void reboot_normal();
void reboot_rcm(); void reboot_rcm();
void reboot_full();
void power_off(); void power_off();
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops); void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
u32 crc32_calc(u32 crc, const u8 *buf, u32 len); u32 crc32_calc(u32 crc, const u8 *buf, u32 len);

View File

@ -23,6 +23,7 @@
#include "gfx/tui.h" #include "gfx/tui.h"
#include <libs/fatfs/ff.h> #include <libs/fatfs/ff.h>
#include <soc/fuse.h> #include <soc/fuse.h>
#include <soc/hw_init.h>
#include <soc/t210.h> #include <soc/t210.h>
#include <storage/nx_sd.h> #include <storage/nx_sd.h>
#include <storage/sdmmc.h> #include <storage/sdmmc.h>
@ -42,12 +43,14 @@ void set_default_configuration()
h_cfg.autohosoff = 0; h_cfg.autohosoff = 0;
h_cfg.autonogc = 1; h_cfg.autonogc = 1;
h_cfg.updater2p = 0; h_cfg.updater2p = 0;
h_cfg.brand = NULL; h_cfg.bootprotect = 0;
h_cfg.tagline = NULL;
h_cfg.errors = 0; h_cfg.errors = 0;
h_cfg.eks = NULL;
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN; h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
h_cfg.aes_slots_new = false;
h_cfg.rcm_patched = fuse_check_patched_rcm(); h_cfg.rcm_patched = fuse_check_patched_rcm();
h_cfg.emummc_force_disable = false; h_cfg.emummc_force_disable = false;
h_cfg.t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01;
sd_power_cycle_time_start = 0; sd_power_cycle_time_start = 0;
} }

View File

@ -17,6 +17,7 @@
#ifndef _CONFIG_H_ #ifndef _CONFIG_H_
#define _CONFIG_H_ #define _CONFIG_H_
#include "hos/hos.h"
#include <utils/types.h> #include <utils/types.h>
typedef struct _hekate_config typedef struct _hekate_config
@ -29,14 +30,16 @@ typedef struct _hekate_config
u32 autohosoff; u32 autohosoff;
u32 autonogc; u32 autonogc;
u32 updater2p; u32 updater2p;
char *brand; u32 bootprotect;
char *tagline;
// Global temporary config. // Global temporary config.
bool t210b01;
bool se_keygen_done; bool se_keygen_done;
bool sept_run; bool sept_run;
bool aes_slots_new;
bool emummc_force_disable; bool emummc_force_disable;
bool rcm_patched; bool rcm_patched;
u32 errors; u32 errors;
hos_eks_mbr_t *eks;
} hekate_config; } hekate_config;
void set_default_configuration(); void set_default_configuration();

View File

@ -19,6 +19,7 @@
#include <string.h> #include <string.h>
#include "fss.h" #include "fss.h"
#include "hos.h"
#include "../config.h" #include "../config.h"
#include <libs/fatfs/ff.h> #include <libs/fatfs/ff.h>
#include <mem/heap.h> #include <mem/heap.h>
@ -35,6 +36,7 @@ extern bool is_ipl_updated(void *buf, char *path, bool force);
// FSS0 Magic and Meta header offset. // FSS0 Magic and Meta header offset.
#define FSS0_MAGIC 0x30535346 #define FSS0_MAGIC 0x30535346
#define FSS0_META_OFFSET 0x4 #define FSS0_META_OFFSET 0x4
#define FSS0_VERSION_0_17_0 0x110000
// FSS0 Content Types. // FSS0 Content Types.
#define CNT_TYPE_FSP 0 #define CNT_TYPE_FSP 0
@ -48,9 +50,10 @@ extern bool is_ipl_updated(void *buf, char *path, bool force);
#define CNT_TYPE_EMC 8 #define CNT_TYPE_EMC 8
#define CNT_TYPE_KLD 9 // Kernel Loader. #define CNT_TYPE_KLD 9 // Kernel Loader.
#define CNT_TYPE_KRN 10 // Kernel. #define CNT_TYPE_KRN 10 // Kernel.
#define CNT_TYPE_EXF 11 // Exosphere Mariko fatal payload.
// FSS0 Content Flags. // FSS0 Content Flags.
#define CNT_FLAG0_EXPERIMENTAL (1 << 0) #define CNT_FLAG0_EXPERIMENTAL BIT(0)
// FSS0 Meta Header. // FSS0 Meta Header.
typedef struct _fss_meta_t typedef struct _fss_meta_t
@ -85,8 +88,12 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
bool stock = false; bool stock = false;
int sept_used = 0; int sept_used = 0;
// Skip if stock and Exosphere and warmboot are not needed.
if (!sept_ctxt) if (!sept_ctxt)
{ {
bool pkg1_old = ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620;
bool emummc_disabled = !emu_cfg.enabled || h_cfg.emummc_force_disable;
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link) LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link)
{ {
if (!strcmp("stock", kv->key)) if (!strcmp("stock", kv->key))
@ -94,7 +101,11 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
stock = true; stock = true;
} }
if (stock && ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && (!emu_cfg.enabled || h_cfg.emummc_force_disable)) #ifdef HOS_MARIKO_STOCK_SECMON
if (stock && emummc_disabled && (pkg1_old || h_cfg.t210b01))
#else
if (stock && emummc_disabled && pkg1_old)
#endif
return 1; return 1;
} }
@ -113,12 +124,25 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
// Check if valid FSS0 and parse it. // Check if valid FSS0 and parse it.
if (fss_meta->magic == FSS0_MAGIC) if (fss_meta->magic == FSS0_MAGIC)
{ {
bool mariko_not_supported = false;
if (h_cfg.t210b01 && (fss_meta->version < FSS0_VERSION_0_17_0))
{
gfx_con.mute = false;
mariko_not_supported = true;
}
gfx_printf("Found FSS0, Atmosphere %d.%d.%d-%08x\n" gfx_printf("Found FSS0, Atmosphere %d.%d.%d-%08x\n"
"Max HOS supported: %d.%d.%d\n" "Max HOS supported: %d.%d.%d\n"
"Unpacking and loading components.. ", "Unpacking and loading components.. ",
fss_meta->version >> 24, (fss_meta->version >> 16) & 0xFF, (fss_meta->version >> 8) & 0xFF, fss_meta->git_rev, fss_meta->version >> 24, (fss_meta->version >> 16) & 0xFF, (fss_meta->version >> 8) & 0xFF, fss_meta->git_rev,
fss_meta->hos_ver >> 24, (fss_meta->hos_ver >> 16) & 0xFF, (fss_meta->hos_ver >> 8) & 0xFF); fss_meta->hos_ver >> 24, (fss_meta->hos_ver >> 16) & 0xFF, (fss_meta->hos_ver >> 8) & 0xFF);
if (mariko_not_supported)
{
EPRINTF("Mariko not supported on < 0.17.0!");
goto fail;
}
if (!sept_ctxt) if (!sept_ctxt)
{ {
ctxt->atmosphere = true; ctxt->atmosphere = true;
@ -137,7 +161,7 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
continue; continue;
// If content is experimental and experimental flag is not enabled, skip it. // If content is experimental and experimental flag is not enabled, skip it.
if ((curr_fss_cnt[i].flags0 & CNT_FLAG0_EXPERIMENTAL) && !ctxt->fss0_enable_experimental) if ((curr_fss_cnt[i].flags0 & CNT_FLAG0_EXPERIMENTAL) && !ctxt->fss0_experimental)
continue; continue;
// Parse content. // Parse content.
@ -154,14 +178,31 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
list_append(&ctxt->kip1_list, &mkip1->link); list_append(&ctxt->kip1_list, &mkip1->link);
DPRINTF("Loaded %s.kip1 from FSS0 (size %08X)\n", curr_fss_cnt[i].name, curr_fss_cnt[i].size); DPRINTF("Loaded %s.kip1 from FSS0 (size %08X)\n", curr_fss_cnt[i].name, curr_fss_cnt[i].size);
break; break;
case CNT_TYPE_KRN:
if (stock)
continue;
ctxt->kernel_size = curr_fss_cnt[i].size;
ctxt->kernel = content;
break;
case CNT_TYPE_EXO: case CNT_TYPE_EXO:
ctxt->secmon_size = curr_fss_cnt[i].size; ctxt->secmon_size = curr_fss_cnt[i].size;
ctxt->secmon = content; ctxt->secmon = content;
break; break;
case CNT_TYPE_EXF:
ctxt->exofatal_size = curr_fss_cnt[i].size;
ctxt->exofatal = content;
break;
case CNT_TYPE_WBT: case CNT_TYPE_WBT:
if (h_cfg.t210b01)
continue;
ctxt->warmboot_size = curr_fss_cnt[i].size; ctxt->warmboot_size = curr_fss_cnt[i].size;
ctxt->warmboot = content; ctxt->warmboot = content;
break; break;
default: default:
continue; continue;
} }
@ -201,6 +242,7 @@ out:
return (!sept_ctxt ? 1 : sept_used); return (!sept_ctxt ? 1 : sept_used);
} }
fail:
f_close(&fp); f_close(&fp);
free(fss); free(fss);

View File

@ -42,6 +42,9 @@
#define HOS_PKG11_MAGIC 0x31314B50 #define HOS_PKG11_MAGIC 0x31314B50
#define HOS_EKS_MAGIC 0x30534B45 #define HOS_EKS_MAGIC 0x30534B45
// Use official Mariko secmon when in stock.
//#define HOS_MARIKO_STOCK_SECMON
typedef struct _exo_ctxt_t typedef struct _exo_ctxt_t
{ {
bool fs_is_510; bool fs_is_510;
@ -66,17 +69,17 @@ typedef struct _hos_eks_bis_keys_t
typedef struct _hos_eks_mbr_t typedef struct _hos_eks_mbr_t
{ {
u32 magic; u32 magic;
u8 enabled[6]; u8 enabled[5];
u8 enabled_bis; u8 enabled_bis;
u8 rsvd; u8 rsvd[2];
u32 sbk_low; u32 lot0;
u8 dkg[0x10]; u8 dkg[0x10];
u8 dkk[0x10]; u8 dkk[0x10];
hos_eks_keys_t keys[6]; hos_eks_keys_t keys[5];
hos_eks_bis_keys_t bis_keys[3]; hos_eks_bis_keys_t bis_keys[3];
} hos_eks_mbr_t; } hos_eks_mbr_t;
static_assert(sizeof(hos_eks_mbr_t) == 336, "HOS EKS size is wrong!"); static_assert(sizeof(hos_eks_mbr_t) == 304, "HOS EKS size is wrong!");
typedef struct _launch_ctxt_t typedef struct _launch_ctxt_t
{ {
@ -90,6 +93,8 @@ typedef struct _launch_ctxt_t
u32 warmboot_size; u32 warmboot_size;
void *secmon; void *secmon;
u32 secmon_size; u32 secmon_size;
void *exofatal;
u32 exofatal_size;
void *pkg2; void *pkg2;
u32 pkg2_size; u32 pkg2_size;
@ -97,6 +102,7 @@ typedef struct _launch_ctxt_t
void *kernel; void *kernel;
u32 kernel_size; u32 kernel_size;
link_t kip1_list; link_t kip1_list;
char* kip1_patches; char* kip1_patches;
@ -105,7 +111,7 @@ typedef struct _launch_ctxt_t
bool debugmode; bool debugmode;
bool stock; bool stock;
bool atmosphere; bool atmosphere;
bool fss0_enable_experimental; bool fss0_experimental;
bool emummc_forced; bool emummc_forced;
exo_ctxt_t exo_ctx; exo_ctxt_t exo_ctx;

Some files were not shown because too many files have changed in this diff Show More