From 2628044ba88a5c5868188fd1265cffc4bde88e36 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Sat, 26 Dec 2020 16:34:12 +0200 Subject: [PATCH] fuse: Move more parsing into its specific object --- bdk/mem/minerva.c | 4 ++-- bdk/mem/sdram.c | 13 ++----------- bdk/soc/ccplex.c | 2 +- bdk/soc/fuse.c | 32 +++++++++++++++++++++++++++++++- bdk/soc/fuse.h | 12 +++++++++++- bootloader/frontend/fe_info.c | 17 +++++------------ bootloader/hos/hos.c | 4 ++-- nyx/nyx_gui/frontend/gui_info.c | 19 +++++++------------ 8 files changed, 61 insertions(+), 42 deletions(-) diff --git a/bdk/mem/minerva.c b/bdk/mem/minerva.c index 183b633..7c192ac 100644 --- a/bdk/mem/minerva.c +++ b/bdk/mem/minerva.c @@ -60,7 +60,7 @@ u32 minerva_init() mtc_config_t mtc_tmp; mtc_tmp.mtc_table = mtc_cfg->mtc_table; - mtc_tmp.sdram_id = (fuse_read_odm(4) >> 3) & 0x1F; + mtc_tmp.sdram_id = fuse_read_dramid(false); mtc_tmp.init_done = MTC_NEW_MAGIC; u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)&mtc_tmp); @@ -81,7 +81,7 @@ u32 minerva_init() // Set table to nyx storage. mtc_cfg->mtc_table = (emc_table_t *)nyx_str->mtc_table; - mtc_cfg->sdram_id = (fuse_read_odm(4) >> 3) & 0x1F; + mtc_cfg->sdram_id = fuse_read_dramid(false); mtc_cfg->init_done = MTC_NEW_MAGIC; // Initialize mtc table. u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg); diff --git a/bdk/mem/sdram.c b/bdk/mem/sdram.c index aad98db..ae6ba20 100644 --- a/bdk/mem/sdram.c +++ b/bdk/mem/sdram.c @@ -54,11 +54,6 @@ typedef struct _sdram_vendor_patch_t #include "sdram_config_t210b01.inl" -static u32 _sdram_get_id() -{ - return ((fuse_read_odm(4) & 0xF8) >> 3); -} - static bool _sdram_wait_emc_status(u32 reg_offset, u32 bit_mask, bool updated_state, s32 emc_channel) { bool err = true; @@ -1374,9 +1369,7 @@ static void _sdram_patch_model_params_t210b01(u32 dramid, u32 *params) static void *_sdram_get_params_t210() { // Check if id is proper. - u32 dramid = _sdram_get_id(); - if (dramid > 6) - dramid = 0; + u32 dramid = fuse_read_dramid(false); #ifdef CONFIG_SDRAM_COMPRESS_CFG @@ -1413,9 +1406,7 @@ static void *_sdram_get_params_t210() void *sdram_get_params_t210b01() { // Check if id is proper. - u32 dramid = _sdram_get_id(); - if (dramid > 27) - dramid = 8; + u32 dramid = fuse_read_dramid(false); u32 *buf = (u32 *)SDRAM_PARAMS_ADDR; memcpy(buf, &_dram_cfg_08_10_12_14_samsung_hynix_4gb, sizeof(sdram_params_t210b01_t)); diff --git a/bdk/soc/ccplex.c b/bdk/soc/ccplex.c index a8d782d..e353679 100644 --- a/bdk/soc/ccplex.c +++ b/bdk/soc/ccplex.c @@ -46,7 +46,7 @@ void _ccplex_enable_power_t210() void _ccplex_enable_power_t210b01() { - u8 pmic_cpu_addr = !(FUSE(FUSE_RESERVED_ODM28) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR; + u8 pmic_cpu_addr = !(FUSE(FUSE_RESERVED_ODM28_T210B01) & 1) ? MAX77812_PHASE31_CPU_I2C_ADDR : MAX77812_PHASE211_CPU_I2C_ADDR; u8 tmp = i2c_recv_byte(I2C_5, pmic_cpu_addr, MAX77812_REG_EN_CTRL); i2c_send_byte(I2C_5, pmic_cpu_addr, MAX77812_REG_EN_CTRL, tmp | MAX77812_EN_CTRL_EN_M4); i2c_send_byte(I2C_5, pmic_cpu_addr, MAX77812_REG_M4_VOUT, MAX77812_M4_VOUT_0_80V); diff --git a/bdk/soc/fuse.c b/bdk/soc/fuse.c index 62dba31..780af8e 100644 --- a/bdk/soc/fuse.c +++ b/bdk/soc/fuse.c @@ -2,7 +2,7 @@ * Copyright (c) 2018 naehrwert * Copyright (c) 2018 shuffle2 * Copyright (c) 2018 balika011 - * Copyright (c) 2019 CTCaer + * Copyright (c) 2019-2020 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -76,6 +76,35 @@ u32 fuse_read_odm_keygen_rev() return 0; } +u32 fuse_read_dramid(bool raw_id) +{ + u32 dramid = (fuse_read_odm(4) & 0xF8) >> 3; + + if (raw_id) + return raw_id; + + if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210) + { + if (dramid > 6) + dramid = 0; + } + else + { + if (dramid > 27) + dramid = 8; + } + + return dramid; +} + +u32 fuse_read_hw_state() +{ + if ((fuse_read_odm(4) & 3) != 3) + return FUSE_NX_HW_STATE_PROD; + else + return FUSE_NX_HW_STATE_DEV; +} + u32 fuse_read_hw_type() { if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01) @@ -118,6 +147,7 @@ u32 fuse_read(u32 addr) FUSE(FUSE_ADDR) = addr; FUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ; fuse_wait_idle(); + return FUSE(FUSE_RDATA); } diff --git a/bdk/soc/fuse.h b/bdk/soc/fuse.h index d7d5c77..810efd6 100644 --- a/bdk/soc/fuse.h +++ b/bdk/soc/fuse.h @@ -2,6 +2,7 @@ * Copyright (c) 2018 naehrwert * Copyright (c) 2018 shuffle2 * Copyright (c) 2018 balika011 + * Copyright (c) 2019-2020 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -64,9 +65,10 @@ #define FUSE_OPT_X_COORDINATE 0x214 #define FUSE_OPT_Y_COORDINATE 0x218 #define FUSE_GPU_IDDQ_CALIB 0x228 -#define FUSE_RESERVED_ODM28 0x240 #define FUSE_USB_CALIB_EXT 0x350 +#define FUSE_RESERVED_ODM28_T210B01 0x240 + /*! Fuse commands. */ #define FUSE_READ 0x1 #define FUSE_WRITE 0x2 @@ -83,9 +85,17 @@ enum FUSE_NX_HW_TYPE_HOAG }; +enum +{ + FUSE_NX_HW_STATE_PROD, + FUSE_NX_HW_STATE_DEV +}; + void fuse_disable_program(); u32 fuse_read_odm(u32 idx); u32 fuse_read_odm_keygen_rev(); +u32 fuse_read_dramid(bool raw_id); +u32 fuse_read_hw_state(); u32 fuse_read_hw_type(); u8 fuse_count_burnt(u32 val); void fuse_wait_idle(); diff --git a/bootloader/frontend/fe_info.c b/bootloader/frontend/fe_info.c index 24e2ca3..d915550 100644 --- a/bootloader/frontend/fe_info.c +++ b/bootloader/frontend/fe_info.c @@ -49,25 +49,18 @@ void print_fuseinfo() gfx_clear_partial_grey(0x1B, 0, 1256); gfx_con_setpos(0, 0); - u32 burntFuses = 0; - for (u32 i = 0; i < 32; i++) - { - if ((fuse_read_odm(7) >> i) & 1) - burntFuses++; - } - gfx_printf("\nSKU: %X - ", FUSE(FUSE_SKU_INFO)); - switch (fuse_read_odm(4) & 3) + switch (fuse_read_hw_state()) { - case 0: + case FUSE_NX_HW_STATE_PROD: gfx_printf("Retail\n"); break; - case 3: + case FUSE_NX_HW_STATE_DEV: gfx_printf("Dev\n"); break; } - gfx_printf("Sdram ID: %d\n", (fuse_read_odm(4) >> 3) & 0x1F); - gfx_printf("Burnt fuses: %d / 64\n", burntFuses); + gfx_printf("Sdram ID: %d\n", fuse_read_dramid(true)); + gfx_printf("Burnt fuses: %d / 64\n", fuse_count_burnt(fuse_read_odm(7))); gfx_printf("Secure key: %08X%08X%08X%08X\n\n\n", byte_swap_32(FUSE(FUSE_PRIVATE_KEY0)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY1)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY2)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY3))); diff --git a/bootloader/hos/hos.c b/bootloader/hos/hos.c index a65b8c1..e4ee889 100644 --- a/bootloader/hos/hos.c +++ b/bootloader/hos/hos.c @@ -1060,13 +1060,13 @@ int hos_launch(ini_sec_t *cfg) if (kb <= KB_FIRMWARE_VERSION_500 && !exo_new) { memset((void *)SECMON_BCT_CFG_ADDR, 0, 0x3000); - if ((fuse_read_odm(4) & 3) == 3) + if (fuse_read_hw_state() == FUSE_NX_HW_STATE_DEV) memcpy((void *)SECMON_BCT_CFG_ADDR, bootConfigBuf, 0x1000); } else { memset((void *)SECMON6_BCT_CFG_ADDR, 0, 0x800); - if ((fuse_read_odm(4) & 3) == 3) + if (fuse_read_hw_state() == FUSE_NX_HW_STATE_DEV) memcpy((void *)SECMON6_BCT_CFG_ADDR, bootConfigBuf, 0x800); } free(bootConfigBuf); diff --git a/nyx/nyx_gui/frontend/gui_info.c b/nyx/nyx_gui/frontend/gui_info.c index 255ce04..111ab9b 100644 --- a/nyx/nyx_gui/frontend/gui_info.c +++ b/nyx/nyx_gui/frontend/gui_info.c @@ -556,24 +556,19 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn) // Decode fuses. char *sku; char dram_man[32]; - u32 odm4 = fuse_read_odm(4); - u8 dram_id = (odm4 >> 3) & 0x1F; - u32 hw_type3 = (odm4 & 0xF0000) >> 16; + u8 dram_id = fuse_read_dramid(true); - switch (hw_type3) + switch (fuse_read_hw_type()) { - case 0: + case FUSE_NX_HW_TYPE_ICOSA: sku = "Icosa (Erista)"; break; - case 1: + case FUSE_NX_HW_TYPE_IOWA: sku = "Iowa (Mariko)"; break; - case 2: + case FUSE_NX_HW_TYPE_HOAG: sku = "Hoag (Mariko)"; break; - case 4: - sku = "Calcio (Mariko)"; - break; default: sku = "Unknown"; break; @@ -673,7 +668,7 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn) "%s\n%d.%02d (0x%X)\n%d.%02d (0x%X)\n%d\n%d\n%d\n%d\n%d\n0x%X\n%d\n%d\n%d\n%d\n" "%d\n%d\n%d (0x%X)\n%d\n%d\n%d\n%d\n" "ID: %02X, Major: A0%d, Minor: %d", - FUSE(FUSE_SKU_INFO), sku, (fuse_read_odm(4) & 3) ? "Dev" : "Retail", + FUSE(FUSE_SKU_INFO), sku, fuse_read_hw_state() ? "Dev" : "Retail", dram_id, dram_man, burnt_fuses_7, burnt_fuses_6, byte_swap_32(FUSE(FUSE_PRIVATE_KEY0)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY1)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY2)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY3)), @@ -709,7 +704,7 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn) u32 ranks = EMC(EMC_ADR_CFG) + 1; u32 channels = (EMC(EMC_FBIO_CFG7) >> 1) & 3; u32 die_channels = ranks * ((channels & 1) + ((channels & 2) >> 1)); - s_printf(txt_buf, "#00DDFF %s SDRAM ##FF8000 (Ch 0 | Ch 1):#\n#FF8000 Vendor:# ", hw_type3 ? "LPDDR4X" : "LPDDR4"); + s_printf(txt_buf, "#00DDFF %s SDRAM ##FF8000 (Ch 0 | Ch 1):#\n#FF8000 Vendor:# ", dram_id > 6 ? "LPDDR4X" : "LPDDR4"); switch (ram_vendor.rank0_ch0) { case 1: