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