diff options
-rw-r--r-- | hw/capp.c | 12 | ||||
-rw-r--r-- | hw/phb4.c | 54 | ||||
-rw-r--r-- | include/capp.h | 12 | ||||
-rw-r--r-- | include/chip.h | 1 | ||||
-rw-r--r-- | include/phb4.h | 3 |
5 files changed, 74 insertions, 8 deletions
@@ -240,3 +240,15 @@ int64_t capp_get_info(int chip_id, struct phb *phb, struct capp_info *info) return OPAL_PARAMETER; } + +int64_t capp_xscom_read(struct capp *capp, int64_t off, uint64_t *val) +{ + return capp == NULL ? OPAL_PARAMETER : + xscom_read(capp->chip_id, off + capp->capp_xscom_offset, val); +} + +int64_t capp_xscom_write(struct capp *capp, int64_t off, uint64_t val) +{ + return capp == NULL ? OPAL_PARAMETER : + xscom_write(capp->chip_id, off + capp->capp_xscom_offset, val); +} @@ -3880,13 +3880,13 @@ static int64_t phb4_get_capp_info(int chip_id, struct phb *phb, struct capp_info *info) { struct phb4 *p = phb_to_phb4(phb); - struct proc_chip *chip = get_chip(p->chip_id); uint32_t offset; if (chip_id != p->chip_id) return OPAL_PARAMETER; - if (!((1 << p->index) & chip->capp_phb4_attached_mask)) + /* Check is CAPP is attached to the PHB */ + if (p->capp == NULL || p->capp->phb != phb) return OPAL_PARAMETER; offset = PHB4_CAPP_REG_OFFSET(p); @@ -4397,23 +4397,63 @@ static int64_t enable_capi_mode(struct phb4 *p, uint64_t pe_number, return OPAL_SUCCESS; } + +static int64_t phb4_init_capp(struct phb4 *p) +{ + struct capp *capp; + int rc; + + if (p->index != CAPP0_PHB_INDEX && + p->index != CAPP1_PHB_INDEX) + return OPAL_UNSUPPORTED; + + capp = zalloc(sizeof(struct capp)); + if (capp == NULL) + return OPAL_NO_MEM; + + if (p->index == CAPP0_PHB_INDEX) { + capp->capp_index = 0; + capp->capp_xscom_offset = 0; + + } else if (p->index == CAPP1_PHB_INDEX) { + capp->capp_index = 1; + capp->capp_xscom_offset = CAPP1_REG_OFFSET; + } + + capp->attached_pe = phb4_get_reserved_pe_number(&p->phb); + capp->chip_id = p->chip_id; + + /* Load capp microcode into the capp unit */ + rc = load_capp_ucode(p); + + if (rc == OPAL_SUCCESS) + p->capp = capp; + else + free(capp); + + return rc; +} + static int64_t phb4_set_capi_mode(struct phb *phb, uint64_t mode, uint64_t pe_number) { struct phb4 *p = phb_to_phb4(phb); struct proc_chip *chip = get_chip(p->chip_id); + struct capp *capp = p->capp; uint64_t reg, ret; uint32_t offset; + if (capp == NULL) + return OPAL_UNSUPPORTED; if (!capp_ucode_loaded(chip, p->index)) { PHBERR(p, "CAPP: ucode not loaded\n"); return OPAL_RESOURCE; } - lock(&capi_lock); - chip->capp_phb4_attached_mask |= 1 << p->index; - unlock(&capi_lock); + /* mark the capp attached to the phb */ + capp->phb = phb; + capp->attached_pe = pe_number; offset = PHB4_CAPP_REG_OFFSET(p); xscom_read(p->chip_id, CAPP_ERR_STATUS_CTRL + offset, ®); @@ -5595,8 +5635,8 @@ static void phb4_create(struct dt_node *np) /* Get the HW up and running */ phb4_init_hw(p); - /* Load capp microcode into capp unit */ - load_capp_ucode(p); + /* init capp that might get attached to the phb */ + phb4_init_capp(p); /* Compute XIVE source flags depending on PHB revision */ irq_flags = 0; diff --git a/include/capp.h b/include/capp.h index 6ec3f7fe..cc70e443 100644 --- a/include/capp.h +++ b/include/capp.h @@ -79,6 +79,14 @@ struct capp_ops { int64_t (*get_capp_info)(int, struct phb *, struct capp_info *); }; +struct capp { + struct phb *phb; + unsigned int capp_index; + uint64_t capp_xscom_offset; + uint64_t attached_pe; + uint64_t chip_id; +}; + struct proc_chip; extern struct lock capi_lock; extern struct capp_ops capi_ops; @@ -96,4 +104,8 @@ extern int64_t capp_load_ucode(unsigned int chip_id, uint32_t opal_id, extern int64_t capp_get_info(int chip_id, struct phb *phb, struct capp_info *info); + +/* Helpers to read/write capp registers */ +extern int64_t capp_xscom_read(struct capp *capp, int64_t off, uint64_t *val); +extern int64_t capp_xscom_write(struct capp *capp, int64_t off, uint64_t val); #endif /* __CAPP_H */ diff --git a/include/chip.h b/include/chip.h index 2fb8126d..c759d0a0 100644 --- a/include/chip.h +++ b/include/chip.h @@ -197,7 +197,6 @@ struct proc_chip { /* Must hold capi_lock to change */ uint8_t capp_phb3_attached_mask; - uint8_t capp_phb4_attached_mask; uint8_t capp_ucode_loaded; /* Used by hw/centaur.c */ diff --git a/include/phb4.h b/include/phb4.h index 43819d57..60c1735d 100644 --- a/include/phb4.h +++ b/include/phb4.h @@ -232,6 +232,9 @@ struct phb4 { /* Current NPU2 relaxed ordering state */ bool ro_state; + /* Any capp instance attached to the PHB4 */ + struct capp *capp; + struct phb phb; }; |