aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>2018-01-17 09:50:24 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2018-02-13 01:30:10 -0600
commit725d4a2c6cc7c97bb6754094567d079e70f06323 (patch)
tree3ccac23d71f7121ec509d80492e8a99be2588537
parent85f55e36bbd27fb9f75ba7cec912fd24490570ed (diff)
downloadskiboot-725d4a2c6cc7c97bb6754094567d079e70f06323.zip
skiboot-725d4a2c6cc7c97bb6754094567d079e70f06323.tar.gz
skiboot-725d4a2c6cc7c97bb6754094567d079e70f06323.tar.bz2
core: hostservices: Remove redundant special wakeup code
Use the generic dctl_{set/clear}_special_wakeup() in hostservices to assert and de-assert core special wakeup for P8 and remove the duplicated code. Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r--core/hostservices.c164
1 files changed, 3 insertions, 161 deletions
diff --git a/core/hostservices.c b/core/hostservices.c
index 20334b2..c37bf2f 100644
--- a/core/hostservices.c
+++ b/core/hostservices.c
@@ -545,162 +545,8 @@ static void hservice_nanosleep(uint64_t i_seconds, uint64_t i_nano_seconds)
nanosleep_nopoll(&ts, NULL);
}
-static int hservice_set_special_wakeup(struct cpu_thread *cpu)
-{
- uint64_t val, core_id, poll_target, stamp;
- int rc;
-
- /*
- * Note: HWP checks for checkstops, but I assume we don't need to
- * as we wouldn't be running if one was present
- */
-
- /* Grab core ID once */
- core_id = pir_to_core_id(cpu->pir);
-
- /*
- * The original HWp reads the XSCOM first but ignores the result
- * and error, let's do the same until I know for sure that is
- * not necessary
- */
- xscom_read(cpu->chip_id,
- XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),
- &val);
-
- /* Then we write special wakeup */
- rc = xscom_write(cpu->chip_id,
- XSCOM_ADDR_P8_EX_SLAVE(core_id,
- EX_PM_SPECIAL_WAKEUP_PHYP),
- PPC_BIT(0));
- if (rc) {
- prerror("HBRT: XSCOM error %d asserting special"
- " wakeup on 0x%x\n", rc, cpu->pir);
- return rc;
- }
-
- /*
- * HWP uses the history for Perf register here, dunno why it uses
- * that one instead of the pHyp one, maybe to avoid clobbering it...
- *
- * In any case, it does that to check for run/nap vs.sleep/winkle/other
- * to decide whether to poll on checkstop or not. Since we don't deal
- * with checkstop conditions here, we ignore that part.
- */
-
- /*
- * Now poll for completion of special wakeup. The HWP is nasty here,
- * it will poll at 5ms intervals for up to 200ms. This is not quite
- * acceptable for us at runtime, at least not until we have the
- * ability to "context switch" HBRT. In practice, because we don't
- * winkle, it will never take that long, so we increase the polling
- * frequency to 1us per poll. However we do have to keep the same
- * timeout.
- *
- * We don't use time_wait_ms() either for now as we don't want to
- * poll the FSP here.
- */
- stamp = mftb();
- poll_target = stamp + msecs_to_tb(200);
- val = 0;
- while (!(val & EX_PM_GP0_SPECIAL_WAKEUP_DONE)) {
- /* Wait 1 us */
- hservice_nanosleep(0, 1000);
-
- /* Read PM state */
- rc = xscom_read(cpu->chip_id,
- XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_GP0),
- &val);
- if (rc) {
- prerror("HBRT: XSCOM error %d reading PM state on"
- " 0x%x\n", rc, cpu->pir);
- return rc;
- }
- /* Check timeout */
- if (mftb() > poll_target)
- break;
- }
-
- /* Success ? */
- if (val & EX_PM_GP0_SPECIAL_WAKEUP_DONE) {
- uint64_t now = mftb();
- prlog(PR_TRACE, "HBRT: Special wakeup complete after %ld us\n",
- tb_to_usecs(now - stamp));
- return 0;
- }
-
- /*
- * We timed out ...
- *
- * HWP has a complex workaround for HW255321 which affects
- * Murano DD1 and Venice DD1. Ignore that for now
- *
- * Instead we just dump some XSCOMs for error logging
- */
- prerror("HBRT: Timeout on special wakeup of 0x%0x\n", cpu->pir);
- prerror("HBRT: PM0 = 0x%016llx\n", val);
- val = -1;
- xscom_read(cpu->chip_id,
- XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),
- &val);
- prerror("HBRT: SPC_WKUP = 0x%016llx\n", val);
- val = -1;
- xscom_read(cpu->chip_id,
- XSCOM_ADDR_P8_EX_SLAVE(core_id,
- EX_PM_IDLE_STATE_HISTORY_PHYP),
- &val);
- prerror("HBRT: HISTORY = 0x%016llx\n", val);
-
- return OPAL_HARDWARE;
-}
-
-static int hservice_clr_special_wakeup(struct cpu_thread *cpu)
-{
- uint64_t val, core_id;
- int rc;
-
- /*
- * Note: HWP checks for checkstops, but I assume we don't need to
- * as we wouldn't be running if one was present
- */
-
- /* Grab core ID once */
- core_id = pir_to_core_id(cpu->pir);
-
- /*
- * The original HWp reads the XSCOM first but ignores the result
- * and error, let's do the same until I know for sure that is
- * not necessary
- */
- xscom_read(cpu->chip_id,
- XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),
- &val);
-
- /* Then we write special wakeup */
- rc = xscom_write(cpu->chip_id,
- XSCOM_ADDR_P8_EX_SLAVE(core_id,
- EX_PM_SPECIAL_WAKEUP_PHYP), 0);
- if (rc) {
- prerror("HBRT: XSCOM error %d deasserting"
- " special wakeup on 0x%x\n", rc, cpu->pir);
- return rc;
- }
-
- /*
- * The original HWp reads the XSCOM again with the comment
- * "This puts an inherent delay in the propagation of the reset
- * transition"
- */
- xscom_read(cpu->chip_id,
- XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),
- &val);
-
- return 0;
-}
-
int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
{
- int (*set_wakeup)(struct cpu_thread *cpu);
- int (*clear_wakeup)(struct cpu_thread *cpu);
struct cpu_thread *cpu;
int rc = OPAL_SUCCESS;
@@ -712,14 +558,10 @@ int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
*/
i_core &= 0x0fffffff;
i_core <<= 3;
- set_wakeup = hservice_set_special_wakeup;
- clear_wakeup = hservice_clr_special_wakeup;
break;
case proc_gen_p9:
i_core &= SPR_PIR_P9_MASK;
i_core <<= 2;
- set_wakeup = dctl_set_special_wakeup;
- clear_wakeup = dctl_clear_special_wakeup;
break;
default:
return OPAL_UNSUPPORTED;
@@ -734,7 +576,7 @@ int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
prlog(PR_DEBUG, "HBRT: Special wakeup assert for core 0x%x,"
" count=%d\n", i_core, cpu->hbrt_spec_wakeup);
if (cpu->hbrt_spec_wakeup == 0)
- rc = set_wakeup(cpu);
+ rc = dctl_set_special_wakeup(cpu);
if (rc == 0)
cpu->hbrt_spec_wakeup++;
return rc;
@@ -753,7 +595,7 @@ int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
/* What to do with count on errors ? */
cpu->hbrt_spec_wakeup--;
if (cpu->hbrt_spec_wakeup == 0)
- rc = clear_wakeup(cpu);
+ rc = dctl_clear_special_wakeup(cpu);
return rc;
case 2: /* Clear all special wakeups */
prlog(PR_DEBUG, "HBRT: Special wakeup release for all cores\n");
@@ -761,7 +603,7 @@ int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
if (cpu->hbrt_spec_wakeup) {
cpu->hbrt_spec_wakeup = 0;
/* What to do on errors ? */
- clear_wakeup(cpu);
+ dctl_clear_special_wakeup(cpu);
}
}
return OPAL_SUCCESS;