All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] cxl: Abstract the differences between the PSL and XSL
@ 2016-05-23 17:39 Ian Munsie
  2016-05-27 12:48 ` Frederic Barrat
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Ian Munsie @ 2016-05-23 17:39 UTC (permalink / raw)
  To: Michael Ellerman, mikey, linuxppc-dev, Frederic Barrat, Huy Nguyen
  Cc: Frederic Barrat, Ian Munsie

From: Frederic Barrat <fbarrat@linux.vnet.ibm.com>

The XSL (Translation Service Layer) is a stripped down version of the
PSL (Power Service Layer) used in some cards such as the Mellanox CX4.

Like the PSL, it implements the CAIA architecture, but has a number of
differences, mostly in it's implementation dependent registers. This
adds an ops structure to abstract these differences to bring initial
support for XSL CAPI devices.

The XSL does not implement the optional architected SERR register,
however while it treats it as a reserved register and should work with
no special treatment, attempting to access it will cause the XSL_FEC
(First Error Capture) register to be filled out, preventing it from
capturing any subsequent errors. Therefore, this patch also prevents the
kernel from trying to set up the SERR register so that the FEC register
may still be useful, and to save one interrupt.

The XSL also uses a special DMA cxl mode, which uses a slightly
different init sequence for the CAPP and PHB. The kernel support for
this will be in a future patch once the corresponding support has been
merged into skiboot.

Co-authored-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
---
 drivers/misc/cxl/cxl.h     |  26 ++++++++
 drivers/misc/cxl/debugfs.c |  35 ++++++++---
 drivers/misc/cxl/native.c  |  53 +++++++++++-----
 drivers/misc/cxl/pci.c     | 152 ++++++++++++++++++++++++++++++++++++++-------
 4 files changed, 218 insertions(+), 48 deletions(-)

diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index d12a035..92e7f19 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -81,6 +81,7 @@ static const cxl_p1_reg_t CXL_PSL_TLBIA   = {0x00A8};
 static const cxl_p1_reg_t CXL_PSL_AFUSEL  = {0x00B0};
 
 /* 0x00C0:7EFF Implementation dependent area */
+/* PSL registers */
 static const cxl_p1_reg_t CXL_PSL_FIR1      = {0x0100};
 static const cxl_p1_reg_t CXL_PSL_FIR2      = {0x0108};
 static const cxl_p1_reg_t CXL_PSL_Timebase  = {0x0110};
@@ -91,6 +92,11 @@ static const cxl_p1_reg_t CXL_PSL_FIR_CNTL  = {0x0148};
 static const cxl_p1_reg_t CXL_PSL_DSNDCTL   = {0x0150};
 static const cxl_p1_reg_t CXL_PSL_SNWRALLOC = {0x0158};
 static const cxl_p1_reg_t CXL_PSL_TRACE     = {0x0170};
+/* XSL registers (Mellanox CX4) */
+static const cxl_p1_reg_t CXL_XSL_Timebase  = {0x0100};
+static const cxl_p1_reg_t CXL_XSL_TB_CTLSTAT = {0x0108};
+static const cxl_p1_reg_t CXL_XSL_FEC       = {0x0158};
+static const cxl_p1_reg_t CXL_XSL_DSNCTL    = {0x0168};
 /* 0x7F00:7FFF Reserved PCIe MSI-X Pending Bit Array area */
 /* 0x8000:FFFF Reserved PCIe MSI-X Table Area */
 
@@ -524,6 +530,20 @@ struct cxl_context {
 	struct rcu_head rcu;
 };
 
+struct cxl_service_layer_ops {
+	int (*adapter_regs_init)(struct cxl *adapter, struct pci_dev *dev);
+	int (*afu_regs_init)(struct cxl_afu *afu);
+	int (*register_serr_irq)(struct cxl_afu *afu);
+	void (*release_serr_irq)(struct cxl_afu *afu);
+	void (*debugfs_add_adapter_sl_regs)(struct cxl *adapter, struct dentry *dir);
+	void (*debugfs_add_afu_sl_regs)(struct cxl_afu *afu, struct dentry *dir);
+	void (*psl_irq_dump_registers)(struct cxl_context *ctx);
+	void (*err_irq_dump_registers)(struct cxl *adapter);
+	void (*debugfs_stop_trace)(struct cxl *adapter);
+	void (*write_timebase_ctrl)(struct cxl *adapter);
+	u64 (*timebase_read)(struct cxl *adapter);
+};
+
 struct cxl_native {
 	u64 afu_desc_off;
 	u64 afu_desc_size;
@@ -532,6 +552,7 @@ struct cxl_native {
 	irq_hw_number_t err_hwirq;
 	unsigned int err_virq;
 	u64 ps_off;
+	const struct cxl_service_layer_ops *sl_ops;
 };
 
 struct cxl_guest {
@@ -804,6 +825,11 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter);
 int cxl_afu_disable(struct cxl_afu *afu);
 int cxl_psl_purge(struct cxl_afu *afu);
 
+void cxl_debugfs_add_adapter_psl_regs(struct cxl *adapter, struct dentry *dir);
+void cxl_debugfs_add_adapter_xsl_regs(struct cxl *adapter, struct dentry *dir);
+void cxl_debugfs_add_afu_psl_regs(struct cxl_afu *afu, struct dentry *dir);
+void cxl_native_psl_irq_dump_regs(struct cxl_context *ctx);
+void cxl_native_err_irq_dump_regs(struct cxl *adapter);
 void cxl_stop_trace(struct cxl *cxl);
 int cxl_pci_vphb_add(struct cxl_afu *afu);
 void cxl_pci_vphb_remove(struct cxl_afu *afu);
diff --git a/drivers/misc/cxl/debugfs.c b/drivers/misc/cxl/debugfs.c
index 5751899..ec7b8a0 100644
--- a/drivers/misc/cxl/debugfs.c
+++ b/drivers/misc/cxl/debugfs.c
@@ -51,6 +51,19 @@ static struct dentry *debugfs_create_io_x64(const char *name, umode_t mode,
 	return debugfs_create_file(name, mode, parent, (void __force *)value, &fops_io_x64);
 }
 
+void cxl_debugfs_add_adapter_psl_regs(struct cxl *adapter, struct dentry *dir)
+{
+	debugfs_create_io_x64("fir1", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_FIR1));
+	debugfs_create_io_x64("fir2", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_FIR2));
+	debugfs_create_io_x64("fir_cntl", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_FIR_CNTL));
+	debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_TRACE));
+}
+
+void cxl_debugfs_add_adapter_xsl_regs(struct cxl *adapter, struct dentry *dir)
+{
+	debugfs_create_io_x64("fec", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_XSL_FEC));
+}
+
 int cxl_debugfs_adapter_add(struct cxl *adapter)
 {
 	struct dentry *dir;
@@ -65,13 +78,10 @@ int cxl_debugfs_adapter_add(struct cxl *adapter)
 		return PTR_ERR(dir);
 	adapter->debugfs = dir;
 
-	debugfs_create_io_x64("fir1",     S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_FIR1));
-	debugfs_create_io_x64("fir2",     S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_FIR2));
-	debugfs_create_io_x64("fir_cntl", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_FIR_CNTL));
 	debugfs_create_io_x64("err_ivte", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_ErrIVTE));
 
-	debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_TRACE));
-
+	if (adapter->native->sl_ops->debugfs_add_adapter_sl_regs)
+		adapter->native->sl_ops->debugfs_add_adapter_sl_regs(adapter, dir);
 	return 0;
 }
 
@@ -80,6 +90,14 @@ void cxl_debugfs_adapter_remove(struct cxl *adapter)
 	debugfs_remove_recursive(adapter->debugfs);
 }
 
+void cxl_debugfs_add_afu_psl_regs(struct cxl_afu *afu, struct dentry *dir)
+{
+	debugfs_create_io_x64("fir", S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_FIR_SLICE_An));
+	debugfs_create_io_x64("serr", S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SERR_An));
+	debugfs_create_io_x64("afu_debug", S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_AFU_DEBUG_An));
+	debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SLICE_TRACE));
+}
+
 int cxl_debugfs_afu_add(struct cxl_afu *afu)
 {
 	struct dentry *dir;
@@ -94,18 +112,15 @@ int cxl_debugfs_afu_add(struct cxl_afu *afu)
 		return PTR_ERR(dir);
 	afu->debugfs = dir;
 
-	debugfs_create_io_x64("fir",        S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_FIR_SLICE_An));
-	debugfs_create_io_x64("serr",       S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SERR_An));
-	debugfs_create_io_x64("afu_debug",  S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_AFU_DEBUG_An));
 	debugfs_create_io_x64("sr",         S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SR_An));
-
 	debugfs_create_io_x64("dsisr",      S_IRUSR, dir, _cxl_p2n_addr(afu, CXL_PSL_DSISR_An));
 	debugfs_create_io_x64("dar",        S_IRUSR, dir, _cxl_p2n_addr(afu, CXL_PSL_DAR_An));
 	debugfs_create_io_x64("sstp0",      S_IRUSR, dir, _cxl_p2n_addr(afu, CXL_SSTP0_An));
 	debugfs_create_io_x64("sstp1",      S_IRUSR, dir, _cxl_p2n_addr(afu, CXL_SSTP1_An));
 	debugfs_create_io_x64("err_status", S_IRUSR, dir, _cxl_p2n_addr(afu, CXL_PSL_ErrStat_An));
 
-	debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SLICE_TRACE));
+	if (afu->adapter->native->sl_ops->debugfs_add_afu_sl_regs)
+		afu->adapter->native->sl_ops->debugfs_add_afu_sl_regs(afu, dir);
 
 	return 0;
 }
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index aa0be79..45f3f09 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -794,26 +794,38 @@ static int native_get_irq_info(struct cxl_afu *afu, struct cxl_irq_info *info)
 	return 0;
 }
 
-static irqreturn_t native_handle_psl_slice_error(struct cxl_context *ctx,
-						u64 dsisr, u64 errstat)
+void cxl_native_psl_irq_dump_regs(struct cxl_context *ctx)
 {
 	u64 fir1, fir2, fir_slice, serr, afu_debug;
 
 	fir1 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR1);
 	fir2 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR2);
 	fir_slice = cxl_p1n_read(ctx->afu, CXL_PSL_FIR_SLICE_An);
-	serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An);
 	afu_debug = cxl_p1n_read(ctx->afu, CXL_AFU_DEBUG_An);
 
-	dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%016llx\n", errstat);
 	dev_crit(&ctx->afu->dev, "PSL_FIR1: 0x%016llx\n", fir1);
 	dev_crit(&ctx->afu->dev, "PSL_FIR2: 0x%016llx\n", fir2);
-	dev_crit(&ctx->afu->dev, "PSL_SERR_An: 0x%016llx\n", serr);
+	if (ctx->afu->adapter->native->sl_ops->register_serr_irq) {
+		serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An);
+		dev_crit(&ctx->afu->dev, "PSL_SERR_An: 0x%016llx\n", serr);
+	}
 	dev_crit(&ctx->afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice);
 	dev_crit(&ctx->afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug);
+}
+
+static irqreturn_t native_handle_psl_slice_error(struct cxl_context *ctx,
+						u64 dsisr, u64 errstat)
+{
+
+	dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%016llx\n", errstat);
 
-	dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n");
-	cxl_stop_trace(ctx->afu->adapter);
+	if (ctx->afu->adapter->native->sl_ops->psl_irq_dump_registers)
+		ctx->afu->adapter->native->sl_ops->psl_irq_dump_registers(ctx);
+
+	if (ctx->afu->adapter->native->sl_ops->debugfs_stop_trace) {
+		dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n");
+		ctx->afu->adapter->native->sl_ops->debugfs_stop_trace(ctx->afu->adapter);
+	}
 
 	return cxl_ops->ack_irq(ctx, 0, errstat);
 }
@@ -862,6 +874,9 @@ static irqreturn_t native_slice_irq_err(int irq, void *data)
 	struct cxl_afu *afu = data;
 	u64 fir_slice, errstat, serr, afu_debug;
 
+	/*
+	 * slice err interrupt is only used with full PSL (no XSL)
+	 */
 	WARN(irq, "CXL SLICE ERROR interrupt %i\n", irq);
 
 	serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
@@ -878,23 +893,33 @@ static irqreturn_t native_slice_irq_err(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+void cxl_native_err_irq_dump_regs(struct cxl *adapter)
+{
+	u64 fir1, fir2;
+
+	fir1 = cxl_p1_read(adapter, CXL_PSL_FIR1);
+	fir2 = cxl_p1_read(adapter, CXL_PSL_FIR2);
+
+	dev_crit(&adapter->dev, "PSL_FIR1: 0x%016llx\nPSL_FIR2: 0x%016llx\n", fir1, fir2);
+}
+
 static irqreturn_t native_irq_err(int irq, void *data)
 {
 	struct cxl *adapter = data;
-	u64 fir1, fir2, err_ivte;
+	u64 err_ivte;
 
 	WARN(1, "CXL ERROR interrupt %i\n", irq);
 
 	err_ivte = cxl_p1_read(adapter, CXL_PSL_ErrIVTE);
 	dev_crit(&adapter->dev, "PSL_ErrIVTE: 0x%016llx\n", err_ivte);
 
-	dev_crit(&adapter->dev, "STOPPING CXL TRACE\n");
-	cxl_stop_trace(adapter);
-
-	fir1 = cxl_p1_read(adapter, CXL_PSL_FIR1);
-	fir2 = cxl_p1_read(adapter, CXL_PSL_FIR2);
+	if (adapter->native->sl_ops->debugfs_stop_trace) {
+		dev_crit(&adapter->dev, "STOPPING CXL TRACE\n");
+		adapter->native->sl_ops->debugfs_stop_trace(adapter);
+	}
 
-	dev_crit(&adapter->dev, "PSL_FIR1: 0x%016llx\nPSL_FIR2: 0x%016llx\n", fir1, fir2);
+	if (adapter->native->sl_ops->err_irq_dump_registers)
+		adapter->native->sl_ops->err_irq_dump_registers(adapter);
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index a08fcc8..556718d 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -352,13 +352,10 @@ static u64 get_capp_unit_id(struct device_node *np)
 	return 0;
 }
 
-static int init_implementation_adapter_regs(struct cxl *adapter, struct pci_dev *dev)
+static int calc_capp_routing(struct pci_dev *dev, u64 *chipid, u64 *capp_unit_id)
 {
 	struct device_node *np;
 	const __be32 *prop;
-	u64 psl_dsnctl;
-	u64 chipid;
-	u64 capp_unit_id;
 
 	if (!(np = pnv_pci_get_phb_node(dev)))
 		return -ENODEV;
@@ -367,14 +364,28 @@ static int init_implementation_adapter_regs(struct cxl *adapter, struct pci_dev
 		np = of_get_next_parent(np);
 	if (!np)
 		return -ENODEV;
-	chipid = be32_to_cpup(prop);
-	capp_unit_id = get_capp_unit_id(np);
+	*chipid = be32_to_cpup(prop);
+	*capp_unit_id = get_capp_unit_id(np);
 	of_node_put(np);
-	if (!capp_unit_id) {
+	if (!*capp_unit_id) {
 		pr_err("cxl: invalid capp unit id\n");
 		return -ENODEV;
 	}
 
+	return 0;
+}
+
+static int init_implementation_adapter_psl_regs(struct cxl *adapter, struct pci_dev *dev)
+{
+	u64 psl_dsnctl;
+	u64 chipid;
+	u64 capp_unit_id;
+	int rc;
+
+	rc = calc_capp_routing(dev, &chipid, &capp_unit_id);
+	if (rc)
+		return rc;
+
 	psl_dsnctl = 0x0000900000000000ULL; /* pteupd ttype, scdone */
 	psl_dsnctl |= (0x2ULL << (63-38)); /* MMIO hang pulse: 256 us */
 	/* Tell PSL where to route data to */
@@ -393,8 +404,61 @@ static int init_implementation_adapter_regs(struct cxl *adapter, struct pci_dev
 	return 0;
 }
 
+static int init_implementation_adapter_xsl_regs(struct cxl *adapter, struct pci_dev *dev)
+{
+	u64 xsl_dsnctl;
+	u64 chipid;
+	u64 capp_unit_id;
+	int rc;
+
+	rc = calc_capp_routing(dev, &chipid, &capp_unit_id);
+	if (rc)
+		return rc;
+
+	/* Tell XSL where to route data to */
+	xsl_dsnctl = 0x0000600000000000ULL | (chipid << (63-5));
+	xsl_dsnctl |= (capp_unit_id << (63-13));
+	cxl_p1_write(adapter, CXL_XSL_DSNCTL, xsl_dsnctl);
+
+	return 0;
+}
+
+/* PSL & XSL */
+#define TBSYNC_CAL(n) (((u64)n & 0x7) << (63-3))
 #define TBSYNC_CNT(n) (((u64)n & 0x7) << (63-6))
-#define _2048_250MHZ_CYCLES 1
+/* For the PSL this is a multiple for 0 < n <= 7: */
+#define PSL_2048_250MHZ_CYCLES 1
+
+static void write_timebase_ctrl_psl(struct cxl *adapter)
+{
+	cxl_p1_write(adapter, CXL_PSL_TB_CTLSTAT,
+		     TBSYNC_CNT(2 * PSL_2048_250MHZ_CYCLES));
+}
+
+/* XSL */
+#define TBSYNC_ENA (1ULL << 63)
+/* For the XSL this is 2**n * 2000 clocks for 0 < n <= 6: */
+#define XSL_2000_CLOCKS 1
+#define XSL_4000_CLOCKS 2
+#define XSL_8000_CLOCKS 3
+
+static void write_timebase_ctrl_xsl(struct cxl *adapter)
+{
+	cxl_p1_write(adapter, CXL_XSL_TB_CTLSTAT,
+		     TBSYNC_ENA |
+		     TBSYNC_CAL(3) |
+		     TBSYNC_CNT(XSL_4000_CLOCKS));
+}
+
+static u64 timebase_read_psl(struct cxl *adapter)
+{
+	return cxl_p1_read(adapter, CXL_PSL_Timebase);
+}
+
+static u64 timebase_read_xsl(struct cxl *adapter)
+{
+	return cxl_p1_read(adapter, CXL_XSL_Timebase);
+}
 
 static void cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
 {
@@ -421,8 +485,7 @@ static void cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
 	 * Setup PSL Timebase Control and Status register
 	 * with the recommended Timebase Sync Count value
 	 */
-	cxl_p1_write(adapter, CXL_PSL_TB_CTLSTAT,
-		     TBSYNC_CNT(2 * _2048_250MHZ_CYCLES));
+	adapter->native->sl_ops->write_timebase_ctrl(adapter);
 
 	/* Enable PSL Timebase */
 	cxl_p1_write(adapter, CXL_PSL_Control, 0x0000000000000000);
@@ -435,7 +498,7 @@ static void cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
 			dev_info(&dev->dev, "PSL timebase can't synchronize\n");
 			return;
 		}
-		psl_tb = cxl_p1_read(adapter, CXL_PSL_Timebase);
+		psl_tb = adapter->native->sl_ops->timebase_read(adapter);
 		delta = mftb() - psl_tb;
 		if (delta < 0)
 			delta = -delta;
@@ -445,7 +508,7 @@ static void cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
 	return;
 }
 
-static int init_implementation_afu_regs(struct cxl_afu *afu)
+static int init_implementation_afu_psl_regs(struct cxl_afu *afu)
 {
 	/* read/write masks for this slice */
 	cxl_p1n_write(afu, CXL_PSL_APCALLOC_A, 0xFFFFFFFEFEFEFEFEULL);
@@ -753,11 +816,13 @@ static int sanitise_afu_regs(struct cxl_afu *afu)
 		else
 			cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);
 	}
-	reg = cxl_p1n_read(afu, CXL_PSL_SERR_An);
-	if (reg) {
-		if (reg & ~0xffff)
-			dev_warn(&afu->dev, "AFU had pending SERR: %#016llx\n", reg);
-		cxl_p1n_write(afu, CXL_PSL_SERR_An, reg & ~0xffff);
+	if (afu->adapter->native->sl_ops->register_serr_irq) {
+		reg = cxl_p1n_read(afu, CXL_PSL_SERR_An);
+		if (reg) {
+			if (reg & ~0xffff)
+				dev_warn(&afu->dev, "AFU had pending SERR: %#016llx\n", reg);
+			cxl_p1n_write(afu, CXL_PSL_SERR_An, reg & ~0xffff);
+		}
 	}
 	reg = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);
 	if (reg) {
@@ -835,11 +900,13 @@ static int pci_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pc
 	if ((rc = cxl_afu_descriptor_looks_ok(afu)))
 		goto err1;
 
-	if ((rc = init_implementation_afu_regs(afu)))
-		goto err1;
+	if (adapter->native->sl_ops->afu_regs_init)
+		if ((rc = adapter->native->sl_ops->afu_regs_init(afu)))
+			goto err1;
 
-	if ((rc = cxl_native_register_serr_irq(afu)))
-		goto err1;
+	if (adapter->native->sl_ops->register_serr_irq)
+		if ((rc = adapter->native->sl_ops->register_serr_irq(afu)))
+			goto err1;
 
 	if ((rc = cxl_native_register_psl_irq(afu)))
 		goto err2;
@@ -847,7 +914,8 @@ static int pci_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pc
 	return 0;
 
 err2:
-	cxl_native_release_serr_irq(afu);
+	if (adapter->native->sl_ops->release_serr_irq)
+		adapter->native->sl_ops->release_serr_irq(afu);
 err1:
 	pci_unmap_slice_regs(afu);
 	return rc;
@@ -856,7 +924,8 @@ err1:
 static void pci_deconfigure_afu(struct cxl_afu *afu)
 {
 	cxl_native_release_psl_irq(afu);
-	cxl_native_release_serr_irq(afu);
+	if (afu->adapter->native->sl_ops->release_serr_irq)
+		afu->adapter->native->sl_ops->release_serr_irq(afu);
 	pci_unmap_slice_regs(afu);
 }
 
@@ -1177,7 +1246,7 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev)
 	if ((rc = sanitise_adapter_regs(adapter)))
 		goto err;
 
-	if ((rc = init_implementation_adapter_regs(adapter, dev)))
+	if ((rc = adapter->native->sl_ops->adapter_regs_init(adapter, dev)))
 		goto err;
 
 	if ((rc = pnv_phb_to_cxl_mode(dev, OPAL_PHB_CAPI_MODE_CAPI)))
@@ -1212,6 +1281,39 @@ static void cxl_deconfigure_adapter(struct cxl *adapter)
 	pci_disable_device(pdev);
 }
 
+static const struct cxl_service_layer_ops psl_ops = {
+	.adapter_regs_init = init_implementation_adapter_psl_regs,
+	.afu_regs_init = init_implementation_afu_psl_regs,
+	.register_serr_irq = cxl_native_register_serr_irq,
+	.release_serr_irq = cxl_native_release_serr_irq,
+	.debugfs_add_adapter_sl_regs = cxl_debugfs_add_adapter_psl_regs,
+	.debugfs_add_afu_sl_regs = cxl_debugfs_add_afu_psl_regs,
+	.psl_irq_dump_registers = cxl_native_psl_irq_dump_regs,
+	.err_irq_dump_registers = cxl_native_err_irq_dump_regs,
+	.debugfs_stop_trace = cxl_stop_trace,
+	.write_timebase_ctrl = write_timebase_ctrl_psl,
+	.timebase_read = timebase_read_psl,
+};
+
+static const struct cxl_service_layer_ops xsl_ops = {
+	.adapter_regs_init = init_implementation_adapter_xsl_regs,
+	.debugfs_add_adapter_sl_regs = cxl_debugfs_add_adapter_xsl_regs,
+	.write_timebase_ctrl = write_timebase_ctrl_xsl,
+	.timebase_read = timebase_read_xsl,
+};
+
+static void set_sl_ops(struct cxl *adapter, struct pci_dev *dev)
+{
+	if (dev->vendor == PCI_VENDOR_ID_MELLANOX && dev->device == 0x1013) {
+		dev_info(&adapter->dev, "Device uses an XSL\n");
+		adapter->native->sl_ops = &xsl_ops;
+	} else {
+		dev_info(&adapter->dev, "Device uses a PSL\n");
+		adapter->native->sl_ops = &psl_ops;
+	}
+}
+
+
 static struct cxl *cxl_pci_init_adapter(struct pci_dev *dev)
 {
 	struct cxl *adapter;
@@ -1227,6 +1329,8 @@ static struct cxl *cxl_pci_init_adapter(struct pci_dev *dev)
 		goto err_release;
 	}
 
+	set_sl_ops(adapter, dev);
+
 	/* Set defaults for parameters which need to persist over
 	 * configure/reconfigure
 	 */
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] cxl: Abstract the differences between the PSL and XSL
  2016-05-23 17:39 [PATCH] cxl: Abstract the differences between the PSL and XSL Ian Munsie
@ 2016-05-27 12:48 ` Frederic Barrat
  2016-05-27 13:06 ` John W Walthour
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Frederic Barrat @ 2016-05-27 12:48 UTC (permalink / raw)
  To: Ian Munsie, Michael Ellerman, mikey, linuxppc-dev,
	Frederic Barrat, Huy Nguyen

Hi Ian,

It looks good, just one question:

> +/* XSL registers (Mellanox CX4) */
> +static const cxl_p1_reg_t CXL_XSL_Timebase  = {0x0100};
> +static const cxl_p1_reg_t CXL_XSL_TB_CTLSTAT = {0x0108};
> +static const cxl_p1_reg_t CXL_XSL_FEC       = {0x0158};
> +static const cxl_p1_reg_t CXL_XSL_DSNCTL    = {0x0168};

Out of curiosity, in which document did you get those offsets from? I 
remember there used to be some confusion about it. All I could find was 
the internal offsets the firmware remaps those to (in xsl databook).

Feel free to grab the "From:", since the patch has evolved since I 
worked on it. I don't care.

   Fred

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] cxl: Abstract the differences between the PSL and XSL
  2016-05-23 17:39 [PATCH] cxl: Abstract the differences between the PSL and XSL Ian Munsie
  2016-05-27 12:48 ` Frederic Barrat
