diff options
Diffstat (limited to 'src')
16 files changed, 244 insertions, 67 deletions
diff --git a/src/soc/mediatek/common/Kconfig b/src/soc/mediatek/common/Kconfig new file mode 100644 index 0000000000..543bc02d13 --- /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/mt8192/dpm.c b/src/soc/mediatek/common/dpm.c index 991441e74c..991441e74c 100644 --- a/src/soc/mediatek/mt8192/dpm.c +++ b/src/soc/mediatek/common/dpm.c diff --git a/src/soc/mediatek/common/dram_init.c b/src/soc/mediatek/common/dram_init.c new file mode 100644 index 0000000000..accc7ac5e7 --- /dev/null +++ b/src/soc/mediatek/common/dram_init.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <delay.h> +#include <stdint.h> +#include <soc/dramc_common.h> +#include <soc/dramc_param.h> +#include <soc/emi.h> + +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/mt8192/dramc_param.c b/src/soc/mediatek/common/dramc_param.c index f8f6c7dd14..8548dbc665 100644 --- a/src/soc/mediatek/mt8192/dramc_param.c +++ b/src/soc/mediatek/common/dramc_param.c @@ -18,9 +18,9 @@ void dump_param_header(const void *blob) print("header.status = %#x\n", header->status); print("header.version = %#x (expected: %#x)\n", - header->version, DRAMC_PARAM_HEADER_VERSION); + header->version, DRAMC_PARAM_HEADER_VERSION); print("header.size = %#x (expected: %#lx)\n", - header->size, sizeof(*dparam)); + header->size, sizeof(*dparam)); print("header.flags = %#x\n", header->flags); print("header.checksum = %#x\n", header->checksum); } diff --git a/src/soc/mediatek/mt8192/include/soc/dpm.h b/src/soc/mediatek/common/include/soc/dpm.h index f5e704bc10..7262e09a6f 100644 --- a/src/soc/mediatek/mt8192/include/soc/dpm.h +++ b/src/soc/mediatek/common/include/soc/dpm.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef __SOC_MEDIATEK_MT8192_DPM_H__ -#define __SOC_MEDIATEK_MT8192_DPM_H__ +#ifndef __SOC_MEDIATEK_DPM_H__ +#define __SOC_MEDIATEK_DPM_H__ #include <soc/addressmap.h> #include <stdint.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 0000000000..a5716dc50f --- /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 <console/console.h> + +#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/mt8192/include/soc/dramc_param.h b/src/soc/mediatek/common/include/soc/dramc_param.h index b4e982fdff..d3eda8da92 100644 --- a/src/soc/mediatek/mt8192/include/soc/dramc_param.h +++ b/src/soc/mediatek/common/include/soc/dramc_param.h @@ -1,14 +1,16 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef __SOC_MEDIATEK_MT8192_DRAMC_PARAM_H__ -#define __SOC_MEDIATEK_MT8192_DRAMC_PARAM_H__ +#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 <stdint.h> #include <sys/types.h> -#include <soc/dramc_common_mt8192.h> +#include <soc/dramc_soc.h> enum { - DRAMC_PARAM_HEADER_VERSION = 3, + DRAMC_PARAM_HEADER_VERSION = 5, }; enum DRAMC_PARAM_STATUS_CODES { @@ -39,12 +41,14 @@ enum DRAMC_PARAM_DDR_TYPE { 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, + 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 { @@ -116,10 +120,10 @@ struct emi_mdl { }; 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 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; @@ -145,6 +149,7 @@ struct dramc_param_ops { 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); @@ -153,4 +158,4 @@ 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__ */ +#endif /* __SOC_MEDIATEK_DRAMC_PARAM_H__ */ diff --git a/src/soc/mediatek/mt8192/include/soc/emi.h b/src/soc/mediatek/common/include/soc/emi.h index 02a90be789..c91c8706c4 100644 --- a/src/soc/mediatek/mt8192/include/soc/emi.h +++ b/src/soc/mediatek/common/include/soc/emi.h @@ -1,13 +1,18 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef SOC_MEDIATEK_MT8192_EMI_H -#define SOC_MEDIATEK_MT8192_EMI_H +#ifndef SOC_MEDIATEK_EMI_H +#define SOC_MEDIATEK_EMI_H #include <soc/dramc_param.h> size_t sdram_size(void); -void mt_set_emi(const struct dramc_data *dparam); +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/mt8192/memory.c b/src/soc/mediatek/common/memory.c index 549dede00d..2cc05713a1 100644 --- a/src/soc/mediatek/mt8192/memory.c +++ b/src/soc/mediatek/common/memory.c @@ -9,6 +9,9 @@ #include <symbols.h> #include <timer.h> +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)) { @@ -22,9 +25,8 @@ static int mt_mem_test(const struct dramc_data *dparam) 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"); } + printk(BIOS_DEBUG, "[MEM] rank %u complex R/W mem test passed\n", rank); addr += ddr_info->rank_size[rank]; } @@ -39,7 +41,57 @@ static u32 compute_checksum(const struct dramc_param *dparam) sizeof(dparam->dramc_datas)); } -static int dram_run_fast_calibration(const struct dramc_param *dparam) +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"); @@ -56,7 +108,7 @@ static int dram_run_fast_calibration(const struct dramc_param *dparam) return DRAMC_ERR_INVALID_CHECKSUM; } - const u16 config = CONFIG(MT8192_DRAM_DVFS) ? DRAMC_ENABLE_DVFS : DRAMC_DISABLE_DVFS; + 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 " @@ -66,7 +118,7 @@ static int dram_run_fast_calibration(const struct dramc_param *dparam) } printk(BIOS_INFO, "DRAM-K: DRAM calibration data valid pass\n"); - mt_set_emi(&dparam->dramc_datas); + init_dram_by_params(dparam); if (mt_mem_test(&dparam->dramc_datas) == 0) return 0; @@ -96,7 +148,7 @@ static int dram_run_full_calibration(struct dramc_param *dparam) prog_run(&dram); if (dparam->header.status != DRAMC_SUCCESS) { printk(BIOS_ERR, "DRAM-K: Full calibration failed: status = %d\n", - dparam->header.status); + dparam->header.status); return -3; } @@ -111,31 +163,36 @@ static int dram_run_full_calibration(struct dramc_param *dparam) } static void mem_init_set_default_config(struct dramc_param *dparam, - u32 ddr_geometry) + const struct sdram_info *dram_info) { + u32 type, geometry; memset(dparam, 0, sizeof(*dparam)); - if (CONFIG(MT8192_DRAM_EMCP)) - dparam->dramc_datas.ddr_info.ddr_type = DDR_TYPE_EMCP; + type = dram_info->ddr_type; + geometry = dram_info->ddr_geometry; + + dparam->dramc_datas.ddr_info.ddr_type = type; - if (CONFIG(MT8192_DRAM_DVFS)) + if (CONFIG(MEDIATEK_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); + 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, u32 ddr_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, ddr_geometry); + 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); @@ -160,7 +217,7 @@ static void mt_mem_init_run(struct dramc_param_ops *dparam_ops, u32 ddr_geometry /* Run full calibration */ printk(BIOS_INFO, "DRAM-K: Running full calibration\n"); - mem_init_set_default_config(dparam, ddr_geometry); + mem_init_set_default_config(dparam, dram_info); stopwatch_init(&sw); int err = dram_run_full_calibration(dparam); @@ -183,5 +240,5 @@ 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); + mt_mem_init_run(dparam_ops, sdram_param); } diff --git a/src/soc/mediatek/mt8173/Kconfig b/src/soc/mediatek/mt8173/Kconfig index 15b833f56f..bf53164178 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 ce99c76c8c..5a0a765548 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 e2d7eeac13..9c7a9af9ab 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 f5742a36f2..a872916763 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/emi.c b/src/soc/mediatek/mt8192/emi.c index 80ee9edcc4..a130a8874e 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/dramc_common_mt8192.h b/src/soc/mediatek/mt8192/include/soc/dramc_common_mt8192.h index 185ba8d6bd..b5c7889803 100644 --- a/src/soc/mediatek/mt8192/include/soc/dramc_common_mt8192.h +++ b/src/soc/mediatek/mt8192/include/soc/dramc_common_mt8192.h @@ -4,18 +4,6 @@ #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, FSP_MAX, @@ -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_soc.h b/src/soc/mediatek/mt8192/include/soc/dramc_soc.h new file mode 100644 index 0000000000..1b90eb134e --- /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__ */ |