openbmc.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/14] fsi: Fixes and Coldfire coprocessor offload
@ 2018-06-26 23:23 Benjamin Herrenschmidt
  2018-06-26 23:23 ` [PATCH 01/14] devres: Add devm_of_iomap() Benjamin Herrenschmidt
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2018-06-26 23:23 UTC (permalink / raw)
  To: Joel Stanley
  Cc: linux-aspeed, openbmc, devicetree, Andrew Jeffery, linux-kernel

This series implements support for offloading the FSI protocol bitbanging
to the ColdFire secondary core of the Aspeed SoCs. The result increases
FSI performance by a factor of 4, and on systems that don't support async
FSI clock, provide much more regular and continuous clocking which helps
reliability.

Patch 1 may go a different route and was already posted a few weeks ago,
I included it for completeness.

Patches 2..9 add some infrastructure to the FSI core to control some
of the FSI protocol delays and adjustements/fixes to the existing GPIO
bitbanging master. They are "mechanical" dependencies

Patch 10 moves some protocol definitions to a common place where the
new master driver can find them

Patch 11 is the DT binding for the new driver with comes with patch 12

Finally patch 13 and 14 update the Romulus and Palmetto board device-trees
to use the new driver.

There's another dependency on the Aspeed GPIO driver changes for handling
with GPIO lines ownership and handshaking. The patches have been submitted
and can be found for reference there:

        https://github.com/ozbenh/linux-ast/commits/gpio

Finally, the driver needs a machine specific firmware file. The firwmare
is open source and available at:

        https://github.com/ozbenh/cf-fsi

I will submit it to linux-firmware if there's enough popular demand ;-)

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

* [PATCH 01/14] devres: Add devm_of_iomap()
  2018-06-26 23:23 [PATCH 00/14] fsi: Fixes and Coldfire coprocessor offload Benjamin Herrenschmidt
@ 2018-06-26 23:23 ` Benjamin Herrenschmidt
  2018-06-26 23:23 ` [PATCH 02/14] fsi: Move code around to avoid forward declaration Benjamin Herrenschmidt
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2018-06-26 23:23 UTC (permalink / raw)
  To: Joel Stanley
  Cc: linux-aspeed, openbmc, devicetree, Andrew Jeffery, linux-kernel,
	Benjamin Herrenschmidt

There are still quite a few cases where a device might want
to get to a different node of the device-tree, obtain the
resources and map them.

We have of_iomap() and of_io_request_and_map() but they both
have shortcomings, such as not returning the size of the
resource found (which can be useful) and not being "managed".

This adds a devm_of_iomap() that provides all of these and
should probably replace uses of the above in most drivers.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 include/linux/device.h |  4 ++++
 lib/devres.c           | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/include/linux/device.h b/include/linux/device.h
index 477956990f5e..96249d790374 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -688,6 +688,10 @@ extern void devm_free_pages(struct device *dev, unsigned long addr);
 
 void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
 
+void __iomem *devm_of_iomap(struct device *dev,
+			    struct device_node *node, int index,
+			    resource_size_t *size);
+
 /* allows to add/remove a custom action to devres stack */
 int devm_add_action(struct device *dev, void (*action)(void *), void *data);
 void devm_remove_action(struct device *dev, void (*action)(void *), void *data);
diff --git a/lib/devres.c b/lib/devres.c
index 5bec1120b392..faccf1a037d0 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -4,6 +4,7 @@
 #include <linux/io.h>
 #include <linux/gfp.h>
 #include <linux/export.h>
+#include <linux/of_address.h>
 
 enum devm_ioremap_type {
 	DEVM_IOREMAP = 0,
@@ -162,6 +163,41 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res)
 }
 EXPORT_SYMBOL(devm_ioremap_resource);
 
+/*
+ * devm_of_iomap - Requests a resource and maps the memory mapped IO
+ *		   for a given device_node managed by a given device
+ *
+ * Checks that a resource is a valid memory region, requests the memory
+ * region and ioremaps it. All operations are managed and will be undone
+ * on driver detach of the device.
+ *
+ * This is to be used when a device requests/maps resources described
+ * by other device tree nodes (children or otherwise).
+ *
+ * @dev:	The device "managing" the resource
+ * @node:       The device-tree node where the resource resides
+ * @index:	index of the MMIO range in the "reg" property
+ * @size:	Returns the size of the resource (pass NULL if not needed)
+ * Returns a pointer to the requested and mapped memory or an ERR_PTR() encoded
+ * error code on failure. Usage example:
+ *
+ *	base = devm_of_iomap(&pdev->dev, node, 0, NULL);
+ *	if (IS_ERR(base))
+ *		return PTR_ERR(base);
+ */
+void __iomem *devm_of_iomap(struct device *dev, struct device_node *node, int index,
+			    resource_size_t *size)
+{
+	struct resource res;
+
+	if (of_address_to_resource(node, index, &res))
+		return IOMEM_ERR_PTR(-EINVAL);
+	if (size)
+		*size = resource_size(&res);
+	return devm_ioremap_resource(dev, &res);
+}
+EXPORT_SYMBOL(devm_of_iomap);
+
 #ifdef CONFIG_HAS_IOPORT_MAP
 /*
  * Generic iomap devres
-- 
2.17.1

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

* [PATCH 02/14] fsi: Move code around to avoid forward declaration
  2018-06-26 23:23 [PATCH 00/14] fsi: Fixes and Coldfire coprocessor offload Benjamin Herrenschmidt
  2018-06-26 23:23 ` [PATCH 01/14] devres: Add devm_of_iomap() Benjamin Herrenschmidt
