mail.coreboot.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
List overview
Download
coreboot-gerrit
October 2020
----- 2025 -----
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
coreboot-gerrit@coreboot.org
1 participants
3474 discussions
Start a n
N
ew thread
Change in coreboot[master]: soc/mediatek/mt8192: Do dramc rx window training
by CK HU (Code Review)
08 Mar '21
08 Mar '21
Hello Duan huayang, I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/44719
to review the following change. Change subject: soc/mediatek/mt8192: Do dramc rx window training ...................................................................... soc/mediatek/mt8192: Do dramc rx window training Signed-off-by: Huayang Duan <huayang.duan(a)mediatek.com> Change-Id: I584db990a9777551bcf3d4d59cdd3fd64d6e52cc --- M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c M src/soc/mediatek/mt8192/dramc_pi_main.c 2 files changed, 264 insertions(+), 0 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/19/44719/1 diff --git a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c index 8d65a67..363a3bd 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c @@ -27,6 +27,15 @@ u8 dqsien_dly_pi_p1[DQS_NUMBER]; }; +typedef struct { + s16 first_pass; + s16 last_pass; + s16 win_center; + u16 win_size; + u16 best_dqdly; +} pass_win_data_t; + + static const u8 imp_vref_sel[ODT_MAX][IMP_DRV_MAX] = { /* DRVP DRVN ODTP ODTN */ [ODT_OFF] = {0x37, 0x33, 0x00, 0x37}, @@ -1695,3 +1704,255 @@ read_dqs_inctl, rank_inctl_root, xrtr2r); } + +static void dramc_set_rank_engin2(u8 chn, u8 rank) +{ + SET32_BITFIELDS(&ch[chn].ao.test2_a3, TEST2_A3_ADRDECEN_TARKMODE, 1); + SET32_BITFIELDS(&ch[chn].ao.test2_a4, TEST2_A4_TESTAGENTRKSEL, 0); + SET32_BITFIELDS(&ch[chn].ao.test2_a4, TEST2_A4_TESTAGENTRK, rank); +} + +static void dramc_engin2_set_ui_shift(u8 chn) +{ + SET32_BITFIELDS(&ch[chn].ao.test2_a0, + TEST2_A0_TA2_LOOP_EN, 1, + TEST2_A0_LOOP_CNT_INDEX, 3); + SET32_BITFIELDS(&ch[chn].ao.test2_a3, + TEST2_A3_TEST2_PAT_SHIFT, 1, + TEST2_A3_PAT_SHIFT_SW_EN, 0); +} + +static void dramc_engin2_set_pat(u8 chn, u8 rank, u8 loop_cnt) +{ + SET32_BITFIELDS(&ch[chn].ao.test2_a4, + TEST2_A4_TEST_REQ_LEN1, 1, + TEST2_A4_TESTAUDINIT, 0, + TEST2_A4_TESTAUDINC, 0, + TEST2_A4_TESTXTALKPAT, 0, + TEST2_A4_TESTSSOPAT, 0); + SET32_BITFIELDS(&ch[chn].ao.test2_a3, + TEST2_A3_TESTAUDPAT, 0, + TEST2_A3_AUTO_GEN_PAT, 1, + TEST2_A3_HFIDPAT, 1, + TEST2_A3_TEST_AID_EN, 1, + TEST2_A3_TESTCNT, loop_cnt); + SET32_BITFIELDS(&ch[chn].ao.test2_a2, TEST2_A2_TEST2_OFF, 0x56); + dramc_engin2_set_ui_shift(chn); +} + +static void dramc_engine2_init(u8 chn, u8 rank) +{ + u32 test2_1 = 0x55000000; + u32 test2_2 = 0xaa000100; + + dramc_set_rank_engin2(chn, rank); + SET32_BITFIELDS(&ch[chn].ao.dummy_rd, + DUMMY_RD_DQSG_DMYRD_EN, 0, + DUMMY_RD_DQSG_DMYWR_EN, 0, + DUMMY_RD_DUMMY_RD_EN, 0, + DUMMY_RD_SREF_DMYRD_EN, 0, + DUMMY_RD_DMY_RD_DBG, 0, + DUMMY_RD_DMY_WR_DBG, 0); + SET32_BITFIELDS(&ch[chn].ao.test2_a3, + TEST2_A3_TEST2W, 0, + TEST2_A3_TEST2R, 0, + TEST2_A3_TEST1, 0); + SET32_BITFIELDS(&ch[chn].ao.test2_a0, + TEST2_A0_TEST2_PAT0, test2_1 >> 24, + TEST2_A0_TEST2_PAT1, test2_2 >> 24); + SET32_BITFIELDS(&ch[chn].ao.rk[rank].rk_test2_a1, + RK_TEST2_A1_TEST2_BASE, (test2_1 + 0x10000) & 0x00ffffff); + SET32_BITFIELDS(&ch[chn].ao.test2_a2, TEST2_A2_TEST2_OFF, test2_2 & 0x00ffffff); + + dramc_engin2_set_pat(chn, rank, 0); +} + +static const u8 uiLPDDR4_RDDQC_Mapping_POP[PINMUX_MAX][CHANNEL_MAX][DQ_DATA_WIDTH] = +{ + [PINMUX_DSC] = { + [CHANNEL_A] = { 0, 1, 6, 7, 4, 5, 3, 2, 9, 8, 11, 10, 15, 14, 12, 13}, + [CHANNEL_B] = { 1, 0, 5, 4, 7, 2, 3, 6, 8, 9, 11, 10, 12, 14, 13, 15}, + }, + [PINMUX_LPBK] = { + }, + [PINMUX_EMCP] = { + [CHANNEL_A] = {1, 0, 3, 2, 4, 7, 6, 5, 8, 9, 10, 12, 15, 14, 11, 13}, + [CHANNEL_B] = {0, 1, 7, 4, 2, 5, 6, 3, 9, 8, 10, 12, 11, 14, 13, 15}, + } +}; + +static void rddqc_pinmux_set(const struct ddr_cali* cali) +{ + u8 chn = cali->chn; + u8 pinmux = get_pinmux_type(cali); + + const u8 *pinmux_map = uiLPDDR4_RDDQC_Mapping_POP[pinmux][chn]; + + SET32_BITFIELDS(&ch[chn].ao.mrr_bit_mux1, + MRR_BIT_MUX1_MRR_BIT0_SEL, pinmux_map[0], + MRR_BIT_MUX1_MRR_BIT1_SEL, pinmux_map[1], + MRR_BIT_MUX1_MRR_BIT2_SEL, pinmux_map[2], + MRR_BIT_MUX1_MRR_BIT3_SEL, pinmux_map[3]); + SET32_BITFIELDS(&ch[chn].ao.mrr_bit_mux2, + MRR_BIT_MUX2_MRR_BIT4_SEL, pinmux_map[4], + MRR_BIT_MUX2_MRR_BIT5_SEL, pinmux_map[5], + MRR_BIT_MUX2_MRR_BIT6_SEL, pinmux_map[6], + MRR_BIT_MUX2_MRR_BIT7_SEL, pinmux_map[7]); + SET32_BITFIELDS(&ch[chn].ao.mrr_bit_mux3, + MRR_BIT_MUX3_MRR_BIT8_SEL, pinmux_map[8], + MRR_BIT_MUX3_MRR_BIT9_SEL, pinmux_map[9], + MRR_BIT_MUX3_MRR_BIT10_SEL, pinmux_map[10], + MRR_BIT_MUX3_MRR_BIT11_SEL, pinmux_map[11]); + SET32_BITFIELDS(&ch[chn].ao.mrr_bit_mux4, + MRR_BIT_MUX4_MRR_BIT12_SEL, pinmux_map[12], + MRR_BIT_MUX4_MRR_BIT13_SEL, pinmux_map[13], + MRR_BIT_MUX4_MRR_BIT14_SEL, pinmux_map[14], + MRR_BIT_MUX4_MRR_BIT15_SEL, pinmux_map[15]); +} + +static void dramc_rx_rddqc_init(const struct ddr_cali* cali) +{ + u8 rddqc_bit_ctrl_lower = 0x55; + u8 rddqc_bit_ctrl_upper = 0x55; + u8 rddqc_patternA = 0x5A; + u8 rddqc_patternB = 0x3C; + + u8 chn = cali->chn; + u8 rank = cali->rank; + + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].shu_b0_dq7, + SHU_B0_DQ7_R_DMDQMDBI_SHU_B0, 0); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].shu_b0_dq7, + SHU_B1_DQ7_R_DMDQMDBI_SHU_B1, 0); + + SET32_BITFIELDS(&ch[chn].ao.swcmd_ctrl0, SWCMD_CTRL0_MRSRK, rank); + rddqc_pinmux_set(cali); + dramc_mode_reg_write_by_rank(cali, chn, rank, 15, rddqc_bit_ctrl_lower); + dramc_mode_reg_write_by_rank(cali, chn, rank, 20, rddqc_bit_ctrl_upper); + dramc_mode_reg_write_by_rank(cali, chn, rank, 32, rddqc_patternA); + dramc_mode_reg_write_by_rank(cali, chn, rank, 40, rddqc_patternB); + + SET32_BITFIELDS(&ch[chn].ao.rddqcgolden, + RDDQCGOLDEN_MR15_GOLDEN, rddqc_bit_ctrl_lower, + RDDQCGOLDEN_MR20_GOLDEN, rddqc_bit_ctrl_upper, + RDDQCGOLDEN_MR32_GOLDEN, rddqc_patternA, + RDDQCGOLDEN_MR40_GOLDEN, rddqc_patternB); + + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].shu_b0_dq8, + SHU_B0_DQ8_R_DMRXDLY_CG_IG_B0, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].shu_b0_dq8, + SHU_B1_DQ8_R_DMRXDLY_CG_IG_B1, 1); +} +void dramc_rx_window_perbit_cal(const struct ddr_cali* cali, rx_cali_type cali_type) +{ + u8 chn, rank, fsp; + dram_odt_state odt; + dram_freq_grp freq_group = cali->freq_group; + const struct sdram_params *params = cali->params; + + u8 bit, byte; + bool enable_vref_scan = false; + u16 final_vref[DQS_NUMBER] = {0xe, 0xe}; + pass_win_data_t final_win_perbit[DQ_DATA_WIDTH]; + s32 dqs_dly_perbyte[DQS_NUMBER] = {0x0}, dqm_dly_perbyte[DQS_NUMBER] = {0x0}; + + chn = cali->chn; + rank = cali->rank; + fsp = get_fsp(cali); + odt = get_odt_state(cali); + dramc_dbg("RX window ch:%d, rank:%d, freq_group:%d, type:%d\n", + chn, rank, freq_group, cali_type); + + struct reg_bak regs_bak[] = { + {&ch[chn].ao.mrr_bit_mux1}, + {&ch[chn].ao.mrr_bit_mux2}, + {&ch[chn].ao.mrr_bit_mux3}, + {&ch[chn].ao.mrr_bit_mux4}, + }; + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + regs_bak[i].value = read32(regs_bak[i].addr); + + dramc_auto_refresh_switch(chn, false); + + if (cali_type == RX_WIN_TEST_ENG) { + dramc_engine2_init(chn, rank); + + if ((rank == RANK_0) || (freq_group == DDRFREQ_2133)) + enable_vref_scan = true; + } else { + dramc_rx_rddqc_init(cali); + } + + if (enable_vref_scan) { + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[0].b0_dq5, + B0_DQ5_RG_RX_ARDQ_VREF_EN_B0, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[1].b0_dq5, + B1_DQ5_RG_RX_ARDQ_VREF_EN_B1, 1); + } + + for (byte = 0; byte < BYTE_NUM; byte++) { + if (enable_vref_scan) + final_vref[byte] = params->rx_best_vref[chn][rank][byte]; + + dqs_dly_perbyte[byte] = params->rx_perbit_dqs[chn][rank][byte]; + dqm_dly_perbyte[byte] = params->rx_perbit_dqm[chn][rank][byte]; + } + + for (bit = 0; bit < DQ_DATA_WIDTH; bit++) + final_win_perbit[bit].best_dqdly = params->rx_perbit_dq[chn][rank][bit]; + + if (enable_vref_scan) { + for (u8 rk = rank; rk < cali->support_ranks; rk++) { + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].rk[rk].shu_b0_phy_vref_sel, + RG_RX_ARDQ_VREF_SEL_LB_B0, final_vref[0], + RG_RX_ARDQ_VREF_SEL_UB_B0, final_vref[0]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].rk[rk].shu_b0_phy_vref_sel, + RG_RX_ARDQ_VREF_SEL_LB_B1, final_vref[1], + RG_RX_ARDQ_VREF_SEL_UB_B1, final_vref[1]); + + for (byte = 0; byte < BYTE_NUM; byte++) { + dramc_dbg("Final RX Vref Byte %d = %d to rank%d\n", + byte, final_vref[byte], rk); + } + } + } + + /* set dqs delay, (dqm delay) */ + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].rk[rank].shu_r0_b0_rxdly5, + SHU_R0_B0_RXDLY5_RX_ARDQS0_R_DLY_B0, dqs_dly_perbyte[0]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].rk[rank].shu_r0_b0_rxdly4, + SHU_R0_B0_RXDLY4_RX_ARDQM0_R_DLY_B0, dqm_dly_perbyte[0]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].rk[rank].shu_r0_b0_rxdly5, + SHU_R0_B1_RXDLY5_RX_ARDQS0_R_DLY_B1, dqs_dly_perbyte[1]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].rk[rank].shu_r0_b0_rxdly4, + SHU_R0_B1_RXDLY4_RX_ARDQM0_R_DLY_B1, dqm_dly_perbyte[1]); + + /* set dq delay */ + for (bit = 0; bit < DQS_BIT_NUMBER; bit += 2) { + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].rk[rank].shu_r0_b0_rxdly0 + bit / 2, + SHU_R0_B0_RXDLY0_RX_ARDQ0_R_DLY_B0, final_win_perbit[bit].best_dqdly, + SHU_R0_B0_RXDLY0_RX_ARDQ1_R_DLY_B0, final_win_perbit[bit + 1].best_dqdly); + + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].rk[rank].shu_r0_b0_rxdly0 + bit / 2, + SHU_R0_B1_RXDLY0_RX_ARDQ0_R_DLY_B1, final_win_perbit[bit + 8].best_dqdly, + SHU_R0_B1_RXDLY0_RX_ARDQ1_R_DLY_B1, final_win_perbit[bit + 9].best_dqdly); + } + + dramc_phy_reset(chn); + + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + write32(regs_bak[i].addr, regs_bak[i].value); + + dramc_dbg("DQS Delay:\nDQS0 = %d, DQS1 = %d\n" + "DQM Delay:\nDQM0 = %d, DQM1 = %d\n", + dqs_dly_perbyte[0], dqs_dly_perbyte[1], + dqm_dly_perbyte[0], dqm_dly_perbyte[1]); + + dramc_dbg("DQ Delay:\n"); + for (bit = 0; bit < DQ_DATA_WIDTH; bit = bit + 4) + dramc_dbg("DQ%d =%d, DQ%d =%d, DQ%d =%d, DQ%d =%d\n", + bit, final_win_perbit[bit].best_dqdly, + bit + 1, final_win_perbit[bit + 1].best_dqdly, + bit + 2, final_win_perbit[bit + 2].best_dqdly, + bit + 3, final_win_perbit[bit + 3].best_dqdly); +} diff --git a/src/soc/mediatek/mt8192/dramc_pi_main.c b/src/soc/mediatek/mt8192/dramc_pi_main.c index 4b77c85..41d85a2 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_main.c +++ b/src/soc/mediatek/mt8192/dramc_pi_main.c @@ -248,6 +248,9 @@ /* should enable the auto refresh before do RX and TX calibration */ dramc_auto_refresh_switch(chn, true); dramc_rx_dqs_gating_cal(cali, &txdly_min, &txdly_max); + + dramc_rx_window_perbit_cal(cali, RX_WIN_RD_DQC); + dramc_rx_window_perbit_cal(cali, RX_WIN_TEST_ENG); } dramc_rx_dqs_gating_post_process(cali, txdly_min, txdly_max); } -- To view, visit
https://review.coreboot.org/c/coreboot/+/44719
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: I584db990a9777551bcf3d4d59cdd3fd64d6e52cc Gerrit-Change-Number: 44719 Gerrit-PatchSet: 1 Gerrit-Owner: CK HU <ck.hu(a)mediatek.com> Gerrit-Reviewer: Duan huayang <huayang.duan(a)mediatek.com> Gerrit-Reviewer: Julius Werner <jwerner(a)chromium.org> Gerrit-MessageType: newchange
3
6
0
0
Change in coreboot[master]: soc/mediatek/mt8192: Do dramc command bus training
by CK HU (Code Review)
08 Mar '21
08 Mar '21
Hello Duan huayang, I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/44716
to review the following change. Change subject: soc/mediatek/mt8192: Do dramc command bus training ...................................................................... soc/mediatek/mt8192: Do dramc command bus training Signed-off-by: Huayang Duan <huayang.duan(a)mediatek.com> Change-Id: I06ee26e3b82811bffa09ab5e3e535b3174c3e3a6 --- M src/soc/mediatek/mt8192/dramc_dvfs.c M src/soc/mediatek/mt8192/dramc_pi_basic_api.c M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c M src/soc/mediatek/mt8192/dramc_pi_main.c 4 files changed, 761 insertions(+), 1 deletion(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/16/44716/1 diff --git a/src/soc/mediatek/mt8192/dramc_dvfs.c b/src/soc/mediatek/mt8192/dramc_dvfs.c index 67e2340..c51c261 100644 --- a/src/soc/mediatek/mt8192/dramc_dvfs.c +++ b/src/soc/mediatek/mt8192/dramc_dvfs.c @@ -193,3 +193,19 @@ MISC_SRAM_DMA0_SW_MODE, 0); } } + +void shuffle_dfs_to_fsp1(const struct ddr_cali* cali) +{ + u8 operating_fsp = cali->fsp; + struct mr_values *mr_value = cali->mr_value; + + /* Double confirm PLL switched from CLRPLL to PHYPLL */ + if (operating_fsp == FSP_1) { + for (u8 rk = 0; rk < cali->support_ranks; rk++) { + u8 mr13 = mr_value->mr13[rk]; + mr13 |= (BIT(6) | BIT(7)); + mr_value->mr13[rk] = mr13; + } + cbt_switch_freq(cali, CBT_HIGH_FREQ); + } +} diff --git a/src/soc/mediatek/mt8192/dramc_pi_basic_api.c b/src/soc/mediatek/mt8192/dramc_pi_basic_api.c index 8362c05..84acb3e 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_basic_api.c +++ b/src/soc/mediatek/mt8192/dramc_pi_basic_api.c @@ -111,6 +111,26 @@ set_dqO1_pinmux_mapping(cali); } +u8 get_cbt_vref_pinmux_value(const struct ddr_cali* cali, u8 range, u8 vref_lev) +{ + u8 chn = cali->chn; + u8 vref_bit, vref_org; + u8 vref_new = 0; + const u8 *map = mrr_o1_pinmux_mapping[get_pinmux_type(cali)][chn]; + + if (get_cbt_mode(cali) == CBT_BYTE_MODE1) + return ((range & 0x1) << 6) | (vref_lev & 0x3f); + + vref_org = ((range & 0x1) << 6) | (vref_lev & 0x3f); + + for (vref_bit = 0; vref_bit < 8; vref_bit++) + if (vref_org & (1 << vref_bit)) + vref_new |= (1 << map[vref_bit]); + + dramc_dbg("=== vref_new: 0x%x --> 0x%x\n", vref_org, vref_new); + return vref_new; +} + static void dramc_init_default_mr_value(const struct ddr_cali *cali) { struct mr_values *mr_value = cali->mr_value; diff --git a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c index e1f3d67..e531de0 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c @@ -5,6 +5,19 @@ #include <soc/dramc_register.h> #include <timer.h> +static const u8 ca_pinmux_mapping[PINMUX_MAX][CHANNEL_MAX][CA_NUM_LP4] = { + [PINMUX_DSC] = { + [CHANNEL_A] = {1, 4, 5, 3, 2, 0}, + [CHANNEL_B] = {3, 5, 0, 2, 4, 1}, + }, + [PINMUX_LPBK] = { + }, + [PINMUX_EMCP] = { + [CHANNEL_A] = {2, 4, 3, 5, 1, 0}, + [CHANNEL_B] = {4, 5, 2, 0, 3, 1} + }, +}; + static const u8 imp_vref_sel[ODT_MAX][IMP_DRV_MAX] = { /* DRVP DRVN ODTP ODTN */ [ODT_OFF] = {0x37, 0x33, 0x00, 0x37}, @@ -580,6 +593,710 @@ write32(regs_bak[i].addr, regs_bak[i].value); } +static void ca_training_set_perbit_delay_cell(const struct ddr_cali* cali, + u8 chn, u8 rank, u8 *ca_center) +{ + u8 ca_prebit_delay[DQS_BIT_NUMBER] = {0}; + const u8 *ca_mapping = ca_pinmux_mapping[get_pinmux_type(cali)][chn]; + + for (u8 u1CA = 0;u1CA < CA_NUM_LP4;u1CA++) { + ca_prebit_delay[ca_mapping[u1CA]] = ca_center[u1CA]; + dramc_dbg("CA_PerBit_DelayLine[%d]= %d\n", + ca_mapping[u1CA], ca_prebit_delay[ca_mapping[u1CA]]); + } + + SET32_BITFIELDS(&ch[chn].phy_ao.ca_rk[rank].shu_r0_ca_txdly0, + SHU_R0_CA_TXDLY0_TX_ARCA0_DLY, ca_prebit_delay[0], + SHU_R0_CA_TXDLY0_TX_ARCA1_DLY, ca_prebit_delay[1], + SHU_R0_CA_TXDLY0_TX_ARCA2_DLY, ca_prebit_delay[2], + SHU_R0_CA_TXDLY0_TX_ARCA3_DLY, ca_prebit_delay[3]); + SET32_BITFIELDS(&ch[chn].phy_ao.ca_rk[rank].shu_r0_ca_txdly1, + SHU_R0_CA_TXDLY1_TX_ARCA4_DLY, ca_prebit_delay[4], + SHU_R0_CA_TXDLY1_TX_ARCA5_DLY, ca_prebit_delay[5], + SHU_R0_CA_TXDLY1_TX_ARCA6_DLY, ca_prebit_delay[6], + SHU_R0_CA_TXDLY1_TX_ARCA7_DLY, ca_prebit_delay[7]); +} + +static u32 get_ca_ui(u8 chn) +{ + u32 dly = read32(&ch[chn].ao.shu_selph_ca7); + return dly & 0x0FFFFFFFU; +} + +static void put_ca_ui(u8 chn, u32 ca_ui) +{ + u32 dly; + + dly = read32(&ch[chn].ao.shu_selph_ca7); + dly &= 0xF0000000U; + ca_ui &= 0x0FFFFFFFU; + dly |= ca_ui; + + write32(&ch[chn].ao.shu_selph_ca7, dly); + SET32_BITFIELDS(&ch[chn].ao.shu_selph_ca5, SHU_SELPH_CA5_DLY_CKE, ca_ui & 0xF); + SET32_BITFIELDS(&ch[chn].ao.shu_selph_ca6, SHU_SELPH_CA6_DLY_CKE1, ca_ui & 0xF); +} + +static void put_ca_mck(u8 chn, u32 ca_mck) +{ + u32 dly; + + dly = read32(&ch[chn].ao.shu_selph_ca3); + dly &= 0xF0000000U; + ca_mck &= 0x0FFFFFFFU; + dly |= ca_mck; + + write32(&ch[chn].ao.shu_selph_ca3, dly); +} + +static u32 get_cs_ui(u8 chn, u8 rank) +{ + if (rank == RANK_1) + return READ32_BITFIELD(&ch[chn].ao.shu_selph_ca5, SHU_SELPH_CA5_DLY_CS1); + else + return READ32_BITFIELD(&ch[chn].ao.shu_selph_ca5, SHU_SELPH_CA5_DLY_CS); +} + +static u32 get_cs_mck(u8 chn, u8 rank) +{ + if (rank == RANK_1) + return READ32_BITFIELD(&ch[chn].ao.shu_selph_ca1, SHU_SELPH_CA1_TXDLY_CS1); + else + return READ32_BITFIELD(&ch[chn].ao.shu_selph_ca1, SHU_SELPH_CA1_TXDLY_CS); +} + +static int get_capi_max(dram_freq_grp freq_group) +{ + if (freq_group == DDRFREQ_400) + return 32; + + return 64; +} + +static u8 get_ca_pi_per_ui(void) +{ + return 32; +} + +static u8 get_mck_ck_ratio(u8 chn) +{ + u32 ratio = READ32_BITFIELD(&ch[chn].ao.shu_lp5_cmd, SHU_LP5_CMD_LP5_CMD1TO2EN); + + dramc_dbg("MCK:CK=%s\n", ratio == 1 ? "1:1" : "1:2"); + return ratio; +} + +static u8 get_cbtui_adjustable_maxvalue(u8 chn) +{ + u8 ratio = get_mck_ck_ratio(chn); + return ratio == 1 ? 1 : 3; +} + +static void put_cs_ui(u8 chn, u8 rank, u32 cs_ui) +{ + if (rank == RANK_1) + SET32_BITFIELDS(&ch[chn].ao.shu_selph_ca5, SHU_SELPH_CA5_DLY_CS1, cs_ui); + else + SET32_BITFIELDS(&ch[chn].ao.shu_selph_ca5, SHU_SELPH_CA5_DLY_CS, cs_ui); +} + +static void put_cs_mck(u8 chn, u8 rank, u32 cs_ui) +{ + if (rank == RANK_1) + SET32_BITFIELDS(&ch[chn].ao.shu_selph_ca1, SHU_SELPH_CA1_TXDLY_CS1, cs_ui); + else + SET32_BITFIELDS(&ch[chn].ao.shu_selph_ca1, SHU_SELPH_CA1_TXDLY_CS, cs_ui); +} + +static u32 get_ca_mck(u8 chn) +{ + u32 dly = read32(&ch[chn].ao.shu_selph_ca3); + return dly & 0x0FFFFFFFU; +} + +static void xlate_ca_mck_ui(u8 chn, u32 ui_delta, + u32 mck_old, u32 ui_old, u32 *mck_new, u32 *ui_new) +{ + u8 i; + u32 mask, max; + u32 bit_ui, bit_mck; + u32 ui_tmp = 0, mck_tmp = 0; + + max = get_cbtui_adjustable_maxvalue(chn); + mask = max; + + for (i = 0; i < 7; i++) { + bit_mck = 0; + bit_ui = ((ui_old >> (i * 4)) & mask) + ui_delta; + if (bit_ui > max) { + bit_mck = bit_ui / (max + 1); + bit_ui = bit_ui % (max + 1); + } + + mck_tmp += (bit_mck << (i * 4)); + ui_tmp += (bit_ui << (i * 4)); + } + + if (ui_new) + *ui_new = ui_tmp; + + if (mck_new) + *mck_new = mck_old + mck_tmp; +} + +static s16 adjust_cs_ui(const struct ddr_cali* cali, u32 cs_mck, u32 cs_ui, s16 pi_dly) +{ + u8 ratio; + s16 p2u,ui = 0, pi = 0; + u32 ui_max, cs_bit_mask, cs_ui_tmp, cs_mck_tmp; + dram_freq_grp freq_group = get_freq_group(cali); + + u8 chn = cali->chn; + u8 rank = cali->rank; + dramc_dbg("pi_dly:%d, get_capi_max:%d\n", pi_dly, get_capi_max(freq_group)); + + if (pi_dly < get_capi_max(freq_group)) + return pi_dly; + + p2u = get_ca_pi_per_ui(); + + ui = pi_dly / p2u; + pi = pi_dly % p2u; + + ratio = get_mck_ck_ratio(chn); + if (ratio) + /* 1:1 */ + cs_bit_mask = 1; + else + /* 1:2 */ + cs_bit_mask = 3; + + ui_max = get_cbtui_adjustable_maxvalue(chn); + cs_ui_tmp = (cs_ui & cs_bit_mask) + ui; + cs_mck_tmp = 0; + if (cs_ui_tmp > ui_max) { + cs_mck_tmp = cs_ui_tmp / (ui_max + 1); + cs_ui_tmp = cs_ui_tmp % (ui_max + 1); + } + + cs_mck_tmp += cs_mck; + put_cs_ui(chn, rank, cs_ui_tmp); + put_cs_mck(chn, rank, cs_mck_tmp); + + return pi; +} + +static s8 adjust_ca_ui(const struct ddr_cali* cali, u32 ca_mck, u32 ca_ui, s16 pi_dly) +{ + s16 p2u; + s16 ui, pi; + u32 ui_new = 0, mck_new = 0; + dram_freq_grp freq_group = get_freq_group(cali); + + u8 chn = cali->chn; + if (pi_dly < get_capi_max(freq_group)) + return pi_dly; + + p2u = get_ca_pi_per_ui(); + ui = pi_dly / p2u; + pi = pi_dly % p2u; + xlate_ca_mck_ui(chn, ui, ca_mck, ca_ui, &mck_new, &ui_new); + + put_ca_ui(chn, ui_new); + put_ca_mck(chn, mck_new); + dramc_dbg("mck_new: %#x, ui_new: %#x, pi:%d\n", mck_new, ui_new, pi); + + return pi; +} + +static void cbt_set_ca_clk_result(const struct ddr_cali* cali, u32 mck, u32 ui) +{ + s8 final_ca_clk; + u8 chn, rank; + u8 ca_center[DQS_BIT_NUMBER] = {0}; + + chn = cali->chn; + rank = cali->rank; + const struct sdram_params *params = cali->params; + s8 cmd_dly = params->cbt_cmd_dly[chn][rank]; + + for (u8 ca = 0; ca < CA_NUM_LP4; ca++) { + ca_center[ca] = params->cbt_ca_prebit_dly[chn][rank][ca]; + dramc_dbg("ca_center[%d]= %d\n", ca, ca_center[ca]); + } + + final_ca_clk = cmd_dly; + dramc_dbg("CA Dly = %d\n", final_ca_clk); + + final_ca_clk = adjust_ca_ui(cali, mck, ui, final_ca_clk); + dramc_dbg("after adjust, CA Dly = %d\n", final_ca_clk); + for (u8 rk = RANK_0; rk <= rank; rk++) { + cbt_delay_ca_clk(chn, rk, final_ca_clk); + ca_training_set_perbit_delay_cell(cali, chn, rk, ca_center); + } +} + +static void cbt_adjust_cs(const struct ddr_cali* cali) +{ + u8 chn, rank, cs_dly[RANK_MAX]; + u8 cs_final_delay; + u32 pi_dly; + u32 cs_ui, cs_mck; + + const struct sdram_params *params = cali->params; + chn = cali->chn; + rank = cali->rank; + cs_dly[RANK_0] = params->cbt_cs_dly[chn][RANK_0]; + cs_dly[RANK_1] = params->cbt_cs_dly[chn][RANK_1]; + + cs_ui = get_cs_ui(chn, rank); + cs_mck = get_cs_mck(chn, rank); + + if (rank == RANK_0) + cs_final_delay = cs_dly[RANK_0]; + else + cs_final_delay = (cs_dly[RANK_0] + cs_dly[RANK_1]) >> 1; + + for (u8 rk = RANK_0; rk <= rank; rk++) { + pi_dly = adjust_cs_ui(cali, cs_mck, cs_ui, cs_final_delay); + SET32_BITFIELDS(&ch[chn].phy_ao.ca_rk[rk].shu_r0_ca_cmd0, + SHU_R0_CA_CMD0_RG_ARPI_CS, pi_dly); + } + + dramc_dbg("CS Dly: %d\n", cs_final_delay); +} + +static void set_dram_mr_cbt_on_off(const struct ddr_cali* cali, o1_state o1) +{ + u8 chn, rank, fsp; + struct mr_values *mr_value = cali->mr_value; + + chn = cali->chn; + rank = cali->rank; + fsp = get_fsp(cali); + u8 mr13 = mr_value->mr13[rank] & (~ BIT(0)) & (~ BIT(6)) & (~ BIT(7)) ; + + if (o1 == O1_ON) { + if (fsp == FSP_1) + mr13 |= BIT(0) | BIT(6); + else + mr13 |= BIT(0) | BIT(7); + + if (get_cbt_mode(cali) == CBT_BYTE_MODE1) + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl0, + CBT_WLEV_CTRL0_BYTEMODECBTEN, 1, + CBT_WLEV_CTRL0_CBT_CMP_BYTEMODE, 1); + } else { + if (fsp == FSP_1) + mr13 |= BIT(6); + } + + dramc_mode_reg_write_by_rank(cali, chn, rank, 13, mr13); + mr_value->mr13[rank] = mr13; +} + +void o1_path_on_off(const struct ddr_cali* cali, o1_state o1) +{ + u8 chn = cali->chn; + u8 rank = cali->rank; + u8 vref_sel = 0x37; + + if (o1 == O1_ON) { + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].shu_b0_vref, + SHU_B0_VREF_RG_RX_ARDQ_VREF_UNTERM_EN_B0, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].shu_b0_vref, + SHU_B1_VREF_RG_RX_ARDQ_VREF_UNTERM_EN_B1, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].rk[rank].shu_b0_phy_vref_sel, + RG_RX_ARDQ_VREF_SEL_LB_B0, vref_sel, + RG_RX_ARDQ_VREF_SEL_UB_B0, vref_sel); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].rk[rank].shu_b0_phy_vref_sel, + RG_RX_ARDQ_VREF_SEL_LB_B1, vref_sel, + RG_RX_ARDQ_VREF_SEL_UB_B1, vref_sel); + } + + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[0].b0_dq6, + B0_DQ6_RG_RX_ARDQ_O1_SEL_B0, o1); + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[1].b0_dq6, + B1_DQ6_RG_RX_ARDQ_O1_SEL_B1, o1); + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[0].b0_dq3, + B0_DQ3_RG_RX_ARDQ_IN_BUFF_EN_B0, o1, + B0_DQ3_RG_RX_ARDQS0_IN_BUFF_EN_B0, o1); + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[1].b0_dq3, + B1_DQ3_RG_RX_ARDQ_IN_BUFF_EN_B1, o1, + B1_DQ3_RG_RX_ARDQS0_IN_BUFF_EN_B1, o1); + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[0].b0_phy3, + B0_PHY3_RG_RX_ARDQ_BUFF_EN_SEL_B0, o1); + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[1].b0_phy3, + B1_PHY3_RG_RX_ARDQ_BUFF_EN_SEL_B1, o1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_rx_in_gate_en_ctrl, + MISC_RX_IN_GATE_EN_CTRL_FIX_IN_GATE_EN, (o1 << 1) | o1); + + udelay(1); +} + +static void dramc_mode_reg_ca_term(const struct ddr_cali* cali, u8 do_term) +{ + + u8 chn = cali->chn; + u8 fsp = get_fsp(cali); + u8 mr11, mr13, mr22; + struct mr_values *mr_value = cali->mr_value; + static u8 state_do_term[CHANNEL_MAX] = {0}; + + if (state_do_term[chn] == do_term) + return; + + state_do_term[chn] = do_term; + u32 bc_bak = dramc_get_broadcast(); + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + + mr11 = 0x3; + if (get_cbt_mode(cali) == CBT_NORMAL_MODE) + mr11 |= 0x40; + else + mr11 |= 0x20; + + for (u8 rk = RANK_0; rk < cali->support_ranks; rk++) { + mr13 = mr_value->mr13[rk] & (~ BIT(6)) & (~ BIT(7)); + mr13 |= BIT(6); + dramc_mode_reg_write_by_rank(cali, chn, rk, 13, mr13); + mr_value->mr13[rk] = mr13; + + dramc_mode_reg_write_by_rank(cali, chn, rk, 11, mr11); + mr_value->mr11[fsp] = mr11; + + if (do_term) { + mr22 = 0x4; + } else { + if (rk == RANK_0) + mr22 = 0x4; + else + mr22 = 0x2c; + } + + dramc_mode_reg_write_by_rank(cali, chn, rk, 22, mr22); + mr_value->mr22[fsp] = mr22; + } + + dramc_set_broadcast(bc_bak); +} + +static void cbt_entry(const struct ddr_cali* cali) +{ + u8 chn, rank, fsp; + u8 mr13, dram_dq_b0 = 0; + struct mr_values *mr_value = cali->mr_value; + + chn = cali->chn; + rank = cali->rank; + fsp = get_fsp(cali); + mr13 = mr_value->mr13[rank]; + + if (fsp == FSP_1) + dramc_mode_reg_ca_term(cali, 1); + + SET32_BITFIELDS(&ch[chn].phy_ao.misc_stbcal, MISC_STBCAL_DQSIENCG_NORMAL_EN, 0); + + cke_fix_onoff(cali, chn, rank, CKE_FIXON); + SET32_BITFIELDS(&ch[chn].ao.swcmd_ctrl0, SWCMD_CTRL0_MRSRK, rank); + + set_dram_mr_cbt_on_off(cali, true); + + if (get_cbt_mode(cali) == CBT_NORMAL_MODE) { + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl0, + CBT_WLEV_CTRL0_WRITE_LEVEL_EN, 1); + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl0, + CBT_WLEV_CTRL0_DQSOEAOEN, 0x1); + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl0, + CBT_WLEV_CTRL0_CBT_DQBYTE_OEAO_EN, 1 << dram_dq_b0); + } + + udelay(1); + cke_fix_onoff(cali, chn, rank, CKE_FIXOFF); + + if (fsp == FSP_1) + mr13 |= BIT(7); + else + mr13 &= (~ BIT(7)); + mr_value->mr13[rank] = mr13; + + o1_path_on_off(cali, O1_ON); + + udelay(1); +} + +static void cbt_exit(const struct ddr_cali* cali) +{ + u8 chn = cali->chn; + u8 rank = cali->rank; + u8 cbt_mode = get_cbt_mode(cali); + + if (cbt_mode == CBT_NORMAL_MODE || cbt_mode == CBT_BYTE_MODE1) { + cke_fix_onoff(cali, chn, rank, CKE_FIXON); + udelay(1); + set_dram_mr_cbt_on_off(cali, false); + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl0, CBT_WLEV_CTRL0_WRITE_LEVEL_EN, 0); + } + + o1_path_on_off(cali, O1_OFF); + if (cbt_mode == CBT_BYTE_MODE1) + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl0, + CBT_WLEV_CTRL0_BYTEMODECBTEN, 0, + CBT_WLEV_CTRL0_CBT_CMP_BYTEMODE, 0); + + udelay(1); +} + +static void cbt_entry_top(const struct ddr_cali* cali) +{ + u8 chn, fsp; + + chn = cali->chn; + fsp = get_fsp(cali); + + if(fsp == FSP_1) { + SET32_BITFIELDS(&ch[chn].phy_ao.ca_cmd2, + CA_CMD2_RG_TX_ARCMD_OE_DIS_CA, 1, + CA_CMD2_RG_TX_ARCA_OE_TIE_SEL_CA, 0, + CA_CMD2_RG_TX_ARCA_OE_TIE_EN_CA, 0xff); + cbt_switch_freq(cali, CBT_LOW_FREQ); + SET32_BITFIELDS(&ch[chn].phy_ao.ca_cmd2, + CA_CMD2_RG_TX_ARCMD_OE_DIS_CA, 0, + CA_CMD2_RG_TX_ARCA_OE_TIE_SEL_CA, 1, + CA_CMD2_RG_TX_ARCA_OE_TIE_EN_CA, 0xff); + } + cbt_entry(cali); + + if(fsp == FSP_1) + cbt_switch_freq(cali, CBT_HIGH_FREQ); +} + +static void cbt_exit_top(const struct ddr_cali* cali, cbt_state state) +{ + if (state == OUT_CBT || get_cbt_mode(cali) == CBT_BYTE_MODE1){ + if (get_fsp(cali) == FSP_1) + cbt_switch_freq(cali, CBT_LOW_FREQ); + cbt_exit(cali); + } +} + +static void cbt_set_vref(const struct ddr_cali* cali, cbt_state state) +{ + u8 chn, rank, fsp, range; + u8 dram_dq_b0 = 0; + u8 vref_value_pinmux; + u8 ca_vref, mr12, mr13; + struct mr_values *mr_value = cali->mr_value; + const struct sdram_params *params = cali->params; + + chn = cali->chn; + rank = cali->rank; + fsp = get_fsp(cali); + ca_vref = params->cbt_final_vref[chn][rank]; + mr12 = mr_value->mr12[chn][rank][fsp]; + range = mr12 >> 6; + + if (state == IN_CBT && get_cbt_mode(cali) == CBT_NORMAL_MODE) { + vref_value_pinmux = get_cbt_vref_pinmux_value(cali, range, ca_vref); + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl4, + CBT_WLEV_CTRL4_CBT_TXDQ_B0, vref_value_pinmux); + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl0, + CBT_WLEV_CTRL0_CBT_WLEV_DQS_SEL, 0x1 << dram_dq_b0); + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl3, + CBT_WLEV_CTRL3_DQSBX_G, 0xa); + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl0, + CBT_WLEV_CTRL0_CBT_WLEV_DQS_TRIG, 1); + udelay(1); + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl0, + CBT_WLEV_CTRL0_CBT_WLEV_DQS_TRIG, 0); + } else { + if (fsp == FSP_1) { + mr13 = mr_value->mr13[rank] | (0x1 << 6); + dramc_mode_reg_write_by_rank(cali, chn, rank, 13, mr13); + mr_value->mr13[rank] = mr13; + } + + dramc_dbg("CmdBusTraining Vref(ca) range %d: %d\n", range, ca_vref); + + ca_vref = ((range & 0x1) << 6) | (ca_vref & 0x3f); + dramc_mode_reg_write_by_rank(cali, chn, rank, 12, ca_vref); + mr_value->mr12[chn][rank][fsp] = ca_vref; + } + udelay(1); +} + +static void cbt_set_best_vref(const struct ddr_cali* cali, cbt_state state) +{ + u8 fsp = get_fsp(cali); + + if (state == IN_CBT && get_cbt_mode(cali) == CBT_BYTE_MODE1) { + if (fsp == FSP_1) + cbt_switch_freq(cali, CBT_LOW_FREQ); + + cbt_exit(cali); + cbt_set_vref(cali, state); + cbt_entry(cali); + if (fsp == FSP_1) + cbt_switch_freq(cali, CBT_HIGH_FREQ); + } else { + cbt_set_vref(cali, state); + } +} + +static void set_cbt_wlev_intv(u8 chn, dram_freq_grp freq_group) +{ + u8 tcmdo1lat; + u8 catrain_intv; + u8 new_cbt_pat_intv; + u8 wlev_dqspat_lat; + + switch (freq_group) { + case DDRFREQ_400: + tcmdo1lat = 12; + catrain_intv = 13; + new_cbt_pat_intv = 12; + wlev_dqspat_lat = 12; + break; + case DDRFREQ_600: + tcmdo1lat = 9; + catrain_intv = 8; + new_cbt_pat_intv = 11; + wlev_dqspat_lat = 11; + break; + case DDRFREQ_800: + tcmdo1lat = 10; + catrain_intv = 8; + new_cbt_pat_intv = 12; + wlev_dqspat_lat = 12; + break; + case DDRFREQ_933: + tcmdo1lat = 11; + catrain_intv = 9; + new_cbt_pat_intv = 13; + wlev_dqspat_lat = 13; + break; + case DDRFREQ_1200: + tcmdo1lat = 12; + catrain_intv = 9; + new_cbt_pat_intv = 14; + wlev_dqspat_lat = 14; + break; + case DDRFREQ_1600: + tcmdo1lat = 14; + catrain_intv = 11; + new_cbt_pat_intv = 16; + wlev_dqspat_lat = 16; + break; + case DDRFREQ_2133: + tcmdo1lat = 17; + catrain_intv = 14; + new_cbt_pat_intv = 19; + wlev_dqspat_lat = 19; + break; + default: + die("Invalid DDR frequency group %u\n", freq_group); + return; + } + + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl1, + CBT_WLEV_CTRL1_TCMDO1LAT, tcmdo1lat, + CBT_WLEV_CTRL1_CATRAIN_INTV, catrain_intv); + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl5, + CBT_WLEV_CTRL5_NEW_CBT_PAT_INTV, new_cbt_pat_intv); + SET32_BITFIELDS(&ch[chn].ao.cbt_wlev_ctrl0, + CBT_WLEV_CTRL0_WLEV_DQSPAT_LAT, wlev_dqspat_lat); +} + +static void dramc_cmd_ui_delay_setting(u8 chn, u8 value) +{ + SET32_BITFIELDS(&ch[chn].ao.shu_selph_ca7, + SHU_SELPH_CA7_DLY_RA0, value, + SHU_SELPH_CA7_DLY_RA1, value, + SHU_SELPH_CA7_DLY_RA2, value, + SHU_SELPH_CA7_DLY_RA3, value, + SHU_SELPH_CA7_DLY_RA4, value, + SHU_SELPH_CA7_DLY_RA5, value, + SHU_SELPH_CA7_DLY_RA6, value); + + SET32_BITFIELDS(&ch[chn].ao.shu_selph_ca5, + SHU_SELPH_CA5_DLY_CKE, value); + SET32_BITFIELDS(&ch[chn].ao.shu_selph_ca6, + SHU_SELPH_CA6_DLY_CKE1, value); +} + +void dramc_cmd_bus_training(const struct ddr_cali* cali) +{ + u8 chn, rank, fsp; + u32 ca_ui, ca_mck; + u8 ca_final_center[CA_NUM_LP4] = {0}; + + chn = cali->chn; + rank = cali->rank; + fsp = get_fsp(cali); + + struct reg_bak regs_bak[] = { + {&ch[chn].ao.dramc_pd_ctrl}, + {&ch[chn].phy_ao.misc_stbcal}, + {&ch[chn].ao.ckectrl}, + {&ch[chn].phy_ao.dvs_b[0].b0_dq2}, + {&ch[chn].phy_ao.dvs_b[1].b0_dq2}, + {&ch[chn].ao.cbt_wlev_ctrl0}, + {&ch[chn].ao.cbt_wlev_ctrl1}, + {&ch[chn].ao.cbt_wlev_ctrl2}, + {&ch[chn].ao.cbt_wlev_ctrl3}, + {&ch[chn].ao.cbt_wlev_ctrl4}, + {&ch[chn].ao.swcmd_ctrl0}, + {&ch[chn].ao.refctrl0}, + {&ch[chn].phy_ao.byte[0].shu_b0_vref}, + {&ch[chn].phy_ao.byte[1].shu_b0_vref}, + {&ch[chn].phy_ao.byte[0].rk[rank].shu_b0_phy_vref_sel}, + {&ch[chn].phy_ao.byte[1].rk[rank].shu_b0_phy_vref_sel}, + }; + + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + regs_bak[i].value = read32(regs_bak[i].addr); + + ca_training_set_perbit_delay_cell(cali, chn, rank, ca_final_center); + dramc_cmd_ui_delay_setting(chn, 1); + cbt_delay_ca_clk(chn, rank, 0); + + ca_mck = get_ca_mck(chn); + dramc_auto_refresh_switch(chn, false); + + set_cbt_wlev_intv(chn, get_freq_group(cali)); + SET32_BITFIELDS(&ch[chn].ao.tx_set0, TX_SET0_TXRANK, rank); + SET32_BITFIELDS(&ch[chn].ao.tx_set0, TX_SET0_TXRANKFIX, 1); + SET32_BITFIELDS(&ch[chn].ao.dramc_pd_ctrl, + DRAMC_PD_CTRL_DCMEN2, 0, + DRAMC_PD_CTRL_MIOCKCTRLOFF, 1, + DRAMC_PD_CTRL_PHYCLKDYNGEN, 0, + DRAMC_PD_CTRL_COMBCLKCTRL, 0, + DRAMC_PD_CTRL_APHYCKCG_FIXOFF, 1, + DRAMC_PD_CTRL_TCKFIXON, 1); + + cbt_entry_top(cali); + cbt_set_best_vref(cali, IN_CBT); + dramc_cmd_UI_delay_setting(chn, 0); + ca_ui = get_ca_ui(chn); + + put_ca_ui(chn, ca_ui); + cbt_set_ca_clk_result(cali, ca_mck, ca_ui); + udelay(1); + + cbt_adjust_cs(cali); + cbt_exit_top(cali, OUT_CBT); + cbt_set_best_vref(cali, OUT_CBT); + + if (fsp == FSP_1) + dramc_mode_reg_ca_term(cali, 0); + + SET32_BITFIELDS(&ch[chn].ao.tx_set0, TX_SET0_TXRANK, 0); + SET32_BITFIELDS(&ch[chn].ao.tx_set0, TX_SET0_TXRANKFIX, 0); + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + write32(regs_bak[i].addr, regs_bak[i].value); + +} + static void duty_delay_reg_convert(s8 duty_delay, u8 *delay) { u8 delay_tmp; @@ -615,7 +1332,6 @@ } } - static void dramc_duty_set_wck_delay_cell(u8 chn, const s8* duty_delay) { u8 dqs; diff --git a/src/soc/mediatek/mt8192/dramc_pi_main.c b/src/soc/mediatek/mt8192/dramc_pi_main.c index 11ec636..214bf55 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_main.c +++ b/src/soc/mediatek/mt8192/dramc_pi_main.c @@ -225,6 +225,14 @@ CA_CMD2_RG_TX_ARCMD_OE_DIS_CA, 0, CA_CMD2_RG_TX_ARCA_OE_TIE_SEL_CA, 1, CA_CMD2_RG_TX_ARCA_OE_TIE_EN_CA, 0xff); + + for (u8 rank = RANK_0; rank < cali->support_ranks; rank++) { + cali->rank = rank; + dramc_auto_refresh_switch(chn, false); + dramc_cmd_bus_training(cali); + } + + shuffle_dfs_to_fsp1(cali); } static void dramc_calibration_all_channels(struct ddr_cali *cali) -- To view, visit
https://review.coreboot.org/c/coreboot/+/44716
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: I06ee26e3b82811bffa09ab5e3e535b3174c3e3a6 Gerrit-Change-Number: 44716 Gerrit-PatchSet: 1 Gerrit-Owner: CK HU <ck.hu(a)mediatek.com> Gerrit-Reviewer: Duan huayang <huayang.duan(a)mediatek.com> Gerrit-Reviewer: Julius Werner <jwerner(a)chromium.org> Gerrit-MessageType: newchange
7
17
0
0
Change in coreboot[master]: soc/mediatek/mt8192: Do dramc rx datlat training
by CK HU (Code Review)
08 Mar '21
08 Mar '21
Hello Duan huayang, I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/44721
to review the following change. Change subject: soc/mediatek/mt8192: Do dramc rx datlat training ...................................................................... soc/mediatek/mt8192: Do dramc rx datlat training Signed-off-by: Huayang Duan <huayang.duan(a)mediatek.com> Change-Id: I9a426e1273dceae3a739bbbfc36db44d3ba9140d --- M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c M src/soc/mediatek/mt8192/dramc_pi_main.c 2 files changed, 54 insertions(+), 0 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/21/44721/1 diff --git a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c index 602e61d..9ccedf1 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c @@ -1408,6 +1408,36 @@ dramc_set_broadcast(bc_bak); } +static void dramc_dle_factor_handler(u8 chn, u8 value) +{ + u8 datlat_dsel = 0, dlecg_ext1 = 0, dlecg_ext2 = 0, dlecg_ext3 = 0; + + if (READ32_BITFIELD(&ch[chn].phy_ao.shu_misc_rx_pipe_ctrl, + SHU_MISC_RX_PIPE_CTRL_RX_PIPE_BYPASS_EN)) + datlat_dsel = value; + else + datlat_dsel = (value < 1) ? value : value - 1; + + SET32_BITFIELDS(&ch[chn].phy_ao.misc_shu_rdat, + MISC_SHU_RDAT_DATLAT, value, + MISC_SHU_RDAT_DATLAT_DSEL, datlat_dsel, + MISC_SHU_RDAT_DATLAT_DSEL_PHY, datlat_dsel); + + dlecg_ext1 = (value >= 8) ? 1 : 0; + dlecg_ext2 = (value >= 14) ? 1 : 0; + dlecg_ext3 = (value >= 19) ? 1 : 0; + + SET32_BITFIELDS(&ch[chn].ao.shu_rx_cg_set0, + SHU_RX_CG_SET0_READ_START_EXTEND1, dlecg_ext1, + SHU_RX_CG_SET0_DLE_LAST_EXTEND1, dlecg_ext1, + SHU_RX_CG_SET0_READ_START_EXTEND2, dlecg_ext2, + SHU_RX_CG_SET0_DLE_LAST_EXTEND2, dlecg_ext2, + SHU_RX_CG_SET0_READ_START_EXTEND3, dlecg_ext3, + SHU_RX_CG_SET0_DLE_LAST_EXTEND3, dlecg_ext3); + + dramc_phy_reset(chn); +} + static u8 rxdqs_gating_get_tx_dly_min(dram_freq_grp freq_group, struct rxdqs_gating_best_win *rxdqs_best_win) { @@ -2713,3 +2743,25 @@ update_tx_tracking(chn, rk, cali_type, dq_pi, dqm_pi); } } + +void dramc_rx_datlat_cal(const struct ddr_cali* cali) +{ + u8 chn = cali->chn; + u8 rank = cali->rank; + u8 datlat = cali->params->rx_datlat[chn][rank]; + dramc_dbg("best_step = %d\n", datlat); + + dramc_engine2_init(chn, rank); + dramc_dle_factor_handler(chn, datlat); +} + +void dramc_dual_rank_rx_datlat_cal(const struct ddr_cali* cali) +{ + u8 chn = cali->chn; + u8 datlat_1 = cali->params->rx_datlat[chn][0]; + u8 datlat_2 = cali->params->rx_datlat[chn][1]; + u8 final_datlat = MAX(datlat_1, datlat_2); + + dramc_dle_factor_handler(chn, final_datlat); +} + diff --git a/src/soc/mediatek/mt8192/dramc_pi_main.c b/src/soc/mediatek/mt8192/dramc_pi_main.c index f724e54..9df4285 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_main.c +++ b/src/soc/mediatek/mt8192/dramc_pi_main.c @@ -287,9 +287,11 @@ switch_write_dbi_settings(cali, DBI_OFF); } + dramc_rx_datlat_cal(cali); dramc_rx_window_perbit_cal(cali, RX_WIN_TEST_ENG); } dramc_rx_dqs_gating_post_process(cali, txdly_min, txdly_max); + dramc_dual_rank_rx_datlat_cal(cali); } static void dramc_calibration_all_channels(struct ddr_cali *cali) -- To view, visit
https://review.coreboot.org/c/coreboot/+/44721
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: I9a426e1273dceae3a739bbbfc36db44d3ba9140d Gerrit-Change-Number: 44721 Gerrit-PatchSet: 1 Gerrit-Owner: CK HU <ck.hu(a)mediatek.com> Gerrit-Reviewer: Duan huayang <huayang.duan(a)mediatek.com> Gerrit-Reviewer: Julius Werner <jwerner(a)chromium.org> Gerrit-MessageType: newchange
5
8
0
0
Change in coreboot[master]: soc/mediatek/mt8192: Do dramc txoe training
by CK HU (Code Review)
08 Mar '21
08 Mar '21
Hello Duan huayang, I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/44722
to review the following change. Change subject: soc/mediatek/mt8192: Do dramc txoe training ...................................................................... soc/mediatek/mt8192: Do dramc txoe training Signed-off-by: Huayang Duan <huayang.duan(a)mediatek.com> Change-Id: I72ae272d145f3b4aaa1076f1fec3b8b1384d4293 --- M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c M src/soc/mediatek/mt8192/dramc_pi_main.c 2 files changed, 31 insertions(+), 1 deletion(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/22/44722/1 diff --git a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c index 9ccedf1..ce03db4 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c @@ -2744,6 +2744,35 @@ } } +void dramc_tx_oe_calibration(const struct ddr_cali* cali) +{ + u8 chn = cali->chn; + u8 rank = cali->rank; + const struct sdram_params *params = cali->params; + u8 large[DQS_NUMBER], small[DQS_NUMBER]; + + if (cali->freq_group < DDRFREQ_1600) + return; + + for (u8 byte = 0; byte < DQS_NUMBER; byte++) { + large[byte] = params->tx_oe_dq_mck[chn][rank][byte]; + small[byte] = params->tx_oe_dq_ui[chn][rank][byte]; + } + + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_selph_dq0, + SHURK_SELPH_DQ0_TXDLY_OEN_DQ0, large[0], + SHURK_SELPH_DQ0_TXDLY_OEN_DQ1, large[1]); + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_selph_dq1, + SHURK_SELPH_DQ1_TXDLY_OEN_DQM0, large[0], + SHURK_SELPH_DQ1_TXDLY_OEN_DQM1, large[1]); + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_selph_dq2, + SHURK_SELPH_DQ2_DLY_OEN_DQ0, small[0], + SHURK_SELPH_DQ2_DLY_OEN_DQ1, small[1]); + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_selph_dq3, + SHURK_SELPH_DQ3_DLY_OEN_DQM0, small[0], + SHURK_SELPH_DQ3_DLY_OEN_DQM1, small[1]); +} + void dramc_rx_datlat_cal(const struct ddr_cali* cali) { u8 chn = cali->chn; diff --git a/src/soc/mediatek/mt8192/dramc_pi_main.c b/src/soc/mediatek/mt8192/dramc_pi_main.c index 9df4285..052b320 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_main.c +++ b/src/soc/mediatek/mt8192/dramc_pi_main.c @@ -30,7 +30,7 @@ dramc_write_shift_mck_write_DBI(cali, tx_shift); mr03 = (mr03 & ~(0x1 << 7)) | (dbi_state << 7); - dramc_mode_reg_write_by_rank(chn, rank, 3, mr03); + dramc_mode_reg_write_by_rank(cali, chn, rank, 3, mr03); mr_value->mr03[get_fsp(cali)] = mr03; dramc_write_dbi_onoff(dbi_state); @@ -289,6 +289,7 @@ dramc_rx_datlat_cal(cali); dramc_rx_window_perbit_cal(cali, RX_WIN_TEST_ENG); + dramc_tx_oe_calibration(cali); } dramc_rx_dqs_gating_post_process(cali, txdly_min, txdly_max); dramc_dual_rank_rx_datlat_cal(cali); -- To view, visit
https://review.coreboot.org/c/coreboot/+/44722
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: I72ae272d145f3b4aaa1076f1fec3b8b1384d4293 Gerrit-Change-Number: 44722 Gerrit-PatchSet: 1 Gerrit-Owner: CK HU <ck.hu(a)mediatek.com> Gerrit-Reviewer: Duan huayang <huayang.duan(a)mediatek.com> Gerrit-Reviewer: Julius Werner <jwerner(a)chromium.org> Gerrit-MessageType: newchange
4
7
0
0
Change in coreboot[master]: soc/mediatek/mt8192: set dramc dqsosc shuffle setting
by CK HU (Code Review)
08 Mar '21
08 Mar '21
Hello Duan huayang, I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/44723
to review the following change. Change subject: soc/mediatek/mt8192: set dramc dqsosc shuffle setting ...................................................................... soc/mediatek/mt8192: set dramc dqsosc shuffle setting Signed-off-by: Huayang Duan <huayang.duan(a)mediatek.com> Change-Id: Icf638f4d88a10ce451d63ea431facb2899b2be85 --- M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c M src/soc/mediatek/mt8192/dramc_pi_main.c 2 files changed, 225 insertions(+), 0 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/23/44723/1 diff --git a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c index ce03db4..2082f4d 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c @@ -2794,3 +2794,223 @@ dramc_dle_factor_handler(chn, final_datlat); } +static void dramc_start_dqsosc(const struct ddr_cali* cali) +{ + u8 chn = cali->chn; + const u32 timeout = 100; + + struct reg_bak regs_bak[] = { + {&ch[chn].ao.swcmd_en}, + {&ch[chn].ao.swcmd_ctrl0}, + {&ch[chn].ao.dramc_pd_ctrl}, + {&ch[chn].ao.ckectrl}, + }; + + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + regs_bak[i].value = read32(regs_bak[i].addr); + + SET32_BITFIELDS(&ch[chn].ao.dramc_pd_ctrl, DRAMC_PD_CTRL_APHYCKCG_FIXOFF, 1); + SET32_BITFIELDS(&ch[chn].ao.dramc_pd_ctrl, DRAMC_PD_CTRL_TCKFIXON, 1); + + udelay(1); + cke_fix_onoff(cali, chn, RANK_MAX, CKE_FIXON); + SET32_BITFIELDS(&ch[chn].ao.swcmd_en, SWCMD_EN_WCK2DQI_START_SWTRIG, 1); + + if (!wait_us(timeout, READ32_BITFIELD(&ch[chn].nao.spcmdresp3, + SPCMDRESP3_WCK2DQI_START_SWTRIG_RESPONSE))) { + dramc_err("ZQCAL Start fail (time out)\n"); + return; + } + SET32_BITFIELDS(&ch[chn].ao.swcmd_en, SWCMD_EN_WCK2DQI_START_SWTRIG, 0); + + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + write32(regs_bak[i].addr, regs_bak[i].value); +} + +static u16 dramc_dqsosc_auto(const struct ddr_cali* cali) +{ + u8 chn, rank; + u8 mr18, mr19, mr23; + u32 frequency; + + u16 dqs_cnt; + u16 dqsosc_cnt[RANK_MAX]; + u16 final_dqsosc; + + chn = cali->chn; + rank = cali->rank; + mr23 = cali->mr_value->mr23[chn][rank]; + frequency = get_frequency(cali); + + struct reg_bak regs_bak[] = { + {&ch[chn].ao.dramc_pd_ctrl}, + {&ch[chn].ao.ckectrl} + }; + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + regs_bak[i].value = read32(regs_bak[i].addr); + + dramc_mode_reg_write_by_rank(cali, chn, rank, 23, mr23); + SET32_BITFIELDS(&ch[chn].ao.shu_dqsosc_set0, SHU_DQSOSC_SET0_DQSOSCENDIS, 1); + SET32_BITFIELDS(&ch[chn].ao.dramc_pd_ctrl, DRAMC_PD_CTRL_APHYCKCG_FIXOFF, 1); + SET32_BITFIELDS(&ch[chn].ao.dramc_pd_ctrl, DRAMC_PD_CTRL_TCKFIXON, 1); + + cke_fix_onoff(cali, chn, rank, CKE_FIXON); + dramc_start_dqsosc(cali); + udelay(1); + + mr18 = dramc_mode_reg_read_by_rank(chn, rank, 18); + mr19 = dramc_mode_reg_read_by_rank(chn, rank, 19); + + dqs_cnt = mr18 | (mr19 << 8); + if (dqs_cnt != 0) + dqsosc_cnt[0] = mr23 * 16 * 1000000 / (2 * dqs_cnt * frequency); + else + dqsosc_cnt[0] = 0; + + dqs_cnt = (mr18 >> 8) | (mr19 & 0xff00); + if (dqs_cnt != 0) + dqsosc_cnt[1] = mr23 * 16 * 1000000 / (2 * dqs_cnt * frequency); + else + dqsosc_cnt[1] = 0; + dramc_dbg("[DQSOSCAuto] RK%d, (LSB)MR18= %#x, (MSB)MR19= %#x, tDQSOscB0 = %d ps tDQSOscB1 = %d ps\n", + rank, mr18, mr19, dqsosc_cnt[0], dqsosc_cnt[1]); + + cali->mr_value->mr18[chn][rank] = mr18; + cali->mr_value->mr19[chn][rank] = mr19; + + if (dqsosc_cnt[1] != 0 && dqsosc_cnt[1] < dqsosc_cnt[0]) + final_dqsosc = dqsosc_cnt[1]; + else + final_dqsosc = dqsosc_cnt[0]; + + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + write32(regs_bak[i].addr, regs_bak[i].value); + + return final_dqsosc; +} + +void dramc_dqsosc_set_mr18_mr19(const struct ddr_cali* cali, + u16 *dqsosc_thrd_inc, u16 *dqsosc_thrd_dec) +{ + u8 chn, rank; + u8 mr18, mr19, mr23; + u16 dqsosc_cnt[2], dqsosc; + u32 tCK; + + chn = cali->chn; + rank = cali->rank; + + dqsosc = dramc_dqsosc_auto(cali); + mr18 = cali->mr_value->mr18[chn][rank]; + mr19 = cali->mr_value->mr19[chn][rank]; + mr23 = cali->mr_value->mr23[chn][rank]; + + dqsosc_cnt[0] = mr18 | (mr19 << 8); + dqsosc_cnt[1] = (mr18 >> 8) | ((mr19 & 0xff00)); + + if ((get_cbt_mode(cali) == CBT_NORMAL_MODE) && (dqsosc_cnt[1] == 0)) + dqsosc_cnt[1] = dqsosc_cnt[0]; + + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_dqsosc, + SHURK_DQSOSC_DQSOSC_BASE_RK0, dqsosc_cnt[0], + SHURK_DQSOSC_DQSOSC_BASE_RK0_B1, dqsosc_cnt[1]); + + tCK = 1000000 / get_frequency(cali); + if (dqsosc != 0) { + dqsosc_thrd_inc[rank] = (3 * mr23 * tCK * tCK) / (dqsosc * dqsosc * 20); + dqsosc_thrd_dec[rank] = (mr23 * tCK * tCK) / (dqsosc * dqsosc * 10); + } + + dramc_dbg("CH%d_RK%d: MR19=0x%X, MR18=0x%X, DQSOSC=%d, MR23=%u, INC=%u, DEC=%u\n", + chn, rank, mr19, mr18, dqsosc, mr23, + dqsosc_thrd_inc[rank], dqsosc_thrd_dec[rank]); +} + +void dqsosc_shu_settings(const struct ddr_cali* cali, + u16 *dqsosc_thrd_inc, u16 *dqsosc_thrd_dec) +{ + u8 prd_cnt_div = 4; + u8 filt_pi_thrd = 0; + u8 w2r_sel = 0; + u8 dqsosc_cr_cnt = 0, is_div4 = 0, round_up= 0; + u16 dqsosc_en_cnt = 0xfff; + u16 prd_cnt = 0x3ff, prd_cnt_tmp = 0x3ff; + + u8 chn = cali->chn; + u32 frequency = get_frequency(cali); + dram_freq_grp freq_group = cali->freq_group; + u8 mr23[RANK_MAX] = {cali->mr_value->mr23[chn][0], cali->mr_value->mr23[chn][1]}; + + SET32_BITFIELDS(&ch[chn].ao.shu_tx_set0, SHU_TX_SET0_DQS2DQ_FILT_PITHRD, 0x0); + SET32_BITFIELDS(&ch[chn].ao.dqsoscr, DQSOSCR_R_DMDQS2DQ_FILT_OPT, 0x0); + + switch (freq_group) { + case DDRFREQ_400: + filt_pi_thrd = 0x5; + w2r_sel = 0x2; + prd_cnt_div = 2; + is_div4 = 1; + break; + case DDRFREQ_600: + filt_pi_thrd = 0x6; + w2r_sel = 0x5; + break; + case DDRFREQ_800: + filt_pi_thrd = 0x6; + w2r_sel = 0x5; + break; + case DDRFREQ_933: + filt_pi_thrd = 0x9; + w2r_sel = 0x2; + break; + case DDRFREQ_1200: + filt_pi_thrd = 0xb; + w2r_sel = 0x2; + break; + case DDRFREQ_1600: + filt_pi_thrd = 0xE; + w2r_sel = 0x2; + break; + case DDRFREQ_2133: + filt_pi_thrd = 0x17; + w2r_sel = 0x2; + break; + default: + die("Invalid DDR frequency group %u\n", freq_group); + return; + } + + dqsosc_cr_cnt = ((frequency << is_div4)) / 100; + if ((frequency % 100) != 0) + dqsosc_cr_cnt++; + + if (mr23[RANK_1] > mr23[RANK_0]) + prd_cnt_tmp = ((mr23[RANK_1] * 100) / prd_cnt_div); + else + prd_cnt_tmp = ((mr23[RANK_0] * 100) / prd_cnt_div); + + prd_cnt = (prd_cnt_tmp + dqsosc_cr_cnt * 100 / 16) / 100; + round_up = (prd_cnt_tmp + dqsosc_cr_cnt *100 / 16) % 100; + if (round_up != 0) + prd_cnt++; + + SET32_BITFIELDS(&ch[chn].ao.shu_dqsosc_set0, + SHU_DQSOSC_SET0_DQSOSC_PRDCNT, prd_cnt); + SET32_BITFIELDS(&ch[chn].ao.shu_dqsoscr, + SHU_DQSOSCR_DQSOSCRCNT, dqsosc_cr_cnt); + SET32_BITFIELDS(&ch[chn].ao.shu_tx_set0, + SHU_TX_SET0_DQS2DQ_FILT_PITHRD, filt_pi_thrd); + SET32_BITFIELDS(&ch[chn].ao.shu_tx_set0, + SHU_TX_SET0_TXUPD_W2R_SEL, w2r_sel, + SHU_TX_SET0_TXUPD_SEL, 0x0); + + for (u8 rk = RANK_0; rk < cali->support_ranks; rk++) { + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rk].shurk_dqsosc_thrd, + SHURK_DQSOSC_THRD_DQSOSCTHRD_INC, dqsosc_thrd_inc[rk]); + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rk].shurk_dqsosc_thrd, + SHURK_DQSOSC_THRD_DQSOSCTHRD_DEC, dqsosc_thrd_dec[rk]); + } + + SET32_BITFIELDS(&ch[chn].ao.shu_dqsosc_set0, + SHU_DQSOSC_SET0_DQSOSCENCNT, dqsosc_en_cnt); +} diff --git a/src/soc/mediatek/mt8192/dramc_pi_main.c b/src/soc/mediatek/mt8192/dramc_pi_main.c index 052b320..11c5d3a 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_main.c +++ b/src/soc/mediatek/mt8192/dramc_pi_main.c @@ -242,6 +242,8 @@ { u8 txdly_min, txdly_max; u8 dqs_final_delay[RANK_MAX][DQS_NUMBER]; + u16 dqsosc_thrd_inc[RANK_MAX]; + u16 dqsosc_thrd_dec[RANK_MAX]; cali->chn = chn; SET32_BITFIELDS(&ch[chn].phy_ao.ca_cmd2, @@ -290,7 +292,10 @@ dramc_rx_datlat_cal(cali); dramc_rx_window_perbit_cal(cali, RX_WIN_TEST_ENG); dramc_tx_oe_calibration(cali); + dramc_auto_refresh_switch(chn, false); + dramc_dqsosc_set_mr18_mr19(cali, dqsosc_thrd_inc, dqsosc_thrd_dec); } + dqsosc_shu_settings(cali, dqsosc_thrd_inc, dqsosc_thrd_dec); dramc_rx_dqs_gating_post_process(cali, txdly_min, txdly_max); dramc_dual_rank_rx_datlat_cal(cali); } -- To view, visit
https://review.coreboot.org/c/coreboot/+/44723
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: Icf638f4d88a10ce451d63ea431facb2899b2be85 Gerrit-Change-Number: 44723 Gerrit-PatchSet: 1 Gerrit-Owner: CK HU <ck.hu(a)mediatek.com> Gerrit-Reviewer: Duan huayang <huayang.duan(a)mediatek.com> Gerrit-Reviewer: Julius Werner <jwerner(a)chromium.org> Gerrit-MessageType: newchange
6
10
0
0
Change in coreboot[master]: soc/mediatek/mt8192: Do dramc tx window training
by CK HU (Code Review)
08 Mar '21
08 Mar '21
Hello Duan huayang, I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/44720
to review the following change. Change subject: soc/mediatek/mt8192: Do dramc tx window training ...................................................................... soc/mediatek/mt8192: Do dramc tx window training Signed-off-by: Huayang Duan <huayang.duan(a)mediatek.com> Change-Id: Ica11573c1e0b657be0e8ddcbf81a9e3f2399e258 --- M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c M src/soc/mediatek/mt8192/dramc_pi_main.c 2 files changed, 794 insertions(+), 0 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/44720/1 diff --git a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c index 363a3bd..602e61d 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c @@ -5,6 +5,11 @@ #include <soc/dramc_register.h> #include <timer.h> +#define PASS_RANGE_NA 0x7fff +#define TX_VREF_RANGE_BEGIN 16 +#define TX_VREF_RANGE_END 50 +#define TX_VREF_RANGE_STEP 2 + static const u8 ca_pinmux_mapping[PINMUX_MAX][CHANNEL_MAX][CA_NUM_LP4] = { [PINMUX_DSC] = { [CHANNEL_A] = {1, 4, 5, 3, 2, 0}, @@ -35,6 +40,12 @@ u16 best_dqdly; } pass_win_data_t; +typedef struct { + u16 vref_used; + u16 winsum_by_vref; + u8 worse_bit_winsize; + u8 worse_bit_idx; +} pass_win_data_vref_t; static const u8 imp_vref_sel[ODT_MAX][IMP_DRV_MAX] = { /* DRVP DRVN ODTP ODTN */ @@ -1704,6 +1715,19 @@ read_dqs_inctl, rank_inctl_root, xrtr2r); } +static void dramc_set_rw_ofoen(u8 chn, u8 onoff) +{ + u32 loop = 0, loop_cnt = 100000; + + while (READ32_BITFIELD(&ch[chn].nao.misc_statusa, MISC_STATUSA_REQQ_EMPTY) != 1) { + loop ++; + if (loop > loop_cnt) { + dramc_dbg("RWOFOEN timout! queue is not empty\n"); + break; + } + } + SET32_BITFIELDS(&ch[chn].ao.scheduler_com, SCHEDULER_COM_RWOFOEN, onoff); +} static void dramc_set_rank_engin2(u8 chn, u8 rank) { @@ -1767,6 +1791,94 @@ dramc_engin2_set_pat(chn, rank, 0); } +static void dramc_engine2_check_complete(u8 chn, u8 status) +{ + u32 loop = 0, loop_max = 100000; + u32 ta2_loop_cnt = 0; + + while ((read32(&ch[chn].nao.testrpt) & status) != status) { + udelay(1); + loop++; + if (loop > loop_max) { + dramc_dbg("testrpt time out, [22:20]=%#x\n", + READ32_BITFIELD(&ch[chn].nao.testrpt, TESTRPT_TESTSTAT)); + break; + } + } + + loop = 0; + if (READ32_BITFIELD(&ch[chn].ao.test2_a3, TEST2_A3_TEST2_PAT_SHIFT)) { + while ((ta2_loop_cnt = read32(&ch[chn].nao.test_loop_cnt)) != 8) { + loop++; + if (loop > loop_max) { + dramc_dbg("test_loop_cnt time out, TEST_LOOP_CNT[%d]\n", + ta2_loop_cnt); + break; + } + } + } +} + +static u32 dramc_engine2_compare(u8 chn) +{ + u8 status = 1; + u32 result = 0xffffffff; + u32 loop_cnt; + u32 shift_ui_flag = 0; + + loop_cnt = READ32_BITFIELD(&ch[chn].ao.test2_a3, TEST2_A3_TESTCNT); + if (loop_cnt == 1) + status = 3; + + shift_ui_flag = READ32_BITFIELD(&ch[chn].ao.test2_a3, TEST2_A3_TEST2_PAT_SHIFT); + + if (!shift_ui_flag) { + dramc_engine2_check_complete(chn, status); + + SET32_BITFIELDS(&ch[chn].ao.test2_a3, + TEST2_A3_TEST2W, 0, + TEST2_A3_TEST2R, 0, + TEST2_A3_TEST1, 0); + udelay(1); + SET32_BITFIELDS(&ch[chn].ao.test2_a3, + TEST2_A3_TEST2W, 0, + TEST2_A3_TEST2R, 1, + TEST2_A3_TEST1, 0); + } + + dramc_engine2_check_complete(chn, status); + result = (read32(&ch[chn].nao.testrpt) >> 4) & status; + + return result; +} + +static u32 dramc_engine2_run(u8 chn) +{ + u32 result = 0xffffffff; + + SET32_BITFIELDS(&ch[chn].ao.test2_a3, + TEST2_A3_TEST2W, 1, + TEST2_A3_TEST2R, 0, + TEST2_A3_TEST1, 0); + dramc_engine2_compare(chn); + udelay(1); + result = read32(&ch[chn].nao.cmp_err); + SET32_BITFIELDS(&ch[chn].ao.test2_a3, + TEST2_A3_TEST2W, 0, + TEST2_A3_TEST2R, 0, + TEST2_A3_TEST1, 0); + + return result; +} + +static void dramc_engine2_end(u8 chn, u32 dummy_rd) +{ + SET32_BITFIELDS(&ch[chn].ao.test2_a4, + TEST2_A4_TEST_REQ_LEN1, 0); + dramc_set_rw_ofoen(chn, 1); + write32(&ch[chn].ao.dummy_rd, dummy_rd); +} + static const u8 uiLPDDR4_RDDQC_Mapping_POP[PINMUX_MAX][CHANNEL_MAX][DQ_DATA_WIDTH] = { [PINMUX_DSC] = { @@ -1843,6 +1955,7 @@ SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].shu_b0_dq8, SHU_B1_DQ8_R_DMRXDLY_CG_IG_B1, 1); } + void dramc_rx_window_perbit_cal(const struct ddr_cali* cali, rx_cali_type cali_type) { u8 chn, rank, fsp; @@ -1956,3 +2069,647 @@ bit + 2, final_win_perbit[bit + 2].best_dqdly, bit + 3, final_win_perbit[bit + 3].best_dqdly); } + +static void tx_perbit_calibarion_init(u8 chn, u8 rank, u8 cali_type) +{ + if (cali_type != TX_DQ_DQS_MOVE_DQM_ONLY) { + write32(&ch[chn].phy_ao.byte[0].rk[rank].shu_r0_b0_txdly0, 0); + write32(&ch[chn].phy_ao.byte[0].rk[rank].shu_r0_b0_txdly1, 0); + write32(&ch[chn].phy_ao.byte[1].rk[rank].shu_r0_b0_txdly0, 0); + write32(&ch[chn].phy_ao.byte[1].rk[rank].shu_r0_b0_txdly1, 0); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].rk[rank].shu_r0_b0_txdly3, + SHU_R0_B0_TXDLY3_TX_ARDQM0_DLY_B0, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].rk[rank].shu_r0_b0_txdly3, + SHU_R0_B1_TXDLY3_TX_ARDQM0_DLY_B1, 0x0); + } +} + +static void tx_win_transfer_delay_to_uipi(const struct ddr_cali* cali, u16 delay, + u8 pi_to_center, u8 *p_ui_large_dq, u8 *p_ui_small_dq, u8 *p_pi, + u8 *p_ui_large_dqoe, u8 *p_ui_small_dqoe) +{ + dram_freq_grp freq_group = cali->freq_group; + bool is_freq_400 = freq_group == DDRFREQ_400; + + u8 small_ui_to_large, pi = 0, pi_to_ui, tx_dq_oe_shift = 0; + u8 pi_tap = is_freq_400 ? TX_PHASE_DQ_UI_TO_PI_TAP : TX_DQ_UI_TO_PI_TAP; + u16 tmp_val, dqoe_shift; + u8 mr03 = cali->mr_value->mr03[get_fsp(cali)]; + small_ui_to_large = get_mck2ui_div_shift(cali); + tx_dq_oe_shift = 3; + + if (p_pi != NULL) { + pi = delay & (pi_tap-1); + *p_pi =pi; + } + + if (is_freq_400) + pi_to_ui = 0; + else + pi_to_ui = 1; + + tmp_val = (delay /pi_tap) << pi_to_ui; + + if (pi_to_center && (p_pi != NULL) && (!is_freq_400)) { + if (pi < 10) { + pi += (pi_tap) >> 1; + tmp_val --; + } else if (pi > pi_tap - 10) { + pi -= (pi_tap) >> 1; + tmp_val ++; + } + + *p_pi = pi; + } + + *p_ui_small_dq = tmp_val - ((tmp_val >> small_ui_to_large) << small_ui_to_large); + *p_ui_large_dq = (tmp_val >> small_ui_to_large); + + tmp_val -= tx_dq_oe_shift; + + if (((mr03 & 0x80) >> 7) == 1) { + if (get_div_mode(cali) == DIV4_MODE) + dqoe_shift = 4; + else + dqoe_shift = 8; + + tmp_val += dqoe_shift; + } + + *p_ui_small_dqoe = tmp_val - ((tmp_val >> small_ui_to_large) << small_ui_to_large); + *p_ui_large_dqoe = (tmp_val >> small_ui_to_large); +} + +static void tx_set_delay_reg_dq(u8 chn, u8 rank, u8 update_reg_ui, u8 dq_ui_large[], + u8 dq_oen_ui_large[], u8 dq_ui_small[], u8 dq_oen_ui_small[], u8 dql_pi[]) +{ + if (update_reg_ui) { + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_selph_dq0, + SHURK_SELPH_DQ0_TXDLY_DQ0, dq_ui_large[0], + SHURK_SELPH_DQ0_TXDLY_DQ1, dq_ui_large[1], + SHURK_SELPH_DQ0_TXDLY_DQ2, dq_ui_large[0], + SHURK_SELPH_DQ0_TXDLY_DQ3, dq_ui_large[1], + SHURK_SELPH_DQ0_TXDLY_OEN_DQ0, dq_oen_ui_large[0], + SHURK_SELPH_DQ0_TXDLY_OEN_DQ1, dq_oen_ui_large[1], + SHURK_SELPH_DQ0_TXDLY_OEN_DQ2, dq_oen_ui_large[0], + SHURK_SELPH_DQ0_TXDLY_OEN_DQ3, dq_oen_ui_large[1]); + + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_selph_dq2, + SHURK_SELPH_DQ2_DLY_DQ0, dq_ui_small[0], + SHURK_SELPH_DQ2_DLY_DQ1, dq_ui_small[1], + SHURK_SELPH_DQ2_DLY_DQ2, dq_ui_small[0], + SHURK_SELPH_DQ2_DLY_DQ3, dq_ui_small[1], + SHURK_SELPH_DQ2_DLY_OEN_DQ0, dq_oen_ui_small[0], + SHURK_SELPH_DQ2_DLY_OEN_DQ1, dq_oen_ui_small[1], + SHURK_SELPH_DQ2_DLY_OEN_DQ2, dq_oen_ui_small[0], + SHURK_SELPH_DQ2_DLY_OEN_DQ3, dq_oen_ui_small[1]); + } + + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].rk[rank].shu_r0_b0_dq0, + SHU_R0_B0_DQ0_SW_ARPI_DQ_B0, dql_pi[0]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].rk[rank].shu_r0_b0_dq0, + SHU_R0_B1_DQ0_SW_ARPI_DQ_B1, dql_pi[1]); +} + +static void tx_set_delay_reg_dqm(u8 chn, u8 rank, u8 update_reg_ui, u8 dqm_ui_large[], + u8 dqm_oen_ui_large[], u8 dqm_ui_small[], u8 dqm_oen_ui_small[], u8 dqm_pi[]) +{ + if (update_reg_ui) { + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_selph_dq1, + SHURK_SELPH_DQ1_TXDLY_DQM0, dqm_ui_large[0], + SHURK_SELPH_DQ1_TXDLY_DQM1, dqm_ui_large[1], + SHURK_SELPH_DQ1_TXDLY_DQM2, dqm_ui_large[0], + SHURK_SELPH_DQ1_TXDLY_DQM3, dqm_ui_large[1], + SHURK_SELPH_DQ1_TXDLY_OEN_DQM0, dqm_oen_ui_large[0], + SHURK_SELPH_DQ1_TXDLY_OEN_DQM1, dqm_oen_ui_large[1], + SHURK_SELPH_DQ1_TXDLY_OEN_DQM2, dqm_oen_ui_large[0], + SHURK_SELPH_DQ1_TXDLY_OEN_DQM3, dqm_oen_ui_large[1]); + + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_selph_dq3, + SHURK_SELPH_DQ3_DLY_DQM0, dqm_ui_small[0], + SHURK_SELPH_DQ3_DLY_DQM1, dqm_ui_small[1], + SHURK_SELPH_DQ3_DLY_DQM2, dqm_ui_small[0], + SHURK_SELPH_DQ3_DLY_DQM3, dqm_ui_small[1], + SHURK_SELPH_DQ3_DLY_OEN_DQM0, dqm_oen_ui_small[0], + SHURK_SELPH_DQ3_DLY_OEN_DQM1, dqm_oen_ui_small[1], + SHURK_SELPH_DQ3_DLY_OEN_DQM2, dqm_oen_ui_small[0], + SHURK_SELPH_DQ3_DLY_OEN_DQM3, dqm_oen_ui_small[1]); + } + + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].rk[rank].shu_r0_b0_dq0, + SHU_R0_B0_DQ0_SW_ARPI_DQM_B0, dqm_pi[0]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].rk[rank].shu_r0_b0_dq0, + SHU_R0_B1_DQ0_SW_ARPI_DQM_B1, dqm_pi[1]); +} + +static void update_tx_tracking(u8 chn, u8 rank, tx_cali_type cali_type, u8 dq_pi[], u8 dqm_pi[]) +{ + if (cali_type == TX_DQ_DQS_MOVE_DQ_ONLY || cali_type == TX_DQ_DQS_MOVE_DQM_ONLY) { + if (cali_type == TX_DQ_DQS_MOVE_DQ_ONLY) { + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_pi, + SHURK_PI_RK0_ARPI_DQ_B0, dq_pi[0], + SHURK_PI_RK0_ARPI_DQ_B1, dq_pi[1]); + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_dqs2dq_cal1, + SHURK_DQS2DQ_CAL1_BOOT_ORIG_UI_RK0_DQ1, dq_pi[1], + SHURK_DQS2DQ_CAL1_BOOT_ORIG_UI_RK0_DQ0, dq_pi[0]); + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_dqs2dq_cal2, + SHURK_DQS2DQ_CAL2_BOOT_TARG_UI_RK0_DQ1, dq_pi[1], + SHURK_DQS2DQ_CAL2_BOOT_TARG_UI_RK0_DQ0, dq_pi[0]); + } + + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_pi, + SHURK_PI_RK0_ARPI_DQM_B0, dqm_pi[0], + SHURK_PI_RK0_ARPI_DQM_B1, dqm_pi[1]); + + SET32_BITFIELDS(&ch[chn].ao.shu_rk[rank].shurk_dqs2dq_cal5, + SHURK_DQS2DQ_CAL5_BOOT_TARG_UI_RK0_DQM1, dqm_pi[1], + SHURK_DQS2DQ_CAL5_BOOT_TARG_UI_RK0_DQM0, dqm_pi[0]); + } +} + +static void dramc_tx_set_vref(const struct ddr_cali* cali, u8 vref_range, u8 vref) +{ + u8 mr_value = (vref & 0x3f) | (vref_range << 6); + + dramc_mode_reg_write_by_rank(cali, cali->chn, cali->rank, 14, mr_value); +} + +static void tx_scan_range_PI(const struct ddr_cali* cali, tx_cali_type cali_type, + u16 *begin, u16 *end, const u8 dqs_final_delay[2][2]) +{ + u8 mck_to_ui, ui_to_pi, byte; + u8 dq_ui_large_bak[DQS_NUMBER], dq_ui_small_bak[DQS_NUMBER]; + u16 temp_virtual_delay, smallest_virtual_delay = 0xffff; + u16 delay_begin = 0, delay_end = 0; + u32 tx_dly, delay; + + u8 chn = cali->chn; + u8 rank = cali->rank; + + tx_dly = read32(&ch[chn].ao.shu_selph_dqs0); + delay = read32(&ch[chn].ao.shu_selph_dqs1); + mck_to_ui = get_mck2ui_div_shift(cali); + ui_to_pi = 5; + + for (byte = 0; byte < BYTE_NUM; byte++) { + dq_ui_large_bak[byte] = (tx_dly >> (byte << 2)) & 0x7; + dq_ui_small_bak[byte] = (delay >> (byte << 2)) & 0x7; + temp_virtual_delay = (((dq_ui_large_bak[byte] << mck_to_ui) + + dq_ui_small_bak[byte]) << ui_to_pi) + dqs_final_delay[rank][byte]; + + if (temp_virtual_delay < smallest_virtual_delay) + smallest_virtual_delay = temp_virtual_delay; + } + + delay_begin = smallest_virtual_delay; + + if (cali_type == TX_DQ_DQS_MOVE_DQM_ONLY) + delay_begin -= (1 << (mck_to_ui + 5)); + delay_end = delay_begin + ((1 << mck_to_ui) << ui_to_pi); + + *begin = delay_begin; + *end = delay_end; +} + +static void tx_scan_range_vref(const struct ddr_cali* cali, bool enable_vref_scan, + u16 *range, u16 *begin, u16 *end, u16 *step) +{ + u16 vref_begin, vref_end; + u8 odt = get_odt_state(cali); + const struct sdram_params *params = cali->params; + + if (enable_vref_scan) { + vref_begin = params->tx_window_vref[cali->chn][cali->rank]; + vref_end = vref_begin + 1; + }else { + vref_begin = 0; + vref_end = 0; + } + + *range = (!odt); + *begin = vref_begin; + *end = vref_end; + *step = TX_VREF_RANGE_STEP; +} + +static u16 tx_choose_vref(pass_win_data_vref_t vref_info[], u8 vref_num) +{ + u8 vref, worse_bit = 0, win_size_worse_bit = 0; + u16 max_winsum = 0; + u16 final_vref = 0; + + for (vref = 0; vref < vref_num; vref++) + dramc_dbg("TX Vref=%d, minBit %d, minWin=%d, winSum=%d\n", + vref_info[vref].vref_used, + vref_info[vref].worse_bit_idx, + vref_info[vref].worse_bit_winsize, + vref_info[vref].winsum_by_vref); + + for (vref = 0; vref < vref_num; vref++) { + if ((vref_info[vref].worse_bit_winsize > win_size_worse_bit) || + ((vref_info[vref].worse_bit_winsize == win_size_worse_bit) && + (vref_info[vref].winsum_by_vref > max_winsum))) { + win_size_worse_bit = vref_info[vref].worse_bit_winsize; + worse_bit = vref_info[vref].worse_bit_idx; + max_winsum = vref_info[vref].winsum_by_vref; + final_vref = vref_info[vref].vref_used; + } + } + + dramc_dbg("Worse bit %d, Min win %d, Win sum %d, Final Vref %d\n", + worse_bit, win_size_worse_bit, max_winsum, final_vref); + + return final_vref; +} + +static void dramc_tx_window_perbit_cal_find_best_delay(const struct ddr_cali* cali, + tx_cali_type cali_type, bool enable_vref_scan, u16 delay_begin, u16 delay_end, + u16 delay_step, u32 *finish_count, u8 *ui_small_reg_value, + pass_win_data_t win_perbit[DQ_DATA_WIDTH], + pass_win_data_t vref_win_perbit[DQ_DATA_WIDTH]) +{ + u8 chn = cali->chn; + u8 rank = cali->rank; + u8 pi, ui_small, ui_large, oen_ui_small, oen_ui_large; + u8 update_reg_ui; + u8 dq_ui_large[DQS_NUMBER] = {0}, dq_ui_small[DQS_NUMBER] = {0}; + u8 dq_oen_ui_large[DQS_NUMBER] = {0}, dq_oen_ui_small[DQS_NUMBER] = {0}; + u8 dqm_ui_large[DQS_NUMBER] = {0}, dqm_ui_small[DQS_NUMBER] = {0}; + u8 dqm_oen_ui_large[DQS_NUMBER] = {0}, dqm_oen_ui_small[DQS_NUMBER] = {0}; + u8 dq_pi[DQS_NUMBER] = {0}, dqm_pi[DQS_NUMBER] = {0}; + u16 perbit_winsum, vref_winsum; + u32 err_value, fail_bit; + + for (u16 delay = delay_begin; delay < delay_end; delay += delay_step) { + tx_win_transfer_delay_to_uipi(cali, delay, 0, &ui_large, + &ui_small, &pi, &oen_ui_large, &oen_ui_small); + + if (*ui_small_reg_value != ui_small) { + update_reg_ui = 1; + *ui_small_reg_value = ui_small; + } else + update_reg_ui = 0; + + for (u8 byte = 0; byte < DQS_NUMBER; byte++) { + if (update_reg_ui) { + dq_ui_large[byte] = ui_large; + dq_ui_small[byte] = ui_small; + dq_oen_ui_large[byte] = oen_ui_large; + dq_oen_ui_small[byte] = oen_ui_small; + + dqm_ui_large[byte] = ui_large; + dqm_ui_small[byte] = ui_small; + dqm_oen_ui_large[byte] = oen_ui_large; + dqm_oen_ui_small[byte] = oen_ui_small; + } + + dq_pi[byte] = pi; + dqm_pi[byte] = pi; + } + + if (cali_type == TX_DQ_DQS_MOVE_DQ_ONLY || + cali_type == TX_DQ_DQS_MOVE_DQ_DQM) + tx_set_delay_reg_dq(chn, rank, update_reg_ui, dq_ui_large, + dq_oen_ui_large, dq_ui_small, dq_oen_ui_small, dq_pi); + + if (cali_type == TX_DQ_DQS_MOVE_DQM_ONLY || + cali_type == TX_DQ_DQS_MOVE_DQ_DQM) + tx_set_delay_reg_dqm(chn, rank, update_reg_ui, + dqm_ui_large, dqm_oen_ui_large, dqm_ui_small, + dqm_oen_ui_small, dqm_pi); + + err_value = dramc_engine2_run(chn); + + if (!enable_vref_scan && (cali_type != TX_DQ_DQS_MOVE_DQM_ONLY)) + if (err_value != 0) + dramc_dbg("%d |%d %d %d|[0]", delay, ui_large, ui_small, pi); + + for (u8 bit = 0; bit < DQ_DATA_WIDTH; bit++) { + fail_bit = err_value & BIT(bit); + + if (win_perbit[bit].first_pass == PASS_RANGE_NA) { + if (fail_bit == 0) + win_perbit[bit].first_pass = delay; + } else if (win_perbit[bit].last_pass == PASS_RANGE_NA) { + if (fail_bit != 0) + win_perbit[bit].last_pass = delay - delay_step; + else if (delay > (delay_end - delay_step)) + win_perbit[bit].last_pass = delay; + + if (win_perbit[bit].last_pass != PASS_RANGE_NA) { + perbit_winsum = win_perbit[bit].last_pass - + win_perbit[bit].first_pass; + vref_winsum = vref_win_perbit[bit].last_pass - + vref_win_perbit[bit].first_pass; + if (perbit_winsum >= vref_winsum) { + if ((vref_win_perbit[bit].last_pass != + PASS_RANGE_NA) && + vref_winsum > 0) + dramc_dbg("Bit[%d] Bigger window update %d > %d, window broken\n", + bit, perbit_winsum, + vref_winsum); + + if (perbit_winsum > TX_PASS_WIN_CRITERIA) + *finish_count |= BIT(bit); + + vref_win_perbit[bit].first_pass = + win_perbit[bit].first_pass; + vref_win_perbit[bit].last_pass = + win_perbit[bit].last_pass; + } + + win_perbit[bit].first_pass = PASS_RANGE_NA; + win_perbit[bit].last_pass = PASS_RANGE_NA; + } + } + + if (!enable_vref_scan && (cali_type != TX_DQ_DQS_MOVE_DQM_ONLY)) { + if (err_value != 0) { + if (bit % DQS_BIT_NUMBER == 0) + dramc_dbg(" "); + + if (fail_bit == 0) + dramc_dbg("o"); + else + dramc_dbg("x"); + } + } + } + + if (!enable_vref_scan && (cali_type != TX_DQ_DQS_MOVE_DQM_ONLY)) + if (err_value != 0) + dramc_dbg("[MSB]\n"); + + if (*finish_count == 0xffff) + break; + } +} + +static u16 dramc_tx_window_perbit_cal_find_best_vref(const struct ddr_cali* cali, + tx_cali_type cali_type, bool enable_vref_scan, u16 final_range, + u16 vref_begin, u16 vref_end, u16 vref_step, + u16 delay_begin, u16 delay_end, u16 delay_step, u8 *vref_tmp, + u16 center_min[DQS_NUMBER], u16 center_max[DQS_NUMBER], + pass_win_data_t final_win_perbit[DQ_DATA_WIDTH], + pass_win_data_vref_t vref_info[LP4_TX_VREF_DATA_NUM]) +{ + u8 bit, byte, min_bit, min_winsize = 0, bit_tmp; + u8 ui_small_reg_value; + u16 vref_level; + u16 winsum, temp_winsum, max_window_sum = 0; + u32 finish_count; + u32 dummy_rd_bak = 0; + pass_win_data_t win_perbit[DQ_DATA_WIDTH], vref_win_perbit[DQ_DATA_WIDTH]; + + u8 chn = cali->chn; + u8 rank = cali->rank; + + dummy_rd_bak = read32(&ch[chn].ao.dummy_rd); + dramc_engine2_init(chn, rank); + + for (vref_level = vref_begin; vref_level <= vref_end; vref_level += vref_step) { + if (enable_vref_scan) { + dramc_dbg("LP4 TX VrefRange %d, VrefLevel=%d\n", final_range, vref_level); + dramc_tx_set_vref(cali, final_range, vref_level); + } else { + dramc_dbg("TX Vref Scan disable\n"); + } + + finish_count = 0; + temp_winsum = 0; + ui_small_reg_value = 0xff; + + for (bit = 0; bit < DQ_DATA_WIDTH; bit++) { + win_perbit[bit].first_pass = (s16)PASS_RANGE_NA; + win_perbit[bit].last_pass = (s16)PASS_RANGE_NA; + vref_win_perbit[bit].first_pass = (s16)PASS_RANGE_NA; + vref_win_perbit[bit].last_pass = (s16)PASS_RANGE_NA; + } + + dramc_tx_window_perbit_cal_find_best_delay(cali, cali_type,enable_vref_scan, + delay_begin, delay_end, delay_step, &finish_count, &ui_small_reg_value, + win_perbit, vref_win_perbit); + + min_winsize = 0xff; + min_bit = 0xff; + for (bit = 0; bit < DQ_DATA_WIDTH; bit++) { + winsum = vref_win_perbit[bit].last_pass - + vref_win_perbit[bit].first_pass; + if (vref_win_perbit[bit].first_pass == PASS_RANGE_NA) + vref_win_perbit[bit].win_size = 0; + else + vref_win_perbit[bit].win_size = winsum + delay_step; + + if (vref_win_perbit[bit].win_size < min_winsize) { + min_bit = bit; + min_winsize = vref_win_perbit[bit].win_size; + } + + temp_winsum += vref_win_perbit[bit].win_size; + vref_win_perbit[bit].win_center = (vref_win_perbit[bit].first_pass + + vref_win_perbit[bit].last_pass) >> 1; + } + + if (enable_vref_scan) { + if (temp_winsum > max_window_sum) + max_window_sum = temp_winsum; + + vref_info[*vref_tmp].vref_used = vref_level; + vref_info[*vref_tmp].worse_bit_winsize = min_winsize; + vref_info[*vref_tmp].worse_bit_idx = min_bit; + vref_info[*vref_tmp].winsum_by_vref = temp_winsum; + *vref_tmp = *vref_tmp + 1; + } + + if (enable_vref_scan && + (temp_winsum < (max_window_sum * 95 / 100)) && + (min_winsize > TX_PASS_WIN_CRITERIA)) { + dramc_dbg("TX Vref early break, caculate TX vref\n"); + break; + } + } + + dramc_engine2_end(chn, dummy_rd_bak); + if (enable_vref_scan) + return vref_level; + + for (byte = 0; byte < (DQ_DATA_WIDTH / DQS_BIT_NUMBER); byte++) { + center_min[byte] = 0xffff; + center_max[byte] = 0; + + for (bit = 0; bit < DQS_BIT_NUMBER; bit++) { + bit_tmp = byte * DQS_BIT_NUMBER + bit; + memcpy(final_win_perbit, vref_win_perbit, sizeof(vref_win_perbit)); + + if (final_win_perbit[bit_tmp].win_center < center_min[byte]) + center_min[byte] = final_win_perbit[bit_tmp].win_center; + + if (final_win_perbit[bit_tmp].win_center > center_max[byte]) + center_max[byte] = final_win_perbit[bit_tmp].win_center; + } + } + + return vref_level; +} + +void dramc_tx_window_perbit_cal(const struct ddr_cali* cali, + tx_cali_type cali_type, const u8 dqs_final_delay[2][2], bool enable_vref_scan) +{ + u8 chn, rank, fsp, odt; + u8 pi_diff; + u8 bit_tmp, bit, byte, rk; + u8 enable_delaycell = 0; + u8 vref_tmp = 0; + u8 dq_ui_large[DQS_NUMBER], dq_ui_small[DQS_NUMBER], dq_pi[DQS_NUMBER]; + u8 dq_oen_ui_large[DQS_NUMBER], dq_oen_ui_small[DQS_NUMBER]; + u8 dqm_ui_large[DQS_NUMBER] = {0}, dqm_ui_small[DQS_NUMBER] = {0}; + u8 dqm_oen_ui_large[DQS_NUMBER] = {0}, dqm_oen_ui_small[DQS_NUMBER] = {0}; + u8 dqm_pi[DQS_NUMBER] = {0}; + u16 delay, delay_step, dqm_delay; + u16 center_min[DQS_NUMBER] = {0}, center_max[DQS_NUMBER] = {0}; + u16 delaycell_offset[DQ_DATA_WIDTH] = {0}; + u16 final_range = 0, final_vref = 0; + u16 vref_begin, vref_end, vref_step; + u16 delay_begin, delay_end; + u32 frequency; + dram_freq_grp freq_group; + pass_win_data_t final_win_perbit[DQ_DATA_WIDTH]; + pass_win_data_vref_t vref_info[LP4_TX_VREF_DATA_NUM]; + + fsp = get_fsp(cali); + odt = get_odt_state(cali); + bool bypass_cali = !fsp; + const struct sdram_params *params = cali->params; + + chn = cali->chn; + rank = cali->rank; + freq_group = cali->freq_group; + frequency = get_frequency(cali); + + tx_perbit_calibarion_init(chn, rank, cali_type); + + tx_scan_range_PI(cali, cali_type, &delay_begin, &delay_end, dqs_final_delay); + tx_scan_range_vref(cali, enable_vref_scan, &final_range, &vref_begin, &vref_end, &vref_step); + dramc_dbg("delay_begin:%d, delay_end:%d,final_range:%d,vref_begin:%d, vref_end:%d,vref_step:%d\n", + delay_begin, delay_end, final_range, vref_begin, vref_end, vref_step); + + if (freq_group == DDRFREQ_400) + delay_step = 8; + else if (cali_type == TX_DQ_DQS_MOVE_DQ_DQM) + delay_step = 2; + else + delay_step = 1; + + if (bypass_cali) { + for (byte = 0; byte < BYTE_NUM; byte++) { + center_min[byte] = params->tx_center_min[chn][rank][byte]; + center_max[byte] = params->tx_center_max[chn][rank][byte]; + + for (bit = 0; bit < DQS_BIT_NUMBER; bit++) { + bit_tmp = byte * DQS_BIT_NUMBER + bit; + final_win_perbit[bit_tmp].win_center = + params->tx_win_center[chn][rank][bit_tmp]; + } + } + } else { + final_vref = dramc_tx_window_perbit_cal_find_best_vref(cali, cali_type, enable_vref_scan, + final_range, vref_begin, vref_end, vref_step, + delay_begin, delay_end, delay_step, &vref_tmp, + center_min, center_max, final_win_perbit, vref_info); + } + + if (enable_vref_scan) { + if (bypass_cali) + final_vref = params->tx_window_vref[chn][rank]; + else + final_vref = tx_choose_vref(vref_info, vref_tmp); + + dramc_tx_set_vref(cali, final_range, final_vref); + return; + } + + if ((cali_type == TX_DQ_DQS_MOVE_DQ_ONLY) && (freq_group > DDRFREQ_1200)) { + enable_delaycell = 1; + dramc_dbg("[TX_PER_BIT_DELAY_CELL] DelayCellTimex100 =%d/100 ps\n", params->delay_cell_timex100); + } + + for (byte = 0; byte < BYTE_NUM; byte++) { + dramc_dbg(" == TX Byte %d ==\n", byte); + dqm_delay = ((center_min[byte] + center_max[byte]) >> 1); + + if (enable_delaycell == 0) { + delay = dqm_delay; + } else { + delay = center_min[byte]; + + for (bit = 0; bit < DQS_BIT_NUMBER; bit++) { + bit_tmp = byte * DQS_BIT_NUMBER + bit; + pi_diff = final_win_perbit[bit_tmp].win_center - + center_min[byte]; + if (params->delay_cell_timex100 != 0) { + delaycell_offset[bit_tmp] = (pi_diff * 100000000 / + (frequency << 6)) / + params->delay_cell_timex100; + dramc_dbg("delaycell_offset[%d]=%d cells (%d PI)\n", + bit_tmp, delaycell_offset[bit_tmp], pi_diff); + if (delaycell_offset[bit_tmp] > 255) { + dramc_dbg("[WARNING] TX DQ%d delay cell %d >255, adjust to 255 cell\n", + bit, delaycell_offset[bit_tmp]); + delaycell_offset[bit_tmp] = 255; + } + } + } + } + + tx_win_transfer_delay_to_uipi(cali, delay, 1, &dq_ui_large[byte], + &dq_ui_small[byte], &dq_pi[byte], + &dq_oen_ui_large[byte], &dq_oen_ui_small[byte]); + tx_win_transfer_delay_to_uipi(cali, dqm_delay, 1, &dqm_ui_large[byte], + &dqm_ui_small[byte], &dqm_pi[byte], + &dqm_oen_ui_large[byte], &dqm_oen_ui_small[byte]); + + if (cali_type == TX_DQ_DQS_MOVE_DQ_ONLY || cali_type == TX_DQ_DQS_MOVE_DQ_DQM) { + dramc_dbg("Update DQ dly =%d (%d ,%d, %d) DQ OEN =(%d ,%d)\n", + delay, dq_ui_large[byte], dq_ui_small[byte], dq_pi[byte], \ + dq_oen_ui_large[byte], dq_oen_ui_small[byte]); + } + + dramc_dbg("Update DQM dly =%d (%d ,%d, %d) DQM OEN =(%d ,%d)", + dqm_delay, dqm_ui_large[byte], dqm_ui_small[byte], dqm_pi[byte], + dqm_oen_ui_large[byte], dqm_oen_ui_small[byte]); + dramc_dbg("\n"); + } + + for (rk = rank; rk < RANK_MAX; rk++) { + if (cali_type == TX_DQ_DQS_MOVE_DQ_ONLY || cali_type == TX_DQ_DQS_MOVE_DQ_DQM) + tx_set_delay_reg_dq(chn, rk, true, dq_ui_large, dq_oen_ui_large, + dq_ui_small, dq_oen_ui_small, dq_pi); + tx_set_delay_reg_dqm(chn, rk, true, dqm_ui_large, dqm_oen_ui_large, + dqm_ui_small, dqm_oen_ui_small, dqm_pi); + + if (enable_delaycell) { + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].rk[rk].shu_r0_b0_txdly0, + SHU_R0_B0_TXDLY0_TX_ARDQ3_DLY_B0, delaycell_offset[3], + SHU_R0_B0_TXDLY0_TX_ARDQ2_DLY_B0, delaycell_offset[2], + SHU_R0_B0_TXDLY0_TX_ARDQ1_DLY_B0, delaycell_offset[1], + SHU_R0_B0_TXDLY0_TX_ARDQ0_DLY_B0, delaycell_offset[0]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].rk[rk].shu_r0_b0_txdly1, + SHU_R0_B0_TXDLY1_TX_ARDQ7_DLY_B0, delaycell_offset[7], + SHU_R0_B0_TXDLY1_TX_ARDQ6_DLY_B0, delaycell_offset[6], + SHU_R0_B0_TXDLY1_TX_ARDQ5_DLY_B0, delaycell_offset[5], + SHU_R0_B0_TXDLY1_TX_ARDQ4_DLY_B0, delaycell_offset[4]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].rk[rk].shu_r0_b0_txdly0, + SHU_R0_B1_TXDLY0_TX_ARDQ3_DLY_B1, delaycell_offset[11], + SHU_R0_B1_TXDLY0_TX_ARDQ2_DLY_B1, delaycell_offset[10], + SHU_R0_B1_TXDLY0_TX_ARDQ1_DLY_B1, delaycell_offset[9], + SHU_R0_B1_TXDLY0_TX_ARDQ0_DLY_B1, delaycell_offset[8]); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].rk[rk].shu_r0_b0_txdly1, + SHU_R0_B1_TXDLY1_TX_ARDQ7_DLY_B1, delaycell_offset[15], + SHU_R0_B1_TXDLY1_TX_ARDQ6_DLY_B1, delaycell_offset[14], + SHU_R0_B1_TXDLY1_TX_ARDQ5_DLY_B1, delaycell_offset[13], + SHU_R0_B1_TXDLY1_TX_ARDQ4_DLY_B1, delaycell_offset[12]); + } + + update_tx_tracking(chn, rk, cali_type, dq_pi, dqm_pi); + } +} diff --git a/src/soc/mediatek/mt8192/dramc_pi_main.c b/src/soc/mediatek/mt8192/dramc_pi_main.c index 41d85a2..f724e54 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_main.c +++ b/src/soc/mediatek/mt8192/dramc_pi_main.c @@ -16,6 +16,26 @@ shift_dq_ui(cali, cali->rank, ui_move); } +static void switch_write_dbi_settings(const struct ddr_cali *cali, dbi_mode dbi_state) +{ + s8 tx_shift; + u8 chn, rank; + struct mr_values *mr_value = cali->mr_value; + u8 mr03 = mr_value->mr03[get_fsp(cali)]; + + chn = cali->chn; + rank = cali->rank; + + tx_shift = dbi_state ? -1 : 1; + dramc_write_shift_mck_write_DBI(cali, tx_shift); + + mr03 = (mr03 & ~(0x1 << 7)) | (dbi_state << 7); + dramc_mode_reg_write_by_rank(chn, rank, 3, mr03); + mr_value->mr03[get_fsp(cali)] = mr03; + + dramc_write_dbi_onoff(dbi_state); +} + static void dramc_ac_timing_optimize(const struct ddr_cali* cali) { u8 rf_group = 0, cab_id = 0; @@ -250,6 +270,23 @@ dramc_rx_dqs_gating_cal(cali, &txdly_min, &txdly_max); dramc_rx_window_perbit_cal(cali, RX_WIN_RD_DQC); + dramc_tx_window_perbit_cal(cali, TX_DQ_DQS_MOVE_DQ_DQM, + dqs_final_delay, false); + if (get_vref_cali(cali) == VREF_CALI_ON) + dramc_tx_window_perbit_cal(cali, TX_DQ_DQS_MOVE_DQ_ONLY, + dqs_final_delay, true); + + dramc_tx_window_perbit_cal(cali, TX_DQ_DQS_MOVE_DQ_ONLY, + dqs_final_delay, false); + + if (get_write_dbi(cali) == DBI_ON) { + dramc_dbg("K DQM with DBI_ON\n"); + switch_write_dbi_settings(cali, DBI_ON); + dramc_tx_window_perbit_cal(cali, TX_DQ_DQS_MOVE_DQM_ONLY, + dqs_final_delay, false); + switch_write_dbi_settings(cali, DBI_OFF); + } + dramc_rx_window_perbit_cal(cali, RX_WIN_TEST_ENG); } dramc_rx_dqs_gating_post_process(cali, txdly_min, txdly_max); -- To view, visit
https://review.coreboot.org/c/coreboot/+/44720
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: Ica11573c1e0b657be0e8ddcbf81a9e3f2399e258 Gerrit-Change-Number: 44720 Gerrit-PatchSet: 1 Gerrit-Owner: CK HU <ck.hu(a)mediatek.com> Gerrit-Reviewer: Duan huayang <huayang.duan(a)mediatek.com> Gerrit-Reviewer: Julius Werner <jwerner(a)chromium.org> Gerrit-MessageType: newchange
4
39
0
0
Change in coreboot[master]: soc/mediatek/mt8192: Do dramc runtime config settings
by CK HU (Code Review)
08 Mar '21
08 Mar '21
Hello Duan huayang, I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/44724
to review the following change. Change subject: soc/mediatek/mt8192: Do dramc runtime config settings ...................................................................... soc/mediatek/mt8192: Do dramc runtime config settings Signed-off-by: Huayang Duan <huayang.duan(a)mediatek.com> Change-Id: Id7ccf0e2332f789f5ae50ec80479c4cd48bb9b40 --- M src/soc/mediatek/mt8192/Makefile.inc M src/soc/mediatek/mt8192/dramc_pi_main.c A src/soc/mediatek/mt8192/dramc_tracking.c 3 files changed, 821 insertions(+), 1 deletion(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/24/44724/1 diff --git a/src/soc/mediatek/mt8192/Makefile.inc b/src/soc/mediatek/mt8192/Makefile.inc index f42ae75..bfa3316 100644 --- a/src/soc/mediatek/mt8192/Makefile.inc +++ b/src/soc/mediatek/mt8192/Makefile.inc @@ -16,7 +16,7 @@ verstage-y += ../common/uart.c romstage-y += ../common/cbmem.c -romstage-y += dramc_pi_main.c dramc_pi_basic_api.c dramc_pi_calibration_api.c dramc_utility.c dramc_dvfs.c +romstage-y += dramc_pi_main.c dramc_pi_basic_api.c dramc_pi_calibration_api.c dramc_utility.c dramc_dvfs.c dramc_tracking.c romstage-y += emi.c romstage-y += flash_controller.c romstage-y += ../common/gpio.c gpio.c diff --git a/src/soc/mediatek/mt8192/dramc_pi_main.c b/src/soc/mediatek/mt8192/dramc_pi_main.c index 11c5d3a..c3c19bf 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_main.c +++ b/src/soc/mediatek/mt8192/dramc_pi_main.c @@ -297,7 +297,12 @@ } dqsosc_shu_settings(cali, dqsosc_thrd_inc, dqsosc_thrd_dec); dramc_rx_dqs_gating_post_process(cali, txdly_min, txdly_max); + dramc_dqs_precalculation_preset(cali); dramc_dual_rank_rx_datlat_cal(cali); + + if (cali->support_ranks == DUAL_RANK_DDR) + xrtwtw_shu_setting(cali); + } static void dramc_calibration_all_channels(struct ddr_cali *cali) @@ -431,4 +436,6 @@ first_freq_k = false; dramc_info("frequency %d calibration finish\n", get_frequency(&cali)); } + + dramc_runtime_config(&cali); } diff --git a/src/soc/mediatek/mt8192/dramc_tracking.c b/src/soc/mediatek/mt8192/dramc_tracking.c new file mode 100644 index 0000000..3c13447 --- /dev/null +++ b/src/soc/mediatek/mt8192/dramc_tracking.c @@ -0,0 +1,813 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <soc/dramc_pi_api.h> +#include <soc/dramc_register.h> + +static void dramc_dqs_precalculation_enable(void) +{ + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.misc_pre_tdqsck1, + MISC_PRE_TDQSCK1_TDQSCK_PRECAL_HW, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_pre_tdqsck1, + MISC_PRE_TDQSCK1_TDQSCK_REG_DVFS, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_pre_tdqsck1, + MISC_PRE_TDQSCK1_TDQSCK_HW_SW_UP_SEL, 0x1); + } +} + +static void dramc_hw_gating_debug(bool enable) +{ + u8 dbg_en = enable ? 0x3 : 0x0; + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.misc_stbcal2, + MISC_STBCAL2_STB_DBG_EN, dbg_en, + MISC_STBCAL2_STB_PIDLYCG_IG, enable, + MISC_STBCAL2_STB_UIDLYCG_IG, enable, + MISC_STBCAL2_STB_GERRSTOP, enable, + MISC_STBCAL2_STB_DBG_CG_AO, 0, + MISC_STBCAL2_STB_DBG_UIPI_UPD_OPT, 0); + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[0].b0_dq9, + B0_DQ9_R_DMRXFIFO_STBENCMP_EN_B0, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[1].b0_dq9, + B1_DQ9_R_DMRXFIFO_STBENCMP_EN_B1, 1); + } +} + +static void tx_picg_new_mode_enable(void) +{ + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.misc_ctrl3, + MISC_CTRL3_ARPI_CG_MCK_DQ_OPT, 0, + MISC_CTRL3_ARPI_MPDIV_CG_DQ_OPT, 0, + MISC_CTRL3_ARPI_CG_DQS_OPT, 0, + MISC_CTRL3_ARPI_CG_DQ_OPT, 0); + } +} + +static void enable_common_dcm_non_shuffle(void) +{ + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].ao.actiming_ctrl, + ACTIMING_CTRL_SEQCLKRUN3, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl0, + MISC_CG_CTRL0_RG_CG_EMI_OFF_DISABLE, 0x1, + MISC_CG_CTRL0_RG_CG_IDLE_SYNC_EN, 0x0, + MISC_CG_CTRL0_RG_CG_NAO_FORCE_OFF, 0x0, + MISC_CG_CTRL0_RG_CG_DRAMC_CK_OFF, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_CG_OFF_DISABLE, 0x1, + MISC_CG_CTRL2_RG_MEM_DCM_APB_SEL, 0x17, + MISC_CG_CTRL2_RG_MEM_DCM_FSEL, 0x0, + MISC_CG_CTRL2_RESERVED_MISC_CG_CTRL2_BIT27, 0x0, + MISC_CG_CTRL2_RG_MEM_DCM_IDLE_FSEL, 0x3, + MISC_CG_CTRL2_RESERVED_MISC_CG_CTRL2_BIT30, 0x0, + MISC_CG_CTRL2_RG_MEM_DCM_FORCE_OFF, 0x0, + MISC_CG_CTRL2_RG_MEM_DCM_DBC_EN, 0x1, + MISC_CG_CTRL2_RG_PHY_CG_OFF_DISABLE, 0x0, + MISC_CG_CTRL2_RG_PIPE0_CG_OFF_DISABLE, 0x0, + MISC_CG_CTRL2_RG_MEM_DCM_APB_TOG, 0x0, + MISC_CG_CTRL2_RG_MEM_DCM_DBC_CNT, 0x5); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_APB_TOG, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_APB_TOG, 0); + SET32_BITFIELDS(&ch[chn].phy_ao.ca_dll_arpi1, + CA_DLL_ARPI1_RG_ARPISM_MCK_SEL_CA_REG_OPT, 0x0); + SET32_BITFIELDS(&ch[chn].ao.dummy_rd, + DUMMY_RD_DUMMY_RD_PA_OPT, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_ctrl3, + MISC_CTRL3_ARPI_CG_DQS_OPT, 0x0, + MISC_CTRL3_ARPI_MPDIV_CG_CA_OPT, 0x0, + MISC_CTRL3_ARPI_CG_DQ_OPT, 0x0, + MISC_CTRL3_ARPI_CG_MCK_DQ_OPT, 0x0, + MISC_CTRL3_ARPI_CG_CMD_OPT, 0x0, + MISC_CTRL3_ARPI_CG_MCTL_DQ_OPT, 0x0, + MISC_CTRL3_ARPI_CG_MCTL_CA_OPT, 0x0, + MISC_CTRL3_ARPI_CG_CLK_OPT, 0x0, + MISC_CTRL3_ARPI_MPDIV_CG_DQ_OPT, 0x0, + MISC_CTRL3_ARPI_CG_MCK_CA_OPT, 0x0); + } +} + +static void enable_common_dcm_shuffle(u8 shuffle) +{ + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_cmd13 + shuffle * SHU_OFFSET, + SHU_CA_CMD13_RG_TX_ARCLKB_READ_BASE_DATA_TIE_EN_CA, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_shu_rx_cg_ctrl + shuffle * SHU_OFFSET, + MISC_SHU_RX_CG_CTRL_RX_DQSIEN_RETRY_CG_EN, 0x1, + MISC_SHU_RX_CG_CTRL_RX_RDSEL_TRACKING_CG_EN, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].shu_b0_dq8 + shuffle * SHU_OFFSET, + SHU_B0_DQ8_R_DMRXDLY_CG_IG_B0, 0x1, + SHU_B0_DQ8_R_RMRX_TOPHY_CG_IG_B0, 0x1); + write32(&ch[chn].phy_ao.misc_shu_cg_ctrl0 + shuffle * SHU_OFFSET, + 0x33403000); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].shu_b0_dq8 + shuffle * SHU_OFFSET, + SHU_B1_DQ8_R_RMRX_TOPHY_CG_IG_B1, 0x1, + SHU_B1_DQ8_R_DMRXDLY_CG_IG_B1, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].shu_b0_dq7 + shuffle * SHU_OFFSET, + SHU_B1_DQ7_R_DMTX_ARPI_CG_DQS_NEW_B1, 0x0, + SHU_B1_DQ7_R_DMTX_ARPI_CG_DQM_NEW_B1, 0x0, + SHU_B1_DQ7_R_DMTX_ARPI_CG_DQ_NEW_B1, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_cmd7 + shuffle * SHU_OFFSET, + SHU_CA_CMD7_R_DMTX_ARPI_CG_CS_NEW, 0x0, + SHU_CA_CMD7_R_DMTX_ARPI_CG_CMD_NEW, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].shu_b0_dq7 + shuffle * SHU_OFFSET, + SHU_B0_DQ7_R_DMTX_ARPI_CG_DQ_NEW_B0, 0x0, + SHU_B0_DQ7_R_DMTX_ARPI_CG_DQM_NEW_B0, 0x0, + SHU_B0_DQ7_R_DMTX_ARPI_CG_DQS_NEW_B0, 0x0); + } +} + +void enable_phy_dcm_shuffle(dcm_state enable, u8 shuffle) +{ + u8 val = enable ? 0 : 1; + enable_common_dcm_shuffle(shuffle); + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].shu_b0_dq8 + shuffle * SHU_OFFSET, + SHU_B0_DQ8_R_DMDQSIEN_RDSEL_TOG_PIPE_CG_IG_B0, val, + SHU_B0_DQ8_R_DMDQSIEN_FLAG_PIPE_CG_IG_B0, val, + SHU_B0_DQ8_R_DMDQSIEN_FLAG_SYNC_CG_IG_B0, val, + SHU_B0_DQ8_R_DMRANK_PIPE_CG_IG_B0, val, + SHU_B0_DQ8_R_RMRODTEN_CG_IG_B0, val, + SHU_B0_DQ8_R_DMRANK_RXDLY_PIPE_CG_IG_B0, val, + SHU_B0_DQ8_R_DMRXDVS_RDSEL_PIPE_CG_IG_B0, val, + SHU_B0_DQ8_R_DMRXDVS_RDSEL_TOG_PIPE_CG_IG_B0, val, + SHU_B0_DQ8_R_DMRANK_CHG_PIPE_CG_IG_B0, val, + SHU_B0_DQ8_R_DMDQSIEN_RDSEL_PIPE_CG_IG_B0, val); + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_cmd8 + shuffle * SHU_OFFSET, + SHU_CA_CMD8_R_DMDQSIEN_RDSEL_PIPE_CG_IG_CA, val, + SHU_CA_CMD8_R_DMRANK_PIPE_CG_IG_CA, val, + SHU_CA_CMD8_R_DMDQSIEN_RDSEL_TOG_PIPE_CG_IG_CA, val, + SHU_CA_CMD8_R_DMDQSIEN_FLAG_PIPE_CG_IG_CA, val, + SHU_CA_CMD8_R_DMDQSIEN_FLAG_SYNC_CG_IG_CA, val, + SHU_CA_CMD8_R_DMRANK_CHG_PIPE_CG_IG_CA, val, + SHU_CA_CMD8_R_RMRX_TOPHY_CG_IG_CA, val, + SHU_CA_CMD8_R_RMRODTEN_CG_IG_CA, val); + SET32_BITFIELDS(&ch[chn].ao.shu_aphy_tx_picg_ctrl + shuffle * SHU_OFFSET, + SHU_APHY_TX_PICG_CTRL_DDRPHY_CLK_EN_COMB_TX_OPT, enable); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].shu_b0_dq8 + shuffle * SHU_OFFSET, + SHU_B1_DQ8_R_RMRODTEN_CG_IG_B1, val, + SHU_B1_DQ8_R_DMDQSIEN_RDSEL_PIPE_CG_IG_B1, val, + SHU_B1_DQ8_R_DMDQSIEN_RDSEL_TOG_PIPE_CG_IG_B1, val, + SHU_B1_DQ8_R_DMRANK_PIPE_CG_IG_B1, val, + SHU_B1_DQ8_R_DMDQSIEN_FLAG_PIPE_CG_IG_B1, val, + SHU_B1_DQ8_R_DMRXDVS_RDSEL_PIPE_CG_IG_B1, val, + SHU_B1_DQ8_R_DMRANK_RXDLY_PIPE_CG_IG_B1, val, + SHU_B1_DQ8_R_DMDQSIEN_FLAG_SYNC_CG_IG_B1, val, + SHU_B1_DQ8_R_DMRANK_CHG_PIPE_CG_IG_B1, val, + SHU_B1_DQ8_R_DMRXDVS_RDSEL_TOG_PIPE_CG_IG_B1, val); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_shu_odtctrl + shuffle * SHU_OFFSET, + MISC_SHU_ODTCTRL_RODTENSTB_SELPH_CG_IG, val); + } +} + +void enable_phy_dcm_non_shuffle(dcm_state enable) +{ + enable_common_dcm_non_shuffle(); + + if (enable) { + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].ao.tx_cg_set0, + TX_CG_SET0_DWCLKRUN, 0x0, + TX_CG_SET0_SELPH_CG_DIS, 0x0, + TX_CG_SET0_SELPH_4LCG_DIS, 0x0, + TX_CG_SET0_TX_ATK_CLKRUN, 0x0, + TX_CG_SET0_WDATA_CG_DIS, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl5, + MISC_CG_CTRL5_R_DQ1_DLY_DCM_EN, 0x1, + MISC_CG_CTRL5_R_DQ1_PI_DCM_EN, 0x1, + MISC_CG_CTRL5_R_DQ0_PI_DCM_EN, 0x1, + MISC_CG_CTRL5_R_CA_PI_DCM_EN, 0x1, + MISC_CG_CTRL5_R_DQ0_DLY_DCM_EN, 0x1, + MISC_CG_CTRL5_R_CA_DLY_DCM_EN, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl0, + MISC_CG_CTRL0_RG_CG_DRAMC_OFF_DISABLE, 0x0, + MISC_CG_CTRL0_RG_CG_COMB_OFF_DISABLE, 0x0, + MISC_CG_CTRL0_RG_CG_CMD_OFF_DISABLE, 0x0, + MISC_CG_CTRL0_RG_CG_COMB0_OFF_DISABLE, 0x0, + MISC_CG_CTRL0_RG_CG_RX_COMB1_OFF_DISABLE, 0x0, + MISC_CG_CTRL0_RG_CG_RX_COMB0_OFF_DISABLE, 0x0, + MISC_CG_CTRL0_RG_CG_INFRA_OFF_DISABLE, 0x0, + MISC_CG_CTRL0_RG_CG_PHY_OFF_DIABLE, 0x0, + MISC_CG_CTRL0_RG_CG_COMB1_OFF_DISABLE, 0x0, + MISC_CG_CTRL0_RG_CG_RX_CMD_OFF_DISABLE, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_FORCE_ON, 0x0, + MISC_CG_CTRL2_RG_MEM_DCM_DCM_EN, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_APB_TOG, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_APB_TOG, 0); + SET32_BITFIELDS(&ch[chn].ao.misctl0, + MISCTL0_REFP_ARBMASK_PBR2PBR_PA_DIS, 0x0); + SET32_BITFIELDS(&ch[chn].ao.sref_dpd_ctrl, + SREF_DPD_CTRL_SREF_CG_OPT, 0x0); + SET32_BITFIELDS(&ch[chn].ao.rx_cg_set0, + RX_CG_SET0_RDYCKAR, 0x0, + RX_CG_SET0_RDATCKAR, 0x0); + SET32_BITFIELDS(&ch[chn].ao.actiming_ctrl, + ACTIMING_CTRL_SEQCLKRUN2, 0x0, + ACTIMING_CTRL_SEQCLKRUN, 0x0); + SET32_BITFIELDS(&ch[chn].ao.scsmctrl_cg, + SCSMCTRL_CG_SCARB_SM_CGAR, 0x0, + SCSMCTRL_CG_SCSM_CGAR, 0x0); + SET32_BITFIELDS(&ch[chn].ao.cmd_dec_ctrl0, + CMD_DEC_CTRL0_SELPH_CMD_CG_DIS, 0x0); + SET32_BITFIELDS(&ch[chn].ao.clkar, + CLKAR_REQQUE_PACG_DIS, 0x0, + CLKAR_REQQUECLKRUN, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_dutyscan1, + MISC_DUTYSCAN1_RX_EYE_SCAN_CG_EN, 0x0); + SET32_BITFIELDS(&ch[chn].ao.ddrcommon0, + DDRCOMMON0_DISSTOP26M, 0x0); + SET32_BITFIELDS(&ch[chn].ao.dvfs_ctrl0, + DVFS_CTRL0_DVFS_CG_OPT, 0x0); + SET32_BITFIELDS(&ch[chn].ao.dcm_ctrl0, DCM_CTRL0_BCLKAR, 0x0); + SET32_BITFIELDS(&ch[chn].ao.dramc_pd_ctrl, + DRAMC_PD_CTRL_PHYCLKDYNGEN, 0x1, + DRAMC_PD_CTRL_DCMEN2, 0x1, + DRAMC_PD_CTRL_DCMEN, 0x1, + DRAMC_PD_CTRL_PHYGLUECLKRUN, 0x0, + DRAMC_PD_CTRL_COMBPHY_CLKENSAME, 0x0, + DRAMC_PD_CTRL_APHYCKCG_FIXOFF, 0x0, + DRAMC_PD_CTRL_MIOCKCTRLOFF, 0x0, + DRAMC_PD_CTRL_DCMENNOTRFC, 0x1, + DRAMC_PD_CTRL_COMBCLKCTRL, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_ctrl3, + MISC_CTRL3_R_DDRPHY_RX_PIPE_CG_IG, 0x0, + MISC_CTRL3_R_DDRPHY_COMB_CG_IG, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_ctrl4, + MISC_CTRL4_R_OPT2_CG_MCK, 0x1, + MISC_CTRL4_R_OPT2_MPDIV_CG, 0x1, + MISC_CTRL4_R_OPT2_CG_DQSIEN, 0x1, + MISC_CTRL4_R_OPT2_CG_DQ, 0x1, + MISC_CTRL4_R_OPT2_CG_DQS, 0x1, + MISC_CTRL4_R_OPT2_CG_DQM, 0x1, + MISC_CTRL4_R_OPT2_CG_CMD, 0x1, + MISC_CTRL4_R_OPT2_CG_CLK, 0x1, + MISC_CTRL4_R_OPT2_CG_CS, 0x1); + SET32_BITFIELDS(&ch[chn].ao.tx_tracking_set0, + TX_TRACKING_SET0_TXUIPI_CAL_CGAR, 0x0, + TX_TRACKING_SET0_RDDQSOSC_CGAR, 0x0, + TX_TRACKING_SET0_HMRRSEL_CGAR, 0x0); + SET32_BITFIELDS(&ch[chn].ao.zq_set0, + ZQ_SET0_ZQCS_MASK_SEL_CGAR, 0x0, + ZQ_SET0_ZQMASK_CGAR, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_rx_autok_cfg0, + MISC_RX_AUTOK_CFG0_RX_CAL_CG_EN, 0x0); + } + } else { + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].ao.tx_cg_set0, + TX_CG_SET0_DWCLKRUN, 0x1, + TX_CG_SET0_SELPH_CG_DIS, 0x1, + TX_CG_SET0_SELPH_4LCG_DIS, 0x1, + TX_CG_SET0_TX_ATK_CLKRUN, 0x1, + TX_CG_SET0_WDATA_CG_DIS, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl5, + MISC_CG_CTRL5_R_DQ1_DLY_DCM_EN, 0x0, + MISC_CG_CTRL5_R_DQ1_PI_DCM_EN, 0x0, + MISC_CG_CTRL5_R_DQ0_PI_DCM_EN, 0x0, + MISC_CG_CTRL5_R_CA_PI_DCM_EN, 0x0, + MISC_CG_CTRL5_R_DQ0_DLY_DCM_EN, 0x0, + MISC_CG_CTRL5_R_CA_DLY_DCM_EN, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl0, + MISC_CG_CTRL0_RG_CG_DRAMC_OFF_DISABLE, 0x1, + MISC_CG_CTRL0_RG_CG_COMB_OFF_DISABLE, 0x1, + MISC_CG_CTRL0_RG_CG_CMD_OFF_DISABLE, 0x1, + MISC_CG_CTRL0_RG_CG_COMB0_OFF_DISABLE, 0x1, + MISC_CG_CTRL0_RG_CG_RX_COMB1_OFF_DISABLE, 0x1, + MISC_CG_CTRL0_RG_CG_RX_COMB0_OFF_DISABLE, 0x1, + MISC_CG_CTRL0_RG_CG_INFRA_OFF_DISABLE, 0x1, + MISC_CG_CTRL0_RG_CG_PHY_OFF_DIABLE, 0x1, + MISC_CG_CTRL0_RG_CG_COMB1_OFF_DISABLE, 0x1, + MISC_CG_CTRL0_RG_CG_RX_CMD_OFF_DISABLE, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_FORCE_ON, 0x1, + MISC_CG_CTRL2_RG_MEM_DCM_DCM_EN, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_APB_TOG, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_APB_TOG, 0); + SET32_BITFIELDS(&ch[chn].ao.misctl0, + MISCTL0_REFP_ARBMASK_PBR2PBR_PA_DIS, 0x1); + SET32_BITFIELDS(&ch[chn].ao.sref_dpd_ctrl, + SREF_DPD_CTRL_SREF_CG_OPT, 0x1); + SET32_BITFIELDS(&ch[chn].ao.rx_cg_set0, + RX_CG_SET0_RDYCKAR, 0x1, + RX_CG_SET0_RDATCKAR, 0x1); + SET32_BITFIELDS(&ch[chn].ao.actiming_ctrl, + ACTIMING_CTRL_SEQCLKRUN2, 0x1, + ACTIMING_CTRL_SEQCLKRUN, 0x1); + SET32_BITFIELDS(&ch[chn].ao.scsmctrl_cg, + SCSMCTRL_CG_SCARB_SM_CGAR, 0x1, + SCSMCTRL_CG_SCSM_CGAR, 0x1); + SET32_BITFIELDS(&ch[chn].ao.cmd_dec_ctrl0, + CMD_DEC_CTRL0_SELPH_CMD_CG_DIS, 0x1); + SET32_BITFIELDS(&ch[chn].ao.clkar, + CLKAR_REQQUE_PACG_DIS, 0x7fff, + CLKAR_REQQUECLKRUN, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_dutyscan1, + MISC_DUTYSCAN1_RX_EYE_SCAN_CG_EN, 0x1); + SET32_BITFIELDS(&ch[chn].ao.ddrcommon0, + DDRCOMMON0_DISSTOP26M, 0x1); + SET32_BITFIELDS(&ch[chn].ao.dvfs_ctrl0, + DVFS_CTRL0_DVFS_CG_OPT, 0x1); + SET32_BITFIELDS(&ch[chn].ao.dcm_ctrl0, DCM_CTRL0_BCLKAR, 0x1); + SET32_BITFIELDS(&ch[chn].ao.dramc_pd_ctrl, + DRAMC_PD_CTRL_PHYCLKDYNGEN, 0x0, + DRAMC_PD_CTRL_DCMEN2, 0x0, + DRAMC_PD_CTRL_DCMEN, 0x0, + DRAMC_PD_CTRL_PHYGLUECLKRUN, 0x1, + DRAMC_PD_CTRL_COMBPHY_CLKENSAME, 0x1, + DRAMC_PD_CTRL_APHYCKCG_FIXOFF, 0x1, + DRAMC_PD_CTRL_MIOCKCTRLOFF, 0x1, + DRAMC_PD_CTRL_DCMENNOTRFC, 0x0, + DRAMC_PD_CTRL_COMBCLKCTRL, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_ctrl3, + MISC_CTRL3_R_DDRPHY_RX_PIPE_CG_IG, 0x1, + MISC_CTRL3_R_DDRPHY_COMB_CG_IG, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_ctrl4, + MISC_CTRL4_R_OPT2_CG_DQSIEN, 0x0, + MISC_CTRL4_R_OPT2_CG_CLK, 0x0, + MISC_CTRL4_R_OPT2_MPDIV_CG, 0x0, + MISC_CTRL4_R_OPT2_CG_DQM, 0x0, + MISC_CTRL4_R_OPT2_CG_CMD, 0x0, + MISC_CTRL4_R_OPT2_CG_DQS, 0x0, + MISC_CTRL4_R_OPT2_CG_MCK, 0x0, + MISC_CTRL4_R_OPT2_CG_CS, 0x0, + MISC_CTRL4_R_OPT2_CG_DQ, 0x0); + SET32_BITFIELDS(&ch[chn].ao.tx_tracking_set0, + TX_TRACKING_SET0_TXUIPI_CAL_CGAR, 0x1, + TX_TRACKING_SET0_RDDQSOSC_CGAR, 0x1, + TX_TRACKING_SET0_HMRRSEL_CGAR, 0x1); + SET32_BITFIELDS(&ch[chn].ao.zq_set0, + ZQ_SET0_ZQCS_MASK_SEL_CGAR, 0x1, + ZQ_SET0_ZQMASK_CGAR, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_rx_autok_cfg0, + MISC_RX_AUTOK_CFG0_RX_CAL_CG_EN, 0x1); + } + } +} + +static void enable_tx_tracking(dram_freq_grp freq_group, u8 shuffle) +{ + u8 dqsosc_en = (freq_group <= DDRFREQ_400) ? 1 : 0; + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].ao.shu_dqsosc_set0 + shuffle * SHU_OFFSET, + SHU_DQSOSC_SET0_DQSOSCENDIS, dqsosc_en); +} + +static void enable_gating_tracking(dram_freq_grp freq_group, u8 shuffle) +{ + u8 stbcal = (freq_group <= DDRFREQ_400) ? 0 : 1; + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].phy_ao.misc_shu_stbcal + shuffle * SHU_OFFSET, + MISC_SHU_STBCAL_STBCALEN, stbcal, + MISC_SHU_STBCAL_STB_SELPHCALEN, stbcal); +} + +static void enable_rx_dcm_dphy(dram_freq_grp freq_group, u8 shuffle) +{ + u8 precal_cg_en = (freq_group <= DDRFREQ_400) ? 1 : 0; + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].phy_ao.misc_shu_rx_cg_ctrl + shuffle * SHU_OFFSET, + MISC_SHU_RX_CG_CTRL_RX_DCM_OPT, 0x1, + MISC_SHU_RX_CG_CTRL_RX_APHY_CTRL_DCM_OPT, 0x1, + MISC_SHU_RX_CG_CTRL_RX_RODT_DCM_OPT, 0x1, + MISC_SHU_RX_CG_CTRL_RX_DQSIEN_STBCAL_CG_EN, 0x0, + MISC_SHU_RX_CG_CTRL_RX_DQSIEN_AUTOK_CG_EN, 0x1, + MISC_SHU_RX_CG_CTRL_RX_RDSEL_TRACKING_CG_EN, 0x1, + MISC_SHU_RX_CG_CTRL_RX_DQSIEN_RETRY_CG_EN, 0x1, + MISC_SHU_RX_CG_CTRL_RX_PRECAL_CG_EN, precal_cg_en, + MISC_SHU_RX_CG_CTRL_RX_DCM_EXT_DLY, 0x2, + MISC_SHU_RX_CG_CTRL_RX_DCM_WAIT_DLE_EXT_DLY, 0x0); +} + + +static void enable_clk_tx_rx_latch_en(u8 shuffle) +{ + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].shu_b0_dq13 + shuffle * SHU_OFFSET, + SHU_B0_DQ13_RG_TX_ARDQ_DLY_LAT_EN_B0, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].shu_b0_dq13 + shuffle * SHU_OFFSET, + SHU_B1_DQ13_RG_TX_ARDQ_DLY_LAT_EN_B1, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].shu_b0_dq10 + shuffle * SHU_OFFSET, + SHU_B0_DQ10_RG_RX_ARDQS_DLY_LAT_EN_B0, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].shu_b0_dq10 + shuffle * SHU_OFFSET, + SHU_B1_DQ10_RG_RX_ARDQS_DLY_LAT_EN_B1, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].shu_b0_dq2 + shuffle * SHU_OFFSET, + SHU_B0_DQ2_RG_ARPI_OFFSET_LAT_EN_B0, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].shu_b0_dq2 + shuffle * SHU_OFFSET, + SHU_B1_DQ2_RG_ARPI_OFFSET_LAT_EN_B1, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].shu_b0_dq11 + shuffle * SHU_OFFSET, + SHU_B0_DQ11_RG_RX_ARDQ_OFFSETC_LAT_EN_B0, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].shu_b0_dq11 + shuffle * SHU_OFFSET, + SHU_B1_DQ11_RG_RX_ARDQ_OFFSETC_LAT_EN_B1, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_cmd11 + shuffle * SHU_OFFSET, + SHU_CA_CMD11_RG_RX_ARCA_OFFSETC_LAT_EN_CA, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_cmd10 + shuffle * SHU_OFFSET, + SHU_CA_CMD10_RG_RX_ARCLK_DLY_LAT_EN_CA, 1); + } + +} + +static void enable_tx_wdqs(u8 shuffle) +{ + u8 dqsb_read_base = 1; + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.byte[0].shu_b0_dq13 + shuffle * SHU_OFFSET, + SHU_B0_DQ13_RG_TX_ARDQS_READ_BASE_EN_B0, 1, + SHU_B0_DQ13_RG_TX_ARDQSB_READ_BASE_EN_B0, dqsb_read_base, + SHU_B0_DQ13_RG_TX_ARDQS_READ_BASE_DATA_TIE_EN_B0, 1, + SHU_B0_DQ13_RG_TX_ARDQSB_READ_BASE_DATA_TIE_EN_B0, + dqsb_read_base); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[1].shu_b0_dq13 + shuffle * SHU_OFFSET, + SHU_B1_DQ13_RG_TX_ARDQS_READ_BASE_EN_B1, 1, + SHU_B1_DQ13_RG_TX_ARDQSB_READ_BASE_EN_B1, dqsb_read_base, + SHU_B1_DQ13_RG_TX_ARDQS_READ_BASE_DATA_TIE_EN_B1, 1, + SHU_B1_DQ13_RG_TX_ARDQSB_READ_BASE_DATA_TIE_EN_B1, + dqsb_read_base); + } +} + +static void set_mr13_vrcg_to_normal_operation_shuffle(u8 shuffle) +{ + u32 value = READ32_BITFIELD(&ch[0].ao.shu_hwset_vrcg + shuffle * SHU_OFFSET, + SHU_HWSET_VRCG_HWSET_VRCG_OP); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].ao.shu_hwset_vrcg + shuffle * SHU_OFFSET, + SHU_HWSET_VRCG_HWSET_VRCG_OP, value & ~ BIT(3)); +} + +static void dramc_shu_tracking_dcm_en_by_sram(const struct ddr_cali* cali) +{ + u8 shuffle, chn, shuffle_save; + dram_freq_grp freq_group = 0; + dram_freq_grp freq_group_bak = get_freq_group(cali); + + struct reg_bak regs_bak[] = { + {&ch[0].phy_ao.misc_sram_dma0}, + {&ch[1].phy_ao.misc_sram_dma0}, + {&ch[0].phy_ao.misc_sram_dma1}, + {&ch[1].phy_ao.misc_sram_dma1}, + }; + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + regs_bak[i].value = read32(regs_bak[i].addr); + + for (chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.misc_sram_dma0, + MISC_SRAM_DMA0_APB_SLV_SEL, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_sram_dma1, + MISC_SRAM_DMA1_R_APB_DMA_DBG_ACCESS, 0x1); + } + + for (shuffle = DRAM_DFS_SHU0; shuffle <= DRAM_DFS_SHU_MAX; shuffle++) { + if (shuffle < DRAM_DFS_SHU_MAX) { + /* save to shuffle */ + freq_group = get_freq_group_by_shu_save(shuffle); + for (chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.misc_sram_dma0, + MISC_SRAM_DMA0_APB_SLV_SEL, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_sram_dma1, + MISC_SRAM_DMA1_R_APB_DMA_DBG_LEVEL, shuffle); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_sram_dma0, + MISC_SRAM_DMA0_APB_SLV_SEL, 0x1); + } + shuffle_save = DRAM_DFS_SHU1; + } else { + /* restore to SRAM */ + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + write32(regs_bak[i].addr, regs_bak[i].value); + shuffle_save = DRAM_DFS_SHU0; + freq_group = freq_group_bak; + } + + enable_tx_tracking(freq_group, shuffle_save); + enable_gating_tracking(freq_group, shuffle_save); + enable_rx_dcm_dphy(freq_group, shuffle_save); + enable_clk_tx_rx_latch_en(shuffle_save); + enable_tx_wdqs(shuffle_save); + enable_phy_dcm_shuffle(DCM_ON, shuffle_save); + set_mr13_vrcg_to_normal_operation_shuffle(shuffle_save); + } +} + +static void dramc_impedance_tracking_enable(void) +{ + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.misc_ctrl0, + MISC_CTRL0_IMPCAL_CHAB_EN, 0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_impcal, + MISC_IMPCAL_IMPCAL_HW, 1, + MISC_IMPCAL_IMPCAL_EN, 0, + MISC_IMPCAL_IMPCAL_SWVALUE_EN, 1, + MISC_IMPCAL_IMPCAL_NEW_OLD_SL, 1, + MISC_IMPCAL_IMPCAL_DRVUPDOPT, 1, + MISC_IMPCAL_IMPCAL_CHGDRV_ECO_OPT, 1, + MISC_IMPCAL_IMPCAL_SM_ECO_OPT, 1, + MISC_IMPCAL_IMPBINARY, 1, + MISC_IMPCAL_DRV_ECO_OPT, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_ctrl0, + MISC_CTRL0_IMPCAL_LP_ECO_OPT, 0x1, + MISC_CTRL0_IMPCAL_TRACK_DISABLE, chn); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_impcal, + MISC_IMPCAL_IMPCAL_BYPASS_UP_CA_DRV, 1); + } + + SET32_BITFIELDS(&ch[0].phy_ao.misc_impcal, + MISC_IMPCAL_DIS_SUS_CH0_DRV, 0, + MISC_IMPCAL_DIS_SUS_CH1_DRV, 1, + MISC_IMPCAL_IMPSRCEXT, 0, + MISC_IMPCAL_IMPCAL_ECO_OPT, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_impcal, + MISC_IMPCAL_DIS_SUS_CH0_DRV, 1, + MISC_IMPCAL_DIS_SUS_CH1_DRV, 0, + MISC_IMPCAL_IMPSRCEXT, 1, + MISC_IMPCAL_IMPCAL_ECO_OPT, 0); + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.misc_impcal, MISC_IMPCAL_DRVCGWREF, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_impcal, MISC_IMPCAL_DQDRVSWUPD, 1); + } +} + +static void dramc_impedance_hw_saving(void) +{ + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].phy_ao.misc_impcal, + MISC_IMPCAL_IMPCAL_HWSAVE_EN, 1); +} + +static void switch_hmr4(const struct ddr_cali* cali, bool en) +{ + u8 tog_opt = (en && cali->support_ranks == DUAL_RANK_DDR) ? 1 : 0; + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].ao.ref_bounce2, REF_BOUNCE2_PRE_MR4INT_TH, 5); + SET32_BITFIELDS(&ch[chn].ao.refctrl2, REFCTRL2_MR4INT_TH, 5); + SET32_BITFIELDS(&ch[chn].ao.hmr4, HMR4_HMR4_TOG_OPT, tog_opt); + SET32_BITFIELDS(&ch[chn].ao.hmr4, HMR4_REFRDIS, !en); + } +} + +static void dramc_refresh_rate_debounce_enable(void) +{ + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].ao.ref_bounce1, + REF_BOUNCE1_REFRATE_DEBOUNCE_COUNT, 0x4, + REF_BOUNCE1_REFRATE_DEBOUNCE_TH, 5, + REF_BOUNCE1_REFRATE_DEBOUNCE_OPT, 0, + REF_BOUNCE1_REFRATE_DEBOUNCE_DIS, 0xff1f); +} + +static void enable_dfs_no_queue_flush(void) +{ + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].ao.dvfs_ctrl0, + DVFS_CTRL0_HWSET_WLRL, 0, + DVFS_CTRL0_DVFS_RXFIFOST_SKIP, 0, + DVFS_CTRL0_DVFS_NOQUEFLUSH_EN, 1, + DVFS_CTRL0_R_DMDVFSMRW_EN, 0); + SET32_BITFIELDS(&ch[chn].ao.shuctrl1, + SHUCTRL1_FC_PRDCNT, 0, + SHUCTRL1_CKFSPE_PRDCNT, 0, + SHUCTRL1_VRCGEN_PRDCNT, 0, + SHUCTRL1_CKFSPX_PRDCNT, 0); + SET32_BITFIELDS(&ch[chn].ao.bypass_fspop, + BYPASS_FSPOP_BPFSP_OPT, 0); + } +} + +static void _dramc_dqs_precalculation_preset(u8 chn, u8 rk, u8 b) +{ + u8 mck, ui, pi, mck_p1, ui_p1, write_ui, write_pi; + const u8 mck2ui = 4; + + if (b == 0) { + mck = READ32_BITFIELD(&ch[chn].phy_ao.byte[b].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B0); + ui = READ32_BITFIELD(&ch[chn].phy_ao.byte[b].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B0); + mck_p1= READ32_BITFIELD(&ch[chn].phy_ao.byte[b].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B0); + ui_p1 = READ32_BITFIELD(&ch[chn].phy_ao.byte[b].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B0); + pi = READ32_BITFIELD(&ch[chn].phy_ao.byte[b].rk[rk].shu_rk_b0_dqsien_pi_dly, + SHU_RK_B0_DQSIEN_PI_DLY_DQSIEN_PI_B0); + + write_ui = (mck << mck2ui) + ui; + write_pi = (mck_p1 << mck2ui) + ui_p1; + SET32_BITFIELDS(&ch[chn].phy_ao.byte[b].rk[rk].shu_r0_b0_ini_uipi, + SHU_R0_B0_INI_UIPI_CURR_INI_UI_B0, write_ui, + SHU_R0_B0_INI_UIPI_CURR_INI_PI_B0, pi); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[b].rk[rk].shu_r0_b0_next_ini_uipi, + SHU_R0_B0_NEXT_INI_UIPI_NEXT_INI_UI_B0, write_ui, + SHU_R0_B0_NEXT_INI_UIPI_NEXT_INI_UI_P1_B0, write_pi, + SHU_R0_B0_NEXT_INI_UIPI_NEXT_INI_PI_B0, pi); + } else { + mck = READ32_BITFIELD(&ch[chn].phy_ao.byte[b].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B1); + ui = READ32_BITFIELD(&ch[chn].phy_ao.byte[b].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B1); + mck_p1= READ32_BITFIELD(&ch[chn].phy_ao.byte[b].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B1); + ui_p1 = READ32_BITFIELD(&ch[chn].phy_ao.byte[b].rk[rk].shu_dqsien_mck_ui_dly, + SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B1); + pi = READ32_BITFIELD(&ch[chn].phy_ao.byte[b].rk[rk].shu_rk_b0_dqsien_pi_dly, + SHU_RK_B1_DQSIEN_PI_DLY_DQSIEN_PI_B1); + + write_ui = (mck << mck2ui) +ui; + write_pi = (mck_p1 << mck2ui) + ui_p1; + SET32_BITFIELDS(&ch[chn].phy_ao.byte[b].rk[rk].shu_r0_b0_ini_uipi, + SHU_R0_B1_INI_UIPI_CURR_INI_UI_B1, write_ui, + SHU_R0_B1_INI_UIPI_CURR_INI_PI_B1, pi); + SET32_BITFIELDS(&ch[chn].phy_ao.byte[b].rk[rk].shu_r0_b0_next_ini_uipi, + SHU_R0_B1_NEXT_INI_UIPI_NEXT_INI_UI_B1, write_ui, + SHU_R0_B1_NEXT_INI_UIPI_NEXT_INI_UI_P1_B1, write_pi, + SHU_R0_B0_NEXT_INI_UIPI_NEXT_INI_PI_B0, pi); + } +} + +void dramc_dqs_precalculation_preset(const struct ddr_cali* cali) +{ + u8 chn = cali->chn; + + for (u8 byte = 0; byte < DQS_NUMBER; byte++) + for (u8 rank = RANK_0; rank < cali->support_ranks; rank++) + _dramc_dqs_precalculation_preset(chn, rank, byte); + + if (get_shu(cali) == DRAM_DFS_SHU6) { + SET32_BITFIELDS(&ch[chn].phy_ao.shu_misc_pre_tdqsck, + SHU_MISC_PRE_TDQSCK_PRECAL_DISABLE, 0x1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_shu_rx_cg_ctrl, + MISC_SHU_RX_CG_CTRL_RX_PRECAL_CG_EN, 0x1); + } else { + SET32_BITFIELDS(&ch[chn].phy_ao.shu_misc_pre_tdqsck, + SHU_MISC_PRE_TDQSCK_PRECAL_DISABLE, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_shu_rx_cg_ctrl, + MISC_SHU_RX_CG_CTRL_RX_PRECAL_CG_EN, 0x0); + } +} + +void xrtwtw_shu_setting(const struct ddr_cali* cali) +{ + u8 byte, chn; + u16 tx_dly_oen_rk[2][2] = {0}, tx_pi_upd[2] = {0}; + u16 tx_rank_inctl, tx_dly_oen_rk_max, tx_pi_upd_max; + + dram_freq_grp freq_group = get_freq_group(cali); + chn = cali->chn; + + for (u8 rk = RANK_0; rk < cali->support_ranks; rk++) { + tx_dly_oen_rk[rk][0] = READ32_BITFIELD(&ch[chn].ao.shu_rk[rk].shurk_selph_dq0, + SHURK_SELPH_DQ0_TXDLY_OEN_DQ0); + tx_dly_oen_rk[rk][1] = READ32_BITFIELD(&ch[chn].ao.shu_rk[rk].shurk_selph_dq0, + SHURK_SELPH_DQ0_TXDLY_OEN_DQ1); + } + + for (byte = 0; byte < DQS_NUMBER; byte++) { + tx_dly_oen_rk_max = (tx_dly_oen_rk[0][byte] > tx_dly_oen_rk[1][byte]) ? + tx_dly_oen_rk[0][byte]: tx_dly_oen_rk[1][byte]; + if (freq_group >= DDRFREQ_1200) + tx_pi_upd[byte] = (tx_dly_oen_rk_max > 2) ? (tx_dly_oen_rk_max - 2) : 0; + else + tx_pi_upd[byte] = (tx_dly_oen_rk_max > 1) ? (tx_dly_oen_rk_max - 1) : 0; + } + + tx_pi_upd_max = (tx_pi_upd[0] > tx_pi_upd[1]) ? tx_pi_upd[0] : tx_pi_upd[1]; + tx_rank_inctl = (tx_pi_upd_max > 1) ? (tx_pi_upd_max - 1) : 0; + + SET32_BITFIELDS(&ch[chn].ao.shu_new_xrw2w_ctrl, + SHU_NEW_XRW2W_CTRL_TXPI_UPD_MODE, 0x0, + SHU_NEW_XRW2W_CTRL_TX_PI_UPDCTL_B0, tx_pi_upd[0], + SHU_NEW_XRW2W_CTRL_TX_PI_UPDCTL_B1, tx_pi_upd[1]); + + SET32_BITFIELDS(&ch[chn].ao.shu_tx_rankctl, + SHU_TX_RANKCTL_TXRANKINCTL_ROOT, 0x0, + SHU_TX_RANKCTL_TXRANKINCTL, tx_rank_inctl, + SHU_TX_RANKCTL_TXRANKINCTL_TXDLY, tx_rank_inctl); +} + +static void dpm_control_init(const struct ddr_cali *cali) +{ + u8 val, pll1_val, pll2_val; + u8 shu_sram = get_shu(cali); + u8 pll_mode = *(cali->pll_mode); + + + val = 0x3; + SET32_BITFIELDS(&mtk_dpm->low_power_cfg_0, + LPIF_LOW_POWER_CFG_0_PHYPLL_EN, val, + LPIF_LOW_POWER_CFG_0_DPY_DLL_EN, val, + LPIF_LOW_POWER_CFG_0_DPY_2ND_DLL_EN, val, + LPIF_LOW_POWER_CFG_0_DPY_DLL_CK_EN, val, + LPIF_LOW_POWER_CFG_0_DPY_VREF_EN, val); + SET32_BITFIELDS(&mtk_dpm->low_power_cfg_3, + LPIF_LOW_POWER_CFG_3_DPY_MCK8X_EN, val, + LPIF_LOW_POWER_CFG_3_DPY_MIDPI_EN, val, + LPIF_LOW_POWER_CFG_3_DPY_PI_RESETB_EN, val); + + if (pll_mode == PHYPLL_MODE) { + dramc_dbg("PHYPLL\n"); + pll1_val = val; + pll2_val = 0; + } else { + dramc_dbg("CLRPLL\n"); + pll1_val = 0; + pll2_val = val; + } + + SET32_BITFIELDS(&mtk_dpm->low_power_cfg_0, + LPIF_LOW_POWER_CFG_0_PHYPLL_SHU_EN, pll1_val, + LPIF_LOW_POWER_CFG_0_PHYPLL_MODE_SW, pll1_val, + LPIF_LOW_POWER_CFG_0_PHYPLL2_SHU_EN, pll2_val, + LPIF_LOW_POWER_CFG_0_PHYPLL2_MODE_SW, pll2_val); + SET32_BITFIELDS(&mtk_dpm->fsm_cfg_1, + LPIF_FSM_CFG_1_LPIF_LEGACY_CONTROL, 0x0, + LPIF_FSM_CFG_1_LPIF_LEGACY_CONTROL_2ND, 0x0, + LPIF_FSM_CFG_1_LPIF_LEGACY_CONTROL_FOR_PWR, 0x0, + LPIF_FSM_CFG_1_LPIF_LEGACY_CONTROL_FOR_PWR_2ND, 0x0, + LPIF_FSM_CFG_1_LPIF_OUTPUT_PATH_FROM_SW, 0x1, + LPIF_FSM_CFG_1_LPIF_OUTPUT_PATH_FROM_SW_2ND, 0x1, + LPIF_FSM_CFG_1_LPIF_POWER_CONTROL_SEL, 0x1, + LPIF_FSM_CFG_1_LPIF_POWER_CONTROL_SEL_2ND, 0x1); + SET32_BITFIELDS(&mtk_dpm->fsm_out_ctrl_0, + LPIF_FSM_OUT_CTRL_0_LOG_OPT_PHYPLL_EN, 0x1, + LPIF_FSM_OUT_CTRL_0_LOG_OPT_DPY_DLL_EN, 0x1, + LPIF_FSM_OUT_CTRL_0_LOG_OPT_DPY_2ND_DLL_EN, 0x1, + LPIF_FSM_OUT_CTRL_0_LOG_OPT_DPY_DLL_CK_EN, 0x1, + LPIF_FSM_OUT_CTRL_0_LOG_OPT_DPY_VREF_EN, 0x1, + LPIF_FSM_OUT_CTRL_0_LOG_OPT_PHYPLL_SHU_EN, 0x1, + LPIF_FSM_OUT_CTRL_0_LOG_OPT_PHYPLL_MODE_SW, 0x1); + + shu_sram |= shu_sram << 4; + SET32_BITFIELDS(&mtk_dpm->low_power_cfg_1, + LPIF_LOW_POWER_CFG_1_DR_SHU_SRAM_LEVEL, shu_sram); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.misc_rg_dfs_ctrl, + MISC_RG_DFS_CTRL_SPM_DVFS_CONTROL_SEL, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.phypll0, + PHYPLL0_RG_RPHYPLL_EN, 0x0); + SET32_BITFIELDS(&ch[chn].phy_ao.clrpll0, + CLRPLL0_RG_RCLRPLL_EN, 0x0); + } + SET32_BITFIELDS(&mtk_dpm->dfd_dbug_0, + LPIF_DFD_DBUG_0_LPIF_DFD_DEBUG_ISO_EN, 0x1); +} + +void dramc_runtime_config(const struct ddr_cali* cali) +{ + dpm_control_init(cali); + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].ao.refctrl1, + REFCTRL1_REF_OVERHEAD_SLOW_REFPB_ENA, 0x1); + dramc_dbg("REFRESH_OVERHEAD_REDUCTION: ON\n"); + + dramc_dqs_precalculation_enable(); + dramc_dbg("DQS Precalculation for DVFS: ON\n"); + + dramc_hw_gating_debug(true); + dramc_dbg("HW_GATING DBG: ON\n"); + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].ao.zq_set1, ZQ_SET1_ZQCALDISB, 1); + dramc_dbg("ZQCS_ENABLE_LP4: ON\n"); + + tx_picg_new_mode_enable(); + dramc_dbg("TX_PICG_NEW_MODE: ON\n"); + + enable_phy_dcm_non_shuffle(DCM_ON); + dramc_dbg("LOWPOWER_GOLDEN_SETTINGS(DCM): ON\n"); + + dramc_shu_tracking_dcm_en_by_sram(cali); + + dramc_impedance_tracking_enable(); + dramc_dbg("IMPEDANCE_TRACKING: ON\n"); + dramc_impedance_hw_saving(); + + switch_hmr4(cali, true); + dramc_dbg("TEMP_SENSOR: ON\n"); + + dramc_dbg("Refresh Rate DeBounce: ON\n"); + dramc_refresh_rate_debounce_enable(); + + enable_dfs_no_queue_flush(); + dramc_dbg("DFS_NO_QUEUE_FLUSH: ON\n"); + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].ao.refctrl0, REFCTRL0_REFDIS, 0x0); + + dramc_dbg("DDR_RESERVE_NEW_MODE: ON\n"); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].phy_ao.misc_ddr_reserve, + MISC_DDR_RESERVE_WDT_LITE_EN, 1, + MISC_DDR_RESERVE_WDT_SM_CLR, 0); +} -- To view, visit
https://review.coreboot.org/c/coreboot/+/44724
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: Id7ccf0e2332f789f5ae50ec80479c4cd48bb9b40 Gerrit-Change-Number: 44724 Gerrit-PatchSet: 1 Gerrit-Owner: CK HU <ck.hu(a)mediatek.com> Gerrit-Reviewer: Duan huayang <huayang.duan(a)mediatek.com> Gerrit-Reviewer: Julius Werner <jwerner(a)chromium.org> Gerrit-Reviewer: Martin Roth <martinroth(a)google.com> Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com> Gerrit-MessageType: newchange
6
11
0
0
Change in coreboot[master]: soc/mediatek/mt8192: Do dramc after calibration settings
by CK HU (Code Review)
08 Mar '21
08 Mar '21
Hello Duan huayang, I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/44725
to review the following change. Change subject: soc/mediatek/mt8192: Do dramc after calibration settings ...................................................................... soc/mediatek/mt8192: Do dramc after calibration settings Signed-off-by: Huayang Duan <huayang.duan(a)mediatek.com> Change-Id: Id90219ca0be83ecb6342480a9692820462d9ae9d --- M src/soc/mediatek/mt8192/dramc_pi_basic_api.c M src/soc/mediatek/mt8192/dramc_pi_calibration_api.c M src/soc/mediatek/mt8192/dramc_pi_main.c 3 files changed, 58 insertions(+), 0 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/25/44725/1 diff --git a/src/soc/mediatek/mt8192/dramc_pi_basic_api.c b/src/soc/mediatek/mt8192/dramc_pi_basic_api.c index d418228..ab6b027 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_basic_api.c +++ b/src/soc/mediatek/mt8192/dramc_pi_basic_api.c @@ -4893,6 +4893,38 @@ SET32_BITFIELDS(&ch[chn].ao.dqsoscr, DQSOSCR_DQSOSC_CALEN, 1); } +void enable_write_DBI_after_calibration(const struct ddr_cali* cali) +{ + struct mr_values *mr_value = cali->mr_value; + + for (u8 chn = CHANNEL_A; chn < CHANNEL_MAX; chn++) + for (u8 rk = RANK_0; rk < cali->support_ranks; rk++) + for (u8 fsp = FSP_0; fsp < FSP_MAX; fsp++) { + u8 mr13 = mr_value->mr13[rk]; + u8 mr03 = mr_value->mr03[fsp]; + + mr13 = (mr13 & ~ BIT(6)) | (fsp << 6); + dramc_mode_reg_write_by_rank(cali, chn, rk, 13, mr13); + mr03 = (mr03 & ~ BIT(7)) | (cali->w_dbi[fsp] << 7); + dramc_mode_reg_write_by_rank(cali, chn, rk, 3, mr03); + + mr_value->mr13[rk] = mr13; + mr_value->mr03[fsp] = mr03; + } +} + +void dramc_set_mr13_vrcg_to_normal(const struct ddr_cali* cali) +{ + struct mr_values *mr_value = cali->mr_value; + + for (u8 chn = CHANNEL_A; chn < CHANNEL_MAX; chn++) + for (u8 rk = RANK_0; rk < cali->support_ranks; rk++) { + u8 mr13 = mr_value->mr13[rk] & ~ BIT(3); + dramc_mode_reg_write_by_rank(cali, chn, rk, 13, mr13); + mr_value->mr13[rk] = mr13; + } +} + void apply_write_dbi_power_improve(bool en) { for (u8 chn = 0; chn < CHANNEL_MAX; chn++) diff --git a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c index 2082f4d..9fee4d1 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8192/dramc_pi_calibration_api.c @@ -3014,3 +3014,26 @@ SET32_BITFIELDS(&ch[chn].ao.shu_dqsosc_set0, SHU_DQSOSC_SET0_DQSOSCENCNT, dqsosc_en_cnt); } + +void after_calib(const struct ddr_cali* cali) +{ + enable_write_DBI_after_calibration(cali); + dramc_set_mr13_vrcg_to_normal(cali); + cke_fix_onoff(cali, CHANNEL_A, RANK_MAX, CKE_DYNAMIC); + cke_fix_onoff(cali, CHANNEL_B, RANK_MAX, CKE_DYNAMIC); + + for (u8 chn = CHANNEL_A; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].ao.dummy_rd, + DUMMY_RD_RANK_NUM, cali->support_ranks); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl7, + MISC_CG_CTRL7_CK_BFE_DCM_EN, 0); + SET32_BITFIELDS(&ch[chn].ao.test2_a4, + TEST2_A4_TESTAGENTRKSEL, 4); + SET32_BITFIELDS(&ch[chn].ao.test2_a2, + TEST2_A2_TEST2_OFF, 0x20); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_dutyscan1, + MISC_DUTYSCAN1_DQSERRCNT_DIS, 0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_ctrl1, + MISC_CTRL1_R_DMSTBENCMP_RK_OPT, 0); + } +} diff --git a/src/soc/mediatek/mt8192/dramc_pi_main.c b/src/soc/mediatek/mt8192/dramc_pi_main.c index c3c19bf..2bcc449 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_main.c +++ b/src/soc/mediatek/mt8192/dramc_pi_main.c @@ -437,5 +437,8 @@ dramc_info("frequency %d calibration finish\n", get_frequency(&cali)); } + after_calib(&cali); + enable_dfs_hw_mode_clk(); + dramc_runtime_config(&cali); } -- To view, visit
https://review.coreboot.org/c/coreboot/+/44725
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: Id90219ca0be83ecb6342480a9692820462d9ae9d Gerrit-Change-Number: 44725 Gerrit-PatchSet: 1 Gerrit-Owner: CK HU <ck.hu(a)mediatek.com> Gerrit-Reviewer: Duan huayang <huayang.duan(a)mediatek.com> Gerrit-Reviewer: Julius Werner <jwerner(a)chromium.org> Gerrit-MessageType: newchange
5
9
0
0
Change in coreboot[master]: soc/mediatek/mt8192: Do dramc analog init setting
by CK HU (Code Review)
08 Mar '21
08 Mar '21
Hello Duan huayang, I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/44727
to review the following change. Change subject: soc/mediatek/mt8192: Do dramc analog init setting ...................................................................... soc/mediatek/mt8192: Do dramc analog init setting Signed-off-by: Huayang Duan <huayang.duan(a)mediatek.com> Change-Id: I53b30a2bbed5acb363f85f7cbc7f255fdbc52304 --- M src/soc/mediatek/mt8192/Makefile.inc A src/soc/mediatek/mt8192/dramc_ana_init_config.c M src/soc/mediatek/mt8192/dramc_pi_basic_api.c A src/soc/mediatek/mt8192/dramc_subsys_config.c M src/soc/mediatek/mt8192/emi.c 5 files changed, 1,411 insertions(+), 0 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/27/44727/1 diff --git a/src/soc/mediatek/mt8192/Makefile.inc b/src/soc/mediatek/mt8192/Makefile.inc index bfa3316..e3463cd 100644 --- a/src/soc/mediatek/mt8192/Makefile.inc +++ b/src/soc/mediatek/mt8192/Makefile.inc @@ -17,6 +17,7 @@ romstage-y += ../common/cbmem.c romstage-y += dramc_pi_main.c dramc_pi_basic_api.c dramc_pi_calibration_api.c dramc_utility.c dramc_dvfs.c dramc_tracking.c +romstage-y += dramc_subsys_config.c dramc_ana_init_config.c romstage-y += emi.c romstage-y += flash_controller.c romstage-y += ../common/gpio.c gpio.c diff --git a/src/soc/mediatek/mt8192/dramc_ana_init_config.c b/src/soc/mediatek/mt8192/dramc_ana_init_config.c new file mode 100644 index 0000000..0fd3a9a --- /dev/null +++ b/src/soc/mediatek/mt8192/dramc_ana_init_config.c @@ -0,0 +1,1242 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <soc/dramc_pi_api.h> +#include <soc/dramc_register.h> + +static void suspend_on(void) +{ + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_lp_ctrl0, + B0_LP_CTRL0_RG_ARDMSUS_10_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_lp_ctrl0, + B1_LP_CTRL0_RG_ARDMSUS_10_B1, 0); + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].phy_ao.ca_lp_ctrl0, + CA_LP_CTRL0_RG_ARDMSUS_10_CA, 0); + dramc_set_broadcast(DRAMC_BROADCAST_ON); +} + +void resetb_pull_dn(void) +{ + SET32_BITFIELDS(&ch[0].phy_ao.ca_cmd11, + CA_CMD11_RG_RRESETB_DRVP, 1, + CA_CMD11_RG_RRESETB_DRVN, 1, + CA_CMD11_RG_TX_RRESETB_DDR3_SEL, 1, + CA_CMD11_RG_TX_RRESETB_PULL_DN, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_ctrl1, + MISC_CTRL1_R_DMRRESETB_I_OPT, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_ctrl1, + MISC_CTRL1_R_DMDA_RRESETB_E, 1); + SET32_BITFIELDS(&ch[0].phy_ao.ca_cmd11, + CA_CMD11_RG_TX_RRESETB_PULL_DN, 0); +} + +static void spm_control(ana_top_config *a_cfg) +{ + u8 new_8x_mode = a_cfg->new_8x_mode; + + SET32_BITFIELDS(&ch[0].phy_ao.misc_lp_ctrl, + MISC_LP_CTRL_RG_ARDMSUS_10_LP_SEL, 1, + MISC_LP_CTRL_RG_RIMP_DMSUS_10_LP_SEL, 1, + MISC_LP_CTRL_RG_RRESETB_LP_SEL, 1, + MISC_LP_CTRL_RG_RPHYPLL_RESETB_LP_SEL, 1, + MISC_LP_CTRL_RG_RPHYPLL_EN_LP_SEL, 1, + MISC_LP_CTRL_RG_RCLRPLL_EN_LP_SEL, 1, + MISC_LP_CTRL_RG_RPHYPLL_ADA_MCK8X_EN_LP_SEL, 1, + MISC_LP_CTRL_RG_RPHYPLL_AD_MCK8X_EN_LP_SEL, 1, + MISC_LP_CTRL_RG_RPHYPLL_TOP_REV_0_LP_SEL, 1, + MISC_LP_CTRL_RG_SC_ARPI_RESETB_8X_SEQ_LP_SEL, new_8x_mode, + MISC_LP_CTRL_RG_ADA_MCK8X_8X_SEQ_LP_SEL, new_8x_mode, + MISC_LP_CTRL_RG_AD_MCK8X_8X_SEQ_LP_SEL, new_8x_mode, + MISC_LP_CTRL_RG_MIDPI_EN_8X_SEQ_LP_SEL, new_8x_mode, + MISC_LP_CTRL_RG_MIDPI_CKDIV4_EN_8X_SEQ_LP_SEL, new_8x_mode, + MISC_LP_CTRL_RG_MCK8X_CG_SRC_LP_SEL, new_8x_mode, + MISC_LP_CTRL_RG_MCK8X_CG_SRC_AND_LP_SEL, new_8x_mode); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_lp_ctrl0, + B0_LP_CTRL0_RG_ARDMSUS_10_B0_LP_SEL, 1, + B0_LP_CTRL0_RG_ARDQ_RESETB_B0_LP_SEL, 1, + B0_LP_CTRL0_RG_ARPI_RESETB_B0_LP_SEL, 1, + B0_LP_CTRL0_RG_B0_MS_SLV_LP_SEL, 0, + B0_LP_CTRL0_RG_ARDLL_PHDET_EN_B0_LP_SEL, 1, + B0_LP_CTRL0_RG_RX_ARDQ_BIAS_EN_B0_LP_SEL, 0, + B0_LP_CTRL0_DA_ARPI_CG_MCK_B0_LP_SEL, 1, + B0_LP_CTRL0_DA_ARPI_CG_MCK_FB2DLL_B0_LP_SEL, 1, + B0_LP_CTRL0_DA_ARPI_CG_MCTL_B0_LP_SEL, 1, + B0_LP_CTRL0_DA_ARPI_CG_FB_B0_LP_SEL, 1, + B0_LP_CTRL0_DA_ARPI_CG_DQ_B0_LP_SEL, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_lp_ctrl0, + B0_LP_CTRL0_DA_ARPI_CG_DQM_B0_LP_SEL, 1, + B0_LP_CTRL0_DA_ARPI_CG_DQS_B0_LP_SEL, 1, + B0_LP_CTRL0_DA_ARPI_CG_DQSIEN_B0_LP_SEL, 1, + B0_LP_CTRL0_DA_ARPI_MPDIV_CG_B0_LP_SEL, 1, + B0_LP_CTRL0_RG_RX_ARDQ_VREF_EN_B0_LP_SEL, 1, + B0_LP_CTRL0_DA_ARPI_MIDPI_EN_B0_LP_SEL, 1, + B0_LP_CTRL0_DA_ARPI_MIDPI_CKDIV4_EN_B0_LP_SEL, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_lp_ctrl0, + B1_LP_CTRL0_RG_ARDMSUS_10_B1_LP_SEL, 1, + B1_LP_CTRL0_RG_ARDQ_RESETB_B1_LP_SEL, 1, + B1_LP_CTRL0_RG_ARPI_RESETB_B1_LP_SEL, 1, + B1_LP_CTRL0_RG_B1_MS_SLV_LP_SEL, 0, + B1_LP_CTRL0_RG_ARDLL_PHDET_EN_B1_LP_SEL, 1, + B1_LP_CTRL0_RG_RX_ARDQ_BIAS_EN_B1_LP_SEL, 0, + B1_LP_CTRL0_DA_ARPI_CG_MCK_B1_LP_SEL, 1, + B1_LP_CTRL0_DA_ARPI_CG_MCK_FB2DLL_B1_LP_SEL, 1, + B1_LP_CTRL0_DA_ARPI_CG_MCTL_B1_LP_SEL, 1, + B1_LP_CTRL0_DA_ARPI_CG_FB_B1_LP_SEL, 1, + B1_LP_CTRL0_DA_ARPI_CG_DQ_B1_LP_SEL, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_lp_ctrl0, + B1_LP_CTRL0_DA_ARPI_CG_DQM_B1_LP_SEL, 1, + B1_LP_CTRL0_DA_ARPI_CG_DQS_B1_LP_SEL, 1, + B1_LP_CTRL0_DA_ARPI_CG_DQSIEN_B1_LP_SEL, 1, + B1_LP_CTRL0_DA_ARPI_MPDIV_CG_B1_LP_SEL, 1, + B1_LP_CTRL0_RG_RX_ARDQ_VREF_EN_B1_LP_SEL, 1, + B1_LP_CTRL0_DA_ARPI_MIDPI_EN_B1_LP_SEL, 1, + B1_LP_CTRL0_DA_ARPI_MIDPI_CKDIV4_EN_B1_LP_SEL, 1); + + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.ca_lp_ctrl0, + CA_LP_CTRL0_RG_ARDMSUS_10_CA_LP_SEL, 1, + CA_LP_CTRL0_RG_ARCMD_RESETB_LP_SEL, 1, + CA_LP_CTRL0_RG_ARPI_RESETB_CA_LP_SEL, 1, + CA_LP_CTRL0_RG_ARDLL_PHDET_EN_CA_LP_SEL, 1, + CA_LP_CTRL0_RG_TX_ARCS_PULL_UP_LP_SEL, 1, + CA_LP_CTRL0_RG_TX_ARCS_PULL_DN_LP_SEL, 1, + CA_LP_CTRL0_RG_TX_ARCA_PULL_UP_LP_SEL, 1, + CA_LP_CTRL0_RG_TX_ARCA_PULL_DN_LP_SEL, 1, + CA_LP_CTRL0_DA_ARPI_CG_MCK_CA_LP_SEL, 1, + CA_LP_CTRL0_DA_ARPI_CG_MCK_FB2DLL_CA_LP_SEL, 1, + CA_LP_CTRL0_DA_ARPI_CG_MCTL_CA_LP_SEL, 1, + CA_LP_CTRL0_DA_ARPI_CG_FB_CA_LP_SEL, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.ca_lp_ctrl0, + CA_LP_CTRL0_DA_ARPI_CG_CS_LP_SEL, 1, + CA_LP_CTRL0_DA_ARPI_CG_CLK_LP_SEL, 1, + CA_LP_CTRL0_DA_ARPI_CG_CMD_LP_SEL, 1, + CA_LP_CTRL0_DA_ARPI_CG_CLKIEN_LP_SEL, 1, + CA_LP_CTRL0_DA_ARPI_MPDIV_CG_CA_LP_SEL, 1, + CA_LP_CTRL0_RG_RX_ARCMD_VREF_EN_LP_SEL, 1, + CA_LP_CTRL0_DA_ARPI_MIDPI_EN_CA_LP_SEL, 1, + CA_LP_CTRL0_DA_ARPI_MIDPI_CKDIV4_EN_CA_LP_SEL, 1, + CA_LP_CTRL0_RG_RX_ARCMD_BIAS_EN_LP_SEL, 0); + } + + if (a_cfg->dll_async_en == 1) { + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].phy_ao.ca_lp_ctrl0, + CA_LP_CTRL0_RG_CA_MS_SLV_LP_SEL, a_cfg->all_slave_en==0); + } else { + SET32_BITFIELDS(&ch[0].phy_ao.ca_lp_ctrl0, + CA_LP_CTRL0_RG_CA_MS_SLV_LP_SEL, a_cfg->all_slave_en==0); + SET32_BITFIELDS(&ch[1].phy_ao.ca_lp_ctrl0, + CA_LP_CTRL0_RG_CA_MS_SLV_LP_SEL, 0); + } + dramc_set_broadcast(DRAMC_BROADCAST_ON); + + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl9, + MISC_CG_CTRL9_RG_M_CK_OPENLOOP_MODE_EN, 1, + MISC_CG_CTRL9_RG_MCK4X_I_OPENLOOP_MODE_EN, 1, + MISC_CG_CTRL9_RG_CG_DDR400_MCK4X_I_OFF, 1, + MISC_CG_CTRL9_RG_DDR400_MCK4X_I_FORCE_ON, 0, + MISC_CG_CTRL9_RG_MCK4X_I_FB_CK_CG_OFF, 1, + MISC_CG_CTRL9_RG_MCK4X_Q_OPENLOOP_MODE_EN, 1, + MISC_CG_CTRL9_RG_CG_DDR400_MCK4X_Q_OFF, 1, + MISC_CG_CTRL9_RG_DDR400_MCK4X_Q_FORCE_ON, 0, + MISC_CG_CTRL9_RG_MCK4X_Q_FB_CK_CG_OFF, 1); +} + +static void ana_tx_nonshuffle_config(ana_top_config *a_cfg) +{ + SET32_BITFIELDS(&ch[0].phy_ao.ca_cmd6, + CA_CMD6_RG_TX_ARCMD_DDR3_SEL, 0, + CA_CMD6_RG_TX_ARCMD_DDR4_SEL, 0, + CA_CMD6_RG_TX_ARCMD_LP4_SEL, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq6, + B0_DQ6_RG_TX_ARDQ_DDR3_SEL_B0, 0, + B0_DQ6_RG_TX_ARDQ_DDR4_SEL_B0, !(a_cfg->aphy_comb_en), + B0_DQ6_RG_TX_ARDQ_LP4_SEL_B0, a_cfg->aphy_comb_en); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq6, + B1_DQ6_RG_TX_ARDQ_DDR3_SEL_B1, 0, + B1_DQ6_RG_TX_ARDQ_DDR4_SEL_B1, !(a_cfg->aphy_comb_en), + B1_DQ6_RG_TX_ARDQ_LP4_SEL_B1, a_cfg->aphy_comb_en); + dramc_dbg("[CONFIGURE PHASE]: ANA_TX\n"); + SET32_BITFIELDS(&ch[0].phy_ao.ca_cmd2, + CA_CMD2_RG_TX_ARCMD_OE_DIS_CA, 1, + CA_CMD2_RG_TX_ARCMD_ODTEN_DIS_CA, 0, + CA_CMD2_RG_TX_ARCLK_OE_DIS_CA, 0, + CA_CMD2_RG_TX_ARCLK_ODTEN_DIS_CA, 0, + CA_CMD2_RG_TX_ARCS_OE_TIE_SEL_CA, 1, + CA_CMD2_RG_TX_ARCS_OE_TIE_EN_CA, 1, + CA_CMD2_RG_TX_ARCA_OE_TIE_SEL_CA, 0, + CA_CMD2_RG_TX_ARCA_OE_TIE_EN_CA, 0xff); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq2, + B0_DQ2_RG_TX_ARDQ_OE_DIS_B0, 0, + B0_DQ2_RG_TX_ARDQ_ODTEN_DIS_B0, 0, + B0_DQ2_RG_TX_ARDQM0_OE_DIS_B0, 0, + B0_DQ2_RG_TX_ARDQM0_ODTEN_DIS_B0, 0, + B0_DQ2_RG_TX_ARDQS0_OE_DIS_B0, 0, + B0_DQ2_RG_TX_ARDQS0_ODTEN_DIS_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq2, + B1_DQ2_RG_TX_ARDQ_OE_DIS_B1, 0, + B1_DQ2_RG_TX_ARDQ_ODTEN_DIS_B1, 0, + B1_DQ2_RG_TX_ARDQM0_OE_DIS_B1, 0, + B1_DQ2_RG_TX_ARDQM0_ODTEN_DIS_B1, 0, + B1_DQ2_RG_TX_ARDQS0_OE_DIS_B1, 0, + B1_DQ2_RG_TX_ARDQS0_ODTEN_DIS_B1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.ca_cmd3, + CA_CMD3_RG_TX_ARCMD_EN, 1, + CA_CMD3_RG_ARCMD_RESETB, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq3, + B0_DQ3_RG_ARDQ_RESETB_B0, 1, + B0_DQ3_RG_TX_ARDQ_EN_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq3, + B1_DQ3_RG_ARDQ_RESETB_B1, 1, + B1_DQ3_RG_TX_ARDQ_EN_B1, 1); +} + +static void ana_rx_nonshuffle_config(void) +{ + SET32_BITFIELDS(&ch[0].phy_ao.ca_cmd6, + CA_CMD6_RG_RX_ARCMD_DDR3_SEL, 0, + CA_CMD6_RG_RX_ARCMD_DDR4_SEL, 0, + CA_CMD6_RG_RX_ARCMD_BIAS_VREF_SEL, 0, + CA_CMD6_RG_RX_ARCMD_RES_BIAS_EN, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq5, + B0_DQ5_RG_RX_ARDQ_VREF_EN_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq6, + B0_DQ6_RG_RX_ARDQ_DDR3_SEL_B0, 0, + B0_DQ6_RG_RX_ARDQ_DDR4_SEL_B0, 1, + B0_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B0, 0, + B0_DQ6_RG_RX_ARDQ_BIAS_EN_B0, 1, + B0_DQ6_RG_RX_ARDQ_OP_BIAS_SW_EN_B0, 0, + B0_DQ6_RG_RX_ARDQ_RES_BIAS_EN_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq3, + B0_DQ3_RG_RX_ARDQ_STBENCMP_EN_B0, 1, + B0_DQ3_RG_RX_ARDQ_SMT_EN_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq5, + B1_DQ5_RG_RX_ARDQ_VREF_EN_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq6, + B1_DQ6_RG_RX_ARDQ_DDR3_SEL_B1, 0, + B1_DQ6_RG_RX_ARDQ_DDR4_SEL_B1, 1, + B1_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B1, 0, + B1_DQ6_RG_RX_ARDQ_BIAS_EN_B1, 1, + B1_DQ6_RG_RX_ARDQ_OP_BIAS_SW_EN_B1, 0, + B1_DQ6_RG_RX_ARDQ_RES_BIAS_EN_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq3, + B1_DQ3_RG_RX_ARDQ_STBENCMP_EN_B1, 1, + B1_DQ3_RG_RX_ARDQ_SMT_EN_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.ca_cmd9, + CA_CMD9_RG_RX_ARCMD_STBEN_RESETB, 1, + CA_CMD9_RG_RX_ARCLK_STBEN_RESETB, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq9, + B0_DQ9_RG_RX_ARDQ_STBEN_RESETB_B0, 1, + B0_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq9, + B1_DQ9_RG_RX_ARDQ_STBEN_RESETB_B1, 1, + B1_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.ca_cmd8, + CA_CMD8_RG_RX_ARCLK_SER_RST_MODE, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq8, + B0_DQ8_RG_RX_ARDQS_SER_RST_MODE_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq8, + B1_DQ8_RG_RX_ARDQS_SER_RST_MODE_B1, 1); +} + +static void dig_dcm_nonshuffle_config(void) +{ + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rx_cg_ctrl, + MISC_SHU_RX_CG_CTRL_RX_DCM_EXT_DLY, 3); +} + +static void ana_imp_configure(void) +{ + SET32_BITFIELDS(&ch[0].phy_ao.misc_imp_ctrl1, + MISC_IMP_CTRL1_RG_RIMP_DDR3_SEL, 0); + SET32_BITFIELDS(&ch[0].phy_ao.misc_imp_ctrl1, + MISC_IMP_CTRL1_RG_RIMP_DDR4_SEL, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_imp_ctrl1, + MISC_IMP_CTRL1_RG_RIMP_BIAS_EN, 0, + MISC_IMP_CTRL1_RG_RIMP_ODT_EN, 0, + MISC_IMP_CTRL1_RG_RIMP_PRE_EN, 0, + MISC_IMP_CTRL1_RG_RIMP_VREF_EN, 0); +} + +static void ana_dll_non_shuffle_config(dram_freq_grp freq_group, + ana_top_config *a_cfg) +{ + u8 pd_zone = (freq_group >= DDRFREQ_2133) ? 0x2 : 0x3; + + if (a_cfg->dll_idle_mode == 1) { + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + if (a_cfg->dll_async_en == 1) { + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.ca_dll_arpi5, + CA_DLL_ARPI5_RG_ARDLL_IDLE_EN_CA, 0, + CA_DLL_ARPI5_RG_ARDLL_PD_ZONE_CA, pd_zone); + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[0].b0_dll_arpi5, + B0_DLL_ARPI5_RG_ARDLL_IDLE_EN_B0, 1, + B0_DLL_ARPI5_RG_ARDLL_PD_ZONE_B0, pd_zone); + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[1].b0_dll_arpi5, + B1_DLL_ARPI5_RG_ARDLL_IDLE_EN_B1, 1, + B1_DLL_ARPI5_RG_ARDLL_PD_ZONE_B1, pd_zone); + } + } else { + SET32_BITFIELDS(&ch[0].phy_ao.ca_dll_arpi5, + CA_DLL_ARPI5_RG_ARDLL_IDLE_EN_CA, 0, + CA_DLL_ARPI5_RG_ARDLL_PD_ZONE_CA, pd_zone); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dll_arpi5, + B0_DLL_ARPI5_RG_ARDLL_IDLE_EN_B0, 1, + B0_DLL_ARPI5_RG_ARDLL_PD_ZONE_B0, pd_zone); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dll_arpi5, + B1_DLL_ARPI5_RG_ARDLL_IDLE_EN_B1, 1, + B1_DLL_ARPI5_RG_ARDLL_PD_ZONE_B1, pd_zone); + SET32_BITFIELDS(&ch[1].phy_ao.ca_dll_arpi5, + CA_DLL_ARPI5_RG_ARDLL_IDLE_EN_CA, 1, + CA_DLL_ARPI5_RG_ARDLL_PD_ZONE_CA, pd_zone); + SET32_BITFIELDS(&ch[1].phy_ao.dvs_b[0].b0_dll_arpi5, + B0_DLL_ARPI5_RG_ARDLL_IDLE_EN_B0, 1, + B0_DLL_ARPI5_RG_ARDLL_PD_ZONE_B0, pd_zone); + SET32_BITFIELDS(&ch[1].phy_ao.dvs_b[1].b0_dll_arpi5, + B1_DLL_ARPI5_RG_ARDLL_IDLE_EN_B1, 1, + B1_DLL_ARPI5_RG_ARDLL_PD_ZONE_B1, pd_zone); + } + dramc_set_broadcast(DRAMC_BROADCAST_ON); + } + + SET32_BITFIELDS(&ch[0].phy_ao.ca_dll_arpi1, + CA_DLL_ARPI1_RG_ARPI_CLKIEN_JUMP_EN, 0, + CA_DLL_ARPI1_RG_ARPI_CMD_JUMP_EN, 0, + CA_DLL_ARPI1_RG_ARPI_CLK_JUMP_EN, 0, + CA_DLL_ARPI1_RG_ARPI_CS_JUMP_EN, 0, + CA_DLL_ARPI1_RG_ARPI_FB_JUMP_EN_CA, 0, + CA_DLL_ARPI1_RG_ARPI_MCTL_JUMP_EN_CA, 0, + CA_DLL_ARPI1_RG_ARPISM_MCK_SEL_CA, 1, + CA_DLL_ARPI1_RG_ARPISM_MCK_SEL_CA_REG_OPT, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dll_arpi1, + B0_DLL_ARPI1_RG_ARPI_DQSIEN_JUMP_EN_B0, 0, + B0_DLL_ARPI1_RG_ARPI_DQ_JUMP_EN_B0, 0, + B0_DLL_ARPI1_RG_ARPI_DQM_JUMP_EN_B0, 0, + B0_DLL_ARPI1_RG_ARPI_DQS_JUMP_EN_B0, 0, + B0_DLL_ARPI1_RG_ARPI_FB_JUMP_EN_B0, 0, + B0_DLL_ARPI1_RG_ARPI_MCTL_JUMP_EN_B0, 0, + B0_DLL_ARPI1_RG_ARPISM_MCK_SEL_B0, 0, + B0_DLL_ARPI1_RG_ARPISM_MCK_SEL_B0_REG_OPT, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dll_arpi1, + B1_DLL_ARPI1_RG_ARPI_DQSIEN_JUMP_EN_B1, 0, + B1_DLL_ARPI1_RG_ARPI_DQ_JUMP_EN_B1, 0, + B1_DLL_ARPI1_RG_ARPI_DQM_JUMP_EN_B1, 0, + B1_DLL_ARPI1_RG_ARPI_DQS_JUMP_EN_B1, 0, + B1_DLL_ARPI1_RG_ARPI_FB_JUMP_EN_B1, 0, + B1_DLL_ARPI1_RG_ARPI_MCTL_JUMP_EN_B1, 0, + B1_DLL_ARPI1_RG_ARPISM_MCK_SEL_B1, 0, + B1_DLL_ARPI1_RG_ARPISM_MCK_SEL_B1_REG_OPT, 0); + + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.ca_dll_arpi5, + CA_DLL_ARPI5_RG_ARDLL_FJ_OUT_MODE_CA, 0, + CA_DLL_ARPI5_RG_ARDLL_FJ_OUT_MODE_SEL_CA, 0, + CA_DLL_ARPI5_RG_ARDLL_DIV_DEC_CA, 0, + CA_DLL_ARPI5_RG_ARDLL_MON_SEL_CA, 0); + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[0].b0_dll_arpi5, + B0_DLL_ARPI5_RG_ARDLL_FJ_OUT_MODE_B0, 0, + B0_DLL_ARPI5_RG_ARDLL_FJ_OUT_MODE_SEL_B0, 0, + B0_DLL_ARPI5_RG_ARDLL_DIV_DEC_B0, 0, + B0_DLL_ARPI5_RG_ARDLL_MON_SEL_B0, 0); + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[1].b0_dll_arpi5, + B1_DLL_ARPI5_RG_ARDLL_FJ_OUT_MODE_B1, 0, + B1_DLL_ARPI5_RG_ARDLL_FJ_OUT_MODE_SEL_B1, 0, + B1_DLL_ARPI5_RG_ARDLL_DIV_DEC_B1, 0, + B1_DLL_ARPI5_RG_ARDLL_MON_SEL_B1, 0); + } + dramc_set_broadcast(DRAMC_BROADCAST_ON); +} + +static void ana_pll_shuffle_Config(ana_dvfs_core *dvfs_core) +{ + u8 prediv = 1; + u8 posdiv = 0; + u8 fbk_sel = 0; + u8 div16_ck_sel = 0; + u32 pcw; + u32 pll_freq = dvfs_core->pll_freq; + u32 xtal_freq = 26; + + if (dvfs_core->dq_ca_open == 1) + div16_ck_sel = 1; + else + fbk_sel = (pll_freq > 3800) ? 1 : 0; + + pcw = (pll_freq/xtal_freq) << (8 + 1 -fbk_sel-prediv - posdiv); + dramc_dbg("pll_freq:%d, fbk_sel:%d, pcw = %#x\n", pll_freq, fbk_sel, pcw); + + SET32_BITFIELDS(&ch[0].phy_ao.phypll1, + PHYPLL1_RG_RPHYPLL_TST_EN, 0, + PHYPLL1_RG_RPHYPLL_TSTOP_EN, 0); + SET32_BITFIELDS(&ch[0].phy_ao.shu_phypll0, + SHU_PHYPLL0_RG_RPHYPLL_RESERVED, 0, + SHU_PHYPLL0_RG_RPHYPLL_ICHP, 0); + SET32_BITFIELDS(&ch[0].phy_ao.shu_clrpll0, + SHU_CLRPLL0_RG_RCLRPLL_RESERVED, 0, + SHU_CLRPLL0_RG_RCLRPLL_ICHP, 0); + SET32_BITFIELDS(&ch[0].phy_ao.shu_phypll2, + SHU_PHYPLL2_RG_RPHYPLL_PREDIV, prediv, + SHU_PHYPLL2_RG_RPHYPLL_POSDIV, posdiv); + SET32_BITFIELDS(&ch[0].phy_ao.shu_clrpll2, + SHU_CLRPLL2_RG_RCLRPLL_PREDIV, prediv, + SHU_CLRPLL2_RG_RCLRPLL_POSDIV, posdiv); + SET32_BITFIELDS(&ch[0].phy_ao.shu_phypll1, + SHU_PHYPLL1_RG_RPHYPLL_SDM_PCW, pcw, + SHU_PHYPLL1_RG_RPHYPLL_SDM_PCW_CHG, 1, + SHU_PHYPLL1_RG_RPHYPLL_SDM_FRA_EN, 0); + SET32_BITFIELDS(&ch[0].phy_ao.shu_clrpll1, + SHU_CLRPLL1_RG_RCLRPLL_SDM_PCW, pcw, + SHU_CLRPLL1_RG_RCLRPLL_SDM_PCW_CHG, 1, + SHU_CLRPLL1_RG_RCLRPLL_SDM_FRA_EN, 0); + SET32_BITFIELDS(&ch[0].phy_ao.shu_pll1, + SHU_PLL1_RG_RPHYPLLGP_CK_SEL, 1, + SHU_PLL1_R_SHU_AUTO_PLL_MUX, 1); + SET32_BITFIELDS(&ch[0].phy_ao.shu_phypll3, + SHU_PHYPLL3_RG_RPHYPLL_LVROD_EN, 0, + SHU_PHYPLL3_RG_RPHYPLL_RST_DLY, 1, + SHU_PHYPLL3_RG_RPHYPLL_FBKSEL, fbk_sel); + SET32_BITFIELDS(&ch[0].phy_ao.shu_clrpll3, + SHU_CLRPLL3_RG_RCLRPLL_LVROD_EN, 0, + SHU_CLRPLL3_RG_RCLRPLL_RST_DLY, 1, + SHU_CLRPLL3_RG_RCLRPLL_FBKSEL, fbk_sel); + if (dvfs_core->dq_ca_open == 1) { + SET32_BITFIELDS(&ch[0].phy_ao.shu_misc_clk_ctrl0, + SHU_MISC_CLK_CTRL0_M_CK_OPENLOOP_MODE_SEL, + dvfs_core->dq_ca_open); + SET32_BITFIELDS(&ch[0].phy_ao.shu_phypll3, + SHU_PHYPLL3_RG_RPHYPLL_MONCK_EN, 1, + SHU_PHYPLL3_RG_RPHYPLL_DIV_CK_SEL, div16_ck_sel); + SET32_BITFIELDS(&ch[0].phy_ao.shu_clrpll3, + SHU_CLRPLL3_RG_RCLRPLL_MONCK_EN, 1, + SHU_CLRPLL3_RG_RCLRPLL_DIV_CK_SEL, div16_ck_sel); + } + dramc_dbg("PLL\n"); +} + +static void ana_arpi_shuffle_config(ana_top_config *a_cfg, ana_dvfs_core *tr) +{ + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_dll_arpi3, + SHU_CA_DLL_ARPI3_RG_ARPI_CLKIEN_EN, 0, + SHU_CA_DLL_ARPI3_RG_ARPI_CMD_EN, !(tr->dq_semi_open), + SHU_CA_DLL_ARPI3_RG_ARPI_CS_EN, !(tr->dq_semi_open)); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dll_arpi3, + SHU_B0_DLL_ARPI3_RG_ARPI_DQSIEN_EN_B0, !(tr->dq_semi_open), + SHU_B0_DLL_ARPI3_RG_ARPI_DQ_EN_B0, !(tr->dq_semi_open), + SHU_B0_DLL_ARPI3_RG_ARPI_DQM_EN_B0, !(tr->dq_semi_open), + SHU_B0_DLL_ARPI3_RG_ARPI_DQS_EN_B0, !(tr->dq_semi_open), + SHU_B0_DLL_ARPI3_RG_ARPI_FB_EN_B0, !(tr->dq_semi_open)); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dll_arpi3, + SHU_B0_DLL_ARPI3_RG_ARPI_MCTL_EN_B0, + (!(tr->dq_semi_open)) && (a_cfg->rank_mode)); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dll_arpi3, + SHU_B1_DLL_ARPI3_RG_ARPI_DQSIEN_EN_B1, !(tr->dq_semi_open), + SHU_B1_DLL_ARPI3_RG_ARPI_DQ_EN_B1, !(tr->dq_semi_open), + SHU_B1_DLL_ARPI3_RG_ARPI_DQM_EN_B1, !(tr->dq_semi_open), + SHU_B1_DLL_ARPI3_RG_ARPI_DQS_EN_B1, !(tr->dq_semi_open), + SHU_B1_DLL_ARPI3_RG_ARPI_FB_EN_B1, !(tr->dq_semi_open)); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dll_arpi3, + SHU_B1_DLL_ARPI3_RG_ARPI_MCTL_EN_B1, + (!(tr->dq_semi_open)) && (a_cfg->rank_mode)); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd2, + SHU_CA_CMD2_RG_ARPISM_MCK_SEL_CA_SHU, 1, + SHU_CA_CMD2_RG_ARPI_TX_CG_SYNC_DIS_CA, 1, + SHU_CA_CMD2_RG_ARPI_TX_CG_CA_EN_CA, 1, + SHU_CA_CMD2_RG_ARPI_TX_CG_CLK_EN_CA, 1, + SHU_CA_CMD2_RG_ARPI_TX_CG_CS_EN_CA, 1, + SHU_CA_CMD2_RG_ARPI_PD_MCTL_SEL_CA, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq2, + SHU_B0_DQ2_RG_ARPISM_MCK_SEL_B0_SHU, 1, + SHU_B0_DQ2_RG_ARPI_TX_CG_SYNC_DIS_B0, 1, + SHU_B0_DQ2_RG_ARPI_TX_CG_DQ_EN_B0, 1, + SHU_B0_DQ2_RG_ARPI_TX_CG_DQS_EN_B0, 1, + SHU_B0_DQ2_RG_ARPI_TX_CG_DQM_EN_B0, 1, + SHU_B0_DQ2_RG_ARPI_PD_MCTL_SEL_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq2, + SHU_B1_DQ2_RG_ARPISM_MCK_SEL_B1_SHU, 1, + SHU_B1_DQ2_RG_ARPI_TX_CG_SYNC_DIS_B1, 1, + SHU_B1_DQ2_RG_ARPI_TX_CG_DQ_EN_B1, 1, + SHU_B1_DQ2_RG_ARPI_TX_CG_DQS_EN_B1, 1, + SHU_B1_DQ2_RG_ARPI_TX_CG_DQM_EN_B1, 1, + SHU_B1_DQ2_RG_ARPI_PD_MCTL_SEL_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq7, + SHU_B0_DQ7_R_DMTX_ARPI_CG_DQ_NEW_B0, 0, + SHU_B0_DQ7_R_DMTX_ARPI_CG_DQS_NEW_B0, 0, + SHU_B0_DQ7_R_DMTX_ARPI_CG_DQM_NEW_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq7, + SHU_B1_DQ7_R_DMTX_ARPI_CG_DQ_NEW_B1, 0, + SHU_B1_DQ7_R_DMTX_ARPI_CG_DQS_NEW_B1, 0, + SHU_B1_DQ7_R_DMTX_ARPI_CG_DQM_NEW_B1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd7, + SHU_CA_CMD7_R_DMTX_ARPI_CG_CS_NEW, 0, + SHU_CA_CMD7_R_DMTX_ARPI_CG_CMD_NEW, 0); +} + +static void ana_tx_shuffle_config(ana_top_config *a_cfg) +{ + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd14, + SHU_CA_CMD14_RG_TX_ARCA_OE_ODTEN_CG_EN_CA, 0); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd13, + SHU_CA_CMD13_RG_TX_ARCLK_OE_ODTEN_CG_EN_CA, 0, + SHU_CA_CMD13_RG_TX_ARCS_OE_ODTEN_CG_EN_CA, 0); + + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq13, + SHU_B0_DQ13_RG_TX_ARDQS_OE_ODTEN_CG_EN_B0, 1, + SHU_B0_DQ13_RG_TX_ARDQM_OE_ODTEN_CG_EN_B0, 1, + SHU_B0_DQ13_RG_TX_ARDQS_READ_BASE_EN_B0, 0, + SHU_B0_DQ13_RG_TX_ARDQSB_READ_BASE_EN_B0, 0, + SHU_B0_DQ13_RG_TX_ARDQS_READ_BASE_DATA_TIE_EN_B0, 0, + SHU_B0_DQ13_RG_TX_ARDQSB_READ_BASE_DATA_TIE_EN_B0, 0, + SHU_B0_DQ13_RG_TX_ARDQ_IO_ODT_DIS_B0, a_cfg->tx_odt_dis); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq13, + SHU_B1_DQ13_RG_TX_ARDQS_OE_ODTEN_CG_EN_B1, 1, + SHU_B1_DQ13_RG_TX_ARDQM_OE_ODTEN_CG_EN_B1, 1, + SHU_B1_DQ13_RG_TX_ARDQS_READ_BASE_EN_B1, 0, + SHU_B1_DQ13_RG_TX_ARDQSB_READ_BASE_EN_B1, 0, + SHU_B1_DQ13_RG_TX_ARDQS_READ_BASE_DATA_TIE_EN_B1, 0, + SHU_B1_DQ13_RG_TX_ARDQSB_READ_BASE_DATA_TIE_EN_B1, 0, + SHU_B1_DQ13_RG_TX_ARDQ_IO_ODT_DIS_B1, a_cfg->tx_odt_dis); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq14, + SHU_B0_DQ14_RG_TX_ARDQ_OE_ODTEN_CG_EN_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq14, + SHU_B1_DQ14_RG_TX_ARDQ_OE_ODTEN_CG_EN_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq13, + SHU_B0_DQ13_RG_TX_ARDQS_MCKIO_SEL_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq13, + SHU_B1_DQ13_RG_TX_ARDQS_MCKIO_SEL_B1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq14, + SHU_B0_DQ14_RG_TX_ARDQ_MCKIO_SEL_B0, 0, + SHU_B0_DQ14_RG_TX_ARWCK_MCKIO_SEL_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq14, + SHU_B1_DQ14_RG_TX_ARDQ_MCKIO_SEL_B1, 0, + SHU_B1_DQ14_RG_TX_ARWCK_MCKIO_SEL_B1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq13, + SHU_B0_DQ13_RG_TX_ARDQ_DLY_LAT_EN_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq13, + SHU_B1_DQ13_RG_TX_ARDQ_DLY_LAT_EN_B1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd13, + SHU_CA_CMD13_RG_TX_ARCA_DLY_LAT_EN_CA, 0); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd2, + SHU_CA_CMD2_RG_ARPI_OFFSET_LAT_EN_CA, 0, + SHU_CA_CMD2_RG_ARPI_OFFSET_ASYNC_EN_CA, 0); +} + +static void dig_phy_shu_misc_cg_ctrl(void) +{ + setbits32(&ch[0].phy_ao.misc_shu_cg_ctrl0, 0x33400000); +} + +static void ana_clk_div_config_setting(ana_dvfs_core *tr, ana_top_config *a_cfg) +{ + u8 tx_ardq_sermode=0; + u8 tx_arcr_sermode=0; + u8 ardll_sermode_b=0; + u8 ardll_sermode_c=0; + + dramc_dbg("ANA CLOCK DIV configuration\n"); + switch (tr->dq_p2s_ratio) { + case 4 : + tx_ardq_sermode = 1; + break; + case 8 : + tx_ardq_sermode = 2; + break; + case 16: + tx_ardq_sermode = 3; + break; + default: dramc_dbg("ERROR: tr->dq_p2s_ratio= %2d, Not support!!",tr->dq_p2s_ratio); + break; + } + + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq14, + SHU_B0_DQ14_RG_TX_ARDQ_SER_MODE_B0, tx_ardq_sermode); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq14, + SHU_B1_DQ14_RG_TX_ARDQ_SER_MODE_B1, tx_ardq_sermode); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq6, + SHU_B0_DQ6_RG_RX_ARDQ_RANK_SEL_SER_MODE_B0, tx_ardq_sermode); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq6, + SHU_B1_DQ6_RG_RX_ARDQ_RANK_SEL_SER_MODE_B1, tx_ardq_sermode); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd11, + SHU_CA_CMD11_RG_RX_ARCA_DES_MODE_CA, (tr->dq_p2s_ratio == 16 ) ? 3 : 2); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq11, + SHU_B0_DQ11_RG_RX_ARDQ_DES_MODE_B0, (tr->dq_p2s_ratio == 16 ) ? 3 : 2); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq11, + SHU_B1_DQ11_RG_RX_ARDQ_DES_MODE_B1, (tr->dq_p2s_ratio == 16 ) ? 3 : 2); + + switch (tr->ca_p2s_ratio) { + case 2 : + tx_arcr_sermode = (0 + tr->ca_full_rate); + break; + case 4 : + tx_arcr_sermode = (1 + tr->ca_full_rate); + break; + case 8: + tx_arcr_sermode = (2 + tr->ca_full_rate); + break; + default: dramc_dbg("ERROR: tr->ca_p2s_ratio= %2d, Not support!!",tr->ca_p2s_ratio); + break; + } + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd14, + SHU_CA_CMD14_RG_TX_ARCA_SER_MODE_CA, tx_arcr_sermode); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd6, + SHU_CA_CMD6_RG_RX_ARCMD_RANK_SEL_SER_MODE, tx_arcr_sermode); + + switch (tr->dq_aamck_div) { + case 2 : + ardll_sermode_b = 1; + break; + case 4 : + ardll_sermode_b = 2; + break; + case 8: + ardll_sermode_b = 3; + break; + default: dramc_dbg("WARN: tr->dq_aamck_div= %2d, Because of dq_semi_open, It's don't care.",tr->dq_aamck_div); + break; + } + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dll1, + SHU_B0_DLL1_RG_ARDLL_SER_MODE_B0, ardll_sermode_b); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dll1, + SHU_B1_DLL1_RG_ARDLL_SER_MODE_B1, ardll_sermode_b); + + switch (tr->ca_admck_div) { + case 2 : + ardll_sermode_c = 1; + break; + case 4 : + ardll_sermode_c = 2; + break; + case 8: + ardll_sermode_c = 3; + break; + default: dramc_dbg("ERROR: tr->ca_admck_div= %2d, Not support!!",tr->ca_admck_div); + break; + } + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_dll1, + SHU_CA_DLL1_RG_ARDLL_SER_MODE_CA, ardll_sermode_c); + + dramc_set_broadcast(DRAMC_BROADCAST_ON); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq6, + SHU_B0_DQ6_RG_ARPI_SOPEN_EN_B0, tr->dq_semi_open, + SHU_B0_DQ6_RG_ARPI_OPEN_EN_B0, tr->dq_ca_open); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq6, + SHU_B1_DQ6_RG_ARPI_SOPEN_EN_B1, tr->dq_semi_open, + SHU_B1_DQ6_RG_ARPI_OPEN_EN_B1, tr->dq_ca_open); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq1, + SHU_B0_DQ1_RG_ARPI_MIDPI_EN_B0, + !(tr->dq_semi_open) && (!(tr->dq_ckdiv4_en)), + SHU_B0_DQ1_RG_ARPI_MIDPI_CKDIV4_EN_B0, + !(tr->dq_semi_open) && (tr->dq_ckdiv4_en), + SHU_B0_DQ1_RG_ARPI_MIDPI_8PH_DLY_B0, tr->ph8_dly); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq1, + SHU_B1_DQ1_RG_ARPI_MIDPI_EN_B1, + !(tr->dq_semi_open) && (!(tr->dq_ckdiv4_en)), + SHU_B1_DQ1_RG_ARPI_MIDPI_CKDIV4_EN_B1, + !(tr->dq_semi_open) && (tr->dq_ckdiv4_en), + SHU_B1_DQ1_RG_ARPI_MIDPI_8PH_DLY_B1, tr->ph8_dly); + + if (tr->ca_semi_open == 0) { + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd6, + SHU_CA_CMD6_RG_ARPI_SOPEN_EN_CA, 0, + SHU_CA_CMD6_RG_ARPI_SOPEN_CKGEN_EN_CA, 0, + SHU_CA_CMD6_RG_ARPI_OFFSET_DQSIEN_CA, 0); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_dll_arpi3, + SHU_CA_DLL_ARPI3_RG_ARPI_FB_EN_CA, 1, + SHU_CA_DLL_ARPI3_RG_ARPI_CLK_EN, 1, + SHU_CA_DLL_ARPI3_RG_ARPI_MCTL_EN_CA, 1); + } else { + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_cmd6, + SHU_CA_CMD6_RG_ARPI_SOPEN_EN_CA, 1, + SHU_CA_CMD6_RG_ARPI_SOPEN_CKGEN_EN_CA, 1, + SHU_CA_CMD6_RG_ARPI_OFFSET_DQSIEN_CA, 16); + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_dll_arpi3, + SHU_CA_DLL_ARPI3_RG_ARPI_FB_EN_CA, 1, + SHU_CA_DLL_ARPI3_RG_ARPI_CLK_EN, 1); + } + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_dll_arpi3, + SHU_CA_DLL_ARPI3_RG_ARPI_MCTL_EN_CA, 1); + SET32_BITFIELDS(&ch[1].phy_ao.shu_ca_dll_arpi3, + SHU_CA_DLL_ARPI3_RG_ARPI_MCTL_EN_CA, 0); + dramc_set_broadcast(DRAMC_BROADCAST_ON); + } + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd6, + SHU_CA_CMD6_RG_ARPI_OPEN_EN_CA, tr->dq_ca_open); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd13, + SHU_CA_CMD13_RG_TX_ARCA_FRATE_EN_CA, tr->ca_full_rate); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd1, + SHU_CA_CMD1_RG_ARPI_MIDPI_8PH_DLY_CA, tr->ph8_dly); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd1, + SHU_CA_CMD1_RG_ARPI_MIDPI_CKDIV4_PREDIV_EN_CA, tr->ca_prediv_en); + + if (tr->semi_open_ca_pick_mck_ratio == 4) + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd6, + SHU_CA_CMD6_RG_ARPI_SOPEN_CKGEN_DIV_CA, 0); + else if (tr->semi_open_ca_pick_mck_ratio == 8) + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd6, + SHU_CA_CMD6_RG_ARPI_SOPEN_CKGEN_DIV_CA, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dll1, + SHU_B0_DLL1_RG_ARDLL_TRACKING_CA_EN_B0, tr->dq_track_ca_en); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dll1, + SHU_B1_DLL1_RG_ARDLL_TRACKING_CA_EN_B1, tr->dq_track_ca_en); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_dll_arpi2, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_CLKIEN, 1); +} + +static void ana_dll_shuffle_config(dram_freq_grp freq_group, ana_top_config *a_cfg) +{ + u8 gain = 0; + if (freq_group <= DDRFREQ_1600) { + gain = 2; + dramc_dbg("Add DLL Gain = %d\n",gain); + } + + dramc_dbg("DLL\n"); + if (a_cfg->dll_async_en == 1) { + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_dll0, + SHU_CA_DLL0_RG_ARDLL_GAIN_CA, + (a_cfg->all_slave_en == 0) ? 6 : 7, + SHU_CA_DLL0_RG_ARDLL_IDLECNT_CA, + (a_cfg->all_slave_en == 0) ? 9 : 7, + SHU_CA_DLL0_RG_ARDLL_FAST_PSJP_CA, + !(a_cfg->all_slave_en), + SHU_CA_DLL0_RG_ARDLL_GEAR2_PSJP_CA, 0, + SHU_CA_DLL0_RG_ARDLL_FASTPJ_CK_SEL_CA, + a_cfg->all_slave_en); + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_dll1, + SHU_CA_DLL1_RG_ARDLL_PHDET_OUT_SEL_CA, + a_cfg->all_slave_en, + SHU_CA_DLL1_RG_ARDLL_PHDET_IN_SWAP_CA, + a_cfg->all_slave_en, + SHU_CA_DLL1_RG_ARDLL_PGAIN_CA, 0, + SHU_CA_DLL1_RG_ARDLL_PSJP_EN_CA, 1, + SHU_CA_DLL1_RG_ARDLL_PHDIV_CA, 1, + SHU_CA_DLL1_RG_ARDLL_UDIV_EN_CA, 1, + SHU_CA_DLL1_RG_ARDLL_PS_EN_CA, 1, + SHU_CA_DLL1_RG_ARDLL_PD_CK_SEL_CA, + !(a_cfg->all_slave_en)); + } + dramc_set_broadcast(DRAMC_BROADCAST_ON); + } else { + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_dll0, + SHU_CA_DLL0_RG_ARDLL_GAIN_CA, + (a_cfg->all_slave_en == 0) ? 6 + gain : 7 + gain, + SHU_CA_DLL0_RG_ARDLL_IDLECNT_CA, + (a_cfg->all_slave_en == 0) ? 9 : 7, + SHU_CA_DLL0_RG_ARDLL_FAST_PSJP_CA, + !(a_cfg->all_slave_en), + SHU_CA_DLL0_RG_ARDLL_GEAR2_PSJP_CA, 0, + SHU_CA_DLL0_RG_ARDLL_FASTPJ_CK_SEL_CA, + a_cfg->all_slave_en); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_dll1, + SHU_CA_DLL1_RG_ARDLL_PHDET_OUT_SEL_CA, + a_cfg->all_slave_en, + SHU_CA_DLL1_RG_ARDLL_PHDET_IN_SWAP_CA, + a_cfg->all_slave_en, + SHU_CA_DLL1_RG_ARDLL_PGAIN_CA, 0, + SHU_CA_DLL1_RG_ARDLL_PSJP_EN_CA, 1, + SHU_CA_DLL1_RG_ARDLL_PHDIV_CA, 1, + SHU_CA_DLL1_RG_ARDLL_UDIV_EN_CA, 1, + SHU_CA_DLL1_RG_ARDLL_PS_EN_CA, 1, + SHU_CA_DLL1_RG_ARDLL_PD_CK_SEL_CA, + !(a_cfg->all_slave_en)); + SET32_BITFIELDS(&ch[1].phy_ao.shu_ca_dll0, + SHU_CA_DLL0_RG_ARDLL_GAIN_CA, 7+gain, + SHU_CA_DLL0_RG_ARDLL_IDLECNT_CA, 7, + SHU_CA_DLL0_RG_ARDLL_FAST_PSJP_CA, 0, + SHU_CA_DLL0_RG_ARDLL_GEAR2_PSJP_CA, 0, + SHU_CA_DLL0_RG_ARDLL_FASTPJ_CK_SEL_CA, 1); + SET32_BITFIELDS(&ch[1].phy_ao.shu_ca_dll1, + SHU_CA_DLL1_RG_ARDLL_PHDET_OUT_SEL_CA, 1, + SHU_CA_DLL1_RG_ARDLL_PHDET_IN_SWAP_CA, 1, + SHU_CA_DLL1_RG_ARDLL_PGAIN_CA, 0, + SHU_CA_DLL1_RG_ARDLL_PSJP_EN_CA, 1, + SHU_CA_DLL1_RG_ARDLL_PHDIV_CA, 1, + SHU_CA_DLL1_RG_ARDLL_UDIV_EN_CA, 1, + SHU_CA_DLL1_RG_ARDLL_PS_EN_CA, 1, + SHU_CA_DLL1_RG_ARDLL_PD_CK_SEL_CA, 0); + dramc_set_broadcast(DRAMC_BROADCAST_ON); + } + + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dll0, + SHU_B0_DLL0_RG_ARDLL_GAIN_B0, 7+gain, + SHU_B0_DLL0_RG_ARDLL_IDLECNT_B0, 7, + SHU_B0_DLL0_RG_ARDLL_FAST_PSJP_B0, 0, + SHU_B0_DLL0_RG_ARDLL_GEAR2_PSJP_B0, 0, + SHU_B0_DLL0_RG_ARDLL_FASTPJ_CK_SEL_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dll1, + SHU_B0_DLL1_RG_ARDLL_PHDET_OUT_SEL_B0, 1, + SHU_B0_DLL1_RG_ARDLL_PHDET_IN_SWAP_B0, 1, + SHU_B0_DLL1_RG_ARDLL_PGAIN_B0, 0, + SHU_B0_DLL1_RG_ARDLL_PSJP_EN_B0, 1, + SHU_B0_DLL1_RG_ARDLL_PHDIV_B0, 1, + SHU_B0_DLL1_RG_ARDLL_UDIV_EN_B0, 1, + SHU_B0_DLL1_RG_ARDLL_PS_EN_B0, 1, + SHU_B0_DLL1_RG_ARDLL_PD_CK_SEL_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dll0, + SHU_B1_DLL0_RG_ARDLL_GAIN_B1, 7+gain, + SHU_B1_DLL0_RG_ARDLL_IDLECNT_B1, 7, + SHU_B1_DLL0_RG_ARDLL_FAST_PSJP_B1, 0, + SHU_B1_DLL0_RG_ARDLL_GEAR2_PSJP_B1, 0, + SHU_B1_DLL0_RG_ARDLL_FASTPJ_CK_SEL_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dll1, + SHU_B1_DLL1_RG_ARDLL_PHDET_OUT_SEL_B1, 1, + SHU_B1_DLL1_RG_ARDLL_PHDET_IN_SWAP_B1, 1, + SHU_B1_DLL1_RG_ARDLL_PGAIN_B1, 0, + SHU_B1_DLL1_RG_ARDLL_PSJP_EN_B1, 1, + SHU_B1_DLL1_RG_ARDLL_PHDIV_B1, 1, + SHU_B1_DLL1_RG_ARDLL_UDIV_EN_B1, 1, + SHU_B1_DLL1_RG_ARDLL_PS_EN_B1, 1, + SHU_B1_DLL1_RG_ARDLL_PD_CK_SEL_B1, 0); +} + +static void ana_rx_shuffle_config(dramc_subsys_config *subsys) +{ + u8 rdqs_se_en; + u8 dqsien_mode; + u8 rank_mode; + + rdqs_se_en = 0; + dqsien_mode = subsys->dfs_gp->dqsien_mode; + rank_mode = subsys->a_cfg->rank_mode; + + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq10, + SHU_B0_DQ10_RG_RX_ARDQS_SE_EN_B0, rdqs_se_en, + SHU_B0_DQ10_RG_RX_ARDQS_DQSIEN_MODE_B0, dqsien_mode, + SHU_B0_DQ10_RG_RX_ARDQS_DLY_LAT_EN_B0, 1, + SHU_B0_DQ10_RG_RX_ARDQS_RANK_SEL_LAT_EN_B0, rank_mode, + SHU_B0_DQ10_RG_RX_ARDQS_DQSIEN_RANK_SEL_LAT_EN_B0, rank_mode); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq11, + SHU_B0_DQ11_RG_RX_ARDQ_RANK_SEL_SER_EN_B0, rank_mode, + SHU_B0_DQ11_RG_RX_ARDQ_RANK_SEL_LAT_EN_B0, rank_mode); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq2, + SHU_B0_DQ2_RG_ARPI_OFFSET_LAT_EN_B0, rank_mode, + SHU_B0_DQ2_RG_ARPI_OFFSET_ASYNC_EN_B0, rank_mode); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq10, + SHU_B1_DQ10_RG_RX_ARDQS_SE_EN_B1, rdqs_se_en, + SHU_B1_DQ10_RG_RX_ARDQS_DQSIEN_MODE_B1, dqsien_mode, + SHU_B1_DQ10_RG_RX_ARDQS_DLY_LAT_EN_B1, 1, + SHU_B1_DQ10_RG_RX_ARDQS_RANK_SEL_LAT_EN_B1, rank_mode, + SHU_B1_DQ10_RG_RX_ARDQS_DQSIEN_RANK_SEL_LAT_EN_B1, rank_mode); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq11, + SHU_B1_DQ11_RG_RX_ARDQ_RANK_SEL_SER_EN_B1, rank_mode, + SHU_B1_DQ11_RG_RX_ARDQ_RANK_SEL_LAT_EN_B1, rank_mode); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq2, + SHU_B1_DQ2_RG_ARPI_OFFSET_LAT_EN_B1, rank_mode, + SHU_B1_DQ2_RG_ARPI_OFFSET_ASYNC_EN_B1, rank_mode); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq10, + SHU_B0_DQ10_RG_RX_ARDQS_DLY_LAT_EN_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq2, + SHU_B0_DQ2_RG_ARPI_OFFSET_LAT_EN_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq10, + SHU_B1_DQ10_RG_RX_ARDQS_DLY_LAT_EN_B1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq2, + SHU_B1_DQ2_RG_ARPI_OFFSET_LAT_EN_B1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd10, + SHU_CA_CMD10_RG_RX_ARCLK_RANK_SEL_LAT_EN_CA, 1, + SHU_CA_CMD10_RG_RX_ARCLK_DQSIEN_RANK_SEL_LAT_EN_CA, 1); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd11, + SHU_CA_CMD11_RG_RX_ARCA_RANK_SEL_LAT_EN_CA, 1); +} + +static void ana_config_nonshuffle(dram_freq_grp freq_group, ana_top_config *a_cfg) +{ + suspend_on(); + spm_control(a_cfg); + ana_tx_nonshuffle_config(a_cfg); + ana_rx_nonshuffle_config(); + dig_dcm_nonshuffle_config(); + ana_imp_configure(); + ana_dll_non_shuffle_config(freq_group, a_cfg); +} + +static void ana_config_shuffle(dram_freq_grp freq_group, dramc_subsys_config *subsys) +{ + ana_top_config *a_cfg = subsys->a_cfg; + ana_dvfs_core *dvfs_core = subsys->dvfs_core; + + ana_pll_shuffle_Config(dvfs_core); + ana_arpi_shuffle_config(a_cfg, dvfs_core); + ana_tx_shuffle_config(a_cfg); + ana_rx_shuffle_config(subsys); + dig_phy_shu_misc_cg_ctrl(); + ana_clk_div_config_setting(dvfs_core, a_cfg); + ana_dll_shuffle_config(freq_group, a_cfg); +} + +static void ana_phy_config(dram_freq_grp freq_group, dramc_subsys_config *subsys) +{ + ana_top_config *a_cfg = subsys->a_cfg; + + ana_config_nonshuffle(freq_group, a_cfg); + ana_config_shuffle(freq_group, subsys); +} + +static void ana_clockoff_sequence(void) +{ + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl0, + MISC_CG_CTRL0_CLK_MEM_SEL, 0, + MISC_CG_CTRL0_W_CHG_MEM, 1); + udelay(1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl0, + MISC_CG_CTRL0_W_CHG_MEM, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dll1, + SHU_B0_DLL1_RG_ARDLL_PHDET_EN_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dll1, + SHU_B1_DLL1_RG_ARDLL_PHDET_EN_B1, 0); + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_dll1, + SHU_CA_DLL1_RG_ARDLL_PHDET_EN_CA, 0); + + dramc_set_broadcast(DRAMC_BROADCAST_ON); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dll_arpi2, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_MCK_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_MCK_FB2DLL_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_MCTL_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_FB_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_DQS_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_DQM_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_DQ_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_DQSIEN_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_MPDIV_CG_B0, 0x1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dll_arpi2, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_MCK_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_MCK_FB2DLL_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_MCTL_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_FB_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_DQS_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_DQM_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_DQ_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_DQSIEN_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_MPDIV_CG_B1, 0x1); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_dll_arpi2, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_MCK_CA, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_MCK_FB2DLL_CA, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_MCTL_CA, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_FB_CA, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_CS, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_CLK, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_CMD, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_CLKIEN, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_MPDIV_CG_CA, 0x1); + SET32_BITFIELDS(&ch[0].phy_ao.shu_pll2, + SHU_PLL2_RG_RPHYPLL_ADA_MCK8X_EN_SHU, 0); + SET32_BITFIELDS(&ch[0].phy_ao.phypll2, + PHYPLL2_RG_RPHYPLL_AD_MCK8X_EN, 0, + PHYPLL2_RG_RPHYPLL_ADA_MCK8X_EN, 0); + SET32_BITFIELDS(&ch[0].phy_ao.phypll0, PHYPLL0_RG_RPHYPLL_EN, 0); + SET32_BITFIELDS(&ch[0].phy_ao.phypll2, PHYPLL2_RG_RPHYPLL_RESETB, 0); +} + +static void ana_pll_sequence(void) +{ + SET32_BITFIELDS(&ch[0].phy_ao.phypll2, PHYPLL2_RG_RPHYPLL_RESETB, 1); + SET32_BITFIELDS(&ch[0].phy_ao.phypll0, PHYPLL0_RG_RPHYPLL_EN, 1); + udelay(20); +} + +static void ana_midpi_sequence(ana_dvfs_core *dvfs_core) +{ + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq1, + SHU_B0_DQ1_RG_ARPI_MIDPI_LDO_VREF_SEL_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq1, + SHU_B1_DQ1_RG_ARPI_MIDPI_LDO_VREF_SEL_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd1, + SHU_CA_CMD1_RG_ARPI_MIDPI_LDO_VREF_SEL_CA, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dll_arpi2, + SHU_B0_DLL_ARPI2_RG_ARPI_MPDIV_CG_B0, 1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_FB_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dll_arpi2, + SHU_B1_DLL_ARPI2_RG_ARPI_MPDIV_CG_B1, 1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_FB_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_dll_arpi2, + SHU_CA_DLL_ARPI2_RG_ARPI_MPDIV_CG_CA, 1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_FB_CA, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dll_arpi2, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_MCK_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_MCK_FB2DLL_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_MCTL_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_FB_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_DQS_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_DQM_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_DQ_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_DQSIEN_B0, 0x1, + SHU_B0_DLL_ARPI2_RG_ARPI_MPDIV_CG_B0, 0x1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dll_arpi2, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_MCK_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_MCK_FB2DLL_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_MCTL_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_FB_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_DQS_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_DQM_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_DQ_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_DQSIEN_B1, 0x1, + SHU_B1_DLL_ARPI2_RG_ARPI_MPDIV_CG_B1, 0x1); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_dll_arpi2, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_MCK_CA, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_MCK_FB2DLL_CA, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_MCTL_CA, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_FB_CA, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_CS, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_CLK, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_CMD, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_CLKIEN, 0x1, + SHU_CA_DLL_ARPI2_RG_ARPI_MPDIV_CG_CA, 0x1); + SET32_BITFIELDS(&ch[0].phy_ao.shu_pll2, + SHU_PLL2_RG_RPHYPLL_ADA_MCK8X_EN_SHU, 0); + SET32_BITFIELDS(&ch[0].phy_ao.phypll2, + PHYPLL2_RG_RPHYPLL_AD_MCK8X_EN, 0, + PHYPLL2_RG_RPHYPLL_ADA_MCK8X_EN, 0); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd1, + SHU_CA_CMD1_RG_ARPI_MIDPI_EN_CA, !(dvfs_core->ca_ckdiv4_en), + SHU_CA_CMD1_RG_ARPI_MIDPI_CKDIV4_EN_CA, dvfs_core->ca_ckdiv4_en); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd1, + SHU_CA_CMD1_RG_ARPI_MIDPI_CKDIV4_PREDIV_EN_CA, dvfs_core->ca_prediv_en); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].b0_shu_midpi_ctrl, + B0_SHU_MIDPI_CTRL_MIDPI_ENABLE_B0, + (!(dvfs_core->dq_semi_open)) && (!(dvfs_core->dq_ckdiv4_en)), + B0_SHU_MIDPI_CTRL_MIDPI_DIV4_ENABLE_B0, + (!(dvfs_core->dq_semi_open)) && (dvfs_core->dq_ckdiv4_en)); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].b0_shu_midpi_ctrl, + B1_SHU_MIDPI_CTRL_MIDPI_ENABLE_B1, + (!(dvfs_core->dq_semi_open)) && (!(dvfs_core->dq_ckdiv4_en)), + B1_SHU_MIDPI_CTRL_MIDPI_DIV4_ENABLE_B1, + (!(dvfs_core->dq_semi_open)) && (dvfs_core->dq_ckdiv4_en)); + SET32_BITFIELDS(&ch[0].phy_ao.ca_shu_midpi_ctrl, + CA_SHU_MIDPI_CTRL_MIDPI_ENABLE_CA, !(dvfs_core->ca_ckdiv4_en), + CA_SHU_MIDPI_CTRL_MIDPI_DIV4_ENABLE_CA, dvfs_core->ca_ckdiv4_en); + SET32_BITFIELDS(&ch[0].phy_ao.ca_dll_arpi0, + CA_DLL_ARPI0_RG_ARPI_RESETB_CA, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dll_arpi0, + B0_DLL_ARPI0_RG_ARPI_RESETB_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dll_arpi0, + B1_DLL_ARPI0_RG_ARPI_RESETB_B1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.ca_dll_arpi0, + CA_DLL_ARPI0_RG_ARPI_RESETB_CA, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dll_arpi0, + B0_DLL_ARPI0_RG_ARPI_RESETB_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dll_arpi0, + B1_DLL_ARPI0_RG_ARPI_RESETB_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.shu_pll2, + SHU_PLL2_RG_RPHYPLL_ADA_MCK8X_EN_SHU, 1); + SET32_BITFIELDS(&ch[0].phy_ao.phypll2, + PHYPLL2_RG_RPHYPLL_AD_MCK8X_EN, 1, + PHYPLL2_RG_RPHYPLL_ADA_MCK8X_EN, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dll_arpi2, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_MCK_B0, 0x0, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_MCK_FB2DLL_B0, 0x0, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_MCTL_B0, 0x0, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_FB_B0, 0x0, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_DQS_B0, 0x0, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_DQM_B0, 0x0, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_DQ_B0, 0x0, + SHU_B0_DLL_ARPI2_RG_ARPI_CG_DQSIEN_B0, 0x0, + SHU_B0_DLL_ARPI2_RG_ARPI_MPDIV_CG_B0, dvfs_core->dq_semi_open); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dll_arpi2, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_MCK_B1, 0x0, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_MCK_FB2DLL_B1, 0x0, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_MCTL_B1, 0x0, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_FB_B1, 0x0, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_DQS_B1, 0x0, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_DQM_B1, 0x0, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_DQ_B1, 0x0, + SHU_B1_DLL_ARPI2_RG_ARPI_CG_DQSIEN_B1, 0x0, + SHU_B1_DLL_ARPI2_RG_ARPI_MPDIV_CG_B1, dvfs_core->dq_semi_open); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_dll_arpi2, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_MCK_CA, 0x0, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_MCK_FB2DLL_CA, 0x0, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_MCTL_CA, 0x0, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_FB_CA, 0x0, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_CS, 0x0, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_CLK, 0x0, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_CMD, 0x0, + SHU_CA_DLL_ARPI2_RG_ARPI_CG_CLKIEN, 0x0, + SHU_CA_DLL_ARPI2_RG_ARPI_MPDIV_CG_CA, 0x0); +} + +static void ana_clock_switch(ana_dvfs_core *a_dvfs_cor) +{ + if (a_dvfs_cor->dq_ca_open) { + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl0, + MISC_CG_CTRL0_RESERVED_MISC_CG_CTRL0_BIT3_1, 1); + udelay(1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl0, + MISC_CG_CTRL0_RESERVED_MISC_CG_CTRL0_BIT3_1, 0); + } + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].phy_ao.misc_ckmux_sel, + MISC_CKMUX_SEL_R_PHYCTRLDCM, 1, + MISC_CKMUX_SEL_R_PHYCTRLMUX, 1); + + dramc_set_broadcast(DRAMC_BROADCAST_ON); + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl0, + MISC_CG_CTRL0_CLK_MEM_SEL, 1, + MISC_CG_CTRL0_W_CHG_MEM, 1); + + udelay(1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl0, + MISC_CG_CTRL0_W_CHG_MEM, 0); + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl0, + MISC_CG_CTRL0_RG_FREERUN_MCK_CG, 1); + if (a_dvfs_cor->dq_ca_open) + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl0, + MISC_CG_CTRL0_RESERVED_MISC_CG_CTRL0_BIT7, 1); +} + +static void ana_dll_sequence(ana_dvfs_core *dvfs_core, ana_top_config *a_cfg) +{ + u8 dll_async_en; + u8 all_slave_en; + + dll_async_en = a_cfg->dll_async_en; + all_slave_en = a_cfg->all_slave_en; + + dramc_dbg("[ANA_INIT] DLL >>\n"); + SET32_BITFIELDS(&ch[0].phy_ao.ca_cmd8, + CA_CMD8_RG_ARDLL_RESETB_CA, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq8, + B0_DQ8_RG_ARDLL_RESETB_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq8, + B1_DQ8_RG_ARDLL_RESETB_B1, 1); + if (all_slave_en == 1) { + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_dll1, + SHU_CA_DLL1_RG_ARDLL_PHDET_EN_CA, 1); + + dramc_set_broadcast(DRAMC_BROADCAST_ON); + udelay(1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dll1, + SHU_B0_DLL1_RG_ARDLL_PHDET_EN_B0, !(dvfs_core->dq_semi_open)); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dll1, + SHU_B1_DLL1_RG_ARDLL_PHDET_EN_B1, !(dvfs_core->dq_semi_open)); + udelay(1); + } else { + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + if (dll_async_en == 1) { + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].phy_ao.shu_ca_dll1, + SHU_CA_DLL1_RG_ARDLL_PHDET_EN_CA, 1); + udelay(1); + } else { + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_dll1, + SHU_CA_DLL1_RG_ARDLL_PHDET_EN_CA, 1); + udelay(1); + SET32_BITFIELDS(&ch[1].phy_ao.shu_ca_dll1, + SHU_CA_DLL1_RG_ARDLL_PHDET_EN_CA, 1); + udelay(1); + } + dramc_set_broadcast(DRAMC_BROADCAST_ON); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dll1, + SHU_B0_DLL1_RG_ARDLL_PHDET_EN_B0, !(dvfs_core->dq_semi_open)); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dll1, + SHU_B1_DLL1_RG_ARDLL_PHDET_EN_B1, !(dvfs_core->dq_semi_open)); + udelay(1); + } +} + +void ana_clk_div_config( ana_dvfs_core *tr, dvfs_group_config *dfs) +{ + u32 semi_open_fmin = 300; + u32 semi_open_fmax = 500; + u32 pi_fmin = 600; + u32 dq_pick; + u32 ca_pick; + u32 ca_mckio; + u32 mckio_semi = 0; + u16 data_rate = dfs->data_rate; + tr->dq_p2s_ratio = dfs->dq_p2s_ratio; + tr->ckr = dfs->ckr; + + tr->ca_p2s_ratio = tr->dq_p2s_ratio/tr->ckr; + tr->dq_ca_open = ( data_rate < (semi_open_fmin * 2)) ? 1 : 0; + tr->dq_semi_open = ( data_rate/2 < pi_fmin) ? (1-tr->dq_ca_open) : + ((data_rate <= semi_open_fmax*2) ? (1-tr->dq_ca_open) : 0); + tr->ca_semi_open = (( data_rate/(tr->ckr*2) < pi_fmin) ? + ((data_rate/(tr->ckr*2) > semi_open_fmax) ? 0 : + (((tr->ca_p2s_ratio>2)||(tr->dq_semi_open)) * (1-tr->dq_ca_open))) : + tr->dq_semi_open); + tr->ca_full_rate = (tr->dq_ca_open == 1) ? ((tr->ckr>1)?1:0) : + ((tr->dq_semi_open*tr->ca_semi_open*(tr->ckr>>1)) + + (( data_rate/(tr->ckr*2) < pi_fmin) ? (1-tr->ca_semi_open) : 0)); + tr->dq_ckdiv4_en = ( tr->dq_semi_open == 1) ? 0 : + ((( (data_rate/2) < 1200) ? 1 : 0) * (1-tr->dq_ca_open)) ; + + ca_mckio = (data_rate/(tr->ckr*2))*(1+tr->ca_full_rate); + dq_pick = (tr->dq_semi_open == 1) ? 0 : (data_rate/2) ; + ca_pick = (tr->ca_semi_open == 1) ? ca_mckio*2 : ((ca_mckio>=pi_fmin) ? + ca_mckio : (( ca_mckio >= (pi_fmin/2)) ? ca_mckio*2 : ca_mckio *4)); + tr->ca_ckdiv4_en = ((ca_pick < 1200) ? 1 : 0) * ( 1- tr->dq_ca_open) ; + tr->ca_prediv_en = (data_rate >= 4800) ? 1 : 0 ; + + if (data_rate <= 1866) + tr->ph8_dly = 0; + else if (data_rate <= 2400) + tr->ph8_dly = 0x11; + else if (data_rate <= 3200) + tr->ph8_dly = 0xc; + else if (data_rate <= 3733) + tr->ph8_dly = 0x9; + else + tr->ph8_dly = 0x7; + + tr->semi_open_ca_pick_mck_ratio = ( mckio_semi == 0) ? + 0 : (ca_pick*tr->dq_p2s_ratio)/data_rate ; + tr->dq_aamck_div = (tr->dq_semi_open == 0) ? + ((tr->dq_p2s_ratio/2)*(1-tr->dq_semi_open)) : 0; + tr->ca_admck_div = ca_pick/(data_rate/tr->dq_p2s_ratio); + tr->dq_track_ca_en = 0 ; + tr->pll_freq = ((dq_pick * 2 * (tr->dq_ckdiv4_en+1)) > (ca_pick * 2 *(tr->ca_ckdiv4_en + 1))) ? + (dq_pick*2*(tr->dq_ckdiv4_en+1)) : (ca_pick*2*(tr->ca_ckdiv4_en+1)); + + if (data_rate==2400) + tr->pll_freq = 2366; + else if (data_rate==1200) + tr->pll_freq = 2288; + else if (data_rate==3200 || data_rate==1600) + tr->pll_freq = 3068; + else if (data_rate==800) + tr->pll_freq = 3016; + else if (data_rate==400) + tr->pll_freq = 4000; +} + +static void ana_init_sequence(ana_dvfs_core *dvfs_core, ana_top_config *a_cfg) +{ + ana_pll_sequence(); + ana_midpi_sequence(dvfs_core); + ana_clock_switch(dvfs_core); + ana_dll_sequence(dvfs_core,a_cfg); +} + +void ana_init(const struct ddr_cali *cali, dramc_subsys_config *subsys) +{ + dram_freq_grp freq_group = cali->freq_group; + + dramc_subsys_pre_config(freq_group, subsys); + dramc_dbg("ANA_INIT\n"); + + SET32_BITFIELDS(&ch[0].phy_ao.ca_cmd2, + CA_CMD2_RG_TX_ARCMD_OE_DIS_CA, 1, + CA_CMD2_RG_TX_ARCA_OE_TIE_SEL_CA, 0, + CA_CMD2_RG_TX_ARCA_OE_TIE_EN_CA, 0xff); + ana_clockoff_sequence(); + ana_phy_config(freq_group, subsys); + ana_init_sequence(subsys->dvfs_core, subsys->a_cfg); + SET32_BITFIELDS(&ch[0].phy_ao.ca_cmd2, + CA_CMD2_RG_TX_ARCMD_OE_DIS_CA, 0, + CA_CMD2_RG_TX_ARCA_OE_TIE_SEL_CA, 1, + CA_CMD2_RG_TX_ARCA_OE_TIE_EN_CA, 0xff); + single_end_dramc_post_config(subsys->lp4_init->lp4y_en); +} diff --git a/src/soc/mediatek/mt8192/dramc_pi_basic_api.c b/src/soc/mediatek/mt8192/dramc_pi_basic_api.c index 1d6b6c2..d32c268 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_basic_api.c +++ b/src/soc/mediatek/mt8192/dramc_pi_basic_api.c @@ -3742,6 +3742,12 @@ static void dramc_setting(const struct ddr_cali *cali) { + dramc_subsys_config subsys; + ana_top_config ana_top_p; + struct gating_config gat_config; + static ana_dvfs_core ana_dvfs; + static dram_config lp4_config; + dvfs_group_config dvfs_config; dram_freq_grp freq_group = cali->freq_group; dramc_set_broadcast(DRAMC_BROADCAST_ON); @@ -3766,6 +3772,13 @@ return; } + resetb_pull_dn(); + subsys.a_cfg = &ana_top_p; + subsys.dvfs_core = &ana_dvfs; + subsys.lp4_init = &lp4_config; + subsys.dfs_gp = &dvfs_config; + subsys.gat_c = &gat_config; + ana_init(cali, &subsys); update_initial_settings(cali); dramc_set_broadcast(DRAMC_BROADCAST_OFF); } diff --git a/src/soc/mediatek/mt8192/dramc_subsys_config.c b/src/soc/mediatek/mt8192/dramc_subsys_config.c new file mode 100644 index 0000000..146e073 --- /dev/null +++ b/src/soc/mediatek/mt8192/dramc_subsys_config.c @@ -0,0 +1,134 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <soc/dramc_pi_api.h> +#include <soc/dramc_register.h> + +static u8 get_dram_RL_WL_mr_field_config(dram_freq_grp freq_group) +{ + u8 mr2_rl_wl = 2; + + switch(freq_group) { + case DDRFREQ_400: + case DDRFREQ_600: + case DDRFREQ_800: + mr2_rl_wl = 2; + break; + case DDRFREQ_933: + mr2_rl_wl = 3; + break; + case DDRFREQ_1200: + mr2_rl_wl = 4; + break; + case DDRFREQ_1600: + mr2_rl_wl = 5; + break; + case DDRFREQ_2133: + mr2_rl_wl = 7; + break; + default: + dramc_dbg("ERROR: Unexpected freq:0x%x\n", freq_group); + break; + } + + return mr2_rl_wl; +} + +void dram_configure(dram_freq_grp freq_group, dram_config *tr) +{ + tr->mr_wl = get_dram_RL_WL_mr_field_config(freq_group); + tr->dbi_wr = 0; + tr->dbi_rd = 0; + tr->lp4y_en = 0; + tr->work_fsp = (freq_group > DDRFREQ_1200) ? 1 : 0; +} + +void dramc_subsys_pre_config(dram_freq_grp freq_group, dramc_subsys_config *subsys) +{ + ana_top_config *a_cfg = subsys->a_cfg; + dram_config *lp4_init = subsys->lp4_init; + dvfs_group_config *dfs_gp = subsys->dfs_gp; + + subsys->freq_group = freq_group; + dfs_gp->ckr = 1; + dfs_gp->dqsien_mode = 1; + lp4_init->ex_row_en[RANK_0] = (get_row_width_from_emi(RANK_0) >= 18) ? 1 : 0; + lp4_init->ex_row_en[RANK_1] = (get_row_width_from_emi(RANK_1) >= 18) ? 1 : 0; + lp4_init->lp4y_en = 0; + a_cfg->new_8x_mode = 1; + a_cfg->aphy_comb_en = 1 ; + a_cfg->dll_idle_mode = 1; + a_cfg->rank_mode = 1; + a_cfg->dll_async_en = 0; + + switch (freq_group) { + case DDRFREQ_400: + dfs_gp->data_rate = 800; + dfs_gp->dq_p2s_ratio = 4; + break; + case DDRFREQ_600: + dfs_gp->data_rate = 1200; + dfs_gp->dq_p2s_ratio = 8; + break; + case DDRFREQ_800: + dfs_gp->data_rate = 1600; + dfs_gp->dq_p2s_ratio = 8; + break; + case DDRFREQ_933: + dfs_gp->data_rate = 1866; + dfs_gp->dq_p2s_ratio = 8; + break; + case DDRFREQ_1200: + dfs_gp->data_rate = 2400; + dfs_gp->dq_p2s_ratio = 8; + break; + case DDRFREQ_1600: + dfs_gp->data_rate = 3200; + dfs_gp->dq_p2s_ratio = 8; + break; + case DDRFREQ_2133: + dfs_gp->data_rate = 4266; + dfs_gp->dq_p2s_ratio = 8; + break; + default: + die("Invalid DDR frequency group %u\n", freq_group); + return; + } + + dram_configure(freq_group, lp4_init); + + a_cfg->all_slave_en = (freq_group <= DDRFREQ_933) ? 1 : 0; + a_cfg->tx_odt_dis = (freq_group <= DDRFREQ_1200) ? 1 : 0 ; + + ana_clk_div_config(subsys->dvfs_core, subsys->dfs_gp); +} + +void single_end_dramc_post_config(u8 lp4y_en) +{ + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd13, + SHU_CA_CMD13_RG_TX_ARCLKB_OE_TIE_SEL_CA, lp4y_en, + SHU_CA_CMD13_RG_TX_ARCLKB_OE_TIE_EN_CA, lp4y_en); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq13, + SHU_B0_DQ13_RG_TX_ARDQSB_OE_TIE_SEL_B0, lp4y_en, + SHU_B0_DQ13_RG_TX_ARDQSB_OE_TIE_EN_B0, lp4y_en); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq13, + SHU_B1_DQ13_RG_TX_ARDQSB_OE_TIE_SEL_B1, lp4y_en, + SHU_B1_DQ13_RG_TX_ARDQSB_OE_TIE_EN_B1, lp4y_en); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd0, + SHU_CA_CMD0_R_LP4Y_WDN_MODE_CLK, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq0, + SHU_B0_DQ0_R_LP4Y_WDN_MODE_DQS0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq0, + SHU_B1_DQ0_R_LP4Y_WDN_MODE_DQS1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd7, + SHU_CA_CMD7_R_LP4Y_SDN_MODE_CLK, 0); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq7, + SHU_B0_DQ7_R_LP4Y_SDN_MODE_DQS0, lp4y_en); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq7, + SHU_B1_DQ7_R_LP4Y_SDN_MODE_DQS1, lp4y_en); + SET32_BITFIELDS(&ch[0].phy_ao.ca_cmd7, + CA_CMD7_RG_TX_ARCLKB_PULL_DN_LP4Y, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq7, + B0_DQ7_RG_TX_ARDQS0B_PULL_DN_B0_LP4Y, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq7, + B1_DQ7_RG_TX_ARDQS0B_PULL_DN_B1_LP4Y, 0); +} diff --git a/src/soc/mediatek/mt8192/emi.c b/src/soc/mediatek/mt8192/emi.c index b587993..acd605f 100644 --- a/src/soc/mediatek/mt8192/emi.c +++ b/src/soc/mediatek/mt8192/emi.c @@ -320,6 +320,27 @@ return ma_type; } +u32 get_row_width_from_emi(u32 rank) +{ + u32 emi_cona; + u32 shift_row, shift_ext; + int row_width; + + if (rank == 0) { + shift_row = 12; + shift_ext = 22; + } else if (rank == 1) { + shift_row = 14; + shift_ext = 23; + } else + return -1; + + emi_cona = read32(&emi_reg->cona); + row_width = ((emi_cona >> shift_row) & 0x3) | ((emi_cona >> shift_ext) & 0x4); + + return (row_width + 13); +} + static void emi_sw_setting(void) { setbits32(&emi_mpu->mpu_ctrl_d[1], BIT(4)); -- To view, visit
https://review.coreboot.org/c/coreboot/+/44727
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: I53b30a2bbed5acb363f85f7cbc7f255fdbc52304 Gerrit-Change-Number: 44727 Gerrit-PatchSet: 1 Gerrit-Owner: CK HU <ck.hu(a)mediatek.com> Gerrit-Reviewer: Duan huayang <huayang.duan(a)mediatek.com> Gerrit-Reviewer: Julius Werner <jwerner(a)chromium.org> Gerrit-Reviewer: Martin Roth <martinroth(a)google.com> Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com> Gerrit-MessageType: newchange
3
47
0
0
Change in coreboot[master]: soc/mediatek/mt8192: Do dramc digital init setting
by CK HU (Code Review)
08 Mar '21
08 Mar '21
Hello Duan huayang, I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/44728
to review the following change. Change subject: soc/mediatek/mt8192: Do dramc digital init setting ...................................................................... soc/mediatek/mt8192: Do dramc digital init setting Signed-off-by: Huayang Duan <huayang.duan(a)mediatek.com> Change-Id: If84def990983fae32506c1cd409bd1a1e3a550cd --- M src/soc/mediatek/mt8192/Makefile.inc A src/soc/mediatek/mt8192/dramc_dig_config.c M src/soc/mediatek/mt8192/dramc_pi_basic_api.c 3 files changed, 1,245 insertions(+), 1 deletion(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/28/44728/1 diff --git a/src/soc/mediatek/mt8192/Makefile.inc b/src/soc/mediatek/mt8192/Makefile.inc index e3463cd..2b9e0d6 100644 --- a/src/soc/mediatek/mt8192/Makefile.inc +++ b/src/soc/mediatek/mt8192/Makefile.inc @@ -17,7 +17,7 @@ romstage-y += ../common/cbmem.c romstage-y += dramc_pi_main.c dramc_pi_basic_api.c dramc_pi_calibration_api.c dramc_utility.c dramc_dvfs.c dramc_tracking.c -romstage-y += dramc_subsys_config.c dramc_ana_init_config.c +romstage-y += dramc_subsys_config.c dramc_ana_init_config.c dramc_dig_config.c romstage-y += emi.c romstage-y += flash_controller.c romstage-y += ../common/gpio.c gpio.c diff --git a/src/soc/mediatek/mt8192/dramc_dig_config.c b/src/soc/mediatek/mt8192/dramc_dig_config.c new file mode 100644 index 0000000..c13f24c --- /dev/null +++ b/src/soc/mediatek/mt8192/dramc_dig_config.c @@ -0,0 +1,1241 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <soc/dramc_pi_api.h> +#include <soc/dramc_register.h> + +static void dig_phy_config(dramc_subsys_config *subsys) +{ + u8 rk_swap_en = 0; + + dramc_dbg("[Flow] Enable top DCM control\n"); + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_IDLE_FSEL, 3); + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_APB_TOG, 0, + MISC_CG_CTRL2_RG_MEM_DCM_APB_SEL, 0x1f); + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_APB_TOG, 1, + MISC_CG_CTRL2_RG_MEM_DCM_APB_SEL, 0x1f); + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_APB_TOG, 0, + MISC_CG_CTRL2_RG_MEM_DCM_APB_SEL, 0x1f); + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_APB_SEL, 0x17, + MISC_CG_CTRL2_RG_MEM_DCM_APB_TOG, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_ctrl0, + MISC_CTRL0_R_STBENCMP_DIV4CK_EN, 0, + MISC_CTRL0_R_DQS0IEN_DIV4_CK_CG_CTRL, 1, + MISC_CTRL0_R_DQS1IEN_DIV4_CK_CG_CTRL, 1, + MISC_CTRL0_R_CLKIEN_DIV4_CK_CG_CTRL, 0, + MISC_CTRL0_R_DMSHU_PHYDCM_FORCEOFF, 1); + + SET32_BITFIELDS(&ch[0].phy_ao.misc_rxdvs2, + MISC_RXDVS2_R_DMRXDVS_SHUFFLE_CTRL_CG_IG, 1); + + dramc_dbg("Enable DLL master slave shuffle \n"); + SET32_BITFIELDS(&ch[0].phy_ao.misc_dvfs_emi_clk, + MISC_DVFS_EMI_CLK_RG_DLL_SHUFFLE_DDRPHY, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq9, + B0_DQ9_R_DMRXFIFO_STBENCMP_EN_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq9, + B1_DQ9_R_DMRXFIFO_STBENCMP_EN_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_ctrl1, + MISC_CTRL1_R_RK_PINMUXSWAP_EN, rk_swap_en); + + udelay(1); + + if (subsys->a_cfg->rank_mode==0) { + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq9, + B0_DQ9_R_IN_GATE_EN_LOW_OPT_B0, 4, + B0_DQ9_R_DMRXDVS_R_F_DLY_RK_OPT_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq9, + B1_DQ9_R_IN_GATE_EN_LOW_OPT_B1, 4, + B1_DQ9_R_DMRXDVS_R_F_DLY_RK_OPT_B1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq10, + B0_DQ10_ARPI_CG_RK1_SRC_SEL_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq10, + B1_DQ10_ARPI_CG_RK1_SRC_SEL_B1, 0); + } else { + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq9, + B0_DQ9_R_IN_GATE_EN_LOW_OPT_B0, 0, + B0_DQ9_R_DMRXDVS_R_F_DLY_RK_OPT_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq9, + B1_DQ9_R_IN_GATE_EN_LOW_OPT_B1, 0, + B1_DQ9_R_DMRXDVS_R_F_DLY_RK_OPT_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq10, + B0_DQ10_ARPI_CG_RK1_SRC_SEL_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq10, + B1_DQ10_ARPI_CG_RK1_SRC_SEL_B1, 1); + } + + if (subsys->a_cfg->new_8x_mode==1) { + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].phy_ao.misc_dvfsctl, + MISC_DVFSCTL_R_SHUFFLE_PI_RESET_ENABLE, 1, + MISC_DVFSCTL_R_DVFS_MCK8X_MARGIN, 3); + dramc_set_broadcast(DRAMC_BROADCAST_ON); + } +} + +static void gating_mode_cfg(dramc_subsys_config *subsys) +{ + struct gating_config *gat_c = subsys->gat_c; + + gat_c->gat_track_en = ((subsys->dvfs_core->dq_semi_open == 1) + ||(subsys->dvfs_core->dq_ca_open==1)) ? 0 : 1; + gat_c->rx_gating_mode = 2; + gat_c->rx_gating_track_mode = 2; + gat_c->valid_lat_value = 1; +} + +static void dphy_gat_track_config(dramc_subsys_config *subsys) +{ + dramc_dbg("Enter into Gating configuration\n"); + u8 selph_mode = 1; + struct gating_config *gat_c = subsys->gat_c; + + SET32_BITFIELDS(&ch[0].phy_ao.misc_stbcal1, + MISC_STBCAL1_STBCNT_SW_RST, !gat_c->gat_track_en); + SET32_BITFIELDS(&ch[0].phy_ao.misc_stbcal2, + MISC_STBCAL2_DQSIEN_SELPH_BY_RANK_EN, selph_mode); + SET32_BITFIELDS(&ch[0].phy_ao.misc_stbcal1, + MISC_STBCAL1_STBCNT_SHU_RST_EN, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_stbcal1, + MISC_STBCAL1_DIS_PI_TRACK_AS_NOT_RD, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq6, + B0_DQ6_RG_RX_ARDQ_OP_BIAS_SW_EN_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq6, + B1_DQ6_RG_RX_ARDQ_OP_BIAS_SW_EN_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_stbcal2, + MISC_STBCAL2_STB_PICG_EARLY_1T_EN, 1); + + switch (gat_c->rx_gating_mode) { + case 0: + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq9, + B0_DQ9_RG_RX_ARDQS0_DQSIENMODE_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq9, + B1_DQ9_RG_RX_ARDQS0_DQSIENMODE_B1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq6, + B0_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq6, + B1_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_stbcal, + MISC_SHU_STBCAL_DQSIEN_BURST_MODE, 0); + break; + case 1: + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq9, + B0_DQ9_RG_RX_ARDQS0_DQSIENMODE_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq9, + B1_DQ9_RG_RX_ARDQS0_DQSIENMODE_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq6, + B0_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq6, + B1_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B1, 1); + break; + case 2: + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq9, + B0_DQ9_RG_RX_ARDQS0_DQSIENMODE_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq9, + B1_DQ9_RG_RX_ARDQS0_DQSIENMODE_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq6, + B0_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B0, 2); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq6, + B1_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B1, 2); + SET32_BITFIELDS(&ch[0].phy_ao.misc_stbcal1, + MISC_STBCAL1_DQSIEN_7UI_EN, 1); + break; + case 3: + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq9, + B0_DQ9_RG_RX_ARDQS0_DQSIENMODE_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq9, + B1_DQ9_RG_RX_ARDQS0_DQSIENMODE_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq6, + B0_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq6, + B1_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B1, 0); + break; + default: + dramc_dbg("ERROR: Gating Mode choose unexpected Mode!!!!\n"); + break; + } + + if (gat_c->rx_gating_track_mode == 2) { + SET32_BITFIELDS(&ch[0].phy_ao.misc_stbcal, + MISC_STBCAL_STB_DQIEN_IG, 1, + MISC_STBCAL_PICHGBLOCK_NORD, 1, + MISC_STBCAL_REFUICHG, 0, + MISC_STBCAL_PHYVALID_IG, 0, + MISC_STBCAL_STBSTATE_OPT, 0, + MISC_STBCAL_STBDLELAST_FILTER, 0, + MISC_STBCAL_STBDLELAST_PULSE, 0, + MISC_STBCAL_STBDLELAST_OPT, 0, + MISC_STBCAL_PIMASK_RKCHG_OPT, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_stbcal1, + MISC_STBCAL1_STBCAL_FILTER, 1, + MISC_STBCAL1_STB_FLAGCLR_OPT, 1, + MISC_STBCAL1_STB_SHIFT_DTCOUT_IG, 1, + MISC_STBCAL1_STBCNT_MODESEL, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_ctrl0, + MISC_CTRL0_R_DMDQSIEN_FIFO_EN, 1, + MISC_CTRL0_R_DMVALID_DLY, 0, + MISC_CTRL0_R_DMVALID_DLY_OPT, 0, + MISC_CTRL0_R_DMSTBEN_SYNCOPT, 0, + MISC_CTRL0_R_DMVALID_NARROW_IG, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq6, + B0_DQ6_RG_RX_ARDQ_DMRANK_OUTSEL_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq9, + B0_DQ9_R_DMDQSIEN_RDSEL_LAT_B0, 1+gat_c->valid_lat_value, + B0_DQ9_R_DMDQSIEN_VALID_LAT_B0, 0+gat_c->valid_lat_value); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq6, + B1_DQ6_RG_RX_ARDQ_DMRANK_OUTSEL_B1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq9, + B1_DQ9_R_DMDQSIEN_RDSEL_LAT_B1, 1+gat_c->valid_lat_value, + B1_DQ9_R_DMDQSIEN_VALID_LAT_B1, 0+gat_c->valid_lat_value); + } + + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_phy2, + B0_PHY2_RG_RX_ARDQS_DQSIEN_UI_LEAD_LAG_EN_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_phy2, + B1_PHY2_RG_RX_ARDQS_DQSIEN_UI_LEAD_LAG_EN_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_stbcal, + MISC_STBCAL_DQSIENMODE, 1, + MISC_STBCAL_SREF_DQSGUPD, 1, + MISC_STBCAL_DQSIENCG_CHG_EN, 1, + MISC_STBCAL_PICGEN, 1, + MISC_STBCAL_RKCHGMASKDIS, 0, + MISC_STBCAL_STBCAL2R, 0); + SET32_BITFIELDS(&ch[0].phy_ao.misc_ctrl1, + MISC_CTRL1_R_DMDQSIENCG_EN, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_stbcal2, + MISC_STBCAL2_STB_GERRSTOP, 0, + MISC_STBCAL2_STB_GERR_RST, 0, + MISC_STBCAL2_STB_GERR_B01, 1, + MISC_STBCAL2_STB_GERR_B23, 0); + SET32_BITFIELDS(&ch[0].phy_ao.misc_rx_in_gate_en_ctrl, + MISC_RX_IN_GATE_EN_CTRL_RX_IN_GATE_EN_OPT, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_rx_in_buff_en_ctrl, + MISC_RX_IN_BUFF_EN_CTRL_RX_IN_BUFF_EN_OPT, 1); + + if (subsys->a_cfg->rank_mode == 1) + SET32_BITFIELDS(&ch[0].phy_ao.misc_stbcal2, + MISC_STBCAL2_STB_IG_XRANK_CG_RST, 1, + MISC_STBCAL2_STB_RST_BY_RANK, 1, + MISC_STBCAL2_DQSIEN_SELPH_BY_RANK_EN, 1); + dramc_dbg("Exit from Gating configuration\n"); +} + +static void dig_config_shuf_alg_txca(dram_freq_grp freq_group) +{ + dramc_dbg("[TX_CA][Delay]\n"); + + u8 tx_ui = (freq_group <= DDRFREQ_400) ? 1: 0 ; + SET32_BITFIELDS(&ch[0].ao.shu_selph_ca1, + SHU_SELPH_CA1_TXDLY_CS, 0, + SHU_SELPH_CA1_TXDLY_CKE, 0, + SHU_SELPH_CA1_TXDLY_ODT, 0, + SHU_SELPH_CA1_TXDLY_RESET, 0, + SHU_SELPH_CA1_TXDLY_WE, 0, + SHU_SELPH_CA1_TXDLY_CAS, 0, + SHU_SELPH_CA1_TXDLY_RAS, 0, + SHU_SELPH_CA1_TXDLY_CS1, 0); + SET32_BITFIELDS(&ch[0].ao.shu_selph_ca2, + SHU_SELPH_CA2_TXDLY_BA0, 0, + SHU_SELPH_CA2_TXDLY_BA1, 0, + SHU_SELPH_CA2_TXDLY_BA2, 0, + SHU_SELPH_CA2_TXDLY_CKE1, 0); + SET32_BITFIELDS(&ch[0].ao.shu_selph_ca3, + SHU_SELPH_CA3_TXDLY_RA0, 0, + SHU_SELPH_CA3_TXDLY_RA1, 0, + SHU_SELPH_CA3_TXDLY_RA2, 0, + SHU_SELPH_CA3_TXDLY_RA3, 0, + SHU_SELPH_CA3_TXDLY_RA4, 0, + SHU_SELPH_CA3_TXDLY_RA5, 0, + SHU_SELPH_CA3_TXDLY_RA6, 0, + SHU_SELPH_CA3_TXDLY_RA7, 0); + SET32_BITFIELDS(&ch[0].ao.shu_selph_ca4, + SHU_SELPH_CA4_TXDLY_RA8, 0, + SHU_SELPH_CA4_TXDLY_RA9, 0, + SHU_SELPH_CA4_TXDLY_RA10, 0, + SHU_SELPH_CA4_TXDLY_RA11, 0, + SHU_SELPH_CA4_TXDLY_RA12, 0, + SHU_SELPH_CA4_TXDLY_RA13, 0, + SHU_SELPH_CA4_TXDLY_RA14, 0, + SHU_SELPH_CA4_TXDLY_RA15, 0); + SET32_BITFIELDS(&ch[0].ao.shu_selph_ca5, + SHU_SELPH_CA5_DLY_CS, tx_ui, + SHU_SELPH_CA5_DLY_CKE, 1, + SHU_SELPH_CA5_DLY_ODT, 0, + SHU_SELPH_CA5_DLY_RESET, 1, + SHU_SELPH_CA5_DLY_WE, 1, + SHU_SELPH_CA5_DLY_CAS, 1, + SHU_SELPH_CA5_DLY_RAS, 1, + SHU_SELPH_CA5_DLY_CS1, tx_ui); + SET32_BITFIELDS(&ch[0].ao.shu_selph_ca6, + SHU_SELPH_CA6_DLY_BA0, 1, + SHU_SELPH_CA6_DLY_BA1, 1, + SHU_SELPH_CA6_DLY_BA2, 1, + SHU_SELPH_CA6_DLY_CKE1, 1); + SET32_BITFIELDS(&ch[0].ao.shu_selph_ca7, + SHU_SELPH_CA7_DLY_RA0, tx_ui, + SHU_SELPH_CA7_DLY_RA1, tx_ui, + SHU_SELPH_CA7_DLY_RA2, tx_ui, + SHU_SELPH_CA7_DLY_RA3, tx_ui, + SHU_SELPH_CA7_DLY_RA4, tx_ui, + SHU_SELPH_CA7_DLY_RA5, tx_ui, + SHU_SELPH_CA7_DLY_RA6, tx_ui, + SHU_SELPH_CA7_DLY_RA7, tx_ui); + SET32_BITFIELDS(&ch[0].ao.shu_selph_ca8, + SHU_SELPH_CA8_DLY_RA8, tx_ui, + SHU_SELPH_CA8_DLY_RA9, tx_ui, + SHU_SELPH_CA8_DLY_RA10, tx_ui, + SHU_SELPH_CA8_DLY_RA11, tx_ui, + SHU_SELPH_CA8_DLY_RA12, tx_ui, + SHU_SELPH_CA8_DLY_RA13, tx_ui, + SHU_SELPH_CA8_DLY_RA14, tx_ui, + SHU_SELPH_CA8_DLY_RA15, tx_ui); +} + +static void dig_config_shuf_imp(dram_freq_grp freq_group) +{ + dramc_dbg("[IMPDANCE][Configuration]\n"); + u8 ipm_odt_en; + u8 chk_cycle = 7; + u8 tx_dly_cmd = 8; + + ipm_odt_en = (freq_group > DDRFREQ_1200) ? 1 : 0; + if (freq_group >= DDRFREQ_2133) + tx_dly_cmd = 0xc; + else if (freq_group >= DDRFREQ_1600) + tx_dly_cmd = 0xa; + + SET32_BITFIELDS(&ch[0].phy_ao.shu_misc_drving2, + SHU_MISC_DRVING2_DIS_IMPCAL_ODT_EN, !ipm_odt_en); + SET32_BITFIELDS(&ch[0].phy_ao.shu_misc_impcal1, + SHU_MISC_IMPCAL1_IMPCAL_CHKCYCLE, chk_cycle, + SHU_MISC_IMPCAL1_IMPCAL_CALICNT, 8, + SHU_MISC_IMPCAL1_IMPCAL_CALEN_CYCLE, 4, + SHU_MISC_IMPCAL1_IMPCALCNT, 0x40); + SET32_BITFIELDS(&ch[0].phy_ao.shu_ca_cmd12, + SHU_CA_CMD12_RG_RIMP_REV, ipm_odt_en?0x1b:0x0f); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_impedamce_upd_dis1, + MISC_SHU_IMPEDAMCE_UPD_DIS1_CMD2_DRVP_UPD_DIS, 1, + MISC_SHU_IMPEDAMCE_UPD_DIS1_CMD2_DRVN_UPD_DIS, 1, + MISC_SHU_IMPEDAMCE_UPD_DIS1_CMD2_ODTN_UPD_DIS, 1); + SET32_BITFIELDS(&ch[0].phy_ao.shu_misc_drving6, + SHU_MISC_DRVING6_IMP_TXDLY_CMD, tx_dly_cmd); +} + +static void dig_config_shuf_rxinput(void) +{ + u8 perbyte_track_en = 1; + u8 dqm_track_en = 1; + u8 dqm_flow_dq_sel = 3; + u8 rx_force_upd = 0; + + dramc_dbg("[RX_INPUT][Configuration] \n"); + if (rx_force_upd == 1) { + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq8, + SHU_B0_DQ8_R_DMRXDVS_UPD_FORCE_EN_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq8, + SHU_B1_DQ8_R_DMRXDVS_UPD_FORCE_EN_B1, 1); + } + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq7, + SHU_B0_DQ7_R_DMRXDVS_PBYTE_FLAG_OPT_B0, perbyte_track_en, + SHU_B0_DQ7_R_DMRXDVS_DQM_FLAGSEL_B0, dqm_flow_dq_sel, + SHU_B0_DQ7_R_DMRXDVS_PBYTE_DQM_EN_B0, dqm_track_en, + SHU_B0_DQ7_R_DMRXTRACK_DQM_EN_B0, dqm_track_en); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq7, + SHU_B1_DQ7_R_DMRXDVS_PBYTE_FLAG_OPT_B1, perbyte_track_en, + SHU_B1_DQ7_R_DMRXDVS_DQM_FLAGSEL_B1, dqm_flow_dq_sel, + SHU_B1_DQ7_R_DMRXDVS_PBYTE_DQM_EN_B1, dqm_track_en, + SHU_B1_DQ7_R_DMRXTRACK_DQM_EN_B1, dqm_track_en); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq11, + SHU_B0_DQ11_RG_RX_ARDQ_DVS_EN_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq11, + SHU_B1_DQ11_RG_RX_ARDQ_DVS_EN_B1, 1); +} + +static void dig_config_shuf_misc_fix(const struct ddr_cali *cali, dramc_subsys_config *subsys) +{ + u8 picg_mode = 1; + u8 dqsien_dqsstb_mode=0; + u8 cas_mode = 1; + u8 wck_dual = 0; + u8 rank_mode = 1; + u8 dual_schen = 1; + u8 dqoe_opt = 0, dqoe_cnt = 0; + u32 data_rate = subsys->dfs_gp->data_rate; + struct gating_config *gat_c = subsys->gat_c; + + dramc_dbg("[DIG_SHUF_CONFIG] MISC\n"); + dual_schen = (subsys->dvfs_core->dq_p2s_ratio==4) ? 0 : 1; + + switch(subsys->dfs_gp->dqsien_mode) { + case 1: + dqsien_dqsstb_mode = 1; + break; + case 2: + dqsien_dqsstb_mode = 2; + break; + case 3: + dqsien_dqsstb_mode = 3; + break; + case 6: + dqsien_dqsstb_mode = 2; + break; + case 7: + dqsien_dqsstb_mode = 3; + break; + default: dramc_dbg("[DIG_SHUF_CONFIG] Unexpected subsys->dfs_gp->dqsien_mode=%1d \n", + subsys->dfs_gp->dqsien_mode); + break; + } + + switch(cas_mode) { + case 1: + wck_dual = 0; + break; + case 2: + wck_dual = 1; + break; + case 3: + wck_dual = 0; + break; + default: dramc_dbg("[DIG_SHUF_CONFIG] Unexpected cas_mode(%d) input\n",cas_mode); + break; + } + + SET32_BITFIELDS(&ch[0].ao.shu_common0, + SHU_COMMON0_BL4, 1, + SHU_COMMON0_FREQDIV4, subsys->dvfs_core->dq_p2s_ratio==8, + SHU_COMMON0_FDIV2, subsys->dvfs_core->dq_p2s_ratio==4, + SHU_COMMON0_BC4OTF, 1, + SHU_COMMON0_DM64BITEN, !(subsys->dvfs_core->dq_p2s_ratio==4)); + SET32_BITFIELDS(&ch[0].ao.shu_actiming_conf, + SHU_ACTIMING_CONF_TREFBWIG, 1, + SHU_ACTIMING_CONF_SCINTV, 54); + SET32_BITFIELDS(&ch[0].ao.shu_dcm_ctrl0, + SHU_DCM_CTRL0_FASTWAKE2, 1, + SHU_DCM_CTRL0_FASTWAKE, 1); + SET32_BITFIELDS(&ch[0].ao.shu_conf0, + SHU_CONF0_ADVPREEN, 1, + SHU_CONF0_DMPGTIM, 63, + SHU_CONF0_REFTHD, 0, + SHU_CONF0_PBREFEN, 1); + SET32_BITFIELDS(&ch[0].ao.shu_matype, + SHU_MATYPE_MATYPE, 2); + SET32_BITFIELDS(&ch[0].ao.shu_scheduler, + SHU_SCHEDULER_DUALSCHEN, dual_schen); + SET32_BITFIELDS(&ch[0].ao.tx_set0, + TX_SET0_WPRE2T, 1); + SET32_BITFIELDS(&ch[0].ao.shu_tx_set0, + SHU_TX_SET0_WDATRGO, subsys->dvfs_core->dq_p2s_ratio == 4, + SHU_TX_SET0_WPST1P5T, data_rate >= 3200, + SHU_TX_SET0_DQOE_OPT, dqoe_opt, + SHU_TX_SET0_DQOE_CNT, dqoe_cnt, + SHU_TX_SET0_OE_EXT2UI, 0, + SHU_TX_SET0_TXUPD_W2R_SEL, + ((data_rate == 1600) && (subsys->dvfs_core->dq_p2s_ratio == 8)) ? 5 : 2); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_stbcal1, + MISC_SHU_STBCAL1_STB_PI_TRACKING_RATIO, 0x30, + MISC_SHU_STBCAL1_STB_UPDMASK_EN, 1, + MISC_SHU_STBCAL1_STB_UPDMASKCYC, 9, + MISC_SHU_STBCAL1_DQSINCTL_PRE_SEL, data_rate > 1600); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_stbcal, + MISC_SHU_STBCAL_STBCALEN, gat_c->gat_track_en, + MISC_SHU_STBCAL_STB_SELPHCALEN, gat_c->gat_track_en, + MISC_SHU_STBCAL_DQSIEN_DQSSTB_MODE, dqsien_dqsstb_mode); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_stbcal, + MISC_SHU_STBCAL_DMSTBLAT, + (((gat_c->gat_track_en) && (data_rate >= 1866)) ? + (2 + gat_c->valid_lat_value) : (gat_c->valid_lat_value)), + MISC_SHU_STBCAL_PICGLAT, 1, + MISC_SHU_STBCAL_DQSG_MODE, 1, + MISC_SHU_STBCAL_DQSIEN_PICG_MODE, picg_mode); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rankctl, + MISC_SHU_RANKCTL_RANK_RXDLY_OPT, picg_mode); + SET32_BITFIELDS(&ch[0].ao.shu_misc, + SHU_MISC_REQQUE_MAXCNT, 1); + for (u8 rk = RANK_0; rk < cali->support_ranks; rk++) + SET32_BITFIELDS(&ch[0].phy_ao.misc_rk[rk].misc_shu_rk_dqsien_picg_ctrl, + MISC_SHU_RK_DQSIEN_PICG_CTRL_DQSIEN_PICG_HEAD_EXT_LAT, 0, + MISC_SHU_RK_DQSIEN_PICG_CTRL_DQSIEN_PICG_TAIL_EXT_LAT, + subsys->dvfs_core->dq_p2s_ratio == 4); + + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rodtenstb, + MISC_SHU_RODTENSTB_RODTENSTB_TRACK_EN, 1, + MISC_SHU_RODTENSTB_RODTEN_P1_ENABLE, 0, + MISC_SHU_RODTENSTB_RODTENSTB_SELPH_MODE, rank_mode?1:picg_mode, + MISC_SHU_RODTENSTB_RODTENSTB_TRACK_UDFLWCTRL, 1, + MISC_SHU_RODTENSTB_RODTENSTB_MCK_OFFSET, + (subsys->dvfs_core->dq_p2s_ratio == 4) ? 2 : 0, + MISC_SHU_RODTENSTB_RODTENSTB__UI_OFFSET, + (subsys->dvfs_core->dq_p2s_ratio == 4) ? 1 : 4, + MISC_SHU_RODTENSTB_RODTENSTB_EXT, + (subsys->dvfs_core->dq_p2s_ratio == 16) ? + 19 : ((subsys->dvfs_core->dq_p2s_ratio == 8) ? 13 : 10)); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rodtenstb1, + MISC_SHU_RODTENSTB1_RODTENCGEN_TAIL, (data_rate >= 3200) ? 1 : 0); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rodtenstb1, + MISC_SHU_RODTENSTB1_RODTENCGEN_HEAD, (data_rate >= 3200) ? 2 : 1); + + switch (subsys->dvfs_core->dq_p2s_ratio) { + case 4: + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rx_selph_mode, + MISC_SHU_RX_SELPH_MODE_DQSIEN_SELPH_SERMODE, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rx_selph_mode, + MISC_SHU_RX_SELPH_MODE_RODT_SELPH_SERMODE, 0, + MISC_SHU_RX_SELPH_MODE_RANK_SELPH_SERMODE, 0); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rdat1, + MISC_SHU_RDAT1_R_DMRDSEL_DIV2_OPT, 1, + MISC_SHU_RDAT1_R_DMRDSEL_LOBYTE_OPT, 1, + MISC_SHU_RDAT1_R_DMRDSEL_HIBYTE_OPT, 0); + break; + case 8: + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rx_selph_mode, + MISC_SHU_RX_SELPH_MODE_DQSIEN_SELPH_SERMODE, 2); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rx_selph_mode, + MISC_SHU_RX_SELPH_MODE_RODT_SELPH_SERMODE, 1, + MISC_SHU_RX_SELPH_MODE_RANK_SELPH_SERMODE, 1); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rdat1, + MISC_SHU_RDAT1_R_DMRDSEL_DIV2_OPT, 0, + MISC_SHU_RDAT1_R_DMRDSEL_LOBYTE_OPT, 0, + MISC_SHU_RDAT1_R_DMRDSEL_HIBYTE_OPT, 0); + break; + case 16: + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rx_selph_mode, + MISC_SHU_RX_SELPH_MODE_DQSIEN_SELPH_SERMODE, 3); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rx_selph_mode, + MISC_SHU_RX_SELPH_MODE_RODT_SELPH_SERMODE, 2, + MISC_SHU_RX_SELPH_MODE_RANK_SELPH_SERMODE, 2); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_rdat1, + MISC_SHU_RDAT1_R_DMRDSEL_DIV2_OPT, 0, + MISC_SHU_RDAT1_R_DMRDSEL_LOBYTE_OPT, 0, + MISC_SHU_RDAT1_R_DMRDSEL_HIBYTE_OPT, 0); + break; + default:dramc_dbg("ERROR:Unexcepted subsys->dvfs_core.dq_p2s_ratio = %d\n", + subsys->dvfs_core->dq_p2s_ratio); + break; + } + SET32_BITFIELDS(&ch[0].ao.shu_rk[0].shurk_cke_ctrl, + SHURK_CKE_CTRL_CKE_DBE_CNT, 0); +} + +static void dig_config_shuf_misc_dqsgretry(dram_freq_grp freq_group) +{ + bool is_high_speed = (freq_group == DDRFREQ_2133); + + dramc_dbg("[DIG_SHUF_CONFIG] DQSG_RETRY\n"); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_dqsg_retry1, + MISC_SHU_DQSG_RETRY1_RETRY_SW_RESET, 0, + MISC_SHU_DQSG_RETRY1_RETRY_SW_EN, 0, + MISC_SHU_DQSG_RETRY1_RETRY_DDR1866_PLUS, is_high_speed, + MISC_SHU_DQSG_RETRY1_RETRY_ONCE, 0, + MISC_SHU_DQSG_RETRY1_RETRY_3TIMES, is_high_speed, + MISC_SHU_DQSG_RETRY1_RETRY_1RANK, 0, + MISC_SHU_DQSG_RETRY1_RETRY_BY_RANK, is_high_speed, + MISC_SHU_DQSG_RETRY1_RETRY_DM4BYTE, 0, + MISC_SHU_DQSG_RETRY1_RETRY_DQSIENLAT, 0, + MISC_SHU_DQSG_RETRY1_RETRY_STBENCMP_ALLBYTE, 0); + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_dqsg_retry1, + MISC_SHU_DQSG_RETRY1_XSR_DQSG_RETRY_EN, 0, + MISC_SHU_DQSG_RETRY1_XSR_RETRY_SPM_MODE, 0, + MISC_SHU_DQSG_RETRY1_RETRY_CMP_DATA, 0, + MISC_SHU_DQSG_RETRY1_RETRY_ALE_BLOCK_MASK, 0, + MISC_SHU_DQSG_RETRY1_RETRY_RDY_SEL_DLE, is_high_speed, + MISC_SHU_DQSG_RETRY1_RETRY_USE_NON_EXTEND, is_high_speed, + MISC_SHU_DQSG_RETRY1_RETRY_USE_CG_GATING, is_high_speed, + MISC_SHU_DQSG_RETRY1_RETRY_ROUND_NUM, 1, + MISC_SHU_DQSG_RETRY1_RETRY_RANKSEL_FROM_PHY, 0, + MISC_SHU_DQSG_RETRY1_RETRY_PA_DISABLE, 0, + MISC_SHU_DQSG_RETRY1_RETRY_STBEN_RESET_MSK, 0, + MISC_SHU_DQSG_RETRY1_RETRY_USE_BURST_MODE, is_high_speed); +} + +static void dig_config_shuf_dbi(dramc_subsys_config *subsys) +{ + u8 rd_dbi_en = 0, wr_dbi_en = 0; + dramc_dbg("[DIG_SHUF_CONFIG] DBI\n"); + + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq7, + SHU_B0_DQ7_R_DMDQMDBI_SHU_B0, rd_dbi_en, + SHU_B0_DQ7_R_DMDQMDBI_EYE_SHU_B0, rd_dbi_en); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq7, + SHU_B1_DQ7_R_DMDQMDBI_SHU_B1, rd_dbi_en, + SHU_B1_DQ7_R_DMDQMDBI_EYE_SHU_B1, rd_dbi_en); + SET32_BITFIELDS(&ch[0].ao.shu_tx_set0, + SHU_TX_SET0_DBIWR, wr_dbi_en); +} + +static void dig_config_shuf_dvfswlrl(dramc_subsys_config *subsys) +{ + dram_config *lp4_init = subsys->lp4_init; + + u8 hwset_mr13_op_value =0; + u8 hwset_vrcg_op_value =0; + u8 hwset_mr2_op_value =0; + + dramc_dbg("[DIG_SHUF_CONFIG] DVFSRLWL\n"); + + hwset_mr13_op_value = ((lp4_init->work_fsp & 1) << 7) | + ((lp4_init->work_fsp & 1) << 6) | (( 0 << 5) | 8); + hwset_vrcg_op_value = ((lp4_init->work_fsp & 1) << 7) | + ((lp4_init->work_fsp & 1) << 6); + hwset_mr2_op_value = ((lp4_init->mr_wl & 7) << 3) | (lp4_init->mr_wl & 7); + + SET32_BITFIELDS(&ch[0].ao.shu_hwset_mr13, + SHU_HWSET_MR13_HWSET_MR13_OP, hwset_mr13_op_value); + SET32_BITFIELDS(&ch[0].ao.shu_hwset_vrcg, + SHU_HWSET_VRCG_HWSET_VRCG_OP, hwset_vrcg_op_value); + SET32_BITFIELDS(&ch[0].ao.shu_hwset_vrcg, + SHU_HWSET_VRCG_VRCGDIS_PRDCNT, 0xb); + SET32_BITFIELDS(&ch[0].ao.shu_hwset_mr2, + SHU_HWSET_MR2_HWSET_MR2_OP, hwset_mr2_op_value); +} + +static void dig_config_dvfs_dependence(dramc_subsys_config *subsys) +{ + dig_config_shuf_dvfswlrl(subsys); + + SET32_BITFIELDS(&ch[0].phy_ao.misc_shu_dvfsdll, + MISC_SHU_DVFSDLL_R_DLL_IDLE, 0x37, + MISC_SHU_DVFSDLL_R_2ND_DLL_IDLE, 0x4d, + MISC_SHU_DVFSDLL_R_BYPASS_1ST_DLL, subsys->a_cfg->all_slave_en, + MISC_SHU_DVFSDLL_R_BYPASS_2ND_DLL, 0); +} + +static void dramc_common_config(const struct ddr_cali *cali, + dramc_subsys_config *subsys) +{ + u8 rd2mrr_extend_en = 1; + u8 ebg_en = 0; + u8 tmrri_mode = 1; + u8 noblock_ale_en = 1; + u8 runtime_mrr = 1; + u8 pinmux = get_pinmux_type(cali); + + SET32_BITFIELDS(&ch[0].ao.ddrcommon0, + DDRCOMMON0_BK8EN, 1, + DDRCOMMON0_LPDDR5EN, 0, + DDRCOMMON0_LPDDR4EN, 1, + DDRCOMMON0_TRCDEARLY, 0); + SET32_BITFIELDS(&ch[0].phy_ao.misc_ctrl1, + MISC_CTRL1_R_DMPINMUX, pinmux); + SET32_BITFIELDS(&ch[0].ao.rx_set0, + RX_SET0_DM4TO1MODE, 0); + SET32_BITFIELDS(&ch[0].ao.refctrl0, + REFCTRL0_REF_PREGATE_CNT, 5, + REFCTRL0_DMPGVLD_IG, 0, + REFCTRL0_DISBYREFNUM, 4, + REFCTRL0_PBREF_DISBYRATE, 0, + REFCTRL0_PBREF_DISBYREFNUM, 1, + REFCTRL0_PBREF_BK_REFA_ENA, 1, + REFCTRL0_PBREF_BK_REFA_NUM, 1); + SET32_BITFIELDS(&ch[0].ao.refctrl1, + REFCTRL1_PB2AB_OPT, 1, + REFCTRL1_REF_QUE_AUTOSAVE_EN, 1, + REFCTRL1_REF_OVERHEAD_ALL_REFPB_ENA, 0, + REFCTRL1_REF_OVERHEAD_SLOW_REFPB_ENA, 1, + REFCTRL1_REF_OVERHEAD_ALL_REFAL_ENA, 0, + REFCTRL1_REF_OVERHEAD_SLOW_REFAL_ENA, 0, + REFCTRL1_REF_OVERHEAD_RATE_REFPB_ENA, 0, + REFCTRL1_REF_OVERHEAD_RATE_REFAL_ENA, 0); + SET32_BITFIELDS(&ch[0].ao.refctrl2, + REFCTRL2_REF_OVERHEAD_RATE, 0); + SET32_BITFIELDS(&ch[0].ao.dllfrz_ctrl, + DLLFRZ_CTRL_UPDBYWR, 0, + DLLFRZ_CTRL_DLLFRZ, 1); + SET32_BITFIELDS(&ch[0].ao.dramctrl, + DRAMCTRL_ADRDECEN, 0, + DRAMCTRL_PREALL_OPTION, 1, + DRAMCTRL_REQQUE_THD_EN, 1, + DRAMCTRL_DYNMWREN, 1, + DRAMCTRL_AG0MWR, 0, + DRAMCTRL_ADRBIT3DEC, 0, + DRAMCTRL_CTOREQ_HPRI_OPT, 0); + SET32_BITFIELDS(&ch[0].ao.actiming_ctrl, + ACTIMING_CTRL_CLKWITRFC, 0, + ACTIMING_CTRL_SEQCLKRUN3, 1, + ACTIMING_CTRL_FASTW2R, 0, + ACTIMING_CTRL_REFBW_FREN, 0, + ACTIMING_CTRL_TMRRICHKDIS, 1, + ACTIMING_CTRL_REFNA_OPT, 0, + ACTIMING_CTRL_MRRIOPT, !tmrri_mode, + ACTIMING_CTRL_TMRRIBYRK_DIS, !tmrri_mode, + ACTIMING_CTRL_TMRRICHKDIS, tmrri_mode); + SET32_BITFIELDS(&ch[0].ao.arbctl, + ARBCTL_MAXPENDCNT, 0x80, + ARBCTL_WDATACNTDIS, 0); + SET32_BITFIELDS(&ch[0].ao.dram_clk_ctrl, + DRAM_CLK_CTRL_CLK_EN, 1); + SET32_BITFIELDS(&ch[0].ao.clkar, + CLKAR_DCMREF_OPT, 1); + SET32_BITFIELDS(&ch[0].ao.dramc_pd_ctrl, + DRAMC_PD_CTRL_COMBCLKCTRL, 1, + DRAMC_PD_CTRL_MIOCKCTRLOFF, 0, + DRAMC_PD_CTRL_PHYCLKDYNGEN, 1, + DRAMC_PD_CTRL_DCMEN, 1, + DRAMC_PD_CTRL_DCMEN2, 1, + DRAMC_PD_CTRL_PG_DCM_OPT, 0); + SET32_BITFIELDS(&ch[0].ao.rkcfg, + RKCFG_CKE2RANK, 0, + RKCFG_MRS2RK, 0); + SET32_BITFIELDS(&ch[0].ao.ckectrl, + CKECTRL_CKE2RANK_OPT2, 1, + CKECTRL_CKEON, 1, + CKECTRL_CKETIMER_SEL, 0, + CKECTRL_CKE2RANK_OPT8, 1, + CKECTRL_RUNTIMEMRRMIODIS, !runtime_mrr, + CKECTRL_FASTWAKE_SEL, 1, + CKECTRL_CKEPBDIS, 1, + CKECTRL_RUNTIMEMRRCKEFIX, !tmrri_mode, + CKECTRL_CKELCKFIX, 0); + SET32_BITFIELDS(&ch[0].ao.sref_dpd_ctrl, + SREF_DPD_CTRL_SELFREF_AUTOSAVE_EN, 1, + SREF_DPD_CTRL_GT_SYNC_MASK, 0, + SREF_DPD_CTRL_DAT_SYNC_MASK, 0, + SREF_DPD_CTRL_PHY_SYNC_MASK, 0, + SREF_DPD_CTRL_LPSM_BYPASS_B, 1, + SREF_DPD_CTRL_SREF_PRD_OPT, 0, + SREF_DPD_CTRL_CLR_EN, 1, + SREF_DPD_CTRL_SRFPD_DIS, 0, + SREF_DPD_CTRL_SREFDLY, 8, + SREF_DPD_CTRL_SREF_HW_EN, 1); + SET32_BITFIELDS(&ch[0].ao.scheduler_com, + SCHEDULER_COM_DISRDPHASE1, 1, + SCHEDULER_COM_MWHPRIEN, 1, + SCHEDULER_COM_RWHPRICTL, 0, + SCHEDULER_COM_RWOFOEN, 1, + SCHEDULER_COM_RWSPLIT, 1); + SET32_BITFIELDS(&ch[0].ao.perfctl0, + PERFCTL0_EMILLATEN, 1, + PERFCTL0_RWHPRIEN, 1, + PERFCTL0_EBG_EN, ebg_en, + PERFCTL0_RWLLATEN, 1, + PERFCTL0_RWAGEEN, 1, + PERFCTL0_WFLUSHEN, 1, + PERFCTL0_REORDEREN, 0, + PERFCTL0_REORDER_MODE, 0); + SET32_BITFIELDS(&ch[0].ao.hw_mrr_fun, + HW_MRR_FUN_TMRR_ENA, runtime_mrr, + HW_MRR_FUN_TRPMRR_EN, 0, + HW_MRR_FUN_TRCDMRR_EN, 0, + HW_MRR_FUN_MRR_HW_HIPRI, 1, + HW_MRR_FUN_TR2MRR_ENA, rd2mrr_extend_en, + HW_MRR_FUN_R2MRRHPRICTL, rd2mrr_extend_en, + HW_MRR_FUN_MANTMRR_EN, rd2mrr_extend_en); + SET32_BITFIELDS(&ch[0].ao.zq_set0, + ZQ_SET0_ZQCSAD, 0x0a, + ZQ_SET0_ZQCSOP, 0x56); + SET32_BITFIELDS(&ch[0].ao.mpc_option, + MPC_OPTION_MPCRKEN, 1); + SET32_BITFIELDS(&ch[0].ao.mpc_ctrl, + MPC_CTRL_REFR_BLOCKEN, !runtime_mrr, + MPC_CTRL_ZQ_BLOCKALE_OPT, noblock_ale_en, + MPC_CTRL_MPC_BLOCKALE_OPT, noblock_ale_en, + MPC_CTRL_MPC_BLOCKALE_OPT1, noblock_ale_en, + MPC_CTRL_MPC_BLOCKALE_OPT2, noblock_ale_en); + SET32_BITFIELDS(&ch[0].ao.hmr4, + HMR4_SPDR_MR4_OPT, 1); + SET32_BITFIELDS(&ch[0].ao.rk[0].rk_test2_a1, + RK_TEST2_A1_TEST2_BASE, 0x010000); + SET32_BITFIELDS(&ch[0].ao.test2_a2, + TEST2_A2_TEST2_OFF, 0x000020); + SET32_BITFIELDS(&ch[0].ao.test2_a3, + TEST2_A3_TESTAUDPAT, 1, + TEST2_A3_TEST2WREN2_HW_EN, 1); + SET32_BITFIELDS(&ch[0].ao.test2_a4, + TEST2_A4_TESTAUDINIT, 0x11, + TEST2_A4_TESTAUDINC, 0x0d, + TEST2_A4_TESTAGENTRKSEL, 0x04); + SET32_BITFIELDS(&ch[0].ao.cmd_dec_ctrl0, + CMD_DEC_CTRL0_RKMODE, 1); + SET32_BITFIELDS(&ch[0].ao.misctl0, + MISCTL0_PAGDIS, 0, + MISCTL0_PBC_ARB_E1T, 0, + MISCTL0_REFA_ARB_EN2, 1, + MISCTL0_PBC_ARB_EN, 1, + MISCTL0_REFP_ARB_EN2, 1, + MISCTL0_EMIPREEN, 0, + MISCTL0_PG_WAKEUP_OPT, 1); + SET32_BITFIELDS(&ch[0].ao.scsmctrl, + SCSMCTRL_SC_PG_MAN_DIS, 1, + SCSMCTRL_SC_PG_UPD_OPT, tmrri_mode); + SET32_BITFIELDS(&ch[0].ao.shuctrl1, + SHUCTRL1_FC_PRDCNT, 0x1a); + SET32_BITFIELDS(&ch[0].ao.dvfs_timing_ctrl1, + DVFS_TIMING_CTRL1_DMSHU_CNT, 1); + SET32_BITFIELDS(&ch[0].ao.refpend1, + REFPEND1_MPENDREFCNT_TH0, 0x5, + REFPEND1_MPENDREFCNT_TH1, 0x5, + REFPEND1_MPENDREFCNT_TH2, 0x5, + REFPEND1_MPENDREFCNT_TH3, 0x5, + REFPEND1_MPENDREFCNT_TH4, 0x5, + REFPEND1_MPENDREFCNT_TH5, 0x3, + REFPEND1_MPENDREFCNT_TH6, 0x3, + REFPEND1_MPENDREFCNT_TH7, 0x3); + SET32_BITFIELDS(&ch[0].ao.cbt_wlev_ctrl1, + CBT_WLEV_CTRL1_CATRAIN_INTV, 0x10, + CBT_WLEV_CTRL1_CATRAINLAT, 0x3); + SET32_BITFIELDS(&ch[0].ao.tx_set0, + TX_SET0_DRSCLR_EN, 1, + TX_SET0_RK_SCINPUT_OPT, !tmrri_mode); + + if (subsys->a_cfg->aphy_comb_en == 1) + SET32_BITFIELDS(&ch[0].ao.tx_set0, TX_SET0_OE_DOWNGRADE, 1); + + SET32_BITFIELDS(&ch[0].ao.dqsoscr, + DQSOSCR_SREF_TXUI_RELOAD_OPT, 0, + DQSOSCR_SREF_TXPI_RELOAD_OPT, 1); + SET32_BITFIELDS(&ch[0].ao.dummy_rd, + DUMMY_RD_DRS_SELFWAKE_DMYRD_DIS, 1, + DUMMY_RD_RANK_NUM, 2, + DUMMY_RD_DUMMY_RD_SW, 1, + DUMMY_RD_DQSG_DMYRD_EN, 1); + SET32_BITFIELDS(&ch[0].ao.dummy_rd_intv, + DUMMY_RD_INTV_DUMMY_RD_CNT7, 0, + DUMMY_RD_INTV_DUMMY_RD_CNT6, 1, + DUMMY_RD_INTV_DUMMY_RD_CNT5, 1, + DUMMY_RD_INTV_DUMMY_RD_CNT4, 0, + DUMMY_RD_INTV_DUMMY_RD_CNT3, 1, + DUMMY_RD_INTV_DUMMY_RD_CNT2, 0, + DUMMY_RD_INTV_DUMMY_RD_CNT1, 0, + DUMMY_RD_INTV_DUMMY_RD_CNT0, 0); + SET32_BITFIELDS(&ch[0].ao.rk[0].rk_dqsosc, + RK_DQSOSC_RK0_BYTE_MODE, cali->cbt_mode[RANK_0]); + SET32_BITFIELDS(&ch[0].ao.rk[1].rk_dqsosc, + RK_DQSOSC_RK0_BYTE_MODE, cali->cbt_mode[RANK_1]); + SET32_BITFIELDS(&ch[0].ao.tx_tracking_set0, + TX_TRACKING_SET0_TX_TRACKING_OPT, 0); + SET32_BITFIELDS(&ch[0].ao.tx_cg_set0, + TX_CG_SET0_SELPH_4LCG_DIS, 1); + SET32_BITFIELDS(&ch[0].ao.tx_freq_ratio_old_mode0, + TX_FREQ_RATIO_OLD_MODE0_SHUFFLE_LEVEL_MODE_SELECT, 1); + SET32_BITFIELDS(&ch[0].ao.swcmd_ctrl1, + SWCMD_CTRL1_WRFIFO_MODE2, 1); + SET32_BITFIELDS(&ch[0].ao.dbg_cmddec_cmdsel0, + DBG_CMDDEC_CMDSEL0_RANK0_10GBEN, subsys->lp4_init->ex_row_en[0], + DBG_CMDDEC_CMDSEL0_RANK1_10GBEN, subsys->lp4_init->ex_row_en[1]); + SET32_BITFIELDS(&ch[0].ao.dbiwr_protect, + DBIWR_PROTECT_DBIWR_IMP_EN, 1, + DBIWR_PROTECT_DBIWR_PINMUX_EN, 0); + SET32_BITFIELDS(&ch[0].ao.rx_set0, + RX_SET0_PRE_DLE_VLD_OPT, 1, + RX_SET0_DATLAT_PDLE_TH, 7); + SET32_BITFIELDS(&ch[0].phy_ao.misc_sram_dma0, + MISC_SRAM_DMA0_PENABLE_LAT_WR, 1, + MISC_SRAM_DMA0_KEEP_APB_ARB_ENA, 1, + MISC_SRAM_DMA0_KEEP_SRAM_ARB_ENA, 1); + SET32_BITFIELDS(&mtk_dpm->mclk_div, + SSPM_MCLK_DIV_MCLK_DCM_EN, 1); + + write32(&ch[0].phy_ao.misc_dbg_irq_ctrl1, 0xFFFFFFFF); + write32(&ch[0].phy_ao.misc_dbg_irq_ctrl4, 0xFFFFFFFF); + write32(&ch[0].phy_ao.misc_dbg_irq_ctrl7, 0xFFFFFFFF); +} + +static void dvfs_pre_config(dramc_subsys_config *subsys) +{ + u32 mcp_en = 0; + u32 ref_104m_en = 1; + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + dramc_dbg("Enter into dvfs_pre_config\n"); + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[0].b0_dq11, + B0_DQ11_DMY_DQ11_B0, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.dvs_b[1].b0_dq11, + B1_DQ11_DMY_DQ11_B1, 1); + SET32_BITFIELDS(&ch[chn].ao.dvfs_ctrl0, + DVFS_CTRL0_VRCG_EN, 1, + DVFS_CTRL0_DVFS_SYNC_MASK, 0, + DVFS_CTRL0_MR13_SHU_EN, 1, + DVFS_CTRL0_HWSET_WLRL, 1, + DVFS_CTRL0_MRWWOPRA, 0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_rg_dfs_ctrl, + MISC_RG_DFS_CTRL_SPM_DVFS_CONTROL_SEL, 0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_sram_dma0, + MISC_SRAM_DMA0_DMA_TIMER_EN, 0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_sram_dma1, + MISC_SRAM_DMA1_SPM_RESTORE_STEP_EN, 0x1ffff); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_cg_ctrl7, + MISC_CG_CTRL7_ARMCTL_CK_OUT_CG_SEL, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_dvfsctl, + MISC_DVFSCTL_R_DVFS_PICG_POSTPONE, 1, + MISC_DVFSCTL_R_DMSHUFFLE_CHANGE_FREQ_OPT, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_dvfsctl2, + MISC_DVFSCTL2_R_CDC_MUX_SEL_OPTION, 0, + MISC_DVFSCTL2_R_DVFS_SYNC_MODULE_RST_SEL, 0); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_dvfsctl2, + MISC_DVFSCTL2_R_DVFS_CDC_OPTION, 1); + SET32_BITFIELDS(&ch[chn].ao.dvfs_ctrl0, + DVFS_CTRL0_DVFS_CKE_OPT, 0, + DVFS_CTRL0_SCARB_PRI_OPT, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_dvfsctl3, + MISC_DVFSCTL3_RG_PHY_ST_DELAY_AFT_CHG_TO_MCLK, 1, + MISC_DVFSCTL3_RG_PHY_ST_DELAY_AFT_CHG_TO_BCLK, 0, + MISC_DVFSCTL3_RG_PHY_ST_DELAY_BEF_CHG_TO_MCLK, 0, + MISC_DVFSCTL3_RG_PHY_ST_DELAY_BEF_CHG_TO_BCLK, 1, + MISC_DVFSCTL3_RG_DVFS_MEM_CK_SEL_DESTI, 3, + MISC_DVFSCTL3_RG_DVFS_MEM_CK_SEL_SOURCE, 1, + MISC_DVFSCTL3_RG_CNT_PHY_ST_DELAY_BEF_CHG_TO_BCLK, 7, + MISC_DVFSCTL3_RG_CNT_PHY_ST_DELAY_AFT_CHG_TO_MCLK, 1, + MISC_DVFSCTL3_RG_CNT_PHY_ST_DELAY_AFT_CHG_TO_BCLK, 0x3f); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_clk_ctrl, + MISC_CLK_CTRL_DVFS_CLK_MEM_SEL, 1, + MISC_CLK_CTRL_DVFS_MEM_CK_MUX_UPDATE_EN, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_dvfsctl3, + MISC_DVFSCTL3_RG_CNT_PHY_ST_DELAY_AFT_CHG_TO_BCLK, 0x10); + SET32_BITFIELDS(&ch[chn].ao.dvfs_timing_ctrl1, + DVFS_TIMING_CTRL1_DMSHU_CNT, 1, + DVFS_TIMING_CTRL1_SHU_PERIOD_GO_ZERO_CNT, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_dvfsctl2, + MISC_DVFSCTL2_R_DVFS_CDC_OPTION, 1, + MISC_DVFSCTL2_R_DVFS_DLL_CHA, 0, + MISC_DVFSCTL2_RG_TOPCK_FMEM_CK_BLOCK_DURING_DFS, 1, + MISC_DVFSCTL2_R_DVFS_PARK_N, 1, + MISC_DVFSCTL2_R_DVFS_OPTION, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_ckmux_sel, + MISC_CKMUX_SEL_RG_52M_104M_SEL, ref_104m_en); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_shu_opt, + MISC_SHU_OPT_R_DQB0_SHU_PHY_GATING_RESETB_SPM_EN, 1, + MISC_SHU_OPT_R_DQB0_SHU_PHDET_SPM_EN, 2, + MISC_SHU_OPT_R_DQB1_SHU_PHY_GATING_RESETB_SPM_EN, 1, + MISC_SHU_OPT_R_DQB1_SHU_PHDET_SPM_EN, 2, + MISC_SHU_OPT_R_CA_SHU_PHY_GATING_RESETB_SPM_EN, 1, + MISC_SHU_OPT_R_CA_SHU_PHDET_SPM_EN, 1); + SET32_BITFIELDS(&ch[chn].phy_ao.misc_dvfsctl, + MISC_DVFSCTL_R_DVFS_PICG_MARGIN_NEW, (ref_104m_en==1)?3:1, + MISC_DVFSCTL_R_DVFS_PICG_MARGIN2_NEW, (ref_104m_en==1)?3:1, + MISC_DVFSCTL_R_DVFS_PICG_MARGIN3_NEW, (ref_104m_en==1)?3:1); + } + + if (subsys->a_cfg->dll_async_en == 0) { + SET32_BITFIELDS(&ch[1].phy_ao.misc_dvfsctl2, + MISC_DVFSCTL2_R_DVFS_DLL_CHA, 0); + SET32_BITFIELDS(&ch[1].phy_ao.misc_shu_opt, + MISC_SHU_OPT_R_CA_SHU_PHDET_SPM_EN, 2); + } + + if (mcp_en == 1) { + dramc_dbg("MCP Enable leading 2ch's sync singles should adjust delay margin."); + SET32_BITFIELDS(&ch[1].phy_ao.misc_dvfsctl, + MISC_DVFSCTL_R_DVFS_PICG_MARGIN_NEW, + (ref_104m_en==1) ? 6 : 4); + SET32_BITFIELDS(&ch[1].phy_ao.misc_dvfsctl3, + MISC_DVFSCTL3_RG_CNT_PHY_ST_DELAY_BEF_CHG_TO_BCLK, 9); + } + + SET32_BITFIELDS(&ch[0].phy_ao.misc_ckmux_sel, + MISC_CKMUX_SEL_FMEM_CK_MUX, 1); + SET32_BITFIELDS(&ch[0].ao.dvfs_ctrl0, + DVFS_CTRL0_R_DRAMC_CHA, 0, + DVFS_CTRL0_SHU_PHYRST_SEL, 0); + SET32_BITFIELDS(&ch[1].phy_ao.misc_ckmux_sel, + MISC_CKMUX_SEL_FMEM_CK_MUX, 3); + SET32_BITFIELDS(&ch[1].ao.dvfs_ctrl0, + DVFS_CTRL0_R_DRAMC_CHA, 0, + DVFS_CTRL0_SHU_PHYRST_SEL, 1); + dramc_set_broadcast(DRAMC_BROADCAST_ON); +} + +static void ddrphy_picg_config(void) +{ + u8 picg_mode = 1; + u8 misc_cg_en = 1; + u8 misc_cg_reverse = 0; + + dramc_dbg("Enter into PICG configuration\n"); + SET32_BITFIELDS(&ch[0].phy_ao.misc_ctrl4, + MISC_CTRL4_R_OPT2_MPDIV_CG, picg_mode, + MISC_CTRL4_R_OPT2_CG_MCK, picg_mode, + MISC_CTRL4_R_OPT2_CG_DQM, picg_mode, + MISC_CTRL4_R_OPT2_CG_DQS, picg_mode, + MISC_CTRL4_R_OPT2_CG_DQ, picg_mode, + MISC_CTRL4_R_OPT2_CG_DQSIEN, picg_mode); + SET32_BITFIELDS(&ch[0].phy_ao.misc_ctrl3, + MISC_CTRL3_ARPI_MPDIV_CG_DQ_OPT, !picg_mode, + MISC_CTRL3_ARPI_CG_MCK_DQ_OPT, !picg_mode, + MISC_CTRL3_ARPI_CG_DQS_OPT, !picg_mode, + MISC_CTRL3_ARPI_CG_DQ_OPT, !picg_mode); + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl0, + MISC_CG_CTRL0_RG_CG_DRAMC_OFF_DISABLE, !misc_cg_en, + MISC_CG_CTRL0_RG_CG_PHY_OFF_DIABLE, !misc_cg_en, + MISC_CG_CTRL0_RG_CG_COMB_OFF_DISABLE, !misc_cg_en, + MISC_CG_CTRL0_RG_CG_CMD_OFF_DISABLE, !misc_cg_en, + MISC_CG_CTRL0_RG_CG_COMB0_OFF_DISABLE, !misc_cg_en, + MISC_CG_CTRL0_RG_CG_COMB1_OFF_DISABLE, !misc_cg_en, + MISC_CG_CTRL0_RG_CG_RX_CMD_OFF_DISABLE, !misc_cg_en, + MISC_CG_CTRL0_RG_CG_RX_COMB0_OFF_DISABLE, !misc_cg_en, + MISC_CG_CTRL0_RG_CG_RX_COMB1_OFF_DISABLE, !misc_cg_en, + MISC_CG_CTRL0_RG_CG_INFRA_OFF_DISABLE, !misc_cg_en); + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl2, + MISC_CG_CTRL2_RG_MEM_DCM_CG_OFF_DISABLE, !misc_cg_en, + MISC_CG_CTRL2_RG_PIPE0_CG_OFF_DISABLE, !misc_cg_en, + MISC_CG_CTRL2_RG_PHY_CG_OFF_DISABLE, !misc_cg_en); + SET32_BITFIELDS(&ch[0].phy_ao.misc_cg_ctrl5, + MISC_CG_CTRL5_R_DQ1_DLY_DCM_EN, misc_cg_en, + MISC_CG_CTRL5_R_DQ0_DLY_DCM_EN, misc_cg_en, + MISC_CG_CTRL5_R_CA_DLY_DCM_EN, misc_cg_en, + MISC_CG_CTRL5_R_DQ1_PI_DCM_EN, misc_cg_en, + MISC_CG_CTRL5_R_DQ0_PI_DCM_EN, misc_cg_en, + MISC_CG_CTRL5_R_CA_PI_DCM_EN, misc_cg_en); + + if (misc_cg_reverse == 1) { + SET32_BITFIELDS(&ch[0].ao.rx_cg_set0, + RX_CG_SET0_RDATCKAR, 1, + RX_CG_SET0_RDYCKAR, 1); + SET32_BITFIELDS(&ch[0].ao.sref_dpd_ctrl, + SREF_DPD_CTRL_CMDCKAR, 1); + SET32_BITFIELDS(&ch[0].ao.dcm_ctrl0, + DCM_CTRL0_BCLKAR, 1); + SET32_BITFIELDS(&ch[0].ao.tx_cg_set0, + TX_CG_SET0_PSELAR, 1, + TX_CG_SET0_DWCLKRUN, 1); + SET32_BITFIELDS(&ch[0].ao.scsmctrl_cg, + SCSMCTRL_CG_SCSM_CGAR, 1, + SCSMCTRL_CG_SCARB_SM_CGAR, 1); + SET32_BITFIELDS(&ch[0].ao.tx_tracking_set0, + TX_TRACKING_SET0_RDDQSOSC_CGAR, 1, + TX_TRACKING_SET0_HMRRSEL_CGAR, 1, + TX_TRACKING_SET0_TXUIPI_CAL_CGAR, 1); + SET32_BITFIELDS(&ch[0].ao.zq_set0, + ZQ_SET0_ZQCS_MASK_SEL_CGAR, 1); + SET32_BITFIELDS(&ch[0].ao.actiming_ctrl, + ACTIMING_CTRL_CLKWITRFC, 1, + ACTIMING_CTRL_SEQCLKRUN3, 1, + ACTIMING_CTRL_SEQCLKRUN2, 1, + ACTIMING_CTRL_SEQCLKRUN, 1); + SET32_BITFIELDS(&ch[0].ao.clkar, + CLKAR_REQQUECLKRUN, 1, + CLKAR_REQQUE_PACG_DIS, 1); + SET32_BITFIELDS(&ch[0].ao.dramc_pd_ctrl, + DRAMC_PD_CTRL_PHYGLUECLKRUN, 1); + SET32_BITFIELDS(&ch[0].ao.test2_a3, + TEST2_A3_TESTCLKRUN, 1); + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) + SET32_BITFIELDS(&ch[chn].ao.dvfs_ctrl0, + DVFS_CTRL0_DVFS_CG_OPT, 1); + + dramc_set_broadcast(DRAMC_BROADCAST_ON); + SET32_BITFIELDS(&ch[0].phy_ao.misc_dutyscan1, + MISC_DUTYSCAN1_EYESCAN_DQS_OPT, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[0].shu_b0_dq8, + SHU_B0_DQ8_R_DMRANK_RXDLY_PIPE_CG_IG_B0, 1, + SHU_B0_DQ8_R_RMRODTEN_CG_IG_B0, 1, + SHU_B0_DQ8_R_RMRX_TOPHY_CG_IG_B0, 1, + SHU_B0_DQ8_R_DMRXDVS_RDSEL_PIPE_CG_IG_B0, 1, + SHU_B0_DQ8_R_DMRXDVS_RDSEL_TOG_PIPE_CG_IG_B0, 1, + SHU_B0_DQ8_R_DMRXDLY_CG_IG_B0, 1, + SHU_B0_DQ8_R_DMDQSIEN_FLAG_SYNC_CG_IG_B0, 1, + SHU_B0_DQ8_R_DMDQSIEN_FLAG_PIPE_CG_IG_B0, 1, + SHU_B0_DQ8_R_DMDQSIEN_RDSEL_PIPE_CG_IG_B0, 1, + SHU_B0_DQ8_R_DMDQSIEN_RDSEL_TOG_PIPE_CG_IG_B0, 1, + SHU_B0_DQ8_R_DMRANK_PIPE_CG_IG_B0, 1, + SHU_B0_DQ8_R_DMRANK_CHG_PIPE_CG_IG_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.byte[1].shu_b0_dq8, + SHU_B1_DQ8_R_DMRANK_RXDLY_PIPE_CG_IG_B1, 1, + SHU_B1_DQ8_R_RMRODTEN_CG_IG_B1, 1, + SHU_B1_DQ8_R_RMRX_TOPHY_CG_IG_B1, 1, + SHU_B1_DQ8_R_DMRXDVS_RDSEL_PIPE_CG_IG_B1, 1, + SHU_B1_DQ8_R_DMRXDVS_RDSEL_TOG_PIPE_CG_IG_B1, 1, + SHU_B1_DQ8_R_DMRXDLY_CG_IG_B1, 1, + SHU_B1_DQ8_R_DMDQSIEN_FLAG_SYNC_CG_IG_B1, 1, + SHU_B1_DQ8_R_DMDQSIEN_FLAG_PIPE_CG_IG_B1, 1, + SHU_B1_DQ8_R_DMDQSIEN_RDSEL_PIPE_CG_IG_B1, 1, + SHU_B1_DQ8_R_DMDQSIEN_RDSEL_TOG_PIPE_CG_IG_B1, 1, + SHU_B1_DQ8_R_DMRANK_PIPE_CG_IG_B1, 1, + SHU_B1_DQ8_R_DMRANK_CHG_PIPE_CG_IG_B1, 1); + } + + dramc_dbg("Exit from PICG configuration\n"); +} + +static void io_release(void) +{ + SET32_BITFIELDS(&ch[0].phy_ao.misc_ctrl1, + MISC_CTRL1_R_DM_TX_ARCLK_OE, 1, + MISC_CTRL1_R_DM_TX_ARCMD_OE, 1); + + SET32_BITFIELDS(&ch[0].phy_ao.ca_cmd7, + CA_CMD7_RG_TX_ARCLKB_PULL_DN, 0, + CA_CMD7_RG_TX_ARCLKB_PULL_UP, 0, + CA_CMD7_RG_TX_ARCLK_PULL_DN, 0, + CA_CMD7_RG_TX_ARCLK_PULL_UP, 0, + CA_CMD7_RG_TX_ARCS0_PULL_DN, 0, + CA_CMD7_RG_TX_ARCS0_PULL_UP, 0, + CA_CMD7_RG_TX_ARCMD_PULL_DN, 0, + CA_CMD7_RG_TX_ARCMD_PULL_UP, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq7, + B0_DQ7_RG_TX_ARDQS0B_PULL_DN_B0, 0, + B0_DQ7_RG_TX_ARDQS0B_PULL_UP_B0, 0, + B0_DQ7_RG_TX_ARDQS0_PULL_DN_B0, 0, + B0_DQ7_RG_TX_ARDQS0_PULL_UP_B0, 0, + B0_DQ7_RG_TX_ARDQM0_PULL_DN_B0, 0, + B0_DQ7_RG_TX_ARDQM0_PULL_UP_B0, 0, + B0_DQ7_RG_TX_ARDQ_PULL_DN_B0, 0, + B0_DQ7_RG_TX_ARDQ_PULL_UP_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq7, + B1_DQ7_RG_TX_ARDQS0B_PULL_DN_B1, 0, + B1_DQ7_RG_TX_ARDQS0B_PULL_UP_B1, 0, + B1_DQ7_RG_TX_ARDQS0_PULL_DN_B1, 0, + B1_DQ7_RG_TX_ARDQS0_PULL_UP_B1, 0, + B1_DQ7_RG_TX_ARDQM0_PULL_DN_B1, 0, + B1_DQ7_RG_TX_ARDQM0_PULL_UP_B1, 0, + B1_DQ7_RG_TX_ARDQ_PULL_DN_B1, 0, + B1_DQ7_RG_TX_ARDQ_PULL_UP_B1, 0); +} + +static void rx_input_config(const struct ddr_cali *cali) +{ + u8 valid_lat = 1; + u8 rdsel_lat = 2; + u8 dq_min = 0; + u8 dq_max = 0xff; + u8 scale = 3; + u8 threadhold = 0; + u8 rx_force_upd = 0; + u8 f_leadlag = 0; + u8 rg_mode_en = 0; + u32 dqs_min = 0; + u32 dqs_max = 0x1ff; + + dramc_dbg("[RX_INPUT] configuration \n"); + + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_rxdvs0, + B0_RXDVS0_R_HWSAVE_MODE_ENA_B0, 1, + B0_RXDVS0_R_DMRXDVS_CNTCMP_OPT_B0, 0, + B0_RXDVS0_R_DMRXDVS_DQIENPRE_OPT_B0, 1, + B0_RXDVS0_R_HWRESTORE_ENA_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_rxdvs0, + B1_RXDVS0_R_HWSAVE_MODE_ENA_B1, 1, + B1_RXDVS0_R_DMRXDVS_CNTCMP_OPT_B1, 0, + B1_RXDVS0_R_DMRXDVS_DQIENPRE_OPT_B1, 1, + B1_RXDVS0_R_HWRESTORE_ENA_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq9, + B0_DQ9_R_DMRXDVS_VALID_LAT_B0, valid_lat, + B0_DQ9_R_DMRXDVS_RDSEL_LAT_B0, rdsel_lat); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq9, + B1_DQ9_R_DMRXDVS_VALID_LAT_B1, valid_lat, + B1_DQ9_R_DMRXDVS_RDSEL_LAT_B1, rdsel_lat); + SET32_BITFIELDS(&ch[0].phy_ao.misc_rxdvs2, + MISC_RXDVS2_R_DMRXDVS_DBG_MON_EN, 1, + MISC_RXDVS2_R_DMRXDVS_DBG_MON_CLR, 0, + MISC_RXDVS2_R_DMRXDVS_DBG_PAUSE_EN, 0, + MISC_RXDVS2_R_DMRXDVS_DEPTH_HALF, 1); + + for (u8 rank = RANK_0; rank < cali->support_ranks; rank++) { + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].rk[rank].rk_b0_rxdvs3, + RK_B0_RXDVS3_RG_RK0_ARDQ_MIN_DLY_B0, dq_min, + RK_B0_RXDVS3_RG_RK0_ARDQ_MAX_DLY_B0, dq_max); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].rk[rank].rk_b0_rxdvs4, + RK_B0_RXDVS4_RG_RK0_ARDQS0_MIN_DLY_B0, dqs_min, + RK_B0_RXDVS4_RG_RK0_ARDQS0_MAX_DLY_B0, dqs_max); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].rk[rank].rk_b0_rxdvs2, + RK_B0_RXDVS2_R_RK0_RX_DLY_FAL_DQS_SCALE_B0, scale, + RK_B0_RXDVS2_R_RK0_RX_DLY_FAL_DQ_SCALE_B0, scale, + RK_B0_RXDVS2_R_RK0_RX_DLY_FAL_TRACK_GATE_ENA_B0, 0, + RK_B0_RXDVS2_R_RK0_RX_DLY_RIS_DQS_SCALE_B0, scale, + RK_B0_RXDVS2_R_RK0_RX_DLY_RIS_DQ_SCALE_B0, scale, + RK_B0_RXDVS2_R_RK0_RX_DLY_RIS_TRACK_GATE_ENA_B0, 0, + RK_B0_RXDVS2_R_RK0_DVS_FDLY_MODE_B0, 1, + RK_B0_RXDVS2_R_RK0_DVS_MODE_B0, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].rk[rank].rk_b0_rxdvs1, + RK_B0_RXDVS1_R_RK0_B0_DVS_TH_LAG, threadhold, + RK_B0_RXDVS1_R_RK0_B0_DVS_TH_LEAD, threadhold); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].rk[rank].rk_b0_rxdvs3, + RK_B1_RXDVS3_RG_RK0_ARDQ_MIN_DLY_B1, dq_min, + RK_B1_RXDVS3_RG_RK0_ARDQ_MAX_DLY_B1, dq_max); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].rk[rank].rk_b0_rxdvs4, + RK_B1_RXDVS4_RG_RK0_ARDQS0_MIN_DLY_B1, dqs_min, + RK_B1_RXDVS4_RG_RK0_ARDQS0_MAX_DLY_B1, dqs_max); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].rk[rank].rk_b0_rxdvs2, + RK_B1_RXDVS2_R_RK0_RX_DLY_FAL_DQS_SCALE_B1, scale, + RK_B1_RXDVS2_R_RK0_RX_DLY_FAL_DQ_SCALE_B1, scale, + RK_B1_RXDVS2_R_RK0_RX_DLY_FAL_TRACK_GATE_ENA_B1, 0, + RK_B1_RXDVS2_R_RK0_RX_DLY_RIS_DQS_SCALE_B1, scale, + RK_B1_RXDVS2_R_RK0_RX_DLY_RIS_DQ_SCALE_B1, scale, + RK_B1_RXDVS2_R_RK0_RX_DLY_RIS_TRACK_GATE_ENA_B1, 0, + RK_B1_RXDVS2_R_RK0_DVS_FDLY_MODE_B1, 1, + RK_B1_RXDVS2_R_RK0_DVS_MODE_B1, 0); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].rk[rank].rk_b0_rxdvs1, + RK_B1_RXDVS1_R_RK0_B1_DVS_TH_LAG, threadhold, + RK_B1_RXDVS1_R_RK0_B1_DVS_TH_LEAD, threadhold); + } + + write32(&ch[0].phy_ao.misc_cg_ctrl1, 0xffffffff); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_rxdvs1, + B0_RXDVS1_F_LEADLAG_TRACK_B0, f_leadlag); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_rxdvs1, + B1_RXDVS1_F_LEADLAG_TRACK_B1, f_leadlag); + + if (rx_force_upd == 1) { + SET32_BITFIELDS(&ch[0].ao.dllfrz_ctrl, + DLLFRZ_CTRL_DLLFRZ_MON_PBREF_OPT, 1, + DLLFRZ_CTRL_DLLFRZ_BLOCKLONG, 1, + DLLFRZ_CTRL_INPUTRXTRACK_BLOCK, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_rxdvs1, + B0_RXDVS1_R_DMRXDVS_UPD_CLR_NORD_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_rxdvs1, + B1_RXDVS1_R_DMRXDVS_UPD_CLR_NORD_B1, 1); + } + + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_dq5, + B1_DQ5_RG_RX_ARDQS0_DVS_EN_B1, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_dq5, + B0_DQ5_RG_RX_ARDQS0_DVS_EN_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].b0_rxdvs0, + B0_RXDVS0_R_RX_DLY_TRACK_ENA_B0, 1, + B0_RXDVS0_R_RX_DLY_TRACK_CG_EN_B0, 1, + B0_RXDVS0_R_RX_DLY_TRACK_SPM_CTRL_B0, 1, + B0_RXDVS0_R_RX_RANKINCTL_B0, 0, + B0_RXDVS0_R_RX_RANKINSEL_B0, 1); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].b0_rxdvs0, + B1_RXDVS0_R_RX_DLY_TRACK_ENA_B1, 1, + B1_RXDVS0_R_RX_DLY_TRACK_CG_EN_B1, 1, + B1_RXDVS0_R_RX_DLY_TRACK_SPM_CTRL_B1, 1, + B1_RXDVS0_R_RX_RANKINCTL_B1, 0, + B1_RXDVS0_R_RX_RANKINSEL_B1, 1); + + for (u8 rank = RANK_0; rank < RANK_MAX; rank++) { + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[0].rk[rank].rk_b0_rxdvs2, + RK_B0_RXDVS2_R_RK0_RX_DLY_FAL_TRACK_GATE_ENA_B0, 1, + RK_B0_RXDVS2_R_RK0_RX_DLY_RIS_TRACK_GATE_ENA_B0, 1, + RK_B0_RXDVS2_R_RK0_DVS_MODE_B0, 2); + SET32_BITFIELDS(&ch[0].phy_ao.dvs_b[1].rk[rank].rk_b0_rxdvs2, + RK_B1_RXDVS2_R_RK0_RX_DLY_FAL_TRACK_GATE_ENA_B1, 1, + RK_B1_RXDVS2_R_RK0_RX_DLY_RIS_TRACK_GATE_ENA_B1, 1, + RK_B1_RXDVS2_R_RK0_DVS_MODE_B1, 2); + } + + if (rg_mode_en == 1) + SET32_BITFIELDS(&ch[0].phy_ao.misc_rg_dfs_ctrl, + MISC_RG_DFS_CTRL_RG_DPY_RXDLY_TRACK_EN, 1); + + dramc_dbg("[RX_INPUT] configuration\n"); +} + +void dig_static_setting(const struct ddr_cali *cali, dramc_subsys_config *subsys) +{ + dig_phy_config(subsys); + gating_mode_cfg(subsys); + dphy_gat_track_config(subsys); + dramc_common_config(cali, subsys); + dvfs_pre_config(subsys); + ddrphy_picg_config(); + io_release(); + rx_input_config(cali); +} + +void dig_config_shuf(const struct ddr_cali *cali, dramc_subsys_config *subsys) +{ + dig_config_shuf_alg_txca(subsys->freq_group); + dig_config_shuf_imp(subsys->freq_group); + dig_config_shuf_rxinput(); + dig_config_shuf_misc_fix(cali, subsys); + dig_config_shuf_misc_dqsgretry(subsys->freq_group); + dig_config_shuf_dbi(subsys); + dig_config_dvfs_dependence(subsys); +} diff --git a/src/soc/mediatek/mt8192/dramc_pi_basic_api.c b/src/soc/mediatek/mt8192/dramc_pi_basic_api.c index d32c268..510cb13 100644 --- a/src/soc/mediatek/mt8192/dramc_pi_basic_api.c +++ b/src/soc/mediatek/mt8192/dramc_pi_basic_api.c @@ -3779,6 +3779,9 @@ subsys.dfs_gp = &dvfs_config; subsys.gat_c = &gat_config; ana_init(cali, &subsys); + dig_static_setting(cali, &subsys); + dig_config_shuf(cali, &subsys); + update_initial_settings(cali); dramc_set_broadcast(DRAMC_BROADCAST_OFF); } -- To view, visit
https://review.coreboot.org/c/coreboot/+/44728
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: If84def990983fae32506c1cd409bd1a1e3a550cd Gerrit-Change-Number: 44728 Gerrit-PatchSet: 1 Gerrit-Owner: CK HU <ck.hu(a)mediatek.com> Gerrit-Reviewer: Duan huayang <huayang.duan(a)mediatek.com> Gerrit-Reviewer: Julius Werner <jwerner(a)chromium.org> Gerrit-Reviewer: Martin Roth <martinroth(a)google.com> Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com> Gerrit-MessageType: newchange
4
8
0
0
← Newer
1
...
81
82
83
84
85
86
87
...
348
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
Results per page:
10
25
50
100
200