summaryrefslogtreecommitdiffstats
path: root/src/lib/pstates.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pstates.h')
-rwxr-xr-xsrc/lib/pstates.h601
1 files changed, 601 insertions, 0 deletions
diff --git a/src/lib/pstates.h b/src/lib/pstates.h
new file mode 100755
index 0000000..3e4b1c9
--- /dev/null
+++ b/src/lib/pstates.h
@@ -0,0 +1,601 @@
+#ifndef __PSTATES_H__
+#define __PSTATES_H__
+
+// $Id: pstates.h,v 1.3 2014/05/27 15:35:05 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/pstates.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pstates.h
+/// \brief Pstate structures and support routines for OCC product firmware
+
+#include "pgp_common.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Global and Local Pstate Tables
+////////////////////////////////////////////////////////////////////////////
+
+/// The Global Pstate Table must be 1KB-aligned in SRAM. The alignment is
+/// specified in the traditional log2 form.
+#define GLOBAL_PSTATE_TABLE_ALIGNMENT 10
+
+/// The Global Pstate table has 128 * 8-byte entries
+#define GLOBAL_PSTATE_TABLE_ENTRIES 128
+
+/// The Local Pstate table has 32 x 64-bit entries
+#define LOCAL_PSTATE_ARRAY_ENTRIES 32
+
+/// The VDS/VIN table has 32 x 64-bit entries
+#define VDSVIN_ARRAY_ENTRIES 64
+
+/// 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
+
+/// The iVID base voltage in micro-Volts
+#define IVID_BASE_UV 600000
+
+/// The iVID step as an unsigned number (micro-Volts)
+#define IVID_STEP_UV 6250
+
+/// CPM Inflection Points
+#define CPM_RANGES 8
+
+// Error/Panic codes for support routines
+
+#define VRM11_INVALID_VOLTAGE 0x00876101
+
+#define PSTATE_OVERFLOW_BIAS_PS 0x00778a01
+#define PSTATE_UNDERFLOW_BIAS_PS 0x00778a02
+#define PSTATE_OVERFLOW_GPST_F2P 0x00778a03
+#define PSTATE_UNDERFLOW_GPST_F2P 0x00778a04
+
+#define PSTATE_LT_PSTATE_MIN 0x00778a05
+#define PSTATE_GT_PSTATE_MAX 0x00778a06
+
+#define DPLL_OVERFLOW 0x00d75501
+#define DPLL_UNDERFLOW1 0x00d75502
+#define DPLL_UNDERFLOW2 0x00d75503
+
+#define VID11_OVERFLOW_VID11_VALIDATE 0x00843101
+#define VID11_OVERFLOW_BIAS_VID11 0x00843102
+#define VID11_UNDERFLOW_VID11_VALIDATE 0x00843103
+#define VID11_UNDERFLOW_BIAS_VID11 0x00843104
+
+#define GPST_INVALID_OBJECT_GPST_ENTRY 0x00477801
+#define GPST_INVALID_OBJECT_GPST_V2P 0x00477802
+#define GPST_INVALID_ARGUMENT 0x00477803
+#define GPST_INVALID_ENTRY 0x00477804
+#define GPST_PSTATE_CLIPPED_HIGH_GPSM_BGA 0x00477805
+#define GPST_PSTATE_CLIPPED_LOW_GPSM_BGA 0x00477806
+#define GPST_PSTATE_CLIPPED_HIGH_GPST_ENTRY 0x00477807
+#define GPST_PSTATE_CLIPPED_LOW_GPST_ENTRY 0x00477808
+#define GPST_PSTATE_CLIPPED_HIGH_GPST_V2P 0x00477809
+#define GPST_PSTATE_CLIPPED_LOW_GPST_V2P 0x0047780a
+#define GPST_BUG 0x0047780b
+#define GPST_PSTATE_GT_GPST_PMAX 0x0047780c
+
+#define LPST_INVALID_OBJECT 0x00477901
+#define LPST_GPST_WARNING 0x00477902
+#define LPST_INCR_CLIP_ERROR 0x00477903
+
+/// PstateSuperStructure Magic Number
+///
+/// This magic number identifies a particular version of the
+/// PstateSuperStructure and its substructures. The version number should be
+/// kept up to date as changes are made to the layout or contents of the
+/// structure.
+
+#define PSTATE_SUPERSTRUCTURE_MAGIC 0x5053544154453033ull /* PSTATE03 */
+#define PSTATE_SUPERSTRUCTURE_GOOD1 0x5053544154453031ull /* PSTATE01 */
+#define PSTATE_SUPERSTRUCTURE_GOOD2 0x5053544154453032ull /* PSTATE02 */
+#define PSTATE_SUPERSTRUCTURE_GOOD3 0x5053544154453033ull /* PSTATE03 */
+
+
+/// \defgroup pstate_options Pstate Options
+///
+/// These are flag bits for the \a options field of the PstateOptions
+/// structure.
+///
+/// @{
+
+/// gpsm_gpst_install() - Bypass copying the Pstate table from the
+/// PstateSuperStructure into the aligned global location.
+#define PSTATE_NO_COPY_GPST 0x01
+
+/// gpsm_gpst_install() - Bypass Global Pstate Table installation and setup.
+#define PSTATE_NO_INSTALL_GPST 0x02
+
+/// gpsm_lpsa_install() - Bylass Local Pstate Array installation and setup
+#define PSTATE_NO_INSTALL_LPSA 0x04
+
+/// gpsm_resclk_install - Bypass resonant clocking Pstate limit setup
+#define PSTATE_NO_INSTALL_RESCLK 0x08
+
+/// gpsm_enable_pstates() - Force the system to the minimum Pstate at
+/// initialization
+///
+/// This mode is added as a workaround for the case that the SPIVID interface
+/// is not working correctly during initial bringup. This forces Pstate mode
+/// to come up at a low frequency.
+#define PSTATE_FORCE_INITIAL_PMIN 0x10
+
+/// @}
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+/// A Global Pstate Table Entry, in the form of a packed 'firmware register'
+///
+/// Global Pstate table entries are referenced by OCC firmware, for example
+/// in procedures that do 'manual' Pstate manipulation.
+
+typedef union gpst_entry {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t evid_vdd : 8;
+ uint64_t evid_vcs : 8;
+ uint64_t reserved16 : 1;
+ uint64_t evid_vdd_eff : 7;
+ uint64_t reserved24 : 1;
+ uint64_t evid_vcs_eff : 7;
+ uint64_t reserved32 : 1;
+ uint64_t maxreg_vdd : 7;
+ uint64_t reserved40 : 1;
+ uint64_t maxreg_vcs : 7;
+ uint64_t reserved48 : 8;
+ uint64_t ecc : 8;
+#else
+ uint64_t ecc : 8;
+ uint64_t reserved48 : 8;
+ uint64_t maxreg_vcs : 7;
+ uint64_t reserved40 : 1;
+ uint64_t maxreg_vdd : 7;
+ uint64_t reserved32 : 1;
+ uint64_t evid_vcs_eff : 7;
+ uint64_t reserved24 : 1;
+ uint64_t evid_vdd_eff : 7;
+ uint64_t reserved16 : 1;
+ uint64_t evid_vcs : 8;
+ uint64_t evid_vdd : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+
+} gpst_entry_t;
+
+
+/// A Local Pstate Table Entry, in the form of a packed 'firmware register'
+///
+/// This structure is provided for reference only; Currently the OCC firmware
+/// does not manupulate Local Pstate table entries, however it is possible
+/// that future lab applications will require this.
+
+typedef union lpst_entry {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ivid_vdd : 7;
+ uint64_t ivid_vcs : 7;
+ uint64_t vdd_core_pwrratio : 6;
+ uint64_t vcs_core_pwrratio : 6;
+ uint64_t vdd_eco_pwrratio : 6;
+ uint64_t vcs_eco_pwrratio : 6;
+ uint64_t ps1_vid_incr : 3;
+ uint64_t ps2_vid_incr : 3;
+ uint64_t ps3_vid_incr : 3;
+ uint64_t reserved47 : 7;
+ uint64_t inc_step : 3;
+ uint64_t dec_step : 3;
+ uint64_t reserved60 : 4;
+#else
+ uint64_t reserved60 : 4;
+ uint64_t dec_step : 3;
+ uint64_t inc_step : 3;
+ uint64_t reserved47 : 7;
+ uint64_t ps3_vid_incr : 3;
+ uint64_t ps2_vid_incr : 3;
+ uint64_t ps1_vid_incr : 3;
+ uint64_t vcs_eco_pwrratio : 6;
+ uint64_t vdd_eco_pwrratio : 6;
+ uint64_t vcs_core_pwrratio : 6;
+ uint64_t vdd_core_pwrratio : 6;
+ uint64_t ivid_vcs : 7;
+ uint64_t ivid_vdd : 7;
+#endif // _BIG_ENDIAN
+ } fields;
+
+} lpst_entry_t;
+
+
+/// A VDS/VIN table Entry
+
+typedef union vdsvin_entry {
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ivid0 : 7;
+ uint64_t ivid1 : 7;
+ uint64_t reserved14 : 2;
+ uint64_t pfet0 : 5;
+ uint64_t pfet1 : 5;
+ uint64_t pfet2 : 5;
+ uint64_t pfet3 : 5;
+ uint64_t pfet4 : 5;
+ uint64_t pfet5 : 5;
+ uint64_t pfet6 : 5;
+ uint64_t pfet7 : 5;
+ uint64_t reserved_56 : 8;
+#else
+ uint64_t reserved_56 : 8;
+ uint64_t pfet7 : 5;
+ uint64_t pfet6 : 5;
+ uint64_t pfet5 : 5;
+ uint64_t pfet4 : 5;
+ uint64_t pfet3 : 5;
+ uint64_t pfet2 : 5;
+ uint64_t pfet1 : 5;
+ uint64_t pfet0 : 5;
+ uint64_t reserved14 : 2;
+ uint64_t ivid1 : 7;
+ uint64_t ivid0 : 7;
+#endif // _BIG_ENDIAN
+ } fields;
+} vdsvin_entry_t;
+
+/// Standard options controlling Pstate setup and GPSM procedures
+
+typedef struct {
+
+ /// Option flags; See \ref pstate_options
+ uint32_t options;
+
+ /// Pad structure to 8 bytes. Could also be used for other options later.
+ uint32_t pad;
+
+} PstateOptions;
+
+
+/// An abstract Global Pstate table
+///
+/// The GlobalPstateTable is an abstraction of a set of voltage/frequency
+/// operating points along with hardware limits. Besides the hardware global
+/// Pstate table, the abstract table contains enough extra information to make
+/// it the self-contained source for setting up and managing voltage and
+/// frequency in either Hardware or Firmware Pstate mode.
+///
+/// When installed in PMC, Global Pstate table indices are adjusted such that
+/// the defined Pstates begin with table entry 0. The table need not be full -
+/// the \a pmin and \a entries fields define the minimum and maximum Pstates
+/// represented in the table. However at least 1 entry must be defined to
+/// create a legal table.
+///
+/// Note that Global Pstate table structures to be mapped into PMC hardware
+/// must be 1KB-aligned. This requirement is fullfilled by ensuring that
+/// instances of this structure are 1KB-aligned.
+
+typedef struct {
+
+ /// The Pstate table
+ gpst_entry_t pstate[GLOBAL_PSTATE_TABLE_ENTRIES];
+
+ /// Pstate options
+ ///
+ /// The options are included as part of the GlobalPstateTable so that they
+ /// are available to all procedures after gpsm_initialize().
+ PstateOptions options;
+
+ /// The frequency associated with Pstate[0] in KHz
+ uint32_t pstate0_frequency_khz;
+
+ /// The frequency step in KHz
+ uint32_t frequency_step_khz;
+
+ /// The DPLL frequency code corresponding to Pstate 0
+ ///
+ /// This frequency code is installed in the PCB Slave as the DPLL Fnom
+ /// when the Pstate table is activated. Normally this frequency code is
+ /// computed as
+ ///
+ /// pstate0_frequency_khz / frequency_step_khz
+ ///
+ /// however it may be replaced by any other code as a way to
+ /// transparently bias frequency on a per-core basis.
+ DpllCode pstate0_frequency_code[PGP_NCORES];
+
+ /// The DPLL Fmax bias
+ ///
+ /// This bias value (default 0, range -8 to +7 frequency ticks) is
+ /// installed when the Pstate table is installed. The value is allowed to
+ /// vary per core. This bias value will usually be set to a small
+ /// positive number to provide a small amount of frequency headroom for
+ /// the CPM-DPLL voltage control algorithm.
+ ///
+ /// \bug Hardware currently specifies this field as unsigned for the
+ /// computation of frequency stability in
+ /// dpll_freqout_mode_en. (HW217404). This issue will be fixed in
+ /// Venice. Since we never plan to use this mode no workaround or
+ /// mitigation is provided by GPSM procedures.
+
+ int8_t dpll_fmax_bias[PGP_NCORES];
+
+ /// The number of entries defined in the table.
+ uint8_t entries;
+
+ /// The minimum Pstate in the table
+ ///
+ /// Note that gpsi_min = pmin - PSTATE_MIN, gpsi_max = pmin + entries - 1.
+ Pstate pmin;
+
+ /// The "Safe" Global Pstate
+ ///
+ /// This Pstate is installed in the PMC and represents the safe-mode
+ /// voltage.
+ Pstate pvsafe;
+
+ /// The "Safe" Local Pstate
+ ///
+ /// This Pstate is installed in the PCB Slaves and represents the
+ /// safe-mode frequency.
+ Pstate psafe;
+
+ /// Step size of Global Pstate steps
+ uint8_t pstate_stepsize;
+
+ /// The exponent of the exponential encoding of Pstate stepping delay
+ uint8_t vrm_stepdelay_range;
+
+ /// The significand of the exponential encoding of Pstate stepping delay
+ uint8_t vrm_stepdelay_value;
+
+ /// The Pstate for minimum core frequency in the system, defined by MRW
+ uint8_t pfloor;
+
+} GlobalPstateTable;
+
+
+/// This macro creates a properly-aligned Global Pstate table structure as a
+/// static initialization.
+
+#define GLOBAL_PSTATE_TABLE(x) \
+ GlobalPstateTable x \
+ ALIGNED_ATTRIBUTE(POW2_32(GLOBAL_PSTATE_TABLE_ALIGNMENT)) \
+ SECTION_ATTRIBUTE(".noncacheable") \
+ = {.entries = 0}
+
+
+/// An opaque Local Pstate Array
+///
+/// An array local to each core contains the Local Pstate Table, Vds table and
+/// Vin table. The array contents are presented to OCC firmware as an opaque
+/// set of 96 x 64-bit entries which are simply installed verbatim into each
+/// core. Every core stores the same table.
+///
+/// When installed in the core, Local Pstate table indices are adjusted such
+/// that the defined Pstates begin with table entry 0. The table need not be
+/// full - the \a pmin and \a entries fields define the minimum and maximum
+/// Pstates represented in the table. However at least 1 entry must be
+/// defined to create a legal table.
+
+typedef struct {
+
+ /// The vdsvin table contents
+ vdsvin_entry_t vdsvin[VDSVIN_ARRAY_ENTRIES];
+
+ /// The local pstate table contents
+ lpst_entry_t pstate[LOCAL_PSTATE_ARRAY_ENTRIES];
+
+ /// The number of entries defined in the Local Pstate Table
+ uint8_t entries;
+
+ /// The minimum Pstate in the Local Pstate table
+ ///
+ /// Note that lpsi_min = pmin - PSTATE_MIN, lpsi_max = pmin + entries - 1.
+ Pstate pmin;
+
+ /// Pstate step delay for rising iVRM voltages
+ uint8_t stepdelay_rising;
+
+ /// Pstate step delay for falling iVRM voltages
+ uint8_t stepdelay_lowering;
+
+ /// Pad structure to 8-byte alignment
+ uint8_t pad[4];
+
+} LocalPstateArray;
+
+
+/// Resonant Clocking setup parameters
+///
+/// All Pstate parameters are specified in terms of Pstates as defined in the
+/// current PstateSuperStructure.
+
+typedef struct {
+
+ /// Full Clock Sector Buffer Pstate
+ Pstate full_csb_ps;
+
+ /// Low-Frequency Resonant Lower Pstate
+ Pstate res_low_lower_ps;
+
+ /// Low-Frequency Resonant Upper Pstate
+ Pstate res_low_upper_ps;
+
+ /// High-Frequency Resonant Lower Pstate
+ Pstate res_high_lower_ps;
+
+ /// High-Frequency Resonant Upper Pstate
+ Pstate res_high_upper_ps;
+
+ /// Pad structure to 8-byte alignment
+ uint8_t pad[3];
+
+} ResonantClockingSetup;
+
+/// CPM Pstate ranges per mode
+///
+/// These Pstate range specifications apply to all chiplets operating in the
+/// same mode.
+
+typedef union {
+
+ /// Forces alignment
+ uint64_t quad[2];
+
+ struct {
+
+ /// Lower limit of each CPM calibration range
+ ///
+ /// The entries in this table are Pstates representing the
+ /// lowest-numbered (lowest-voltage) Pstate of each range. This is the
+ /// inflection point between range N and range N+1.
+ Pstate inflectionPoint[CPM_RANGES];
+
+ /// The number of ranges valid in the \a inflectionPoint table
+ ///
+ /// Validity here is defined by the original characterization
+ /// data. Whether or not OCC will use any particular range is managed
+ /// by OCC.
+ uint8_t validRanges;
+
+ /// The Pstate corresponding to the upper limit of range 0.
+ ///
+ /// This is the "CPmax" for the mode. The "CPmin" for this
+ /// mode is the value of inflectionPoint[valid_ranges - 1].
+ Pstate pMax;
+
+ uint8_t pad[6];
+ };
+
+} CpmPstateModeRanges;
+
+
+/// The layout of the data created by the Pstate table creation firmware
+///
+/// This structure is only used for passing Pstate data from the FSP into OCC,
+/// therefore there is no alignment requirement. The \gpst member is copied
+/// to an aligned location, and the \a lpsa and \a resclk members are directly
+/// installed in hardware.
+///
+/// Both the master and slave OCCs (in DCM-mode) install their Pstate tables
+/// independently via the API gpsm_initialize(). At that point the
+/// PstateSuperStructure can be discarded.
+
+typedef struct {
+
+ /// Magic Number
+ uint64_t magic;
+
+ /// Global Pstate Table
+ GlobalPstateTable gpst;
+
+ /// Local Pstate Array
+ LocalPstateArray lpsa;
+
+ /// Resonant Clocking Setup
+ ResonantClockingSetup resclk;
+
+ /// CPM Pstate ranges
+ CpmPstateModeRanges cpmranges;
+
+} PstateSuperStructure;
+
+
+int
+vid11_validate(Vid11 vid);
+
+int
+bias_pstate(Pstate pstate, int bias, Pstate* biased_pstate);
+
+int
+bias_frequency(DpllCode fcode, int bias, DpllCode* biased_fcode);
+
+int
+bias_vid11(Vid11 vid, int bias, Vid11* biased_fcode);
+
+int
+gpst_entry(const GlobalPstateTable* gpst,
+ const Pstate pstate,
+ const int bias,
+ gpst_entry_t* entry);
+
+int
+gpst_frequency2pstate(const GlobalPstateTable* gpst,
+ const uint32_t frequency_khz,
+ Pstate* pstate);
+
+int
+gpst_vdd2pstate(const GlobalPstateTable* gpst,
+ const uint8_t vdd,
+ Pstate* pstate,
+ gpst_entry_t* entry);
+
+
+/// Return the Pmin value associated with a GlobalPstateTable
+static inline Pstate
+gpst_pmin(const GlobalPstateTable* gpst)
+{
+ return gpst->pmin;
+}
+
+
+/// Return the Pmax value associated with a GlobalPstateTable
+static inline Pstate
+gpst_pmax(const GlobalPstateTable* gpst)
+{
+ return (int)(gpst->pmin) + (int)(gpst->entries) - 1;
+}
+
+/// Return the Pmin value associated with a LocalPstateTable
+static inline Pstate
+lpst_pmin(const LocalPstateArray* lpsa)
+{
+ return lpsa->pmin;
+}
+
+
+/// Return the Pmax value associated with a GlobalPstateTable
+static inline Pstate
+lpst_pmax(const LocalPstateArray* lpsa)
+{
+ return (int)(lpsa->pmin) + (int)(lpsa->entries) - 1;
+}
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PSTATES_H__ */
OpenPOWER on IntegriCloud