From a8d529cf6a0b331a5eb91a73aa13924d6ae125d5 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Thu, 12 Sep 2019 23:08:38 +0300 Subject: [PATCH] Refactoring and comment adding --- bootloader/config/config.c | 4 +- bootloader/config/config.h | 1 - bootloader/gfx/di.c | 95 ++++++++------- bootloader/gfx/gfx.c | 4 +- bootloader/hos/hos.c | 33 +++--- bootloader/hos/pkg2.c | 16 +-- bootloader/hos/pkg2.h | 2 +- bootloader/libs/fatfs/ffunicode.c | 2 - bootloader/main.c | 3 +- bootloader/mem/mc.c | 2 +- bootloader/mem/minerva.c | 2 + bootloader/power/bq24193.c | 5 + bootloader/power/max17050.c | 5 + bootloader/rtc/max77620-rtc.c | 2 +- bootloader/rtc/max77620-rtc.h | 2 +- bootloader/soc/bpmp.c | 2 +- bootloader/soc/clock.c | 1 - bootloader/soc/clock.h | 2 +- bootloader/storage/emummc.c | 5 +- bootloader/storage/sdmmc.c | 150 +++++++++++++++--------- bootloader/storage/sdmmc.h | 2 + bootloader/storage/sdmmc_driver.c | 42 +++++-- nyx/nyx_gui/config/config.c | 4 +- nyx/nyx_gui/config/config.h | 1 - nyx/nyx_gui/frontend/gui.c | 1 + nyx/nyx_gui/frontend/gui_emummc_tools.c | 1 + nyx/nyx_gui/gfx/di.c | 91 +++++++------- nyx/nyx_gui/gfx/di.h | 2 +- nyx/nyx_gui/gfx/di.inl | 2 - nyx/nyx_gui/gfx/gfx.c | 4 +- nyx/nyx_gui/gfx/logos-gui.h | 29 +++-- nyx/nyx_gui/libs/lv_conf.h | 22 ++-- nyx/nyx_gui/mem/mc.c | 2 +- nyx/nyx_gui/mem/minerva.c | 2 + nyx/nyx_gui/nyx.c | 9 +- nyx/nyx_gui/power/bq24193.c | 5 + nyx/nyx_gui/power/max17050.c | 5 + nyx/nyx_gui/rtc/max77620-rtc.c | 2 +- nyx/nyx_gui/rtc/max77620-rtc.h | 2 +- nyx/nyx_gui/soc/bpmp.c | 2 +- nyx/nyx_gui/soc/clock.c | 1 - nyx/nyx_gui/soc/clock.h | 2 +- nyx/nyx_gui/soc/hw_init.c | 2 +- nyx/nyx_gui/storage/sdmmc.c | 150 +++++++++++++++--------- nyx/nyx_gui/storage/sdmmc.h | 2 + nyx/nyx_gui/storage/sdmmc_driver.c | 42 +++++-- nyx/nyx_gui/thermal/fan.c | 10 +- 47 files changed, 477 insertions(+), 300 deletions(-) diff --git a/bootloader/config/config.c b/bootloader/config/config.c index 1e2db7d..f9df696 100644 --- a/bootloader/config/config.c +++ b/bootloader/config/config.c @@ -23,6 +23,7 @@ #include "../gfx/tui.h" #include "../libs/fatfs/ff.h" #include "../soc/t210.h" +#include "../storage/sdmmc.h" #include "../utils/btn.h" #include "../utils/list.h" #include "../utils/util.h" @@ -47,8 +48,9 @@ void set_default_configuration() h_cfg.errors = 0; h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN; h_cfg.rcm_patched = true; - h_cfg.sd_timeoff = 0; h_cfg.emummc_force_disable = false; + + sd_power_cycle_time_start = 0xFFFFFFF; } int create_config_entry() diff --git a/bootloader/config/config.h b/bootloader/config/config.h index 14851a3..8cd34e1 100644 --- a/bootloader/config/config.h +++ b/bootloader/config/config.h @@ -37,7 +37,6 @@ typedef struct _hekate_config bool emummc_force_disable; bool rcm_patched; u32 sbar_time_keeping; - u32 sd_timeoff; u32 errors; } hekate_config; diff --git a/bootloader/gfx/di.c b/bootloader/gfx/di.c index ad0ec5c..1dcef3f 100644 --- a/bootloader/gfx/di.c +++ b/bootloader/gfx/di.c @@ -47,54 +47,61 @@ void display_init() max77620_regulator_set_volt_and_flags(REGULATOR_LDO0, 1200000, MAX77620_POWER_MODE_NORMAL); // Configure to 1.2V. i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO7, MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH | MAX77620_CNFG_GPIO_DRV_PUSHPULL); - // Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. - CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x1010000; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x1010000; - CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = 0x18000000; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = 0x18000000; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x20000; - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIP_CAL) = 0xA; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = 0x80000; - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 0xA; + // Enable Display Interface specific clocks. + CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x1010000; // Clear reset DSI, MIPI_CAL. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x1010000; // Set enable clock DSI, MIPI_CAL. - // DPD idle. + CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = 0x18000000; // Clear reset DISP1, HOST1X. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = 0x18000000; // Set enable clock DISP1, HOST1X. + + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x20000; // Set enable clock UART_FST_MIPI_CAL. + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = 10; // Set PLLP_OUT3 and div 6 (17MHz). + + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = 0x80000; // Set enable clock DSIA_LP. + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 10; // Set PLLP_OUT and div 6 (68MHz). + + // Disable deap power down. PMC(APBDEV_PMC_IO_DPD_REQ) = 0x40000000; PMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000; - // Config pins. + // Config LCD and Backlight pins. PINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE; PINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE; PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= ~PINMUX_TRISTATE; PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE; PINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE; - gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO); // Backlight +-5V. - gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE); // Backlight +-5V. + // Set Backlight +-5V pins mode and direction + gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO); + gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE); + + // Enable Backlight power. gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); // Backlight +5V enable. - usleep(10000); - gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); // Backlight -5V enable. - usleep(10000); - gpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO); // Backlight PWM, Enable, Reset. + // Configure Backlight pins (PWM, EN, RST). + gpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO); gpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE); - gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH); // Backlight Enable enable. + gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH); // Enable Backlight EN. - // Config display interface and display. + // Power up supply regulator for display interface. MIPI_CAL(MIPI_CAL_MIPI_BIAS_PAD_CFG2) = 0; + // Set DISP1 clock source and parrent clock. exec_cfg((u32 *)CLOCK_BASE, _display_config_1, 4); + + // Setup display communication interfaces. exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_2, 94); exec_cfg((u32 *)DSI_BASE, _display_config_3, 61); - usleep(10000); - gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH); // Backlight Reset enable. - + // Enable Backlight Reset. + gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH); usleep(60000); + // Setups DSI packet configuration and request display id. DSI(_DSIREG(DSI_BTA_TIMING)) = 0x50204; DSI(_DSIREG(DSI_WR_DATA)) = 0x337; // MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST; @@ -123,19 +130,22 @@ void display_init() usleep(20000); + // Configure PLLD for DISP1. exec_cfg((u32 *)CLOCK_BASE, _display_config_6, 3); + + // Finalize DSI configuration. exec_cfg((u32 *)DSI_BASE, _display_config_5, 21); DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = 4; exec_cfg((u32 *)DSI_BASE, _display_config_7, 10); - usleep(10000); + // Calibrate display communication pads. exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_8, 6); exec_cfg((u32 *)DSI_BASE, _display_config_9, 4); exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_10, 16); - usleep(10000); + // Enable video display controller. exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_11, 113); } @@ -143,11 +153,10 @@ void display_backlight_pwm_init() { clock_enable_pwm(); - PWM(PWM_CONTROLLER_PWM_CSR_0) = (1 << 31); // Enable PWM + PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN; // Enable PWM and set it to 25KHz PFM. - PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) >> 2) << 2 | 1; // PWM clock source. + PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & 0xFFFFFFFC) | 1; // PWM clock source. gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode. - } void display_backlight(bool enable) @@ -168,7 +177,7 @@ void display_backlight_brightness(u32 brightness, u32 step_delay) { for (u32 i = old_value; i < brightness + 1; i++) { - PWM(PWM_CONTROLLER_PWM_CSR_0) = (1 << 31) | (i << 16); // Enable PWM + PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); // Enable PWM and set it to 25KHz PFM. usleep(step_delay); } } @@ -176,7 +185,7 @@ void display_backlight_brightness(u32 brightness, u32 step_delay) { for (u32 i = old_value; i > brightness; i--) { - PWM(PWM_CONTROLLER_PWM_CSR_0) = (1 << 31) | (i << 16); // Enable PWM + PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); // Enable PWM and set it to 25KHz PFM. usleep(step_delay); } } @@ -192,13 +201,14 @@ void display_end() DSI(_DSIREG(DSI_WR_DATA)) = 0x2805; // MIPI_DCS_SET_DISPLAY_OFF DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX; - DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0; + DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0; // Disable host cmd packet. + // De-initialize video controller. exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_12, 17); exec_cfg((u32 *)DSI_BASE, _display_config_13, 16); - usleep(10000); + // De-initialize display panel. if (_display_ver == 0x10) exec_cfg((u32 *)DSI_BASE, _display_config_14, 22); @@ -207,31 +217,31 @@ void display_end() usleep(50000); + // Disable display and backlight pins. gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); //Backlight Reset disable. - usleep(10000); gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); //Backlight -5V disable. - usleep(10000); gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); //Backlight +5V disable. - usleep(10000); - // Disable clocks. - CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x1010000; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = 0x1010000; - CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = 0x18000000; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = 0x18000000; + // Disable Display Interface specific clocks. + CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x1010000; // Set reset clock DSI, MIPI_CAL. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = 0x1010000; // Clear enable clock DSI, MIPI_CAL. + CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = 0x18000000; // Set reset DISP1, HOST1X. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = 0x18000000; // Clear enable DISP1, HOST1X. + // Power down pads. DSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF); DSI(_DSIREG(DSI_POWER_CONTROL)) = 0; + // Switch to automatic function mode. gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM. PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_TRISTATE) | PINMUX_TRISTATE; - PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) >> 2) << 2 | 1; + PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & 0xFFFFFFFC)| 1; } void display_color_screen(u32 color) @@ -244,7 +254,6 @@ void display_color_screen(u32 color) DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0; DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color; DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ; - usleep(35000); display_backlight(true); @@ -254,10 +263,10 @@ u32 *display_init_framebuffer() { // Sanitize framebuffer area. memset((u32 *)FB_ADDRESS, 0, 0x3C0000); - // This configures the framebuffer @ 0xC0000000 with a resolution of 1280x720 (line stride 720). + // This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 1280x720 (line stride 720). exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, 32); - usleep(35000); return (u32 *)FB_ADDRESS; } + diff --git a/bootloader/gfx/gfx.c b/bootloader/gfx/gfx.c index a98512f..a5e9c4c 100644 --- a/bootloader/gfx/gfx.c +++ b/bootloader/gfx/gfx.c @@ -127,12 +127,12 @@ void gfx_init_ctxt(u32 *fb, u32 width, u32 height, u32 stride) void gfx_clear_grey(u8 color) { - memset(gfx_ctxt.fb, color, 0x3C0000); + memset(gfx_ctxt.fb, color, gfx_ctxt.width * gfx_ctxt.height * 4); } void gfx_clear_color(u32 color) { - for (u32 i = 0; i < gfx_ctxt.height * gfx_ctxt.stride; i++) + for (u32 i = 0; i < gfx_ctxt.width * gfx_ctxt.height; i++) gfx_ctxt.fb[i] = color; } diff --git a/bootloader/hos/hos.c b/bootloader/hos/hos.c index a960267..c119a79 100644 --- a/bootloader/hos/hos.c +++ b/bootloader/hos/hos.c @@ -105,6 +105,12 @@ static const u8 master_keyseed_620[0x10] = static const u8 console_keyseed_4xx_5xx[0x10] = { 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 }; +static void _hos_crit_error(const char *text) +{ + display_backlight_brightness(h_cfg.backlight, 1000); + gfx_con.mute = false; + gfx_printf("%k%s%k\n", 0xFFFF0000, text, 0xFFCCCCCC); +} static void _se_lock(bool lock_se) { @@ -218,7 +224,7 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt) // We rely on racing conditions, make sure we cover even the unluckiest cases. if (retries > 15) { - EHPRINTF("\nFailed to get TSEC keys. Please try again.\n"); + _hos_crit_error("\nFailed to get TSEC keys. Please try again."); return 0; } } @@ -339,7 +345,7 @@ static int _read_emmc_pkg1(launch_ctxt_t *ctxt) ctxt->pkg1_id = pkg1_identify(ctxt->pkg1); if (!ctxt->pkg1_id) { - EHPRINTF("Unknown pkg1 version."); + _hos_crit_error("Unknown pkg1 version."); goto out; } gfx_printf("Identified pkg1 and Keyblob %d\n\n", ctxt->pkg1_id->kb); @@ -368,7 +374,7 @@ static u8 *_read_emmc_pkg2(launch_ctxt_t *ctxt) // Parse eMMC GPT. LIST_INIT(gpt); nx_emmc_gpt_parse(&gpt, &storage); - DPRINTF("Parsed GPT\n"); +DPRINTF("Parsed GPT\n"); // Find package2 partition. emmc_part_t *pkg2_part = nx_emmc_part_find(&gpt, "BCPKG2-1-Normal-Main"); if (!pkg2_part) @@ -381,7 +387,7 @@ static u8 *_read_emmc_pkg2(launch_ctxt_t *ctxt) nx_emmc_part_read(&storage, pkg2_part, BCT_SIZE / NX_EMMC_BLOCKSIZE, 1, bctBuf); u32 *hdr = (u32 *)(bctBuf + 0x100); u32 pkg2_size = hdr[0] ^ hdr[2] ^ hdr[3]; - DPRINTF("pkg2 size on emmc is %08X\n", pkg2_size); +DPRINTF("pkg2 size on emmc is %08X\n", pkg2_size); // Read in Boot Config. memset(bctBuf, 0, BCT_SIZE); @@ -389,7 +395,7 @@ static u8 *_read_emmc_pkg2(launch_ctxt_t *ctxt) // Read in package2. u32 pkg2_size_aligned = ALIGN(pkg2_size, NX_EMMC_BLOCKSIZE); - DPRINTF("pkg2 size aligned is %08X\n", pkg2_size_aligned); +DPRINTF("pkg2 size aligned is %08X\n", pkg2_size_aligned); ctxt->pkg2 = malloc(pkg2_size_aligned); ctxt->pkg2_size = pkg2_size; nx_emmc_part_read(&storage, pkg2_part, BCT_SIZE / NX_EMMC_BLOCKSIZE, @@ -438,7 +444,7 @@ int hos_launch(ini_sec_t *cfg) // Try to parse config if present. if (ctxt.cfg && !parse_boot_config(&ctxt)) { - EHPRINTF("Wrong ini cfg or missing files!"); + _hos_crit_error("Wrong ini cfg or missing files!"); return 0; } @@ -447,7 +453,7 @@ int hos_launch(ini_sec_t *cfg) { if (ctxt.stock) { - EHPRINTF("Stock emuMMC is not supported yet!"); + _hos_crit_error("Stock emuMMC is not supported yet!"); return 0; } @@ -471,13 +477,13 @@ int hos_launch(ini_sec_t *cfg) if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.sept_run) { - gfx_printf("Failed to run sept\n"); + _hos_crit_error("Failed to run sept"); return 0; } if (!keygen(ctxt.keyblob, ctxt.pkg1_id->kb, &tsec_ctxt, &ctxt)) return 0; - DPRINTF("Generated keys\n"); +DPRINTF("Generated keys\n"); if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_600) h_cfg.se_keygen_done = 1; } @@ -495,7 +501,7 @@ int hos_launch(ini_sec_t *cfg) } else { - EHPRINTF("No mandatory secmon or warmboot provided!"); + _hos_crit_error("No mandatory secmon or warmboot provided!"); return 0; } } @@ -507,7 +513,7 @@ int hos_launch(ini_sec_t *cfg) { if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700) { - EHPRINTF("No warmboot provided!"); + _hos_crit_error("No warmboot provided!"); return 0; } // Else we patch it to allow downgrading. @@ -545,7 +551,7 @@ int hos_launch(ini_sec_t *cfg) pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(ctxt.pkg2); if (!pkg2_hdr) { - gfx_printf("Pkg2 decryption failed!\n"); + _hos_crit_error("Pkg2 decryption failed!"); return 0; } @@ -573,11 +579,10 @@ int hos_launch(ini_sec_t *cfg) ctxt.pkg2_kernel_id = pkg2_identify(kernel_hash); if (!ctxt.pkg2_kernel_id) { - EHPRINTF("Failed to identify kernel!"); + _hos_crit_error("Failed to identify kernel!"); return 0; } - // In case a kernel patch option is set; allows to disable SVC verification or/and enable debug mode. kernel_patch_t *kernel_patchset = ctxt.pkg2_kernel_id->kernel_patchset; if (kernel_patchset != NULL) diff --git a/bootloader/hos/pkg2.c b/bootloader/hos/pkg2.c index 0f33f06..dbc66d7 100644 --- a/bootloader/hos/pkg2.c +++ b/bootloader/hos/pkg2.c @@ -315,19 +315,19 @@ static const pkg2_kernel_id_t _pkg2_kernel_ids[] = enum kip_offset_section { - KIP_TEXT = 0, - KIP_RODATA = 1, - KIP_DATA = 2, - KIP_BSS = 3, + KIP_TEXT = 0, + KIP_RODATA = 1, + KIP_DATA = 2, + KIP_BSS = 3, KIP_UNKSEC1 = 4, KIP_UNKSEC2 = 5 }; -#define KIP_PATCH_SECTION_SHIFT (29) -#define KIP_PATCH_SECTION_MASK (7 << KIP_PATCH_SECTION_SHIFT) -#define KIP_PATCH_OFFSET_MASK (~KIP_PATCH_SECTION_MASK) +#define KIP_PATCH_SECTION_SHIFT (29) +#define KIP_PATCH_SECTION_MASK (7 << KIP_PATCH_SECTION_SHIFT) +#define KIP_PATCH_OFFSET_MASK (~KIP_PATCH_SECTION_MASK) #define GET_KIP_PATCH_SECTION(x) ((x >> KIP_PATCH_SECTION_SHIFT) & 7) -#define GET_KIP_PATCH_OFFSET(x) (x & KIP_PATCH_OFFSET_MASK) +#define GET_KIP_PATCH_OFFSET(x) (x & KIP_PATCH_OFFSET_MASK) #define KPS(x) ((u32)(x) << KIP_PATCH_SECTION_SHIFT) static kip1_patch_t _fs_emummc[] = diff --git a/bootloader/hos/pkg2.h b/bootloader/hos/pkg2.h index cf0bdc8..fbcca30 100644 --- a/bootloader/hos/pkg2.h +++ b/bootloader/hos/pkg2.h @@ -140,7 +140,7 @@ typedef struct _kip1_id_t } kip1_id_t; void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2); -int pkg2_has_kip(link_t *info, u64 tid); +int pkg2_has_kip(link_t *info, u64 tid); void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1); void pkg2_add_kip(link_t *info, pkg2_kip1_t *kip1); void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1); diff --git a/bootloader/libs/fatfs/ffunicode.c b/bootloader/libs/fatfs/ffunicode.c index bc23f80..9f03963 100644 --- a/bootloader/libs/fatfs/ffunicode.c +++ b/bootloader/libs/fatfs/ffunicode.c @@ -34,7 +34,6 @@ #define MERGE2(a, b) a ## b #define CVTBL(tbl, cp) MERGE2(tbl, cp) - /*------------------------------------------------------------------------*/ /* Code Conversion Tables */ /*------------------------------------------------------------------------*/ @@ -623,5 +622,4 @@ DWORD ff_wtoupper ( /* Returns up-converted code point */ return uni; } - #endif /* #if FF_USE_LFN */ diff --git a/bootloader/main.c b/bootloader/main.c index 2096c31..8bedb18 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -1263,7 +1263,8 @@ void ipl_main() // Save sdram lp0 config. if (!ianos_loader(false, "bootloader/sys/libsys_lp0.bso", DRAM_LIB, (void *)sdram_get_params_patched())) h_cfg.errors |= ERR_LIBSYS_LP0; - + + // Train DRAM and switch to max frequency. minerva_init(); minerva_change_freq(FREQ_1600); diff --git a/bootloader/mem/mc.c b/bootloader/mem/mc.c index c799573..dd508e2 100644 --- a/bootloader/mem/mc.c +++ b/bootloader/mem/mc.c @@ -127,7 +127,7 @@ void mc_disable_ahb_redirect() void mc_enable() { CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | 0x40000000; - // Enable MIPI CAL clock. + // Enable EMC clock. CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFDFFFFFF) | 0x2000000; // Enable MC clock. CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFFFFFFFE) | 1; diff --git a/bootloader/mem/minerva.c b/bootloader/mem/minerva.c index 4b3c3bc..d74bef3 100644 --- a/bootloader/mem/minerva.c +++ b/bootloader/mem/minerva.c @@ -64,6 +64,7 @@ void minerva_change_freq(minerva_freq_t freq) { if (!minerva_cfg) return; + mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg; if (minerva_cfg && (mtc_cfg->rate_from != freq)) { @@ -77,6 +78,7 @@ void minerva_periodic_training() { if (!minerva_cfg) return; + mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg; if (minerva_cfg && mtc_cfg->rate_from == FREQ_1600) { diff --git a/bootloader/power/bq24193.c b/bootloader/power/bq24193.c index 717c364..20fec3a 100644 --- a/bootloader/power/bq24193.c +++ b/bootloader/power/bq24193.c @@ -20,6 +20,9 @@ #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; @@ -160,3 +163,5 @@ 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 2a2c8f6..d34c340 100644 --- a/bootloader/power/max17050.c +++ b/bootloader/power/max17050.c @@ -43,6 +43,9 @@ #define MAX17050_VMAX_TOLERANCE 50 /* 50 mV */ +#pragma GCC push_options +#pragma GCC optimize ("Os") + int max17050_get_property(enum MAX17050_reg reg, int *value) { u16 data; @@ -264,3 +267,5 @@ int max17050_fix_configuration() return 0; } + +#pragma GCC pop_options \ No newline at end of file diff --git a/bootloader/rtc/max77620-rtc.c b/bootloader/rtc/max77620-rtc.c index 85895af..7e2d3af 100644 --- a/bootloader/rtc/max77620-rtc.c +++ b/bootloader/rtc/max77620-rtc.c @@ -52,7 +52,7 @@ void max77620_rtc_get_time(rtc_time_t *time) } // Get date. - time->date = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f; + time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f; time->month = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MONTH_REG) & 0xF) - 1; time->year = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_YEAR_REG) & 0x7F) + 2000; } diff --git a/bootloader/rtc/max77620-rtc.h b/bootloader/rtc/max77620-rtc.h index 756e67c..981ccfe 100644 --- a/bootloader/rtc/max77620-rtc.h +++ b/bootloader/rtc/max77620-rtc.h @@ -64,7 +64,7 @@ typedef struct _rtc_time_t { u8 sec; u8 min; u8 hour; - u8 date; + u8 day; u8 month; u16 year; } rtc_time_t; diff --git a/bootloader/soc/bpmp.c b/bootloader/soc/bpmp.c index a142b8e..3d6091d 100644 --- a/bootloader/soc/bpmp.c +++ b/bootloader/soc/bpmp.c @@ -149,7 +149,7 @@ void bpmp_mmu_disable() // Clean and invalidate cache. bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY); - // Enable cache. + // Disable cache. BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = 0; // HW bug. Invalidate cache again. diff --git a/bootloader/soc/clock.c b/bootloader/soc/clock.c index 7e824b5..73e5fb3 100644 --- a/bootloader/soc/clock.c +++ b/bootloader/soc/clock.c @@ -366,7 +366,6 @@ static void _clock_sdmmc_clear_enable(u32 id) static u32 _clock_sdmmc_table[8] = { 0 }; #define PLLP_OUT0 0x0 - static int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val) { u32 divisor = 0; diff --git a/bootloader/soc/clock.h b/bootloader/soc/clock.h index 754608f..db7a974 100644 --- a/bootloader/soc/clock.h +++ b/bootloader/soc/clock.h @@ -123,7 +123,7 @@ #define CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP 0x620 #define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 0x65C #define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664 -#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIP_CAL 0x66C +#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL 0x66C #define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694 #define CLK_RST_CONTROLLER_CLK_SOURCE_NVENC 0x6A0 #define CLK_RST_CONTROLLER_SE_SUPER_CLK_DIVIDER 0x704 diff --git a/bootloader/storage/emummc.c b/bootloader/storage/emummc.c index d7eb1e1..3ad60c9 100644 --- a/bootloader/storage/emummc.c +++ b/bootloader/storage/emummc.c @@ -116,8 +116,7 @@ int emummc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc) if (f_stat(emu_cfg.emummc_file_based_path, &fno)) { - gfx_printf("e1\n"); - gfx_printf(" %X\n ", emu_cfg.sector); + EPRINTF("Failed to open eMMC folder."); goto out; } f_chmod(emu_cfg.emummc_file_based_path, AM_ARC, AM_ARC); @@ -125,7 +124,7 @@ int emummc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc) strcat(emu_cfg.emummc_file_based_path, "/00"); if (f_stat(emu_cfg.emummc_file_based_path, &fno)) { - gfx_printf("e2\n"); + EPRINTF("Failed to open emuMMC rawnand."); goto out; } emu_cfg.file_based_part_size = fno.fsize >> 9; diff --git a/bootloader/storage/sdmmc.c b/bootloader/storage/sdmmc.c index db37944..8ec807c 100644 --- a/bootloader/storage/sdmmc.c +++ b/bootloader/storage/sdmmc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (C) 2018 CTCaer + * Copyright (C) 2018-2019 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -19,7 +19,6 @@ #include "sdmmc.h" #include "mmc.h" #include "sd.h" -#include "../config/config.h" #include "../gfx/gfx.h" #include "../mem/heap.h" #include "../utils/util.h" @@ -27,8 +26,6 @@ //#define DPRINTF(...) gfx_printf(__VA_ARGS__) #define DPRINTF(...) -extern hekate_config h_cfg; - static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size) { const u32 mask = (size < 32 ? 1 << size : 0) - 1; @@ -72,6 +69,7 @@ static int _sdmmc_storage_execute_cmd_type1_ex(sdmmc_storage_t *storage, u32 *re if (_sdmmc_storage_check_result(*resp)) if (expected_state == 0x10 || R1_CURRENT_STATE(*resp) == expected_state) return 1; + return 0; } @@ -85,6 +83,7 @@ static int _sdmmc_storage_go_idle_state(sdmmc_storage_t *storage) { sdmmc_cmd_t cmd; sdmmc_init_cmd(&cmd, MMC_GO_IDLE_STATE, 0, SDMMC_RSP_TYPE_0, 0); + return sdmmc_execute_cmd(storage->sdmmc, &cmd, 0, 0); } @@ -94,7 +93,9 @@ static int _sdmmc_storage_get_cid(sdmmc_storage_t *storage, void *buf) sdmmc_init_cmd(&cmd, MMC_ALL_SEND_CID, 0, SDMMC_RSP_TYPE_2, 0); if (!sdmmc_execute_cmd(storage->sdmmc, &cmd, 0, 0)) return 0; + sdmmc_get_rsp(storage->sdmmc, buf, 0x10, SDMMC_RSP_TYPE_2); + return 1; } @@ -109,7 +110,9 @@ static int _sdmmc_storage_get_csd(sdmmc_storage_t *storage, void *buf) sdmmc_init_cmd(&cmdbuf, MMC_SEND_CSD, storage->rca << 16, SDMMC_RSP_TYPE_2, 0); if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0)) return 0; + sdmmc_get_rsp(storage->sdmmc, buf, 0x10, SDMMC_RSP_TYPE_2); + return 1; } @@ -147,8 +150,10 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out u32 tmp = 0; sdmmc_stop_transmission(storage->sdmmc, &tmp); _sdmmc_storage_get_status(storage, &tmp, 0); + return 0; } + return 1; } @@ -156,7 +161,9 @@ int sdmmc_storage_end(sdmmc_storage_t *storage) { if (!_sdmmc_storage_go_idle_state(storage)) return 0; + sdmmc_end(storage->sdmmc); + return 1; } @@ -178,14 +185,16 @@ static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 nu msleep(100); } while (retries); + return 0; out:; - DPRINTF("readwrite: %08X\n", blkcnt); +DPRINTF("readwrite: %08X\n", blkcnt); sector += blkcnt; num_sectors -= blkcnt; bbuf += 512 * blkcnt; } + return 1; } @@ -236,14 +245,17 @@ static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power) u32 cond = 0; if (!_mmc_storage_get_op_cond_inner(storage, &cond, power)) break; + if (cond & MMC_CARD_BUSY) { if (cond & 0x40000000) storage->has_sector_access = 1; + return 1; } if (get_tmr_ms() > timeout) break; + usleep(1000); } @@ -373,6 +385,7 @@ static int _mmc_storage_switch_buswidth(sdmmc_storage_t *storage, u32 bus_width) if (_sdmmc_storage_check_status(storage)) { sdmmc_set_bus_width(storage->sdmmc, bus_width); + return 1; } @@ -383,14 +396,19 @@ static int _mmc_storage_enable_HS(sdmmc_storage_t *storage, int check) { if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS))) return 0; + if (check && !_sdmmc_storage_check_status(storage)) return 0; + if (!sdmmc_setup_clock(storage->sdmmc, 2)) return 0; - DPRINTF("[MMC] switched to HS\n"); + +DPRINTF("[MMC] switched to HS\n"); storage->csd.busspeed = 52; + if (check || _sdmmc_storage_check_status(storage)) return 1; + return 0; } @@ -398,12 +416,16 @@ static int _mmc_storage_enable_HS200(sdmmc_storage_t *storage) { if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200))) return 0; + if (!sdmmc_setup_clock(storage->sdmmc, 3)) return 0; + if (!sdmmc_config_tuning(storage->sdmmc, 3, MMC_SEND_TUNING_BLOCK_HS200)) return 0; - DPRINTF("[MMC] switched to HS200\n"); + +DPRINTF("[MMC] switched to HS200\n"); storage->csd.busspeed = 200; + return _sdmmc_storage_check_status(storage); } @@ -411,17 +433,24 @@ static int _mmc_storage_enable_HS400(sdmmc_storage_t *storage) { if (!_mmc_storage_enable_HS200(storage)) return 0; + sdmmc_get_venclkctl(storage->sdmmc); + if (!_mmc_storage_enable_HS(storage, 0)) return 0; + if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_DDR_BUS_WIDTH_8))) return 0; + if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400))) return 0; + if (!sdmmc_setup_clock(storage->sdmmc, 4)) return 0; - DPRINTF("[MMC] switched to HS400\n"); + +DPRINTF("[MMC] switched to HS400\n"); storage->csd.busspeed = 400; + return _sdmmc_storage_check_status(storage); } @@ -433,8 +462,7 @@ static int _mmc_storage_enable_highspeed(sdmmc_storage_t *storage, u32 card_type goto out; if (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 && - card_type & EXT_CSD_CARD_TYPE_HS400_1_8V && - type == 4) + card_type & EXT_CSD_CARD_TYPE_HS400_1_8V && type == 4) return _mmc_storage_enable_HS400(storage); if (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 || @@ -446,6 +474,7 @@ static int _mmc_storage_enable_highspeed(sdmmc_storage_t *storage, u32 card_type out:; if (card_type & EXT_CSD_CARD_TYPE_HS_52) return _mmc_storage_enable_HS(storage, 1); + return 1; } @@ -453,6 +482,7 @@ static int _mmc_storage_enable_bkops(sdmmc_storage_t *storage) { if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_SET_BITS, EXT_CSD_BKOPS_EN, EXT_CSD_BKOPS_LEVEL_2))) return 0; + return _sdmmc_storage_check_status(storage); } @@ -464,42 +494,42 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 if (!sdmmc_init(sdmmc, id, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_1, 0, 0)) return 0; - DPRINTF("[MMC] after init\n"); +DPRINTF("[MMC] after init\n"); usleep(1000 + (74000 + sdmmc->divisor - 1) / sdmmc->divisor); if (!_sdmmc_storage_go_idle_state(storage)) return 0; - DPRINTF("[MMC] went to idle state\n"); +DPRINTF("[MMC] went to idle state\n"); if (!_mmc_storage_get_op_cond(storage, SDMMC_POWER_1_8)) return 0; - DPRINTF("[MMC] got op cond\n"); +DPRINTF("[MMC] got op cond\n"); if (!_sdmmc_storage_get_cid(storage, storage->raw_cid)) return 0; - DPRINTF("[MMC] got cid\n"); +DPRINTF("[MMC] got cid\n"); if (!_mmc_storage_set_relative_addr(storage)) return 0; - DPRINTF("[MMC] set relative addr\n"); +DPRINTF("[MMC] set relative addr\n"); if (!_sdmmc_storage_get_csd(storage, storage->raw_csd)) return 0; - DPRINTF("[MMC] got csd\n"); +DPRINTF("[MMC] got csd\n"); _mmc_storage_parse_csd(storage); if (!sdmmc_setup_clock(storage->sdmmc, 1)) return 0; - DPRINTF("[MMC] after setup clock\n"); +DPRINTF("[MMC] after setup clock\n"); if (!_sdmmc_storage_select_card(storage)) return 0; - DPRINTF("[MMC] card selected\n"); +DPRINTF("[MMC] card selected\n"); if (!_sdmmc_storage_set_blocklen(storage, 512)) return 0; - DPRINTF("[MMC] set blocklen to 512\n"); +DPRINTF("[MMC] set blocklen to 512\n"); u32 *csd = (u32 *)storage->raw_csd; //Check system specification version, only version 4.0 and later support below features. @@ -511,7 +541,7 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 if (!_mmc_storage_switch_buswidth(storage, bus_width)) return 0; - DPRINTF("[MMC] switched buswidth\n"); +DPRINTF("[MMC] switched buswidth\n"); u8 *ext_csd = (u8 *)malloc(512); if (!_mmc_storage_get_ext_csd(storage, ext_csd)) @@ -520,7 +550,7 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 return 0; } free(ext_csd); - DPRINTF("[MMC] got ext_csd\n"); +DPRINTF("[MMC] got ext_csd\n"); _mmc_storage_parse_cid(storage); //This needs to be after csd and ext_csd //gfx_hexdump(0, ext_csd, 512); @@ -530,16 +560,16 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 if (storage->ext_csd.bkops & 0x1 && !(storage->ext_csd.bkops_en & EXT_CSD_BKOPS_LEVEL_2) && 0) { _mmc_storage_enable_bkops(storage); - DPRINTF("[MMC] BKOPS enabled\n"); +DPRINTF("[MMC] BKOPS enabled\n"); } else { - DPRINTF("[MMC] BKOPS disabled\n"); +DPRINTF("[MMC] BKOPS disabled\n"); } if (!_mmc_storage_enable_highspeed(storage, storage->ext_csd.card_type, type)) return 0; - DPRINTF("[MMC] succesfully switched to highspeed mode\n"); +DPRINTF("[MMC] succesfully switched to highspeed mode\n"); sdmmc_sd_clock_ctrl(storage->sdmmc, 1); @@ -550,8 +580,10 @@ int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition) { if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_PART_CONFIG, partition))) return 0; + if (!_sdmmc_storage_check_status(storage)) return 0; + storage->partition = partition; return 1; } @@ -565,6 +597,7 @@ static int _sd_storage_execute_app_cmd(sdmmc_storage_t *storage, u32 expected_st u32 tmp; if (!_sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, MMC_APP_CMD, storage->rca << 16, 0, expected_state, mask)) return 0; + return sdmmc_execute_cmd(storage->sdmmc, cmd, req, blkcnt_out); } @@ -572,6 +605,7 @@ static int _sd_storage_execute_app_cmd_type1(sdmmc_storage_t *storage, u32 *resp { if (!_sdmmc_storage_execute_cmd_type1(storage, MMC_APP_CMD, storage->rca << 16, 0, R1_STATE_TRAN)) return 0; + return _sdmmc_storage_execute_cmd_type1_ex(storage, resp, cmd, arg, check_busy, expected_state, 0); } @@ -603,6 +637,7 @@ static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int sdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0); if (!_sd_storage_execute_app_cmd(storage, 0x10, is_version_1 ? 0x400000 : 0, &cmdbuf, 0, 0)) return 0; + return sdmmc_get_rsp(storage->sdmmc, cond, 4, SDMMC_RSP_TYPE_3); } @@ -630,7 +665,7 @@ static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, i return 0; storage->is_low_voltage = 1; - DPRINTF("-> switched to low voltage\n"); +DPRINTF("-> switched to low voltage\n"); } } @@ -784,17 +819,17 @@ void _sd_storage_set_current_limit(sdmmc_storage_t *storage, u8 *buf) switch (pwr) { case SD_SET_CURRENT_LIMIT_800: - DPRINTF("[SD] Power limit raised to 800mA\n"); +DPRINTF("[SD] Power limit raised to 800mA\n"); break; case SD_SET_CURRENT_LIMIT_600: - DPRINTF("[SD] Power limit raised to 600mA\n"); +DPRINTF("[SD] Power limit raised to 600mA\n"); break; case SD_SET_CURRENT_LIMIT_400: - DPRINTF("[SD] Power limit raised to 800mA\n"); +DPRINTF("[SD] Power limit raised to 800mA\n"); break; default: case SD_SET_CURRENT_LIMIT_200: - DPRINTF("[SD] Power limit defaulted to 200mA\n"); +DPRINTF("[SD] Power limit defaulted to 200mA\n"); break; } } @@ -803,10 +838,12 @@ int _sd_storage_enable_highspeed(sdmmc_storage_t *storage, u32 hs_type, u8 *buf) { if (!_sd_storage_switch(storage, buf, SD_SWITCH_CHECK, 0, hs_type)) return 0; +DPRINTF("[SD] SD supports switch to (U)HS check\n"); u32 type_out = buf[16] & 0xF; if (type_out != hs_type) return 0; +DPRINTF("[SD] SD supports selected (U)HS mode\n"); if ((((u16)buf[0] << 8) | buf[1]) < 0x320) { @@ -841,7 +878,7 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 { type = 11; hs_type = UHS_SDR104_BUS_SPEED; - DPRINTF("[SD] Bus speed set to SDR104\n"); +DPRINTF("[SD] Bus speed set to SDR104\n"); storage->csd.busspeed = 104; break; } @@ -850,7 +887,7 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 { type = 10; hs_type = UHS_SDR50_BUS_SPEED; - DPRINTF("[SD] Bus speed set to SDR50\n"); +DPRINTF("[SD] Bus speed set to SDR50\n"); storage->csd.busspeed = 50; break; } @@ -859,7 +896,7 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 return 0; type = 8; hs_type = UHS_SDR12_BUS_SPEED; - DPRINTF("[SD] Bus speed set to SDR12\n"); +DPRINTF("[SD] Bus speed set to SDR12\n"); storage->csd.busspeed = 12; break; default: @@ -869,10 +906,13 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 if (!_sd_storage_enable_highspeed(storage, hs_type, buf)) return 0; +DPRINTF("[SD] SD card accepted UHS\n"); if (!sdmmc_setup_clock(storage->sdmmc, type)) return 0; +DPRINTF("[SD] setup clock\n"); if (!sdmmc_config_tuning(storage->sdmmc, type, MMC_SEND_TUNING_BLOCK)) return 0; +DPRINTF("[SD] config tuning\n"); return _sdmmc_storage_check_status(storage); } @@ -886,8 +926,10 @@ int _sd_storage_enable_highspeed_high_volt(sdmmc_storage_t *storage, u8 *buf) if (!_sd_storage_enable_highspeed(storage, 1, buf)) return 0; + if (!_sdmmc_storage_check_status(storage)) return 0; + return sdmmc_setup_clock(storage->sdmmc, 7); } @@ -950,7 +992,7 @@ static int _sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf) if (!(storage->csd.cmdclass & CCC_APP_SPEC)) { - DPRINTF("[SD] ssr: Card lacks mandatory SD Status function\n"); +DPRINTF("[SD] ssr: Card lacks mandatory SD Status function\n"); return 0; } @@ -1014,7 +1056,7 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage) void sdmmc_storage_init_wait_sd() { - u32 sd_poweroff_time = (u32)get_tmr_ms() - h_cfg.sd_timeoff; + u32 sd_poweroff_time = (u32)get_tmr_ms() - sd_power_cycle_time_start; if (sd_poweroff_time < 100) msleep(100 - sd_poweroff_time); } @@ -1031,35 +1073,35 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 if (!sdmmc_init(sdmmc, id, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, 5, 0)) return 0; - DPRINTF("[SD] after init\n"); +DPRINTF("[SD] after init\n"); usleep(1000 + (74000 + sdmmc->divisor - 1) / sdmmc->divisor); if (!_sdmmc_storage_go_idle_state(storage)) return 0; - DPRINTF("[SD] went to idle state\n"); +DPRINTF("[SD] went to idle state\n"); is_version_1 = _sd_storage_send_if_cond(storage); if (is_version_1 == 2) return 0; - DPRINTF("[SD] after send if cond\n"); +DPRINTF("[SD] after send if cond\n"); if (!_sd_storage_get_op_cond(storage, is_version_1, bus_width == SDMMC_BUS_WIDTH_4 && type == 11)) return 0; - DPRINTF("[SD] got op cond\n"); +DPRINTF("[SD] got op cond\n"); if (!_sdmmc_storage_get_cid(storage, storage->raw_cid)) return 0; - DPRINTF("[SD] got cid\n"); +DPRINTF("[SD] got cid\n"); _sd_storage_parse_cid(storage); if (!_sd_storage_get_rca(storage)) return 0; - DPRINTF("[SD] got rca (= %04X)\n", storage->rca); +DPRINTF("[SD] got rca (= %04X)\n", storage->rca); if (!_sdmmc_storage_get_csd(storage, storage->raw_csd)) return 0; - DPRINTF("[SD] got csd\n"); +DPRINTF("[SD] got csd\n"); //Parse CSD. _sd_storage_parse_csd(storage); @@ -1072,7 +1114,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 storage->sec_cnt = storage->csd.c_size << 10; break; default: - DPRINTF("[SD] Unknown CSD structure %d\n", storage->csd.structure); +DPRINTF("[SD] unknown CSD structure %d\n", storage->csd.structure); break; } @@ -1080,21 +1122,21 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 { if (!sdmmc_setup_clock(storage->sdmmc, 6)) return 0; - DPRINTF("[SD] after setup clock\n"); +DPRINTF("[SD] after setup clock\n"); } if (!_sdmmc_storage_select_card(storage)) return 0; - DPRINTF("[SD] card selected\n"); +DPRINTF("[SD] card selected\n"); if (!_sdmmc_storage_set_blocklen(storage, 512)) return 0; - DPRINTF("[SD] set blocklen to 512\n"); +DPRINTF("[SD] set blocklen to 512\n"); u32 tmp = 0; if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_CLR_CARD_DETECT, 0, 0, R1_STATE_TRAN)) return 0; - DPRINTF("[SD] cleared card detect\n"); +DPRINTF("[SD] cleared card detect\n"); u8 *buf = (u8 *)malloc(512); if (!_sd_storage_get_scr(storage, buf)) @@ -1104,7 +1146,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 } //gfx_hexdump(0, storage->raw_scr, 8); - DPRINTF("[SD] got scr\n"); +DPRINTF("[SD] got scr\n"); // Check if card supports a wider bus and if it's not SD Version 1.X if (bus_width == SDMMC_BUS_WIDTH_4 && (storage->scr.bus_widths & 4) && (storage->scr.sda_vsn & 0xF)) @@ -1115,11 +1157,11 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 return 0; } sdmmc_set_bus_width(storage->sdmmc, SDMMC_BUS_WIDTH_4); - DPRINTF("[SD] switched to wide bus width\n"); +DPRINTF("[SD] switched to wide bus width\n"); } else { - DPRINTF("[SD] SD does not support wide bus width\n"); +DPRINTF("[SD] SD does not support wide bus width\n"); } if (storage->is_low_voltage) @@ -1129,7 +1171,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 free(buf); return 0; } - DPRINTF("[SD] enabled highspeed (low voltage)\n"); +DPRINTF("[SD] enabled UHS\n"); } else if (type != 6 && (storage->scr.sda_vsn & 0xF) != 0) { @@ -1138,7 +1180,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 free(buf); return 0; } - DPRINTF("[SD] enabled highspeed (high voltage)\n"); +DPRINTF("[SD] enabled HS\n"); storage->csd.busspeed = 25; } @@ -1147,7 +1189,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 // Parse additional card info from sd status. if (_sd_storage_get_ssr(storage, buf)) { - DPRINTF("[SD] got sd status\n"); +DPRINTF("[SD] got sd status\n"); } free(buf); @@ -1192,13 +1234,13 @@ int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc) if (!sdmmc_init(sdmmc, SDMMC_2, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_8, 14, 0)) return 0; - DPRINTF("[gc] after init\n"); +DPRINTF("[gc] after init\n"); usleep(1000 + (10000 + sdmmc->divisor - 1) / sdmmc->divisor); if (!sdmmc_config_tuning(storage->sdmmc, 14, MMC_SEND_TUNING_BLOCK_HS200)) return 0; - DPRINTF("[gc] after tuning\n"); +DPRINTF("[gc] after tuning\n"); sdmmc_sd_clock_ctrl(sdmmc, 1); diff --git a/bootloader/storage/sdmmc.h b/bootloader/storage/sdmmc.h index 2427324..fdc2bbb 100644 --- a/bootloader/storage/sdmmc.h +++ b/bootloader/storage/sdmmc.h @@ -21,6 +21,8 @@ #include "../utils/types.h" #include "sdmmc_driver.h" +u32 sd_power_cycle_time_start; + typedef struct _mmc_cid { u32 manfid; diff --git a/bootloader/storage/sdmmc_driver.c b/bootloader/storage/sdmmc_driver.c index bf990e9..0c0c2ff 100644 --- a/bootloader/storage/sdmmc_driver.c +++ b/bootloader/storage/sdmmc_driver.c @@ -19,7 +19,6 @@ #include "mmc.h" #include "sdmmc.h" -#include "../config/config.h" #include "../gfx/gfx.h" #include "../power/max7762x.h" #include "../soc/bpmp.h" @@ -33,8 +32,6 @@ //#define DPRINTF(...) gfx_printf(__VA_ARGS__) #define DPRINTF(...) -extern hekate_config h_cfg; - /*! SCMMC controller base addresses. */ static const u32 _sdmmc_bases[4] = { 0x700B0000, @@ -125,6 +122,7 @@ static int _sdmmc_config_ven_ceata_clk(sdmmc_t *sdmmc, u32 id) { if (!sdmmc->venclkctl_set) return 0; + tap_val = sdmmc->venclkctl_tap; } else @@ -235,7 +233,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; break; case 4: - // Non standard + // Non standard. sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | HS400_BUS_SPEED; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; break; @@ -513,13 +511,17 @@ static int _sdmmc_config_tuning_once(sdmmc_t *sdmmc, u32 cmd) return 0; _sdmmc_setup_read_small_block(sdmmc); + sdmmc->regs->norintstsen |= TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY; sdmmc->regs->norintsts = sdmmc->regs->norintsts; sdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; + _sdmmc_parse_cmd_48(sdmmc, cmd); _sdmmc_get_clkcon(sdmmc); usleep(1); + _sdmmc_reset(sdmmc); + sdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; _sdmmc_get_clkcon(sdmmc); @@ -535,10 +537,13 @@ static int _sdmmc_config_tuning_once(sdmmc_t *sdmmc, u32 cmd) return 1; } } + _sdmmc_reset(sdmmc); + sdmmc->regs->norintstsen &= 0xFFDF; _sdmmc_get_clkcon(sdmmc); usleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor); + return 0; } @@ -565,8 +570,8 @@ int sdmmc_config_tuning(sdmmc_t *sdmmc, u32 type, u32 cmd) return 0; } - sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag; - sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | 0x40; + sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag; // Tries. + sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | 0x40; // Multiplier. sdmmc->regs->ventunctl0 |= 0x20000; sdmmc->regs->hostctl2 |= SDHCI_CTRL_EXEC_TUNING; @@ -579,6 +584,7 @@ int sdmmc_config_tuning(sdmmc_t *sdmmc, u32 type, u32 cmd) if (sdmmc->regs->hostctl2 & SDHCI_CTRL_TUNED_CLK) return 1; + return 0; } @@ -748,11 +754,14 @@ static int _sdmmc_stop_transmission_inner(sdmmc_t *sdmmc, u32 *rsp) return 0; _sdmmc_enable_interrupts(sdmmc); + cmd.cmd = MMC_STOP_TRANSMISSION; cmd.arg = 0; cmd.rsp_type = SDMMC_RSP_TYPE_1; cmd.check_busy = 1; + _sdmmc_parse_cmdbuf(sdmmc, &cmd, false); + int res = _sdmmc_wait_request(sdmmc); _sdmmc_mask_interrupts(sdmmc); @@ -760,6 +769,7 @@ static int _sdmmc_stop_transmission_inner(sdmmc_t *sdmmc, u32 *rsp) return 0; _sdmmc_cache_rsp(sdmmc, rsp, 4, SDMMC_RSP_TYPE_1); + return _sdmmc_wait_prnsts_type1(sdmmc); } @@ -779,6 +789,7 @@ int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp) int res = _sdmmc_stop_transmission_inner(sdmmc, rsp); usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor); + if (should_disable_sd_clock) sdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; @@ -838,7 +849,7 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc) while (1) { u16 intr = 0; - res = _sdmmc_check_mask_interrupt(sdmmc, &intr, + res = _sdmmc_check_mask_interrupt(sdmmc, &intr, TEGRA_MMC_NORINTSTS_XFER_COMPLETE | TEGRA_MMC_NORINTSTS_DMA_INTERRUPT); if (res < 0) break; @@ -911,6 +922,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_ { if (blkcnt_out) *blkcnt_out = blkcnt; + if (req->is_auto_cmd12) sdmmc->rsp3 = sdmmc->regs->rspreg3; } @@ -930,6 +942,8 @@ static int _sdmmc_config_sdmmc1() gpio_config(GPIO_PORT_Z, GPIO_PIN_1, GPIO_MODE_GPIO); gpio_output_enable(GPIO_PORT_Z, GPIO_PIN_1, GPIO_OUTPUT_DISABLE); usleep(100); + + // Check if SD card is inserted. if(!!gpio_read(GPIO_PORT_Z, GPIO_PIN_1)) return 0; @@ -943,7 +957,7 @@ static int _sdmmc_config_sdmmc1() */ // Configure SDMMC1 pinmux. - APB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1; + APB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1; // Enable deep loopback for SDMMC1 CLK pad. PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED; PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP; PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP; @@ -1014,18 +1028,23 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int n sdmmc->regs->sdmemcmppadctl = (sdmmc->regs->sdmemcmppadctl & 0xF) | 7; if (!_sdmmc_autocal_config_offset(sdmmc, power)) return 0; + _sdmmc_autocal_execute(sdmmc, power); + if (_sdmmc_enable_internal_clock(sdmmc)) { sdmmc_set_bus_width(sdmmc, bus_width); _sdmmc_set_voltage(sdmmc, power); + if (sdmmc_setup_clock(sdmmc, type)) { sdmmc_sd_clock_ctrl(sdmmc, no_sd); _sdmmc_sd_clock_enable(sdmmc); _sdmmc_get_clkcon(sdmmc); + return 1; } + return 0; } return 0; @@ -1044,8 +1063,8 @@ void sdmmc_end(sdmmc_t *sdmmc) { gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE); max77620_regulator_enable(REGULATOR_LDO2, 0); - h_cfg.sd_timeoff = get_tmr_ms(); // Some sandisc U1 cards need 100ms for a power cycle. - msleep(1); // To power cycle, min 1ms without power is needed. + sd_power_cycle_time_start = get_tmr_ms(); // Some sandisc U1 cards need 100ms for a power cycle. + usleep(1000); // To power cycle, min 1ms without power is needed. } _sdmmc_get_clkcon(sdmmc); @@ -1082,6 +1101,7 @@ int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *b int res = _sdmmc_execute_cmd_inner(sdmmc, cmd, req, blkcnt_out); usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor); + if (should_disable_sd_clock) sdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; @@ -1119,7 +1139,7 @@ int sdmmc_enable_low_voltage(sdmmc_t *sdmmc) { sdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; _sdmmc_get_clkcon(sdmmc); - msleep(1); + usleep(1000); if ((sdmmc->regs->prnsts & 0xF00000) == 0xF00000) return 1; } diff --git a/nyx/nyx_gui/config/config.c b/nyx/nyx_gui/config/config.c index 152295d..177f374 100644 --- a/nyx/nyx_gui/config/config.c +++ b/nyx/nyx_gui/config/config.c @@ -23,6 +23,7 @@ #include "../libs/fatfs/ff.h" #include "../soc/fuse.h" #include "../soc/t210.h" +#include "../storage/sdmmc.h" #include "../utils/btn.h" #include "../utils/list.h" #include "../utils/util.h" @@ -50,8 +51,9 @@ void set_default_configuration() h_cfg.errors = 0; h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN; h_cfg.rcm_patched = fuse_check_patched_rcm(); - h_cfg.sd_timeoff = 0; h_cfg.emummc_force_disable = false; + + sd_power_cycle_time_start = 0xFFFFFFF; } int create_config_entry() diff --git a/nyx/nyx_gui/config/config.h b/nyx/nyx_gui/config/config.h index f588eeb..9e29de1 100644 --- a/nyx/nyx_gui/config/config.h +++ b/nyx/nyx_gui/config/config.h @@ -37,7 +37,6 @@ typedef struct _hekate_config bool emummc_force_disable; bool rcm_patched; u32 sbar_time_keeping; - u32 sd_timeoff; u32 errors; } hekate_config; diff --git a/nyx/nyx_gui/frontend/gui.c b/nyx/nyx_gui/frontend/gui.c index d30c92f..2d74a81 100644 --- a/nyx/nyx_gui/frontend/gui.c +++ b/nyx/nyx_gui/frontend/gui.c @@ -1181,6 +1181,7 @@ static lv_res_t _create_window_home_launch(lv_obj_t *btn) } else no_boot_entries = true; + sd_unmount(false); free(tmp_path); diff --git a/nyx/nyx_gui/frontend/gui_emummc_tools.c b/nyx/nyx_gui/frontend/gui_emummc_tools.c index 599c0cb..766c6a2 100644 --- a/nyx/nyx_gui/frontend/gui_emummc_tools.c +++ b/nyx/nyx_gui/frontend/gui_emummc_tools.c @@ -20,6 +20,7 @@ #include "fe_emummc_tools.h" #include "../config/ini.h" #include "../libs/fatfs/ff.h" +#include "../mem/heap.h" #include "../storage/sdmmc.h" #include "../utils/dirlist.h" #include "../utils/list.h" diff --git a/nyx/nyx_gui/gfx/di.c b/nyx/nyx_gui/gfx/di.c index 28ee3a5..75d24ae 100644 --- a/nyx/nyx_gui/gfx/di.c +++ b/nyx/nyx_gui/gfx/di.c @@ -51,54 +51,61 @@ void display_init() max77620_regulator_set_volt_and_flags(REGULATOR_LDO0, 1200000, MAX77620_POWER_MODE_NORMAL); // Configure to 1.2V. i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO7, MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH | MAX77620_CNFG_GPIO_DRV_PUSHPULL); - // Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. - CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x1010000; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x1010000; - CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = 0x18000000; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = 0x18000000; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x20000; - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIP_CAL) = 0xA; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = 0x80000; - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 0xA; + // Enable Display Interface specific clocks. + CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x1010000; // Clear reset DSI, MIPI_CAL. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x1010000; // Set enable clock DSI, MIPI_CAL. - // DPD idle. + CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = 0x18000000; // Clear reset DISP1, HOST1X. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = 0x18000000; // Set enable clock DISP1, HOST1X. + + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x20000; // Set enable clock UART_FST_MIPI_CAL. + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = 10; // Set PLLP_OUT3 and div 6 (17MHz). + + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = 0x80000; // Set enable clock DSIA_LP. + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 10; // Set PLLP_OUT and div 6 (68MHz). + + // Disable deap power down. PMC(APBDEV_PMC_IO_DPD_REQ) = 0x40000000; PMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000; - // Config pins. + // Config LCD and Backlight pins. PINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE; PINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE; PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= ~PINMUX_TRISTATE; PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE; PINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE; - gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO); // Backlight +-5V. - gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE); // Backlight +-5V. + // Set Backlight +-5V pins mode and direction + gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO); + gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE); + + // Enable Backlight power. gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); // Backlight +5V enable. - usleep(10000); - gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); // Backlight -5V enable. - usleep(10000); - gpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO); // Backlight PWM, Enable, Reset. + // Configure Backlight pins (PWM, EN, RST). + gpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO); gpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE); - gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH); // Backlight Enable enable. + gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH); // Enable Backlight EN. - // Config display interface and display. + // Power up supply regulator for display interface. MIPI_CAL(MIPI_CAL_MIPI_BIAS_PAD_CFG2) = 0; + // Set DISP1 clock source and parrent clock. exec_cfg((u32 *)CLOCK_BASE, _display_config_1, 4); + + // Setup display communication interfaces. exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_2, 94); exec_cfg((u32 *)DSI_BASE, _display_config_3, 61); - usleep(10000); - gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH); // Backlight Reset enable. - + // Enable Backlight Reset. + gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH); usleep(60000); + // Setups DSI packet configuration and request display id. DSI(_DSIREG(DSI_BTA_TIMING)) = 0x50204; DSI(_DSIREG(DSI_WR_DATA)) = 0x337; // MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST; @@ -127,19 +134,22 @@ void display_init() usleep(20000); + // Configure PLLD for DISP1. exec_cfg((u32 *)CLOCK_BASE, _display_config_6, 3); + + // Finalize DSI configuration. exec_cfg((u32 *)DSI_BASE, _display_config_5, 21); DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = 4; exec_cfg((u32 *)DSI_BASE, _display_config_7, 10); - usleep(10000); + // Calibrate display communication pads. exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_8, 6); exec_cfg((u32 *)DSI_BASE, _display_config_9, 4); exec_cfg((u32 *)MIPI_CAL_BASE, _display_config_10, 16); - usleep(10000); + // Enable video display controller. exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_11, 113); } @@ -147,11 +157,10 @@ void display_backlight_pwm_init() { clock_enable_pwm(); - PWM(PWM_CONTROLLER_PWM_CSR_0) = (1 << 31); // Enable PWM + PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN; // Enable PWM and set it to 25KHz PFM. - PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) >> 2) << 2 | 1; // PWM clock source. + PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & 0xFFFFFFFC) | 1; // PWM clock source. gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode. - } void display_backlight(bool enable) @@ -172,7 +181,7 @@ void display_backlight_brightness(u32 brightness, u32 step_delay) { for (u32 i = old_value; i < brightness + 1; i++) { - PWM(PWM_CONTROLLER_PWM_CSR_0) = (1 << 31) | (i << 16); // Enable PWM + PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); // Enable PWM and set it to 25KHz PFM. usleep(step_delay); } } @@ -180,7 +189,7 @@ void display_backlight_brightness(u32 brightness, u32 step_delay) { for (u32 i = old_value; i > brightness; i--) { - PWM(PWM_CONTROLLER_PWM_CSR_0) = (1 << 31) | (i << 16); // Enable PWM + PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); // Enable PWM and set it to 25KHz PFM. usleep(step_delay); } } @@ -196,13 +205,14 @@ void display_end() DSI(_DSIREG(DSI_WR_DATA)) = 0x2805; // MIPI_DCS_SET_DISPLAY_OFF DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX; - DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0; + DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0; // Disable host cmd packet. + // De-initialize video controller. exec_cfg((u32 *)DISPLAY_A_BASE, _display_config_12, 17); exec_cfg((u32 *)DSI_BASE, _display_config_13, 16); - usleep(10000); + // De-initialize display panel. if (_display_ver == 0x10) exec_cfg((u32 *)DSI_BASE, _display_config_14, 22); @@ -211,31 +221,31 @@ void display_end() usleep(50000); + // Disable display and backlight pins. gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); //Backlight Reset disable. - usleep(10000); gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); //Backlight -5V disable. - usleep(10000); gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); //Backlight +5V disable. - usleep(10000); - // Disable clocks. - CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x1010000; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = 0x1010000; - CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = 0x18000000; - CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = 0x18000000; + // Disable Display Interface specific clocks. + CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x1010000; // Set reset clock DSI, MIPI_CAL. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = 0x1010000; // Clear enable clock DSI, MIPI_CAL. + CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = 0x18000000; // Set reset DISP1, HOST1X. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = 0x18000000; // Clear enable DISP1, HOST1X. + // Power down pads. DSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF); DSI(_DSIREG(DSI_POWER_CONTROL)) = 0; + // Switch to automatic function mode. gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM. PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_TRISTATE) | PINMUX_TRISTATE; - PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) >> 2) << 2 | 1; + PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & 0xFFFFFFFC)| 1; } void display_color_screen(u32 color) @@ -248,7 +258,6 @@ void display_color_screen(u32 color) DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0; DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color; DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ; - usleep(35000); display_backlight(true); diff --git a/nyx/nyx_gui/gfx/di.h b/nyx/nyx_gui/gfx/di.h index 04a4e1d..9be7954 100644 --- a/nyx/nyx_gui/gfx/di.h +++ b/nyx/nyx_gui/gfx/di.h @@ -235,7 +235,7 @@ #define UV_LINE_STRIDE(x) (((x) & 0xffff) << 16) #define DC_WIN_DV_CONTROL 0x70E -// The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER). +/*! The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER). */ #define DC_WINBUF_START_ADDR 0x800 #define DC_WINBUF_ADDR_H_OFFSET 0x806 #define DC_WINBUF_ADDR_V_OFFSET 0x808 diff --git a/nyx/nyx_gui/gfx/di.inl b/nyx/nyx_gui/gfx/di.inl index a19b98a..2f53c11 100644 --- a/nyx/nyx_gui/gfx/di.inl +++ b/nyx/nyx_gui/gfx/di.inl @@ -548,7 +548,6 @@ static const cfg_op_t cfg_display_framebuffer[32] = { {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements. {DC_WIN_BUFFER_CONTROL, 0}, {DC_WINBUF_SURFACE_KIND, 0}, //Regular surface. - //{DC_WINBUF_SURFACE_KIND, BLOCK_HEIGHT(4) | BLOCK}, //Regular surface. {DC_WINBUF_START_ADDR, FB_ADDRESS}, //Framebuffer address. {DC_WINBUF_ADDR_H_OFFSET, 0}, //Linear: 0x383FFC, Block: 0x3813FC {DC_WINBUF_ADDR_V_OFFSET, 1279}, //Linear: 1279, Block: 0 @@ -559,7 +558,6 @@ static const cfg_op_t cfg_display_framebuffer[32] = { {DC_WIN_WIN_OPTIONS, 0}, {DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE {DC_WIN_WIN_OPTIONS, WIN_ENABLE | V_DIRECTION}, //Enable window AD. - //{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}, //DISPLAY_CTRL_MODE: continuous display. {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, //General update; window A update. {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} //General activation request; window A activation request. diff --git a/nyx/nyx_gui/gfx/gfx.c b/nyx/nyx_gui/gfx/gfx.c index c7aff0a..4eabaa0 100644 --- a/nyx/nyx_gui/gfx/gfx.c +++ b/nyx/nyx_gui/gfx/gfx.c @@ -131,12 +131,12 @@ void gfx_init_ctxt(u32 *fb, u32 width, u32 height, u32 stride) void gfx_clear_grey(u8 color) { - memset(gfx_ctxt.fb, color, 0x3C0000); + memset(gfx_ctxt.fb, color, gfx_ctxt.width * gfx_ctxt.height * 4); } void gfx_clear_color(u32 color) { - for (u32 i = 0; i < gfx_ctxt.height * gfx_ctxt.stride; i++) + for (u32 i = 0; i < gfx_ctxt.width * gfx_ctxt.height; i++) gfx_ctxt.fb[i] = color; } diff --git a/nyx/nyx_gui/gfx/logos-gui.h b/nyx/nyx_gui/gfx/logos-gui.h index 502e5fc..9ab2cac 100644 --- a/nyx/nyx_gui/gfx/logos-gui.h +++ b/nyx/nyx_gui/gfx/logos-gui.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef _LOGOS_GUI_H_ +#define _LOGOS_GUI_H_ #include "../libs/lv_conf.h" #include "../libs/lvgl/lv_draw/lv_draw_img.h" @@ -9,21 +10,23 @@ #ifdef HEKATE_LOGO lv_img_dsc_t hekate_logo = { - .header.always_zero = 0, - .header.w = 193, - .header.h = 76, - .data_size = 14668 * LV_IMG_PX_SIZE_ALPHA_BYTE, - .header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA, - .data = (const uint8_t *)(NYX_RES_ADDR + 0x1D900), + .header.always_zero = 0, + .header.w = 193, + .header.h = 76, + .data_size = 14668 * LV_IMG_PX_SIZE_ALPHA_BYTE, + .header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA, + .data = (const uint8_t *)(NYX_RES_ADDR + 0x1D900), }; lv_img_dsc_t ctcaer_logo = { - .header.always_zero = 0, - .header.w = 147, - .header.h = 76, - .data_size = 11172 * LV_IMG_PX_SIZE_ALPHA_BYTE, - .header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA, - .data = (const uint8_t *)(NYX_RES_ADDR + 0x2BF00), + .header.always_zero = 0, + .header.w = 147, + .header.h = 76, + .data_size = 11172 * LV_IMG_PX_SIZE_ALPHA_BYTE, + .header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA, + .data = (const uint8_t *)(NYX_RES_ADDR + 0x2BF00), }; +#endif + #endif \ No newline at end of file diff --git a/nyx/nyx_gui/libs/lv_conf.h b/nyx/nyx_gui/libs/lv_conf.h index d53f09f..fe037cd 100644 --- a/nyx/nyx_gui/libs/lv_conf.h +++ b/nyx/nyx_gui/libs/lv_conf.h @@ -24,12 +24,12 @@ /* Memory size which will be used by the library * to store the graphical objects and other data */ -#define LV_MEM_CUSTOM 0 /*1: use custom malloc/free, 0: use the built-in lv_mem_alloc/lv_mem_free*/ +#define LV_MEM_CUSTOM 0 /*1: use custom malloc/free, 0: use the built-in lv_mem_alloc/lv_mem_free*/ #if LV_MEM_CUSTOM == 0 # define LV_MEM_SIZE (0x38000U * 1024U) /*Size memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ -# define LV_MEM_ATTR /*Complier prefix for big array declaration*/ -# define LV_MEM_ADR 0xF1000000 /*Set an address for memory pool instead of allocation it as an array. Can be in external SRAM too.*/ -# define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/ +# define LV_MEM_ATTR /*Complier prefix for big array declaration*/ +# define LV_MEM_ADR 0xF1000000 /*Set an address for memory pool instead of allocation it as an array. Can be in external SRAM too.*/ +# define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/ #else /*LV_MEM_CUSTOM*/ # define LV_MEM_CUSTOM_INCLUDE "../../../mem/heap.h" /*Header for the dynamic memory function*/ # define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/ @@ -119,10 +119,10 @@ #define LV_INDEV_LONG_PRESS_REP_TIME 1000 //Fix keyb /*Repeated trigger period in long press [ms] */ /*Color settings*/ -#define LV_COLOR_DEPTH 32 /*Color depth: 1/8/16/32*/ -#define LV_COLOR_16_SWAP 0 /*Swap the 2 bytes of RGB565 color. Useful if the display has a 8 bit interface (e.g. SPI)*/ -#define LV_COLOR_SCREEN_TRANSP 0 /*1: Enable screen transparency. Useful for OSD or other overlapping GUIs. Requires ARGB8888 colors*/ -#define LV_COLOR_TRANSP LV_COLOR_LIME /*Images pixels with this color will not be drawn (with chroma keying)*/ +#define LV_COLOR_DEPTH 32 /*Color depth: 1/8/16/32*/ +#define LV_COLOR_16_SWAP 0 /*Swap the 2 bytes of RGB565 color. Useful if the display has a 8 bit interface (e.g. SPI)*/ +#define LV_COLOR_SCREEN_TRANSP 0 /*1: Enable screen transparency. Useful for OSD or other overlapping GUIs. Requires ARGB8888 colors*/ +#define LV_COLOR_TRANSP LV_COLOR_LIME /*Images pixels with this color will not be drawn (with chroma keying)*/ /*Text settings*/ #define LV_TXT_UTF8 0 /*Enable UTF-8 coded Unicode character usage */ @@ -184,10 +184,10 @@ * which will determine the bit-per-pixel. Higher value means smoother fonts */ #define LV_FONT_QUALITY 8 -#define USE_UBUNTU_MONO LV_FONT_QUALITY +#define USE_UBUNTU_MONO LV_FONT_QUALITY -#define USE_INTERUI_20 LV_FONT_QUALITY -#define USE_INTERUI_30 LV_FONT_QUALITY +#define USE_INTERUI_20 LV_FONT_QUALITY +#define USE_INTERUI_30 LV_FONT_QUALITY #define USE_HEKATE_SYMBOL_20 USE_INTERUI_20 #define USE_HEKATE_SYMBOL_30 USE_INTERUI_30 diff --git a/nyx/nyx_gui/mem/mc.c b/nyx/nyx_gui/mem/mc.c index c799573..dd508e2 100644 --- a/nyx/nyx_gui/mem/mc.c +++ b/nyx/nyx_gui/mem/mc.c @@ -127,7 +127,7 @@ void mc_disable_ahb_redirect() void mc_enable() { CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF) | 0x40000000; - // Enable MIPI CAL clock. + // Enable EMC clock. CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFDFFFFFF) | 0x2000000; // Enable MC clock. CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = (CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFFFFFFFE) | 1; diff --git a/nyx/nyx_gui/mem/minerva.c b/nyx/nyx_gui/mem/minerva.c index a80bd0b..0f3bed8 100644 --- a/nyx/nyx_gui/mem/minerva.c +++ b/nyx/nyx_gui/mem/minerva.c @@ -77,6 +77,7 @@ void minerva_change_freq(minerva_freq_t freq) { if (!minerva_cfg) return; + mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg; if (minerva_cfg && (mtc_cfg->rate_from != freq)) { @@ -90,6 +91,7 @@ void minerva_periodic_training() { if (!minerva_cfg) return; + mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg; if (minerva_cfg && mtc_cfg->rate_from == FREQ_1600) { diff --git a/nyx/nyx_gui/nyx.c b/nyx/nyx_gui/nyx.c index b4baccd..0edc321 100644 --- a/nyx/nyx_gui/nyx.c +++ b/nyx/nyx_gui/nyx.c @@ -59,6 +59,7 @@ u8 *Kc_MENU_LOGO; #endif //MENU_LOGO_ENABLE hekate_config h_cfg; + const volatile ipl_ver_meta_t __attribute__((section ("._ipl_version"))) ipl_ver = { .magic = BL_MAGIC, .version = (BL_VER_MJ + '0') | ((BL_VER_MN + '0') << 8) | ((BL_VER_HF + '0') << 16), @@ -168,6 +169,9 @@ int sd_save_to_file(void *buf, u32 size, const char *filename) return 0; } +#pragma GCC push_options +#pragma GCC target ("thumb") + void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage) { sdmmc_storage_t storage2; @@ -307,14 +311,13 @@ out: void load_saved_configuration() { LIST_INIT(ini_sections); - LIST_INIT(ini_list_sections); if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false)) { // Load configuration. LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) { - // Skip other ini entries for autoboot. + // Skip other ini entries. if (ini_sec->type == INI_CHOICE) { if (!strcmp(ini_sec->name, "config")) @@ -430,3 +433,5 @@ void ipl_main() while (true) bpmp_halt(); } + +#pragma GCC pop_options diff --git a/nyx/nyx_gui/power/bq24193.c b/nyx/nyx_gui/power/bq24193.c index 717c364..ed1b022 100644 --- a/nyx/nyx_gui/power/bq24193.c +++ b/nyx/nyx_gui/power/bq24193.c @@ -20,6 +20,9 @@ #include "../soc/i2c.h" #include "../utils/util.h" +#pragma GCC push_options +#pragma GCC target ("thumb") + int bq24193_get_property(enum BQ24193_reg_prop prop, int *value) { u8 data; @@ -160,3 +163,5 @@ 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/nyx/nyx_gui/power/max17050.c b/nyx/nyx_gui/power/max17050.c index 2a2c8f6..70d4fd9 100644 --- a/nyx/nyx_gui/power/max17050.c +++ b/nyx/nyx_gui/power/max17050.c @@ -43,6 +43,9 @@ #define MAX17050_VMAX_TOLERANCE 50 /* 50 mV */ +#pragma GCC push_options +#pragma GCC target ("thumb") + int max17050_get_property(enum MAX17050_reg reg, int *value) { u16 data; @@ -264,3 +267,5 @@ int max17050_fix_configuration() return 0; } + +#pragma GCC pop_options diff --git a/nyx/nyx_gui/rtc/max77620-rtc.c b/nyx/nyx_gui/rtc/max77620-rtc.c index 85895af..7e2d3af 100644 --- a/nyx/nyx_gui/rtc/max77620-rtc.c +++ b/nyx/nyx_gui/rtc/max77620-rtc.c @@ -52,7 +52,7 @@ void max77620_rtc_get_time(rtc_time_t *time) } // Get date. - time->date = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f; + time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f; time->month = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MONTH_REG) & 0xF) - 1; time->year = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_YEAR_REG) & 0x7F) + 2000; } diff --git a/nyx/nyx_gui/rtc/max77620-rtc.h b/nyx/nyx_gui/rtc/max77620-rtc.h index 756e67c..981ccfe 100644 --- a/nyx/nyx_gui/rtc/max77620-rtc.h +++ b/nyx/nyx_gui/rtc/max77620-rtc.h @@ -64,7 +64,7 @@ typedef struct _rtc_time_t { u8 sec; u8 min; u8 hour; - u8 date; + u8 day; u8 month; u16 year; } rtc_time_t; diff --git a/nyx/nyx_gui/soc/bpmp.c b/nyx/nyx_gui/soc/bpmp.c index 16367f2..effca15 100644 --- a/nyx/nyx_gui/soc/bpmp.c +++ b/nyx/nyx_gui/soc/bpmp.c @@ -152,7 +152,7 @@ void bpmp_mmu_disable() // Clean and invalidate cache. bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY); - // Enable cache. + // Disable cache. BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = 0; // HW bug. Invalidate cache again. diff --git a/nyx/nyx_gui/soc/clock.c b/nyx/nyx_gui/soc/clock.c index 5ebdaea..65dca64 100644 --- a/nyx/nyx_gui/soc/clock.c +++ b/nyx/nyx_gui/soc/clock.c @@ -369,7 +369,6 @@ static void _clock_sdmmc_clear_enable(u32 id) static u32 _clock_sdmmc_table[8] = { 0 }; #define PLLP_OUT0 0x0 - static int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val) { u32 divisor = 0; diff --git a/nyx/nyx_gui/soc/clock.h b/nyx/nyx_gui/soc/clock.h index 754608f..db7a974 100644 --- a/nyx/nyx_gui/soc/clock.h +++ b/nyx/nyx_gui/soc/clock.h @@ -123,7 +123,7 @@ #define CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP 0x620 #define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 0x65C #define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664 -#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIP_CAL 0x66C +#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL 0x66C #define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694 #define CLK_RST_CONTROLLER_CLK_SOURCE_NVENC 0x6A0 #define CLK_RST_CONTROLLER_SE_SUPER_CLK_DIVIDER 0x704 diff --git a/nyx/nyx_gui/soc/hw_init.c b/nyx/nyx_gui/soc/hw_init.c index b354a5b..eb8e33d 100644 --- a/nyx/nyx_gui/soc/hw_init.c +++ b/nyx/nyx_gui/soc/hw_init.c @@ -42,7 +42,7 @@ void reconfig_hw_workaround(bool extra_reconfig, u32 magic) // Re-enable clocks to Audio Processing Engine as a workaround to hanging. CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= (1 << 10); // Enable AHUB clock. - CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= (1 << 6); // Enable APE clock. + CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= (1 << 6); // Enable APE clock. if (extra_reconfig) { diff --git a/nyx/nyx_gui/storage/sdmmc.c b/nyx/nyx_gui/storage/sdmmc.c index b0837ec..d471883 100644 --- a/nyx/nyx_gui/storage/sdmmc.c +++ b/nyx/nyx_gui/storage/sdmmc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (C) 2018 CTCaer + * Copyright (C) 2018-2019 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -19,7 +19,6 @@ #include "sdmmc.h" #include "mmc.h" #include "sd.h" -#include "../config/config.h" #include "../gfx/gfx.h" #include "../mem/heap.h" #include "../utils/util.h" @@ -27,8 +26,6 @@ //#define DPRINTF(...) gfx_printf(__VA_ARGS__) #define DPRINTF(...) -extern hekate_config h_cfg; - #pragma GCC push_options #pragma GCC target ("thumb") @@ -75,6 +72,7 @@ static int _sdmmc_storage_execute_cmd_type1_ex(sdmmc_storage_t *storage, u32 *re if (_sdmmc_storage_check_result(*resp)) if (expected_state == 0x10 || R1_CURRENT_STATE(*resp) == expected_state) return 1; + return 0; } @@ -88,6 +86,7 @@ static int _sdmmc_storage_go_idle_state(sdmmc_storage_t *storage) { sdmmc_cmd_t cmd; sdmmc_init_cmd(&cmd, MMC_GO_IDLE_STATE, 0, SDMMC_RSP_TYPE_0, 0); + return sdmmc_execute_cmd(storage->sdmmc, &cmd, 0, 0); } @@ -97,7 +96,9 @@ static int _sdmmc_storage_get_cid(sdmmc_storage_t *storage, void *buf) sdmmc_init_cmd(&cmd, MMC_ALL_SEND_CID, 0, SDMMC_RSP_TYPE_2, 0); if (!sdmmc_execute_cmd(storage->sdmmc, &cmd, 0, 0)) return 0; + sdmmc_get_rsp(storage->sdmmc, buf, 0x10, SDMMC_RSP_TYPE_2); + return 1; } @@ -112,7 +113,9 @@ static int _sdmmc_storage_get_csd(sdmmc_storage_t *storage, void *buf) sdmmc_init_cmd(&cmdbuf, MMC_SEND_CSD, storage->rca << 16, SDMMC_RSP_TYPE_2, 0); if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, 0, 0)) return 0; + sdmmc_get_rsp(storage->sdmmc, buf, 0x10, SDMMC_RSP_TYPE_2); + return 1; } @@ -150,8 +153,10 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out u32 tmp = 0; sdmmc_stop_transmission(storage->sdmmc, &tmp); _sdmmc_storage_get_status(storage, &tmp, 0); + return 0; } + return 1; } @@ -159,7 +164,9 @@ int sdmmc_storage_end(sdmmc_storage_t *storage) { if (!_sdmmc_storage_go_idle_state(storage)) return 0; + sdmmc_end(storage->sdmmc); + return 1; } @@ -181,14 +188,16 @@ static int _sdmmc_storage_readwrite(sdmmc_storage_t *storage, u32 sector, u32 nu msleep(100); } while (retries); + return 0; out:; - DPRINTF("readwrite: %08X\n", blkcnt); +DPRINTF("readwrite: %08X\n", blkcnt); sector += blkcnt; num_sectors -= blkcnt; bbuf += 512 * blkcnt; } + return 1; } @@ -239,14 +248,17 @@ static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power) u32 cond = 0; if (!_mmc_storage_get_op_cond_inner(storage, &cond, power)) break; + if (cond & MMC_CARD_BUSY) { if (cond & 0x40000000) storage->has_sector_access = 1; + return 1; } if (get_tmr_ms() > timeout) break; + usleep(1000); } @@ -376,6 +388,7 @@ static int _mmc_storage_switch_buswidth(sdmmc_storage_t *storage, u32 bus_width) if (_sdmmc_storage_check_status(storage)) { sdmmc_set_bus_width(storage->sdmmc, bus_width); + return 1; } @@ -386,14 +399,19 @@ static int _mmc_storage_enable_HS(sdmmc_storage_t *storage, int check) { if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS))) return 0; + if (check && !_sdmmc_storage_check_status(storage)) return 0; + if (!sdmmc_setup_clock(storage->sdmmc, 2)) return 0; - DPRINTF("[MMC] switched to HS\n"); + +DPRINTF("[MMC] switched to HS\n"); storage->csd.busspeed = 52; + if (check || _sdmmc_storage_check_status(storage)) return 1; + return 0; } @@ -401,12 +419,16 @@ static int _mmc_storage_enable_HS200(sdmmc_storage_t *storage) { if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200))) return 0; + if (!sdmmc_setup_clock(storage->sdmmc, 3)) return 0; + if (!sdmmc_config_tuning(storage->sdmmc, 3, MMC_SEND_TUNING_BLOCK_HS200)) return 0; - DPRINTF("[MMC] switched to HS200\n"); + +DPRINTF("[MMC] switched to HS200\n"); storage->csd.busspeed = 200; + return _sdmmc_storage_check_status(storage); } @@ -414,17 +436,24 @@ static int _mmc_storage_enable_HS400(sdmmc_storage_t *storage) { if (!_mmc_storage_enable_HS200(storage)) return 0; + sdmmc_get_venclkctl(storage->sdmmc); + if (!_mmc_storage_enable_HS(storage, 0)) return 0; + if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH, EXT_CSD_DDR_BUS_WIDTH_8))) return 0; + if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400))) return 0; + if (!sdmmc_setup_clock(storage->sdmmc, 4)) return 0; - DPRINTF("[MMC] switched to HS400\n"); + +DPRINTF("[MMC] switched to HS400\n"); storage->csd.busspeed = 400; + return _sdmmc_storage_check_status(storage); } @@ -436,8 +465,7 @@ static int _mmc_storage_enable_highspeed(sdmmc_storage_t *storage, u32 card_type goto out; if (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 && - card_type & EXT_CSD_CARD_TYPE_HS400_1_8V && - type == 4) + card_type & EXT_CSD_CARD_TYPE_HS400_1_8V && type == 4) return _mmc_storage_enable_HS400(storage); if (sdmmc_get_bus_width(storage->sdmmc) == SDMMC_BUS_WIDTH_8 || @@ -449,6 +477,7 @@ static int _mmc_storage_enable_highspeed(sdmmc_storage_t *storage, u32 card_type out:; if (card_type & EXT_CSD_CARD_TYPE_HS_52) return _mmc_storage_enable_HS(storage, 1); + return 1; } @@ -456,6 +485,7 @@ static int _mmc_storage_enable_bkops(sdmmc_storage_t *storage) { if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_SET_BITS, EXT_CSD_BKOPS_EN, EXT_CSD_BKOPS_LEVEL_2))) return 0; + return _sdmmc_storage_check_status(storage); } @@ -467,42 +497,42 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 if (!sdmmc_init(sdmmc, id, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_1, 0, 0)) return 0; - DPRINTF("[MMC] after init\n"); +DPRINTF("[MMC] after init\n"); usleep(1000 + (74000 + sdmmc->divisor - 1) / sdmmc->divisor); if (!_sdmmc_storage_go_idle_state(storage)) return 0; - DPRINTF("[MMC] went to idle state\n"); +DPRINTF("[MMC] went to idle state\n"); if (!_mmc_storage_get_op_cond(storage, SDMMC_POWER_1_8)) return 0; - DPRINTF("[MMC] got op cond\n"); +DPRINTF("[MMC] got op cond\n"); if (!_sdmmc_storage_get_cid(storage, storage->raw_cid)) return 0; - DPRINTF("[MMC] got cid\n"); +DPRINTF("[MMC] got cid\n"); if (!_mmc_storage_set_relative_addr(storage)) return 0; - DPRINTF("[MMC] set relative addr\n"); +DPRINTF("[MMC] set relative addr\n"); if (!_sdmmc_storage_get_csd(storage, storage->raw_csd)) return 0; - DPRINTF("[MMC] got csd\n"); +DPRINTF("[MMC] got csd\n"); _mmc_storage_parse_csd(storage); if (!sdmmc_setup_clock(storage->sdmmc, 1)) return 0; - DPRINTF("[MMC] after setup clock\n"); +DPRINTF("[MMC] after setup clock\n"); if (!_sdmmc_storage_select_card(storage)) return 0; - DPRINTF("[MMC] card selected\n"); +DPRINTF("[MMC] card selected\n"); if (!_sdmmc_storage_set_blocklen(storage, 512)) return 0; - DPRINTF("[MMC] set blocklen to 512\n"); +DPRINTF("[MMC] set blocklen to 512\n"); u32 *csd = (u32 *)storage->raw_csd; //Check system specification version, only version 4.0 and later support below features. @@ -514,7 +544,7 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 if (!_mmc_storage_switch_buswidth(storage, bus_width)) return 0; - DPRINTF("[MMC] switched buswidth\n"); +DPRINTF("[MMC] switched buswidth\n"); u8 *ext_csd = (u8 *)malloc(512); if (!_mmc_storage_get_ext_csd(storage, ext_csd)) @@ -523,7 +553,7 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 return 0; } free(ext_csd); - DPRINTF("[MMC] got ext_csd\n"); +DPRINTF("[MMC] got ext_csd\n"); _mmc_storage_parse_cid(storage); //This needs to be after csd and ext_csd //gfx_hexdump(0, ext_csd, 512); @@ -533,16 +563,16 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 if (storage->ext_csd.bkops & 0x1 && !(storage->ext_csd.bkops_en & EXT_CSD_BKOPS_LEVEL_2) && 0) { _mmc_storage_enable_bkops(storage); - DPRINTF("[MMC] BKOPS enabled\n"); +DPRINTF("[MMC] BKOPS enabled\n"); } else { - DPRINTF("[MMC] BKOPS disabled\n"); +DPRINTF("[MMC] BKOPS disabled\n"); } if (!_mmc_storage_enable_highspeed(storage, storage->ext_csd.card_type, type)) return 0; - DPRINTF("[MMC] succesfully switched to highspeed mode\n"); +DPRINTF("[MMC] succesfully switched to highspeed mode\n"); sdmmc_sd_clock_ctrl(storage->sdmmc, 1); @@ -553,8 +583,10 @@ int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition) { if (!_mmc_storage_switch(storage, SDMMC_SWITCH(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_PART_CONFIG, partition))) return 0; + if (!_sdmmc_storage_check_status(storage)) return 0; + storage->partition = partition; return 1; } @@ -568,6 +600,7 @@ static int _sd_storage_execute_app_cmd(sdmmc_storage_t *storage, u32 expected_st u32 tmp; if (!_sdmmc_storage_execute_cmd_type1_ex(storage, &tmp, MMC_APP_CMD, storage->rca << 16, 0, expected_state, mask)) return 0; + return sdmmc_execute_cmd(storage->sdmmc, cmd, req, blkcnt_out); } @@ -575,6 +608,7 @@ static int _sd_storage_execute_app_cmd_type1(sdmmc_storage_t *storage, u32 *resp { if (!_sdmmc_storage_execute_cmd_type1(storage, MMC_APP_CMD, storage->rca << 16, 0, R1_STATE_TRAN)) return 0; + return _sdmmc_storage_execute_cmd_type1_ex(storage, resp, cmd, arg, check_busy, expected_state, 0); } @@ -606,6 +640,7 @@ static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int sdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0); if (!_sd_storage_execute_app_cmd(storage, 0x10, is_version_1 ? 0x400000 : 0, &cmdbuf, 0, 0)) return 0; + return sdmmc_get_rsp(storage->sdmmc, cond, 4, SDMMC_RSP_TYPE_3); } @@ -633,7 +668,7 @@ static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, i return 0; storage->is_low_voltage = 1; - DPRINTF("-> switched to low voltage\n"); +DPRINTF("-> switched to low voltage\n"); } } @@ -787,17 +822,17 @@ void _sd_storage_set_current_limit(sdmmc_storage_t *storage, u8 *buf) switch (pwr) { case SD_SET_CURRENT_LIMIT_800: - DPRINTF("[SD] Power limit raised to 800mA\n"); +DPRINTF("[SD] Power limit raised to 800mA\n"); break; case SD_SET_CURRENT_LIMIT_600: - DPRINTF("[SD] Power limit raised to 600mA\n"); +DPRINTF("[SD] Power limit raised to 600mA\n"); break; case SD_SET_CURRENT_LIMIT_400: - DPRINTF("[SD] Power limit raised to 800mA\n"); +DPRINTF("[SD] Power limit raised to 800mA\n"); break; default: case SD_SET_CURRENT_LIMIT_200: - DPRINTF("[SD] Power limit defaulted to 200mA\n"); +DPRINTF("[SD] Power limit defaulted to 200mA\n"); break; } } @@ -806,10 +841,12 @@ int _sd_storage_enable_highspeed(sdmmc_storage_t *storage, u32 hs_type, u8 *buf) { if (!_sd_storage_switch(storage, buf, SD_SWITCH_CHECK, 0, hs_type)) return 0; +DPRINTF("[SD] SD supports switch to (U)HS check\n"); u32 type_out = buf[16] & 0xF; if (type_out != hs_type) return 0; +DPRINTF("[SD] SD supports selected (U)HS mode\n"); if ((((u16)buf[0] << 8) | buf[1]) < 0x320) { @@ -844,7 +881,7 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 { type = 11; hs_type = UHS_SDR104_BUS_SPEED; - DPRINTF("[SD] Bus speed set to SDR104\n"); +DPRINTF("[SD] Bus speed set to SDR104\n"); storage->csd.busspeed = 104; break; } @@ -853,7 +890,7 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 { type = 10; hs_type = UHS_SDR50_BUS_SPEED; - DPRINTF("[SD] Bus speed set to SDR50\n"); +DPRINTF("[SD] Bus speed set to SDR50\n"); storage->csd.busspeed = 50; break; } @@ -862,7 +899,7 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 return 0; type = 8; hs_type = UHS_SDR12_BUS_SPEED; - DPRINTF("[SD] Bus speed set to SDR12\n"); +DPRINTF("[SD] Bus speed set to SDR12\n"); storage->csd.busspeed = 12; break; default: @@ -872,10 +909,13 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 if (!_sd_storage_enable_highspeed(storage, hs_type, buf)) return 0; +DPRINTF("[SD] SD card accepted UHS\n"); if (!sdmmc_setup_clock(storage->sdmmc, type)) return 0; +DPRINTF("[SD] setup clock\n"); if (!sdmmc_config_tuning(storage->sdmmc, type, MMC_SEND_TUNING_BLOCK)) return 0; +DPRINTF("[SD] config tuning\n"); return _sdmmc_storage_check_status(storage); } @@ -889,8 +929,10 @@ int _sd_storage_enable_highspeed_high_volt(sdmmc_storage_t *storage, u8 *buf) if (!_sd_storage_enable_highspeed(storage, 1, buf)) return 0; + if (!_sdmmc_storage_check_status(storage)) return 0; + return sdmmc_setup_clock(storage->sdmmc, 7); } @@ -953,7 +995,7 @@ static int _sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf) if (!(storage->csd.cmdclass & CCC_APP_SPEC)) { - DPRINTF("[SD] ssr: Card lacks mandatory SD Status function\n"); +DPRINTF("[SD] ssr: Card lacks mandatory SD Status function\n"); return 0; } @@ -1017,7 +1059,7 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage) void sdmmc_storage_init_wait_sd() { - u32 sd_poweroff_time = (u32)get_tmr_ms() - h_cfg.sd_timeoff; + u32 sd_poweroff_time = (u32)get_tmr_ms() - sd_power_cycle_time_start; if (sd_poweroff_time < 100) msleep(100 - sd_poweroff_time); } @@ -1034,35 +1076,35 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 if (!sdmmc_init(sdmmc, id, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, 5, 0)) return 0; - DPRINTF("[SD] after init\n"); +DPRINTF("[SD] after init\n"); usleep(1000 + (74000 + sdmmc->divisor - 1) / sdmmc->divisor); if (!_sdmmc_storage_go_idle_state(storage)) return 0; - DPRINTF("[SD] went to idle state\n"); +DPRINTF("[SD] went to idle state\n"); is_version_1 = _sd_storage_send_if_cond(storage); if (is_version_1 == 2) return 0; - DPRINTF("[SD] after send if cond\n"); +DPRINTF("[SD] after send if cond\n"); if (!_sd_storage_get_op_cond(storage, is_version_1, bus_width == SDMMC_BUS_WIDTH_4 && type == 11)) return 0; - DPRINTF("[SD] got op cond\n"); +DPRINTF("[SD] got op cond\n"); if (!_sdmmc_storage_get_cid(storage, storage->raw_cid)) return 0; - DPRINTF("[SD] got cid\n"); +DPRINTF("[SD] got cid\n"); _sd_storage_parse_cid(storage); if (!_sd_storage_get_rca(storage)) return 0; - DPRINTF("[SD] got rca (= %04X)\n", storage->rca); +DPRINTF("[SD] got rca (= %04X)\n", storage->rca); if (!_sdmmc_storage_get_csd(storage, storage->raw_csd)) return 0; - DPRINTF("[SD] got csd\n"); +DPRINTF("[SD] got csd\n"); //Parse CSD. _sd_storage_parse_csd(storage); @@ -1075,7 +1117,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 storage->sec_cnt = storage->csd.c_size << 10; break; default: - DPRINTF("[SD] Unknown CSD structure %d\n", storage->csd.structure); +DPRINTF("[SD] unknown CSD structure %d\n", storage->csd.structure); break; } @@ -1083,21 +1125,21 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 { if (!sdmmc_setup_clock(storage->sdmmc, 6)) return 0; - DPRINTF("[SD] after setup clock\n"); +DPRINTF("[SD] after setup clock\n"); } if (!_sdmmc_storage_select_card(storage)) return 0; - DPRINTF("[SD] card selected\n"); +DPRINTF("[SD] card selected\n"); if (!_sdmmc_storage_set_blocklen(storage, 512)) return 0; - DPRINTF("[SD] set blocklen to 512\n"); +DPRINTF("[SD] set blocklen to 512\n"); u32 tmp = 0; if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_CLR_CARD_DETECT, 0, 0, R1_STATE_TRAN)) return 0; - DPRINTF("[SD] cleared card detect\n"); +DPRINTF("[SD] cleared card detect\n"); u8 *buf = (u8 *)malloc(512); if (!_sd_storage_get_scr(storage, buf)) @@ -1107,7 +1149,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 } //gfx_hexdump(0, storage->raw_scr, 8); - DPRINTF("[SD] got scr\n"); +DPRINTF("[SD] got scr\n"); // Check if card supports a wider bus and if it's not SD Version 1.X if (bus_width == SDMMC_BUS_WIDTH_4 && (storage->scr.bus_widths & 4) && (storage->scr.sda_vsn & 0xF)) @@ -1118,11 +1160,11 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 return 0; } sdmmc_set_bus_width(storage->sdmmc, SDMMC_BUS_WIDTH_4); - DPRINTF("[SD] switched to wide bus width\n"); +DPRINTF("[SD] switched to wide bus width\n"); } else { - DPRINTF("[SD] SD does not support wide bus width\n"); +DPRINTF("[SD] SD does not support wide bus width\n"); } if (storage->is_low_voltage) @@ -1132,7 +1174,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 free(buf); return 0; } - DPRINTF("[SD] enabled highspeed (low voltage)\n"); +DPRINTF("[SD] enabled UHS\n"); } else if (type != 6 && (storage->scr.sda_vsn & 0xF) != 0) { @@ -1141,7 +1183,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 free(buf); return 0; } - DPRINTF("[SD] enabled highspeed (high voltage)\n"); +DPRINTF("[SD] enabled HS\n"); storage->csd.busspeed = 25; } @@ -1150,7 +1192,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 // Parse additional card info from sd status. if (_sd_storage_get_ssr(storage, buf)) { - DPRINTF("[SD] got sd status\n"); +DPRINTF("[SD] got sd status\n"); } free(buf); @@ -1195,13 +1237,13 @@ int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc) if (!sdmmc_init(sdmmc, SDMMC_2, SDMMC_POWER_1_8, SDMMC_BUS_WIDTH_8, 14, 0)) return 0; - DPRINTF("[gc] after init\n"); +DPRINTF("[gc] after init\n"); usleep(1000 + (10000 + sdmmc->divisor - 1) / sdmmc->divisor); if (!sdmmc_config_tuning(storage->sdmmc, 14, MMC_SEND_TUNING_BLOCK_HS200)) return 0; - DPRINTF("[gc] after tuning\n"); +DPRINTF("[gc] after tuning\n"); sdmmc_sd_clock_ctrl(sdmmc, 1); diff --git a/nyx/nyx_gui/storage/sdmmc.h b/nyx/nyx_gui/storage/sdmmc.h index 2427324..fdc2bbb 100644 --- a/nyx/nyx_gui/storage/sdmmc.h +++ b/nyx/nyx_gui/storage/sdmmc.h @@ -21,6 +21,8 @@ #include "../utils/types.h" #include "sdmmc_driver.h" +u32 sd_power_cycle_time_start; + typedef struct _mmc_cid { u32 manfid; diff --git a/nyx/nyx_gui/storage/sdmmc_driver.c b/nyx/nyx_gui/storage/sdmmc_driver.c index bf990e9..0c0c2ff 100644 --- a/nyx/nyx_gui/storage/sdmmc_driver.c +++ b/nyx/nyx_gui/storage/sdmmc_driver.c @@ -19,7 +19,6 @@ #include "mmc.h" #include "sdmmc.h" -#include "../config/config.h" #include "../gfx/gfx.h" #include "../power/max7762x.h" #include "../soc/bpmp.h" @@ -33,8 +32,6 @@ //#define DPRINTF(...) gfx_printf(__VA_ARGS__) #define DPRINTF(...) -extern hekate_config h_cfg; - /*! SCMMC controller base addresses. */ static const u32 _sdmmc_bases[4] = { 0x700B0000, @@ -125,6 +122,7 @@ static int _sdmmc_config_ven_ceata_clk(sdmmc_t *sdmmc, u32 id) { if (!sdmmc->venclkctl_set) return 0; + tap_val = sdmmc->venclkctl_tap; } else @@ -235,7 +233,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; break; case 4: - // Non standard + // Non standard. sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | HS400_BUS_SPEED; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; break; @@ -513,13 +511,17 @@ static int _sdmmc_config_tuning_once(sdmmc_t *sdmmc, u32 cmd) return 0; _sdmmc_setup_read_small_block(sdmmc); + sdmmc->regs->norintstsen |= TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY; sdmmc->regs->norintsts = sdmmc->regs->norintsts; sdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; + _sdmmc_parse_cmd_48(sdmmc, cmd); _sdmmc_get_clkcon(sdmmc); usleep(1); + _sdmmc_reset(sdmmc); + sdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; _sdmmc_get_clkcon(sdmmc); @@ -535,10 +537,13 @@ static int _sdmmc_config_tuning_once(sdmmc_t *sdmmc, u32 cmd) return 1; } } + _sdmmc_reset(sdmmc); + sdmmc->regs->norintstsen &= 0xFFDF; _sdmmc_get_clkcon(sdmmc); usleep((1000 * 8 + sdmmc->divisor - 1) / sdmmc->divisor); + return 0; } @@ -565,8 +570,8 @@ int sdmmc_config_tuning(sdmmc_t *sdmmc, u32 type, u32 cmd) return 0; } - sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag; - sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | 0x40; + sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag; // Tries. + sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | 0x40; // Multiplier. sdmmc->regs->ventunctl0 |= 0x20000; sdmmc->regs->hostctl2 |= SDHCI_CTRL_EXEC_TUNING; @@ -579,6 +584,7 @@ int sdmmc_config_tuning(sdmmc_t *sdmmc, u32 type, u32 cmd) if (sdmmc->regs->hostctl2 & SDHCI_CTRL_TUNED_CLK) return 1; + return 0; } @@ -748,11 +754,14 @@ static int _sdmmc_stop_transmission_inner(sdmmc_t *sdmmc, u32 *rsp) return 0; _sdmmc_enable_interrupts(sdmmc); + cmd.cmd = MMC_STOP_TRANSMISSION; cmd.arg = 0; cmd.rsp_type = SDMMC_RSP_TYPE_1; cmd.check_busy = 1; + _sdmmc_parse_cmdbuf(sdmmc, &cmd, false); + int res = _sdmmc_wait_request(sdmmc); _sdmmc_mask_interrupts(sdmmc); @@ -760,6 +769,7 @@ static int _sdmmc_stop_transmission_inner(sdmmc_t *sdmmc, u32 *rsp) return 0; _sdmmc_cache_rsp(sdmmc, rsp, 4, SDMMC_RSP_TYPE_1); + return _sdmmc_wait_prnsts_type1(sdmmc); } @@ -779,6 +789,7 @@ int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp) int res = _sdmmc_stop_transmission_inner(sdmmc, rsp); usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor); + if (should_disable_sd_clock) sdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; @@ -838,7 +849,7 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc) while (1) { u16 intr = 0; - res = _sdmmc_check_mask_interrupt(sdmmc, &intr, + res = _sdmmc_check_mask_interrupt(sdmmc, &intr, TEGRA_MMC_NORINTSTS_XFER_COMPLETE | TEGRA_MMC_NORINTSTS_DMA_INTERRUPT); if (res < 0) break; @@ -911,6 +922,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_ { if (blkcnt_out) *blkcnt_out = blkcnt; + if (req->is_auto_cmd12) sdmmc->rsp3 = sdmmc->regs->rspreg3; } @@ -930,6 +942,8 @@ static int _sdmmc_config_sdmmc1() gpio_config(GPIO_PORT_Z, GPIO_PIN_1, GPIO_MODE_GPIO); gpio_output_enable(GPIO_PORT_Z, GPIO_PIN_1, GPIO_OUTPUT_DISABLE); usleep(100); + + // Check if SD card is inserted. if(!!gpio_read(GPIO_PORT_Z, GPIO_PIN_1)) return 0; @@ -943,7 +957,7 @@ static int _sdmmc_config_sdmmc1() */ // Configure SDMMC1 pinmux. - APB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1; + APB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1; // Enable deep loopback for SDMMC1 CLK pad. PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED; PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP; PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP; @@ -1014,18 +1028,23 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int n sdmmc->regs->sdmemcmppadctl = (sdmmc->regs->sdmemcmppadctl & 0xF) | 7; if (!_sdmmc_autocal_config_offset(sdmmc, power)) return 0; + _sdmmc_autocal_execute(sdmmc, power); + if (_sdmmc_enable_internal_clock(sdmmc)) { sdmmc_set_bus_width(sdmmc, bus_width); _sdmmc_set_voltage(sdmmc, power); + if (sdmmc_setup_clock(sdmmc, type)) { sdmmc_sd_clock_ctrl(sdmmc, no_sd); _sdmmc_sd_clock_enable(sdmmc); _sdmmc_get_clkcon(sdmmc); + return 1; } + return 0; } return 0; @@ -1044,8 +1063,8 @@ void sdmmc_end(sdmmc_t *sdmmc) { gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE); max77620_regulator_enable(REGULATOR_LDO2, 0); - h_cfg.sd_timeoff = get_tmr_ms(); // Some sandisc U1 cards need 100ms for a power cycle. - msleep(1); // To power cycle, min 1ms without power is needed. + sd_power_cycle_time_start = get_tmr_ms(); // Some sandisc U1 cards need 100ms for a power cycle. + usleep(1000); // To power cycle, min 1ms without power is needed. } _sdmmc_get_clkcon(sdmmc); @@ -1082,6 +1101,7 @@ int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *b int res = _sdmmc_execute_cmd_inner(sdmmc, cmd, req, blkcnt_out); usleep((8000 + sdmmc->divisor - 1) / sdmmc->divisor); + if (should_disable_sd_clock) sdmmc->regs->clkcon &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; @@ -1119,7 +1139,7 @@ int sdmmc_enable_low_voltage(sdmmc_t *sdmmc) { sdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; _sdmmc_get_clkcon(sdmmc); - msleep(1); + usleep(1000); if ((sdmmc->regs->prnsts & 0xF00000) == 0xF00000) return 1; } diff --git a/nyx/nyx_gui/thermal/fan.c b/nyx/nyx_gui/thermal/fan.c index 5dfbe22..c41a662 100644 --- a/nyx/nyx_gui/thermal/fan.c +++ b/nyx/nyx_gui/thermal/fan.c @@ -63,13 +63,9 @@ void set_fan_duty(u32 duty) // If disabled send a 0 duty. if (inv_duty == 236) - inv_duty = 255; - - // Set PWM duty. - if (inv_duty == 255) - PWM(PWM_CONTROLLER_PWM_CSR_1) = 0; - else - PWM(PWM_CONTROLLER_PWM_CSR_1) = (1 << 31) | (inv_duty << 16); + PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (1 << 24); + else // Set PWM duty. + PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (inv_duty << 16); } void get_fan_speed(u32 *duty, u32 *rpm)