aboutsummaryrefslogtreecommitdiff
path: root/hdata
diff options
context:
space:
mode:
authorOliver O'Halloran <oohall@gmail.com>2017-01-12 14:54:04 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-01-15 12:42:09 +1100
commitac5e0d83622bca7efa13ee87ec868a3cceab0f3d (patch)
tree9f63805e31c857c35b5a0deb66c82f6f6fdfa821 /hdata
parentb7ac68771baaebff3fb47120a73b3901e8e6a839 (diff)
downloadskiboot-ac5e0d83622bca7efa13ee87ec868a3cceab0f3d.zip
skiboot-ac5e0d83622bca7efa13ee87ec868a3cceab0f3d.tar.gz
skiboot-ac5e0d83622bca7efa13ee87ec868a3cceab0f3d.tar.bz2
hdat: Add support for PHB4
Adds support for parsing the PHB4 entries in the IOHUB array and populating the devicetree appropriately. Signed-off-by: Oliver O'Halloran <oohall@gmail.com> [stewart@linux.vnet.ibm.com: s/DOUMO/DUOMO/, assert(), spotted by Vasant] Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hdata')
-rw-r--r--hdata/iohub.c122
-rw-r--r--hdata/spira.h28
2 files changed, 143 insertions, 7 deletions
diff --git a/hdata/iohub.c b/hdata/iohub.c
index 50915f8..0e7ef65 100644
--- a/hdata/iohub.c
+++ b/hdata/iohub.c
@@ -248,6 +248,90 @@ static struct dt_node *io_add_phb3(const struct cechub_io_hub *hub,
return pbcq;
}
+static struct dt_node *add_pec_stack(const struct cechub_io_hub *hub,
+ struct dt_node *pbcq, int stack_index,
+ int phb_index, u8 active_phbs)
+{
+ struct dt_node *stack;
+ u64 eq[8];
+ int i;
+
+ stack = dt_new_addr(pbcq, "stack", stack_index);
+ assert(stack);
+
+ dt_add_property_cells(stack, "reg", stack_index);
+ dt_add_property_cells(stack, "ibm,phb-index", phb_index);
+ dt_add_property_string(stack, "compatible", "ibm,power9-phb-stack");
+
+ /* XXX: This should probably just return if the PHB is disabled
+ * rather than adding the extra properties.
+ */
+
+ if (active_phbs & (0x80 >> phb_index))
+ dt_add_property_string(stack, "status", "okay");
+ else
+ dt_add_property_string(stack, "status", "disabled");
+
+ for (i = 0; i < 4; i++) /* gen 3 eq settings */
+ eq[i] = be64_to_cpu(hub->phb4_lane_eq[phb_index][i]);
+
+ for (i = 4; i < 8; i++) /* gen 4 eq settings */
+ eq[i] = be64_to_cpu(hub->phb4_lane_eq[phb_index][i]);
+
+ __dt_add_property_u64s(stack, "ibm,lane-eq", 8, eq);
+
+ return stack;
+}
+
+static struct dt_node *io_add_phb4(const struct cechub_io_hub *hub,
+ const struct HDIF_common_hdr *sp_iohubs,
+ struct dt_node *xcom,
+ unsigned int pec_index,
+ int stacks,
+ int phb_base)
+{
+ struct dt_node *pbcq;
+ uint32_t reg[4];
+ uint8_t active_phb_mask = hub->fab_br0_pdt;
+ uint32_t pe_xscom = 0x4010c00 + (pec_index * 0x0000400);
+ uint32_t pci_xscom = 0xd010800 + (pec_index * 0x1000000);
+ int i;
+
+ /* Create PBCQ node under xscom */
+ pbcq = dt_new_addr(xcom, "pbcq", pe_xscom);
+ if (!pbcq)
+ return NULL;
+
+ /* "reg" property contains (in order) the PE and PCI XSCOM addresses */
+ reg[0] = pe_xscom;
+ reg[1] = 0x100;
+ reg[2] = pci_xscom;
+ reg[3] = 0x200;
+ dt_add_property(pbcq, "reg", reg, sizeof(reg));
+
+ /* The hubs themselves go under the stacks */
+ dt_add_property_strings(pbcq, "compatible", "ibm,power9-pbcq");
+ dt_add_property_cells(pbcq, "ibm,pec-index", pec_index);
+ dt_add_property_cells(pbcq, "#address-cells", 1);
+ dt_add_property_cells(pbcq, "#size-cells", 0);
+
+ for (i = 0; i < stacks; i++)
+ add_pec_stack(hub, pbcq, i, phb_base + i, active_phb_mask);
+
+ dt_add_property_cells(pbcq, "ibm,hub-id", be16_to_cpu(hub->hub_num));
+
+ /* The loc code of the PHB itself is different from the base
+ * loc code of the slots (It's actually the DCM's loc code).
+ */
+ io_get_loc_code(sp_iohubs, pbcq, "ibm,loc-code");
+
+ prlog(PR_INFO, "CEC: Added PHB4 PBCQ %d with %d stacks\n",
+ pec_index, stacks);
+
+ /* the actual PHB nodes created later on by skiboot */
+ return pbcq;
+}
+
static struct dt_node *io_add_p8(const struct cechub_io_hub *hub,
const struct HDIF_common_hdr *sp_iohubs)
{
@@ -279,6 +363,34 @@ static struct dt_node *io_add_p8(const struct cechub_io_hub *hub,
return xscom;
}
+static struct dt_node *io_add_p9(const struct cechub_io_hub *hub,
+ const struct HDIF_common_hdr *sp_iohubs)
+{
+ struct dt_node *xscom;
+ unsigned int chip_id;
+
+ chip_id = pcid_to_chip_id(be32_to_cpu(hub->proc_chip_id));
+
+ prlog(PR_INFO, "CEC: HW CHIP=0x%x, HW TOPO=0x%04x\n", chip_id,
+ be16_to_cpu(hub->hw_topology));
+
+ xscom = find_xscom_for_chip(chip_id);
+ if (!xscom) {
+ prerror("P9: Can't find XSCOM for chip %d\n", chip_id);
+ return NULL;
+ }
+
+ printf("IOHUB: PHB4 active bridge mask %x\n", (u32) hub->fab_br0_pdt);
+
+ /* Create PBCQs */
+ io_add_phb4(hub, sp_iohubs, xscom, 0, 1, 0);
+ io_add_phb4(hub, sp_iohubs, xscom, 1, 2, 1);
+ io_add_phb4(hub, sp_iohubs, xscom, 2, 3, 3);
+
+ return xscom;
+}
+
+
static void io_add_p8_cec_vpd(const struct HDIF_common_hdr *sp_iohubs)
{
const struct HDIF_child_ptr *iokids;
@@ -387,6 +499,16 @@ static void io_parse_fru(const void *sp_iohubs)
prlog(PR_INFO, "CEC: Venice !\n");
hn = io_add_p8(hub, sp_iohubs);
break;
+ case CECHUB_HUB_NIMBUS_SFORAZ:
+ case CECHUB_HUB_NIMBUS_MONZA:
+ case CECHUB_HUB_NIMBUS_LAGRANGE:
+ prlog(PR_INFO, "CEC: Nimbus !\n");
+ hn = io_add_p9(hub, sp_iohubs);
+ break;
+ case CECHUB_HUB_CUMULUS_DUOMO:
+ prlog(PR_INFO, "CEC: Cumulus !\n");
+ hn = io_add_p9(hub, sp_iohubs);
+ break;
default:
prlog(PR_ERR, "CEC: Hub ID 0x%04x unsupported !\n",
hub_id);
diff --git a/hdata/spira.h b/hdata/spira.h
index b04a3df..6d55b78 100644
--- a/hdata/spira.h
+++ b/hdata/spira.h
@@ -575,6 +575,8 @@ struct cechub_io_hub {
#define CECHUB_HUB_FAB_BR0_PDT_PHB1 0x40
#define CECHUB_HUB_FAB_BR0_PDT_PHB2 0x20
#define CECHUB_HUB_FAB_BR0_PDT_PHB3 0x10
+#define CECHUB_HUB_FAB_BR0_PDT_PHB4 0x08
+#define CECHUB_HUB_FAB_BR0_PDT_PHB5 0x04
uint8_t fab_br1_pdt; /* p5ioc2 & p7ioc PCI-E */
#define CECHUB_HUB_FAB_BR1_PDT_PHB0 0x80
#define CECHUB_HUB_FAB_BR1_PDT_PHB1 0x40
@@ -583,10 +585,14 @@ struct cechub_io_hub {
#define CECHUB_HUB_FAB_BR1_PDT_PHB4 0x08 /* p7ioc only */
#define CECHUB_HUB_FAB_BR1_PDT_PHB5 0x04 /* p7ioc only */
__be16 iohub_id; /* the type of hub */
-#define CECHUB_HUB_P7IOC 0x60e7 /* from VPL3 */
-#define CECHUB_HUB_MURANO 0x20ef /* Murano from spec */
-#define CECHUB_HUB_MURANO_SEGU 0x0001 /* Murano+Seguso from spec */
-#define CECHUB_HUB_VENICE_WYATT 0x0010 /* Venice+Wyatt from spec */
+#define CECHUB_HUB_P7IOC 0x60e7 /* from VPL3 */
+#define CECHUB_HUB_MURANO 0x20ef /* Murano from spec */
+#define CECHUB_HUB_MURANO_SEGU 0x0001 /* Murano+Seguso from spec */
+#define CECHUB_HUB_VENICE_WYATT 0x0010 /* Venice+Wyatt from spec */
+#define CECHUB_HUB_NIMBUS_SFORAZ 0x0020 /* Nimbus+sforaz from spec */
+#define CECHUB_HUB_NIMBUS_MONZA 0x0021 /* Nimbus+monza from spec */
+#define CECHUB_HUB_NIMBUS_LAGRANGE 0x0022 /* Nimbus+lagrange from spec */
+#define CECHUB_HUB_CUMULUS_DUOMO 0x0031 /* cumulus+duomo from spec */
__be32 ec_level;
__be32 aff_dom2; /* HDAT < v9.x only */
__be32 aff_dom3; /* HDAT < v9.x only */
@@ -623,10 +629,18 @@ struct cechub_io_hub {
__be16 gx_bus_speed; /* Version 0x58 */
};
- /* HDAT >= v9.x, HDIF version 0x6A or later */
+ /* HDAT >= v9.x, HDIF version 0x6A adds phb_lane_eq with four
+ * words per PHB (4 PHBs).
+ *
+ * HDAT >= 10.x, HDIF version 0x7A adds space for another two
+ * two PHBs (6 total) and the gen4 EQ values.
+ */
struct {
- /* 4 values per PHB, 4 PHBs */
- __be64 phb_lane_eq[4][4];
+ /* Gen 3 PHB eq values, 6 PHBs */
+ __be64 phb_lane_eq[6][4];
+
+ /* Gen 4 PHB eq values */
+ __be64 phb4_lane_eq[6][4];
};
};
} __packed;