diff options
author | Stephen Glancy <sglancy@us.ibm.com> | 2017-11-27 14:47:16 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2018-01-13 14:13:50 -0500 |
commit | 01c730dd41576de25c422070d89e5117ed6975dc (patch) | |
tree | 39c2b7e3ac0660c53f0ad10463c30af2c59d0d9e /src/import/chips/p9/procedures/hwp/memory/lib/phy | |
parent | 02e505b4c437fbf21b39f29c005c934137ad0c6a (diff) | |
download | talos-hostboot-01c730dd41576de25c422070d89e5117ed6975dc.tar.gz talos-hostboot-01c730dd41576de25c422070d89e5117ed6975dc.zip |
Updates WR VREF for characterization results
Change-Id: I9803ee77afa2ebc32e12d9d528ac4ae6a6c947f8
CQ:SW411492
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/50709
Dev-Ready: STEPHEN GLANCY <sglancy@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/50713
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/phy')
4 files changed, 766 insertions, 22 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C index 3fabd4b4e..5522ec472 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ +/* Contributors Listed Below - COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -1072,6 +1072,349 @@ const std::vector< std::vector<uint64_t> > dp16Traits<TARGET_TYPE_MCA>::RDCLK_RE }, }; +const std::vector< std::vector<uint64_t> > dp16Traits<TARGET_TYPE_MCA>::WR_DQ_DELAY_REG = +{ + // RP0 + { + // DP0 + MCA_DP16_WR_DELAY_VALUE_0_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_1_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_2_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_3_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_4_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_5_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_6_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_7_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_8_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_9_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_10_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_11_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_12_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_13_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_14_RP0_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_15_RP0_REG_P0_0, + + // DP1 + MCA_DP16_WR_DELAY_VALUE_0_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_1_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_2_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_3_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_4_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_5_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_6_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_7_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_8_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_9_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_10_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_11_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_12_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_13_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_14_RP0_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_15_RP0_REG_P0_1, + + // DP2 + MCA_DP16_WR_DELAY_VALUE_0_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_1_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_2_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_3_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_4_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_5_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_6_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_7_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_8_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_9_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_10_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_11_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_12_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_13_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_14_RP0_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_15_RP0_REG_P0_2, + + // DP3 + MCA_DP16_WR_DELAY_VALUE_0_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_1_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_2_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_3_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_4_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_5_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_6_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_7_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_8_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_9_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_10_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_11_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_12_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_13_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_14_RP0_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_15_RP0_REG_P0_3, + + // DP4 + MCA_DP16_WR_DELAY_VALUE_0_RP0_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_1_RP0_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_2_RP0_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_3_RP0_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_4_RP0_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_5_RP0_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_6_RP0_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_7_RP0_REG_P0_4, + }, + + // RP1 + { + // DP0 + MCA_DP16_WR_DELAY_VALUE_0_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_1_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_2_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_3_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_4_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_5_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_6_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_7_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_8_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_9_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_10_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_11_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_12_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_13_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_14_RP1_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_15_RP1_REG_P0_0, + + // DP1 + MCA_DP16_WR_DELAY_VALUE_0_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_1_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_2_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_3_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_4_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_5_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_6_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_7_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_8_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_9_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_10_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_11_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_12_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_13_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_14_RP1_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_15_RP1_REG_P0_1, + + // DP2 + MCA_DP16_WR_DELAY_VALUE_0_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_1_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_2_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_3_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_4_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_5_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_6_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_7_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_8_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_9_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_10_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_11_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_12_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_13_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_14_RP1_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_15_RP1_REG_P0_2, + + // DP3 + MCA_DP16_WR_DELAY_VALUE_0_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_1_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_2_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_3_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_4_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_5_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_6_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_7_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_8_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_9_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_10_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_11_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_12_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_13_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_14_RP1_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_15_RP1_REG_P0_3, + + // DP4 + MCA_DP16_WR_DELAY_VALUE_0_RP1_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_1_RP1_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_2_RP1_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_3_RP1_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_4_RP1_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_5_RP1_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_6_RP1_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_7_RP1_REG_P0_4, + }, + + // RP2 + { + // DP0 + MCA_DP16_WR_DELAY_VALUE_0_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_1_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_2_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_3_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_4_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_5_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_6_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_7_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_8_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_9_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_10_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_11_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_12_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_13_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_14_RP2_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_15_RP2_REG_P0_0, + + // DP1 + MCA_DP16_WR_DELAY_VALUE_0_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_1_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_2_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_3_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_4_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_5_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_6_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_7_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_8_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_9_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_10_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_11_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_12_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_13_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_14_RP2_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_15_RP2_REG_P0_1, + + // DP2 + MCA_DP16_WR_DELAY_VALUE_0_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_1_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_2_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_3_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_4_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_5_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_6_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_7_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_8_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_9_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_10_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_11_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_12_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_13_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_14_RP2_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_15_RP2_REG_P0_2, + + // DP3 + MCA_DP16_WR_DELAY_VALUE_0_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_1_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_2_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_3_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_4_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_5_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_6_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_7_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_8_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_9_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_10_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_11_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_12_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_13_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_14_RP2_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_15_RP2_REG_P0_3, + + // DP4 + MCA_DP16_WR_DELAY_VALUE_0_RP2_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_1_RP2_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_2_RP2_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_3_RP2_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_4_RP2_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_5_RP2_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_6_RP2_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_7_RP2_REG_P0_4, + }, + + // RP3 + { + // DP0 + MCA_DP16_WR_DELAY_VALUE_0_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_1_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_2_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_3_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_4_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_5_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_6_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_7_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_8_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_9_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_10_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_11_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_12_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_13_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_14_RP3_REG_P0_0, + MCA_DP16_WR_DELAY_VALUE_15_RP3_REG_P0_0, + + // DP1 + MCA_DP16_WR_DELAY_VALUE_0_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_1_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_2_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_3_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_4_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_5_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_6_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_7_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_8_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_9_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_10_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_11_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_12_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_13_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_14_RP3_REG_P0_1, + MCA_DP16_WR_DELAY_VALUE_15_RP3_REG_P0_1, + + // DP2 + MCA_DP16_WR_DELAY_VALUE_0_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_1_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_2_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_3_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_4_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_5_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_6_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_7_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_8_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_9_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_10_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_11_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_12_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_13_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_14_RP3_REG_P0_2, + MCA_DP16_WR_DELAY_VALUE_15_RP3_REG_P0_2, + + // DP3 + MCA_DP16_WR_DELAY_VALUE_0_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_1_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_2_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_3_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_4_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_5_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_6_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_7_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_8_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_9_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_10_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_11_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_12_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_13_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_14_RP3_REG_P0_3, + MCA_DP16_WR_DELAY_VALUE_15_RP3_REG_P0_3, + + // DP4 + MCA_DP16_WR_DELAY_VALUE_0_RP3_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_1_RP3_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_2_RP3_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_3_RP3_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_4_RP3_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_5_RP3_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_6_RP3_REG_P0_4, + MCA_DP16_WR_DELAY_VALUE_7_RP3_REG_P0_4, + }, +}; + /// /// @brief Given a RD_VREF value, create a PHY 'standard' bit field for that percentage. /// @tparam T fapi2 Target Type - derived @@ -2539,33 +2882,32 @@ fapi2::ReturnCode reset_wr_vref_config0( const fapi2::Target<TARGET_TYPE_MCA>& i // traits definition typedef dp16Traits<TARGET_TYPE_MCA> TT; - // builds up the base register value + // Builds up the base register value by field for clarity, using characterized values that lead to the best results fapi2::buffer<uint64_t> l_config0_data; - l_config0_data.clearBit<TT::WR_VREF_CONFIG0_FULL_1D>() - // TK putting hardcoded defaults here - revisit how to handle this (values should be obtained through characterization) - // smallest available step size - algorithm adds 1 so this is a 1 not a 0 + l_config0_data.setBit<TT::WR_VREF_CONFIG0_FULL_1D>() + // Smallest available step size - algorithm adds 1 so this is a 1 not a 0 .insertFromRight<TT::WR_VREF_CONFIG0_2D_SMALL_STEP_VAL, TT::WR_VREF_CONFIG0_2D_SMALL_STEP_VAL_LEN>(0b000) - // step size of 4 - algorithm adds 1 so this is a 4, not a 3 - .insertFromRight<TT::WR_VREF_CONFIG0_2D_BIG_STEP_VAL, TT::WR_VREF_CONFIG0_2D_BIG_STEP_VAL_LEN>(0b0011) - // for intermediary bits, skip all 7, aka only run one bit on each DRAM for intermediary bits - .insertFromRight<TT::WR_VREF_CONFIG0_NUM_BITS_TO_SKIP, TT::WR_VREF_CONFIG0_NUM_BITS_TO_SKIP_LEN>(0b111) - // run for two VREFs looking for an increase - this is register value + 1 to the algorithm, so it's a 1, not a 0 - .insertFromRight<TT::WR_VREF_CONFIG0_NUM_NO_INC_COMP, TT::WR_VREF_CONFIG0_NUM_NO_INC_COMP_LEN>(0b001); + // Big step size of 2 - algorithm adds 1 so the register setting is a 1 + .insertFromRight<TT::WR_VREF_CONFIG0_2D_BIG_STEP_VAL, TT::WR_VREF_CONFIG0_2D_BIG_STEP_VAL_LEN>(0b0001) + // For intermediary bits, skip all 7, aka only run one bit on each DRAM for intermediary bits + .insertFromRight<TT::WR_VREF_CONFIG0_NUM_BITS_TO_SKIP, TT::WR_VREF_CONFIG0_NUM_BITS_TO_SKIP_LEN>(0b000) + // Run for the maximum number of VREFs looking for an increase + .insertFromRight<TT::WR_VREF_CONFIG0_NUM_NO_INC_COMP, TT::WR_VREF_CONFIG0_NUM_NO_INC_COMP_LEN>(0b111); // Whether the 2D VREF is enabled or not varies by the calibration attribute fapi2::buffer<uint32_t> l_cal_steps_enabled; FAPI_TRY( mss::cal_step_enable(i_target, l_cal_steps_enabled) ); - // adds the information to the buffer + // Adds the information to the buffer l_config0_data.writeBit<TT::WR_VREF_CONFIG0_1D_ONLY_SWITCH>(!l_cal_steps_enabled.getBit<WRITE_CTR_2D_VREF>()); - //blast out the scoms + // Blast out the scoms FAPI_TRY( mss::scom_blastah(i_target, TT::WR_VREF_CONFIG0_REG, l_config0_data) ); - // return success + // Return success return fapi2::FAPI2_RC_SUCCESS; - // handle errors + // Handle errors fapi_try_exit: return fapi2::current_err; } @@ -3679,6 +4021,95 @@ fapi_try_exit: return fapi2::current_err; } +namespace wr_vref +{ + +/// +/// @brief Gets the WR VREF range based upon the composite range +/// @param[in] i_value the composite range value +/// @return l_range the JEDEC WR VREF range +/// +uint8_t get_range(const uint64_t i_value) +{ + // According to JEDEC range 1 uses a 0 and range 2 uses a 1 + constexpr uint64_t RANGE1 = 0x00; + constexpr uint64_t RANGE2 = 0x01; + const uint8_t l_range = ((i_value >= WR_VREF_CROSSOVER_RANGE) ? RANGE1 : RANGE2); + return l_range; +} + +/// +/// @brief Gets the WR VREF value based upon the composite range +/// @param[in] i_value the composite range value +/// @return l_range the JEDEC WR VREF value +/// +uint8_t get_value(const uint64_t i_value) +{ + // Subtract out the crossover range if need be + // Remember, the JEDEC range overlaps for a number of VREFs + // The crossover range is used to offset the start of the JEDEC range that is higher than the other + const uint8_t l_value = ((i_value >= WR_VREF_CROSSOVER_RANGE) ? + (i_value - WR_VREF_CROSSOVER_RANGE) : (i_value)); + return l_value; +} + +/// +/// @brief Gets the WR VREF value based upon the inputted values +/// @param[in] i_range the JEDEC range to use +/// @param[in] i_value the JEDED value to use +/// @return l_range the JEDEC WR VREF value +/// +uint64_t compute_composite_value(const uint64_t i_range, const uint64_t i_value) +{ + // Add in the crossover range if need be + // Remember, the JEDEC range overlaps for a number of VREFs + // The crossover range is used to offset the start of the JEDEC range that is higher than the other + constexpr uint64_t USE_CROSSOVER_RANGE = 0; + return i_value + ((i_range == USE_CROSSOVER_RANGE) ? WR_VREF_CROSSOVER_RANGE : 0); +} + +/// +/// @brief Offsets the WR VREF train and range values based upon the offset attribute +/// @param[in] i_target the fapi2 target of the port +/// @param[in,out] io_train_range - train range value to update +/// @param[in,out] io_train_value - train range value to update +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +fapi2::ReturnCode offset_values( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + uint8_t& io_train_range, + uint8_t& io_train_value ) +{ + const auto& l_mcs = mss::find_target<fapi2::TARGET_TYPE_MCS>(i_target); + // Computing the composite range simplifies the logic for offsetting a WR VREF range and value + int64_t l_composite = compute_composite_value(io_train_range, io_train_value); + + int8_t l_offset = 0; + FAPI_TRY( mss::wr_vref_offset(mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_offset) ); + l_composite += l_offset; + + // Check that the value is in range + FAPI_ASSERT( (l_composite >= 0) && (l_composite <= WR_VREF_MAX_COMPOSITE_RANGE), + fapi2::MSS_OFFSET_WR_VREF_OUT_OF_RANGE() + .set_TARGET(i_target) + .set_MCS_TARGET(l_mcs) + .set_MAX(WR_VREF_MAX_COMPOSITE_RANGE) + .set_OFFSET(l_offset) + .set_COMPOSITE(l_composite), + "%s Offset composite range is out of bounds (%d - %d): %d offset is: %d", + mss::c_str(i_target), + 0, + WR_VREF_MAX_COMPOSITE_RANGE, + l_composite, + l_offset ); + + io_train_range = get_range(l_composite); + io_train_value = get_value(l_composite); + +fapi_try_exit: + return fapi2::current_err; +} + +} // close namespace wr_vref } // close namespace dp16 } // close namespace mss diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H index 238eaa3dc..e36b5969a 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ +/* Contributors Listed Below - COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -196,6 +196,9 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA> static const std::vector< std::pair<uint64_t, uint64_t> > WR_VREF_VALUE_RP2_REG; static const std::vector< std::pair<uint64_t, uint64_t> > WR_VREF_VALUE_RP3_REG; + // WR DQ delay registers - in terms of rank pair, then bit + static const std::vector< std::vector<uint64_t> > WR_DQ_DELAY_REG; + static const std::vector< uint64_t > RD_DIA_CONFIG5_REG; static const std::vector< uint64_t > DATA_BIT_ENABLE0_REG; static const std::vector< uint64_t > DATA_BIT_ENABLE1_REG; @@ -379,6 +382,13 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA> WR_VREF_VALUE_VALUE_DRAM_ODD = MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR0_P0_0_01_VALUE_DRAM1 , WR_VREF_VALUE_VALUE_DRAM_ODD_LEN = MCA_DDRPHY_DP16_WR_VREF_VALUE0_RANK_PAIR0_P0_0_01_VALUE_DRAM1_LEN , + // Write delay fields + WR_DELAY = MCA_DP16_WR_DELAY_VALUE_0_RP0_REG_P0_0_01_DELAYG, + WR_DELAY_LEN = MCA_DP16_WR_DELAY_VALUE_0_RP0_REG_P0_0_01_DELAYG_LEN, + + // Bit disable field start + BIT_DISABLE = MCA_DDRPHY_DP16_DATA_BIT_DISABLE0_RP0_P0_0_01_DISABLE_15, + // Read Delay fields. READ_OFFSET_LOWER = MCA_DDRPHY_DP16_READ_DELAY_OFFSET0_RANK_PAIR0_P0_0_01, READ_OFFSET_LOWER_LEN = MCA_DDRPHY_DP16_READ_DELAY_OFFSET0_RANK_PAIR0_P0_0_01_LEN, @@ -2316,6 +2326,42 @@ fapi_try_exit: return fapi2::current_err; } +namespace wr_vref +{ + +/// +/// @brief Gets the WR VREF range based upon the composite range +/// @param[in] i_value the composite range value +/// @return l_range the JEDEC WR VREF range +/// +uint8_t get_range(const uint64_t i_value); + +/// +/// @brief Gets the WR VREF value based upon the composite range +/// @param[in] i_value the composite range value +/// @return l_range the JEDEC WR VREF value +/// +uint8_t get_value(const uint64_t i_value); + +/// +/// @brief Gets the WR VREF value based upon the inputted values +/// @param[in] i_range the JEDEC range to use +/// @param[in] i_value the JEDED value to use +/// @return l_range the JEDEC WR VREF value +/// +uint64_t compute_composite_value(const uint64_t i_range, const uint64_t i_value); + +/// +/// @brief Offsets the WR VREF train and range values based upon the offset attribute +/// @param[in] i_target the fapi2 target of the port +/// @param[in,out] io_train_range - train range value to update +/// @param[in,out] io_train_value - train range value to update +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +fapi2::ReturnCode offset_values( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + uint8_t& io_train_range, + uint8_t& io_train_value ); +} // close namespace wr_vref } // close namespace dp16 } // close namespace mss diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C index c7438b096..06131bd61 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2017 */ +/* Contributors Listed Below - COPYRIGHT 2017,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -53,6 +53,7 @@ #include <lib/utils/count_dimm.H> #include <lib/dimm/rank.H> #include <lib/shared/mss_const.H> +#include <lib/dimm/ddr4/pda.H> namespace mss { @@ -468,17 +469,18 @@ uint64_t read_ctr::calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA> return l_read_ctr_cycles + rc::vref_guess_time(i_target); } - /// -/// @brief Sets up and runs the calibration step +/// @brief Sets up and runs the calibration step according to an external 1D vs 2D input /// @param[in] i_target - the MCA target on which to operate /// @param[in] i_rp - the rank pair /// @param[in] i_abort_on_error - whether or not we are aborting on cal error +/// @param[in] i_wr_vref - true IFF write VREF calibration needs to be run /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok /// fapi2::ReturnCode write_ctr::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_rp, - const uint8_t i_abort_on_error ) const + const uint8_t i_abort_on_error, + const bool i_wr_vref ) const { typedef mss::dp16Traits<fapi2::TARGET_TYPE_MCA> TT; std::vector<fapi2::buffer<uint64_t>> l_wr_vref_config; @@ -489,7 +491,7 @@ fapi2::ReturnCode write_ctr::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i { // 0: Run only the VREF (2D) write centering algorithm // 1: Run only the 1D - l_data.writeBit<TT::WR_VREF_CONFIG0_1D_ONLY_SWITCH>(!iv_wr_vref); + l_data.writeBit<TT::WR_VREF_CONFIG0_1D_ONLY_SWITCH>(!i_wr_vref); } FAPI_TRY(mss::scom_blastah(i_target, TT::WR_VREF_CONFIG0_REG, l_wr_vref_config)); @@ -501,6 +503,231 @@ fapi_try_exit: } /// +/// @brief Sets up and runs the calibration step +/// @param[in] i_target - the MCA target on which to operate +/// @param[in] i_rp - the rank pair +/// @param[in] i_abort_on_error - whether or not we are aborting on cal error +/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode write_ctr::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + const uint64_t i_rp, + const uint8_t i_abort_on_error ) const +{ + return run(i_target, i_rp, i_abort_on_error, iv_wr_vref); +} + +/// +/// @brief Executes the pre-cal step workaround +/// @param[in] i_target - the MCA target on which to operate +/// @param[in] i_rp - the rank pair +/// @param[in] i_abort_on_error - whether or not we are aborting on cal error +/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode write_ctr::pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + const uint64_t i_rp, + const uint8_t i_abort_on_error ) const +{ + iv_dram_to_check.clear(); + + // Only add DRAMs to check if: + // 1) WR VREF is enabled + // 2) the part is a DD2 or above + if(iv_wr_vref && (!mss::chip_ec_nimbus_lt_2_0(i_target))) + { + FAPI_INF("%s checking for clear DRAMs", mss::c_str(i_target)); + uint64_t l_num_dram = 0; + + uint8_t l_width[MAX_DIMM_PER_PORT] = {}; + FAPI_TRY( mss::eff_dram_width(i_target, l_width) ); + l_num_dram = (l_width[0] == fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8) ? MAX_DRAMS_X8 : MAX_DRAMS_X4; + + // Loops through all the DRAM and adds them to be checked if they are clean of any bad bits + // We only want to run the workaround on an entirely clean DRAM that goes bad + // If we have a DRAM that already has bad bit(s), there could be something else going on and the workaround will not help or could make matters worse + for(uint64_t l_dram = 0; l_dram < l_num_dram; l_dram++) + { + bool l_has_disables = false; + + FAPI_TRY(mss::workarounds::dp16::wr_vref::dram_has_disables(i_target, i_rp, l_dram, l_has_disables)); + + FAPI_INF("%s RP%lu DRAM%lu Disables? %s", mss::c_str(i_target), i_rp, l_dram, l_has_disables ? "yes" : "no"); + + // If there are no disables, then we need to check the DRAM + if(!l_has_disables) + { + // Gets the starting WR DQ delay for the DRAM + uint64_t l_value = 0; + + FAPI_TRY(mss::workarounds::dp16::wr_vref::get_starting_wr_dq_delay(i_target, i_rp, l_dram, l_value)); + + iv_dram_to_check.push_back({l_dram, l_value}); + } + } + } + else + { + FAPI_INF("%s workaround is not being run. WR VREF: %s chip version: %s", mss::c_str(i_target), + iv_wr_vref ? "enabled" : "disabled", mss::chip_ec_nimbus_lt_2_0(i_target) ? "DD1" : "DD2"); + } + + return fapi2::FAPI2_RC_SUCCESS; +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Executes the post-cal step workaround +/// @param[in] i_target - the MCA target on which to operate +/// @param[in] i_rp - the rank pair +/// @param[in] i_abort_on_error - whether or not we are aborting on cal error +/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode write_ctr::post_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + const uint64_t i_rp, + const uint8_t i_abort_on_error ) const +{ + // Loops through the DRAMs to check and creates a vector of bad DRAMs and their associated starting delays + std::vector<std::pair<uint64_t, uint64_t>> l_bad_drams; + + // Checking all of the DRAMs that had been good before WR VREF + // If any of them have gone bad, then note it and run the workaround + for(const auto l_pair : iv_dram_to_check) + { + const auto l_dram = l_pair.first; + const auto l_delay = l_pair.second; + bool l_is_bad = false; + FAPI_TRY(mss::workarounds::dp16::wr_vref::is_dram_disabled(i_target, i_rp, l_dram, l_is_bad)); + + // If we have a bad DRAM, note it and add it to the DRAM to test + if(l_is_bad) + { + FAPI_INF("%s RP%lu DRAM%lu is bad! Workaround will be run on it", mss::c_str(i_target), i_rp, l_dram); + l_bad_drams.push_back({l_dram, l_delay}); + } + } + + iv_dram_to_check.clear(); + + // Only run the rest of the workaround if we have any bad DRAMs + if(l_bad_drams.size() > 0) + { + fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_dimm; + std::vector<uint64_t> l_ranks; + + // Gets the ranks on which to latch the VREF's + FAPI_TRY(mss::rank::get_ranks_in_pair( i_target, i_rp, l_ranks)); + + // If the rank vector is empty log an error + FAPI_ASSERT(!l_ranks.empty(), + fapi2::MSS_INVALID_RANK(). + set_MCA_TARGET(i_target). + set_RANK(i_rp). + set_FUNCTION(mss::ffdc_function_codes::WR_VREF_TRAINING_WORKAROUND), + "%s rank pair is empty! %lu", mss::c_str(i_target), i_rp); + + FAPI_ASSERT(l_ranks[0] != NO_RANK, + fapi2::MSS_INVALID_RANK(). + set_MCA_TARGET(i_target). + set_RANK(NO_RANK). + set_FUNCTION(mss::ffdc_function_codes::WR_VREF_TRAINING_WORKAROUND), + "%s rank pair has no ranks %lu", mss::c_str(i_target), i_rp); + + // Ensures we get a valid DIMM target / rank combo + FAPI_TRY( mss::rank::get_dimm_target_from_rank(i_target, l_ranks[0], l_dimm), + "%s Failed get_dimm_target_from_rank in write_ctr::post_workaround", + mss::c_str(i_target)); + + // Assembles the PDA container and fixes the disables + { + mss::ddr4::pda::commands<mss::ddr4::mrs06_data> l_container; + + // Loops through and sets up all the data needed the workaround + for(const auto& l_pair : l_bad_drams ) + { + const auto l_dram = l_pair.first; + const auto l_delay = l_pair.second; + + // Adds in the PDA necessary for the latching commands + fapi2::ReturnCode l_rc(fapi2::FAPI2_RC_SUCCESS); + mss::ddr4::mrs06_data l_mrs(l_dimm, l_rc); + FAPI_TRY(l_rc, "%s failed to create MRS06 data class", mss::c_str(l_dimm)); + + // Updates the MRS06 settings to have the proper VREF settings + FAPI_TRY(mss::workarounds::dp16::wr_vref::modify_mrs_vref_to_vpd( l_dimm, l_mrs)); + + FAPI_TRY(l_container.add_command(l_dimm, l_ranks[0], l_mrs, l_dram)); + + // Updates the WR VREF value in the DP + FAPI_TRY(mss::workarounds::dp16::wr_vref::configure_wr_vref_to_nominal( l_dimm, i_rp, l_dram)); + + // Restores the known good values for WR DQ delays + FAPI_TRY(mss::workarounds::dp16::wr_vref::reset_wr_dq_delay( i_target, i_rp, l_dram, l_delay )); + + // Clears the disable bits for PDA latching + FAPI_TRY(mss::workarounds::dp16::wr_vref::clear_dram_disable_bits( i_target, i_rp, l_dram )); + } + + // Latches the failing DRAM's originally good values out to the DRAMs with PDA + FAPI_TRY(mss::ddr4::pda::execute_wr_vref_latch(l_container)); + + // Disabling bits prior to PDA could cause issues with DRAM latching in the VREF values + // As such, we're setting disable bits after latching PDA + for(const auto& l_pair : l_bad_drams ) + { + const auto l_dram = l_pair.first; + FAPI_TRY(mss::workarounds::dp16::wr_vref::disable_bits( i_target, i_rp, l_dram)); + } + } + + FAPI_TRY(mss::workarounds::dp16::wr_vref::configure_skip_bits( i_target )); + + // Re-runs WR VREF calibration + FAPI_TRY(run( i_target, + i_rp, + i_abort_on_error, + true )); + + // Clears the training FIR's + FAPI_TRY(mss::workarounds::dp16::wr_vref::clear_training_firs( i_target )); + + // If the DRAM's are still bad, exit + for(const auto& l_pair : l_bad_drams ) + { + bool l_is_bad = false; + const auto l_dram = l_pair.first; + + FAPI_TRY(mss::workarounds::dp16::wr_vref::is_dram_disabled(i_target, i_rp, l_dram, l_is_bad)); + + if(l_is_bad) + { + FAPI_INF("%s RP%lu found DRAM%lu as bad after the second run of WR VREF! Exiting and letting ECC clean this up", + mss::c_str(i_target), i_rp, l_dram); + } + else + { + FAPI_INF("%s RP%lu found DRAM%lu as recovered after the second run of WR VREF! Restoring disable bits and running WR CTR 1D calibration", + mss::c_str(i_target), i_rp, l_dram); + FAPI_TRY(mss::workarounds::dp16::wr_vref::clear_dram_disable_bits( i_target, i_rp, l_dram )); + } + + // Logs the results for this DRAM + // Note: always logged as recovered, as we want this to be informational + FAPI_TRY(mss::workarounds::dp16::wr_vref::log_dram_results(i_target, i_rp, l_dram, l_is_bad)); + } + + // Re-runs WR VREF + FAPI_TRY(run( i_target, + i_rp, + i_abort_on_error, + false )); + } + + return fapi2::FAPI2_RC_SUCCESS; +fapi_try_exit: + return fapi2::current_err; +} + +/// /// @brief Calculates the number of cycles a given calibration step will take /// @param[in] i_target - the MCA target on which to operate /// @return l_cycles - the number of cycles a given calibration step wil take diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H index 37f756098..69372ef85 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2017 */ +/* Contributors Listed Below - COPYRIGHT 2017,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -580,6 +580,28 @@ class write_ctr : public phy_step const uint8_t i_abort_on_error ) const override; /// + /// @brief Executes the pre-cal step workaround + /// @param[in] i_target - the MCA target on which to operate + /// @param[in] i_rp - the rank pair + /// @param[in] i_abort_on_error - whether or not we are aborting on cal error + /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok + /// + fapi2::ReturnCode pre_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + const uint64_t i_rp, + const uint8_t i_abort_on_error ) const override; + + /// + /// @brief Executes the post-cal step workaround + /// @param[in] i_target - the MCA target on which to operate + /// @param[in] i_rp - the rank pair + /// @param[in] i_abort_on_error - whether or not we are aborting on cal error + /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok + /// + fapi2::ReturnCode post_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + const uint64_t i_rp, + const uint8_t i_abort_on_error ) const override; + + /// /// @brief Calculates the number of cycles a given calibration step will take /// @param[in] i_target - the MCA target on which to operate /// @return l_cycles - the number of cycles a given calibration step wil take @@ -597,6 +619,24 @@ class write_ctr : public phy_step private: bool iv_wr_vref; + // Contains all information related to any DRAMs that were disabled due to the WR VREF algorithm + // The pair contains the following information: + // first -> the DRAM's number to test + // second -> the DRAM's starting write delay value + mutable std::vector<std::pair<uint64_t, uint64_t>> iv_dram_to_check; + + /// + /// @brief Sets up and runs the calibration step according to an external 1D vs 2D input + /// @param[in] i_target - the MCA target on which to operate + /// @param[in] i_rp - the rank pair + /// @param[in] i_abort_on_error - whether or not we are aborting on cal error + /// @param[in] i_wr_vref - true IFF write VREF calibration needs to be run + /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok + /// + fapi2::ReturnCode run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + const uint64_t i_rp, + const uint8_t i_abort_on_error, + const bool i_wr_vref ) const; }; /// |