summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory/lib/phy
diff options
context:
space:
mode:
authorStephen Glancy <sglancy@us.ibm.com>2017-11-27 14:47:16 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-01-13 14:13:50 -0500
commit01c730dd41576de25c422070d89e5117ed6975dc (patch)
tree39c2b7e3ac0660c53f0ad10463c30af2c59d0d9e /src/import/chips/p9/procedures/hwp/memory/lib/phy
parent02e505b4c437fbf21b39f29c005c934137ad0c6a (diff)
downloadtalos-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')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C461
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H48
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C237
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.H42
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;
};
///
OpenPOWER on IntegriCloud