diff options
author | Richard J. Knight <rjknight@us.ibm.com> | 2013-07-23 12:10:41 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-09-12 13:58:59 -0500 |
commit | 23c61636fe51145db2d7554ea8022aa4d58179b6 (patch) | |
tree | 15d0150cf2bdfb59cfa516621a314e519f5d2a97 /src/usr | |
parent | 7e14a67f70a873c3d6d3fe2640ce7cc84e6065c5 (diff) | |
download | talos-hostboot-23c61636fe51145db2d7554ea8022aa4d58179b6.tar.gz talos-hostboot-23c61636fe51145db2d7554ea8022aa4d58179b6.zip |
Integrate p8_pfet_control into hostboot
Change-Id: If6b97e0012d09e93781af59a349d08fa30d13d1b
RTC:70673
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/5849
Tested-by: Jenkins Server
Reviewed-by: Brian H. Horton <brianh@linux.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr')
8 files changed, 2545 insertions, 195 deletions
diff --git a/src/usr/hwpf/hwp/build_winkle_images/makefile b/src/usr/hwpf/hwp/build_winkle_images/makefile index 890cd5e25..8c5be9a53 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/makefile +++ b/src/usr/hwpf/hwp/build_winkle_images/makefile @@ -64,7 +64,8 @@ OBJS = build_winkle_images.o \ p8_ring_identification.o \ p8_slw_build.o \ p8_image_help_base.o \ - p8_pfet_init.o + p8_pfet_init.o \ + p8_pfet_control.o ## NOTE: add a new directory onto the vpaths when you add a new HWP ## EXAMPLE: diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_control.C b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_control.C new file mode 100644 index 000000000..cac327961 --- /dev/null +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_control.C @@ -0,0 +1,2249 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_control.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: p8_pfet_control.C,v 1.10 2013/08/02 19:05:03 stillgs Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/p8_pfet_control.C,v $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2011 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! OWNER NAME: Greg Still Email: stillgs@us.ibm.com +// *! +/// \file p8_pfet_control.C +/// \brief Perform override operations to the EX PFET headers +/// +/// High-level procedure flow: +/// \verbatim +/// +/** + Check for valid parms + Check if PMGP0(0) has the PM function enabled. If not, enable it. + + + + + + + + + + + + + + + */ +/// +/// Procedure Prereq: +/// - System clocks are running +/// \endverbatim +/// +/// PFVddCntlStat (0x106) layout +/// Control +/// 0:1 - core_vdd_pfet_force_state 00: nop; 01: Voff; 10: Vret; 11: Von (4:5 must be 00) +/// 2:3 - eco_vdd_pfet_force_state 00: nop; 01: Voff; 10: Vret; 11: Von (6:7 must be 00) +/// 4 - core_vdd_pfet_val_override 0: disable; 1: enable (0 enables 0:1) +/// 5 - core_vdd_pfet_sel_override 0: disable; 1: enable (0 enables 0:1) +/// 6 - eco_vdd_pfet_val_override 0: disable; 1: enable (0 enables 2:3) +/// 7 - eco_vdd_pfet_sel_override 0: disable; 1: enable (0 enables 2:3) +/// +/// Status +/// 42:45 - core_vdd_pfet_state (42: Idle; 43: Increment; 44: Decrement; 45: Wait) +/// 46:49 - not relevant +/// 50:53 - eco_vdd_pfet_state (50: Idle; 51: Increment; 52: Decrement; 53: Wait) +/// 54:57 - not relevant +/// +/// PFVcsCntlStat (0x10E) layout +/// Control +/// 0:1 - core_vcs_pfet_force_state 00: nop; 01: Voff; 10: Vret; 11: Von (4:5 must be 00) +/// 2:3 - eco_vcs_pfet_force_state 00: nop; 01: Voff; 10: Vret; 11: Von (6:7 must be 00) +/// 4 - core_vcs_pfet_val_override 0: disable; 1: enable (0 enables 0:1) +/// 5 - core_vcs_pfet_sel_override 0: disable; 1: enable (0 enables 0:1) +/// 6 - eco_vcs_pfet_val_override 0: disable; 1: enable (0 enables 2:3) +/// 7 - eco_vcs_pfet_sel_override 0: disable; 1: enable (0 enables 2:3) +/// Status +/// 42:45 - core_vcs_pfet_state (42: Idle; 43: Increment; 44: Decrement; 45: Wait) +/// 46:49 - not relevant +/// 50:53 - eco_vcs_pfet_state (50: Idle; 51: Increment; 52: Decrement; 53: Wait) +/// 54:57 - not relevant + + + +//------------------------------------------------------------------------------ + + +// ---------------------------------------------------------------------- +// Includes +// ---------------------------------------------------------------------- +#include "p8_pm.H" +#include "p8_pfet_control.H" + + +extern "C" { + + +using namespace fapi; + +//------------------------------------------------------------------------------ +// Constant definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Global variables +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Constant definitions +//------------------------------------------------------------------------------ + +const uint32_t CORE_FORCE_STATE = 0; +const uint32_t CORE_FORCE_LENGTH = 2; // 0:1 +const uint32_t ECO_FORCE_STATE = 2; +const uint32_t ECO_FORCE_LENGTH = 2; // 2:3 +const uint32_t CORE_OVERRIDE_STATE = 4; +const uint32_t CORE_OVERRIDE_LENGTH = 2; // 4:5 +const uint32_t ECO_OVERRIDE_STATE = 6; +const uint32_t ECO_OVERRIDE_LENGTH = 2; // 6:7 +const uint32_t CORE_OVERRIDE_SEL = 22; +const uint32_t CORE_OVERRIDE_SEL_LENGTH = 4; // 22:25 +const uint32_t ECO_OVERRIDE_SEL = 38; +const uint32_t ECO_OVERRIDE_SEL_LENGTH = 4; // 38:41 +const uint32_t CORE_FSM_IDLE_BIT = 42; +const uint32_t ECO_FSM_IDLE_BIT = 50; +const uint32_t PFET_MAX_IDLE_POLLS = 16; +const uint32_t PFET_POLL_WAIT = 1000000; // 100us (in ns units) +const uint32_t PFET_POLL_WAIT_SIM = 1000; // 100us (in sim cycles) + + +//------------------------------------------------------------------------------ +// Function prototypes +//------------------------------------------------------------------------------ + +fapi::ReturnCode p8_pfet_on (const fapi::Target& i_target, + uint8_t i_ex_number, + pfet_dom_t i_domain); + +fapi::ReturnCode p8_pfet_off(const fapi::Target& i_target, + uint8_t i_ex_number, + pfet_dom_t i_domain); + +fapi::ReturnCode p8_pfet_off_override( const fapi::Target& i_target, + uint8_t i_ex_number, + pfet_dom_t i_domain); + +fapi::ReturnCode p8_pfet_poll(const fapi::Target& i_target, + uint64_t i_address, + pfet_dom_t i_domain); + +fapi::ReturnCode p8_pfet_read_state(const fapi::Target& i_target, + const uint64_t i_address, + const uint32_t i_bitoffset, + char * o_state); + +fapi::ReturnCode p8_pfet_ivrm_fsm_fix(const fapi::Target& i_target, + uint8_t i_ex_number, + pfet_dom_t i_domain, + pfet_force_t i_op); + +//------------------------------------------------------------------------------ +// Function definitions +//------------------------------------------------------------------------------ + +/// \param[in] i_target Chip target +/// \param[in] i_ex_number EX number +/// \param[in] i_domain Domain: BOTH, ECO, CORE +/// \param[in] i_op Operation: VON, VOFF, NONE +/// +/// \retval FAPI_RC_SUCCESS if something good happens, +/// \retval BAD_RETURN_CODE otherwise +fapi::ReturnCode +p8_pfet_control( const fapi::Target& i_target, + uint8_t i_ex_number, + pfet_dom_t i_domain, + pfet_force_t i_op + ) +{ + fapi::ReturnCode l_rc; + uint32_t e_rc = 0; + ecmdDataBufferBase data(64); + ecmdDataBufferBase pmgp0(64); + ecmdDataBufferBase gp3(64); + uint64_t address; + bool restore_pmgp0 = false; + bool restore_gp3 = false; + + // valid domain options + const char * pfet_dom_names[] = + { + "BOTH", // write to both domains + "ECO", // eco only + "CORE" // core only + }; + + do + { + // Check for valid operation parameter + if ((i_op != VON) && (i_op != VOFF) && (i_op != VOFF_OVERRIDE) && (i_op != NONE)) + { + FAPI_ERR("\tInvalid operation parm 0x%x", i_op); + const uint64_t& EX = i_ex_number; + const uint64_t& DOMAIN = i_domain; + const uint64_t& OPERATION = i_op; + FAPI_SET_HWP_ERROR(l_rc, RC_PMPROC_PFETLIB_BAD_OP); + break; + } + + // Check for valid domain parameter + if ((i_domain != CORE) && (i_domain != ECO) && (i_domain != BOTH)) + { + FAPI_ERR("\tInvalid domain parm 0x%x", i_domain); + const uint64_t& EX = i_ex_number; + const uint64_t& DOMAIN = i_domain; + FAPI_SET_HWP_ERROR(l_rc, RC_PMPROC_PFETLIB_BAD_DOMAIN); + break; + } + + FAPI_INF("Processing target %s", i_target.toEcmdString()); + + // Check the PM controls and Pervasive clocks are enabled. + FAPI_DBG("\tChecking PMGP0(0) for enablement on EX %d ", i_ex_number); + address = EX_PMGP0_0x100F0100 + (0x01000000 * i_ex_number); + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + // If not, enable them. + if (data.isBitSet(0)) + { + FAPI_INF("\tPM controls not enabled; enabling to allow control"); + restore_pmgp0 = true; + pmgp0 = data; + + address = EX_PMGP0_AND_0x100F0101 + (0x01000000 * i_ex_number); + e_rc |= data.flushTo1(); + e_rc |= data.clearBit(0); // PM disable + e_rc |= data.clearBit(39); // Remove logical pervasive/pcbs-pm fence + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // Read to allow for Cronus 5.1 or 5.6 to look at the resultant setting + address = EX_PMGP0_0x100F0100 + (0x01000000 * i_ex_number); + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + // Clear PCB_EP_RESET and the Winkle Electrical Fence to allow + // settings to take on non-reset values + address = EX_GP3_0x100F0012 + (0x01000000 * i_ex_number); + + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + FAPI_DBG("\tEX_GP3_0x%08llX before 0x%16llX", + address, + data.getDoubleWord(0)); + + if (data.isBitSet(1)) + { + restore_gp3 = true; + gp3 = data; + + // --- Glitchless Mux reset + FAPI_DBG("\tClearing glitchless mux reset in GP3"); + address = EX_GP3_AND_0x100F0013 + (0x01000000 * i_ex_number); + e_rc |= data.flushTo1(); + e_rc |= data.clearBit(2); // Glitchless Mux reset + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // --- Test override + FAPI_DBG("\tSetting test override in GP3"); + address = EX_GP3_OR_0x100F0014 + (0x01000000 * i_ex_number); + e_rc |= data.flushTo0(); + e_rc |= data.setBit(20); // Test override + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // --- End point reset + FAPI_DBG("\tClearing PCB endpoint reset for allow for non-reset values."); + address = EX_GP3_AND_0x100F0013 + (0x01000000 * i_ex_number); + e_rc |= data.flushTo1(); + e_rc |= data.clearBit(1); // End point reset + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // GP3 + address = EX_GP3_0x100F0012 + (0x01000000 * i_ex_number); + l_rc = fapiGetScom(i_target, address, data); + if (l_rc) { + FAPI_ERR("fapiGetScom error (addr: 0x%08llX)", address); + break; + } + + FAPI_DBG("\tDebug Info: GP3 (addr: 0x%08llX) - 0x%016llX", address, data.getDoubleWord(0)); + + // --- Chiplet enable + FAPI_DBG("\tTemporarily setting chiplet enable in GP3"); + address = EX_GP3_OR_0x100F0014 + (0x01000000 * i_ex_number); + e_rc |= data.flushTo0(); + e_rc |= data.setBit(0); // Chiplet enable + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // --- Vital THOLD, Winkle Fence + FAPI_DBG("\tSetting Vital THOLD and Winkle Fence in GP3"); + address = EX_GP3_OR_0x100F0014 + (0x01000000 * i_ex_number); + e_rc |= data.flushTo0(); + e_rc |= data.setBit(16); // Vital THOLD + e_rc |= data.setBit(27); // Electrical Winkle Fence for PM + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // --- Align f and f/2 (done only to mimic proc_sbe_chiplet_init.S) +// address = EX_GP0_AND_0x10000004 + (0x01000000 * i_ex_number); +// e_rc |= data.flushTo1(); +// e_rc |= data.clearBit(62); // Edge delayed +// +// if (e_rc) +// { +// FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); +// l_rc.setEcmdError(e_rc); +// break; +// } +// +// l_rc=fapiPutScom( i_target, address, data ); +// if(!l_rc.ok()) +// { +// FAPI_ERR("PutScom error 0x%08llX", address); +// break; +// } + + FAPI_DBG("\tSetting DPLL, PERV THOLD and Perv ECO Fence in PMGP0"); + address = EX_PMGP0_OR_0x100F0102 + (0x01000000 * i_ex_number); + e_rc |= data.flushTo0(); + e_rc |= data.setBit(3); // DPLL THOLD + e_rc |= data.setBit(4); // PERV THOLD + e_rc |= data.setBit(22); // PERVASIVE_ECO_FENCE + e_rc |= data.setBit(39); // Remove logical pervasive/pcbs-pm fence/ + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + FAPI_DBG("\tClearing old winkle fence to match SBE implementation in PMGP0"); + address = EX_PMGP0_AND_0x100F0101 + (0x01000000 * i_ex_number); + e_rc |= data.flushTo1(); + e_rc |= data.clearBit(23); // Old + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // Clear Special Wakeups present in uninitialized chiplets + FAPI_DBG("\tClear Special Wakeups present in uninitialized chiplets"); + address = EX_PMSpcWkupOCC_REG_0x100F010C + (0x01000000 * i_ex_number); + e_rc |= data.flushTo0(); + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + } + } + + // Reads to allow for Cronus 5.1 or 5.6 to look at the resultant setting + address = EX_PMGP0_0x100F0100 + (0x01000000 * i_ex_number); + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + address = EX_GP3_0x100F0012 + (0x01000000 * i_ex_number); + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + // Off + if (i_op == VOFF) + { + l_rc=p8_pfet_off(i_target, i_ex_number, i_domain); + if(!l_rc.ok()) + { + FAPI_ERR("\tPFET turn off of %s domains failed", + pfet_dom_names[i_domain]); + break; + } + } + else if (i_op == VOFF_OVERRIDE) + { + l_rc=p8_pfet_off_override(i_target, i_ex_number, i_domain); + if(!l_rc.ok()) + { + FAPI_ERR("\tPFET turn off of %s domains failed", + pfet_dom_names[i_domain]); + break; + } + } + // On + else if (i_op == VON) + { + l_rc=p8_pfet_on(i_target, i_ex_number, i_domain); + if(!l_rc.ok()) + { + FAPI_ERR("\tPFET turn on of %s domains failed", + pfet_dom_names[i_domain]); + break; + } + } + // Error + else + { + FAPI_ERR("\tUnreachable core op point 0x%x", i_op); + const uint64_t& EX = i_ex_number; + const uint64_t& DOMAIN = i_domain; + const uint64_t& OPERATION = i_op; + FAPI_SET_HWP_ERROR(l_rc, RC_PMPROC_PFETLIB_CODE_FAULT); + break; + } + + + // Restore GP3 except for reinit_endp as this will force power on + if (restore_gp3) + { + address = EX_GP3_0x100F0012 + (0x01000000 * i_ex_number); + e_rc |= gp3.clearBit(1); // End point reset + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + FAPI_DBG("\tRestoring GP3 with the exception of endpoint reset: 0x%16llX", gp3.getDoubleWord(0)); + l_rc=fapiPutScom( i_target, address, gp3 ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + } + + // Restore PMGP0 settings + if (restore_pmgp0) + { + address = EX_PMGP0_0x100F0100 + (0x01000000 * i_ex_number); + FAPI_DBG("\tRestoring PMGP0: 0x%16llX", pmgp0.getDoubleWord(0)); + l_rc=fapiPutScom( i_target, address, pmgp0 ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + } + + + } while(0); + + + + return l_rc; +} + +///----------------------------------------------------------------------------- +/// Turn a chiplet domain on - VCS first, then VDD +/// +/// \param[in] i_target Chip target +/// \param[in] i_ex_number EX number +/// \param[in] i_domain Domain: ECO, CORE, BOTH +/// +/// \retval FAPI_RC_SUCCESS if something good happens, +/// \retval BAD_RETURN_CODE otherwise +fapi::ReturnCode +p8_pfet_on( const fapi::Target& i_target, + uint8_t i_ex_number, + pfet_dom_t i_domain + ) +{ + + fapi::ReturnCode l_rc; + uint32_t e_rc = 0; + ecmdDataBufferBase data(64); + uint64_t address; + bool b_core = false; + bool b_eco = false; + + do + { + if ((i_domain == CORE) || (i_domain == BOTH)) + { + b_core = true; + } + if ((i_domain == ECO) || (i_domain == BOTH)) + { + b_eco = true; + } + + l_rc = p8_pfet_ivrm_fsm_fix(i_target, + i_ex_number, + i_domain, + VON); + if(!l_rc.ok()) + { + FAPI_ERR("PFET IVMR fix error"); + break; + } + + // VCS --------------------- + + FAPI_INF("Turning on VCS"); + address = EX_PFET_CTL_REG_0x100F010E + (0x01000000 * i_ex_number); + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX before 0x%16llX", + address, + data.getDoubleWord(0)); + + if (b_core) + { + FAPI_DBG("\tEnabling turn on of Core VDD"); + e_rc |= data.clearBit(CORE_OVERRIDE_STATE, CORE_OVERRIDE_LENGTH); + e_rc |= data.clearBit(CORE_FORCE_STATE, CORE_FORCE_LENGTH); + e_rc |= data.insert((uint32_t)VON, CORE_FORCE_STATE, CORE_FORCE_LENGTH, 30); + } + + if (b_eco) + { + FAPI_DBG("\tEnabling turn on of ECO VDD"); + e_rc |= data.clearBit(ECO_OVERRIDE_STATE, ECO_OVERRIDE_LENGTH); + e_rc |= data.clearBit(ECO_FORCE_STATE, ECO_FORCE_LENGTH); + e_rc |= data.insert((uint32_t)VON, ECO_FORCE_STATE, ECO_FORCE_LENGTH, 30); + } + + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX before 0x%16llX", + address, + data.getDoubleWord(0)); + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // Poll for completion + l_rc=p8_pfet_poll(i_target, address, i_domain); + if(!l_rc.ok()) + { + FAPI_ERR("PFET poll timeout turning on VCS"); + // l_rc is set timeout xml based code in p8_pfet_poll + break; + } + + // Put the controls back to a Nop state + e_rc |= data.clearBit(CORE_FORCE_STATE, CORE_FORCE_LENGTH); + e_rc |= data.clearBit(ECO_FORCE_STATE, ECO_FORCE_LENGTH); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // VDD --------------------- + + FAPI_INF("Turning on VDD for EX %d", i_ex_number); + address = EX_PFET_CTL_REG_0x100F0106 + (0x01000000 * i_ex_number); + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX before 0x%16llX", + address, + data.getDoubleWord(0)); + + if (b_core) + { + FAPI_DBG("\tEnabling turn on of Core VDD"); + e_rc |= data.clearBit(CORE_OVERRIDE_STATE, CORE_OVERRIDE_LENGTH); + e_rc |= data.clearBit(CORE_FORCE_STATE, CORE_FORCE_LENGTH); + e_rc |= data.insert((uint32_t)VON, CORE_FORCE_STATE, CORE_FORCE_LENGTH, 30); + } + + if (b_eco) + { + FAPI_DBG("\tEnabling turn on of ECO VDD"); + e_rc |= data.clearBit(ECO_OVERRIDE_STATE, ECO_OVERRIDE_LENGTH); + e_rc |= data.clearBit(ECO_FORCE_STATE, ECO_FORCE_LENGTH); + e_rc |= data.insert((uint32_t)VON, ECO_FORCE_STATE, ECO_FORCE_LENGTH, 30); + } + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX before 0x%16llX", + address, + data.getDoubleWord(0)); + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // Poll for completion + l_rc=p8_pfet_poll(i_target, address, i_domain); + if(!l_rc.ok()) + { + FAPI_ERR("PFET poll timeout turning on VDD"); + // l_rc is set timeout xml based code in p8_pfet_poll + break; + } + + // Put the controls back to a Nop state + e_rc |= data.clearBit(CORE_FORCE_STATE, CORE_FORCE_LENGTH); + e_rc |= data.clearBit(ECO_FORCE_STATE, ECO_FORCE_LENGTH); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + } while(0); + return l_rc; +} + +///----------------------------------------------------------------------------- +/// Turn a chiplet domain off - VDD first, then VCS +/// +/// \param[in] i_target Chip target +/// \param[in] i_ex_number EX number +/// \param[in] i_domain Domain: ECO, CORE, BOTH +/// +/// \retval FAPI_RC_SUCCESS if something good happens, +/// \retval BAD_RETURN_CODE otherwise +fapi::ReturnCode +p8_pfet_off( const fapi::Target& i_target, + uint8_t i_ex_number, + pfet_dom_t i_domain + ) +{ + fapi::ReturnCode l_rc; + uint32_t e_rc = 0; + ecmdDataBufferBase data(64); + uint64_t address; + bool b_core = false; + bool b_eco = false; + + do + { + if ((i_domain == CORE) || (i_domain == BOTH)) + { + b_core = true; + } + if ((i_domain == ECO) || (i_domain == BOTH)) + { + b_eco = true; + } + + l_rc = p8_pfet_ivrm_fsm_fix(i_target, + i_ex_number, + i_domain, + VOFF); + if(!l_rc.ok()) + { + FAPI_ERR("PFET IVMR fix error"); + break; + } + + + // Check if iVRM Bypasses are active + address = EX_PCBS_iVRM_Control_Status_Reg_0x100F0154 + + (0x01000000 * i_ex_number); + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + FAPI_DBG("\tEX_PCBS_iVRM_Control_Status_Reg_0x%08llX before 0x%16llX", + address, + data.getDoubleWord(0)); + + e_rc |= data.flushTo0(); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + FAPI_DBG("\tEX_PCBS_iVRM_Control_Status_Reg_0x%08llX after 0x%16llX", + address, + data.getDoubleWord(0)); + + // VDD --------------------- + + FAPI_INF("Turning off VDD"); + + + + address = EX_PFET_CTL_REG_0x100F0106 + (0x01000000 * i_ex_number); + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX before 0x%16llX", + address, + data.getDoubleWord(0)); + + + + if (b_core) + { + FAPI_DBG("\tClearing overrides to enable turn off of Core VDD"); + e_rc |= data.clearBit(CORE_OVERRIDE_STATE, CORE_OVERRIDE_LENGTH); + e_rc |= data.clearBit(CORE_FORCE_STATE, CORE_FORCE_LENGTH); + e_rc |= data.insert((uint32_t)VOFF, CORE_FORCE_STATE, CORE_FORCE_LENGTH, 30); + } + + if (b_eco) + { + FAPI_DBG("\tClearing overrides to enable turn off of ECO VDD"); + e_rc |= data.clearBit(ECO_OVERRIDE_STATE, ECO_OVERRIDE_LENGTH); + e_rc |= data.clearBit(ECO_FORCE_STATE, ECO_FORCE_LENGTH); + e_rc |= data.insert((uint32_t)VOFF, ECO_FORCE_STATE, ECO_FORCE_LENGTH, 30); + } + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX after 0x%16llX", + address, + data.getDoubleWord(0)); + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // Poll for completion + l_rc=p8_pfet_poll(i_target, address, i_domain); + if(!l_rc.ok()) + { + FAPI_ERR("PFET poll timeout turning off VDD"); + // l_rc is set timeout xml based code in p8_pfet_poll + break; + } + + FAPI_DBG("Put the controls back to a Nop state"); + e_rc |= data.clearBit(CORE_FORCE_STATE, CORE_FORCE_LENGTH); + e_rc |= data.clearBit(ECO_FORCE_STATE, ECO_FORCE_LENGTH); +// e_rc |= data.insert((uint32_t)NONE, CORE_FORCE_STATE, CORE_FORCE_LENGTH, 30); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + FAPI_DBG("\tNOP 0x%16llX", data.getDoubleWord(0)); + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // Read to allow for Cronus 5.1 or 5.6 to look at the resultant setting + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + // VCS --------------------- + + FAPI_INF("Turning off VCS"); + address = EX_PFET_CTL_REG_0x100F010E + (0x01000000 * i_ex_number); + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX before 0x%16llX", + address, + data.getDoubleWord(0)); + + if (b_core) + { + FAPI_DBG("\tClearing overrides to enable turn off of Core VDD"); + e_rc |= data.clearBit(CORE_OVERRIDE_STATE, CORE_OVERRIDE_LENGTH); + e_rc |= data.clearBit(CORE_FORCE_STATE, CORE_FORCE_LENGTH); + e_rc |= data.insert((uint32_t)VOFF, CORE_FORCE_STATE, CORE_FORCE_LENGTH, 30); + } + + if (b_eco) + { + FAPI_DBG("\tClearing overrides to enable turn off of ECO VDD"); + e_rc |= data.clearBit(ECO_OVERRIDE_STATE, ECO_OVERRIDE_LENGTH); + e_rc |= data.clearBit(ECO_FORCE_STATE, ECO_FORCE_LENGTH); + e_rc |= data.insert((uint32_t)VOFF, ECO_FORCE_STATE, ECO_FORCE_LENGTH, 30); + } + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX after 0x%16llX", + address, + data.getDoubleWord(0)); + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // Poll for completion + l_rc=p8_pfet_poll(i_target, address, i_domain); + if(!l_rc.ok()) + { + FAPI_ERR("PFET poll timeout turning on VCS"); + // l_rc is set timeout xml based code in p8_pfet_poll + break; + } + + FAPI_DBG("\tPut the controls back to a Nop state"); + e_rc |= data.clearBit(CORE_FORCE_STATE, CORE_FORCE_LENGTH); + e_rc |= data.clearBit(ECO_FORCE_STATE, ECO_FORCE_LENGTH); + // e_rc |= data.insert((uint32_t)NONE, ECO_FORCE_STATE, ECO_FORCE_LENGTH, 30); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + FAPI_DBG("\tNOP 0x%16llX", data.getDoubleWord(0)); + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + + // Read to allow for Cronus 5.1 or 5.6 to look at the resultant setting + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + } while(0); + return l_rc; +} + +///----------------------------------------------------------------------------- +/// Turn a chiplet domain off - VDD first, then VCS +/// +/// \param[in] i_target Chip target +/// \param[in] i_ex_number EX number +/// \param[in] i_domain Domain: ECO, CORE, BOTH +/// +/// \retval FAPI_RC_SUCCESS if something good happens, +/// \retval BAD_RETURN_CODE otherwise +fapi::ReturnCode +p8_pfet_off_override( const fapi::Target& i_target, + uint8_t i_ex_number, + pfet_dom_t i_domain + ) +{ + fapi::ReturnCode l_rc; + uint32_t e_rc = 0; + ecmdDataBufferBase data(64); + uint64_t address; + bool b_core = false; + bool b_eco = false; + const uint32_t core_regulation_finger = 10; + const uint32_t eco_regulation_finger = 26; + + do + { + if ((i_domain == CORE) || (i_domain == BOTH)) + { + b_core = true; + } + if ((i_domain == ECO) || (i_domain == BOTH)) + { + b_eco = true; + } + + l_rc = p8_pfet_ivrm_fsm_fix(i_target, + i_ex_number, + i_domain, + VOFF); + if(!l_rc.ok()) + { + FAPI_ERR("PFET IVMR fix error"); + break; + } + + // Check if iVRM Bypasses are active + address = EX_PCBS_iVRM_Control_Status_Reg_0x100F0154 + + (0x01000000 * i_ex_number); + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + FAPI_DBG("\tEX_PCBS_iVRM_Control_Status_Reg_0x%08llX before 0x%16llX", + address, + data.getDoubleWord(0)); + + e_rc |= data.flushTo0(); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + FAPI_DBG("\tEX_PCBS_iVRM_Control_Status_Reg_0x%08llX after 0x%16llX", + address, + data.getDoubleWord(0)); + + // VDD --------------------- + + FAPI_INF("Turning off VDD with controller override"); + + address = EX_PFET_CTL_REG_0x100F0106 + (0x01000000 * i_ex_number); + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX before 0x%16llX", + address, + data.getDoubleWord(0)); + + // Turn off the non-regulation fingers (relative bits 1:11) + for (int i = 1; i <= 11; i++) + { + if (b_core) + { + FAPI_DBG("\tClearing Core VDD finger %d", core_regulation_finger+i); + e_rc |= data.clearBit(core_regulation_finger+i); + } + + if (b_eco) + { + FAPI_DBG("\tClearing ECO VDD finger %d", eco_regulation_finger+i); + e_rc |= data.clearBit(eco_regulation_finger+i); + } + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX after 0x%16llX", + address, + data.getDoubleWord(0)); + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // Read to allow for Cronus 5.1 or 5.6 to look at the resultant setting + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + } + + // Turn off the regulation finger: core first, then ECO + if (b_core) + { + FAPI_DBG("\tClearing Core VDD regulation finger %d", core_regulation_finger); + e_rc |= data.clearBit(core_regulation_finger); + +// FAPI_DBG("\tSetting the select value to indicate OFF for ECO VDD"); +// e_rc |= data.setBit(5); +// e_rc |= data.insert((uint32_t)0xB, CORE_OVERRIDE_SEL, CORE_OVERRIDE_SEL_LENGTH, 28); + } + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + +// FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX after 0x%16llX", +// address, +// data.getDoubleWord(0)); +// +// l_rc=fapiPutScom( i_target, address, data ); +// if(!l_rc.ok()) +// { +// FAPI_ERR("PutScom error 0x%08llX", address); +// break; +// } +// + if (b_eco) + { + FAPI_DBG("\tClearing ECO regulation VDD finger %d", eco_regulation_finger); + e_rc |= data.clearBit(eco_regulation_finger); + +// FAPI_DBG("\tSetting the select value to indicate OFF for ECO VDD"); +// e_rc |= data.setBit(7); +// e_rc |= data.insert((uint32_t)0xB, ECO_OVERRIDE_SEL, ECO_OVERRIDE_SEL_LENGTH, 28); + } + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + + + + // VCS --------------------- + + FAPI_INF("Turning off VCS with controller override"); + + address = EX_PFET_CTL_REG_0x100F010E + (0x01000000 * i_ex_number); + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX before 0x%16llX", + address, + data.getDoubleWord(0)); + + // Turn off the non-regulation fingers (relative bits 1:11) + for (int i = 1; i <= 11; i++) + { + if (b_core) + { + FAPI_DBG("\tClearing Core VCS finger %d", core_regulation_finger+i); + e_rc |= data.clearBit(core_regulation_finger+i); + } + + if (b_eco) + { + FAPI_DBG("\tClearing ECO VCS finger %d", eco_regulation_finger+i); + e_rc |= data.clearBit(eco_regulation_finger+i); + } + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX after 0x%16llX", + address, + data.getDoubleWord(0)); + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + } + + // Turn off the regulation finger: core first, then ECO + if (b_core) + { + FAPI_DBG("\tClearing Core VCS regulation finger %d", core_regulation_finger); + e_rc |= data.clearBit(core_regulation_finger); + +// FAPI_DBG("\tSetting the select value to indicate OFF for ECO VCS"); +// e_rc |= data.setBit(5); +// e_rc |= data.insert((uint32_t)0xB, CORE_OVERRIDE_SEL, CORE_OVERRIDE_SEL_LENGTH, 28); + } + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + +// FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX after 0x%16llX", +// address, +// data.getDoubleWord(0)); +// +// l_rc=fapiPutScom( i_target, address, data ); +// if(!l_rc.ok()) +// { +// FAPI_ERR("PutScom error 0x%08llX", address); +// break; +// } + + if (b_eco) + { + FAPI_DBG("\tClearing ECO regulation VCS finger %d", eco_regulation_finger); + e_rc |= data.clearBit(eco_regulation_finger); + +// FAPI_DBG("\tSetting the select value to indicate OFF for ECO VCS"); +// e_rc |= data.setBit(7); +// e_rc |= data.insert((uint32_t)0xB, ECO_OVERRIDE_SEL, ECO_OVERRIDE_SEL_LENGTH, 28); + } + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + if (b_core) + { + FAPI_DBG("\tClearing Core VCS overrides %d", core_regulation_finger); + e_rc |= data.clearBit(core_regulation_finger); + + FAPI_DBG("\tSetting the select value to indicate OFF for ECO VCS"); + e_rc |= data.setBit(5); + e_rc |= data.insert((uint32_t)0xB, CORE_OVERRIDE_SEL, CORE_OVERRIDE_SEL_LENGTH, 28); + } + + + // Read to allow for Cronus 5.1 or 5.6 to look at the resultant setting + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + } while(0); + return l_rc; +} + +/// \param[in] i_target Chip target +/// \param[in] i_address Address to poll for PFET State +/// \param[in] i_domain Domain: BOTH, ECO, CORE +/// +/// \retval FAPI_RC_SUCCESS +/// \retval RC_PROCPM_PFET_TIMEOUT otherwise +fapi::ReturnCode +p8_pfet_poll( const fapi::Target& i_target, + uint64_t i_address, + pfet_dom_t i_domain) +{ + fapi::ReturnCode l_rc; + ecmdDataBufferBase data(64); + uint32_t i; + bool b_core_idle = false; + bool b_eco_idle = false; + char core_state_buffer[32]; + char eco_state_buffer[32]; + + uint32_t CORE_PFET_IDLE_STATE_START_BIT = 46; + uint32_t ECO_PFET_IDLE_STATE_START_BIT = 54; + + do + { + FAPI_DBG("\tPoll for FSM to go back to idle"); + for (i=0; i<=PFET_MAX_IDLE_POLLS; i++) + { + + // Delay between polls + l_rc=fapiDelay( PFET_POLL_WAIT, PFET_POLL_WAIT_SIM ); + if(!l_rc.ok()) + { + FAPI_ERR("fapiDelay error"); + break; + } + + l_rc=fapiGetScom(i_target, i_address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", i_address); + break; + } + + if ((i_domain == CORE) || (i_domain == BOTH)) + { + if (data.isBitSet(CORE_FSM_IDLE_BIT)) + { + FAPI_DBG("\tCore domain idle"); + b_core_idle=true; + } + } + if ((i_domain == ECO) || (i_domain == BOTH)) + { + if (data.isBitSet(ECO_FSM_IDLE_BIT)) + { + FAPI_DBG("\tECO domain idle"); + b_eco_idle=true; + } + } + + // Exit the polling loop if both are idle + if (b_core_idle && b_eco_idle) + { + FAPI_DBG("\tPoll complete"); + + // Check for Core State + l_rc = p8_pfet_read_state( i_target, + i_address, + CORE_PFET_IDLE_STATE_START_BIT, + core_state_buffer ); + if(!l_rc.ok()) + { + FAPI_ERR("pfet_read_state Core error 0x%08llX", i_address); + break; + } + + // Check for ECO State + l_rc = p8_pfet_read_state( i_target, + i_address, + ECO_PFET_IDLE_STATE_START_BIT, + eco_state_buffer ); + if(!l_rc.ok()) + { + FAPI_ERR("pfet_read_state ECO error 0x%08llX", i_address); + break; + } + + FAPI_DBG("\tCore State: %s; ECO State: %s", core_state_buffer, eco_state_buffer); + + break; + } + + + } + // If both rails are not idle, error out + if (!(b_core_idle && b_eco_idle)) + { + FAPI_ERR("\tERROR: Polling timeout "); + const uint64_t& ADDRESS = i_address; + const uint64_t& PFETCONTROLVALUE = data.getDoubleWord(0); + const uint64_t& DOMAIN = i_domain; + FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFETLIB_TIMEOUT); + break; + } + + + + } while(0); + return l_rc; +} + +//------------------------------------------------------------------------------ +/// pfet_read_state_delay +/// +/// \param[in] i_target Chip target +/// \param[in] i_address Address to poll for PFET State +/// \param[in] i_bitoffset Bit to poll on +/// \param[out] o_state String representing the state of the controller +/// "OFF", "ON", "REGULATION", "UNDEFINED" +fapi::ReturnCode +p8_pfet_read_state(const fapi::Target& i_target, + const uint64_t i_address, + const uint32_t i_bitoffset, + char * o_state) +{ + fapi::ReturnCode l_rc; + uint32_t e_rc = 0; + ecmdDataBufferBase data; + uint32_t value; + + do + { + l_rc=fapiGetScom( i_target, i_address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", i_address); + break; + } + + FAPI_DBG("\tEX_PFET_CTL_REG_0x%08llX 0x%16llX", + i_address, + data.getDoubleWord(0)); + + + e_rc = data.extractToRight(&value,i_bitoffset,4); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + + if (value == 0xB) + { + strcpy(o_state, "OFF"); + } + else if (value == 0) + { + strcpy(o_state, "ON"); + } + else if (value == 8) + { + strcpy(o_state, "REGULATION"); + } + else + { + strcpy(o_state, "UNDEFINED"); + } + + } while(0); + return l_rc; +} + +//------------------------------------------------------------------------------ +/// p8_pfet_ivrm_fsm_fix +/// Fix ivrm FSM interference with PFET power off +/// \param[in] i_target Chip target +/// \param[in] i_ex_number EX number +/// \param[in] i_domain Domain: BOTH, ECO, CORE +/// \param[in] i_op Operation: VON, VOFF, NONE +//------------------------------------------------------------------------------ +fapi::ReturnCode +p8_pfet_ivrm_fsm_fix(const fapi::Target& i_target, + uint8_t i_ex_number, + pfet_dom_t i_domain, + pfet_force_t i_op) +{ + fapi::ReturnCode l_rc; + uint32_t e_rc = 0; + ecmdDataBufferBase data(64); + uint64_t address; + uint32_t value; + + ecmdDataBufferBase gp3(64); + + ecmdDataBufferBase pmgp0(64); + const uint32_t PM_DISABLE_BIT = 0; + + ecmdDataBufferBase pcbspm_mode(64); + const uint32_t TIMER_MODE_BIT = 7; + + ecmdDataBufferBase cpm_dpll_parm(64); + const uint32_t DPLL_LOCK_TIMER_BIT = 15; + const uint32_t DPLL_LOCK_TIMER_BITS = 9; + + ecmdDataBufferBase pmgp1(64); + const uint32_t WINKLE_POWER_DN_EN_BIT = 3; + const uint32_t WINKLE_POWER_OFF_SEL_BIT = 5; + + ecmdDataBufferBase ivrm_control_status(64); + const uint32_t GOTO_WINKLE_BIT = 3; + const uint32_t GOTO_WAKEUP_BIT = 4; + const uint32_t BABYSTEPPER_WINKLE_TIMEOUT = 10; + const uint32_t BABYSTEPPER_WAKEUP_TIMEOUT = 10; + + ecmdDataBufferBase core_voff_vret(64); + ecmdDataBufferBase eco_voff_vret(64); + + + FAPI_INF("Beginning FET work-around for IVRM FSM"); + do + { + + // --------------------------------------------------------------------- + + address = EX_GP3_0x100F0012 + 0x01000000*i_ex_number; + + // Save the setting for later restoration + l_rc=fapiGetScom( i_target, address, gp3 ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + address = EX_PMGP0_0x100F0100 + 0x01000000*i_ex_number; + + // Save the setting for possible setting later + l_rc=fapiGetScom( i_target, address, pmgp0 ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + + if (gp3.isBitClear(0)) + { + FAPI_INF("Set PMGP0 access mode, fence the PCB, raise PB electrical fence"); + e_rc |= data.flushTo0(); + e_rc |= data.setBit(20); + e_rc |= data.setBit(26); + e_rc |= data.setBit(27); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + // Set the bit + address = EX_GP3_OR_0x100F0014 + 0x01000000*i_ex_number; + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // ---------------------- + // Read back for debug + address = EX_GP3_0x100F0012 + 0x01000000*i_ex_number; + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + FAPI_DBG("\tGP3 value: 0x%016llX", data.getDoubleWord(0)); + + // ---------------------- + FAPI_INF("Set Slave Winkle fence"); + e_rc |= data.flushTo0(); + e_rc |= data.setBit(39); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + // Set the bit + address = EX_PMGP0_OR_0x100F0102 + 0x01000000*i_ex_number; + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // ---------------------- + // Read back for debug + address = EX_PMGP0_0x100F0100 + 0x01000000*i_ex_number; + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + FAPI_DBG("\tPMGP0 value: 0x%016llX", data.getDoubleWord(0)); + + FAPI_INF("Temporarily enable the chiplet"); + e_rc |= data.flushTo0(); + e_rc |= data.setBit(0); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + // Set the bit + address = EX_GP3_OR_0x100F0014 + 0x01000000*i_ex_number; + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // ---------------------- + // Read back for debug + address = EX_GP3_OR_0x100F0014 + 0x01000000*i_ex_number; + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + FAPI_DBG("\tGP3 value: 0x%016llX", data.getDoubleWord(0)); + + address = EX_PMGP0_0x100F0100 + 0x01000000*i_ex_number; + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + FAPI_DBG("\tPMGP0 value: 0x%016llX", data.getDoubleWord(0)); + // ---------------------- + } + + // --------------------------------------------------------------------- + + if (pmgp0.isBitSet(PM_DISABLE_BIT)) + { + FAPI_INF("Enabling Power Management as it is needed"); + e_rc |= data.flushTo1(); + e_rc |= data.clearBit(PM_DISABLE_BIT); + if (e_rc) + { + l_rc.setEcmdError(e_rc); + break; + } + + // Clear the bit + address = EX_PMGP0_AND_0x100F0101 + 0x01000000*i_ex_number; + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + } + + // --------------------------------------------------------------------- + FAPI_INF("Set timer Mode"); + address = EX_PCBSPM_MODE_REG_0x100F0156 + 0x01000000*i_ex_number; + + // Save the setting + l_rc=fapiGetScom( i_target, address, pcbspm_mode ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + data = pcbspm_mode; + e_rc |= data.setBit(TIMER_MODE_BIT); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // --------------------------------------------------------------------- + FAPI_INF("Clear dpll_lock_timer_replacement value to disable waiting"); + address = EX_DPLL_CPM_PARM_REG_0x100F0152 + 0x01000000*i_ex_number; + + // Save the setting + l_rc=fapiGetScom( i_target, address, cpm_dpll_parm ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + data = cpm_dpll_parm; + e_rc |= data.clearBit(DPLL_LOCK_TIMER_BIT, DPLL_LOCK_TIMER_BITS); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // --------------------------------------------------------------------- + FAPI_INF("Set Local Pstate Table VID value to > 0"); + // Set address to 0 to be sure + address = EX_PCBS_PSTATE_TABLE_CTRL_REG_0x100F015E + 0x01000000*i_ex_number; + e_rc |= data.flushTo0(); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + address = EX_PCBS_PSTATE_TABLE_REG_0x100F015F + 0x01000000*i_ex_number; + value = 1; + e_rc |= data.insertFromRight(&value, 0, 7); + e_rc |= data.insertFromRight(&value, 7, 7); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // --------------------------------------------------------------------- + FAPI_INF("Writing Local Pstate Table Size"); + address = EX_PCBS_Power_Management_Bounds_Reg_0x100F015D + + 0x01000000*i_ex_number; + + uint32_t lpsi_min = 0; + uint32_t lpsi_entries_minus_1 = 0; // one entry + uint32_t lpsi_min_index = lpsi_min + 128; // converted into index space + + + e_rc |= data.flushTo0(); + e_rc |= data.insertFromRight(&lpsi_min_index, 0, 8); + e_rc |= data.insertFromRight(&lpsi_entries_minus_1, 8, 7); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // --------------------------------------------------------------------- + FAPI_INF("Enable IVRM FSM and then PState mode"); + + // IVRM Enable + address = EX_PCBS_iVRM_Control_Status_Reg_0x100F0154 + + 0x01000000*i_ex_number; + + + l_rc=fapiGetScom( i_target, address, ivrm_control_status ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + data = ivrm_control_status; + e_rc |= data.setBit(0); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // Pstate mode + address = EX_PCBSPM_MODE_REG_0x100F0156 + 0x01000000*i_ex_number; + + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + e_rc |= data.setBit(0); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // --------------------------------------------------------------------- + // Setup the appropriate off action when triggering the babystepper to + // winkle entry (fast without off for configured chiplets; deep with + // power loss for deconfigured chiplets). + + address = EX_CorePFVRET_REG_0x100F0130 + 0x01000000*i_ex_number; + l_rc=fapiGetScom( i_target, address, core_voff_vret ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + address = EX_ECOPFVRET_REG_0x100F0150 + 0x01000000*i_ex_number; + l_rc=fapiGetScom( i_target, address, eco_voff_vret ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + address = EX_PMGP1_0x100F0103 + 0x01000000*i_ex_number; + l_rc=fapiGetScom( i_target, address, pmgp1 ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + data = pmgp1; + + if (i_op == VOFF) + { + FAPI_INF("Set winkle power off select to deep"); + e_rc |= data.setBit(WINKLE_POWER_OFF_SEL_BIT); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + } + else if (i_op == VON) + { + FAPI_INF("Set winkle power off select to fast with no power change"); + e_rc |= data.clearBit(WINKLE_POWER_OFF_SEL_BIT); + e_rc |= data.clearBit(WINKLE_POWER_DN_EN_BIT); + + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // Don't let the power go off + e_rc |= data.flushTo0(); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + address = EX_CorePFVRET_REG_0x100F0130 + 0x01000000*i_ex_number; + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + address = EX_ECOPFVRET_REG_0x100F0150 + 0x01000000*i_ex_number; + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + } + else + { + FAPI_ERR("Unsupported i_op to iVRM fix"); + break; + } + + // --------------------------------------------------------------------- + FAPI_INF("Trigger winkle to synchronize the iVRM babystepper"); + + address = EX_IDLEGOTO_0x100F0114 + 0x01000000*i_ex_number; + + e_rc |= data.flushTo0(); + e_rc |= data.setBit(GOTO_WINKLE_BIT); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + uint32_t i = 0; + do + { + FAPI_DBG("Poll for completion: %d", i); + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + if (data.isBitClear(GOTO_WINKLE_BIT)) + { + break; + } + + e_rc |= fapiDelay(10000, 1000); + if (e_rc) + { + FAPI_ERR("Error (0x%x) from fapiDelay", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + + i++; + + } while (data.isBitSet(GOTO_WINKLE_BIT) && i < BABYSTEPPER_WINKLE_TIMEOUT); + + if (i >= BABYSTEPPER_WINKLE_TIMEOUT) + { + FAPI_DBG("\tBaby Stepper Timeout %d", i_ex_number); + //const uint64_t& EX = i_ex_number; + //FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFETLIB_BABYSTEPPER_TIMEOUT); + //break; + + } + + // --------------------------------------------------------------------- + FAPI_INF("Trigger winkle wakeup to get get the FSM back to idle"); + // IVRM Enable + address = EX_IDLEGOTO_0x100F0114 + 0x01000000*i_ex_number; + + e_rc |= data.flushTo0(); + e_rc |= data.setBit(GOTO_WAKEUP_BIT); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } + l_rc=fapiPutScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + i = 0; + do + { + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + + if (data.isBitClear(GOTO_WAKEUP_BIT)) + { + break; + } + + i++; + + } while (data.isBitSet(GOTO_WAKEUP_BIT) && i < BABYSTEPPER_WAKEUP_TIMEOUT); + if (i >= BABYSTEPPER_WAKEUP_TIMEOUT) + { + FAPI_DBG("\tBaby Stepper Timeout on Wakeup %d", i_ex_number); + //const uint64_t& EX = i_ex_number; + //FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFETLIB_BABYSTEPPER_WAKEUP_TIMEOUT); + //break; + + } + + + // ----- Debug registers ----- + address = EX_PCBS_FSM_MONITOR1_REG_0x100F0170 + + 0x01000000*i_ex_number; + + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + FAPI_DBG("\tPCBS Monitor1 for Core %d: 0x%16llX", i_ex_number, data.getDoubleWord(0)); + + address = EX_PCBS_FSM_MONITOR2_REG_0x100F0171 + + 0x01000000*i_ex_number; + + l_rc=fapiGetScom( i_target, address, data ); + if(!l_rc.ok()) + { + FAPI_ERR("GetScom error 0x%08llX", address); + break; + } + FAPI_DBG("\tPCBS Monitor2 for Core %d: 0x%16llX", i_ex_number, data.getDoubleWord(0)); + + + // ----- Restore registers ----- + + // DPLL_CPM_PARM_REG + FAPI_DBG("Restore DPLL_CPM_PARM_REG: 0x%16llX", cpm_dpll_parm.getDoubleWord(0)); + + address = EX_DPLL_CPM_PARM_REG_0x100F0152 + + 0x01000000*i_ex_number; + + l_rc=fapiPutScom( i_target, address, cpm_dpll_parm ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // Core OFF/VRET + FAPI_DBG("Restore Core OFF/VRET pointers: 0x%16llX", core_voff_vret.getDoubleWord(0)); + + address = EX_CorePFVRET_REG_0x100F0130 + + 0x01000000*i_ex_number; + + l_rc=fapiPutScom( i_target, address, core_voff_vret ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // ECO OFF/VRET + FAPI_DBG("Restore ECO OFF/VRET pointers: 0x%16llX", eco_voff_vret.getDoubleWord(0)); + + address = EX_ECOPFVRET_REG_0x100F0150 + + 0x01000000*i_ex_number; + + l_rc=fapiPutScom( i_target, address, eco_voff_vret ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // PM MODE + FAPI_DBG("Restore PM MODE: 0x%16llX", pcbspm_mode.getDoubleWord(0)); + + address = EX_PCBSPM_MODE_REG_0x100F0156 + + 0x01000000*i_ex_number; + + l_rc=fapiPutScom( i_target, address, pcbspm_mode ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // iVRM_Control_Status + FAPI_DBG("Restore IVRM Control / Status: 0x%16llX", ivrm_control_status.getDoubleWord(0)); + + address = EX_PCBS_iVRM_Control_Status_Reg_0x100F0154 + + 0x01000000*i_ex_number; + + l_rc=fapiPutScom( i_target, address, ivrm_control_status ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + // PMGP1 + FAPI_DBG("Restore PMGP1: 0x%16llX", pmgp1.getDoubleWord(0)); + + address = EX_PMGP1_0x100F0103 + 0x01000000*i_ex_number; + + l_rc=fapiPutScom( i_target, address, pmgp1 ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // PMGP0 + FAPI_DBG("Restore PMGP0: 0x%16llX", pmgp0.getDoubleWord(0)); + + address = EX_PMGP0_0x100F0100 + 0x01000000*i_ex_number; + + l_rc=fapiPutScom( i_target, address, pmgp0 ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + // GP3 + FAPI_DBG("Restore GP3: 0x%16llX", gp3.getDoubleWord(0)); + + address = EX_GP3_0x100F0012 + 0x01000000*i_ex_number; + + l_rc=fapiPutScom( i_target, address, gp3 ); + if(!l_rc.ok()) + { + FAPI_ERR("PutScom error 0x%08llX", address); + break; + } + + } while(0); + + FAPI_INF("Completing PFET work-around for IVRM FSM"); + return l_rc; +} + +} //end extern + diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_control.H b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_control.H index 1c5ce25ad..11e280c0a 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_control.H +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_control.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_pfet_control.H,v 1.2 2012/12/12 04:28:30 stillgs Exp $ +// $Id: p8_pfet_control.H,v 1.4 2013/08/02 19:05:23 stillgs Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/p8_pfet_control.H,v $ //------------------------------------------------------------------------------ // *| @@ -44,32 +44,6 @@ extern "C" { #include "p8_pfet_types.H" -// Overrides -extern const uint32_t NO_ORVAL_PARM; -extern const uint32_t NO_ORSEL_PARM; -extern const uint32_t OR_DISABLE; -extern uint32_t or_val; -extern uint32_t or_sel; - -// Domains -extern pfet_dom_t domain; - -// Force operation -extern pfet_force_t force_op; - -// Vret and voff selectors -extern const int32_t FIRST_STAGE; -extern const int32_t LAST_STAGE; -extern const int32_t NO_SEL_PARM; -extern int32_t vret_sel; -extern int32_t voff_sel; - -// stage_value string -extern char * stage_values_str; -// powup_delay_values_str -extern char * powup_delay_values_str; -// powdn_delay_values_str -extern char * powdn_delay_values_str; // \todo Define the read structure for programmatic data return @@ -80,47 +54,39 @@ extern char * powdn_delay_values_str; // function pointer typedef definition for HWP call support typedef fapi::ReturnCode (*p8_pfet_control_FP_t) (const fapi::Target&, - uint8_t, + uint8_t, pfet_dom_t, pfet_force_t ); - + typedef fapi::ReturnCode (*p8_pfet_read_FP_t) (const fapi::Target&); //------------------------------------------------------------------------------ // Constant definitions //------------------------------------------------------------------------------ -// Macros for easier handling of parms -#define PFET_FORCE(target_mac, ex_mac, domain_mac, op_mac) \ - p8_pfet_control(target_mac, ex_mac, domain_mac, op_mac); //------------------------------------------------------------------------------ // Parameter structure definitions //------------------------------------------------------------------------------ - //------------------------------------------------------------------------------ // Function prototype //------------------------------------------------------------------------------ /// \param[in] i_target Chip target -/// \param[in] domain Domain: BOTH, ECO, CORE - +/// \param[in] i_ex_number EX number +/// \param[in] i_domain Domain: BOTH, ECO, CORE +/// \param[in] i_op Operation: VON, VOFF, NONE +/// /// \retval ECMD_SUCCESS if something good happens, /// \retval BAD_RETURN_CODE otherwise -fapi::ReturnCode -p8_pfet_control( const fapi::Target& i_target, +fapi::ReturnCode +p8_pfet_control( const fapi::Target& i_target, uint8_t i_ex_number, pfet_dom_t domain, pfet_force_t op ); -fapi::ReturnCode -p8_pfet_read( const fapi::Target& i_target); - - -uint8_t convert_delay_to_value (uint32_t i_delay, uint32_t i_attr_proc_nest_frequency); - } // extern "C" #endif // _P8_PFETCTL_H_ diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_errors.xml b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_errors.xml new file mode 100644 index 000000000..5bc6eafe8 --- /dev/null +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_errors.xml @@ -0,0 +1,85 @@ +<!-- IBM_PROLOG_BEGIN_TAG --> +<!-- This is an automatically generated prolog. --> +<!-- --> +<!-- $Source: src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_errors.xml $ --> +<!-- --> +<!-- IBM CONFIDENTIAL --> +<!-- --> +<!-- COPYRIGHT International Business Machines Corp. 2013 --> +<!-- --> +<!-- p1 --> +<!-- --> +<!-- Object Code Only (OCO) source materials --> +<!-- Licensed Internal Code Source Materials --> +<!-- IBM HostBoot Licensed Internal Code --> +<!-- --> +<!-- The source code for this program is not published or otherwise --> +<!-- divested of its trade secrets, irrespective of what has been --> +<!-- deposited with the U.S. Copyright Office. --> +<!-- --> +<!-- Origin: 30 --> +<!-- --> +<!-- IBM_PROLOG_END_TAG --> +<!-- $Id: p8_pfet_errors.xml,v 1.4 2013/05/23 18:44:19 stillgs Exp $ --> +<!-- Error definitions for p8_pfet_init and p8_pfet_lib procedures --> +<hwpErrors> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PMPROC_PFETLIB_BAD_DOMAIN</rc> + <description>Invalid domain value passed to p8_pfet_control.</description> + <ffdc>EX</ffdc> + <ffdc>DOMAIN</ffdc> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PMPROC_PFETLIB_BAD_OP</rc> + <description>Invalid operation value passed to p8_pfet_control.</description> + <ffdc>EX</ffdc> + <ffdc>DOMAIN</ffdc> + <ffdc>OPERATION</ffdc> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PMPROC_PFETLIB_RAIL_ON</rc> + <description>Error returned turning PFETs on in p8_pfet_control.</description> + <ffdc>EX</ffdc> + <ffdc>DOMAIN</ffdc> + <ffdc>OPERATION</ffdc> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PMPROC_PFETLIB_RAIL_OFF</rc> + <description>Error returned turning PFETs off in p8_pfet_control.</description> + <ffdc>EX</ffdc> + <ffdc>DOMAIN</ffdc> + <ffdc>OPERATION</ffdc> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PMPROC_PFETLIB_CODE_FAULT</rc> + <ffdc>EX</ffdc> + <ffdc>DOMAIN</ffdc> + <ffdc>OPERATION</ffdc> + <description>Unreachable code point in p8_pfet_control.</description> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PROCPM_PFETLIB_TIMEOUT</rc> + <description>PFET sequencer timed out in p8_pfet_control.</description> + <ffdc>ADDRESS</ffdc> + <ffdc>PFETCONTROLVALUE</ffdc> + <ffdc>DOMAIN</ffdc> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PROCPM_PFETLIB_BABYSTEPPER_TIMEOUT</rc> + <description>IVRM babystepper timed out in p8_pfet_control.</description> + <ffdc>EX</ffdc> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PROCPM_PFETLIB_BABYSTEPPER_WAKEUP_TIMEOUT</rc> + <description>IVRM babystepper timed out waking up in p8_pfet_control.</description> + <ffdc>EX</ffdc> + </hwpError> +</hwpErrors> diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_init.C b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_init.C index 20ef82d5b..541ac824d 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_init.C +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_init.C @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_pfet_init.C,v 1.3 2013/03/18 17:58:33 pchatnah Exp $ +// $Id: p8_pfet_init.C,v 1.9 2013/08/02 19:05:49 stillgs Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/p8_pfet_init.C,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 @@ -90,13 +90,15 @@ using namespace fapi; // Function prototypes // ---------------------------------------------------------------------- -fapi::ReturnCode pfet_init(const Target& i_target); +fapi::ReturnCode pfet_init(const Target& i_target, uint32_t i_mode); fapi::ReturnCode pfet_config(const Target& i_target); fapi::ReturnCode pfet_set_delay( const fapi::Target& i_target, const uint64_t i_address, const uint8_t i_delay0, const uint8_t i_delay1, const uint32_t i_select); +uint8_t convert_delay_to_value ( uint32_t i_delay, + uint32_t i_attr_proc_nest_frequency); // ---------------------------------------------------------------------- // Function definitions @@ -104,26 +106,24 @@ fapi::ReturnCode pfet_set_delay( const fapi::Target& i_target, /// \param[in] i_target EX target -/// \param[in] mode Control mode for the procedure +/// \param[in] i_mode Control mode for the procedure /// (PM_CONFIG, PM_INIT, PM_RESET, /// PM_OVERRIDE) -/// \param[in] domain -/// \param[in] opcontrol - +/// /// \retval FAPI_RC_SUCCESS /// \retval ERROR defined in xml fapi::ReturnCode -p8_pfet_init(const Target& i_target, uint32_t mode) +p8_pfet_init(const Target& i_target, uint32_t i_mode) { fapi::ReturnCode l_rc; - FAPI_INF("Executing p8_pfet_init in mode %x ....", mode); + FAPI_INF("Executing p8_pfet_init in mode %x ....", i_mode); /// ------------------------------- /// Configuration: perform translation of any Platform Attributes /// into Feature Attributes that are applied during Initalization - if (mode == PM_CONFIG) + if (i_mode == PM_CONFIG) { FAPI_INF("PFET config..."); FAPI_INF("---> None is defined..."); @@ -132,16 +132,16 @@ p8_pfet_init(const Target& i_target, uint32_t mode) /// ------------------------------- /// Initialization: perform order or dynamic operations to initialize /// the SLW using necessary Platform or Feature attributes. - else if (mode == PM_INIT) + else if (i_mode == PM_INIT || i_mode == PM_INIT_SPECIAL) { FAPI_INF("PFET init..."); - l_rc = pfet_init(i_target); + l_rc = pfet_init(i_target, i_mode); } /// ------------------------------- /// Reset: perform reset of PFETs so that it can reconfigured and /// reinitialized - else if (mode == PM_RESET) + else if (i_mode == PM_RESET) { FAPI_INF("PFET reset..."); FAPI_INF("---> None is defined..."); @@ -152,7 +152,7 @@ p8_pfet_init(const Target& i_target, uint32_t mode) else { - FAPI_ERR("Unknown mode passed to p8_pfet_init. Mode %x ....", mode); + FAPI_ERR("Unknown mode passed to p8_pfet_init. Mode %x ....", i_mode); FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFET_CODE_BAD_MODE); } @@ -164,7 +164,7 @@ p8_pfet_init(const Target& i_target, uint32_t mode) // PFET Configuration Function //------------------------------------------------------------------------------ fapi::ReturnCode -pfet_init(const Target& i_target) +pfet_init(const Target& i_target, uint32_t i_mode) { fapi::ReturnCode l_rc; uint32_t e_rc = 0; @@ -173,13 +173,14 @@ pfet_init(const Target& i_target) std::vector<fapi::Target> l_exChiplets; uint8_t l_functional = 0; uint8_t l_ex_number = 0; - bool __attribute__((unused)) error_flag = false; // HACK uint64_t address; uint8_t core_vret_voff_value; uint8_t eco_vret_voff_value; + pfet_force_t off_mode; + uint32_t attr_proc_refclk_frequency; uint32_t attr_pm_pfet_powerup_core_delay0; @@ -266,7 +267,6 @@ pfet_init(const Target& i_target) if (l_rc) { FAPI_ERR("fapiGetAttribute ATTR_FREQ_PROC_REFCLOCK"); - // FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFET_GET_ATTR); break; } @@ -277,7 +277,6 @@ pfet_init(const Target& i_target) if (l_rc) { FAPI_ERR("fapiGetAttribute ATTR_PM_PFET_POWERUP_CORE_DELAY0"); - // FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFET_GET_ATTR); break; } @@ -288,7 +287,6 @@ pfet_init(const Target& i_target) if (l_rc) { FAPI_ERR("fapiGetAttribute ATTR_PM_PFET_POWERUP_CORE_DELAY1"); - // FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFET_GET_ATTR); break; } @@ -299,7 +297,6 @@ pfet_init(const Target& i_target) if (l_rc) { FAPI_ERR("fapiGetAttribute ATTR_PM_PFET_POWERDOWN_CORE_DELAY0"); - // FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFET_GET_ATTR); break; } @@ -310,7 +307,6 @@ pfet_init(const Target& i_target) if (l_rc) { FAPI_ERR("fapiGetAttribute ATTR_PM_PFET_POWERDOWN_CORE_DELAY1"); - // FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFET_GET_ATTR); break; } @@ -321,7 +317,6 @@ pfet_init(const Target& i_target) if (l_rc) { FAPI_ERR("fapiGetAttribute ATTR_PM_PFET_POWERUP_ECO_DELAY0"); - // FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFET_GET_ATTR); break; } @@ -333,17 +328,16 @@ pfet_init(const Target& i_target) if (l_rc) { FAPI_ERR("fapiGetAttribute ATTR_PM_PFET_POWERUP_ECO_DELAY1"); - // FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFET_GET_ATTR); break; } /// ---------------------------------------------------------- l_rc = FAPI_ATTR_GET( ATTR_PM_PFET_POWERDOWN_ECO_DELAY0, - &i_target, attr_pm_pfet_powerdown_eco_delay0); + &i_target, + attr_pm_pfet_powerdown_eco_delay0); if (l_rc) { FAPI_ERR("fapiGetAttribute ATTR_PM_PFET_POWERDOWN_ECO_DELAY0"); - // FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFET_GET_ATTR); break; } @@ -354,7 +348,6 @@ pfet_init(const Target& i_target) if (l_rc) { FAPI_ERR("fapiGetAttribute ATTR_PM_PFET_POWERDOWN_ECO_DELAY1"); - // FAPI_SET_HWP_ERROR(l_rc, RC_PROCPM_PFET_GET_ATTR); break; } @@ -453,149 +446,194 @@ pfet_init(const Target& i_target) TARGET_TYPE_EX_CHIPLET, l_exChiplets, TARGET_STATE_PRESENT); - if (l_rc) - { - FAPI_ERR("Error from fapiGetChildChiplets!"); - break; - } + if (l_rc) + { + FAPI_ERR("Error from fapiGetChildChiplets!"); + break; + } - FAPI_DBG("\tChiplet vector size => %u ", l_exChiplets.size()); + FAPI_DBG("\tNumber of EX chiplets present => %u", l_exChiplets.size()); // Iterate through the returned chiplets - for (uint8_t j=0; j < l_exChiplets.size(); j++) - { + for (uint8_t j=0; j < l_exChiplets.size(); j++) + { // Determine if it's functional l_rc = FAPI_ATTR_GET(ATTR_FUNCTIONAL, &l_exChiplets[j], l_functional); if (l_rc) { FAPI_ERR("fapiGetAttribute of ATTR_FUNCTIONAL error"); - error_flag = true; break; } - else if ( l_functional ) + + // Get the core number + l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &l_exChiplets[j], l_ex_number); + if (l_rc) { - // Get the core number - l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &l_exChiplets[j], l_ex_number); - if (l_rc) - { - FAPI_ERR("fapiGetAttribute of ATTR_CHIP_UNIT_POS error"); - error_flag = true; - break; - } + FAPI_ERR("fapiGetAttribute of ATTR_CHIP_UNIT_POS error"); + break; + } - FAPI_DBG("\tGP0(0) from core %x (@ %08llx) => 0x%16llx", - l_ex_number, - EX_GP3_0x100F0012+(l_ex_number*0x01000000), - data.getDoubleWord(0)); + FAPI_INF("Set PFET attribute values into EX %X", l_ex_number); - FAPI_INF("\tSet the PFET attribute values into the appropriate registers"); + // ------------------------------------------------------------- + FAPI_DBG("\tSetting Core Power up Delays"); + address = EX_CorePFPUDly_REG_0x100F012C + (0x01000000 * l_ex_number); + l_rc=pfet_set_delay(i_target, + address, + attr_pm_pfet_powerup_core_delay0_value, + attr_pm_pfet_powerup_core_delay1_value, + attr_pm_pfet_powerup_core_sequence_delay_select + ); + if (l_rc) + { + FAPI_ERR("pfet_set_delay error 0x%08llu", address); + break; + } - // ------------------------------------------------------------- - FAPI_DBG("\tSetting Core Power up Delays"); - address = EX_CorePFPUDly_REG_0x100F012C + (0x01000000 * l_ex_number); - l_rc=pfet_set_delay(i_target, - address, - attr_pm_pfet_powerup_core_delay0_value, - attr_pm_pfet_powerup_core_delay1_value, - attr_pm_pfet_powerup_core_sequence_delay_select - ); - if (l_rc) - { - FAPI_ERR("pfet_step_delay error 0x%08llu", address); - break; - } + // ------------------------------------------------------------- + FAPI_DBG("\tSetting Core Power down Delays"); + address = EX_CorePFPDDly_REG_0x100F012D + (0x01000000 * l_ex_number); + l_rc=pfet_set_delay(i_target, + address, + attr_pm_pfet_powerup_core_delay0_value, + attr_pm_pfet_powerup_core_delay1_value, + attr_pm_pfet_powerup_core_sequence_delay_select + ); + if (l_rc) + { + FAPI_ERR("pfet_set_delay error 0x%08llu", address); + break; + } - // ------------------------------------------------------------- - FAPI_DBG("\tSetting Core Power down Delays"); - address = EX_CorePFPDDly_REG_0x100F012D + (0x01000000 * l_ex_number); - l_rc=pfet_set_delay(i_target, - address, - attr_pm_pfet_powerup_core_delay0_value, - attr_pm_pfet_powerup_core_delay1_value, - attr_pm_pfet_powerup_core_sequence_delay_select - ); - if (l_rc) - { - FAPI_ERR("pfet_step_delay error 0x%08llu", address); - break; - } + // ------------------------------------------------------------- + FAPI_DBG("\tSetting Core Voff Settings"); + e_rc |= data.setBitLength(64); + e_rc |= data.insertFromRight(core_vret_voff_value, 0, 8); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } - // ------------------------------------------------------------- - FAPI_DBG("\tSetting Core Voff Settings"); - e_rc |= data.setBitLength(64); - e_rc |= data.insertFromRight(core_vret_voff_value, 0, 8); - if (e_rc) - { - FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); - l_rc.setEcmdError(e_rc); - break; - } + address = EX_CorePFVRET_REG_0x100F0130 + (0x01000000 * l_ex_number); + l_rc=fapiPutScom(i_target, address, data ); + if (l_rc) + { + FAPI_ERR("PutScom error 0x%08llu", address); + break; + } - address = EX_CorePFVRET_REG_0x100F0130 + (0x01000000 * l_ex_number); - l_rc=fapiPutScom(i_target, address, data ); - if (l_rc) - { - FAPI_ERR("pfet_step_delay error 0x%08llu", address); - break; - } + // ------------------------------------------------------------- + FAPI_DBG("\tSetting ECO Power up Delays"); + address = EX_ECOPFPUDly_REG_0x100F014C + (0x01000000 * l_ex_number); + l_rc=pfet_set_delay(i_target, + address, + attr_pm_pfet_powerup_eco_delay0_value, + attr_pm_pfet_powerup_eco_delay1_value, + attr_pm_pfet_powerup_eco_sequence_delay_select + ); + if (l_rc) + { + FAPI_ERR("pfet_set_delay error 0x%08llu", address); + break; + } - // ------------------------------------------------------------- - FAPI_DBG("\tSetting ECO Power up Delays"); - address = EX_ECOPFPUDly_REG_0x100F014C + (0x01000000 * l_ex_number); - l_rc=pfet_set_delay(i_target, - address, - attr_pm_pfet_powerup_core_delay0_value, - attr_pm_pfet_powerup_core_delay1_value, - attr_pm_pfet_powerup_core_sequence_delay_select - ); - if (l_rc) - { - FAPI_ERR("pfet_step_delay error 0x%08llu", address); - break; - } + // ------------------------------------------------------------- + FAPI_DBG("\tSetting ECO Power down Delays"); + address = EX_ECOPFPDDly_REG_0x100F014D + (0x01000000 * l_ex_number); + l_rc=pfet_set_delay(i_target, + address, + attr_pm_pfet_powerdown_eco_delay0_value, + attr_pm_pfet_powerdown_eco_delay1_value, + attr_pm_pfet_powerdown_eco_sequence_delay_select + ); + if (l_rc) + { + FAPI_ERR("pfet_set_delay error 0x%08llu", address); + break; + } - // ------------------------------------------------------------- - FAPI_DBG("\tSetting ECO Power down Delays"); - address = EX_ECOPFPDDly_REG_0x100F014D + (0x01000000 * l_ex_number); - l_rc=pfet_set_delay(i_target, - address, - attr_pm_pfet_powerup_core_delay0_value, - attr_pm_pfet_powerup_core_delay1_value, - attr_pm_pfet_powerup_core_sequence_delay_select - ); - if (l_rc) - { - FAPI_ERR("pfet_step_delay error 0x%08llu", address); - break; - } + // ------------------------------------------------------------- + FAPI_DBG("\tSetting ECO Voff Settings"); + e_rc |= data.setBitLength(64); + e_rc |= data.insertFromRight(eco_vret_voff_value, 0, 8); + if (e_rc) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); + l_rc.setEcmdError(e_rc); + break; + } - // ------------------------------------------------------------- - FAPI_DBG("\tSetting ECO Voff Settings"); - e_rc |= data.setBitLength(64); - e_rc |= data.insertFromRight(eco_vret_voff_value, 0, 8); - if (e_rc) - { - FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", e_rc); - l_rc.setEcmdError(e_rc); - break; - } + address = EX_ECOPFVRET_REG_0x100F0150 + (0x01000000 * l_ex_number); + l_rc=fapiPutScom(i_target, address, data ); + if (l_rc) + { + FAPI_ERR("PutScom error 0x%08llu", address); + break; + } - address = EX_ECOPFVRET_REG_0x100F0150 + (0x01000000 * l_ex_number); - l_rc=fapiPutScom(i_target, address, data ); - if (l_rc) + // Functional - run any work-arounds necessary + if (l_functional) + { + // \todo: make DD1 relevent + FAPI_INF("Perform iVRM work-around on configured EX %d", l_ex_number); + + FAPI_EXEC_HWP(l_rc, p8_pfet_control, i_target, + l_ex_number, + BOTH, + VON); + if(l_rc) { - FAPI_ERR("pfet_step_delay error 0x%08llu", address); + FAPI_ERR("iVRM / PFET Controller error"); break; } } // Not Functional - disable the PFETs + // Only done on hardware as this can cause sim issue for unpopulated + // chiplest + uint8_t is_sim; + + l_rc = FAPI_ATTR_GET(ATTR_IS_SIMULATION, NULL, is_sim); + if (l_rc) + { + FAPI_ERR("fapi_attr_get(ATTR_IS_SIMULATION ) failed. " + "With rc = 0x%x", (uint32_t) l_rc ); + break; + } + if(!is_sim) + { + if (!l_functional ) + { + FAPI_INF("Turn off PFETs on EX %d", l_ex_number); + off_mode = VOFF; + if (i_mode == PM_INIT_SPECIAL) + { + FAPI_INF("\tUsing PFET override mode"); + off_mode = VOFF_OVERRIDE; + } + + FAPI_EXEC_HWP(l_rc, p8_pfet_control, i_target, + l_ex_number, + BOTH, + off_mode); + + + + if(l_rc) + { + FAPI_ERR("PFET Controller error"); + break; + } + } + } else { - // Do nothing + FAPI_INF("Simulation detected: Not disabling PFETs in deconfigured chiplets"); } } // chiplet loop } while(0); @@ -624,8 +662,8 @@ pfet_set_delay( const fapi::Target& i_target, { e_rc |= data.setBitLength(64); - e_rc |= data.insertFromRight(i_delay0, 0, 4); // bits 0:3 - e_rc |= data.insertFromRight(i_delay1, 4, 4); // bits 4:7 + e_rc |= data.insertFromRight(i_delay0, 0, 4); // bits 0:3 + e_rc |= data.insertFromRight(i_delay1, 4, 4); // bits 4:7 e_rc |= data.insertFromRight(i_select, 8, 12); // bits 8:19 if (e_rc) { @@ -634,7 +672,7 @@ pfet_set_delay( const fapi::Target& i_target, break; } - l_rc=fapiPutScom(i_target, i_address, data ); + l_rc=fapiPutScom(i_target, i_address, data ); if (l_rc) { FAPI_ERR("PutScom error 0x%08llu", i_address); @@ -685,7 +723,6 @@ convert_delay_to_value (uint32_t i_delay, } - /* *************** Do not edit this area *************** This section is automatically updated by CVS when you check in this file. diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_init.H b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_init.H index df08edc16..7f7cd69b7 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_init.H +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_init.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_pfet_init.H,v 1.1 2012/12/07 20:12:30 stillgs Exp $ +// $Id: p8_pfet_init.H,v 1.2 2013/08/02 19:06:05 stillgs Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/p8_pfet_init.H,v $ //------------------------------------------------------------------------------ // *| @@ -69,7 +69,7 @@ extern "C" { /// \retval FAPI_RC_SUCCESS if something good happens, /// \retval RC per p8_pfet_init_errors.xml otherwise fapi::ReturnCode -p8_pfet_init(const fapi::Target& i_target, uint32_t mode); +p8_pfet_init(const fapi::Target& i_target, uint32_t i_mode); } // extern "C" diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_types.H b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_types.H index 7b3f0c3d2..2f57e367b 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_types.H +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_types.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_pfet_types.H,v 1.1 2012/12/12 04:29:27 stillgs Exp $ +// $Id: p8_pfet_types.H,v 1.3 2013/05/17 20:15:44 stillgs Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/p8_pfet_types.H,v $ //------------------------------------------------------------------------------ // *| @@ -54,13 +54,24 @@ typedef enum pfet_dom_type // valid force options typedef enum pfet_force_type { - NONE, // no operation (00) - VOFF, // voff (01) - VRET, // Vret (10)... not supported - VON, // von (11) - NO_FORCE_PARM // use this when not writing to reg. + NONE, // no operation (00) + VOFF, // voff (01) + VRET, // Vret (10)... not supported + VON, // von (11) + NO_FORCE_PARM, // use this when not writing to reg. + VOFF_OVERRIDE } pfet_force_t; +// valid read options +typedef enum pfet_read_type +{ + PFET_READ_VOFF, + PFET_READ_VREG, + PFET_READ_VON, + PFET_READ_VBETWEEN, + PFET_READ_VOFFOVRD +} pfet_read_t; + } // extern "C" diff --git a/src/usr/hwpf/makefile b/src/usr/hwpf/makefile index 316d73f59..dc90a1745 100644 --- a/src/usr/hwpf/makefile +++ b/src/usr/hwpf/makefile @@ -55,6 +55,7 @@ HWP_ERROR_XML_FILES = hwp/fapiHwpErrorInfo.xml \ hwp/dram_initialization/proc_pcie_config/proc_pcie_config_errors.xml \ hwp/build_winkle_images/p8_set_pore_bar/p8_set_pore_bar_errors.xml \ hwp/build_winkle_images/p8_set_pore_bar/p8_pmc_deconfig_setup_errors.xml \ + hwp/build_winkle_images/p8_set_pore_bar/p8_pfet_errors.xml \ hwp/build_winkle_images/p8_set_pore_bar/p8_poreslw_errors.xml \ hwp/slave_sbe/proc_check_slave_sbe_seeprom_complete/proc_check_slave_sbe_seeprom_complete_errors.xml \ hwp/slave_sbe/proc_check_slave_sbe_seeprom_complete/proc_extract_sbe_rc_errors.xml \ |