aboutsummaryrefslogtreecommitdiff
path: root/hw/npu2.c
diff options
context:
space:
mode:
authorReza Arbab <arbab@linux.ibm.com>2019-07-17 15:44:22 -0500
committerOliver O'Halloran <oohall@gmail.com>2019-07-26 15:30:21 +1000
commit8279e529d524bce56fca20f6ece0e6f92b0f7aba (patch)
tree34eca8ed940bc7d791f57b72178a86fa43463d45 /hw/npu2.c
parent6db75f1d8e91548a52143949f2b5c49f1e87d608 (diff)
downloadskiboot-8279e529d524bce56fca20f6ece0e6f92b0f7aba.zip
skiboot-8279e529d524bce56fca20f6ece0e6f92b0f7aba.tar.gz
skiboot-8279e529d524bce56fca20f6ece0e6f92b0f7aba.tar.bz2
npu2: Prepare purge_l2_l3_caches() for reuse
Move this to a separate compilation unit with its own header, for reuse. The code formerly in npu2.c is copied verbatim. The #defines formerly in npu2-regs.h have been reformatted and changed to use PPC_BITMASK() instead of multiple consecutive PPC_BIT()s. Signed-off-by: Reza Arbab <arbab@linux.ibm.com> Reviewed-by: Andrew Donnellan <ajd@linux.ibm.com> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Reviewed-by: Stewart Smith <stewart@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Diffstat (limited to 'hw/npu2.c')
-rw-r--r--hw/npu2.c139
1 files changed, 1 insertions, 138 deletions
diff --git a/hw/npu2.c b/hw/npu2.c
index c7ce443..a904ccb 100644
--- a/hw/npu2.c
+++ b/hw/npu2.c
@@ -28,6 +28,7 @@
#include <nvram.h>
#include <xscom-p9-regs.h>
#include <phb4.h>
+#include <cache-p9.h>
#define VENDOR_CAP_START 0x80
#define VENDOR_CAP_END 0x90
@@ -307,144 +308,6 @@ static int64_t npu2_dev_cfg_bar(void *dev, struct pci_cfg_reg_filter *pcrf,
return npu2_cfg_read_bar(ndev, pcrf, offset, len, data);
}
-static int start_l2_purge(uint32_t chip_id, uint32_t core_id)
-{
- uint64_t addr = XSCOM_ADDR_P9_EX(core_id, L2_PRD_PURGE_CMD_REG);
- int rc;
-
- rc = xscom_write_mask(chip_id, addr, L2CAC_FLUSH,
- L2_PRD_PURGE_CMD_TYPE_MASK);
- if (!rc)
- rc = xscom_write_mask(chip_id, addr, L2_PRD_PURGE_CMD_TRIGGER,
- L2_PRD_PURGE_CMD_TRIGGER);
- if (rc)
- prlog(PR_ERR, "PURGE L2 on core 0x%x: XSCOM write_mask "
- "failed %i\n", core_id, rc);
- return rc;
-}
-
-static int wait_l2_purge(uint32_t chip_id, uint32_t core_id)
-{
- uint64_t val;
- uint64_t addr = XSCOM_ADDR_P9_EX(core_id, L2_PRD_PURGE_CMD_REG);
- unsigned long now = mftb();
- unsigned long end = now + msecs_to_tb(L2_L3_PRD_PURGE_TIMEOUT_MS);
- int rc;
-
- while (1) {
- rc = xscom_read(chip_id, addr, &val);
- if (rc) {
- prlog(PR_ERR, "PURGE L2 on core 0x%x: XSCOM read "
- "failed %i\n", core_id, rc);
- break;
- }
- if (!(val & L2_PRD_PURGE_CMD_REG_BUSY))
- break;
- now = mftb();
- if (tb_compare(now, end) == TB_AAFTERB) {
- prlog(PR_ERR, "PURGE L2 on core 0x%x timed out %i\n",
- core_id, rc);
- return OPAL_BUSY;
- }
- }
-
- /* We have to clear the trigger bit ourselves */
- val &= ~L2_PRD_PURGE_CMD_TRIGGER;
- rc = xscom_write(chip_id, addr, val);
- if (rc)
- prlog(PR_ERR, "PURGE L2 on core 0x%x: XSCOM write failed %i\n",
- core_id, rc);
- return rc;
-}
-
-static int start_l3_purge(uint32_t chip_id, uint32_t core_id)
-{
- uint64_t addr = XSCOM_ADDR_P9_EX(core_id, L3_PRD_PURGE_REG);
- int rc;
-
- rc = xscom_write_mask(chip_id, addr, L3_FULL_PURGE,
- L3_PRD_PURGE_TTYPE_MASK);
- if (!rc)
- rc = xscom_write_mask(chip_id, addr, L3_PRD_PURGE_REQ,
- L3_PRD_PURGE_REQ);
- if (rc)
- prlog(PR_ERR, "PURGE L3 on core 0x%x: XSCOM write_mask "
- "failed %i\n", core_id, rc);
- return rc;
-}
-
-static int wait_l3_purge(uint32_t chip_id, uint32_t core_id)
-{
- uint64_t val;
- uint64_t addr = XSCOM_ADDR_P9_EX(core_id, L3_PRD_PURGE_REG);
- unsigned long now = mftb();
- unsigned long end = now + msecs_to_tb(L2_L3_PRD_PURGE_TIMEOUT_MS);
- int rc;
-
- /* Trigger bit is automatically set to zero when flushing is done */
- while (1) {
- rc = xscom_read(chip_id, addr, &val);
- if (rc) {
- prlog(PR_ERR, "PURGE L3 on core 0x%x: XSCOM read "
- "failed %i\n", core_id, rc);
- break;
- }
- if (!(val & L3_PRD_PURGE_REQ))
- break;
- now = mftb();
- if (tb_compare(now, end) == TB_AAFTERB) {
- prlog(PR_ERR, "PURGE L3 on core 0x%x timed out %i\n",
- core_id, rc);
- return OPAL_BUSY;
- }
- }
- return rc;
-}
-
-static int64_t purge_l2_l3_caches(void)
-{
- struct cpu_thread *t;
- uint64_t core_id, prev_core_id = (uint64_t)-1;
- int rc;
- unsigned long now = mftb();
-
- for_each_ungarded_cpu(t) {
- /* Only need to do it once per core chiplet */
- core_id = pir_to_core_id(t->pir);
- if (prev_core_id == core_id)
- continue;
- prev_core_id = core_id;
- rc = start_l2_purge(t->chip_id, core_id);
- if (rc)
- goto trace_exit;
- rc = start_l3_purge(t->chip_id, core_id);
- if (rc)
- goto trace_exit;
- }
-
- prev_core_id = (uint64_t)-1;
- for_each_ungarded_cpu(t) {
- /* Only need to do it once per core chiplet */
- core_id = pir_to_core_id(t->pir);
- if (prev_core_id == core_id)
- continue;
- prev_core_id = core_id;
-
- rc = wait_l2_purge(t->chip_id, core_id);
- if (rc)
- goto trace_exit;
- rc = wait_l3_purge(t->chip_id, core_id);
- if (rc)
- goto trace_exit;
- }
-
-trace_exit:
- prlog(PR_TRACE, "L2/L3 purging took %ldus\n",
- tb_to_usecs(mftb() - now));
-
- return rc;
-}
-
static int64_t npu2_dev_cfg_exp_devcap(void *dev,
struct pci_cfg_reg_filter *pcrf __unused,
uint32_t offset, uint32_t size,