@ 2018-06-26 23:23 ` Benjamin Herrenschmidt
  2018-06-28  4:10   ` Joel Stanley
  2018-06-26 23:23 ` [PATCH 03/14] fsi: Add mechanism to set the tSendDelay and tEchoDelay values Benjamin Herrenschmidt
  2018-06-26 23:23 ` [PATCH 04/14] fsi: master-gpio: Rename and adjust send delay Benjamin Herrenschmidt
  3 siblings, 1 reply; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2018-06-26 23:23 UTC (permalink / raw)
  To: Joel Stanley
  Cc: linux-aspeed, openbmc, devicetree, Andrew Jeffery, linux-kernel,
	Benjamin Herrenschmidt

Move fsi_slave_set_smode() and its helpers to before it's
first user and remove the corresponding forward declaration.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 drivers/fsi/fsi-core.c | 94 +++++++++++++++++++++---------------------
 1 file changed, 46 insertions(+), 48 deletions(-)

diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index 565218872635..2f6f9b8c75e4 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -215,7 +215,52 @@ static int fsi_slave_report_and_clear_errors(struct fsi_slave *slave)
 			&irq, sizeof(irq));
 }
 
-static int fsi_slave_set_smode(struct fsi_master *master, int link, int id);
+/* Encode slave local bus echo delay */
+static inline uint32_t fsi_smode_echodly(int x)
+{
+	return (x & FSI_SMODE_ED_MASK) << FSI_SMODE_ED_SHIFT;
+}
+
+/* Encode slave local bus send delay */
+static inline uint32_t fsi_smode_senddly(int x)
+{
+	return (x & FSI_SMODE_SD_MASK) << FSI_SMODE_SD_SHIFT;
+}
+
+/* Encode slave local bus clock rate ratio */
+static inline uint32_t fsi_smode_lbcrr(int x)
+{
+	return (x & FSI_SMODE_LBCRR_MASK) << FSI_SMODE_LBCRR_SHIFT;
+}
+
+/* Encode slave ID */
+static inline uint32_t fsi_smode_sid(int x)
+{
+	return (x & FSI_SMODE_SID_MASK) << FSI_SMODE_SID_SHIFT;
+}
+
+static uint32_t fsi_slave_smode(int id)
+{
+	return FSI_SMODE_WSC | FSI_SMODE_ECRC
+		| fsi_smode_sid(id)
+		| fsi_smode_echodly(0xf) | fsi_smode_senddly(0xf)
+		| fsi_smode_lbcrr(0x8);
+}
+
+static int fsi_slave_set_smode(struct fsi_master *master, int link, int id)
+{
+	uint32_t smode;
+	__be32 data;
+
+	/* set our smode register with the slave ID field to 0; this enables
+	 * extended slave addressing
+	 */
+	smode = fsi_slave_smode(id);
+	data = cpu_to_be32(smode);
+
+	return fsi_master_write(master, link, id, FSI_SLAVE_BASE + FSI_SMODE,
+			&data, sizeof(data));
+}
 
 static int fsi_slave_handle_error(struct fsi_slave *slave, bool write,
 				  uint32_t addr, size_t size)
@@ -569,53 +614,6 @@ static const struct bin_attribute fsi_slave_term_attr = {
 	.write = fsi_slave_sysfs_term_write,
 };
 
