diff options
-rw-r--r-- | src/mainboard/google/asurada/chromeos.fmd | 2 | ||||
-rw-r--r-- | src/mainboard/google/asurada/romstage.c | 41 | ||||
-rw-r--r-- | src/soc/mediatek/common/dramc_param.c | 20 | ||||
-rw-r--r-- | src/soc/mediatek/common/include/soc/dramc_param.h | 18 | ||||
-rw-r--r-- | src/soc/mediatek/common/include/soc/emi.h | 3 | ||||
-rw-r--r-- | src/soc/mediatek/common/memory.c | 80 | ||||
-rw-r--r-- | src/soc/mediatek/mt8192/Kconfig | 1 |
7 files changed, 56 insertions, 109 deletions
diff --git a/src/mainboard/google/asurada/chromeos.fmd b/src/mainboard/google/asurada/chromeos.fmd index 2635854866..7194632e36 100644 --- a/src/mainboard/google/asurada/chromeos.fmd +++ b/src/mainboard/google/asurada/chromeos.fmd @@ -29,7 +29,7 @@ FLASH@0x0 8M { RW_MISC 36K { RW_VPD(PRESERVE) 16K # At least 8K. RW_NVRAM(PRESERVE) 8K - RW_DDR_TRAINING(PRESERVE) 8K + RW_MRC_CACHE(PRESERVE) 8K RW_ELOG(PRESERVE) 4K # ELOG driver hard-coded size in 4K. } RW_SECTION_B 1500K { diff --git a/src/mainboard/google/asurada/romstage.c b/src/mainboard/google/asurada/romstage.c index 0f88d2022d..4cd9b2abd3 100644 --- a/src/mainboard/google/asurada/romstage.c +++ b/src/mainboard/google/asurada/romstage.c @@ -1,13 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include <arch/stages.h> -#include <console/console.h> #include <delay.h> -#include <fmap.h> #include <soc/clkbuf.h> -#include <soc/dramc_param.h> #include <soc/emi.h> -#include <soc/mmu_operations.h> #include <soc/mt6315.h> #include <soc/mt6359p.h> #include <soc/pll_common.h> @@ -15,40 +11,6 @@ #include <soc/rtc.h> #include <soc/srclken_rc.h> -/* This must be defined in chromeos.fmd in same name and size. */ -#define CALIBRATION_REGION "RW_DDR_TRAINING" -#define CALIBRATION_REGION_SIZE 0x2000 - -_Static_assert(sizeof(struct dramc_param) <= CALIBRATION_REGION_SIZE, - "sizeof(struct dramc_param) exceeds " CALIBRATION_REGION); - -static bool read_calibration_data_from_flash(struct dramc_param *dparam) -{ - const size_t length = sizeof(*dparam); - size_t ret = fmap_read_area(CALIBRATION_REGION, dparam, length); - printk(BIOS_DEBUG, "read data from flash, ret=%#zx, length=%#zx\n", ret, length); - - return ret == length; -} - -static bool write_calibration_data_to_flash(const struct dramc_param *dparam) -{ - const size_t length = sizeof(*dparam); - size_t ret = fmap_overwrite_area(CALIBRATION_REGION, dparam, length); - printk(BIOS_DEBUG, "write data from flash, ret=%#zx, length=%#zx\n", ret, length); - - return ret == length; -} - -/* dramc_param is ~2K and too large to fit in stack. */ -static struct dramc_param dramc_parameter; - -static struct dramc_param_ops dparam_ops = { - .param = &dramc_parameter, - .read_from_flash = &read_calibration_data_from_flash, - .write_to_flash = &write_calibration_data_to_flash, -}; - static void raise_little_cpu_freq(void) { mt6359p_buck_set_voltage(MT6359P_SRAM_PROC2, 1000 * 1000); @@ -67,6 +29,5 @@ void platform_romstage_main(void) clk_buf_init(); rtc_boot(); raise_little_cpu_freq(); - mt_mem_init(&dparam_ops); - mtk_mmu_after_dram(); + mtk_dram_init(); } diff --git a/src/soc/mediatek/common/dramc_param.c b/src/soc/mediatek/common/dramc_param.c index 8548dbc665..c596adb208 100644 --- a/src/soc/mediatek/common/dramc_param.c +++ b/src/soc/mediatek/common/dramc_param.c @@ -22,26 +22,6 @@ void dump_param_header(const void *blob) print("header.size = %#x (expected: %#lx)\n", header->size, sizeof(*dparam)); print("header.flags = %#x\n", header->flags); - print("header.checksum = %#x\n", header->checksum); -} - -int validate_dramc_param(const void *blob) -{ - const struct dramc_param *param = blob; - const struct dramc_param_header *hdr = ¶m->header; - - if (hdr->version != DRAMC_PARAM_HEADER_VERSION) - return DRAMC_ERR_INVALID_VERSION; - - if (hdr->size != sizeof(*param)) - return DRAMC_ERR_INVALID_SIZE; - - return DRAMC_SUCCESS; -} - -int is_valid_dramc_param(const void *blob) -{ - return validate_dramc_param(blob) == DRAMC_SUCCESS; } int initialize_dramc_param(void *blob) diff --git a/src/soc/mediatek/common/include/soc/dramc_param.h b/src/soc/mediatek/common/include/soc/dramc_param.h index d3eda8da92..e809379261 100644 --- a/src/soc/mediatek/common/include/soc/dramc_param.h +++ b/src/soc/mediatek/common/include/soc/dramc_param.h @@ -3,21 +3,21 @@ #ifndef __SOC_MEDIATEK_DRAMC_PARAM_H__ #define __SOC_MEDIATEK_DRAMC_PARAM_H__ -/* any change in this file should sync to blob dramc_param.h */ +/* + * This file is shared between coreboot and dram blob. Any change in this file + * should be synced to the other repository. + */ #include <stdint.h> #include <sys/types.h> #include <soc/dramc_soc.h> -enum { - DRAMC_PARAM_HEADER_VERSION = 5, -}; +#define DRAMC_PARAM_HEADER_VERSION 6 enum DRAMC_PARAM_STATUS_CODES { DRAMC_SUCCESS = 0, DRAMC_ERR_INVALID_VERSION, DRAMC_ERR_INVALID_SIZE, - DRAMC_ERR_INVALID_CHECKSUM, DRAMC_ERR_INVALID_FLAGS, DRAMC_ERR_RECALIBRATE, DRAMC_ERR_INIT_DRAM, @@ -41,7 +41,6 @@ enum DRAMC_PARAM_DDR_TYPE { DDR_TYPE_EMCP, }; -/* Don't change the order, which is matched with blob */ enum DRAMC_PARAM_GEOMETRY_TYPE { DDR_TYPE_2CH_2RK_4GB_2_2, DDR_TYPE_2CH_2RK_6GB_3_3, @@ -58,7 +57,6 @@ enum DRAM_PARAM_VOLTAGE_TYPE { }; struct dramc_param_header { - u32 checksum; /* checksum of dramc_datas, update in the coreboot */ u16 version; /* DRAMC_PARAM_HEADER_VERSION, update in the coreboot */ u16 size; /* size of whole dramc_param, update in the coreboot */ u16 status; /* DRAMC_PARAM_STATUS_CODES, update in the dram blob */ @@ -141,12 +139,6 @@ struct dramc_param { struct dramc_data dramc_datas; }; -struct dramc_param_ops { - struct dramc_param *param; - bool (*read_from_flash)(struct dramc_param *dparam); - bool (*write_to_flash)(const struct dramc_param *dparam); -}; - struct sdram_info { u32 ddr_geometry; /* DRAMC_PARAM_GEOMETRY_TYPE */ u32 ddr_type; /* DRAMC_PARAM_DDR_TYPE */ diff --git a/src/soc/mediatek/common/include/soc/emi.h b/src/soc/mediatek/common/include/soc/emi.h index c91c8706c4..994d35a8ec 100644 --- a/src/soc/mediatek/common/include/soc/emi.h +++ b/src/soc/mediatek/common/include/soc/emi.h @@ -7,7 +7,8 @@ size_t sdram_size(void); void mt_set_emi(struct dramc_param *dparam); -void mt_mem_init(struct dramc_param_ops *dparam_ops); +void mt_mem_init(struct dramc_param *dparam); +void mtk_dram_init(void); int complex_mem_test(u8 *start, unsigned int len); bool is_dvfs_enabled(void); diff --git a/src/soc/mediatek/common/memory.c b/src/soc/mediatek/common/memory.c index b8bda6e82c..016863503a 100644 --- a/src/soc/mediatek/common/memory.c +++ b/src/soc/mediatek/common/memory.c @@ -5,10 +5,20 @@ #include <cbfs.h> #include <console/console.h> #include <ip_checksum.h> +#include <mrc_cache.h> +#include <soc/dramc_param.h> #include <soc/emi.h> +#include <soc/mmu_operations.h> #include <symbols.h> #include <timer.h> +/* This must be defined in chromeos.fmd in same name and size. */ +#define CALIBRATION_REGION "RW_MRC_CACHE" +#define CALIBRATION_REGION_SIZE 0x2000 + +_Static_assert(sizeof(struct dramc_param) <= CALIBRATION_REGION_SIZE, + "sizeof(struct dramc_param) exceeds " CALIBRATION_REGION); + const char *get_dram_geometry_str(u32 ddr_geometry); const char *get_dram_type_str(u32 ddr_type); @@ -35,12 +45,6 @@ static int mt_mem_test(const struct dramc_data *dparam) return 0; } -static u32 compute_checksum(const struct dramc_param *dparam) -{ - return (u32)compute_ip_checksum(&dparam->dramc_datas, - sizeof(dparam->dramc_datas)); -} - const char *get_dram_geometry_str(u32 ddr_geometry) { const char *s; @@ -93,21 +97,6 @@ const char *get_dram_type_str(u32 ddr_type) static int dram_run_fast_calibration(struct dramc_param *dparam) { - if (!is_valid_dramc_param(dparam)) { - printk(BIOS_WARNING, "DRAM-K: Invalid DRAM calibration data from flash\n"); - dump_param_header((void *)dparam); - return -1; - } - - const u32 checksum = compute_checksum(dparam); - if (dparam->header.checksum != checksum) { - printk(BIOS_ERR, - "DRAM-K: Invalid DRAM calibration checksum from flash " - "(expected: %#x, saved: %#x)\n", - checksum, dparam->header.checksum); - return DRAMC_ERR_INVALID_CHECKSUM; - } - const u16 config = CONFIG(MEDIATEK_DRAM_DVFS) ? DRAMC_ENABLE_DVFS : DRAMC_DISABLE_DVFS; if (dparam->dramc_datas.ddr_info.config_dvfs != config) { printk(BIOS_WARNING, @@ -131,6 +120,7 @@ static int dram_run_full_calibration(struct dramc_param *dparam) struct prog dram = PROG_INIT(PROG_REFCODE, CONFIG_CBFS_PREFIX "/dram"); initialize_dramc_param(dparam); + dump_param_header(dparam); if (cbfs_prog_stage_load(&dram)) { printk(BIOS_ERR, "DRAM-K: CBFS load program failed\n"); @@ -179,16 +169,21 @@ static void mem_init_set_default_config(struct dramc_param *dparam, get_dram_geometry_str(geometry)); } -static void mt_mem_init_run(struct dramc_param_ops *dparam_ops, +static void mt_mem_init_run(struct dramc_param *dparam, const struct sdram_info *dram_info) { - struct dramc_param *dparam = dparam_ops->param; + const ssize_t mrc_cache_size = sizeof(dparam->dramc_datas); + ssize_t data_size; struct stopwatch sw; int ret; /* Load calibration params from flash and run fast calibration */ mem_init_set_default_config(dparam, dram_info); - if (dparam_ops->read_from_flash(dparam)) { + data_size = mrc_cache_load_current(MRC_TRAINING_DATA, + DRAMC_PARAM_HEADER_VERSION, + &dparam->dramc_datas, + mrc_cache_size); + if (data_size == mrc_cache_size) { printk(BIOS_INFO, "DRAM-K: Running fast calibration\n"); stopwatch_init(&sw); @@ -199,15 +194,20 @@ static void mt_mem_init_run(struct dramc_param_ops *dparam_ops, stopwatch_duration_msecs(&sw), ret); /* Erase flash data after fast calibration failed */ - memset(dparam, 0xa5, sizeof(*dparam)); - dparam_ops->write_to_flash(dparam); + memset(&dparam->dramc_datas, 0xa5, mrc_cache_size); + if (mrc_cache_stash_data(MRC_TRAINING_DATA, + DRAMC_PARAM_HEADER_VERSION, + &dparam->dramc_datas, mrc_cache_size)) + printk(BIOS_ERR, "DRAM-K: Failed to erase " + "calibration data\n"); } else { printk(BIOS_INFO, "DRAM-K: Fast calibration passed in %ld msecs\n", stopwatch_duration_msecs(&sw)); return; } } else { - printk(BIOS_WARNING, "DRAM-K: Failed to read calibration data from flash\n"); + printk(BIOS_WARNING, "DRAM-K: Invalid data in flash (size: %#zx, expected: %#zx)\n", + data_size, mrc_cache_size); } /* Run full calibration */ @@ -220,20 +220,32 @@ static void mt_mem_init_run(struct dramc_param_ops *dparam_ops, printk(BIOS_INFO, "DRAM-K: Full calibration passed in %ld msecs\n", stopwatch_duration_msecs(&sw)); - dparam->header.checksum = compute_checksum(dparam); - dparam_ops->write_to_flash(dparam); - printk(BIOS_DEBUG, "DRAM-K: Calibration params saved to flash: " - "version=%#x, size=%#x\n", - dparam->header.version, dparam->header.size); + if (mrc_cache_stash_data(MRC_TRAINING_DATA, + DRAMC_PARAM_HEADER_VERSION, + &dparam->dramc_datas, mrc_cache_size) == 0) + printk(BIOS_DEBUG, "DRAM-K: Calibration params saved " + "to flash: version=%#x, size=%#zx\n", + DRAMC_PARAM_HEADER_VERSION, sizeof(*dparam)); + else + printk(BIOS_ERR, "DRAM-K: Failed to save calibration " + "data to flash\n"); } else { printk(BIOS_ERR, "DRAM-K: Full calibration failed in %ld msecs\n", stopwatch_duration_msecs(&sw)); } } -void mt_mem_init(struct dramc_param_ops *dparam_ops) +void mt_mem_init(struct dramc_param *dparam) { const struct sdram_info *sdram_param = get_sdram_config(); - mt_mem_init_run(dparam_ops, sdram_param); + mt_mem_init_run(dparam, sdram_param); +} + +void mtk_dram_init(void) +{ + /* dramc_param is too large to fit in stack. */ + static struct dramc_param dramc_parameter; + mt_mem_init(&dramc_parameter); + mtk_mmu_after_dram(); } diff --git a/src/soc/mediatek/mt8192/Kconfig b/src/soc/mediatek/mt8192/Kconfig index aa4fb01e9e..eb4aab65fe 100644 --- a/src/soc/mediatek/mt8192/Kconfig +++ b/src/soc/mediatek/mt8192/Kconfig @@ -6,6 +6,7 @@ config SOC_MEDIATEK_MT8192 select ARCH_ROMSTAGE_ARMV8_64 select ARCH_RAMSTAGE_ARMV8_64 select ARM64_USE_ARM_TRUSTED_FIRMWARE + select CACHE_MRC_SETTINGS select HAVE_DEBUG_RAM_SETUP select HAVE_UART_SPECIAL select SOC_MEDIATEK_COMMON |