Hung-Te Lin has uploaded this change for review.

View Change

WIP: Change to use the shared 'dramc_param' module

A demonstration for how to use the dramc_param module shared with
mtk-dramk blob.

Change-Id: I611490f00a5507caded7321dfc0359fcdf10e4e0
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
---
M src/mainboard/google/kukui/romstage.c
M src/soc/mediatek/mt8183/Makefile.inc
A src/soc/mediatek/mt8183/dramc_param.c
A src/soc/mediatek/mt8183/include/soc/dramc_param.h
M src/soc/mediatek/mt8183/include/soc/emi.h
5 files changed, 151 insertions(+), 56 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/46/35646/1
diff --git a/src/mainboard/google/kukui/romstage.c b/src/mainboard/google/kukui/romstage.c
index cc1def7..f2dd4e4 100644
--- a/src/mainboard/google/kukui/romstage.c
+++ b/src/mainboard/google/kukui/romstage.c
@@ -18,22 +18,22 @@
#include <cbfs.h>
#include <console/console.h>
#include <fmap.h>
+#include <soc/dramc_param.h>
#include <soc/emi.h>
#include <soc/mmu_operations.h>
#include <soc/mt6358.h>
#include <soc/pll.h>
#include <soc/rtc.h>
+#include <string.h>

#include "early_init.h"

-struct params_data calibration_results;
-
#define CALIBRATION_REGION "RW_DDR_TRAINING"
+
static bool read_calibration_data_from_flash(void *data, size_t length)
{
size_t ret = fmap_read_area(CALIBRATION_REGION, data, length);
- printk(BIOS_INFO, "%s: ret=%#lx, length=%#lx\n",
- __func__, ret, length);
+ printk(BIOS_INFO, "%s: ret=%#lx, length=%#lx\n", __func__, ret, length);

return ret == length;
}
@@ -47,25 +47,16 @@
return ret == length;
}

+/* dramc_param is ~2K and too large to fit in stack. */
+static struct dramc_param dparam;
+
void clean_calibration_data(void)
{
- size_t ret;
- struct params_data *params_result = &calibration_results;
- size_t length = sizeof(calibration_results);
-
- if (read_calibration_data_from_flash(params_result, length) &&
- have_calibration_params(params_result->freq_params)) {
- /* reset all params to 0 */
- memset(params_result, 0x0, length);
-
- ret = fmap_overwrite_area(CALIBRATION_REGION,
- params_result, length);
- printk(BIOS_INFO, "%s: ret=%#lx, length=%#lx\n",
- __func__, ret, length);
- }
+ dparam.header.status = DRAMC_ERR_RECALIBRATE;
+ fmap_overwrite_area(CALIBRATION_REGION, &dparam, sizeof(dparam));
}

-static int dram_run_full_calibration(struct params_data *params_result)
+static int dram_run_full_calibration(struct dramc_param *param)
{
/* Load and run the provided blob for full-calibration if available */
struct prog dram = PROG_INIT(PROG_REFCODE, CONFIG_CBFS_PREFIX "/dram");
@@ -76,10 +67,9 @@
if (cbfs_prog_stage_load(&dram))
return -2;

- prog_set_entry(&dram, prog_entry(&dram), params_result);
+ prog_set_entry(&dram, prog_entry(&dram), param);
prog_run(&dram);
-
- return 0;
+ return param->header.status == DRAMC_SUCCESS;
}