-/* Encode slave local bus echo delay */
-static inline uint32_t fsi_smode_echodly(int x)
-{
-	return (x & FSI_SMODE_ED_MASK) << FSI_SMODE_ED_SHIFT;
-}
-
-/* Encode slave local bus send delay */
-static inline uint32_t fsi_smode_senddly(int x)
-{
-	return (x & FSI_SMODE_SD_MASK) << FSI_SMODE_SD_SHIFT;
-}
-
-/* Encode slave local bus clock rate ratio */
-static inline uint32_t fsi_smode_lbcrr(int x)
-{
-	return (x & FSI_SMODE_LBCRR_MASK) << FSI_SMODE_LBCRR_SHIFT;
-}
-
-/* Encode slave ID */
-static inline uint32_t fsi_smode_sid(int x)
-{
-	return (x & FSI_SMODE_SID_MASK) << FSI_SMODE_SID_SHIFT;
-}
-
-static uint32_t fsi_slave_smode(int id)
-{
-	return FSI_SMODE_WSC | FSI_SMODE_ECRC
-		| fsi_smode_sid(id)
-		| fsi_smode_echodly(0xf) | fsi_smode_senddly(0xf)
-		| fsi_smode_lbcrr(0x8);
-}
-
-static int fsi_slave_set_smode(struct fsi_master *master, int link, int id)
-{
-	uint32_t smode;
-	__be32 data;
-
-	/* set our smode register with the slave ID field to 0; this enables
-	 * extended slave addressing
-	 */
-	smode = fsi_slave_smode(id);
-	data = cpu_to_be32(smode);
-
-	return fsi_master_write(master, link, id, FSI_SLAVE_BASE + FSI_SMODE,
-			&data, sizeof(data));
-}
-
 static void fsi_slave_release(struct device *dev)
 {
 	struct fsi_slave *slave = to_fsi_slave(dev);
-- 
2.17.1

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

* [PATCH 03/14] fsi: Add mechanism to set the tSendDelay and tEchoDelay values
  2018-06-26 23:23 [PATCH 00/14] fsi: Fixes and Coldfire coprocessor offload Benjamin Herrenschmidt
  2018-06-26 23:23 ` [PATCH 01/14] devres: Add devm_of_iomap() Benjamin Herrenschmidt
  2018-06-26 23:23 ` [PATCH 02/14] fsi: Move code around to avoid forward declaration Benjamin Herrenschmidt
@ 2018-06-26 23:23 ` Benjamin Herrenschmidt
  2018-06-26 23:23 ` [PATCH 04/14] fsi: master-gpio: Rename and adjust send delay Benjamin Herrenschmidt
  3 siblings, 0 replies; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2018-06-26 23:23 UTC (permalink / raw)
  To: Joel Stanley
  Cc: linux-aspeed, openbmc, devicetree, Andrew Jeffery, linux-kernel,
	Benjamin Herrenschmidt

Those values control the amount of "dummy" clocks between commands and
between a command and its response.

This adds a way to configure them from sysfs (to be later extended to
defaults in the device-tree). The default remains 16 (the HW default).

This is only supported if the backend supports the new link_config()
callback to configure the generation of those delays.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
---
 drivers/fsi/fsi-core.c   | 109 ++++++++++++++++++++++++++++++++-------
 drivers/fsi/fsi-master.h |   2 +
 2 files changed, 93 insertions(+), 18 deletions(-)

diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index 2f6f9b8c75e4..1ae5be31b4bf 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -81,6 +81,8 @@ struct fsi_slave {
 	int			id;
 	int			link;
 	uint32_t		size;	/* size of slave address space */
+	u8			t_send_delay;
+	u8			t_echo_delay;
 };
 
 #define to_fsi_master(d) container_of(d, struct fsi_master, dev)
@@ -239,15 +241,15 @@ static inline uint32_t fsi_smode_sid(int x)
 	return (x & FSI_SMODE_SID_MASK) << FSI_SMODE_SID_SHIFT;
 }
 
-static uint32_t fsi_slave_smode(int id)
+static uint32_t fsi_slave_smode(int id, u8 t_senddly, u8 t_echodly)
 {
 	return FSI_SMODE_WSC | FSI_SMODE_ECRC
 		| fsi_smode_sid(id)
-		| fsi_smode_echodly(0xf) | fsi_smode_senddly(0xf)
+		| fsi_smode_echodly(t_echodly - 1) | fsi_smode_senddly(t_senddly - 1)
 		| fsi_smode_lbcrr(0x8);
 }
 
