summaryrefslogtreecommitdiffstats
path: root/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.c
diff options
context:
space:
mode:
Diffstat (limited to 'import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.c')
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_pstate.c99
1 files changed, 75 insertions, 24 deletions
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 f20d1f8c..bd8a3fbb 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
@@ -112,6 +112,8 @@ void p9_pgpe_pstate_init()
G_pgpe_pstate_record.numActiveCores = 0;
G_pgpe_pstate_record.vratio = 0; //This will be filled up when WOF is enabled
G_pgpe_pstate_record.fratio = 0; //This will be filled up when WOF is enabled
+ G_pgpe_pstate_record.pendingPminClipBcast = 0;
+ G_pgpe_pstate_record.pendingPmaxClipBcast = 0;
PK_TRACE_INF("SafePstate=0x%x", G_pgpe_pstate_record.safePstate);
}
@@ -1044,7 +1046,7 @@ void p9_pgpe_pstate_start(uint32_t pstate_start_origin)
ocb_qcsr_t qcsr;
uint8_t quadPstates[MAX_QUADS];
uint32_t lowestDpll, syncPstate, q;
- uint64_t value;
+ uint64_t value, pmin, pmax;
qcsr.value = in32(OCB_QCSR);
@@ -1124,26 +1126,6 @@ void p9_pgpe_pstate_start(uint32_t pstate_start_origin)
p9_pgpe_pstate_dpll_write(0xfc, dpllFreq.value);
}
- //4. Determine PMCR Owner
- if (pstate_start_origin == PSTATE_START_OCC_IPC)
- {
- PK_TRACE_DBG("g_oimr_override:0x%llx", g_oimr_override);
- ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_PSTATE_START_STOP].cmd;
- ipcmsg_start_stop_t* args = (ipcmsg_start_stop_t*)async_cmd->cmd_data;
- p9_pgpe_pstate_set_pmcr_owner(args->pmcr_owner);
- }
- else
- {
- //Bring up the PGPE in Characterizaion Mode by default. This mimics
- //first starting pstates with OCC as owner which enables SCOM writes
- //to PMCR, and then switching the owner to CHAR which enables PCB_TYPE1 interrupts
- //and allows CME to forward Pstate Requests
- p9_pgpe_pstate_set_pmcr_owner(PMCR_OWNER_OCC);
- PK_TRACE_DBG("OWNER_CHAR");
- G_pgpe_pstate_record.pmcrOwner = PMCR_OWNER_CHAR;
- g_oimr_override &= ~(BIT64(46));
- out32(OCB_OIMR1_CLR, BIT32(14)); //Enable PCB_INTR_TYPE1
- }
//4. Init PStates Data and Send Pstate Start DB0 to active CMEs
for (q = 0; q < MAX_QUADS; q++)
@@ -1160,20 +1142,28 @@ void p9_pgpe_pstate_start(uint32_t pstate_start_origin)
p9_pgpe_pstate_update(quadPstates);
- //Set up CME_SCRATCH0[Local_Pstate_Index]
+ //5. Set up CME_SCRATCH0[Local_Pstate_Index]
for (q = 0; q < MAX_QUADS; q++)
{
if(G_pgpe_pstate_record.activeQuads & (0x80 >> q))
{
//Give Quad Manager CME control of DPLL through inter-ppm
GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QPMMR_OR, q), BIT64(26));
+ pmin = G_pgpe_pstate_record.psClipMax[q];
+ pmax = G_pgpe_pstate_record.psClipMin[q];
if (qcsr.fields.ex_config & (0x800 >> (q << 1)))
{
GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SRTCH0, q, 0), value);
value |= (uint64_t)((MAX_QUADS - 1 - q) << 3) << 32;
GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SRTCH0, q, 0), value);
- PK_TRACE_DBG("SRTCH0[%d_1]:0x%08x%08x", q, value >> 32, value);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_LMCR_OR, q, 0), BIT64(2));
+ value = 0;
+ value |= (pmin << SHIFT64(23));
+ value |= (pmax << SHIFT64(31));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PMSRS0, q, 0), value);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PMSRS1, q, 0), value);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_LMCR_CLR, q, 0), BIT64(2));
}
if (qcsr.fields.ex_config & (0x400 >> (q << 1)))
@@ -1181,11 +1171,38 @@ void p9_pgpe_pstate_start(uint32_t pstate_start_origin)
GPE_GETSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SRTCH0, q, 1), value);
value |= (uint64_t)((MAX_QUADS - 1 - q) << 3) << 32;
GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SRTCH0, q, 1), value);
- PK_TRACE_DBG("SRTCH0[%d_1]:0x%08x%08x", q, value >> 32, value);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_LMCR_OR, q, 1), BIT64(2));
+ value = 0;
+ value |= (pmin << SHIFT64(23));
+ value |= (pmax << SHIFT64(31));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PMSRS0, q, 1), value);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_PMSRS1, q, 1), value);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_LMCR_CLR, q, 1), BIT64(2));
}
}
}
+ //6. Determine PMCR Owner
+ if (pstate_start_origin == PSTATE_START_OCC_IPC)
+ {
+ ipc_async_cmd_t* async_cmd = (ipc_async_cmd_t*)G_pgpe_pstate_record.ipcPendTbl[IPC_PEND_PSTATE_START_STOP].cmd;
+ ipcmsg_start_stop_t* args = (ipcmsg_start_stop_t*)async_cmd->cmd_data;
+ p9_pgpe_pstate_set_pmcr_owner(args->pmcr_owner);
+ }
+ else
+ {
+ //Bring up the PGPE in Characterizaion Mode by default. This mimics
+ //first starting pstates with OCC as owner which enables SCOM writes
+ //to PMCR, and then switching the owner to CHAR which enables PCB_TYPE1 interrupts
+ //and allows CME to forward Pstate Requests
+ p9_pgpe_pstate_set_pmcr_owner(PMCR_OWNER_OCC);
+ PK_TRACE_DBG("OWNER_CHAR");
+ G_pgpe_pstate_record.pmcrOwner = PMCR_OWNER_CHAR;
+ g_oimr_override &= ~(BIT64(46));
+ out32(OCB_OIMR1_CLR, BIT32(14)); //Enable PCB_INTR_TYPE1
+ }
+
+ //7. Send Pstate Start Doorbell0
pgpe_db0_start_ps_bcast_t db0;
db0.value = 0;
db0.fields.msg_id = MSGID_DB0_START_PSTATE_BROADCAST;
@@ -1263,6 +1280,40 @@ void p9_pgpe_pstate_stop()
PK_TRACE_DBG("Stop Done");
}
+void p9_pgpe_pstate_clip_bcast(uint32_t clip_bcast_type)
+{
+ PK_TRACE_DBG("Clip Bcast");
+ pgpe_db0_clip_bcast_t db0;
+ db0.value = 0;
+ db0.fields.msg_id = MSGID_DB0_CLIP_BROADCAST;
+ db0.fields.clip_type = clip_bcast_type;
+
+ //Note that we store PMIN as psClipMax(which lower Pstate, but higher numbered Pstate)
+ if (clip_bcast_type == DB0_CLIP_BCAST_TYPE_PMIN)
+ {
+ db0.fields.quad0_clip = G_pgpe_pstate_record.psClipMax[0];
+ db0.fields.quad1_clip = G_pgpe_pstate_record.psClipMax[1];
+ db0.fields.quad2_clip = G_pgpe_pstate_record.psClipMax[2];
+ db0.fields.quad3_clip = G_pgpe_pstate_record.psClipMax[3];
+ db0.fields.quad4_clip = G_pgpe_pstate_record.psClipMax[4];
+ db0.fields.quad5_clip = G_pgpe_pstate_record.psClipMax[5];
+ }
+ else if (clip_bcast_type == DB0_CLIP_BCAST_TYPE_PMAX)
+ {
+ db0.fields.quad0_clip = G_pgpe_pstate_record.psClipMin[0];
+ db0.fields.quad1_clip = G_pgpe_pstate_record.psClipMin[1];
+ db0.fields.quad2_clip = G_pgpe_pstate_record.psClipMin[2];
+ db0.fields.quad3_clip = G_pgpe_pstate_record.psClipMin[3];
+ db0.fields.quad4_clip = G_pgpe_pstate_record.psClipMin[4];
+ db0.fields.quad5_clip = G_pgpe_pstate_record.psClipMin[5];
+ }
+
+ p9_pgpe_send_db0(db0.value,
+ G_pgpe_pstate_record.activeQuads,
+ G_pgpe_pstate_record.activeCores,
+ PGPE_DB0_UNICAST);
+}
+
void p9_pgpe_pstate_setup_process_pcb_type4()
{
ocb_ccsr_t ccsr;
OpenPOWER on IntegriCloud