summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Cain <cjcain@us.ibm.com>2019-01-09 17:21:57 -0600
committerChristopher J. Cain <cjcain@us.ibm.com>2019-01-29 15:46:29 -0600
commitf7b1e2a3bcae240b8a9d47b7997f82367c11e1bd (patch)
tree020d3b0ca82037487b71a2868f26c0051df23c22
parentd03cb7413705fe805cb41d5bc259d825fc814e3d (diff)
downloadtalos-occ-f7b1e2a3bcae240b8a9d47b7997f82367c11e1bd.tar.gz
talos-occ-f7b1e2a3bcae240b8a9d47b7997f82367c11e1bd.zip
Add support for a second voltage sense from APSS
Change-Id: I8c356e2962c0e25c0335dc7af7dc79fc0702df60 RTC: 202003 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/70401 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Martha Broyles <mbroyles@us.ibm.com> Reviewed-by: William A. Bryan <wilbryan@us.ibm.com> Reviewed-by: Christopher J. Cain <cjcain@us.ibm.com>
-rwxr-xr-xsrc/occ_405/amec/amec_master_smh.c5
-rwxr-xr-xsrc/occ_405/amec/amec_sensors_power.c143
-rwxr-xr-xsrc/occ_405/cmdh/cmdh_fsp_cmds.c53
-rwxr-xr-xsrc/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c186
-rw-r--r--src/occ_405/occ_service_codes.h5
-rwxr-xr-xsrc/occ_405/occ_sys_config.c4
-rwxr-xr-xsrc/occ_405/occ_sys_config.h10
7 files changed, 335 insertions, 71 deletions
diff --git a/src/occ_405/amec/amec_master_smh.c b/src/occ_405/amec/amec_master_smh.c
index 33d6c13..df3e2cb 100755
--- a/src/occ_405/amec/amec_master_smh.c
+++ b/src/occ_405/amec/amec_master_smh.c
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER OnChipController Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -441,7 +441,8 @@ void amec_mst_check_under_pcap(void)
if((l_apss_func_id != ADC_RESERVED) &&
(l_apss_func_id != ADC_12V_SENSE) &&
(l_apss_func_id != ADC_GND_REMOTE_SENSE) &&
- (l_apss_func_id != ADC_12V_STANDBY_CURRENT) )
+ (l_apss_func_id != ADC_12V_STANDBY_CURRENT) &&
+ (l_apss_func_id != ADC_VOLT_SENSE_2))
{
l_trace[l_trace_idx] = (i << 24) | (l_apss_func_id << 16) | (AMECSENSOR_PTR(PWRAPSSCH0 + i)->sample);
l_trace_idx++;
diff --git a/src/occ_405/amec/amec_sensors_power.c b/src/occ_405/amec/amec_sensors_power.c
index bf13cb4..6ad3406 100755
--- a/src/occ_405/amec/amec_sensors_power.c
+++ b/src/occ_405/amec/amec_sensors_power.c
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER OnChipController Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -84,6 +84,10 @@ extern task_t G_task_table[TASK_END];
extern uint16_t G_configured_mbas;
extern uint8_t G_injected_epow_asserted;
+extern uint8_t G_gpu_volt_type[MAX_GPU_DOMAINS][MAX_NUM_GPU_PER_DOMAIN];
+
+#define GPU0_USING_VOLT2(proc, channel) ((channel == G_sysConfigData.apss_adc_map.gpu[proc][0]) && (G_gpu_volt_type[proc][0] == 2))
+#define GPU1_USING_VOLT2(proc, channel) ((channel == G_sysConfigData.apss_adc_map.gpu[proc][1]) && (G_gpu_volt_type[proc][1] == 2))
//*************************************************************************/
// Code
@@ -152,7 +156,7 @@ uint32_t amec_value_from_apss_adc(uint8_t i_chan)
* gain adjusted output: 1024mV * 10,000 mA/V = 10,240,000 (mV . mA)/V
* Reduced value: adjusted/1000 = 10,240 mA
*
- * Note that in the case of the remote ground and 12V sense the gain
+ * Note that in the case of the remote ground and voltage sense the gain
* values are in V/V so the returned value is actually in mVs.
*
* Max returnable value is 4,294,967,295 mA or approx. 4.3 MA
@@ -193,6 +197,7 @@ uint32_t amec_value_from_apss_adc(uint8_t i_chan)
#define ADCMULT_TO_UNITS 1000000
#define ADCMULT_ROUND ADCMULT_TO_UNITS/2
+#define ROUND_POWER(value) ((((uint64_t)value) + ADCMULT_ROUND) / ADCMULT_TO_UNITS)
// Function Specification
//
// Name: amec_update_apss_sensors
@@ -218,7 +223,6 @@ bool amec_update_apss_sensors(void)
uint8_t l_proc = G_pbax_id.chip_id;
uint32_t temp32 = 0;
uint8_t l_idx = 0;
- uint32_t l_bulk_current_sum = 0;
// Check GPIO_EPOW. Skip everything if asserted
if (epow_gpio_asserted())
@@ -233,25 +237,22 @@ bool amec_update_apss_sensors(void)
for (l_idx = 0; l_idx < MAX_APSS_ADC_CHANNELS; l_idx++)
{
// These values returned are gain adjusted. The APSS readings for
- // the remote ground and 12V sense are returned in mVs, all other
+ // the remote ground and voltage sense are returned in mVs, all other
// readings are treated as mAs.
G_lastValidAdcValue[l_idx] = amec_value_from_apss_adc(l_idx);
-
- // Add up all channels now, we will subtract ones later that don't
- // count towards the system power
- l_bulk_current_sum += G_lastValidAdcValue[l_idx];
}
// --------------------------------------------------------------
- // Convert 12Vsense into interim value - this has to happen first
+ // Convert voltages into interim value - this has to happen first
// --------------------------------------------------------------
// Calculations involving bulk_voltage must be 64bit so final result
// does not get truncated (before dividing by ADCMULT_TO_UNITS)
uint64_t l_bulk_voltage = ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.sense_12v);
+ uint64_t l_bulk_voltage_2 = ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.sense_volt2);
if (OCC_MASTER == G_occ_role)
{
- // Update channel sensors for all channels (except 12v sense and gnd)
+ // Update channel sensors for all channels (except voltage sense and gnd)
for (l_idx = 0; l_idx < MAX_APSS_ADC_CHANNELS; l_idx++)
{
if(l_idx == G_sysConfigData.apss_adc_map.current_12v_stby)
@@ -261,9 +262,18 @@ bool amec_update_apss_sensors(void)
sensor_update(AMECSENSOR_PTR(CUR12VSTBY), (uint16_t) temp32);
}
else if((l_idx != G_sysConfigData.apss_adc_map.sense_12v) &&
+ (l_idx != G_sysConfigData.apss_adc_map.sense_volt2) &&
(l_idx != G_sysConfigData.apss_adc_map.remote_gnd))
{
- temp32 = ((ADC_CONVERTED_VALUE(l_idx) * l_bulk_voltage)+ADCMULT_ROUND)/ADCMULT_TO_UNITS;
+ uint64_t l_bulk_v = l_bulk_voltage;
+ if ( GPU0_USING_VOLT2(0, l_idx) || GPU1_USING_VOLT2(0, l_idx) ||
+ GPU0_USING_VOLT2(1, l_idx) || GPU1_USING_VOLT2(1, l_idx) ||
+ (l_idx == G_sysConfigData.apss_adc_map.total_current_volt2) )
+ {
+ // Channel is using Voltge 2
+ l_bulk_v = l_bulk_voltage_2;
+ }
+ temp32 = ROUND_POWER(ADC_CONVERTED_VALUE(l_idx) * l_bulk_v);
sensor_update(AMECSENSOR_PTR(PWRAPSSCH0 + l_idx), (uint16_t) temp32);
}
}
@@ -291,7 +301,7 @@ bool amec_update_apss_sensors(void)
{
uint32_t l_vdd = ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.vdd[l_proc]);
uint32_t l_vcs_vio_vpcie = ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.vcs_vio_vpcie[l_proc]);
- temp32 = ((l_vcs_vio_vpcie + l_vdd) * l_bulk_voltage)/ADCMULT_TO_UNITS;
+ temp32 = ROUND_POWER((l_vcs_vio_vpcie + l_vdd) * l_bulk_voltage);
sensor_update(AMECSENSOR_PTR(PWRPROC), (uint16_t) temp32);
}
@@ -300,7 +310,7 @@ bool amec_update_apss_sensors(void)
{
uint32_t l_vd = ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.vdd[l_idx]);
uint32_t l_vpcie = ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.vcs_vio_vpcie[l_idx]);
- g_amec->proc_snr_pwr[l_idx] = ((l_vpcie + l_vd) * l_bulk_voltage)/ADCMULT_TO_UNITS;
+ g_amec->proc_snr_pwr[l_idx] = ROUND_POWER((l_vpcie + l_vd) * l_bulk_voltage);
}
// All readings from APSS come back as milliUnits, so if we want
@@ -317,14 +327,14 @@ bool amec_update_apss_sensors(void)
// Fans: Add up all Fan channels
temp32 = ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.fans[0]);
temp32 += ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.fans[1]);
- temp32 = ((temp32 * l_bulk_voltage)+ADCMULT_ROUND)/ADCMULT_TO_UNITS;
+ temp32 = ROUND_POWER(temp32 * l_bulk_voltage);
sensor_update( AMECSENSOR_PTR(PWRFAN), (uint16_t)temp32);
// I/O: Add up all I/O channels
temp32 = ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.io[0]);
temp32 += ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.io[1]);
temp32 += ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.io[2]);
- temp32 = ((temp32 * l_bulk_voltage)+ADCMULT_ROUND)/ADCMULT_TO_UNITS;
+ temp32 = ROUND_POWER(temp32 * l_bulk_voltage);
sensor_update( AMECSENSOR_PTR(PWRIO), (uint16_t)temp32);
// Memory: Add up all channels for the same processor.
@@ -337,7 +347,7 @@ bool amec_update_apss_sensors(void)
{
temp32 += ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.mem_cache);
}
- temp32 = ((temp32 * l_bulk_voltage)+ADCMULT_ROUND)/ADCMULT_TO_UNITS;
+ temp32 = ROUND_POWER(temp32 * l_bulk_voltage);
sensor_update( AMECSENSOR_PTR(PWRMEM), (uint16_t)temp32);
// Save off the combined power from all memory
@@ -347,46 +357,103 @@ bool amec_update_apss_sensors(void)
l_temp += ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.memory[l_idx][1]);
l_temp += ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.memory[l_idx][2]);
l_temp += ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.memory[l_idx][3]);
- g_amec->mem_snr_pwr[l_idx] = ((l_temp * l_bulk_voltage)+ADCMULT_ROUND)/ADCMULT_TO_UNITS;
+ g_amec->mem_snr_pwr[l_idx] = ROUND_POWER(l_temp * l_bulk_voltage);
}
// Storage/Media
temp32 = ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.storage_media[0]);
temp32 += ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.storage_media[1]);
- temp32 = ((temp32 * l_bulk_voltage)+ADCMULT_ROUND)/ADCMULT_TO_UNITS;
+ temp32 = ROUND_POWER(temp32 * l_bulk_voltage);
sensor_update( AMECSENSOR_PTR(PWRSTORE), (uint16_t)temp32);
// Save total GPU adapter for this proc
if (l_proc < MAX_GPU_DOMAINS)
{
- temp32 = ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.gpu[l_proc][0]);
- temp32 += ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.gpu[l_proc][1]);
- temp32 += ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.gpu[l_proc][2]);
- temp32 = ((temp32 * l_bulk_voltage)+ADCMULT_ROUND)/ADCMULT_TO_UNITS;
+ // GPU0
+ uint64_t l_bulk_v = l_bulk_voltage;
+ if (G_gpu_volt_type[l_proc][0] == 2)
+ {
+ l_bulk_v = l_bulk_voltage_2;
+ }
+ temp32 = l_bulk_v * ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.gpu[l_proc][0]);
+ // GPU1
+ if (G_gpu_volt_type[l_proc][1] == 2)
+ {
+ l_bulk_v = l_bulk_voltage_2;
+ }
+ else
+ {
+ l_bulk_v = l_bulk_voltage;
+ }
+ temp32 += l_bulk_v * ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.gpu[l_proc][1]);
+ // GPU2
+ temp32 += l_bulk_voltage * ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.gpu[l_proc][2]);
+ temp32 = ROUND_POWER(temp32);
sensor_update( AMECSENSOR_PTR(PWRGPU), (uint16_t)temp32);
}
// ----------------------------------------------------
// Convert Raw Bulk Power from APSS into sensors
// ----------------------------------------------------
- // We don't get this adc channel in some systems, we have to add it manually.
- // With valid sysconfig data the code here should automatically use what
- // is provided by the APSS if it is available, or manually sum it up if not.
- temp32 = ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.total_current_12v);
- temp32 = ((temp32 * l_bulk_voltage)+ADCMULT_ROUND)/ADCMULT_TO_UNITS;
-
- // To calculated the total 12V current based on a sum of all ADC channels,
- // Subract adc channels that don't measure power
- l_bulk_current_sum -= ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.sense_12v);
- l_bulk_current_sum -= ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.remote_gnd);
- l_bulk_current_sum -= ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.current_12v_stby);
-
- // If we don't have a ADC channel that measures the bulk 12v power, use
- // the ADC sum instead
- if(0 == temp32)
+ // Not all systems provide a total system current/power, in which case it must be calculated.
+ temp32 = 0;
+ const uint32_t syspwr_volt1 = l_bulk_voltage * ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.total_current_12v);
+ const uint32_t syspwr_volt2 = l_bulk_voltage_2 * ADC_CONVERTED_VALUE(G_sysConfigData.apss_adc_map.total_current_volt2);
+ if(0 != syspwr_volt1)
+ {
+ // Total System Power (voltage 1 (12V)) was provided, use directly
+ temp32 = syspwr_volt1;
+ if (0 != syspwr_volt2)
+ {
+ // Total System Power (voltage 2) was provided, use directly
+ temp32 += syspwr_volt2;
+ }
+ else
+ {
+ // No Total System Power (voltage 2) - Add powers for GPUs using voltage 2
+ for (l_idx = 0; l_idx < MAX_APSS_ADC_CHANNELS; l_idx++)
+ {
+ if ( GPU0_USING_VOLT2(0, l_idx) || GPU1_USING_VOLT2(0, l_idx) ||
+ GPU0_USING_VOLT2(1, l_idx) || GPU1_USING_VOLT2(1, l_idx) )
+ {
+ temp32 += l_bulk_voltage_2 * G_lastValidAdcValue[l_idx];
+ }
+ }
+ }
+ }
+ else
{
- temp32 = ((l_bulk_current_sum * l_bulk_voltage)+ADCMULT_ROUND)/ADCMULT_TO_UNITS;
+ // No Total System Power (voltage 1 (12V)) - Add powers for channels using voltage 1
+ for (l_idx = 0; l_idx < MAX_APSS_ADC_CHANNELS; l_idx++)
+ {
+ if ( (0 != syspwr_volt2) &&
+ ( GPU0_USING_VOLT2(0, l_idx) || GPU1_USING_VOLT2(0, l_idx) ||
+ GPU0_USING_VOLT2(1, l_idx) || GPU1_USING_VOLT2(1, l_idx) ) )
+ {
+ // Total System Power (voltage 2) was provided, so skip GPU channels using voltage 2
+ continue;
+ }
+
+ uint64_t l_bulk_v = l_bulk_voltage;
+ if ( GPU0_USING_VOLT2(0, l_idx) || GPU1_USING_VOLT2(0, l_idx) ||
+ GPU0_USING_VOLT2(1, l_idx) || GPU1_USING_VOLT2(1, l_idx) ||
+ (l_idx == G_sysConfigData.apss_adc_map.total_current_volt2) )
+ {
+ // GPU (or total current) is using voltage 2
+ l_bulk_v = l_bulk_voltage_2;
+ }
+
+ if ((l_idx != G_sysConfigData.apss_adc_map.sense_12v) &&
+ (l_idx != G_sysConfigData.apss_adc_map.remote_gnd) &&
+ (l_idx != G_sysConfigData.apss_adc_map.current_12v_stby) &&
+ (l_idx != G_sysConfigData.apss_adc_map.sense_volt2))
+ {
+ // Add power for this channel
+ temp32 += l_bulk_v * G_lastValidAdcValue[l_idx];
+ }
+ }
}
+ temp32 = ROUND_POWER(temp32);
sensor_update(AMECSENSOR_PTR(PWRSYS), (uint16_t)temp32);
// Calculate average frequency of all OCCs.
diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds.c b/src/occ_405/cmdh/cmdh_fsp_cmds.c
index 47cb457..042e71b 100755
--- a/src/occ_405/cmdh/cmdh_fsp_cmds.c
+++ b/src/occ_405/cmdh/cmdh_fsp_cmds.c
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER OnChipController Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -559,26 +559,45 @@ ERRL_RC cmdh_poll_v20(cmdh_fsp_rsp_t * o_rsp_ptr)
cmdh_poll_power_sensor_t l_pwrSensorList[MAX_APSS_ADC_CHANNELS];
for (k = 0; k < MAX_APSS_ADC_CHANNELS; k++)
{
- if ((G_apss_ch_to_function[k] != ADC_12V_SENSE) &&
- (G_apss_ch_to_function[k] != ADC_GND_REMOTE_SENSE) &&
- (G_apss_ch_to_function[k] != ADC_12V_STANDBY_CURRENT))
+ const uint8_t function_id = G_apss_ch_to_function[k];
+ if ((function_id != ADC_12V_SENSE) &&
+ (function_id != ADC_GND_REMOTE_SENSE) &&
+ (function_id != ADC_12V_STANDBY_CURRENT) &&
+ (function_id != ADC_VOLT_SENSE_2))
{
// only return channel power for GPU if the GPU is present
- if( ( (G_apss_ch_to_function[k] != ADC_GPU_0_0) &&
- (G_apss_ch_to_function[k] != ADC_GPU_0_1) &&
- (G_apss_ch_to_function[k] != ADC_GPU_0_2) &&
- (G_apss_ch_to_function[k] != ADC_GPU_1_0) &&
- (G_apss_ch_to_function[k] != ADC_GPU_1_1) &&
- (G_apss_ch_to_function[k] != ADC_GPU_1_2) ) ||
- ( (G_apss_ch_to_function[k] == ADC_GPU_0_0) && (G_first_sys_gpu_config & 0x01) ) ||
- ( (G_apss_ch_to_function[k] == ADC_GPU_0_1) && (G_first_sys_gpu_config & 0x02) ) ||
- ( (G_apss_ch_to_function[k] == ADC_GPU_0_2) && (G_first_sys_gpu_config & 0x04) ) ||
- ( (G_apss_ch_to_function[k] == ADC_GPU_1_0) && (G_first_sys_gpu_config & 0x08) ) ||
- ( (G_apss_ch_to_function[k] == ADC_GPU_1_1) && (G_first_sys_gpu_config & 0x10) ) ||
- ( (G_apss_ch_to_function[k] == ADC_GPU_1_2) && (G_first_sys_gpu_config & 0x20) ) )
+ bool include = FALSE;
+ if ( (function_id == ADC_GPU_0_0) ||
+ ((function_id >= ADC_GPU_0_1) && (function_id <= ADC_GPU_VOLT2_1_1)) )
+ {
+ // GPU channel: include if has a non-zero reading or if GPU is present
+ if ( ( G_amec_sensor_list[PWRAPSSCH0 + k]->sample > 0) ||
+ ( ((ADC_GPU_0_0 == function_id) || (ADC_GPU_VOLT2_0_0 == function_id)) &&
+ (G_first_sys_gpu_config & 0x01) ) ||
+ ( ((ADC_GPU_0_1 == function_id) || (ADC_GPU_VOLT2_0_1 == function_id)) &&
+ (G_first_sys_gpu_config & 0x02) ) ||
+ ( ( ADC_GPU_0_2 == function_id) &&
+ (G_first_sys_gpu_config & 0x04) ) ||
+ ( ((ADC_GPU_1_0 == function_id) || (ADC_GPU_VOLT2_1_0 == function_id)) &&
+ (G_first_sys_gpu_config & 0x08) ) ||
+ ( ((ADC_GPU_1_1 == function_id) || (ADC_GPU_VOLT2_1_1 == function_id)) &&
+ (G_first_sys_gpu_config & 0x10) ) ||
+ ( ( ADC_GPU_1_2 == function_id) &&
+ (G_first_sys_gpu_config & 0x20) ) )
+ {
+ // GPU is present
+ include = TRUE;
+ }
+ }
+ else
+ {
+ // non-GPU channel
+ include = TRUE;
+ }
+ if (include)
{
l_pwrSensorList[l_sensorHeader.count].id = G_amec_sensor_list[PWRAPSSCH0 + k]->ipmi_sid;
- l_pwrSensorList[l_sensorHeader.count].function_id = G_apss_ch_to_function[k];
+ l_pwrSensorList[l_sensorHeader.count].function_id = function_id;
l_pwrSensorList[l_sensorHeader.count].apss_channel = k;
l_pwrSensorList[l_sensorHeader.count].reserved = 0;
l_pwrSensorList[l_sensorHeader.count].current = G_amec_sensor_list[PWRAPSSCH0 + k]->sample;
diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c
index 920b88e..23f9b29 100755
--- a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c
+++ b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER OnChipController Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -113,6 +113,10 @@ cmdh_ips_config_data_t G_ips_config_data = {0};
bool G_mem_monitoring_allowed = FALSE;
+// Save which voltage the GPU is using (1 = default (12V), 2 = 2nd voltage (54V))
+uint8_t G_gpu_volt_type[MAX_GPU_DOMAINS][MAX_NUM_GPU_PER_DOMAIN] = {{0}};
+bool G_found_volt2 = FALSE;
+
// Will get set when receiving APSS config data
PWR_READING_TYPE G_pwr_reading_type = PWR_READING_TYPE_NONE;
@@ -545,6 +549,7 @@ errlHndl_t data_store_freq_data(const cmdh_fsp_cmd_t * i_cmd_ptr,
errlHndl_t apss_store_adc_channel(const eApssAdcChannelAssignments i_func_id, const uint8_t i_channel_num )
{
errlHndl_t l_err = NULL;
+ bool l_gpu_volt_conflict = FALSE;
// Check function ID and channel number
if ( (i_func_id >= NUM_ADC_ASSIGNMENT_TYPES) ||
@@ -635,6 +640,10 @@ errlHndl_t apss_store_adc_channel(const eApssAdcChannelAssignments i_func_id, co
l_adc_function = &G_sysConfigData.apss_adc_map.sense_12v;
break;
+ case ADC_VOLT_SENSE_2:
+ l_adc_function = &G_sysConfigData.apss_adc_map.sense_volt2;
+ break;
+
case ADC_GND_REMOTE_SENSE:
l_adc_function = &G_sysConfigData.apss_adc_map.remote_gnd;
break;
@@ -643,6 +652,10 @@ errlHndl_t apss_store_adc_channel(const eApssAdcChannelAssignments i_func_id, co
l_adc_function = &G_sysConfigData.apss_adc_map.total_current_12v;
break;
+ case ADC_TOTAL_SYS_CURRENT_2:
+ l_adc_function = &G_sysConfigData.apss_adc_map.total_current_volt2;
+ break;
+
case ADC_MEM_CACHE:
l_adc_function = &G_sysConfigData.apss_adc_map.mem_cache;
break;
@@ -652,11 +665,27 @@ errlHndl_t apss_store_adc_channel(const eApssAdcChannelAssignments i_func_id, co
break;
case ADC_GPU_0_0:
- l_adc_function = &G_sysConfigData.apss_adc_map.gpu[0][0];
+ if (G_gpu_volt_type[0][0] != 2)
+ {
+ G_gpu_volt_type[0][0] = 1;
+ l_adc_function = &G_sysConfigData.apss_adc_map.gpu[0][0];
+ }
+ else
+ {
+ l_gpu_volt_conflict = TRUE;
+ }
break;
case ADC_GPU_0_1:
- l_adc_function = &G_sysConfigData.apss_adc_map.gpu[0][1];
+ if (G_gpu_volt_type[0][1] != 2)
+ {
+ G_gpu_volt_type[0][1] = 1;
+ l_adc_function = &G_sysConfigData.apss_adc_map.gpu[0][1];
+ }
+ else
+ {
+ l_gpu_volt_conflict = TRUE;
+ }
break;
case ADC_GPU_0_2:
@@ -664,17 +693,85 @@ errlHndl_t apss_store_adc_channel(const eApssAdcChannelAssignments i_func_id, co
break;
case ADC_GPU_1_0:
- l_adc_function = &G_sysConfigData.apss_adc_map.gpu[1][0];
+ if (G_gpu_volt_type[1][0] != 2)
+ {
+ G_gpu_volt_type[1][0] = 1;
+ l_adc_function = &G_sysConfigData.apss_adc_map.gpu[1][0];
+ }
+ else
+ {
+ l_gpu_volt_conflict = TRUE;
+ }
break;
case ADC_GPU_1_1:
- l_adc_function = &G_sysConfigData.apss_adc_map.gpu[1][1];
+ if (G_gpu_volt_type[1][1] != 2)
+ {
+ G_gpu_volt_type[1][1] = 1;
+ l_adc_function = &G_sysConfigData.apss_adc_map.gpu[1][1];
+ }
+ else
+ {
+ l_gpu_volt_conflict = TRUE;
+ }
break;
case ADC_GPU_1_2:
l_adc_function = &G_sysConfigData.apss_adc_map.gpu[1][2];
break;
+ case ADC_GPU_VOLT2_0_0:
+ if (G_gpu_volt_type[0][0] != 1)
+ {
+ G_found_volt2 = TRUE;
+ G_gpu_volt_type[0][0] = 2;
+ l_adc_function = &G_sysConfigData.apss_adc_map.gpu[0][0];
+ }
+ else
+ {
+ l_gpu_volt_conflict = TRUE;
+ }
+ break;
+
+ case ADC_GPU_VOLT2_0_1:
+ if (G_gpu_volt_type[0][1] != 1)
+ {
+ G_found_volt2 = TRUE;
+ G_gpu_volt_type[0][1] = 2;
+ l_adc_function = &G_sysConfigData.apss_adc_map.gpu[0][1];
+ }
+ else
+ {
+ l_gpu_volt_conflict = TRUE;
+ }
+ break;
+
+ case ADC_GPU_VOLT2_1_0:
+ if (G_gpu_volt_type[1][0] != 1)
+ {
+ G_found_volt2 = TRUE;
+ G_gpu_volt_type[1][0] = 2;
+ l_adc_function = &G_sysConfigData.apss_adc_map.gpu[1][0];
+ }
+ else
+ {
+ l_gpu_volt_conflict = TRUE;
+ }
+ break;
+
+ case ADC_GPU_VOLT2_1_1:
+ if (G_gpu_volt_type[1][1] != 1)
+ {
+ G_found_volt2 = TRUE;
+ G_gpu_volt_type[1][1] = 2;
+ l_adc_function = &G_sysConfigData.apss_adc_map.gpu[1][1];
+ }
+ else
+ {
+ l_gpu_volt_conflict = TRUE;
+ }
+ break;
+
default:
// It should never happen
CMDH_TRAC_ERR("apss_store_adc_channel: Invalid function ID: 0x%x", i_func_id);
@@ -693,7 +790,6 @@ errlHndl_t apss_store_adc_channel(const eApssAdcChannelAssignments i_func_id, co
}
else
{
-
CMDH_TRAC_ERR("apss_store_adc_channel: Function ID is duplicated (id:0x%x, channel:%d)", i_func_id, i_channel_num);
/* @
@@ -721,6 +817,33 @@ errlHndl_t apss_store_adc_channel(const eApssAdcChannelAssignments i_func_id, co
ERRL_CALLOUT_PRIORITY_HIGH);
}
}
+ else if (l_gpu_volt_conflict)
+ {
+ CMDH_TRAC_ERR("apss_store_adc_channel: GPU has conflicting voltage function ids (0x%02X)", i_func_id);
+ /* @
+ * @errortype
+ * @moduleid DATA_STORE_APSS_DATA
+ * @reasoncode INVALID_INPUT_DATA
+ * @userdata1 function ID
+ * @userdata2 channel number
+ * @userdata4 ERC_APSS_GPU_VOLTAGE_CONFLICT
+ * @devdesc Function ID conflict for GPU voltage
+ */
+ l_err = createErrl(DATA_STORE_APSS_DATA,
+ INVALID_INPUT_DATA,
+ ERC_APSS_GPU_VOLTAGE_CONFLICT,
+ ERRL_SEV_UNRECOVERABLE,
+ NULL,
+ DEFAULT_TRACE_SIZE,
+ (uint32_t)i_func_id,
+ (uint32_t)i_channel_num);
+
+ // Callout firmware
+ addCalloutToErrl(l_err,
+ ERRL_CALLOUT_TYPE_COMPONENT_ID,
+ ERRL_COMPONENT_ID_FIRMWARE,
+ ERRL_CALLOUT_PRIORITY_HIGH);
+ }
}
return l_err;
@@ -780,6 +903,7 @@ void apss_store_ipmi_sensor_id(const uint16_t i_channel, const apss_cfg_adc_v20_
break;
case ADC_12V_SENSE:
+ case ADC_VOLT_SENSE_2:
//None
break;
@@ -788,6 +912,7 @@ void apss_store_ipmi_sensor_id(const uint16_t i_channel, const apss_cfg_adc_v20_
break;
case ADC_TOTAL_SYS_CURRENT:
+ case ADC_TOTAL_SYS_CURRENT_2:
//None
break;
@@ -802,6 +927,8 @@ void apss_store_ipmi_sensor_id(const uint16_t i_channel, const apss_cfg_adc_v20_
case ADC_GPU_0_0:
case ADC_GPU_0_1:
case ADC_GPU_0_2:
+ case ADC_GPU_VOLT2_0_0:
+ case ADC_GPU_VOLT2_0_1:
if((i_adc->ipmisensorId != 0) && (l_proc == 0))
{
AMECSENSOR_PTR(PWRGPU)->ipmi_sid = i_adc->ipmisensorId;
@@ -811,6 +938,8 @@ void apss_store_ipmi_sensor_id(const uint16_t i_channel, const apss_cfg_adc_v20_
case ADC_GPU_1_0:
case ADC_GPU_1_1:
case ADC_GPU_1_2:
+ case ADC_GPU_VOLT2_1_0:
+ case ADC_GPU_VOLT2_1_1:
if((i_adc->ipmisensorId != 0) && (l_proc == 1))
{
AMECSENSOR_PTR(PWRGPU)->ipmi_sid = i_adc->ipmisensorId;
@@ -833,9 +962,11 @@ void apss_store_ipmi_sensor_id(const uint16_t i_channel, const apss_cfg_adc_v20_
//no sensor IDs to be reported in the poll command.
}
- //Only store sensor ids for power sensors. 12V sensor and gnd remote sensors do not report power used.
- if ((i_adc->assignment != ADC_12V_SENSE) && (i_adc->assignment != ADC_GND_REMOTE_SENSE) &&
- (i_adc->assignment != ADC_12V_STANDBY_CURRENT))
+ //Only store sensor ids for power sensors. voltage and gnd remote sensors do not report power used.
+ if ((i_adc->assignment != ADC_12V_SENSE) &&
+ (i_adc->assignment != ADC_GND_REMOTE_SENSE) &&
+ (i_adc->assignment != ADC_12V_STANDBY_CURRENT) &&
+ (i_adc->assignment != ADC_VOLT_SENSE_2))
{
AMECSENSOR_PTR(PWRAPSSCH0 + i_channel)->ipmi_sid = i_adc->ipmisensorId;
CNFG_DBG("apss_store_ipmi_sensor_id: SID[0x%08X] stored as 0x%08X for channel %d",
@@ -1027,6 +1158,7 @@ errlHndl_t data_store_apss_config_v20(const cmdh_apss_config_v20_t * i_cmd_ptr,
G_pwr_reading_type = PWR_READING_TYPE_NONE;
}
+ bool l_found_volt2_sense = FALSE;
for(l_channel=0;(l_channel < l_num_channels) && (NULL == l_err);l_channel++)
{
G_sysConfigData.apss_cal[l_channel].gnd_select = i_cmd_ptr->adc[l_channel].gnd_select;
@@ -1037,6 +1169,11 @@ errlHndl_t data_store_apss_config_v20(const cmdh_apss_config_v20_t * i_cmd_ptr,
l_err = apss_store_adc_channel(i_cmd_ptr->adc[l_channel].assignment, l_channel);
if (l_err == NULL)
{
+ if (i_cmd_ptr->adc[l_channel].assignment == ADC_VOLT_SENSE_2)
+ {
+ l_found_volt2_sense = TRUE;
+ }
+
//Write sensor IDs to the appropriate powr sensors.
apss_store_ipmi_sensor_id(l_channel, &(i_cmd_ptr->adc[l_channel]));
@@ -1054,6 +1191,31 @@ errlHndl_t data_store_apss_config_v20(const cmdh_apss_config_v20_t * i_cmd_ptr,
G_sysConfigData.apss_cal[l_channel].offset);
}
+ if ((NULL == l_err) && G_found_volt2 && (!l_found_volt2_sense))
+ {
+ CMDH_TRAC_ERR("data_store_apss_config_v20: Found GPU using 2nd voltage but no ADC_VOLT_SENSE_2 supplied");
+ /* @
+ * @errortype
+ * @moduleid DATA_STORE_APSS_DATA
+ * @reasoncode INVALID_INPUT_DATA
+ * @userdata4 ERC_APSS_MISSING_ADC_VOLT_SENSE_2
+ * @devdesc ADC_VOLT_SENSE_2 was not provided
+ */
+ l_err = createErrl(DATA_STORE_APSS_DATA,
+ INVALID_INPUT_DATA,
+ ERC_APSS_MISSING_ADC_VOLT_SENSE_2,
+ ERRL_SEV_UNRECOVERABLE,
+ NULL,
+ DEFAULT_TRACE_SIZE,
+ 0,
+ 0);
+ // Callout firmware
+ addCalloutToErrl(l_err,
+ ERRL_CALLOUT_TYPE_COMPONENT_ID,
+ ERRL_COMPONENT_ID_FIRMWARE,
+ ERRL_CALLOUT_PRIORITY_HIGH);
+ }
+
if( (NULL == l_err) && (G_pwr_reading_type == PWR_READING_TYPE_APSS) ) // only APSS has GPIO config
{
@@ -1094,9 +1256,11 @@ errlHndl_t data_store_apss_config(const cmdh_fsp_cmd_t * i_cmd_ptr,
uint32_t l_v20_data_sz = sizeof(cmdh_apss_config_v20_t) - sizeof(cmdh_fsp_cmd_header_t);
- // Set to default value
+ // Set to default values
memset(&G_sysConfigData.apss_adc_map, SYSCFG_INVALID_ADC_CHAN, sizeof(G_sysConfigData.apss_adc_map));
memset(&G_sysConfigData.apss_gpio_map, SYSCFG_INVALID_PIN, sizeof(G_sysConfigData.apss_gpio_map));
+ memset(G_gpu_volt_type, 0, sizeof(G_gpu_volt_type));
+ G_found_volt2 = FALSE;
// only version 0x20 supported and data length must be at least 4
if( (l_cmd_ptr->version != DATA_APSS_VERSION20) || (l_data_length < 4))
@@ -1126,7 +1290,7 @@ errlHndl_t data_store_apss_config(const cmdh_fsp_cmd_t * i_cmd_ptr,
if(l_invalid_data)
{
G_pwr_reading_type = PWR_READING_TYPE_NONE;
- CMDH_TRAC_ERR("data_store_apss_config: Invalid System Data packet. Given Version:0x%02X length:0x%04X",
+ CMDH_TRAC_ERR("data_store_apss_config: Invalid APSS Config Data packet. Given Version:0x%02X length:0x%04X",
l_cmd_ptr->version, l_data_length);
/* @
diff --git a/src/occ_405/occ_service_codes.h b/src/occ_405/occ_service_codes.h
index 59e7ce9..d54244e 100644
--- a/src/occ_405/occ_service_codes.h
+++ b/src/occ_405/occ_service_codes.h
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER OnChipController Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -202,6 +202,9 @@ enum occExtReasonCode
ERC_AMEC_CENT_TEMP_TIMEOUT = 0x0032,
ERC_AMEC_GPE1_TIMEOUT = 0x0033,
+ ERC_APSS_MISSING_ADC_VOLT_SENSE_2 = 0x0038,
+ ERC_APSS_GPU_VOLTAGE_CONFLICT = 0x0039,
+
ERC_CMDH_MBOX_REQST_FAILURE = 0x0040,
ERC_CMDH_INTERNAL_FAILURE = 0x0041,
ERC_CMDH_THRM_DATA_MISSING = 0x0042,
diff --git a/src/occ_405/occ_sys_config.c b/src/occ_405/occ_sys_config.c
index 7255246..9b11da3 100755
--- a/src/occ_405/occ_sys_config.c
+++ b/src/occ_405/occ_sys_config.c
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER OnChipController Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -152,6 +152,8 @@ occSysConfigData_t G_sysConfigData =
.gpu[1][0] = SYSCFG_INVALID_ADC_CHAN,
.gpu[1][1] = SYSCFG_INVALID_ADC_CHAN,
.gpu[1][2] = SYSCFG_INVALID_ADC_CHAN,
+ .sense_volt2 = SYSCFG_INVALID_ADC_CHAN,
+ .total_current_volt2 = SYSCFG_INVALID_ADC_CHAN,
},
.apssGpioPortsMode = {0, 0},
diff --git a/src/occ_405/occ_sys_config.h b/src/occ_405/occ_sys_config.h
index 0b16aa5..33ea0be 100755
--- a/src/occ_405/occ_sys_config.h
+++ b/src/occ_405/occ_sys_config.h
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER OnChipController Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -148,6 +148,12 @@ typedef enum
ADC_GPU_1_0 = 0x1F,
ADC_GPU_1_1 = 0x20,
ADC_GPU_1_2 = 0x21,
+ ADC_GPU_VOLT2_0_0 = 0x22,
+ ADC_GPU_VOLT2_0_1 = 0x23,
+ ADC_GPU_VOLT2_1_0 = 0x24,
+ ADC_GPU_VOLT2_1_1 = 0x25,
+ ADC_VOLT_SENSE_2 = 0x26,
+ ADC_TOTAL_SYS_CURRENT_2 = 0x27,
NUM_ADC_ASSIGNMENT_TYPES // This should always be the last member
} eApssAdcChannelAssignments;
@@ -225,6 +231,8 @@ typedef struct
uint8_t mem_cache;
uint8_t current_12v_stby;
uint8_t gpu[MAX_GPU_DOMAINS][MAX_NUM_GPU_PER_DOMAIN];
+ uint8_t sense_volt2;
+ uint8_t total_current_volt2;
} apssAdcChannelData_t;
typedef struct
OpenPOWER on IntegriCloud