-static int fsi_slave_set_smode(struct fsi_master *master, int link, int id)
+static int fsi_slave_set_smode(struct fsi_slave *slave)
 {
 	uint32_t smode;
 	__be32 data;
@@ -255,11 +257,12 @@ static int fsi_slave_set_smode(struct fsi_master *master, int link, int id)
 	/* set our smode register with the slave ID field to 0; this enables
 	 * extended slave addressing
 	 */
-	smode = fsi_slave_smode(id);
+	smode = fsi_slave_smode(slave->id, slave->t_send_delay, slave->t_echo_delay);
 	data = cpu_to_be32(smode);
 
-	return fsi_master_write(master, link, id, FSI_SLAVE_BASE + FSI_SMODE,
-			&data, sizeof(data));
+	return fsi_master_write(slave->master, slave->link, slave->id,
+				FSI_SLAVE_BASE + FSI_SMODE,
+				&data, sizeof(data));
 }
 
 static int fsi_slave_handle_error(struct fsi_slave *slave, bool write,
@@ -268,7 +271,7 @@ static int fsi_slave_handle_error(struct fsi_slave *slave, bool write,
 	struct fsi_master *master = slave->master;
 	int rc, link;
 	uint32_t reg;
-	uint8_t id;
+	uint8_t id, send_delay, echo_delay;
 
 	if (discard_errors)
 		return -1;
@@ -299,15 +302,26 @@ static int fsi_slave_handle_error(struct fsi_slave *slave, bool write,
 		}
 	}
 
+	send_delay = slave->t_send_delay;
+	echo_delay = slave->t_echo_delay;
+
 	/* getting serious, reset the slave via BREAK */
 	rc = fsi_master_break(master, link);
 	if (rc)
 		return rc;
 
-	rc = fsi_slave_set_smode(master, link, id);
+	slave->t_send_delay = send_delay;
+	slave->t_echo_delay = echo_delay;
+
+	rc = fsi_slave_set_smode(slave);
 	if (rc)
 		return rc;
 
+	if (master->link_config)
+		master->link_config(master, link,
+				    slave->t_send_delay,
+				    slave->t_echo_delay);
+
 	return fsi_slave_report_and_clear_errors(slave);
 }
 
@@ -665,6 +679,50 @@ static struct device_node *fsi_slave_find_of_node(struct fsi_master *master,
 	return NULL;
 }
 
