diff options
author | Reza Arbab <arbab@linux.ibm.com> | 2019-07-17 15:44:22 -0500 |
---|---|---|
committer | Oliver O'Halloran <oohall@gmail.com> | 2019-07-26 15:30:21 +1000 |
commit | 8279e529d524bce56fca20f6ece0e6f92b0f7aba (patch) | |
tree | 34eca8ed940bc7d791f57b72178a86fa43463d45 /hw/npu2.c | |
parent | 6db75f1d8e91548a52143949f2b5c49f1e87d608 (diff) | |
download | skiboot-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.c | 139 |
1 files changed, 1 insertions, 138 deletions
@@ -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, |