@ 2016-05-27 13:06 ` John W Walthour
       [not found] ` <20160527130754.71F7DBE03E@b03ledav005.gho.boulder.ibm.com>
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: John W Walthour @ 2016-05-27 13:06 UTC (permalink / raw)
  To: fbarrat; +Cc: frederic.barrat, huyn, imunsie, linuxppc-dev, mikey, mpe

[-- Attachment #1: Type: text/html, Size: 2992 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] cxl: Abstract the differences between the PSL and XSL
       [not found] ` <20160527130754.71F7DBE03E@b03ledav005.gho.boulder.ibm.com>
@ 2016-05-30 23:01   ` Michael Ellerman
  2016-05-30 23:28     ` Andrew Donnellan
  0 siblings, 1 reply; 10+ messages in thread
From: Michael Ellerman @ 2016-05-30 23:01 UTC (permalink / raw)
  To: John W Walthour, fbarrat
  Cc: frederic.barrat, huyn, imunsie, linuxppc-dev, mikey

On Fri, 2016-05-27 at 13:06 +0000, John W Walthour wrote:

>  
> Those come from
> XSL_databook_09_June_2014.pdf

Where do I find that?

cheers

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] cxl: Abstract the differences between the PSL and XSL
  2016-05-30 23:01   ` Michael Ellerman
@ 2016-05-30 23:28     ` Andrew Donnellan
  0 siblings, 0 replies; 10+ messages in thread
From: Andrew Donnellan @ 2016-05-30 23:28 UTC (permalink / raw)
  To: Michael Ellerman, John W Walthour, fbarrat
  Cc: huyn, mikey, linuxppc-dev, imunsie, frederic.barrat

On 31/05/16 09:01, Michael Ellerman wrote:
>> Those come from
>> XSL_databook_09_June_2014.pdf
>
> Where do I find that?

My understanding is that it's IBM Confidential and isn't available to 
the general community, unfortunately.


Andrew

-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan@au1.ibm.com  IBM Australia Limited

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH, RFC] cxl: Add support for CAPP DMA mode
  2016-05-23 17:39 [PATCH] cxl: Abstract the differences between the PSL and XSL Ian Munsie
                   ` (2 preceding siblings ...)
       [not found] ` <20160527130754.71F7DBE03E@b03ledav005.gho.boulder.ibm.com>
@ 2016-06-08  5:09 ` Ian Munsie
  2016-06-08  7:46   ` Stewart Smith
                     ` (2 more replies)
  2016-06-21  0:40 ` cxl: Abstract the differences between the PSL and XSL Michael Ellerman
  4 siblings, 3 replies; 10+ messages in thread
From: Ian Munsie @ 2016-06-08  5:09 UTC (permalink / raw)
  To: Michael Ellerman, mikey, linuxppc-dev, Frederic Barrat, Huy Nguyen
  Cc: Ian Munsie

From: Ian Munsie <imunsie@au1.ibm.com>

This adds support for using CAPP DMA mode, which is required for XSL
based cards such as the Mellanox CX4 to function.

This is currently an RFC as it depends on the corresponding support to
be merged into skiboot first, which was submitted here:
http://patchwork.ozlabs.org/patch/625582/

In the event that the skiboot on the system does not have the above
support, it will indicate as such in the kernel log and abort the init
process.

Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
---
 arch/powerpc/include/asm/opal-api.h       | 1 +
 arch/powerpc/platforms/powernv/pci-ioda.c | 4 +++-
 drivers/misc/cxl/cxl.h                    | 1 +
 drivers/misc/cxl/pci.c                    | 4 +++-
 4 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index 9bb8ddf..d29c584 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -825,6 +825,7 @@ enum {
 	OPAL_PHB_CAPI_MODE_CAPI		= 1,
 	OPAL_PHB_CAPI_MODE_SNOOP_OFF    = 2,
 	OPAL_PHB_CAPI_MODE_SNOOP_ON	= 3,
+	OPAL_PHB_CAPI_MODE_DMA		= 4,
 };
 
 /* OPAL I2C request */
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 3a5ea82..5a42e98 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2793,7 +2793,9 @@ int pnv_phb_to_cxl_mode(struct pci_dev *dev, uint64_t mode)
 	pe_info(pe, "Switching PHB to CXL\n");
 
 	rc = opal_pci_set_phb_cxl_mode(phb->opal_id, mode, pe->pe_number);
-	if (rc)
+	if (rc == OPAL_UNSUPPORTED)
+		dev_err(&dev->dev, "Required cxl mode not supported by firmware - update skiboot\n");
+	else if (rc)
 		dev_err(&dev->dev, "opal_pci_set_phb_cxl_mode failed: %i\n", rc);
 
 	return rc;
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index 92e7f19..aa69a84 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -542,6 +542,7 @@ struct cxl_service_layer_ops {
 	void (*debugfs_stop_trace)(struct cxl *adapter);
 	void (*write_timebase_ctrl)(struct cxl *adapter);
 	u64 (*timebase_read)(struct cxl *adapter);
+	int capi_mode;
 };
 
 struct cxl_native {
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 556718d..648817a 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -1249,7 +1249,7 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev)
 	if ((rc = adapter->native->sl_ops->adapter_regs_init(adapter, dev)))
 		goto err;
 
-	if ((rc = pnv_phb_to_cxl_mode(dev, OPAL_PHB_CAPI_MODE_CAPI)))
+	if ((rc = pnv_phb_to_cxl_mode(dev, adapter->native->sl_ops->capi_mode)))
 		goto err;
 
 	/* If recovery happened, the last step is to turn on snooping.
@@ -1293,6 +1293,7 @@ static const struct cxl_service_layer_ops psl_ops = {
 	.debugfs_stop_trace = cxl_stop_trace,
 	.write_timebase_ctrl = write_timebase_ctrl_psl,
 	.timebase_read = timebase_read_psl,
+	.capi_mode = OPAL_PHB_CAPI_MODE_CAPI,
 };
 
 static const struct cxl_service_layer_ops xsl_ops = {
@@ -1300,6 +1301,7 @@ static const struct cxl_service_layer_ops xsl_ops = {
 	.debugfs_add_adapter_sl_regs = cxl_debugfs_add_adapter_xsl_regs,
 	.write_timebase_ctrl = write_timebase_ctrl_xsl,
 	.timebase_read = timebase_read_xsl,
+	.capi_mode = OPAL_PHB_CAPI_MODE_DMA,
 };
 
 static void set_sl_ops(struct cxl *adapter, struct pci_dev *dev)
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH, RFC] cxl: Add support for CAPP DMA mode
  2016-06-08  5:09 ` [PATCH, RFC] cxl: Add support for CAPP DMA mode Ian Munsie
@ 2016-06-08  7:46   ` Stewart Smith
  2016-06-09  5:49   ` Stewart Smith
  2016-06-21  0:40   ` [RFC] " Michael Ellerman
  2 siblings, 0 replies; 10+ messages in thread
From: Stewart Smith @ 2016-06-08  7:46 UTC (permalink / raw)
  To: Ian Munsie, Michael Ellerman, mikey, linuxppc-dev,
	Frederic Barrat, Huy Nguyen
  Cc: Ian Munsie

Ian Munsie <imunsie@au1.ibm.com> writes:
> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
> index 3a5ea82..5a42e98 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
> @@ -2793,7 +2793,9 @@ int pnv_phb_to_cxl_mode(struct pci_dev *dev, uint64_t mode)
>  	pe_info(pe, "Switching PHB to CXL\n");
>  
>  	rc = opal_pci_set_phb_cxl_mode(phb->opal_id, mode, pe->pe_number);
> -	if (rc)
> +	if (rc == OPAL_UNSUPPORTED)
> +		dev_err(&dev->dev, "Required cxl mode not supported by firmware - update skiboot\n");
> +	else if (rc)
>  		dev_err(&dev->dev, "opal_pci_set_phb_cxl_mode failed:
> %i\n", rc);

Could mention version required, which would be skiboot 5.3.x or higher.

This could be something we start doing - there's enough random bits of
functionality we could tell the user exactly what they have to upgrade
to to have work.

-- 
Stewart Smith
OPAL Architect, IBM.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH, RFC] cxl: Add support for CAPP DMA mode
  2016-06-08  5:09 ` [PATCH, RFC] cxl: Add support for CAPP DMA mode Ian Munsie
  2016-06-08  7:46   ` Stewart Smith
@ 2016-06-09  5:49   ` Stewart Smith
  2016-06-21  0:40   ` [RFC] " Michael Ellerman
  2 siblings, 0 replies; 10+ messages in thread
From: Stewart Smith @ 2016-06-09  5:49 UTC (permalink / raw)
  To: Ian Munsie, Michael Ellerman, mikey, linuxppc-dev,
	Frederic Barrat, Huy Nguyen
  Cc: Ian Munsie

Ian Munsie <imunsie@au1.ibm.com> writes:

> From: Ian Munsie <imunsie@au1.ibm.com>
>
> This adds support for using CAPP DMA mode, which is required for XSL
> based cards such as the Mellanox CX4 to function.
>
> This is currently an RFC as it depends on the corresponding support to
> be merged into skiboot first, which was submitted here:
> http://patchwork.ozlabs.org/patch/625582/

Merged to skiboot as of 5477148a439fda9fb55ea4a828c958fcdcc10f2e - which
will make it into skiboot 5.3.x

-- 
Stewart Smith
OPAL Architect, IBM.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: cxl: Abstract the differences between the PSL and XSL
  2016-05-23 17:39 [PATCH] cxl: Abstract the differences between the PSL and XSL Ian Munsie
                   ` (3 preceding siblings ...)
  2016-06-08  5:09 ` [PATCH, RFC] cxl: Add support for CAPP DMA mode Ian Munsie
@ 2016-06-21  0:40 ` Michael Ellerman
  4 siblings, 0 replies; 10+ messages in thread
From: Michael Ellerman @ 2016-06-21  0:40 UTC (permalink / raw)
  To: Ian Munsie, mikey, linuxppc-dev, Frederic Barrat, Huy Nguyen
  Cc: Ian Munsie, Frederic Barrat

On Mon, 2016-23-05 at 17:39:18 UTC, Ian Munsie wrote:
> From: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
> 
> The XSL (Translation Service Layer) is a stripped down version of the
> PSL (Power Service Layer) used in some cards such as the Mellanox CX4.
> 
> Like the PSL, it implements the CAIA architecture, but has a number of
> differences, mostly in it's implementation dependent registers. This
> adds an ops structure to abstract these differences to bring initial
> support for XSL CAPI devices.
> 
> The XSL does not implement the optional architected SERR register,
> however while it treats it as a reserved register and should work with
> no special treatment, attempting to access it will cause the XSL_FEC
> (First Error Capture) register to be filled out, preventing it from
> capturing any subsequent errors. Therefore, this patch also prevents the
> kernel from trying to set up the SERR register so that the FEC register
> may still be useful, and to save one interrupt.
> 
> The XSL also uses a special DMA cxl mode, which uses a slightly
> different init sequence for the CAPP and PHB. The kernel support for
> this will be in a future patch once the corresponding support has been
> merged into skiboot.
> 
> Co-authored-by: Ian Munsie <imunsie@au1.ibm.com>
> Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/6d382616ac2283ed65c7a6a52d

cheers

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] cxl: Add support for CAPP DMA mode
  2016-06-08  5:09 ` [PATCH, RFC] cxl: Add support for CAPP DMA mode Ian Munsie
  2016-06-08  7:46   ` Stewart Smith
  2016-06-09  5:49   ` Stewart Smith
@ 2016-06-21  0:40   ` Michael Ellerman
  2 siblings, 0 replies; 10+ messages in thread
