Skip to content

Commit 360934d

Browse files
committed
Pstates Support in OCC
1. Initialize Pstates global parameters (G_proc_fmax, G_proc_fmin, G_khz_per_pstate and G_proc_pmin from the OCC Pstate Parameter Block) 2. When frequency config data packet is received and OCC is NOT already in Active state: Send IPC command to PGPE to set pState clips to be wide open from min frequency to turbo First verify min/max frequency from TMGT is within what PGPE allows saved in G_proc_fmax and G_proc_fmin if not within bounds trace and clip to G_proc_fmax/fmin) 3. Transition to active state: Send IPC command to PGPE to start pState protocol (give correct data for OCC vs OPAL in control of Pstates) and if OPAL system update OPAL shared memory with Pstate information. 4. amec_slv_freq_smh(): Send IPC command to PGPE to set requested pState (PowerVM) or set clips (OPAL). 5. Address all the TODO/TEMP/#if 0 in amec_freq.c either remove or add RTC# for when it will be addressed Change-Id: Ic323321b8c66945732a6b7345ad85d6f41a62edd RTC: 130201 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/33704 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Martha Broyles <mbroyles@us.ibm.com> Reviewed-by: Andres A. Lugo-Reyes <aalugore@us.ibm.com> Reviewed-by: Wael El-Essawy <welessa@us.ibm.com>
1 parent c35e73b commit 360934d

31 files changed

+1843
-468
lines changed

src/common/ipc_func_ids.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,12 @@ IPC_FUNCIDS_TABLE_START
7373
//Functions that are only supported by GPE2 should be defined here
7474
//These function ID's can only be sent to GPE2 (PGPE)
7575
IPC_FUNCIDS_ST_START(OCCHW_INST_ID_GPE2)
76-
IPC_FUNC_ID(IPC_PGPE_INVALID_FUNCID)
77-
IPC_FUNC_ID(IPC_PGPE_START_SUSPEND_FUNCID)
78-
IPC_FUNC_ID(IPC_PGPE_CLIPS_FUNCID)
79-
IPC_FUNC_ID(IPC_PGPE_SET_PMCR_FUNCID)
80-
IPC_FUNC_ID(IPC_PGPE_WOF_CONTROL_FUNCID)
81-
IPC_FUNC_ID(IPC_PGPE_WOF_VFRT_FUNCID)
76+
IPC_FUNC_ID(IPC_MSGID_405_INVALID)
77+
IPC_FUNC_ID(IPC_MSGID_405_START_SUSPEND)
78+
IPC_FUNC_ID(IPC_MSGID_405_CLIPS)
79+
IPC_FUNC_ID(IPC_MSGID_405_SET_PMCR)
80+
IPC_FUNC_ID(IPC_MSGID_405_WOF_CONTROL)
81+
IPC_FUNC_ID(IPC_MSGID_405_WOF_VFRT)
8282
IPC_FUNCIDS_ST_END(OCCHW_INST_ID_GPE2)
8383

8484
//Functions that are only supported by GPE3 should be defined here

src/include/p9_pstates_occ.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ typedef struct
168168
// Minimum Pstate; Maximum is always 0.
169169
uint32_t pstate_min; // Comes from PowerSave #V point after biases
170170

171+
// TODO: Temporary hack untill interface is finalized.
172+
uint8_t pad[88]; // total size = 0xE00, devisible by 128
171173
} OCCPstateParmBlock;
172174

173175

src/occ_405/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ LIB_DIRS = -L$(OBJDIR) \
6969
-L$(OBJDIR)/firdata \
7070
-L$(OBJDIR)/cent \
7171
-L$(OBJDIR)/mem \
72-
-L$(OBJDIR)/wof
72+
-L$(OBJDIR)/wof \
73+
-L$(OBJDIR)/pgpe
7374

7475
#default target is to make a binary application image
7576
.PHONY : all

src/occ_405/amec/amec_data.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
#include <amec_sensors_fw.h>
4848
#include <amec_data.h>
4949
#include <amec_freq.h>
50+
#include <pgpe_interface.h>
51+
#include <p9_pstates_occ.h>
5052

5153
//*************************************************************************
5254
// Externs
@@ -64,8 +66,9 @@
6466
// Globals
6567
//*************************************************************************
6668
extern uint8_t G_occ_interrupt_type;
67-
extern uint32_t G_proc_fmin;
68-
extern uint32_t G_proc_fmax;
69+
70+
//max(fturbo,futurbo)
71+
extern uint16_t G_proc_fmax_mhz;
6972

