aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/imc.c196
1 files changed, 186 insertions, 10 deletions
diff --git a/hw/imc.c b/hw/imc.c
index 73f25da..9f59348 100644
--- a/hw/imc.c
+++ b/hw/imc.c
@@ -49,7 +49,7 @@ static unsigned int *htm_scom_index;
* imc_chip_avl_vector(in struct imc_chip_cb, look at include/imc.h).
* nest_pmus[] is an array containing all the possible nest IMC PMU node names.
*/
-static char const *nest_pmus[] = {
+static const char *nest_pmus_p9[] = {
"powerbus0",
"mcs0",
"mcs1",
@@ -104,6 +104,67 @@ static char const *nest_pmus[] = {
/* reserved bits : 51 - 63 */
};
+static const char *nest_pmus_p10[] = {
+ "pb",
+ "mcs0",
+ "mcs1",
+ "mcs2",
+ "mcs3",
+ "mcs4",
+ "mcs5",
+ "mcs6",
+ "mcs7",
+ "pec0",
+ "pec1",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "NA",
+ "phb0",
+ "phb1",
+ "phb2",
+ "phb3",
+ "phb4",
+ "phb5",
+ "ocmb0",
+ "ocmb1",
+ "ocmb2",
+ "ocmb3",
+ "ocmb4",
+ "ocmb5",
+ "ocmb6",
+ "ocmb7",
+ "ocmb8",
+ "ocmb9",
+ "ocmb10",
+ "ocmb11",
+ "ocmb12",
+ "ocmb13",
+ "ocmb14",
+ "ocmb15",
+ "nx",
+};
+
/*
* Due to Nest HW/OCC restriction, microcode will not support individual unit
* events for these nest units mcs0, mcs1 ... mcs7 in the accumulation mode.
@@ -371,7 +432,7 @@ static void disable_unavailable_units(struct dt_node *dev)
uint64_t avl_vec;
struct imc_chip_cb *cb;
struct dt_node *target;
- int i;
+ int i, j;
bool disable_all_nests = false;
struct proc_chip *chip;
@@ -409,14 +470,129 @@ static void disable_unavailable_units(struct dt_node *dev)
avl_vec = (0xffULL) << 56;
}
- for (i = 0; i < ARRAY_SIZE(nest_pmus); i++) {
- if (!(PPC_BITMASK(i, i) & avl_vec)) {
- /* Check if the device node exists */
- target = dt_find_by_name_before_addr(dev, nest_pmus[i]);
- if (!target)
- continue;
- /* Remove the device node */
- dt_free(target);
+ if (proc_gen == proc_gen_p9) {
+ for (i = 0; i < ARRAY_SIZE(nest_pmus_p9); i++) {
+ if (!(PPC_BIT(i) & avl_vec)) {
+ /* Check if the device node exists */
+ target = dt_find_by_name_before_addr(dev, nest_pmus_p9[i]);
+ if (!target)
+ continue;
+ /* Remove the device node */
+ dt_free(target);
+ }
+ }
+ } else if (proc_gen == proc_gen_p10) {
+ int val;
+ char name[8];
+
+ for (i = 0; i < 11; i++) {
+ if (!(PPC_BIT(i) & avl_vec)) {
+ /* Check if the device node exists */
+ target = dt_find_by_name_before_addr(dev, nest_pmus_p10[i]);
+ if (!target)
+ continue;
+ /* Remove the device node */
+ dt_free(target);
+ }
+ }
+
+ for (i = 35; i < 41; i++) {
+ if (!(PPC_BIT(i) & avl_vec)) {
+ /* Check if the device node exists for phb */
+ for (j = 0; j < 3; j++) {
+ snprintf(name, sizeof(name), "phb%d_%d", (i-35), j);
+ target = dt_find_by_name_before_addr(dev, name);
+ if (!target)
+ continue;
+ /* Remove the device node */
+ dt_free(target);
+ }
+ }
+ }
+
+ for (i = 41; i < 58; i++) {
+ if (!(PPC_BIT(i) & avl_vec)) {
+ /* Check if the device node exists */
+ target = dt_find_by_name_before_addr(dev, nest_pmus_p10[i]);
+ if (!target)
+ continue;
+ /* Remove the device node */
+ dt_free(target);
+ }
+ }
+
+ for (i = 0; i < 8; i++) {
+ val = ((avl_vec & (0x7ULL << (29 + (3 * i)))) >> (29 + (3 * i)));
+ switch (val) {
+ case 0x5: //xlink configured and functional
+
+ snprintf(name, sizeof(name), "alink%1d", (7-i));
+ target = dt_find_by_name_before_addr(dev, name);
+ if (target)
+ dt_free(target);
+
+ snprintf(name, sizeof(name), "otl%1d_0", (7-i));
+ target = dt_find_by_name_before_addr(dev, name);
+ if (target)
+ dt_free(target);
+
+ snprintf(name, sizeof(name), "otl%1d_1", (7-i));
+ target = dt_find_by_name_before_addr(dev, name);
+ if (target)
+ dt_free(target);
+
+ break;
+ case 0x6: //alink configured and functional
+
+ snprintf(name, sizeof(name), "xlink%1d", (7-i));
+ target = dt_find_by_name_before_addr(dev, name);
+ if (target)
+ dt_free(target);
+
+ snprintf(name, sizeof(name), "otl%1d_0", (7-i));
+ target = dt_find_by_name_before_addr(dev, name);
+ if (target)
+ dt_free(target);
+
+ snprintf(name, sizeof(name), "otl%1d_1", (7-i));
+ target = dt_find_by_name_before_addr(dev, name);
+ if (target)
+ dt_free(target);
+ break;
+
+ case 0x7: //CAPI configured and functional
+ snprintf(name, sizeof(name), "alink%1d", (7-i));
+ target = dt_find_by_name_before_addr(dev, name);
+ if (target)
+ dt_free(target);
+
+ snprintf(name, sizeof(name), "xlink%1d", (7-i));
+ target = dt_find_by_name_before_addr(dev, name);
+ if (target)
+ dt_free(target);
+ break;
+ default:
+ snprintf(name, sizeof(name), "xlink%1d", (7-i));
+ target = dt_find_by_name_before_addr(dev, name);
+ if (target)
+ dt_free(target);
+
+ snprintf(name, sizeof(name), "alink%1d", (7-i));
+ target = dt_find_by_name_before_addr(dev, name);
+ if (target)
+ dt_free(target);
+
+ snprintf(name, sizeof(name), "otl%1d_0", (7-i));
+ target = dt_find_by_name_before_addr(dev, name);
+ if (target)
+ dt_free(target);
+
+ snprintf(name, sizeof(name), "otl%1d_1", (7-i));
+ target = dt_find_by_name_before_addr(dev, name);
+ if (target)
+ dt_free(target);
+ break;
+ }
}
}