From 0db758592a4ab55846962c391d3bbb57f6383946 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Wed, 17 Dec 2025 05:24:16 +0200 Subject: [PATCH] bdk: minerva: add IRB support Aka no table support. --- bdk/mem/minerva.c | 77 +++++++++++++++++++++++++++++------------------ bdk/mem/minerva.h | 10 ++++-- bdk/mem/sdram.c | 35 --------------------- bdk/mem/sdram.h | 1 - 4 files changed, 55 insertions(+), 68 deletions(-) diff --git a/bdk/mem/minerva.c b/bdk/mem/minerva.c index c406bb2c..583fc9b0 100644 --- a/bdk/mem/minerva.c +++ b/bdk/mem/minerva.c @@ -26,22 +26,22 @@ #include #include +#define FREQ_NO_TABLE_MAX FREQ_408 + #define TABLE_FREQ_KHZ_OFFSET 0x40 #define TABLE_LA_REGS_T210_OFFSET 0x1284 #define TABLE_LA_REGS_T210B01_OFFSET 0xFA4 #define LA_SDMMC1_INDEX 6 +static bool no_table = false; static mtc_config_t *mtc_cfg = NULL; void (*mtc_call)(mtc_config_t *mtc_cfg, void *); u32 minerva_init(minerva_str_t *mtc_str) { mtc_call = NULL; - mtc_cfg = (mtc_config_t *)&mtc_str->mtc_cfg; - - //!TODO: Not supported on T210B01 yet. - if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) - return 0; + mtc_cfg = (mtc_config_t *)&mtc_str->mtc_cfg; + no_table = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01; #ifdef BDK_MINERVA_CFG_FROM_RAM // Set table to nyx storage. @@ -50,7 +50,8 @@ u32 minerva_init(minerva_str_t *mtc_str) // Check if Minerva is already initialized. if (mtc_cfg->init_done == MTC_INIT_MAGIC) { - mtc_cfg->train_mode = OP_PERIODIC_TRAIN; // Retrain if needed. + // Load library and do a periodic training if needed. + mtc_cfg->train_mode = OP_PERIODIC_TRAIN; u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg); mtc_call = (void *)ep_addr; @@ -60,13 +61,15 @@ u32 minerva_init(minerva_str_t *mtc_str) { mtc_config_t mtc_tmp; - mtc_tmp.mtc_table = mtc_cfg->mtc_table; - mtc_tmp.sdram_id = fuse_read_dramid(false); - mtc_tmp.init_done = MTC_NEW_MAGIC; + // Initialize table. + mtc_tmp.mtc_table = mtc_cfg->mtc_table; + mtc_tmp.sdram_id = fuse_read_dramid(false); + mtc_tmp.init_done = !no_table ? MTC_NEW_MAGIC : MTC_IRB_MAGIC; + // Load library and get table. u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)&mtc_tmp); - // Ensure that Minerva is new. + // Ensure that Minerva is initialized. if (mtc_tmp.init_done == MTC_INIT_MAGIC) mtc_call = (void *)ep_addr; else @@ -77,17 +80,17 @@ u32 minerva_init(minerva_str_t *mtc_str) memcpy(mtc_cfg, (void *)&mtc_tmp, sizeof(mtc_config_t)); } #else + // Fully initialize Minerva. memset(mtc_cfg, 0, sizeof(mtc_config_t)); - // Set table to nyx storage. - mtc_cfg->mtc_table = (emc_table_t *)mtc_str->mtc_table; - - mtc_cfg->sdram_id = fuse_read_dramid(false); - mtc_cfg->init_done = MTC_NEW_MAGIC; // Initialize mtc table. + // Initialize mtc table. + mtc_cfg->mtc_table = mtc_str->mtc_table; + mtc_cfg->sdram_id = fuse_read_dramid(false); + mtc_cfg->init_done = !no_table ? MTC_NEW_MAGIC : MTC_IRB_MAGIC; u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg); - // Ensure that Minerva is new. + // Ensure that Minerva is initialized. if (mtc_cfg->init_done == MTC_INIT_MAGIC) mtc_call = (void *)ep_addr; else @@ -97,18 +100,20 @@ u32 minerva_init(minerva_str_t *mtc_str) if (!mtc_call) return 1; - // Get current frequency - u32 current_emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC); - u32 tbl_idx = 0; - for (tbl_idx = 0; tbl_idx < mtc_cfg->table_entries; tbl_idx++) + if (no_table) { - if (current_emc_clk_src == mtc_cfg->mtc_table[tbl_idx].clk_src_emc) - break; + mtc_cfg->train_mode = OP_SWITCH; + mtc_cfg->rate_from = FREQ_204; + mtc_cfg->rate_to = FREQ_NO_TABLE_MAX; + mtc_call(mtc_cfg, NULL); + + return 0; } - mtc_cfg->rate_from = mtc_cfg->mtc_table[tbl_idx].rate_khz; - mtc_cfg->rate_to = FREQ_204; + // Train frequencies. mtc_cfg->train_mode = OP_TRAIN; + mtc_cfg->rate_from = FREQ_204; + mtc_cfg->rate_to = FREQ_204; mtc_call(mtc_cfg, NULL); mtc_cfg->rate_to = FREQ_800; mtc_call(mtc_cfg, NULL); @@ -132,11 +137,15 @@ void minerva_change_freq(minerva_freq_t freq) if (!mtc_call) return; + // Clamp max allowed frequency when no table exists. + if (no_table && freq > FREQ_NO_TABLE_MAX) + freq = FREQ_NO_TABLE_MAX; + // Check if requested frequency is different. Do not allow otherwise because it will hang. if (mtc_cfg->rate_from != freq) { - mtc_cfg->rate_to = freq; mtc_cfg->train_mode = OP_SWITCH; + mtc_cfg->rate_to = freq; mtc_call(mtc_cfg, NULL); } } @@ -170,11 +179,19 @@ void minerva_sdmmc_la_program(void *table, bool t210b01) } } -void minerva_prep_boot_freq() +void minerva_prep_boot_hos() { if (!mtc_call) return; + // Restore boot frequency for no table mode. + if (no_table) + { + minerva_deinit(); + + return; + } + // Check if there's RAM OC. If not exit. if (mtc_cfg->mtc_table[mtc_cfg->table_entries - 1].rate_khz == FREQ_1600) return; @@ -187,7 +204,7 @@ void minerva_prep_boot_freq() void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom, bool prg_sdmmc_la) { - if (!mtc_call) + if (!mtc_call || no_table) return; // Program SDMMC LA regs. @@ -255,7 +272,7 @@ void minerva_periodic_training() if (!mtc_call) return; - if (mtc_cfg->rate_from == FREQ_1600) + if (mtc_cfg->rate_from >= FREQ_1066) { mtc_cfg->train_mode = OP_PERIODIC_TRAIN; mtc_call(mtc_cfg, NULL); @@ -264,7 +281,7 @@ void minerva_periodic_training() emc_table_t *minerva_get_mtc_table() { - if (!mtc_call) + if (!mtc_call || no_table) return NULL; return mtc_cfg->mtc_table; @@ -272,7 +289,7 @@ emc_table_t *minerva_get_mtc_table() int minerva_get_mtc_table_entries() { - if (!mtc_call) + if (!mtc_call || no_table) return 0; return mtc_cfg->table_entries; diff --git a/bdk/mem/minerva.h b/bdk/mem/minerva.h index 1ef2aaa3..96dfa689 100644 --- a/bdk/mem/minerva.h +++ b/bdk/mem/minerva.h @@ -22,6 +22,7 @@ #define MTC_INIT_MAGIC 0x3043544D #define MTC_NEW_MAGIC 0x5243544D +#define MTC_IRB_MAGIC 0x4943544D #define EMC_PERIODIC_TRAIN_MS 250 @@ -60,9 +61,14 @@ typedef enum { FREQ_204 = 204000, FREQ_408 = 408000, + FREQ_666 = 665600, FREQ_800 = 800000, + FREQ_1066 = 1065600, FREQ_1333 = 1331200, - FREQ_1600 = 1600000 + FREQ_1600 = 1600000, + + FREQ_MIN = FREQ_204, + FREQ_MAX = FREQ_1600 } minerva_freq_t; extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *); @@ -70,7 +76,7 @@ u32 minerva_init(minerva_str_t *mtc_str); void minerva_deinit(); void minerva_change_freq(minerva_freq_t freq); void minerva_sdmmc_la_program(void *table, bool t210b01); -void minerva_prep_boot_freq(); +void minerva_prep_boot_hos(); void minerva_prep_boot_l4t(u32 oc_freq, u32 opt_custom, bool prg_sdmmc_la); void minerva_periodic_training(); emc_table_t *minerva_get_mtc_table(); diff --git a/bdk/mem/sdram.c b/bdk/mem/sdram.c index 9eacf0fa..427f75ae 100644 --- a/bdk/mem/sdram.c +++ b/bdk/mem/sdram.c @@ -182,41 +182,6 @@ emc_mr_data_t sdram_read_mrx(emc_mr_t mrx) return data; } -void sdram_src_pllc(bool enable) -{ - static bool enabled = false; - - if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210 || enable == enabled) - return; - - enabled = enable; - - // Clear CC interrupt. - EMC(EMC_INTSTATUS) = BIT(4); - (void)EMC(EMC_INTSTATUS); - - u32 clk_src_emc = _dram_cfg_08_10_12_14_samsung_hynix_4gb.emc_clock_source; - - if (enable) - { - // Check if clock source is not the expected one. - if (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) != clk_src_emc) - return; - - // Set source as PLLC_OUT0. - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = 0x20188002; - } - else - { - // Restore MC/EMC clock. - CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = clk_src_emc; - } - - // Wait for CC interrupt. - while (!(EMC(EMC_INTSTATUS) & BIT(4))) - usleep(1); -} - static void _sdram_config_t210(const sdram_params_t210_t *params) { // VDDP Select. diff --git a/bdk/mem/sdram.h b/bdk/mem/sdram.h index b6e66f00..54a59c44 100644 --- a/bdk/mem/sdram.h +++ b/bdk/mem/sdram.h @@ -135,7 +135,6 @@ void sdram_init(); void *sdram_get_params_patched(); void *sdram_get_params_t210b01(); void sdram_lp0_save_params(const void *params); -void sdram_src_pllc(bool enable); emc_mr_data_t sdram_read_mrx(emc_mr_t mrx); #endif