aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorChristophe Lombard <clombard@linux.vnet.ibm.com>2021-10-14 17:56:51 +0200
committerVasant Hegde <hegdevasant@linux.vnet.ibm.com>2021-10-19 12:26:01 +0530
commit768f67e686e5691a6d6d956f625ce455d3b48fb5 (patch)
tree5bd43725c341f3c8014c2e0cf3a88f71f61bfa4b /hw
parentb10c12c63a4f58fe2c31dafdc5269c65b3a8a613 (diff)
downloadskiboot-768f67e686e5691a6d6d956f625ce455d3b48fb5.zip
skiboot-768f67e686e5691a6d6d956f625ce455d3b48fb5.tar.gz
skiboot-768f67e686e5691a6d6d956f625ce455d3b48fb5.tar.bz2
pau: introduce support
OpenCapi for P10 is included in the P10 chip. This requires OCAPI capable PHYs, Datalink Layer Logic and Transaction Layer Logic to be included. The PHYs are the physical connection to the OCAPI interconnect. The Datalink Layer provides link training. The Transaction Layer executes the cache coherent and data movement commands on the P10 chip. The PAU provides the Transaction Layer functionality for the OCAPI link(s) on the P10 chip. The P10 PAU supports two OCAPI links. Six accelerator units PAUs are instantiated on the P10 chip for a total of twelve OCAPI links. This patch adds PAU opencapi structure for supporting OpenCapi5. hw/pau.c file contains main of PAU management functions. Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/Makefile.inc2
-rw-r--r--hw/pau.c224
2 files changed, 225 insertions, 1 deletions
diff --git a/hw/Makefile.inc b/hw/Makefile.inc
index c254fcb..0b12f0b 100644
--- a/hw/Makefile.inc
+++ b/hw/Makefile.inc
@@ -8,7 +8,7 @@ HW_OBJS += dts.o lpc-rtc.o npu.o npu-hw-procedures.o xive.o phb4.o
HW_OBJS += fake-nvram.o lpc-mbox.o npu2.o npu2-hw-procedures.o
HW_OBJS += npu2-common.o npu2-opencapi.o phys-map.o sbe-p9.o capp.o
HW_OBJS += occ-sensor.o vas.o sbe-p8.o dio-p9.o lpc-port80h.o cache-p9.o
-HW_OBJS += npu-opal.o ocmb.o xive2.o
+HW_OBJS += npu-opal.o ocmb.o xive2.o pau.o
HW=hw/built-in.a
include $(SRC)/hw/fsp/Makefile.inc
diff --git a/hw/pau.c b/hw/pau.c
new file mode 100644
index 0000000..63b69d3
--- /dev/null
+++ b/hw/pau.c
@@ -0,0 +1,224 @@
+/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ * Copyright 2021 IBM Corp.
+ */
+
+#include <phys-map.h>
+#include <pau.h>
+#include <pau-regs.h>
+
+struct pau_dev *pau_next_dev(struct pau *pau, struct pau_dev *dev,
+ enum pau_dev_type type)
+{
+ uint32_t i = 0;
+
+ if (dev)
+ i = dev->index + 1;
+
+ for (; i < pau->links; i++) {
+ dev = &pau->devices[i];
+
+ if (dev->type == type || type == PAU_DEV_TYPE_ANY)
+ return dev;
+ }
+
+ return NULL;
+}
+
+static void pau_dt_create_link(struct dt_node *pau, uint32_t pau_index,
+ uint32_t dev_index)
+{
+ struct dt_node *link;
+ uint32_t phy_lane_mask = 0, pau_unit = 0;
+ uint32_t op_unit = 0, odl_index = 0;
+
+ link = dt_new_addr(pau, "link", dev_index);
+
+ dt_add_property_string(link, "compatible", "ibm,pau-link");
+ dt_add_property_cells(link, "reg", dev_index);
+ dt_add_property_cells(link, "ibm,pau-link-index", dev_index);
+
+ /* pau_index Interface Link - OPxA/B
+ * 0 OPT0 -- PAU0
+ * OPT1 -- no PAU, SMP only
+ * OPT2 -- no PAU, SMP only
+ * 1 OPT3 -- PAU3
+ * 2 OPT4 -- PAU4 by default, but can be muxed to use PAU5
+ * 3 OPT5 -- PAU5 by default, but can be muxed to use PAU4
+ * 4 OPT6 -- PAU6 by default, but can be muxed to use PAU7
+ * 5 OPT7 -- PAU7 by default, but can be muxed to use PAU6
+ */
+ switch (pau_index) {
+ case 0:
+ /* OP0A - OP0B */
+ pau_unit = 0;
+ op_unit = 0;
+ break;
+ case 1:
+ /* OP3A - OP3B */
+ pau_unit = 3;
+ op_unit = 3;
+ break;
+ case 2:
+ /* OP4A - OP4B or OP5A - OP5B (TO DO) */
+ pau_unit = 4;
+ op_unit = 4;
+ break;
+ case 3:
+ /* OP5A - OP5B or OP4A - OP4B (TO DO) */
+ pau_unit = 5;
+ op_unit = 5;
+ break;
+ case 4:
+ /* OP6A - OP6B or OP7A - OP7B (TO DO) */
+ pau_unit = 6;
+ op_unit = 6;
+ break;
+ case 5:
+ /* OP7A - OP7B or OP6A - OP6B (TO DO) */
+ pau_unit = 7;
+ op_unit = 7;
+ break;
+ default:
+ return;
+ }
+
+ /* ODL0 is hooked up to OTL0 */
+ if (dev_index == 0) {
+ odl_index = 0;
+ phy_lane_mask = PPC_BITMASK32(0, 3);
+ phy_lane_mask |= PPC_BITMASK32(5, 8);
+ } else if (dev_index == 1) {
+ odl_index = 1;
+ phy_lane_mask = PPC_BITMASK32(9, 12);
+ phy_lane_mask |= PPC_BITMASK32(14, 17);
+ }
+
+ dt_add_property_cells(link, "ibm,odl-index", odl_index);
+ dt_add_property_cells(link, "ibm,pau-unit", pau_unit);
+ dt_add_property_cells(link, "ibm,op-unit", op_unit);
+ dt_add_property_cells(link, "ibm,pau-lane-mask", phy_lane_mask);
+ dt_add_property_cells(link, "ibm,phb-index", pau_get_phb_index(pau_index, dev_index));
+}
+
+static void pau_dt_create_pau(struct dt_node *xscom, uint32_t pau_index)
+{
+ const uint32_t pau_base[] = { 0x10010800, 0x11010800,
+ 0x12010800, 0x12011000,
+ 0x13010800, 0x13011000};
+ struct dt_node *pau;
+ uint32_t links;
+
+ assert(pau_index < PAU_NBR);
+ pau = dt_new_addr(xscom, "pau", pau_base[pau_index]);
+
+ dt_add_property_cells(pau, "#size-cells", 0);
+ dt_add_property_cells(pau, "#address-cells", 1);
+ dt_add_property_cells(pau, "reg", pau_base[pau_index], 0x2c);
+ dt_add_property_string(pau, "compatible", "ibm,power10-pau");
+ dt_add_property_cells(pau, "ibm,pau-index", pau_index);
+
+ links = PAU_LINKS_OPENCAPI_PER_PAU;
+ for (uint32_t i = 0; i < links; i++)
+ pau_dt_create_link(pau, pau_index, i);
+}
+
+static bool pau_dt_create(void)
+{
+ struct dt_node *xscom;
+
+ /* P10 chips only */
+ if (proc_gen < proc_gen_p10)
+ return false;
+
+ dt_for_each_compatible(dt_root, xscom, "ibm,xscom")
+ for (uint32_t i = 0; i < PAU_NBR; i++)
+ pau_dt_create_pau(xscom, i);
+
+ return true;
+}
+
+static struct pau *pau_create(struct dt_node *dn)
+{
+ struct pau *pau;
+ struct dt_node *link;
+ struct pau_dev *dev;
+ char *path;
+ uint32_t i;
+
+ pau = zalloc(sizeof(*pau));
+ assert(pau);
+
+ init_lock(&pau->lock);
+
+ pau->dt_node = dn;
+ pau->index = dt_prop_get_u32(dn, "ibm,pau-index");
+ pau->xscom_base = dt_get_address(dn, 0, NULL);
+
+ pau->chip_id = dt_get_chip_id(dn);
+ assert(get_chip(pau->chip_id));
+
+ pau->links = PAU_LINKS_OPENCAPI_PER_PAU;
+ dt_for_each_compatible(dn, link, "ibm,pau-link") {
+ i = dt_prop_get_u32(link, "ibm,pau-link-index");
+ assert(i < PAU_LINKS_OPENCAPI_PER_PAU);
+
+ dev = &pau->devices[i];
+ dev->index = i;
+ dev->pau = pau;
+ dev->dn = link;
+ dev->odl_index = dt_prop_get_u32(link, "ibm,odl-index");
+ dev->op_unit = dt_prop_get_u32(link, "ibm,op-unit");
+ dev->phy_lane_mask = dt_prop_get_u32(link, "ibm,pau-lane-mask");
+ };
+
+ path = dt_get_path(dn);
+ PAUINF(pau, "Found %s\n", path);
+ PAUINF(pau, "SCOM base: 0x%llx\n", pau->xscom_base);
+ free(path);
+
+ return pau;
+}
+
+static void pau_device_detect_fixup(struct pau_dev *dev)
+{
+ struct dt_node *dn = dev->dn;
+
+ if (dev->type == PAU_DEV_TYPE_OPENCAPI) {
+ PAUDEVDBG(dev, "Link type opencapi\n");
+ dt_add_property_strings(dn, "ibm,pau-link-type", "opencapi");
+ return;
+ }
+
+ PAUDEVDBG(dev, "Link type unknown\n");
+ dt_add_property_strings(dn, "ibm,pau-link-type", "unknown");
+}
+
+static void pau_init(struct pau *pau)
+{
+ struct pau_dev *dev;
+
+ platform.pau_device_detect(pau);
+ pau_for_each_dev(dev, pau)
+ pau_device_detect_fixup(dev);
+
+}
+
+void probe_pau(void)
+{
+ struct dt_node *dn;
+ struct pau *pau;
+
+ /* This can be removed when/if we decide to use HDAT instead */
+ if (!pau_dt_create())
+ return;
+
+ if (!platform.pau_device_detect) {
+ prlog(PR_INFO, "PAU: Platform does not support PAU\n");
+ return;
+ }
+
+ dt_for_each_compatible(dt_root, dn, "ibm,power10-pau") {
+ pau = pau_create(dn);
+ pau_init(pau);
+ }
+}