diff --git a/bootloader/config/config.c b/bootloader/config/config.c
index adcfee4..aaaa154 100644
--- a/bootloader/config/config.c
+++ b/bootloader/config/config.c
@@ -47,7 +47,7 @@ void set_default_configuration()
h_cfg.errors = 0;
h_cfg.eks = NULL;
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
- h_cfg.rcm_patched = true;
+ h_cfg.rcm_patched = fuse_check_patched_rcm();
h_cfg.emummc_force_disable = false;
sd_power_cycle_time_start = 0;
diff --git a/bootloader/config/ini.c b/bootloader/config/ini.c
index 4c200dd..b83160c 100644
--- a/bootloader/config/ini.c
+++ b/bootloader/config/ini.c
@@ -81,7 +81,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
// Get all ini filenames.
if (is_dir)
{
- filelist = dirlist(filename, "*.ini", false);
+ filelist = dirlist(filename, "*.ini", false, false);
if (!filelist)
{
free(filename);
diff --git a/bootloader/frontend/fe_emmc_tools.c b/bootloader/frontend/fe_emmc_tools.c
index e3a7468..5da3745 100644
--- a/bootloader/frontend/fe_emmc_tools.c
+++ b/bootloader/frontend/fe_emmc_tools.c
@@ -95,8 +95,8 @@ static int _dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFi
return 1;
}
- se_calc_sha256(hashEm, bufEm, num << 9);
- se_calc_sha256(hashSd, bufSd, num << 9);
+ se_calc_sha256_oneshot(hashEm, bufEm, num << 9);
+ se_calc_sha256_oneshot(hashSd, bufSd, num << 9);
res = memcmp(hashEm, hashSd, 0x10);
if (res)
diff --git a/bootloader/gfx/di.c b/bootloader/gfx/di.c
index 3252475..015df23 100644
--- a/bootloader/gfx/di.c
+++ b/bootloader/gfx/di.c
@@ -145,13 +145,13 @@ void display_init()
// Decode Display ID.
_display_id = ((_display_id >> 8) & 0xFF00) | (_display_id & 0xFF);
- if ((_display_id & 0xFF) == PANEL_JDI_LPM062M)
- _display_id = PANEL_JDI_LPM062M;
+ if ((_display_id & 0xFF) == PANEL_JDI_XXX062M)
+ _display_id = PANEL_JDI_XXX062M;
// Initialize display panel.
switch (_display_id)
{
- case PANEL_JDI_LPM062M:
+ case PANEL_JDI_XXX062M:
exec_cfg((u32 *)DSI_BASE, _display_init_config_jdi, 43);
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
break;
@@ -264,7 +264,7 @@ void display_end()
// De-initialize display panel.
switch (_display_id)
{
- case PANEL_JDI_LPM062M:
+ case PANEL_JDI_XXX062M:
exec_cfg((u32 *)DSI_BASE, _display_deinit_config_jdi, 22);
break;
case PANEL_AUO_A062TAN01:
@@ -337,15 +337,111 @@ void display_color_screen(u32 color)
display_backlight(true);
}
-u32 *display_init_framebuffer()
+u32 *display_init_framebuffer_pitch()
{
// Sanitize framebuffer area.
memset((u32 *)IPL_FB_ADDRESS, 0, 0x3C0000);
// This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
- exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, 32);
+ exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch, 32);
usleep(35000);
return (u32 *)IPL_FB_ADDRESS;
}
+u32 *display_init_framebuffer_pitch_inv()
+{
+ // This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
+ exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch_inv, 34);
+
+ usleep(35000);
+
+ return (u32 *)NYX_FB_ADDRESS;
+}
+
+u32 *display_init_framebuffer_block()
+{
+ // This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
+ exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_block, 34);
+
+ usleep(35000);
+
+ return (u32 *)NYX_FB_ADDRESS;
+}
+
+u32 *display_init_framebuffer_log()
+{
+ // This configures the framebuffer @ LOG_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
+ exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_log, 20);
+
+ return (u32 *)LOG_FB_ADDRESS;
+}
+
+void display_activate_console()
+{
+ DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window C.
+ DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = WIN_ENABLE; // Enable window DD.
+ DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0xFF80;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
+
+ for (u32 i = 0xFF80; i < 0x10000; i++)
+ {
+ DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
+ usleep(1000);
+ }
+
+ DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
+}
+
+void display_deactivate_console()
+{
+ DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window C.
+
+ for (u32 i = 0xFFFF; i > 0xFF7F; i--)
+ {
+ DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
+ usleep(500);
+ }
+
+ DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
+ DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = 0; // Disable window DD.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
+}
+
+void display_init_cursor(void *crs_fb, u32 size)
+{
+ // Setup cursor.
+ DISPLAY_A(_DIREG(DC_DISP_CURSOR_START_ADDR)) = CURSOR_CLIPPING(CURSOR_CLIP_WIN_A) | size | ((u32)crs_fb >> 10);
+ DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) =
+ CURSOR_BLEND_R8G8B8A8 | CURSOR_BLEND_DST_FACTOR(CURSOR_BLEND_K1) | CURSOR_BLEND_SRC_FACTOR(CURSOR_BLEND_K1) | 0xFF;
+
+ DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) |= CURSOR_ENABLE;
+
+ // Arm and activate changes.
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
+}
+
+void display_set_pos_cursor(u32 x, u32 y)
+{
+ DISPLAY_A(_DIREG(DC_DISP_CURSOR_POSITION)) = x | (y << 16);
+
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
+}
+
+void display_deinit_cursor()
+{
+ DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) = 0;
+ DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) &= ~CURSOR_ENABLE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
+ DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
+}
diff --git a/bootloader/gfx/di.h b/bootloader/gfx/di.h
index a160eff..2b4e579 100644
--- a/bootloader/gfx/di.h
+++ b/bootloader/gfx/di.h
@@ -506,7 +506,9 @@
enum
{
- PANEL_JDI_LPM062M = 0x10,
+ PANEL_JDI_XXX062M = 0x10,
+ PANEL_JDI_LAM062M109A = 0x0910,
+ PANEL_JDI_LPM062M326A = 0x2610,
PANEL_INL_P062CCA_AZ1 = 0x0F20,
PANEL_AUO_A062TAN01 = 0x0F30,
PANEL_INL_P062CCA_AZ2 = 0x1020,
@@ -525,7 +527,12 @@ void display_backlight(bool enable);
void display_backlight_brightness(u32 brightness, u32 step_delay);
/*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */
-u32 *display_init_framebuffer();
+u32 *display_init_framebuffer_pitch();
+u32 *display_init_framebuffer_pitch_inv();
+u32 *display_init_framebuffer_block();
+u32 *display_init_framebuffer_log();
+void display_activate_console();
+void display_deactivate_console();
void display_init_cursor(void *crs_fb, u32 size);
void display_set_pos_cursor(u32 x, u32 y);
void display_deinit_cursor();
diff --git a/bootloader/gfx/di.inl b/bootloader/gfx/di.inl
index 9a275eb..ef3b1b0 100644
--- a/bootloader/gfx/di.inl
+++ b/bootloader/gfx/di.inl
@@ -559,8 +559,8 @@ static const cfg_op_t cfg_display_one_color[8] = {
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} // Continuous display.
};
-//Display A config.
-static const cfg_op_t cfg_display_framebuffer[32] = {
+//Display A config linear pitch.
+static const cfg_op_t cfg_display_framebuffer_pitch[32] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
@@ -568,14 +568,14 @@ static const cfg_op_t cfg_display_framebuffer[32] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
- {DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, //NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8
+ {DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
{DC_WIN_WIN_OPTIONS, 0},
{DC_WIN_WIN_OPTIONS, 0},
{DC_WIN_POSITION, 0}, //(0,0)
{DC_WIN_H_INITIAL_DDA, 0},
{DC_WIN_V_INITIAL_DDA, 0},
- {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)},
- {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x
+ {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
+ {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
@@ -594,3 +594,103 @@ static const cfg_op_t cfg_display_framebuffer[32] = {
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
};
+
+//Display A config linear pitch inverse + Win D support.
+static const cfg_op_t cfg_display_framebuffer_pitch_inv[34] = {
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
+ {DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_WIN_POSITION, 0}, //(0,0)
+ {DC_WIN_H_INITIAL_DDA, 0},
+ {DC_WIN_V_INITIAL_DDA, 0},
+ {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
+ {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
+ {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
+ {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
+ {DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
+ {DC_WINBUF_SURFACE_KIND, PITCH},
+ {DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
+ {DC_WINBUF_ADDR_H_OFFSET, 0}, // Linear: 0x383FFC, Block: 0x3813FC.
+ {DC_WINBUF_ADDR_V_OFFSET, 1279}, // Linear: 1279, Block: 0.
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
+ {DC_WIN_WIN_OPTIONS, WIN_ENABLE | V_DIRECTION}, // Enable window AD.
+ {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
+};
+
+//Display A config block linear.
+static const cfg_op_t cfg_display_framebuffer_block[34] = {
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
+ {DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_WIN_POSITION, 0}, //(0,0)
+ {DC_WIN_H_INITIAL_DDA, 0},
+ {DC_WIN_V_INITIAL_DDA, 0},
+ {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
+ {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
+ {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
+ {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
+ {DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
+ {DC_WINBUF_SURFACE_KIND, BLOCK_HEIGHT(4) | BLOCK},
+ {DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
+ {DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, // Linear: 0x383FFC, Block: 0x3813FC.
+ {DC_WINBUF_ADDR_V_OFFSET, 0}, // Linear: 1279, Block: 0.
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
+ {DC_WIN_WIN_OPTIONS, WIN_ENABLE | SCAN_COLUMN | H_DIRECTION}, // Enable window AD. | SCAN_COLUMN | H_DIRECTION.
+ {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
+};
+
+//Display D config.
+static const cfg_op_t cfg_display_framebuffer_log[20] = {
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8},
+ {DC_WIN_POSITION, 0}, //(0,0)
+ {DC_WIN_H_INITIAL_DDA, 0},
+ {DC_WIN_V_INITIAL_DDA, 0},
+ {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(656 * 4)},
+ {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
+ {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(656)},
+ {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(656 * 2) | LINE_STRIDE(656 * 4)}, //656*2x656*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
+ {DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
+ {DC_WINBUF_SURFACE_KIND, PITCH},
+ {DC_WINBUF_START_ADDR, LOG_FB_ADDRESS}, // Framebuffer address.
+ {DC_WINBUF_ADDR_H_OFFSET, 0},
+ {DC_WINBUF_ADDR_V_OFFSET, 0},
+ {DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_ENABLE | WIN_K1(200)},
+ {DC_WINBUF_BLEND_MATCH_SELECT, WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_K1 | WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_NEG_K1},
+ {DC_WIN_WIN_OPTIONS, 0}, // Enable window DD.
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_D_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_D_ACT_REQ}
+};
diff --git a/bootloader/gfx/gfx.c b/bootloader/gfx/gfx.c
index 46551c9..5c30ba7 100644
--- a/bootloader/gfx/gfx.c
+++ b/bootloader/gfx/gfx.c
@@ -121,28 +121,28 @@ static const u8 _gfx_font[] = {
0x00, 0x00, 0x00, 0x4C, 0x32, 0x00, 0x00, 0x00 // Char 126 (~)
};
-void gfx_init_ctxt(u32 *fb, u32 width, u32 height, u32 stride)
-{
- gfx_ctxt.fb = fb;
- gfx_ctxt.width = width;
- gfx_ctxt.height = height;
- gfx_ctxt.stride = stride;
-}
-
void gfx_clear_grey(u8 color)
{
memset(gfx_ctxt.fb, color, gfx_ctxt.width * gfx_ctxt.height * 4);
}
+void gfx_clear_partial_grey(u8 color, u32 pos_x, u32 height)
+{
+ memset(gfx_ctxt.fb + pos_x * gfx_ctxt.stride, color, height * 4 * gfx_ctxt.stride);
+}
+
void gfx_clear_color(u32 color)
{
for (u32 i = 0; i < gfx_ctxt.width * gfx_ctxt.height; i++)
gfx_ctxt.fb[i] = color;
}
-void gfx_clear_partial_grey(u8 color, u32 pos_x, u32 height)
+void gfx_init_ctxt(u32 *fb, u32 width, u32 height, u32 stride)
{
- memset(gfx_ctxt.fb + pos_x * gfx_ctxt.stride, color, height * 4 * gfx_ctxt.stride);
+ gfx_ctxt.fb = fb;
+ gfx_ctxt.width = width;
+ gfx_ctxt.height = height;
+ gfx_ctxt.stride = stride;
}
void gfx_con_init()
diff --git a/bootloader/libs/fatfs/diskio.h b/bootloader/libs/fatfs/diskio.h
index e868352..31b855d 100644
--- a/bootloader/libs/fatfs/diskio.h
+++ b/bootloader/libs/fatfs/diskio.h
@@ -23,6 +23,13 @@ typedef enum {
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
+typedef enum {
+ DRIVE_SD = 0,
+ DRIVE_RAM = 1,
+ DRIVE_EMMC = 2,
+ DRIVE_BIS = 3
+} DDRIVE;
+
/*---------------------------------------*/
/* Prototypes for disk control functions */
@@ -33,6 +40,7 @@ DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
+DRESULT disk_set_info (BYTE pdrv, BYTE cmd, void *buff);
/* Disk Status Bits (DSTATUS) */
diff --git a/bootloader/libs/fatfs/ff.c b/bootloader/libs/fatfs/ff.c
index 732e31b..c6c4d75 100644
--- a/bootloader/libs/fatfs/ff.c
+++ b/bootloader/libs/fatfs/ff.c
@@ -3906,6 +3906,92 @@ FRESULT f_read (
+#if FF_FASTFS && FF_USE_FASTSEEK
+/*-----------------------------------------------------------------------*/
+/* Fast Read Aligned Sized File Without a Cache */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_read_fast (
+ FIL* fp, /* Pointer to the file object */
+ const void* buff, /* Pointer to the data to be written */
+ UINT btr /* Number of bytes to read */
+)
+{
+ FRESULT res;
+ FATFS *fs;
+ UINT csize_bytes;
+ DWORD clst;
+ UINT count = 0;
+ FSIZE_t work_sector = 0;
+ FSIZE_t sector_base = 0;
+ BYTE *wbuff = (BYTE*)buff;
+
+ // TODO support sector reading inside a cluster
+
+ res = validate(&fp->obj, &fs); /* Check validity of the file object */
+ if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
+ EFSPRINTF("FOV");
+ LEAVE_FF(fs, res); /* Check validity */
+ }
+
+ if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
+ FSIZE_t remain = fp->obj.objsize - fp->fptr;
+ if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */
+
+ csize_bytes = fs->csize * SS(fs);
+
+ if (!fp->fptr) { /* On the top of the file? */
+ clst = fp->obj.sclust; /* Follow from the origin */
+ } else {
+ if (fp->cltbl) clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
+ else { EFSPRINTF("CLTBL"); ABORT(fs, FR_CLTBL_NO_INIT); }
+ }
+ if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); }
+ else if (clst == 0xFFFFFFFF) { EFSPRINTF("DSKC"); ABORT(fs, FR_DISK_ERR); }
+
+ fp->clust = clst; /* Set working cluster */
+
+ sector_base = clst2sect(fs, fp->clust);
+ count += fs->csize;
+ btr -= csize_bytes;
+ fp->fptr += csize_bytes;
+
+ while (btr) {
+ clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
+
+ if (clst < 2) { EFSPRINTF("CCHK2"); ABORT(fs, FR_INT_ERR); }
+ else if (clst == 0xFFFFFFFF) { EFSPRINTF("DSKC"); ABORT(fs, FR_DISK_ERR); }
+
+ fp->clust = clst;
+
+ work_sector = clst2sect(fs, fp->clust);
+ if ((work_sector - sector_base) == count) count += fs->csize;
+ else {
+ if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
+ wbuff += count * SS(fs);
+
+ sector_base = work_sector;
+ count = fs->csize;
+ }
+
+ fp->fptr += MIN(btr, csize_bytes);
+ btr -= MIN(btr, csize_bytes);
+
+ // TODO: what about if data is smaller than cluster?
+ // Must read-write back that cluster.
+
+ if (!btr) { /* Final cluster/sectors read. */
+ if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
+ }
+ }
+
+ LEAVE_FF(fs, FR_OK);
+}
+#endif
+
+
+
+
#if !FF_FS_READONLY
/*-----------------------------------------------------------------------*/
/* Write File */
@@ -4045,6 +4131,97 @@ FRESULT f_write (
+#if FF_FASTFS && FF_USE_FASTSEEK
+/*-----------------------------------------------------------------------*/
+/* Fast Write Aligned Sized File Without a Cache */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_write_fast (
+ FIL* fp, /* Pointer to the file object */
+ const void* buff, /* Pointer to the data to be written */
+ UINT btw /* Number of bytes to write */
+)
+{
+ FRESULT res;
+ FATFS *fs;
+ UINT csize_bytes;
+ DWORD clst;
+ UINT count = 0;
+ FSIZE_t work_sector = 0;
+ FSIZE_t sector_base = 0;
+ const BYTE *wbuff = (const BYTE*)buff;
+
+ // TODO support sector writing inside a cluster
+
+ res = validate(&fp->obj, &fs); /* Check validity of the file object */
+ if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
+ EFSPRINTF("FOV");
+ LEAVE_FF(fs, res); /* Check validity */
+ }
+
+ if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
+ /* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */
+ if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) {
+ btw = (UINT)(0xFFFFFFFF - (DWORD)fp->fptr);
+ }
+
+ csize_bytes = fs->csize * SS(fs);
+
+ if (!fp->fptr) { /* On the top of the file? */
+ clst = fp->obj.sclust; /* Follow from the origin */
+ } else {
+ if (fp->cltbl) clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
+ else { EFSPRINTF("CLTBL"); ABORT(fs, FR_CLTBL_NO_INIT); }
+ }
+
+ if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); }
+ else if (clst == 0xFFFFFFFF) { EFSPRINTF("DERR"); ABORT(fs, FR_DISK_ERR); }
+
+ fp->clust = clst; /* Set working cluster */
+
+ sector_base = clst2sect(fs, fp->clust);
+ count += fs->csize;
+ btw -= csize_bytes;
+ fp->fptr += csize_bytes;
+
+ while (btw) {
+ clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
+
+ if (clst < 2) { EFSPRINTF("CCHK2"); ABORT(fs, FR_INT_ERR); }
+ else if (clst == 0xFFFFFFFF) { EFSPRINTF("DERR"); ABORT(fs, FR_DISK_ERR); }
+
+ fp->clust = clst;
+
+ work_sector = clst2sect(fs, fp->clust);
+ if ((work_sector - sector_base) == count) count += fs->csize;
+ else {
+ if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
+ wbuff += count * SS(fs);
+
+ sector_base = work_sector;
+ count = fs->csize;
+ }
+
+ fp->fptr += MIN(btw, csize_bytes);
+ btw -= MIN(btw, csize_bytes);
+
+ // what about if data is smaller than cluster?
+ // Probably must read-write back that cluster.
+ if (!btw) { /* Final cluster/sectors write. */
+ if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
+ fp->flag &= (BYTE)~FA_DIRTY;
+ }
+ }
+
+ fp->flag |= FA_MODIFIED; /* Set file change flag */
+
+ LEAVE_FF(fs, FR_OK);
+}
+#endif
+
+
+
+
/*-----------------------------------------------------------------------*/
/* Synchronize the File */
/*-----------------------------------------------------------------------*/
@@ -4501,6 +4678,37 @@ FRESULT f_lseek (
+#if FF_FASTFS && FF_USE_FASTSEEK
+/*-----------------------------------------------------------------------*/
+/* Seek File Read/Write Pointer */
+/*-----------------------------------------------------------------------*/
+
+DWORD *f_expand_cltbl (
+ FIL* fp, /* Pointer to the file object */
+ UINT tblsz, /* Size of table */
+ FSIZE_t ofs /* File pointer from top of file */
+)
+{
+ if (fp->flag & FA_WRITE) f_lseek(fp, ofs); /* Expand file if write is enabled */
+ if (!fp->cltbl) { /* Allocate memory for cluster link table */
+ fp->cltbl = (DWORD *)ff_memalloc(tblsz);
+ fp->cltbl[0] = tblsz;
+ }
+ if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */
+ ff_memfree(fp->cltbl);
+ fp->cltbl = NULL;
+ EFSPRINTF("CLTBLSZ");
+ return NULL;
+ }
+ f_lseek(fp, 0);
+
+ return fp->cltbl;
+}
+#endif
+
+
+
+
#if FF_FS_MINIMIZE <= 1
/*-----------------------------------------------------------------------*/
/* Create a Directory Object */
diff --git a/bootloader/libs/fatfs/ff.h b/bootloader/libs/fatfs/ff.h
index b036443..af1151f 100644
--- a/bootloader/libs/fatfs/ff.h
+++ b/bootloader/libs/fatfs/ff.h
@@ -246,7 +246,12 @@ typedef enum {
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
+#if FF_FASTFS
+ FR_INVALID_PARAMETER, /* (19) Given parameter is invalid */
+ FR_CLTBL_NO_INIT /* (20) The cluster table for fast seek/read/write was not created */
+#else
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
+#endif
} FRESULT;
@@ -258,6 +263,8 @@ FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a f
FRESULT f_close (FIL* fp); /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
+FRESULT f_read_fast (FIL* fp, const void* buff, UINT btr); /* Fast read data from the file */
+FRESULT f_write_fast (FIL* fp, const void* buff, UINT btw); /* Fast write data to the file */
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
FRESULT f_truncate (FIL* fp); /* Truncate the file */
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
@@ -279,6 +286,7 @@ FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get numbe
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
+DWORD *f_expand_cltbl (FIL* fp, UINT tblsz, FSIZE_t ofs); /* Expand file and populate cluster table */
FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
diff --git a/bootloader/libs/fatfs/ffconf.h b/bootloader/libs/fatfs/ffconf.h
index be64ef3..ee536ef 100644
--- a/bootloader/libs/fatfs/ffconf.h
+++ b/bootloader/libs/fatfs/ffconf.h
@@ -45,6 +45,13 @@
#define FF_USE_FASTSEEK 0
/* This option switches fast seek function. (0:Disable or 1:Enable) */
+#define FF_FASTFS 0
+
+#if FF_FASTFS
+#undef FF_USE_FASTSEEK
+#define FF_USE_FASTSEEK 1
+#endif
+
#define FF_USE_EXPAND 0
/* This option switches f_expand function. (0:Disable or 1:Enable) */
@@ -239,7 +246,7 @@
#define FF_FS_NORTC 1
#define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1
-#define FF_NORTC_YEAR 2019
+#define FF_NORTC_YEAR 2020
/* The option FF_FS_NORTC switches timestamp function. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
diff --git a/bootloader/main.c b/bootloader/main.c
index 573abd5..37c3e8f 100644
--- a/bootloader/main.c
+++ b/bootloader/main.c
@@ -318,7 +318,7 @@ void launch_tools()
memcpy(dir, "bootloader/payloads", 20);
- filelist = dirlist(dir, NULL, false);
+ filelist = dirlist(dir, NULL, false, false);
u32 i = 0;
@@ -1022,7 +1022,7 @@ skip_list:
// Wait before booting. If VOL- is pressed go into bootloader menu.
if (!h_cfg.sept_run && !(b_cfg.boot_cfg & BOOT_CFG_FROM_LAUNCH))
{
- btn = btn_wait_timeout(h_cfg.bootwait * 1000, BTN_VOL_DOWN | BTN_SINGLE);
+ btn = btn_wait_timeout_single(h_cfg.bootwait * 1000, BTN_VOL_DOWN | BTN_SINGLE);
if (btn & BTN_VOL_DOWN)
goto out;
@@ -1082,8 +1082,6 @@ static void _patched_rcm_protection()
sdmmc_storage_t storage;
sdmmc_t sdmmc;
- h_cfg.rcm_patched = fuse_check_patched_rcm();
-
if (!h_cfg.rcm_patched)
return;
@@ -1253,12 +1251,12 @@ static void _check_low_battery()
}
// Check if charging status changed or Power button was pressed.
- if (((charge_status != current_charge_status) || (btn_wait_timeout(0, BTN_POWER) & BTN_POWER)))
+ if ((charge_status != current_charge_status) || (btn_wait_timeout_single(0, BTN_POWER) & BTN_POWER))
{
if (!screen_on)
{
display_init();
- u32 *fb = display_init_framebuffer();
+ u32 *fb = display_init_framebuffer_pitch();
gfx_init_ctxt(fb, 720, 1280, 720);
gfx_set_rect_rgb(battery_icon, X_BATTERY_EMPTY, Y_BATTERY_EMPTY_BATT, 16, battery_icon_y_pos);
@@ -1350,9 +1348,9 @@ ment_t ment_options[] = {
MDEF_BACK(),
MDEF_CHGLINE(),
MDEF_HANDLER("Auto boot", config_autoboot),
- //MDEF_HANDLER("Boot delay", config_bootdelay),
- //MDEF_HANDLER("Auto NoGC", config_nogc),
- //MDEF_HANDLER("Auto HOS power off", config_auto_hos_poweroff),
+ MDEF_HANDLER("Boot delay", config_bootdelay),
+ MDEF_HANDLER("Auto NoGC", config_nogc),
+ MDEF_HANDLER("Auto HOS power off", config_auto_hos_poweroff),
MDEF_HANDLER("Backlight", config_backlight),
MDEF_END()
};
@@ -1431,7 +1429,7 @@ menu_t menu_tools = { ment_tools, "Tools", 0, 0 };
ment_t ment_top[] = {
MDEF_HANDLER("Launch", launch_firmware),
- MDEF_MENU("Options", &menu_options),
+ //MDEF_MENU("Options", &menu_options),
MDEF_CAPTION("---------------", 0xFF444444),
MDEF_MENU("Tools", &menu_tools),
MDEF_MENU("Console info", &menu_cinfo),
@@ -1482,7 +1480,7 @@ void ipl_main()
display_init();
- u32 *fb = display_init_framebuffer();
+ u32 *fb = display_init_framebuffer_pitch();
gfx_init_ctxt(fb, 720, 1280, 720);
#ifdef MENU_LOGO_ENABLE
diff --git a/bootloader/mem/minerva.c b/bootloader/mem/minerva.c
index 2607c4b..c399070 100644
--- a/bootloader/mem/minerva.c
+++ b/bootloader/mem/minerva.c
@@ -27,6 +27,7 @@
#include "../soc/t210.h"
extern volatile nyx_storage_t *nyx_str;
+
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
u32 minerva_init()
@@ -35,6 +36,41 @@ u32 minerva_init()
minerva_cfg = NULL;
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
+
+#ifdef NYX
+ // Set table to nyx storage.
+ mtc_cfg->mtc_table = (emc_table_t *)nyx_str->mtc_table;
+
+ // Check if Minerva is already initialized.
+ if (mtc_cfg->init_done == MTC_INIT_MAGIC)
+ {
+ mtc_cfg->train_mode = OP_PERIODIC_TRAIN; // Retrain if needed.
+ u32 ep_addr = ianos_loader(false, "bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg);
+ minerva_cfg = (void *)ep_addr;
+
+ return 0;
+ }
+ else
+ {
+ mtc_config_t mtc_tmp;
+
+ mtc_tmp.mtc_table = mtc_cfg->mtc_table;
+ mtc_tmp.sdram_id = (fuse_read_odm(4) >> 3) & 0x1F;
+ mtc_tmp.init_done = MTC_NEW_MAGIC;
+
+ u32 ep_addr = ianos_loader(false, "bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)&mtc_tmp);
+
+ // Ensure that Minerva is new.
+ if (mtc_tmp.init_done == MTC_INIT_MAGIC)
+ minerva_cfg = (void *)ep_addr;
+ else
+ mtc_cfg->init_done = 0;
+
+ // Copy Minerva context to Nyx storage.
+ if (minerva_cfg)
+ memcpy(mtc_cfg, (void *)&mtc_tmp, sizeof(mtc_config_t));
+ }
+#else
memset(mtc_cfg, 0, sizeof(mtc_config_t));
// Set table to nyx storage.
@@ -50,6 +86,7 @@ u32 minerva_init()
minerva_cfg = (void *)ep_addr;
else
mtc_cfg->init_done = 0;
+#endif
if (!minerva_cfg)
return 1;
diff --git a/bootloader/mem/sdram.c b/bootloader/mem/sdram.c
index 36f54c1..d1e5db9 100644
--- a/bootloader/mem/sdram.c
+++ b/bootloader/mem/sdram.c
@@ -202,7 +202,7 @@ break_nosleep:
EMC(EMC_SWIZZLE_RANK1_BYTE2) = params->emc_swizzle_rank1_byte2;
EMC(EMC_SWIZZLE_RANK1_BYTE3) = params->emc_swizzle_rank1_byte3;
- // Patch 4 using BCT spare variables.
+ // Patch 3 using BCT spare variables.
if (params->emc_bct_spare6)
*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;
@@ -345,7 +345,7 @@ break_nosleep:
// Common pad macro (cpm).
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = (params->emc_pmacro_common_pad_tx_ctrl & 1) | 0xE;
- // Patch 3 using BCT spare variables.
+ // Patch 4 using BCT spare variables.
if (params->emc_bct_spare4)
*(vu32 *)params->emc_bct_spare4 = params->emc_bct_spare5;
@@ -723,11 +723,14 @@ sdram_params_t *sdram_get_params()
case DRAM_4GB_SAMSUNG_K4F6E304HB_MGCH:
case DRAM_4GB_MICRON_MT53B512M32D2NP_062_WT:
break;
+
case DRAM_4GB_HYNIX_H9HCNNNBPUMLHR_NLN:
- case DRAM_4GB_COPPER_UNK_3:
case DRAM_6GB_SAMSUNG_K4FHE3D4HM_MFCH:
- case DRAM_4GB_COPPER_UNK_5:
- case DRAM_4GB_COPPER_UNK_6:
+#ifdef CONFIG_SDRAM_COPPER_SUPPORT
+ case DRAM_4GB_COPPER_SAMSUNG:
+ case DRAM_4GB_COPPER_HYNIX:
+ case DRAM_4GB_COPPER_MICRON:
+#endif
_sdram_patch_model_params(dramid, (u32 *)buf);
break;
}
diff --git a/bootloader/mem/sdram_config.inl b/bootloader/mem/sdram_config.inl
index 58eb62d..42e0555 100644
--- a/bootloader/mem/sdram_config.inl
+++ b/bootloader/mem/sdram_config.inl
@@ -15,15 +15,17 @@
* along with this program. If not, see .
*/
+#define DRAM_CFG_SIZE 1896
+
#define DRAM_ID(x) (1 << (x))
#define DRAM_4GB_SAMSUNG_K4F6E304HB_MGCH 0
#define DRAM_4GB_HYNIX_H9HCNNNBPUMLHR_NLN 1
#define DRAM_4GB_MICRON_MT53B512M32D2NP_062_WT 2
-#define DRAM_4GB_COPPER_UNK_3 3 // Samsung?
+#define DRAM_4GB_COPPER_SAMSUNG 3
#define DRAM_6GB_SAMSUNG_K4FHE3D4HM_MFCH 4
-#define DRAM_4GB_COPPER_UNK_5 5 // Samsung?
-#define DRAM_4GB_COPPER_UNK_6 6 // Samsung?
+#define DRAM_4GB_COPPER_HYNIX 5
+#define DRAM_4GB_COPPER_MICRON 6
typedef struct _sdram_vendor_patch_t
{
@@ -658,11 +660,22 @@ static const sdram_params_t _dram_cfg_0_samsung_4gb = {
};
static const sdram_vendor_patch_t sdram_cfg_vendor_patches[] = {
- { 0x0000003A, 59, DRAM_ID(6) }, // emc_rfc. Auto refresh.
- { 0x0000001D, 60, DRAM_ID(6) }, // emc_rfc_pb. Bank Auto refresh.
+ // Hynix timing config.
{ 0x0000000D, 67, DRAM_ID(1) | DRAM_ID(5) }, // emc_r2w.
{ 0x00000001, 91, DRAM_ID(1) | DRAM_ID(5) }, // emc_puterm_extra.
{ 0x80000000, 92, DRAM_ID(1) | DRAM_ID(5) }, // emc_puterm_width.
+ { 0x00000210, 317, DRAM_ID(1) | DRAM_ID(5) }, // emc_pmacro_data_rx_term_mode.
+ { 0x00000005, 368, DRAM_ID(1) | DRAM_ID(5) }, // mc_emem_arb_timing_r2w.
+
+ // Samsung 6GB density config.
+ { 0x000C0302, 347, DRAM_ID(4) }, // mc_emem_adr_cfg_dev0. 768MB sub-partition density.
+ { 0x000C0302, 348, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB sub-partition density.
+ { 0x00001800, 353, DRAM_ID(4) }, // mc_emem_cfg. 6GB total density.
+
+#ifdef CONFIG_SDRAM_COPPER_SUPPORT
+ // Copper prototype Samsung/Hynix/Micron timing configs.
+ { 0x0000003A, 59, DRAM_ID(6) }, // emc_rfc. Auto refresh.
+ { 0x0000001D, 60, DRAM_ID(6) }, // emc_rfc_pb. Bank Auto refresh.
{ 0x00000012, 108, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_rw2pden.
{ 0x0000003B, 112, DRAM_ID(6) }, // emc_txsr.
{ 0x0000003B, 113, DRAM_ID(6) }, // emc_txsr_dll.
@@ -687,11 +700,7 @@ static const sdram_vendor_patch_t sdram_cfg_vendor_patches[] = {
{ 0x00000015, 237, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_4.
{ 0x00000012, 295, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft2.
{ 0x00000012, 296, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft3.
- { 0x00000210, 317, DRAM_ID(1) | DRAM_ID(5) }, // emc_pmacro_data_rx_term_mode.
- { 0x000C0302, 347, DRAM_ID(4) }, // mc_emem_adr_cfg_dev0. 768MB sub-partition density.
- { 0x000C0302, 348, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB sub-partition density.
- { 0x00001800, 353, DRAM_ID(4) }, // mc_emem_cfg. 6GB total density.
- { 0x00000005, 368, DRAM_ID(1) | DRAM_ID(5) }, // mc_emem_arb_timing_r2w.
{ 0x00000007, 370, DRAM_ID(6) }, // mc_emem_arb_timing_rfcpb. Bank refresh.
- { 0x72A30504, 373, DRAM_ID(6) } // mc_emem_arb_misc0.
+ { 0x72A30504, 373, DRAM_ID(6) }, // mc_emem_arb_misc0.
+#endif
};
diff --git a/bootloader/mem/sdram_param_t210.h b/bootloader/mem/sdram_param_t210.h
index 4980918..4c6c60a 100644
--- a/bootloader/mem/sdram_param_t210.h
+++ b/bootloader/mem/sdram_param_t210.h
@@ -113,7 +113,6 @@ typedef struct _sdram_params
/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
u32 emc_auto_cal_config3;
-
u32 emc_auto_cal_config4;
u32 emc_auto_cal_config5;
u32 emc_auto_cal_config6;
diff --git a/bootloader/power/bq24193.c b/bootloader/power/bq24193.c
index e5f24a7..d95b322 100644
--- a/bootloader/power/bq24193.c
+++ b/bootloader/power/bq24193.c
@@ -20,9 +20,6 @@
#include "../soc/i2c.h"
#include "../utils/util.h"
-#pragma GCC push_options
-#pragma GCC optimize ("Os")
-
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value)
{
u8 data;
@@ -166,5 +163,3 @@ void bq24193_fake_battery_removal()
value |= BQ24193_MISC_BATFET_DI_MASK;
i2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Misc, value);
}
-
-#pragma GCC pop_options
diff --git a/bootloader/power/max17050.c b/bootloader/power/max17050.c
index bfd80c4..5fc9e3f 100644
--- a/bootloader/power/max17050.c
+++ b/bootloader/power/max17050.c
@@ -43,9 +43,6 @@
#define MAX17050_VMAX_TOLERANCE 50 /* 50 mV */
-#pragma GCC push_options
-#pragma GCC optimize ("Os")
-
static u32 battery_voltage = 0;
u32 max17050_get_cached_batt_volt()
{
@@ -274,5 +271,3 @@ int max17050_fix_configuration()
return 0;
}
-
-#pragma GCC pop_options
\ No newline at end of file
diff --git a/bootloader/sec/se.c b/bootloader/sec/se.c
index 57c0958..52f8fea 100644
--- a/bootloader/sec/se.c
+++ b/bootloader/sec/se.c
@@ -71,9 +71,11 @@ static int _se_wait()
return 1;
}
-static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)
+se_ll_t *ll_dst, *ll_src;
+static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot)
{
- se_ll_t *ll_dst = NULL, *ll_src = NULL;
+ ll_dst = NULL;
+ ll_src = NULL;
if (dst)
{
@@ -95,14 +97,39 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op);
+
+ int res = 1;
+ if (is_oneshot)
+ {
+ res = _se_wait();
+
+ bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
+
+ if (src)
+ free(ll_src);
+ if (dst)
+ free(ll_dst);
+ }
+
+ return res;
+}
+
+static int _se_execute_finalize()
+{
int res = _se_wait();
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
- if (src)
+ if (ll_src)
+ {
free(ll_src);
- if (dst)
+ ll_src = NULL;
+ }
+ if (ll_dst)
+ {
free(ll_dst);
+ ll_dst = NULL;
+ }
return res;
}
@@ -118,7 +145,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
memcpy(block, src, src_size);
- int res = _se_execute(op, block, 0x10, block, 0x10);
+ int res = _se_execute(op, block, 0x10, block, 0x10, true);
memcpy(dst, block, dst_size);
free(block);
@@ -176,7 +203,7 @@ int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst);
- return _se_execute(OP_START, NULL, 0, input, 0x10);
+ return _se_execute(OP_START, NULL, 0, input, 0x10, true);
}
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
@@ -192,7 +219,7 @@ int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src,
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
}
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
- return _se_execute(OP_START, dst, dst_size, src, src_size);
+ return _se_execute(OP_START, dst, dst_size, src, src_size, true);
}
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
@@ -210,7 +237,7 @@ int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src,
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
}
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
- return _se_execute(OP_START, dst, dst_size, src, src_size);
+ return _se_execute(OP_START, dst, dst_size, src, src_size, true);
}
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src)
@@ -232,7 +259,7 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
if (src_size_aligned)
{
SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1;
- if (!_se_execute(OP_START, dst, dst_size, src, src_size_aligned))
+ if (!_se_execute(OP_START, dst, dst_size, src, src_size_aligned, true))
return 0;
}
@@ -293,28 +320,90 @@ int se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u
return 1;
}
-int se_calc_sha256(void *dst, const void *src, u32 src_size)
+int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot)
{
int res;
- // Setup config for SHA256, size = BITS(src_size).
+ u32 *hash32 = (u32 *)hash;
+
+ if (src_size > 0xFFFFFF || (u32)hash % 4 || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer.
+ return 0;
+
+ // Setup config for SHA256.
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
- SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_INIT_HASH;
- SE(SE_SHA_MSG_LENGTH_0_REG_OFFSET) = (u32)(src_size << 3);
- SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = 0;
+ SE(SE_SHA_CONFIG_REG_OFFSET) = sha_cfg;
+ SE(SE_BLOCK_COUNT_REG_OFFSET) = 0;
+
+ // Set total size to current buffer size if empty.
+ if (!total_size)
+ total_size = src_size;
+
+ // Set total size: BITS(src_size), up to 2 EB.
+ SE(SE_SHA_MSG_LENGTH_0_REG_OFFSET) = (u32)(total_size << 3);
+ SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = (u32)(total_size >> 29);
SE(SE_SHA_MSG_LENGTH_2_REG_OFFSET) = 0;
SE(SE_SHA_MSG_LENGTH_3_REG_OFFSET) = 0;
- SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = (u32)(src_size << 3);
- SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = 0;
+
+ // Set size left to hash.
+ SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = (u32)(total_size << 3);
+ SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = (u32)(total_size >> 29);
SE(SE_SHA_MSG_LEFT_2_REG_OFFSET) = 0;
SE(SE_SHA_MSG_LEFT_3_REG_OFFSET) = 0;
+ // If we hash in chunks, copy over the intermediate.
+ if (sha_cfg == SHA_CONTINUE)
+ {
+ if (!msg_left)
+ return 0;
+
+ // Restore message left to process.
+ SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = msg_left[0];
+ SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = msg_left[1];
+
+ // Restore hash reg.
+ for (u32 i = 0; i < 8; i++)
+ SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)) = byte_swap_32(hash32[i]);
+ }
+
// Trigger the operation.
- res = _se_execute(OP_START, NULL, 0, src, src_size);
+ res = _se_execute(OP_START, NULL, 0, src, src_size, is_oneshot);
+
+ if (is_oneshot)
+ {
+ // Backup message left.
+ if (msg_left)
+ {
+ msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET);
+ msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET);
+ }
+
+ // Copy output hash.
+ for (u32 i = 0; i < 8; i++)
+ hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));
+ }
+
+ return res;
+}
+
+int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size)
+{
+ return se_calc_sha256(hash, NULL, src, src_size, 0, SHA_INIT_HASH, true);
+}
+
+int se_calc_sha256_finalize(void *hash, u32 *msg_left)
+{
+ u32 *hash32 = (u32 *)hash;
+ int res = _se_execute_finalize();
+
+ // Backup message left.
+ if (msg_left)
+ {
+ msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET);
+ msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET);
+ }
// Copy output hash.
- u32 *dst32 = (u32 *)dst;
for (u32 i = 0; i < 8; i++)
- dst32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));
+ hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));
return res;
}
@@ -333,7 +422,7 @@ int se_gen_prng128(void *dst)
SE(SE_BLOCK_COUNT_REG_OFFSET) = (16 >> 4) - 1;
// Trigger the operation.
- return _se_execute(OP_START, dst, 16, NULL, 0);
+ return _se_execute(OP_START, dst, 16, NULL, 0, true);
}
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
@@ -345,7 +434,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY) | SE_RNG_CONFIG_MODE(RNG_MODE_FORCE_RESEED);
SE(SE_CRYPTO_LAST_BLOCK) = 0;
- _se_execute(OP_START, NULL, 0, NULL, 0);
+ _se_execute(OP_START, NULL, 0, NULL, 0, true);
// Save AES keys.
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
@@ -356,7 +445,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
(i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_0_3);
SE(SE_CRYPTO_LAST_BLOCK) = 0;
- _se_execute(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0);
+ _se_execute(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0, true);
memcpy(keys + i * keysize, aligned_buf, 0x10);
if (keysize > 0x10)
@@ -365,7 +454,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
(i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_4_7);
SE(SE_CRYPTO_LAST_BLOCK) = 0;
- _se_execute(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0);
+ _se_execute(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0, true);
memcpy(keys + i * keysize + 0x10, aligned_buf, 0x10);
}
}
@@ -373,11 +462,11 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
// Save SRK to PMC secure scratches.
SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(SRK);
SE(0x80) = 0; // SE_CRYPTO_LAST_BLOCK
- _se_execute(OP_CTX_SAVE, NULL, 0, NULL, 0);
+ _se_execute(OP_CTX_SAVE, NULL, 0, NULL, 0, true);
// End context save.
SE(SE_CONFIG_REG_OFFSET) = 0;
- _se_execute(OP_CTX_SAVE, NULL, 0, NULL, 0);
+ _se_execute(OP_CTX_SAVE, NULL, 0, NULL, 0, true);
// Get SRK.
u32 srk[4];
diff --git a/bootloader/sec/se.h b/bootloader/sec/se.h
index 7d12207..2184b4d 100644
--- a/bootloader/sec/se.h
+++ b/bootloader/sec/se.h
@@ -28,7 +28,9 @@ int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input);
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);
-int se_calc_sha256(void *dst, const void *src, u32 src_size);
+int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot);
+int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size);
+int se_calc_sha256_finalize(void *hash, u32 *msg_left);
int se_gen_prng128(void *dst);
#endif
diff --git a/bootloader/soc/clock.c b/bootloader/soc/clock.c
index 60a069b..5d49b33 100644
--- a/bootloader/soc/clock.c
+++ b/bootloader/soc/clock.c
@@ -276,7 +276,7 @@ void clock_enable_pllc(u32 divn)
return;
// Take PLLC out of reset and set basic misc parameters.
- CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) =
+ CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) =
((CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) & 0xFFF0000F) & ~PLLC_MISC_RESET) | (0x80000 << 4); // PLLC_EXT_FRU.
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) |= 0xF0 << 8; // PLLC_FLL_LD_MEM.
@@ -312,6 +312,53 @@ void clock_disable_pllc()
usleep(10);
}
+#define PLLC4_ENABLED (1 << 31)
+#define PLLC4_IN_USE (~PLLC4_ENABLED)
+
+u32 pllc4_enabled = 0;
+
+static void _clock_enable_pllc4(u32 mask)
+{
+ pllc4_enabled |= mask;
+
+ if (pllc4_enabled & PLLC4_ENABLED)
+ return;
+
+ // Enable Phase and Frequency lock detection.
+ //CLOCK(CLK_RST_CONTROLLER_PLLC4_MISC) = PLLC4_MISC_EN_LCKDET;
+
+ // Disable PLL and IDDQ in case they are on.
+ CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLLCX_BASE_ENABLE;
+ CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLLC4_BASE_IDDQ;
+ usleep(10);
+
+ // Set PLLC4 dividers.
+ CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = (104 << 8) | 4; // DIVM: 4, DIVP: 1.
+
+ // Enable PLLC4 and wait for Phase and Frequency lock.
+ CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLLCX_BASE_ENABLE;
+ while (!(CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) & PLLCX_BASE_LOCK))
+ ;
+
+ msleep(1); // Wait a bit for PLL to stabilize.
+
+ pllc4_enabled |= PLLC4_ENABLED;
+}
+
+static void _clock_disable_pllc4(u32 mask)
+{
+ pllc4_enabled &= ~mask;
+
+ if (pllc4_enabled & PLLC4_IN_USE)
+ return;
+
+ // Disable PLLC4.
+ CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) &= ~PLLCX_BASE_ENABLE;
+ CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLLC4_BASE_IDDQ;
+
+ pllc4_enabled = 0;
+}
+
#define L_SWR_SDMMC1_RST (1 << 14)
#define L_SWR_SDMMC2_RST (1 << 9)
#define L_SWR_SDMMC4_RST (1 << 15)
@@ -501,16 +548,32 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
divisor = 14; // 8 div.
break;
case 100000:
- *pclock = 90667;
- divisor = 7; // 4.5 div.
+ source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
+ *pclock = 99840;
+ divisor = 2; // 2 div.
break;
case 164000:
*pclock = 163200;
divisor = 3; // 2.5 div.
break;
- case 200000:
- *pclock = 204000;
- divisor = 2; // 2 div.
+ case 200000: // 240MHz evo+.
+ switch (id)
+ {
+ case SDMMC_1:
+ source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
+ break;
+ case SDMMC_2:
+ source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ;
+ break;
+ case SDMMC_3:
+ source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
+ break;
+ case SDMMC_4:
+ source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ;
+ break;
+ }
+ *pclock = 199680;
+ divisor = 0; // 1 div.
break;
default:
*pclock = 24728;
@@ -520,6 +583,10 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
_clock_sdmmc_table[id].clock = val;
_clock_sdmmc_table[id].real_clock = *pclock;
+ // Enable PLLC4 if in use by any SDMMC.
+ if (source)
+ _clock_enable_pllc4(1 << id);
+
// Set SDMMC legacy timeout clock.
_clock_sdmmc_config_legacy_tm();
@@ -642,4 +709,5 @@ void clock_sdmmc_disable(u32 id)
_clock_sdmmc_set_reset(id);
_clock_sdmmc_clear_enable(id);
_clock_sdmmc_is_reset(id);
+ _clock_disable_pllc4(1 << id);
}
diff --git a/bootloader/soc/hw_init.c b/bootloader/soc/hw_init.c
index f5df093..b038623 100644
--- a/bootloader/soc/hw_init.c
+++ b/bootloader/soc/hw_init.c
@@ -25,18 +25,23 @@
#include "i2c.h"
#include "pinmux.h"
#include "pmc.h"
-#include "t210.h"
#include "uart.h"
+#include "t210.h"
+#include "../input/joycon.h"
+#include "../input/touch.h"
#include "../gfx/di.h"
#include "../mem/mc.h"
#include "../mem/minerva.h"
#include "../mem/sdram.h"
-#include "../power/max77620.h"
-#include "../power/max7762x.h"
#include "../sec/se.h"
#include "../sec/se_t210.h"
+#include "../power/max77620.h"
+#include "../power/max7762x.h"
+#include "../gfx/di.h"
+#include "../power/regulator_5v.h"
#include "../storage/nx_sd.h"
#include "../storage/sdmmc.h"
+#include "../thermal/fan.h"
#include "../utils/util.h"
extern boot_cfg_t b_cfg;
@@ -326,9 +331,21 @@ void config_hw()
void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
{
- // Flush and disable MMU.
- bpmp_mmu_disable();
+ // Disable BPMP max clock.
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
+
+#ifdef NYX
+ // Deinit touchscreen, 5V regulators and Joy-Con.
+ touch_power_off();
+ set_fan_duty(0);
+ jc_deinit();
+ regulator_disable_5v(REGULATOR_5V_ALL);
+ clock_disable_uart(UART_B);
+ clock_disable_uart(UART_C);
+#endif
+
+ // Flush/disable MMU cache and set DRAM clock to 204MHz.
+ bpmp_mmu_disable();
minerva_change_freq(FREQ_204);
nyx_str->mtc_cfg.init_done = 0;
diff --git a/bootloader/soc/kfuse.c b/bootloader/soc/kfuse.c
index f2fde5a..cdfba53 100644
--- a/bootloader/soc/kfuse.c
+++ b/bootloader/soc/kfuse.c
@@ -18,9 +18,6 @@
#include "../soc/clock.h"
#include "../soc/t210.h"
-#pragma GCC push_options
-#pragma GCC optimize ("Os")
-
int kfuse_wait_ready()
{
// Wait for KFUSE to finish init and verification of data.
@@ -48,9 +45,7 @@ int kfuse_read(u32 *buf)
res = 1;
-out:;
+out:
clock_disable_kfuse();
return res;
}
-
-#pragma GCC pop_options
diff --git a/bootloader/soc/uart.c b/bootloader/soc/uart.c
index 2568d10..3aea2f7 100644
--- a/bootloader/soc/uart.c
+++ b/bootloader/soc/uart.c
@@ -79,7 +79,7 @@ void uart_send(u32 idx, const u8 *buf, u32 len)
while (!(uart->UART_LSR & UART_LSR_THRE))
;
uart->UART_THR_DLAB = buf[i];
- };
+ }
}
u32 uart_recv(u32 idx, u8 *buf, u32 len)
diff --git a/bootloader/storage/emummc.c b/bootloader/storage/emummc.c
index 4fffd6b..3da09e2 100644
--- a/bootloader/storage/emummc.c
+++ b/bootloader/storage/emummc.c
@@ -31,7 +31,6 @@
extern hekate_config h_cfg;
emummc_cfg_t emu_cfg;
-
void emummc_load_cfg()
{
emu_cfg.enabled = 0;
diff --git a/bootloader/storage/nx_emmc.c b/bootloader/storage/nx_emmc.c
index f5765a1..897a7e3 100644
--- a/bootloader/storage/nx_emmc.c
+++ b/bootloader/storage/nx_emmc.c
@@ -22,6 +22,10 @@
#include "../mem/heap.h"
#include "../utils/list.h"
+sdmmc_t emmc_sdmmc;
+sdmmc_storage_t emmc_storage;
+FATFS emmc_fs;
+
void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
{
gpt_t *gpt_buf = (gpt_t *)calloc(NX_GPT_NUM_BLOCKS, NX_EMMC_BLOCKSIZE);
diff --git a/bootloader/storage/nx_emmc.h b/bootloader/storage/nx_emmc.h
index 19bc1ca..380b7a0 100644
--- a/bootloader/storage/nx_emmc.h
+++ b/bootloader/storage/nx_emmc.h
@@ -18,10 +18,11 @@
#define _NX_EMMC_H_
#include "sdmmc.h"
+#include "../libs/fatfs/ff.h"
#include "../utils/types.h"
#include "../utils/list.h"
-#define NX_GPT_FIRST_LBA 1
+#define NX_GPT_FIRST_LBA 1
#define NX_GPT_NUM_BLOCKS 33
#define NX_EMMC_BLOCKSIZE 512
@@ -35,6 +36,10 @@ typedef struct _emmc_part_t
link_t link;
} emmc_part_t;
+extern sdmmc_t emmc_sdmmc;
+extern sdmmc_storage_t emmc_storage;
+extern FATFS emmc_fs;
+
void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage);
void nx_emmc_gpt_free(link_t *gpt);
emmc_part_t *nx_emmc_part_find(link_t *gpt, const char *name);
diff --git a/bootloader/storage/sd.h b/bootloader/storage/sd.h
index 3ecfc07..a780ec8 100644
--- a/bootloader/storage/sd.h
+++ b/bootloader/storage/sd.h
@@ -1,6 +1,4 @@
/*
- * include/linux/mmc/sd.h
- *
* Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved.
* Copyright (c) 2018 CTCaer
*
@@ -10,8 +8,8 @@
* your option) any later version.
*/
-#ifndef LINUX_MMC_SD_H
-#define LINUX_MMC_SD_H
+#ifndef MMC_SD_H
+#define MMC_SD_H
/* SD commands type argument response */
/* class 0 */
diff --git a/bootloader/storage/sdmmc_driver.c b/bootloader/storage/sdmmc_driver.c
index 8e32f5d..957a0bc 100644
--- a/bootloader/storage/sdmmc_driver.c
+++ b/bootloader/storage/sdmmc_driver.c
@@ -30,9 +30,13 @@
#include "../utils/util.h"
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
+//#define ERROR_EXTRA_PRINTING
#define DPRINTF(...)
-u32 sd_power_cycle_time_start;
+#ifdef NYX
+#define ERROR_EXTRA_PRINTING
+#define SDMMC_EMMC_OC
+#endif
/*! SCMMC controller base addresses. */
static const u32 _sdmmc_bases[4] = {
@@ -222,7 +226,11 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
}
+#ifdef SDMMC_EMMC_OC
+static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc, bool overclock)
+#else
static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
+#endif
{
int result = 1, should_disable_sd_clock = 0;
@@ -232,6 +240,11 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
}
+#ifdef SDMMC_EMMC_OC
+ if (sdmmc->id == SDMMC_4 && overclock)
+ sdmmc->regs->vendllcalcfg = sdmmc->regs->vendllcalcfg &= 0xFFFFC07F | (0x7C << 7); // Add -4 TX_DLY_CODE_OFFSET if HS533.
+#endif
+
sdmmc->regs->vendllcalcfg |= TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE;
_sdmmc_get_clkcon(sdmmc);
@@ -345,7 +358,15 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
if (type == SDHCI_TIMING_MMC_HS400)
+ {
+#ifdef SDMMC_EMMC_OC
+ bool overclock_en = clock > 208000;
+ return _sdmmc_dll_cal_execute(sdmmc, overclock_en);
+#else
return _sdmmc_dll_cal_execute(sdmmc);
+#endif
+ }
+
return 1;
}
@@ -906,7 +927,9 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc)
}
if (result != SDMMC_MASKINT_NOERROR)
{
- DPRINTF("%08X!\n", result);
+#ifdef ERROR_EXTRA_PRINTING
+ EPRINTFARGS("%08X!", result);
+#endif
_sdmmc_reset(sdmmc);
return 0;
}
@@ -929,7 +952,9 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
{
if (!_sdmmc_config_dma(sdmmc, &blkcnt, req))
{
- DPRINTF("SDMMC: DMA Wrong cfg!\n");
+#ifdef ERROR_EXTRA_PRINTING
+ EPRINTF("SDMMC: DMA Wrong cfg!");
+#endif
return 0;
}
@@ -945,14 +970,18 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
if (!_sdmmc_send_cmd(sdmmc, cmd, is_data_present))
{
- DPRINTF("SDMMC: Wrong Response type %08X!\n", cmd->rsp_type);
+#ifdef ERROR_EXTRA_PRINTING
+ EPRINTFARGS("SDMMC: Wrong Response type %08X!", cmd->rsp_type);
+#endif
return 0;
}
int result = _sdmmc_wait_response(sdmmc);
if (!result)
{
- DPRINTF("SDMMC: Transfer timeout!\n");
+#ifdef ERROR_EXTRA_PRINTING
+ EPRINTF("SDMMC: Transfer timeout!");
+#endif
}
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);
@@ -964,7 +993,9 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
result = _sdmmc_cache_rsp(sdmmc, sdmmc->rsp, 0x10, cmd->rsp_type);
if (!result)
{
- DPRINTF("SDMMC: Unknown response %08X!\n", sdmmc->rsp[0]);
+#ifdef ERROR_EXTRA_PRINTING
+ EPRINTFARGS("SDMMC: Unknown response %08X!", sdmmc->rsp[0]);
+#endif
}
}
if (req && result)
@@ -972,7 +1003,9 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
result = _sdmmc_update_dma(sdmmc);
if (!result)
{
- DPRINTF("SDMMC: DMA Update failed!\n");
+#ifdef ERROR_EXTRA_PRINTING
+ EPRINTF("SDMMC: DMA Update failed!");
+#endif
}
}
}
@@ -998,7 +1031,9 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
result = _sdmmc_wait_card_busy(sdmmc);
if (!result)
{
- DPRINTF("SDMMC: Busy timeout!\n");
+#ifdef ERROR_EXTRA_PRINTING
+ EPRINTF("SDMMC: Busy timeout!");
+#endif
}
return result;
}
diff --git a/bootloader/utils/btn.c b/bootloader/utils/btn.c
index 5a1d024..b6e5db3 100644
--- a/bootloader/utils/btn.c
+++ b/bootloader/utils/btn.c
@@ -70,6 +70,22 @@ u8 btn_wait()
}
u8 btn_wait_timeout(u32 time_ms, u8 mask)
+{
+ u32 timeout = get_tmr_ms() + time_ms;
+ u8 res = btn_read() & mask;
+
+ while (get_tmr_ms() < timeout)
+ {
+ if (res == mask)
+ break;
+ else
+ res = btn_read() & mask;
+ };
+
+ return res;
+}
+
+u8 btn_wait_timeout_single(u32 time_ms, u8 mask)
{
u8 single_button = mask & BTN_SINGLE;
mask &= ~BTN_SINGLE;
diff --git a/bootloader/utils/btn.h b/bootloader/utils/btn.h
index 4f6b4d2..1c42cc2 100644
--- a/bootloader/utils/btn.h
+++ b/bootloader/utils/btn.h
@@ -29,5 +29,6 @@ u8 btn_read();
u8 btn_read_vol();
u8 btn_wait();
u8 btn_wait_timeout(u32 time_ms, u8 mask);
+u8 btn_wait_timeout_single(u32 time_ms, u8 mask);
#endif
diff --git a/bootloader/utils/dirlist.c b/bootloader/utils/dirlist.c
index 2bb8eaf..a895c2c 100644
--- a/bootloader/utils/dirlist.c
+++ b/bootloader/utils/dirlist.c
@@ -21,7 +21,7 @@
#include "../mem/heap.h"
#include "../utils/types.h"
-char *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles)
+char *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles, bool parse_dirs)
{
u8 max_entries = 61;
@@ -40,12 +40,18 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile
res = f_readdir(&dir, &fno);
if (res || !fno.fname[0])
break;
- if (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))
+
+ bool curr_parse = parse_dirs ? (fno.fattrib & AM_DIR) : !(fno.fattrib & AM_DIR);
+
+ if (curr_parse)
{
- strcpy(dir_entries + (k * 256), fno.fname);
- k++;
- if (k > (max_entries - 1))
- break;
+ if ((fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))
+ {
+ strcpy(dir_entries + (k * 256), fno.fname);
+ k++;
+ if (k > (max_entries - 1))
+ break;
+ }
}
}
f_closedir(&dir);
diff --git a/bootloader/utils/dirlist.h b/bootloader/utils/dirlist.h
index 4fb9af7..9ad3c38 100644
--- a/bootloader/utils/dirlist.h
+++ b/bootloader/utils/dirlist.h
@@ -16,4 +16,4 @@
#include "../utils/types.h"
-char *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles);
+char *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles, bool parse_dirs);
diff --git a/nyx/nyx_gui/frontend/fe_emmc_tools.c b/nyx/nyx_gui/frontend/fe_emmc_tools.c
index 5f6f1d1..03a4e53 100644
--- a/nyx/nyx_gui/frontend/fe_emmc_tools.c
+++ b/nyx/nyx_gui/frontend/fe_emmc_tools.c
@@ -252,7 +252,7 @@ static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32
}
manual_system_maintenance(false);
se_calc_sha256_finalize(hashEm, NULL);
- se_calc_sha256(hashSd, NULL, bufSd, num << 9, 0, SHA_INIT_HASH, true);
+ se_calc_sha256_oneshot(hashSd, bufSd, num << 9);
res = memcmp(hashEm, hashSd, 0x10);
if (res)
diff --git a/nyx/nyx_gui/frontend/gui.c b/nyx/nyx_gui/frontend/gui.c
index 8e40a45..7efc9fc 100644
--- a/nyx/nyx_gui/frontend/gui.c
+++ b/nyx/nyx_gui/frontend/gui.c
@@ -116,7 +116,7 @@ static gui_status_bar_ctx status_bar;
static void _nyx_disp_init()
{
display_backlight_brightness(0, 1000);
- display_init_framebuffer_pitch();
+ display_init_framebuffer_pitch_inv();
display_init_framebuffer_log();
display_backlight_brightness(h_cfg.backlight - 20, 1000);
}
diff --git a/nyx/nyx_gui/frontend/gui_info.c b/nyx/nyx_gui/frontend/gui_info.c
index 950e550..0d5b15d 100644
--- a/nyx/nyx_gui/frontend/gui_info.c
+++ b/nyx/nyx_gui/frontend/gui_info.c
@@ -447,7 +447,7 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
default:
switch (display_id & 0xFF)
{
- case PANEL_JDI_LPM062M:
+ case PANEL_JDI_XXX062M:
s_printf(txt_buf + strlen(txt_buf), "JDI ");
break;
case (PANEL_INL_P062CCA_AZ1 & 0xFF):
diff --git a/nyx/nyx_gui/gfx/di.c b/nyx/nyx_gui/gfx/di.c
index 56b9631..015df23 100644
--- a/nyx/nyx_gui/gfx/di.c
+++ b/nyx/nyx_gui/gfx/di.c
@@ -145,13 +145,13 @@ void display_init()
// Decode Display ID.
_display_id = ((_display_id >> 8) & 0xFF00) | (_display_id & 0xFF);
- if ((_display_id & 0xFF) == PANEL_JDI_LPM062M)
- _display_id = PANEL_JDI_LPM062M;
+ if ((_display_id & 0xFF) == PANEL_JDI_XXX062M)
+ _display_id = PANEL_JDI_XXX062M;
// Initialize display panel.
switch (_display_id)
{
- case PANEL_JDI_LPM062M:
+ case PANEL_JDI_XXX062M:
exec_cfg((u32 *)DSI_BASE, _display_init_config_jdi, 43);
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
break;
@@ -264,7 +264,7 @@ void display_end()
// De-initialize display panel.
switch (_display_id)
{
- case PANEL_JDI_LPM062M:
+ case PANEL_JDI_XXX062M:
exec_cfg((u32 *)DSI_BASE, _display_deinit_config_jdi, 22);
break;
case PANEL_AUO_A062TAN01:
@@ -338,9 +338,21 @@ void display_color_screen(u32 color)
}
u32 *display_init_framebuffer_pitch()
+{
+ // Sanitize framebuffer area.
+ memset((u32 *)IPL_FB_ADDRESS, 0, 0x3C0000);
+
+ // This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
+ exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch, 32);
+ usleep(35000);
+
+ return (u32 *)IPL_FB_ADDRESS;
+}
+
+u32 *display_init_framebuffer_pitch_inv()
{
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
- exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch, 34);
+ exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch_inv, 34);
usleep(35000);
diff --git a/nyx/nyx_gui/gfx/di.h b/nyx/nyx_gui/gfx/di.h
index cefc764..29685c6 100644
--- a/nyx/nyx_gui/gfx/di.h
+++ b/nyx/nyx_gui/gfx/di.h
@@ -506,7 +506,7 @@
enum
{
- PANEL_JDI_LPM062M = 0x10,
+ PANEL_JDI_XXX062M = 0x10,
PANEL_JDI_LAM062M109A = 0x0910,
PANEL_JDI_LPM062M326A = 0x2610,
PANEL_INL_P062CCA_AZ1 = 0x0F20,
@@ -528,6 +528,7 @@ void display_backlight_brightness(u32 brightness, u32 step_delay);
/*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */
u32 *display_init_framebuffer_pitch();
+u32 *display_init_framebuffer_pitch_inv();
u32 *display_init_framebuffer_block();
u32 *display_init_framebuffer_log();
void display_activate_console();
diff --git a/nyx/nyx_gui/gfx/di.inl b/nyx/nyx_gui/gfx/di.inl
index 071b489..ef3b1b0 100644
--- a/nyx/nyx_gui/gfx/di.inl
+++ b/nyx/nyx_gui/gfx/di.inl
@@ -559,8 +559,44 @@ static const cfg_op_t cfg_display_one_color[8] = {
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} // Continuous display.
};
-//Display A config pitch.
-static const cfg_op_t cfg_display_framebuffer_pitch[34] = {
+//Display A config linear pitch.
+static const cfg_op_t cfg_display_framebuffer_pitch[32] = {
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
+ {DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_WIN_POSITION, 0}, //(0,0)
+ {DC_WIN_H_INITIAL_DDA, 0},
+ {DC_WIN_V_INITIAL_DDA, 0},
+ {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
+ {DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
+ {DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
+ {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
+ {DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
+ {DC_WINBUF_SURFACE_KIND, PITCH},
+ {DC_WINBUF_START_ADDR, IPL_FB_ADDRESS}, // Framebuffer address.
+ {DC_WINBUF_ADDR_H_OFFSET, 0},
+ {DC_WINBUF_ADDR_V_OFFSET, 0},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
+ {DC_WIN_WIN_OPTIONS, 0},
+ {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
+ {DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
+ {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
+ {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
+ {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
+};
+
+//Display A config linear pitch inverse + Win D support.
+static const cfg_op_t cfg_display_framebuffer_pitch_inv[34] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
@@ -576,7 +612,7 @@ static const cfg_op_t cfg_display_framebuffer_pitch[34] = {
{DC_WIN_POSITION, 0}, //(0,0)
{DC_WIN_H_INITIAL_DDA, 0},
{DC_WIN_V_INITIAL_DDA, 0},
- {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)},
+ {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
@@ -614,7 +650,7 @@ static const cfg_op_t cfg_display_framebuffer_block[34] = {
{DC_WIN_POSITION, 0}, //(0,0)
{DC_WIN_H_INITIAL_DDA, 0},
{DC_WIN_V_INITIAL_DDA, 0},
- {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)},
+ {DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
diff --git a/nyx/nyx_gui/libs/fatfs/ff.c b/nyx/nyx_gui/libs/fatfs/ff.c
index c48c036..c6c4d75 100644
--- a/nyx/nyx_gui/libs/fatfs/ff.c
+++ b/nyx/nyx_gui/libs/fatfs/ff.c
@@ -3906,11 +3906,11 @@ FRESULT f_read (
-#ifdef FF_FASTFS
+#if FF_FASTFS && FF_USE_FASTSEEK
/*-----------------------------------------------------------------------*/
/* Fast Read Aligned Sized File Without a Cache */
/*-----------------------------------------------------------------------*/
-#if FF_USE_FASTSEEK
+
FRESULT f_read_fast (
FIL* fp, /* Pointer to the file object */
const void* buff, /* Pointer to the data to be written */
@@ -3988,7 +3988,6 @@ FRESULT f_read_fast (
LEAVE_FF(fs, FR_OK);
}
#endif
-#endif
@@ -4132,11 +4131,11 @@ FRESULT f_write (
-#ifdef FF_FASTFS
+#if FF_FASTFS && FF_USE_FASTSEEK
/*-----------------------------------------------------------------------*/
/* Fast Write Aligned Sized File Without a Cache */
/*-----------------------------------------------------------------------*/
-#if FF_USE_FASTSEEK
+
FRESULT f_write_fast (
FIL* fp, /* Pointer to the file object */
const void* buff, /* Pointer to the data to be written */
@@ -4219,7 +4218,6 @@ FRESULT f_write_fast (
LEAVE_FF(fs, FR_OK);
}
#endif
-#endif
@@ -4680,8 +4678,7 @@ FRESULT f_lseek (
-#ifdef FF_FASTFS
-#if FF_USE_FASTSEEK
+#if FF_FASTFS && FF_USE_FASTSEEK
/*-----------------------------------------------------------------------*/
/* Seek File Read/Write Pointer */
/*-----------------------------------------------------------------------*/
@@ -4708,7 +4705,6 @@ DWORD *f_expand_cltbl (
return fp->cltbl;
}
#endif
-#endif
diff --git a/nyx/nyx_gui/libs/fatfs/ff.h b/nyx/nyx_gui/libs/fatfs/ff.h
index 6c47c73..af1151f 100644
--- a/nyx/nyx_gui/libs/fatfs/ff.h
+++ b/nyx/nyx_gui/libs/fatfs/ff.h
@@ -246,7 +246,7 @@ typedef enum {
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
-#ifdef FF_FASTFS
+#if FF_FASTFS
FR_INVALID_PARAMETER, /* (19) Given parameter is invalid */
FR_CLTBL_NO_INIT /* (20) The cluster table for fast seek/read/write was not created */
#else
@@ -263,10 +263,8 @@ FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a f
FRESULT f_close (FIL* fp); /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
-#ifdef FF_FASTFS
FRESULT f_read_fast (FIL* fp, const void* buff, UINT btr); /* Fast read data from the file */
FRESULT f_write_fast (FIL* fp, const void* buff, UINT btw); /* Fast write data to the file */
-#endif
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
FRESULT f_truncate (FIL* fp); /* Truncate the file */
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
@@ -288,9 +286,7 @@ FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get numbe
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
-#ifdef FF_FASTFS
DWORD *f_expand_cltbl (FIL* fp, UINT tblsz, FSIZE_t ofs); /* Expand file and populate cluster table */
-#endif
FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
diff --git a/nyx/nyx_gui/libs/fatfs/ffconf.h b/nyx/nyx_gui/libs/fatfs/ffconf.h
index dc83987..1f79990 100644
--- a/nyx/nyx_gui/libs/fatfs/ffconf.h
+++ b/nyx/nyx_gui/libs/fatfs/ffconf.h
@@ -41,14 +41,16 @@
#define FF_USE_MKFS 1
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
+
+#define FF_USE_FASTSEEK 0
+/* This option switches fast seek function. (0:Disable or 1:Enable) */
+
#define FF_FASTFS 1
-#ifdef FF_FASTFS
+#if FF_FASTFS
+#undef FF_USE_FASTSEEK
#define FF_USE_FASTSEEK 1
-#else
-#define FF_USE_FASTSEEK 0
#endif
-/* This option switches fast seek function. (0:Disable or 1:Enable) */
#define FF_USE_EXPAND 0
@@ -245,7 +247,7 @@
#define FF_FS_NORTC 0
#define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1
-#define FF_NORTC_YEAR 2019
+#define FF_NORTC_YEAR 2020
/* The option FF_FS_NORTC switches timestamp function. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
diff --git a/nyx/nyx_gui/mem/minerva.c b/nyx/nyx_gui/mem/minerva.c
index 71c9dbf..c399070 100644
--- a/nyx/nyx_gui/mem/minerva.c
+++ b/nyx/nyx_gui/mem/minerva.c
@@ -37,6 +37,7 @@ u32 minerva_init()
minerva_cfg = NULL;
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
+#ifdef NYX
// Set table to nyx storage.
mtc_cfg->mtc_table = (emc_table_t *)nyx_str->mtc_table;
@@ -69,6 +70,23 @@ u32 minerva_init()
if (minerva_cfg)
memcpy(mtc_cfg, (void *)&mtc_tmp, sizeof(mtc_config_t));
}
+#else
+ memset(mtc_cfg, 0, sizeof(mtc_config_t));
+
+ // Set table to nyx storage.
+ mtc_cfg->mtc_table = (emc_table_t *)nyx_str->mtc_table;
+
+ mtc_cfg->sdram_id = (fuse_read_odm(4) >> 3) & 0x1F;
+ mtc_cfg->init_done = MTC_NEW_MAGIC; // Initialize mtc table.
+
+ u32 ep_addr = ianos_loader(false, "bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg);
+
+ // Ensure that Minerva is new.
+ if (mtc_cfg->init_done == MTC_INIT_MAGIC)
+ minerva_cfg = (void *)ep_addr;
+ else
+ mtc_cfg->init_done = 0;
+#endif
if (!minerva_cfg)
return 1;
diff --git a/nyx/nyx_gui/mem/sdram.c b/nyx/nyx_gui/mem/sdram.c
index 6c6d264..bf72966 100644
--- a/nyx/nyx_gui/mem/sdram.c
+++ b/nyx/nyx_gui/mem/sdram.c
@@ -723,11 +723,14 @@ sdram_params_t *sdram_get_params()
case DRAM_4GB_SAMSUNG_K4F6E304HB_MGCH:
case DRAM_4GB_MICRON_MT53B512M32D2NP_062_WT:
break;
+
case DRAM_4GB_HYNIX_H9HCNNNBPUMLHR_NLN:
- case DRAM_4GB_COPPER_UNK_3:
case DRAM_6GB_SAMSUNG_K4FHE3D4HM_MFCH:
- case DRAM_4GB_COPPER_UNK_5:
- case DRAM_4GB_COPPER_UNK_6:
+#ifdef CONFIG_SDRAM_COPPER_SUPPORT
+ case DRAM_4GB_COPPER_SAMSUNG:
+ case DRAM_4GB_COPPER_HYNIX:
+ case DRAM_4GB_COPPER_MICRON:
+#endif
_sdram_patch_model_params(dramid, (u32 *)buf);
break;
}
diff --git a/nyx/nyx_gui/mem/sdram_config.inl b/nyx/nyx_gui/mem/sdram_config.inl
index 58eb62d..42e0555 100644
--- a/nyx/nyx_gui/mem/sdram_config.inl
+++ b/nyx/nyx_gui/mem/sdram_config.inl
@@ -15,15 +15,17 @@
* along with this program. If not, see .
*/
+#define DRAM_CFG_SIZE 1896
+
#define DRAM_ID(x) (1 << (x))
#define DRAM_4GB_SAMSUNG_K4F6E304HB_MGCH 0
#define DRAM_4GB_HYNIX_H9HCNNNBPUMLHR_NLN 1
#define DRAM_4GB_MICRON_MT53B512M32D2NP_062_WT 2
-#define DRAM_4GB_COPPER_UNK_3 3 // Samsung?
+#define DRAM_4GB_COPPER_SAMSUNG 3
#define DRAM_6GB_SAMSUNG_K4FHE3D4HM_MFCH 4
-#define DRAM_4GB_COPPER_UNK_5 5 // Samsung?
-#define DRAM_4GB_COPPER_UNK_6 6 // Samsung?
+#define DRAM_4GB_COPPER_HYNIX 5
+#define DRAM_4GB_COPPER_MICRON 6
typedef struct _sdram_vendor_patch_t
{
@@ -658,11 +660,22 @@ static const sdram_params_t _dram_cfg_0_samsung_4gb = {
};
static const sdram_vendor_patch_t sdram_cfg_vendor_patches[] = {
- { 0x0000003A, 59, DRAM_ID(6) }, // emc_rfc. Auto refresh.
- { 0x0000001D, 60, DRAM_ID(6) }, // emc_rfc_pb. Bank Auto refresh.
+ // Hynix timing config.
{ 0x0000000D, 67, DRAM_ID(1) | DRAM_ID(5) }, // emc_r2w.
{ 0x00000001, 91, DRAM_ID(1) | DRAM_ID(5) }, // emc_puterm_extra.
{ 0x80000000, 92, DRAM_ID(1) | DRAM_ID(5) }, // emc_puterm_width.
+ { 0x00000210, 317, DRAM_ID(1) | DRAM_ID(5) }, // emc_pmacro_data_rx_term_mode.
+ { 0x00000005, 368, DRAM_ID(1) | DRAM_ID(5) }, // mc_emem_arb_timing_r2w.
+
+ // Samsung 6GB density config.
+ { 0x000C0302, 347, DRAM_ID(4) }, // mc_emem_adr_cfg_dev0. 768MB sub-partition density.
+ { 0x000C0302, 348, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB sub-partition density.
+ { 0x00001800, 353, DRAM_ID(4) }, // mc_emem_cfg. 6GB total density.
+
+#ifdef CONFIG_SDRAM_COPPER_SUPPORT
+ // Copper prototype Samsung/Hynix/Micron timing configs.
+ { 0x0000003A, 59, DRAM_ID(6) }, // emc_rfc. Auto refresh.
+ { 0x0000001D, 60, DRAM_ID(6) }, // emc_rfc_pb. Bank Auto refresh.
{ 0x00000012, 108, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_rw2pden.
{ 0x0000003B, 112, DRAM_ID(6) }, // emc_txsr.
{ 0x0000003B, 113, DRAM_ID(6) }, // emc_txsr_dll.
@@ -687,11 +700,7 @@ static const sdram_vendor_patch_t sdram_cfg_vendor_patches[] = {
{ 0x00000015, 237, DRAM_ID(5) | DRAM_ID(6) }, // emc_pmacro_ddll_long_cmd_4.
{ 0x00000012, 295, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft2.
{ 0x00000012, 296, DRAM_ID(3) | DRAM_ID(5) | DRAM_ID(6) }, // emc_cmd_brlshft3.
- { 0x00000210, 317, DRAM_ID(1) | DRAM_ID(5) }, // emc_pmacro_data_rx_term_mode.
- { 0x000C0302, 347, DRAM_ID(4) }, // mc_emem_adr_cfg_dev0. 768MB sub-partition density.
- { 0x000C0302, 348, DRAM_ID(4) }, // mc_emem_adr_cfg_dev1. 768MB sub-partition density.
- { 0x00001800, 353, DRAM_ID(4) }, // mc_emem_cfg. 6GB total density.
- { 0x00000005, 368, DRAM_ID(1) | DRAM_ID(5) }, // mc_emem_arb_timing_r2w.
{ 0x00000007, 370, DRAM_ID(6) }, // mc_emem_arb_timing_rfcpb. Bank refresh.
- { 0x72A30504, 373, DRAM_ID(6) } // mc_emem_arb_misc0.
+ { 0x72A30504, 373, DRAM_ID(6) }, // mc_emem_arb_misc0.
+#endif
};
diff --git a/nyx/nyx_gui/mem/sdram_param_t210.h b/nyx/nyx_gui/mem/sdram_param_t210.h
index 4980918..4c6c60a 100644
--- a/nyx/nyx_gui/mem/sdram_param_t210.h
+++ b/nyx/nyx_gui/mem/sdram_param_t210.h
@@ -113,7 +113,6 @@ typedef struct _sdram_params
/* Specifies the value for EMC_AUTO_CAL_CONFIG3 */
u32 emc_auto_cal_config3;
-
u32 emc_auto_cal_config4;
u32 emc_auto_cal_config5;
u32 emc_auto_cal_config6;
diff --git a/nyx/nyx_gui/sec/se.c b/nyx/nyx_gui/sec/se.c
index 9dc4a77..52f8fea 100644
--- a/nyx/nyx_gui/sec/se.c
+++ b/nyx/nyx_gui/sec/se.c
@@ -384,6 +384,11 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
return res;
}
+int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size)
+{
+ return se_calc_sha256(hash, NULL, src, src_size, 0, SHA_INIT_HASH, true);
+}
+
int se_calc_sha256_finalize(void *hash, u32 *msg_left)
{
u32 *hash32 = (u32 *)hash;
diff --git a/nyx/nyx_gui/sec/se.h b/nyx/nyx_gui/sec/se.h
index 3a2b9f5..2184b4d 100644
--- a/nyx/nyx_gui/sec/se.h
+++ b/nyx/nyx_gui/sec/se.h
@@ -29,6 +29,7 @@ int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src,
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot);
+int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size);
int se_calc_sha256_finalize(void *hash, u32 *msg_left);
int se_gen_prng128(void *dst);
diff --git a/nyx/nyx_gui/soc/clock.c b/nyx/nyx_gui/soc/clock.c
index 20c6d62..5d49b33 100644
--- a/nyx/nyx_gui/soc/clock.c
+++ b/nyx/nyx_gui/soc/clock.c
@@ -276,7 +276,7 @@ void clock_enable_pllc(u32 divn)
return;
// Take PLLC out of reset and set basic misc parameters.
- CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) =
+ CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) =
((CLOCK(CLK_RST_CONTROLLER_PLLC_MISC) & 0xFFF0000F) & ~PLLC_MISC_RESET) | (0x80000 << 4); // PLLC_EXT_FRU.
CLOCK(CLK_RST_CONTROLLER_PLLC_MISC_2) |= 0xF0 << 8; // PLLC_FLL_LD_MEM.
@@ -315,7 +315,7 @@ void clock_disable_pllc()
#define PLLC4_ENABLED (1 << 31)
#define PLLC4_IN_USE (~PLLC4_ENABLED)
-static u32 pllc4_enabled = 0;
+u32 pllc4_enabled = 0;
static void _clock_enable_pllc4(u32 mask)
{
diff --git a/nyx/nyx_gui/soc/hw_init.c b/nyx/nyx_gui/soc/hw_init.c
index 45482cc..ffdb0fc 100644
--- a/nyx/nyx_gui/soc/hw_init.c
+++ b/nyx/nyx_gui/soc/hw_init.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
@@ -19,27 +20,333 @@
#include "hw_init.h"
#include "bpmp.h"
#include "clock.h"
+#include "fuse.h"
#include "gpio.h"
+#include "i2c.h"
+#include "pinmux.h"
#include "pmc.h"
#include "uart.h"
#include "t210.h"
-#include "../mem/minerva.h"
-#include "../gfx/di.h"
#include "../input/joycon.h"
#include "../input/touch.h"
+#include "../gfx/di.h"
+#include "../mem/mc.h"
+#include "../mem/minerva.h"
+#include "../mem/sdram.h"
+#include "../sec/se.h"
+#include "../sec/se_t210.h"
+#include "../power/max77620.h"
+#include "../power/max7762x.h"
+#include "../gfx/di.h"
#include "../power/regulator_5v.h"
#include "../storage/nx_sd.h"
#include "../storage/sdmmc.h"
#include "../thermal/fan.h"
#include "../utils/util.h"
+extern boot_cfg_t b_cfg;
extern volatile nyx_storage_t *nyx_str;
+/*
+ * CLK_OSC - 38.4 MHz crystal.
+ * CLK_M - 19.2 MHz (osc/2).
+ * CLK_S - 32.768 KHz (from PMIC).
+ * SCLK - 204MHz init (-> 408MHz -> OC).
+ * HCLK - 204MHz init (-> 408MHz -> OC).
+ * PCLK - 68MHz init (-> 136MHz -> OC/4).
+ */
+
+void _config_oscillators()
+{
+ CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4; // Set CLK_M_DIVISOR to 2.
+ SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
+ TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.
+ CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength.
+
+ PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE; // Set LP0 OSC drive strength.
+ PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF) | PMC_OSC_EDPD_OVER_OSC_CTRL_OVER;
+ PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
+ PMC(APBDEV_PMC_SCRATCH188) = (PMC(APBDEV_PMC_SCRATCH188) & 0xFCFFFFFF) | (4 << 23); // LP0 EMC2TMC_CFG_XM2COMP_PU_VREF_SEL_RANGE.
+
+ CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
+ CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
+
+ PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; //0x249F = 19200000 * (16 / 32.768 kHz)
+
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set SCLK div to 1.
+ CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set clk source to Run and PLLP_OUT2 (204MHz).
+ CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000; // Enable SUPER_SDIV to 1.
+ CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
+}
+
+void _config_gpios()
+{
+ /////////////////put mariko stuff, basically lite.
+
+ PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
+ PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
+
+ // Set Joy-Con IsAttached direction.
+ PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
+ PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
+
+ // Set pin mode for Joy-Con IsAttached and UARTB/C TX pins.
+#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B
+ gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
+#endif
+#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_C
+ gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
+#endif
+ // Set Joy-Con IsAttached mode.
+ gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO);
+ gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO);
+
+ // Enable input logic for Joy-Con IsAttached and UARTB/C TX pins.
+ gpio_output_enable(GPIO_PORT_G, GPIO_PIN_0, GPIO_OUTPUT_DISABLE);
+ gpio_output_enable(GPIO_PORT_D, GPIO_PIN_1, GPIO_OUTPUT_DISABLE);
+ gpio_output_enable(GPIO_PORT_E, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
+ gpio_output_enable(GPIO_PORT_H, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
+
+ pinmux_config_i2c(I2C_1);
+ pinmux_config_i2c(I2C_5);
+ pinmux_config_uart(UART_A);
+
+ // Configure volume up/down as inputs.
+ gpio_config(GPIO_PORT_X, GPIO_PIN_6, GPIO_MODE_GPIO);
+ gpio_config(GPIO_PORT_X, GPIO_PIN_7, GPIO_MODE_GPIO);
+ gpio_output_enable(GPIO_PORT_X, GPIO_PIN_6, GPIO_OUTPUT_DISABLE);
+ gpio_output_enable(GPIO_PORT_X, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
+
+ // Configure HOME as inputs.
+ // PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
+ // gpio_config(GPIO_PORT_Y, GPIO_PIN_1, GPIO_MODE_GPIO);
+}
+
+void _config_pmc_scratch()
+{
+ PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; // Unset Debug console from Customer Option.
+ PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset DATA_DQ_E_IVREF EMC_PMACRO_DATA_PAD_TX_CTRL
+ PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
+}
+
+void _mbist_workaround()
+{
+ CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= (1 << 10); // Enable AHUB clock.
+ CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= (1 << 6); // Enable APE clock.
+
+ // Set mux output to SOR1 clock switch.
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) | 0x8000) & 0xFFFFBFFF;
+ // Enabled PLLD and set csi to PLLD for test pattern generation.
+ CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= 0x40800000;
+
+ // Clear per-clock resets.
+ CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = 0x40; // Clear reset APE.
+ CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_CLR) = 0x40000; // Clear reset VIC.
+ CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = 0x18000000; // Clear reset DISP1, HOST1X.
+ usleep(2);
+
+ // I2S channels to master and disable SLCG.
+ I2S(I2S1_CTRL) |= I2S_CTRL_MASTER_EN;
+ I2S(I2S1_CG) &= ~I2S_CG_SLCG_ENABLE;
+ I2S(I2S2_CTRL) |= I2S_CTRL_MASTER_EN;
+ I2S(I2S2_CG) &= ~I2S_CG_SLCG_ENABLE;
+ I2S(I2S3_CTRL) |= I2S_CTRL_MASTER_EN;
+ I2S(I2S3_CG) &= ~I2S_CG_SLCG_ENABLE;
+ I2S(I2S4_CTRL) |= I2S_CTRL_MASTER_EN;
+ I2S(I2S4_CG) &= ~I2S_CG_SLCG_ENABLE;
+ I2S(I2S5_CTRL) |= I2S_CTRL_MASTER_EN;
+ I2S(I2S5_CG) &= ~I2S_CG_SLCG_ENABLE;
+
+ DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= 4; // DSC_SLCG_OVERRIDE.
+ VIC(0x8C) = 0xFFFFFFFF;
+ usleep(2);
+
+ // Set per-clock reset.
+ CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_SET) = 0x40; // Set reset APE.
+ CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = 0x18000000; // Set reset DISP1, HOST1x.
+ CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_SET) = 0x40000; // Set reset VIC.
+
+ // Enable specific clocks and disable all others.
+ CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = 0xC0; // Enable clock PMC, FUSE.
+ CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80000130; // Enable clock RTC, TMR, GPIO, BPMP_CACHE.
+ //CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80400130; // Keep USBD ON.
+ CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) = 0x1F00200; // Enable clock CSITE, IRAMA, IRAMB, IRAMC, IRAMD, BPMP_CACHE_RAM.
+ CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = 0x80400808; // Enable clock MSELECT, APB2APE, SPDIF_DOUBLER, SE.
+ CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) = 0x402000FC; // Enable clock PCIERX0, PCIERX1, PCIERX2, PCIERX3, PCIERX4, PCIERX5, ENTROPY, MC1.
+ CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) = 0x23000780; // Enable clock MC_CAPA, MC_CAPB, MC_CPU, MC_BBC, DBGAPB, HPLL_ADSP, PLLG_REF.
+ CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) = 0x300; // Enable clock MC_CDPA, MC_CCPA.
+
+ // Disable clock gate overrides.
+ CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA) = 0;
+ CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB) = 0;
+ CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC) = 0;
+ CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) = 0;
+ CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE) = 0;
+
+ // Set child clock sources.
+ CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF; // Disable PLLD and set reference clock and csi clock.
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= 0xFFFF3FFF; // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch.
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
+}
+
+void _config_se_brom()
+{
+ // Enable fuse clock.
+ clock_enable_fuse(true);
+
+ // Skip SBK/SSK if sept was run.
+ if (!(b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN))
+ {
+ // 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, 0x10);
+
+ // Lock SBK from being read.
+ SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 14 * 4) = 0x7E;
+
+ // Lock SSK (although it's not set and unused anyways).
+ SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 15 * 4) = 0x7E;
+ }
+
+ // This memset needs to happen here, else TZRAM will behave weirdly later on.
+ memset((void *)TZRAM_BASE, 0, 0x10000);
+ PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE;
+ SE(SE_INT_STATUS_REG_OFFSET) = 0x1F;
+
+ // Clear the boot reason to avoid problems later
+ PMC(APBDEV_PMC_SCRATCH200) = 0x0;
+ PMC(APBDEV_PMC_RST_STATUS) = 0x0;
+ APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10);
+}
+
+void _config_regulators()
+{
+ // Disable low battery shutdown monitor.
+ max77620_low_battery_monitor_config(false);
+
+ // Disable SDMMC1 IO power.
+ gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
+ max77620_regulator_enable(REGULATOR_LDO2, 0);
+ sd_power_cycle_time_start = get_tmr_ms();
+
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,
+ (1 << 6) | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.
+
+///////// not on mariko
+ // Configure all Flexible Power Sequencers.
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0,
+ (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1,
+ (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (1 << MAX77620_FPS_EN_SRC_SHIFT));
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2,
+ (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
+ max77620_regulator_config_fps(REGULATOR_LDO4);
+ max77620_regulator_config_fps(REGULATOR_LDO8);
+ max77620_regulator_config_fps(REGULATOR_SD0);
+ max77620_regulator_config_fps(REGULATOR_SD1);
+ max77620_regulator_config_fps(REGULATOR_SD3);
+
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3,
+ (4 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT)); // 3.x+
+////////
+
+ // Set vdd_core voltage to 1.125V.
+ max77620_regulator_set_voltage(REGULATOR_SD0, 1125000); // 1050000 on mariko.
+
+ //if (lite)
+ // ldo8 2.8V enable.
+
+ // Fix CPU/GPU after a L4T warmboot.
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 2);
+ i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO6, 2);
+
+ i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_0_95V); // Disable power.
+ i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_VOUT_DVS_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_1_09V); // Enable DVS power.
+ i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL1_REG, MAX77621_RAMP_50mV_PER_US);
+ i2c_send_byte(I2C_5, MAX77621_CPU_I2C_ADDR, MAX77621_CONTROL2_REG,
+ MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
+ MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
+
+ i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_VOUT_REG, MAX77621_VOUT_0_95V); // Disable power.
+ i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_VOUT_DVS_REG, MAX77621_VOUT_ENABLE | MAX77621_VOUT_1_09V); // Enable DVS power.
+ i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL1_REG, MAX77621_RAMP_50mV_PER_US);
+ i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL2_REG,
+ MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
+ MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
+}
+
+void config_hw()
+{
+ // Bootrom stuff we skipped by going through rcm.
+ _config_se_brom();
+ //FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11;
+ SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F; // Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
+ PMC(APBDEV_PMC_SCRATCH49) = PMC(APBDEV_PMC_SCRATCH49) & 0xFFFFFFFC;
+
+ _mbist_workaround(); // not on mariko.
+ clock_enable_se();
+ // CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SE) |= 0x100; // Lock clock. mariko.
+
+ // Enable fuse clock.
+ clock_enable_fuse(true);
+
+ // Disable fuse programming.
+ fuse_disable_program();
+
+ mc_enable();
+
+ _config_oscillators();
+ APB_MISC(APB_MISC_PP_PINMUX_GLOBAL) = 0;
+ _config_gpios();
+
+#ifdef DEBUG_UART_PORT
+ clock_enable_uart(DEBUG_UART_PORT);
+ uart_init(DEBUG_UART_PORT, 115200);
+#endif
+
+ clock_enable_cl_dvfs();
+
+ clock_enable_i2c(I2C_1);
+ clock_enable_i2c(I2C_5);
+
+ clock_enable_tzram();
+
+ i2c_init(I2C_1);
+ i2c_init(I2C_5);
+
+ _config_regulators();
+
+ _config_pmc_scratch(); // Missing from 4.x+
+
+ CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // Set SCLK to PLLP_OUT (408MHz).
+
+ // APBDEV_PMC_UNK_BE8 &= 0xFFFFFFFE; // mariko
+ // APBDEV_PMC_UNK_BF0 = 3; // mariko
+ // APBDEV_PMC_UNK_BEC = 3; // mariko
+
+ sdram_init();
+
+ bpmp_mmu_enable();
+
+ // Clear flags from PMC_SCRATCH0
+ PMC(APBDEV_PMC_SCRATCH0) &= ~PMC_SCRATCH0_MODE_PAYLOAD;
+}
+
void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
{
// Disable BPMP max clock.
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
+#ifdef NYX
// Deinit touchscreen, 5V regulators and Joy-Con.
touch_power_off();
set_fan_duty(0);
@@ -47,6 +354,7 @@ void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
regulator_disable_5v(REGULATOR_5V_ALL);
clock_disable_uart(UART_B);
clock_disable_uart(UART_C);
+#endif
// Flush/disable MMU cache and set DRAM clock to 204MHz.
bpmp_mmu_disable();
diff --git a/nyx/nyx_gui/soc/hw_init.h b/nyx/nyx_gui/soc/hw_init.h
index fe4defa..b92814b 100644
--- a/nyx/nyx_gui/soc/hw_init.h
+++ b/nyx/nyx_gui/soc/hw_init.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
@@ -19,6 +20,7 @@
#include "../utils/types.h"
+void config_hw();
void reconfig_hw_workaround(bool extra_reconfig, u32 magic);
#endif
diff --git a/nyx/nyx_gui/soc/kfuse.c b/nyx/nyx_gui/soc/kfuse.c
index a02acda..cdfba53 100644
--- a/nyx/nyx_gui/soc/kfuse.c
+++ b/nyx/nyx_gui/soc/kfuse.c
@@ -45,7 +45,7 @@ int kfuse_read(u32 *buf)
res = 1;
-out:;
+out:
clock_disable_kfuse();
return res;
}
diff --git a/nyx/nyx_gui/soc/uart.c b/nyx/nyx_gui/soc/uart.c
index 2568d10..3aea2f7 100644
--- a/nyx/nyx_gui/soc/uart.c
+++ b/nyx/nyx_gui/soc/uart.c
@@ -79,7 +79,7 @@ void uart_send(u32 idx, const u8 *buf, u32 len)
while (!(uart->UART_LSR & UART_LSR_THRE))
;
uart->UART_THR_DLAB = buf[i];
- };
+ }
}
u32 uart_recv(u32 idx, u8 *buf, u32 len)
diff --git a/nyx/nyx_gui/storage/nx_emmc.h b/nyx/nyx_gui/storage/nx_emmc.h
index b3a90dc..380b7a0 100644
--- a/nyx/nyx_gui/storage/nx_emmc.h
+++ b/nyx/nyx_gui/storage/nx_emmc.h
@@ -22,7 +22,7 @@
#include "../utils/types.h"
#include "../utils/list.h"
-#define NX_GPT_FIRST_LBA 1
+#define NX_GPT_FIRST_LBA 1
#define NX_GPT_NUM_BLOCKS 33
#define NX_EMMC_BLOCKSIZE 512
diff --git a/nyx/nyx_gui/storage/sd.h b/nyx/nyx_gui/storage/sd.h
index 3ecfc07..a780ec8 100644
--- a/nyx/nyx_gui/storage/sd.h
+++ b/nyx/nyx_gui/storage/sd.h
@@ -1,6 +1,4 @@
/*
- * include/linux/mmc/sd.h
- *
* Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved.
* Copyright (c) 2018 CTCaer
*
@@ -10,8 +8,8 @@
* your option) any later version.
*/
-#ifndef LINUX_MMC_SD_H
-#define LINUX_MMC_SD_H
+#ifndef MMC_SD_H
+#define MMC_SD_H
/* SD commands type argument response */
/* class 0 */
diff --git a/nyx/nyx_gui/storage/sdmmc_driver.c b/nyx/nyx_gui/storage/sdmmc_driver.c
index 9f68bee..957a0bc 100644
--- a/nyx/nyx_gui/storage/sdmmc_driver.c
+++ b/nyx/nyx_gui/storage/sdmmc_driver.c
@@ -30,8 +30,14 @@
#include "../utils/util.h"
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
+//#define ERROR_EXTRA_PRINTING
#define DPRINTF(...)
+#ifdef NYX
+#define ERROR_EXTRA_PRINTING
+#define SDMMC_EMMC_OC
+#endif
+
/*! SCMMC controller base addresses. */
static const u32 _sdmmc_bases[4] = {
0x700B0000,
@@ -220,7 +226,11 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
}
+#ifdef SDMMC_EMMC_OC
static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc, bool overclock)
+#else
+static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
+#endif
{
int result = 1, should_disable_sd_clock = 0;
@@ -230,8 +240,10 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc, bool overclock)
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
}
+#ifdef SDMMC_EMMC_OC
if (sdmmc->id == SDMMC_4 && overclock)
sdmmc->regs->vendllcalcfg = sdmmc->regs->vendllcalcfg &= 0xFFFFC07F | (0x7C << 7); // Add -4 TX_DLY_CODE_OFFSET if HS533.
+#endif
sdmmc->regs->vendllcalcfg |= TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE;
_sdmmc_get_clkcon(sdmmc);
@@ -347,8 +359,12 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
if (type == SDHCI_TIMING_MMC_HS400)
{
+#ifdef SDMMC_EMMC_OC
bool overclock_en = clock > 208000;
return _sdmmc_dll_cal_execute(sdmmc, overclock_en);
+#else
+ return _sdmmc_dll_cal_execute(sdmmc);
+#endif
}
return 1;
@@ -911,7 +927,9 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc)
}
if (result != SDMMC_MASKINT_NOERROR)
{
+#ifdef ERROR_EXTRA_PRINTING
EPRINTFARGS("%08X!", result);
+#endif
_sdmmc_reset(sdmmc);
return 0;
}
@@ -934,7 +952,9 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
{
if (!_sdmmc_config_dma(sdmmc, &blkcnt, req))
{
- EPRINTF("DMA CFG Failed!");
+#ifdef ERROR_EXTRA_PRINTING
+ EPRINTF("SDMMC: DMA Wrong cfg!");
+#endif
return 0;
}
@@ -950,14 +970,18 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
if (!_sdmmc_send_cmd(sdmmc, cmd, is_data_present))
{
- EPRINTFARGS("SDMMC: Wrong Response type %08X!\n", cmd->rsp_type);
+#ifdef ERROR_EXTRA_PRINTING
+ EPRINTFARGS("SDMMC: Wrong Response type %08X!", cmd->rsp_type);
+#endif
return 0;
}
int result = _sdmmc_wait_response(sdmmc);
if (!result)
{
+#ifdef ERROR_EXTRA_PRINTING
EPRINTF("SDMMC: Transfer timeout!");
+#endif
}
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", result,
sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);
@@ -969,7 +993,9 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
result = _sdmmc_cache_rsp(sdmmc, sdmmc->rsp, 0x10, cmd->rsp_type);
if (!result)
{
+#ifdef ERROR_EXTRA_PRINTING
EPRINTFARGS("SDMMC: Unknown response %08X!", sdmmc->rsp[0]);
+#endif
}
}
if (req && result)
@@ -977,7 +1003,9 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
result = _sdmmc_update_dma(sdmmc);
if (!result)
{
+#ifdef ERROR_EXTRA_PRINTING
EPRINTF("SDMMC: DMA Update failed!");
+#endif
}
}
}
@@ -1003,7 +1031,9 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
result = _sdmmc_wait_card_busy(sdmmc);
if (!result)
{
+#ifdef ERROR_EXTRA_PRINTING
EPRINTF("SDMMC: Busy timeout!");
+#endif
}
return result;
}
diff --git a/nyx/nyx_gui/utils/btn.c b/nyx/nyx_gui/utils/btn.c
index 7ac35ef..b6e5db3 100644
--- a/nyx/nyx_gui/utils/btn.c
+++ b/nyx/nyx_gui/utils/btn.c
@@ -84,3 +84,31 @@ u8 btn_wait_timeout(u32 time_ms, u8 mask)
return res;
}
+
+u8 btn_wait_timeout_single(u32 time_ms, u8 mask)
+{
+ u8 single_button = mask & BTN_SINGLE;
+ mask &= ~BTN_SINGLE;
+
+ u32 timeout = get_tmr_ms() + time_ms;
+ u8 res = btn_read();
+
+ while (get_tmr_ms() < timeout)
+ {
+ if ((res & mask) == mask)
+ {
+ if (single_button && (res & ~mask)) // Undesired button detected.
+ res = btn_read();
+ else
+ return (res & mask);
+ }
+ else
+ res = btn_read();
+ };
+
+ // Timed out.
+ if (!single_button || !time_ms)
+ return (res & mask);
+ else
+ return 0; // Return no button press if single button requested.
+}
diff --git a/nyx/nyx_gui/utils/btn.h b/nyx/nyx_gui/utils/btn.h
index c0f0e08..1c42cc2 100644
--- a/nyx/nyx_gui/utils/btn.h
+++ b/nyx/nyx_gui/utils/btn.h
@@ -23,10 +23,12 @@
#define BTN_POWER (1 << 0)
#define BTN_VOL_DOWN (1 << 1)
#define BTN_VOL_UP (1 << 2)
+#define BTN_SINGLE (1 << 7)
u8 btn_read();
u8 btn_read_vol();
u8 btn_wait();
u8 btn_wait_timeout(u32 time_ms, u8 mask);
+u8 btn_wait_timeout_single(u32 time_ms, u8 mask);
#endif