Skip to content

Commit

Permalink
OCC support for no APSS and new GPU Config Data
Browse files Browse the repository at this point in the history
Change-Id: Id58a06378f3c0a7fd9fb436b96823eca15028031
RTC: 160889
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/41513
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christopher J. Cain <cjcain@us.ibm.com>
Reviewed-by: William A. Bryan <wilbryan@us.ibm.com>
  • Loading branch information
marthabroyles authored and wilbryan committed Jun 12, 2017
1 parent dadf272 commit a635739
Show file tree
Hide file tree
Showing 18 changed files with 333 additions and 68 deletions.
4 changes: 2 additions & 2 deletions src/occ_405/amec/amec_pcap.c
Expand Up @@ -50,7 +50,7 @@
//*************************************************************************/
// Globals
//*************************************************************************/
extern bool G_apss_present;
extern PWR_READING_TYPE G_pwr_reading_type;

//Number of ticks to wait before dropping below nominal frequency
#define PWR_SETTLED_TICKS 4
Expand Down Expand Up @@ -374,7 +374,7 @@ void amec_power_control(void)
/* Code */
/*------------------------------------------------------------------------*/

if(G_apss_present)
if(G_pwr_reading_type == PWR_READING_TYPE_APSS)
{
// Calculate the pcap for the proc, memory and the power capping limit
// for nominal cores.
Expand Down
10 changes: 5 additions & 5 deletions src/occ_405/amec/amec_sensors_power.c
Expand Up @@ -72,7 +72,7 @@ uint32_t G_curr_num_gpus_sys = 0;

extern uint8_t G_occ_interrupt_type;
extern bool G_vrm_thermal_monitoring;
extern bool G_apss_present;
extern PWR_READING_TYPE G_pwr_reading_type;

//*************************************************************************/
// Code
Expand Down Expand Up @@ -195,7 +195,7 @@ void amec_update_apss_sensors(void)
{
// Need to check to make sure APSS data has been received
// via slave inbox first
if (G_slv_inbox_received && G_apss_present)
if (G_slv_inbox_received && (G_pwr_reading_type == PWR_READING_TYPE_APSS))
{
uint8_t l_proc = G_pbax_id.chip_id;
uint32_t temp32 = 0;
Expand Down Expand Up @@ -571,12 +571,12 @@ void update_avsbus_power_sensors(const avsbus_type_e i_type)
// = v(100uV) * i(10mA) / 1,000,000
const uint32_t l_power = l_chip_voltage_100uv * l_current_10ma / 1000000;
sensor_update(AMECSENSOR_PTR(l_powerSensor), (uint16_t)l_power);
if(!G_apss_present)
if(G_pwr_reading_type != PWR_READING_TYPE_APSS)
{
// no APSS, update the processor power sensor with total processor power
// TODO RTC 160889 add in processor power for parts not measured (i.e. Vddr, Vcs, Vio etc)
// Vdd + Vdn + fixed adder for parts not measured (i.e. Vddr, Vcs, Vio etc)
sensor_t *l_sensor2 = getSensorByGsid(l_powerSensor2);
const uint16_t l_proc_power = (uint16_t)l_power + l_sensor2->sample;
const uint16_t l_proc_power = (uint16_t)l_power + l_sensor2->sample + G_sysConfigData.proc_power_adder;
sensor_update(AMECSENSOR_PTR(PWRPROC), l_proc_power);
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/occ_405/amec/amec_sys.h
Expand Up @@ -471,9 +471,15 @@ typedef struct
sensor_t temp2mscent;
sensor_t tempdimmthrm;
sensor_t memsp2ms_tls;

// Nimbus DIMM Sensors
sensor_t tempdimm[NUM_DIMM_PORTS*NUM_DIMMS_PER_I2CPORT];

// GPU Sensors
sensor_t tempgpu0;
sensor_t tempgpu1;
sensor_t tempgpu2;

sensor_t curvdn;
sensor_t pwrvdd;
sensor_t pwrvdn;
Expand Down
110 changes: 91 additions & 19 deletions src/occ_405/cmdh/cmdh_fsp_cmds.c
Expand Up @@ -47,6 +47,7 @@
#include <proc_data.h>
#include "homer.h"
#include <centaur_data.h>
#include <avsbus.h>
#include "cmdh_dbug_cmd.h"
#include "wof.h"
extern dimm_sensor_flags_t G_dimm_temp_expired_bitmap;
Expand Down Expand Up @@ -141,7 +142,7 @@ errlHndl_t cmdh_tmgt_poll (const cmdh_fsp_cmd_t * i_cmd_ptr,
ERRL_RC cmdh_poll_v20(cmdh_fsp_rsp_t * o_rsp_ptr)
{
ERRL_RC l_rc = ERRL_RC_INTERNAL_FAIL;
uint8_t k = 0;
uint8_t k = 0, l_max_sensors = 0;
cmdh_poll_sensor_db_t l_sensorHeader;

// Set pointer to start of o_rsp_ptr
Expand Down Expand Up @@ -244,7 +245,9 @@ ERRL_RC cmdh_poll_v20(cmdh_fsp_rsp_t * o_rsp_ptr)
l_sensorHeader.count = 0;

//Initialize to max number of possible temperature sensors.
cmdh_poll_temp_sensor_t l_tempSensorList[MAX_NUM_CORES + MAX_NUM_MEM_CONTROLLERS + (MAX_NUM_MEM_CONTROLLERS * NUM_DIMMS_PER_CENTAUR)];
l_max_sensors = MAX_NUM_CORES + MAX_NUM_MEM_CONTROLLERS + (MAX_NUM_MEM_CONTROLLERS * NUM_DIMMS_PER_CENTAUR) + MAX_NUM_GPU_PER_DOMAIN;
l_max_sensors++; // +1 for VRM
cmdh_poll_temp_sensor_t l_tempSensorList[l_max_sensors];
memset(l_tempSensorList, 0x00, sizeof(l_tempSensorList));

// Add the core temperatures
Expand Down Expand Up @@ -342,6 +345,18 @@ ERRL_RC cmdh_poll_v20(cmdh_fsp_rsp_t * o_rsp_ptr)
}
}

// Add GPU temperatures
for (k=0; k<MAX_NUM_GPU_PER_DOMAIN; k++)
{
if(GPU_PRESENT(k))
{
l_tempSensorList[l_sensorHeader.count].id = G_amec_sensor_list[TEMPGPU0 + k]->ipmi_sid;
l_tempSensorList[l_sensorHeader.count].fru_type = DATA_FRU_GPU;
l_tempSensorList[l_sensorHeader.count].value = (G_amec_sensor_list[TEMPGPU0 + k]->sample) & 0xFF;
l_sensorHeader.count++;
}
}

// Copy header first.
memcpy ((void *) &(o_rsp_ptr->data[l_rsp_index]), (void *)&l_sensorHeader, sizeof(l_sensorHeader));
// Increment index into response buffer.
Expand Down Expand Up @@ -395,8 +410,10 @@ ERRL_RC cmdh_poll_v20(cmdh_fsp_rsp_t * o_rsp_ptr)

/////////////////////
// POWR Sensors:
// Generate datablock header for power sensors and sensor data. RETURNED by MASTER ONLY.
if (G_occ_role == OCC_MASTER)
// Generate datablock header for power sensors and sensor data.
// If APSS is present return format version 0x02 by MASTER ONLY.
// If no APSS present return format version 0xA0 by all OCCs.
if ( (G_occ_role == OCC_MASTER) && (G_pwr_reading_type == PWR_READING_TYPE_APSS) )
{
memset((void*) &l_sensorHeader, 0, (size_t)sizeof(cmdh_poll_sensor_db_t));
memcpy ((void *) &(l_sensorHeader.eyecatcher[0]), SENSOR_POWR, 4);
Expand Down Expand Up @@ -439,6 +456,58 @@ ERRL_RC cmdh_poll_v20(cmdh_fsp_rsp_t * o_rsp_ptr)
}
}

else if (G_pwr_reading_type != PWR_READING_TYPE_APSS)
{
memset((void*) &l_sensorHeader, 0, (size_t)sizeof(cmdh_poll_sensor_db_t));
memcpy ((void *) &(l_sensorHeader.eyecatcher[0]), SENSOR_POWR, 4);
l_sensorHeader.format = 0xA0;
l_sensorHeader.length = sizeof(cmdh_poll_power_no_apss_sensor_t);
l_sensorHeader.count = 1;

cmdh_poll_power_no_apss_sensor_t l_pwrData;
memset((void*) &l_pwrData, 0, (size_t)sizeof(cmdh_poll_power_no_apss_sensor_t));

// if there is a non-APSS chip for system power fill in system power else return 0's
if(G_pwr_reading_type != PWR_READING_TYPE_NONE)
{
l_pwrData.sys_pwr_id = G_amec_sensor_list[PWRSYS]->ipmi_sid;
l_pwrData.sys_pwr_update_time = G_mics_per_tick; // system power is read every tick
l_pwrData.sys_pwr_current = G_amec_sensor_list[PWRSYS]->sample;
l_pwrData.sys_pwr_update_tag = G_amec_sensor_list[PWRSYS]->update_tag;
l_pwrData.sys_pwr_accumul = G_amec_sensor_list[PWRSYS]->accumulator;
}

// Proc power is from AVS bus, return readings if reading Vdd and Vdn else return 0's
if( (G_avsbus_vdd_monitoring) && (G_avsbus_vdn_monitoring) )
{
// when no APSS present proc readings are updated based on AVS timing use PWRVDD/N timing (2 ticks)
l_pwrData.proc_pwr_update_time = G_mics_per_tick * 2;
l_pwrData.proc_pwr_current = G_amec_sensor_list[PWRPROC]->sample;
l_pwrData.proc_pwr_update_tag = G_amec_sensor_list[PWRPROC]->update_tag;
l_pwrData.proc_pwr_accumul = G_amec_sensor_list[PWRPROC]->accumulator;
l_pwrData.vdd_pwr_current = G_amec_sensor_list[PWRVDD]->sample;
l_pwrData.vdd_pwr_update_tag = G_amec_sensor_list[PWRVDD]->update_tag;
l_pwrData.vdd_pwr_accumul = G_amec_sensor_list[PWRVDD]->accumulator;
l_pwrData.vdn_pwr_current = G_amec_sensor_list[PWRVDN]->sample;
l_pwrData.vdn_pwr_update_tag = G_amec_sensor_list[PWRVDN]->update_tag;
l_pwrData.vdn_pwr_accumul = G_amec_sensor_list[PWRVDN]->accumulator;
}

// Copy header to response buffer.
memcpy ((void *) &(o_rsp_ptr->data[l_rsp_index]),
(void *)&l_sensorHeader, sizeof(l_sensorHeader));
// Increment index into response buffer.
l_rsp_index += sizeof(l_sensorHeader);

// Copy sensor data into response buffer.
memcpy ((void *) &(o_rsp_ptr->data[l_rsp_index]),
(void *)&(l_pwrData), sizeof(cmdh_poll_power_no_apss_sensor_t));
// Increment index into response buffer.
l_rsp_index += sizeof(cmdh_poll_power_no_apss_sensor_t);

l_poll_rsp->sensor_dblock_count +=1;
}

////////////////////////
// POWER CAPS:
// Generate datablock header for power caps. RETURNED by MASTER ONLY.
Expand All @@ -448,37 +517,40 @@ ERRL_RC cmdh_poll_v20(cmdh_fsp_rsp_t * o_rsp_ptr)
memcpy ((void *) &(l_sensorHeader.eyecatcher[0]), SENSOR_CAPS, 4);
l_sensorHeader.format = 0x03;
l_sensorHeader.length = sizeof(cmdh_poll_pcaps_sensor_t);

l_sensorHeader.count = 1;

cmdh_poll_pcaps_sensor_t l_pcapData;
l_pcapData.current = g_amec->pcap.active_node_pcap;
l_pcapData.system = G_amec_sensor_list[PWRSYS]->sample;
l_pcapData.n = G_sysConfigData.pcap.oversub_pcap;
l_pcapData.max = G_sysConfigData.pcap.max_pcap;
l_pcapData.hard_min = G_sysConfigData.pcap.hard_min_pcap;
l_pcapData.soft_min = G_sysConfigData.pcap.soft_min_pcap;
l_pcapData.user = G_sysConfigData.pcap.current_pcap;
l_pcapData.source = G_sysConfigData.pcap.source;
l_sensorHeader.count = 1;
memset((void*) &l_pcapData, 0, (size_t)sizeof(cmdh_poll_pcaps_sensor_t));

// Return 0's for power cap section if there is no system power reading
// OCC can't support power capping without knowing the system power
if(G_pwr_reading_type != PWR_READING_TYPE_NONE)
{
l_pcapData.current = g_amec->pcap.active_node_pcap;
l_pcapData.system = G_amec_sensor_list[PWRSYS]->sample;
l_pcapData.n = G_sysConfigData.pcap.oversub_pcap;
l_pcapData.max = G_sysConfigData.pcap.max_pcap;
l_pcapData.hard_min = G_sysConfigData.pcap.hard_min_pcap;
l_pcapData.soft_min = G_sysConfigData.pcap.soft_min_pcap;
l_pcapData.user = G_sysConfigData.pcap.current_pcap;
l_pcapData.source = G_sysConfigData.pcap.source;
}

// Copy header to response buffer.
memcpy ((void *) &(o_rsp_ptr->data[l_rsp_index]),
(void *)&l_sensorHeader, sizeof(l_sensorHeader));
// Increment index into response buffer.
l_rsp_index += sizeof(l_sensorHeader);

uint8_t l_sensordataSz = l_sensorHeader.count * l_sensorHeader.length;
// Copy sensor data into response buffer.
memcpy ((void *) &(o_rsp_ptr->data[l_rsp_index]),
(void *)&(l_pcapData), l_sensordataSz);
(void *)&(l_pcapData), sizeof(cmdh_poll_pcaps_sensor_t));
// Increment index into response buffer.
l_rsp_index += l_sensordataSz;
l_rsp_index += sizeof(cmdh_poll_pcaps_sensor_t);

l_poll_rsp->sensor_dblock_count +=1;

}


///////////////////
// EXTN Sensors:
// Generate datablock header for freq sensors and sensor data.
Expand Down
20 changes: 20 additions & 0 deletions src/occ_405/cmdh/cmdh_fsp_cmds.h
Expand Up @@ -202,6 +202,26 @@ typedef struct __attribute__ ((packed)) cmdh_poll_powr_sensor
uint16_t current; // Most recent 250us reading in watts.
} cmdh_poll_power_sensor_t;

