Hung-Te Lin has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/35646 )
Change subject: WIP: Change to use the shared 'dramc_param' module ......................................................................
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 = ¶m->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 = ¶m->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,