diff options
author | Oliver O'Halloran <oohall@gmail.com> | 2017-01-12 14:54:04 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-01-15 12:42:09 +1100 |
commit | ac5e0d83622bca7efa13ee87ec868a3cceab0f3d (patch) | |
tree | 9f63805e31c857c35b5a0deb66c82f6f6fdfa821 /hdata | |
parent | b7ac68771baaebff3fb47120a73b3901e8e6a839 (diff) | |
download | skiboot-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.c | 122 | ||||
-rw-r--r-- | hdata/spira.h | 28 |
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; |