From 92fb91935b7e8736dd4e74a446215bd823b9615f Mon Sep 17 00:00:00 2001 From: Huayang Duan Date: Mon, 8 Jun 2020 19:19:34 +0800 Subject: soc/mediatek/mt8183: Adjust tRFCab and tRFCpb by the density value Different density should correspond to different tRFCab and tRFCpb timing. BUG=none BRANCH=kukui TEST=Boots correctly on Kukui Change-Id: I2599fcd620cdefe2e12480932ffd75e0416b9545 Signed-off-by: Huayang Duan Reviewed-on: https://review.coreboot.org/c/coreboot/+/42194 Tested-by: build bot (Jenkins) Reviewed-by: Hung-Te Lin Reviewed-by: Yu-Ping Wu --- src/soc/mediatek/mt8183/dramc_pi_calibration_api.c | 62 +++++++++++ src/soc/mediatek/mt8183/emi.c | 114 +++++++++++++++++---- src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h | 1 + 3 files changed, 157 insertions(+), 20 deletions(-) diff --git a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c index ee9b9b6b70..50d847f542 100644 --- a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c @@ -130,6 +130,19 @@ void dramc_mode_reg_write(u8 chn, u8 mr_idx, u8 value) dramc_dbg("Write MR%d =0x%x\n", mr_idx, value); } +static u8 dramc_mode_reg_read_by_rank(u8 chn, u8 rank, u8 mr_idx) +{ + u8 value; + u32 rk_bak = READ32_BITFIELD(&ch[chn].ao.mrs, MRS_MRRRK); + + SET32_BITFIELDS(&ch[chn].ao.mrs, MRS_MRRRK, rank); + value = dramc_mode_reg_read(chn, mr_idx); + SET32_BITFIELDS(&ch[chn].ao.mrs, MRS_MRRRK, rk_bak); + + dramc_dbg("Mode reg read rank%d MR%d = %#x\n", rank, mr_idx, value); + return value; +} + static void dramc_mode_reg_write_by_rank(u8 chn, u8 rank, u8 mr_idx, u8 value) { @@ -2694,6 +2707,55 @@ void dramc_dqs_precalculation_preset(void) } } +void get_dram_info_after_cal(u8 *density_result) +{ + u8 vendor_id, density, max_density = 0; + u32 ddr_size, max_size = 0; + + vendor_id = dramc_mode_reg_read_by_rank(CHANNEL_A, RANK_0, 5); + dramc_show("Vendor id is %#x\n", vendor_id); + + for (u8 rk = RANK_0; rk < RANK_MAX; rk++) { + density = dramc_mode_reg_read_by_rank(CHANNEL_A, rk, 8); + dramc_dbg("MR8 %#x\n", density); + density = (density >> 2) & 0xf; + + switch (density) { + case 0x0: + ddr_size = 4; + break; + case 0x1: + ddr_size = 6; + break; + case 0x2: + ddr_size = 8; + break; + case 0x3: + ddr_size = 12; + break; + case 0x4: + ddr_size = 16; + break; + case 0x5: + ddr_size = 24; + break; + case 0x6: + ddr_size = 32; + break; + default: + ddr_size = 0; + break; + } + if (ddr_size > max_size) { + max_size = ddr_size; + max_density = density; + } + dramc_dbg("RK%d size %dGb, density:%d\n", rk, ddr_size, max_density); + } + + *density_result = max_density; +} + int dramc_calibrate_all_channels(const struct sdram_params *pams, u8 freq_group, const struct mr_value *mr) { diff --git a/src/soc/mediatek/mt8183/emi.c b/src/soc/mediatek/mt8183/emi.c index fd09ef1b77..579bfbecbc 100644 --- a/src/soc/mediatek/mt8183/emi.c +++ b/src/soc/mediatek/mt8183/emi.c @@ -49,10 +49,10 @@ const u8 phy_mapping[CHANNEL_MAX][16] = { }; struct optimize_ac_time { - u8 rfc; - u8 rfc_05t; - u8 rfc_pb; - u8 rfrc_pb05t; + u8 trfc; + u8 trfrc_05t; + u8 trfc_pb; + u8 trfrc_pb05t; u16 tx_ref_cnt; }; @@ -319,30 +319,102 @@ static void dramc_init_pre_settings(void) setbits32(&ch[0].phy.misc_ctrl1, 0x1 << 31); } -static void dramc_ac_timing_optimize(u8 freq_group) +static void dramc_ac_timing_optimize(u8 freq_group, u8 density) { - struct optimize_ac_time rf_cab_opt[LP4X_DDRFREQ_MAX] = { - [LP4X_DDR1600] = {.rfc = 44, .rfc_05t = 0, .rfc_pb = 16, - .rfrc_pb05t = 0, .tx_ref_cnt = 62}, - [LP4X_DDR2400] = {.rfc = 72, .rfc_05t = 0, .rfc_pb = 30, - .rfrc_pb05t = 0, .tx_ref_cnt = 91}, - [LP4X_DDR3200] = {.rfc = 100, .rfc_05t = 0, .rfc_pb = 44, - .rfrc_pb05t = 0, .tx_ref_cnt = 119}, - [LP4X_DDR3600] = {.rfc = 118, .rfc_05t = 1, .rfc_pb = 53, - .rfrc_pb05t = 1, .tx_ref_cnt = 138}, + u8 rfcab_grp = 0; + u8 trfc, trfrc_05t, trfc_pb, trfrc_pb05t, tx_ref_cnt; + enum tRFCAB { + tRFCAB_130 = 0, + tRFCAB_180, + tRFCAB_280, + tRFCAB_380, + tRFCAB_NUM }; + const struct optimize_ac_time rf_cab_opt[LP4X_DDRFREQ_MAX][tRFCAB_NUM] = { + [LP4X_DDR1600] = { + [tRFCAB_130] = {.trfc = 14, .trfrc_05t = 0, .trfc_pb = 0, + .trfrc_pb05t = 0, .tx_ref_cnt = 32}, + [tRFCAB_180] = {.trfc = 24, .trfrc_05t = 0, .trfc_pb = 6, + .trfrc_pb05t = 0, .tx_ref_cnt = 42}, + [tRFCAB_280] = {.trfc = 44, .trfrc_05t = 0, .trfc_pb = 16, + .trfrc_pb05t = 0, .tx_ref_cnt = 62}, + [tRFCAB_380] = {.trfc = 64, .trfrc_05t = 0, .trfc_pb = 26, + .trfrc_pb05t = 0, .tx_ref_cnt = 82} + }, + [LP4X_DDR2400] = { + [tRFCAB_130] = {.trfc = 27, .trfrc_05t = 0, .trfc_pb = 6, + .trfrc_pb05t = 0, .tx_ref_cnt = 46}, + [tRFCAB_180] = {.trfc = 42, .trfrc_05t = 0, .trfc_pb = 15, + .trfrc_pb05t = 0, .tx_ref_cnt = 61}, + [tRFCAB_280] = {.trfc = 72, .trfrc_05t = 0, .trfc_pb = 30, + .trfrc_pb05t = 0, .tx_ref_cnt = 91}, + [tRFCAB_380] = {.trfc = 102, .trfrc_05t = 0, .trfc_pb = 45, + .trfrc_pb05t = 0, .tx_ref_cnt = 121} + }, + [LP4X_DDR3200] = { + [tRFCAB_130] = {.trfc = 40, .trfrc_05t = 0, .trfc_pb = 12, + .trfrc_pb05t = 0, .tx_ref_cnt = 59}, + [tRFCAB_180] = {.trfc = 60, .trfrc_05t = 0, .trfc_pb = 24, + .trfrc_pb05t = 0, .tx_ref_cnt = 79}, + [tRFCAB_280] = {.trfc = 100, .trfrc_05t = 0, .trfc_pb = 44, + .trfrc_pb05t = 0, .tx_ref_cnt = 119}, + [tRFCAB_380] = {.trfc = 140, .trfrc_05t = 0, .trfc_pb = 64, + .trfrc_pb05t = 0, .tx_ref_cnt = 159} + }, + [LP4X_DDR3600] = { + [tRFCAB_130] = {.trfc = 48, .trfrc_05t = 1, .trfc_pb = 16, + .trfrc_pb05t = 0, .tx_ref_cnt = 68}, + [tRFCAB_180] = {.trfc = 72, .trfrc_05t = 0, .trfc_pb = 30, + .trfrc_pb05t = 0, .tx_ref_cnt = 92}, + [tRFCAB_280] = {.trfc = 118, .trfrc_05t = 1, .trfc_pb = 53, + .trfrc_pb05t = 1, .tx_ref_cnt = 138}, + [tRFCAB_380] = {.trfc = 165, .trfrc_05t = 0, .trfc_pb = 76, + .trfrc_pb05t = 1, .tx_ref_cnt = 185} + }, + }; + + switch (density) { + case 0x0: + rfcab_grp = tRFCAB_130; + break; + case 0x1: + case 0x2: + rfcab_grp = tRFCAB_180; + break; + case 0x3: + case 0x4: + rfcab_grp = tRFCAB_280; + break; + case 0x5: + case 0x6: + rfcab_grp = tRFCAB_380; + break; + default: + dramc_err("density err!\n"); + break; + } + + const struct optimize_ac_time *ac_tim = &rf_cab_opt[freq_group][rfcab_grp]; + trfc = ac_tim->trfc; + trfrc_05t = ac_tim->trfrc_05t; + trfc_pb = ac_tim->trfc_pb; + trfrc_pb05t = ac_tim->trfrc_pb05t; + tx_ref_cnt = ac_tim->tx_ref_cnt; + dramc_dbg("Density %d, trfc %u, trfrc_05t %d, tx_ref_cnt %d, trfc_pb %d, trfrc_pb05t %d\n", + density, trfc, trfrc_05t, tx_ref_cnt, trfc_pb, trfrc_pb05t); + for (size_t chn = 0; chn < CHANNEL_MAX; chn++) { clrsetbits32(&ch[chn].ao.shu[0].actim[3], - 0xff << 16, rf_cab_opt[freq_group].rfc << 16); + 0xff << 16, trfc << 16); clrsetbits32(&ch[chn].ao.shu[0].ac_time_05t, - 0x1 << 2, rf_cab_opt[freq_group].rfc_05t << 2); + 0x1 << 2, trfrc_05t << 2); clrsetbits32(&ch[chn].ao.shu[0].actim[4], - 0x3ff << 0, rf_cab_opt[freq_group].tx_ref_cnt << 0); + 0x3ff << 0, tx_ref_cnt << 0); clrsetbits32(&ch[chn].ao.shu[0].actim[3], - 0xff << 0, rf_cab_opt[freq_group].rfc_pb << 0); + 0xff << 0, trfc_pb << 0); clrsetbits32(&ch[chn].ao.shu[0].ac_time_05t, - 0x1 << 1, rf_cab_opt[freq_group].rfrc_pb05t << 1); + 0x1 << 1, trfrc_pb05t << 1); } } @@ -494,6 +566,7 @@ static int run_calib(const struct dramc_param *dparam, struct dram_shared_data *shared, const int shuffle, bool *first_run) { + u8 density; const u8 *freq_tbl; if (CONFIG(MT8183_DRAM_EMCP)) @@ -518,7 +591,8 @@ static int run_calib(const struct dramc_param *dparam, dramc_dbg("Start K (current clock: %u\n", params->frequency); if (dramc_calibrate_all_channels(params, freq_group, &shared->mr) != 0) return -1; - dramc_ac_timing_optimize(freq_group); + get_dram_info_after_cal(&density); + dramc_ac_timing_optimize(freq_group, density); dramc_dbg("K finished (current clock: %u\n", params->frequency); dramc_save_result_to_shuffle(DRAM_DFS_SHUFFLE_1, shuffle); diff --git a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h index 66433602c5..437ed3db2d 100644 --- a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h +++ b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h @@ -106,5 +106,6 @@ void dramc_cke_fix_onoff(u8 chn, bool fix_on, bool fix_off); u32 get_shu_freq(u8 shu); void dramc_hw_dqsosc(u8 chn); void dramc_dqs_precalculation_preset(void); +void get_dram_info_after_cal(u8 *density); #endif /* _DRAMC_PI_API_MT8183_H */ -- cgit v1.2.3