+static ssize_t slave_send_echo_show(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	struct fsi_slave *slave = to_fsi_slave(dev);
+
+	return sprintf(buf, "%u\n", slave->t_send_delay);
+}
+
+static ssize_t slave_send_echo_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct fsi_slave *slave = to_fsi_slave(dev);
+	struct fsi_master *master = slave->master;
+	unsigned long val;
+	int rc;
+
+	if (kstrtoul(buf, 0, &val) < 0)
+		return -EINVAL;
+
+	if (val < 1 || val > 16)
+		return -EINVAL;
+
+	if (!master->link_config)
+		return -ENXIO;
+
+	/* Current HW mandates that send and echo delay are identical */
+	slave->t_send_delay = val;
+	slave->t_echo_delay = val;
+
+	rc = fsi_slave_set_smode(slave);
+	if (rc < 0)
+		return rc;
+	if (master->link_config)
+		master->link_config(master, slave->link,
+				    slave->t_send_delay,
+				    slave->t_echo_delay);
+
+	return count;
+}
+
+static DEVICE_ATTR(send_echo_delays, 0600,
+		   slave_send_echo_show, slave_send_echo_store);
+
 static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
 {
 	uint32_t chip_id;
@@ -697,14 +755,6 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
 	dev_dbg(&master->dev, "fsi: found chip %08x at %02x:%02x:%02x\n",
 			chip_id, master->idx, link, id);
 
-	rc = fsi_slave_set_smode(master, link, id);
-	if (rc) {
-		dev_warn(&master->dev,
-				"can't set smode on slave:%02x:%02x %d\n",
-				link, id, rc);
-		return -ENODEV;
-	}
-
 	/* If we're behind a master that doesn't provide a self-running bus
 	 * clock, put the slave into async mode
 	 */
@@ -733,6 +783,21 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
 	slave->link = link;
 	slave->id = id;
 	slave->size = FSI_SLAVE_SIZE_23b;
+	slave->t_send_delay = 16;
+	slave->t_echo_delay = 16;
+
+	rc = fsi_slave_set_smode(slave);
+	if (rc) {
+		dev_warn(&master->dev,
+				"can't set smode on slave:%02x:%02x %d\n",
+				link, id, rc);
+		kfree(slave);
+		return -ENODEV;
+	}
+	if (master->link_config)
+		master->link_config(master, link,
+				    slave->t_send_delay,
+				    slave->t_echo_delay);
 
 	dev_set_name(&slave->dev, "slave@%02x:%02x", link, id);
 	rc = device_register(&slave->dev);
@@ -751,6 +816,10 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
 	if (rc)
 		dev_warn(&slave->dev, "failed to create term attr: %d\n", rc);
 
+	rc = device_create_file(&slave->dev, &dev_attr_send_echo_delays);
+	if (rc)
+		dev_warn(&slave->dev, "failed to create delay attr: %d\n", rc);
+
 	rc = fsi_slave_scan(slave);
 	if (rc)
 		dev_dbg(&master->dev, "failed during slave scan with: %d\n",
@@ -821,12 +890,16 @@ static int fsi_master_link_enable(struct fsi_master *master, int link)
  */
 static int fsi_master_break(struct fsi_master *master, int link)
 {
+	int rc = 0;
+
 	trace_fsi_master_break(master, link);
 
 	if (master->send_break)
-		return master->send_break(master, link);
+		rc = master->send_break(master, link);
+	if (master->link_config)
+		master->link_config(master, link, 16, 16);
 
-	return 0;
+	return rc;
 }
 
 static int fsi_master_scan(struct fsi_master *master)
diff --git a/drivers/fsi/fsi-master.h b/drivers/fsi/fsi-master.h
index ee0b46086026..7d619c68ab9b 100644
--- a/drivers/fsi/fsi-master.h
+++ b/drivers/fsi/fsi-master.h
@@ -33,6 +33,8 @@ struct fsi_master {
 	int		(*term)(struct fsi_master *, int link, uint8_t id);
 	int		(*send_break)(struct fsi_master *, int link);
 	int		(*link_enable)(struct fsi_master *, int link);
+	int		(*link_config)(struct fsi_master *, int link,
+				       u8 t_send_delay, u8 t_echo_delay);
 };
 
 #define dev_to_fsi_master(d) container_of(d, struct fsi_master, dev)
-- 
2.17.1

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

* [PATCH 04/14] fsi: master-gpio: Rename and adjust send delay
  2018-06-26 23:23 [PATCH 00/14] fsi: Fixes and Coldfire coprocessor offload Benjamin Herrenschmidt
                   ` (2 preceding siblings ...)
  2018-06-26 23:23 ` [PATCH 03/14] fsi: Add mechanism to set the tSendDelay and tEchoDelay values Benjamin Herrenschmidt
@ 2018-06-26 23:23 ` Benjamin Herrenschmidt
  2018-06-28  4:10   ` Joel Stanley
  3 siblings, 1 reply; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2018-06-26 23:23 UTC (permalink / raw)
  To: Joel Stanley
  Cc: linux-aspeed, openbmc, devicetree, Andrew Jeffery, linux-kernel,
	Benjamin Herrenschmidt

What the driver called "FSI_GPIO_PRIME_SLAVE_CLOCKS" is what
the FSI spec calls tSendDelay and should be 16 clocks by
default.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 drivers/fsi/fsi-master-gpio.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c
index 1fd8b417939d..836587701ceb 100644
--- a/drivers/fsi/fsi-master-gpio.c
+++ b/drivers/fsi/fsi-master-gpio.c
@@ -18,6 +18,7 @@
 
 #define	FSI_GPIO_STD_DLY	1	/* Standard pin delay in nS */
 #define	FSI_ECHO_DELAY_CLOCKS	16	/* Number clocks for echo delay */
+#define	FSI_SEND_DELAY_CLOCKS	16	/* Number clocks for send delay */
 #define	FSI_PRE_BREAK_CLOCKS	50	/* Number clocks to prep for break */
 #define	FSI_BREAK_CLOCKS	256	/* Number of clocks to issue break */
 #define	FSI_POST_BREAK_CLOCKS	16000	/* Number clocks to set up cfam */
@@ -48,7 +49,6 @@
 #define	FSI_GPIO_CRC_SIZE	4
 #define	FSI_GPIO_MSG_ID_SIZE		2
 #define	FSI_GPIO_MSG_RESPID_SIZE	2
-#define	FSI_GPIO_PRIME_SLAVE_CLOCKS	20
 
 #define LAST_ADDR_INVALID		0x1
 
@@ -535,9 +535,12 @@ static int poll_for_response(struct fsi_master_gpio *master,
 	if (busy_count > 0)
 		trace_fsi_master_gpio_poll_response_busy(master, busy_count);
  fail:
-	/* Clock the slave enough to be ready for next operation */
+	/*
+	 * tSendDelay clocks, avoids signal reflections when switching
+	 * from receive of response back to send of data.
+	 */
 	local_irq_save(flags);
-	clock_zeros(master, FSI_GPIO_PRIME_SLAVE_CLOCKS);
+	clock_zeros(master, FSI_SEND_DELAY_CLOCKS);
 	local_irq_restore(flags);
 
 	return rc;
-- 
2.17.1

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

* Re: [PATCH 02/14] fsi: Move code around to avoid forward declaration
  2018-06-26 23:23 ` [PATCH 02/14] fsi: Move code around to avoid forward declaration Benjamin Herrenschmidt
@ 2018-06-28  4:10   ` Joel Stanley
  0 siblings, 0 replies; 9+ messages in thread
From: Joel Stanley @ 2018-06-28  4:10 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linux-aspeed, OpenBMC Maillist, devicetree, Andrew Jeffery,
	Linux Kernel Mailing List

On 27 June 2018 at 08:53, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> Move fsi_slave_set_smode() and its helpers to before it's
> first user and remove the corresponding forward declaration.
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Reviewed-by: Joel Stanley <joel@jms.id.au>

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

* Re: [PATCH 04/14] fsi: master-gpio: Rename and adjust send delay
  2018-06-26 23:23 ` [PATCH 04/14] fsi: master-gpio: Rename and adjust send delay Benjamin Herrenschmidt
@ 2018-06-28  4:10   ` Joel Stanley
  0 siblings, 0 replies; 9+ messages in thread
From: Joel Stanley @ 2018-06-28  4:10 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linux-aspeed, OpenBMC Maillist, devicetree, Andrew Jeffery,
	Linux Kernel Mailing List

On 27 June 2018 at 08:53, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> What the driver called "FSI_GPIO_PRIME_SLAVE_CLOCKS" is what
> the FSI spec calls tSendDelay and should be 16 clocks by
> default.
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Reviewed-by: Joel Stanley <joel@jms.id.au>

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

* Re: [PATCH 03/14] fsi: Add mechanism to set the tSendDelay and tEchoDelay values
  2018-06-26 23:25 ` [PATCH 03/14] fsi: Add mechanism to set the tSendDelay and tEchoDelay values Benjamin Herrenschmidt
@ 2018-06-28  4:10   ` Joel Stanley
  0 siblings, 0 replies; 9+ messages in thread
From: Joel Stanley @ 2018-06-28  4:10 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linux-aspeed, OpenBMC Maillist, devicetree, Andrew Jeffery,
	Linux Kernel Mailing List

On 27 June 2018 at 08:55, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> Those values control the amount of "dummy" clocks between commands and
> between a command and its response.
>
> This adds a way to configure them from sysfs (to be later extended to
> defaults in the device-tree). The default remains 16 (the HW default).

We should add these to  Documentation/ABI/testing/sysfs-bus-fsi.

> This is only supported if the backend supports the new link_config()
> callback to configure the generation of those delays.
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Reviewed-by: Joel Stanley <joel@jms.id.au>

> ---
> ---
>  drivers/fsi/fsi-core.c   | 109 ++++++++++++++++++++++++++++++++-------
>  drivers/fsi/fsi-master.h |   2 +
>  2 files changed, 93 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
> index 2f6f9b8c75e4..1ae5be31b4bf 100644
> --- a/drivers/fsi/fsi-core.c
> +++ b/drivers/fsi/fsi-core.c
> @@ -81,6 +81,8 @@ struct fsi_slave {
>         int                     id;
>         int                     link;
>         uint32_t                size;   /* size of slave address space */
> +       u8                      t_send_delay;
> +       u8                      t_echo_delay;
>  };
>
>  #define to_fsi_master(d) container_of(d, struct fsi_master, dev)
> @@ -239,15 +241,15 @@ static inline uint32_t fsi_smode_sid(int x)
>         return (x & FSI_SMODE_SID_MASK) << FSI_SMODE_SID_SHIFT;
>  }
>
> -static uint32_t fsi_slave_smode(int id)
> +static uint32_t fsi_slave_smode(int id, u8 t_senddly, u8 t_echodly)

Can I buy you a vowel? :)

>  {
>         return FSI_SMODE_WSC | FSI_SMODE_ECRC
>                 | fsi_smode_sid(id)
> -               | fsi_smode_echodly(0xf) | fsi_smode_senddly(0xf)
> +               | fsi_smode_echodly(t_echodly - 1) | fsi_smode_senddly(t_senddly - 1)
>                 | fsi_smode_lbcrr(0x8);
>  }
>

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

* [PATCH 03/14] fsi: Add mechanism to set the tSendDelay and tEchoDelay values
  2018-06-26 23:25 [PATCH 00/14] fsi: Fixes and Coldfire coprocessor offload Benjamin Herrenschmidt
@ 2018-06-26 23:25 ` Benjamin Herrenschmidt
  2018-06-28  4:10   ` Joel Stanley
  0 siblings, 1 reply; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2018-06-26 23:25 UTC (permalink / raw)
  To: Joel Stanley
  Cc: linux-aspeed, openbmc, devicetree, Andrew Jeffery, linux-kernel,
	Benjamin Herrenschmidt

Those values control the amount of "dummy" clocks between commands and
between a command and its response.

This adds a way to configure them from sysfs (to be later extended to
defaults in the device-tree). The default remains 16 (the HW default).

This is only supported if the backend supports the new link_config()
callback to configure the generation of those delays.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
---
 drivers/fsi/fsi-core.c   | 109 ++++++++++++++++++++++++++++++++-------
 drivers/fsi/fsi-master.h |   2 +
 2 files changed, 93 insertions(+), 18 deletions(-)

diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index 2f6f9b8c75e4..1ae5be31b4bf 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -81,6 +81,8 @@ struct fsi_slave {
 	int			id;
 	int			link;
 	uint32_t		size;	/* size of slave address space */
+	u8			t_send_delay;
+	u8			t_echo_delay;
 };
 
 #define to_fsi_master(d) container_of(d, struct fsi_master, dev)
@@ -239,15 +241,15 @@ static inline uint32_t fsi_smode_sid(int x)
 	return (x & FSI_SMODE_SID_MASK) << FSI_SMODE_SID_SHIFT;
 }
 