7073
//*************************************************************************
7174
// Function Prototypes
@@ -98,31 +101,39 @@ errlHndl_t AMEC_data_write_fcurr(const OCC_MODE i_mode)
98101
/* Code */
99102
/*------------------------------------------------------------------------*/
100103

101-
// If we're active we need to load this new range into DVFS MIN/MAX
102-
if(CURRENT_STATE() == OCC_STATE_ACTIVE)
103-
{
104-
// Use i_mode here since this function understands turbo
105-
l_err = amec_set_freq_range(i_mode);
104+
// Load new range into DVFS MIN/MAX,
105+
// Use i_mode here since this function understands turbo
106+
l_err = amec_set_freq_range(i_mode);
106107

107-
if(l_err)
108-
{
109-
//break;
110-
}
108+
if(l_err)
109+
{
110+
//break;
111111
}
112112

113113
// If we are in OpenPower environment with OPAL, load this new range into DVFS
114114
// min/max for AMEC component. PowerVM on BMC and FSP the min/max is set above
115115
// in amec_set_freq_range() based on mode
116116
if((G_occ_interrupt_type != FSP_SUPPORTED_OCC) && (G_sysConfigData.system_type.kvm))
117117
{
118-
g_amec->sys.fmax = G_proc_fmax;
119-
g_amec->sys.fmin = G_proc_fmin; // = G_sysConfigData.sys_mode_freq.table[OCC_MODE_MIN_FREQUENCY]
118+
g_amec->sys.fmax = G_proc_fmax_mhz;
119+
g_amec->sys.fmin = G_sysConfigData.sys_mode_freq.table[OCC_MODE_MIN_FREQUENCY];
120120

121121
TRAC_INFO("AMEC_data_write_fcurr: New frequency range Fmin[%u] Fmax[%u]",
122122
g_amec->sys.fmin,
123123
g_amec->sys.fmax);
124124
}
125125

126+
if(!l_err)
127+
{
128+
// set the clip bounds wide open (if not in active state)
129+
// if not already in active mode, send IPC command to PGPE to set
130+
// pStates clips wide open (pmin - pmax)
131+
if(!IS_OCC_STATE_ACTIVE())
132+
{
133+
l_err = pgpe_widen_clip_ranges();
134+
}
135+
}
136+
126137
return l_err;
127138
}
128139

src/occ_405/amec/amec_freq.c

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@
5656
extern uint8_t G_cent_temp_expired_bitmap;
5757
extern dimm_sensor_flags_t G_dimm_temp_expired_bitmap;
5858

59+
extern uint16_t G_proc_fmax_mhz;
60+
61+
extern GPE_BUFFER(PstatesClips* G_core_data_control_occwrite_ptr);
62+
63+
5964
//*************************************************************************
6065
// Defines/Enums
6166
//*************************************************************************
@@ -67,12 +72,12 @@ extern dimm_sensor_flags_t G_dimm_temp_expired_bitmap;
6772
//*************************************************************************
6873
// Globals
6974
//*************************************************************************
70-
BOOLEAN G_non_dps_power_limited = FALSE;
75+
BOOLEAN G_non_dps_power_limited = FALSE;
7176

7277
opal_proc_voting_reason_t G_amec_opal_proc_throt_reason = NO_THROTTLE;
7378
opal_mem_voting_reason_t G_amec_opal_mem_throt_reason = NO_MEM_THROTTLE;
7479

75-
uint16_t G_time_until_freq_check = FREQ_CHG_CHECK_TIME;
80+
uint16_t G_time_until_freq_check = FREQ_CHG_CHECK_TIME;
7681

7782
//FFDC SCOM addresses as requested by Greg Still in defect SW247927
7883
//If new SCOM addresses are added, update the size of the array.
@@ -162,7 +167,15 @@ errlHndl_t amec_set_freq_range(const OCC_MODE i_mode)
162167
/*------------------------------------------------------------------------*/
163168