static void init_sdram_params(struct sdram_params *dst,
@@ -92,30 +82,28 @@

static void dram_initialize(void)
{
- u16 is_emcp = 0;
- struct params_data *params_result = &calibration_results;
- size_t length = sizeof(calibration_results);
- struct sdram_params *freq_params = params_result->freq_params;
+ struct sdram_params *freq_params = &dparam.freq_params[0];

- if (!read_calibration_data_from_flash(params_result, length) &&
- (params_result->param_header.pl_version != PARAM_PL_VERSION)) {
+ u32 flags = 0;
+ if (CONFIG(MT8183_DRAM_EMCP))
+ flags |= DRAMC_FLAG_HAS_EMCP;

- /* EMCP devices should run 3600Mbps for high frequency calibartion */
- is_emcp = CONFIG(MT8183_DRAM_EMCP) ? PARAM_EMCP_MAGIC : 0;
- params_result->param_header.is_emcp = is_emcp;
- printk(BIOS_INFO, "is_emcp current DDR type is %s\n",
- (is_emcp == PARAM_EMCP_MAGIC) ? "EMCP" : "Discrete");
- /* try to re-run DRAM full calibration if avalible */
- int err = dram_run_full_calibration(params_result);
+ if (!read_calibration_data_from_flash(&dparam, sizeof(dparam)) ||
+ !is_valid_dramc_param(&dparam) ||
+ dparam.header.flags != flags) {
+
+ initialize_dramc_param(&dparam, flags);
+ /* try to re-run DRAM full calibration if available */
+ int err = dram_run_full_calibration(&dparam);
if (err == 0) {
printk(BIOS_INFO, "successfully load dram_blob and "
"run DRAM calibration\n");

- printk(BIOS_INFO, "save params to flash. pl_version: 0x%x, body_size: 0x%x\n",
- params_result->param_header.pl_version,
- params_result->param_header.body_size);
+ printk(BIOS_INFO, "save params to flash. pl_version: %#x, body_size: %#x\n",
+ dparam.header.version,
+ dparam.header.size);

- write_calibration_data_to_flash(freq_params, length);
+ write_calibration_data_to_flash(&dparam, sizeof(dparam));
return;
}

@@ -124,11 +112,8 @@

/* init params setting from sdram configs if no have dram calibraion result */
init_sdram_params(freq_params, get_sdram_config());
- mt_mem_init(freq_params);
- } else {
- printk(BIOS_INFO, "have dram calibraion params\n");
- mt_mem_init(freq_params);
}
+ mt_mem_init(freq_params);
}

void platform_romstage_main(void)
diff --git a/src/soc/mediatek/mt8183/Makefile.inc b/src/soc/mediatek/mt8183/Makefile.inc
index b6c3a33..27591df 100644
--- a/src/soc/mediatek/mt8183/Makefile.inc
+++ b/src/soc/mediatek/mt8183/Makefile.inc
@@ -27,6 +27,7 @@
romstage-y += auxadc.c
romstage-y += ../common/cbmem.c emi.c
romstage-y += dramc_init_setting.c
+romstage-y += dramc_param.c
romstage-y += dramc_pi_basic_api.c
romstage-y += dramc_pi_calibration_api.c
romstage-y += memory.c
diff --git a/src/soc/mediatek/mt8183/dramc_param.c b/src/soc/mediatek/mt8183/dramc_param.c
new file mode 100644
index 0000000..31d71c7
--- /dev/null
+++ b/src/soc/mediatek/mt8183/dramc_param.c
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2019 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <string.h>
+#include "soc/dramc_param.h"
+
+struct dramc_param *get_dramc_param_from_blob(void *blob)
+{
+ return (struct dramc_param *)blob;
+}
+
+int validate_dramc_param(const void *blob)
+{
+ const struct dramc_param *param = blob;
+ const struct dramc_param_header *hdr = &param->header;
+
+ if (hdr->magic != DRAMC_PARAM_HEADER_MAGIC)
+ return DRAMC_ERR_INVALID_MAGIC;
+
+ if (hdr->version != DRAMC_PARAM_HEADER_VERSION)
+ return DRAMC_ERR_INVALID_VERSION;
+
+ if (hdr->size != sizeof(*param))
+ return DRAMC_ERR_INVALID_SIZE;
+
+ /* TODO(hungte) Verify and check hdr->checksum. */
+ return DRAMC_SUCCESS;
+}
+
+int is_valid_dramc_param(const void *blob)
+{
+ return validate_dramc_param(blob) == DRAMC_SUCCESS;
+}
+
+int initialize_dramc_param(void *blob, u32 flags)
+{
+ struct dramc_param *param = blob;
+ struct dramc_param_header *hdr = &param->header;
+
+ memset(blob, 0, sizeof(*param));
+ hdr->magic = DRAMC_PARAM_HEADER_MAGIC;
+ hdr->size = sizeof(*param);
+ hdr->version = DRAMC_PARAM_HEADER_VERSION;
+ hdr->flags = flags;
+ return 0;
+}
+
diff --git a/src/soc/mediatek/mt8183/include/soc/dramc_param.h b/src/soc/mediatek/mt8183/include/soc/dramc_param.h
new file mode 100644
index 0000000..aa8a4e8
--- /dev/null
+++ b/src/soc/mediatek/mt8183/include/soc/dramc_param.h
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2019 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef SOC_MEDIATEK_MT8183_DRAMC_PARAM_H
+#define SOC_MEDIATEK_MT8183_DRAMC_PARAM_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "emi.h"
+
+enum {
+ DRAMC_PARAM_HEADER_MAGIC = 0x44524d4b,
+ DRAMC_PARAM_HEADER_VERSION = 1,
+};
+
+enum DRAMC_PARAM_STATUS_CODES {
+ DRAMC_SUCCESS = 0,
+ DRAMC_ERR_INVALID_MAGIC,
+ DRAMC_ERR_INVALID_VERSION,
+ DRAMC_ERR_INVALID_SIZE,
+ DRAMC_ERR_INVALID_CHECKSUM,
+ DRAMC_ERR_INVALID_FLAGS,
+ DRAMC_ERR_RECALIBRATE,
+};
+
+/* Bit flags. */
+enum DRAMC_PARAM_FLAGS {
+ DRAMC_FLAG_HAS_EMCP = 0x0001,
+};
+
+struct dramc_param_header {
+ u32 status; /* DRAMC_PARAM_STATUS_CODES */
+ u32 magic;
+ u32 version;
+ u32 size; /* size of whole dramc_param */
+ u32 flags; /* DRAMC_PARAM_FLAGS */
+ u32 checksum;
+};
+
+struct dramc_param {
+ struct dramc_param_header header;
+ struct sdram_params freq_params[DRAM_DFS_SHUFFLE_MAX];
+};
+
+struct dramc_param *get_dramc_param_from_blob(void *blob);
+int validate_dramc_param(const void *blob);
+int is_valid_dramc_param(const void *blob);
+int initialize_dramc_param(void *blob, u32 flags);
+
+#endif /* SOC_MEDIATEK_MT8183_DRAMC_PARAM_H */
diff --git a/src/soc/mediatek/mt8183/include/soc/emi.h b/src/soc/mediatek/mt8183/include/soc/emi.h
index a4b9150..be10bf5 100644
--- a/src/soc/mediatek/mt8183/include/soc/emi.h
+++ b/src/soc/mediatek/mt8183/include/soc/emi.h
@@ -22,14 +22,6 @@

#define PARAM_START_PATTERN 0x5a5a
#define PARAM_END_PATTERN 0x3c3c
-#define PARAM_PL_VERSION 0x20190927
-#define PARAM_EMCP_MAGIC 0x5acc
-
-struct sdram_params_header {
- u32 pl_version;
- u16 is_emcp;
- u16 body_size;
-};

struct sdram_params {
u16 calibration_result_start;
@@ -77,11 +69,6 @@
u16 calibration_result_end;
};

-struct params_data {
- struct sdram_params_header param_header;
- struct sdram_params freq_params[DRAM_DFS_SHUFFLE_MAX];
-};
-
enum {
LP4X_DDR1600,
LP4X_DDR2400,

To view, visit change 35646. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I611490f00a5507caded7321dfc0359fcdf10e4e0
Gerrit-Change-Number: 35646
Gerrit-PatchSet: 1
Gerrit-Owner: Hung-Te Lin <hungte@chromium.org>
Gerrit-MessageType: newchange