-static uint32_t fsi_slave_smode(int id)
+static uint32_t fsi_slave_smode(int id, u8 t_senddly, u8 t_echodly)
 {
 	return FSI_SMODE_WSC | FSI_SMODE_ECRC
 		| fsi_smode_sid(id)
-		| fsi_smode_echodly(0xf) | fsi_smode_senddly(0xf)
+		| fsi_smode_echodly(t_echodly - 1) | fsi_smode_senddly(t_senddly - 1)
 		| fsi_smode_lbcrr(0x8);
 }
 
-static int fsi_slave_set_smode(struct fsi_master *master, int link, int id)
+static int fsi_slave_set_smode(struct fsi_slave *slave)
 {
 	uint32_t smode;
 	__be32 data;
@@ -255,11 +257,12 @@ static int fsi_slave_set_smode(struct fsi_master *master, int link, int id)
 	/* set our smode register with the slave ID field to 0; this enables
 	 * extended slave addressing
 	 */
-	smode = fsi_slave_smode(id);
+	smode = fsi_slave_smode(slave->id, slave->t_send_delay, slave->t_echo_delay);
 	data = cpu_to_be32(smode);
 
-	return fsi_master_write(master, link, id, FSI_SLAVE_BASE + FSI_SMODE,
-			&data, sizeof(data));
+	return fsi_master_write(slave->master, slave->link, slave->id,
+				FSI_SLAVE_BASE + FSI_SMODE,
+				&data, sizeof(data));
 }
 
 static int fsi_slave_handle_error(struct fsi_slave *slave, bool write,
@@ -268,7 +271,7 @@ static int fsi_slave_handle_error(struct fsi_slave *slave, bool write,
 	struct fsi_master *master = slave->master;
 	int rc, link;
 	uint32_t reg;
-	uint8_t id;
+	uint8_t id, send_delay, echo_delay;
 
 	if (discard_errors)
 		return -1;
@@ -299,15 +302,26 @@ static int fsi_slave_handle_error(struct fsi_slave *slave, bool write,
 		}
 	}
 
+	send_delay = slave->t_send_delay;
+	echo_delay = slave->t_echo_delay;
+
 	/* getting serious, reset the slave via BREAK */
 	rc = fsi_master_break(master, link);
 	if (rc)
 		return rc;
 
-	rc = fsi_slave_set_smode(master, link, id);
+	slave->t_send_delay = send_delay;
+	slave->t_echo_delay = echo_delay;
+
+	rc = fsi_slave_set_smode(slave);
 	if (rc)
 		return rc;
 
+	if (master->link_config)
+		master->link_config(master, link,
+				    slave->t_send_delay,
+				    slave->t_echo_delay);
+
 	return fsi_slave_report_and_clear_errors(slave);
 }
 
