From e8c681cc6249cc7717885a12373e4fcf34034b1c Mon Sep 17 00:00:00 2001 From: Xi Chen Date: Wed, 3 Mar 2021 17:58:07 +0800 Subject: soc/mediatek/common: Move DRAM implementation from mt8192 to common To reduce duplicated dram sources on seperate SOCs, add dpm, dram_init, dramc_params, memory(fast-k or full-k) implementations, also add dramc log level macro header files. Signed-off-by: Xi Chen Change-Id: I557c96b3d09828472b8b6f932b0192a90894043e Reviewed-on: https://review.coreboot.org/c/coreboot/+/51203 Tested-by: build bot (Jenkins) Reviewed-by: Hung-Te Lin --- src/soc/mediatek/common/Kconfig | 32 +++ src/soc/mediatek/common/dpm.c | 47 ++++ src/soc/mediatek/common/dram_init.c | 37 ++++ src/soc/mediatek/common/dramc_param.c | 56 +++++ src/soc/mediatek/common/include/soc/dpm.h | 49 +++++ src/soc/mediatek/common/include/soc/dramc_common.h | 17 ++ src/soc/mediatek/common/include/soc/dramc_param.h | 161 ++++++++++++++ src/soc/mediatek/common/include/soc/emi.h | 18 ++ src/soc/mediatek/common/memory.c | 244 +++++++++++++++++++++ src/soc/mediatek/mt8173/Kconfig | 5 +- src/soc/mediatek/mt8183/Kconfig | 5 +- src/soc/mediatek/mt8192/Kconfig | 1 + src/soc/mediatek/mt8192/Makefile.inc | 5 +- src/soc/mediatek/mt8192/dpm.c | 47 ---- src/soc/mediatek/mt8192/dramc_param.c | 56 ----- src/soc/mediatek/mt8192/emi.c | 4 +- src/soc/mediatek/mt8192/include/soc/dpm.h | 49 ----- .../mt8192/include/soc/dramc_common_mt8192.h | 19 -- src/soc/mediatek/mt8192/include/soc/dramc_param.h | 156 ------------- src/soc/mediatek/mt8192/include/soc/dramc_soc.h | 47 ++++ src/soc/mediatek/mt8192/include/soc/emi.h | 13 -- src/soc/mediatek/mt8192/memory.c | 187 ---------------- 22 files changed, 716 insertions(+), 539 deletions(-) create mode 100644 src/soc/mediatek/common/Kconfig create mode 100644 src/soc/mediatek/common/dpm.c create mode 100644 src/soc/mediatek/common/dram_init.c create mode 100644 src/soc/mediatek/common/dramc_param.c create mode 100644 src/soc/mediatek/common/include/soc/dpm.h create mode 100644 src/soc/mediatek/common/include/soc/dramc_common.h create mode 100644 src/soc/mediatek/common/include/soc/dramc_param.h create mode 100644 src/soc/mediatek/common/include/soc/emi.h create mode 100644 src/soc/mediatek/common/memory.c delete mode 100644 src/soc/mediatek/mt8192/dpm.c delete mode 100644 src/soc/mediatek/mt8192/dramc_param.c delete mode 100644 src/soc/mediatek/mt8192/include/soc/dpm.h delete mode 100644 src/soc/mediatek/mt8192/include/soc/dramc_param.h create mode 100644 src/soc/mediatek/mt8192/include/soc/dramc_soc.h delete mode 100644 src/soc/mediatek/mt8192/include/soc/emi.h delete mode 100644 src/soc/mediatek/mt8192/memory.c diff --git a/src/soc/mediatek/common/Kconfig b/src/soc/mediatek/common/Kconfig new file mode 100644 index 000000000000..543bc02d1363 --- /dev/null +++ b/src/soc/mediatek/common/Kconfig @@ -0,0 +1,32 @@ +config SOC_MEDIATEK_COMMON + bool + help + common code blocks for Mediatek SOCs + +if SOC_MEDIATEK_COMMON + +config MEDIATEK_DRAM_DVFS + bool + default n + help + This option enables DRAM calibration with multiple frequencies (low, + medium and high frequency groups, with total 7 frequencies) for DVFS + feature. All supported data rates are: 800, 1200, 1600, 1866, 2400, + 3200, 4266. + +config MEDIATEK_DRAM_DVFS_LIMIT_FREQ_CNT + bool + default y + select MEDIATEK_DRAM_DVFS + help + This options limit DRAM frequency calibration count from total 7 to 3, + other frequency will directly use the low frequency shu result. + +config MEMORY_TEST + bool + default y + help + This option enables memory basic compare test to verify the DRAM read + or write is as expected. + +endif diff --git a/src/soc/mediatek/common/dpm.c b/src/soc/mediatek/common/dpm.c new file mode 100644 index 000000000000..991441e74cf0 --- /dev/null +++ b/src/soc/mediatek/common/dpm.c @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +static void reset_dpm(struct mtk_mcu *mcu) +{ + /* write bootargs */ + write32(&mtk_dpm->twam_window_len, 0x0); + write32(&mtk_dpm->twam_mon_type, 0x0); + + /* free RST */ + setbits32(&mtk_dpm->sw_rstn, DPM_SW_RSTN_RESET); +} + +static struct mtk_mcu dpm_mcu[] = { + { + .firmware_name = CONFIG_DPM_DM_FIRMWARE, + .run_address = (void *)DPM_DM_SRAM_BASE, + }, + { + .firmware_name = CONFIG_DPM_PM_FIRMWARE, + .run_address = (void *)DPM_PM_SRAM_BASE, + .reset = reset_dpm, + }, +}; + +int dpm_init(void) +{ + int i; + struct mtk_mcu *dpm; + + /* config DPM SRAM layout */ + clrsetbits32(&mtk_dpm->sw_rstn, DPM_MEM_RATIO_MASK, DPM_MEM_RATIO_CFG1); + + for (i = 0; i < ARRAY_SIZE(dpm_mcu); i++) { + dpm = &dpm_mcu[i]; + dpm->load_buffer = _dram_dma; + dpm->buffer_size = REGION_SIZE(dram_dma); + if (mtk_init_mcu(dpm)) + return -1; + } + + return 0; +} diff --git a/src/soc/mediatek/common/dram_init.c b/src/soc/mediatek/common/dram_init.c new file mode 100644 index 000000000000..accc7ac5e78e --- /dev/null +++ b/src/soc/mediatek/common/dram_init.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include + +struct dramc_param *dramc_params; + +bool is_dvfs_enabled(void) +{ + dramc_info("dram_init: config_dvfs: %d\n", + dramc_params->dramc_datas.ddr_info.config_dvfs); + return !!(dramc_params->dramc_datas.ddr_info.config_dvfs); +} + +u32 get_ddr_geometry(void) +{ + dramc_info("dram_init: ddr_geometry: %d\n", + dramc_params->dramc_datas.ddr_info.ddr_geometry); + return dramc_params->dramc_datas.ddr_info.ddr_geometry; +} + +u32 get_ddr_type(void) +{ + dramc_info("dram_init: ddr_type: %d\n", + dramc_params->dramc_datas.ddr_info.ddr_type); + return dramc_params->dramc_datas.ddr_info.ddr_type; +} + +void init_dram_by_params(struct dramc_param *dparam) +{ + dramc_params = dparam; + mt_set_emi(dramc_params); +} diff --git a/src/soc/mediatek/common/dramc_param.c b/src/soc/mediatek/common/dramc_param.c new file mode 100644 index 000000000000..8548dbc66513 --- /dev/null +++ b/src/soc/mediatek/common/dramc_param.c @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +#define print(_x_...) printk(BIOS_INFO, _x_) + +struct dramc_param *get_dramc_param_from_blob(void *blob) +{ + return (struct dramc_param *)blob; +} + +void dump_param_header(const void *blob) +{ + const struct dramc_param *dparam = blob; + const struct dramc_param_header *header = &dparam->header; + + print("header.status = %#x\n", header->status); + print("header.version = %#x (expected: %#x)\n", + header->version, DRAMC_PARAM_HEADER_VERSION); + 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 = ¶m->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) +{ + struct dramc_param *param = blob; + struct dramc_param_header *hdr = ¶m->header; + + memset(hdr, 0, sizeof(*hdr)); + hdr->version = DRAMC_PARAM_HEADER_VERSION; + hdr->size = sizeof(*param); + return 0; +} diff --git a/src/soc/mediatek/common/include/soc/dpm.h b/src/soc/mediatek/common/include/soc/dpm.h new file mode 100644 index 000000000000..7262e09a6f5f --- /dev/null +++ b/src/soc/mediatek/common/include/soc/dpm.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_DPM_H__ +#define __SOC_MEDIATEK_DPM_H__ + +#include +#include +#include + +struct dpm_regs { + u32 sw_rstn; + u32 rsvd_0[3072]; + u32 mclk_div; + u32 rsvd_1[3071]; + u32 twam_window_len; + u32 twam_mon_type; + u32 rsvd_2[1022]; + u32 low_power_cfg_0; + u32 low_power_cfg_1; + u32 rsvd_3[1]; + u32 fsm_out_ctrl_0; + u32 rsvd_4[8]; + u32 fsm_cfg_1; + u32 low_power_cfg_3; + u32 dfd_dbug_0; + u32 rsvd_5[28]; + u32 status_4; +}; + +check_member(dpm_regs, mclk_div, 0x3004); +check_member(dpm_regs, twam_window_len, 0x6004); +check_member(dpm_regs, low_power_cfg_0, 0x7004); +check_member(dpm_regs, low_power_cfg_1, 0x7008); +check_member(dpm_regs, fsm_out_ctrl_0, 0x7010); +check_member(dpm_regs, fsm_cfg_1, 0x7034); +check_member(dpm_regs, low_power_cfg_3, 0x7038); +check_member(dpm_regs, dfd_dbug_0, 0x703C); +check_member(dpm_regs, status_4, 0x70B0); + +#define DPM_SW_RSTN_RESET BIT(0) +#define DPM_MEM_RATIO_OFFSET 28 +#define DPM_MEM_RATIO_MASK (0x3 << DPM_MEM_RATIO_OFFSET) +#define DPM_MEM_RATIO_CFG1 (1 << DPM_MEM_RATIO_OFFSET) + +static struct dpm_regs *const mtk_dpm = (void *)DPM_CFG_BASE; + +int dpm_init(void); + +#endif /* __SOC_MEDIATEK_MT8192_DPM_H__ */ diff --git a/src/soc/mediatek/common/include/soc/dramc_common.h b/src/soc/mediatek/common/include/soc/dramc_common.h new file mode 100644 index 000000000000..a5716dc50f9c --- /dev/null +++ b/src/soc/mediatek/common/include/soc/dramc_common.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_DRAMC_COMMON_H__ +#define __SOC_MEDIATEK_DRAMC_COMMON_H__ + +#include + +#define dramc_err(_x_...) printk(BIOS_ERR, _x_) +#define dramc_info(_x_...) printk(BIOS_INFO, _x_) +#define dramc_show dramc_info +#define dramc_dbg(_x_...) \ + do { \ + if (CONFIG(DEBUG_RAM_SETUP)) \ + printk(BIOS_INFO, _x_); \ + } while (0) + +#endif diff --git a/src/soc/mediatek/common/include/soc/dramc_param.h b/src/soc/mediatek/common/include/soc/dramc_param.h new file mode 100644 index 000000000000..d3eda8da92ed --- /dev/null +++ b/src/soc/mediatek/common/include/soc/dramc_param.h @@ -0,0 +1,161 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_DRAMC_PARAM_H__ +#define __SOC_MEDIATEK_DRAMC_PARAM_H__ + +/* any change in this file should sync to blob dramc_param.h */ + +#include +#include +#include + +enum { + DRAMC_PARAM_HEADER_VERSION = 5, +}; + +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, + DRAMC_ERR_COMPLEX_RW_MEM_TEST, + DRAMC_ERR_1ST_COMPLEX_RW_MEM_TEST, + DRAMC_ERR_2ND_COMPLEX_RW_MEM_TEST, + DRAMC_ERR_FAST_CALIBRATION, +}; + +enum DRAMC_PARAM_DVFS_FLAG { + DRAMC_DISABLE_DVFS, + DRAMC_ENABLE_DVFS, +}; + +enum DRAMC_PARAM_FLAGS { + DRAMC_FLAG_HAS_SAVED_DATA = 0x0001, +}; + +enum DRAMC_PARAM_DDR_TYPE { + DDR_TYPE_DISCRETE, + 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, + DDR_TYPE_2CH_2RK_8GB_4_4_BYTE, + DDR_TYPE_2CH_1RK_4GB_4_0, + DDR_TYPE_2CH_2RK_6GB_2_4, + DDR_TYPE_2CH_2RK_8GB_4_4, +}; + +enum DRAM_PARAM_VOLTAGE_TYPE { + DRAM_VOLTAGE_NVCORE_NVDRAM, + DRAM_VOLTAGE_HVCORE_HVDRAM, + DRAM_VOLTAGE_LVCORE_LVDRAM, +}; + +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 */ + u16 flags; /* DRAMC_PARAM_FLAGS, update in the dram blob */ +}; + +struct sdram_params { + u32 rank_num; + u16 num_dlycell_perT; + u16 delay_cell_timex100; + + /* duty */ + 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 */ + u8 cbt_final_vref[CHANNEL_MAX][RANK_MAX]; + s8 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 */ + u8 wr_level[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4]; + + /* Gating */ + 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 */ + 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 */ + u8 rx_datlat[CHANNEL_MAX][RANK_MAX]; + + /* RX perbit */ + 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]; + + /* TX OE */ + u8 tx_oe_dq_mck[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4]; + u8 tx_oe_dq_ui[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4]; +}; + +struct emi_mdl { + u32 cona_val; + u32 conh_val; + u32 conf_val; + u32 chn_cona_val; +}; + +struct ddr_base_info { + u32 config_dvfs; /* DRAMC_PARAM_DVFS_FLAG */ + u32 ddr_type; /* DRAMC_PARAM_DDR_TYPE */ + u32 ddr_geometry; /* DRAMC_PARAM_GEOMETRY_TYPE */ + u32 voltage_type; /* DRAM_PARAM_VOLTAGE_TYPE */ + u32 support_ranks; + u64 rank_size[RANK_MAX]; + struct emi_mdl emi_config; + dram_cbt_mode cbt_mode[RANK_MAX]; +}; + +struct dramc_data { + struct ddr_base_info ddr_info; + struct sdram_params freq_params[DRAM_DFS_SHU_MAX]; +}; + +struct dramc_param { + struct dramc_param_header header; + void (*do_putc)(unsigned char c); + 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 */ +}; + +const struct sdram_info *get_sdram_config(void); +struct dramc_param *get_dramc_param_from_blob(void *blob); +void dump_param_header(const void *blob); +int validate_dramc_param(const void *blob); +int is_valid_dramc_param(const void *blob); +int initialize_dramc_param(void *blob); +#endif /* __SOC_MEDIATEK_DRAMC_PARAM_H__ */ diff --git a/src/soc/mediatek/common/include/soc/emi.h b/src/soc/mediatek/common/include/soc/emi.h new file mode 100644 index 000000000000..c91c8706c4e7 --- /dev/null +++ b/src/soc/mediatek/common/include/soc/emi.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SOC_MEDIATEK_EMI_H +#define SOC_MEDIATEK_EMI_H + +#include + +size_t sdram_size(void); +void mt_set_emi(struct dramc_param *dparam); +void mt_mem_init(struct dramc_param_ops *dparam_ops); +int complex_mem_test(u8 *start, unsigned int len); + +bool is_dvfs_enabled(void); +u32 get_ddr_geometry(void); +u32 get_ddr_type(void); +void init_dram_by_params(struct dramc_param *dparam); + +#endif /* SOC_MEDIATEK_MT8192_EMI_H */ diff --git a/src/soc/mediatek/common/memory.c b/src/soc/mediatek/common/memory.c new file mode 100644 index 000000000000..2cc05713a13d --- /dev/null +++ b/src/soc/mediatek/common/memory.c @@ -0,0 +1,244 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include + +const char *get_dram_geometry_str(u32 ddr_geometry); +const char *get_dram_type_str(u32 ddr_type); + +static int mt_mem_test(const struct dramc_data *dparam) +{ + if (CONFIG(MEMORY_TEST)) { + u8 *addr = _dram; + const struct ddr_base_info *ddr_info = &dparam->ddr_info; + + for (u8 rank = RANK_0; rank < ddr_info->support_ranks; rank++) { + int result = complex_mem_test(addr, 0x2000); + + if (result != 0) { + printk(BIOS_ERR, + "[MEM] complex R/W mem test failed: %d\n", result); + return -1; + } + printk(BIOS_DEBUG, "[MEM] rank %u complex R/W mem test passed\n", rank); + + addr += ddr_info->rank_size[rank]; + } + } + + 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; + + switch (ddr_geometry) { + case DDR_TYPE_2CH_2RK_4GB_2_2: + s = "2CH_2RK_4GB_2_2"; + break; + case DDR_TYPE_2CH_2RK_6GB_3_3: + s = "2CH_2RK_6GB_3_3"; + break; + case DDR_TYPE_2CH_2RK_8GB_4_4: + s = "2CH_2RK_8GB_4_4"; + break; + case DDR_TYPE_2CH_2RK_8GB_4_4_BYTE: + s = "2CH_2RK_8GB_4_4_BYTE"; + break; + case DDR_TYPE_2CH_1RK_4GB_4_0: + s = "2CH_1RK_4GB_4_0"; + break; + case DDR_TYPE_2CH_2RK_6GB_2_4: + s = "2CH_2RK_6GB_2_4"; + break; + default: + s = ""; + break; + } + + return s; +} + +const char *get_dram_type_str(u32 ddr_type) +{ + const char *s; + + switch (ddr_type) { + case DDR_TYPE_DISCRETE: + s = "DSC"; + break; + case DDR_TYPE_EMCP: + s = "EMCP"; + break; + default: + s = ""; + break; + } + + return s; +} + +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, + "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) +{ + /* 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); + + if (prog_locate(&dram)) { + printk(BIOS_ERR, "DRAM-K: Locate program failed\n"); + return -1; + } + + if (cbfs_prog_stage_load(&dram)) { + printk(BIOS_ERR, "DRAM-K: CBFS load program failed\n"); + return -2; + } + + dparam->do_putc = do_putchar; + + 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", + dparam->header.status); + return -3; + } + + if (!(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"); + return -4; + } + + return 0; +} + +static void mem_init_set_default_config(struct dramc_param *dparam, + const struct sdram_info *dram_info) +{ + u32 type, geometry; + memset(dparam, 0, sizeof(*dparam)); + + type = dram_info->ddr_type; + geometry = dram_info->ddr_geometry; + + dparam->dramc_datas.ddr_info.ddr_type = type; + + if (CONFIG(MEDIATEK_DRAM_DVFS)) + dparam->dramc_datas.ddr_info.config_dvfs = DRAMC_ENABLE_DVFS; + + dparam->dramc_datas.ddr_info.ddr_geometry = geometry; + + printk(BIOS_INFO, "DRAM-K: ddr_type: %s, config_dvfs: %d, ddr_geometry: %s\n", + get_dram_type_str(type), + dparam->dramc_datas.ddr_info.config_dvfs, + get_dram_geometry_str(geometry)); +} + +static void mt_mem_init_run(struct dramc_param_ops *dparam_ops, + const struct sdram_info *dram_info) +{ + struct dramc_param *dparam = dparam_ops->param; + 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)) { + printk(BIOS_INFO, "DRAM-K: Running fast calibration\n"); + stopwatch_init(&sw); + + ret = dram_run_fast_calibration(dparam); + if (ret != 0) { + printk(BIOS_ERR, "DRAM-K: Failed to run fast calibration " + "in %ld msecs, error: %d\n", + stopwatch_duration_msecs(&sw), ret); + + /* Erase flash data after fast calibration failed */ + memset(dparam, 0xa5, sizeof(*dparam)); + dparam_ops->write_to_flash(dparam); + } 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"); + } + + /* Run full calibration */ + printk(BIOS_INFO, "DRAM-K: Running full calibration\n"); + mem_init_set_default_config(dparam, dram_info); + + stopwatch_init(&sw); + int err = dram_run_full_calibration(dparam); + if (err == 0) { + 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); + } 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) +{ + const struct sdram_info *sdram_param = get_sdram_config(); + + mt_mem_init_run(dparam_ops, sdram_param); +} diff --git a/src/soc/mediatek/mt8173/Kconfig b/src/soc/mediatek/mt8173/Kconfig index 15b833f56f5f..bf5316417851 100644 --- a/src/soc/mediatek/mt8173/Kconfig +++ b/src/soc/mediatek/mt8173/Kconfig @@ -10,6 +10,7 @@ config SOC_MEDIATEK_MT8173 select HAVE_UART_SPECIAL select GENERIC_GPIO_LIB select RTC + select SOC_MEDIATEK_COMMON if SOC_MEDIATEK_MT8173 @@ -22,10 +23,6 @@ config VBOOT select VBOOT_STARTS_IN_BOOTBLOCK select VBOOT_SEPARATE_VERSTAGE -config MEMORY_TEST - bool - default n - config DEBUG_SOC_DRIVER bool "The top level switch for soc driver debug messages" default n diff --git a/src/soc/mediatek/mt8183/Kconfig b/src/soc/mediatek/mt8183/Kconfig index ce99c76c8c3c..5a0a76554873 100644 --- a/src/soc/mediatek/mt8183/Kconfig +++ b/src/soc/mediatek/mt8183/Kconfig @@ -8,6 +8,7 @@ config SOC_MEDIATEK_MT8183 select ARM64_USE_ARM_TRUSTED_FIRMWARE select HAVE_UART_SPECIAL select COMPRESS_BOOTBLOCK + select SOC_MEDIATEK_COMMON if SOC_MEDIATEK_MT8183 @@ -41,10 +42,6 @@ config MT8183_DRAM_DVFS This options enables DRAM calibration with multiple frequencies (low, medium and high) for DVFS feature. -config MEMORY_TEST - bool - default y - config SSPM_FIRMWARE string default "sspm.bin" diff --git a/src/soc/mediatek/mt8192/Kconfig b/src/soc/mediatek/mt8192/Kconfig index e2d7eeac13c6..9c7a9af9abfb 100644 --- a/src/soc/mediatek/mt8192/Kconfig +++ b/src/soc/mediatek/mt8192/Kconfig @@ -7,6 +7,7 @@ config SOC_MEDIATEK_MT8192 select ARCH_RAMSTAGE_ARMV8_64 select ARM64_USE_ARM_TRUSTED_FIRMWARE select HAVE_UART_SPECIAL + select SOC_MEDIATEK_COMMON if SOC_MEDIATEK_MT8192 diff --git a/src/soc/mediatek/mt8192/Makefile.inc b/src/soc/mediatek/mt8192/Makefile.inc index f5742a36f2e2..a87291676316 100644 --- a/src/soc/mediatek/mt8192/Makefile.inc +++ b/src/soc/mediatek/mt8192/Makefile.inc @@ -28,6 +28,7 @@ verstage-y += ../common/uart.c romstage-y += ../common/auxadc.c romstage-y += ../common/cbmem.c +romstage-y += ../common/dram_init.c romstage-y += dramc_pi_main.c dramc_pi_basic_api.c dramc_pi_calibration_api.c romstage-y += dramc_utility.c dramc_dvfs.c romstage-y += emi.c @@ -35,7 +36,7 @@ romstage-y += ../common/flash_controller.c romstage-y += ../common/gpio.c gpio.c romstage-y += ../common/i2c.c i2c.c romstage-y += ../common/mmu_operations.c mmu_operations.c -romstage-y += memory.c dramc_param.c ../common/memory_test.c +romstage-y += ../common/memory.c ../common/dramc_param.c ../common/memory_test.c romstage-y += ../common/pll.c pll.c romstage-$(CONFIG_SPI_FLASH) += ../common/spi.c spi.c romstage-y += ../common/timer.c @@ -47,7 +48,7 @@ romstage-y += mt6359p.c ramstage-y += ../common/auxadc.c ramstage-y += ../common/ddp.c ddp.c ramstage-y += devapc.c -ramstage-y += dpm.c +ramstage-y += ../common/dpm.c ramstage-y += ../common/dsi.c ../common/mtk_mipi_dphy.c ramstage-y += ../common/flash_controller.c ramstage-y += ../common/gpio.c gpio.c diff --git a/src/soc/mediatek/mt8192/dpm.c b/src/soc/mediatek/mt8192/dpm.c deleted file mode 100644 index 991441e74cf0..000000000000 --- a/src/soc/mediatek/mt8192/dpm.c +++ /dev/null @@ -1,47 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -static void reset_dpm(struct mtk_mcu *mcu) -{ - /* write bootargs */ - write32(&mtk_dpm->twam_window_len, 0x0); - write32(&mtk_dpm->twam_mon_type, 0x0); - - /* free RST */ - setbits32(&mtk_dpm->sw_rstn, DPM_SW_RSTN_RESET); -} - -static struct mtk_mcu dpm_mcu[] = { - { - .firmware_name = CONFIG_DPM_DM_FIRMWARE, - .run_address = (void *)DPM_DM_SRAM_BASE, - }, - { - .firmware_name = CONFIG_DPM_PM_FIRMWARE, - .run_address = (void *)DPM_PM_SRAM_BASE, - .reset = reset_dpm, - }, -}; - -int dpm_init(void) -{ - int i; - struct mtk_mcu *dpm; - - /* config DPM SRAM layout */ - clrsetbits32(&mtk_dpm->sw_rstn, DPM_MEM_RATIO_MASK, DPM_MEM_RATIO_CFG1); - - for (i = 0; i < ARRAY_SIZE(dpm_mcu); i++) { - dpm = &dpm_mcu[i]; - dpm->load_buffer = _dram_dma; - dpm->buffer_size = REGION_SIZE(dram_dma); - if (mtk_init_mcu(dpm)) - return -1; - } - - return 0; -} diff --git a/src/soc/mediatek/mt8192/dramc_param.c b/src/soc/mediatek/mt8192/dramc_param.c deleted file mode 100644 index f8f6c7dd146f..000000000000 --- a/src/soc/mediatek/mt8192/dramc_param.c +++ /dev/null @@ -1,56 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -#define print(_x_...) printk(BIOS_INFO, _x_) - -struct dramc_param *get_dramc_param_from_blob(void *blob) -{ - return (struct dramc_param *)blob; -} - -void dump_param_header(const void *blob) -{ - const struct dramc_param *dparam = blob; - const struct dramc_param_header *header = &dparam->header; - - print("header.status = %#x\n", header->status); - print("header.version = %#x (expected: %#x)\n", - header->version, DRAMC_PARAM_HEADER_VERSION); - 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 = ¶m->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) -{ - struct dramc_param *param = blob; - struct dramc_param_header *hdr = ¶m->header; - - memset(hdr, 0, sizeof(*hdr)); - hdr->version = DRAMC_PARAM_HEADER_VERSION; - hdr->size = sizeof(*param); - return 0; -} diff --git a/src/soc/mediatek/mt8192/emi.c b/src/soc/mediatek/mt8192/emi.c index 80ee9edcc469..a130a8874ec5 100644 --- a/src/soc/mediatek/mt8192/emi.c +++ b/src/soc/mediatek/mt8192/emi.c @@ -434,7 +434,7 @@ size_t sdram_size(void) return dram_size; } -void mt_set_emi(const struct dramc_data *dparam) +void mt_set_emi(struct dramc_param *dparam) { - init_dram(dparam); + init_dram(&dparam->dramc_datas); } diff --git a/src/soc/mediatek/mt8192/include/soc/dpm.h b/src/soc/mediatek/mt8192/include/soc/dpm.h deleted file mode 100644 index f5e704bc1042..000000000000 --- a/src/soc/mediatek/mt8192/include/soc/dpm.h +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __SOC_MEDIATEK_MT8192_DPM_H__ -#define __SOC_MEDIATEK_MT8192_DPM_H__ - -#include -#include -#include - -struct dpm_regs { - u32 sw_rstn; - u32 rsvd_0[3072]; - u32 mclk_div; - u32 rsvd_1[3071]; - u32 twam_window_len; - u32 twam_mon_type; - u32 rsvd_2[1022]; - u32 low_power_cfg_0; - u32 low_power_cfg_1; - u32 rsvd_3[1]; - u32 fsm_out_ctrl_0; - u32 rsvd_4[8]; - u32 fsm_cfg_1; - u32 low_power_cfg_3; - u32 dfd_dbug_0; - u32 rsvd_5[28]; - u32 status_4; -}; - -check_member(dpm_regs, mclk_div, 0x3004); -check_member(dpm_regs, twam_window_len, 0x6004); -check_member(dpm_regs, low_power_cfg_0, 0x7004); -check_member(dpm_regs, low_power_cfg_1, 0x7008); -check_member(dpm_regs, fsm_out_ctrl_0, 0x7010); -check_member(dpm_regs, fsm_cfg_1, 0x7034); -check_member(dpm_regs, low_power_cfg_3, 0x7038); -check_member(dpm_regs, dfd_dbug_0, 0x703C); -check_member(dpm_regs, status_4, 0x70B0); - -#define DPM_SW_RSTN_RESET BIT(0) -#define DPM_MEM_RATIO_OFFSET 28 -#define DPM_MEM_RATIO_MASK (0x3 << DPM_MEM_RATIO_OFFSET) -#define DPM_MEM_RATIO_CFG1 (1 << DPM_MEM_RATIO_OFFSET) - -static struct dpm_regs *const mtk_dpm = (void *)DPM_CFG_BASE; - -int dpm_init(void); - -#endif /* __SOC_MEDIATEK_MT8192_DPM_H__ */ diff --git a/src/soc/mediatek/mt8192/include/soc/dramc_common_mt8192.h b/src/soc/mediatek/mt8192/include/soc/dramc_common_mt8192.h index 185ba8d6bd46..b5c7889803e0 100644 --- a/src/soc/mediatek/mt8192/include/soc/dramc_common_mt8192.h +++ b/src/soc/mediatek/mt8192/include/soc/dramc_common_mt8192.h @@ -3,18 +3,6 @@ #ifndef __SOC_MEDIATEK_MT8192_DRAMC_COMMON_MT8192_H__ #define __SOC_MEDIATEK_MT8192_DRAMC_COMMON_MT8192_H__ -enum { - CHANNEL_A = 0, - CHANNEL_B, - CHANNEL_MAX -}; - -enum { - RANK_0 = 0, - RANK_1, - RANK_MAX -}; - enum { FSP_0 = 0, FSP_1, @@ -56,13 +44,6 @@ enum { DQS_NUMBER = (DQ_DATA_WIDTH / DQS_BIT_NUMBER), }; #define BYTE_NUM DQS_NUMBER -#define DQS_NUMBER_LP4 DQS_NUMBER -#define DQ_DATA_WIDTH_LP4 DQ_DATA_WIDTH - -typedef enum { - CBT_NORMAL_MODE = 0, - CBT_BYTE_MODE1 -} dram_cbt_mode; /* DONOT change the sequence of pinmux */ typedef enum { diff --git a/src/soc/mediatek/mt8192/include/soc/dramc_param.h b/src/soc/mediatek/mt8192/include/soc/dramc_param.h deleted file mode 100644 index b4e982fdff57..000000000000 --- a/src/soc/mediatek/mt8192/include/soc/dramc_param.h +++ /dev/null @@ -1,156 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __SOC_MEDIATEK_MT8192_DRAMC_PARAM_H__ -#define __SOC_MEDIATEK_MT8192_DRAMC_PARAM_H__ - -#include -#include -#include - -enum { - DRAMC_PARAM_HEADER_VERSION = 3, -}; - -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, - DRAMC_ERR_COMPLEX_RW_MEM_TEST, - DRAMC_ERR_1ST_COMPLEX_RW_MEM_TEST, - DRAMC_ERR_2ND_COMPLEX_RW_MEM_TEST, - DRAMC_ERR_FAST_CALIBRATION, -}; - -enum DRAMC_PARAM_DVFS_FLAG { - DRAMC_DISABLE_DVFS, - DRAMC_ENABLE_DVFS, -}; - -enum DRAMC_PARAM_FLAGS { - DRAMC_FLAG_HAS_SAVED_DATA = 0x0001, -}; - -enum DRAMC_PARAM_DDR_TYPE { - DDR_TYPE_DISCRETE, - DDR_TYPE_EMCP, -}; - -enum DRAMC_PARAM_GEOMETRY_TYPE { - DDR_TYPE_2CH_2RK_4GB_2_2, - DDR_TYPE_2CH_2RK_6GB_3_3, - DDR_TYPE_2CH_2RK_8GB_4_4, - DDR_TYPE_2CH_1RK_4GB_4_0, - DDR_TYPE_2CH_2RK_6GB_2_4, -}; - -enum DRAM_PARAM_VOLTAGE_TYPE { - DRAM_VOLTAGE_NVCORE_NVDRAM, - DRAM_VOLTAGE_HVCORE_HVDRAM, - DRAM_VOLTAGE_LVCORE_LVDRAM, -}; - -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 */ - u16 flags; /* DRAMC_PARAM_FLAGS, update in the dram blob */ -}; - -struct sdram_params { - u32 rank_num; - u16 num_dlycell_perT; - u16 delay_cell_timex100; - - /* duty */ - 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 */ - u8 cbt_final_vref[CHANNEL_MAX][RANK_MAX]; - s8 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 */ - u8 wr_level[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4]; - - /* Gating */ - 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 */ - 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 */ - u8 rx_datlat[CHANNEL_MAX][RANK_MAX]; - - /* RX perbit */ - 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]; - - /* TX OE */ - u8 tx_oe_dq_mck[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4]; - u8 tx_oe_dq_ui[CHANNEL_MAX][RANK_MAX][DQS_NUMBER_LP4]; -}; - -struct emi_mdl { - u32 cona_val; - u32 conh_val; - u32 conf_val; - u32 chn_cona_val; -}; - -struct ddr_base_info { - u16 config_dvfs; /* DRAMC_PARAM_DVFS_FLAG */ - u16 ddr_type; /* DRAMC_PARAM_DDR_TYPE */ - u16 ddr_geometry; /* DRAMC_PARAM_GEOMETRY_TYPE */ - u16 voltage_type; /* DRAM_PARAM_VOLTAGE_TYPE */ - u32 support_ranks; - u64 rank_size[RANK_MAX]; - struct emi_mdl emi_config; - dram_cbt_mode cbt_mode[RANK_MAX]; -}; - -struct dramc_data { - struct ddr_base_info ddr_info; - struct sdram_params freq_params[DRAM_DFS_SHU_MAX]; -}; - -struct dramc_param { - struct dramc_param_header header; - void (*do_putc)(unsigned char c); - 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 */ -}; - -const struct sdram_info *get_sdram_config(void); -struct dramc_param *get_dramc_param_from_blob(void *blob); -void dump_param_header(const void *blob); -int validate_dramc_param(const void *blob); -int is_valid_dramc_param(const void *blob); -int initialize_dramc_param(void *blob); -#endif /* __SOC_MEDIATEK_MT8192_DRAMC_PARAM_H__ */ diff --git a/src/soc/mediatek/mt8192/include/soc/dramc_soc.h b/src/soc/mediatek/mt8192/include/soc/dramc_soc.h new file mode 100644 index 000000000000..1b90eb134ef6 --- /dev/null +++ b/src/soc/mediatek/mt8192/include/soc/dramc_soc.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_DRAMC_SOC_H__ +#define __SOC_MEDIATEK_DRAMC_SOC_H__ + +typedef enum { + CHANNEL_A = 0, + CHANNEL_B, + CHANNEL_MAX +} DRAM_CHANNEL_T; + +typedef enum { + RANK_0 = 0, + RANK_1, + RANK_MAX +} DRAM_RANK_T; + +typedef enum { + DRAM_DFS_SHUFFLE_1 = 0, + DRAM_DFS_SHUFFLE_2, + DRAM_DFS_SHUFFLE_3, + DRAM_DFS_SHUFFLE_4, + DRAM_DFS_SHUFFLE_5, + DRAM_DFS_SHUFFLE_6, + DRAM_DFS_SHUFFLE_7, + DRAM_DFS_SHUFFLE_MAX +} DRAM_DFS_SHUFFLE_TYPE_T; // DRAM SHUFFLE RG type + +/* + * Internal CBT mode enum + * 1. Calibration flow uses vGet_Dram_CBT_Mode to + * differentiate between mixed vs non-mixed LP4 + * 2. Declared as dram_cbt_mode[RANK_MAX] internally to + * store each rank's CBT mode type + */ +typedef enum { + CBT_NORMAL_MODE = 0, + CBT_BYTE_MODE1 +} DRAM_CBT_MODE_T, dram_cbt_mode; + +#define DRAM_DFS_SHU_MAX DRAM_DFS_SHUFFLE_MAX + +#define DQS_NUMBER_LP4 2 +#define DQS_BIT_NUMBER 8 +#define DQ_DATA_WIDTH_LP4 16 + +#endif /* __SOC_MEDIATEK_DRAMC_SOC_H__ */ diff --git a/src/soc/mediatek/mt8192/include/soc/emi.h b/src/soc/mediatek/mt8192/include/soc/emi.h deleted file mode 100644 index 02a90be789af..000000000000 --- a/src/soc/mediatek/mt8192/include/soc/emi.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef SOC_MEDIATEK_MT8192_EMI_H -#define SOC_MEDIATEK_MT8192_EMI_H - -#include - -size_t sdram_size(void); -void mt_set_emi(const struct dramc_data *dparam); -void mt_mem_init(struct dramc_param_ops *dparam_ops); -int complex_mem_test(u8 *start, unsigned int len); - -#endif /* SOC_MEDIATEK_MT8192_EMI_H */ diff --git a/src/soc/mediatek/mt8192/memory.c b/src/soc/mediatek/mt8192/memory.c deleted file mode 100644 index 549dede00d13..000000000000 --- a/src/soc/mediatek/mt8192/memory.c +++ /dev/null @@ -1,187 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static int mt_mem_test(const struct dramc_data *dparam) -{ - if (CONFIG(MEMORY_TEST)) { - u8 *addr = _dram; - const struct ddr_base_info *ddr_info = &dparam->ddr_info; - - for (u8 rank = RANK_0; rank < ddr_info->support_ranks; rank++) { - int result = complex_mem_test(addr, 0x2000); - - if (result != 0) { - printk(BIOS_ERR, - "[MEM] complex R/W mem test failed: %d\n", result); - return -1; - } else { - printk(BIOS_DEBUG, "[MEM] complex R/W mem test passed\n"); - } - - addr += ddr_info->rank_size[rank]; - } - } - - return 0; -} - -static u32 compute_checksum(const struct dramc_param *dparam) -{ - return (u32)compute_ip_checksum(&dparam->dramc_datas, - sizeof(dparam->dramc_datas)); -} - -static int dram_run_fast_calibration(const 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(MT8192_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"); - mt_set_emi(&dparam->dramc_datas); - 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) -{ - /* 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); - - if (prog_locate(&dram)) { - printk(BIOS_ERR, "DRAM-K: Locate program failed\n"); - return -1; - } - - if (cbfs_prog_stage_load(&dram)) { - printk(BIOS_ERR, "DRAM-K: CBFS load program failed\n"); - return -2; - } - - dparam->do_putc = do_putchar; - - 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", - dparam->header.status); - return -3; - } - - if (!(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"); - return -4; - } - - return 0; -} - -static void mem_init_set_default_config(struct dramc_param *dparam, - u32 ddr_geometry) -{ - memset(dparam, 0, sizeof(*dparam)); - - if (CONFIG(MT8192_DRAM_EMCP)) - dparam->dramc_datas.ddr_info.ddr_type = DDR_TYPE_EMCP; - - if (CONFIG(MT8192_DRAM_DVFS)) - dparam->dramc_datas.ddr_info.config_dvfs = DRAMC_ENABLE_DVFS; - dparam->dramc_datas.ddr_info.ddr_geometry = ddr_geometry; - - printk(BIOS_INFO, "DRAM-K: ddr_type: %d, config_dvfs: %d, ddr_geometry: %d\n", - dparam->dramc_datas.ddr_info.ddr_type, - dparam->dramc_datas.ddr_info.config_dvfs, - dparam->dramc_datas.ddr_info.ddr_geometry); -} - -static void mt_mem_init_run(struct dramc_param_ops *dparam_ops, u32 ddr_geometry) -{ - struct dramc_param *dparam = dparam_ops->param; - struct stopwatch sw; - int ret; - - /* Load calibration params from flash and run fast calibration */ - mem_init_set_default_config(dparam, ddr_geometry); - if (dparam_ops->read_from_flash(dparam)) { - printk(BIOS_INFO, "DRAM-K: Running fast calibration\n"); - stopwatch_init(&sw); - - ret = dram_run_fast_calibration(dparam); - if (ret != 0) { - printk(BIOS_ERR, "DRAM-K: Failed to run fast calibration " - "in %ld msecs, error: %d\n", - stopwatch_duration_msecs(&sw), ret); - - /* Erase flash data after fast calibration failed */ - memset(dparam, 0xa5, sizeof(*dparam)); - dparam_ops->write_to_flash(dparam); - } 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"); - } - - /* Run full calibration */ - printk(BIOS_INFO, "DRAM-K: Running full calibration\n"); - mem_init_set_default_config(dparam, ddr_geometry); - - stopwatch_init(&sw); - int err = dram_run_full_calibration(dparam); - if (err == 0) { - 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); - } 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) -{ - const struct sdram_info *sdram_param = get_sdram_config(); - - mt_mem_init_run(dparam_ops, sdram_param->ddr_geometry); -} -- cgit v1.2.3