aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mainboard/google/asurada/chromeos.fmd2
-rw-r--r--src/mainboard/google/asurada/romstage.c41
-rw-r--r--src/soc/mediatek/common/dramc_param.c20
-rw-r--r--src/soc/mediatek/common/include/soc/dramc_param.h18
-rw-r--r--src/soc/mediatek/common/include/soc/emi.h3
-rw-r--r--src/soc/mediatek/common/memory.c80
-rw-r--r--src/soc/mediatek/mt8192/Kconfig1
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 = &param->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