@@ -665,6 +679,50 @@ static struct device_node *fsi_slave_find_of_node(struct fsi_master *master,
 	return NULL;
 }
 
+static ssize_t slave_send_echo_show(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	struct fsi_slave *slave = to_fsi_slave(dev);
+
+	return sprintf(buf, "%u\n", slave->t_send_delay);
+}
+
+static ssize_t slave_send_echo_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct fsi_slave *slave = to_fsi_slave(dev);
+	struct fsi_master *master = slave->master;
+	unsigned long val;
+	int rc;
+
+	if (kstrtoul(buf, 0, &val) < 0)
+		return -EINVAL;
+
+	if (val < 1 || val > 16)
+		return -EINVAL;
+
+	if (!master->link_config)
+		return -ENXIO;
+
+	/* Current HW mandates that send and echo delay are identical */
+	slave->t_send_delay = val;
+	slave->t_echo_delay = val;
+
+	rc = fsi_slave_set_smode(slave);
+	if (rc < 0)
+		return rc;
+	if (master->link_config)
+		master->link_config(master, slave->link,
+				    slave->t_send_delay,
+				    slave->t_echo_delay);
+
+	return count;
+}
+
+static DEVICE_ATTR(send_echo_delays, 0600,
+		   slave_send_echo_show, slave_send_echo_store);
+
 static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
 {
 	uint32_t chip_id;
@@ -697,14 +755,6 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
 	dev_dbg(&master->dev, "fsi: found chip %08x at %02x:%02x:%02x\n",
 			chip_id, master->idx, link, id);
 
-	rc = fsi_slave_set_smode(master, link, id);
-	if (rc) {
-		dev_warn(&master->dev,
-				"can't set smode on slave:%02x:%02x %d\n",
-				link, id, rc);
-		return -ENODEV;
-	}
-
 	/* If we're behind a master that doesn't provide a self-running bus
 	 * clock, put the slave into async mode
 	 */
@@ -733,6 +783,21 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
 	slave->link = link;
 	slave->id = id;
 	slave->size = FSI_SLAVE_SIZE_23b;
+	slave->t_send_delay = 16;
+	slave->t_echo_delay = 16;
+
+	rc = fsi_slave_set_smode(slave);
+	if (rc) {
+		dev_warn(&master->dev,
+				"can't set smode on slave:%02x:%02x %d\n",
+				link, id, rc);
+		kfree(slave);
+		return -ENODEV;
+	}
+	if (master->link_config)
+		master->link_config(master, link,
+				    slave->t_send_delay,
+				    slave->t_echo_delay);
 
 	dev_set_name(&slave->dev, "slave@%02x:%02x", link, id);
 	rc = device_register(&slave->dev);
@@ -751,6 +816,10 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
 	if (rc)
 		dev_warn(&slave->dev, "failed to create term attr: %d\n", rc);
 
+	rc = device_create_file(&slave->dev, &dev_attr_send_echo_delays);
+	if (rc)
+		dev_warn(&slave->dev, "failed to create delay attr: %d\n", rc);
+
 	rc = fsi_slave_scan(slave);
 	if (rc)
 		dev_dbg(&master->dev, "failed during slave scan with: %d\n",
@@ -821,12 +890,16 @@ static int fsi_master_link_enable(struct fsi_master *master, int link)
  */
 static int fsi_master_break(struct fsi_master *master, int link)
 {
+	int rc = 0;
+
 	trace_fsi_master_break(master, link);
 
 	if (master->send_break)
-		return master->send_break(master, link);
+		rc = master->send_break(master, link);
+	if (master->link_config)
+		master->link_config(master, link, 16, 16);
 
-	return 0;
+	return rc;
 }
 
 static int fsi_master_scan(struct fsi_master *master)
diff --git a/drivers/fsi/fsi-master.h b/drivers/fsi/fsi-master.h
index ee0b46086026..7d619c68ab9b 100644
--- a/drivers/fsi/fsi-master.h
+++ b/drivers/fsi/fsi-master.h
@@ -33,6 +33,8 @@ struct fsi_master {
 	int		(*term)(struct fsi_master *, int link, uint8_t id);
 	int		(*send_break)(struct fsi_master *, int link);
 	int		(*link_enable)(struct fsi_master *, int link);
+	int		(*link_config)(struct fsi_master *, int link,
+				       u8 t_send_delay, u8 t_echo_delay);
 };
 
 #define dev_to_fsi_master(d) container_of(d, struct fsi_master, dev)
-- 
2.17.1

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

end of thread, other threads:[~2018-06-28  4:11 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-26 23:23 [PATCH 00/14] fsi: Fixes and Coldfire coprocessor offload Benjamin Herrenschmidt
2018-06-26 23:23 ` [PATCH 01/14] devres: Add devm_of_iomap() Benjamin Herrenschmidt
2018-06-26 23:23 ` [PATCH 02/14] fsi: Move code around to avoid forward declaration Benjamin Herrenschmidt
2018-06-28  4:10   ` Joel Stanley
2018-06-26 23:23 ` [PATCH 03/14] fsi: Add mechanism to set the tSendDelay and tEchoDelay values Benjamin Herrenschmidt
2018-06-26 23:23 ` [PATCH 04/14] fsi: master-gpio: Rename and adjust send delay Benjamin Herrenschmidt
2018-06-28  4:10   ` Joel Stanley
2018-06-26 23:25 [PATCH 00/14] fsi: Fixes and Coldfire coprocessor offload Benjamin Herrenschmidt
2018-06-26 23:25 ` [PATCH 03/14] fsi: Add mechanism to set the tSendDelay and tEchoDelay values Benjamin Herrenschmidt
2018-06-28  4:10   ` Joel Stanley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).