From: Michael Ellerman @ 2016-06-21  0:40 UTC (permalink / raw)
  To: Ian Munsie, mikey, linuxppc-dev, Frederic Barrat, Huy Nguyen; +Cc: Ian Munsie

On Wed, 2016-08-06 at 05:09:54 UTC, Ian Munsie wrote:
> From: Ian Munsie <imunsie@au1.ibm.com>
> 
> This adds support for using CAPP DMA mode, which is required for XSL
> based cards such as the Mellanox CX4 to function.
> 
> This is currently an RFC as it depends on the corresponding support to
> be merged into skiboot first, which was submitted here:
> http://patchwork.ozlabs.org/patch/625582/
> 
> In the event that the skiboot on the system does not have the above
> support, it will indicate as such in the kernel log and abort the init
> process.
> 
> Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/b385c9e971468eb8816b267424

cheers

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-06-21  0:40 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-23 17:39 [PATCH] cxl: Abstract the differences between the PSL and XSL Ian Munsie
2016-05-27 12:48 ` Frederic Barrat
2016-05-27 13:06 ` John W Walthour
     [not found] ` <20160527130754.71F7DBE03E@b03ledav005.gho.boulder.ibm.com>
2016-05-30 23:01   ` Michael Ellerman
2016-05-30 23:28     ` Andrew Donnellan
2016-06-08  5:09 ` [PATCH, RFC] cxl: Add support for CAPP DMA mode Ian Munsie
2016-06-08  7:46   ` Stewart Smith
2016-06-09  5:49   ` Stewart Smith
2016-06-21  0:40   ` [RFC] " Michael Ellerman
2016-06-21  0:40 ` cxl: Abstract the differences between the PSL and XSL Michael Ellerman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.