diff options
author | Rahul Batra <rbatra@us.ibm.com> | 2019-01-15 16:45:58 -0500 |
---|---|---|
committer | hostboot <hostboot@us.ibm.com> | 2019-06-25 10:47:16 -0500 |
commit | 4d775c52daa42a8302b2489bd23078a2b844b7d1 (patch) | |
tree | 961bb10e3fd34f2d8bf5ec1c8917e7921387e38c /import | |
parent | 0bf8ba716cea6e64c6f0ae592497a603c87d3fa3 (diff) | |
download | talos-hcode-4d775c52daa42a8302b2489bd23078a2b844b7d1.tar.gz talos-hcode-4d775c52daa42a8302b2489bd23078a2b844b7d1.zip |
PM: WOV(OCS) PGPE Hcode Changes (2/2)
2nd commit in the series of 2 commits for
WOV(OverCurrent Sampling, OCS)
Commit 1: WOV(OCS) HW procedures updates
Commit 2: WOV(OCS) PGPE Hcode updates
Key_Cronus_Test=PM_REGRESS
HW-Image-Prereq: I6234f0f60b9ed57b8b144159f3fe9c0b756df1e3
Change-Id: I64d72c8c2c3163d000a640959e0b188ab63d3819
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/70514
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: RANGANATHPRASAD G. BRAHMASAMUDRA <prasadbgr@in.ibm.com>
Tested-by: Cronus HW CI <cronushw-ci+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
Reviewed-by: Jennifer A Stofer <stofer@us.ibm.com>
Diffstat (limited to 'import')
9 files changed, 238 insertions, 64 deletions
diff --git a/import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h b/import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h index cdaff84c..f7a2692f 100644 --- a/import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h +++ b/import/chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h @@ -41,7 +41,8 @@ extern "C" { #endif -#define HCODE_OCC_SHARED_MAGIC_NUMBER 0x4F505330 //OPS0 +#define HCODE_OCC_SHARED_MAGIC_NUMBER_OPS0 0x4F505330 //OPS0 +#define HCODE_OCC_SHARED_MAGIC_NUMBER_OPS1 0x4F505331 //OPS1 //--------------- // IPC from 405 diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/avs_driver.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/avs_driver.c index d7beb770..ce1838c6 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/avs_driver.c +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/avs_driver.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2018 */ +/* COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -81,16 +81,17 @@ uint32_t CRC_calc(uint32_t data) //################################################################################################# // Function polls OCB status register O2SST for o2s_ongoing=0 //################################################################################################# -uint8_t pollVoltageTransDone(void) +uint8_t pollVoltageTransDone(uint32_t BusNum) { uint8_t rc = 0; uint32_t ocbRegReadData = 0; uint8_t ongoingFlag = 1; uint8_t count = 0; - uint32_t BusMask = (in32(G_OCB_OCCS2) & AVS_BUS_NUM_MASK) << 4; + uint32_t BusMask = BusNum << O2S_BUSNUM_OFFSET_SHIFT; // The point of MAX_POLL_COUNT_AVS is to verify that ongoingFlag turns to // zero very fast. Otherwise, something wrong with this i/f and error out. + //PK_TRACE_INF("PV:OCB_O2SST0A =0x%x",OCB_O2SST0A | BusMask); while (ongoingFlag || (count <= MAX_POLL_COUNT_AVS)) { ocbRegReadData = in32(OCB_O2SST0A | BusMask); @@ -120,11 +121,11 @@ uint8_t pollVoltageTransDone(void) //################################################################################################# // Function which writes to OCB registers to initialize the AVS Slave with an idle frame //################################################################################################# -uint8_t driveIdleFrame(void) +uint8_t driveIdleFrame(uint32_t BusNum) { uint8_t rc = 0; uint32_t idleframe = 0xFFFFFFFF; - uint32_t BusMask = (in32(G_OCB_OCCS2) & AVS_BUS_NUM_MASK) << 4; + uint32_t BusMask = BusNum << O2S_BUSNUM_OFFSET_SHIFT; // Clear sticky bits in o2s_status_reg out32(OCB_O2SCMD0A | BusMask , 0x40000000); @@ -133,7 +134,7 @@ uint8_t driveIdleFrame(void) out32(OCB_O2SWD0A | BusMask , idleframe); // Wait on o2s_ongoing = 0 - rc = pollVoltageTransDone(); + rc = pollVoltageTransDone(BusNum); return rc; } @@ -142,18 +143,18 @@ uint8_t driveIdleFrame(void) //################################################################################################# // Function which writes to OCB registers to initiate a AVS write transaction //################################################################################################# -uint8_t driveWrite(uint32_t CmdDataType, uint32_t CmdData) +uint8_t driveWrite(uint32_t CmdDataType, uint32_t CmdData, uint32_t BusNum, uint32_t RailNum) { uint8_t rc = 0, retryCnt = 0, done = 0; uint32_t ocbRegWriteData = 0; uint32_t ocbRegReadData = 0; - uint32_t RailSelect = in32(G_OCB_OCCS2) & AVS_RAIL_NUM_MASK; + uint32_t RailSelect = RailNum; uint32_t StartCode = 1; uint32_t CmdType = 0; // 0:write+commit, 1:write+hold, 2: d/c, 3:read uint32_t CmdGroup = 0; uint32_t CRC = 0; - uint32_t BusMask = (in32(G_OCB_OCCS2) & AVS_BUS_NUM_MASK) << 4; + uint32_t BusMask = BusNum << O2S_BUSNUM_OFFSET_SHIFT; // Clear sticky bits in o2s_status_reg out32(OCB_O2SCMD0A | BusMask, 0x40000000); @@ -174,7 +175,7 @@ uint8_t driveWrite(uint32_t CmdDataType, uint32_t CmdData) out32(OCB_O2SWD0A | BusMask, ocbRegWriteData); // Wait on o2s_ongoing = 0 - rc = pollVoltageTransDone(); + rc = pollVoltageTransDone(BusNum); if (rc) { @@ -199,7 +200,7 @@ uint8_t driveWrite(uint32_t CmdDataType, uint32_t CmdData) else { retryCnt++; - rc = driveIdleFrame(); + rc = driveIdleFrame(BusNum); if (rc) { @@ -222,20 +223,20 @@ uint8_t driveWrite(uint32_t CmdDataType, uint32_t CmdData) //################################################################################################# // Function which writes to OCB registers to initiate a AVS read transaction //################################################################################################# -uint8_t driveRead(uint32_t CmdDataType, uint32_t* CmdData) +uint8_t driveRead(uint32_t CmdDataType, uint32_t* CmdData, uint32_t BusNum, uint32_t RailNum) { uint8_t rc = 0, retryCnt = 0, done = 0; uint32_t ocbRegReadData = 0; uint32_t ocbRegWriteData = 0; - uint32_t RailSelect = in32(G_OCB_OCCS2) & AVS_RAIL_NUM_MASK; + uint32_t RailSelect = RailNum; uint32_t StartCode = 1; uint32_t CmdType = 3; // 0:write+commit, 1:write+hold, 2: d/c, 3:read uint32_t CmdGroup = 0; uint32_t Reserved = 0xFFFF; uint32_t CRC = 0; - uint32_t BusMask = (in32(G_OCB_OCCS2) & AVS_BUS_NUM_MASK) << 4; + uint32_t BusMask = BusNum << O2S_BUSNUM_OFFSET_SHIFT; // Clear sticky bits in o2s_status_reg out32(OCB_O2SCMD0A | BusMask, 0x40000000); @@ -256,7 +257,7 @@ uint8_t driveRead(uint32_t CmdDataType, uint32_t* CmdData) out32(OCB_O2SWD0A | BusMask, ocbRegWriteData); // Wait on o2s_ongoing = 0 - rc = pollVoltageTransDone(); + rc = pollVoltageTransDone(BusNum); if (rc) { @@ -281,7 +282,7 @@ uint8_t driveRead(uint32_t CmdDataType, uint32_t* CmdData) else { retryCnt++; - rc = driveIdleFrame(); + rc = driveIdleFrame(BusNum); if (rc) { @@ -301,19 +302,20 @@ uint8_t driveRead(uint32_t CmdDataType, uint32_t* CmdData) return rc; } +void avs_driver_init() +{ + //Initialize VDD + avs_driver_bus_init(G_gppb->avs_bus_topology.vdd_avsbus_num); -//################################################################################################# -// Function which initializes the OCB O2S registers -//################################################################################################# -void external_voltage_control_init(uint32_t* vext_read_mv) + //Initialize VDN + avs_driver_bus_init(G_gppb->avs_bus_topology.vdn_avsbus_num); +} + + +void avs_driver_bus_init(uint32_t BusNum) { uint8_t rc = 0; - uint32_t CmdDataRead = 0; -//#if EPM_P9_TUNING -// We do not need to initialize O2S and AVS slave in product -// because this is done in istep 6. But for EPM, we need to do it. -//\todo Read from Parameter Block. These are attributes #define CLOCK_SPIVID_MHZ 10 PK_TRACE_DBG("NestFreq=0x%x", G_gppb->nest_frequency_mhz); uint32_t ocbRegReadData = 0; @@ -324,11 +326,8 @@ void external_voltage_control_init(uint32_t* vext_read_mv) uint32_t O2SCTRL1_value = 0b10010000000000000100000000000000 | (G_gppb->nest_frequency_mhz / (8 * CLOCK_SPIVID_MHZ) - 1) << 18; - // // OCI to SPIPMBus (O2S) bridge initialization - // - - uint32_t BusMask = (in32(G_OCB_OCCS2) & AVS_BUS_NUM_MASK) << 4; + uint32_t BusMask = BusNum << O2S_BUSNUM_OFFSET_SHIFT; // O2SCTRLF ocbRegReadData = in32(OCB_O2SCTRLF0A | BusMask); @@ -358,8 +357,7 @@ void external_voltage_control_init(uint32_t* vext_read_mv) // In principle this only has to be done once. Though Doug Lane // says that due to noise on the chip this init should be done // periodically. - - rc = driveIdleFrame(); + rc = driveIdleFrame(BusNum); if (rc) { @@ -367,36 +365,25 @@ void external_voltage_control_init(uint32_t* vext_read_mv) PGPE_TRACE_AND_PANIC(PGPE_AVS_INIT_DRIVE_IDLE_FRAME); } - // Drive read transaction to return initial setting of rail voltage and wait on o2s_ongoing=0 - rc = driveRead(0, &CmdDataRead); - - if (rc) - { - PK_TRACE_ERR("AVS_INIT: DriveRead FAIL"); - PGPE_TRACE_AND_PANIC(PGPE_AVS_INIT_DRIVE_READ); - } - - *vext_read_mv = CmdDataRead; } - //################################################################################################# // Main function to initiate an eVRM voltage change. There is a write followed by a // read, and then a voltage value compare check. //################################################################################################# -void external_voltage_control_write(uint32_t vext_write_mv) +void avs_driver_voltage_write(uint32_t BusNum, uint32_t RailNum, uint32_t VoltMV) { uint8_t rc = 0; uint32_t CmdDataType = 0; // 0b0000=Target rail voltage - if (vext_write_mv > AVS_DRIVER_MAX_EXTERNAL_VOLTAGE || - vext_write_mv < AVS_DRIVER_MIN_EXTERNAL_VOLTAGE) + if (VoltMV > AVS_DRIVER_MAX_EXTERNAL_VOLTAGE || + VoltMV < AVS_DRIVER_MIN_EXTERNAL_VOLTAGE) { PGPE_TRACE_AND_PANIC(PGPE_VOLTAGE_OUT_OF_BOUNDS); } // Drive write transaction with a target voltage on a particular rail and wait on o2s_ongoing=0 - rc = driveWrite(CmdDataType, vext_write_mv); + rc = driveWrite(CmdDataType, VoltMV, BusNum, RailNum); switch (rc) { @@ -419,3 +406,29 @@ void external_voltage_control_write(uint32_t vext_write_mv) break; } } + +void avs_driver_voltage_read(uint32_t BusNum, uint32_t RailNum, uint32_t* RetVolt) +{ + uint32_t rc = 0; + + rc = driveRead(0x0, RetVolt, BusNum, RailNum); + + if (rc) + { + PK_TRACE_ERR("AVS_READ_VOLT: DriveRead FAILED. BusNum=0x%x,RailNum=0x%x", BusNum, RailNum); + PGPE_TRACE_AND_PANIC(PGPE_AVS_DRIVE_READ); + } +} + +void avs_driver_current_read(uint32_t BusNum, uint32_t RailNum, uint32_t* RetCurrent) +{ + uint32_t rc = 0; + + rc = driveRead(0x2, RetCurrent, BusNum, RailNum); + + if (rc) + { + PK_TRACE_ERR("AVS_READ_CURRENT: DriveRead FAILED rc=0x%x. BusNum=0x%x, RailNum=0x%x", rc, BusNum, RailNum); + PGPE_TRACE_AND_PANIC(PGPE_AVS_DRIVE_READ); + } +} diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/avs_driver.h b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/avs_driver.h index 574c62c3..06fa5624 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/avs_driver.h +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/avs_driver.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2015,2017 */ +/* COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -26,16 +26,20 @@ // Setup and enable the O2S bridge on the AVS bus. // + #ifndef _AVS_DRIVER_H_ #define _AVS_DRIVER_H_ +#include "pstate_pgpe_occ_api.h" + #define MAX_POLL_COUNT_AVS 10 #define AVS_RAIL_NUM_MASK 0xF #define AVS_BUS_NUM_MASK 0x10 enum AVS_DRIVER { AVS_DRIVER_MAX_EXTERNAL_VOLTAGE = 1500, - AVS_DRIVER_MIN_EXTERNAL_VOLTAGE = 500 + AVS_DRIVER_MIN_EXTERNAL_VOLTAGE = 500, + O2S_BUSNUM_OFFSET_SHIFT = 8 }; enum AVS_DRIVER_RETURN_CODES @@ -45,11 +49,17 @@ enum AVS_DRIVER_RETURN_CODES AVS_RC_RESYNC_ERROR = 2 }; +void avs_driver_init(); + +void avs_driver_bus_init(uint32_t BusNum); + void -external_voltage_control_init(uint32_t* vext_read_mv); +avs_driver_voltage_write(uint32_t BusNum, uint32_t RailNum, uint32_t VoltMV); +void +avs_driver_voltage_read(uint32_t BusNum, uint32_t RailNum, uint32_t* RetVolt); void -external_voltage_control_write(uint32_t vext_write_mv); +avs_driver_current_read(uint32_t BusNum, uint32_t RailNum, uint32_t* RetCurrent); #endif //_AVS_DRIVER_H_ diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c index cb42d9ad..181666bf 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c @@ -30,6 +30,7 @@ #include <p9_hcd_memmap_occ_sram.H> #include "p9_pgpe_optrace.h" #include "occhw_shared_data.h" +#include "avs_driver.h" #define AUX_TASK 14 #define GPE2TSEL 0xC0020000 @@ -389,14 +390,43 @@ extern uint32_t G_pib_reset_flag; // __attribute__((always_inline)) inline void handle_wov() { - if (G_pgpe_pstate_record.wov.status & WOV_UNDERVOLT_ENABLED) + + G_wov_count++; + + if ((G_gppb->wov_sample_125us >> 1) == G_wov_count) { - G_wov_count++; + G_wov_count = 0; + + if (G_pgpe_pstate_record.produceWOFValues) + { + p9_pgpe_pstate_update_wof_produced_values(); + } - if ((G_gppb->wov_sample_125us / 2) == G_wov_count) + //If enabled, run undervolting algorithm + if (G_pgpe_pstate_record.wov.status & WOV_UNDERVOLT_ENABLED) { p9_pgpe_pstate_adjust_wov(); - G_wov_count = 0; + } + + //If enabled, run over rvolting algorithm + if (G_pgpe_pstate_record.wov.status & WOV_OVERVOLT_ENABLED) + { + if (G_pgpe_pstate_record.excessiveDroop == 1) + { + out32(G_OCB_OCCFLG_OR, BIT32(PGPE_OCS_DIRTY)); + } + else + { + if (G_pgpe_pstate_record.pWofValues->dw2.fields.vdd_avg_mv >= + G_pgpe_pstate_record.vddCurrentThresh) //(default is #V turbo current) + { + out32(G_OCB_OCCFLG_OR, BIT32(PGPE_OCS_DIRTY)); + } + else + { + out32(G_OCB_OCCFLG_CLR, BIT32(PGPE_OCS_DIRTY)); + } + } } } } @@ -418,4 +448,5 @@ void p9_pgpe_fit_handler(void* arg, PkIrqId irq) handle_aux_task(); handle_fit_timebase_sync(); handle_wov(); + } diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_header.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_header.c index 30f1f9cc..c5a1feb9 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_header.c +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_header.c @@ -27,9 +27,6 @@ #include "p9_hcode_image_defines.H" #include "p9_hcd_memmap_base.H" -//OCC Shared SRAM starts at bottom 2K of PGPE OCC SRAM space -#define OCC_SHARED_SRAM_ADDR_START \ - (OCC_SRAM_PGPE_BASE_ADDR + OCC_SRAM_PGPE_REGION_SIZE - PGPE_OCC_SHARED_SRAM_SIZE) PgpeHeader_t* G_pgpe_header_data; extern PgpeHeader_t* _PGPE_IMG_HEADER __attribute__ ((section (".pgpe_image_header"))); @@ -78,7 +75,6 @@ void p9_pgpe_header_init() G_pgpe_header_data->g_pgpe_wof_state_address = (uint32_t)&occ_shared_data->pgpe_wof_state;//Wof State G_pgpe_header_data->g_pgpe_req_active_quad_address = (uint32_t) &occ_shared_data->req_active_quads;//Requested Active Quads + G_pgpe_header_data->g_pgpe_wof_values_address = (uint32_t)&occ_shared_data->pgpe_wof_values;//Wof Values - //Write the magic number in the HcodeOCCSharedData struct - occ_shared_data->magic = HCODE_OCC_SHARED_MAGIC_NUMBER; } diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_header.h b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_header.h index f441479d..bc3504b1 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_header.h +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_header.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HCODE Project */ /* */ -/* COPYRIGHT 2016,2018 */ +/* COPYRIGHT 2016,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -26,6 +26,12 @@ #define _P9_PGPE_HEADER_H_ #include "pk.h" +#include "p9_hcode_image_defines.H" +#include "p9_hcd_memmap_base.H" + +//OCC Shared SRAM starts at bottom 2K of PGPE OCC SRAM space +#define OCC_SHARED_SRAM_ADDR_START \ + (OCC_SRAM_PGPE_BASE_ADDR + OCC_SRAM_PGPE_REGION_SIZE - PGPE_OCC_SHARED_SRAM_SIZE) // // p9_pgpe_header_init diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.c index d53d5fc4..20419cee 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.c +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.c @@ -124,6 +124,7 @@ void p9_pgpe_pstate_init() G_pgpe_pstate_record.pQuadState0 = (quad_state0_t*)G_pgpe_header_data->g_quad_status_addr; G_pgpe_pstate_record.pQuadState1 = (quad_state1_t*)(G_pgpe_header_data->g_quad_status_addr + 8); G_pgpe_pstate_record.pReqActQuads = (requested_active_quads_t*)(G_pgpe_header_data->g_pgpe_req_active_quad_address); + G_pgpe_pstate_record.pWofValues = (pgpe_wof_values_t*)(G_pgpe_header_data->g_pgpe_wof_values_address); G_pgpe_pstate_record.pQuadState0->fields.quad0_pstate = 0xff; G_pgpe_pstate_record.pQuadState0->fields.quad1_pstate = 0xff; G_pgpe_pstate_record.pQuadState0->fields.quad2_pstate = 0xff; @@ -134,6 +135,15 @@ void p9_pgpe_pstate_init() G_pgpe_pstate_record.pQuadState1->fields.active_cores = 0x0; G_pgpe_pstate_record.pReqActQuads->fields.requested_active_quads = 0x0; G_pgpe_pstate_record.activeCoreUpdtAction = ACTIVE_CORE_UPDATE_ACTION_ERROR; + G_pgpe_pstate_record.pWofValues->dw0.value = 0; + G_pgpe_pstate_record.pWofValues->dw1.value = 0; + G_pgpe_pstate_record.pWofValues->dw2.value = 0; + G_pgpe_pstate_record.pWofValues->dw3.value = 0; + G_pgpe_pstate_record.prevIdd = 0; + G_pgpe_pstate_record.prevIdn = 0; + G_pgpe_pstate_record.prevVdd = 0; + G_pgpe_pstate_record.vddCurrentThresh = G_gppb->operating_points_set[VPD_PT_SET_BIASED_SYSP][TURBO].idd_100ma; + G_pgpe_pstate_record.excessiveDroop = 0; //Create Semaphores pk_semaphore_create(&(G_pgpe_pstate_record.sem_actuate), 0, 1); @@ -142,6 +152,30 @@ void p9_pgpe_pstate_init() //WOV init p9_pgpe_pstate_wov_init(); + + //Initialize avs_driver + avs_driver_init(); + + HcodeOCCSharedData_t* occ_shared_data = (HcodeOCCSharedData_t*) + OCC_SHARED_SRAM_ADDR_START; //Bottom 2K of PGPE OCC Sram Space + + if (in32(OCB_OCCFLG2) & BIT32(OCCFLG2_ENABLE_PRODUCE_WOF_VALUES)) + { + //Write the magic number in the HcodeOCCSharedData struct + occ_shared_data->magic = HCODE_OCC_SHARED_MAGIC_NUMBER_OPS1; + G_pgpe_pstate_record.produceWOFValues = 1; + + //Read VDN Voltage. On P9, VDN is NOT updated by PGPE, so we read it + //once during init and then don't read it all + uint32_t vdn = 0; + avs_driver_voltage_read(G_gppb->avs_bus_topology.vdn_avsbus_num, G_gppb->avs_bus_topology.vdn_avsbus_rail, &vdn); + G_pgpe_pstate_record.pWofValues->dw2.fields.vdn_avg_mv = vdn; + } + else + { + occ_shared_data->magic = HCODE_OCC_SHARED_MAGIC_NUMBER_OPS0; + G_pgpe_pstate_record.produceWOFValues = 0; + } } // @@ -419,6 +453,64 @@ void p9_pgpe_pstate_update_wof_state() wof_state->fields.vratio = G_pgpe_pstate_record.vratio; PK_TRACE_INF("WFU: FClip_PS=0x%x, vindex=0x%x, vratio=0x%x", G_pgpe_pstate_record.wofClip, G_pgpe_pstate_record.vindex, G_pgpe_pstate_record.vratio); + +} + +// +// p9_pgpe_pstate_update_wof_produced_values +// +// This function updates the wof produced values in the OCC Shared SRAM area +// +void p9_pgpe_pstate_update_wof_produced_values() +{ + uint32_t current; + + avs_driver_current_read(G_gppb->avs_bus_topology.vdd_avsbus_num, G_gppb->avs_bus_topology.vdd_avsbus_rail, ¤t); + PK_TRACE_DBG("VDD Current=0x%x, BusNum=0x%x, RailNum=0x%x", current, G_gppb->avs_bus_topology.vdd_avsbus_num, + G_gppb->avs_bus_topology.vdd_avsbus_rail); + + G_pgpe_pstate_record.pWofValues->dw1.fields.idd_avg_ma = (G_pgpe_pstate_record.prevIdd + current) >> 1; + G_pgpe_pstate_record.prevIdd = current; + + avs_driver_current_read(G_gppb->avs_bus_topology.vdn_avsbus_num, G_gppb->avs_bus_topology.vdn_avsbus_rail, ¤t); + PK_TRACE_DBG("VDN Current=0x%x, BusNum=0x%x, RailNum=0x%x", current, G_gppb->avs_bus_topology.vdn_avsbus_num, + G_gppb->avs_bus_topology.vdn_avsbus_rail); + + G_pgpe_pstate_record.pWofValues->dw1.fields.idn_avg_ma = (G_pgpe_pstate_record.prevIdn + current) >> 1; + G_pgpe_pstate_record.prevIdn = current; + + G_pgpe_pstate_record.pWofValues->dw2.fields.vdd_avg_mv = (G_pgpe_pstate_record.prevVdd + + G_pgpe_pstate_record.extVrmCurr) >> 1; + G_pgpe_pstate_record.prevVdd = G_pgpe_pstate_record.extVrmCurr; + + + uint32_t avg_pstate = 0; + uint32_t q, num = 0; + + for (q = 0; q < MAX_QUADS; q++) + { + if (G_pgpe_pstate_record.activeQuads & QUAD_MASK(q)) + { + avg_pstate += G_pgpe_pstate_record.psComputed.fields.quads[q]; + num = num + 1; + } + } + + if (num > 0) + { + G_pgpe_pstate_record.pWofValues->dw0.fields.average_pstate = ((avg_pstate / num) + G_pgpe_pstate_record.prevAvgPstate) + >> 1; + G_pgpe_pstate_record.pWofValues->dw0.fields.average_frequency_pstate = + G_pgpe_pstate_record.pWofValues->dw0.fields.average_pstate; + G_pgpe_pstate_record.prevAvgPstate = G_pgpe_pstate_record.pWofValues->dw0.fields.average_pstate; + } + + G_pgpe_pstate_record.pWofValues->dw0.fields.clip_pstate = G_pgpe_pstate_record.wofClip; + G_pgpe_pstate_record.pWofValues->dw0.fields.vratio_inst = G_pgpe_pstate_record.vratio; + G_pgpe_pstate_record.pWofValues->dw0.fields.vratio_avg = (G_pgpe_pstate_record.vratio + + G_pgpe_pstate_record.prevVratio) >> 1; + G_pgpe_pstate_record.prevVratio = G_pgpe_pstate_record.vratio; + } // @@ -810,7 +902,15 @@ void p9_pgpe_pstate_start(uint32_t pstate_start_origin) } //3. Move system to SyncPState - external_voltage_control_init(&G_pgpe_pstate_record.extVrmCurr); + PK_TRACE_INF("VDD_BUS_NUM=0x%x" , G_gppb->avs_bus_topology.vdd_avsbus_num); + PK_TRACE_INF("VDD_RAIL_NUM=0x%x", G_gppb->avs_bus_topology.vdd_avsbus_rail); + PK_TRACE_INF("VDN_BUS_NUM=0x%x" , G_gppb->avs_bus_topology.vdn_avsbus_num); + PK_TRACE_INF("VDN_RAIL_NUM=0x%x", G_gppb->avs_bus_topology.vdn_avsbus_rail); + + //avs_driver_init(); + avs_driver_voltage_read(G_gppb->avs_bus_topology.vdd_avsbus_num, G_gppb->avs_bus_topology.vdd_avsbus_rail, + &G_pgpe_pstate_record.extVrmCurr); + G_pgpe_pstate_record.biasSyspExtVrmCurr = G_pgpe_pstate_record.extVrmCurr; G_pgpe_pstate_record.biasSyspExtVrmNext = p9_pgpe_gppb_intp_vdd_from_ps(syncPstate, VPD_PT_SET_BIASED_SYSP); PK_TRACE_INF("PST: SyncPstate=0x%x eVid(Boot)=%umV,eVid(SyncPstate)=%umV", syncPstate, @@ -978,6 +1078,12 @@ void p9_pgpe_pstate_start(uint32_t pstate_start_origin) PK_TRACE_INF("PST: Undervolting Enabled"); } + if (G_pgpe_header_data->g_pgpe_flags & PGPE_FLAG_WOV_OVERVOLT_ENABLE) + { + G_pgpe_pstate_record.wov.status = WOV_OVERVOLT_ENABLED; + PK_TRACE_INF("PST: Overvolting Enabled"); + } + PK_TRACE_DBG("PST: Start Done"); } @@ -2080,7 +2186,8 @@ void p9_pgpe_pstate_updt_ext_volt() #endif //Update external voltage - external_voltage_control_write(G_pgpe_pstate_record.extVrmNext); + avs_driver_voltage_write(G_gppb->avs_bus_topology.vdd_avsbus_num, G_gppb->avs_bus_topology.vdd_avsbus_rail, + G_pgpe_pstate_record.extVrmNext); #if !EPM_P9_TUNING @@ -2159,6 +2266,7 @@ void p9_pgpe_pstate_updt_ext_volt() G_pgpe_pstate_record.wov.max_volt = G_pgpe_pstate_record.wov.curr_mv; } + //If VDM is disabled, update VDMCFG register for every quad if (!(G_pgpe_header_data->g_pgpe_flags & PGPE_FLAG_VDM_ENABLE)) { @@ -2565,6 +2673,8 @@ void p9_pgpe_pstate_adjust_wov() { G_pgpe_pstate_record.wov.target_pct = G_gppb->wov_underv_max_pct; } + + G_pgpe_pstate_record.excessiveDroop = 0; } else { @@ -2572,6 +2682,8 @@ void p9_pgpe_pstate_adjust_wov() { G_pgpe_pstate_record.wov.target_pct -= G_gppb->wov_underv_step_incr_pct; } + + G_pgpe_pstate_record.excessiveDroop = 1; } }// WOV ALGORITHM END diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.h b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.h index 78bfe77a..7a8e3921 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.h +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.h @@ -227,6 +227,10 @@ typedef struct uint32_t activeCoreUpdtAction; uint32_t biasSyspExtVrmCurr, biasSyspExtVrmNext; wov_t wov; + pgpe_wof_values_t* pWofValues; + uint32_t produceWOFValues; + uint32_t prevIdd, prevIdn, prevVdd, prevAvgPstate, prevVratio; + uint32_t excessiveDroop, vddCurrentThresh; } PgpePstateRecord __attribute__ ((aligned (8))); @@ -266,6 +270,7 @@ void p9_pgpe_pstate_apply_clips(); void p9_pgpe_pstate_calc_wof(); void p9_pgpe_pstate_updt_actual_quad(); void p9_pgpe_pstate_update_wof_state(); +void p9_pgpe_pstate_update_wof_produced_values(); //CME Communication void p9_pgpe_send_db0(db0_parms_t p); diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pgpe_panic_codes.h b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pgpe_panic_codes.h index 7703cd35..d7471bac 100644 --- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pgpe_panic_codes.h +++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/pgpe_panic_codes.h @@ -51,7 +51,7 @@ PGPE_AVS_WRITE_ONGOING_FLAG_TIMEOUT = 0x1c04, PGPE_AVS_INIT_DRIVE_IDLE_FRAME = 0x1c05, PGPE_AVS_INIT_DRIVE_READ = 0x1c06, PGPE_AVS_RESYNC_ERROR = 0x1c07, -//_UNUSED_1c08 = 0x1c08, +PGPE_AVS_DRIVE_READ = 0x1c08, PGPE_CME_FAULT = 0x1c09, PGPE_PVREF_ERROR = 0x1c0a, PGPE_OCC_FIR_IRQ = 0x1c0d, |