summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hw/capp.c12
-rw-r--r--hw/phb4.c54
-rw-r--r--include/capp.h12
-rw-r--r--include/chip.h1
-rw-r--r--include/phb4.h3
5 files changed, 74 insertions, 8 deletions
diff --git a/hw/capp.c b/hw/capp.c
index eeaa4ac4..78ab0580 100644
--- a/hw/capp.c
+++ b/hw/capp.c
@@ -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);
+}
diff --git a/hw/phb4.c b/hw/phb4.c
index c0797647..a0431d4f 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -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, &reg);
@@ -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;
};
OpenPOWER on IntegriCloud