typedef struct __attribute__ ((packed)) cmdh_poll_powr_no_apss_sensor
{
uint32_t sys_pwr_id; // Sensor id - to represent total system power.
uint16_t sys_pwr_update_time; // Time in us that system power is read
uint16_t sys_pwr_current; // Most recent system power reading in watts
uint32_t sys_pwr_update_tag; // Count of number of samples represented by sys pwr accumulator
uint64_t sys_pwr_accumul; // Accumulation of system power readings
uint32_t reserved;
uint16_t proc_pwr_update_time; // Time in us that processor power is updated
uint16_t proc_pwr_current; // Most recent processor power reading in watts
uint32_t proc_pwr_update_tag; // Count of number of samples represented by proc accumulator
uint64_t proc_pwr_accumul; // Accumulation of processor power readings
uint16_t vdd_pwr_current; // Most recent processor Vdd power reading in watts
uint32_t vdd_pwr_update_tag; // Count of number of samples represented by Vdd accumulator
uint64_t vdd_pwr_accumul; // Accumulation of processor Vdd power readings
uint16_t vdn_pwr_current; // Most recent processor Vdn power reading in watts
uint32_t vdn_pwr_update_tag; // Count of number of samples represented by Vdn accumulator
uint64_t vdn_pwr_accumul; // Accumulation of processor Vdn power readings
} cmdh_poll_power_no_apss_sensor_t;

// Only available from master occ.
typedef struct __attribute__ ((packed)) cmdh_poll_caps_sensor
{
Expand Down

0 comments on commit a635739

Please sign in to comment.