summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/mediatek/common/Kconfig7
-rw-r--r--src/soc/mediatek/common/memory.c71
-rw-r--r--src/soc/mediatek/mt8186/Kconfig1
-rw-r--r--src/soc/mediatek/mt8186/include/soc/dramc_param.h42
-rw-r--r--src/soc/mediatek/mt8186/include/soc/dramc_soc.h5
5 files changed, 90 insertions, 36 deletions
diff --git a/src/soc/mediatek/common/Kconfig b/src/soc/mediatek/common/Kconfig
index 7d1e4554bc..27f6cec125 100644
--- a/src/soc/mediatek/common/Kconfig
+++ b/src/soc/mediatek/common/Kconfig
@@ -22,6 +22,13 @@ config MEDIATEK_DRAM_DVFS_LIMIT_FREQ_CNT
This options limit DRAM frequency calibration count from total 7 to 3,
other frequency will directly use the low frequency shu result.
+config MEDIATEK_BLOB_FAST_INIT
+ bool "Enable running fast calibration by blob"
+ default n
+ help
+ This option allows performing fast calibration through different
+ open-source policy.
+
config MEMORY_TEST
bool
default y
diff --git a/src/soc/mediatek/common/memory.c b/src/soc/mediatek/common/memory.c
index 1b18dc7210..3ca36117e9 100644
--- a/src/soc/mediatek/common/memory.c
+++ b/src/soc/mediatek/common/memory.c
@@ -4,6 +4,7 @@
#include <bootmode.h>
#include <cbfs.h>
#include <console/console.h>
+#include <soc/dramc_common.h>
#include <ip_checksum.h>
#include <mrc_cache.h>
#include <soc/dramc_param.h>
@@ -95,31 +96,11 @@ const char *get_dram_type_str(u32 ddr_type)
return s;
}
-static int dram_run_fast_calibration(struct dramc_param *dparam)
-{
- 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,
- "DRAM-K: Incompatible config for calibration data from flash "
- "(expected: %#x, saved: %#x)\n",
- config, dparam->dramc_datas.ddr_info.config_dvfs);
- return -1;
- }
-
- printk(BIOS_INFO, "DRAM-K: DRAM calibration data valid pass\n");
- init_dram_by_params(dparam);
- if (mt_mem_test(&dparam->dramc_datas) == 0)
- return 0;
-
- return DRAMC_ERR_FAST_CALIBRATION;
-}
-
-static int dram_run_full_calibration(struct dramc_param *dparam)
+static int run_dram_blob(struct dramc_param *dparam)
{
/* Load and run the provided blob for full-calibration if available */
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)) {
@@ -132,12 +113,13 @@ static int dram_run_full_calibration(struct dramc_param *dparam)
prog_set_entry(&dram, prog_entry(&dram), dparam);
prog_run(&dram);
if (dparam->header.status != DRAMC_SUCCESS) {
- printk(BIOS_ERR, "DRAM-K: Full calibration failed: status = %d\n",
+ printk(BIOS_ERR, "DRAM-K: calibration failed: status = %d\n",
dparam->header.status);
return -3;
}
- if (!(dparam->header.flags & DRAMC_FLAG_HAS_SAVED_DATA)) {
+ if (!(dparam->header.config & DRAMC_CONFIG_FAST_K)
+ && !(dparam->header.flags & DRAMC_FLAG_HAS_SAVED_DATA)) {
printk(BIOS_ERR,
"DRAM-K: Full calibration executed without saving parameters. "
"Please ensure the blob is built properly.\n");
@@ -147,6 +129,49 @@ static int dram_run_full_calibration(struct dramc_param *dparam)
return 0;
}
+static int dram_run_fast_calibration(struct dramc_param *dparam)
+{
+ 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,
+ "DRAM-K: Incompatible config for calibration data from flash "
+ "(expected: %#x, saved: %#x)\n",
+ config, dparam->dramc_datas.ddr_info.config_dvfs);
+ return -1;
+ }
+
+ printk(BIOS_INFO, "DRAM-K: DRAM calibration data valid pass\n");
+
+ if (CONFIG(MEDIATEK_BLOB_FAST_INIT)) {
+ printk(BIOS_INFO, "DRAM-K: Run fast calibration run in blob mode\n");
+
+ /*
+ * The loaded config should not contain FAST_K (done in full calibration),
+ * so we have to set that now to indicate the blob taking the config instead
+ * of generating a new config.
+ */
+ dparam->header.config |= DRAMC_CONFIG_FAST_K;
+
+ if (run_dram_blob(dparam) < 0)
+ return -3;
+ } else {
+ init_dram_by_params(dparam);
+ }
+
+ if (mt_mem_test(&dparam->dramc_datas) < 0)
+ return -4;
+
+ return 0;
+}
+
+static int dram_run_full_calibration(struct dramc_param *dparam)
+{
+ initialize_dramc_param(dparam);
+
+ return run_dram_blob(dparam);
+}
+
static void mem_init_set_default_config(struct dramc_param *dparam,
const struct sdram_info *dram_info)
{
diff --git a/src/soc/mediatek/mt8186/Kconfig b/src/soc/mediatek/mt8186/Kconfig
index 11a18f2e10..654baf20d0 100644
--- a/src/soc/mediatek/mt8186/Kconfig
+++ b/src/soc/mediatek/mt8186/Kconfig
@@ -9,6 +9,7 @@ config SOC_MEDIATEK_MT8186
select CACHE_MRC_SETTINGS
select HAVE_UART_SPECIAL
select SOC_MEDIATEK_COMMON
+ select MEDIATEK_BLOB_FAST_INIT
if SOC_MEDIATEK_MT8186
diff --git a/src/soc/mediatek/mt8186/include/soc/dramc_param.h b/src/soc/mediatek/mt8186/include/soc/dramc_param.h
index 5559b0a914..b5c019fbff 100644
--- a/src/soc/mediatek/mt8186/include/soc/dramc_param.h
+++ b/src/soc/mediatek/mt8186/include/soc/dramc_param.h
@@ -59,48 +59,53 @@ struct sdram_info {
};
struct sdram_params {
+ /* Sometimes, we may need to compare params member
+ * between coreboot and blob for analysis. Here,
+ * add member size using xxxB.
+ */
+ /* 4 + 4 = 8B */
u32 rank_num;
u16 num_dlycell_perT;
u16 delay_cell_timex100;
- /* duty */
+ /* duty 16B */
s8 duty_clk_delay[CHANNEL_MAX][RANK_MAX];
s8 duty_dqs_delay[CHANNEL_MAX][DQS_NUMBER_LP4];
- s8 duty_wck_delay[CHANNEL_MAX][DQS_NUMBER_LP4];
s8 duty_dq_delay[CHANNEL_MAX][DQS_NUMBER_LP4];
s8 duty_dqm_delay[CHANNEL_MAX][DQS_NUMBER_LP4];
- /* CBT */
+ /* CBT 48B */
u8 cbt_final_vref[CHANNEL_MAX][RANK_MAX];
- s8 cbt_cmd_dly[CHANNEL_MAX][RANK_MAX];
+ u8 cbt_clk_dly[CHANNEL_MAX][RANK_MAX];
+ u8 cbt_cmd_dly[CHANNEL_MAX][RANK_MAX];
u8 cbt_cs_dly[CHANNEL_MAX][RANK_MAX];
u8 cbt_ca_prebit_dly[CHANNEL_MAX][RANK_MAX][DQS_BIT_NUMBER];
- /* write leveling */
+ /* write leveling 8B */
u8 wr_level[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
- /* Gating */
+ /* Gating 32B */
u8 gating_MCK[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
u8 gating_UI[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
u8 gating_PI[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
u8 gating_pass_count[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
- /* TX perbit */
+ /* TX perbit 164B */
u8 tx_window_vref[CHANNEL_MAX][RANK_MAX];
u16 tx_center_min[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
u16 tx_center_max[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
u16 tx_win_center[CHANNEL_MAX][RANK_MAX][DQ_DATA_WIDTH_LP4];
- /* rx datlat */
+ /* rx datlat 4B */
u8 rx_datlat[CHANNEL_MAX][RANK_MAX];
- /* RX perbit */
+ /* RX perbit 88B */
u8 rx_best_vref[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
- u16 rx_perbit_dqs[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
- u16 rx_perbit_dqm[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
- u16 rx_perbit_dq[CHANNEL_MAX][RANK_MAX][DQ_DATA_WIDTH_LP4];
+ u8 rx_perbit_dqs[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
+ u8 rx_perbit_dqm[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
+ u8 rx_perbit_dq[CHANNEL_MAX][RANK_MAX][DQ_DATA_WIDTH_LP4];
- /* TX OE */
+ /* TX OE 16B */
u8 tx_oe_dq_mck[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
u8 tx_oe_dq_ui[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4];
};
@@ -112,6 +117,15 @@ struct emi_mdl {
u32 chn_cona_val;
};
+struct ddr_mrr_info {
+ u16 mr5_vendor_id;
+ u16 mr6_revision_id;
+ u16 mr7_revision_id;
+ u64 mr8_density[RANK_MAX];
+ u32 rank_nums;
+ u8 die_num[RANK_MAX];
+};
+
struct ddr_base_info {
u32 config_dvfs; /* SDRAM_DVFS_FLAG */
struct sdram_info sdram;
@@ -120,6 +134,8 @@ struct ddr_base_info {
u64 rank_size[RANK_MAX];
struct emi_mdl emi_config;
DRAM_CBT_MODE_T cbt_mode[RANK_MAX];
+ struct ddr_mrr_info mrr_info;
+ u32 data_rate;
};
struct dramc_data {
diff --git a/src/soc/mediatek/mt8186/include/soc/dramc_soc.h b/src/soc/mediatek/mt8186/include/soc/dramc_soc.h
index 34e8414d47..5602e144cb 100644
--- a/src/soc/mediatek/mt8186/include/soc/dramc_soc.h
+++ b/src/soc/mediatek/mt8186/include/soc/dramc_soc.h
@@ -15,6 +15,11 @@ typedef enum {
RANK_MAX,
} DRAM_RANK_T;
+typedef enum {
+ RANK_SINGLE = 1,
+ RANK_DUAL,
+} DRAM_RANK_NUMBER_T;
+
/* DRAM SHUFFLE RG type */
typedef enum {
DRAM_DFS_SHUFFLE_1 = 0,