164169
// First set to Max Freq Range for this mode
165-
if( VALID_MODE(i_mode) )
170+
// if no mode set yet default to the full range
171+
if(i_mode == OCC_MODE_NOCHANGE)
172+
{
173+
l_freq_min = G_sysConfigData.sys_mode_freq.table[OCC_MODE_MIN_FREQUENCY];
174+
175+
// Set Max frequency (ultra turbo freq if wof enabled, to turbo freq otherwise)
176+
l_freq_max = G_proc_fmax_mhz;
177+
}
178+
else if( VALID_MODE(i_mode) ) // Set to Max Freq Range for this mode
166179
{
167180
l_freq_min = G_sysConfigData.sys_mode_freq.table[OCC_MODE_MIN_FREQUENCY];
168181
l_freq_max = G_sysConfigData.sys_mode_freq.table[i_mode];
@@ -573,39 +586,54 @@ void amec_slv_proc_voting_box(void)
573586
// End Function Specification
574587
void amec_slv_freq_smh(void)
575588
{
576-
// RTC:130201
577-
// TODO/TEMP: Remove '#if 0' when/if needed. Currently does nothing and
578-
// causes warning of set but not used..
579-
#if 0
580-
581589
/*------------------------------------------------------------------------*/
582590
/* Local Variables */
583591
/*------------------------------------------------------------------------*/
584-
uint16_t k = 0;
585-
Pstate l_pstate[MAX_NUM_CORES];
592+
uint8_t quad = 0; // loop through quads
593+
uint8_t core_num = 0; // core ID
594+
uint8_t core_idx = 0; // loop through cores within each quad
595+
Pstate pmax = 0; // select the maximum pstate (minimum frequency)
596+
// within each quad, initialize to 0
586597

587598
/*------------------------------------------------------------------------*/
588599
/* Code */
589600
/*------------------------------------------------------------------------*/
590601

591-
for (k=0; k<MAX_NUM_CORES; k++)
602+
// loop through all quads, get f_requests, translate to pstates
603+
for (quad = 0; quad < MAX_QUADS; quad++)
592604
{
593-
// Translate frequency requests into pstates
594-
l_pstate[k]= proc_freq2pstate(g_amec->proc[0].core[k].f_request);
595-
}
605+
for (core_idx=0; core_idx<NUM_CORES_PER_QUAD; core_idx++) // scan quad cores
606+
{
607+
core_num = (quad*NUM_CORES_PER_QUAD) + core_idx; // loop through all cores
596608

597-
// If this is an OPAL system, send PGPE an IPC to set clipping bounds
598-
// otherwise, set send PGPE an IPC to set pstates
609+
if(pmax < proc_freq2pstate(g_amec->proc[0].core[core_num].f_request))
610+
{
611+
pmax = proc_freq2pstate(g_amec->proc[0].core[core_num].f_request);
612+
}
613+
}
599614

600-
if(G_sysConfigData.system_type.kvm)
601-
{
602-
// Send IPC with G_proc_pmin and l_pstate to set pmin and pmax clips
603-
}
604-
else
605-
{
606-
// send an IPC with l_pstate to set pstates for all Cores
615+
// set quad clip bounds/pstates based on system type
616+
if(G_sysConfigData.system_type.kvm)
617+
{
618+
// update quad bounds on OPAL systems
619+
G_core_data_control_occwrite_ptr->clips.ps_val_clip_min[quad] =
620+
G_opal_static_table.config.pmin;
621+
G_core_data_control_occwrite_ptr->clips.ps_val_clip_max[quad] = pmax;
622+
623+
PROC_DBG("Setting Quad %d's min-max clip bounds to %d-%d\n",
624+
quad, G_opal_static_table.config.pmin, pmax);
625+
}
626+
else
627+
{
628+
// update quad pstate request on non-OPAL systems
629+
G_core_data_control_occwrite_ptr->pstates.pmcr[quad] =
630+
((uint64_t) pmax << 48) +1; // Version 1 (Power9 format)
631+
632+
PROC_DBG("Setting Quad %d's Pstate to %d\n",quad, pmax);
633+
}
634+
635+
pmax = 0; // initialize for next loop iteration
607636
}
608-
#endif
609637
}
610638

611639

src/occ_405/amec/amec_sys.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,6 @@ typedef struct
337337
uint16_t f_request;
338338
// Reason for the frequency request generated by the voting box
339339
uint32_t f_reason;
340-
// Current state of this core frequency state machine
341-
uint8_t f_sms;
342340

343341
} amec_core_t;
344342

src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include <centaur_data.h>
4343
#include "dimm.h"
4444
#include <avsbus.h>
45+
#include "p9_pstates_occ.h"
4546

