diff options
author | Prasad Bg Ranganath <prasadbgr@in.ibm.com> | 2019-01-11 06:27:33 -0600 |
---|---|---|
committer | Christian R. Geddes <crgeddes@us.ibm.com> | 2019-03-16 14:53:16 -0500 |
commit | 4d983e4c8bdd4c190ccbfd5e36dfbaa2a22a4951 (patch) | |
tree | 2184801f4b9353ec100bcb8a758b340e04c7bff6 /src/import | |
parent | 1c169fc8be5af0a3422088d0644188928f0c46fe (diff) | |
download | talos-hostboot-4d983e4c8bdd4c190ccbfd5e36dfbaa2a22a4951.tar.gz talos-hostboot-4d983e4c8bdd4c190ccbfd5e36dfbaa2a22a4951.zip |
PPB: Refactor pstate parameter block
Key_Cronus_Test=PM_REGRESS
CQ:SW458304
Change-Id: Ia854423e663919a192a8fd271f2656d7d7469406
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/70365
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Prem Shanker Jha <premjha2@in.ibm.com>
Tested-by: Cronus HW CI <cronushw-ci+hostboot@us.ibm.com>
Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/70906
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: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import')
7 files changed, 4269 insertions, 4675 deletions
diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_pstates_cmeqm.h b/src/import/chips/p9/procedures/hwp/lib/p9_pstates_cmeqm.h index 8148e3249..d7739af81 100644 --- a/src/import/chips/p9/procedures/hwp/lib/p9_pstates_cmeqm.h +++ b/src/import/chips/p9/procedures/hwp/lib/p9_pstates_cmeqm.h @@ -36,32 +36,6 @@ #include <p9_pstates_common.h> -/// \defgroup QM Flags -/// -/// These are flag bits for the \a Quad Manager field. -/// -/// @{ - -/// qmflag() - Disable Resonant Clock use. -#define PSTATE_RESCLK_DISABLE 0x8000 - -/// qmflag() - Disable IVRM use. -#define PSTATE_IVRMS_DISABLE 0x4000 - -/// qmflag() - Disable VDM use. -#define PSTATE_VDM_DISABLE 0x2000 - -/// qmflag() - Disable WOF. -#define PSTATE_WOF_DISABLE 0x1000 - -/// qmflag() - dpll_dynamic_fmax_enable -#define PSTATE_DPLL_DYNAMIC_FMAX_ENABLE 0x0800 - -/// qmflag() - dpll_dynamic_fmin_enable -#define PSTATE_DPLL_DYNAMIC_FMIN_ENABLE 0x0400 - -/// qmflag() - dpll_droop_protect_enable -#define PSTATE_DPLL_DROOP_PROTECT_ENABLE 0x0200 /// @} diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_pstates_common.h b/src/import/chips/p9/procedures/hwp/lib/p9_pstates_common.h index 6e80fe410..b35d2c0ab 100644 --- a/src/import/chips/p9/procedures/hwp/lib/p9_pstates_common.h +++ b/src/import/chips/p9/procedures/hwp/lib/p9_pstates_common.h @@ -43,44 +43,6 @@ /// decreasing frequency) #define PSTATE_MIN 0 -/// The minimum \e legal DPLL frequency code -/// -/// This is ~1GHz with a 16.6MHz tick frequency. -/// @todo Check this and the maximum -#define DPLL_MIN 0x03c - -/// The maximum DPLL frequency code -#define DPLL_MAX 0x1ff - -/// The minimum \a legal (non-power-off) AVS VID code -/// @todo Need to check with J. Kuesmann if there is a limit. May want this -/// to be an attribute. -#define AVS_MIN 0x0000 - -/// The maximum \a legal (non-power-off) AVS VID code -/// @todo Need to check with J. Kuesmann if there is a limit. May want this -/// to be an attribute. -#define AVS_MAX 0xFFFF - -/// The AVS VID base voltage in micro-Volts -#define AVS_BASE_UV 1612500 - -/// The AVS VID step as an unsigned number (micro-Volts) -#define AVS_STEP_UV 1000 - -//ssrivath, Is this the same as IVID_BASE_UV and IVID_STEP_UV below -/// The VRM-11 VID base voltage in micro-Volts -#define VRM11_BASE_UV 1612500 - -/// The VRM-11 VID step as an unsigned number (micro-Volts) -#define VRM11_STEP_UV 6250 - -// ssrivath, iVID values based on Section 2.8.7 of spec -/// The iVID base voltage in micro-Volts -#define IVID_BASE_UV 512000 - -/// The iVID step as an unsigned number (micro-Volts) -#define IVID_STEP_UV 4000 /// Maximum number of Quads (4 cores plus associated caches) #define MAXIMUM_QUADS 6 @@ -121,7 +83,6 @@ typedef enum #endif #define NUM_OP_POINTS 4 -#define NUM_PV_POINTS 5 #define VPD_PV_POWERSAVE 1 #define VPD_PV_NOMINAL 0 #define VPD_PV_TURBO 2 @@ -174,11 +135,12 @@ typedef enum #define VDM_DROOP_OP_POINTS 5 +#define PSTATE_LT_PSTATE_MIN 0x00778a03 +#define PSTATE_GT_PSTATE_MAX 0x00778a04 +#define ACTIVE_QUADS 6 /// IDDQ readings, #define IDDQ_MEASUREMENTS 6 -#define MEASUREMENT_ELEMENTS 6 // Number of Quads for P9 -#define IDDQ_READINGS_PER_IQ 2 #define IDDQ_ARRAY_VOLTAGES { 0.60 , 0.70 , 0.80 , 0.90 , 1.00 , 1.10} #define IDDQ_ARRAY_VOLTAGES_STR {"0.60", "0.70", "0.80", "0.90", "1.00", "1.10"} @@ -186,39 +148,7 @@ typedef enum #define NUM_ACTIVE_CORES 24 #define MAX_UT_PSTATES 64 // Oversized -//ssrivath, Temporary definition -#define PGP_NCORES 24 - -/// Error/Panic codes for support routines -/// @todo Review the necessary error codes. This are really PGPE functions now -/// and many below elsewhere. However, the error code plumbing from PGPE to -/// OCC for error logging purposes is an action. - -#define VRM11_INVALID_VOLTAGE 0x00876101 - -#define PSTATE_OVERFLOW 0x00778a01 -#define PSTATE_UNDERFLOW 0x00778a02 - -#define PSTATE_LT_PSTATE_MIN 0x00778a03 -#define PSTATE_GT_PSTATE_MAX 0x00778a04 - -#define DPLL_OVERFLOW 0x00d75501 -#define DPLL_UNDERFLOW 0x00d75502 - -#define AVSVID_OVERFLOW 0x00843101 -#define AVSVID_UNDERFLOW 0x00843102 -#define GPST_INVALID_OBJECT 0x00477801 -#define GPST_INVALID_ARGUMENT 0x00477802 -#define GPST_INVALID_ENTRY 0x00477803 -#define GPST_PSTATE_CLIPPED_LOW 0x00477804 -#define GPST_PSTATE_CLIPPED_HIGH 0x00477805 -#define GPST_BUG 0x00477806 -#define GPST_PSTATE_GT_GPST_PMAX 0x00477807 - -#define LPST_INVALID_OBJECT 0x00477901 -#define LPST_GPST_WARNING 0x00477902 -#define LPST_INCR_CLIP_ERROR 0x00477903 #ifndef __ASSEMBLER__ #ifdef __cplusplus @@ -240,7 +170,6 @@ typedef uint16_t DpllCode; /// An AVS VID code typedef uint16_t VidAVS; -// ssrivath, Modified units for vdd/vcs/idd/ics as per P9 VPD spec /// A VPD operating point /// /// VPD operating points are stored without load-line correction. Frequencies @@ -258,6 +187,15 @@ typedef struct uint8_t pad[3]; // Alignment padding } VpdOperatingPoint; +//Defined same as #V vpd points used to validate +typedef struct +{ + uint32_t frequency_mhz; + uint32_t vdd_mv; + uint32_t idd_100ma; + uint32_t vcs_mv; + uint32_t ics_100ma; +} VpdPoint; /// VPD Biases. /// /// Percent bias applied to VPD operating points prior to interolation @@ -457,9 +395,6 @@ typedef struct __attribute__((packed, aligned(128))) WofTablesHeader } WofTablesHeader_t; -#define CEF_VDN_INDEX 8 -#define CEF_VDD_INDEX 21 -#define ACTIVE_QUADS 6 // Data is provided in 1/24ths granularity with adjustments for integer // representation @@ -468,12 +403,6 @@ typedef struct __attribute__((packed, aligned(128))) WofTablesHeader // 5 steps down from 100% is Fratio_step sizes #define VFRT_FRATIO_SIZE 5 -// System VFRT layout -typedef struct __attribute__((packed, aligned(128))) HomerSysVFRTLayout -{ - VFRTHeaderLayout_t vfrtHeader; - uint8_t vfrt_data[VFRT_FRATIO_SIZE][VFRT_VRATIO_SIZE]; -} HomerSysVFRTLayout_t; // HOMER VFRT Layout typedef struct __attribute__((packed, aligned(256))) HomerVFRTLayout @@ -483,18 +412,6 @@ typedef struct __attribute__((packed, aligned(256))) HomerVFRTLayout uint8_t padding[128]; } HomerVFRTLayout_t; -// HOMER WOF layout -typedef struct __attribute__((packed)) HomerWOFLayout -{ - WofTablesHeader_t wof_header_data; - HomerVFRTLayout_t homer_vfrt_data[CEF_VDN_INDEX][CEF_VDD_INDEX][ACTIVE_QUADS]; -} HomerWOFLayout_t; - -typedef uint8_t VFRT_Circuit_t; -typedef Pstate VFRT_Hcode_t; - -extern VFRT_Circuit_t VFRTCircuitTable[VFRT_FRATIO_SIZE][VFRT_FRATIO_SIZE]; -extern VFRT_Hcode_t VFRTInputTable[VFRT_FRATIO_SIZE][VFRT_FRATIO_SIZE]; #ifdef __cplusplus } // end extern C diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.C b/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.C index 9428d1573..b373de2e5 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.C +++ b/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.C @@ -46,352 +46,208 @@ #include <fapi2.H> #include <p9_pstate_parameter_block.H> #include <p9_hcd_memmap_base.H> -#include "p9_pm_get_poundw_bucket.H" #include "p9_resclk_defines.H" #include <attribute_ids.H> #include <math.h> -//the value in this table are in Index format -uint8_t g_GreyCodeIndexMapping [] = -{ -/* 0mV 0x00*/ 0, -/* - 8mV 0x01*/ 1, -/* -24mV 0x02*/ 3, -/* -16mV 0x03*/ 2, -/* -56mV 0x04*/ 7, -/* -48mV 0x05*/ 6, -/* -32mV 0x06*/ 4, -/* -40mV 0x07*/ 5, -/* -96mV 0x08*/ 12, -/* -96mV 0x09*/ 12, -/* -96mV 0x0a*/ 12, -/* -96mV 0x0b*/ 12, -/* -64mV 0x0c*/ 8, -/* -72mV 0x0d*/ 9, -/* -88mV 0x0e*/ 11, -/* -80mV 0x0f*/ 10 -}; -// from above mapping -const uint8_t GREYCODE_INDEX_M32MV = 4; +using namespace pm_pstate_parameter_block; -// #W version number where no special checks are needed. -const uint32_t FULLY_VALID_POUNDW_VERSION = 3; -fapi2::vdmData_t g_vpdData = {1, - 2, -{ - 0x29, 0x0C, 0x05, 0xC3, 0x61, 0x36, 0x1, 0x3, 0x0, 0x0, //Nominal - 0x28, 0xa8, 0x05, 0x5f, 0x21, 0x36, 0x1, 0x3, 0x0, 0x0, //PowerSave - 0x29, 0x70, 0x06, 0x27, 0x71, 0x36, 0x1, 0x3, 0x0, 0x0, //Turbo - 0x29, 0xD4, 0x06, 0x8b, 0x51, 0x36, 0x1, 0x3, 0x0, 0x0, //UltraTurbo - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0, //Resistance - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0 //Spare -} - }; - - -uint8_t g_wofData[] = { 0x57, 0x46, 0x54, 0x48 /*MAGIC CODE WFTH*/, - 0x00, 0x00, 0x00, 0x01 /*version*/, - 0x00, 0x80 /*VFRT block size*/, - 0x00, 0x08 /*VFRT header size*/, - 0x00, 0x01 /*VFRT data size*/, - 0x6 /*Quad value*/, - 0x18 /*core count*/, - 0x00, 0xFA /*Vdn start*/, - 0x00, 0x64 /*Vdn step*/, - 0x00, 0x08 /*Vdn size*/, - 0x00, 0x00 /*Vdd start*/, - 0x00, 0x32 /*Vdd step*/, - 0x00, 0x15 /*Vdd size*/, - 0x03, 0xE8 /*Vratio start*/, - 0x00, 0x53 /*Vratio step*/, - 0x00, 0x18 /*Vratio size*/, - 0x03, 0xE8 /*Fratio start*/, - 0x00, 0x64 /*Fratio step*/, - 0x00, 0x5 /*Fratio size*/, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*Vdn percent*/, - 0x00, 0x64 /*Socket power Watts*/, - 0x07, 0x4a /*nest freq*/, - 0x09, 0x60 /*nominl freq*/, - 0x00, 0x00 /*RDP capacity*/, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* WOF table source tag*/, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*package name*/, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*Pad to 128B*/ - }; - - -// uint8_t g_sysvfrtData[] = {0x56, 0x54, 0x00, 0x00, 0x02, 0x01, 0x01, 0x06, /// VFRT header values -// // Magic_codea(2B) -// // reserved(2B) -// // type(4b),version(4b) -// // vdn(1B),vdd(1B) -// // quad id(1B) -// 0xB1, 0xB1, 0xB0, 0xAF, 0xA9, 0xA1, 0x97, 0x8E, 0x86, 0x7F, 0x78, 0x73, 0x6D, 0x68, 0x63, 0x5F, 0x5B, 0x57, 0x53, 0x4E, 0x4D, 0x4D, 0x4D, 0x4D, -// 0xB1, 0xB1, 0xB0, 0xAF, 0xA9, 0xA1, 0x97, 0x8E, 0x86, 0x7F, 0x78, 0x73, 0x6D, 0x68, 0x63, 0x5F, 0x5B, 0x57, 0x53, 0x4E, 0x4D, 0x4D, 0x4D, 0x4D, -// 0xB1, 0xB1, 0xB0, 0xAF, 0xA9, 0xA1, 0x97, 0x8E, 0x86, 0x7F, 0x78, 0x73, 0x6D, 0x68, 0x63, 0x5F, 0x5B, 0x57, 0x53, 0x4E, 0x4D, 0x4D, 0x4D, 0x4D, -// 0xB1, 0xB1, 0xB0, 0xAF, 0xA9, 0xA1, 0x97, 0x8E, 0x86, 0x7F, 0x78, 0x73, 0x6D, 0x68, 0x63, 0x5F, 0x5B, 0x57, 0x53, 0x4E, 0x4D, 0x4D, 0x4D, 0x4D, -// 0xB1, 0xB1, 0xB0, 0xAF, 0xA9, 0xA1, 0x97, 0x8E, 0x86, 0x7F, 0x78, 0x73, 0x6D, 0x68, 0x63, 0x5F, 0x5B, 0x57, 0x53, 0x4E, 0x4D, 0x4D, 0x4D, 0x4D -// }; - -const uint8_t VDN_PERCENT_KEY = 35; -const uint8_t QID_KEY = 6; -uint8_t g_sysvfrtData[] = {0x56, 0x54, // Magic_code 2B) - 0x00, 0x00, // reserved (2B) - 0x02, // type(4b),version(4b) - VDN_PERCENT_KEY, // vdn percentage(1B), - 0x05, // vdd percentage(1B) - QID_KEY, // quad id(1B) - 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA5, 0xA5, 0xA1, 0x9D, 0x9A, - 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA5, 0xA5, 0xA1, 0x9D, 0x9A, - 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA5, 0xA5, 0xA1, 0x9D, 0x9A, - 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA5, 0xA5, 0xA1, 0x9D, 0x9A, - 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA5, 0xA5, 0xA1, 0x9D, 0x9A - }; - -#define VALIDATE_VID_VALUES(w,x,y,z,state) \ - if (!((w <= x) && (x <= y) && (y <= z))) \ - {state = 0;} +//Pstate macros +#define PSTATE_MAX 255 +#define PSTATE_MIN 0 +#define NUM_OP_POINTS 4 -#define VALIDATE_THRESHOLD_VALUES(w,x,y,z,state) \ - if ((w > 0x7 && w != 0xC) || /* overvolt */ \ - (x == 8) || (x == 9) || (x > 0xF) || \ - (y == 8) || (y == 9) || (y > 0xF) || \ - (z == 8) || (z == 9) || (z > 0xF) ) \ - {state = 0;} +#define VPD_PV_POWERSAVE 1 +#define VPD_PV_NOMINAL 0 +#define VPD_PV_TURBO 2 +#define VPD_PV_ULTRA 3 +#define VPD_PV_POWERBUS 4 -//w => N_L (w > 7 is invalid) -//x => N_S (x > N_L is invalid) -//y => L_S (y > (N_L - S_N) is invalid) -//z => S_N (z > N_S is invalid -#define VALIDATE_FREQUENCY_DROP_VALUES(w,x,y,z,state) \ - if ((w > 7) || \ - (x > w) || \ - (y > (w - z)) || \ - (z > x) || \ - ((w | x | y | z) == 0)) \ - {state = 0; } +#define VPD_PV_CORE_FREQ_MHZ 0 +#define VPD_PV_VDD_MV 1 +#define VPD_PV_IDD_100MA 2 +#define VPD_PV_VCS_MV 3 +#define VPD_PV_ICS_100MA 4 +#define VPD_PV_PB_FREQ_MHZ 0 +#define VPD_PV_VDN_MV 1 +#define VPD_PV_IDN_100MA 2 -#define VALIDATE_WOF_HEADER_DATA(a,b,c,d,e,f,g,state) \ - if ( ((!a) || (!b) || (!c) || (!d) || (!e) || (!f) || (!g))) \ - {state = 0; } -double internal_ceil(double x) -{ - if ((x-(int)(x))>0) return (int)x+1; - return ((int)x); -} -double internal_floor(double x) -{ - if(x>=0)return (int)x; - return (int)(x-0.9999999999999999); -} +#define SET_ATTR(attr_name, target, attr_assign) \ + FAPI_TRY(FAPI_ATTR_SET(attr_name, target, attr_assign),"Attribute set failed"); \ + FAPI_INF("%-60s = 0x%08x %d", #attr_name, attr_assign, attr_assign); -// Struct Variable for all attributes -AttributeList attr; -// Strings used in traces -char const* vpdSetStr[NUM_VPD_PTS_SET] = VPD_PT_SET_ORDER_STR; -char const* region_names[] = { "REGION_POWERSAVE_NOMINAL", - "REGION_NOMINAL_TURBO", - "REGION_TURBO_ULTRA" - }; -char const* prt_region_names[] = VPD_OP_SLOPES_REGION_ORDER_STR; +#define VPD_PV_ORDER {VPD_PV_POWERSAVE, VPD_PV_NOMINAL, VPD_PV_TURBO, VPD_PV_ULTRA} +#define VPD_PV_ORDER_STR {"Nominal ","PowerSave ", "Turbo ", "UltraTurbo"} +#define VPD_THRESHOLD_ORDER_STR {"Overvolt", "Small", "Large", "Extreme" } +#define PV_OP_ORDER {POWERSAVE, NOMINAL, TURBO, ULTRA} +#define PV_OP_ORDER_STR {"PowerSave ", "Nominal ","Turbo ", "UltraTurbo"} +#define IDDQ_ARRAY_VOLTAGES { 0.60 , 0.70 , 0.80 , 0.90 , 1.00 , 1.10} +#define IDDQ_ARRAY_VOLTAGES_STR {"0.60", "0.70", "0.80", "0.90", "1.00", "1.10"} +#define POUNDV_SLOPE_CHECK(x,y) x > y ? " is GREATER (ERROR!) than " : " is less than " -///-------------------------------------- -/// @brief Check wof is enabled or not -/// @param[in] pstate attribute state -/// @return true or false -///-------------------------------------- -bool -is_wof_enabled(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - PSTATE_attribute_state* i_state) -{ - uint8_t attr_dd_wof_not_supported; - uint8_t attr_system_wof_disable; - const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_WOF_DISABLE, FAPI_SYSTEM, attr_system_wof_disable); - FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_WOF_NOT_SUPPORTED, i_target, attr_dd_wof_not_supported); - return - (!(attr_system_wof_disable) && - !(attr_dd_wof_not_supported) && - i_state->iv_wof_enabled) - ? true : false; -} +const uint8_t pv_op_order[NUM_OP_POINTS] = VPD_PV_ORDER; +const char* pv_op_str[NUM_OP_POINTS] = VPD_PV_ORDER_STR; -///-------------------------------------- -/// @brief Check vdm is enabled or not -/// @param[in] pstate attribute state -/// @return true or false -///-------------------------------------- -bool -is_vdm_enabled(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - PSTATE_attribute_state* i_state) -{ - const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - uint8_t attr_dd_vdm_not_supported; - uint8_t attr_system_vdm_disable; +#define MAX_ACTIVE_CORES 24 +#define ACTIVE_QUADS 6 - FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_VDM_DISABLE, FAPI_SYSTEM, attr_system_vdm_disable); - FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_VDM_NOT_SUPPORTED, i_target, attr_dd_vdm_not_supported); +//WOF constants +#define HOMER_WOF_TABLE_SIZE 258176 +#define VDN_PERCENT_KEY 35 +#define QID_KEY 6 - return - (!(attr_system_vdm_disable) && - !(attr_dd_vdm_not_supported) && - i_state->iv_vdm_enabled) - ? true : false; -} +//VPD(#V & #W) constants +#define PV_D 5 +#define PV_W 5 +#define IQ_BUFFER_ALLOC 255 +#define FULLY_VALID_POUNDW_VERSION 3 +#define GREYCODE_INDEX_M32MV 4 -///-------------------------------------- -/// @brief Check wov_underv is enabled or not -/// @param[in] pstate attribute state -/// @return true or false -///-------------------------------------- -bool -is_wov_underv_enabled(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - PSTATE_attribute_state* i_state) -{ - const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - uint8_t attr_system_wov_underv_disable = 0; +//#W data verification +#define VALIDATE_VID_VALUES(w, x, y, z, state) \ + if (!((w <= x) && (x <= y) && (y <= z))) \ + { state = 0; } - FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_WOV_UNDERV_DISABLE, FAPI_SYSTEM, attr_system_wov_underv_disable); - return - (!(attr_system_wov_underv_disable) && - i_state->iv_wov_underv_enabled) - ? true : false; -} +#define VALIDATE_THRESHOLD_VALUES(w, x, y, z, state) \ + if ((w > 0x7 && w != 0xC) || /* overvolt */ \ + (x == 8) || (x == 9) || (x > 0xF) || \ + (y == 8) || (y == 9) || (y > 0xF) || \ + (z == 8) || (z == 9) || (z > 0xF) ) \ + { state = 0; } -///-------------------------------------- -/// @brief Check wov_underv is enabled or not -/// @param[in] pstate attribute state -/// @return true or false -///-------------------------------------- -bool -is_wov_overv_enabled(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - PSTATE_attribute_state* i_state) -{ - const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - uint8_t attr_system_wov_overv_disable = 0; +//w => N_L (w > 7 is invalid) +//x => N_S (x > N_L is invalid) +//y => L_S (y > (N_L - S_N) is invalid) +//z => S_N (z > N_S is invalid +#define VALIDATE_FREQUENCY_DROP_VALUES(w, x, y, z, state) \ + if ((w > 7) || \ + (x > w) || \ + (y > (w - z)) || \ + (z > x) || \ + ((w | x | y | z) == 0)) \ + { state = 0; } - FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_WOV_OVERV_DISABLE, FAPI_SYSTEM, attr_system_wov_overv_disable); - return - (!(attr_system_wov_overv_disable) && - i_state->iv_wov_overv_enabled) - ? true : false; -} -void -load_gppb_attrs(const AttributeList* i_attr, - GlobalPstateParmBlock* o_globalppb) +#define VALIDATE_WOF_HEADER_DATA(a, b, c, d, e, f, g, state) \ + if ( ((!a) || (!b) || (!c) || (!d) || (!e) || (!f) || (!g))) \ + { state = 0; } +// #W sample data +const fapi2::vdmData_t g_vpdData = { - //Variables for Loadline, Distribution loss and offset - SysPowerDistParms l_vdd_sysparm; - memset(&l_vdd_sysparm,0x00,sizeof(SysPowerDistParms)); - - SysPowerDistParms l_vcs_sysparm; - memset(&l_vcs_sysparm,0x00,sizeof(SysPowerDistParms)); - - SysPowerDistParms l_vdn_sysparm; - memset(&l_vdn_sysparm,0x00,sizeof(SysPowerDistParms)); + 1, 2, + { + 0x29, 0x0C, 0x05, 0xC3, 0x61, 0x36, 0x1, 0x3, 0x0, 0x0, //Nominal + 0x28, 0xa8, 0x05, 0x5f, 0x21, 0x36, 0x1, 0x3, 0x0, 0x0, //PowerSave + 0x29, 0x70, 0x06, 0x27, 0x71, 0x36, 0x1, 0x3, 0x0, 0x0, //Turbo + 0x29, 0xD4, 0x06, 0x8b, 0x51, 0x36, 0x1, 0x3, 0x0, 0x0, //UltraTurbo + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0, //Resistance + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0 //Spare + } +}; - // Frequency step variable - double l_frequency_step_khz; - // ----------------------------------------------- - // System power distribution parameters - // ----------------------------------------------- - // VDD rail - l_vdd_sysparm.loadline_uohm = revle32(i_attr->attr_proc_r_loadline_vdd_uohm); - l_vdd_sysparm.distloss_uohm = revle32(i_attr->attr_proc_r_distloss_vdd_uohm); - l_vdd_sysparm.distoffset_uv = revle32(i_attr->attr_proc_vrm_voffset_vdd_uv); - // VCS rail - l_vcs_sysparm.loadline_uohm = revle32(i_attr->attr_proc_r_loadline_vcs_uohm); - l_vcs_sysparm.distloss_uohm = revle32(i_attr->attr_proc_r_distloss_vcs_uohm); - l_vcs_sysparm.distoffset_uv = revle32(i_attr->attr_proc_vrm_voffset_vcs_uv); - - // VDN rail - l_vdn_sysparm.loadline_uohm = revle32(i_attr->attr_proc_r_loadline_vdn_uohm); - l_vdn_sysparm.distloss_uohm = revle32(i_attr->attr_proc_r_distloss_vdn_uohm); - l_vdn_sysparm.distoffset_uv = revle32(i_attr->attr_proc_vrm_voffset_vdn_uv); - - o_globalppb->vdd_sysparm = l_vdd_sysparm; - o_globalppb->vcs_sysparm = l_vcs_sysparm; - o_globalppb->vdn_sysparm = l_vdn_sysparm; - - // frequency_step_khz - - l_frequency_step_khz = (i_attr->attr_freq_proc_refclock_khz / - i_attr->attr_proc_dpll_divider); - - o_globalppb->frequency_step_khz = revle32((uint32_t)l_frequency_step_khz); - o_globalppb->nest_frequency_mhz = revle32(i_attr->attr_nest_frequency_mhz); - - // External VRM parameters - o_globalppb->ext_vrm_transition_start_ns = - revle32(i_attr->attr_ext_vrm_transition_start_ns); - o_globalppb->ext_vrm_transition_rate_inc_uv_per_us = - revle32(i_attr->attr_ext_vrm_transition_rate_inc_uv_per_us); - o_globalppb->ext_vrm_transition_rate_dec_uv_per_us = - revle32(i_attr->attr_ext_vrm_transition_rate_dec_uv_per_us); - o_globalppb->ext_vrm_stabilization_time_us = - revle32(i_attr->attr_ext_vrm_stabilization_time_us); - o_globalppb->ext_vrm_step_size_mv = - revle32(i_attr->attr_ext_vrm_step_size_mv); - - // load the biases - // Note: all are uint8_t so no endianess correction is necessary - for (auto p = 0; p < NUM_OP_POINTS; p++) - { - switch (p) - { - case POWERSAVE: - o_globalppb->ext_biases[p].frequency_hp = i_attr->attr_freq_bias_powersave; - o_globalppb->ext_biases[p].vdd_ext_hp = i_attr->attr_voltage_ext_vdd_bias_powersave; - o_globalppb->int_biases[p].vdd_int_hp = i_attr->attr_voltage_int_vdd_bias_powersave; - break; - case NOMINAL: - o_globalppb->ext_biases[p].frequency_hp = i_attr->attr_freq_bias_nominal; - o_globalppb->ext_biases[p].vdd_ext_hp = i_attr->attr_voltage_ext_vdd_bias_nominal; - o_globalppb->int_biases[p].vdd_int_hp = i_attr->attr_voltage_int_vdd_bias_nominal; - break; - case TURBO: - o_globalppb->ext_biases[p].frequency_hp = i_attr->attr_freq_bias_turbo; - o_globalppb->ext_biases[p].vdd_ext_hp = i_attr->attr_voltage_ext_vdd_bias_turbo; - o_globalppb->int_biases[p].vdd_int_hp = i_attr->attr_voltage_int_vdd_bias_turbo; - break; - case ULTRA: - o_globalppb->ext_biases[p].frequency_hp = i_attr->attr_freq_bias_ultraturbo; - o_globalppb->ext_biases[p].vdd_ext_hp = i_attr->attr_voltage_ext_vdd_bias_ultraturbo; - o_globalppb->int_biases[p].vdd_int_hp = i_attr->attr_voltage_int_vdd_bias_ultraturbo; - } +//Sample data to verify functionality +// +// WOF sample data +const uint8_t g_wofData[] = +{ + 0x57, 0x46, 0x54, 0x48 /*MAGIC CODE WFTH*/, + 0x00, 0x00, 0x00, 0x01 /*version*/, + 0x00, 0x80 /*VFRT block size*/, + 0x00, 0x08 /*VFRT header size*/, + 0x00, 0x01 /*VFRT data size*/, + 0x6 /*Quad value*/, + 0x18 /*core count*/, + 0x00, 0xFA /*Vdn start*/, + 0x00, 0x64 /*Vdn step*/, + 0x00, 0x08 /*Vdn size*/, + 0x00, 0x00 /*Vdd start*/, + 0x00, 0x32 /*Vdd step*/, + 0x00, 0x15 /*Vdd size*/, + 0x03, 0xE8 /*Vratio start*/, + 0x00, 0x53 /*Vratio step*/, + 0x00, 0x18 /*Vratio size*/, + 0x03, 0xE8 /*Fratio start*/, + 0x00, 0x64 /*Fratio step*/, + 0x00, 0x5 /*Fratio size*/, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*Vdn percent*/, + 0x00, 0x64 /*Socket power Watts*/, + 0x07, 0x4a /*nest freq*/, + 0x09, 0x60 /*nominl freq*/, + 0x00, 0x00 /*RDP capacity*/, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* WOF table source tag*/, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*package name*/, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*Pad to 128B*/ +}; - o_globalppb->ext_biases[p].vdn_ext_hp = i_attr->attr_voltage_ext_vdn_bias; - o_globalppb->ext_biases[p].vcs_ext_hp = i_attr->attr_voltage_ext_vcs_bias; +//Sample VFRT data +const uint8_t g_sysvfrtData[] = +{ + 0x56, 0x54, // Magic_code 2B) + 0x00, 0x00, // reserved (2B) + 0x02, // type(4b),version(4b) + VDN_PERCENT_KEY, // vdn percentage(1B), + 0x05, // vdd percentage(1B) + QID_KEY, // quad id(1B) + 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, + 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, + 0xA8, 0xA5, 0xA5, 0xA1, 0x9D, 0x9A, 0xA8, 0xA8, 0xA8, + 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, + 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA5, 0xA5, + 0xA1, 0x9D, 0x9A, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, + 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, + 0xA8, 0xA8, 0xA8, 0xA8, 0xA5, 0xA5, 0xA1, 0x9D, 0x9A, + 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, + 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, + 0xA8, 0xA5, 0xA5, 0xA1, 0x9D, 0x9A, 0xA8, 0xA8, 0xA8, + 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, + 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA5, 0xA5, + 0xA1, 0x9D, 0x9A +}; - } +// Strings used in traces +char const* vpdSetStr[NUM_VPD_PTS_SET] = VPD_PT_SET_ORDER_STR; +char const* region_names[] = { "REGION_POWERSAVE_NOMINAL", + "REGION_NOMINAL_TURBO", + "REGION_TURBO_ULTRA" + }; +char const* prt_region_names[] = VPD_OP_SLOPES_REGION_ORDER_STR; - //WOV parameters - o_globalppb->wov_sample_125us = revle32(i_attr->attr_wov_sample_125us); - o_globalppb->wov_max_droop_pct = revle32(i_attr->attr_wov_max_droop_pct); - o_globalppb->wov_underv_perf_loss_thresh_pct = i_attr->attr_wov_underv_perf_loss_thresh_pct; - o_globalppb->wov_underv_step_incr_pct = i_attr->attr_wov_underv_step_incr_pct; - o_globalppb->wov_underv_step_decr_pct = i_attr->attr_wov_underv_step_decr_pct; - o_globalppb->wov_underv_max_pct = i_attr->attr_wov_underv_max_pct; - o_globalppb->wov_underv_vmin_mv = revle16(i_attr->attr_wov_underv_vmin_mv); - o_globalppb->wov_overv_vmax_mv = revle16(i_attr->attr_wov_overv_vmax_mv); - o_globalppb->wov_overv_step_incr_pct = i_attr->attr_wov_overv_step_incr_pct; - o_globalppb->wov_overv_step_decr_pct = i_attr->attr_wov_overv_step_decr_pct; - o_globalppb->wov_overv_max_pct = i_attr->attr_wov_overv_max_pct; -} +//the value in this table are in Index format +uint8_t g_GreyCodeIndexMapping [] = +{ + /* 0mV 0x00*/ 0, + /* - 8mV 0x01*/ 1, + /* -24mV 0x02*/ 3, + /* -16mV 0x03*/ 2, + /* -56mV 0x04*/ 7, + /* -48mV 0x05*/ 6, + /* -32mV 0x06*/ 4, + /* -40mV 0x07*/ 5, + /* -96mV 0x08*/ 12, + /* -96mV 0x09*/ 12, + /* -96mV 0x0a*/ 12, + /* -96mV 0x0b*/ 12, + /* -64mV 0x0c*/ 8, + /* -72mV 0x0d*/ 9, + /* -88mV 0x0e*/ 11, + /* -80mV 0x0f*/ 10 +}; -// START OF PSTATE PARAMETER BLOCK function +/////////////////////////////////////////////////////////// +//////// p9_pstate_parameter_block +/////////////////////////////////////////////////////////// fapi2::ReturnCode p9_pstate_parameter_block( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, PstateSuperStructure* io_pss, @@ -403,11 +259,10 @@ p9_pstate_parameter_block( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_ fapi2::ReturnCode l_rc = 0; io_size = 0; - const uint8_t pv_op_order[NUM_OP_POINTS] = VPD_PV_ORDER; - const char* pv_op_str[NUM_OP_POINTS] = VPD_PV_ORDER_STR; - do { + //Instantiate pstate object + PlatPmPPB l_pmPPB(i_target); // ----------------------------------------------------------- // Clear the PstateSuperStructure and install the magic number @@ -430,77 +285,9 @@ p9_pstate_parameter_block( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_ OCCPstateParmBlock l_occppb; memset (&l_occppb , 0, sizeof (OCCPstateParmBlock)); - // QuadManagerFlags - QuadManagerFlags l_qm_flags; - - PSTATE_attribute_state l_state; - l_state.iv_pstates_enabled = false; - l_state.iv_resclk_enabled = false; - l_state.iv_vdm_enabled = false; - l_state.iv_ivrm_enabled = false; - l_state.iv_wof_enabled = false; - l_state.iv_wov_underv_enabled = false; - l_state.iv_wov_overv_enabled = false; - - //By default first disable the PSTATE attributes - FAPI_TRY(p9_pstate_set_global_feature_attributes(i_target, - l_state, - &l_qm_flags)); - - l_state.iv_pstates_enabled = true; - l_state.iv_resclk_enabled = true; - l_state.iv_vdm_enabled = true; - l_state.iv_ivrm_enabled = true; - l_state.iv_wof_enabled = true; - l_state.iv_wov_underv_enabled = true; - l_state.iv_wov_overv_enabled = true; - - // Enablement state - PoundW_data l_poundw_data; - memset (&l_poundw_data,0,sizeof(l_poundw_data)); - - // MVPD #V variables - uint32_t attr_mvpd_poundv[PV_D][PV_W]; - uint32_t attr_mvpd_poundv_biased[PV_D][PV_W]; - uint8_t present_chiplets = 0; - uint32_t valid_pdv_points = 0; - - // Local IDDQ table variable - IddqTable l_iddqt; - memset( & l_iddqt, 0x00, sizeof(IddqTable)); - - //VDM Parm block - GP_VDMParmBlock l_gp_vdmpb; - memset (&l_gp_vdmpb,0x00,sizeof(GP_VDMParmBlock)); - - LP_VDMParmBlock l_lp_vdmpb; - memset (&l_lp_vdmpb, 0x00, sizeof(LP_VDMParmBlock)); - - //Resonant Clocking setup - ResonantClockingSetup l_resclk_setup; - memset (&l_resclk_setup,0x00, sizeof(ResonantClockingSetup)); - - //IVRM Parm block - IvrmParmBlock l_ivrmpb; - memset (&l_ivrmpb, 0x00,sizeof(IvrmParmBlock)); - - // VPD voltage and frequency biases - VpdBias l_vpdbias[NUM_OP_POINTS]; - memset (l_vpdbias,0,sizeof(VpdBias)); - - // ------------------------- - // Get all attributes needed - // ------------------------- - FAPI_INF("Getting Attributes to build Pstate Superstructure"); - - FAPI_TRY(proc_get_attributes(i_target, &attr), "Get attributes function failed"); - - // Put attr driven content into GPPB - load_gppb_attrs(&attr, &l_globalppb); - //if PSTATES_MODE is off then we dont need to execute further to collect //the data. - if (attr.attr_pstate_mode == fapi2::ENUM_ATTR_SYSTEM_PSTATES_MODE_OFF) + if (l_pmPPB.isPstateModeEnabled()) { FAPI_INF("Pstate mode is to not boot the PGPE. Thus, none of the parameter blocks will be constructed"); @@ -511,42 +298,14 @@ p9_pstate_parameter_block( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_ } // ---------------- - // get #V data + // get VPD data (#V,#W,IQ) // ---------------- - FAPI_IMP("Getting #V Data"); - uint8_t l_poundv_bucketId = 0; - - // clear MVPD arrays - memset(attr_mvpd_poundv, 0, sizeof(attr_mvpd_poundv)); - memset(attr_mvpd_poundv_biased, 0, sizeof(attr_mvpd_poundv_biased)); - fapi2::voltageBucketData_t l_poundv_data; - - FAPI_TRY(proc_get_mvpd_data(i_target, attr_mvpd_poundv, - &valid_pdv_points, - &present_chiplets, - l_poundv_bucketId, - &l_poundv_data, &l_state), - "proc_get_mvpd_data function failed to retrieve pound V data"); - - for (int i = 0; i <= NUM_OP_POINTS - 1; i++) - { - FAPI_DBG("Raw #V operating point (%s) f=%u v=%u i=%u v=%u i=%u", - pv_op_str[pv_op_order[i]], - attr_mvpd_poundv[pv_op_order[i]][0], - attr_mvpd_poundv[pv_op_order[i]][1], - attr_mvpd_poundv[pv_op_order[i]][2], - attr_mvpd_poundv[pv_op_order[i]][3], - attr_mvpd_poundv[pv_op_order[i]][4]); - } + FAPI_TRY(l_pmPPB.vpd_init(),"vpd_init function failed"); - if (!present_chiplets) + if (!l_pmPPB.isEqChipletPresent()) { FAPI_IMP("**** WARNING : There are no EQ chiplets present which means there is no valid #V VPD"); FAPI_IMP("**** WARNING : Pstates and all related functions will NOT be enabled."); - l_state.iv_pstates_enabled = false; - l_state.iv_resclk_enabled = false; - l_state.iv_resclk_enabled = false; - l_state.iv_wof_enabled = false; // Set the io_size to 0 so that memory allocation issues won't be // detected by the caller. @@ -554,430 +313,338 @@ p9_pstate_parameter_block( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_ break; } - FAPI_DBG("Pstate Base Frequency - Raw %X (%d)", - attr_mvpd_poundv[ULTRA][0] * 1000, - attr_mvpd_poundv[ULTRA][0] * 1000); - - VpdOperatingPoint l_raw_operating_points[NUM_OP_POINTS]; - FAPI_INF("Load RAW VPD"); - FAPI_TRY(load_mvpd_operating_point(attr_mvpd_poundv, - l_raw_operating_points, - revle32(l_globalppb.frequency_step_khz)), - "Loading MVPD operating point failed"); - - // --------------------------------------------- - // process external and internal bias attributes - // --------------------------------------------- - FAPI_IMP("Apply Biasing to #V"); - - // Copy to Bias array - for (int i = 0; i <= NUM_OP_POINTS - 1; i++) - { - for (int d = 0; d < PV_D; ++d) - { - for (int w = 0; w < PV_W; ++w) - { - attr_mvpd_poundv_biased[d][w] = attr_mvpd_poundv[d][w]; - } - } - FAPI_DBG("Biased #V operating point (%s) f=%u v=%u i=%u v=%u i=%u", - pv_op_str[pv_op_order[i]], - attr_mvpd_poundv_biased[pv_op_order[i]][0], - attr_mvpd_poundv_biased[pv_op_order[i]][1], - attr_mvpd_poundv_biased[pv_op_order[i]][2], - attr_mvpd_poundv_biased[pv_op_order[i]][3], - attr_mvpd_poundv_biased[pv_op_order[i]][4]); - } - - FAPI_TRY(proc_get_extint_bias(attr_mvpd_poundv_biased, - &attr, - l_vpdbias), - "Bias application function failed"); - - //Validating Bias values - FAPI_INF("Validate Biasd Voltage and Frequency values"); - - FAPI_TRY(proc_chk_valid_poundv( i_target, - attr_mvpd_poundv_biased, - &valid_pdv_points, - i_target.getChipletNumber(), - l_poundv_bucketId, - &l_state,true)); - - FAPI_DBG("Pstate Base Frequency - after bias %X (%d)", - attr_mvpd_poundv_biased[ULTRA][0] * 1000, - attr_mvpd_poundv_biased[ULTRA][0] * 1000); - - //if wof is disabled.. don't call IQ function - if (is_wof_enabled(i_target,&l_state)) - { - // ---------------- - // get IQ (IDDQ) data - // ---------------- - FAPI_INF("Getting IQ (IDDQ) Data"); - l_rc = proc_get_mvpd_iddq(i_target, &l_iddqt, &l_state); - - if (l_rc) - { - FAPI_ASSERT_NOEXIT(false, - fapi2::PSTATE_PB_IQ_ACCESS_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_FAPI_RC(l_rc), - "Pstate Parameter Block proc_get_mvpd_iddq function failed"); - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - } - } - else - { - FAPI_INF("Skipping IQ (IDDQ) Data as WOF is disabled"); - l_state.iv_wof_enabled = false; - } - - // ---------------- - // get VDM Parameters data - // ---------------- - FAPI_INF("Getting VDM Parameters Data"); - FAPI_TRY(proc_get_vdm_parms(i_target, &attr, &l_gp_vdmpb)); - - // Note: the proc_get_mvpd_poundw has the conditional checking for VDM - // and WOF enablement as #W has both VDM and WOF content - - l_rc = proc_get_mvpd_poundw(i_target, - l_poundv_bucketId, - &l_lp_vdmpb, - &l_poundw_data, - l_poundv_data, &l_state); - - if (l_rc) - { - FAPI_ASSERT_NOEXIT(false, - fapi2::PSTATE_PB_POUND_W_ACCESS_FAIL(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_FAPI_RC(l_rc), - "Pstate Parameter Block proc_get_mvpd_poundw function failed"); - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - } - - // ---------------- // get IVRM Parameters data // ---------------- + // TBD FAPI_INF("Getting IVRM Parameters Data"); - FAPI_TRY(proc_get_ivrm_parms(i_target, - &attr, - &l_ivrmpb, - &l_state)); - - // ----------------------------------------------- - // Global parameter block - // ----------------------------------------------- - - // Needs to be Endianness corrected going into the block + FAPI_TRY(l_pmPPB.get_ivrm_parms()); - l_globalppb.magic = revle64(PSTATE_PARMSBLOCK_MAGIC); - - l_globalppb.options.options = 0; // until options get defined. + // ---------------- + // Compute VPD points for different regions + // ---------------- + l_pmPPB.compute_vpd_pts(); - // ----------------------------------------------- - // populate VpdOperatingPoint with biased MVPD attributes - // ----------------------------------------------- + // ---------------- + // Safe mode freq and volt init + // ---------------- + FAPI_TRY(l_pmPPB.safe_mode_init()); - FAPI_INF("Load VPD"); - // VPD operating point - FAPI_TRY(load_mvpd_operating_point(attr_mvpd_poundv, - l_globalppb.operating_points, - revle32(l_globalppb.frequency_step_khz)), - "Loading MVPD operating point failed"); + // ---------------- + // Initialize VDM data + // ---------------- + l_pmPPB.vdm_init(); - VpdOperatingPoint l_operating_points[NUM_VPD_PTS_SET][NUM_OP_POINTS]; - // Compute VPD pointsp9_pstate_compute_PStateV_slope - p9_pstate_compute_vpd_pts(l_operating_points, - &l_globalppb, - l_raw_operating_points); + // ---------------- + // get Resonant clocking attributes + // ---------------- + FAPI_TRY(l_pmPPB.resclk_init()); - memcpy(l_globalppb.operating_points_set, - l_operating_points, - sizeof(l_operating_points)); + // ---------------- + // Initialize GPPB structure + // ---------------- + FAPI_TRY(l_pmPPB.gppb_init(&l_globalppb)); - FAPI_INF("Pstate Base Frequency %X (%d)", - revle32(l_globalppb.reference_frequency_khz), - revle32(l_globalppb.reference_frequency_khz)); - // VpdBias External and Internal Biases for Global and Local parameter + // ---------------- + // Initialize LPPB structure + // ---------------- + FAPI_TRY(l_pmPPB.lppb_init(&l_localppb)); - // block - for (uint8_t i = 0; i < NUM_OP_POINTS; i++) - { - l_globalppb.ext_biases[i] = l_vpdbias[i]; - l_globalppb.int_biases[i] = l_vpdbias[i]; + // ---------------- + // WOF initialization + // ---------------- + io_size = 0; + FAPI_TRY(l_pmPPB.wof_init( + o_buf, + io_size), + "WOF initialization failure"); - l_localppb.ext_biases[i] = l_vpdbias[i]; - l_localppb.int_biases[i] = l_vpdbias[i]; - } + // ---------------- + //Initialize OPPB structure + // ---------------- + FAPI_TRY(l_pmPPB.oppb_init(&l_occppb)); + // ---------------- + //Initialize pstate feature attribute state + // ---------------- + FAPI_TRY(l_pmPPB.set_global_feature_attributes()); + // Put out the Parmater Blocks to the trace + gppb_print(&(l_globalppb)); + oppb_print(&(l_occppb)); - // VpdBias External and Internal Biases for Global and Local parameter - // block - for (uint8_t i = 0; i < NUM_OP_POINTS; i++) - { - l_globalppb.ext_biases[i] = l_vpdbias[i]; - l_globalppb.int_biases[i] = l_vpdbias[i]; + // Populate Global,local and OCC parameter blocks into Pstate super structure + (*io_pss).globalppb = l_globalppb; + (*io_pss).localppb = l_localppb; + (*io_pss).occppb = l_occppb; + } + while(0); - l_localppb.ext_biases[i] = l_vpdbias[i]; - l_localppb.int_biases[i] = l_vpdbias[i]; - } - if (!attr.attr_pm_safe_voltage_mv && - !attr.attr_pm_safe_frequency_mhz) - { - uint8_t l_ps_pstate = 0; - Safe_mode_parameters l_safe_mode_values; - uint32_t l_ps_freq_khz = - l_operating_points[VPD_PT_SET_BIASED][POWERSAVE].frequency_mhz * 1000; - freq2pState(&l_globalppb, l_ps_freq_khz, &l_ps_pstate); - //Compute safe mode values - FAPI_TRY(p9_pstate_safe_mode_computation ( - i_target, - l_operating_points, - revle32(l_globalppb.reference_frequency_khz), - revle32(l_globalppb.frequency_step_khz), - l_ps_pstate, - &l_safe_mode_values, - l_poundw_data), - "Error from p9_pstate_safe_mode_computation function"); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ, - i_target,attr.attr_pm_safe_frequency_mhz )); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_VOLTAGE_MV, - i_target, attr.attr_pm_safe_voltage_mv)); +fapi_try_exit: + FAPI_DBG("< p9_pstate_parameter_block"); + return fapi2::current_err; +} +// END OF PSTATE PARAMETER BLOCK function - } - // safe_voltage_mv - l_globalppb.safe_voltage_mv = revle32(attr.attr_pm_safe_voltage_mv); - // safe_frequency_khz - l_globalppb.safe_frequency_khz = - revle32(attr.attr_pm_safe_frequency_mhz * 1000); - FAPI_INF("Safe Mode Frequency %d (0x%X) kHz; Voltage %d (0x%X) mV", - revle32(l_globalppb.safe_frequency_khz), - revle32(l_globalppb.safe_frequency_khz), - revle32(l_globalppb.safe_voltage_mv), - revle32(l_globalppb.safe_voltage_mv)); +/////////////////////////////////////////////////////////// +//////// freq2pState +/////////////////////////////////////////////////////////// +int PlatPmPPB::freq2pState (const uint32_t i_freq_khz, + Pstate* o_pstate, + const FREQ2PSTATE_ROUNDING i_round) +{ + int rc = 0; + float pstate32 = 0; - // ---------------- - // get Resonant clocking attributes - // ---------------- - { - if (attr.attr_resclk_disable == fapi2::ENUM_ATTR_SYSTEM_RESCLK_DISABLE_OFF) - { - FAPI_TRY(proc_set_resclk_table_attrs(i_target, - &l_state), - "proc_set_resclk_table_attrs failed"); + // ---------------------------------- + // compute pstate for given frequency + // ---------------------------------- + pstate32 = ((float)((iv_reference_frequency_khz) - (float)i_freq_khz)) / + (float) (iv_frequency_step_khz); + // @todo Bug fix from Characterization team to deal with VPD not being + // exactly in step increments + // - not yet included to separate changes + // As higher Pstate numbers represent lower frequencies, the pstate must be + // snapped to the nearest *higher* integer value for safety. (e.g. slower + // frequencies are safer). + if ((i_round == ROUND_SLOW) && (i_freq_khz)) + { + *o_pstate = (Pstate)internal_ceil(pstate32); + FAPI_DBG("freq2pState: ROUND SLOW"); + } + else + { + *o_pstate = (Pstate)pstate32; + FAPI_DBG("freq2pState: ROUND FAST"); + } - if (l_state.iv_resclk_enabled) - { - FAPI_TRY(proc_res_clock_setup(i_target, - &l_resclk_setup, - &l_globalppb)); - l_localppb.resclk = l_resclk_setup; - l_globalppb.resclk = l_resclk_setup; - } + FAPI_DBG("freq2pState: i_freq_khz = %u (0x%X); pstate32 = %f; o_pstate = %u (0x%X)", + i_freq_khz, i_freq_khz, pstate32, *o_pstate, *o_pstate); + FAPI_DBG("freq2pState: ref_freq_khz = %u (0x%X); step_freq_khz= %u (0x%X)", + (iv_reference_frequency_khz), + (iv_reference_frequency_khz), + (iv_frequency_step_khz), + (iv_frequency_step_khz)); - FAPI_INF("Resonant Clocks are enabled"); - } - else - { - l_state.iv_resclk_enabled = false; - FAPI_INF("Resonant Clocks are disabled. Skipping setup."); - } - } + // ------------------------------ + // perform pstate bounds checking + // ------------------------------ + if (pstate32 < PSTATE_MIN) + { + rc = -PSTATE_LT_PSTATE_MIN; + *o_pstate = PSTATE_MIN; + } - // VDMParmBlock vdm - l_globalppb.vdm = l_gp_vdmpb; + if (pstate32 > PSTATE_MAX) + { + rc = -PSTATE_GT_PSTATE_MAX; + *o_pstate = PSTATE_MAX; + } - // IvrmParmBlock - l_globalppb.ivrm = l_ivrmpb; + return rc; +} //end of freq2pState - // Calculate pre-calculated slopes - p9_pstate_compute_PStateV_slope(l_operating_points, &l_globalppb); +/////////////////////////////////////////////////////////// +//////// set_global_feature_attributes +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::set_global_feature_attributes() +{ + // Quad Manager Flags + fapi2::buffer<uint16_t> l_data16; - l_globalppb.dpll_pstate0_value = - revle32(revle32(l_globalppb.reference_frequency_khz) / - revle32(l_globalppb.frequency_step_khz)); + fapi2::ATTR_PSTATES_ENABLED_Type l_ps_enabled = + (fapi2::ATTR_PSTATES_ENABLED_Type)fapi2::ENUM_ATTR_PSTATES_ENABLED_FALSE; - FAPI_INF("l_globalppb.dpll_pstate0_value %X (%d)", - revle32(l_globalppb.dpll_pstate0_value), - revle32(l_globalppb.dpll_pstate0_value)); + fapi2::ATTR_RESCLK_ENABLED_Type l_resclk_enabled = + (fapi2::ATTR_RESCLK_ENABLED_Type)fapi2::ENUM_ATTR_RESCLK_ENABLED_FALSE; - // ----------------------------------------------- - // Local parameter block - // ----------------------------------------------- - l_localppb.magic = revle64(LOCAL_PARMSBLOCK_MAGIC); + fapi2::ATTR_VDM_ENABLED_Type l_vdm_enabled = + (fapi2::ATTR_VDM_ENABLED_Type)fapi2::ENUM_ATTR_VDM_ENABLED_FALSE; - // VPD operating point - FAPI_TRY(load_mvpd_operating_point(attr_mvpd_poundv_biased, - l_localppb.operating_points, - revle32(l_globalppb.frequency_step_khz)), - "Loading MVPD operating point failed"); + fapi2::ATTR_IVRM_ENABLED_Type l_ivrm_enabled = + (fapi2::ATTR_IVRM_ENABLED_Type)fapi2::ENUM_ATTR_IVRM_ENABLED_FALSE; - l_localppb.vdd_sysparm = l_globalppb.vdd_sysparm; + fapi2::ATTR_WOF_ENABLED_Type l_wof_enabled = + (fapi2::ATTR_WOF_ENABLED_Type)fapi2::ENUM_ATTR_WOF_ENABLED_FALSE; - // IvrmParmBlock - l_localppb.ivrm = l_ivrmpb; + fapi2::ATTR_WOV_UNDERV_ENABLED_Type l_wov_underv_enabled = + (fapi2::ATTR_WOV_UNDERV_ENABLED_Type)fapi2::ENUM_ATTR_WOV_UNDERV_ENABLED_FALSE; - // VDMParmBlock - l_localppb.vdm = l_lp_vdmpb; + fapi2::ATTR_WOV_OVERV_ENABLED_Type l_wov_overv_enabled = + (fapi2::ATTR_WOV_OVERV_ENABLED_Type)fapi2::ENUM_ATTR_WOV_OVERV_ENABLED_FALSE; - l_localppb.dpll_pstate0_value = - revle32(revle32(l_globalppb.reference_frequency_khz) / - revle32(l_globalppb.frequency_step_khz)); - FAPI_INF("l_localppb.dpll_pstate0_value %X (%d)", - revle32(l_localppb.dpll_pstate0_value), - revle32(l_localppb.dpll_pstate0_value)); + iv_wov_underv_enabled = false; + iv_wov_overv_enabled = false; + //Check whether to enable WOV Undervolting. WOV can + //only be enabled if VDMs are enabled + if (is_wov_underv_enabled() && + is_vdm_enabled()) + { + iv_wov_underv_enabled = true; + } + + //Check whether to enable WOV Overvolting. WOV can + //only be enabled if VDMs are enabled + if (is_wov_overv_enabled() && + is_vdm_enabled()) + { + iv_wov_overv_enabled = true; + } + + if (iv_pstates_enabled) + { + l_ps_enabled = (fapi2::ATTR_PSTATES_ENABLED_Type)fapi2::ENUM_ATTR_PSTATES_ENABLED_TRUE; + } - uint8_t l_biased_pstate[NUM_OP_POINTS]; + if (iv_resclk_enabled) + { + l_resclk_enabled = (fapi2::ATTR_RESCLK_ENABLED_Type)fapi2::ENUM_ATTR_RESCLK_ENABLED_TRUE; + } - for (uint8_t i = 0; i < NUM_OP_POINTS; ++i) - { - l_biased_pstate[i] = l_operating_points[VPD_PT_SET_BIASED][i].pstate; - FAPI_INF ("l_biased_pstate %d ", l_biased_pstate[i]); - } + if (iv_vdm_enabled) + { + l_vdm_enabled = (fapi2::ATTR_VDM_ENABLED_Type)fapi2::ENUM_ATTR_VDM_ENABLED_TRUE; + } - if (attr.attr_system_vdm_disable == fapi2::ENUM_ATTR_SYSTEM_VDM_DISABLE_OFF) - { - p9_pstate_compute_vdm_threshold_pts(l_poundw_data, &l_localppb); + if (iv_ivrm_enabled) + { + l_ivrm_enabled = (fapi2::ATTR_IVRM_ENABLED_Type)fapi2::ENUM_ATTR_IVRM_ENABLED_TRUE; + } - // VID slope calculation - p9_pstate_compute_PsVIDCompSlopes_slopes(l_poundw_data, - &l_localppb, - l_biased_pstate); + if (iv_wof_enabled) + { + l_wof_enabled = (fapi2::ATTR_WOF_ENABLED_Type)fapi2::ENUM_ATTR_WOF_ENABLED_TRUE; + } - // VDM threshold slope calculation - p9_pstate_compute_PsVDMThreshSlopes(&l_localppb, l_biased_pstate); - // VDM Jump slope calculation - p9_pstate_compute_PsVDMJumpSlopes (&l_localppb, l_biased_pstate); + if (iv_wov_underv_enabled) + { + l_wov_underv_enabled = (fapi2::ATTR_WOV_UNDERV_ENABLED_Type)fapi2::ENUM_ATTR_WOV_UNDERV_ENABLED_TRUE; + } + if (iv_wov_overv_enabled) + { + l_wov_overv_enabled = (fapi2::ATTR_WOV_OVERV_ENABLED_Type)fapi2::ENUM_ATTR_WOV_OVERV_ENABLED_TRUE; + } - //Initializing threshold and jump values for GPPB - memcpy ( l_globalppb.vid_point_set, - l_localppb.vid_point_set, - sizeof(l_localppb.vid_point_set)); - memcpy ( l_globalppb.threshold_set, - l_localppb.threshold_set, - sizeof(l_localppb.threshold_set)); - memcpy ( l_globalppb.jump_value_set, - l_localppb.jump_value_set, - sizeof(l_localppb.jump_value_set)); + SET_ATTR(fapi2::ATTR_PSTATES_ENABLED, iv_procChip, l_ps_enabled); + SET_ATTR(fapi2::ATTR_RESCLK_ENABLED, iv_procChip, l_resclk_enabled); + SET_ATTR(fapi2::ATTR_VDM_ENABLED, iv_procChip, l_vdm_enabled); + SET_ATTR(fapi2::ATTR_IVRM_ENABLED, iv_procChip, l_ivrm_enabled); + SET_ATTR(fapi2::ATTR_WOF_ENABLED, iv_procChip, l_wof_enabled); + SET_ATTR(fapi2::ATTR_WOV_UNDERV_ENABLED, iv_procChip, l_wov_underv_enabled); + SET_ATTR(fapi2::ATTR_WOV_OVERV_ENABLED, iv_procChip, l_wov_overv_enabled); - memcpy ( l_globalppb.PsVIDCompSlopes, - l_localppb.PsVIDCompSlopes, - sizeof(l_localppb.PsVIDCompSlopes)); - memcpy ( l_globalppb.PsVDMThreshSlopes, - l_localppb.PsVDMThreshSlopes, - sizeof(l_localppb.PsVDMThreshSlopes)); +fapi_try_exit: + return fapi2::current_err; +} //end of set_global_feature_attributes - memcpy ( l_globalppb.PsVDMJumpSlopes, - l_localppb.PsVDMJumpSlopes, - sizeof(l_localppb.PsVDMJumpSlopes)); - } +/////////////////////////////////////////////////////////// +//////// oppb_init +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::oppb_init( + OCCPstateParmBlock *i_occppb ) +{ + FAPI_INF(">>>>>>>> oppb_init"); + do + { // ----------------------------------------------- // OCC parameter block // ----------------------------------------------- - l_occppb.magic = revle64(OCC_PARMSBLOCK_MAGIC); + i_occppb->magic = revle64(OCC_PARMSBLOCK_MAGIC); - // VPD operating point - FAPI_TRY(load_mvpd_operating_point(attr_mvpd_poundv_biased, - l_occppb.operating_points, - l_globalppb.frequency_step_khz), - "Loading MVPD operating point failed"); + i_occppb->wof.wof_enabled = iv_wof_enabled; + i_occppb->vdd_sysparm = iv_vdd_sysparam; + i_occppb->vcs_sysparm = iv_vcs_sysparam; + i_occppb->vdn_sysparm = iv_vdn_sysparam; + + //load vpd operating points + for (uint32_t i = 0; i < NUM_OP_POINTS; i++) + { + i_occppb->operating_points[i].frequency_mhz = revle32(iv_biased_vpd_pts[i].frequency_mhz); + i_occppb->operating_points[i].vdd_mv = revle32(iv_biased_vpd_pts[i].vdd_mv); + i_occppb->operating_points[i].idd_100ma = revle32(iv_biased_vpd_pts[i].idd_100ma); + i_occppb->operating_points[i].vcs_mv = revle32(iv_biased_vpd_pts[i].vcs_mv); + i_occppb->operating_points[i].ics_100ma = revle32(iv_biased_vpd_pts[i].ics_100ma); + i_occppb->operating_points[i].pstate = iv_biased_vpd_pts[i].pstate; + } - l_occppb.vdd_sysparm = l_globalppb.vdd_sysparm; - l_occppb.vcs_sysparm = l_globalppb.vcs_sysparm; - l_occppb.vdn_sysparm = l_globalppb.vdn_sysparm; // frequency_min_khz - Value from Power safe operating point after biases Pstate l_ps; //Translate safe mode frequency to pstate - freq2pState(&l_globalppb, - revle32(attr.attr_pm_safe_frequency_mhz * 1000), + freq2pState((iv_attrs.attr_pm_safe_frequency_mhz * 1000), &l_ps, ROUND_FAST); //Compute real frequency - l_occppb.frequency_min_khz = l_globalppb.reference_frequency_khz - - (l_ps * l_globalppb.frequency_step_khz); + i_occppb->frequency_min_khz = iv_reference_frequency_khz - + (l_ps * iv_frequency_step_khz); + + i_occppb->frequency_min_khz = revle32(i_occppb->frequency_min_khz); // frequency_max_khz - Value from Ultra Turbo operating point after biases - l_occppb.frequency_max_khz = l_globalppb.reference_frequency_khz; + i_occppb->frequency_max_khz = revle32(iv_reference_frequency_khz); // frequency_step_khz - l_occppb.frequency_step_khz = l_globalppb.frequency_step_khz; + i_occppb->frequency_step_khz = revle32(iv_frequency_step_khz); // Power bus nest freq - uint16_t l_pbus_nest_freq = revle16(l_poundv_data.pbFreq); + uint16_t l_pbus_nest_freq = revle16(iv_poundV_raw_data.pbFreq); + FAPI_INF("l_pbus_nest_freq 0x%x (%d)", l_pbus_nest_freq, l_pbus_nest_freq); // I- VDN PB current - uint16_t l_vpd_idn_100ma = revle16(l_poundv_data.IdnPbCurr); + uint16_t l_vpd_idn_100ma = revle16(iv_poundV_raw_data.IdnPbCurr); FAPI_INF("l_vpd_idn_100ma 0x%x (%d)", l_vpd_idn_100ma, l_vpd_idn_100ma); - if (is_wof_enabled(i_target,&l_state)) + if (is_wof_enabled()) { // Iddq Table - l_occppb.iddq = l_iddqt; + i_occppb->iddq = iv_iddqt; - l_occppb.wof.tdp_rdp_factor = revle32(attr.attr_tdp_rdp_current_factor); - FAPI_INF("l_occppb.wof.tdp_rdp_factor 0x%x", revle32(l_occppb.wof.tdp_rdp_factor)); + i_occppb->wof.tdp_rdp_factor = (iv_attrs.attr_tdp_rdp_current_factor); + FAPI_INF("l_occppb.wof.tdp_rdp_factor 0x%x", revle32(i_occppb->wof.tdp_rdp_factor)); // nest leakage percent - l_occppb.nest_leakage_percent = attr.attr_nest_leakage_percent; - FAPI_INF("l_occppb.nest_leakage_percent 0x%x", l_occppb.nest_leakage_percent); + i_occppb->nest_leakage_percent = iv_attrs.attr_nest_leakage_percent; + FAPI_INF("l_occppb.nest_leakage_percent 0x%x", i_occppb->nest_leakage_percent); - l_occppb.lac_tdp_vdd_turbo_10ma = - revle16(l_poundw_data.poundw[TURBO].ivdd_tdp_ac_current_10ma); - l_occppb.lac_tdp_vdd_nominal_10ma = - revle16(l_poundw_data.poundw[NOMINAL].ivdd_tdp_ac_current_10ma); + i_occppb->lac_tdp_vdd_turbo_10ma = + revle16(iv_poundW_data.poundw[TURBO].ivdd_tdp_ac_current_10ma); + i_occppb->lac_tdp_vdd_nominal_10ma = + revle16(iv_poundW_data.poundw[NOMINAL].ivdd_tdp_ac_current_10ma); FAPI_INF("l_occppb.lac_tdp_vdd_turbo_10ma 0x%x (%d)", - l_occppb.lac_tdp_vdd_turbo_10ma, l_occppb.lac_tdp_vdd_turbo_10ma); + i_occppb->lac_tdp_vdd_turbo_10ma, i_occppb->lac_tdp_vdd_turbo_10ma); FAPI_INF("l_occppb.lac_tdp_vdd_nominal_10ma 0x%x (%d)", - l_occppb.lac_tdp_vdd_nominal_10ma, l_occppb.lac_tdp_vdd_nominal_10ma); + i_occppb->lac_tdp_vdd_nominal_10ma, i_occppb->lac_tdp_vdd_nominal_10ma); // As the Vdn dimension is not supported in the WOF tables, // hardcoding this value to the OCC as non-zero to keep it // happy. - l_occppb.ceff_tdp_vdn = 1; + i_occppb->ceff_tdp_vdn = 1; FAPI_INF(" l_occppb.ceff_tdp_vdn 0x%x (note: the Vdn dimension is not supported; this value is forced)", - l_occppb.ceff_tdp_vdn); + i_occppb->ceff_tdp_vdn); - // Put the good_normal_cores value into the GPPB for PGPE - // This is done as a union overlay so that the inter-platform headers - // are not touched. - GPPBOptionsPadUse pad; - pad.fields.good_cores_in_sort = l_iddqt.good_normal_cores_per_sort; - l_globalppb.options.pad = pad.value; - // Note: the following is presently accurate as the first 3 bytes - // are reserved. - FAPI_INF("good normal cores per sort %d 0x%X", - revle32(l_globalppb.options.pad), - revle32(l_globalppb.options.pad)); } else { - l_state.iv_wof_enabled = false; + iv_wof_enabled = false; } //Update nest frequency in OPPB - l_occppb.nest_frequency_mhz = l_globalppb.nest_frequency_mhz; + i_occppb->nest_frequency_mhz = revle32(iv_nest_freq_mhz); // The minimum Pstate must be rounded FAST so that core floor // constraints are not violated. Pstate pstate_min; - int rc = freq2pState(&l_globalppb, - revle32(l_occppb.frequency_min_khz), + int rc = freq2pState(revle32(i_occppb->frequency_min_khz), &pstate_min, ROUND_FAST); @@ -990,96 +657,373 @@ p9_pstate_parameter_block( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_ case -PSTATE_GT_PSTATE_MAX: FAPI_INF("OCC Minimum Frequency %d KHz is outside the range that can be represented" " by a Pstate with a base frequency of %d KHz and step size %d KHz", - revle32(l_occppb.frequency_min_khz), - revle32(l_globalppb.reference_frequency_khz), - revle32(l_globalppb.frequency_step_khz)); + revle32(i_occppb->frequency_min_khz), + (iv_reference_frequency_khz), + (iv_frequency_step_khz)); FAPI_INF("Pstate is set to %X (%d)", pstate_min); break; } - l_occppb.pstate_min = pstate_min; + i_occppb->pstate_min = pstate_min; FAPI_INF("l_occppb.pstate_min 0x%x (%u)", pstate_min, pstate_min); - //Check WOF is enabled or not - io_size = 0; - if (is_wof_enabled(i_target,&l_state)) + + }while(0); + + FAPI_INF("<<<<<<<< oppb_init"); + return fapi2::current_err; +} //end of oppb_init + + +/////////////////////////////////////////////////////////// +//////// lppb_init +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::lppb_init( + LocalPstateParmBlock *i_localppb) +{ + FAPI_INF(">>>>>>>> lppb_init"); + do + { + // ----------------------------------------------- + // Local parameter block + // ----------------------------------------------- + i_localppb->magic = revle64(LOCAL_PARMSBLOCK_MAGIC); + + // VpdBias External and Internal Biases for Global and Local parameter + // block + for (uint8_t i = 0; i < NUM_OP_POINTS; i++) { - FAPI_TRY(p9_pstate_wof_initialization( - i_target, - &l_globalppb, - o_buf, - io_size, - &l_state, - attr_mvpd_poundv_biased[VPD_PV_ULTRA][0]), - "WOF initialization failure"); + i_localppb->ext_biases[i] = iv_bias[i]; + i_localppb->int_biases[i] = iv_bias[i]; } - else + + //load vpd operating points + for (uint32_t i = 0; i < NUM_OP_POINTS; i++) { - FAPI_INF("WOF is not enabled"); - l_state.iv_wof_enabled = false; + i_localppb->operating_points[i].frequency_mhz = revle32(iv_biased_vpd_pts[i].frequency_mhz); + i_localppb->operating_points[i].vdd_mv = revle32(iv_biased_vpd_pts[i].vdd_mv); + i_localppb->operating_points[i].idd_100ma = revle32(iv_biased_vpd_pts[i].idd_100ma); + i_localppb->operating_points[i].vcs_mv = revle32(iv_biased_vpd_pts[i].vcs_mv); + i_localppb->operating_points[i].ics_100ma = revle32(iv_biased_vpd_pts[i].ics_100ma); + i_localppb->operating_points[i].pstate = iv_biased_vpd_pts[i].pstate; } - l_occppb.wof.wof_enabled = l_state.iv_wof_enabled; + i_localppb->vdd_sysparm = iv_vdd_sysparam; + + // IvrmParmBlock + i_localppb->ivrm = iv_ivrmpb; + + // VDMParmBlock + memset (&(i_localppb->vdm),0,sizeof(i_localppb->vdm)); + + i_localppb->dpll_pstate0_value = + ((iv_reference_frequency_khz) / + (iv_frequency_step_khz)); + i_localppb->dpll_pstate0_value = revle32(i_localppb->dpll_pstate0_value); + + FAPI_INF("l_localppb.dpll_pstate0_value %X (%d)", + revle32(i_localppb->dpll_pstate0_value), + revle32(i_localppb->dpll_pstate0_value)); + + i_localppb->resclk = iv_resclk_setup; - //Check whether to enable WOV Undervolting. WOV can - //only be enabled if VDMs are enabled - FAPI_INF("WOV_VMIN_MV=%u",attr.attr_wov_underv_vmin_mv); - if (attr.attr_wov_underv_vmin_mv == 0) { - l_globalppb.wov_underv_vmin_mv = revle16(uint16_t(revle32(l_globalppb.safe_voltage_mv))); - FAPI_INF("WOV_VMIN_MV=%u",revle16(l_globalppb.wov_underv_vmin_mv)); - FAPI_INF("SafeVoltage=%u",revle32(l_globalppb.safe_voltage_mv)); + if (iv_attrs.attr_system_vdm_disable == fapi2::ENUM_ATTR_SYSTEM_VDM_DISABLE_OFF) + { + + //Initializing threshold and jump values for LPPB + memcpy ( i_localppb->vid_point_set, + iv_vid_point_set, + sizeof(i_localppb->vid_point_set)); + + memcpy ( i_localppb->threshold_set, + iv_threshold_set, + sizeof(i_localppb->threshold_set)); + + memcpy ( i_localppb->jump_value_set, + iv_jump_value_set, + sizeof(i_localppb->jump_value_set)); + + memcpy ( i_localppb->PsVIDCompSlopes, + iv_PsVIDCompSlopes, + sizeof(i_localppb->PsVIDCompSlopes)); + + memcpy ( i_localppb->PsVDMThreshSlopes, + iv_PsVDMThreshSlopes, + sizeof(i_localppb->PsVDMThreshSlopes)); + + memcpy ( i_localppb->PsVDMJumpSlopes, + iv_PsVDMJumpSlopes, + sizeof(i_localppb->PsVDMJumpSlopes)); } - if (is_wov_underv_enabled(i_target, &l_state) && - is_vdm_enabled(i_target, &l_state)){ - l_state.iv_wov_underv_enabled = true; - } else{ - FAPI_INF("WOV Undervolting is not enabled"); - l_state.iv_wov_underv_enabled = false; + }while(0); + + FAPI_INF("<<<<<<<< lppb_init"); + return fapi2::current_err; + +} //end of lppb_init + + +/////////////////////////////////////////////////////////// +//////// gppb_init +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::gppb_init( + GlobalPstateParmBlock *io_globalppb) +{ + FAPI_INF(">>>>>>>> gppb_init"); + do + { + // Needs to be Endianness corrected going into the block + + io_globalppb->magic = revle64(PSTATE_PARMSBLOCK_MAGIC); + + io_globalppb->options.options = 0; // until options get defined. + + io_globalppb->reference_frequency_khz = revle32(iv_reference_frequency_khz); + + io_globalppb->nest_frequency_mhz = revle32(iv_nest_freq_mhz); + + io_globalppb->frequency_step_khz = revle32(iv_frequency_step_khz); + + FAPI_INF("Pstate Base Frequency %X (%d)", + revle32(io_globalppb->reference_frequency_khz), + revle32(io_globalppb->reference_frequency_khz)); + + // VpdBias External and Internal Biases for Global and Local parameter + // block + for (uint8_t i = 0; i < NUM_OP_POINTS; i++) + { + io_globalppb->ext_biases[i] = iv_bias[i]; + io_globalppb->int_biases[i] = iv_bias[i]; } - //Check whether to enable WOV Overvolting. WOV can - //only be enabled if VDMs are enabled - if (is_wov_overv_enabled(i_target, &l_state) && - is_vdm_enabled(i_target, &l_state)){ - l_state.iv_wov_overv_enabled = true; - } else{ - FAPI_INF("WOV Overvolting is not enabled"); - l_state.iv_wov_overv_enabled = false; + io_globalppb->vdd_sysparm = iv_vdd_sysparam; + io_globalppb->vcs_sysparm = iv_vcs_sysparam; + io_globalppb->vdn_sysparm = iv_vdn_sysparam; + + // External VRM parameters + io_globalppb->ext_vrm_transition_start_ns = + revle32(iv_attrs.attr_ext_vrm_transition_start_ns); + io_globalppb->ext_vrm_transition_rate_inc_uv_per_us = + revle32(iv_attrs.attr_ext_vrm_transition_rate_inc_uv_per_us); + io_globalppb->ext_vrm_transition_rate_dec_uv_per_us = + revle32(iv_attrs.attr_ext_vrm_transition_rate_dec_uv_per_us); + io_globalppb->ext_vrm_stabilization_time_us = + revle32(iv_attrs.attr_ext_vrm_stabilization_time_us); + io_globalppb->ext_vrm_step_size_mv = + revle32(iv_attrs.attr_ext_vrm_step_size_mv); + + + + // safe_voltage_mv + io_globalppb->safe_voltage_mv = revle32(iv_attrs.attr_pm_safe_voltage_mv); + + // safe_frequency_khz + io_globalppb->safe_frequency_khz = + iv_attrs.attr_pm_safe_frequency_mhz * 1000; + io_globalppb->safe_frequency_khz = revle32(io_globalppb->safe_frequency_khz); + FAPI_INF("Safe Mode Frequency %d (0x%X) kHz; Voltage %d (0x%X) mV", + revle32(io_globalppb->safe_frequency_khz), + revle32(io_globalppb->safe_frequency_khz), + revle32(io_globalppb->safe_voltage_mv), + revle32(io_globalppb->safe_voltage_mv)); + + io_globalppb->vdm = iv_vdmpb; + + // IvrmParmBlock + io_globalppb->ivrm = iv_ivrmpb; + + //load vpd operating points + for (uint32_t i = 0; i < NUM_OP_POINTS; i++) + { + io_globalppb->operating_points[i].frequency_mhz = revle32(iv_biased_vpd_pts[i].frequency_mhz); + io_globalppb->operating_points[i].vdd_mv = revle32(iv_biased_vpd_pts[i].vdd_mv); + io_globalppb->operating_points[i].idd_100ma = revle32(iv_biased_vpd_pts[i].idd_100ma); + io_globalppb->operating_points[i].vcs_mv = revle32(iv_biased_vpd_pts[i].vcs_mv); + io_globalppb->operating_points[i].ics_100ma = revle32(iv_biased_vpd_pts[i].ics_100ma); + io_globalppb->operating_points[i].pstate = iv_biased_vpd_pts[i].pstate; } - // QuadManagerFlags - FAPI_TRY(p9_pstate_set_global_feature_attributes(i_target, - l_state, - &l_qm_flags)); - l_localppb.qmflags = l_qm_flags; + // Initialize res clk data - // Put out the Parmater Blocks to the trace - gppb_print(&(l_globalppb)); - oppb_print(&(l_occppb)); + io_globalppb->resclk = iv_resclk_setup; - // Populate Global,local and OCC parameter blocks into Pstate super structure - (*io_pss).globalppb = l_globalppb; - (*io_pss).localppb = l_localppb; - (*io_pss).occppb = l_occppb; - } - while(0); + // ----------------------------------------------- + // populate VpdOperatingPoint with biased MVPD attributes + // ----------------------------------------------- + for (uint8_t i = 0; i < NUM_VPD_PTS_SET; i++) + { + for (uint8_t j = 0; j < NUM_OP_POINTS; j++) + { + io_globalppb->operating_points_set[i][j].frequency_mhz = revle32(iv_operating_points[i][j].frequency_mhz); + io_globalppb->operating_points_set[i][j].vdd_mv = revle32(iv_operating_points[i][j].vdd_mv); + io_globalppb->operating_points_set[i][j].idd_100ma = revle32(iv_operating_points[i][j].idd_100ma); + io_globalppb->operating_points_set[i][j].vcs_mv = revle32(iv_operating_points[i][j].vcs_mv); + io_globalppb->operating_points_set[i][j].ics_100ma = revle32(iv_operating_points[i][j].ics_100ma); + io_globalppb->operating_points_set[i][j].pstate = iv_operating_points[i][j].pstate; + } + } -fapi_try_exit: - FAPI_DBG("< p9_pstate_parameter_block"); + // Calculate pre-calculated slopes + compute_PStateV_slope(io_globalppb); + FAPI_INF("Finished compute_PStateV_slope"); + + io_globalppb->dpll_pstate0_value = + revle32(revle32(io_globalppb->reference_frequency_khz) / + revle32(io_globalppb->frequency_step_khz)); + + FAPI_INF("l_globalppb.dpll_pstate0_value %X (%d)", + revle32(io_globalppb->dpll_pstate0_value), + revle32(io_globalppb->dpll_pstate0_value)); + + if (iv_attrs.attr_system_vdm_disable == fapi2::ENUM_ATTR_SYSTEM_VDM_DISABLE_OFF) + { + //Initializing threshold and jump values for GPPB + memcpy ( io_globalppb->vid_point_set, + iv_vid_point_set, + sizeof(io_globalppb->vid_point_set)); + + memcpy ( io_globalppb->threshold_set, + iv_threshold_set, + sizeof(io_globalppb->threshold_set)); + + memcpy ( io_globalppb->jump_value_set, + iv_jump_value_set, + sizeof(io_globalppb->jump_value_set)); + + memcpy ( io_globalppb->PsVIDCompSlopes, + iv_PsVIDCompSlopes, + sizeof(io_globalppb->PsVIDCompSlopes)); + + memcpy ( io_globalppb->PsVDMThreshSlopes, + iv_PsVDMThreshSlopes, + sizeof(io_globalppb->PsVDMThreshSlopes)); + + memcpy ( io_globalppb->PsVDMJumpSlopes, + iv_PsVDMJumpSlopes, + sizeof(io_globalppb->PsVDMJumpSlopes)); + + // Put the good_normal_cores value into the GPPB for PGPE + // This is done as a union overlay so that the inter-platform headers + // are not touched. + GPPBOptionsPadUse pad; + + pad.fields.good_cores_in_sort = iv_iddqt.good_normal_cores_per_sort; + io_globalppb->options.pad = pad.value; + // Note: the following is presently accurate as the first 3 bytes + // are reserved. + FAPI_INF("good normal cores per sort %d 0x%X", + revle32(io_globalppb->options.pad), + revle32(io_globalppb->options.pad)); + + } + + //WOV parameters + io_globalppb->wov_sample_125us = revle32(iv_attrs.attr_wov_sample_125us); + io_globalppb->wov_max_droop_pct = revle32(iv_attrs.attr_wov_max_droop_pct); + io_globalppb->wov_underv_perf_loss_thresh_pct = iv_attrs.attr_wov_underv_perf_loss_thresh_pct; + io_globalppb->wov_underv_step_incr_pct = iv_attrs.attr_wov_underv_step_incr_pct; + io_globalppb->wov_underv_step_decr_pct = iv_attrs.attr_wov_underv_step_decr_pct; + io_globalppb->wov_underv_max_pct = iv_attrs.attr_wov_underv_max_pct; + io_globalppb->wov_underv_vmin_mv = revle16(iv_attrs.attr_wov_underv_vmin_mv); + io_globalppb->wov_overv_vmax_mv = revle16(iv_attrs.attr_wov_overv_vmax_mv); + io_globalppb->wov_overv_step_incr_pct = iv_attrs.attr_wov_overv_step_incr_pct; + io_globalppb->wov_overv_step_decr_pct = iv_attrs.attr_wov_overv_step_decr_pct; + io_globalppb->wov_overv_max_pct = iv_attrs.attr_wov_overv_max_pct; + + if (io_globalppb->wov_underv_vmin_mv == 0) + { + io_globalppb->wov_underv_vmin_mv = revle16(uint16_t(revle32(io_globalppb->safe_voltage_mv))); + FAPI_INF("WOV_VMIN_MV=%u",revle16(io_globalppb->wov_underv_vmin_mv)); + FAPI_INF("SafeVoltage=%u",revle32(io_globalppb->safe_voltage_mv)); + } + + + } while (0); + + FAPI_INF("<<<<<<<<<< gppb_init"); return fapi2::current_err; -} -// END OF PSTATE PARAMETER BLOCK function +} //end of gppb_init -fapi2::ReturnCode -p9_pstate_wof_initialization (const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - const GlobalPstateParmBlock* i_gppb, - uint8_t* o_buf, - uint32_t& io_size, - PSTATE_attribute_state* o_state, - const uint32_t i_base_state_frequency) +// +// PState(Frequency) on y-axis, Voltage is on x-axis for VF curve +// Interpolation formula: (y-y0)/(x-x0) = (y1-y0)/(x1-x0) +// m = (x1-x0)/(y1-y0), then use this to calculate voltage, x = (y-y0)*m + x0 +// 1/m = (y1-y0)/(x1-x0) here, then use this to calculate pstate(frequency), y = (x-x0)*m + y0 +// Region 0 is b/w POWERSAVE and NOMINAL +// Region 1 is b/w NOMINAL and TURBO +// Region 2 is between TURBO and ULTRA_TURBO +// +// Inflection Point 3 is ULTRA_TURBO +// Inflection Point 2 is TURBO +// Inflection Point 1 is NOMINAL +// Inflection Point 0 is POWERSAVE +// +/////////////////////////////////////////////////////////// +//////// compute_PStateV_slope +/////////////////////////////////////////////////////////// +void PlatPmPPB::compute_PStateV_slope( + GlobalPstateParmBlock* o_gppb) { + for(auto pt_set = 0; pt_set < NUM_VPD_PTS_SET; ++pt_set) + { + + // ULTRA TURBO pstate check is not required..because it's pstate will be + // 0 + if (!(iv_operating_points[pt_set][POWERSAVE].pstate) || + !(iv_operating_points[pt_set][NOMINAL].pstate) || + !(iv_operating_points[pt_set][TURBO].pstate)) + { + FAPI_ERR("Non-UltraTurbo PSTATE value shouldn't be zero for %s", vpdSetStr[pt_set]); + return; + } + //Calculate slopes + for(auto region(REGION_POWERSAVE_NOMINAL); region <= REGION_TURBO_ULTRA; ++region) + { + // Pstate value decreases with increasing region. Thus the values + // are swapped to result in a positive difference. + o_gppb->PStateVSlopes[pt_set][region] = + revle16( + compute_slope_4_12((iv_operating_points[pt_set][region + 1].vdd_mv), + (iv_operating_points[pt_set][region].vdd_mv), + iv_operating_points[pt_set][region].pstate, + iv_operating_points[pt_set][region + 1].pstate) + ); + + FAPI_DBG("PStateVSlopes[%s][%s] 0x%04x %d", vpdSetStr[pt_set], region_names[region], + revle16(o_gppb->PStateVSlopes[pt_set][region]), + revle16(o_gppb->PStateVSlopes[pt_set][region])); + } + + //Calculate inverted slopes + for(auto region(REGION_POWERSAVE_NOMINAL); region <= REGION_TURBO_ULTRA; ++region) + { + // Pstate value decreases with increasing region. Thus the values + // are swapped to result in a positive difference. + o_gppb->VPStateSlopes[pt_set][region] = + revle16( + compute_slope_4_12(iv_operating_points[pt_set][region].pstate, + iv_operating_points[pt_set][region + 1].pstate, + (iv_operating_points[pt_set][region + 1].vdd_mv), + (iv_operating_points[pt_set][region].vdd_mv)) + ); + + FAPI_DBG("VPStateSlopes[%s][%s] 0x%04x %d", vpdSetStr[pt_set], region_names[region], + revle16(o_gppb->VPStateSlopes[pt_set][region]), + revle16(o_gppb->VPStateSlopes[pt_set][region])); + } + } +} + + +/////////////////////////////////////////////////////////// +//////// wof_init +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::wof_init( + uint8_t* o_buf, + uint32_t& io_size) +{ FAPI_DBG(">> WOF initialization"); fapi2::ReturnCode l_rc = 0; @@ -1089,23 +1033,31 @@ p9_pstate_wof_initialization (const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& //this structure has VFRT header + data HomerVFRTLayout_t l_vfrt; memset (&l_vfrt, 0, sizeof(l_vfrt)); - // Use new to avoid over-running the stack fapi2::ATTR_WOF_TABLE_DATA_Type* l_wof_table_data = - (fapi2::ATTR_WOF_TABLE_DATA_Type*)new fapi2::ATTR_WOF_TABLE_DATA_Type; - - FAPI_DBG("l_wof_table_data addr = %p size = %d", - l_wof_table_data, sizeof(fapi2::ATTR_WOF_TABLE_DATA_Type)); + (fapi2::ATTR_WOF_TABLE_DATA_Type*)new fapi2::ATTR_WOF_TABLE_DATA_Type; do { + + if (!is_wof_enabled()) + { + FAPI_INF("WOF is not enabled"); + iv_wof_enabled = false; + break; + } + + FAPI_DBG("l_wof_table_data addr = %p size = %d", + l_wof_table_data, sizeof(fapi2::ATTR_WOF_TABLE_DATA_Type)); + + // If this attribute is set, fill in l_wof_table_data with the VFRT data // from the internal, static table. const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; fapi2::ATTR_SYS_VFRT_STATIC_DATA_ENABLE_Type l_sys_vfrt_static_data = 0; FAPI_ATTR_GET(fapi2::ATTR_SYS_VFRT_STATIC_DATA_ENABLE, - FAPI_SYSTEM, - l_sys_vfrt_static_data); + FAPI_SYSTEM, + l_sys_vfrt_static_data); if (l_sys_vfrt_static_data) { @@ -1140,8 +1092,8 @@ p9_pstate_wof_initialization (const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& { l_vfrt.vfrtHeader.VddId_QAId = vdd << 4 | qid; FAPI_DBG(" l_vfrt.vfrtHeader res_vdnId = %1X VddId_QAId = 0x%2X", - l_vfrt.vfrtHeader.res_vdnId, - l_vfrt.vfrtHeader.VddId_QAId); + l_vfrt.vfrtHeader.res_vdnId, + l_vfrt.vfrtHeader.VddId_QAId); memcpy((*l_wof_table_data) + l_index, &l_vfrt, sizeof (l_vfrt)); l_index += sizeof (g_sysvfrtData); @@ -1157,13 +1109,13 @@ p9_pstate_wof_initialization (const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& // Read System VFRT data l_rc = FAPI_ATTR_GET(fapi2::ATTR_WOF_TABLE_DATA, - FAPI_SYSTEM, - (*l_wof_table_data)); + FAPI_SYSTEM, + (*l_wof_table_data)); if (l_rc) { FAPI_INF("Pstate Parameter Block ATTR_WOF_TABLE_DATA attribute failed. Disabling WOF"); - o_state->iv_wof_enabled = false; + iv_wof_enabled = false; // Write the returned error content to the error log fapi2::logError(l_rc,fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE); @@ -1183,28 +1135,28 @@ p9_pstate_wof_initialization (const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& bool l_wof_header_data_state = 1; VALIDATE_WOF_HEADER_DATA(p_wfth->magic_number, - p_wfth->reserved_version, - p_wfth->vfrt_block_size, - p_wfth->vfrt_block_header_size, - p_wfth->vfrt_data_size, - p_wfth->quads_active_size, - p_wfth->core_count, - l_wof_header_data_state); + p_wfth->reserved_version, + p_wfth->vfrt_block_size, + p_wfth->vfrt_block_header_size, + p_wfth->vfrt_data_size, + p_wfth->quads_active_size, + p_wfth->core_count, + l_wof_header_data_state); if (!l_wof_header_data_state) { - o_state->iv_wof_enabled = false; + iv_wof_enabled = false; FAPI_ASSERT_NOEXIT(false, - fapi2::PSTATE_PB_WOF_HEADER_DATA_INVALID(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(FAPI_SYSTEM) - .set_MAGIC_NUMBER(p_wfth->magic_number) - .set_VERSION(p_wfth->reserved_version) - .set_VFRT_BLOCK_SIZE(p_wfth->vfrt_block_size) - .set_VFRT_HEADER_SIZE(p_wfth->vfrt_block_header_size) - .set_VFRT_DATA_SIZE(p_wfth->vfrt_data_size) - .set_QUADS_ACTIVE_SIZE(p_wfth->quads_active_size) - .set_CORE_COUNT(p_wfth->core_count), - "Pstate Parameter Block WOF Header validation failed"); + fapi2::PSTATE_PB_WOF_HEADER_DATA_INVALID(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_CHIP_TARGET(FAPI_SYSTEM) + .set_MAGIC_NUMBER(p_wfth->magic_number) + .set_VERSION(p_wfth->reserved_version) + .set_VFRT_BLOCK_SIZE(p_wfth->vfrt_block_size) + .set_VFRT_HEADER_SIZE(p_wfth->vfrt_block_header_size) + .set_VFRT_DATA_SIZE(p_wfth->vfrt_data_size) + .set_QUADS_ACTIVE_SIZE(p_wfth->quads_active_size) + .set_CORE_COUNT(p_wfth->core_count), + "Pstate Parameter Block WOF Header validation failed"); break; } @@ -1216,31 +1168,30 @@ p9_pstate_wof_initialization (const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& // Convert system vfrt to homer vfrt for (auto vfrt_index = 0; - vfrt_index < (l_vdn_size * l_vdd_size * ACTIVE_QUADS); - ++vfrt_index) + vfrt_index < (l_vdn_size * l_vdd_size * ACTIVE_QUADS); + ++vfrt_index) { - l_rc = p9_pstate_update_vfrt (i_target, - i_gppb, - ((*l_wof_table_data) + l_wof_table_index), - &l_vfrt, - i_base_state_frequency); + l_rc = update_vfrt ( + ((*l_wof_table_data) + l_wof_table_index), + &l_vfrt + ); if (l_rc) { - o_state->iv_wof_enabled = false; + iv_wof_enabled = false; FAPI_TRY(l_rc); // Exit the function as a fail } // Check for "VT" at the start of the magic number if (revle16(l_vfrt.vfrtHeader.magic_number) != 0x5654) { - o_state->iv_wof_enabled = false; + iv_wof_enabled = false; FAPI_ASSERT_NOEXIT(false, - fapi2::PSTATE_PB_VFRT_HEADER_DATA_INVALID(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(FAPI_SYSTEM) - .set_MAGIC_NUMBER(l_vfrt.vfrtHeader.magic_number) - .set_VFRT_INDEX(vfrt_index), - "Pstate Parameter Block: Invalid VFRT Magic word"); + fapi2::PSTATE_PB_VFRT_HEADER_DATA_INVALID(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_CHIP_TARGET(FAPI_SYSTEM) + .set_MAGIC_NUMBER(l_vfrt.vfrtHeader.magic_number) + .set_VFRT_INDEX(vfrt_index), + "Pstate Parameter Block: Invalid VFRT Magic word"); break; } l_wof_table_index += 128; //System vFRT size is 128B..hence need to jump after each VFRT entry @@ -1258,21 +1209,777 @@ p9_pstate_wof_initialization (const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; fapi_try_exit: - delete l_wof_table_data; + if (l_wof_table_data) + { + delete l_wof_table_data; + } FAPI_DBG("<< WOF initialization"); return fapi2::current_err; +} //end of wof_init -} +/////////////////////////////////////////////////////////// +//////// update_vfrt +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::update_vfrt( + uint8_t* i_pBuffer, + HomerVFRTLayout_t* o_vfrt_data) +{ + uint32_t l_index_0 = 0; + uint32_t l_index_1 = 0; + uint8_t l_type = 0; + uint32_t l_freq_khz = 0; + uint32_t l_step_freq_khz; + Pstate l_ps; -// START OF GET ATTRIBUTES + l_step_freq_khz = (iv_frequency_step_khz); + FAPI_DBG("l_step_freq_khz = 0x%X (%d)", l_step_freq_khz, l_step_freq_khz); -fapi2::ReturnCode -proc_get_attributes ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - AttributeList* io_attr) +#define UINT16_GET(__uint8_ptr) ((uint16_t)( ( (*((const uint8_t *)(__uint8_ptr)) << 8) | *((const uint8_t *)(__uint8_ptr) + 1) ) )) + //Initialize VFRT header + o_vfrt_data->vfrtHeader.magic_number = revle16(UINT16_GET(i_pBuffer)); + i_pBuffer += 2; + o_vfrt_data->vfrtHeader.reserved = revle16(UINT16_GET(i_pBuffer)); + i_pBuffer += 2; + o_vfrt_data->vfrtHeader.type_version = *i_pBuffer; + i_pBuffer++; + o_vfrt_data->vfrtHeader.res_vdnId = *i_pBuffer; // Future: this name is not accurate but takes a header change. + i_pBuffer++; + o_vfrt_data->vfrtHeader.VddId_QAId = *i_pBuffer; // Future: this name is not accurate but takes a header change. + i_pBuffer++; + o_vfrt_data->vfrtHeader.rsvd_QAId = *i_pBuffer; + i_pBuffer++; + + + //find type + l_type = (o_vfrt_data->vfrtHeader.type_version) >> 4; + + char l_buffer_str[256]; // Temporary formatting string buffer + char l_line_str[256]; // Formatted output line string + + // Filtering Tracing output to only only QID of 0 + bool b_output_trace = false; + if (o_vfrt_data->vfrtHeader.rsvd_QAId == QID_KEY && + o_vfrt_data->vfrtHeader.res_vdnId <= VDN_PERCENT_KEY) + { + b_output_trace = true; + } + FAPI_DBG("res_vdnId = %X, VDN_PERCENT_KEY = %X, .rsvd_QAId = %X, QID_KEY = %X, trace = %u", + o_vfrt_data->vfrtHeader.res_vdnId, VDN_PERCENT_KEY, + o_vfrt_data->vfrtHeader.rsvd_QAId, QID_KEY, + b_output_trace); + + if (b_output_trace) + { + strcpy(l_line_str, "VFRT:"); + sprintf(l_buffer_str, " %X Ver/Type %X VDN%% %3d VDD%% %3d QID %d", + revle16(o_vfrt_data->vfrtHeader.magic_number), + revle16(o_vfrt_data->vfrtHeader.type_version), + o_vfrt_data->vfrtHeader.res_vdnId, /// BUG: this should be VDN!!! + o_vfrt_data->vfrtHeader.VddId_QAId, /// BUG: this should be VDD!!! + o_vfrt_data->vfrtHeader.rsvd_QAId); /// BUG: this should be resvQID!!! + strcat(l_line_str, l_buffer_str); + } + + const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + + fapi2::ATTR_WOF_ENABLE_FRATIO_Type l_enable_fratio; + FAPI_ATTR_GET(fapi2::ATTR_WOF_ENABLE_FRATIO, + FAPI_SYSTEM, + l_enable_fratio); + + fapi2::ATTR_WOF_ENABLE_VRATIO_Type l_enable_vratio; + FAPI_ATTR_GET(fapi2::ATTR_WOF_ENABLE_VRATIO, + FAPI_SYSTEM, + l_enable_vratio); + + bool b_fratio_set = true; + bool b_first_vratio_set = true; + + // Get the frequency biases in place and check that they all match + double f_freq_bias = 0; + int freq_bias_value_hp = 0; + int freq_bias_value_m1_hp = 0; + bool b_bias_error = false; + for (auto v = 0; v < NUM_OP_POINTS; ++v) + { + freq_bias_value_hp = iv_bias[v].frequency_hp; + if (v > 0) + { + if (freq_bias_value_hp != freq_bias_value_m1_hp) + { + b_bias_error = true; + FAPI_DBG("FATAL Bias mismatch error: v = %d; freq_bias_value_hp = %d; freq_bias_value_m1_hp = %d", + v, freq_bias_value_hp, freq_bias_value_m1_hp ); + } + } + + freq_bias_value_m1_hp = freq_bias_value_hp; + + if (v == ULTRA) + { + f_freq_bias = calc_bias(freq_bias_value_hp); + } + } + + FAPI_ASSERT(!b_bias_error, + fapi2::PSTATE_PB_VFRT_BIAS_ERROR() + .set_CHIP_TARGET(iv_procChip) + .set_FREQ_BIAS_HP_ULTRATURBO(iv_bias[ULTRA].frequency_hp) + .set_FREQ_BIAS_HP_TURBO(iv_bias[TURBO].frequency_hp) + .set_FREQ_BIAS_HP_NOMINAL(iv_bias[NOMINAL].frequency_hp) + .set_FREQ_BIAS_HP_POWERSAVE(iv_bias[POWERSAVE].frequency_hp) + .set_UT_FREQ(iv_reference_frequency_khz), + "Frequency Biases do not match so VFRT biasing cannot occur"); + + if (f_freq_bias != 1) + FAPI_INF("A frequency bias multiplier of %f being applied to all VFRT entries", + f_freq_bias); + + //Initialize VFRT data part + for (l_index_0 = 0; l_index_0 < VFRT_FRATIO_SIZE; ++l_index_0) + { + strcpy(l_buffer_str, ""); + + for (l_index_1 = 0; l_index_1 < VFRT_VRATIO_SIZE; ++l_index_1) + { + // Offset MHz*1000 (khz) + step (khz) * sysvalue + float l_freq_raw_khz; + float l_freq_biased_khz; + l_freq_raw_khz = (float)(1000 * 1000 + (l_step_freq_khz * (*i_pBuffer))); + + l_freq_biased_khz = l_freq_raw_khz * f_freq_bias; + + // Round to nearest MHz as that is how the system tables are generated + float l_freq_raw_up_mhz = (l_freq_biased_khz + 500)/1000; + float l_freq_raw_dn_mhz = (l_freq_biased_khz)/1000; + float l_freq_rounded_khz; + if (l_freq_raw_up_mhz >= l_freq_raw_dn_mhz) + l_freq_rounded_khz = (uint32_t)(l_freq_raw_up_mhz * 1000); + else + l_freq_rounded_khz = (uint32_t)(l_freq_raw_dn_mhz * 1000); + + l_freq_khz = (uint32_t)(l_freq_rounded_khz); + + FAPI_DBG("freq_raw_khz = %f; freq_biased_khz = %f; freq_rounded = 0x%X (%d); sysvalue = 0x%X (%d)", + l_freq_raw_khz, + l_freq_biased_khz, + l_freq_khz, l_freq_khz, + *i_pBuffer, *i_pBuffer); + + // Translate to Pstate. The called function will clip to the + // legal range. The rc is only interesting if we care that + // the pstate was clipped; in this case, we don't. + freq2pState(l_freq_khz, &l_ps); + + o_vfrt_data->vfrt_data[l_index_0][l_index_1] = l_ps; + + if (b_first_vratio_set && l_index_1 >= 20 && b_output_trace) + { + sprintf(l_buffer_str, "[%2d][%2d] 0x%2X %4d; ", + l_index_0, l_index_1, + l_ps, l_freq_khz / 1000); + strcat(l_line_str, l_buffer_str); + } + + // Trace the last 8 values of the 24 for debug. As this is + // in a loop that is processing over 1000 tables, the last + // 8 gives a view that can correlate that the input data read + // is correct without overfilling the HB trace buffer. + if (l_index_1+1 == VFRT_VRATIO_SIZE && b_first_vratio_set && b_fratio_set && b_output_trace) + { + FAPI_INF("%s ", l_line_str); + strcpy(l_buffer_str, ""); + strcpy(l_line_str, " "); + b_first_vratio_set = false; + } + + i_pBuffer++; + } + + // If fratio is not enabled, don't trace the remaining, duplicate entries. + if (!l_enable_fratio) + { + b_fratio_set = false; + b_first_vratio_set = false; + } + else + { + b_fratio_set = true; + b_first_vratio_set = true; + } + + } + + // Flip the type from System (0) to HOMER (1) + l_type = 1; + o_vfrt_data->vfrtHeader.type_version |= l_type << 4; + +fapi_try_exit: + return fapi2::current_err; +} // end of update_vfrt + + +/////////////////////////////////////////////////////////// +//////// safe_mode_init +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::safe_mode_init( void ) +{ + FAPI_INF(">>>>>>>>>> safe_mode_init"); + uint8_t l_ps_pstate = 0; + Safe_mode_parameters l_safe_mode_values; + uint32_t l_ps_freq_khz = + iv_operating_points[VPD_PT_SET_BIASED][POWERSAVE].frequency_mhz * 1000; + + do + { + if (!iv_attrs.attr_pm_safe_voltage_mv && + !iv_attrs.attr_pm_safe_frequency_mhz) + { + freq2pState( l_ps_freq_khz, &l_ps_pstate); + + //Compute safe mode values + FAPI_TRY(safe_mode_computation ( + l_ps_pstate, + &l_safe_mode_values), + "Error from safe_mode_computation function"); + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ, + iv_procChip,iv_attrs.attr_pm_safe_frequency_mhz )); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_VOLTAGE_MV, + iv_procChip, iv_attrs.attr_pm_safe_voltage_mv)); + + } + }while(0); + +fapi_try_exit: + FAPI_INF("<<<<<<<<<< safe_mode_init"); + return fapi2::current_err; +} //end of safe_mode_init + + +/////////////////////////////////////////////////////////// +//////// vdm_init +/////////////////////////////////////////////////////////// +void PlatPmPPB::vdm_init( void ) +{ + FAPI_INF(">>>>>>>> vdm_init"); + do + { + uint8_t l_biased_pstate[NUM_OP_POINTS]; + memset(&iv_vid_point_set,0, sizeof(iv_vid_point_set)); + memset(iv_threshold_set,0,sizeof(iv_threshold_set)); + memset(&iv_PsVIDCompSlopes,0,sizeof(iv_PsVIDCompSlopes)); + memset(iv_PsVDMThreshSlopes,0,sizeof(iv_PsVDMThreshSlopes)); + memset(iv_jump_value_set,0,sizeof(iv_jump_value_set)); + memset(iv_PsVDMJumpSlopes,0,sizeof(iv_PsVDMJumpSlopes)); + + for (uint8_t i = 0; i < NUM_OP_POINTS; ++i) + { + l_biased_pstate[i] = iv_operating_points[VPD_PT_SET_BIASED][i].pstate; + FAPI_INF ("l_biased_pstate %d ", l_biased_pstate[i]); + } + + if (iv_attrs.attr_system_vdm_disable == fapi2::ENUM_ATTR_SYSTEM_VDM_DISABLE_OFF) + { + compute_vdm_threshold_pts(); + + // VID slope calculation + compute_PsVIDCompSlopes_slopes(l_biased_pstate); + + // VDM threshold slope calculation + compute_PsVDMThreshSlopes(l_biased_pstate); + + // VDM Jump slope calculation + compute_PsVDMJumpSlopes (l_biased_pstate); + + } + }while(0); + + FAPI_INF("<<<<<<<< vdm_init"); + +} //end of vdm_init + + +/////////////////////////////////////////////////////////// +//////// compute_PsVDMJumpSlopes +/////////////////////////////////////////////////////////// +void PlatPmPPB::compute_PsVDMJumpSlopes( + uint8_t* i_pstate) +{ + do + { + // ULTRA TURBO pstate check is not required..because its pstate will be + // 0 + if (!(i_pstate[POWERSAVE]) || + !(i_pstate[NOMINAL]) || + !(i_pstate[TURBO])) + { + FAPI_ERR("Non-UltraTurbo PSTATE value shouldn't be zero"); + break; + } + + //Calculate slopes + // + for(auto region(REGION_POWERSAVE_NOMINAL); region <= REGION_TURBO_ULTRA; ++region) + { + for (uint8_t i = 0; i < NUM_JUMP_VALUES; ++i) + { + iv_PsVDMJumpSlopes[region][i] = + revle16( + compute_slope_thresh(iv_jump_value_set[region+1][i], + iv_jump_value_set[region][i], + i_pstate[region], + i_pstate[region+1]) + ); + + FAPI_INF("PsVDMJumpSlopes %s %x N_S %d N_L %d L_S %d S_N %d", + prt_region_names[region], + revle16(iv_PsVDMJumpSlopes[region][i]), + iv_jump_value_set[region+1][i], + iv_jump_value_set[region][i], + i_pstate[region], + i_pstate[region+1]); + } + } + } + while(0); +} //end of compute_PsVDMJumpSlopes + + +/////////////////////////////////////////////////////////// +//////// compute_PsVDMThreshSlopes +/////////////////////////////////////////////////////////// +void PlatPmPPB::compute_PsVDMThreshSlopes( + uint8_t* i_pstate) +{ + do + { + // ULTRA TURBO pstate check is not required..because its pstate will be + // 0 + if (!(i_pstate[POWERSAVE]) || + !(i_pstate[NOMINAL]) || + !(i_pstate[TURBO])) + { + FAPI_ERR("Non-UltraTurbo PSTATE value shouldn't be zero"); + break; + } + + for(auto region(REGION_POWERSAVE_NOMINAL); region <= REGION_TURBO_ULTRA; ++region) + { + for (uint8_t i = 0; i < NUM_THRESHOLD_POINTS; ++i) + { + iv_PsVDMThreshSlopes[region][i] = + revle16( + compute_slope_thresh(iv_threshold_set[region+1][i], + iv_threshold_set[region][i], + i_pstate[region], + i_pstate[region+1]) + ); + + FAPI_INF("PsVDMThreshSlopes %s %x TH_N %d TH_P %d PS_P %d PS_N %d", + prt_region_names[region], + revle16(iv_PsVDMThreshSlopes[region][i]), + iv_threshold_set[region+1][i], + iv_threshold_set[region][i], + i_pstate[region], + i_pstate[region+1]); + } + } + } + while(0); +} //end of compute_PsVDMThreshSlopes + + +/////////////////////////////////////////////////////////// +//////// compute_PsVIDCompSlopes_slopes +/////////////////////////////////////////////////////////// +void PlatPmPPB::compute_PsVIDCompSlopes_slopes( + uint8_t* i_pstate) { + do + { + char const* region_names[] = { "REGION_POWERSAVE_NOMINAL", + "REGION_NOMINAL_TURBO", + "REGION_TURBO_ULTRA" + }; + + // ULTRA TURBO pstate check is not required..because its pstate will be + // 0 + if (!(i_pstate[POWERSAVE]) || + !(i_pstate[NOMINAL]) || + !(i_pstate[TURBO])) + { + FAPI_ERR("Non-UltraTurbo PSTATE value shouldn't be zero"); + break; + } + + for(auto region(REGION_POWERSAVE_NOMINAL); region <= REGION_TURBO_ULTRA; ++region) + { + iv_PsVIDCompSlopes[region] = + revle16( + compute_slope_4_12( iv_vid_point_set[region + 1], + iv_vid_point_set[region], + i_pstate[region], + i_pstate[region + 1]) + ); + + FAPI_DBG("PsVIDCompSlopes[%s] 0x%04x %d", region_names[region], + revle16(iv_PsVIDCompSlopes[region]), + revle16(iv_PsVIDCompSlopes[region])); + } + } + while(0); +} // end of compute_PsVIDCompSlopes_slopes + + +/////////////////////////////////////////////////////////// +//////// compute_vdm_threshold_pts +/////////////////////////////////////////////////////////// +void PlatPmPPB::compute_vdm_threshold_pts() +{ + int p = 0; + + //VID POINTS + for (p = 0; p < NUM_OP_POINTS; p++) + { + iv_vid_point_set[p] = iv_poundW_data.poundw[p].vdm_vid_compare_ivid; + FAPI_INF("Bi:VID=%x", iv_vid_point_set[p]); + } + + // Threshold points + for (p = 0; p < NUM_OP_POINTS; p++) + { + // overvolt threshold + iv_threshold_set[p][VDM_OVERVOLT_INDEX] = g_GreyCodeIndexMapping[(iv_poundW_data.poundw[p].vdm_overvolt_small_thresholds >> 4) & 0x0F]; + + FAPI_INF("Bi: OV TSHLD =%d", iv_threshold_set[p][0]); + // small threshold + iv_threshold_set[p][VDM_SMALL_INDEX] = (g_GreyCodeIndexMapping[iv_poundW_data.poundw[p].vdm_overvolt_small_thresholds & 0x0F]); + + FAPI_INF("Bi: SM TSHLD =%d", iv_threshold_set[p][1]); + // large threshold + iv_threshold_set[p][VDM_LARGE_INDEX] = (g_GreyCodeIndexMapping[(iv_poundW_data.poundw[p].vdm_large_extreme_thresholds >> 4) & 0x0F]); + + FAPI_INF("Bi: LG TSHLD =%d", iv_threshold_set[p][2]); + // extreme threshold + iv_threshold_set[p][VDM_XTREME_INDEX] = (g_GreyCodeIndexMapping[iv_poundW_data.poundw[p].vdm_large_extreme_thresholds & 0x0F]); + + FAPI_INF("Bi: EX TSHLD =%d", iv_threshold_set[p][3]); + + } + // Jump value points + for (p = 0; p < NUM_OP_POINTS; p++) + { + // N_L value + iv_jump_value_set[p][VDM_N_S_INDEX] = (iv_poundW_data.poundw[p].vdm_normal_freq_drop >> 4) & 0x0F; + + FAPI_INF("Bi: N_S =%d", iv_jump_value_set[p][0]); + // N_S value + iv_jump_value_set[p][VDM_N_L_INDEX] = iv_poundW_data.poundw[p].vdm_normal_freq_drop & 0x0F; + + FAPI_INF("Bi: N_L =%d", iv_jump_value_set[p][1]); + // L_S value + iv_jump_value_set[p][VDM_L_S_INDEX] = (iv_poundW_data.poundw[p].vdm_normal_freq_return >> 4) & 0x0F; + + FAPI_INF("Bi: L_S =%d", iv_jump_value_set[p][2]); + // S_L value + iv_jump_value_set[p][VDM_S_N_INDEX] = iv_poundW_data.poundw[p].vdm_normal_freq_return & 0x0F; + + FAPI_INF("Bi: S_L =%d", iv_jump_value_set[p][3]); + } +} //end of compute_vdm_threshold_pts + +/////////////////////////////////////////////////////////// +//////// ps2v_mv +/////////////////////////////////////////////////////////// +uint32_t PlatPmPPB::ps2v_mv(const Pstate i_pstate) +{ + + uint32_t region_start, region_end; + const char* pv_op_str[NUM_OP_POINTS] = PV_OP_ORDER_STR; + + FAPI_DBG("i_pstate = 0x%x, (%d)", i_pstate, i_pstate); + + // Determine the VPD region + if(i_pstate > iv_operating_points[VPD_PT_SET_BIASED_SYSP][NOMINAL].pstate) + { + region_start = POWERSAVE; + region_end = NOMINAL; + FAPI_DBG("Region POWERSAVE_NOMINAL detected"); + } + else if(i_pstate > iv_operating_points[VPD_PT_SET_BIASED_SYSP][TURBO].pstate) + { + region_start = NOMINAL; + region_end = TURBO; + FAPI_DBG("Region NOMINAL_TURBO detected"); + } + else + { + region_start = TURBO; + region_end = ULTRA; + FAPI_DBG("Region TURBO_ULTRA detected"); + } + + uint32_t l_SlopeValue = + compute_slope_4_12((iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_end].vdd_mv), + (iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_start].vdd_mv), + iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_start].pstate, + iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_end].pstate); + + FAPI_INF("l_globalppb.i_operating_points[%s].vdd_mv 0x%-3x (%d)", + pv_op_str[region_end], + (iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_end].vdd_mv), + (iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_end].vdd_mv)); + FAPI_INF("l_globalppb.i_operating_points[%s].vdd_mv 0x%-3x (%d)", + pv_op_str[region_start], + (iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_start].vdd_mv), + (iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_start].vdd_mv)); + FAPI_INF("l_globalppb.i_operating_points[%s].pstate 0x%-3x (%d)", + pv_op_str[region_end], + iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_end].pstate, + iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_end].pstate); + FAPI_INF("l_globalppb.i_operating_points[%s].pstate 0x%-3x (%d)", + pv_op_str[region_start], + iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_start].pstate, + iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_start].pstate); + + FAPI_INF ("l_SlopeValue %x",l_SlopeValue); + + + uint32_t x = (l_SlopeValue * (-i_pstate + iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_start].pstate)); + uint32_t y = x >> VID_SLOPE_FP_SHIFT_12; + + uint32_t l_vdd = + (((l_SlopeValue * (-i_pstate + iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_start].pstate)) >> VID_SLOPE_FP_SHIFT_12) + + (iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_start].vdd_mv)); + + // Round up + l_vdd = (l_vdd << 1) + 1; + l_vdd = l_vdd >> 1; + FAPI_DBG("i_pstate = %d " + "i_operating_points[%s].pstate) = %d " + "i_operating_points[%s].vdd_mv = %d " + "VID_SLOPE_FP_SHIFT_12 = %X " + "x = %x (%d) y = %x (%d)", + i_pstate, + pv_op_str[region_start], iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_start].pstate, + pv_op_str[region_start], (iv_operating_points[VPD_PT_SET_BIASED_SYSP][region_start].vdd_mv), + VID_SLOPE_FP_SHIFT_12, + x, x, + y, y); + + + FAPI_INF ("l_vdd 0x%x (%d)", l_vdd, l_vdd); + + return l_vdd; +} //end of ps2v_mv + + +/////////////////////////////////////////////////////////// +//////// safe_mode_computation +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::safe_mode_computation( + const Pstate i_ps_pstate, + Safe_mode_parameters *o_safe_mode_values) +{ + const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + Safe_mode_parameters l_safe_mode_values; + fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ_Type l_safe_mode_freq_mhz; + fapi2::ATTR_SAFE_MODE_VOLTAGE_MV_Type l_safe_mode_mv; + fapi2::ATTR_VDD_BOOT_VOLTAGE_Type l_boot_mv; + uint32_t l_safe_mode_op_ps2freq_mhz; + uint32_t l_core_floor_mhz; + uint32_t l_op_pt; + + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_CORE_FLOOR_MHZ, + FAPI_SYSTEM, + l_core_floor_mhz)); + + // Core floor frequency should be less than ultra turbo freq.. + // if not log an error + if ((l_core_floor_mhz*1000) > iv_reference_frequency_khz) + { + FAPI_ERR("Core floor frequency %08x is greater than UltraTurbo frequency %08x", + (l_core_floor_mhz*1000), iv_reference_frequency_khz); + FAPI_ASSERT(false, + fapi2::PSTATE_PB_CORE_FLOOR_FREQ_GT_UT_FREQ() + .set_CHIP_TARGET(iv_procChip) + .set_CORE_FLOOR_FREQ(l_core_floor_mhz*1000) + .set_UT_FREQ(iv_reference_frequency_khz), + "Core floor freqency is greater than UltraTurbo frequency"); + } + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ, + iv_procChip, l_safe_mode_freq_mhz)); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_VOLTAGE_MV, + iv_procChip, l_safe_mode_mv)); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDD_BOOT_VOLTAGE, + iv_procChip, l_boot_mv)); + + FAPI_DBG ("l_safe_mode_freq_mhz 0%08x (%d)", + l_safe_mode_freq_mhz, l_safe_mode_freq_mhz); + FAPI_DBG ("l_safe_mode_mv 0%08x (%d)", + l_safe_mode_mv, l_safe_mode_mv); + FAPI_DBG ("l_boot_mv 0%08x (%d)", + l_boot_mv, l_boot_mv); + + FAPI_INF ("core_floor_mhz 0%08x (%d)", + l_core_floor_mhz, + l_core_floor_mhz); + FAPI_INF("operating_point[POWERSAVE].frequency_mhz 0%08x (%d)", + (iv_operating_points[VPD_PT_SET_BIASED_SYSP][POWERSAVE].frequency_mhz), + (iv_operating_points[VPD_PT_SET_BIASED_SYSP][POWERSAVE].frequency_mhz)); + FAPI_INF ("reference_freq 0%08x (%d)", + iv_reference_frequency_khz, iv_reference_frequency_khz); + FAPI_INF ("step_frequency 0%08x (%d)", + iv_frequency_step_khz, iv_frequency_step_khz); + + l_op_pt = (iv_operating_points[VPD_PT_SET_BIASED_SYSP][POWERSAVE].frequency_mhz); + // Safe operational frequency is the MAX(core floor, VPD Powersave). + // PowerSave is the lowest operational frequency that the part was tested at + if (l_core_floor_mhz > l_op_pt) + { + FAPI_INF("Core floor greater that POWERSAVE"); + l_safe_mode_values.safe_op_freq_mhz = l_core_floor_mhz; + } + else + { + FAPI_INF("Core floor less than or equal to POWERSAVE"); + l_safe_mode_values.safe_op_freq_mhz = l_op_pt; + } + + FAPI_INF ("safe_mode_values.safe_op_freq_mhz 0%08x (%d)", + l_safe_mode_values.safe_op_freq_mhz, + l_safe_mode_values.safe_op_freq_mhz); + + // Calculate safe operational pstate. This must be rounded down to create + // a faster Pstate than the floor + l_safe_mode_values.safe_op_ps = ((float)(iv_reference_frequency_khz) - + (float)(l_safe_mode_values.safe_op_freq_mhz * 1000)) / + (float)iv_frequency_step_khz; + + l_safe_mode_op_ps2freq_mhz = (iv_reference_frequency_khz - + (l_safe_mode_values.safe_op_ps * iv_frequency_step_khz)) / 1000; + + while (l_safe_mode_op_ps2freq_mhz < l_safe_mode_values.safe_op_freq_mhz) + { + l_safe_mode_values.safe_op_ps--; + + l_safe_mode_op_ps2freq_mhz = + (iv_reference_frequency_khz - (l_safe_mode_values.safe_op_ps * iv_frequency_step_khz)) / 1000; + } + + // Calculate safe jump value for large frequency + l_safe_mode_values.safe_vdm_jump_value = + large_jump_interpolate(l_safe_mode_values.safe_op_ps, + i_ps_pstate); + FAPI_INF ("l_safe_mode_values.safe_vdm_jump_value %x -> %5.2f %%", + l_safe_mode_values.safe_vdm_jump_value, + ((float)l_safe_mode_values.safe_vdm_jump_value/32)*100); + + // Calculate safe mode frequency - Round up to nearest MHz + // The uplifted frequency is based on the fact that the DPLL percentage is a + // "down" value. Hence: + // X (uplifted safe) = Y (safe operating) / (1 - droop percentage) + l_safe_mode_values.safe_mode_freq_mhz = (uint32_t) + (((float)l_safe_mode_op_ps2freq_mhz * 1000 / + (1 - (float)l_safe_mode_values.safe_vdm_jump_value/32) + 500) / 1000); + + if (l_safe_mode_freq_mhz) + { + l_safe_mode_values.safe_mode_freq_mhz = l_safe_mode_freq_mhz; + FAPI_INF("Applying override safe mode freq value of %d MHz", + l_safe_mode_freq_mhz); + } + else + { + FAPI_INF("Setting safe mode frequency to %d MHz (0x%x) %x", + l_safe_mode_values.safe_mode_freq_mhz, + l_safe_mode_values.safe_mode_freq_mhz, iv_reference_frequency_khz); + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ, iv_procChip, l_safe_mode_values.safe_mode_freq_mhz)); + } + FAPI_INF ("l_safe_mode_values.safe_mode_freq_mhz 0x%0x (%d)", + l_safe_mode_values.safe_mode_freq_mhz, + l_safe_mode_values.safe_mode_freq_mhz); + + // Safe frequency must be less than ultra turbo freq. + // if not log an error + if ((l_safe_mode_values.safe_mode_freq_mhz*1000) > iv_reference_frequency_khz) + { + FAPI_ERR("Safe mode frequency %08x is greater than UltraTurbo frequency %08x", + (l_safe_mode_values.safe_mode_freq_mhz*1000), iv_reference_frequency_khz); + FAPI_ASSERT(false, + fapi2::PSTATE_PB_SAFE_FREQ_GT_UT_FREQ() + .set_CHIP_TARGET(iv_procChip) + .set_SAFE_FREQ(l_safe_mode_values.safe_mode_freq_mhz*1000) + .set_UT_FREQ(iv_reference_frequency_khz), + "Safe mode freqency is greater than UltraTurbo frequency"); + } + + l_safe_mode_values.safe_mode_ps = ((float)(iv_reference_frequency_khz) - + (float)(l_safe_mode_values.safe_mode_freq_mhz * 1000)) / + (float)iv_frequency_step_khz; + + FAPI_INF ("l_safe_mode_values.safe_mode_ps %x (%d)", + l_safe_mode_values.safe_mode_ps, + l_safe_mode_values.safe_mode_ps); + + // Calculate safe mode voltage + // Use the biased with system parms operating points + + l_safe_mode_values.safe_mode_mv = ps2v_mv(l_safe_mode_values.safe_mode_ps); + + if (l_safe_mode_mv) + { + l_safe_mode_values.safe_mode_mv = l_safe_mode_mv; + FAPI_INF("Applying override safe mode voltage value of %d mV", + l_safe_mode_mv); + } + else + { + FAPI_INF("Setting safe mode voltage to %d mv (0x%x)", + l_safe_mode_values.safe_mode_mv, + l_safe_mode_values.safe_mode_mv); + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SAFE_MODE_VOLTAGE_MV, + iv_procChip, + l_safe_mode_values.safe_mode_mv)); + } + + FAPI_INF ("l_safe_mode_values.safe_mode_mv 0x%x (%d)", + l_safe_mode_values.safe_mode_mv, + l_safe_mode_values.safe_mode_mv); + + fapi2::ATTR_SAFE_MODE_NOVDM_UPLIFT_MV_Type l_uplift_mv; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_NOVDM_UPLIFT_MV, iv_procChip, l_uplift_mv)); + + // Calculate boot mode voltage + l_safe_mode_values.boot_mode_mv = l_safe_mode_values.safe_mode_mv + l_uplift_mv; + + if (!iv_attrs.vdd_voltage_mv) + { + iv_attrs.vdd_voltage_mv = l_safe_mode_values.boot_mode_mv; + } + + FAPI_INF("l_safe_mode_values.boot_mode_mv 0x%x (%d)", + l_safe_mode_values.boot_mode_mv, + l_safe_mode_values.boot_mode_mv); + + memcpy (o_safe_mode_values,&l_safe_mode_values, sizeof(Safe_mode_parameters)); + +fapi_try_exit: + return fapi2::current_err; +} // end of safe_mode_computation + + +/////////////////////////////////////////////////////////// +//////// attr_init +/////////////////////////////////////////////////////////// +void PlatPmPPB::attr_init( void ) +{ const uint32_t EXT_VRM_TRANSITION_START_NS = 8000; const uint32_t EXT_VRM_TRANSITION_RATE_INC_UV_PER_US = 10000; const uint32_t EXT_VRM_TRANSITION_RATE_DEC_UV_PER_US = 10000; @@ -1284,144 +1991,144 @@ proc_get_attributes ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_targe // -------------------------- // attributes not yet defined // -------------------------- - io_attr->attr_dpll_bias = 0; - io_attr->attr_undervolting = 0; + iv_attrs.attr_dpll_bias = 0; + iv_attrs.attr_undervolting = 0; + // --------------------------------------------------------------- // set ATTR_PROC_DPLL_DIVIDER // --------------------------------------------------------------- - - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_DPLL_DIVIDER, i_target, - io_attr->attr_proc_dpll_divider), "fapiGetAttribute of ATTR_PROC_DPLL_DIVIDER failed"); - FAPI_DBG("ATTR_PROC_DPLL_DIVIDER - get to %x", io_attr->attr_proc_dpll_divider); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_DPLL_DIVIDER, iv_procChip, + iv_attrs.attr_proc_dpll_divider), "fapiGetAttribute of ATTR_PROC_DPLL_DIVIDER failed"); // If value is 0, set a default - if (!io_attr->attr_proc_dpll_divider) + if (!iv_attrs.attr_proc_dpll_divider) { - FAPI_DBG("ATTR_PROC_DPLL_DIVIDER - setting default to %x", io_attr->attr_proc_dpll_divider); - io_attr->attr_proc_dpll_divider = 8; - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PROC_DPLL_DIVIDER, i_target, - io_attr->attr_proc_dpll_divider), "fapiSetAttribute of ATTR_PROC_DPLL_DIVIDER failed"); + FAPI_DBG("ATTR_PROC_DPLL_DIVIDER - setting default to %x", iv_attrs.attr_proc_dpll_divider); + iv_attrs.attr_proc_dpll_divider = 8; + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PROC_DPLL_DIVIDER, iv_procChip, + iv_attrs.attr_proc_dpll_divider), "fapiSetAttribute of ATTR_PROC_DPLL_DIVIDER failed"); } - FAPI_INF("ATTR_PROC_DPLL_DIVIDER - %x", io_attr->attr_proc_dpll_divider); + FAPI_INF("ATTR_PROC_DPLL_DIVIDER - %x", iv_attrs.attr_proc_dpll_divider); // ---------------------------- // attributes currently defined // ---------------------------- #define DATABLOCK_GET_ATTR(attr_name, target, attr_assign) \ -FAPI_TRY(FAPI_ATTR_GET(fapi2::attr_name, target, io_attr->attr_assign),"Attribute read failed"); \ -FAPI_INF("%-60s = 0x%08x %d", #attr_name, io_attr->attr_assign, io_attr->attr_assign); +FAPI_TRY(FAPI_ATTR_GET(fapi2::attr_name, target, iv_attrs.attr_assign),"Attribute read failed"); \ +FAPI_INF("%-60s = 0x%08x %d", #attr_name, iv_attrs.attr_assign, iv_attrs.attr_assign); + // Frequency Bias attributes - DATABLOCK_GET_ATTR(ATTR_FREQ_BIAS_ULTRATURBO, i_target, attr_freq_bias_ultraturbo); - DATABLOCK_GET_ATTR(ATTR_FREQ_BIAS_TURBO, i_target, attr_freq_bias_turbo); - DATABLOCK_GET_ATTR(ATTR_FREQ_BIAS_NOMINAL, i_target, attr_freq_bias_nominal); - DATABLOCK_GET_ATTR(ATTR_FREQ_BIAS_POWERSAVE, i_target, attr_freq_bias_powersave); + DATABLOCK_GET_ATTR(ATTR_FREQ_BIAS_ULTRATURBO, iv_procChip, attr_freq_bias_ultraturbo); + DATABLOCK_GET_ATTR(ATTR_FREQ_BIAS_TURBO, iv_procChip, attr_freq_bias_turbo); + DATABLOCK_GET_ATTR(ATTR_FREQ_BIAS_NOMINAL, iv_procChip, attr_freq_bias_nominal); + DATABLOCK_GET_ATTR(ATTR_FREQ_BIAS_POWERSAVE, iv_procChip, attr_freq_bias_powersave); // Voltage Bias attributes - DATABLOCK_GET_ATTR(ATTR_VOLTAGE_EXT_VDD_BIAS_ULTRATURBO, i_target, attr_voltage_ext_vdd_bias_ultraturbo); - DATABLOCK_GET_ATTR(ATTR_VOLTAGE_EXT_VDD_BIAS_TURBO, i_target, attr_voltage_ext_vdd_bias_turbo); - DATABLOCK_GET_ATTR(ATTR_VOLTAGE_EXT_VDD_BIAS_NOMINAL, i_target, attr_voltage_ext_vdd_bias_nominal); - DATABLOCK_GET_ATTR(ATTR_VOLTAGE_EXT_VDD_BIAS_POWERSAVE, i_target, attr_voltage_ext_vdd_bias_powersave); - DATABLOCK_GET_ATTR(ATTR_VOLTAGE_EXT_VCS_BIAS, i_target, attr_voltage_ext_vcs_bias); - DATABLOCK_GET_ATTR(ATTR_VOLTAGE_EXT_VDN_BIAS, i_target, attr_voltage_ext_vdn_bias); - - DATABLOCK_GET_ATTR(ATTR_VOLTAGE_INT_VDD_BIAS_ULTRATURBO, i_target, attr_voltage_int_vdd_bias_ultraturbo); - DATABLOCK_GET_ATTR(ATTR_VOLTAGE_INT_VDD_BIAS_TURBO, i_target, attr_voltage_int_vdd_bias_turbo); - DATABLOCK_GET_ATTR(ATTR_VOLTAGE_INT_VDD_BIAS_NOMINAL, i_target, attr_voltage_int_vdd_bias_nominal); - DATABLOCK_GET_ATTR(ATTR_VOLTAGE_INT_VDD_BIAS_POWERSAVE, i_target, attr_voltage_int_vdd_bias_powersave); + DATABLOCK_GET_ATTR(ATTR_VOLTAGE_EXT_VDD_BIAS_ULTRATURBO, iv_procChip, attr_voltage_ext_vdd_bias_ultraturbo); + DATABLOCK_GET_ATTR(ATTR_VOLTAGE_EXT_VDD_BIAS_TURBO, iv_procChip, attr_voltage_ext_vdd_bias_turbo); + DATABLOCK_GET_ATTR(ATTR_VOLTAGE_EXT_VDD_BIAS_NOMINAL, iv_procChip, attr_voltage_ext_vdd_bias_nominal); + DATABLOCK_GET_ATTR(ATTR_VOLTAGE_EXT_VDD_BIAS_POWERSAVE, iv_procChip, attr_voltage_ext_vdd_bias_powersave); + DATABLOCK_GET_ATTR(ATTR_VOLTAGE_EXT_VCS_BIAS, iv_procChip, attr_voltage_ext_vcs_bias); + DATABLOCK_GET_ATTR(ATTR_VOLTAGE_EXT_VDN_BIAS, iv_procChip, attr_voltage_ext_vdn_bias); + + DATABLOCK_GET_ATTR(ATTR_VOLTAGE_INT_VDD_BIAS_ULTRATURBO, iv_procChip, attr_voltage_int_vdd_bias_ultraturbo); + DATABLOCK_GET_ATTR(ATTR_VOLTAGE_INT_VDD_BIAS_TURBO, iv_procChip, attr_voltage_int_vdd_bias_turbo); + DATABLOCK_GET_ATTR(ATTR_VOLTAGE_INT_VDD_BIAS_NOMINAL, iv_procChip, attr_voltage_int_vdd_bias_nominal); + DATABLOCK_GET_ATTR(ATTR_VOLTAGE_INT_VDD_BIAS_POWERSAVE, iv_procChip, attr_voltage_int_vdd_bias_powersave); // Frequency attributes DATABLOCK_GET_ATTR(ATTR_FREQ_PROC_REFCLOCK_KHZ, FAPI_SYSTEM, attr_freq_proc_refclock_khz); - DATABLOCK_GET_ATTR(ATTR_FREQ_PB_MHZ, FAPI_SYSTEM, attr_nest_frequency_mhz); - DATABLOCK_GET_ATTR(ATTR_FREQ_CORE_CEILING_MHZ, FAPI_SYSTEM, attr_freq_core_ceiling_mhz); - DATABLOCK_GET_ATTR(ATTR_SAFE_MODE_FREQUENCY_MHZ, i_target, attr_pm_safe_frequency_mhz); - DATABLOCK_GET_ATTR(ATTR_SAFE_MODE_VOLTAGE_MV, i_target, attr_pm_safe_voltage_mv); - DATABLOCK_GET_ATTR(ATTR_FREQ_CORE_FLOOR_MHZ, FAPI_SYSTEM, attr_freq_core_floor_mhz); + DATABLOCK_GET_ATTR(ATTR_FREQ_PB_MHZ, FAPI_SYSTEM, attr_nest_frequency_mhz); + DATABLOCK_GET_ATTR(ATTR_FREQ_CORE_CEILING_MHZ, FAPI_SYSTEM, attr_freq_core_ceiling_mhz); + DATABLOCK_GET_ATTR(ATTR_SAFE_MODE_FREQUENCY_MHZ,iv_procChip, attr_pm_safe_frequency_mhz); + DATABLOCK_GET_ATTR(ATTR_SAFE_MODE_VOLTAGE_MV, iv_procChip, attr_pm_safe_voltage_mv); + DATABLOCK_GET_ATTR(ATTR_FREQ_CORE_FLOOR_MHZ, FAPI_SYSTEM, attr_freq_core_floor_mhz); // Loadline, Distribution loss and Distribution offset attributes - DATABLOCK_GET_ATTR(ATTR_PROC_R_LOADLINE_VDD_UOHM, i_target, attr_proc_r_loadline_vdd_uohm); - DATABLOCK_GET_ATTR(ATTR_PROC_R_DISTLOSS_VDD_UOHM, i_target, attr_proc_r_distloss_vdd_uohm); - DATABLOCK_GET_ATTR(ATTR_PROC_VRM_VOFFSET_VDD_UV, i_target, attr_proc_vrm_voffset_vdd_uv); - DATABLOCK_GET_ATTR(ATTR_PROC_R_LOADLINE_VDN_UOHM, i_target, attr_proc_r_loadline_vdn_uohm); - DATABLOCK_GET_ATTR(ATTR_PROC_R_DISTLOSS_VDN_UOHM, i_target, attr_proc_r_distloss_vdn_uohm); - DATABLOCK_GET_ATTR(ATTR_PROC_VRM_VOFFSET_VDN_UV, i_target, attr_proc_vrm_voffset_vdn_uv); - DATABLOCK_GET_ATTR(ATTR_PROC_R_LOADLINE_VCS_UOHM, i_target, attr_proc_r_loadline_vcs_uohm); - DATABLOCK_GET_ATTR(ATTR_PROC_R_DISTLOSS_VCS_UOHM, i_target, attr_proc_r_distloss_vcs_uohm); - DATABLOCK_GET_ATTR(ATTR_PROC_VRM_VOFFSET_VCS_UV, i_target, attr_proc_vrm_voffset_vcs_uv); + DATABLOCK_GET_ATTR(ATTR_PROC_R_LOADLINE_VDD_UOHM, iv_procChip, attr_proc_r_loadline_vdd_uohm); + DATABLOCK_GET_ATTR(ATTR_PROC_R_DISTLOSS_VDD_UOHM, iv_procChip, attr_proc_r_distloss_vdd_uohm); + DATABLOCK_GET_ATTR(ATTR_PROC_VRM_VOFFSET_VDD_UV, iv_procChip, attr_proc_vrm_voffset_vdd_uv); + DATABLOCK_GET_ATTR(ATTR_PROC_R_LOADLINE_VDN_UOHM, iv_procChip, attr_proc_r_loadline_vdn_uohm); + DATABLOCK_GET_ATTR(ATTR_PROC_R_DISTLOSS_VDN_UOHM, iv_procChip, attr_proc_r_distloss_vdn_uohm); + DATABLOCK_GET_ATTR(ATTR_PROC_VRM_VOFFSET_VDN_UV, iv_procChip, attr_proc_vrm_voffset_vdn_uv); + DATABLOCK_GET_ATTR(ATTR_PROC_R_LOADLINE_VCS_UOHM, iv_procChip, attr_proc_r_loadline_vcs_uohm); + DATABLOCK_GET_ATTR(ATTR_PROC_R_DISTLOSS_VCS_UOHM, iv_procChip, attr_proc_r_distloss_vcs_uohm); + DATABLOCK_GET_ATTR(ATTR_PROC_VRM_VOFFSET_VCS_UV, iv_procChip, attr_proc_vrm_voffset_vcs_uv); // Read IVRM,WOF and DPLL attributes - DATABLOCK_GET_ATTR(ATTR_SYSTEM_IVRM_DISABLE, FAPI_SYSTEM, attr_system_ivrm_disable); - DATABLOCK_GET_ATTR(ATTR_SYSTEM_WOF_DISABLE, FAPI_SYSTEM, attr_system_wof_disable); - DATABLOCK_GET_ATTR(ATTR_SYSTEM_VDM_DISABLE, FAPI_SYSTEM, attr_system_vdm_disable); - DATABLOCK_GET_ATTR(ATTR_DPLL_VDM_RESPONSE, FAPI_SYSTEM, attr_dpll_vdm_response); + DATABLOCK_GET_ATTR(ATTR_SYSTEM_IVRM_DISABLE, FAPI_SYSTEM, attr_system_ivrm_disable); + DATABLOCK_GET_ATTR(ATTR_SYSTEM_WOF_DISABLE, FAPI_SYSTEM, attr_system_wof_disable); + DATABLOCK_GET_ATTR(ATTR_SYSTEM_VDM_DISABLE, FAPI_SYSTEM, attr_system_vdm_disable); + DATABLOCK_GET_ATTR(ATTR_DPLL_VDM_RESPONSE, FAPI_SYSTEM, attr_dpll_vdm_response); DATABLOCK_GET_ATTR(ATTR_SYSTEM_RESCLK_DISABLE, FAPI_SYSTEM, attr_resclk_disable); - DATABLOCK_GET_ATTR(ATTR_CHIP_EC_FEATURE_WOF_NOT_SUPPORTED, i_target, attr_dd_wof_not_supported); - DATABLOCK_GET_ATTR(ATTR_CHIP_EC_FEATURE_VDM_NOT_SUPPORTED, i_target, attr_dd_vdm_not_supported); - DATABLOCK_GET_ATTR(ATTR_SYSTEM_PSTATES_MODE, FAPI_SYSTEM, attr_pstate_mode); + DATABLOCK_GET_ATTR(ATTR_SYSTEM_PSTATES_MODE, FAPI_SYSTEM, attr_pstate_mode); - DATABLOCK_GET_ATTR(ATTR_TDP_RDP_CURRENT_FACTOR, i_target, attr_tdp_rdp_current_factor); + DATABLOCK_GET_ATTR(ATTR_CHIP_EC_FEATURE_WOF_NOT_SUPPORTED, iv_procChip, attr_dd_wof_not_supported); + DATABLOCK_GET_ATTR(ATTR_CHIP_EC_FEATURE_VDM_NOT_SUPPORTED, iv_procChip, attr_dd_vdm_not_supported); + DATABLOCK_GET_ATTR(ATTR_TDP_RDP_CURRENT_FACTOR, iv_procChip, attr_tdp_rdp_current_factor); - DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_START_NS, FAPI_SYSTEM, - attr_ext_vrm_transition_start_ns); - DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_RATE_INC_UV_PER_US, FAPI_SYSTEM, - attr_ext_vrm_transition_rate_inc_uv_per_us); - DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_RATE_DEC_UV_PER_US, FAPI_SYSTEM, - attr_ext_vrm_transition_rate_dec_uv_per_us); - DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_STABILIZATION_TIME_NS, FAPI_SYSTEM, - attr_ext_vrm_stabilization_time_us); + DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_START_NS, + FAPI_SYSTEM, attr_ext_vrm_transition_start_ns); + DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_RATE_INC_UV_PER_US, + FAPI_SYSTEM, attr_ext_vrm_transition_rate_inc_uv_per_us); + DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_RATE_DEC_UV_PER_US, + FAPI_SYSTEM, attr_ext_vrm_transition_rate_dec_uv_per_us); + DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_TRANSITION_STABILIZATION_TIME_NS, + FAPI_SYSTEM, attr_ext_vrm_stabilization_time_us); DATABLOCK_GET_ATTR(ATTR_EXTERNAL_VRM_STEPSIZE, FAPI_SYSTEM, attr_ext_vrm_step_size_mv); - - DATABLOCK_GET_ATTR(ATTR_NEST_LEAKAGE_PERCENT, FAPI_SYSTEM, attr_nest_leakage_percent); + DATABLOCK_GET_ATTR(ATTR_NEST_LEAKAGE_PERCENT, FAPI_SYSTEM, attr_nest_leakage_percent); // AVSBus ... needed by p9_setup_evid - DATABLOCK_GET_ATTR(ATTR_VDD_AVSBUS_BUSNUM, i_target,vdd_bus_num); - DATABLOCK_GET_ATTR(ATTR_VDD_AVSBUS_RAIL, i_target,vdd_rail_select); - DATABLOCK_GET_ATTR(ATTR_VDN_AVSBUS_BUSNUM, i_target,vdn_bus_num); - DATABLOCK_GET_ATTR(ATTR_VDN_AVSBUS_RAIL, i_target,vdn_rail_select); - DATABLOCK_GET_ATTR(ATTR_VCS_AVSBUS_BUSNUM, i_target,vcs_bus_num); - DATABLOCK_GET_ATTR(ATTR_VCS_AVSBUS_RAIL, i_target,vcs_rail_select); - DATABLOCK_GET_ATTR(ATTR_VCS_BOOT_VOLTAGE, i_target,vcs_voltage_mv); - DATABLOCK_GET_ATTR(ATTR_VDD_BOOT_VOLTAGE, i_target,vdd_voltage_mv); - DATABLOCK_GET_ATTR(ATTR_VDN_BOOT_VOLTAGE, i_target,vdn_voltage_mv); - - DATABLOCK_GET_ATTR(ATTR_PROC_R_LOADLINE_VDD_UOHM, i_target,r_loadline_vdd_uohm); - DATABLOCK_GET_ATTR(ATTR_PROC_R_DISTLOSS_VDD_UOHM, i_target,r_distloss_vdd_uohm); - DATABLOCK_GET_ATTR(ATTR_PROC_VRM_VOFFSET_VDD_UV, i_target,vrm_voffset_vdd_uv ); - DATABLOCK_GET_ATTR(ATTR_PROC_R_LOADLINE_VDN_UOHM, i_target,r_loadline_vdn_uohm); - DATABLOCK_GET_ATTR(ATTR_PROC_R_DISTLOSS_VDN_UOHM, i_target,r_distloss_vdn_uohm); - DATABLOCK_GET_ATTR(ATTR_PROC_VRM_VOFFSET_VDN_UV, i_target,vrm_voffset_vdn_uv ); - DATABLOCK_GET_ATTR(ATTR_PROC_R_LOADLINE_VCS_UOHM, i_target,r_loadline_vcs_uohm); - DATABLOCK_GET_ATTR(ATTR_PROC_R_DISTLOSS_VCS_UOHM, i_target,r_distloss_vcs_uohm); - DATABLOCK_GET_ATTR(ATTR_PROC_VRM_VOFFSET_VCS_UV, i_target,vrm_voffset_vcs_uv); - DATABLOCK_GET_ATTR(ATTR_FREQ_PROC_REFCLOCK_KHZ, FAPI_SYSTEM, freq_proc_refclock_khz); - DATABLOCK_GET_ATTR(ATTR_PROC_DPLL_DIVIDER, i_target, proc_dpll_divider); + DATABLOCK_GET_ATTR(ATTR_VDD_AVSBUS_BUSNUM, iv_procChip, vdd_bus_num); + DATABLOCK_GET_ATTR(ATTR_VDD_AVSBUS_RAIL, iv_procChip, vdd_rail_select); + DATABLOCK_GET_ATTR(ATTR_VDN_AVSBUS_BUSNUM, iv_procChip, vdn_bus_num); + DATABLOCK_GET_ATTR(ATTR_VDN_AVSBUS_RAIL, iv_procChip, vdn_rail_select); + DATABLOCK_GET_ATTR(ATTR_VCS_AVSBUS_BUSNUM, iv_procChip, vcs_bus_num); + DATABLOCK_GET_ATTR(ATTR_VCS_AVSBUS_RAIL, iv_procChip, vcs_rail_select); + DATABLOCK_GET_ATTR(ATTR_VCS_BOOT_VOLTAGE, iv_procChip, vcs_voltage_mv); + DATABLOCK_GET_ATTR(ATTR_VDD_BOOT_VOLTAGE, iv_procChip, vdd_voltage_mv); + DATABLOCK_GET_ATTR(ATTR_VDN_BOOT_VOLTAGE, iv_procChip, vdn_voltage_mv); + + DATABLOCK_GET_ATTR(ATTR_PROC_R_LOADLINE_VDD_UOHM, iv_procChip, r_loadline_vdd_uohm); + DATABLOCK_GET_ATTR(ATTR_PROC_R_DISTLOSS_VDD_UOHM, iv_procChip, r_distloss_vdd_uohm); + DATABLOCK_GET_ATTR(ATTR_PROC_VRM_VOFFSET_VDD_UV, iv_procChip, vrm_voffset_vdd_uv ); + DATABLOCK_GET_ATTR(ATTR_PROC_R_LOADLINE_VDN_UOHM, iv_procChip, r_loadline_vdn_uohm); + DATABLOCK_GET_ATTR(ATTR_PROC_R_DISTLOSS_VDN_UOHM, iv_procChip, r_distloss_vdn_uohm); + DATABLOCK_GET_ATTR(ATTR_PROC_VRM_VOFFSET_VDN_UV, iv_procChip, vrm_voffset_vdn_uv ); + DATABLOCK_GET_ATTR(ATTR_PROC_R_LOADLINE_VCS_UOHM, iv_procChip, r_loadline_vcs_uohm); + DATABLOCK_GET_ATTR(ATTR_PROC_R_DISTLOSS_VCS_UOHM, iv_procChip, r_distloss_vcs_uohm); + DATABLOCK_GET_ATTR(ATTR_PROC_VRM_VOFFSET_VCS_UV, iv_procChip, vrm_voffset_vcs_uv); + DATABLOCK_GET_ATTR(ATTR_FREQ_PROC_REFCLOCK_KHZ, FAPI_SYSTEM, freq_proc_refclock_khz); + DATABLOCK_GET_ATTR(ATTR_PROC_DPLL_DIVIDER, iv_procChip, proc_dpll_divider); // AVSBus ... needed by p9_setup_evid - //Get WOV attributes DATABLOCK_GET_ATTR(ATTR_SYSTEM_WOV_OVERV_DISABLE, FAPI_SYSTEM,attr_wov_overv_enable); DATABLOCK_GET_ATTR(ATTR_SYSTEM_WOV_UNDERV_DISABLE, FAPI_SYSTEM,attr_wov_underv_enable); - DATABLOCK_GET_ATTR(ATTR_WOV_UNDERV_FORCE, i_target,attr_wov_underv_force); - DATABLOCK_GET_ATTR(ATTR_WOV_SAMPLE_125US, i_target,attr_wov_sample_125us); - DATABLOCK_GET_ATTR(ATTR_WOV_MAX_DROOP_10THPCT, i_target,attr_wov_max_droop_pct); - DATABLOCK_GET_ATTR(ATTR_WOV_UNDERV_PERF_LOSS_THRESH_10THPCT,i_target,attr_wov_underv_perf_loss_thresh_pct); - DATABLOCK_GET_ATTR(ATTR_WOV_UNDERV_STEP_INCR_10THPCT, i_target,attr_wov_underv_step_incr_pct); - DATABLOCK_GET_ATTR(ATTR_WOV_UNDERV_STEP_DECR_10THPCT, i_target,attr_wov_underv_step_decr_pct); - DATABLOCK_GET_ATTR(ATTR_WOV_UNDERV_MAX_10THPCT, i_target,attr_wov_underv_max_pct); - DATABLOCK_GET_ATTR(ATTR_WOV_UNDERV_VMIN_MV, i_target,attr_wov_underv_vmin_mv); - DATABLOCK_GET_ATTR(ATTR_WOV_OVERV_VMAX_SETPOINT_MV, i_target,attr_wov_overv_vmax_mv); - DATABLOCK_GET_ATTR(ATTR_WOV_OVERV_STEP_INCR_10THPCT, i_target,attr_wov_overv_step_incr_pct); - DATABLOCK_GET_ATTR(ATTR_WOV_OVERV_STEP_DECR_10THPCT, i_target,attr_wov_overv_step_decr_pct); - DATABLOCK_GET_ATTR(ATTR_WOV_OVERV_MAX_10THPCT, i_target,attr_wov_overv_max_pct); + DATABLOCK_GET_ATTR(ATTR_WOV_UNDERV_FORCE, iv_procChip,attr_wov_underv_force); + DATABLOCK_GET_ATTR(ATTR_WOV_SAMPLE_125US, iv_procChip,attr_wov_sample_125us); + DATABLOCK_GET_ATTR(ATTR_WOV_MAX_DROOP_10THPCT, iv_procChip,attr_wov_max_droop_pct); + DATABLOCK_GET_ATTR(ATTR_WOV_UNDERV_PERF_LOSS_THRESH_10THPCT, iv_procChip,attr_wov_underv_perf_loss_thresh_pct); + DATABLOCK_GET_ATTR(ATTR_WOV_UNDERV_STEP_INCR_10THPCT, iv_procChip,attr_wov_underv_step_incr_pct); + DATABLOCK_GET_ATTR(ATTR_WOV_UNDERV_STEP_DECR_10THPCT, iv_procChip,attr_wov_underv_step_decr_pct); + DATABLOCK_GET_ATTR(ATTR_WOV_UNDERV_MAX_10THPCT, iv_procChip,attr_wov_underv_max_pct); + DATABLOCK_GET_ATTR(ATTR_WOV_UNDERV_VMIN_MV, iv_procChip,attr_wov_underv_vmin_mv); + DATABLOCK_GET_ATTR(ATTR_WOV_OVERV_VMAX_SETPOINT_MV, iv_procChip,attr_wov_overv_vmax_mv); + DATABLOCK_GET_ATTR(ATTR_WOV_OVERV_STEP_INCR_10THPCT, iv_procChip,attr_wov_overv_step_incr_pct); + DATABLOCK_GET_ATTR(ATTR_WOV_OVERV_STEP_DECR_10THPCT, iv_procChip,attr_wov_overv_step_decr_pct); + DATABLOCK_GET_ATTR(ATTR_WOV_OVERV_MAX_10THPCT, iv_procChip,attr_wov_overv_max_pct); + + // Deal with defaults if attributes are not set #define SET_DEFAULT(_attr_name, _attr_default) \ - if (!(io_attr->_attr_name)) \ + if (!(iv_attrs._attr_name)) \ { \ - io_attr->_attr_name = _attr_default; \ + iv_attrs._attr_name = _attr_default; \ FAPI_INF("Setting %-44s = 0x%08x %d (internal default)", \ - #_attr_name, io_attr->_attr_name, io_attr->_attr_name); \ + #_attr_name, iv_attrs._attr_name, iv_attrs._attr_name); \ } SET_DEFAULT(attr_freq_proc_refclock_khz, 133333); @@ -1432,6 +2139,7 @@ FAPI_INF("%-60s = 0x%08x %d", #attr_name, io_attr->attr_assign, io_attr->attr_as SET_DEFAULT(attr_ext_vrm_stabilization_time_us, EXT_VRM_STABILIZATION_TIME_NS) SET_DEFAULT(attr_ext_vrm_step_size_mv, EXT_VRM_STEPSIZE_MV) + SET_DEFAULT(attr_wov_sample_125us, 2); SET_DEFAULT(attr_wov_max_droop_pct, 125); SET_DEFAULT(attr_wov_overv_step_incr_pct, 5); @@ -1445,452 +2153,637 @@ FAPI_INF("%-60s = 0x%08x %d", #attr_name, io_attr->attr_assign, io_attr->attr_as //Ensure that the ranges for WOV attributes are honored - if (io_attr->attr_wov_sample_125us < 2) { - io_attr->attr_wov_sample_125us = 2; + if (iv_attrs.attr_wov_sample_125us < 2) { + iv_attrs.attr_wov_sample_125us = 2; } - if(io_attr->attr_wov_overv_step_incr_pct > 20) { - io_attr->attr_wov_overv_step_incr_pct = 20; + if(iv_attrs.attr_wov_overv_step_incr_pct > 20) { + iv_attrs.attr_wov_overv_step_incr_pct = 20; } - if(io_attr->attr_wov_overv_step_decr_pct > 20) { - io_attr->attr_wov_overv_step_decr_pct = 20; + if(iv_attrs.attr_wov_overv_step_decr_pct > 20) { + iv_attrs.attr_wov_overv_step_decr_pct = 20; } - if(io_attr->attr_wov_overv_max_pct > 100) { - io_attr->attr_wov_overv_max_pct = 100; + if(iv_attrs.attr_wov_overv_max_pct > 100) { + iv_attrs.attr_wov_overv_max_pct = 100; } - if(io_attr->attr_wov_underv_step_incr_pct > 20) { - io_attr->attr_wov_underv_step_incr_pct = 20; + if(iv_attrs.attr_wov_underv_step_incr_pct > 20) { + iv_attrs.attr_wov_underv_step_incr_pct = 20; } - if(io_attr->attr_wov_underv_step_decr_pct > 20) { - io_attr->attr_wov_underv_step_decr_pct = 20; + if(iv_attrs.attr_wov_underv_step_decr_pct > 20) { + iv_attrs.attr_wov_underv_step_decr_pct = 20; } - if(io_attr->attr_wov_underv_max_pct < 10) { - io_attr->attr_wov_underv_step_decr_pct = 10; + if(iv_attrs.attr_wov_underv_max_pct < 10) { + iv_attrs.attr_wov_underv_step_decr_pct = 10; } - if (io_attr->attr_wov_underv_perf_loss_thresh_pct > 20) { - io_attr->attr_wov_underv_perf_loss_thresh_pct = 20; + if (iv_attrs.attr_wov_underv_perf_loss_thresh_pct > 20) { + iv_attrs.attr_wov_underv_perf_loss_thresh_pct = 20; } - // Deal with critical attributes that are not set and that any defaults chosen + // Deal with crital attributes that are not set and that any defaults chosen // could well be very wrong - FAPI_ASSERT(io_attr->attr_nest_frequency_mhz, + FAPI_ASSERT(iv_attrs.attr_nest_frequency_mhz, fapi2::PSTATE_PB_NEST_FREQ_EQ_ZERO() - .set_CHIP_TARGET(i_target), + .set_CHIP_TARGET(iv_procChip), "ATTR_FREQ_PB_MHZ has a zero value"); -fapi_try_exit: - return fapi2::current_err; + // ----------------------------------------------- + // System power distribution parameters + // ----------------------------------------------- + // VDD rail + iv_vdd_sysparam.loadline_uohm = revle32(iv_attrs.attr_proc_r_loadline_vdd_uohm); + iv_vdd_sysparam.distloss_uohm = revle32(iv_attrs.attr_proc_r_distloss_vdd_uohm); + iv_vdd_sysparam.distoffset_uv = revle32(iv_attrs.attr_proc_vrm_voffset_vdd_uv); -} -/// END OF GET ATTRIBUTES function + // VCS rail + iv_vcs_sysparam.loadline_uohm = revle32(iv_attrs.attr_proc_r_loadline_vcs_uohm); + iv_vcs_sysparam.distloss_uohm = revle32(iv_attrs.attr_proc_r_distloss_vcs_uohm); + iv_vcs_sysparam.distoffset_uv = revle32(iv_attrs.attr_proc_vrm_voffset_vcs_uv); + + // VDN rail + iv_vdn_sysparam.loadline_uohm = revle32(iv_attrs.attr_proc_r_loadline_vdn_uohm); + iv_vdn_sysparam.distloss_uohm = revle32(iv_attrs.attr_proc_r_distloss_vdn_uohm); + iv_vdn_sysparam.distoffset_uv = revle32(iv_attrs.attr_proc_vrm_voffset_vdn_uv); + + //TBD + // ----------------------- + // get VDM Parameters data + // ---------------------- + if (iv_attrs.attr_system_vdm_disable == fapi2::ENUM_ATTR_SYSTEM_VDM_DISABLE_OFF) + { + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_DROOP_SMALL_OVERRIDE, + FAPI_SYSTEM, + iv_vdmpb.droop_small_override)); + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_DROOP_LARGE_OVERRIDE, + FAPI_SYSTEM, + iv_vdmpb.droop_large_override)); + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_DROOP_EXTREME_OVERRIDE, + FAPI_SYSTEM, + iv_vdmpb.droop_extreme_override)); + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_OVERVOLT_OVERRIDE, + FAPI_SYSTEM, + iv_vdmpb.overvolt_override)); + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_FMIN_OVERRIDE_KHZ, + FAPI_SYSTEM, + iv_vdmpb.fmin_override_khz)); + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_FMAX_OVERRIDE_KHZ, + FAPI_SYSTEM, + iv_vdmpb.fmax_override_khz)); + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_VID_COMPARE_OVERRIDE_MV, + FAPI_SYSTEM, + iv_vdmpb.vid_compare_override_mv)); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_DPLL_VDM_RESPONSE, + FAPI_SYSTEM, + iv_vdmpb.vdm_response)); + } + else + { + FAPI_DBG(" VDM is disabled. Skipping VDM attribute accesses"); + } -/// START OF MVPD DATA FUNCTION + //Set default values + SET_ATTR(fapi2::ATTR_PSTATES_ENABLED, iv_procChip, iv_pstates_enabled); + SET_ATTR(fapi2::ATTR_RESCLK_ENABLED, iv_procChip, iv_resclk_enabled); + SET_ATTR(fapi2::ATTR_VDM_ENABLED, iv_procChip, iv_vdm_enabled); + SET_ATTR(fapi2::ATTR_IVRM_ENABLED, iv_procChip, iv_ivrm_enabled); + SET_ATTR(fapi2::ATTR_WOF_ENABLED, iv_procChip, iv_wof_enabled); + SET_ATTR(fapi2::ATTR_WOV_UNDERV_ENABLED, iv_procChip, iv_wov_underv_enabled); + SET_ATTR(fapi2::ATTR_WOV_OVERV_ENABLED, iv_procChip, iv_wov_overv_enabled); -fapi2::ReturnCode -proc_get_mvpd_data(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - uint32_t o_attr_mvpd_data[PV_D][PV_W], - uint32_t* o_valid_pdv_points, - uint8_t* o_present_chiplets, - uint8_t& o_bucketId, - fapi2::voltageBucketData_t* o_poundv_data, - PSTATE_attribute_state* o_state) + iv_pstates_enabled = true; + iv_resclk_enabled = true; + iv_vdm_enabled = true; + iv_ivrm_enabled = true; + iv_wof_enabled = true; + iv_wov_underv_enabled = true; + iv_wov_overv_enabled = true; + + //Calculate nest & frequency_step_khz + iv_frequency_step_khz = (iv_attrs.attr_freq_proc_refclock_khz / + iv_attrs.attr_proc_dpll_divider); + + iv_nest_freq_mhz = iv_attrs.attr_nest_frequency_mhz; + + +fapi_try_exit: + if (fapi2::current_err) + { + FAPI_ASSERT(false, + fapi2::PSTATE_PB_ATTRIBUTE_ACCESS_ERROR() + .set_CHIP_TARGET(iv_procChip), + "Pstate Parameter Block attribute access error"); + } +} //end of attr_init + + +/////////////////////////////////////////////////////////// +//////// compute_vpd_pts +/////////////////////////////////////////////////////////// +void PlatPmPPB::compute_vpd_pts() { + int p = 0; - std::vector<fapi2::Target<fapi2::TARGET_TYPE_EQ>> l_eqChiplets; - fapi2::voltageBucketData_t l_poundv_data; - fapi2::Target<fapi2::TARGET_TYPE_EQ> l_firstEqChiplet; - uint8_t* l_buffer = reinterpret_cast<uint8_t*>(malloc(sizeof(l_poundv_data)) ); - uint8_t* l_buffer_inc; - uint32_t chiplet_mvpd_data[PV_D][PV_W]; - uint8_t j = 0; - uint8_t i = 0; - uint8_t ii = 0; - uint8_t first_chplt = 1; - uint8_t bucket_id = 0; + uint32_t l_vdd_loadline_uohm = revle32(iv_vdd_sysparam.loadline_uohm); + uint32_t l_vdd_distloss_uohm = revle32(iv_vdd_sysparam.distloss_uohm); + uint32_t l_vdd_distoffset_uv = revle32(iv_vdd_sysparam.distoffset_uv); + uint32_t l_vcs_loadline_uohm = revle32(iv_vcs_sysparam.loadline_uohm); + uint32_t l_vcs_distloss_uohm = revle32(iv_vcs_sysparam.distloss_uohm); + uint32_t l_vcs_distoffset_uv = revle32(iv_vcs_sysparam.distoffset_uv); - do + //RAW POINTS. We just copy them as is + for (p = 0; p < NUM_OP_POINTS; p++) { - // initialize - FAPI_TRY(proc_get_attributes(i_target, &attr), "proc_get_mvpd_data: Get attributes function failed"); - *o_present_chiplets = 0; + iv_operating_points[VPD_PT_SET_RAW][p].vdd_mv = iv_raw_vpd_pts[p].vdd_mv; + iv_operating_points[VPD_PT_SET_RAW][p].vcs_mv = iv_raw_vpd_pts[p].vcs_mv; + iv_operating_points[VPD_PT_SET_RAW][p].idd_100ma = iv_raw_vpd_pts[p].idd_100ma; + iv_operating_points[VPD_PT_SET_RAW][p].ics_100ma = iv_raw_vpd_pts[p].ics_100ma; + iv_operating_points[VPD_PT_SET_RAW][p].frequency_mhz = iv_raw_vpd_pts[p].frequency_mhz; + iv_operating_points[VPD_PT_SET_RAW][p].pstate = iv_raw_vpd_pts[p].pstate; - // ----------------------------------------------------------------- - // get list of quad chiplets and loop over each and get #V data from each - // ----------------------------------------------------------------- - // check that frequency is the same per chiplet - // for voltage, get the max for use for the chip + FAPI_DBG("GP: OpPoint=[%d][%d], PS=%3d, Freq=%3X (%4d), Vdd=%3X (%4d)", + VPD_PT_SET_RAW, p, + iv_operating_points[VPD_PT_SET_RAW][p].pstate, + (iv_operating_points[VPD_PT_SET_RAW][p].frequency_mhz), + (iv_operating_points[VPD_PT_SET_RAW][p].frequency_mhz), + (iv_operating_points[VPD_PT_SET_RAW][p].vdd_mv), + (iv_operating_points[VPD_PT_SET_RAW][p].vdd_mv)); + } - l_eqChiplets = i_target.getChildren<fapi2::TARGET_TYPE_EQ>(fapi2::TARGET_STATE_FUNCTIONAL); + //SYSTEM PARAMS APPLIED POINTS + for (p = 0; p < NUM_OP_POINTS; p++) + { + uint32_t l_vdd_mv = (iv_raw_vpd_pts[p].vdd_mv); + uint32_t l_idd_ma = (iv_raw_vpd_pts[p].idd_100ma * 100); + uint32_t l_vcs_mv = (iv_raw_vpd_pts[p].vcs_mv); + uint32_t l_ics_ma = (iv_raw_vpd_pts[p].ics_100ma * 100); + iv_operating_points[VPD_PT_SET_SYSP][p].vdd_mv = + sysparm_uplift(l_vdd_mv, + l_idd_ma, + l_vdd_loadline_uohm, + l_vdd_distloss_uohm, + l_vdd_distoffset_uv); - *o_present_chiplets = l_eqChiplets.size(); - FAPI_INF("Number of EQ chiplets present => %u", *o_present_chiplets); - for (j = 0; j < l_eqChiplets.size(); j++) - { + iv_operating_points[VPD_PT_SET_SYSP][p].vcs_mv = + sysparm_uplift(l_vcs_mv, + l_ics_ma, + l_vcs_loadline_uohm, + l_vcs_distloss_uohm, + l_vcs_distoffset_uv); - uint8_t l_chipNum = 0xFF; + iv_operating_points[VPD_PT_SET_SYSP][p].idd_100ma = + iv_raw_vpd_pts[p].idd_100ma; + iv_operating_points[VPD_PT_SET_SYSP][p].ics_100ma = + iv_raw_vpd_pts[p].ics_100ma; + iv_operating_points[VPD_PT_SET_SYSP][p].frequency_mhz = + iv_raw_vpd_pts[p].frequency_mhz; + iv_operating_points[VPD_PT_SET_SYSP][p].pstate = + iv_raw_vpd_pts[p].pstate; - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_eqChiplets[j], l_chipNum)); + FAPI_DBG("SP: OpPoint=[%d][%d], PS=%3d, Freq=%3X (%4d), Vdd=%3X (%4d)", + VPD_PT_SET_RAW, p, + iv_operating_points[VPD_PT_SET_SYSP][p].pstate, + (iv_operating_points[VPD_PT_SET_SYSP][p].frequency_mhz), + (iv_operating_points[VPD_PT_SET_SYSP][p].frequency_mhz), + (iv_operating_points[VPD_PT_SET_SYSP][p].vdd_mv), + (iv_operating_points[VPD_PT_SET_SYSP][p].vdd_mv)); + } - FAPI_INF("Chip Number => %u", l_chipNum); + //BIASED POINTS + for (p = 0; p < NUM_OP_POINTS; p++) + { + uint32_t l_frequency_mhz = (iv_biased_vpd_pts[p].frequency_mhz); + uint32_t l_vdd_mv = (iv_biased_vpd_pts[p].vdd_mv); + uint32_t l_vcs_mv = (iv_biased_vpd_pts[p].vcs_mv); - // clear out buffer to known value before calling fapiGetMvpdField - memset(l_buffer, 0, sizeof(o_poundv_data)); + iv_operating_points[VPD_PT_SET_BIASED][p].vdd_mv = + bias_adjust_mv(l_vdd_mv, iv_bias[p].vdd_ext_hp); - FAPI_TRY(p9_pm_get_poundv_bucket(l_eqChiplets[j], l_poundv_data)); + iv_operating_points[VPD_PT_SET_BIASED][p].vcs_mv = + bias_adjust_mv(l_vcs_mv, iv_bias[p].vcs_ext_hp); - memcpy(l_buffer, &l_poundv_data, sizeof(l_poundv_data)); - memcpy(o_poundv_data, &l_poundv_data, sizeof(l_poundv_data)); + iv_operating_points[VPD_PT_SET_BIASED][p].frequency_mhz = + bias_adjust_mhz(l_frequency_mhz, iv_bias[p].frequency_hp); - // clear array - memset(chiplet_mvpd_data, 0, sizeof(chiplet_mvpd_data)); + iv_operating_points[VPD_PT_SET_BIASED][p].idd_100ma = + iv_biased_vpd_pts[p].idd_100ma; + iv_operating_points[VPD_PT_SET_BIASED][p].ics_100ma = + iv_biased_vpd_pts[p].ics_100ma; + } - // fill chiplet_mvpd_data 2d array with data iN buffer (skip first byte - bucket id) -#define UINT16_GET(__uint8_ptr) ((uint16_t)( ( (*((const uint8_t *)(__uint8_ptr)) << 8) | *((const uint8_t *)(__uint8_ptr) + 1) ) )) + // As this is memory to memory, Endianess correction is not necessary. + iv_reference_frequency_khz = + (iv_operating_points[VPD_PT_SET_BIASED][ULTRA].frequency_mhz) * 1000; - l_buffer_inc = l_buffer; + FAPI_DBG("Reference into GPPB: LE local Freq=%X (%d); Freq=%X (%d)", + iv_reference_frequency_khz, + iv_reference_frequency_khz, + (iv_reference_frequency_khz), + (iv_reference_frequency_khz)); - bucket_id = *l_buffer_inc; - l_buffer_inc++; + // Now that the ULTRA frequency is known, Pstates can be calculated + for (p = 0; p < NUM_OP_POINTS; p++) + { + iv_operating_points[VPD_PT_SET_BIASED][p].pstate = + ((((iv_operating_points[VPD_PT_SET_BIASED][ULTRA].frequency_mhz) - + (iv_operating_points[VPD_PT_SET_BIASED][p].frequency_mhz)) * 1000) / + (iv_frequency_step_khz)); - FAPI_INF("#V chiplet = %u bucket id = %u", l_chipNum, bucket_id); + FAPI_DBG("Bi: OpPoint=[%d][%d], PS=%3d, Freq=%3X (%4d), Vdd=%3X (%4d), UT Freq=%3X (%4d) Step Freq=%5d", + VPD_PT_SET_BIASED, p, + iv_operating_points[VPD_PT_SET_BIASED][p].pstate, + (iv_operating_points[VPD_PT_SET_BIASED][p].frequency_mhz), + (iv_operating_points[VPD_PT_SET_BIASED][p].frequency_mhz), + (iv_operating_points[VPD_PT_SET_BIASED][p].vdd_mv), + (iv_operating_points[VPD_PT_SET_BIASED][p].vdd_mv), + (iv_operating_points[VPD_PT_SET_BIASED][ULTRA].frequency_mhz), + (iv_operating_points[VPD_PT_SET_BIASED][ULTRA].frequency_mhz), + (iv_frequency_step_khz)); - for (i = 0; i <= 4; i++) - { + } - for (ii = 0; ii <= 4; ii++) - { - chiplet_mvpd_data[i][ii] = (uint32_t) UINT16_GET(l_buffer_inc); - FAPI_INF("#V data = 0x%04X %-6d", chiplet_mvpd_data[i][ii], - chiplet_mvpd_data[i][ii]); - // increment to next MVPD value in buffer - l_buffer_inc += 2; - } - } + //BIASED POINTS and SYSTEM PARMS APPLIED POINTS + for (p = 0; p < NUM_OP_POINTS; p++) + { + uint32_t l_vdd_mv = (iv_operating_points[VPD_PT_SET_BIASED][p].vdd_mv); + uint32_t l_idd_ma = (iv_operating_points[VPD_PT_SET_BIASED][p].idd_100ma) * 100; + uint32_t l_vcs_mv = (iv_operating_points[VPD_PT_SET_BIASED][p].vcs_mv); + uint32_t l_ics_ma = (iv_operating_points[VPD_PT_SET_BIASED][p].ics_100ma) * 100; - FAPI_TRY(proc_chk_valid_poundv( i_target, - chiplet_mvpd_data, - o_valid_pdv_points, - l_chipNum, - bucket_id, - o_state)); + iv_operating_points[VPD_PT_SET_BIASED_SYSP][p].vdd_mv = + sysparm_uplift(l_vdd_mv, + l_idd_ma, + l_vdd_loadline_uohm, + l_vdd_distloss_uohm, + l_vdd_distoffset_uv); - // on first chiplet put each bucket's data into attr_mvpd_voltage_control - if (first_chplt) - { - l_firstEqChiplet = l_eqChiplets[j]; - o_bucketId = bucket_id; - for (i = 0; i <= 4; i++) - { - for (ii = 0; ii <= 4; ii++) - { - o_attr_mvpd_data[i][ii] = chiplet_mvpd_data[i][ii]; - } - } + iv_operating_points[VPD_PT_SET_BIASED_SYSP][p].vcs_mv = + sysparm_uplift(l_vcs_mv, + l_ics_ma, + l_vcs_loadline_uohm, + l_vcs_distloss_uohm, + l_vcs_distoffset_uv); - first_chplt = 0; - } - else - { - // on subsequent chiplets, check that frequencies are same for each operating point for each chiplet - if ( (o_attr_mvpd_data[0][0] != chiplet_mvpd_data[0][0]) || - (o_attr_mvpd_data[1][0] != chiplet_mvpd_data[1][0]) || - (o_attr_mvpd_data[2][0] != chiplet_mvpd_data[2][0]) || - (o_attr_mvpd_data[3][0] != chiplet_mvpd_data[3][0]) || - (o_attr_mvpd_data[4][0] != chiplet_mvpd_data[4][0]) ) - { - o_state->iv_pstates_enabled = false; - // Error out has Pstate and all dependent functions are suspious. - FAPI_ASSERT(false, - fapi2::PSTATE_MVPD_CHIPLET_VOLTAGE_NOT_EQUAL() - .set_CHIP_TARGET(i_target) - .set_CURRENT_EQ_CHIPLET_TARGET(l_eqChiplets[j]) - .set_FIRST_EQ_CHIPLET_TARGET(l_firstEqChiplet) - .set_BUCKET(bucket_id), - "frequencies are not the same for each operating point for each chiplet"); + iv_operating_points[VPD_PT_SET_BIASED_SYSP][p].idd_100ma = + iv_operating_points[VPD_PT_SET_BIASED][p].idd_100ma; + iv_operating_points[VPD_PT_SET_BIASED_SYSP][p].ics_100ma = + iv_operating_points[VPD_PT_SET_BIASED][p].ics_100ma; + iv_operating_points[VPD_PT_SET_BIASED_SYSP][p].frequency_mhz = + iv_operating_points[VPD_PT_SET_BIASED][p].frequency_mhz; + iv_operating_points[VPD_PT_SET_BIASED_SYSP][p].pstate = + iv_operating_points[VPD_PT_SET_BIASED][p].pstate; - } - } + FAPI_DBG("BS: OpPoint=[%d][%d], PS=%3d, Freq=%3X (%4d), Vdd=%3X (%4d)", + VPD_PT_SET_BIASED_SYSP, p, + iv_operating_points[VPD_PT_SET_SYSP][p].pstate, + (iv_operating_points[VPD_PT_SET_SYSP][p].frequency_mhz), + (iv_operating_points[VPD_PT_SET_SYSP][p].frequency_mhz), + (iv_operating_points[VPD_PT_SET_SYSP][p].vdd_mv), + (iv_operating_points[VPD_PT_SET_SYSP][p].vdd_mv)); - // check each bucket for max voltage and if max, put bucket's data into attr_mvpd_voltage_control - for (i = 0; i <= 4; i++) - { - if (o_attr_mvpd_data[i][1] < chiplet_mvpd_data[i][1]) - { - o_attr_mvpd_data[i][0] = chiplet_mvpd_data[i][0]; - o_attr_mvpd_data[i][1] = chiplet_mvpd_data[i][1]; - o_attr_mvpd_data[i][2] = chiplet_mvpd_data[i][2]; - o_attr_mvpd_data[i][3] = chiplet_mvpd_data[i][3]; - o_attr_mvpd_data[i][4] = chiplet_mvpd_data[i][4]; - o_bucketId = bucket_id; - } - } - } // end for loop } - while(0); +} //end of compute_vpd_pts -fapi_try_exit: +/////////////////////////////////////////////////////////// +//////// resclk_init +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::resclk_init( void ) +{ + memset (&iv_resclk_setup,0,sizeof(iv_resclk_setup)); - if (fapi2::current_err != fapi2::FAPI2_RC_SUCCESS) + if (iv_attrs.attr_resclk_disable == fapi2::ENUM_ATTR_SYSTEM_RESCLK_DISABLE_OFF) { - o_state->iv_pstates_enabled = false; - } - free (l_buffer); + FAPI_TRY(set_resclk_table_attrs(),"set_resclk_table_attrs failed"); - return fapi2::current_err; + if (iv_resclk_enabled) + { + FAPI_TRY(res_clock_setup( )); + } -} // end proc_get_mvpd_data -/// END OF MVPD DATA FUNCTION + FAPI_INF("Resonant Clocks are enabled"); + } + else + { + iv_resclk_enabled = false; + FAPI_INF("Resonant Clocks are disabled. Skipping setup."); + } +fapi_try_exit: + return fapi2::current_err; +} // end of resclk_init -/// START OF IDDQ READ FUNCTION -fapi2::ReturnCode -proc_get_mvpd_iddq( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - IddqTable* io_iddqt, - PSTATE_attribute_state* o_state) +/////////////////////////////////////////////////////////// +//////// res_clock_setup +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::res_clock_setup (void) { + FAPI_DBG(">> res_clock_setup"); + uint8_t l_resclk_freq_index[RESCLK_FREQ_REGIONS]; + uint16_t l_step_delay_ns; + uint16_t l_l3_threshold_mv; + uint16_t l_steparray[RESCLK_STEPS]; + uint16_t l_resclk_freq_regions[RESCLK_FREQ_REGIONS]; + uint32_t l_ultra_turbo_freq_khz = (iv_reference_frequency_khz); - uint8_t* l_buffer_iq_c = reinterpret_cast<uint8_t*>(malloc(IQ_BUFFER_ALLOC)); - uint32_t l_record = 0; - uint32_t l_bufferSize_iq = IQ_BUFFER_ALLOC; + const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_SYSTEM_RESCLK_STEP_DELAY, + FAPI_SYSTEM, + l_step_delay_ns)); + iv_resclk_setup.step_delay_ns = revle16(l_step_delay_ns); - // -------------------------------------------- - // Process IQ Keyword (IDDQ) Data - // -------------------------------------------- + // Resonant Clocking Frequency and Index arrays + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_FREQ_REGIONS, iv_procChip, + l_resclk_freq_regions)); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_FREQ_REGION_INDEX, iv_procChip, + l_resclk_freq_index)); - // clear out buffer to known value before calling fapiGetMvpdField - memset(l_buffer_iq_c, 0, IQ_BUFFER_ALLOC); + // Convert frequencies to pstates + for (uint8_t i = 0; i < RESCLK_FREQ_REGIONS; ++i) + { + Pstate pstate; + // Frequencies are given in MHz, convert to KHz + uint32_t freq_khz = static_cast<uint32_t>((l_resclk_freq_regions[i])) * 1000; + uint8_t idx = l_resclk_freq_index[i]; - // set l_record to appropriate cprx record - l_record = (uint32_t)fapi2::MVPD_RECORD_CRP0; - l_bufferSize_iq = IQ_BUFFER_ALLOC; + FAPI_INF("l_resclk_freq_regions %d l_resclk_freq_index %d %d %d %d",l_resclk_freq_regions[i],l_resclk_freq_index[i], + (freq_khz), l_ultra_turbo_freq_khz, iv_reference_frequency_khz); - //First read is to get size of vpd record, note the o_buffer is NULL - FAPI_TRY( getMvpdField((fapi2::MvpdRecord)l_record, - fapi2::MVPD_KEYWORD_IQ, - i_target, - NULL, - l_bufferSize_iq) ); + // Frequencies need to be capped at Ultra-Turbo, frequencies less-than + // the Minimum can be ignored (because this table is walked from + // end-begin, and the frequencies are stored in ascending order, + // the "walk" will never pass the minimum frequency). + if (freq_khz > l_ultra_turbo_freq_khz) + { + freq_khz = l_ultra_turbo_freq_khz; - //Allocate memory for vpd data - l_buffer_iq_c = reinterpret_cast<uint8_t*>(malloc(l_bufferSize_iq)); + // Need to walk the table backwards to find the index for this frequency + for (uint8_t j = i; j >= 0; --j) + { + if (freq_khz >= (l_resclk_freq_regions[j] * 1000)) + { + idx = l_resclk_freq_index[j]; + break; + } + } + } - // Get Chip IQ MVPD data from the CRPx records - FAPI_TRY(getMvpdField((fapi2::MvpdRecord)l_record, - fapi2::MVPD_KEYWORD_IQ, - i_target, - l_buffer_iq_c, - l_bufferSize_iq)); + int rc = freq2pState(freq_khz, &pstate); - //copy VPD data to IQ structure table - memcpy(io_iddqt, l_buffer_iq_c, l_bufferSize_iq); + switch (rc) + { + case -PSTATE_LT_PSTATE_MIN: + FAPI_INF("Resonant clock frequency %d KHz was clipped to Pstate 0", + freq_khz); + break; - //Verify Payload header data. - if ( !(io_iddqt->iddq_version) || - !(io_iddqt->good_quads_per_sort) || - !(io_iddqt->good_normal_cores_per_sort) || - !(io_iddqt->good_caches_per_sort)) - { - o_state->iv_wof_enabled = false; - FAPI_ASSERT_NOEXIT(false, - fapi2::PSTATE_PB_IQ_VPD_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_VERSION(io_iddqt->iddq_version) - .set_GOOD_QUADS_PER_SORT(io_iddqt->good_quads_per_sort) - .set_GOOD_NORMAL_CORES_PER_SORT(io_iddqt->good_normal_cores_per_sort) - .set_GOOD_CACHES_PER_SORT(io_iddqt->good_caches_per_sort), - "Pstate Parameter Block IQ Payload data error being logged"); - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - } + case -PSTATE_GT_PSTATE_MAX: + FAPI_INF("Resonant clock Frequency %d KHz is outside the range that can be represented" + " by a Pstate with a base frequency of %d KHz and step size %d KHz", + freq_khz, + l_ultra_turbo_freq_khz, + (iv_frequency_step_khz)); + FAPI_INF("Pstate is set to %X (%d)", pstate); + break; + } - //Verify ivdd_all_cores_off_caches_off has MSB bit is set - //if yes then initialized to 0 - for (int i = 0; i < IDDQ_MEASUREMENTS; ++i) - { - if ( io_iddqt->ivdd_all_cores_off_caches_off[i] & 0x8000) - { - io_iddqt->ivdd_all_cores_off_caches_off[i] = 0; - } + iv_resclk_setup.resclk_freq[i] = pstate; + iv_resclk_setup.resclk_index[i] = idx; + + FAPI_DBG("Resclk: freq = %d kHz; pstate = %d; idx = %d", freq_khz, pstate, idx); } - // Put out the structure to the trace - iddq_print(io_iddqt); -fapi_try_exit: + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_L3_VALUE, iv_procChip, + iv_resclk_setup.l3_steparray)); - // Free up memory buffer - free(l_buffer_iq_c); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_L3_VOLTAGE_THRESHOLD_MV, iv_procChip, + l_l3_threshold_mv)); + iv_resclk_setup.l3_threshold_mv = revle16(l_l3_threshold_mv); - if (fapi2::current_err != fapi2::FAPI2_RC_SUCCESS) + // Resonant Clocking Step array + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_VALUE, iv_procChip, + l_steparray)); + + for (uint8_t i = 0; i < RESCLK_STEPS; i++) { - o_state->iv_wof_enabled = false; + iv_resclk_setup.steparray[i].value = revle16(l_steparray[i]); } +fapi_try_exit: + FAPI_DBG("<< res_clock_setup"); return fapi2::current_err; -} // proc_get_mvdp_iddq - -/// END OF IDDQ READ FUNCTION +} // end of res_clock_setup -/// START OF BIAS APPLICATION FUNCTION -// Bias multiplier helper function -// NOTE: BIAS_PCT_UNIT is a multipler on the percentage that the value represents -double -calc_bias(const int8_t i_value) +/////////////////////////////////////////////////////////// +//////// set_resclk_table_attrs +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::set_resclk_table_attrs() { - if (i_value) - { - double temp = 1.0 + ((BIAS_PCT_UNIT/100) * (double)i_value); - FAPI_DBG(" calc_bias: input bias (in 1/2 percent) = %d; percent = %4.1f%% biased multiplier = %6.3f", - i_value, (i_value*BIAS_PCT_UNIT), temp); - return temp; - } - else + uint8_t l_resclk_freq_index[RESCLK_FREQ_REGIONS]; + uint8_t l_l3_steparray[RESCLK_L3_STEPS]; + uint16_t l_resclk_freq_regions[RESCLK_FREQ_REGIONS]; + uint16_t l_resclk_value[RESCLK_STEPS]; + uint16_t l_l3_threshold_mv; + iv_resclk_enabled = true; + + do { - return 1; - } + // Perform some basic sanity checks on the header data structures (since + // the header values are provided by another team) + FAPI_ASSERT_NOEXIT( + (p9_resclk_defines::RESCLK_INDEX_VEC.size() == RESCLK_FREQ_REGIONS), + fapi2::PSTATE_PB_RESCLK_INDEX_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_FREQ_REGIONS(RESCLK_FREQ_REGIONS) + .set_INDEX_VEC_SIZE(p9_resclk_defines::RESCLK_INDEX_VEC.size()), + "p9_resclk_defines.h RESCLK_INDEX_VEC.size() mismatch"); -} + FAPI_ASSERT_NOEXIT( + (p9_resclk_defines::RESCLK_TABLE_VEC.size() == RESCLK_STEPS), + fapi2::PSTATE_PB_RESCLK_TABLE_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_STEPS(RESCLK_STEPS) + .set_TABLE_VEC_SIZE(p9_resclk_defines::RESCLK_TABLE_VEC.size()), + "p9_resclk_defines.h RESCLK_TABLE_VEC.size() mismatch"); + + FAPI_ASSERT_NOEXIT( + (p9_resclk_defines::L3CLK_TABLE_VEC.size() == RESCLK_L3_STEPS), + fapi2::PSTATE_PB_RESCLK_L3_TABLE_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_L3_STEPS(RESCLK_L3_STEPS) + .set_L3_VEC_SIZE(p9_resclk_defines::L3CLK_TABLE_VEC.size()), + "p9_resclk_defines.h L3CLK_TABLE_VEC.size() mismatch"); + //FAPI_ASSERT_NOEXIT will log an error with recoverable.. but rc won't be + //cleared.. So we are initializing again to continue further + if (fapi2::current_err != fapi2::FAPI2_RC_SUCCESS) + { + iv_resclk_enabled = false; + fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; + break; + } + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_L3_VALUE, iv_procChip, + l_l3_steparray)); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_FREQ_REGIONS, iv_procChip, + l_resclk_freq_regions)); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_FREQ_REGION_INDEX, iv_procChip, + l_resclk_freq_index)); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_VALUE, iv_procChip, + l_resclk_value)); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_L3_VOLTAGE_THRESHOLD_MV, iv_procChip, + l_l3_threshold_mv)); + for (uint8_t i = 0; i < RESCLK_FREQ_REGIONS; ++i) + { + if (l_resclk_freq_regions[i] == 0) + { + l_resclk_freq_regions[i] = p9_resclk_defines::RESCLK_INDEX_VEC.at(i).freq; + } -fapi2::ReturnCode -proc_get_extint_bias( uint32_t io_attr_mvpd_data[PV_D][PV_W], - const AttributeList* i_attr, - VpdBias o_vpdbias[NUM_OP_POINTS] - ) -{ - double freq_bias[NUM_OP_POINTS]; - double voltage_ext_vdd_bias[NUM_OP_POINTS]; - double voltage_ext_vcs_bias; - double voltage_ext_vdn_bias; + if (l_resclk_freq_index[i] == 0) + { + l_resclk_freq_index[i] = p9_resclk_defines::RESCLK_INDEX_VEC.at(i).idx; + } + FAPI_INF("entered resclk_attr init %x", l_resclk_freq_index[i]); + } - // Calculate the frequency multiplers and load the biases into the exported - // structure - for (auto p = 0; p < NUM_OP_POINTS; p++) - { - switch (p) + for (uint8_t i = 0; i < RESCLK_STEPS; ++i) { - case POWERSAVE: - o_vpdbias[p].frequency_hp = i_attr->attr_freq_bias_powersave; - o_vpdbias[p].vdd_ext_hp = i_attr->attr_voltage_ext_vdd_bias_powersave; - o_vpdbias[p].vdd_int_hp = i_attr->attr_voltage_int_vdd_bias_powersave; + if (l_resclk_value[i] == 0) + { + l_resclk_value[i] = p9_resclk_defines::RESCLK_TABLE_VEC.at(i); + } + } - break; - case NOMINAL: - o_vpdbias[p].frequency_hp = i_attr->attr_freq_bias_nominal; - o_vpdbias[p].vdd_ext_hp = i_attr->attr_voltage_ext_vdd_bias_nominal; - o_vpdbias[p].vdd_int_hp = i_attr->attr_voltage_int_vdd_bias_nominal; - break; - case TURBO: - o_vpdbias[p].frequency_hp = i_attr->attr_freq_bias_turbo; - o_vpdbias[p].vdd_ext_hp = i_attr->attr_voltage_ext_vdd_bias_turbo; - o_vpdbias[p].vdd_int_hp = i_attr->attr_voltage_int_vdd_bias_turbo; - break; - case ULTRA: - o_vpdbias[p].frequency_hp = i_attr->attr_freq_bias_ultraturbo; - o_vpdbias[p].vdd_ext_hp = i_attr->attr_voltage_ext_vdd_bias_ultraturbo; - o_vpdbias[p].vdd_int_hp = i_attr->attr_voltage_int_vdd_bias_ultraturbo; + for (uint8_t i = 0; i < RESCLK_L3_STEPS; ++i) + { + if (l_l3_steparray[i] == 0) + { + l_l3_steparray[i] = p9_resclk_defines::L3CLK_TABLE_VEC.at(i); + } } - o_vpdbias[p].vdn_ext_hp = i_attr->attr_voltage_ext_vdn_bias; - o_vpdbias[p].vcs_ext_hp = i_attr->attr_voltage_ext_vcs_bias; + if(l_l3_threshold_mv == 0) + { + l_l3_threshold_mv = p9_resclk_defines::L3_VOLTAGE_THRESHOLD_MV; + } - freq_bias[p] = calc_bias(o_vpdbias[p].frequency_hp); - voltage_ext_vdd_bias[p] = calc_bias(o_vpdbias[p].vdd_ext_hp); + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SYSTEM_RESCLK_L3_VALUE, iv_procChip, + l_l3_steparray)); + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SYSTEM_RESCLK_FREQ_REGIONS, iv_procChip, + l_resclk_freq_regions)); + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SYSTEM_RESCLK_FREQ_REGION_INDEX, iv_procChip, + l_resclk_freq_index)); + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SYSTEM_RESCLK_VALUE, iv_procChip, + l_resclk_value)); + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SYSTEM_RESCLK_L3_VOLTAGE_THRESHOLD_MV, iv_procChip, + l_l3_threshold_mv)); + }while(0); - FAPI_DBG(" Biases[%d](bias): Freq=%f (%f%%); VDD=%f (%f%%)", - p, - freq_bias[p], o_vpdbias[p].frequency_hp/2, - voltage_ext_vdd_bias[p], o_vpdbias[p].vdd_ext_hp/2); - } +fapi_try_exit: + return fapi2::current_err; +} // end of set_resclk_table_attrs - // VCS bias applied to all operating points - voltage_ext_vcs_bias = calc_bias(i_attr->attr_voltage_ext_vcs_bias); - // VDN bias applied to all operating points - voltage_ext_vdn_bias = calc_bias(i_attr->attr_voltage_ext_vdn_bias); +/////////////////////////////////////////////////////////// +//////// get_ivrm_parms +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::get_ivrm_parms () +{ + FAPI_DBG(">> proc_get_ivrm_parms"); - // Change the VPD frequency, VDD and VCS values with the bias multiplers - for (auto p = 0; p < NUM_OP_POINTS; p++) + if (iv_attrs.attr_system_ivrm_disable == fapi2::ENUM_ATTR_SYSTEM_IVRM_DISABLE_OFF) { - FAPI_DBG(" Orig values[%d](bias): Freq=%d (%f); VDD=%d (%f), VCS=%d (%f)", - p, - io_attr_mvpd_data[p][VPD_PV_CORE_FREQ_MHZ], freq_bias[p], - io_attr_mvpd_data[p][VPD_PV_VDD_MV], voltage_ext_vdd_bias[p], - io_attr_mvpd_data[p][VPD_PV_VCS_MV], voltage_ext_vcs_bias); + const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - double freq_mhz = - (( (double)io_attr_mvpd_data[p][VPD_PV_CORE_FREQ_MHZ]) * freq_bias[p]); - double vdd_mv = - (( (double)io_attr_mvpd_data[p][VPD_PV_VDD_MV]) * voltage_ext_vdd_bias[p]); - double vcs_mv = - (( (double)io_attr_mvpd_data[p][VPD_PV_VCS_MV]) * voltage_ext_vcs_bias); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IVRM_STRENGTH_LOOKUP, FAPI_SYSTEM, + iv_ivrmpb.strength_lookup)); - io_attr_mvpd_data[p][VPD_PV_CORE_FREQ_MHZ] = (uint32_t)internal_floor(freq_mhz); - io_attr_mvpd_data[p][VPD_PV_VDD_MV] = (uint32_t)internal_ceil(vdd_mv); - io_attr_mvpd_data[p][VPD_PV_VCS_MV] = (uint32_t)(vcs_mv); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IVRM_VIN_MULTIPLIER, FAPI_SYSTEM, + iv_ivrmpb.vin_multiplier)); - FAPI_DBG(" Biased values[%d]: Freq=%f %d; VDD=%f %d, VCS=%f %d ", - p, - freq_mhz, io_attr_mvpd_data[p][VPD_PV_CORE_FREQ_MHZ], - vdd_mv, io_attr_mvpd_data[p][VPD_PV_VDD_MV], - vcs_mv, io_attr_mvpd_data[p][VPD_PV_VCS_MV]); - } + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IVRM_VIN_MAX_MV, FAPI_SYSTEM, + iv_ivrmpb.vin_max_mv)); - // Power bus operating point - double vdn_mv = - (( (double)io_attr_mvpd_data[VPD_PV_POWERBUS][VPD_PV_VDN_MV]) * voltage_ext_vdn_bias); - io_attr_mvpd_data[VPD_PV_POWERBUS][VPD_PV_VDN_MV] = (uint32_t)internal_ceil(vdn_mv); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IVRM_STEP_DELAY_NS, FAPI_SYSTEM, + iv_ivrmpb.step_delay_ns)); - return fapi2::FAPI2_RC_SUCCESS; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IVRM_STABILIZATION_DELAY_NS, FAPI_SYSTEM, + iv_ivrmpb.stablization_delay_ns)); + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IVRM_DEADZONE_MV, FAPI_SYSTEM, + iv_ivrmpb.deadzone_mv)); -} // end proc_get_extint_bias -/// END OF BIAS APPLICATION FUNCTION + // This is presently hardcoded to FALSE until validation code is in + // place to ensure turning IVRM on is a good thing. This attribute write is + // needed to allocate the HWP attribute in Cronus. + + // Indicate that IVRM is good to be enabled (or not) + FAPI_INF(" NOTE: This level of code is forcing the iVRM to OFF"); + { + fapi2::ATTR_IVRM_ENABLED_Type l_ivrm_enabled = + (fapi2::ATTR_IVRM_ENABLED_Type)fapi2::ENUM_ATTR_IVRM_ENABLED_FALSE; + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_IVRM_ENABLED, iv_procChip, l_ivrm_enabled)); + } + } + else + { + memset (&iv_ivrmpb,0,sizeof(iv_ivrmpb)); + FAPI_DBG(" IVRM is disabled. Skipping IVRM attribute accesses"); + iv_ivrm_enabled = false; + } +fapi_try_exit: + FAPI_DBG("<< get_ivrm_parms"); + return fapi2::current_err; +} // end of get_ivrm_parms -fapi2::ReturnCode -proc_chk_valid_poundv(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - const uint32_t i_chiplet_mvpd_data[PV_D][PV_W], - uint32_t* o_valid_pdv_points, - const uint8_t i_chiplet_num, - const uint8_t i_bucket_id, - PSTATE_attribute_state* o_state, +/////////////////////////////////////////////////////////// +//////// chk_valid_poundv +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::chk_valid_poundv( const bool i_biased_state) { - const uint8_t pv_op_order[NUM_OP_POINTS] = VPD_PV_ORDER; + const uint8_t pv_op_order[NUM_OP_POINTS] = VPD_PV_ORDER; const char* pv_op_str[NUM_OP_POINTS] = VPD_PV_ORDER_STR; uint8_t i = 0; bool suspend_ut_check = false; + uint8_t l_chiplet_num = iv_procChip.getChipletNumber(); - FAPI_DBG(">> proc_chk_valid_poundv for %s values", (i_biased_state) ? "biased" : "non-biased" ); + VpdPoint l_attr_mvpd_data[5]; + memcpy (l_attr_mvpd_data,iv_attr_mvpd_poundV_raw,sizeof(l_attr_mvpd_data)); + + if (i_biased_state) + { + memcpy (l_attr_mvpd_data,iv_attr_mvpd_poundV_biased,sizeof(l_attr_mvpd_data)); + } + + FAPI_DBG(">> chk_valid_poundv for %s values", (i_biased_state) ? "biased" : "non-biased" ); const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - fapi2::ATTR_SYSTEM_POUNDV_VALIDITY_HALT_DISABLE_Type attr_poundv_validity_halt_disable; + fapi2::ATTR_SYSTEM_POUNDV_VALIDITY_HALT_DISABLE_Type attr_poundv_validity_halt_disable; + fapi2::ATTR_CHIP_EC_FEATURE_POUNDV_VALIDATE_DISABLE_Type attr_poundv_validate_ec_disable; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_POUNDV_VALIDITY_HALT_DISABLE, FAPI_SYSTEM, attr_poundv_validity_halt_disable)); - fapi2::ATTR_CHIP_EC_FEATURE_POUNDV_VALIDATE_DISABLE_Type attr_poundv_validate_ec_disable; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_POUNDV_VALIDATE_DISABLE, - i_target, + iv_procChip, attr_poundv_validate_ec_disable)); if (attr_poundv_validate_ec_disable) { - o_state->iv_pstates_enabled = false; + iv_pstates_enabled = false; FAPI_INF("**** WARNING : #V zero value checking is not being performed on this chip EC level"); FAPI_INF("**** WARNING : Pstates are not enabled"); } @@ -1900,83 +2793,84 @@ proc_chk_valid_poundv(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_targe for (i = 0; i <= NUM_OP_POINTS - 1; i++) { FAPI_INF("Checking for Zero valued %s data in each #V operating point (%s) f=%u v=%u i=%u v=%u i=%u", - (i_biased_state) ? "biased" : "non-biased", - pv_op_str[pv_op_order[i]], - i_chiplet_mvpd_data[pv_op_order[i]][0], - i_chiplet_mvpd_data[pv_op_order[i]][1], - i_chiplet_mvpd_data[pv_op_order[i]][2], - i_chiplet_mvpd_data[pv_op_order[i]][3], - i_chiplet_mvpd_data[pv_op_order[i]][4]); - - if (is_wof_enabled(i_target,o_state) && (strcmp(pv_op_str[pv_op_order[i]], "UltraTurbo") == 0)) + (i_biased_state) ? "biased" : "non-biased", + pv_op_str[pv_op_order[i]], + (l_attr_mvpd_data[pv_op_order[i]].frequency_mhz), + (l_attr_mvpd_data[pv_op_order[i]].vdd_mv), + (l_attr_mvpd_data[pv_op_order[i]].idd_100ma), + (l_attr_mvpd_data[pv_op_order[i]].vcs_mv), + (l_attr_mvpd_data[pv_op_order[i]].ics_100ma)); + + if (is_wof_enabled() && + (strcmp(pv_op_str[pv_op_order[i]], "UltraTurbo") == 0)) { - if (i_chiplet_mvpd_data[pv_op_order[i]][0] == 0 || - i_chiplet_mvpd_data[pv_op_order[i]][1] == 0 || - i_chiplet_mvpd_data[pv_op_order[i]][2] == 0 || - i_chiplet_mvpd_data[pv_op_order[i]][3] == 0 || - i_chiplet_mvpd_data[pv_op_order[i]][4] == 0 ) + if (l_attr_mvpd_data[pv_op_order[i]].frequency_mhz == 0 || + l_attr_mvpd_data[pv_op_order[i]].vdd_mv == 0 || + l_attr_mvpd_data[pv_op_order[i]].idd_100ma == 0 || + l_attr_mvpd_data[pv_op_order[i]].vcs_mv == 0 || + l_attr_mvpd_data[pv_op_order[i]].ics_100ma == 0 ) { FAPI_INF("**** WARNING: WOF is enabled but zero valued data found in #V (chiplet = %u bucket id = %u op point = %s)", - i_chiplet_num, i_bucket_id, pv_op_str[pv_op_order[i]]); + l_chiplet_num, iv_poundV_bucket_id, pv_op_str[pv_op_order[i]]); FAPI_INF("**** WARNING: Disabling WOF and continuing"); suspend_ut_check = true; // Set ATTR_WOF_ENABLED so the caller can set header flags - o_state->iv_wof_enabled = false; + iv_wof_enabled = false; // Take out an informational error log and then keep going. if (i_biased_state) { FAPI_ASSERT_NOEXIT(false, fapi2::PSTATE_PB_BIASED_POUNDV_WOF_UT_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_CHIPLET_NUMBER(i_chiplet_num) - .set_BUCKET(i_bucket_id) - .set_FREQUENCY(i_chiplet_mvpd_data[pv_op_order[i]][0]) - .set_VDD(i_chiplet_mvpd_data[pv_op_order[i]][1]) - .set_IDD(i_chiplet_mvpd_data[pv_op_order[i]][2]) - .set_VCS(i_chiplet_mvpd_data[pv_op_order[i]][3]) - .set_ICS(i_chiplet_mvpd_data[pv_op_order[i]][4]), + .set_CHIP_TARGET(iv_procChip) + .set_CHIPLET_NUMBER(l_chiplet_num) + .set_BUCKET(iv_poundV_bucket_id) + .set_FREQUENCY(l_attr_mvpd_data[pv_op_order[i]].frequency_mhz) + .set_VDD(l_attr_mvpd_data[pv_op_order[i]].vdd_mv) + .set_IDD(l_attr_mvpd_data[pv_op_order[i]].idd_100ma) + .set_VCS(l_attr_mvpd_data[pv_op_order[i]].vcs_mv) + .set_ICS(l_attr_mvpd_data[pv_op_order[i]].ics_100ma), "Pstate Parameter Block WOF Biased #V UT error being logged"); } else { FAPI_ASSERT_NOEXIT(false, fapi2::PSTATE_PB_POUNDV_WOF_UT_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_CHIPLET_NUMBER(i_chiplet_num) - .set_BUCKET(i_bucket_id) - .set_FREQUENCY(i_chiplet_mvpd_data[pv_op_order[i]][0]) - .set_VDD(i_chiplet_mvpd_data[pv_op_order[i]][1]) - .set_IDD(i_chiplet_mvpd_data[pv_op_order[i]][2]) - .set_VCS(i_chiplet_mvpd_data[pv_op_order[i]][3]) - .set_ICS(i_chiplet_mvpd_data[pv_op_order[i]][4]), + .set_CHIP_TARGET(iv_procChip) + .set_CHIPLET_NUMBER(l_chiplet_num) + .set_BUCKET(iv_poundV_bucket_id) + .set_FREQUENCY(l_attr_mvpd_data[pv_op_order[i]].frequency_mhz) + .set_VDD(l_attr_mvpd_data[pv_op_order[i]].vdd_mv) + .set_IDD(l_attr_mvpd_data[pv_op_order[i]].idd_100ma) + .set_VCS(l_attr_mvpd_data[pv_op_order[i]].vcs_mv) + .set_ICS(l_attr_mvpd_data[pv_op_order[i]].ics_100ma), "Pstate Parameter Block WOF #V UT error being logged"); } fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; } } - else if ((!is_wof_enabled(i_target,o_state)) && (strcmp(pv_op_str[pv_op_order[i]], "UltraTurbo") == 0)) + else if ((!is_wof_enabled()) && (strcmp(pv_op_str[pv_op_order[i]], "UltraTurbo") == 0)) { FAPI_INF("**** NOTE: WOF is disabled so the UltraTurbo VPD is not being checked"); suspend_ut_check = true; } else { - if (i_chiplet_mvpd_data[pv_op_order[i]][0] == 0 || - i_chiplet_mvpd_data[pv_op_order[i]][1] == 0 || - i_chiplet_mvpd_data[pv_op_order[i]][2] == 0 || - i_chiplet_mvpd_data[pv_op_order[i]][3] == 0 || - i_chiplet_mvpd_data[pv_op_order[i]][4] == 0 ) + if (l_attr_mvpd_data[pv_op_order[i]].frequency_mhz == 0 || + l_attr_mvpd_data[pv_op_order[i]].vdd_mv == 0 || + l_attr_mvpd_data[pv_op_order[i]].idd_100ma == 0 || + l_attr_mvpd_data[pv_op_order[i]].vcs_mv == 0 || + l_attr_mvpd_data[pv_op_order[i]].ics_100ma == 0 ) { - o_state->iv_pstates_enabled = false; + iv_pstates_enabled = false; if (attr_poundv_validity_halt_disable) { FAPI_IMP("**** WARNING : halt on #V validity checking has been disabled and errors were found"); FAPI_IMP("**** WARNING : Zero valued data found in #V (chiplet = %u bucket id = %u op point = %s)", - i_chiplet_num, i_bucket_id, pv_op_str[pv_op_order[i]]); + l_chiplet_num, iv_poundV_bucket_id, pv_op_str[pv_op_order[i]]); FAPI_IMP("**** WARNING : Pstates are not enabled but continuing on."); // Log errors based on biased inputs or not @@ -1984,30 +2878,30 @@ proc_chk_valid_poundv(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_targe { FAPI_ASSERT_NOEXIT(false, fapi2::PSTATE_PB_BIASED_POUNDV_ZERO_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_CHIPLET_NUMBER(i_chiplet_num) - .set_BUCKET(i_bucket_id) + .set_CHIP_TARGET(iv_procChip) + .set_CHIPLET_NUMBER(l_chiplet_num) + .set_BUCKET(iv_poundV_bucket_id) .set_POINT(i) - .set_FREQUENCY(i_chiplet_mvpd_data[pv_op_order[i]][0]) - .set_VDD(i_chiplet_mvpd_data[pv_op_order[i]][1]) - .set_IDD(i_chiplet_mvpd_data[pv_op_order[i]][2]) - .set_VCS(i_chiplet_mvpd_data[pv_op_order[i]][3]) - .set_ICS(i_chiplet_mvpd_data[pv_op_order[i]][4]), + .set_FREQUENCY(l_attr_mvpd_data[pv_op_order[i]].frequency_mhz) + .set_VDD(l_attr_mvpd_data[pv_op_order[i]].vdd_mv) + .set_IDD(l_attr_mvpd_data[pv_op_order[i]].idd_100ma) + .set_VCS(l_attr_mvpd_data[pv_op_order[i]].vcs_mv) + .set_ICS(l_attr_mvpd_data[pv_op_order[i]].ics_100ma), "Pstate Parameter Block Biased #V Zero contents error being logged"); } else { FAPI_ASSERT_NOEXIT(false, fapi2::PSTATE_PB_POUNDV_ZERO_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_CHIPLET_NUMBER(i_chiplet_num) - .set_BUCKET(i_bucket_id) + .set_CHIP_TARGET(iv_procChip) + .set_CHIPLET_NUMBER(l_chiplet_num) + .set_BUCKET(iv_poundV_bucket_id) .set_POINT(i) - .set_FREQUENCY(i_chiplet_mvpd_data[pv_op_order[i]][0]) - .set_VDD(i_chiplet_mvpd_data[pv_op_order[i]][1]) - .set_IDD(i_chiplet_mvpd_data[pv_op_order[i]][2]) - .set_VCS(i_chiplet_mvpd_data[pv_op_order[i]][3]) - .set_ICS(i_chiplet_mvpd_data[pv_op_order[i]][4]), + .set_FREQUENCY(l_attr_mvpd_data[pv_op_order[i]].frequency_mhz) + .set_VDD(l_attr_mvpd_data[pv_op_order[i]].vdd_mv) + .set_IDD(l_attr_mvpd_data[pv_op_order[i]].idd_100ma) + .set_VCS(l_attr_mvpd_data[pv_op_order[i]].vcs_mv) + .set_ICS(l_attr_mvpd_data[pv_op_order[i]].ics_100ma), "Pstate Parameter Block #V Zero contents error being logged"); } fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; @@ -2015,37 +2909,37 @@ proc_chk_valid_poundv(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_targe else { FAPI_ERR("**** ERROR : Zero valued data found in #V (chiplet = %u bucket id = %u op point = %s)", - i_chiplet_num, i_bucket_id, pv_op_str[pv_op_order[i]]); + l_chiplet_num, iv_poundV_bucket_id, pv_op_str[pv_op_order[i]]); // Error out has Pstate and all dependent functions are suspious. if (i_biased_state) { FAPI_ASSERT(false, fapi2::PSTATE_PB_BIASED_POUNDV_ZERO_ERROR() - .set_CHIP_TARGET(i_target) - .set_CHIPLET_NUMBER(i_chiplet_num) - .set_BUCKET(i_bucket_id) + .set_CHIP_TARGET(iv_procChip) + .set_CHIPLET_NUMBER(l_chiplet_num) + .set_BUCKET(iv_poundV_bucket_id) .set_POINT(i) - .set_FREQUENCY(i_chiplet_mvpd_data[pv_op_order[i]][0]) - .set_VDD(i_chiplet_mvpd_data[pv_op_order[i]][1]) - .set_IDD(i_chiplet_mvpd_data[pv_op_order[i]][2]) - .set_VCS(i_chiplet_mvpd_data[pv_op_order[i]][3]) - .set_ICS(i_chiplet_mvpd_data[pv_op_order[i]][4]), + .set_FREQUENCY(l_attr_mvpd_data[pv_op_order[i]].frequency_mhz) + .set_VDD(l_attr_mvpd_data[pv_op_order[i]].vdd_mv) + .set_IDD(l_attr_mvpd_data[pv_op_order[i]].idd_100ma) + .set_VCS(l_attr_mvpd_data[pv_op_order[i]].vcs_mv) + .set_ICS(l_attr_mvpd_data[pv_op_order[i]].ics_100ma), "Pstate Parameter Block Biased #V Zero contents error being logged"); } else { FAPI_ASSERT(false, fapi2::PSTATE_PB_POUNDV_ZERO_ERROR() - .set_CHIP_TARGET(i_target) - .set_CHIPLET_NUMBER(i_chiplet_num) - .set_BUCKET(i_bucket_id) + .set_CHIP_TARGET(iv_procChip) + .set_CHIPLET_NUMBER(l_chiplet_num) + .set_BUCKET(iv_poundV_bucket_id) .set_POINT(i) - .set_FREQUENCY(i_chiplet_mvpd_data[pv_op_order[i]][0]) - .set_VDD(i_chiplet_mvpd_data[pv_op_order[i]][1]) - .set_IDD(i_chiplet_mvpd_data[pv_op_order[i]][2]) - .set_VCS(i_chiplet_mvpd_data[pv_op_order[i]][3]) - .set_ICS(i_chiplet_mvpd_data[pv_op_order[i]][4]), + .set_FREQUENCY(l_attr_mvpd_data[pv_op_order[i]].frequency_mhz) + .set_VDD(l_attr_mvpd_data[pv_op_order[i]].vdd_mv) + .set_IDD(l_attr_mvpd_data[pv_op_order[i]].idd_100ma) + .set_VCS(l_attr_mvpd_data[pv_op_order[i]].vcs_mv) + .set_ICS(l_attr_mvpd_data[pv_op_order[i]].ics_100ma), "Pstate Parameter Block #V Zero contents error being logged"); } } // Halt disable @@ -2056,86 +2950,88 @@ proc_chk_valid_poundv(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_targe // Adjust the valid operating point based on UltraTurbo presence // and WOF enablement - *o_valid_pdv_points = NUM_OP_POINTS; + iv_valid_pdv_points = NUM_OP_POINTS; if (suspend_ut_check) { - (*o_valid_pdv_points)--; + iv_valid_pdv_points--; } - FAPI_DBG("o_valid_pdv_points = %d", *o_valid_pdv_points); - -#define POUNDV_SLOPE_CHECK(x,y) x > y ? " is GREATER (ERROR!) than " : " is less than " + FAPI_DBG("iv_valid_pdv_points = %d", iv_valid_pdv_points); if (attr_poundv_validate_ec_disable) { - o_state->iv_pstates_enabled = false; + iv_pstates_enabled = false; FAPI_INF("**** WARNING : #V relationship checking is not being performed on this chip EC level"); FAPI_INF("**** WARNING : Pstates are not enabled"); } else { // check valid operating points' values have this relationship (power save <= nominal <= turbo <= ultraturbo) - for (i = 1; i <= (*o_valid_pdv_points) - 1; i++) + for (i = 1; i <= (iv_valid_pdv_points) - 1; i++) { FAPI_INF("Checking for relationship between #V operating point (%s <= %s)", pv_op_str[pv_op_order[i - 1]], pv_op_str[pv_op_order[i]]); // Only skip checkinug for WOF not enabled and UltraTurbo. - if ( is_wof_enabled(i_target,o_state) || - (!( !is_wof_enabled(i_target,o_state) && (strcmp(pv_op_str[pv_op_order[i]], "UltraTurbo") == 0))) - ) + if ( is_wof_enabled() || + (!( !is_wof_enabled() && + (strcmp(pv_op_str[pv_op_order[i]], "UltraTurbo") == 0)))) { - if (i_chiplet_mvpd_data[pv_op_order[i - 1]][0] > i_chiplet_mvpd_data[pv_op_order[i]][0] || - i_chiplet_mvpd_data[pv_op_order[i - 1]][1] > i_chiplet_mvpd_data[pv_op_order[i]][1] || - i_chiplet_mvpd_data[pv_op_order[i - 1]][2] > i_chiplet_mvpd_data[pv_op_order[i]][2] || - i_chiplet_mvpd_data[pv_op_order[i - 1]][3] > i_chiplet_mvpd_data[pv_op_order[i]][3] || - i_chiplet_mvpd_data[pv_op_order[i - 1]][4] > i_chiplet_mvpd_data[pv_op_order[i]][4] ) + if (l_attr_mvpd_data[pv_op_order[i - 1]].frequency_mhz > + l_attr_mvpd_data[pv_op_order[i]].frequency_mhz || + l_attr_mvpd_data[pv_op_order[i - 1]].vdd_mv > + l_attr_mvpd_data[pv_op_order[i]].vdd_mv || + l_attr_mvpd_data[pv_op_order[i - 1]].idd_100ma > + l_attr_mvpd_data[pv_op_order[i]].idd_100ma || + l_attr_mvpd_data[pv_op_order[i - 1]].vcs_mv > + l_attr_mvpd_data[pv_op_order[i]].vcs_mv || + l_attr_mvpd_data[pv_op_order[i - 1]].ics_100ma > + l_attr_mvpd_data[pv_op_order[i]].ics_100ma ) { - - o_state->iv_pstates_enabled = false; + iv_pstates_enabled = false; if (attr_poundv_validity_halt_disable) { - FAPI_IMP("**** WARNING : halt on #V validity checking has been disabled and relationship errors were found"); - FAPI_IMP("**** WARNING : Relationship error between #V operating point (%s > %s)(power save <= nominal <= turbo <= ultraturbo) (chiplet = %u bucket id = %u op point = %u)", - pv_op_str[pv_op_order[i - 1]], pv_op_str[pv_op_order[i]], i_chiplet_num, i_bucket_id, - pv_op_order[i]); + FAPI_IMP("**** WARNING : halt on #V validity checking has been " + "disabled and relationship errors were found"); + FAPI_IMP("**** WARNING : Relationship error between #V operating point " + "(%s > %s)(power save <= nominal <= turbo <= ultraturbo) (chiplet = %u bucket id = %u op point = %u)", + pv_op_str[pv_op_order[i - 1]], pv_op_str[pv_op_order[i]], l_chiplet_num, iv_poundV_bucket_id, pv_op_order[i]); FAPI_IMP("**** WARNING : Pstates are not enabled but continuing on."); } else { - FAPI_ERR("**** ERROR : Relation../../xml/attribute_info/pm_plat_attributes.xmlship error between #V operating point (%s > %s)(power save <= nominal <= turbo <= ultraturbo) (chiplet = %u bucket id = %u op point = %u)", - pv_op_str[pv_op_order[i - 1]], pv_op_str[pv_op_order[i]], i_chiplet_num, i_bucket_id, - pv_op_order[i]); + FAPI_ERR("**** ERROR : Relation../../xml/attribute_info/pm_plat_attributes.xmlship " + "error between #V operating point (%s > %s)(power save <= nominal <= turbo " + "<= ultraturbo) (chiplet = %u bucket id = %u op point = %u)", + pv_op_str[pv_op_order[i - 1]], pv_op_str[pv_op_order[i]], l_chiplet_num, iv_poundV_bucket_id,pv_op_order[i]); } FAPI_INF("%s Frequency value %u is %s %s Frequency value %u", - pv_op_str[pv_op_order[i - 1]], i_chiplet_mvpd_data[pv_op_order[i - 1]][0], - POUNDV_SLOPE_CHECK(i_chiplet_mvpd_data[pv_op_order[i - 1]][0], i_chiplet_mvpd_data[pv_op_order[i]][0]), - pv_op_str[pv_op_order[i]], i_chiplet_mvpd_data[pv_op_order[i]][0]); + pv_op_str[pv_op_order[i - 1]], l_attr_mvpd_data[pv_op_order[i - 1]].frequency_mhz, + POUNDV_SLOPE_CHECK(l_attr_mvpd_data[pv_op_order[i - 1]].frequency_mhz, + l_attr_mvpd_data[pv_op_order[i]].frequency_mhz),pv_op_str[pv_op_order[i]], l_attr_mvpd_data[pv_op_order[i]].frequency_mhz); FAPI_INF("%s VDD voltage value %u is %s %s Frequency value %u", - pv_op_str[pv_op_order[i - 1]], i_chiplet_mvpd_data[pv_op_order[i - 1]][1], - POUNDV_SLOPE_CHECK(i_chiplet_mvpd_data[pv_op_order[i - 1]][1], i_chiplet_mvpd_data[pv_op_order[i]][1]), - pv_op_str[pv_op_order[i]], i_chiplet_mvpd_data[pv_op_order[i]][1]); + pv_op_str[pv_op_order[i - 1]], l_attr_mvpd_data[pv_op_order[i - 1]].vdd_mv, + POUNDV_SLOPE_CHECK(l_attr_mvpd_data[pv_op_order[i - 1]].vdd_mv, l_attr_mvpd_data[pv_op_order[i]].vdd_mv), + pv_op_str[pv_op_order[i]], l_attr_mvpd_data[pv_op_order[i]].vdd_mv); FAPI_INF("%s VDD current value %u is %s %s Frequency value %u", - pv_op_str[pv_op_order[i - 1]], i_chiplet_mvpd_data[pv_op_order[i - 1]][2], - POUNDV_SLOPE_CHECK(i_chiplet_mvpd_data[pv_op_order[i - 1]][2], i_chiplet_mvpd_data[pv_op_order[i]][2]), - pv_op_str[pv_op_order[i]], i_chiplet_mvpd_data[pv_op_order[i]][2]); + pv_op_str[pv_op_order[i - 1]], l_attr_mvpd_data[pv_op_order[i - 1]].idd_100ma, + POUNDV_SLOPE_CHECK(l_attr_mvpd_data[pv_op_order[i - 1]].idd_100ma, l_attr_mvpd_data[pv_op_order[i]].idd_100ma), + pv_op_str[pv_op_order[i]], l_attr_mvpd_data[pv_op_order[i]].idd_100ma); FAPI_INF("%s VCS voltage value %u is %s %s Frequency value %u", - pv_op_str[pv_op_order[i - 1]], i_chiplet_mvpd_data[pv_op_order[i - 1]][3], - POUNDV_SLOPE_CHECK(i_chiplet_mvpd_data[pv_op_order[i - 1]][3], i_chiplet_mvpd_data[pv_op_order[i]][3]), - pv_op_str[pv_op_order[i]], i_chiplet_mvpd_data[pv_op_order[i]][3]); + pv_op_str[pv_op_order[i - 1]], l_attr_mvpd_data[pv_op_order[i - 1]].vcs_mv, + POUNDV_SLOPE_CHECK(l_attr_mvpd_data[pv_op_order[i - 1]].vcs_mv, l_attr_mvpd_data[pv_op_order[i]].vcs_mv), + pv_op_str[pv_op_order[i]], l_attr_mvpd_data[pv_op_order[i]].vcs_mv); FAPI_INF("%s VCS current value %u i../../xml/attribute_info/pm_plat_attributes.xmls %s %s Frequency value %u", - pv_op_str[pv_op_order[i - 1]], i_chiplet_mvpd_data[pv_op_order[i - 1]][4], - POUNDV_SLOPE_CHECK(i_chiplet_mvpd_data[pv_op_order[i - 1]][4], i_chiplet_mvpd_data[pv_op_order[i]][4]), - pv_op_str[pv_op_order[i]], i_chiplet_mvpd_data[pv_op_order[i]][4]); - - + pv_op_str[pv_op_order[i - 1]], l_attr_mvpd_data[pv_op_order[i - 1]].ics_100ma, + POUNDV_SLOPE_CHECK(l_attr_mvpd_data[pv_op_order[i - 1]].ics_100ma, l_attr_mvpd_data[pv_op_order[i]].ics_100ma), + pv_op_str[pv_op_order[i]], l_attr_mvpd_data[pv_op_order[i]].ics_100ma); if (i_biased_state) { @@ -2144,20 +3040,20 @@ proc_chk_valid_poundv(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_targe // Log the error only. FAPI_ASSERT_NOEXIT(false, fapi2::PSTATE_PB_BIASED_POUNDV_SLOPE_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_CHIPLET_NUMBER(i_chiplet_num) - .set_BUCKET(i_bucket_id) + .set_CHIP_TARGET(iv_procChip) + .set_CHIPLET_NUMBER(l_chiplet_num) + .set_BUCKET(iv_poundV_bucket_id) .set_POINT(i) - .set_FREQUENCY_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][0]) - .set_VDD_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][1]) - .set_IDD_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][2]) - .set_VCS_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][3]) - .set_ICS_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][4]) - .set_FREQUENCY_B(i_chiplet_mvpd_data[pv_op_order[i]][0]) - .set_VDD_B(i_chiplet_mvpd_data[pv_op_order[i]][1]) - .set_IDD_B(i_chiplet_mvpd_data[pv_op_order[i]][2]) - .set_VCS_B(i_chiplet_mvpd_data[pv_op_order[i]][3]) - .set_ICS_B(i_chiplet_mvpd_data[pv_op_order[i]][4]), + .set_FREQUENCY_A(l_attr_mvpd_data[pv_op_order[i - 1]].frequency_mhz) + .set_VDD_A(l_attr_mvpd_data[pv_op_order[i - 1]].vdd_mv) + .set_IDD_A(l_attr_mvpd_data[pv_op_order[i - 1]].idd_100ma) + .set_VCS_A(l_attr_mvpd_data[pv_op_order[i - 1]].vcs_mv) + .set_ICS_A(l_attr_mvpd_data[pv_op_order[i - 1]].ics_100ma) + .set_FREQUENCY_B(l_attr_mvpd_data[pv_op_order[i]].frequency_mhz) + .set_VDD_B(l_attr_mvpd_data[pv_op_order[i]].vdd_mv) + .set_IDD_B(l_attr_mvpd_data[pv_op_order[i]].idd_100ma) + .set_VCS_B(l_attr_mvpd_data[pv_op_order[i]].vcs_mv) + .set_ICS_B(l_attr_mvpd_data[pv_op_order[i]].ics_100ma), "Pstate Parameter Block Biased #V disorder contents error being logged"); fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; @@ -2168,20 +3064,20 @@ proc_chk_valid_poundv(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_targe // Error out has Pstate and all dependent functions are suspious. FAPI_ASSERT(false, fapi2::PSTATE_PB_BIASED_POUNDV_SLOPE_ERROR() - .set_CHIP_TARGET(i_target) - .set_CHIPLET_NUMBER(i_chiplet_num) - .set_BUCKET(i_bucket_id) + .set_CHIP_TARGET(iv_procChip) + .set_CHIPLET_NUMBER(l_chiplet_num) + .set_BUCKET(iv_poundV_bucket_id) .set_POINT(i) - .set_FREQUENCY_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][0]) - .set_VDD_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][1]) - .set_IDD_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][2]) - .set_VCS_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][3]) - .set_ICS_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][4]) - .set_FREQUENCY_B(i_chiplet_mvpd_data[pv_op_order[i]][0]) - .set_VDD_B(i_chiplet_mvpd_data[pv_op_order[i]][1]) - .set_IDD_B(i_chiplet_mvpd_data[pv_op_order[i]][2]) - .set_VCS_B(i_chiplet_mvpd_data[pv_op_order[i]][3]) - .set_ICS_B(i_chiplet_mvpd_data[pv_op_order[i]][4]), + .set_FREQUENCY_A(l_attr_mvpd_data[pv_op_order[i - 1]].frequency_mhz) + .set_VDD_A(l_attr_mvpd_data[pv_op_order[i - 1]].vdd_mv) + .set_IDD_A(l_attr_mvpd_data[pv_op_order[i - 1]].idd_100ma) + .set_VCS_A(l_attr_mvpd_data[pv_op_order[i - 1]].vcs_mv) + .set_ICS_A(l_attr_mvpd_data[pv_op_order[i - 1]].ics_100ma) + .set_FREQUENCY_B(l_attr_mvpd_data[pv_op_order[i]].frequency_mhz) + .set_VDD_B(l_attr_mvpd_data[pv_op_order[i]].vdd_mv) + .set_IDD_B(l_attr_mvpd_data[pv_op_order[i]].idd_100ma) + .set_VCS_B(l_attr_mvpd_data[pv_op_order[i]].vcs_mv) + .set_ICS_B(l_attr_mvpd_data[pv_op_order[i]].ics_100ma), "Pstate Parameter Block Biased #V disorder contents error being logged"); } } @@ -2192,20 +3088,20 @@ proc_chk_valid_poundv(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_targe // Log the error only. FAPI_ASSERT_NOEXIT(false, fapi2::PSTATE_PB_POUNDV_SLOPE_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_CHIPLET_NUMBER(i_chiplet_num) - .set_BUCKET(i_bucket_id) + .set_CHIP_TARGET(iv_procChip) + .set_CHIPLET_NUMBER(l_chiplet_num) + .set_BUCKET(iv_poundV_bucket_id) .set_POINT(i) - .set_FREQUENCY_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][0]) - .set_VDD_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][1]) - .set_IDD_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][2]) - .set_VCS_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][3]) - .set_ICS_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][4]) - .set_FREQUENCY_B(i_chiplet_mvpd_data[pv_op_order[i]][0]) - .set_VDD_B(i_chiplet_mvpd_data[pv_op_order[i]][1]) - .set_IDD_B(i_chiplet_mvpd_data[pv_op_order[i]][2]) - .set_VCS_B(i_chiplet_mvpd_data[pv_op_order[i]][3]) - .set_ICS_B(i_chiplet_mvpd_data[pv_op_order[i]][4]), + .set_FREQUENCY_A(l_attr_mvpd_data[pv_op_order[i - 1]].frequency_mhz) + .set_VDD_A(l_attr_mvpd_data[pv_op_order[i - 1]].vdd_mv) + .set_IDD_A(l_attr_mvpd_data[pv_op_order[i - 1]].idd_100ma) + .set_VCS_A(l_attr_mvpd_data[pv_op_order[i - 1]].vcs_mv) + .set_ICS_A(l_attr_mvpd_data[pv_op_order[i - 1]].ics_100ma) + .set_FREQUENCY_B(l_attr_mvpd_data[pv_op_order[i]].frequency_mhz) + .set_VDD_B(l_attr_mvpd_data[pv_op_order[i]].vdd_mv) + .set_IDD_B(l_attr_mvpd_data[pv_op_order[i]].idd_100ma) + .set_VCS_B(l_attr_mvpd_data[pv_op_order[i]].vcs_mv) + .set_ICS_B(l_attr_mvpd_data[pv_op_order[i]].ics_100ma), "Pstate Parameter Block #V disorder contents error being logged"); fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; @@ -2215,20 +3111,20 @@ proc_chk_valid_poundv(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_targe // Error out has Pstate and all dependent functions are suspious. FAPI_ASSERT(false, fapi2::PSTATE_PB_POUNDV_SLOPE_ERROR() - .set_CHIP_TARGET(i_target) - .set_CHIPLET_NUMBER(i_chiplet_num) - .set_BUCKET(i_bucket_id) + .set_CHIP_TARGET(iv_procChip) + .set_CHIPLET_NUMBER(l_chiplet_num) + .set_BUCKET(iv_poundV_bucket_id) .set_POINT(i) - .set_FREQUENCY_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][0]) - .set_VDD_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][1]) - .set_IDD_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][2]) - .set_VCS_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][3]) - .set_ICS_A(i_chiplet_mvpd_data[pv_op_order[i - 1]][4]) - .set_FREQUENCY_B(i_chiplet_mvpd_data[pv_op_order[i]][0]) - .set_VDD_B(i_chiplet_mvpd_data[pv_op_order[i]][1]) - .set_IDD_B(i_chiplet_mvpd_data[pv_op_order[i]][2]) - .set_VCS_B(i_chiplet_mvpd_data[pv_op_order[i]][3]) - .set_ICS_B(i_chiplet_mvpd_data[pv_op_order[i]][4]), + .set_FREQUENCY_A(l_attr_mvpd_data[pv_op_order[i - 1]].frequency_mhz) + .set_VDD_A(l_attr_mvpd_data[pv_op_order[i - 1]].vdd_mv) + .set_IDD_A(l_attr_mvpd_data[pv_op_order[i - 1]].idd_100ma) + .set_VCS_A(l_attr_mvpd_data[pv_op_order[i - 1]].vcs_mv) + .set_ICS_A(l_attr_mvpd_data[pv_op_order[i - 1]].ics_100ma) + .set_FREQUENCY_B(l_attr_mvpd_data[pv_op_order[i]].frequency_mhz) + .set_VDD_B(l_attr_mvpd_data[pv_op_order[i]].vdd_mv) + .set_IDD_B(l_attr_mvpd_data[pv_op_order[i]].idd_100ma) + .set_VCS_B(l_attr_mvpd_data[pv_op_order[i]].vcs_mv) + .set_ICS_B(l_attr_mvpd_data[pv_op_order[i]].ics_100ma), "Pstate Parameter Block #V disorder contents error being logged"); } } @@ -2237,604 +3133,1458 @@ proc_chk_valid_poundv(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_targe } // point loop } // validity disabled fapi_try_exit: - FAPI_DBG("<< proc_chk_valid_poundv"); + FAPI_DBG("<< chk_valid_poundv"); return fapi2::current_err; -} +} // end of chk_valid_poundv -/// ------------------------------------------------------------ -/// \brief Copy VPD operating point into destination in assending order -/// \param[in] &src[NUM_OP_POINTS] => reference to source VPD structure (array) -/// \param[out] *dest[NUM_OP_POINTS] => pointer to destination VpdOperatingPoint structure -// \param[in] i_frequency_step_khz => Base frequency value for pstate calculation -/// ------------------------------------------------------------ -/// \note: this routine reads the keyword information in "VPD order" (eg Nominal, -/// PowerSave, Turbo, UltraTurbo) into the data structures in "Natural Order" -/// (eg (eg PowerSave, Nominal, Turbo, UltraTurbo) -/// -fapi2::ReturnCode -load_mvpd_operating_point ( const uint32_t i_src[PV_D][PV_W], - VpdOperatingPoint* o_dest, - uint32_t i_frequency_step_khz) + +/////////////////////////////////////////////////////////// +//////// get_mvpd_poundV +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::get_mvpd_poundV() { - FAPI_DBG(">> load_mvpd_operating_point"); - const uint8_t pv_op_order[NUM_OP_POINTS] = VPD_PV_ORDER; + std::vector<fapi2::Target<fapi2::TARGET_TYPE_EQ>> l_eqChiplets; + fapi2::voltageBucketData_t l_fstChlt_vpd_data; + fapi2::Target<fapi2::TARGET_TYPE_EQ> l_firstEqChiplet; + uint8_t j = 0; + uint8_t first_chplt = 1; + uint8_t bucket_id = 0; + uint8_t* l_buffer = + reinterpret_cast<uint8_t*>(malloc(sizeof(voltageBucketData_t)) ); + uint8_t* l_buffer_inc = NULL; - for (uint32_t i = 0; i < NUM_OP_POINTS; i++) + do { - o_dest[i].frequency_mhz = revle32(i_src[pv_op_order[i]][0]); - o_dest[i].vdd_mv = revle32(i_src[pv_op_order[i]][1]); - o_dest[i].idd_100ma = revle32(i_src[pv_op_order[i]][2]); - o_dest[i].vcs_mv = revle32(i_src[pv_op_order[i]][3]); - o_dest[i].ics_100ma = revle32(i_src[pv_op_order[i]][4]); - o_dest[i].pstate = (i_src[ULTRA][0] - i_src[pv_op_order[i]][0]) * 1000 / i_frequency_step_khz; + memset(&l_fstChlt_vpd_data,0,sizeof(l_fstChlt_vpd_data)); + // initialize + iv_eq_chiplet_state = 0; + + // ----------------------------------------------------------------- + // get list of quad chiplets and loop over each and get #V data from each + // ----------------------------------------------------------------- + // check that frequency is the same per chiplet + // for voltage, get the max for use for the chip + + l_eqChiplets = iv_procChip.getChildren<fapi2::TARGET_TYPE_EQ>(fapi2::TARGET_STATE_FUNCTIONAL); + iv_eq_chiplet_state = l_eqChiplets.size(); + + FAPI_INF("Number of EQ chiplets present => %u", iv_eq_chiplet_state); + + for (j = 0; j < l_eqChiplets.size(); j++) + { + uint8_t l_chipNum = 0xFF; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_eqChiplets[j], l_chipNum)); + + FAPI_INF("Chip Number => %u", l_chipNum); + + FAPI_TRY(p9_pm_get_poundv_bucket(l_eqChiplets[j], iv_poundV_raw_data)); + + bucket_id = iv_poundV_raw_data.bucketId; + memset(l_buffer, 0, sizeof(iv_poundV_raw_data)); + + // fill chiplet_mvpd_data 2d array with data iN buffer (skip first byte - bucket id) +#define UINT16_GET(__uint8_ptr) ((uint16_t)( ( (*((const uint8_t *)(__uint8_ptr)) << 8) | *((const uint8_t *)(__uint8_ptr) + 1) ) )) + + //memcpy(iv_attr_mvpd_poundV_raw,&iv_poundV_raw_data.nomFreq,sizeof(iv_attr_mvpd_poundV_raw)); + memcpy(l_buffer, &iv_poundV_raw_data, sizeof(iv_poundV_raw_data)); + + FAPI_INF("#V chiplet = %u bucket id = %u", l_chipNum, bucket_id); + + l_buffer_inc = l_buffer; + l_buffer_inc++; + for (int i = 0; i <= 4; i++) + { + iv_attr_mvpd_poundV_raw[i].frequency_mhz = (uint32_t) UINT16_GET(l_buffer_inc); + l_buffer_inc += 2; + FAPI_INF("#V data = 0x%04X %-6d", iv_attr_mvpd_poundV_raw[i].frequency_mhz, + iv_attr_mvpd_poundV_raw[i].frequency_mhz); + iv_attr_mvpd_poundV_raw[i].vdd_mv= (uint32_t) UINT16_GET(l_buffer_inc); + FAPI_INF("#V data = 0x%04X %-6d", iv_attr_mvpd_poundV_raw[i].vdd_mv, + iv_attr_mvpd_poundV_raw[i].vdd_mv); + l_buffer_inc += 2; + iv_attr_mvpd_poundV_raw[i].idd_100ma= (uint32_t) UINT16_GET(l_buffer_inc); + FAPI_INF("#V data = 0x%04X %-6d", iv_attr_mvpd_poundV_raw[i].idd_100ma, + iv_attr_mvpd_poundV_raw[i].idd_100ma); + l_buffer_inc += 2; + iv_attr_mvpd_poundV_raw[i].vcs_mv= (uint32_t) UINT16_GET(l_buffer_inc); + FAPI_INF("#V data = 0x%04X %-6d", iv_attr_mvpd_poundV_raw[i].vcs_mv, + iv_attr_mvpd_poundV_raw[i].vcs_mv); + l_buffer_inc += 2; + iv_attr_mvpd_poundV_raw[i].ics_100ma= (uint32_t) UINT16_GET(l_buffer_inc); + FAPI_INF("#V data = 0x%04X %-6d", iv_attr_mvpd_poundV_raw[i].ics_100ma, + iv_attr_mvpd_poundV_raw[i].ics_100ma); + l_buffer_inc += 2; + } + + FAPI_TRY(chk_valid_poundv(false)); + + // on first chiplet put each bucket's data into attr_mvpd_voltage_control + if (first_chplt) + { + l_firstEqChiplet = l_eqChiplets[j]; + iv_poundV_bucket_id = bucket_id; + memcpy(&l_fstChlt_vpd_data,&iv_poundV_raw_data,sizeof(iv_poundV_raw_data)); + first_chplt = 0; + } + else + { + // on subsequent chiplets, check that frequencies are same for each operating point for each chiplet + if ( (iv_poundV_raw_data.nomFreq != l_fstChlt_vpd_data.nomFreq) || + (iv_poundV_raw_data.PSFreq != l_fstChlt_vpd_data.PSFreq) || + (iv_poundV_raw_data.turboFreq != l_fstChlt_vpd_data.turboFreq) || + (iv_poundV_raw_data.uTurboFreq != l_fstChlt_vpd_data.uTurboFreq) || + (iv_poundV_raw_data.pbFreq != l_fstChlt_vpd_data.pbFreq) ) + { + iv_pstates_enabled = false; + // Error out has Pstate and all dependent functions are suspious. + FAPI_ASSERT(false, + fapi2::PSTATE_MVPD_CHIPLET_VOLTAGE_NOT_EQUAL() + .set_CHIP_TARGET(iv_procChip) + .set_CURRENT_EQ_CHIPLET_TARGET(l_eqChiplets[j]) + .set_FIRST_EQ_CHIPLET_TARGET(l_firstEqChiplet) + .set_BUCKET(bucket_id), + "frequencies are not the same for each operating point for each chiplet"); + + } + } + + // check each bucket for max voltage and if max, put bucket's data into attr_mvpd_voltage_control + // + if ( (iv_poundV_raw_data.VddNomVltg > l_fstChlt_vpd_data.VddNomVltg) || + (iv_poundV_raw_data.VddPSVltg > l_fstChlt_vpd_data.VddPSVltg) || + (iv_poundV_raw_data.VddTurboVltg > l_fstChlt_vpd_data.VddTurboVltg) || + (iv_poundV_raw_data.VddUTurboVltg > l_fstChlt_vpd_data.VddUTurboVltg) || + (iv_poundV_raw_data.VdnPbVltg > l_fstChlt_vpd_data.VdnPbVltg) ) + { + memcpy(&l_fstChlt_vpd_data,&iv_poundV_raw_data,sizeof(iv_poundV_raw_data)); + iv_poundV_bucket_id = bucket_id; + } + + } // end for loop } + while(0); - FAPI_DBG("<< load_mvpd_operating_point"); - return fapi2::FAPI2_RC_SUCCESS; -} // end load_mvpd_operating_point - -/// ------------------------------------------------------------ -/// @brief Copy out of operating point set into a destination operating point -/// @param[in] &i_op_pt_set => reference to array of VpdOperatingPoint sets -/// @param[out] *dest[NUM_OP_POINTS] => pointer to destination VpdOperatingPoint structure -/// @param[in] i_frequency_step_khz => Base frequency value for pstate calculation -/// ------------------------------------------------------------ -fapi2::ReturnCode -get_operating_point ( const VpdOperatingPoint i_op_pt_set[NUM_VPD_PTS_SET][NUM_OP_POINTS], - uint32_t i_set, - VpdOperatingPoint* o_op_pt) -{ - FAPI_DBG(">> get_operating_point"); - for (uint32_t i = 0; i < NUM_OP_POINTS; i++) +fapi_try_exit: + + if (fapi2::current_err != fapi2::FAPI2_RC_SUCCESS) { - o_op_pt[i].frequency_mhz = i_op_pt_set[i_set][i].frequency_mhz; - o_op_pt[i].vdd_mv = i_op_pt_set[i_set][i].vdd_mv; - o_op_pt[i].idd_100ma = i_op_pt_set[i_set][i].idd_100ma; - o_op_pt[i].vcs_mv = i_op_pt_set[i_set][i].vcs_mv; - o_op_pt[i].ics_100ma = i_op_pt_set[i_set][i].ics_100ma; - o_op_pt[i].pstate = i_op_pt_set[i_set][i].pstate; + iv_pstates_enabled = false; } + free (l_buffer); - FAPI_DBG("<< get_operating_point"); - return fapi2::FAPI2_RC_SUCCESS; -} // end load_mvpd_operating_point + return fapi2::current_err; +} // end of get_mvpd_poundV -fapi2::ReturnCode -proc_get_vdm_parms (const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - const AttributeList* i_attr, - GP_VDMParmBlock* o_vdmpb) +/////////////////////////////////////////////////////////// +//////// get_extint_bias +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::get_extint_bias( ) { - FAPI_DBG(">> proc_get_vdm_parms"); + double freq_bias[NUM_OP_POINTS]; + double voltage_ext_vdd_bias[NUM_OP_POINTS]; + double voltage_ext_vcs_bias; + double voltage_ext_vdn_bias; - if (i_attr->attr_system_vdm_disable == fapi2::ENUM_ATTR_SYSTEM_VDM_DISABLE_OFF) + // Calculate the frequency multiplers and load the biases into the exported + // structure + for (auto p = 0; p < NUM_OP_POINTS; p++) { - const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_DROOP_SMALL_OVERRIDE, - FAPI_SYSTEM, - o_vdmpb->droop_small_override)); - FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_DROOP_LARGE_OVERRIDE, - FAPI_SYSTEM, - o_vdmpb->droop_large_override)); - FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_DROOP_EXTREME_OVERRIDE, - FAPI_SYSTEM, - o_vdmpb->droop_extreme_override)); - FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_OVERVOLT_OVERRIDE, - FAPI_SYSTEM, - o_vdmpb->overvolt_override)); - FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_FMIN_OVERRIDE_KHZ, - FAPI_SYSTEM, - o_vdmpb->fmin_override_khz)); - FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_FMAX_OVERRIDE_KHZ, - FAPI_SYSTEM, - o_vdmpb->fmax_override_khz)); - FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_VDM_VID_COMPARE_OVERRIDE_MV, - FAPI_SYSTEM, - o_vdmpb->vid_compare_override_mv)); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_DPLL_VDM_RESPONSE, - FAPI_SYSTEM, - o_vdmpb->vdm_response)); + switch (p) + { + case POWERSAVE: + iv_bias[p].frequency_hp = iv_attrs.attr_freq_bias_powersave; + iv_bias[p].vdd_ext_hp = iv_attrs.attr_voltage_ext_vdd_bias_powersave; + iv_bias[p].vdd_int_hp = iv_attrs.attr_voltage_int_vdd_bias_powersave; + + break; + case NOMINAL: + iv_bias[p].frequency_hp = iv_attrs.attr_freq_bias_nominal; + iv_bias[p].vdd_ext_hp = iv_attrs.attr_voltage_ext_vdd_bias_nominal; + iv_bias[p].vdd_int_hp = iv_attrs.attr_voltage_int_vdd_bias_nominal; + break; + case TURBO: + iv_bias[p].frequency_hp = iv_attrs.attr_freq_bias_turbo; + iv_bias[p].vdd_ext_hp = iv_attrs.attr_voltage_ext_vdd_bias_turbo; + iv_bias[p].vdd_int_hp = iv_attrs.attr_voltage_int_vdd_bias_turbo; + break; + case ULTRA: + iv_bias[p].frequency_hp = iv_attrs.attr_freq_bias_ultraturbo; + iv_bias[p].vdd_ext_hp = iv_attrs.attr_voltage_ext_vdd_bias_ultraturbo; + iv_bias[p].vdd_int_hp = iv_attrs.attr_voltage_int_vdd_bias_ultraturbo; + } + + iv_bias[p].vdn_ext_hp = iv_attrs.attr_voltage_ext_vdn_bias; + iv_bias[p].vcs_ext_hp = iv_attrs.attr_voltage_ext_vcs_bias; + + freq_bias[p] = calc_bias(iv_bias[p].frequency_hp); + voltage_ext_vdd_bias[p] = calc_bias(iv_bias[p].vdd_ext_hp); + + FAPI_DBG(" Biases[%d](bias): Freq=%f (%f%%); VDD=%f (%f%%)", + p, + freq_bias[p], iv_bias[p].frequency_hp/2, + voltage_ext_vdd_bias[p], iv_bias[p].vdd_ext_hp/2); } - else + + // VCS bias applied to all operating points + voltage_ext_vcs_bias = calc_bias(iv_attrs.attr_voltage_ext_vcs_bias); + + // VDN bias applied to all operating points + voltage_ext_vdn_bias = calc_bias(iv_attrs.attr_voltage_ext_vdn_bias); + + // Change the VPD frequency, VDD and VCS values with the bias multiplers + for (auto p = 0; p < NUM_OP_POINTS; p++) { - FAPI_DBG(" VDM is disabled. Skipping VDM attribute accesses"); + FAPI_DBG(" Orig values[%d](bias): Freq=%d (%f); VDD=%d (%f), VCS=%d (%f)", + p, + iv_attr_mvpd_poundV_biased[p].frequency_mhz, freq_bias[p], + iv_attr_mvpd_poundV_biased[p].vdd_mv, voltage_ext_vdd_bias[p], + iv_attr_mvpd_poundV_biased[p].vcs_mv, voltage_ext_vcs_bias); + + double freq_mhz = + (( (double)iv_attr_mvpd_poundV_biased[p].frequency_mhz) * freq_bias[p]); + double vdd_mv = + (( (double)iv_attr_mvpd_poundV_biased[p].vdd_mv) * voltage_ext_vdd_bias[p]); + double vcs_mv = + (( (double)iv_attr_mvpd_poundV_biased[p].vcs_mv) * voltage_ext_vcs_bias); + + iv_attr_mvpd_poundV_biased[p].frequency_mhz = (uint16_t)internal_floor(freq_mhz); + iv_attr_mvpd_poundV_biased[p].vdd_mv = (uint16_t)internal_ceil(vdd_mv); + iv_attr_mvpd_poundV_biased[p].vcs_mv = (uint16_t)(vcs_mv); + + FAPI_DBG(" Biased values[%d]: Freq=%f %d; VDD=%f %d, VCS=%f %d ", + p, + freq_mhz, iv_attr_mvpd_poundV_biased[p].frequency_mhz, + vdd_mv, iv_attr_mvpd_poundV_biased[p].vdd_mv, + vcs_mv, iv_attr_mvpd_poundV_biased[p].vcs_mv); } + // Power bus operating point + double vdn_mv = + (( (double)iv_attr_mvpd_poundV_biased[VPD_PV_POWERBUS].vdd_mv) * voltage_ext_vdn_bias); + + iv_attr_mvpd_poundV_biased[VPD_PV_POWERBUS].vdd_mv = (uint32_t)internal_ceil(vdn_mv); + + return fapi2::FAPI2_RC_SUCCESS; +} // end of get_extint_bias + + +/////////////////////////////////////////////////////////// +//////// apply_biased_values +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::apply_biased_values () +{ + FAPI_INF(">>>>>>>>>>>>> apply_biased_values"); + + do + { + // --------------------------------------------- + // process external and internal bias attributes + // --------------------------------------------- + FAPI_IMP("Apply Biasing to #V"); + + // Copy to Bias array + memcpy(iv_attr_mvpd_poundV_biased,iv_attr_mvpd_poundV_raw,sizeof(iv_attr_mvpd_poundV_raw)); + + for (int i = 0; i <= NUM_OP_POINTS - 1; i++) + { + FAPI_DBG("BIASED #V operating point (%s) f=%u v=%u i=%u v=%u i=%u", + pv_op_str[pv_op_order[i]], + iv_attr_mvpd_poundV_biased[pv_op_order[i]].frequency_mhz, + iv_attr_mvpd_poundV_biased[pv_op_order[i]].vdd_mv, + iv_attr_mvpd_poundV_biased[pv_op_order[i]].idd_100ma, + iv_attr_mvpd_poundV_biased[pv_op_order[i]].vcs_mv, + iv_attr_mvpd_poundV_biased[pv_op_order[i]].ics_100ma); + } + + FAPI_TRY(get_extint_bias(), + "Bias application function failed"); + + //Validating Bias values + FAPI_INF("Validate Biasd Voltage and Frequency values"); + + FAPI_TRY(chk_valid_poundv(BIASED)); + + FAPI_DBG("Pstate Base Frequency - after bias %X (%d)", + iv_attr_mvpd_poundV_biased[ULTRA].frequency_mhz * 1000, + iv_attr_mvpd_poundV_biased[ULTRA].frequency_mhz * 1000); + }while(0); + fapi_try_exit: - FAPI_DBG("<< proc_get_vdm_parms"); + FAPI_INF("<<<<<<<<<<<< apply_biased_values"); return fapi2::current_err; -} +} // end of apply_biased_values -fapi2::ReturnCode -proc_res_clock_setup ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - ResonantClockingSetup* o_resclk_setup, - const GlobalPstateParmBlock* i_gppb) +/////////////////////////////////////////////////////////// +//////// large_jump_defaults +/////////////////////////////////////////////////////////// +void PlatPmPPB::large_jump_defaults() { - FAPI_DBG(">> proc_res_clock_setup"); - uint8_t l_resclk_freq_index[RESCLK_FREQ_REGIONS]; - uint16_t l_step_delay_ns; - uint16_t l_l3_threshold_mv; - uint16_t l_steparray[RESCLK_STEPS]; - uint16_t l_resclk_freq_regions[RESCLK_FREQ_REGIONS]; - uint32_t l_ultra_turbo_freq_khz = revle32(i_gppb->reference_frequency_khz); + const float DEFAULT_VDM_DROP_PERCENT = 12.5; + const float DEFAULT_VDM_DROP_DIVISOR = 32; + float poundw_freq_drop_float = (DEFAULT_VDM_DROP_PERCENT/100)*DEFAULT_VDM_DROP_DIVISOR; + uint8_t poundw_freq_drop_value = (uint8_t)poundw_freq_drop_float; + FAPI_DBG ("DEFAULT_VDM_DROP_PERCENT = %6.3f%%; DEFAULT_VDM_DROP_DIVISOR = %6.3f; poundw_freq_drop_value = %f %X", + DEFAULT_VDM_DROP_PERCENT, + DEFAULT_VDM_DROP_DIVISOR, + poundw_freq_drop_float, + poundw_freq_drop_value); - const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + // N_S/N_L - each a nibble in a byte + iv_poundW_data.poundw[POWERSAVE].vdm_normal_freq_drop = poundw_freq_drop_value; + iv_poundW_data.poundw[NOMINAL].vdm_normal_freq_drop = poundw_freq_drop_value; - FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_SYSTEM_RESCLK_STEP_DELAY, - FAPI_SYSTEM, - l_step_delay_ns)); - o_resclk_setup->step_delay_ns = revle16(l_step_delay_ns); + FAPI_INF ("Using default Large Jump percentage (%6.3f%%) for N_L (%X) for both POWERSAVE and NOMINAL due to #W access failure ", + DEFAULT_VDM_DROP_PERCENT, + iv_poundW_data.poundw[POWERSAVE].vdm_normal_freq_drop); - // Resonant Clocking Frequency and Index arrays - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_FREQ_REGIONS, i_target, - l_resclk_freq_regions)); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_FREQ_REGION_INDEX, i_target, - l_resclk_freq_index)); + return; +} // end of large_jump_defaults - // Convert frequencies to pstates - for (uint8_t i = 0; i < RESCLK_FREQ_REGIONS; ++i) + +/////////////////////////////////////////////////////////// +//////// get_mvpd_poundW +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::get_mvpd_poundW (void) +{ + std::vector<fapi2::Target<fapi2::TARGET_TYPE_EQ>> l_eqChiplets; + fapi2::vdmData_t l_vdmBuf; + uint8_t selected_eq = 0; + uint8_t bucket_id = 0; + uint8_t version_id = 0; + const uint16_t VDM_VOLTAGE_IN_MV = 512; + const uint16_t MIN_VDM_VOLTAGE_IN_MV = 576; + const uint16_t VDM_GRANULARITY = 4; + uint32_t l_vdm_compare_raw_mv[NUM_OP_POINTS]; + uint32_t l_vdm_compare_biased_mv[NUM_OP_POINTS]; + + const char* pv_op_str[NUM_OP_POINTS] = PV_OP_ORDER_STR; + + FAPI_DBG(">> get_mvpd_poundW"); + + do { - Pstate pstate; - // Frequencies are given in MHz, convert to KHz - uint32_t freq_khz = static_cast<uint32_t>(l_resclk_freq_regions[i]) * 1000; - uint8_t idx = l_resclk_freq_index[i]; + FAPI_DBG("get_mvpd_poundW: VDM enable = %d, WOF enable %d", + is_vdm_enabled(), is_wof_enabled()); - // Frequencies need to be capped at Ultra-Turbo, frequencies less-than - // the Minimum can be ignored (because this table is walked from - // end-begin, and the frequencies are stored in ascending order, - // the "walk" will never pass the minimum frequency). - if (freq_khz > l_ultra_turbo_freq_khz) + // Exit if both VDM and WOF is disabled + if ((!is_vdm_enabled() && !is_wof_enabled())) { - freq_khz = l_ultra_turbo_freq_khz; + FAPI_INF(" get_mvpd_poundW: BOTH VDM and WOF are disabled. Skipping remaining checks"); + iv_vdm_enabled = false; + iv_wof_enabled = false; + iv_wov_underv_enabled = false; + iv_wov_overv_enabled = false; + break; + } - // Need to walk the table backwards to find the index for this frequency - for (uint8_t j = i; j >= 0; --j) + // Below fields for Nominal, Powersave, Turbo, Ultra Turbo + // I-VDD Nominal TDP AC current 2B + // I-VDD Nominal TDP DC current 2B + // Overvolt Threshold 0.5 Upper nibble of byte + // Small Threshold 0.5 Lower nibble of byte + // Large Threshold 0.5 Upper nibble of byte + // eXtreme Threshold 0.5 Lower nibble of byte + // Small Frequency Drop 1B + // Large Frequency Drop 1B + // ----------------------------------------------------------------- + l_eqChiplets = iv_procChip.getChildren<fapi2::TARGET_TYPE_EQ>(fapi2::TARGET_STATE_FUNCTIONAL); + + for (selected_eq = 0; selected_eq < l_eqChiplets.size(); selected_eq++) + { + uint8_t l_chipletNum = 0xFF; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_eqChiplets[selected_eq], l_chipletNum)); + + FAPI_INF("Chiplet Number => %u", l_chipletNum); + + // clear out buffer to known value before calling fapiGetMvpdField + memset(&l_vdmBuf, 0, sizeof(l_vdmBuf)); + + FAPI_TRY(p9_pm_get_poundw_bucket(l_eqChiplets[selected_eq], l_vdmBuf)); + + bucket_id = l_vdmBuf.bucketId; + version_id = l_vdmBuf.version; + + FAPI_INF("#W chiplet = %u bucket id = %u", l_chipletNum, bucket_id, version_id); + + //if we match with the bucket id, then we don't need to continue + if (iv_poundV_bucket_id == bucket_id) { - if (freq_khz >= (l_resclk_freq_regions[j] * 1000)) + break; + } + } + + uint8_t l_poundw_static_data = 0; + const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POUND_W_STATIC_DATA_ENABLE, + FAPI_SYSTEM, + l_poundw_static_data), + "Error from FAPI_ATTR_GET for attribute ATTR_POUND_W_STATIC_DATA_ENABLE"); + + if (l_poundw_static_data) + { + FAPI_INF("attribute ATTR_POUND_W_STATIC_DATA_ENABLE is set"); + // copy the data to the pound w structure from a hardcoded table + memcpy (&iv_poundW_data, &g_vpdData, sizeof (g_vpdData)); + } + else + { + FAPI_INF("attribute ATTR_POUND_W_STATIC_DATA_ENABLE is NOT set"); + // copy the data to the pound w structure from the actual VPD image + memcpy (&iv_poundW_data, l_vdmBuf.vdmData, sizeof (l_vdmBuf.vdmData)); + } + + //Re-ordering to Natural order + // When we read the data from VPD image the order will be N,PS,T,UT. + // But we need the order PS,N,T,UT.. hence we are swapping the data + // between PS and Nominal. + poundw_entry_t l_tmp_data; + memcpy (&l_tmp_data, + &(iv_poundW_data.poundw[VPD_PV_NOMINAL]), + sizeof (poundw_entry_t)); + + memcpy (&(iv_poundW_data.poundw[VPD_PV_NOMINAL]), + &(iv_poundW_data.poundw[VPD_PV_POWERSAVE]), + sizeof(poundw_entry_t)); + + memcpy (&(iv_poundW_data.poundw[VPD_PV_POWERSAVE]), + &l_tmp_data, + sizeof(poundw_entry_t)); + + // If the #W version is less than 3, validate Turbo VDM large threshold + // not larger than -32mV. This filters out parts that have bad VPD. If + // this check fails, log a recovered error, mark the VDMs disabled and + // break out of the reset of the checks. + uint32_t turbo_vdm_large_threshhold = + (iv_poundW_data.poundw[TURBO].vdm_large_extreme_thresholds >> 4) & 0x0F; + + FAPI_DBG("iv_poundW_data.poundw[TURBO].vdm_large_thresholds 0x%X; grey code index %d; max grey code index %d", + turbo_vdm_large_threshhold,g_GreyCodeIndexMapping[turbo_vdm_large_threshhold], + GREYCODE_INDEX_M32MV); + + if (version_id < FULLY_VALID_POUNDW_VERSION && + g_GreyCodeIndexMapping[turbo_vdm_large_threshhold] > GREYCODE_INDEX_M32MV) + { + iv_vdm_enabled = false; + + fapi2::ATTR_CHIP_EC_FEATURE_VDM_POUNDW_SUPPRESS_ERROR_Type l_suppress_pdw_error; + FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_VDM_POUNDW_SUPPRESS_ERROR, + iv_procChip, + l_suppress_pdw_error); + + if (l_suppress_pdw_error) + { + FAPI_INF("VDM #W ERROR: Turbo Large Threshold less than -32mV. Indicates bad VPD so VDMs being disabled and pressing on"); + } + else + { + FAPI_ASSERT_NOEXIT(false, + fapi2::PSTATE_PB_POUND_W_VERY_INVALID_VDM_DATA(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_CHIP_TARGET(iv_procChip) + .set_TURBO_LARGE_THRESHOLD(iv_poundW_data.poundw[TURBO].vdm_large_extreme_thresholds), + "VDM #W ERROR: Turbo Large Threshold less than -32mV. Indicates bad VPD so VDMs being disabled and pressing on"); + fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; + } + + break; + + } + + // Validate the WOF content is non-zero if WOF is enabled + if (is_wof_enabled()) + { + bool b_tdp_ac = true; + bool b_tdp_dc = true; + // Check that the WOF currents are non-zero + for (auto p = 0; p < NUM_OP_POINTS; ++p) + { + FAPI_INF("%s ivdd_tdp_ac_current %5d (10mA) %6.2f (A)", + pv_op_str[p], + revle16(iv_poundW_data.poundw[p].ivdd_tdp_ac_current_10ma), + ((double)revle16(iv_poundW_data.poundw[p].ivdd_tdp_ac_current_10ma)/100)); + FAPI_INF("%s ivdd_tdp_dc_current %5d (10mA) %6.2f (A)", + pv_op_str[p], + revle16(iv_poundW_data.poundw[p].ivdd_tdp_dc_current_10ma), + ((double)revle16(iv_poundW_data.poundw[p].ivdd_tdp_dc_current_10ma)/100)); + + if (!iv_poundW_data.poundw[p].ivdd_tdp_ac_current_10ma) { - idx = l_resclk_freq_index[j]; - break; + FAPI_ERR("%s.ivdd_tdp_ac_current_10ma is zero!!!", + pv_op_str[p]); + b_tdp_ac = false; + iv_wof_enabled = false; + + } + if (!iv_poundW_data.poundw[p].ivdd_tdp_dc_current_10ma) + { + FAPI_ERR("%s.ivdd_tdp_dc_current_10ma is zero!!!", + pv_op_str[p]); + b_tdp_dc = false; + iv_wof_enabled = false; } } + + FAPI_ASSERT_NOEXIT(b_tdp_ac, + fapi2::PSTATE_PB_POUND_W_TDP_IAC_INVALID(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_CHIP_TARGET(iv_procChip) + .set_EQ_TARGET(l_eqChiplets[selected_eq]) + .set_NOMINAL_TDP_IAC(iv_poundW_data.poundw[NOMINAL].ivdd_tdp_dc_current_10ma) + .set_POWERSAVE_TDP_IAC(iv_poundW_data.poundw[POWERSAVE].ivdd_tdp_dc_current_10ma) + .set_TURBO_TDP_IAC(iv_poundW_data.poundw[TURBO].ivdd_tdp_dc_current_10ma) + .set_ULTRA_TDP_IAC(iv_poundW_data.poundw[ULTRA].ivdd_tdp_dc_current_10ma), + "Pstate Parameter Block #W : one or more Idd TDP AC values are zero"); + FAPI_ASSERT_NOEXIT(b_tdp_dc, + fapi2::PSTATE_PB_POUND_W_TDP_IDC_INVALID(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_CHIP_TARGET(iv_procChip) + .set_EQ_TARGET(l_eqChiplets[selected_eq]) + .set_NOMINAL_TDP_IDC(iv_poundW_data.poundw[NOMINAL].ivdd_tdp_dc_current_10ma) + .set_POWERSAVE_TDP_IDC(iv_poundW_data.poundw[POWERSAVE].ivdd_tdp_dc_current_10ma) + .set_TURBO_TDP_IDC(iv_poundW_data.poundw[TURBO].ivdd_tdp_dc_current_10ma) + .set_ULTRA_TDP_IDC(iv_poundW_data.poundw[ULTRA].ivdd_tdp_dc_current_10ma), + "o_dataPstate Parameter Block #W : one or more Idd TDP DC values are zero"); + + // Set the return code to success to keep going. + fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; } - int rc = freq2pState(i_gppb, freq_khz, &pstate); + // The rest of the processing here is all checking of the VDM content + // within #W. If VDMs are not enabled (or supported), skip all of it + if (!is_vdm_enabled()) + { + FAPI_INF(" get_mvpd_poundW: VDM is disabled. Skipping remaining checks"); + iv_vdm_enabled = false; + break; + } - switch (rc) + for (int i = 0; i < NUM_OP_POINTS; ++i) { - case -PSTATE_LT_PSTATE_MIN: - FAPI_INF("Resonant clock frequency %d KHz was clipped to Pstate 0", - freq_khz); + l_vdm_compare_raw_mv[i] = VDM_VOLTAGE_IN_MV + (iv_poundW_data.poundw[i].vdm_vid_compare_ivid << 2); + FAPI_INF("%10s vdm_vid_compare_ivid %3d => %d mv", + pv_op_str[i], + iv_poundW_data.poundw[i].vdm_vid_compare_ivid, + l_vdm_compare_raw_mv[i]); + } + + //Validation of VPD Data + //If all VID compares are zero then use #V VDD voltage to populate local + //data structure..So that we make progress in lab with early hardware + if ( !(iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_ivid) && + !(iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_ivid) && + !(iv_poundW_data.poundw[TURBO].vdm_vid_compare_ivid) && + !(iv_poundW_data.poundw[ULTRA].vdm_vid_compare_ivid)) + { + //vdm_vid_compare_ivid will be in ivid units (eg HEX((Compare + //Voltage (mv) - 512mV)/4mV). + iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_ivid = + (iv_poundV_raw_data.VddNomVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY; + iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_ivid = + (iv_poundV_raw_data.VddPSVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY; + iv_poundW_data.poundw[TURBO].vdm_vid_compare_ivid = + (iv_poundV_raw_data.VddTurboVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY; + iv_poundW_data.poundw[ULTRA].vdm_vid_compare_ivid = + (iv_poundV_raw_data.VddUTurboVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY; + }//if any one of the VID compares are zero, then need to fail because of BAD VPD image. + else if ( !(iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_ivid) || + !(iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_ivid) || + !(iv_poundW_data.poundw[TURBO].vdm_vid_compare_ivid) || + !(iv_poundW_data.poundw[ULTRA].vdm_vid_compare_ivid)) + { + iv_vdm_enabled = false; + FAPI_ASSERT_NOEXIT(false, + fapi2::PSTATE_PB_POUND_W_INVALID_VID_VALUE(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_CHIP_TARGET(iv_procChip) + .set_EQ_TARGET(l_eqChiplets[selected_eq]) + .set_NOMINAL_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_ivid) + .set_POWERSAVE_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_ivid) + .set_TURBO_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[TURBO].vdm_vid_compare_ivid) + .set_ULTRA_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[ULTRA].vdm_vid_compare_ivid), + "Pstate Parameter Block #W : one of the VID compare value is zero"); + break; + } + + // validate vid values + bool l_compare_vid_value_state = 1; + VALIDATE_VID_VALUES (iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_ivid, + iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_ivid, + iv_poundW_data.poundw[TURBO].vdm_vid_compare_ivid, + iv_poundW_data.poundw[ULTRA].vdm_vid_compare_ivid, + l_compare_vid_value_state); + + if (!l_compare_vid_value_state) + { + iv_vdm_enabled = false; + FAPI_ASSERT_NOEXIT(false, + fapi2::PSTATE_PB_POUND_W_INVALID_VID_ORDER(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_CHIP_TARGET(iv_procChip) + .set_EQ_TARGET(l_eqChiplets[selected_eq]) + .set_NOMINAL_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[NOMINAL].vdm_vid_compare_ivid) + .set_POWERSAVE_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[POWERSAVE].vdm_vid_compare_ivid) + .set_TURBO_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[TURBO].vdm_vid_compare_ivid) + .set_ULTRA_VID_COMPARE_IVID_VALUE(iv_poundW_data.poundw[ULTRA].vdm_vid_compare_ivid), + "Pstate Parameter Block #W VID compare data are not in increasing order"); + break; + } + + // validate threshold values + bool l_threshold_value_state = 1; + + for (uint8_t p = 0; p < NUM_OP_POINTS; ++p) + { + FAPI_INF("iv_poundW_data.poundw[%d].vdm_overvolt_thresholds 0x%X", + p,(iv_poundW_data.poundw[p].vdm_overvolt_small_thresholds >> 4) & 0x0F); + FAPI_INF("iv_poundW_data.poundw[%d].vdm_small_thresholds 0x%X", + p,(iv_poundW_data.poundw[p].vdm_overvolt_small_thresholds ) & 0x0F); + FAPI_INF("iv_poundW_data.poundw[%d].vdm_large_thresholds 0x%X", + p,(iv_poundW_data.poundw[p].vdm_large_extreme_thresholds >> 4) & 0x0F); + FAPI_INF("iv_poundW_data.poundw[%d].vdm_extreme_thresholds 0x%X", + p,(iv_poundW_data.poundw[p].vdm_large_extreme_thresholds) & 0x0F); + VALIDATE_THRESHOLD_VALUES(((iv_poundW_data.poundw[p].vdm_overvolt_small_thresholds >> 4) & 0x0F), // overvolt + ((iv_poundW_data.poundw[p].vdm_overvolt_small_thresholds) & 0x0F), //small + ((iv_poundW_data.poundw[p].vdm_large_extreme_thresholds >> 4) & 0x0F), //large + ((iv_poundW_data.poundw[p].vdm_large_extreme_thresholds) & 0x0F), //extreme + l_threshold_value_state); + + if (!l_threshold_value_state) + { + iv_vdm_enabled = false; + FAPI_ASSERT_NOEXIT(false, + fapi2::PSTATE_PB_POUND_W_INVALID_THRESHOLD_VALUE(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_CHIP_TARGET(iv_procChip) + .set_EQ_TARGET(l_eqChiplets[selected_eq]) + .set_OP_POINT_TYPE(p) + .set_VDM_OVERVOLT((iv_poundW_data.poundw[p].vdm_overvolt_small_thresholds >> 4) & 0x0F) + .set_VDM_SMALL(iv_poundW_data.poundw[p].vdm_overvolt_small_thresholds & 0x0F) + .set_VDM_EXTREME((iv_poundW_data.poundw[p].vdm_large_extreme_thresholds >> 4) & 0x0F) + .set_VDM_LARGE((iv_poundW_data.poundw[p].vdm_large_extreme_thresholds) & 0x0F), + "Pstate Parameter Block #W VDM threshold data are invalid"); break; + } + } - case -PSTATE_GT_PSTATE_MAX: - FAPI_INF("Resonant clock Frequency %d KHz is outside the range that can be represented" - " by a Pstate with a base frequency of %d KHz and step size %d KHz", - freq_khz, - l_ultra_turbo_freq_khz, - revle32(i_gppb->frequency_step_khz)); - FAPI_INF("Pstate is set to %X (%d)", pstate); + bool l_frequency_value_state = 1; + + for (uint8_t p = 0; p < NUM_OP_POINTS; ++p) + { + // These fields are 4 bits wide, and stored in a uint8, hence the shifting + // N_S, N_L, L_S, S_N + FAPI_INF("iv_poundW_data.poundw[%d] VDM_FREQ_DROP N_S = %d", + p, ((iv_poundW_data.poundw[p].vdm_normal_freq_drop >> 4) & 0x0F)); + FAPI_INF("iv_poundW_data.poundw[%d] VDM_FREQ_DROP N_L = %d", + p, ((iv_poundW_data.poundw[p].vdm_normal_freq_drop) & 0x0F)); + FAPI_INF("iv_poundW_data.poundw[%d] VDM_FREQ_RETURN L_S = %d", + p, ((iv_poundW_data.poundw[p].vdm_normal_freq_return >> 4) & 0x0F)); + FAPI_INF("iv_poundW_data.poundw[%d] VDM_FREQ_RETURN S_N = %d", + p, ((iv_poundW_data.poundw[p].vdm_normal_freq_return) & 0x0F)); + + VALIDATE_FREQUENCY_DROP_VALUES(((iv_poundW_data.poundw[p].vdm_normal_freq_drop) & 0x0F), // N_L + ((iv_poundW_data.poundw[p].vdm_normal_freq_drop >> 4) & 0x0F), // N_S + ((iv_poundW_data.poundw[p].vdm_normal_freq_return >> 4) & 0x0F), // L_S + ((iv_poundW_data.poundw[p].vdm_normal_freq_return) & 0x0F), // S_N + l_frequency_value_state); + + if (!l_frequency_value_state) + { + iv_vdm_enabled = false; + FAPI_ASSERT_NOEXIT(false, + fapi2::PSTATE_PB_POUND_W_INVALID_FREQ_DROP_VALUE(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_CHIP_TARGET(iv_procChip) + .set_EQ_TARGET(l_eqChiplets[selected_eq]) + .set_OP_POINT_TYPE(p) + .set_VDM_NORMAL_SMALL((iv_poundW_data.poundw[p].vdm_normal_freq_drop >> 4) & 0x0F) + .set_VDM_NORMAL_LARGE(iv_poundW_data.poundw[p].vdm_normal_freq_drop & 0x0F) + .set_VDM_LARGE_SMALL((iv_poundW_data.poundw[p].vdm_normal_freq_return >> 4) & 0x0F) + .set_VDM_SMALL_NORMAL((iv_poundW_data.poundw[p].vdm_normal_freq_return) & 0x0F), + "Pstate Parameter Block #W VDM frequency drop data are invalid"); break; + } } - o_resclk_setup->resclk_freq[i] = pstate; - o_resclk_setup->resclk_index[i] = idx; + //Biased compare vid data + fapi2::ATTR_VDM_VID_COMPARE_BIAS_0P5PCT_Type l_bias_value; - FAPI_DBG("Resclk: freq = %d kHz; pstate = %d; idx = %d", freq_khz, pstate, idx); - } - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_L3_VALUE, i_target, - o_resclk_setup->l3_steparray)); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDM_VID_COMPARE_BIAS_0P5PCT, + iv_procChip, + l_bias_value), + "Error from FAPI_ATTR_GET for attribute ATTR_VDM_VID_COMPARE_BIAS_0P5PCT"); + + float l_pound_w_points[NUM_OP_POINTS]; - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_L3_VOLTAGE_THRESHOLD_MV, i_target, - l_l3_threshold_mv)); - o_resclk_setup->l3_threshold_mv = revle16(l_l3_threshold_mv); + for (uint8_t i = 0; i < NUM_OP_POINTS; i++) + { + l_pound_w_points[i] = calc_bias(l_bias_value[i]); + l_vdm_compare_biased_mv[i] = internal_ceil( (l_vdm_compare_raw_mv[i] * l_pound_w_points[i])); + + if (l_vdm_compare_biased_mv[i] < MIN_VDM_VOLTAGE_IN_MV) + { + l_vdm_compare_biased_mv[i] = MIN_VDM_VOLTAGE_IN_MV; + } + + iv_poundW_data.poundw[i].vdm_vid_compare_ivid = + (l_vdm_compare_biased_mv[i] - VDM_VOLTAGE_IN_MV) >> 2; + + FAPI_INF("vdm_vid_compare_ivid %x %x, %x", + iv_poundW_data.poundw[i].vdm_vid_compare_ivid, + iv_poundW_data.poundw[i].vdm_vid_compare_ivid, + l_pound_w_points[i]); + } + //If we have reached this point, that means VDM is ok to be enabled. Only then we try to + //enable wov undervolting + if ( ((iv_poundW_data.undervolt_tested == 1) || (iv_attrs.attr_wov_underv_force == 1)) && + is_wov_underv_enabled() == 1) { + iv_wov_underv_enabled = true; + FAPI_INF("UNDERV_TESTED or UNDERV_FORCE set to 1"); + } else{ + iv_wov_underv_enabled = false; + FAPI_INF("UNDERV_TESTED and UNDERV_FORCE set to 0"); + } - // Resonant Clocking Step array - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_VALUE, i_target, - l_steparray)); - for (uint8_t i = 0; i < RESCLK_STEPS; i++) - { - o_resclk_setup->steparray[i].value = revle16(l_steparray[i]); } + while(0); + fapi_try_exit: - FAPI_DBG("<< proc_res_clock_setup"); - return fapi2::current_err; -} -fapi2::ReturnCode -proc_get_ivrm_parms ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - const AttributeList* i_attr, - IvrmParmBlock* o_ivrmpb, - PSTATE_attribute_state* o_state) -{ - FAPI_DBG(">> proc_get_ivrm_parms"); + // Given #W has both VDM and WOF content, a failure needs to disable both + if (fapi2::current_err != fapi2::FAPI2_RC_SUCCESS) + { + iv_vdm_enabled = false; + iv_wof_enabled = false; + iv_wov_underv_enabled = false; + iv_wov_overv_enabled = false; + } - if (i_attr->attr_system_ivrm_disable == fapi2::ENUM_ATTR_SYSTEM_IVRM_DISABLE_OFF) + if (!(iv_vdm_enabled)) { - const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + // With VDMs disabled, we have to ensure that we have some Large + // Jump values to compute the safe mode frequency and voltage as some + // part sorts assume that uplift in their guardbands. As systems are + // offered assuming VDM operability which elevates the floor, default + // values are needed. + large_jump_defaults(); + } + FAPI_DBG("<< get_mvpd_poundW"); + return fapi2::current_err; - FAPI_INF(">> proc_get_ivrm_parms"); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IVRM_STRENGTH_LOOKUP, FAPI_SYSTEM, - o_ivrmpb->strength_lookup)); +} // end of get_mvpd_poundW - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IVRM_VIN_MULTIPLIER, FAPI_SYSTEM, - o_ivrmpb->vin_multiplier)); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IVRM_VIN_MAX_MV, FAPI_SYSTEM, - o_ivrmpb->vin_max_mv)); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IVRM_STEP_DELAY_NS, FAPI_SYSTEM, - o_ivrmpb->step_delay_ns)); +/////////////////////////////////////////////////////////// +//////// iddq_print +/////////////////////////////////////////////////////////// +void iddq_print(IddqTable* i_iddqt) +{ + uint32_t i, j; + const char* idd_meas_str[IDDQ_MEASUREMENTS] = IDDQ_ARRAY_VOLTAGES_STR; + char l_buffer_str[1024]; // Temporary formatting string buffer + char l_line_str[1024]; // Formatted output line string - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IVRM_STABILIZATION_DELAY_NS, FAPI_SYSTEM, - o_ivrmpb->stablization_delay_ns)); + static const uint32_t IDDQ_DESC_SIZE = 56; + static const uint32_t IDDQ_QUAD_SIZE = IDDQ_DESC_SIZE - + strlen("Quad X:"); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IVRM_DEADZONE_MV, FAPI_SYSTEM, - o_ivrmpb->deadzone_mv)); + FAPI_INF("IDDQ"); + // Put out the endian-corrected scalars - // This is presently hardcoded to FALSE until validation code is in - // place to ensure turning IVRM on is a good thing. This attribute write is - // needed to allocate the HWP attribute in Cronus. + // get IQ version and advance pointer 1-byte + FAPI_INF(" IDDQ Version Number = %u", i_iddqt->iddq_version); + FAPI_INF(" Sort Info: Good Quads = %02d Good Cores = %02d Good Caches = %02d", + i_iddqt->good_quads_per_sort, + i_iddqt->good_normal_cores_per_sort, + i_iddqt->good_caches_per_sort); - // Indicate that IVRM is good to be enabled (or not) - FAPI_INF(" NOTE: This level of code is forcing the iVRM to OFF"); - { - fapi2::ATTR_IVRM_ENABLED_Type l_ivrm_enabled = - (fapi2::ATTR_IVRM_ENABLED_Type)fapi2::ENUM_ATTR_IVRM_ENABLED_FALSE; - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_IVRM_ENABLED, i_target, l_ivrm_enabled)); - } + // get number of good normal cores in each quad + strcpy(l_line_str, " Good normal cores:"); + strcpy(l_buffer_str, ""); + + for (i = 0; i < MAXIMUM_QUADS; i++) + { + sprintf(l_buffer_str, " Quad %d = %u ", i, i_iddqt->good_normal_cores[i]); + strcat(l_line_str, l_buffer_str); } - else + + FAPI_INF("%s", l_line_str); + + // get number of good caches in each quad + strcpy(l_line_str, " Good caches: "); + strcpy(l_buffer_str, ""); + + for (i = 0; i < MAXIMUM_QUADS; i++) { - FAPI_DBG(" IVRM is disabled. Skipping IVRM attribute accesses"); - o_state->iv_ivrm_enabled = false; + sprintf(l_buffer_str, " Quad %d = %u ", i, i_iddqt->good_caches[i]); + strcat(l_line_str, l_buffer_str); } -fapi_try_exit: - FAPI_DBG("<< proc_get_ivrm_parms"); - return fapi2::current_err; + FAPI_INF("%s", l_line_str); -} + // get RDP TO TDP scalling factor + FAPI_INF(" RDP TO TDP scalling factor = %u", revle16(i_iddqt->rdp_to_tdp_scale_factor)); + // get WOF IDDQ margin factor + FAPI_INF(" WOF IDDQ margin factor = %u", revle16(i_iddqt->wof_iddq_margin_factor)); -// Apply system parameters to a VPD value -uint32_t -sysparm_uplift(const uint32_t i_vpd_mv, - const uint32_t i_vpd_ma, - const uint32_t i_loadline_uohm, - const uint32_t i_distloss_uohm, - const uint32_t i_distoffset_uohm) -{ + // get VDD Temperature scaling factor + FAPI_INF(" VDD Temperature scaling factor = %u", revle16(i_iddqt->vdd_temperature_scale_factor)); - double l_mv = ((double)i_vpd_mv + // mV - ( - // mA*uOhm/1000 -> uV - ((double)(i_vpd_ma * (i_loadline_uohm + i_distloss_uohm)) / 1000 + - // uv - (double)i_distoffset_uohm) - ) / 1000); // uV -> mV - uint32_t l_result = (uint32_t)l_mv; - FAPI_DBG(" system_uplift_mv: i_vpd_mv=%d; i_vpd_ma=%d; i_loadline_uohm=%d " - "i_distloss_uohm = %d i_distoffset_uohm = %d l_mv = %5.3f l_result = %d" , - i_vpd_mv, - i_vpd_ma, - i_loadline_uohm, - i_distloss_uohm, - i_distoffset_uohm, - l_mv, - l_result); - - return revle32(l_result); -} + // get VDN Temperature scaling factor + FAPI_INF(" VDN Temperature scaling factor = %u", revle16(i_iddqt->vdn_temperature_scale_factor)); -// Bias Adjust a voltage data value using a 1/2 percent bias amount. Value -// is always taken to the higher integer value. -uint32_t -bias_adjust_mv(const uint32_t i_value, - const int32_t i_bias_0p5pct) -{ - double l_mult = calc_bias(i_bias_0p5pct); - double l_biased_value = (double)i_value * l_mult; - double l_ceiling = internal_ceil(l_biased_value); - uint32_t l_result = (uint32_t)l_ceiling; - FAPI_DBG(" bias_adjust_mv: i_value=%d; mult=%5.3f; biased value=%3.0f ceiling = %3.0f result = %d", - i_value, - l_mult, - l_biased_value, - l_ceiling, - l_result); - return revle32(l_result); -} + // All IQ IDDQ measurements are at 5mA resolution. The OCC wants to + // consume these at 1mA values. thus, all values are multiplied by + // 5 upon installation into the paramater block. + static const uint32_t CONST_5MA_1MA = 5; + FAPI_INF(" IDDQ data is converted 5mA units to 1mA units"); -// Bias Adjust a frequency data value using a 1/2 percent bias amount. Value -// is always taken to the lower integer value. -uint32_t -bias_adjust_mhz(const uint32_t i_value, - const int32_t i_bias_0p5pct) -{ - double l_mult = calc_bias(i_bias_0p5pct); - double l_biased_value = (double)i_value * l_mult; - FAPI_DBG(" bias_adjust_mhz: i_value=%d; mult=%5.3f; biased value=%3.0f", - i_value, - l_mult, - l_biased_value); - return revle32((uint32_t)internal_floor(l_biased_value)); -} + // Put out the measurement voltages to the trace. + strcpy(l_line_str, " Measurement voltages:"); + sprintf(l_buffer_str, "%-*s ", IDDQ_DESC_SIZE, l_line_str); + strcpy(l_line_str, l_buffer_str); + strcpy(l_buffer_str, ""); -// -// p9_pstate_compute_vpd_pts -// -void p9_pstate_compute_vpd_pts(VpdOperatingPoint (*o_operating_points)[NUM_OP_POINTS], - GlobalPstateParmBlock* i_gppb, - VpdOperatingPoint* i_raw_vpd_pts) -{ - int p = 0; + for (i = 0; i < IDDQ_MEASUREMENTS; i++) + { + sprintf(l_buffer_str, " %*sV ", 5, idd_meas_str[i]); + strcat(l_line_str, l_buffer_str); + } - uint32_t l_vdd_loadline_uohm = revle32(i_gppb->vdd_sysparm.loadline_uohm); - uint32_t l_vdd_distloss_uohm = revle32(i_gppb->vdd_sysparm.distloss_uohm); - uint32_t l_vdd_distoffset_uv = revle32(i_gppb->vdd_sysparm.distoffset_uv); - uint32_t l_vcs_loadline_uohm = revle32(i_gppb->vcs_sysparm.loadline_uohm); - uint32_t l_vcs_distloss_uohm = revle32(i_gppb->vcs_sysparm.distloss_uohm); - uint32_t l_vcs_distoffset_uv = revle32(i_gppb->vcs_sysparm.distoffset_uv); + FAPI_INF("%s", l_line_str); - //RAW POINTS. We just copy them as is - for (p = 0; p < NUM_OP_POINTS; p++) +#define IDDQ_CURRENT_EXTRACT(_member) \ + { \ + uint16_t _temp = revle16(i_iddqt->_member) * CONST_5MA_1MA; \ + sprintf(l_buffer_str, " %6.3f ", (double)_temp/1000); \ + strcat(l_line_str, l_buffer_str); \ + } + +// Temps are all 1B quantities. Not endianess issues. +#define IDDQ_TEMP_EXTRACT(_member) \ + sprintf(l_buffer_str, " %4.1f ", ((double)i_iddqt->_member)/2); \ + strcat(l_line_str, l_buffer_str); + +#define IDDQ_TRACE(string, size) \ + strcpy(l_line_str, string); \ + sprintf(l_buffer_str, "%-*s", size, l_line_str);\ + strcpy(l_line_str, l_buffer_str); \ + strcpy(l_buffer_str, ""); + + // get IVDDQ measurements with all good cores ON + IDDQ_TRACE (" IDDQ all good cores ON:", IDDQ_DESC_SIZE); + + for (i = 0; i < IDDQ_MEASUREMENTS; i++) { - o_operating_points[VPD_PT_SET_RAW][p].vdd_mv = i_raw_vpd_pts[p].vdd_mv; - o_operating_points[VPD_PT_SET_RAW][p].vcs_mv = i_raw_vpd_pts[p].vcs_mv; - o_operating_points[VPD_PT_SET_RAW][p].idd_100ma = i_raw_vpd_pts[p].idd_100ma; - o_operating_points[VPD_PT_SET_RAW][p].ics_100ma = i_raw_vpd_pts[p].ics_100ma; - o_operating_points[VPD_PT_SET_RAW][p].frequency_mhz = i_raw_vpd_pts[p].frequency_mhz; - o_operating_points[VPD_PT_SET_RAW][p].pstate = i_raw_vpd_pts[p].pstate; + IDDQ_CURRENT_EXTRACT(ivdd_all_good_cores_on_caches_on[i]); + } - FAPI_DBG("GP: OpPoint=[%d][%d], PS=%3d, Freq=%3X (%4d), Vdd=%3X (%4d)", - VPD_PT_SET_RAW, p, - o_operating_points[VPD_PT_SET_RAW][p].pstate, - revle32(o_operating_points[VPD_PT_SET_RAW][p].frequency_mhz), - revle32(o_operating_points[VPD_PT_SET_RAW][p].frequency_mhz), - revle32(o_operating_points[VPD_PT_SET_RAW][p].vdd_mv), - revle32(o_operating_points[VPD_PT_SET_RAW][p].vdd_mv)); + FAPI_INF("%s", l_line_str); + + // get IVDDQ measurements with all cores and caches OFF + IDDQ_TRACE (" IVDDQ all cores and caches OFF:", IDDQ_DESC_SIZE); + + for (i = 0; i < IDDQ_MEASUREMENTS; i++) + { + IDDQ_CURRENT_EXTRACT(ivdd_all_cores_off_caches_off[i]); } - //SYSTEM PARAMS APPLIED POINTS - for (p = 0; p < NUM_OP_POINTS; p++) + FAPI_INF("%s", l_line_str);; + + // get IVDDQ measurements with all good cores OFF and caches ON + IDDQ_TRACE (" IVDDQ all good cores OFF and caches ON:", IDDQ_DESC_SIZE); + + for (i = 0; i < IDDQ_MEASUREMENTS; i++) { - uint32_t l_vdd_mv = revle32(i_gppb->operating_points[p].vdd_mv); - uint32_t l_idd_ma = revle32(i_gppb->operating_points[p].idd_100ma * 100); - uint32_t l_vcs_mv = revle32(i_gppb->operating_points[p].vcs_mv); - uint32_t l_ics_ma = revle32(i_gppb->operating_points[p].ics_100ma * 100); + IDDQ_CURRENT_EXTRACT(ivdd_all_good_cores_off_good_caches_on[i]); + } - o_operating_points[VPD_PT_SET_SYSP][p].vdd_mv = - sysparm_uplift(l_vdd_mv, - l_idd_ma, - l_vdd_loadline_uohm, - l_vdd_distloss_uohm, - l_vdd_distoffset_uv); + FAPI_INF("%s", l_line_str); + // get IVDDQ measurements with all good cores in each quad + for (i = 0; i < MAXIMUM_QUADS; i++) + { + IDDQ_TRACE (" IVDDQ all good cores ON and caches ON ", IDDQ_QUAD_SIZE); + sprintf(l_buffer_str, "Quad %d:", i); + strcat(l_line_str, l_buffer_str); - o_operating_points[VPD_PT_SET_SYSP][p].vcs_mv = - sysparm_uplift(l_vcs_mv, - l_ics_ma, - l_vcs_loadline_uohm, - l_vcs_distloss_uohm, - l_vcs_distoffset_uv); + for (j = 0; j < IDDQ_MEASUREMENTS; j++) + { + IDDQ_CURRENT_EXTRACT(ivdd_quad_good_cores_on_good_caches_on[i][j]); + } - o_operating_points[VPD_PT_SET_SYSP][p].idd_100ma = - i_gppb->operating_points[p].idd_100ma; - o_operating_points[VPD_PT_SET_SYSP][p].ics_100ma = - i_gppb->operating_points[p].ics_100ma; - o_operating_points[VPD_PT_SET_SYSP][p].frequency_mhz = - i_gppb->operating_points[p].frequency_mhz; - o_operating_points[VPD_PT_SET_SYSP][p].pstate = - i_gppb->operating_points[p].pstate; + FAPI_INF("%s", l_line_str); + } - FAPI_DBG("SP: OpPoint=[%d][%d], PS=%3d, Freq=%3X (%4d), Vdd=%3X (%4d)", - VPD_PT_SET_RAW, p, - o_operating_points[VPD_PT_SET_SYSP][p].pstate, - revle32(o_operating_points[VPD_PT_SET_SYSP][p].frequency_mhz), - revle32(o_operating_points[VPD_PT_SET_SYSP][p].frequency_mhz), - revle32(o_operating_points[VPD_PT_SET_SYSP][p].vdd_mv), - revle32(o_operating_points[VPD_PT_SET_SYSP][p].vdd_mv)); + // get IVDN data + IDDQ_TRACE (" IVDN", IDDQ_DESC_SIZE); + + for (i = 0; i < IDDQ_MEASUREMENTS; i++) + { + IDDQ_CURRENT_EXTRACT(ivdn[i]); } - //BIASED POINTS - for (p = 0; p < NUM_OP_POINTS; p++) + FAPI_INF("%s", l_line_str); + + // get average temperature measurements with all good cores ON + IDDQ_TRACE (" Average temp all good cores ON:",IDDQ_DESC_SIZE); + + for (i = 0; i < IDDQ_MEASUREMENTS; i++) { - uint32_t l_frequency_mhz = revle32(i_gppb->operating_points[p].frequency_mhz); - uint32_t l_vdd_mv = revle32(i_gppb->operating_points[p].vdd_mv); - uint32_t l_vcs_mv = revle32(i_gppb->operating_points[p].vcs_mv); + IDDQ_TEMP_EXTRACT(avgtemp_all_good_cores_on[i]); + } + + FAPI_INF("%s", l_line_str); + + // get average temperature measurements with all cores and caches OFF + IDDQ_TRACE (" Average temp all cores OFF, caches OFF:", IDDQ_DESC_SIZE); - o_operating_points[VPD_PT_SET_BIASED][p].vdd_mv = - bias_adjust_mv(l_vdd_mv, i_gppb->ext_biases[p].vdd_ext_hp); + for (i = 0; i < IDDQ_MEASUREMENTS; i++) + { + IDDQ_TEMP_EXTRACT(avgtemp_all_cores_off_caches_off[i]); + } - o_operating_points[VPD_PT_SET_BIASED][p].vcs_mv = - bias_adjust_mv(l_vcs_mv, i_gppb->ext_biases[p].vcs_ext_hp); + FAPI_INF("%s", l_line_str); - o_operating_points[VPD_PT_SET_BIASED][p].frequency_mhz = - bias_adjust_mhz(l_frequency_mhz, i_gppb->ext_biases[p].frequency_hp); + // get average temperature measurements with all good cores OFF and caches ON + IDDQ_TRACE (" Average temp all good cores OFF, caches ON:",IDDQ_DESC_SIZE); - o_operating_points[VPD_PT_SET_BIASED][p].idd_100ma = - i_gppb->operating_points[p].idd_100ma; - o_operating_points[VPD_PT_SET_BIASED][p].ics_100ma = - i_gppb->operating_points[p].ics_100ma; + for (i = 0; i < IDDQ_MEASUREMENTS; i++) + { + IDDQ_TEMP_EXTRACT(avgtemp_all_good_cores_off[i]); } - // As this is memory to memory, Endianess correction is not necessary. - uint32_t l_ref_freq_khz = - revle32(o_operating_points[VPD_PT_SET_BIASED][ULTRA].frequency_mhz) * 1000; - i_gppb->reference_frequency_khz = revle32(l_ref_freq_khz); + FAPI_INF("%s", l_line_str); - FAPI_DBG("Reference into GPPB: LE local Freq=%X (%d); Freq=%X (%d)", - l_ref_freq_khz, - l_ref_freq_khz, - revle32(i_gppb->reference_frequency_khz), - revle32(i_gppb->reference_frequency_khz)); + // get average temperature measurements with all good cores in each quad + for (i = 0; i < MAXIMUM_QUADS; i++) + { + IDDQ_TRACE (" Average temp all good cores ON, good caches ON ",IDDQ_QUAD_SIZE); + sprintf(l_buffer_str, "Quad %d:", i); + strcat(l_line_str, l_buffer_str); - // Now that the ULTRA frequency is known, Pstates can be calculated - for (p = 0; p < NUM_OP_POINTS; p++) + for (j = 0; j < IDDQ_MEASUREMENTS; j++) + { + IDDQ_TEMP_EXTRACT(avgtemp_quad_good_cores_on[i][j]); + } + + FAPI_INF("%s", l_line_str); + } + + // get average nest temperature nest + IDDQ_TRACE (" Average temp Nest:",IDDQ_DESC_SIZE); + + for (i = 0; i < IDDQ_MEASUREMENTS; i++) { - o_operating_points[VPD_PT_SET_BIASED][p].pstate = - (((revle32(o_operating_points[VPD_PT_SET_BIASED][ULTRA].frequency_mhz) - - revle32(o_operating_points[VPD_PT_SET_BIASED][p].frequency_mhz)) * 1000) / - revle32(i_gppb->frequency_step_khz)); + IDDQ_TEMP_EXTRACT(avgtemp_vdn[i]); + } - FAPI_DBG("Bi: OpPoint=[%d][%d], PS=%3d, Freq=%3X (%4d), Vdd=%3X (%4d), UT Freq=%3X (%4d) Step Freq=%5d", - VPD_PT_SET_BIASED, p, - o_operating_points[VPD_PT_SET_BIASED][p].pstate, - revle32(o_operating_points[VPD_PT_SET_BIASED][p].frequency_mhz), - revle32(o_operating_points[VPD_PT_SET_BIASED][p].frequency_mhz), - revle32(o_operating_points[VPD_PT_SET_BIASED][p].vdd_mv), - revle32(o_operating_points[VPD_PT_SET_BIASED][p].vdd_mv), - revle32(o_operating_points[VPD_PT_SET_BIASED][ULTRA].frequency_mhz), - revle32(o_operating_points[VPD_PT_SET_BIASED][ULTRA].frequency_mhz), - revle32(i_gppb->frequency_step_khz)); + FAPI_INF("%s", l_line_str); +} // end of iddq_print + + +/////////////////////////////////////////////////////////// +//////// get_mvpd_iddq +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::get_mvpd_iddq( void ) +{ + + uint8_t* l_buffer_iq_c = NULL; + uint32_t l_record = 0; + uint32_t l_bufferSize_iq = IQ_BUFFER_ALLOC; + + + // -------------------------------------------- + // Process IQ Keyword (IDDQ) Data + // -------------------------------------------- + // set l_record to appropriate cprx record + l_record = (uint32_t)fapi2::MVPD_RECORD_CRP0; + + //First read is to get size of vpd record, note the o_buffer is NULL + FAPI_TRY( getMvpdField((fapi2::MvpdRecord)l_record, + fapi2::MVPD_KEYWORD_IQ, + iv_procChip, + NULL, + l_bufferSize_iq) ); + + //Allocate memory for vpd data + l_buffer_iq_c = reinterpret_cast<uint8_t*>(malloc(l_bufferSize_iq)); + + // Get Chip IQ MVPD data from the CRPx records + FAPI_TRY(getMvpdField((fapi2::MvpdRecord)l_record, + fapi2::MVPD_KEYWORD_IQ, + iv_procChip, + l_buffer_iq_c, + l_bufferSize_iq)); + + //copy VPD data to IQ structure table + memcpy(&iv_iddqt, l_buffer_iq_c, l_bufferSize_iq); + + //Verify Payload header data. + if ( !(iv_iddqt.iddq_version) || + !(iv_iddqt.good_quads_per_sort) || + !(iv_iddqt.good_normal_cores_per_sort) || + !(iv_iddqt.good_caches_per_sort)) + { + iv_wof_enabled = false; + FAPI_ASSERT_NOEXIT(false, + fapi2::PSTATE_PB_IQ_VPD_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_CHIP_TARGET(iv_procChip) + .set_VERSION(iv_iddqt.iddq_version) + .set_GOOD_QUADS_PER_SORT(iv_iddqt.good_quads_per_sort) + .set_GOOD_NORMAL_CORES_PER_SORT(iv_iddqt.good_normal_cores_per_sort) + .set_GOOD_CACHES_PER_SORT(iv_iddqt.good_caches_per_sort), + "Pstate Parameter Block IQ Payload data error being logged"); + fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; } - //BIASED POINTS and SYSTEM PARMS APPLIED POINTS - for (p = 0; p < NUM_OP_POINTS; p++) + //Verify ivdd_all_cores_off_caches_off has MSB bit is set + //if yes then initialized to 0 + for (int i = 0; i < IDDQ_MEASUREMENTS; ++i) { - uint32_t l_vdd_mv = revle32(o_operating_points[VPD_PT_SET_BIASED][p].vdd_mv); - uint32_t l_idd_ma = revle32(o_operating_points[VPD_PT_SET_BIASED][p].idd_100ma) * 100; - uint32_t l_vcs_mv = revle32(o_operating_points[VPD_PT_SET_BIASED][p].vcs_mv); - uint32_t l_ics_ma = revle32(o_operating_points[VPD_PT_SET_BIASED][p].ics_100ma) * 100; + if ( iv_iddqt.ivdd_all_cores_off_caches_off[i] & 0x8000) + { + iv_iddqt.ivdd_all_cores_off_caches_off[i] = 0; + } + } + // Put out the structure to the trace + iddq_print(&iv_iddqt); - o_operating_points[VPD_PT_SET_BIASED_SYSP][p].vdd_mv = - sysparm_uplift(l_vdd_mv, - l_idd_ma, - l_vdd_loadline_uohm, - l_vdd_distloss_uohm, - l_vdd_distoffset_uv); +fapi_try_exit: + // Free up memory buffer + free(l_buffer_iq_c); - o_operating_points[VPD_PT_SET_BIASED_SYSP][p].vcs_mv = - sysparm_uplift(l_vcs_mv, - l_ics_ma, - l_vcs_loadline_uohm, - l_vcs_distloss_uohm, - l_vcs_distoffset_uv); + if (fapi2::current_err != fapi2::FAPI2_RC_SUCCESS) + { + iv_wof_enabled = false; + } - o_operating_points[VPD_PT_SET_BIASED_SYSP][p].idd_100ma = - o_operating_points[VPD_PT_SET_BIASED][p].idd_100ma; - o_operating_points[VPD_PT_SET_BIASED_SYSP][p].ics_100ma = - o_operating_points[VPD_PT_SET_BIASED][p].ics_100ma; - o_operating_points[VPD_PT_SET_BIASED_SYSP][p].frequency_mhz = - o_operating_points[VPD_PT_SET_BIASED][p].frequency_mhz; - o_operating_points[VPD_PT_SET_BIASED_SYSP][p].pstate = - o_operating_points[VPD_PT_SET_BIASED][p].pstate; + return fapi2::current_err; +} // end of get_mvpd_iddq + + +/////////////////////////////////////////////////////////// +//////// load_mvpd_operating_point +/////////////////////////////////////////////////////////// +void PlatPmPPB::load_mvpd_operating_point (vpd_type i_type) +{ + FAPI_DBG(">> load_mvpd_operating_point"); + const uint8_t pv_op_order[NUM_OP_POINTS] = VPD_PV_ORDER; - FAPI_DBG("BS: OpPoint=[%d][%d], PS=%3d, Freq=%3X (%4d), Vdd=%3X (%4d)", - VPD_PT_SET_BIASED_SYSP, p, - o_operating_points[VPD_PT_SET_SYSP][p].pstate, - revle32(o_operating_points[VPD_PT_SET_SYSP][p].frequency_mhz), - revle32(o_operating_points[VPD_PT_SET_SYSP][p].frequency_mhz), - revle32(o_operating_points[VPD_PT_SET_SYSP][p].vdd_mv), - revle32(o_operating_points[VPD_PT_SET_SYSP][p].vdd_mv)); + if (i_type == RAW) + { + for (uint32_t i = 0; i < NUM_OP_POINTS; i++) + { + iv_raw_vpd_pts[i].frequency_mhz = (iv_attr_mvpd_poundV_raw[pv_op_order[i]].frequency_mhz); + iv_raw_vpd_pts[i].vdd_mv = (iv_attr_mvpd_poundV_raw[pv_op_order[i]].vdd_mv); + iv_raw_vpd_pts[i].idd_100ma = (iv_attr_mvpd_poundV_raw[pv_op_order[i]].idd_100ma); + iv_raw_vpd_pts[i].vcs_mv = (iv_attr_mvpd_poundV_raw[pv_op_order[i]].vcs_mv); + iv_raw_vpd_pts[i].ics_100ma = (iv_attr_mvpd_poundV_raw[pv_op_order[i]].ics_100ma); + iv_raw_vpd_pts[i].pstate = (iv_attr_mvpd_poundV_raw[ULTRA].frequency_mhz - + iv_attr_mvpd_poundV_raw[pv_op_order[i]].frequency_mhz) * 1000 / (iv_frequency_step_khz); + FAPI_INF("PSTATE %x %x %d",iv_attr_mvpd_poundV_raw[ULTRA].frequency_mhz,iv_attr_mvpd_poundV_raw[pv_op_order[i]].frequency_mhz,iv_raw_vpd_pts[i].pstate); + } } -} + if (i_type == BIASED) + { + for (uint32_t i = 0; i < NUM_OP_POINTS; i++) + { + iv_biased_vpd_pts[i].frequency_mhz = (iv_attr_mvpd_poundV_biased[pv_op_order[i]].frequency_mhz); + iv_biased_vpd_pts[i].vdd_mv = (iv_attr_mvpd_poundV_biased[pv_op_order[i]].vdd_mv); + iv_biased_vpd_pts[i].idd_100ma = (iv_attr_mvpd_poundV_biased[pv_op_order[i]].idd_100ma); + iv_biased_vpd_pts[i].vcs_mv = (iv_attr_mvpd_poundV_biased[pv_op_order[i]].vcs_mv); + iv_biased_vpd_pts[i].ics_100ma = (iv_attr_mvpd_poundV_biased[pv_op_order[i]].ics_100ma); + iv_biased_vpd_pts[i].pstate = (iv_attr_mvpd_poundV_biased[ULTRA].frequency_mhz - + iv_attr_mvpd_poundV_biased[pv_op_order[i]].frequency_mhz) * 1000 / (iv_frequency_step_khz); + } + } + + FAPI_DBG("<< load_mvpd_operating_point"); +} //end of load_mvpd_operating_point + -// Slope of m = (y1-y0)/(x1-x0) in 4.12 Fixed-Pt format -int16_t -compute_slope_4_12(uint32_t y1, uint32_t y0, uint32_t x1, uint32_t x0) +/////////////////////////////////////////////////////////// +//////// vpd_init +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::vpd_init( void ) { - return (int16_t) - ( - // Perform division using floats for maximum precision - // Store resulting slope in 4.12 Fixed-Pt format - ((float)(y1 - y0) / (float)(x1 - x0)) * (1 << VID_SLOPE_FP_SHIFT_12) - ); + FAPI_INF(">>>>>>>>>> vpd_init"); + fapi2::ReturnCode l_rc; + do + { + memset (&iv_raw_vpd_pts, 0, sizeof(iv_raw_vpd_pts)); + memset (&iv_biased_vpd_pts, 0, sizeof(iv_biased_vpd_pts)); + memset (&iv_poundW_data, 0, sizeof(iv_poundW_data)); + memset (&iv_iddqt, 0, sizeof(iv_iddqt)); + memset (iv_operating_points,0,sizeof(iv_operating_points)); + memset (&iv_attr_mvpd_poundV_raw, 0, sizeof(iv_attr_mvpd_poundV_raw)); + memset (&iv_attr_mvpd_poundV_biased, 0, sizeof(iv_attr_mvpd_poundV_biased)); -} + //Read #V data + FAPI_TRY(get_mvpd_poundV(), + "get_mvpd_poundV function failed to retrieve pound V data"); + + + if (!iv_eq_chiplet_state) + { + break; + } + // Apply biased values if any + // + FAPI_IMP("Apply Biasing to #V"); + FAPI_TRY(apply_biased_values(),"apply_biased_values function failed"); + + //Read #W data + + // ---------------- + // get VDM Parameters data + // ---------------- + // Note: the get_mvpd_poundW has the conditional checking for VDM + // and WOF enablement as #W has both VDM and WOF content + l_rc = get_mvpd_poundW(); + if (l_rc) + { + FAPI_ASSERT_NOEXIT(false, + fapi2::PSTATE_PB_POUND_W_ACCESS_FAIL(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_CHIP_TARGET(iv_procChip) + .set_FAPI_RC(l_rc), + "Pstate Parameter Block get_mvpd_poundW function failed"); + fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; + } + + //Read #IQ data + + //if wof is disabled.. don't call IQ function + if (is_wof_enabled()) + { + // ---------------- + // get IQ (IDDQ) data + // ---------------- + FAPI_INF("Getting IQ (IDDQ) Data"); + l_rc = get_mvpd_iddq (); + + if (l_rc) + { + FAPI_ASSERT_NOEXIT(false, + fapi2::PSTATE_PB_IQ_ACCESS_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) + .set_CHIP_TARGET(iv_procChip) + .set_FAPI_RC(l_rc), + "Pstate Parameter Block get_mvpd_iddq function failed"); + fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; + } + } + else + { + FAPI_INF("Skipping IQ (IDDQ) Data as WOF is disabled"); + iv_wof_enabled = false; + } + + FAPI_INF("Load RAW VPD"); + load_mvpd_operating_point(RAW); + + FAPI_INF("Load VPD"); + // VPD operating point + load_mvpd_operating_point(BIASED); + + }while(0); + + FAPI_INF("<<<<<<<<< vpd_init"); + +fapi_try_exit: + return fapi2::current_err; -// Slope of m = (y1-y0)/(x1-x0) in 3.13 Fixed-Pt format -int16_t -compute_slope_3_13(uint32_t y1, uint32_t y0, uint32_t x1, uint32_t x0) +} // end of vpd_init + +/////////////////////////////////////////////////////////// +//////// is_wov_underv_enabled +/////////////////////////////////////////////////////////// +bool PlatPmPPB::is_wov_underv_enabled() { - return (int16_t) - ( - // Perform division using floats for maximum precision - // Store resulting slope in 3.13 Fixed-Pt format - ((float)(y1 - y0) / (float)(x1 - x0)) * (1 << VID_SLOPE_FP_SHIFT) - ); + return(!(iv_attrs.attr_wov_underv_enable) && + iv_wov_underv_enabled) + ? true : false; } -// Slope of m = (y1-y0)/(x1-x0) in 4.12 Fixed-Pt format for thresholds -int16_t -compute_slope_thresh(int32_t y1, int32_t y0, int32_t x1, int32_t x0) +///-------------------------------------- +/////////////////////////////////////////////////////////// +//////// is_wov_overv_enabled +/////////////////////////////////////////////////////////// +bool PlatPmPPB::is_wov_overv_enabled() { - return (int16_t) - ( - // Perform division using double for maximum precision - // Store resulting slope in 4.12 Fixed-Pt format - ((double)(y1 - y0) / (double)(x1 - x0)) * (1 << THRESH_SLOPE_FP_SHIFT) - ); + return (!(iv_attrs.attr_wov_overv_enable) && + iv_wov_overv_enabled) + ? true : false; } -//This fills up the PStateVSlopes and VPStatesSlopes in GlobalParmBlock -//Going forward this method should be retained in favor of the p9_pstate_compute_PsVSlopes -void p9_pstate_compute_PStateV_slope(VpdOperatingPoint i_operating_points[][4], - GlobalPstateParmBlock* o_gppb) +/////////////////////////////////////////////////////////// +//////// is_wof_enabled +/////////////////////////////////////////////////////////// +bool PlatPmPPB::is_wof_enabled() { - for(auto pt_set = 0; pt_set < NUM_VPD_PTS_SET; ++pt_set) + uint8_t attr_dd_wof_not_supported; + uint8_t attr_system_wof_disable; + const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_WOF_DISABLE, FAPI_SYSTEM, attr_system_wof_disable); + FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_WOF_NOT_SUPPORTED, iv_procChip, attr_dd_wof_not_supported); + + return + (!(attr_system_wof_disable) && + !(attr_dd_wof_not_supported) && + iv_wof_enabled) + ? true : false; +} //end of is_wof_enabled + +/////////////////////////////////////////////////////////// +//////// is_vdm_enabled +/////////////////////////////////////////////////////////// +bool PlatPmPPB::is_vdm_enabled() +{ + const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + uint8_t attr_dd_vdm_not_supported; + uint8_t attr_system_vdm_disable; + + FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_VDM_DISABLE, FAPI_SYSTEM, attr_system_vdm_disable); + FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_VDM_NOT_SUPPORTED, iv_procChip, attr_dd_vdm_not_supported); + + return + (!(attr_system_vdm_disable) && + !(attr_dd_vdm_not_supported) && + iv_vdm_enabled) + ? true : false; +} // end of is_vdm_enabled + + +/////////////////////////////////////////////////////////// +//////// isPstateModeEnabled +/////////////////////////////////////////////////////////// +bool PlatPmPPB::isPstateModeEnabled() +{ + return((iv_attrs.attr_pstate_mode == fapi2::ENUM_ATTR_SYSTEM_PSTATES_MODE_OFF) ? + true : false); +} //end of isPstateModeEnabled + + +/////////////////////////////////////////////////////////// +//////// isEqChipletPresent +/////////////////////////////////////////////////////////// +bool PlatPmPPB::isEqChipletPresent () +{ + return iv_eq_chiplet_state; +} //end of isEqChipletPresent + + +/////////////////////////////////////////////////////////// +//////// large_jump_interpolate +/////////////////////////////////////////////////////////// +uint32_t PlatPmPPB::large_jump_interpolate(const Pstate i_pstate, + const Pstate i_ps_pstate) +{ + + uint8_t l_jump_value_set_ps = + iv_poundW_data.poundw[POWERSAVE].vdm_normal_freq_drop & 0x0F; + uint8_t l_jump_value_set_nom = + iv_poundW_data.poundw[NOMINAL].vdm_normal_freq_drop & 0x0F; + + uint32_t l_slope_value = + compute_slope_thresh(l_jump_value_set_nom, + l_jump_value_set_ps, + iv_operating_points[VPD_PT_SET_BIASED][POWERSAVE].pstate, + iv_operating_points[VPD_PT_SET_BIASED][NOMINAL].pstate); + + uint32_t l_vdm_jump_value = + (uint32_t)((int32_t)l_jump_value_set_ps + (((int32_t)l_slope_value * + (i_ps_pstate - i_pstate)) >> THRESH_SLOPE_FP_SHIFT)); + return l_vdm_jump_value; +} //end of large_jump_interpolate + + +/////////////////////////////////////////////////////////// +//////// get_pstate_attrs +/////////////////////////////////////////////////////////// +void PlatPmPPB::get_pstate_attrs(AttributeList *o_attr) +{ + memcpy(o_attr,&iv_attrs, sizeof(iv_attrs)); +} // end of get_pstate_attrs + + +/////////////////////////////////////////////////////////// +//////// compute_boot_safe +/////////////////////////////////////////////////////////// +fapi2::ReturnCode PlatPmPPB::compute_boot_safe( + const VoltageConfigActions_t i_action) +{ + fapi2::ReturnCode l_rc; + + iv_pstates_enabled = true; + iv_resclk_enabled = true; + iv_vdm_enabled = true; + iv_ivrm_enabled = true; + iv_wof_enabled = false; + + do { - // ULTRA TURBO pstate check is not required..because it's pstate will be - // 0 - if (!(i_operating_points[pt_set][POWERSAVE].pstate) || - !(i_operating_points[pt_set][NOMINAL].pstate) || - !(i_operating_points[pt_set][TURBO].pstate)) + //We only wish to compute voltage setting defaults if the action + //inputed to the HWP tells us to + if(i_action == COMPUTE_VOLTAGE_SETTINGS) { - FAPI_ERR("Non-UltraTurbo PSTATE value shouldn't be zero for %s", vpdSetStr[pt_set]); - return; - } - //Calculate slopes - for(auto region(REGION_POWERSAVE_NOMINAL); region <= REGION_TURBO_ULTRA; ++region) - { - // Pstate value decreases with increasing region. Thus the values - // are swapped to result in a positive difference. - o_gppb->PStateVSlopes[pt_set][region] = - revle16( - compute_slope_4_12(revle32(i_operating_points[pt_set][region + 1].vdd_mv), - revle32(i_operating_points[pt_set][region].vdd_mv), - i_operating_points[pt_set][region].pstate, - i_operating_points[pt_set][region + 1].pstate) - ); + // query VPD if any of the voltage attributes are zero + if (!iv_attrs.vdd_voltage_mv || + !iv_attrs.vcs_voltage_mv || + !iv_attrs.vdn_voltage_mv) + { + // ---------------- + // get VPD data (#V,#W) + // ---------------- - FAPI_DBG("PStateVSlopes[%s][%s] 0x%04x %d", vpdSetStr[pt_set], region_names[region], - revle16(o_gppb->PStateVSlopes[pt_set][region]), - revle16(o_gppb->PStateVSlopes[pt_set][region])); - } + FAPI_TRY(vpd_init(),"vpd_init function failed"); - //Calculate inverted slopes - for(auto region(REGION_POWERSAVE_NOMINAL); region <= REGION_TURBO_ULTRA; ++region) - { - // Pstate value decreases with increasing region. Thus the values - // are swapped to result in a positive difference. - o_gppb->VPStateSlopes[pt_set][region] = - revle16( - compute_slope_4_12(i_operating_points[pt_set][region].pstate, - i_operating_points[pt_set][region + 1].pstate, - revle32(i_operating_points[pt_set][region + 1].vdd_mv), - revle32(i_operating_points[pt_set][region].vdd_mv)) - ); + if (!isEqChipletPresent()) + { + FAPI_IMP("**** WARNING : There are no EQ chiplets present which means there is no valid #V VPD"); + FAPI_IMP("**** WARNING : Pstates and all related functions will NOT be enabled."); - FAPI_DBG("VPStateSlopes[%s][%s] 0x%04x %d", vpdSetStr[pt_set], region_names[region], - revle16(o_gppb->VPStateSlopes[pt_set][region]), - revle16(o_gppb->VPStateSlopes[pt_set][region])); - } + break; + } + + // Compute the VPD operating points + compute_vpd_pts(); + + FAPI_TRY(safe_mode_init()); + + + // set VDD voltage to PowerSave Voltage from MVPD data (if no override) + if (iv_attrs.vdd_voltage_mv) + { + FAPI_INF("VDD boot voltage override set."); + } + else + { +// iv_attrs.vdd_voltage_mv = l_safe_mode_values.boot_mode_mv; + FAPI_INF("VDD boot voltage set to %d mV.", iv_attrs.vdd_voltage_mv); + } + + + + // set VCS voltage to UltraTurbo Voltage from MVPD data (if no override) + if (iv_attrs.vcs_voltage_mv) + { + FAPI_INF("VCS boot voltage override set."); + } + else + { + FAPI_INF("VCS boot voltage override not set, using VPD value and correcting for applicable load line setting"); + uint32_t l_int_vcs_mv = (iv_attr_mvpd_poundV_biased[POWERSAVE].vcs_mv); + uint32_t l_ics_ma = (iv_attr_mvpd_poundV_biased[POWERSAVE].ics_100ma) * 100; + + uint32_t l_ext_vcs_mv = sysparm_uplift(l_int_vcs_mv, + l_ics_ma, + revle32(iv_attrs.r_loadline_vcs_uohm), + revle32(iv_attrs.r_distloss_vcs_uohm), + revle32(iv_attrs.vrm_voffset_vcs_uv)); + + + FAPI_INF("VCS VPD voltage %d mV; Corrected voltage: %d mV; ICS: %d mA; LoadLine: %d uOhm; DistLoss: %d uOhm; Offst: %d uOhm", + l_int_vcs_mv, + (l_ext_vcs_mv), + l_ics_ma, + revle32(iv_attrs.r_loadline_vcs_uohm), + revle32(iv_attrs.r_distloss_vcs_uohm), + revle32(iv_attrs.vrm_voffset_vcs_uv)); + + + iv_attrs.vcs_voltage_mv = (l_ext_vcs_mv); + + } + + // set VDN voltage to PowerSave Voltage from MVPD data (if no override) + if (iv_attrs.vdn_voltage_mv) + { + FAPI_INF("VDN boot voltage override set"); + } + else + { + FAPI_INF("VDN boot voltage override not set, using VPD value and correcting for applicable load line setting"); + uint32_t l_int_vdn_mv = (iv_attr_mvpd_poundV_biased[POWERBUS].vdd_mv); + uint32_t l_idn_ma = (iv_attr_mvpd_poundV_biased[POWERBUS].idd_100ma) * 100; + // Returns revle32 + uint32_t l_ext_vdn_mv = sysparm_uplift(l_int_vdn_mv, + l_idn_ma, + revle32(iv_attrs.r_loadline_vdn_uohm), + revle32(iv_attrs.r_distloss_vdn_uohm), + revle32(iv_attrs.vrm_voffset_vdn_uv)); + + FAPI_INF("VDN VPD voltage %d mV; Corrected voltage: %d mV; IDN: %d mA; LoadLine: %d uOhm; DistLoss: %d uOhm; Offst: %d uOhm", + l_int_vdn_mv, + (l_ext_vdn_mv), + l_idn_ma, + revle32(iv_attrs.r_loadline_vdn_uohm), + revle32(iv_attrs.r_distloss_vdn_uohm), + revle32(iv_attrs.vrm_voffset_vdn_uv)); + + iv_attrs.vdn_voltage_mv = (l_ext_vdn_mv); + } + } + else + { + FAPI_INF("Using overrides for all boot voltages (VDD/VCS/VDN) and core frequency"); + + // Set safe frequency to the default BOOT_FREQ_MULT + fapi2::ATTR_BOOT_FREQ_MULT_Type l_boot_freq_mult; + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_BOOT_FREQ_MULT, + iv_procChip, + l_boot_freq_mult)); + + uint32_t l_boot_freq_mhz = + ((l_boot_freq_mult * iv_attrs.freq_proc_refclock_khz ) / + iv_attrs.proc_dpll_divider ) + / 1000; + + + + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ, + iv_procChip, + l_boot_freq_mhz)); + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SAFE_MODE_VOLTAGE_MV, + iv_procChip, + (iv_attrs.vdd_voltage_mv))); + FAPI_INF("Safe mode Frequency = %d MHz (0x%x), Safe mode voltage = %d mV (0x%x)", + l_boot_freq_mhz, l_boot_freq_mhz, + (iv_attrs.vdd_voltage_mv), (iv_attrs.vdd_voltage_mv)); + } + + FAPI_INF("Setting Boot Voltage attributes: VDD = %dmV; VCS = %dmV; VDN = %dmV", + (iv_attrs.vdd_voltage_mv), (iv_attrs.vcs_voltage_mv), (iv_attrs.vdn_voltage_mv)); + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_VDD_BOOT_VOLTAGE, iv_procChip, (iv_attrs.vdd_voltage_mv)), + "Error from FAPI_ATTR_SET (ATTR_VDD_BOOT_VOLTAGE)"); + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_VCS_BOOT_VOLTAGE, iv_procChip, (iv_attrs.vcs_voltage_mv)), + "Error from FAPI_ATTR_SET (ATTR_VCS_BOOT_VOLTAGE)"); + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_VDN_BOOT_VOLTAGE, iv_procChip, (iv_attrs.vdn_voltage_mv)), + "Error from FAPI_ATTR_SET (ATTR_VDN_BOOT_VOLTAGE)"); + } // COMPUTE_VOLTAGE_SETTINGS } -} + while(0); + // trace values to be used + FAPI_INF("VDD boot voltage = %d mV (0x%x)", + (iv_attrs.vdd_voltage_mv), (iv_attrs.vdd_voltage_mv)); + FAPI_INF("VCS boot voltage = %d mV (0x%x)", + (iv_attrs.vcs_voltage_mv), (iv_attrs.vcs_voltage_mv)); + FAPI_INF("VDN boot voltage = %d mV (0x%x)", + (iv_attrs.vdn_voltage_mv), (iv_attrs.vdn_voltage_mv)); + +fapi_try_exit: + return fapi2::current_err; +} // end of compute_boot_safe #define CENTER_STR(_buffer, _variable, _width) \ { \ @@ -2849,12 +4599,11 @@ void p9_pstate_compute_PStateV_slope(VpdOperatingPoint i_operating_points[][4], strcat(_buffer, _temp_buffer); \ } -/// Print a GlobalPstateParameterBlock structure on a given stream -/// -/// \param gppb The Global Pstate Parameter Block print -void -gppb_print(GlobalPstateParmBlock* i_gppb) +/////////////////////////////////////////////////////////// +//////// gppb_print +/////////////////////////////////////////////////////////// +void gppb_print(GlobalPstateParmBlock* i_gppb) { static const uint32_t BUFFSIZE = 256; char l_buffer[BUFFSIZE]; @@ -3006,7 +4755,6 @@ gppb_print(GlobalPstateParmBlock* i_gppb) revle32(i_gppb->nest_frequency_mhz), revle32(i_gppb->nest_frequency_mhz)); - // 4 Slope sets sprintf(l_buffer, "PstateVSlopes:"); sprintf( l_temp_buffer, "%5s", ""); @@ -3184,14 +4932,13 @@ gppb_print(GlobalPstateParmBlock* i_gppb) } FAPI_INF("---------------------------------------------------------------------------------------"); -} +} // end of gppb_print -/// Print an OCCPstateParameterBlock structure on a given stream -/// -/// \param oppb The OCC Pstate Parameter Block print -void -oppb_print(OCCPstateParmBlock* i_oppb) +/////////////////////////////////////////////////////////// +//////// oppb_print +/////////////////////////////////////////////////////////// +void oppb_print(OCCPstateParmBlock* i_oppb) { static const uint32_t BUFFSIZE = 256; char l_buffer[BUFFSIZE]; @@ -3342,1696 +5089,7 @@ oppb_print(OCCPstateParmBlock* i_oppb) iddq_print(&(i_oppb->iddq)); FAPI_INF("---------------------------------------------------------------------------------------"); -} - -/// Print an iddq_print structure on a given stream -/// -/// \param i_iddqt pointer to Iddq structure to output - -void -iddq_print(IddqTable* i_iddqt) -{ - uint32_t i, j; - const char* idd_meas_str[IDDQ_MEASUREMENTS] = IDDQ_ARRAY_VOLTAGES_STR; -// char l_buffer_str[256]; // Temporary formatting string buffer -// char l_line_str[256]; // Formatted output line string - char l_buffer_str[1024]; // Temporary formatting string buffer - char l_line_str[1024]; // Formatted output line string - - static const uint32_t IDDQ_DESC_SIZE = 56; - static const uint32_t IDDQ_QUAD_SIZE = IDDQ_DESC_SIZE - - strlen("Quad X:"); - - FAPI_INF("IDDQ"); - - // Put out the endian-corrected scalars - - // get IQ version and advance pointer 1-byte - FAPI_INF(" IDDQ Version Number = %u", i_iddqt->iddq_version); - FAPI_INF(" Sort Info: Good Quads = %02d Good Cores = %02d Good Caches = %02d", - i_iddqt->good_quads_per_sort, - i_iddqt->good_normal_cores_per_sort, - i_iddqt->good_caches_per_sort); - - // get number of good normal cores in each quad - strcpy(l_line_str, " Good normal cores:"); - strcpy(l_buffer_str, ""); - - for (i = 0; i < MAXIMUM_QUADS; i++) - { - sprintf(l_buffer_str, " Quad %d = %u ", i, i_iddqt->good_normal_cores[i]); - strcat(l_line_str, l_buffer_str); - } - - FAPI_INF("%s", l_line_str); - - // get number of good caches in each quad - strcpy(l_line_str, " Good caches: "); - strcpy(l_buffer_str, ""); - - for (i = 0; i < MAXIMUM_QUADS; i++) - { - sprintf(l_buffer_str, " Quad %d = %u ", i, i_iddqt->good_caches[i]); - strcat(l_line_str, l_buffer_str); - } - - FAPI_INF("%s", l_line_str); - - // get RDP TO TDP scalling factor - FAPI_INF(" RDP TO TDP scalling factor = %u", revle16(i_iddqt->rdp_to_tdp_scale_factor)); - - // get WOF IDDQ margin factor - FAPI_INF(" WOF IDDQ margin factor = %u", revle16(i_iddqt->wof_iddq_margin_factor)); - - // get VDD Temperature scaling factor - FAPI_INF(" VDD Temperature scaling factor = %u", revle16(i_iddqt->vdd_temperature_scale_factor)); - - // get VDN Temperature scaling factor - FAPI_INF(" VDN Temperature scaling factor = %u", revle16(i_iddqt->vdn_temperature_scale_factor)); - - // All IQ IDDQ measurements are at 5mA resolution. The OCC wants to - // consume these at 1mA values. thus, all values are multiplied by - // 5 upon installation into the paramater block. - static const uint32_t CONST_5MA_1MA = 5; - FAPI_INF(" IDDQ data is converted 5mA units to 1mA units"); - - // Put out the measurement voltages to the trace. - strcpy(l_line_str, " Measurement voltages:"); - sprintf(l_buffer_str, "%-*s ", IDDQ_DESC_SIZE, l_line_str); - strcpy(l_line_str, l_buffer_str); - strcpy(l_buffer_str, ""); - - for (i = 0; i < IDDQ_MEASUREMENTS; i++) - { - sprintf(l_buffer_str, " %*sV ", 5, idd_meas_str[i]); - strcat(l_line_str, l_buffer_str); - } - - FAPI_INF("%s", l_line_str); - -#define IDDQ_CURRENT_EXTRACT(_member) \ - { \ - uint16_t _temp = revle16(i_iddqt->_member) * CONST_5MA_1MA; \ - sprintf(l_buffer_str, " %6.3f ", (double)_temp/1000); \ - strcat(l_line_str, l_buffer_str); \ - } +} // end of oppb_print -// Temps are all 1B quantities. Not endianess issues. -#define IDDQ_TEMP_EXTRACT(_member) \ - sprintf(l_buffer_str, " %4.1f ", ((double)i_iddqt->_member)/2); \ - strcat(l_line_str, l_buffer_str); - -#define IDDQ_TRACE(string, size) \ - strcpy(l_line_str, string); \ - sprintf(l_buffer_str, "%-*s", size, l_line_str);\ - strcpy(l_line_str, l_buffer_str); \ - strcpy(l_buffer_str, ""); - - // get IVDDQ measurements with all good cores ON - IDDQ_TRACE (" IDDQ all good cores ON:", IDDQ_DESC_SIZE); - - for (i = 0; i < IDDQ_MEASUREMENTS; i++) - { - IDDQ_CURRENT_EXTRACT(ivdd_all_good_cores_on_caches_on[i]); - } - - FAPI_INF("%s", l_line_str); - - // get IVDDQ measurements with all cores and caches OFF - IDDQ_TRACE (" IVDDQ all cores and caches OFF:", IDDQ_DESC_SIZE); - - for (i = 0; i < IDDQ_MEASUREMENTS; i++) - { - IDDQ_CURRENT_EXTRACT(ivdd_all_cores_off_caches_off[i]); - } - - FAPI_INF("%s", l_line_str);; - - // get IVDDQ measurements with all good cores OFF and caches ON - IDDQ_TRACE (" IVDDQ all good cores OFF and caches ON:", IDDQ_DESC_SIZE); - - for (i = 0; i < IDDQ_MEASUREMENTS; i++) - { - IDDQ_CURRENT_EXTRACT(ivdd_all_good_cores_off_good_caches_on[i]); - } - - FAPI_INF("%s", l_line_str); - - // get IVDDQ measurements with all good cores in each quad - for (i = 0; i < MAXIMUM_QUADS; i++) - { - IDDQ_TRACE (" IVDDQ all good cores ON and caches ON ", IDDQ_QUAD_SIZE); - sprintf(l_buffer_str, "Quad %d:", i); - strcat(l_line_str, l_buffer_str); - - for (j = 0; j < IDDQ_MEASUREMENTS; j++) - { - IDDQ_CURRENT_EXTRACT(ivdd_quad_good_cores_on_good_caches_on[i][j]); - } - - FAPI_INF("%s", l_line_str); - } - - // get IVDN data - IDDQ_TRACE (" IVDN", IDDQ_DESC_SIZE); - - for (i = 0; i < IDDQ_MEASUREMENTS; i++) - { - IDDQ_CURRENT_EXTRACT(ivdn[i]); - } - - FAPI_INF("%s", l_line_str); - - // get average temperature measurements with all good cores ON - IDDQ_TRACE (" Average temp all good cores ON:",IDDQ_DESC_SIZE); - - for (i = 0; i < IDDQ_MEASUREMENTS; i++) - { - IDDQ_TEMP_EXTRACT(avgtemp_all_good_cores_on[i]); - } - - FAPI_INF("%s", l_line_str); - - // get average temperature measurements with all cores and caches OFF - IDDQ_TRACE (" Average temp all cores OFF, caches OFF:", IDDQ_DESC_SIZE); - - for (i = 0; i < IDDQ_MEASUREMENTS; i++) - { - IDDQ_TEMP_EXTRACT(avgtemp_all_cores_off_caches_off[i]); - } - - FAPI_INF("%s", l_line_str); - - // get average temperature measurements with all good cores OFF and caches ON - IDDQ_TRACE (" Average temp all good cores OFF, caches ON:",IDDQ_DESC_SIZE); - - for (i = 0; i < IDDQ_MEASUREMENTS; i++) - { - IDDQ_TEMP_EXTRACT(avgtemp_all_good_cores_off[i]); - } - - FAPI_INF("%s", l_line_str); - - // get average temperature measurements with all good cores in each quad - for (i = 0; i < MAXIMUM_QUADS; i++) - { - IDDQ_TRACE (" Average temp all good cores ON, good caches ON ",IDDQ_QUAD_SIZE); - sprintf(l_buffer_str, "Quad %d:", i); - strcat(l_line_str, l_buffer_str); - - for (j = 0; j < IDDQ_MEASUREMENTS; j++) - { - IDDQ_TEMP_EXTRACT(avgtemp_quad_good_cores_on[i][j]); - } - - FAPI_INF("%s", l_line_str); - } - - // get average nest temperature nest - IDDQ_TRACE (" Average temp Nest:",IDDQ_DESC_SIZE); - - for (i = 0; i < IDDQ_MEASUREMENTS; i++) - { - IDDQ_TEMP_EXTRACT(avgtemp_vdn[i]); - } - - FAPI_INF("%s", l_line_str); -} - -// Convert frequency to Pstate number -int -freq2pState (const GlobalPstateParmBlock* gppb, - const uint32_t freq_khz, - Pstate* pstate, - const FREQ2PSTATE_ROUNDING i_round) -{ - int rc = 0; - float pstate32 = 0; - - // ---------------------------------- - // compute pstate for given frequency - // ---------------------------------- - pstate32 = ((float)(revle32(gppb->reference_frequency_khz) - (float)freq_khz)) / - (float)revle32(gppb->frequency_step_khz); - // @todo Bug fix from Characterization team to deal with VPD not being - // exactly in step increments - // - not yet included to separate changes - // As higher Pstate numbers represent lower frequencies, the pstate must be - // snapped to the nearest *higher* integer value for safety. (e.g. slower - // frequencies are safer). - if ((i_round == ROUND_SLOW) && (freq_khz)) - { - *pstate = (Pstate)internal_ceil(pstate32); - FAPI_DBG("freq2pState: ROUND SLOW"); - } - else - { - *pstate = (Pstate)pstate32; - FAPI_DBG("freq2pState: ROUND FAST"); - } - - FAPI_DBG("freq2pState: freq_khz = %u (0x%X); pstate32 = %f; pstate = %u (0x%X)", - freq_khz, freq_khz, pstate32, *pstate, *pstate); - FAPI_DBG("freq2pState: ref_freq_khz = %u (0x%X); step_freq_khz= %u (0x%X)", - revle32(gppb->reference_frequency_khz), - revle32(gppb->reference_frequency_khz), - revle32(gppb->frequency_step_khz), - revle32(gppb->frequency_step_khz)); - // ------------------------------ - // perform pstate bounds checking - // ------------------------------ - if (pstate32 < PSTATE_MIN) - { - rc = -PSTATE_LT_PSTATE_MIN; - *pstate = PSTATE_MIN; - } - - if (pstate32 > PSTATE_MAX) - { - rc = -PSTATE_GT_PSTATE_MAX; - *pstate = PSTATE_MAX; - } - - return rc; -} - -// Convert Pstate number to frequency -int -pState2freq (const GlobalPstateParmBlock* gppb, - const Pstate i_pstate, - uint32_t* o_freq_khz) -{ - int rc = 0; - float pstate32 = i_pstate; - float l_freq_khz = 0; - - // ---------------------------------- - // compute frequency from a pstate - // ---------------------------------- - l_freq_khz = ((float)(revle32(gppb->reference_frequency_khz)) - - (pstate32 * (float)revle32(gppb->frequency_step_khz))); - - *o_freq_khz = (uint32_t)l_freq_khz; - - return rc; -} - - -fapi2::ReturnCode -proc_get_mvpd_poundw(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - uint8_t i_poundv_bucketId, - LP_VDMParmBlock* o_vdmpb, - PoundW_data* o_data, - fapi2::voltageBucketData_t i_poundv_data, - PSTATE_attribute_state* o_state) -{ - std::vector<fapi2::Target<fapi2::TARGET_TYPE_EQ>> l_eqChiplets; - fapi2::vdmData_t l_vdmBuf; - uint8_t selected_eq = 0; - uint8_t bucket_id = 0; - uint8_t version_id = 0; - const uint16_t VDM_VOLTAGE_IN_MV = 512; - const uint16_t MIN_VDM_VOLTAGE_IN_MV = 576; - const uint16_t VDM_GRANULARITY = 4; - uint32_t l_vdm_compare_raw_mv[NUM_OP_POINTS]; - uint32_t l_vdm_compare_biased_mv[NUM_OP_POINTS]; - - const char* pv_op_str[NUM_OP_POINTS] = PV_OP_ORDER_STR; - - FAPI_DBG(">> proc_get_mvpd_poundw"); - - do - { - FAPI_DBG("proc_get_mvpd_poundw: VDM enable = %d, WOF enable %d", - is_vdm_enabled(i_target,o_state), is_wof_enabled(i_target,o_state)); - - // Exit if both VDM and WOF is disabled - if ((!is_vdm_enabled(i_target,o_state) && !is_wof_enabled(i_target,o_state))) - { - FAPI_INF(" proc_get_mvpd_poundw: BOTH VDM and WOF are disabled. Skipping remaining checks"); - o_state->iv_vdm_enabled = false; - o_state->iv_wof_enabled = false; - - break; - } - - // Below fields for Nominal, Powersave, Turbo, Ultra Turbo - // I-VDD Nominal TDP AC current 2B - // I-VDD Nominal TDP DC current 2B - // Overvolt Threshold 0.5 Upper nibble of byte - // Small Threshold 0.5 Lower nibble of byte - // Large Threshold 0.5 Upper nibble of byte - // eXtreme Threshold 0.5 Lower nibble of byte - // Small Frequency Drop 1B - // Large Frequency Drop 1B - // ----------------------------------------------------------------- - l_eqChiplets = i_target.getChildren<fapi2::TARGET_TYPE_EQ>(fapi2::TARGET_STATE_FUNCTIONAL); - - for (selected_eq = 0; selected_eq < l_eqChiplets.size(); selected_eq++) - { - uint8_t l_chipletNum = 0xFF; - - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_eqChiplets[selected_eq], l_chipletNum)); - - FAPI_INF("Chiplet Number => %u", l_chipletNum); - - // clear out buffer to known value before calling fapiGetMvpdField - memset(&l_vdmBuf, 0, sizeof(l_vdmBuf)); - - FAPI_TRY(p9_pm_get_poundw_bucket(l_eqChiplets[selected_eq], l_vdmBuf)); - - bucket_id = l_vdmBuf.bucketId; - version_id = l_vdmBuf.version; - - FAPI_INF("#W chiplet = %u bucket id = %u", l_chipletNum, bucket_id, version_id); - - //if we match with the bucket id, then we don't need to continue - if (i_poundv_bucketId == bucket_id) - { - break; - } - } - - uint8_t l_poundw_static_data = 0; - const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POUND_W_STATIC_DATA_ENABLE, - FAPI_SYSTEM, - l_poundw_static_data), - "Error from FAPI_ATTR_GET for attribute ATTR_POUND_W_STATIC_DATA_ENABLE"); - - if (l_poundw_static_data) - { - FAPI_INF("attribute ATTR_POUND_W_STATIC_DATA_ENABLE is set"); - // copy the data to the pound w structure from a hardcoded table - memcpy (o_data, &g_vpdData, sizeof (g_vpdData)); - } - else - { - FAPI_INF("attribute ATTR_POUND_W_STATIC_DATA_ENABLE is NOT set"); - // copy the data to the pound w structure from the actual VPD image - memcpy (o_data, l_vdmBuf.vdmData, sizeof (l_vdmBuf.vdmData)); - } - - //Re-ordering to Natural order - // When we read the data from VPD image the order will be N,PS,T,UT. - // But we need the order PS,N,T,UT.. hence we are swapping the data - // between PS and Nominal. - poundw_entry_t l_tmp_data; - memcpy (&l_tmp_data, - &(o_data->poundw[VPD_PV_NOMINAL]), - sizeof (poundw_entry_t)); - - memcpy (&(o_data->poundw[VPD_PV_NOMINAL]), - &(o_data->poundw[VPD_PV_POWERSAVE]), - sizeof(poundw_entry_t)); - - memcpy (&(o_data->poundw[VPD_PV_POWERSAVE]), - &l_tmp_data, - sizeof(poundw_entry_t)); - - // If the #W version is less than 3, validate Turbo VDM large threshold - // not larger than -32mV. This filters out parts that have bad VPD. If - // this check fails, log a recovered error, mark the VDMs disabled and - // break out of the reset of the checks. - uint32_t turbo_vdm_large_threshhold = - (o_data->poundw[TURBO].vdm_large_extreme_thresholds >> 4) & 0x0F; - FAPI_DBG("o_data->poundw[TURBO].vdm_large_thresholds 0x%X; grey code index %d; max grey code index %d", - turbo_vdm_large_threshhold, - g_GreyCodeIndexMapping[turbo_vdm_large_threshhold], - GREYCODE_INDEX_M32MV); - - if (version_id < FULLY_VALID_POUNDW_VERSION && - g_GreyCodeIndexMapping[turbo_vdm_large_threshhold] > GREYCODE_INDEX_M32MV) - { - o_state->iv_vdm_enabled = false; - - fapi2::ATTR_CHIP_EC_FEATURE_VDM_POUNDW_SUPPRESS_ERROR_Type l_suppress_pdw_error; - FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_VDM_POUNDW_SUPPRESS_ERROR, - i_target, - l_suppress_pdw_error); - - if (l_suppress_pdw_error) - { - FAPI_INF("VDM #W ERROR: Turbo Large Threshold less than -32mV. Indicates bad VPD so VDMs being disabled and pressing on"); - } - else - { - FAPI_ASSERT_NOEXIT(false, - fapi2::PSTATE_PB_POUND_W_VERY_INVALID_VDM_DATA(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_TURBO_LARGE_THRESHOLD(o_data->poundw[TURBO].vdm_large_extreme_thresholds), - "VDM #W ERROR: Turbo Large Threshold less than -32mV. Indicates bad VPD so VDMs being disabled and pressing on"); - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - } - - break; - - } - - // Validate the WOF content is non-zero if WOF is enabled - if (is_wof_enabled(i_target,o_state)) - { - bool b_tdp_ac = true; - bool b_tdp_dc = true; - // Check that the WOF currents are non-zero - for (auto p = 0; p < NUM_OP_POINTS; ++p) - { - FAPI_INF("%s ivdd_tdp_ac_current %5d (10mA) %6.2f (A)", - pv_op_str[p], - revle16(o_data->poundw[p].ivdd_tdp_ac_current_10ma), - ((double)revle16(o_data->poundw[p].ivdd_tdp_ac_current_10ma)/100)); - FAPI_INF("%s ivdd_tdp_dc_current %5d (10mA) %6.2f (A)", - pv_op_str[p], - revle16(o_data->poundw[p].ivdd_tdp_dc_current_10ma), - ((double)revle16(o_data->poundw[p].ivdd_tdp_dc_current_10ma)/100)); - if (!o_data->poundw[p].ivdd_tdp_ac_current_10ma) - { - FAPI_ERR("%s.ivdd_tdp_ac_current_10ma is zero!!!", - pv_op_str[p]); - b_tdp_ac = false; - o_state->iv_wof_enabled = false; - - } - if (!o_data->poundw[p].ivdd_tdp_dc_current_10ma) - { - FAPI_ERR("%s.ivdd_tdp_dc_current_10ma is zero!!!", - pv_op_str[p]); - b_tdp_dc = false; - o_state->iv_wof_enabled = false; - } - } - - FAPI_ASSERT_NOEXIT(b_tdp_ac, - fapi2::PSTATE_PB_POUND_W_TDP_IAC_INVALID(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_EQ_TARGET(l_eqChiplets[selected_eq]) - .set_NOMINAL_TDP_IAC(o_data->poundw[NOMINAL].ivdd_tdp_dc_current_10ma) - .set_POWERSAVE_TDP_IAC(o_data->poundw[POWERSAVE].ivdd_tdp_dc_current_10ma) - .set_TURBO_TDP_IAC(o_data->poundw[TURBO].ivdd_tdp_dc_current_10ma) - .set_ULTRA_TDP_IAC(o_data->poundw[ULTRA].ivdd_tdp_dc_current_10ma), - "Pstate Parameter Block #W : one or more Idd TDP AC values are zero"); - FAPI_ASSERT_NOEXIT(b_tdp_dc, - fapi2::PSTATE_PB_POUND_W_TDP_IDC_INVALID(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_EQ_TARGET(l_eqChiplets[selected_eq]) - .set_NOMINAL_TDP_IDC(o_data->poundw[NOMINAL].ivdd_tdp_dc_current_10ma) - .set_POWERSAVE_TDP_IDC(o_data->poundw[POWERSAVE].ivdd_tdp_dc_current_10ma) - .set_TURBO_TDP_IDC(o_data->poundw[TURBO].ivdd_tdp_dc_current_10ma) - .set_ULTRA_TDP_IDC(o_data->poundw[ULTRA].ivdd_tdp_dc_current_10ma), - "o_dataPstate Parameter Block #W : one or more Idd TDP DC values are zero"); - - // Set the return code to success to keep going. - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - } - - // The rest of the processing here is all checking of the VDM content - // within #W. If VDMs are not enabled (or supported), skip all of it - if (!is_vdm_enabled(i_target,o_state)) - { - FAPI_INF(" proc_get_mvpd_poundw: VDM is disabled. Skipping remaining checks"); - o_state->iv_vdm_enabled = false; - break; - } - - for (int i = 0; i < NUM_OP_POINTS; ++i) - { - l_vdm_compare_raw_mv[i] = VDM_VOLTAGE_IN_MV + (o_data->poundw[i].vdm_vid_compare_ivid << 2); - FAPI_INF("%10s vdm_vid_compare_ivid %3d => %d mv", - pv_op_str[i], - o_data->poundw[i].vdm_vid_compare_ivid, - l_vdm_compare_raw_mv[i]); - } - - //Validation of VPD Data - // - //If all VID compares are zero then use #V VDD voltage to populate local - //data structure..So that we make progress in lab with early hardware - if ( !(o_data->poundw[NOMINAL].vdm_vid_compare_ivid) && - !(o_data->poundw[POWERSAVE].vdm_vid_compare_ivid) && - !(o_data->poundw[TURBO].vdm_vid_compare_ivid) && - !(o_data->poundw[ULTRA].vdm_vid_compare_ivid)) - { - //vdm_vid_compare_ivid will be in ivid units (eg HEX((Compare - //Voltage (mv) - 512mV)/4mV). - o_data->poundw[NOMINAL].vdm_vid_compare_ivid = - (i_poundv_data.VddNomVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY; - o_data->poundw[POWERSAVE].vdm_vid_compare_ivid = - (i_poundv_data.VddPSVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY; - o_data->poundw[TURBO].vdm_vid_compare_ivid = - (i_poundv_data.VddTurboVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY; - o_data->poundw[ULTRA].vdm_vid_compare_ivid = - (i_poundv_data.VddUTurboVltg - VDM_VOLTAGE_IN_MV ) / VDM_GRANULARITY; - }//if any one of the VID compares are zero, then need to fail because of BAD VPD image. - else if ( !(o_data->poundw[NOMINAL].vdm_vid_compare_ivid) || - !(o_data->poundw[POWERSAVE].vdm_vid_compare_ivid) || - !(o_data->poundw[TURBO].vdm_vid_compare_ivid) || - !(o_data->poundw[ULTRA].vdm_vid_compare_ivid)) - { - o_state->iv_vdm_enabled = false; - FAPI_ASSERT_NOEXIT(false, - fapi2::PSTATE_PB_POUND_W_INVALID_VID_VALUE(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_EQ_TARGET(l_eqChiplets[selected_eq]) - .set_NOMINAL_VID_COMPARE_IVID_VALUE(o_data->poundw[NOMINAL].vdm_vid_compare_ivid) - .set_POWERSAVE_VID_COMPARE_IVID_VALUE(o_data->poundw[POWERSAVE].vdm_vid_compare_ivid) - .set_TURBO_VID_COMPARE_IVID_VALUE(o_data->poundw[TURBO].vdm_vid_compare_ivid) - .set_ULTRA_VID_COMPARE_IVID_VALUE(o_data->poundw[ULTRA].vdm_vid_compare_ivid), - "Pstate Parameter Block #W : one of the VID compare value is zero"); - break; - } - - // validate vid values - bool l_compare_vid_value_state = 1; - VALIDATE_VID_VALUES (o_data->poundw[POWERSAVE].vdm_vid_compare_ivid, - o_data->poundw[NOMINAL].vdm_vid_compare_ivid, - o_data->poundw[TURBO].vdm_vid_compare_ivid, - o_data->poundw[ULTRA].vdm_vid_compare_ivid, - l_compare_vid_value_state); - - if (!l_compare_vid_value_state) - { - o_state->iv_vdm_enabled = false; - FAPI_ASSERT_NOEXIT(false, - fapi2::PSTATE_PB_POUND_W_INVALID_VID_ORDER(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_EQ_TARGET(l_eqChiplets[selected_eq]) - .set_NOMINAL_VID_COMPARE_IVID_VALUE(o_data->poundw[NOMINAL].vdm_vid_compare_ivid) - .set_POWERSAVE_VID_COMPARE_IVID_VALUE(o_data->poundw[POWERSAVE].vdm_vid_compare_ivid) - .set_TURBO_VID_COMPARE_IVID_VALUE(o_data->poundw[TURBO].vdm_vid_compare_ivid) - .set_ULTRA_VID_COMPARE_IVID_VALUE(o_data->poundw[ULTRA].vdm_vid_compare_ivid), - "Pstate Parameter Block #W VID compare data are not in increasing order"); - break; - } - - // validate threshold values - bool l_threshold_value_state = 1; - - for (uint8_t p = 0; p < NUM_OP_POINTS; ++p) - { - FAPI_INF("o_data->poundw[%d].vdm_overvolt_thresholds 0x%X",p,(o_data->poundw[p].vdm_overvolt_small_thresholds >> 4) & 0x0F); - FAPI_INF("o_data->poundw[%d].vdm_small_thresholds 0x%X",p,(o_data->poundw[p].vdm_overvolt_small_thresholds ) & 0x0F); - FAPI_INF("o_data->poundw[%d].vdm_large_thresholds 0x%X",p,(o_data->poundw[p].vdm_large_extreme_thresholds >> 4) & 0x0F); - FAPI_INF("o_data->poundw[%d].vdm_extreme_thresholds 0x%X",p,(o_data->poundw[p].vdm_large_extreme_thresholds) & 0x0F); - VALIDATE_THRESHOLD_VALUES(((o_data->poundw[p].vdm_overvolt_small_thresholds >> 4) & 0x0F), // overvolt - ((o_data->poundw[p].vdm_overvolt_small_thresholds) & 0x0F), //small - ((o_data->poundw[p].vdm_large_extreme_thresholds >> 4) & 0x0F), //large - ((o_data->poundw[p].vdm_large_extreme_thresholds) & 0x0F), //extreme - l_threshold_value_state); - - if (!l_threshold_value_state) - { - o_state->iv_vdm_enabled = false; - FAPI_ASSERT_NOEXIT(false, - fapi2::PSTATE_PB_POUND_W_INVALID_THRESHOLD_VALUE(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_EQ_TARGET(l_eqChiplets[selected_eq]) - .set_OP_POINT_TYPE(p) - .set_VDM_OVERVOLT((o_data->poundw[p].vdm_overvolt_small_thresholds >> 4) & 0x0F) - .set_VDM_SMALL(o_data->poundw[p].vdm_overvolt_small_thresholds & 0x0F) - .set_VDM_EXTREME((o_data->poundw[p].vdm_large_extreme_thresholds >> 4) & 0x0F) - .set_VDM_LARGE((o_data->poundw[p].vdm_large_extreme_thresholds) & 0x0F), - "Pstate Parameter Block #W VDM threshold data are invalid"); - break; - } - } - - bool l_frequency_value_state = 1; - - for (uint8_t p = 0; p < NUM_OP_POINTS; ++p) - { - // These fields are 4 bits wide, and stored in a uint8, hence the shifting - // N_S, N_L, L_S, S_N - FAPI_INF("o_data->poundw[%d] VDM_FREQ_DROP N_S = %d", p, ((o_data->poundw[p].vdm_normal_freq_drop >> 4) & 0x0F)); - FAPI_INF("o_data->poundw[%d] VDM_FREQ_DROP N_L = %d", p, ((o_data->poundw[p].vdm_normal_freq_drop) & 0x0F)); - FAPI_INF("o_data->poundw[%d] VDM_FREQ_RETURN L_S = %d", p, ((o_data->poundw[p].vdm_normal_freq_return >> 4) & 0x0F)); - FAPI_INF("o_data->poundw[%d] VDM_FREQ_RETURN S_N = %d", p, ((o_data->poundw[p].vdm_normal_freq_return) & 0x0F)); - - VALIDATE_FREQUENCY_DROP_VALUES(((o_data->poundw[p].vdm_normal_freq_drop) & 0x0F), // N_L - ((o_data->poundw[p].vdm_normal_freq_drop >> 4) & 0x0F), // N_S - ((o_data->poundw[p].vdm_normal_freq_return >> 4) & 0x0F), // L_S - ((o_data->poundw[p].vdm_normal_freq_return) & 0x0F), // S_N - l_frequency_value_state); - - if (!l_frequency_value_state) - { - o_state->iv_vdm_enabled = false; - FAPI_ASSERT_NOEXIT(false, - fapi2::PSTATE_PB_POUND_W_INVALID_FREQ_DROP_VALUE(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_EQ_TARGET(l_eqChiplets[selected_eq]) - .set_OP_POINT_TYPE(p) - .set_VDM_NORMAL_SMALL((o_data->poundw[p].vdm_normal_freq_drop >> 4) & 0x0F) - .set_VDM_NORMAL_LARGE(o_data->poundw[p].vdm_normal_freq_drop & 0x0F) - .set_VDM_LARGE_SMALL((o_data->poundw[p].vdm_normal_freq_return >> 4) & 0x0F) - .set_VDM_SMALL_NORMAL((o_data->poundw[p].vdm_normal_freq_return) & 0x0F), - "Pstate Parameter Block #W VDM frequency drop data are invalid"); - break; - } - } - - //Biased compare vid data - fapi2::ATTR_VDM_VID_COMPARE_BIAS_0P5PCT_Type l_bias_value; - - - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDM_VID_COMPARE_BIAS_0P5PCT, - i_target, - l_bias_value), - "Error from FAPI_ATTR_GET for attribute ATTR_VDM_VID_COMPARE_BIAS_0P5PCT"); - - float l_pound_w_points[NUM_OP_POINTS]; - - for (uint8_t i = 0; i < NUM_OP_POINTS; i++) - { - l_pound_w_points[i] = calc_bias(l_bias_value[i]); - - l_vdm_compare_biased_mv[i] = internal_ceil( (l_vdm_compare_raw_mv[i] * l_pound_w_points[i])); - - if (l_vdm_compare_biased_mv[i] < MIN_VDM_VOLTAGE_IN_MV) - { - l_vdm_compare_biased_mv[i] = MIN_VDM_VOLTAGE_IN_MV; - } - - o_data->poundw[i].vdm_vid_compare_ivid = (l_vdm_compare_biased_mv[i] - VDM_VOLTAGE_IN_MV) >> 2; - - FAPI_INF("vdm_vid_compare_ivid %x %x, %x", - o_data->poundw[i].vdm_vid_compare_ivid, - o_data->poundw[i].vdm_vid_compare_ivid, - l_pound_w_points[i]); - } - - //If we have reached this point, that means VDM is ok to be enabled. Only then we try to - //enable wov undervolting - uint8_t wov_underv_force; - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_WOV_UNDERV_FORCE, i_target, wov_underv_force), - "Error from FAPI_ATTR_GET for attribute ATTR_WOV_UNDERV_FORCE"); - if ( ((o_data->undervolt_tested == 1) || (wov_underv_force == 1)) && - is_wov_underv_enabled(i_target,o_state) == 1) { - o_state->iv_wov_underv_enabled = true; - FAPI_INF("UNDERV_TESTED or UNDERV_FORCE set to 1"); - } else{ - o_state->iv_wov_underv_enabled = false; - FAPI_INF("UNDERV_TESTED and UNDERV_FORCE set to 0"); - } - - memcpy(&(o_vdmpb->vpd_w_data), o_data, sizeof(o_vdmpb->vpd_w_data)); - } - while(0); - - -fapi_try_exit: - - // Given #W has VDM, WOF, and WOV content, a failure needs to disable all - if (fapi2::current_err != fapi2::FAPI2_RC_SUCCESS) - { - o_state->iv_vdm_enabled = false; - o_state->iv_wof_enabled = false; - o_state->iv_wov_underv_enabled = false; - o_state->iv_wov_overv_enabled = false; - } - - if (!(o_state->iv_vdm_enabled)) - { - // With VDMs disabled, we have to ensure that we have some Large - // Jump values to compute the safe mode frequency and voltage as some - // part sorts assume that uplift in their guardbands. As systems are - // offered assuming VDM operability which elevates the floor, default - // values are needed. - large_jump_defaults(o_data); - } - FAPI_DBG("<< proc_get_mvpd_poundw"); - return fapi2::current_err; - -} - - -fapi2::ReturnCode -proc_set_resclk_table_attrs(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - PSTATE_attribute_state* o_state) -{ - uint8_t l_resclk_freq_index[RESCLK_FREQ_REGIONS]; - uint8_t l_l3_steparray[RESCLK_L3_STEPS]; - uint16_t l_resclk_freq_regions[RESCLK_FREQ_REGIONS]; - uint16_t l_resclk_value[RESCLK_STEPS]; - uint16_t l_l3_threshold_mv; - o_state->iv_resclk_enabled = true; - - do - { - // Perform some basic sanity checks on the header data structures (since - // the header values are provided by another team) - FAPI_ASSERT_NOEXIT((p9_resclk_defines::RESCLK_INDEX_VEC.size() == RESCLK_FREQ_REGIONS), - fapi2::PSTATE_PB_RESCLK_INDEX_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_FREQ_REGIONS(RESCLK_FREQ_REGIONS) - .set_INDEX_VEC_SIZE(p9_resclk_defines::RESCLK_INDEX_VEC.size()), - "p9_resclk_defines.h RESCLK_INDEX_VEC.size() mismatch"); - - FAPI_ASSERT_NOEXIT((p9_resclk_defines::RESCLK_TABLE_VEC.size() == RESCLK_STEPS), - fapi2::PSTATE_PB_RESCLK_TABLE_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_STEPS(RESCLK_STEPS) - .set_TABLE_VEC_SIZE(p9_resclk_defines::RESCLK_TABLE_VEC.size()), - "p9_resclk_defines.h RESCLK_TABLE_VEC.size() mismatch"); - - FAPI_ASSERT_NOEXIT((p9_resclk_defines::L3CLK_TABLE_VEC.size() == RESCLK_L3_STEPS), - fapi2::PSTATE_PB_RESCLK_L3_TABLE_ERROR(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_L3_STEPS(RESCLK_L3_STEPS) - .set_L3_VEC_SIZE(p9_resclk_defines::L3CLK_TABLE_VEC.size()), - "p9_resclk_defines.h L3CLK_TABLE_VEC.size() mismatch"); - //FAPI_ASSERT_NOEXIT will log an error with recoverable.. but rc won't be - //cleared.. So we are initializing again to continue further - if (fapi2::current_err != fapi2::FAPI2_RC_SUCCESS) - { - o_state->iv_resclk_enabled = false; - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - break; - } - - - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_L3_VALUE, i_target, - l_l3_steparray)); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_FREQ_REGIONS, i_target, - l_resclk_freq_regions)); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_FREQ_REGION_INDEX, i_target, - l_resclk_freq_index)); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_VALUE, i_target, - l_resclk_value)); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RESCLK_L3_VOLTAGE_THRESHOLD_MV, i_target, - l_l3_threshold_mv)); - - for (uint8_t i = 0; i < RESCLK_FREQ_REGIONS; ++i) - { - if (l_resclk_freq_regions[i] == 0) - { - l_resclk_freq_regions[i] = p9_resclk_defines::RESCLK_INDEX_VEC.at(i).freq; - } - - if (l_resclk_freq_index[i] == 0) - { - l_resclk_freq_index[i] = p9_resclk_defines::RESCLK_INDEX_VEC.at(i).idx; - } - } - - for (uint8_t i = 0; i < RESCLK_STEPS; ++i) - { - if (l_resclk_value[i] == 0) - { - l_resclk_value[i] = p9_resclk_defines::RESCLK_TABLE_VEC.at(i); - } - } - - for (uint8_t i = 0; i < RESCLK_L3_STEPS; ++i) - { - if (l_l3_steparray[i] == 0) - { - l_l3_steparray[i] = p9_resclk_defines::L3CLK_TABLE_VEC.at(i); - } - } - - if(l_l3_threshold_mv == 0) - { - l_l3_threshold_mv = p9_resclk_defines::L3_VOLTAGE_THRESHOLD_MV; - } - - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SYSTEM_RESCLK_L3_VALUE, i_target, - l_l3_steparray)); - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SYSTEM_RESCLK_FREQ_REGIONS, i_target, - l_resclk_freq_regions)); - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SYSTEM_RESCLK_FREQ_REGION_INDEX, i_target, - l_resclk_freq_index)); - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SYSTEM_RESCLK_VALUE, i_target, - l_resclk_value)); - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SYSTEM_RESCLK_L3_VOLTAGE_THRESHOLD_MV, i_target, - l_l3_threshold_mv)); - }while(0); - -fapi_try_exit: - return fapi2::current_err; -} - -//@brief Initialize HOMER VFRT data -fapi2::ReturnCode -p9_pstate_update_vfrt(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - const GlobalPstateParmBlock* i_gppb, - uint8_t* i_pBuffer, - HomerVFRTLayout_t* o_vfrt_data, - uint32_t i_reference_freq) -{ - uint32_t l_index_0 = 0; - uint32_t l_index_1 = 0; - uint8_t l_type = 0; - uint32_t l_freq_khz = 0; - uint32_t l_step_freq_khz; - Pstate l_ps; - - l_step_freq_khz = revle32(i_gppb->frequency_step_khz); - FAPI_DBG("l_step_freq_khz = 0x%X (%d)", l_step_freq_khz, l_step_freq_khz); - - //Initialize VFRT header - o_vfrt_data->vfrtHeader.magic_number = revle16(UINT16_GET(i_pBuffer)); - i_pBuffer += 2; - o_vfrt_data->vfrtHeader.reserved = revle16(UINT16_GET(i_pBuffer)); - i_pBuffer += 2; - o_vfrt_data->vfrtHeader.type_version = *i_pBuffer; - i_pBuffer++; - o_vfrt_data->vfrtHeader.res_vdnId = *i_pBuffer; // Future: this name is not accurate but takes a header change. - i_pBuffer++; - o_vfrt_data->vfrtHeader.VddId_QAId = *i_pBuffer; // Future: this name is not accurate but takes a header change. - i_pBuffer++; - o_vfrt_data->vfrtHeader.rsvd_QAId = *i_pBuffer; - i_pBuffer++; - - - //find type - l_type = (o_vfrt_data->vfrtHeader.type_version) >> 4; - - char l_buffer_str[256]; // Temporary formatting string buffer - char l_line_str[256]; // Formatted output line string - - // Filtering Tracing output to only only QID of 0 - bool b_output_trace = false; - if (o_vfrt_data->vfrtHeader.rsvd_QAId == QID_KEY && - o_vfrt_data->vfrtHeader.res_vdnId <= VDN_PERCENT_KEY) - { - b_output_trace = true; - } - FAPI_DBG("res_vdnId = %X, VDN_PERCENT_KEY = %X, .rsvd_QAId = %X, QID_KEY = %X, trace = %u", - o_vfrt_data->vfrtHeader.res_vdnId, VDN_PERCENT_KEY, - o_vfrt_data->vfrtHeader.rsvd_QAId, QID_KEY, - b_output_trace); - - if (b_output_trace) - { - strcpy(l_line_str, "VFRT:"); - sprintf(l_buffer_str, " %X Ver/Type %X VDN%% %3d VDD%% %3d QID %d", - revle16(o_vfrt_data->vfrtHeader.magic_number), - revle16(o_vfrt_data->vfrtHeader.type_version), - o_vfrt_data->vfrtHeader.res_vdnId, /// BUG: this should be VDN!!! - o_vfrt_data->vfrtHeader.VddId_QAId, /// BUG: this should be VDD!!! - o_vfrt_data->vfrtHeader.rsvd_QAId); /// BUG: this should be resvQID!!! - strcat(l_line_str, l_buffer_str); - } - - const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - - fapi2::ATTR_WOF_ENABLE_FRATIO_Type l_enable_fratio; - FAPI_ATTR_GET(fapi2::ATTR_WOF_ENABLE_FRATIO, - FAPI_SYSTEM, - l_enable_fratio); - - fapi2::ATTR_WOF_ENABLE_VRATIO_Type l_enable_vratio; - FAPI_ATTR_GET(fapi2::ATTR_WOF_ENABLE_VRATIO, - FAPI_SYSTEM, - l_enable_vratio); - - bool b_fratio_set = true; - bool b_first_vratio_set = true; - - // Get the frequency biases in place and check that they all match - double f_freq_bias = 0; - int freq_bias_value_hp = 0; - int freq_bias_value_m1_hp = 0; - bool b_bias_error = false; - for (auto v = 0; v < NUM_OP_POINTS; ++v) - { - freq_bias_value_hp = i_gppb->ext_biases[v].frequency_hp; - if (v > 0) - { - if (freq_bias_value_hp != freq_bias_value_m1_hp) - { - b_bias_error = true; - FAPI_DBG("FATAL Bias mismatch error: v = %d; freq_bias_value_hp = %d; freq_bias_value_m1_hp = %d", - v, freq_bias_value_hp, freq_bias_value_m1_hp ); - } - } - - freq_bias_value_m1_hp = freq_bias_value_hp; - - if (v == ULTRA) - { - f_freq_bias = calc_bias(freq_bias_value_hp); - } - } - - FAPI_ASSERT(!b_bias_error, - fapi2::PSTATE_PB_VFRT_BIAS_ERROR() - .set_CHIP_TARGET(i_target) - .set_FREQ_BIAS_HP_ULTRATURBO(i_gppb->ext_biases[ULTRA].frequency_hp) - .set_FREQ_BIAS_HP_TURBO(i_gppb->ext_biases[TURBO].frequency_hp) - .set_FREQ_BIAS_HP_NOMINAL(i_gppb->ext_biases[NOMINAL].frequency_hp) - .set_FREQ_BIAS_HP_POWERSAVE(i_gppb->ext_biases[POWERSAVE].frequency_hp) - .set_UT_FREQ(i_reference_freq), - "Frequency Biases do not match so VFRT biasing cannot occur"); - - if (f_freq_bias != 1) - FAPI_INF("A frequency bias multiplier of %f being applied to all VFRT entries", - f_freq_bias); - - //Initialize VFRT data part - for (l_index_0 = 0; l_index_0 < VFRT_FRATIO_SIZE; ++l_index_0) - { - strcpy(l_buffer_str, ""); - - for (l_index_1 = 0; l_index_1 < VFRT_VRATIO_SIZE; ++l_index_1) - { - // Offset MHz*1000 (khz) + step (khz) * sysvalue - float l_freq_raw_khz; - float l_freq_biased_khz; - l_freq_raw_khz = (float)(1000 * 1000 + (l_step_freq_khz * (*i_pBuffer))); - - l_freq_biased_khz = l_freq_raw_khz * f_freq_bias; - - // Round to nearest MHz as that is how the system tables are generated - float l_freq_raw_up_mhz = (l_freq_biased_khz + 500)/1000; - float l_freq_raw_dn_mhz = (l_freq_biased_khz)/1000; - float l_freq_rounded_khz; - if (l_freq_raw_up_mhz >= l_freq_raw_dn_mhz) - l_freq_rounded_khz = (uint32_t)(l_freq_raw_up_mhz * 1000); - else - l_freq_rounded_khz = (uint32_t)(l_freq_raw_dn_mhz * 1000); - - l_freq_khz = (uint32_t)(l_freq_rounded_khz); - - FAPI_DBG("freq_raw_khz = %f; freq_biased_khz = %f; freq_rounded = 0x%X (%d); sysvalue = 0x%X (%d)", - l_freq_raw_khz, - l_freq_biased_khz, - l_freq_khz, l_freq_khz, - *i_pBuffer, *i_pBuffer); - - // Translate to Pstate. The called function will clip to the - // legal range. The rc is only interesting if we care that - // the pstate was clipped; in this case, we don't. - freq2pState(i_gppb, l_freq_khz, &l_ps); - - o_vfrt_data->vfrt_data[l_index_0][l_index_1] = l_ps; - - if (b_first_vratio_set && l_index_1 >= 20 && b_output_trace) - { - sprintf(l_buffer_str, "[%2d][%2d] 0x%2X %4d; ", - l_index_0, l_index_1, - l_ps, l_freq_khz / 1000); - strcat(l_line_str, l_buffer_str); - } - - // Trace the last 8 values of the 24 for debug. As this is - // in a loop that is processing over 1000 tables, the last - // 8 gives a view that can correlate that the input data read - // is correct without overfilling the HB trace buffer. - if (l_index_1+1 == VFRT_VRATIO_SIZE && b_first_vratio_set && b_fratio_set && b_output_trace) - { - FAPI_INF("%s ", l_line_str); - strcpy(l_buffer_str, ""); - strcpy(l_line_str, " "); - b_first_vratio_set = false; - } - - i_pBuffer++; - } - - // If fratio is not enabled, don't trace the remaining, duplicate entries. - if (!l_enable_fratio) - { - b_fratio_set = false; - b_first_vratio_set = false; - } - else - { - b_fratio_set = true; - b_first_vratio_set = true; - } - - } - - // Flip the type from System (0) to HOMER (1) - l_type = 1; - o_vfrt_data->vfrtHeader.type_version |= l_type << 4; - -fapi_try_exit: - return fapi2::current_err; -} - -// -// p9_pstate_compute_vdm_threshold_pts -// -void p9_pstate_compute_vdm_threshold_pts(PoundW_data i_data, - LocalPstateParmBlock* io_lppb) -{ - int p = 0; - - //VID POINTS - for (p = 0; p < NUM_OP_POINTS; p++) - { - io_lppb->vid_point_set[p] = i_data.poundw[p].vdm_vid_compare_ivid; - FAPI_INF("Bi:VID=%x", io_lppb->vid_point_set[p]); - } - - // Threshold points - for (p = 0; p < NUM_OP_POINTS; p++) - { - // overvolt threshold - io_lppb->threshold_set[p][VDM_OVERVOLT_INDEX] = g_GreyCodeIndexMapping[(i_data.poundw[p].vdm_overvolt_small_thresholds >> 4) & 0x0F]; - - FAPI_INF("Bi: OV TSHLD =%d", io_lppb->threshold_set[p][0]); - // small threshold - io_lppb->threshold_set[p][VDM_SMALL_INDEX] = (g_GreyCodeIndexMapping[i_data.poundw[p].vdm_overvolt_small_thresholds & 0x0F]); - - FAPI_INF("Bi: SM TSHLD =%d", io_lppb->threshold_set[p][1]); - // large threshold - io_lppb->threshold_set[p][VDM_LARGE_INDEX] = (g_GreyCodeIndexMapping[(i_data.poundw[p].vdm_large_extreme_thresholds >> 4) & 0x0F]); - - FAPI_INF("Bi: LG TSHLD =%d", io_lppb->threshold_set[p][2]); - // extreme threshold - io_lppb->threshold_set[p][VDM_XTREME_INDEX] = (g_GreyCodeIndexMapping[i_data.poundw[p].vdm_large_extreme_thresholds & 0x0F]); - - FAPI_INF("Bi: EX TSHLD =%d", io_lppb->threshold_set[p][3]); - - } - // Jump value points - for (p = 0; p < NUM_OP_POINTS; p++) - { - // N_L value - io_lppb->jump_value_set[p][VDM_N_S_INDEX] = (i_data.poundw[p].vdm_normal_freq_drop >> 4) & 0x0F; - - FAPI_INF("Bi: N_S =%d", io_lppb->jump_value_set[p][0]); - // N_S value - io_lppb->jump_value_set[p][VDM_N_L_INDEX] = i_data.poundw[p].vdm_normal_freq_drop & 0x0F; - - FAPI_INF("Bi: N_L =%d", io_lppb->jump_value_set[p][1]); - // L_S value - io_lppb->jump_value_set[p][VDM_L_S_INDEX] = (i_data.poundw[p].vdm_normal_freq_return >> 4) & 0x0F; - - FAPI_INF("Bi: L_S =%d", io_lppb->jump_value_set[p][2]); - // S_L value - io_lppb->jump_value_set[p][VDM_S_N_INDEX] = i_data.poundw[p].vdm_normal_freq_return & 0x0F; - - FAPI_INF("Bi: S_L =%d", io_lppb->jump_value_set[p][3]); - } -} -// -// -// p9_pstate_compute_PsVIDCompSlopes_slopes -// -void p9_pstate_compute_PsVIDCompSlopes_slopes(PoundW_data i_data, - LocalPstateParmBlock* io_lppb, - uint8_t* i_pstate) -{ - do - { - char const* region_names[] = { "REGION_POWERSAVE_NOMINAL", - "REGION_NOMINAL_TURBO", - "REGION_TURBO_ULTRA" - }; - - // ULTRA TURBO pstate check is not required..because its pstate will be - // 0 - if (!(i_pstate[POWERSAVE]) || - !(i_pstate[NOMINAL]) || - !(i_pstate[TURBO])) - { - FAPI_ERR("Non-UltraTurbo PSTATE value shouldn't be zero"); - break; - } - - for(auto region(REGION_POWERSAVE_NOMINAL); region <= REGION_TURBO_ULTRA; ++region) - { - io_lppb->PsVIDCompSlopes[region] = - revle16( - compute_slope_4_12( io_lppb->vid_point_set[region + 1], - io_lppb->vid_point_set[region], - i_pstate[region], - i_pstate[region + 1]) - ); - - FAPI_DBG("PsVIDCompSlopes[%s] 0x%04x %d", region_names[region], - revle16(io_lppb->PsVIDCompSlopes[region]), - revle16(io_lppb->PsVIDCompSlopes[region])); - } - } - while(0); -} - -// -// -// p9_pstate_compute_PsVDMThreshSlopes -// -void p9_pstate_compute_PsVDMThreshSlopes( - LocalPstateParmBlock* io_lppb, - uint8_t* i_pstate) -{ - do - { - // ULTRA TURBO pstate check is not required..because its pstate will be - // 0 - if (!(i_pstate[POWERSAVE]) || - !(i_pstate[NOMINAL]) || - !(i_pstate[TURBO])) - { - FAPI_ERR("Non-UltraTurbo PSTATE value shouldn't be zero"); - break; - } - - for(auto region(REGION_POWERSAVE_NOMINAL); region <= REGION_TURBO_ULTRA; ++region) - { - for (uint8_t i = 0; i < NUM_THRESHOLD_POINTS; ++i) - { - io_lppb->PsVDMThreshSlopes[region][i] = - revle16( - compute_slope_thresh(io_lppb->threshold_set[region+1][i], - io_lppb->threshold_set[region][i], - i_pstate[region], - i_pstate[region+1]) - ); - - FAPI_INF("PsVDMThreshSlopes %s %x TH_N %d TH_P %d PS_P %d PS_N %d", - prt_region_names[region], - revle16(io_lppb->PsVDMThreshSlopes[region][i]), - io_lppb->threshold_set[region+1][i], - io_lppb->threshold_set[region][i], - i_pstate[region], - i_pstate[region+1]); - } - } - } - while(0); -} - -// -// p9_pstate_compute_PsVDMJumpSlopes -// -void p9_pstate_compute_PsVDMJumpSlopes( - LocalPstateParmBlock* io_lppb, - uint8_t* i_pstate) -{ - do - { - // ULTRA TURBO pstate check is not required..because its pstate will be - // 0 - if (!(i_pstate[POWERSAVE]) || - !(i_pstate[NOMINAL]) || - !(i_pstate[TURBO])) - { - FAPI_ERR("Non-UltraTurbo PSTATE value shouldn't be zero"); - break; - } - - //Calculate slopes - // - for(auto region(REGION_POWERSAVE_NOMINAL); region <= REGION_TURBO_ULTRA; ++region) - { - for (uint8_t i = 0; i < NUM_JUMP_VALUES; ++i) - { - io_lppb->PsVDMJumpSlopes[region][i] = - revle16( - compute_slope_thresh(io_lppb->jump_value_set[region+1][i], - io_lppb->jump_value_set[region][i], - i_pstate[region], - i_pstate[region+1]) - ); - - FAPI_INF("PsVDMJumpSlopes %s %x N_S %d N_L %d L_S %d S_N %d", - prt_region_names[region], - revle16(io_lppb->PsVDMJumpSlopes[region][i]), - io_lppb->jump_value_set[region+1][i], - io_lppb->jump_value_set[region][i], - i_pstate[region], - i_pstate[region+1]); - } - } - } - while(0); -} -// p9_pstate_set_global_feature_attributes -fapi2::ReturnCode -p9_pstate_set_global_feature_attributes(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - PSTATE_attribute_state i_state, - QuadManagerFlags* o_qm_flags) -{ - // Quad Manager Flags - fapi2::buffer<uint16_t> l_data16; - - fapi2::ATTR_PSTATES_ENABLED_Type l_ps_enabled = - (fapi2::ATTR_PSTATES_ENABLED_Type)fapi2::ENUM_ATTR_PSTATES_ENABLED_FALSE; - - fapi2::ATTR_RESCLK_ENABLED_Type l_resclk_enabled = - (fapi2::ATTR_RESCLK_ENABLED_Type)fapi2::ENUM_ATTR_RESCLK_ENABLED_FALSE; - - fapi2::ATTR_VDM_ENABLED_Type l_vdm_enabled = - (fapi2::ATTR_VDM_ENABLED_Type)fapi2::ENUM_ATTR_VDM_ENABLED_FALSE; - - fapi2::ATTR_IVRM_ENABLED_Type l_ivrm_enabled = - (fapi2::ATTR_IVRM_ENABLED_Type)fapi2::ENUM_ATTR_IVRM_ENABLED_FALSE; - - fapi2::ATTR_WOF_ENABLED_Type l_wof_enabled = - (fapi2::ATTR_WOF_ENABLED_Type)fapi2::ENUM_ATTR_WOF_ENABLED_FALSE; - - fapi2::ATTR_WOV_UNDERV_ENABLED_Type l_wov_underv_enabled = - (fapi2::ATTR_WOV_UNDERV_ENABLED_Type)fapi2::ENUM_ATTR_WOV_UNDERV_ENABLED_FALSE; - - fapi2::ATTR_WOV_OVERV_ENABLED_Type l_wov_overv_enabled = - (fapi2::ATTR_WOV_OVERV_ENABLED_Type)fapi2::ENUM_ATTR_WOV_OVERV_ENABLED_FALSE; - - if (i_state.iv_pstates_enabled) - { - l_ps_enabled = (fapi2::ATTR_PSTATES_ENABLED_Type)fapi2::ENUM_ATTR_PSTATES_ENABLED_TRUE; - } - - if (i_state.iv_resclk_enabled) - { - l_resclk_enabled = (fapi2::ATTR_RESCLK_ENABLED_Type)fapi2::ENUM_ATTR_RESCLK_ENABLED_TRUE; - } - - if (i_state.iv_vdm_enabled) - { - l_vdm_enabled = (fapi2::ATTR_VDM_ENABLED_Type)fapi2::ENUM_ATTR_VDM_ENABLED_TRUE; - } - - if (i_state.iv_ivrm_enabled) - { - l_ivrm_enabled = (fapi2::ATTR_IVRM_ENABLED_Type)fapi2::ENUM_ATTR_IVRM_ENABLED_TRUE; - } - - if (i_state.iv_wof_enabled) - { - l_wof_enabled = (fapi2::ATTR_WOF_ENABLED_Type)fapi2::ENUM_ATTR_WOF_ENABLED_TRUE; - } - - if (i_state.iv_wov_underv_enabled) - { - l_wov_underv_enabled = (fapi2::ATTR_WOV_UNDERV_ENABLED_Type)fapi2::ENUM_ATTR_WOV_UNDERV_ENABLED_TRUE; - } - - if (i_state.iv_wov_overv_enabled) - { - l_wov_overv_enabled = (fapi2::ATTR_WOV_OVERV_ENABLED_Type)fapi2::ENUM_ATTR_WOV_OVERV_ENABLED_TRUE; - } - -#define SET_ATTR(attr_name, target, attr_assign) \ -FAPI_TRY(FAPI_ATTR_SET(attr_name, target, attr_assign),"Attribute set failed"); \ -FAPI_INF("%-60s = 0x%08x %d", #attr_name, attr_assign, attr_assign); - - SET_ATTR(fapi2::ATTR_PSTATES_ENABLED, i_target, l_ps_enabled); - SET_ATTR(fapi2::ATTR_RESCLK_ENABLED, i_target, l_resclk_enabled); - SET_ATTR(fapi2::ATTR_VDM_ENABLED, i_target, l_vdm_enabled); - SET_ATTR(fapi2::ATTR_IVRM_ENABLED, i_target, l_ivrm_enabled); - SET_ATTR(fapi2::ATTR_WOF_ENABLED, i_target, l_wof_enabled); - SET_ATTR(fapi2::ATTR_WOV_UNDERV_ENABLED, i_target, l_wov_underv_enabled); - SET_ATTR(fapi2::ATTR_WOV_OVERV_ENABLED, i_target, l_wov_overv_enabled); - - // ---------------- - // set CME QM flags - // ---------------- - l_data16.flush<0>(); - - l_data16.insertFromRight<0, 1>(l_resclk_enabled); - l_data16.insertFromRight<1, 1>(l_ivrm_enabled); - l_data16.insertFromRight<2, 1>(l_vdm_enabled); - l_data16.insertFromRight<3, 1>(l_wof_enabled); - - - // DROOP_PROTECT -> DPLL Mode 3 - // DROOP_PROTECT_OVERVOLT -> DPLL Mode 3.5 - // DYNAMIC -> DPLL Mode 4 - // DYNAMIC_PROTECT -> DPLL Mode 5 - - // enable_fmin enable_fmax enable_jump - // DPLL Mode 2 0 0 0 - // DPLL Mode 3 0 0 1 - // DPLL Mode 4 X 1 0 - // DPLL Mode 4 1 X 0 - // DPLL Mode 3.5 0 1 1 - // DPLL Mode 5 1 X 1 - - switch (attr.attr_dpll_vdm_response) - { - case fapi2::ENUM_ATTR_DPLL_VDM_RESPONSE_DROOP_PROTECT: - l_data16 |= CME_QM_FLAG_SYS_JUMP_PROTECT; - FAPI_INF("%-60s", "DPLL Response"); - FAPI_INF("%-60s = Set", "CME_QM_FLAG_SYS_JUMP_PROTECT"); - break; - case fapi2::ENUM_ATTR_DPLL_VDM_RESPONSE_DROOP_PROTECT_OVERVOLT: - l_data16 |= CME_QM_FLAG_SYS_DYN_FMAX_ENABLE; - l_data16 |= CME_QM_FLAG_SYS_JUMP_PROTECT; - FAPI_INF("%-60s", "DPLL Response"); - FAPI_INF("%-60s = Set", "CME_QM_FLAG_SYS_DYN_FMAX_ENABLE"); - FAPI_INF("%-60s = Set", "CME_QM_FLAG_SYS_JUMP_PROTECT"); - break; - case fapi2::ENUM_ATTR_DPLL_VDM_RESPONSE_DYNAMIC: - l_data16 |= CME_QM_FLAG_SYS_DYN_FMIN_ENABLE; - l_data16 |= CME_QM_FLAG_SYS_DYN_FMAX_ENABLE; - FAPI_INF("%-60s", "DPLL Response"); - FAPI_INF("%-60s = Set", "CME_QM_FLAG_SYS_DYN_FMIN_ENABLEE"); - FAPI_INF("%-60s = Set", "CME_QM_FLAG_SYS_DYN_FMAX_ENABLE"); - break; - case fapi2::ENUM_ATTR_DPLL_VDM_RESPONSE_DYNAMIC_PROTECT: - l_data16 |= CME_QM_FLAG_SYS_DYN_FMIN_ENABLE; - l_data16 |= CME_QM_FLAG_SYS_JUMP_PROTECT; - FAPI_INF("%-60s", "DPLL Response"); - FAPI_INF("%-60s = Set", "CME_QM_FLAG_SYS_DYN_FMIN_ENABLE"); - FAPI_INF("%-60s = Set", "CME_QM_FLAG_SYS_JUMP_PROTECT"); - break; - } - - o_qm_flags->value = revle16(l_data16); - FAPI_INF("%-60s = 0x%04x %d", "QM Flags", revle16(o_qm_flags->value)); - -fapi_try_exit: - return fapi2::current_err; -} - -//large_jump_interpolate -uint32_t -large_jump_interpolate(const Pstate i_pstate, - const VpdOperatingPoint i_operating_points[NUM_OP_POINTS], - const uint32_t i_step_frequency, - const Pstate i_ps_pstate, - const PoundW_data i_data) -{ - - uint8_t l_jump_value_set_ps = - i_data.poundw[POWERSAVE].vdm_normal_freq_drop & 0x0F; - uint8_t l_jump_value_set_nom = - i_data.poundw[NOMINAL].vdm_normal_freq_drop & 0x0F; - - uint32_t l_slope_value = - compute_slope_thresh(l_jump_value_set_nom, - l_jump_value_set_ps, - i_operating_points[POWERSAVE].pstate, - i_operating_points[NOMINAL].pstate); - - uint32_t l_vdm_jump_value = - (uint32_t)((int32_t)l_jump_value_set_ps + (((int32_t)l_slope_value * - (i_ps_pstate - i_pstate)) >> THRESH_SLOPE_FP_SHIFT)); - return l_vdm_jump_value; -} - -//large_jump_defaults -void -large_jump_defaults(PoundW_data* io_data) -{ - const float DEFAULT_VDM_DROP_PERCENT = 12.5; - const float DEFAULT_VDM_DROP_DIVISOR = 32; - float poundw_freq_drop_float = (DEFAULT_VDM_DROP_PERCENT/100)*DEFAULT_VDM_DROP_DIVISOR; - uint8_t poundw_freq_drop_value = (uint8_t)poundw_freq_drop_float; - FAPI_DBG ("DEFAULT_VDM_DROP_PERCENT = %6.3f%%; DEFAULT_VDM_DROP_DIVISOR = %6.3f; poundw_freq_drop_value = %f %X", - DEFAULT_VDM_DROP_PERCENT, - DEFAULT_VDM_DROP_DIVISOR, - poundw_freq_drop_float, - poundw_freq_drop_value); - - // N_S/N_L - each a nibble in a byte - io_data->poundw[POWERSAVE].vdm_normal_freq_drop = poundw_freq_drop_value; - io_data->poundw[NOMINAL].vdm_normal_freq_drop = poundw_freq_drop_value; - - FAPI_INF ("Using default Large Jump percentage (%6.3f%%) for N_L (%X) for both POWERSAVE and NOMINAL due to #W access failure ", - DEFAULT_VDM_DROP_PERCENT, - io_data->poundw[POWERSAVE].vdm_normal_freq_drop); - - return; -} - - -//ps2v_mv - Pstate to External Voltage in mV -uint32_t ps2v_mv(const Pstate i_pstate, - const VpdOperatingPoint i_operating_points[NUM_OP_POINTS], - const uint32_t i_step_frequency) -{ - - uint32_t region_start, region_end; - const char* pv_op_str[NUM_OP_POINTS] = PV_OP_ORDER_STR; - - FAPI_DBG("i_pstate = 0x%x, (%d)", i_pstate, i_pstate); - - // Determine the VPD region - if(i_pstate > i_operating_points[NOMINAL].pstate) - { - region_start = POWERSAVE; - region_end = NOMINAL; - FAPI_DBG("Region POWERSAVE_NOMINAL detected"); - } - else if(i_pstate > i_operating_points[TURBO].pstate) - { - region_start = NOMINAL; - region_end = TURBO; - FAPI_DBG("Region NOMINAL_TURBO detected"); - } - else - { - region_start = TURBO; - region_end = ULTRA; - FAPI_DBG("Region TURBO_ULTRA detected"); - } - - uint32_t l_SlopeValue = - compute_slope_4_12(revle32(i_operating_points[region_end].vdd_mv), - revle32(i_operating_points[region_start].vdd_mv), - i_operating_points[region_start].pstate, - i_operating_points[region_end].pstate); - - FAPI_INF("l_globalppb.i_operating_points[%s].vdd_mv 0x%-3x (%d)", - pv_op_str[region_end], - revle32(i_operating_points[region_end].vdd_mv), - revle32(i_operating_points[region_end].vdd_mv)); - FAPI_INF("l_globalppb.i_operating_points[%s].vdd_mv 0x%-3x (%d)", - pv_op_str[region_start], - revle32(i_operating_points[region_start].vdd_mv), - revle32(i_operating_points[region_start].vdd_mv)); - FAPI_INF("l_globalppb.i_operating_points[%s].pstate 0x%-3x (%d)", - pv_op_str[region_end], - i_operating_points[region_end].pstate, - i_operating_points[region_end].pstate); - FAPI_INF("l_globalppb.i_operating_points[%s].pstate 0x%-3x (%d)", - pv_op_str[region_start], - i_operating_points[region_start].pstate, - i_operating_points[region_start].pstate); - - FAPI_INF ("l_SlopeValue %x",l_SlopeValue); - - - uint32_t x = (l_SlopeValue * (-i_pstate + i_operating_points[region_start].pstate)); - uint32_t y = x >> VID_SLOPE_FP_SHIFT_12; - - uint32_t l_vdd = - (((l_SlopeValue * (-i_pstate + i_operating_points[region_start].pstate)) >> VID_SLOPE_FP_SHIFT_12) - + revle32(i_operating_points[region_start].vdd_mv)); - - // Round up - l_vdd = (l_vdd << 1) + 1; - l_vdd = l_vdd >> 1; - - FAPI_DBG("i_pstate = %d " - "i_operating_points[%s].pstate) = %d " - "i_operating_points[%s].vdd_mv = %d " - "VID_SLOPE_FP_SHIFT_12 = %X " - "x = %x (%d) y = %x (%d)", - i_pstate, - pv_op_str[region_start], i_operating_points[region_start].pstate, - pv_op_str[region_start], revle32(i_operating_points[region_start].vdd_mv), - VID_SLOPE_FP_SHIFT_12, - x, x, - y, y); - - - FAPI_INF ("l_vdd 0x%x (%d)", l_vdd, l_vdd); - - return l_vdd; -} - -//p9_pstate_safe_mode_computation -fapi2::ReturnCode -p9_pstate_safe_mode_computation(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - const VpdOperatingPoint i_operating_points[NUM_VPD_PTS_SET][NUM_OP_POINTS], - const uint32_t i_reference_freq, - const uint32_t i_step_frequency, - const Pstate i_ps_pstate, - Safe_mode_parameters *o_safe_mode_values, - const PoundW_data i_poundw_data) -{ - Safe_mode_parameters l_safe_mode_values; - const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; - fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ_Type l_safe_mode_freq_mhz; - fapi2::ATTR_SAFE_MODE_VOLTAGE_MV_Type l_safe_mode_mv; - fapi2::ATTR_VDD_BOOT_VOLTAGE_Type l_boot_mv; - uint32_t l_safe_mode_op_ps2freq_mhz; - uint32_t l_core_floor_mhz; - uint32_t l_op_pt; - - VpdOperatingPoint l_operating_point[NUM_OP_POINTS]; - get_operating_point(i_operating_points, - VPD_PT_SET_BIASED_SYSP, - l_operating_point); - - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_CORE_FLOOR_MHZ, - FAPI_SYSTEM, - l_core_floor_mhz)); - - // Core floor frequency should be less than ultra turbo freq.. - // if not log an error - if ((l_core_floor_mhz*1000) > i_reference_freq) - { - FAPI_ERR("Core floor frequency %08x is greater than UltraTurbo frequency %08x", - (l_core_floor_mhz*1000), i_reference_freq); - FAPI_ASSERT(false, - fapi2::PSTATE_PB_CORE_FLOOR_FREQ_GT_UT_FREQ() - .set_CHIP_TARGET(i_target) - .set_CORE_FLOOR_FREQ(l_core_floor_mhz*1000) - .set_UT_FREQ(i_reference_freq), - "Core floor freqency is greater than UltraTurbo frequency"); - } - - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ, i_target, l_safe_mode_freq_mhz)); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_VOLTAGE_MV, i_target, l_safe_mode_mv)); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDD_BOOT_VOLTAGE, i_target, l_boot_mv)); - - FAPI_DBG ("l_safe_mode_freq_mhz 0%08x (%d)", - l_safe_mode_freq_mhz, l_safe_mode_freq_mhz); - FAPI_DBG ("l_safe_mode_mv 0%08x (%d)", - l_safe_mode_mv, l_safe_mode_mv); - FAPI_DBG ("l_boot_mv 0%08x (%d)", - l_boot_mv, l_boot_mv); - - FAPI_INF ("core_floor_mhz 0%08x (%d)", - l_core_floor_mhz, - l_core_floor_mhz); - FAPI_INF("operating_point[POWERSAVE].frequency_mhz 0%08x (%d)", - revle32(l_operating_point[POWERSAVE].frequency_mhz), - revle32(l_operating_point[POWERSAVE].frequency_mhz)); - FAPI_INF ("reference_freq 0%08x (%d)", - i_reference_freq, i_reference_freq); - FAPI_INF ("step_frequency 0%08x (%d)", - i_step_frequency, i_step_frequency); - - l_op_pt = revle32(l_operating_point[POWERSAVE].frequency_mhz); - // Safe operational frequency is the MAX(core floor, VPD Powersave). - // PowerSave is the lowest operational frequency that the part was tested at - if (l_core_floor_mhz > l_op_pt) - { - FAPI_INF("Core floor greater that POWERSAVE"); - l_safe_mode_values.safe_op_freq_mhz = l_core_floor_mhz; - } - else - { - FAPI_INF("Core floor less than or equal to POWERSAVE"); - l_safe_mode_values.safe_op_freq_mhz = l_op_pt; - } - - FAPI_INF ("safe_mode_values.safe_op_freq_mhz 0%08x (%d)", - l_safe_mode_values.safe_op_freq_mhz, - l_safe_mode_values.safe_op_freq_mhz); - - // Calculate safe operational pstate. This must be rounded down to create - // a faster Pstate than the floor - l_safe_mode_values.safe_op_ps = ((float)(i_reference_freq) - - (float)(l_safe_mode_values.safe_op_freq_mhz * 1000)) / - (float)i_step_frequency; - - l_safe_mode_op_ps2freq_mhz = - (i_reference_freq - (l_safe_mode_values.safe_op_ps * i_step_frequency)) / 1000; - - while (l_safe_mode_op_ps2freq_mhz < l_safe_mode_values.safe_op_freq_mhz) - { - l_safe_mode_values.safe_op_ps--; - - l_safe_mode_op_ps2freq_mhz = - (i_reference_freq - (l_safe_mode_values.safe_op_ps * i_step_frequency)) / 1000; - } - - // Calculate safe jump value for large frequency - l_safe_mode_values.safe_vdm_jump_value = - large_jump_interpolate(l_safe_mode_values.safe_op_ps, - l_operating_point, - i_step_frequency, - i_ps_pstate, - i_poundw_data); - FAPI_INF ("l_safe_mode_values.safe_vdm_jump_value %x -> %5.2f %%", - l_safe_mode_values.safe_vdm_jump_value, - ((float)l_safe_mode_values.safe_vdm_jump_value/32)*100); - - // Calculate safe mode frequency - Round up to nearest MHz - // The uplifted frequency is based on the fact that the DPLL percentage is a - // "down" value. Hence: - // X (uplifted safe) = Y (safe operating) / (1 - droop percentage) - l_safe_mode_values.safe_mode_freq_mhz = (uint32_t) - (((float)l_safe_mode_op_ps2freq_mhz * 1000 / - (1 - (float)l_safe_mode_values.safe_vdm_jump_value/32) + 500) / 1000); - - if (l_safe_mode_freq_mhz) - { - l_safe_mode_values.safe_mode_freq_mhz = l_safe_mode_freq_mhz; - FAPI_INF("Applying override safe mode freq value of %d MHz", - l_safe_mode_freq_mhz); - } - else - { - FAPI_INF("Setting safe mode frequency to %d MHz (0x%x)", - l_safe_mode_values.safe_mode_freq_mhz, - l_safe_mode_values.safe_mode_freq_mhz); - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ, i_target, l_safe_mode_values.safe_mode_freq_mhz)); - } - FAPI_INF ("l_safe_mode_values.safe_mode_freq_mhz 0x%0x (%d)", - l_safe_mode_values.safe_mode_freq_mhz, - l_safe_mode_values.safe_mode_freq_mhz); - - // Safe frequency must be less than ultra turbo freq. - // if not log an error - if ((l_safe_mode_values.safe_mode_freq_mhz*1000) > i_reference_freq) - { - FAPI_ERR("Safe mode frequency %08x is greater than UltraTurbo frequency %08x", - (l_safe_mode_values.safe_mode_freq_mhz*1000), i_reference_freq); - FAPI_ASSERT(false, - fapi2::PSTATE_PB_SAFE_FREQ_GT_UT_FREQ() - .set_CHIP_TARGET(i_target) - .set_SAFE_FREQ(l_safe_mode_values.safe_mode_freq_mhz*1000) - .set_UT_FREQ(i_reference_freq), - "Safe mode freqency is greater than UltraTurbo frequency"); - } - - l_safe_mode_values.safe_mode_ps = ((float)(i_reference_freq) - - (float)(l_safe_mode_values.safe_mode_freq_mhz * 1000)) / - (float)i_step_frequency; - - FAPI_INF ("l_safe_mode_values.safe_mode_ps %x (%d)", - l_safe_mode_values.safe_mode_ps, - l_safe_mode_values.safe_mode_ps); - - // Calculate safe mode voltage - // Use the biased with system parms operating points - - l_safe_mode_values.safe_mode_mv = ps2v_mv(l_safe_mode_values.safe_mode_ps, - l_operating_point, - i_step_frequency); - - if (l_safe_mode_mv) - { - l_safe_mode_values.safe_mode_mv = l_safe_mode_mv; - FAPI_INF("Applying override safe mode voltage value of %d mV", - l_safe_mode_mv); - } - else - { - FAPI_INF("Setting safe mode voltage to %d mv (0x%x)", - l_safe_mode_values.safe_mode_mv, - l_safe_mode_values.safe_mode_mv); - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SAFE_MODE_VOLTAGE_MV, - i_target, - l_safe_mode_values.safe_mode_mv)); - } - - FAPI_INF ("l_safe_mode_values.safe_mode_mv 0x%x (%d)", - l_safe_mode_values.safe_mode_mv, - l_safe_mode_values.safe_mode_mv); - - fapi2::ATTR_SAFE_MODE_NOVDM_UPLIFT_MV_Type l_uplift_mv; - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SAFE_MODE_NOVDM_UPLIFT_MV, i_target, l_uplift_mv)); - - // Calculate boot mode voltage - l_safe_mode_values.boot_mode_mv = l_safe_mode_values.safe_mode_mv + l_uplift_mv; - - FAPI_INF("l_safe_mode_values.boot_mode_mv 0x%x (%d)", - l_safe_mode_values.boot_mode_mv, - l_safe_mode_values.boot_mode_mv); - - memcpy (o_safe_mode_values,&l_safe_mode_values, sizeof(Safe_mode_parameters)); - -fapi_try_exit: - return fapi2::current_err; -} // *INDENT-ON* diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.H b/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.H index f8e3de3fc..971a7be99 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.H +++ b/src/import/chips/p9/procedures/hwp/pm/p9_pstate_parameter_block.H @@ -34,65 +34,64 @@ #ifndef __P9_PSTATE_PARAMETER_BLOCK_H__ #define __P9_PSTATE_PARAMETER_BLOCK_H__ +#include <fapi2.H> #include <p9_pm_utils.H> #include <p9_pstates_common.h> #include <p9_pstates_pgpe.h> #include <p9_pstates_cmeqm.h> #include <p9_pstates_occ.h> #include "p9_pm_get_poundv_bucket.H" +#include "p9_pm_get_poundw_bucket.H" -#ifdef __cplusplus -extern "C" { -#endif -#define MAX_ACTIVE_CORES 24 +//Pstate SuperStructure +typedef struct +{ + /// Magic Number + uint64_t magic; -#define HOMER_WOF_TABLE_SIZE 258176 + // PGPE content + GlobalPstateParmBlock globalppb; -/// An internal operating point -/// -/// Internal operating points include characterization (both the original, -/// unbiased values and biased by external attributes) and load-line corrected -/// voltages for the external VRM. For the internal VRM, effective e-voltages -/// and maxreg voltages are stored. All voltages are stored as -/// uV. Characterization currents are in mA. Frequencies are in KHz. The -/// Pstate of the operating point (as a potentially out-of-bounds value) is -/// also stored. + // CME content + LocalPstateParmBlock localppb; -typedef struct + // OCC content + OCCPstateParmBlock occppb; + +} PstateSuperStructure; + +//VDD Voltage config actions +typedef enum { + COMPUTE_VOLTAGE_SETTINGS, + APPLY_VOLTAGE_SETTINGS +} VoltageConfigActions_t; - uint32_t vdd_uv; - uint32_t vcs_uv; - uint32_t vdd_corrected_uv; - uint32_t vcs_corrected_uv; - uint32_t vdd_corrected_wof_uv[MAX_ACTIVE_CORES]; - uint32_t vcs_corrected_wof_uv[MAX_ACTIVE_CORES]; - uint32_t vdd_ivrm_effective_uv; - uint32_t vcs_ivrm_effective_uv; - uint32_t vdd_maxreg_uv; - uint32_t vcs_maxreg_uv; - uint32_t idd_ma; - uint32_t ics_ma; - uint32_t frequency_khz; - int32_t pstate; -} OperatingPoint; +namespace pm_pstate_parameter_block +{ -typedef struct + +using namespace fapi2; +//VPD types +typedef enum VPD_TYPE +{ + RAW, + BIASED, +} vpd_type; + +//Frequency actions +enum FREQ2PSTATE_ROUNDING { - bool iv_pstates_enabled; - bool iv_resclk_enabled; - bool iv_vdm_enabled; - bool iv_ivrm_enabled; - bool iv_wof_enabled; - bool iv_wov_underv_enabled; - bool iv_wov_overv_enabled; -} PSTATE_attribute_state; + ROUND_FAST, + ROUND_SLOW +}; -// Safe mode frequency and voltage params +#define BIAS_PCT_UNIT 0.5 +//Safe mode parameters typedef struct { uint32_t safe_op_freq_mhz; @@ -104,79 +103,12 @@ typedef struct uint32_t boot_mode_mv; } Safe_mode_parameters; - -/// Constants required to compute and interpolate operating points -/// -/// The nominal frequency and frequency step-size is given in Hz. Load-line -/// and on-chip distribution resistances are given in micro-Ohms. -/// - -typedef struct -{ - uint32_t reference_frequency_khz; - uint32_t frequency_step_khz; // This is the reference frequency / DPPL_DIVIDER - // Load line parameters, This is also called Rloadline - uint32_t vdd_r_loadline_uohm; - uint32_t vcs_r_loadline_uohm; - uint32_t vdn_r_loadline_uohm; - // Distribution loss parameters, This is also called Rpath - uint32_t vdd_r_distloss_uohm; - uint32_t vcs_r_distloss_uohm; - uint32_t vdn_r_distloss_uohm; - uint32_t vdd_voffset_uv; - uint32_t vcs_voffset_uv; - uint32_t vdn_voffset_uv; -} SystemParameters; - - -/// A chip characterization - -typedef struct -{ - - VpdOperatingPoint* vpd; - VpdOperatingPoint* vpd_unbiased; - OperatingPoint* ops; - SystemParameters* parameters; - uint32_t points; - uint32_t max_cores; // Needed for WOF - -} ChipCharacterization; - - -//Section added back by ssrivath -// START OF PARMS REQUIRED VPD parsing procedures -#define PSTATE_STEPSIZE 1 -#define EVRM_DELAY_NS 100 -#define DEAD_ZONE_5MV 20 // 100mV -#define PDV_BUFFER_SIZE 51 -#define PDV_BUFFER_ALLOC 512 - -#define POUND_W_VERSION_2_BUCKET_SIZE 60 -#define PDM_BUFFER_SIZE 257 // Value is for version 3 @ 256 + 1 for version number -#define PDM_BUFFER_ALLOC 513 // Value is for version 2 @ 512 + 1 for version number -#define BIAS_PCT_UNIT 0.5 -#define BOOST_PCT_UNIT 0.001 -#define POUNDM_POINTS 13 -#define POUNDM_MEASUREMENTS_PER_POINT 4 - -// #V 2 dimensional array values (5x5) - 5 operating point and 5 values per operating point -#define PV_D 5 -#define PV_W 5 - -// IQ Keyword Sizes -#define IQ_BUFFER_SIZE 9 -#define IQ_BUFFER_ALLOC 255 -// END OF PARMS REQUIRED VPD parsing procedures - - // Structure contatining all attributes required by Pstate Parameter block typedef struct { - uint32_t attr_freq_core_ceiling_mhz; -// Loadline, Distribution loss and Distribution offset attVpdOpributes + // Loadline, Distribution loss and Distribution offset attVpdOpributes uint32_t attr_proc_r_loadline_vdd_uohm; uint32_t attr_proc_r_distloss_vdd_uohm; uint32_t attr_proc_vrm_voffset_vdd_uv; @@ -191,20 +123,20 @@ typedef struct uint32_t attr_proc_dpll_divider; uint32_t attr_nest_frequency_mhz; -// Frequency Bias attributes + // Frequency Bias attributes int8_t attr_freq_bias_ultraturbo; int8_t attr_freq_bias_turbo; int8_t attr_freq_bias_nominal; int8_t attr_freq_bias_powersave; -// External Voltage Timing attributes + // External Voltage Timing attributes uint32_t attr_ext_vrm_transition_start_ns; uint32_t attr_ext_vrm_transition_rate_inc_uv_per_us; uint32_t attr_ext_vrm_transition_rate_dec_uv_per_us; uint32_t attr_ext_vrm_stabilization_time_us; uint32_t attr_ext_vrm_step_size_mv; -// Voltage Bias attributes + // Voltage Bias attributes int8_t attr_voltage_ext_vdd_bias_ultraturbo; int8_t attr_voltage_ext_vdd_bias_turbo; int8_t attr_voltage_ext_vdd_bias_nominal; @@ -227,7 +159,7 @@ typedef struct uint32_t attr_boot_freq_mhz; uint32_t attr_nest_freq_mhz; -// Resonant clock frequency attributes + // Resonant clock frequency attributes uint32_t attr_pm_resonant_clock_full_clock_sector_buffer_frequency_khz; uint32_t attr_pm_resonant_clock_low_band_lower_frequency_khz; uint32_t attr_pm_resonant_clock_low_band_upper_frequency_khz; @@ -240,7 +172,7 @@ typedef struct uint8_t attr_dpll_vdm_response; uint8_t attr_nest_leakage_percent; -// Control attributes + // Control attributes uint8_t attr_system_ivrm_disable; uint8_t attr_systemp_resclk_disable; uint8_t attr_system_wof_disable; @@ -250,7 +182,7 @@ typedef struct uint8_t attr_dd_vdm_not_supported; uint8_t attr_pstate_mode; -// AVSBus attributes + // AVSBus attributes uint8_t vdd_bus_num; uint8_t vdd_rail_select; uint8_t vdn_bus_num; @@ -272,7 +204,7 @@ typedef struct uint32_t freq_proc_refclock_khz; uint32_t proc_dpll_divider; -//Undervolt and Overvolt Attributes + ///Undervolt and Overvolt Attributes uint8_t attr_wov_underv_enable; uint8_t attr_wov_overv_enable; uint8_t attr_wov_underv_force; @@ -287,344 +219,538 @@ typedef struct uint8_t attr_wov_overv_step_incr_pct; uint8_t attr_wov_overv_step_decr_pct; uint8_t attr_wov_overv_max_pct; + } AttributeList; -/// The layout of the various Pstate Parameter Blocks (PPBs) passed a single -/// structure for data movement. -/// -/// This structure is only used for passing Pstate data from -/// p9_pstate_parameter_block to it caller for placement into HOMER for -/// consumption by into OCC, the Pstate PGPE and CME. Therefore there is no -/// alignment requirement. -typedef struct +//PlatPmPPB Object definition +class PlatPmPPB { + public: + //Constructor with Proc target as input + PlatPmPPB ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> i_target ) : + iv_procChip (i_target), iv_pstates_enabled(0), iv_resclk_enabled(0), + iv_vdm_enabled(0), iv_ivrm_enabled(0), iv_wof_enabled(0), iv_safe_voltage (0), + iv_safe_frequency(0), iv_reference_frequency_mhz(0), iv_reference_frequency_khz(0), + iv_frequency_step_khz(0), iv_proc_dpll_divider(0), iv_nest_freq_mhz(0), + iv_wov_underv_enabled(0), iv_wov_overv_enabled(0) + + { + attr_init(); + } + + /// ----------------------------------------------------------------------- + /// @brief Initialize pstate attributes + /// @return none + /// ----------------------------------------------------------------------- + void attr_init(); + + /// ----------------------------------------------------------------------- + /// @brief Initialize VPD data + // @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode vpd_init(); + + /// ----------------------------------------------------------------------- + /// @brief Initialize resclk data + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode resclk_init(); + + /// ----------------------------------------------------------------------- + /// @brief Initialize WOF data + /// @param[out] o_buf points to WOF data + /// @param[inout] io_size size of the wof table + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode wof_init( + uint8_t* o_buf, + uint32_t& io_size); + + /// ----------------------------------------------------------------------- + /// @brief Initialize global pstate parameter block + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode gppb_init( GlobalPstateParmBlock* i_globalppb); + + /// ----------------------------------------------------------------------- + /// @brief Initialize local pstate parameter block + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode lppb_init(LocalPstateParmBlock* i_localppb); + + /// ----------------------------------------------------------------------- + /// @brief Initialize occ pstate parameter block + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode oppb_init(OCCPstateParmBlock* i_occppb); + + /// ----------------------------------------------------------------------- + /// @brief VDM initializtion based on #W data + /// @return none + /// ----------------------------------------------------------------------- + void vdm_init( void ); + + /// ----------------------------------------------------------------------- + /// @brief Safe mode frquency and voltage init + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode safe_mode_init( void ); + + /// ----------------------------------------------------------------------- + /// @brief VFRT data initialization from WOF data + /// @param[in] i_pBuffer WOF data buffer + /// @param[inout] o_vfrt_data vfrt data + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode update_vfrt( + uint8_t* i_pBuffer, + HomerVFRTLayout_t* o_vfrt_data); + + /// ----------------------------------------------------------------------- + /// @brief Compute and apply biased values + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode get_extint_bias(); + + /// ----------------------------------------------------------------------- + /// @brief apply biased values for #V data + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode apply_biased_values(); + + /// ----------------------------------------------------------------------- + /// @brief Read IQ vpd data + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode get_mvpd_iddq( void ); + + /// ----------------------------------------------------------------------- + /// @brief Read #W(VDM) vpd data + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode get_mvpd_poundW (void); + + /// ----------------------------------------------------------------------- + /// @brief Read IVRM data from attributes + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode get_ivrm_parms (); + + /// ----------------------------------------------------------------------- + /// @brief Set resclk attribute values + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode set_resclk_table_attrs(); + + /// ----------------------------------------------------------------------- + /// @brief Compute and setup resclk values + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode res_clock_setup (void); + + /// ----------------------------------------------------------------------- + /// @brief Compute VDM freq drop values + /// @return none + /// ----------------------------------------------------------------------- + void large_jump_defaults(); + + /// ----------------------------------------------------------------------- + /// @brief Compute safe mode values + /// @param[in] i_action voltage config action (Compute/set) + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode compute_boot_safe( + const VoltageConfigActions_t i_action); + + /// ----------------------------------------------------------------------- + /// @brief This fills up the PStateVSlopes and VPStatesSlopes in + /// GlobalParmBlock + /// @param[out] o_gppb global PPB data + /// @return none + /// ----------------------------------------------------------------------- + void compute_PStateV_slope(GlobalPstateParmBlock* o_gppb); + + /// ----------------------------------------------------------------------- + /// @brief This will set the pstate feature attrbutes(VDM,RESCLK,VRM,WOF) + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode set_global_feature_attributes(); + + /// ----------------------------------------------------------------------- + /// @brief State of WOF Undervolt + /// @return enabled(true)/disabled (false) + /// ----------------------------------------------------------------------- + bool is_wov_underv_enabled(); + + /// ----------------------------------------------------------------------- + /// @brief State of WOF Overvolt + /// @return enabled(true)/disabled (false) + /// ----------------------------------------------------------------------- + bool is_wov_overv_enabled(); + + /// ----------------------------------------------------------------------- + /// @brief State of WOF feature + /// @return enabled(true)/disabled (false) + /// ----------------------------------------------------------------------- + bool is_wof_enabled(); + + /// ----------------------------------------------------------------------- + /// @brief State of VDM feature + /// @return enabled(true)/disabled (false) + /// ----------------------------------------------------------------------- + bool is_vdm_enabled(); + + /// ----------------------------------------------------------------------- + /// @brief Initialize #v vpd points for both raw/biased + /// @param[in] i_state RAW/BIASED + /// @return none + /// ----------------------------------------------------------------------- + void load_mvpd_operating_point (vpd_type i_state); + + /// ----------------------------------------------------------------------- + /// @brief Read #V data form module vpd + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode get_mvpd_poundV(); + + /// ----------------------------------------------------------------------- + /// @brief Validate #V data + /// @param[in] i_biased_state present/nonpresent + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode chk_valid_poundv( + const bool i_biased_state); + + /// ----------------------------------------------------------------------- + /// @brief Compute VPD points of different regions + /// @return none + /// ----------------------------------------------------------------------- + void compute_vpd_pts(); + + /// ----------------------------------------------------------------------- + /// @brief Converts frequency value to pstate number + /// @param[in] i_freq_khz input frequency + /// @param[out] o_pstate pstate output for a given inut frequency + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + int freq2pState (const uint32_t freq_khz, + Pstate* pstate, + const FREQ2PSTATE_ROUNDING i_round = ROUND_SLOW); + + /// ----------------------------------------------------------------------- + /// @brief Compute safe mode values + /// @param[in] i_pstate pstate value + /// @param[out] o_safe_mode_values safe mode freq/voltage values + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + fapi2::ReturnCode safe_mode_computation( + const Pstate i_ps_pstate, + Safe_mode_parameters* o_safe_mode_values); + + /// ----------------------------------------------------------------------- + /// @brief Convert pstate to voltage + /// @param[in] i_pstate pstate value that needs to be converted + /// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. + /// ----------------------------------------------------------------------- + uint32_t ps2v_mv(const Pstate i_pstate); + + /// ----------------------------------------------------------------------- + /// @brief Compute VDM jump values for a given pstate + /// @param[in] i_pstate pstate value + /// @return none + /// ----------------------------------------------------------------------- + void compute_PsVDMJumpSlopes( + uint8_t* i_pstate); + + /// ----------------------------------------------------------------------- + /// @brief Compute VDM threshold values for a given pstate + /// @param[in] i_pstate pstate value + /// @return none + /// ----------------------------------------------------------------------- + void compute_PsVDMThreshSlopes( + uint8_t* i_pstate); + + /// ----------------------------------------------------------------------- + /// @brief Compute VID compare slope values for a given pstate + /// @param[in] i_pstate pstate value + /// @return none + /// ----------------------------------------------------------------------- + void compute_PsVIDCompSlopes_slopes( + uint8_t* i_pstate); + + /// ----------------------------------------------------------------------- + /// @brief Compute VDM threshold points for different regions + /// @return none + /// ----------------------------------------------------------------------- + void compute_vdm_threshold_pts(); + + /// ----------------------------------------------------------------------- + /// @brief Compute bias value for pre-defined percentage unit + /// @param[in] i_value Biased value + /// @return bias value + /// ----------------------------------------------------------------------- + double calc_bias(const int8_t i_value) + { + double temp = 1.0 + ((BIAS_PCT_UNIT / 100) * (double)i_value); + FAPI_DBG(" calc_bias: input bias (in 1/2 percent) = %d; percent = %4.1f%% biased multiplier = %6.3f", + i_value, (i_value * BIAS_PCT_UNIT), temp); + return temp; + } + + /// ----------------------------------------------------------------------- + /// @brief Compute smallest value for a given input + /// @param[in] x value + /// @return smallest value + /// ----------------------------------------------------------------------- + double internal_ceil(double x) + { + if ((x - (int)(x)) > 0) + { + return (int)x + 1; + } + + return ((int)x); + } + + /// ----------------------------------------------------------------------- + /// @brief Compute largest value for a given input + /// @param[in] x value + /// @return largest value + /// ----------------------------------------------------------------------- + double internal_floor(double x) + { + if(x >= 0) + { + return (int)x; + } + + return (int)(x - 0.9999999999999999); + } + + /// ----------------------------------------------------------------------- + /// @brief Adjust bias value for given vdd/vcs voltage + /// @param[in] i_value vdd/vcs value + /// @param[in] i_bias_0p5pct bias value + /// @return computed biase value + /// ----------------------------------------------------------------------- + uint32_t bias_adjust_mv(const uint32_t i_value, + const int32_t i_bias_0p5pct) + { + double l_mult = calc_bias(i_bias_0p5pct); + double l_biased_value = (double)i_value * l_mult; + double l_ceiling = internal_ceil(l_biased_value); + uint32_t l_result = (uint32_t)l_ceiling; + FAPI_DBG(" bias_adjust_mv: i_value=%d; mult=%5.3f; biased value=%3.0f ceiling = %3.0f result = %d", + i_value, + l_mult, + l_biased_value, + l_ceiling, + l_result); + return (l_result); + } + + /// ----------------------------------------------------------------------- + /// @brief Adjust bias value for given frequency value + /// @param[in] i_value frequency value + /// @param[in] i_bias_0p5pct bias value + /// @return computed biase value + /// ----------------------------------------------------------------------- + uint32_t bias_adjust_mhz(const uint32_t i_value, + const int32_t i_bias_0p5pct) + { + double l_mult = calc_bias(i_bias_0p5pct); + double l_biased_value = (double)i_value * l_mult; + FAPI_DBG(" bias_adjust_mhz: i_value=%d; mult=%5.3f; biased value=%3.0f", + i_value, + l_mult, + l_biased_value); + return ((uint32_t)internal_floor(l_biased_value)); + } + + /// ----------------------------------------------------------------------- + /// @brief Compute slope threshold points + /// @param[in] y1 jump/threshold value of nominal + /// @param[in] y0 jump/threshold value of powersave + /// @param[in] x1 pstate value of powersave + /// @param[in] x0 pstate value of nominal + /// @return computed slope threshold value + /// ----------------------------------------------------------------------- + int16_t compute_slope_thresh(int32_t y1, int32_t y0, int32_t x1, int32_t x0) + { + return (int16_t) + ( + // Perform division using double for maximum precision + // Store resulting slope in 4.12 Fixed-Pt format + ((double)(y1 - y0) / (double)(x1 - x0)) * (1 << THRESH_SLOPE_FP_SHIFT) + ); + } + + /// ----------------------------------------------------------------------- + /// @brief Compute slope values for fixed point of shift 4.12 + /// @param[in] y1 pstate value of powersave + /// @param[in] y0 pstate value of nominal + /// @param[in] x1 VDD value of nominal + /// @param[in] x0 VDD value of powersave + /// @return computed slope threshold value + /// ----------------------------------------------------------------------- + int16_t compute_slope_4_12(uint32_t y1, uint32_t y0, uint32_t x1, uint32_t x0) + { + return (int16_t) + ( + // Perform division using floats for maximum precision + // Store resulting slope in 4.12 Fixed-Pt format + ((float)(y1 - y0) / (float)(x1 - x0)) * (1 << VID_SLOPE_FP_SHIFT_12) + ); + + } + + /// ----------------------------------------------------------------------- + /// @brief Compute VDD/VCS/VDN voltage for given system parameters + /// @param[in] i_vpd_mv voltage value in milli volts + /// @param[in] i_vpd_ma Cuurent value in milli amps + /// @param[in] i_loadline_uohm loadline value + /// @param[in] i_distloss_uohm dist loss value + /// @param[in] i_distoffset_uohm dist offset value + /// @return uplift value + /// ----------------------------------------------------------------------- + uint32_t sysparm_uplift(const uint32_t i_vpd_mv, + const uint32_t i_vpd_ma, + const uint32_t i_loadline_uohm, + const uint32_t i_distloss_uohm, + const uint32_t i_distoffset_uohm) + { + double l_mv = ((double)i_vpd_mv + // mV + ( + // mA*uOhm/1000 -> uV + ((double)(i_vpd_ma * (i_loadline_uohm + i_distloss_uohm)) / 1000 + + // uv + (double)i_distoffset_uohm) + ) / 1000); // uV -> mV + uint32_t l_result = (uint32_t)l_mv; + FAPI_DBG(" system_uplift_mv: i_vpd_mv=%d; i_vpd_ma=%d; i_loadline_uohm=%d " + "i_distloss_uohm = %d i_distoffset_uohm = %d l_mv = %5.3f l_result = %d" , + i_vpd_mv, + i_vpd_ma, + i_loadline_uohm, + i_distloss_uohm, + i_distoffset_uohm, + l_mv, + l_result); + + return (l_result); + } + + + /// ----------------------------------------------------------------------- + /// @brief Pstate attribute ATTR_SYSTEM_PSTATES_MODE status + /// @return true/false + /// ----------------------------------------------------------------------- + bool isPstateModeEnabled(); + + /// ----------------------------------------------------------------------- + /// @brief EQ chiplet state + /// @return true/false + /// ----------------------------------------------------------------------- + bool isEqChipletPresent (); + + /// ----------------------------------------------------------------------- + /// @brief Compute jump interpolate + /// @param[in] i_pstate Safe mode pstate + /// @param[in] i_ps_pstate power save pstate + /// @return vdm jump value + /// ----------------------------------------------------------------------- + uint32_t large_jump_interpolate(const Pstate i_pstate, + const Pstate i_ps_pstate); + + /// ----------------------------------------------------------------------- + /// @brief Get pstate attribute data + /// @param[out] o_attr populate attribute list data + /// @return none + /// ----------------------------------------------------------------------- + void get_pstate_attrs(AttributeList* o_attr); +#if 0 + void print_raw_poundV_points() + { + for (int i = 0; i <= NUM_OP_POINTS - 1; i++) + { + FAPI_DBG("Raw #V operating point (%s) f=%u v=%u i=%u v=%u i=%u", + pv_op_str[pv_op_order[i]], + iv_attr_mvpd_poundV_raw[pv_op_order[i]].frequency_mhz, + iv_attr_mvpd_poundV_raw[pv_op_order[i]].vdd_mv, + iv_attr_mvpd_poundV_raw[pv_op_order[i]].idd_100ma, + iv_attr_mvpd_poundV_raw[pv_op_order[i]].vcs_mv, + iv_attr_mvpd_poundV_raw[pv_op_order[i]].ics_100ma); + } + } +#endif - /// Magic Number - uint64_t magic; - - // PGPE content - GlobalPstateParmBlock globalppb; - - // CME content - LocalPstateParmBlock localppb; - - // OCC content - OCCPstateParmBlock occppb; - -} PstateSuperStructure; - -// Start of function declarations - -// ---------------------------------------------------------------------- -// Function prototypes -// ---------------------------------------------------------------------- - -/// ---------------------------------------------------------------- -/// @brief Get #V data and put into array -/// @param[i] i_target Proc Target -/// @param[o] o_attr_mvpd_data 5x5 array to hold the #V data -/// @param[o] o_valid_pdv_points No of Valid VPD points -/// @param[o] o_present_chiplets No of functional chiplets -/// @param[o] o_bucketId bucket id that got selected -/// @param[o] o_poundv_data PoundV data -/// @paran[o] o_state pstate attribute state -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ---------------------------------------------------------------- -fapi2::ReturnCode -proc_get_mvpd_data ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - uint32_t o_attr_mvpd_data[PV_D][PV_W], - uint32_t* o_valid_pdv_points, - uint8_t* o_present_chiplets, - uint8_t& o_bucketId, - fapi2::voltageBucketData_t* o_poundv_data, - PSTATE_attribute_state* o_state); - -/// ------------------------------------------------------------------- -/// @brief Perform data validity check on #V data -/// @param[i] i_target Proc Target -/// @param[i] i_chiplet_mvpd_data Pointer to array of #V data -/// @param[o] o_valid_pdv_points No of Valid VPD points -/// @param[i] i_chiplet_num Chiplet number -/// @param[i] i_bucket_id Bucket ID -/// @param[o] o_state pstate attribute state -/// @param[i] i_biased_state biased validity check state -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ------------------------------------------------------------------- - -fapi2::ReturnCode -proc_chk_valid_poundv ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - const uint32_t i_chiplet_mvpd_data[PV_D][PV_W], - uint32_t* o_valid_pdv_points, - const uint8_t i_chiplet_num, - const uint8_t i_bucket_id, - PSTATE_attribute_state* o_state, - const bool i_biased_state = false); - - -/// ---------------------------------------------------------------- -/// @brief Get IQ (IDDQ) data and put into array -/// @param[in] i_target => Proc Target -/// @param[inout] iddqt => IDDQ table to hold MVPD IDDQ data -/// @param[out] o_state => pstate attribute state -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ---------------------------------------------------------------- - -fapi2::ReturnCode -proc_get_mvpd_iddq ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - IddqTable* io_iddqt, - PSTATE_attribute_state* o_state); -/// ---------------------------------------------------------------- -/// @brief Get #W data and put into array -/// @param[in] i_target => Proc Target -/// @param[in] i_poundv_bucketId => #V bucket id -/// @param[out] o_vdmpb => Vdmparamblock data -/// @param[out] o_poundw_data => #W data -/// @paramg[in] i_poundv_data => #V data -/// @param[o] o_state => pstate attribute state -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ---------------------------------------------------------------- -fapi2::ReturnCode -proc_get_mvpd_poundw(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - uint8_t i_poundv_bucketId, - LP_VDMParmBlock* o_vdmpb, - PoundW_data* o_poundw_data, - fapi2::voltageBucketData_t i_poundv_data, - PSTATE_attribute_state* o_state - ); -/// ----------------------------------------------------------------------- -/// @brief Get needed attributes -/// @param[in] i_target => Proc Target -/// @param[in/out] io_attr => pointer to attribute list structure -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ----------------------------------------------------------------------- -fapi2::ReturnCode -proc_get_attributes ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - AttributeList* io_attr); - - -/// ----------------------------------------------------------------------- -/// @brief Load attribute content into the Global Parameter Block -/// @param[in] i_attr => Reference to attribute list structure -/// @param[out] o_globalppb => Pointer to Global Parameter Block -/// ----------------------------------------------------------------------- -void -load_gppb_attrs(const AttributeList* i_attr, - GlobalPstateParmBlock* o_globalppb); - -// -/// ----------------------------------------------------------------------- -/// @brief Apply system parameters to a VPD value -/// @param[in] i_vpd_mv => Reference to attribute list structure -/// @param[in] i_vpd_ma = Reference to attribute list structure -/// @param[in] i_loadline_uohm => Reference to attribute list structure -/// @param[in] i_distloss_uohm => Reference to attribute list structure -/// @param[in] i_distoffset_uohm => Reference to attribute list structure -/// @return[out] uplifted voltage with system parameters added -/// ----------------------------------------------------------------------- -uint32_t -sysparm_uplift(const uint32_t i_vpd_mv, - const uint32_t i_vpd_ma, - const uint32_t i_loadline_uohm, - const uint32_t i_distloss_uohm, - const uint32_t i_distoffset_uohm); - -/// --------------------------------------------------------------------------- -/// @brief Check and process #V bias attributes for external and internal -/// @param[in/out] io_attr_mvpd_data => 5x5 array to hold the #V data -/// @param[in] i_attr => pointer to attribute list structure -/// @param[out] o_vpdbias => Voltage/Frequency bias values -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// --------------------------------------------------------------------------- - -fapi2::ReturnCode -proc_get_extint_bias ( uint32_t io_attr_mvpd_data[PV_D][PV_W], - const AttributeList* i_attr, - VpdBias o_vpdbias[NUM_OP_POINTS] ); - -/// ------------------------------------------------------------------- -/// @brief Boost max frequency in pstate table based on boost attribute -/// @param[in/out] io_pss => pointer to pstate superstructure -/// @param[in] i_attr_boost_percent => Boost percentage attribute -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ------------------------------------------------------------------- - -fapi2::ReturnCode -proc_boost_gpst ( PstateSuperStructure* io_pss, - uint32_t i_attr_boost_percent); - -/// ------------------------------------------------------------ -/// @brief Update Psafe_pstate -/// @param[in/out] *io_pss => pointer to pstate superstructure -/// @param[in] *i_attr => pointer to attribute list structure -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ------------------------------------------------------------ - -fapi2::ReturnCode -proc_upd_psafe_ps ( PstateSuperStructure* io_pss, - const AttributeList* i_attr); - -/// ------------------------------------------------------------ -/// @brief Update Floor_pstate -/// @param[inout] *io_pss => pointer to pstate superstructure -/// @param[in] *i_attr => pointer to attribute list structure -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ------------------------------------------------------------ - -fapi2::ReturnCode -proc_upd_floor_ps ( PstateSuperStructure* io_pss, - const AttributeList* i_attr); - -/// ------------------------------------------------------------------- -/// @brief Convert Resonant Clocking attributes to pstate values and update superstructure with those values -/// @param[inout] *io_pss => pointer to pstate superstructure -/// @param[in] *i_attr => pointer to attribute list structure -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ------------------------------------------------------------------- -fapi2::ReturnCode -proc_res_clock ( PstateSuperStructure* io_pss, - AttributeList* i_attr); - -/// ------------------------------------------------------------ -/// @brief Populate a subset of the WOFElements structure from Attributes -/// @param[inout] *io_pss => pointer to pstate superstructure -/// @param[in] *i_attr => pointer to attribute list structure -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ------------------------------------------------------------ - -fapi2::ReturnCode -load_wof_attributes ( PstateSuperStructure* io_pss, - const AttributeList* i_attr); - -/// ------------------------------------------------------------ -/// @brief Copy VPD operating point into destination in assending order -/// @param[in] i_src[NUM_OP_POINTS] => Source VPD structure (array) -/// @param[out] * o_dest[NUM_OP_POINTS] => pointer to destination VpdOperatingPoint structure -/// @param[in] i_frequency_step_khz => frequency step size -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ------------------------------------------------------------ - -fapi2::ReturnCode -load_mvpd_operating_point ( const uint32_t i_src[PV_D][PV_W], - VpdOperatingPoint* o_dest, - uint32_t i_frequency_step_khz); - -/// ------------------------------------------------------------ -/// @brief Copy out of operating point set into a destination operating point -/// @param[in] &i_op_pt_set => reference to array of VpdOperatingPoint sets -/// @param[out] *dest[NUM_OP_POINTS] => pointer to destination VpdOperatingPoint structure -/// @param[in] i_frequency_step_khz => Base frequency value for pstate calculation -/// ------------------------------------------------------------ -fapi2::ReturnCode -get_operating_point ( const VpdOperatingPoint i_op_pt_set[NUM_VPD_PTS_SET][NUM_OP_POINTS], - uint32_t i_set, - VpdOperatingPoint* o_op_pt); - -/// ---------------------------------------------------------------- -/// @brief Get VDM parameters from attributes -/// @param[in] i_target => Proc Target -/// @param[in] *i_attr => pointer to attribute list structure -/// @param[out] o_vdmpb => VDM parameter block -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ---------------------------------------------------------------- - -fapi2::ReturnCode -proc_get_vdm_parms ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - const AttributeList* i_attr, - GP_VDMParmBlock* o_vdmpb); - -/// ---------------------------------------------------------------- -/// @brief Get resonant clocking parameters from attributes -/// @param[in] i_target => Proc Target -/// @param[out] o_resclk_setup => Resonant clocking setup -/// @param[in] i_gppb => The Global Pstate Parameter Block -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ---------------------------------------------------------------- - -fapi2::ReturnCode -proc_res_clock_setup ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - ResonantClockingSetup* o_resclk_setup, - const GlobalPstateParmBlock* i_gppb); - -/// ---------------------------------------------------------------- -/// @brief Get IVRM parameters from attributes -/// @param[in] i_target => Proc Target -/// @param[in] *i_attr => pointer to attribute list structure -/// @param[out] o_ivrmpb => IVRM parameter block -/// @param[o] o_state => pstate attribute state -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ---------------------------------------------------------------- - -fapi2::ReturnCode -proc_get_ivrm_parms ( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - const AttributeList* i_attr, - IvrmParmBlock* o_ivrmpb, - PSTATE_attribute_state* o_state); + private: + fapi2::Target< fapi2::TARGET_TYPE_PROC_CHIP > iv_procChip; // processor chip target + AttributeList iv_attrs; // Pstate attributes list + VpdOperatingPoint iv_raw_vpd_pts[NUM_OP_POINTS]; // Raw vpd operating points + VpdOperatingPoint iv_biased_vpd_pts[NUM_OP_POINTS]; // Biased vpd operating points + VpdOperatingPoint iv_operating_points[NUM_VPD_PTS_SET][NUM_OP_POINTS]; + SysPowerDistParms iv_vdd_sysparam; //VDD,VDN,VCS + SysPowerDistParms iv_vdn_sysparam; //VDD,VDN,VCS + SysPowerDistParms iv_vcs_sysparam; //VDD,VDN,VCS + VpdBias iv_bias[NUM_OP_POINTS]; + Safe_mode_parameters iv_safe_mode_values; + uint8_t iv_pstates_enabled; + uint8_t iv_resclk_enabled; + uint8_t iv_vdm_enabled; + uint8_t iv_ivrm_enabled; + uint8_t iv_wof_enabled; + uint32_t iv_safe_voltage; // System safe voltage + uint32_t iv_safe_frequency; // System safe frequency + uint32_t iv_reference_frequency_mhz; //System reference frequency + uint32_t iv_reference_frequency_khz; //System reference frequency + uint32_t iv_frequency_step_khz; // System step frequency + uint32_t iv_proc_dpll_divider; // proc dpll divider value + uint32_t iv_nest_freq_mhz; //Nest frequency + uint8_t iv_poundV_bucket_id; + uint8_t iv_eq_chiplet_state; + uint8_t iv_valid_pdv_points; + + voltageBucketData_t iv_poundV_raw_data; + voltageBucketData_t iv_poundV_biased_data; + VpdPoint iv_attr_mvpd_poundV_raw[5]; + VpdPoint iv_attr_mvpd_poundV_biased[5]; + + PoundW_data iv_poundW_data; + IddqTable iv_iddqt; + GP_VDMParmBlock iv_vdmpb; + IvrmParmBlock iv_ivrmpb; + ResonantClockingSetup iv_resclk_setup; + CompareVIDPoints iv_vid_point_set[NUM_OP_POINTS]; + uint8_t iv_threshold_set[NUM_OP_POINTS][NUM_THRESHOLD_POINTS]; + int16_t iv_PsVIDCompSlopes[VPD_NUM_SLOPES_REGION]; + int16_t iv_PsVDMThreshSlopes[VPD_NUM_SLOPES_REGION][NUM_THRESHOLD_POINTS]; + uint8_t iv_jump_value_set[NUM_OP_POINTS][NUM_JUMP_VALUES]; + int16_t iv_PsVDMJumpSlopes[VPD_NUM_SLOPES_REGION][NUM_JUMP_VALUES]; + uint8_t iv_wov_underv_enabled; + uint8_t iv_wov_overv_enabled; +}; -/// ------------------------------------------------------------------- -/// @brief Set Resonant Clocking "array"/"table" attributes using p9_resclk_defines.h -/// @param[in] i_target => Proc Target -/// @param[in] o_state => resclck attribute state -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ------------------------------------------------------------------- -fapi2::ReturnCode -proc_set_resclk_table_attrs(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - PSTATE_attribute_state* o_state); +} -/// ------------------------------------------------------------------- -/// @brief Compute VPD points for different regions -/// @param[out] o_operating_points => VPD operating points -/// @param[in] i_gppb => Global pstate structure -/// @param[in] i_raw_vpd_pts => Raw vpd operating points data -/// @return void -/// ------------------------------------------------------------------- -void p9_pstate_compute_vpd_pts(VpdOperatingPoint (*o_operating_points)[NUM_OP_POINTS], - GlobalPstateParmBlock* i_gppb, - VpdOperatingPoint* i_raw_vpd_pts); -// -// p9_pstate_compute_PsV_slopes -// -// Computes slope of voltage-PState curve and PState-voltage -// -// PState(Frequency) on y-axis, Voltage is on x-axis for VF curve -// Interpolation formula: (y-y0)/(x-x0) = (y1-y0)/(x1-x0) -// m = (x1-x0)/(y1-y0), then use this to calculate voltage, x = (y-y0)*m + x0 -// 1/m = (y1-y0)/(x1-x0) here, then use this to calculate pstate(frequency), y = (x-x0)*m + y0 -// Region 0 is b/w POWERSAVE and NOMINAL -// Region 1 is b/w NOMINAL and TURBO -// Region 2 is between TURBO and ULTRA_TURBO -// -// Inflection Point 3 is ULTRA_TURBO -// Inflection Point 2 is TURBO -// Inflection Point 1 is NOMINAL -// Inflection Point 0 is POWERSAVE -// -/// ------------------------------------------------------------------- -/// @brief Compute Pstate slope values for different frequencies and pstates -/// @param[in] i_operating_points => VPD operating points -/// @param[out] o_gppb => Global pstate structure -/// @return void -/// ------------------------------------------------------------------- -void p9_pstate_compute_PsV_slopes(VpdOperatingPoint i_operating_points[][4], - GlobalPstateParmBlock* o_gppb); +/// @typedef p9_pstate_parameter_block_FP_t +/// function pointer typedef definition for HWP call support +typedef fapi2::ReturnCode (*p9_pstate_parameter_block_FP_t) ( + const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&, + PstateSuperStructure*, uint8_t*, uint32_t&); -/// ------------------------------------------------------------------- -/// @brief Compute Pstate slope values for different frequencies and pstates -/// @param[in] i_operating_points => VPD operating points -/// @param[out] o_gppb => Global pstate structure -/// @return void -/// ------------------------------------------------------------------- -void p9_pstate_compute_PStateV_slope(VpdOperatingPoint i_operating_points[][4], - GlobalPstateParmBlock* o_gppb); +extern "C" +{ /// ------------------------------------------------------------------- /// @brief Print a GlobalPstateParameterBlock structure on a given stream /// @param[in] i_gppb The Global Pstate Parameter Block to print /// @return void /// ------------------------------------------------------------------- -void -gppb_print(GlobalPstateParmBlock* i_gppb); + void + gppb_print(GlobalPstateParmBlock* i_gppb); /// ------------------------------------------------------------------- @@ -632,220 +758,19 @@ gppb_print(GlobalPstateParmBlock* i_gppb); /// @param[in] i_oppb The OCC Pstate Parameter Block to print /// @return void /// ------------------------------------------------------------------- -void -oppb_print(OCCPstateParmBlock* i_oppb); + void + oppb_print(OCCPstateParmBlock* i_oppb); /// ------------------------------------------------------------------- /// @brief Print an iddq_print structure on a given stream /// @param[in] i_iddqt pointer to Iddq structure to output /// @return void /// ------------------------------------------------------------------- -void -iddq_print(IddqTable* i_iddqt); - - - -enum FREQ2PSTATE_ROUNDING -{ - ROUND_FAST, - ROUND_SLOW -}; - - -/// ------------------------------------------------------------------- -/// @brief Convert frequency to Pstate number -/// @param[in] i_gppb The Global Pstate Parameter Block -/// @param[in] i_freq_khz Input frequency to convert -/// @param[out] o_pstate Computed Pstate -/// @param[out] i_round Pstate rounding (ROUND_FAST, ROUND_SLOW) -// @return pstate state value whether it's lesser than min or greater than max -/// ------------------------------------------------------------------- + void + iddq_print(IddqTable* i_iddqt); -int freq2pState (const GlobalPstateParmBlock* i_gppb, - const uint32_t i_freq_khz, - Pstate* o_pstate, - const FREQ2PSTATE_ROUNDING i_round = ROUND_SLOW); - -/// ------------------------------------------------------------------- -/// @brief Convert Pstate number to frequency -/// @param[in] i_gppb The Global Pstate Parameter Block -/// @param[in] i_pstate Computed Pstate to convert -/// @param[out] o_freq_khz Computed frequency -/// ------------------------------------------------------------------- -int pState2freq (const GlobalPstateParmBlock* gppb, - const Pstate i_pstate, - uint32_t* o_freq_khz); -/// ------------------------------------------------------------------- -/// @brief Pstate VFRT initialization -/// @param[in] i_target proc chip target -/// @param[in] i_gppb The Global Pstate Parameter Block -/// @param[in] i_pBuffer VFRT data coming from HB -/// @param[out] o_vfrt_data Homer VFRT version -/// @param[in] i_reference_freq Ultra frequency @todo get this from the gppb -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ------------------------------------------------------------------- -fapi2::ReturnCode -p9_pstate_update_vfrt( - const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - const GlobalPstateParmBlock* i_gppb, - uint8_t* i_pBuffer, - HomerVFRTLayout_t* o_vfrt_data, - uint32_t i_reference_freq); - -///Compute VID points -/// ------------------------------------------------------------------- -/// @brief Compute VDM threshold points based on pound W data -/// @param[in] i_data => Pound W data -/// @param[in/out] io_lppb => local pstate structure data -/// @return void -/// ------------------------------------------------------------------- -void p9_pstate_compute_vdm_threshold_pts(PoundW_data i_data, - LocalPstateParmBlock* io_lppb); -///Biased slope calculation -/// ------------------------------------------------------------------- -/// @brief Compute VID compare slope values -/// @param[in] i_data => Pound W data -/// @param[in/out] io_lppb => local pstate structure data -/// @param[in] i_pstate => pstate values -/// @return void -/// ------------------------------------------------------------------- -void p9_pstate_compute_PsVIDCompSlopes_slopes(PoundW_data i_data, - LocalPstateParmBlock* io_lppb, - uint8_t* i_pstate); - -// p9_pstate_compute_PsVDMThreshSlopes -// -/// ------------------------------------------------------------------- -/// @brief Compute VDM threshold slope values -/// @param[in/out] io_lppb => local pstate structure data -/// @param[in] i_pstate => pstate values -/// @return void -/// ------------------------------------------------------------------- -void p9_pstate_compute_PsVDMThreshSlopes(LocalPstateParmBlock* io_lppb, - uint8_t* i_pstate); - -// p9_pstate_compute_PsVDMJumpSlopes -// -/// ------------------------------------------------------------------- -/// @brief Compute VDM jump slope values -/// @param[in/out] io_lppb => local pstate structure data -/// @param[in] i_pstate => pstate values -/// @return void -/// ------------------------------------------------------------------- -void p9_pstate_compute_PsVDMJumpSlopes( - LocalPstateParmBlock* io_lppb, - uint8_t* i_pstate); - - -// p9_pstate_wof_initialization -/// ------------------------------------------------------------------- -/// @brief WOF table initialization -/// @param[in] i_target => proc chip target -/// @param[in] i_gppb => pointer to GPPB strucure -/// @param[out] o_buf => wof data -/// @param[in/out] io_size => total wof data size -/// @param[out] o_state => pstate attribute values -/// @param[in] i_base_state_frequency => base frequency value -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ------------------------------------------------------------------- -fapi2::ReturnCode -p9_pstate_wof_initialization( - const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - const GlobalPstateParmBlock* i_gppb, - uint8_t* o_buf, - uint32_t& io_size, - PSTATE_attribute_state* o_state, - const uint32_t i_base_state_frequency); - -/// ------------------------------------------------------------------- -/// @brief This function computes the safe mode frequency and voltage value -/// @param[in] i_target proc chip target -/// @param[in] i_attr_mvpd_data #V vpd data -/// @param[in] i_reference_freq proc reference freq -/// @param[in] i_step_frequency Step frequency -/// @param[in] i_ps_pstate power save pstate -/// @param[out] o_safe_mode_values safe mode values -/// @param[in] i_poundw_data Pound W vpd data -/// @return FAPI2::SUCCESS -fapi2::ReturnCode -p9_pstate_safe_mode_computation(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - const VpdOperatingPoint i_operating_points[NUM_VPD_PTS_SET][NUM_OP_POINTS], - const uint32_t i_reference_freq, - const uint32_t i_step_frequency, - const Pstate i_ps_pstate, - Safe_mode_parameters* o_safe_mode_values, - const PoundW_data i_poundw_data); - - -/// ------------------------------------------------------------------- -/// @brief This function provides ncessary #W data in the event of access failures -/// @paramgin] o_poundw_data Pound W vpd data -/// @return None -void -large_jump_defaults(PoundW_data* o_poundw_data); - - -/// ------------------------------------------------------------------- -/// @brief For a given pstate.. gets the vdd voltge value -/// @param[in] i_pstate safe mode pstate -/// @param[in] i_attr_mvpd_data #V vpd data -/// @param[in] i_step_frequency Step frequency -/// @return uint32_t vdd voltage value -uint32_t pstate2voltage(const Pstate i_pstate, - const uint32_t i_attr_mvpd_data[PV_D][PV_W], - const uint32_t i_step_frequency); - -/// ------------------------------------------------------------------- -/// @brief This function calculates large jump value.. for the given pstate -// values and jump values read from the pound w vpd. -/// @param[in] i_pstate safe mode pstate -/// @param[in] i_attr_mvpd_data #V vpd data -/// @param[in] i_step_frequency Step frequency -/// @param[in] i_ps_pstate power save pstate -/// @paramgin] i_data Pound W vpd data -/// @return uint32_t jump value -uint32_t large_jump_interpolate(const Pstate i_pstate, - const VpdOperatingPoint i_operating_points[NUM_OP_POINTS], - const uint32_t i_step_frequency, - Pstate i_ps_pstate, - const PoundW_data i_data); - -/// ------------------------------------------------------------------- -/// @brief Interpolate the currents based on frequency -/// @param[in] i_biased_vpd - Data to interpolate -/// @param[in] i_freq_mhz - Index grequency -/// @param[out] o_current_ma - Interpolated Current -/// @return true or false -/// -void -interpolate_current( const uint32_t i_biased_vpd[PV_D][PV_W], - const uint32_t i_freq_mhz, - uint32_t* o_current_ma); - -// p9_pstate_set_global_feature_attributes -/// ------------------------------------------------------------------- -/// @brief Set the global pstate attributes -/// @param[in] i_target => Proc target -/// @param[in] i_state => pstate attribute states -/// @param[out] o_qm_flags => Quad manager flags -/// @return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -/// ------------------------------------------------------------------- -fapi2::ReturnCode -p9_pstate_set_global_feature_attributes( - const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - PSTATE_attribute_state i_state, - QuadManagerFlags* o_qm_flags); - -/// @typedef p9_pstate_parameter_block_FP_t -/// function pointer typedef definition for HWP call support -typedef fapi2::ReturnCode (*p9_pstate_parameter_block_FP_t) ( - const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&, - PstateSuperStructure*, uint8_t*, uint32_t&); - -extern "C" -{ /// ------------------------------------------------------------------- /// @brief Populate Pstate super structure from VPD data @@ -862,11 +787,5 @@ extern "C" } // extern C -// End of function declarations - -#ifdef __cplusplus -} // end extern C -#endif - #endif // __P9_PSTATE_PARAMETER_BLOCK_H__ diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_setup_evid.C b/src/import/chips/p9/procedures/hwp/pm/p9_setup_evid.C index f18c220a2..d7326b004 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_setup_evid.C +++ b/src/import/chips/p9/procedures/hwp/pm/p9_setup_evid.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2018 */ +/* Contributors Listed Below - COPYRIGHT 2016,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -50,6 +50,7 @@ #include <p9_quad_scom_addresses.H> #include <p9_quad_scom_addresses_fld.H> +using namespace pm_pstate_parameter_block; //----------------------------------------------------------------------------- // Procedure @@ -93,307 +94,26 @@ struct avsbus_attrs_t uint32_t freq_proc_refclock_khz; uint32_t proc_dpll_divider; }; - -//############################################################################## -//@brief Compute the boot and safe frequencies and voltages -//@param[in] i_target Proc Chip target -//@param[in] attrs Attributes -//@param[in] l_globalppb Global Pstate Parameter Block -//@param[in] i_action Voltage Config action -//@return fapi::ReturnCode: FAPI2_RC_SUCCESS if success, else error code. -//############################################################################## -fapi2::ReturnCode -compute_boot_safe(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, - AttributeList* attrs, - GlobalPstateParmBlock* l_globalppb, - const VoltageConfigActions_t i_action) -{ - fapi2::ReturnCode l_rc; - - uint32_t attr_mvpd_poundv[PV_D][PV_W]; - uint32_t attr_mvpd_poundv_biased[PV_D][PV_W]; - uint32_t valid_pdv_points; - uint8_t present_chiplets; - - PSTATE_attribute_state l_state; - l_state.iv_pstates_enabled = true; - l_state.iv_resclk_enabled = true; - l_state.iv_vdm_enabled = true; - l_state.iv_ivrm_enabled = true; - l_state.iv_wof_enabled = true; - - do - { - - //We only wish to compute voltage setting defaults if the action - //inputed to the HWP tells us to - if(i_action == COMPUTE_VOLTAGE_SETTINGS) - { - - // query VPD if any of the voltage attributes are zero - if (!attrs->vdd_voltage_mv || - !attrs->vcs_voltage_mv || - !attrs->vdn_voltage_mv) - { - - uint8_t l_poundv_bucketId = 0; - fapi2::voltageBucketData_t l_poundv_data; - LP_VDMParmBlock l_lp_vdmpb; - - PoundW_data l_poundw_data; - memset (&l_poundw_data, 0, sizeof(PoundW_data)); - - LocalPstateParmBlock l_localppb; - memset(&l_localppb, 0, sizeof(LocalPstateParmBlock)); - - Safe_mode_parameters l_safe_mode_values; - - uint8_t l_ps_pstate = 0xFF; - - VpdBias l_vpdbias[NUM_OP_POINTS]; - memset (l_vpdbias, 0, sizeof(VpdBias)); - - // Get #V data from MVPD for VDD/VDN and VCS voltage values - FAPI_TRY(proc_get_mvpd_data(i_target, - attr_mvpd_poundv, - &valid_pdv_points, - &present_chiplets, - l_poundv_bucketId, - &l_poundv_data, - &l_state )); - - if (!present_chiplets) - { - FAPI_IMP("**** WARNING : There are no EQ chiplets present which means there is no valid #V VPD"); - break; - } - - //set to default value if dpll divider is 0 - if (!attrs->proc_dpll_divider) - { - attrs->proc_dpll_divider = 8; - } - - FAPI_DBG("Copy to Bias array"); - - for (int i = 0; i < NUM_OP_POINTS; i++) - { - for (int d = 0; d < PV_D; ++d) - { - for (int w = 0; w < PV_W; ++w) - { - attr_mvpd_poundv_biased[d][w] = attr_mvpd_poundv[d][w]; - } - } - } - - // Apply Bias values - FAPI_TRY(proc_get_extint_bias(attr_mvpd_poundv_biased, - attrs, l_vpdbias), - "Bias application function failed"); - - VpdOperatingPoint l_raw_operating_points[NUM_OP_POINTS]; - FAPI_INF("Load RAW VPD"); - FAPI_TRY(load_mvpd_operating_point(attr_mvpd_poundv, - l_raw_operating_points, - revle32(l_globalppb->frequency_step_khz)), - "Loading MVPD operating points failed"); - - // Put raw operating points into the Global Parameter Block - FAPI_INF("Place Raw VPD into GPPB"); - FAPI_TRY(load_mvpd_operating_point(attr_mvpd_poundv, - l_globalppb->operating_points, - revle32(l_globalppb->frequency_step_khz)), - "Putting MVPD into GPPB operating points failed"); - - // Compute the VPD operating points - VpdOperatingPoint l_operating_points[NUM_VPD_PTS_SET][NUM_OP_POINTS]; - p9_pstate_compute_vpd_pts(l_operating_points, - l_globalppb, - l_raw_operating_points); - - uint32_t l_ps_freq_khz = l_operating_points[VPD_PT_SET_BIASED][POWERSAVE].frequency_mhz * 1000; - freq2pState(l_globalppb, l_ps_freq_khz, &l_ps_pstate); - - FAPI_INF ("l_frequency_step_khz %08x", revle32(l_globalppb->frequency_step_khz)); - FAPI_INF ("l_ref_freq_khz %08X", revle32(l_globalppb->reference_frequency_khz)); - FAPI_INF ("l_ps_pstate %x", l_ps_pstate); - - l_rc = proc_get_mvpd_poundw(i_target, - l_poundv_bucketId, - &l_lp_vdmpb, - &l_poundw_data, - l_poundv_data, - &l_state); - - if (l_rc) - { - FAPI_ASSERT_NOEXIT(false, - fapi2::PSTATE_PB_POUND_W_ACCESS_FAIL(fapi2::FAPI2_ERRL_SEV_RECOVERED) - .set_CHIP_TARGET(i_target) - .set_FAPI_RC(l_rc), - "Pstate Parameter Block proc_get_mvpd_poundw function failed"); - fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - } - - //Compute safe mode values - FAPI_TRY(p9_pstate_safe_mode_computation ( - i_target, - l_operating_points, - revle32(l_globalppb->reference_frequency_khz), - revle32(l_globalppb->frequency_step_khz), - l_ps_pstate, - &l_safe_mode_values, - l_poundw_data), - "Error from p9_pstate_safe_mode_computation function"); - - - // set VDD voltage to PowerSave Voltage from MVPD data (if no override) - if (attrs->vdd_voltage_mv) - { - FAPI_INF("VDD boot voltage override set."); - } - else - { - attrs->vdd_voltage_mv = l_safe_mode_values.boot_mode_mv; - FAPI_INF("VDD boot voltage set to %d mV.", attrs->vdd_voltage_mv); - } - - - - // set VCS voltage to UltraTurbo Voltage from MVPD data (if no override) - if (attrs->vcs_voltage_mv) - { - FAPI_INF("VCS boot voltage override set."); - } - else - { - FAPI_INF("VCS boot voltage override not set, using VPD value and correcting for applicable load line setting"); - uint32_t l_int_vcs_mv = (attr_mvpd_poundv_biased[POWERSAVE][VPD_PV_VCS_MV]); - uint32_t l_ics_ma = (attr_mvpd_poundv_biased[POWERSAVE][VPD_PV_ICS_100MA]) * 100; - - uint32_t l_ext_vcs_mv = sysparm_uplift(l_int_vcs_mv, - l_ics_ma, - attrs->r_loadline_vcs_uohm, - attrs->r_distloss_vcs_uohm, - attrs->vrm_voffset_vcs_uv); - - - FAPI_INF("VCS VPD voltage %d mV; Corrected voltage: %d mV; ICS: %d mA; LoadLine: %d uOhm; DistLoss: %d uOhm; Offst: %d uOhm", - l_int_vcs_mv, - revle32(l_ext_vcs_mv), - l_ics_ma, - attrs->r_loadline_vcs_uohm, - attrs->r_distloss_vcs_uohm, - attrs->vrm_voffset_vcs_uv); - - - attrs->vcs_voltage_mv = revle32(l_ext_vcs_mv); - - } - - // set VDN voltage to PowerSave Voltage from MVPD data (if no override) - if (attrs->vdn_voltage_mv) - { - FAPI_INF("VDN boot voltage override set"); - } - else - { - FAPI_INF("VDN boot voltage override not set, using VPD value and correcting for applicable load line setting"); - uint32_t l_int_vdn_mv = (attr_mvpd_poundv_biased[POWERBUS][VPD_PV_VDN_MV]); - uint32_t l_idn_ma = (attr_mvpd_poundv_biased[POWERBUS][VPD_PV_IDN_100MA]) * 100; - // Returns revle32 - uint32_t l_ext_vdn_mv = sysparm_uplift(l_int_vdn_mv, - l_idn_ma, - attrs->r_loadline_vdn_uohm, - attrs->r_distloss_vdn_uohm, - attrs->vrm_voffset_vdn_uv); - - FAPI_INF("VDN VPD voltage %d mV; Corrected voltage: %d mV; IDN: %d mA; LoadLine: %d uOhm; DistLoss: %d uOhm; Offst: %d uOhm", - l_int_vdn_mv, - revle32(l_ext_vdn_mv), - l_idn_ma, - attrs->r_loadline_vdn_uohm, - attrs->r_distloss_vdn_uohm, - attrs->vrm_voffset_vdn_uv); - - attrs->vdn_voltage_mv = revle32(l_ext_vdn_mv); - } - } - else - { - FAPI_INF("Using overrides for all boot voltages (VDD/VCS/VDN) and core frequency"); - - // Set safe frequency to the default BOOT_FREQ_MULT - fapi2::ATTR_BOOT_FREQ_MULT_Type l_boot_freq_mult; - FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_BOOT_FREQ_MULT, - i_target, - l_boot_freq_mult)); - - uint32_t l_boot_freq_mhz = - ((l_boot_freq_mult * attrs->freq_proc_refclock_khz ) / - attrs->proc_dpll_divider ) - / 1000; - - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SAFE_MODE_FREQUENCY_MHZ, - i_target, - l_boot_freq_mhz)); - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_SAFE_MODE_VOLTAGE_MV, - i_target, - attrs->vdd_voltage_mv)); - FAPI_INF("Safe mode Frequency = %d MHz (0x%x), Safe mode voltage = %d mV (0x%x)", - l_boot_freq_mhz, l_boot_freq_mhz, - attrs->vdd_voltage_mv, attrs->vdd_voltage_mv); - } - - FAPI_INF("Setting Boot Voltage attributes: VDD = %dmV; VCS = %dmV; VDN = %dmV", - attrs->vdd_voltage_mv, attrs->vcs_voltage_mv, attrs->vdn_voltage_mv); - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_VDD_BOOT_VOLTAGE, i_target, attrs->vdd_voltage_mv), - "Error from FAPI_ATTR_SET (ATTR_VDD_BOOT_VOLTAGE)"); - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_VCS_BOOT_VOLTAGE, i_target, attrs->vcs_voltage_mv), - "Error from FAPI_ATTR_SET (ATTR_VCS_BOOT_VOLTAGE)"); - FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_VDN_BOOT_VOLTAGE, i_target, attrs->vdn_voltage_mv), - "Error from FAPI_ATTR_SET (ATTR_VDN_BOOT_VOLTAGE)"); - } // COMPUTE_VOLTAGE_SETTINGS - } - while(0); - - // trace values to be used - FAPI_INF("VDD boot voltage = %d mV (0x%x)", - attrs->vdd_voltage_mv, attrs->vdd_voltage_mv); - FAPI_INF("VCS boot voltage = %d mV (0x%x)", - attrs->vcs_voltage_mv, attrs->vcs_voltage_mv); - FAPI_INF("VDN boot voltage = %d mV (0x%x)", - attrs->vdn_voltage_mv, attrs->vdn_voltage_mv); - -fapi_try_exit: - return fapi2::current_err; -} // compute_boot_safe +// compute_boot_safe fapi2::ReturnCode -p9_setup_evid(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const VoltageConfigActions_t i_action) +p9_setup_evid (const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, + const VoltageConfigActions_t i_action) { + pm_pstate_parameter_block::AttributeList attrs; - - AttributeList attrs; - GlobalPstateParmBlock l_globalppb; - memset (&l_globalppb, 0, sizeof(GlobalPstateParmBlock)); - - // Load the attributes - FAPI_TRY(proc_get_attributes(i_target, &attrs), - "Get attributes function failed"); - - // Create Global Parameter Block from attribute structure - load_gppb_attrs(&attrs, &l_globalppb); + //Instantiate PPB object + PlatPmPPB l_pmPPB(i_target); // Compute the boot/safe values - FAPI_TRY(compute_boot_safe(i_target, &attrs, &l_globalppb, i_action)); + FAPI_TRY(l_pmPPB.compute_boot_safe(i_action)); //We only wish to apply settings if i_action says to if(i_action == APPLY_VOLTAGE_SETTINGS) { + l_pmPPB.get_pstate_attrs(&attrs); // Set the DPLL frequency values to safe mode values FAPI_TRY (p9_setup_dpll_values(i_target, attrs.freq_proc_refclock_khz, diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_setup_evid.H b/src/import/chips/p9/procedures/hwp/pm/p9_setup_evid.H index 838783a23..38e850aa6 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_setup_evid.H +++ b/src/import/chips/p9/procedures/hwp/pm/p9_setup_evid.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2018 */ +/* Contributors Listed Below - COPYRIGHT 2016,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -63,12 +63,6 @@ extern "C" /// enum of the two actions this hwp can perform /// it can either compute default voltage settings /// otherwise it can apply voltage setting to the system - typedef enum - { - COMPUTE_VOLTAGE_SETTINGS, - APPLY_VOLTAGE_SETTINGS - } VoltageConfigActions_t; - /// @typedef p9_setup_evid_FP_t /// function pointer typedef definition for HWP call support typedef fapi2::ReturnCode (*p9_setup_evid_FP_t) ( diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_pstate_parameter_block_errors.xml b/src/import/chips/p9/procedures/xml/error_info/p9_pstate_parameter_block_errors.xml index 2fc2804c4..f3073873f 100644 --- a/src/import/chips/p9/procedures/xml/error_info/p9_pstate_parameter_block_errors.xml +++ b/src/import/chips/p9/procedures/xml/error_info/p9_pstate_parameter_block_errors.xml @@ -5,7 +5,7 @@ <!-- --> <!-- OpenPOWER HostBoot Project --> <!-- --> -<!-- Contributors Listed Below - COPYRIGHT 2015,2018 --> +<!-- Contributors Listed Below - COPYRIGHT 2015,2019 --> <!-- [+] International Business Machines Corp. --> <!-- --> <!-- --> @@ -461,6 +461,18 @@ </hwpError> <!-- ******************************************************************** --> <hwpError> + <rc>RC_PSTATE_PB_ATTRIBUTE_ACCESS_ERROR</rc> + <description> Pstate attribute access failure. + </description> + <ffdc>CHIP_TARGET</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + + <!-- ******************************************************************** --> + <hwpError> <rc>RC_PSTATE_PB_NEST_FREQ_EQ_ZERO</rc> <description>The system attribute ATTR_FREQ_PB_MHZ has a zero value. This is fatal to Pstate functionality. |