soc/mediatek: Use MRC cache API for asurada

Use the MRC cache API for asurada, and sync dramc_param.h with dram
blob (CL:*3674585). With this change, the checksum, originally stored in
flash, is replaced with a hash in TPM. In addition, in recovery boot,
full calibration will always ne performed, and the cached calibration
data will be cleared from flash.

This change increases ROMSTAGE size from 236K to 264K. Most of the
increase is caused by TPM-related functions.

Add new API mtk_dram_init() to emi.h, so that 'dramc_parameter' can be
moved to soc folder.

With this CL, there is no significant change in boot time. Normal AP
reboot time (fast calibration) is consistently 0.98s as before, so
this change should not affect the result of platform_BootPerf.

BUG=b:170687062
TEST=emerge-asurada coreboot
TEST=Hayato boots with both full and fast calibration
BRANCH=none

Cq-Depend: chrome-internal:3674585, chrome-internal:3704751
Change-Id: Ief942048ce530433a57e8205d3a68ad56235b427
Signed-off-by: Yu-Ping Wu <yupingso@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51620
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
diff --git a/src/soc/mediatek/common/memory.c b/src/soc/mediatek/common/memory.c
index b8bda6e..0168635 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 @@
 	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 @@
 
 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 @@
 	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 @@
 	       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 @@
 			       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 @@
 		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();
 }