4647
#define FREQ_FORMAT_PWR_MODE_NUM 6
4748
#define FREQ_FORMAT_BASE_DATA_SZ (sizeof(cmdh_store_mode_freqs_t) - sizeof(cmdh_fsp_cmd_header_t))
@@ -67,12 +68,8 @@
6768

6869
extern uint8_t G_occ_interrupt_type;
6970

70-
extern uint32_t G_proc_fmin;
71-
extern uint32_t G_proc_fmax;
72-
extern uint32_t G_khz_per_pstate;
73-
74-
extern uint8_t G_proc_pmin;
75-
extern uint8_t G_proc_pmax;
71+
extern uint16_t G_proc_fmax_mhz; // Maximum frequency (uturbo if WOF enabled, otherwise turbo)
72+
extern OCCPstateParmBlock G_oppb; // OCC Pstate Parameters Block Structure
7673

7774
typedef struct data_req_table
7875
{
@@ -284,59 +281,84 @@ errlHndl_t data_store_freq_data(const cmdh_fsp_cmd_t * i_cmd_ptr,
284281
// Bytes 3-4 Nominal Frequency Point
285282
l_freq = (l_buf[0] << 8 | l_buf[1]);
286283
l_table[OCC_MODE_NOMINAL] = l_freq;
287-
CMDH_TRAC_INFO("Nominal frequency = %d", l_freq);
284+
CMDH_TRAC_INFO("Nominal frequency = %d MHz", l_freq);
288285

289286
// Bytes 5-6 Turbo Frequency Point:
290287
// also store for DPS modes
291288
l_freq = (l_buf[2] << 8 | l_buf[3]);
289+
// Verify that turbo frequency is <= G_proc_fmax_mhz
290+
if(l_freq > G_proc_fmax_mhz)
291+
{
292+
CMDH_TRAC_ERR("Turbo Frequency[%d] (MHz)) is higher than "
293+
"G_proc_fmax_mhz[%d], clip Turbo Frequency",
294+
l_freq, G_proc_fmax_mhz);
295+
l_freq = G_proc_fmax_mhz;
296+
}
292297
l_table[OCC_MODE_TURBO] = l_freq;
293298
l_table[OCC_MODE_DYN_POWER_SAVE] = l_freq;
294299
l_table[OCC_MODE_DYN_POWER_SAVE_FP] = l_freq;
295-
CMDH_TRAC_INFO("Turbo frequency = %d", l_freq);
300+
CMDH_TRAC_INFO("Turbo frequency = %d MHz", l_freq);
296301

297302
// Bytes 7-8 Minimum Frequency Point
298303
l_freq = (l_buf[4] << 8 | l_buf[5]);
304+
// Verify that minimum frequency is >= G_oppb.frequency_min_khz
305+
if(l_freq * 1000 < G_oppb.frequency_min_khz)
306+
{
307+
CMDH_TRAC_ERR("Minimum Frequency[%d] (Mhz) is lower than PGPE's "
308+
"G_oppb.frequency_min_khz[%d], clip Minimum Frequency",
309+
l_freq, G_oppb.frequency_min_khz);
310+
l_freq = G_oppb.frequency_min_khz / 1000;
311+
}
299312
l_table[OCC_MODE_MIN_FREQUENCY] = l_freq;
300-
G_proc_fmin = l_freq;
301-
CMDH_TRAC_INFO("Minimum frequency = %d", l_freq);
313+
CMDH_TRAC_INFO("Minimum frequency = %d MHz", l_freq);
302314

303315
// Bytes 9-10 Ultr Turbo Frequency Point
304316
l_freq = (l_buf[6] << 8 | l_buf[7]);
305-
if(l_freq)
317+
// Verify that ultra turbo frequency is <= G_proc_fmax_mhz
318+
if(l_freq > G_proc_fmax_mhz)
319+
{
320+
CMDH_TRAC_ERR("Ultra Turbo Frequency[%d] (MHz) is higher than PGPE's "
321+
"Max freq (G_proc_fmax_mhz[%d]) clip Ultra Turbo Frequency",
322+
l_freq, G_proc_fmax_mhz);
323+
l_freq = G_proc_fmax_mhz;
324+
}
325+
l_table[OCC_MODE_UTURBO] = l_freq;
326+
CMDH_TRAC_INFO("UT frequency = %d MHz", l_freq);
327+
328+
// clip G_proc_fmax_mhz to TMGT's MAX(turbo, ultra turbo) frequency point
329+
if(l_table[OCC_MODE_UTURBO] > l_table[OCC_MODE_TURBO])
306330
{
307-
G_proc_fmax = l_freq;
331+
G_proc_fmax_mhz = l_table[OCC_MODE_UTURBO];
308332
}
309-
else // If Ultra Turbo Frequency Point = 0, Fmax = Turbo Frequency
333+
else
310334
{
311-
G_proc_fmax = l_table[OCC_MODE_TURBO];
335+
G_proc_fmax_mhz = l_table[OCC_MODE_TURBO];
312336
}
313-
l_table[OCC_MODE_UTURBO] = l_freq;
314-
CMDH_TRAC_INFO("UT frequency = %d", l_freq);
315337

316338
// Bytes 11-12 Static Power Save Frequency Point
317339
l_freq = (l_buf[8] << 8 | l_buf[9]);
318340
l_table[OCC_MODE_PWRSAVE] = l_freq;
319-
CMDH_TRAC_INFO("Static Power Save frequency = %d", l_freq);
341+
CMDH_TRAC_INFO("Static Power Save frequency = %d MHz", l_freq);
320342

321343
// Bytes 13-14 FFO Frequency Point
322344
l_freq = (l_buf[10] << 8 | l_buf[11]);
323345
if (l_freq != 0)
324346
{
325347
// Check and make sure that FFO freq is within valid range
326348
const uint16_t l_req_freq = l_freq;
327-
if (l_freq < G_proc_fmin)
349+
if (l_freq < l_table[OCC_MODE_MIN_FREQUENCY])
328350
{
329-
l_freq = G_proc_fmin;
351+
l_freq = l_table[OCC_MODE_MIN_FREQUENCY];
330352
}
331-
else if (l_freq > G_proc_fmax)
353+
else if (l_freq > G_proc_fmax_mhz)
332354
{
333-
l_freq = G_proc_fmax;
355+
l_freq = G_proc_fmax_mhz;
334356
}
335357

336358
// Log an error if we could not honor the requested FFO frequency, but keep going.
337359
if (l_req_freq != l_freq)
338360
{
339-
TRAC_ERR("FFO Frequency out of range. requested %d, but using %d",
361+
TRAC_ERR("FFO Frequency out of range. requested %d MHz, but using %d MHz",
340362
l_req_freq, l_freq);
341363
/* @
342364
* @errortype
@@ -360,10 +382,7 @@ errlHndl_t data_store_freq_data(const cmdh_fsp_cmd_t * i_cmd_ptr,
360382
}
361383
}
362384
l_table[OCC_MODE_FFO] = l_freq;
363-
CMDH_TRAC_INFO("FFO Frequency = %d", l_freq);
364-
365-
// Calculate minimum Pstate:
366-
G_proc_pmin = G_proc_pmax + ((G_proc_fmax - G_proc_fmin)/G_khz_per_pstate);
385+
CMDH_TRAC_INFO("FFO Frequency = %d Mhz", l_freq);
367386

368387
// inconsistent Frequency Points?
369388
if((l_table[OCC_MODE_UTURBO] < l_table[OCC_MODE_TURBO] && l_table[OCC_MODE_UTURBO]) ||
@@ -2091,6 +2110,8 @@ errlHndl_t DATA_store_cnfgdata (const cmdh_fsp_cmd_t * i_cmd_ptr,
20912110
l_errlHndl = data_store_freq_data(i_cmd_ptr , o_rsp_ptr);
20922111
if(NULL == l_errlHndl)
20932112
{
2113+
// New Frequency config data packet received with no error logs: set the
2114+
// DATA_MASK_FREQ_PRESENT to flag that we received the frequency from TMGT
20942115
l_new_data = DATA_MASK_FREQ_PRESENT;
20952116
}
20962117
break;

src/occ_405/homer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@
5454
#define OCC_HTMGT_RSP_OFFSET_HOMER 0x000E1000
5555
#define OCC_HTMGT_RSP_ADDRESS_HOMER (HOMER_BASE_ADDRESS+OCC_HTMGT_RSP_OFFSET_HOMER)
5656

57+
// PPMR Header space
58+
#define PPMR_OFFSET_HOMER 0x00300000 // PPMR image HOMER offset
59+
#define PPMR_ADDRESS_HOMER (HOMER_BASE_ADDRESS+PPMR_OFFSET_HOMER) // PPMR image memory address
60+
5761

5862
// Version(s) of HOMER host data currently supported
5963
typedef enum homer_version

0 commit comments

Comments
 (0)