From patchwork Tue Jun 26 23:25:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 935150 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Fj0G6Qq7z9s47 for ; Wed, 27 Jun 2018 09:28:30 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41Fj0G4tRLzF1KD for ; Wed, 27 Jun 2018 09:28:30 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41FhyT3MsGzF1LY; Wed, 27 Jun 2018 09:26:57 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6qY022979; Tue, 26 Jun 2018 18:26:15 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 01/14] devres: Add devm_of_iomap() Date: Wed, 27 Jun 2018 09:25:52 +1000 Message-Id: <20180626232605.13420-2-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" 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 --- 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 #include #include +#include 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 From patchwork Tue Jun 26 23:25:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 935152 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Fj1m0MbQz9s4w for ; Wed, 27 Jun 2018 09:29:48 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41Fj1l5MV0zF1LY for ; Wed, 27 Jun 2018 09:29:47 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41Fhyb04bJzF1LK; Wed, 27 Jun 2018 09:27:02 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6qZ022979; Tue, 26 Jun 2018 18:26:22 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 02/14] fsi: Move code around to avoid forward declaration Date: Wed, 27 Jun 2018 09:25:53 +1000 Message-Id: <20180626232605.13420-3-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" 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 --- 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); From patchwork Tue Jun 26 23:25:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 935188 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41FjtS0DL7z9s2L for ; Wed, 27 Jun 2018 10:08:32 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41FjtR647YzF1Hw for ; Wed, 27 Jun 2018 10:08:31 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41FjtM1v55zF158; Wed, 27 Jun 2018 10:08:27 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6qa022979; Tue, 26 Jun 2018 18:26:27 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 03/14] fsi: Add mechanism to set the tSendDelay and tEchoDelay values Date: Wed, 27 Jun 2018 09:25:54 +1000 Message-Id: <20180626232605.13420-4-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" 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 Reviewed-by: Joel Stanley --- --- 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) From patchwork Tue Jun 26 23:25:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 935170 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41FjZD4XDdz9s0n for ; Wed, 27 Jun 2018 09:54:28 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41FjZD2YGCzF1Hg for ; Wed, 27 Jun 2018 09:54:28 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41FjZ62mZdzDrcd; Wed, 27 Jun 2018 09:54:22 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6qb022979; Tue, 26 Jun 2018 18:26:34 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 04/14] fsi: master-gpio: Rename and adjust send delay Date: Wed, 27 Jun 2018 09:25:55 +1000 Message-Id: <20180626232605.13420-5-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" 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 --- 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; From patchwork Tue Jun 26 23:25:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 935215 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Fkrg5GSVz9s1B for ; Wed, 27 Jun 2018 10:52:03 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41Fkrg453jzF1Lb for ; Wed, 27 Jun 2018 10:52:03 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41FknW1BXPzF1Dt; Wed, 27 Jun 2018 10:49:18 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6qc022979; Tue, 26 Jun 2018 18:26:41 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 05/14] fsi: master-gpio: Add support for link_config Date: Wed, 27 Jun 2018 09:25:56 +1000 Message-Id: <20180626232605.13420-6-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" To configure the send and echo delays Signed-off-by: Benjamin Herrenschmidt Reviewed-by: Joel Stanley --- drivers/fsi/fsi-master-gpio.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c index 836587701ceb..48e0e65b2982 100644 --- a/drivers/fsi/fsi-master-gpio.c +++ b/drivers/fsi/fsi-master-gpio.c @@ -64,6 +64,8 @@ struct fsi_master_gpio { bool external_mode; bool no_delays; uint32_t last_addr; + uint8_t t_send_delay; + uint8_t t_echo_delay; }; #define CREATE_TRACE_POINTS @@ -338,7 +340,7 @@ static void build_epoll_command(struct fsi_gpio_msg *cmd, uint8_t slave_id) static void echo_delay(struct fsi_master_gpio *master) { set_sda_output(master, 1); - clock_toggle(master, FSI_ECHO_DELAY_CLOCKS); + clock_toggle(master, master->t_echo_delay); } static void build_term_command(struct fsi_gpio_msg *cmd, uint8_t slave_id) @@ -540,7 +542,7 @@ static int poll_for_response(struct fsi_master_gpio *master, * from receive of response back to send of data. */ local_irq_save(flags); - clock_zeros(master, FSI_SEND_DELAY_CLOCKS); + clock_zeros(master, master->t_send_delay); local_irq_restore(flags); return rc; @@ -728,6 +730,22 @@ static int fsi_master_gpio_link_enable(struct fsi_master *_master, int link) return rc; } +static int fsi_master_gpio_link_config(struct fsi_master *_master, int link, + u8 t_send_delay, u8 t_echo_delay) +{ + struct fsi_master_gpio *master = to_fsi_master_gpio(_master); + + if (link != 0) + return -ENODEV; + + mutex_lock(&master->cmd_lock); + master->t_send_delay = t_send_delay; + master->t_echo_delay = t_echo_delay; + mutex_unlock(&master->cmd_lock); + + return 0; +} + static ssize_t external_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -832,6 +850,10 @@ static int fsi_master_gpio_probe(struct platform_device *pdev) */ master->no_delays = device_property_present(&pdev->dev, "no-gpio-delays"); + /* Default FSI command delays */ + master->t_send_delay = FSI_SEND_DELAY_CLOCKS; + master->t_echo_delay = FSI_ECHO_DELAY_CLOCKS; + master->master.n_links = 1; master->master.flags = FSI_MASTER_FLAG_SWCLOCK; master->master.read = fsi_master_gpio_read; @@ -839,6 +861,7 @@ static int fsi_master_gpio_probe(struct platform_device *pdev) master->master.term = fsi_master_gpio_term; master->master.send_break = fsi_master_gpio_break; master->master.link_enable = fsi_master_gpio_link_enable; + master->master.link_config = fsi_master_gpio_link_config; platform_set_drvdata(pdev, master); mutex_init(&master->cmd_lock); From patchwork Tue Jun 26 23:25:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 935160 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Fj5r5j1pz9s0w for ; Wed, 27 Jun 2018 09:33:20 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41Fj5r4BZ7zF1QH for ; Wed, 27 Jun 2018 09:33:20 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41Fj4r3Q50zF1LP; Wed, 27 Jun 2018 09:32:27 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6qd022979; Tue, 26 Jun 2018 18:26:48 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 06/14] fsi: master-gpio: Add more tracepoints Date: Wed, 27 Jun 2018 09:25:57 +1000 Message-Id: <20180626232605.13420-7-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" This adds a few more tracepoints that have proven useful when debugging issues with the FSI bus. Signed-off-by: Benjamin Herrenschmidt Reviewed-by: Joel Stanley --- drivers/fsi/fsi-master-gpio.c | 16 ++++--- include/trace/events/fsi_master_gpio.h | 59 ++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c index 48e0e65b2982..a00a85aa6d56 100644 --- a/drivers/fsi/fsi-master-gpio.c +++ b/drivers/fsi/fsi-master-gpio.c @@ -130,10 +130,17 @@ static void set_sda_output(struct fsi_master_gpio *master, int value) static void clock_zeros(struct fsi_master_gpio *master, int count) { + trace_fsi_master_gpio_clock_zeros(master, count); set_sda_output(master, 1); clock_toggle(master, count); } +static void echo_delay(struct fsi_master_gpio *master) +{ + clock_zeros(master, master->t_echo_delay); +} + + static void serial_in(struct fsi_master_gpio *master, struct fsi_gpio_msg *msg, uint8_t num_bits) { @@ -279,16 +286,19 @@ static void build_ar_command(struct fsi_master_gpio *master, addr_bits = 2; opcode_bits = 2; opcode = FSI_GPIO_CMD_SAME_AR; + trace_fsi_master_gpio_cmd_same_addr(master); } else if (check_relative_address(master, id, addr, &rel_addr)) { /* 8 bits plus sign */ addr_bits = 9; addr = rel_addr; opcode = FSI_GPIO_CMD_REL_AR; + trace_fsi_master_gpio_cmd_rel_addr(master, rel_addr); } else { addr_bits = 21; opcode = FSI_GPIO_CMD_ABS_AR; + trace_fsi_master_gpio_cmd_abs_addr(master, addr); } /* @@ -337,12 +347,6 @@ static void build_epoll_command(struct fsi_gpio_msg *cmd, uint8_t slave_id) msg_push_crc(cmd); } -static void echo_delay(struct fsi_master_gpio *master) -{ - set_sda_output(master, 1); - clock_toggle(master, master->t_echo_delay); -} - static void build_term_command(struct fsi_gpio_msg *cmd, uint8_t slave_id) { cmd->bits = 0; diff --git a/include/trace/events/fsi_master_gpio.h b/include/trace/events/fsi_master_gpio.h index 389082132433..70ef66e63e84 100644 --- a/include/trace/events/fsi_master_gpio.h +++ b/include/trace/events/fsi_master_gpio.h @@ -50,6 +50,22 @@ TRACE_EVENT(fsi_master_gpio_out, ) ); +TRACE_EVENT(fsi_master_gpio_clock_zeros, + TP_PROTO(const struct fsi_master_gpio *master, int clocks), + TP_ARGS(master, clocks), + TP_STRUCT__entry( + __field(int, master_idx) + __field(int, clocks) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->clocks = clocks; + ), + TP_printk("fsi-gpio%d clock %d zeros", + __entry->master_idx, __entry->clocks + ) +); + TRACE_EVENT(fsi_master_gpio_break, TP_PROTO(const struct fsi_master_gpio *master), TP_ARGS(master), @@ -107,6 +123,49 @@ TRACE_EVENT(fsi_master_gpio_poll_response_busy, __entry->master_idx, __entry->busy) ); +TRACE_EVENT(fsi_master_gpio_cmd_abs_addr, + TP_PROTO(const struct fsi_master_gpio *master, u32 addr), + TP_ARGS(master, addr), + TP_STRUCT__entry( + __field(int, master_idx) + __field(u32, addr) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->addr = addr; + ), + TP_printk("fsi-gpio%d: Sending ABS_ADR %06x", + __entry->master_idx, __entry->addr) +); + +TRACE_EVENT(fsi_master_gpio_cmd_rel_addr, + TP_PROTO(const struct fsi_master_gpio *master, u32 rel_addr), + TP_ARGS(master, rel_addr), + TP_STRUCT__entry( + __field(int, master_idx) + __field(u32, rel_addr) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->rel_addr = rel_addr; + ), + TP_printk("fsi-gpio%d: Sending REL_ADR %03x", + __entry->master_idx, __entry->rel_addr) +); + +TRACE_EVENT(fsi_master_gpio_cmd_same_addr, + TP_PROTO(const struct fsi_master_gpio *master), + TP_ARGS(master), + TP_STRUCT__entry( + __field(int, master_idx) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + ), + TP_printk("fsi-gpio%d: Sending SAME_ADR", + __entry->master_idx) +); + #endif /* _TRACE_FSI_MASTER_GPIO_H */ #include From patchwork Tue Jun 26 23:25:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 935155 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Fj2g4lQbz9s4w for ; Wed, 27 Jun 2018 09:30:35 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41Fj2g2L17zF1L4 for ; Wed, 27 Jun 2018 09:30:35 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41FhzH3GRNzF1Kr; Wed, 27 Jun 2018 09:27:38 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6qe022979; Tue, 26 Jun 2018 18:26:54 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 07/14] fsi: master-gpio: Remove unused definitions Date: Wed, 27 Jun 2018 09:25:58 +1000 Message-Id: <20180626232605.13420-8-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" Signed-off-by: Benjamin Herrenschmidt Reviewed-by: Joel Stanley --- drivers/fsi/fsi-master-gpio.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c index a00a85aa6d56..2bc85514bb0c 100644 --- a/drivers/fsi/fsi-master-gpio.c +++ b/drivers/fsi/fsi-master-gpio.c @@ -25,9 +25,6 @@ #define FSI_INIT_CLOCKS 5000 /* Clock out any old data */ #define FSI_GPIO_DPOLL_CLOCKS 50 /* < 21 will cause slave to hang */ #define FSI_GPIO_EPOLL_CLOCKS 50 /* Number of clocks for E_POLL retry */ -#define FSI_GPIO_STD_DELAY 10 /* Standard GPIO delay in nS */ - /* todo: adjust down as low as */ - /* possible or eliminate */ #define FSI_CRC_ERR_RETRIES 10 #define FSI_GPIO_CMD_DPOLL 0x2 @@ -45,10 +42,7 @@ #define FSI_GPIO_MAX_BUSY 200 #define FSI_GPIO_MTOE_COUNT 1000 -#define FSI_GPIO_DRAIN_BITS 20 #define FSI_GPIO_CRC_SIZE 4 -#define FSI_GPIO_MSG_ID_SIZE 2 -#define FSI_GPIO_MSG_RESPID_SIZE 2 #define LAST_ADDR_INVALID 0x1 From patchwork Tue Jun 26 23:25:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 935161 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Fj5s6vGNz9s0w for ; Wed, 27 Jun 2018 09:33:21 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41Fj5s5pX2zF1LQ for ; Wed, 27 Jun 2018 09:33:21 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41Fj550NbyzF1QL; Wed, 27 Jun 2018 09:32:40 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6qf022979; Tue, 26 Jun 2018 18:27:01 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 08/14] fsi: master-gpio: Remove "GPIO" prefix on some definitions Date: Wed, 27 Jun 2018 09:25:59 +1000 Message-Id: <20180626232605.13420-9-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" Some definitions are generic to the FSI protocol or any give master implementation. Rename them to remove the "GPIO" prefix in preparation for moving them to a common header. Signed-off-by: Benjamin Herrenschmidt Reviewed-by: Joel Stanley --- drivers/fsi/fsi-master-gpio.c | 70 ++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c index 2bc85514bb0c..91d89597784a 100644 --- a/drivers/fsi/fsi-master-gpio.c +++ b/drivers/fsi/fsi-master-gpio.c @@ -23,26 +23,28 @@ #define FSI_BREAK_CLOCKS 256 /* Number of clocks to issue break */ #define FSI_POST_BREAK_CLOCKS 16000 /* Number clocks to set up cfam */ #define FSI_INIT_CLOCKS 5000 /* Clock out any old data */ -#define FSI_GPIO_DPOLL_CLOCKS 50 /* < 21 will cause slave to hang */ -#define FSI_GPIO_EPOLL_CLOCKS 50 /* Number of clocks for E_POLL retry */ +#define FSI_MASTER_DPOLL_CLOCKS 50 /* < 21 will cause slave to hang */ +#define FSI_MASTER_EPOLL_CLOCKS 50 /* Number of clocks for E_POLL retry */ + #define FSI_CRC_ERR_RETRIES 10 -#define FSI_GPIO_CMD_DPOLL 0x2 -#define FSI_GPIO_CMD_EPOLL 0x3 -#define FSI_GPIO_CMD_TERM 0x3f -#define FSI_GPIO_CMD_ABS_AR 0x4 -#define FSI_GPIO_CMD_REL_AR 0x5 -#define FSI_GPIO_CMD_SAME_AR 0x3 /* but only a 2-bit opcode... */ +#define FSI_CMD_DPOLL 0x2 +#define FSI_CMD_EPOLL 0x3 +#define FSI_CMD_TERM 0x3f +#define FSI_CMD_ABS_AR 0x4 +#define FSI_CMD_REL_AR 0x5 +#define FSI_CMD_SAME_AR 0x3 /* but only a 2-bit opcode... */ /* Slave responses */ -#define FSI_GPIO_RESP_ACK 0 /* Success */ -#define FSI_GPIO_RESP_BUSY 1 /* Slave busy */ -#define FSI_GPIO_RESP_ERRA 2 /* Any (misc) Error */ -#define FSI_GPIO_RESP_ERRC 3 /* Slave reports master CRC error */ +#define FSI_RESP_ACK 0 /* Success */ +#define FSI_RESP_BUSY 1 /* Slave busy */ +#define FSI_RESP_ERRA 2 /* Any (misc) Error */ +#define FSI_RESP_ERRC 3 /* Slave reports master CRC error */ + +#define FSI_MASTER_MAX_BUSY 200 -#define FSI_GPIO_MAX_BUSY 200 -#define FSI_GPIO_MTOE_COUNT 1000 -#define FSI_GPIO_CRC_SIZE 4 +#define FSI_MASTER_MTOE_COUNT 1000 +#define FSI_CRC_SIZE 4 #define LAST_ADDR_INVALID 0x1 @@ -279,19 +281,19 @@ static void build_ar_command(struct fsi_master_gpio *master, /* we still address the byte offset within the word */ addr_bits = 2; opcode_bits = 2; - opcode = FSI_GPIO_CMD_SAME_AR; + opcode = FSI_CMD_SAME_AR; trace_fsi_master_gpio_cmd_same_addr(master); } else if (check_relative_address(master, id, addr, &rel_addr)) { /* 8 bits plus sign */ addr_bits = 9; addr = rel_addr; - opcode = FSI_GPIO_CMD_REL_AR; + opcode = FSI_CMD_REL_AR; trace_fsi_master_gpio_cmd_rel_addr(master, rel_addr); } else { addr_bits = 21; - opcode = FSI_GPIO_CMD_ABS_AR; + opcode = FSI_CMD_ABS_AR; trace_fsi_master_gpio_cmd_abs_addr(master, addr); } @@ -327,7 +329,7 @@ static void build_dpoll_command(struct fsi_gpio_msg *cmd, uint8_t slave_id) cmd->msg = 0; msg_push_bits(cmd, slave_id, 2); - msg_push_bits(cmd, FSI_GPIO_CMD_DPOLL, 3); + msg_push_bits(cmd, FSI_CMD_DPOLL, 3); msg_push_crc(cmd); } @@ -337,7 +339,7 @@ static void build_epoll_command(struct fsi_gpio_msg *cmd, uint8_t slave_id) cmd->msg = 0; msg_push_bits(cmd, slave_id, 2); - msg_push_bits(cmd, FSI_GPIO_CMD_EPOLL, 3); + msg_push_bits(cmd, FSI_CMD_EPOLL, 3); msg_push_crc(cmd); } @@ -347,7 +349,7 @@ static void build_term_command(struct fsi_gpio_msg *cmd, uint8_t slave_id) cmd->msg = 0; msg_push_bits(cmd, slave_id, 2); - msg_push_bits(cmd, FSI_GPIO_CMD_TERM, 6); + msg_push_bits(cmd, FSI_CMD_TERM, 6); msg_push_crc(cmd); } @@ -369,14 +371,14 @@ static int read_one_response(struct fsi_master_gpio *master, local_irq_save(flags); /* wait for the start bit */ - for (i = 0; i < FSI_GPIO_MTOE_COUNT; i++) { + for (i = 0; i < FSI_MASTER_MTOE_COUNT; i++) { msg.bits = 0; msg.msg = 0; serial_in(master, &msg, 1); if (msg.msg) break; } - if (i == FSI_GPIO_MTOE_COUNT) { + if (i == FSI_MASTER_MTOE_COUNT) { dev_warn(master->dev, "Master time out waiting for response\n"); local_irq_restore(flags); @@ -392,11 +394,11 @@ static int read_one_response(struct fsi_master_gpio *master, tag = msg.msg & 0x3; /* If we have an ACK and we're expecting data, clock the data in too */ - if (tag == FSI_GPIO_RESP_ACK && data_size) + if (tag == FSI_RESP_ACK && data_size) serial_in(master, &msg, data_size * 8); /* read CRC */ - serial_in(master, &msg, FSI_GPIO_CRC_SIZE); + serial_in(master, &msg, FSI_CRC_SIZE); local_irq_restore(flags); @@ -439,7 +441,7 @@ static int issue_term(struct fsi_master_gpio *master, uint8_t slave) dev_err(master->dev, "TERM failed; lost communication with slave\n"); return -EIO; - } else if (tag != FSI_GPIO_RESP_ACK) { + } else if (tag != FSI_RESP_ACK) { dev_err(master->dev, "TERM failed; response %d\n", tag); return -EIO; } @@ -475,7 +477,7 @@ static int poll_for_response(struct fsi_master_gpio *master, trace_fsi_master_gpio_crc_rsp_error(master); build_epoll_command(&cmd, slave); local_irq_save(flags); - clock_zeros(master, FSI_GPIO_EPOLL_CLOCKS); + clock_zeros(master, FSI_MASTER_EPOLL_CLOCKS); serial_out(master, &cmd); echo_delay(master); local_irq_restore(flags); @@ -484,7 +486,7 @@ static int poll_for_response(struct fsi_master_gpio *master, goto fail; switch (tag) { - case FSI_GPIO_RESP_ACK: + case FSI_RESP_ACK: if (size && data) { uint64_t val = response.msg; /* clear crc & mask */ @@ -497,16 +499,16 @@ static int poll_for_response(struct fsi_master_gpio *master, } } break; - case FSI_GPIO_RESP_BUSY: + case FSI_RESP_BUSY: /* * Its necessary to clock slave before issuing * d-poll, not indicated in the hardware protocol * spec. < 20 clocks causes slave to hang, 21 ok. */ - if (busy_count++ < FSI_GPIO_MAX_BUSY) { + if (busy_count++ < FSI_MASTER_MAX_BUSY) { build_dpoll_command(&cmd, slave); local_irq_save(flags); - clock_zeros(master, FSI_GPIO_DPOLL_CLOCKS); + clock_zeros(master, FSI_MASTER_DPOLL_CLOCKS); serial_out(master, &cmd); echo_delay(master); local_irq_restore(flags); @@ -515,17 +517,17 @@ static int poll_for_response(struct fsi_master_gpio *master, dev_warn(master->dev, "ERR slave is stuck in busy state, issuing TERM\n"); local_irq_save(flags); - clock_zeros(master, FSI_GPIO_DPOLL_CLOCKS); + clock_zeros(master, FSI_MASTER_DPOLL_CLOCKS); local_irq_restore(flags); issue_term(master, slave); rc = -EIO; break; - case FSI_GPIO_RESP_ERRA: + case FSI_RESP_ERRA: dev_warn(master->dev, "ERRA received: 0x%x\n", (int)response.msg); rc = -EIO; break; - case FSI_GPIO_RESP_ERRC: + case FSI_RESP_ERRC: dev_warn(master->dev, "ERRC received: 0x%x\n", (int)response.msg); trace_fsi_master_gpio_crc_cmd_error(master); rc = -EAGAIN; From patchwork Tue Jun 26 23:26:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 935211 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41FkqK6Wyzz9s29 for ; Wed, 27 Jun 2018 10:50:53 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41FkqK5KcDzF1LM for ; Wed, 27 Jun 2018 10:50:53 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41FknQ1YhwzF1D5; Wed, 27 Jun 2018 10:49:13 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6qg022979; Tue, 26 Jun 2018 18:27:08 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 09/14] fsi: master-gpio: Add missing release function Date: Wed, 27 Jun 2018 09:26:00 +1000 Message-Id: <20180626232605.13420-10-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" The embedded struct device needs a release function to be able to successfully remove the driver. We remove the devm_gpiod_put() as they are unnecessary (the resources will be released automatically) and because fsi_master_unregister() will cause the master structure to be freed. Signed-off-by: Benjamin Herrenschmidt Reviewed-by: Joel Stanley --- drivers/fsi/fsi-master-gpio.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c index 91d89597784a..bad7951a2677 100644 --- a/drivers/fsi/fsi-master-gpio.c +++ b/drivers/fsi/fsi-master-gpio.c @@ -792,6 +792,15 @@ static ssize_t external_mode_store(struct device *dev, static DEVICE_ATTR(external_mode, 0664, external_mode_show, external_mode_store); +static void fsi_master_gpio_release(struct device *dev) +{ + struct fsi_master_gpio *master = to_fsi_master_gpio(dev_to_fsi_master(dev)); + + of_node_put(dev_of_node(master->dev)); + + kfree(dev); +} + static int fsi_master_gpio_probe(struct platform_device *pdev) { struct fsi_master_gpio *master; @@ -805,6 +814,7 @@ static int fsi_master_gpio_probe(struct platform_device *pdev) master->dev = &pdev->dev; master->master.dev.parent = master->dev; master->master.dev.of_node = of_node_get(dev_of_node(master->dev)); + master->master.dev.release = fsi_master_gpio_release; master->last_addr = LAST_ADDR_INVALID; gpio = devm_gpiod_get(&pdev->dev, "clock", 0); @@ -871,25 +881,21 @@ static int fsi_master_gpio_probe(struct platform_device *pdev) if (rc) return rc; - return fsi_master_register(&master->master); + rc = fsi_master_register(&master->master); + if (rc) + device_remove_file(&pdev->dev, &dev_attr_external_mode); + return rc; } + static int fsi_master_gpio_remove(struct platform_device *pdev) { struct fsi_master_gpio *master = platform_get_drvdata(pdev); - devm_gpiod_put(&pdev->dev, master->gpio_clk); - devm_gpiod_put(&pdev->dev, master->gpio_data); - if (master->gpio_trans) - devm_gpiod_put(&pdev->dev, master->gpio_trans); - if (master->gpio_enable) - devm_gpiod_put(&pdev->dev, master->gpio_enable); - if (master->gpio_mux) - devm_gpiod_put(&pdev->dev, master->gpio_mux); - fsi_master_unregister(&master->master); + device_remove_file(&pdev->dev, &dev_attr_external_mode); - of_node_put(master->master.dev.of_node); + fsi_master_unregister(&master->master); return 0; } From patchwork Tue Jun 26 23:26:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 935157 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Fj3X4GMNz9s1b for ; Wed, 27 Jun 2018 09:31:20 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41Fj3X1f7CzF1Kr for ; Wed, 27 Jun 2018 09:31:20 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41Fhzf38l5zF1KG; Wed, 27 Jun 2018 09:27:57 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6qh022979; Tue, 26 Jun 2018 18:27:16 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 10/14] fsi: Move various master definitions to a common header Date: Wed, 27 Jun 2018 09:26:01 +1000 Message-Id: <20180626232605.13420-11-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" This moves the definitions for various protocol details (message & response codes, delays etc...) out of fsi-master-gpio.c to fsi-master.h in order to share them with other master implementations. Signed-off-by: Benjamin Herrenschmidt Reviewed-by: Joel Stanley --- drivers/fsi/fsi-master-gpio.c | 29 ----------------------------- drivers/fsi/fsi-master.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c index bad7951a2677..edc257e40102 100644 --- a/drivers/fsi/fsi-master-gpio.c +++ b/drivers/fsi/fsi-master-gpio.c @@ -17,35 +17,6 @@ #include "fsi-master.h" #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 */ -#define FSI_INIT_CLOCKS 5000 /* Clock out any old data */ -#define FSI_MASTER_DPOLL_CLOCKS 50 /* < 21 will cause slave to hang */ -#define FSI_MASTER_EPOLL_CLOCKS 50 /* Number of clocks for E_POLL retry */ - -#define FSI_CRC_ERR_RETRIES 10 - -#define FSI_CMD_DPOLL 0x2 -#define FSI_CMD_EPOLL 0x3 -#define FSI_CMD_TERM 0x3f -#define FSI_CMD_ABS_AR 0x4 -#define FSI_CMD_REL_AR 0x5 -#define FSI_CMD_SAME_AR 0x3 /* but only a 2-bit opcode... */ - -/* Slave responses */ -#define FSI_RESP_ACK 0 /* Success */ -#define FSI_RESP_BUSY 1 /* Slave busy */ -#define FSI_RESP_ERRA 2 /* Any (misc) Error */ -#define FSI_RESP_ERRC 3 /* Slave reports master CRC error */ - -#define FSI_MASTER_MAX_BUSY 200 - -#define FSI_MASTER_MTOE_COUNT 1000 -#define FSI_CRC_SIZE 4 - #define LAST_ADDR_INVALID 0x1 struct fsi_master_gpio { diff --git a/drivers/fsi/fsi-master.h b/drivers/fsi/fsi-master.h index 7d619c68ab9b..f653f75da7be 100644 --- a/drivers/fsi/fsi-master.h +++ b/drivers/fsi/fsi-master.h @@ -19,6 +19,39 @@ #include +/* Various protocol delays */ +#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 */ +#define FSI_INIT_CLOCKS 5000 /* Clock out any old data */ +#define FSI_MASTER_DPOLL_CLOCKS 50 /* < 21 will cause slave to hang */ +#define FSI_MASTER_EPOLL_CLOCKS 50 /* Number of clocks for E_POLL retry */ + +/* Various retry maximums */ +#define FSI_CRC_ERR_RETRIES 10 +#define FSI_MASTER_MAX_BUSY 200 +#define FSI_MASTER_MTOE_COUNT 1000 + +/* Command encodings */ +#define FSI_CMD_DPOLL 0x2 +#define FSI_CMD_EPOLL 0x3 +#define FSI_CMD_TERM 0x3f +#define FSI_CMD_ABS_AR 0x4 +#define FSI_CMD_REL_AR 0x5 +#define FSI_CMD_SAME_AR 0x3 /* but only a 2-bit opcode... */ + +/* Slave responses */ +#define FSI_RESP_ACK 0 /* Success */ +#define FSI_RESP_BUSY 1 /* Slave busy */ +#define FSI_RESP_ERRA 2 /* Any (misc) Error */ +#define FSI_RESP_ERRC 3 /* Slave reports master CRC error */ + +/* Misc */ +#define FSI_CRC_SIZE 4 + +/* fsi-master definition and flags */ #define FSI_MASTER_FLAG_SWCLOCK 0x1 struct fsi_master { From patchwork Tue Jun 26 23:26:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 935213 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Fkr06WhDz9s1B for ; Wed, 27 Jun 2018 10:51:28 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41Fkr05K6TzF1LP for ; Wed, 27 Jun 2018 10:51:28 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41FknT1PsHzF1Hw; Wed, 27 Jun 2018 10:49:16 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6qi022979; Tue, 26 Jun 2018 18:27:23 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 11/14] dt-bindings: fsi: Document binding for the fsi-master-ast-cf "device" Date: Wed, 27 Jun 2018 09:26:02 +1000 Message-Id: <20180626232605.13420-12-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" This isn't per-se a real device, it's a pseudo-device that represents the use of the Aspeed built-in ColdFire to implement the FSI protocol by bitbanging the GPIOs instead of doing it from the ARM core. Thus it's a drop-in replacement for the existing fsi-master-gpio pseudo-device for use on systems for which a corresponding firmware file exists. It has most of the same properties, plus some more needed to operate the coprocessor. Signed-off-by: Benjamin Herrenschmidt Acked-by: Joel Stanley --- .../bindings/fsi/fsi-master-ast-cf.txt | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Documentation/devicetree/bindings/fsi/fsi-master-ast-cf.txt diff --git a/Documentation/devicetree/bindings/fsi/fsi-master-ast-cf.txt b/Documentation/devicetree/bindings/fsi/fsi-master-ast-cf.txt new file mode 100644 index 000000000000..50913ae685cc --- /dev/null +++ b/Documentation/devicetree/bindings/fsi/fsi-master-ast-cf.txt @@ -0,0 +1,36 @@ +Device-tree bindings for ColdFire offloaded gpio-based FSI master driver +------------------------------------------------------------------------ + +Required properties: + - compatible = + "fsi-master-ast-2400-cf" for an AST2400 based system + or + "fsi-master-ast-2500-cf" for an AST2500 based system + + - clock-gpios = ; : GPIO for FSI clock + - data-gpios = ; : GPIO for FSI data signal + - enable-gpios = ; : GPIO for enable signal + - trans-gpios = ; : GPIO for voltage translator enable + - mux-gpios = ; : GPIO for pin multiplexing with other + functions (eg, external FSI masters) + - memory-region = ; : Reference to the reserved memory for + the ColdFire. Must be 2M aligned on + AST2400 and 1M aligned on AST2500 + - sram = ; : Reference to the SRAM node. + - cvic = ; : Reference to the CVIC node. + - fw-name = ; : The name used to construct the firmware + file name (cf-fsi-.bin) + - fw-platform-sig = ; : A signature value that must match the one + contained in the firmware image. Known + values are listed in the firmware interface + file cf-fsi-fw.h +Examples: + + fsi-master { + compatible = "fsi-master-gpio", "fsi-master"; + clock-gpios = <&gpio 0>; + data-gpios = <&gpio 1>; + enable-gpios = <&gpio 2>; + trans-gpios = <&gpio 3>; + mux-gpios = <&gpio 4>; + } From patchwork Tue Jun 26 23:26:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 939613 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41LggH46Ypz9s2R for ; Thu, 5 Jul 2018 11:46:03 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41LggH1Y1gzDqrT for ; Thu, 5 Jul 2018 11:46:03 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41Fj022gPCzF1KG; Wed, 27 Jun 2018 09:28:17 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6qj022979; Tue, 26 Jun 2018 18:27:29 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 12/14] fsi: master-ast-cf: Add new FSI master using Aspeed ColdFire Date: Wed, 27 Jun 2018 09:26:03 +1000 Message-Id: <20180626232605.13420-13-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-Mailman-Approved-At: Thu, 05 Jul 2018 11:44:51 +1000 X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" The Aspeed AST2x00 can contain a ColdFire v1 coprocessor which is currently unused on OpenPower systems. This adds an alternative to the fsi-master-gpio driver that uses that coprocessor instead of bit banging from the ARM core itself. The end result is about 4 times faster. The firmware for the coprocessor and its source code can be found at https://github.com/ozbenh/cf-fsi and is system specific. Currently tested on Romulus and Palmetto systems. Signed-off-by: Benjamin Herrenschmidt --- drivers/fsi/Kconfig | 9 + drivers/fsi/Makefile | 1 + drivers/fsi/cf-fsi-fw.h | 131 ++ drivers/fsi/fsi-master-ast-cf.c | 1376 ++++++++++++++++++++++ include/trace/events/fsi_master_ast_cf.h | 150 +++ 5 files changed, 1667 insertions(+) create mode 100644 drivers/fsi/cf-fsi-fw.h create mode 100644 drivers/fsi/fsi-master-ast-cf.c create mode 100644 include/trace/events/fsi_master_ast_cf.h diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig index 322cec393cf2..e0220d1e1357 100644 --- a/drivers/fsi/Kconfig +++ b/drivers/fsi/Kconfig @@ -27,6 +27,15 @@ config FSI_MASTER_HUB allow chaining of FSI links to an arbitrary depth. This allows for a high target device fanout. +config FSI_MASTER_AST_CF + tristate "FSI master based on Aspeed ColdFire coprocessor" + depends on GPIOLIB + depends on GPIO_ASPEED + ---help--- + This option enables a FSI master using the AST2400 and AST2500 GPIO + lines driven by the internal ColdFire coprocessor. This requires + the corresponding machine specific ColdFire firmware to be available. + config FSI_SCOM tristate "SCOM FSI client device driver" ---help--- diff --git a/drivers/fsi/Makefile b/drivers/fsi/Makefile index 75fdc6d8cfc4..62687ec86d2e 100644 --- a/drivers/fsi/Makefile +++ b/drivers/fsi/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_FSI) += fsi-core.o obj-$(CONFIG_FSI_MASTER_HUB) += fsi-master-hub.o obj-$(CONFIG_FSI_MASTER_GPIO) += fsi-master-gpio.o +obj-$(CONFIG_FSI_MASTER_AST_CF) += fsi-master-ast-cf.o obj-$(CONFIG_FSI_SCOM) += fsi-scom.o obj-$(CONFIG_FSI_SBEFIFO) += fsi-sbefifo.o obj-$(CONFIG_FSI_OCC) += fsi-occ.o diff --git a/drivers/fsi/cf-fsi-fw.h b/drivers/fsi/cf-fsi-fw.h new file mode 100644 index 000000000000..5f6cffd30861 --- /dev/null +++ b/drivers/fsi/cf-fsi-fw.h @@ -0,0 +1,131 @@ +#ifndef __CF_FSI_FW_H +#define __CF_FSI_FW_H + +/* + * uCode file layout + * + * 0000...03ff : m68k exception vectors + * 0400...04ff : Header info & boot config block + * 0500....... : Code & stack + */ + +/* + * Header info & boot config area + * + * The Header info is built into the ucode and provide version and + * platform information. + * + * the Boot config needs to be adjusted by the ARM prior to starting + * the ucode if the Command/Status area isn't at 0x320000 in CF space + * (ie. beginning of SRAM). + */ + +#define HDR_OFFSET 0x400 + +/* Info: Signature & version */ +#define HDR_SYS_SIG 0x00 /* 2 bytes system signature */ +#define SYS_SIG_ROMULUS 0x526d /* 'Rm' */ +#define SYS_SIG_WITHERSPOON 0x5773 /* 'Ws' */ +#define HDR_FW_VERS 0x02 /* 2 bytes Major.Minor */ +#define HDR_API_VERS 0x04 /* 2 bytes Major.Minor */ +#define API_VERSION_MAJ 1 /* Current version */ +#define API_VERSION_MIN 1 +#define HDR_FW_OPTIONS 0x08 /* 4 bytes option flags */ +#define FW_OPTION_TRACE_EN 0x00000001 /* FW tracing enabled */ + +/* Boot Config: Address of Command/Status area */ +#define HDR_CMD_STAT_AREA 0x80 /* 4 bytes CF address */ + +/* + * Command/Status area layout: Main part + */ + +/* Command/Status register: + * + * +---------------------------+ + * | STAT | RLEN | CLEN | CMD | + * | 8 | 8 | 8 | 8 | + * +---------------------------+ + * | | | | + * status | | | + * Response len | | + * (in bits) | | + * | | + * Command len | + * (in bits) | + * | + * Command code + * + * Due to the big endian layout, that means that a byte read will + * return the status byte + */ +#define CMD_STAT_REG 0x00 +#define CMD_REG_CMD_MASK 0x000000ff +#define CMD_REG_CMD_SHIFT 0 +#define CMD_NONE 0x00 +#define CMD_COMMAND 0x01 +#define CMD_BREAK 0x02 +#define CMD_IDLE_CLOCKS 0x03 /* clen = #clocks */ +#define CMD_INVALID 0xff +#define CMD_REG_CLEN_MASK 0x0000ff00 +#define CMD_REG_CLEN_SHIFT 8 +#define CMD_REG_RLEN_MASK 0x00ff0000 +#define CMD_REG_RLEN_SHIFT 16 +#define CMD_REG_STAT_MASK 0xff000000 +#define CMD_REG_STAT_SHIFT 24 +#define STAT_WORKING 0x00 +#define STAT_COMPLETE 0x01 +#define STAT_ERR_INVAL_CMD 0x80 +#define STAT_ERR_INVAL_IRQ 0x81 +#define STAT_ERR_MTOE 0x82 + +/* Response tag & CRC */ +#define STAT_RTAG 0x04 + +/* Response CRC */ +#define STAT_RCRC 0x05 + +/* Echo and Send delay */ +#define ECHO_DLY_REG 0x08 +#define SEND_DLY_REG 0x09 + +/* Command data area + * + * Last byte of message must be left aligned + */ +#define CMD_DATA 0x10 /* 64 bit of data */ + +/* Response data area, right aligned, unused top bits are 1 */ +#define RSP_DATA 0x20 /* 32 bit of data */ + +/* Misc */ +#define INT_CNT 0x30 /* 32-bit interrupt count */ +#define BAD_INT_VEC 0x34 +#define CF_STARTED 0x38 /* byte, set to -1 when copro started */ + +/* + * SRAM layout: GPIO arbitration part + */ +#define ARB_REG 0x40 +#define ARB_ARM_REQ 0x01 +#define ARB_ARM_ACK 0x02 + +/* + * SRAM layout: Trace buffer (debug builds only) + */ +#define TRACEBUF 0x100 +#define TR_CLKOBIT0 0xc0 +#define TR_CLKOBIT1 0xc1 +#define TR_CLKOSTART 0x82 +#define TR_OLEN 0x83 /* + len */ +#define TR_CLKZ 0x84 /* + count */ +#define TR_CLKWSTART 0x85 +#define TR_CLKTAG 0x86 /* + tag */ +#define TR_CLKDATA 0x87 /* + len */ +#define TR_CLKCRC 0x88 /* + raw crc */ +#define TR_CLKIBIT0 0x90 +#define TR_CLKIBIT1 0x91 +#define TR_END 0xff + +#endif /* __CF_FSI_FW_H */ + diff --git a/drivers/fsi/fsi-master-ast-cf.c b/drivers/fsi/fsi-master-ast-cf.c new file mode 100644 index 000000000000..6b17f27c27f6 --- /dev/null +++ b/drivers/fsi/fsi-master-ast-cf.c @@ -0,0 +1,1376 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * A FSI master controller, using a simple GPIO bit-banging interface + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fsi-master.h" +#include "cf-fsi-fw.h" + +/* Common SCU based coprocessor control registers */ +#define SCU_COPRO_CTRL 0x100 +#define SCU_COPRO_RESET 0x00000002 +#define SCU_COPRO_CLK_EN 0x00000001 + +/* AST2500 specific ones */ +#define SCU_2500_COPRO_SEG0 0x104 +#define SCU_2500_COPRO_SEG1 0x108 +#define SCU_2500_COPRO_SEG2 0x10c +#define SCU_2500_COPRO_SEG3 0x110 +#define SCU_2500_COPRO_SEG4 0x114 +#define SCU_2500_COPRO_SEG5 0x118 +#define SCU_2500_COPRO_SEG6 0x11c +#define SCU_2500_COPRO_SEG7 0x120 +#define SCU_2500_COPRO_SEG8 0x124 +#define SCU_2500_COPRO_SEG_SWAP 0x00000001 +#define SCU_2500_COPRO_CACHE_CTL 0x128 +#define SCU_2500_COPRO_CACHE_EN 0x00000001 +#define SCU_2500_COPRO_SEG0_CACHE_EN 0x00000002 +#define SCU_2500_COPRO_SEG1_CACHE_EN 0x00000004 +#define SCU_2500_COPRO_SEG2_CACHE_EN 0x00000008 +#define SCU_2500_COPRO_SEG3_CACHE_EN 0x00000010 +#define SCU_2500_COPRO_SEG4_CACHE_EN 0x00000020 +#define SCU_2500_COPRO_SEG5_CACHE_EN 0x00000040 +#define SCU_2500_COPRO_SEG6_CACHE_EN 0x00000080 +#define SCU_2500_COPRO_SEG7_CACHE_EN 0x00000100 +#define SCU_2500_COPRO_SEG8_CACHE_EN 0x00000200 + +#define SCU_2400_COPRO_SEG0 0x104 +#define SCU_2400_COPRO_SEG2 0x108 +#define SCU_2400_COPRO_SEG4 0x10c +#define SCU_2400_COPRO_SEG6 0x110 +#define SCU_2400_COPRO_SEG8 0x114 +#define SCU_2400_COPRO_SEG_SWAP 0x80000000 +#define SCU_2400_COPRO_CACHE_CTL 0x118 +#define SCU_2400_COPRO_CACHE_EN 0x00000001 +#define SCU_2400_COPRO_SEG0_CACHE_EN 0x00000002 +#define SCU_2400_COPRO_SEG2_CACHE_EN 0x00000004 +#define SCU_2400_COPRO_SEG4_CACHE_EN 0x00000008 +#define SCU_2400_COPRO_SEG6_CACHE_EN 0x00000010 +#define SCU_2400_COPRO_SEG8_CACHE_EN 0x00000020 + +/* CVIC registers */ +#define CVIC_EN_REG 0x10 +#define CVIC_TRIG_REG 0x18 + +/* + * System register base address (needed for configuring the + * coldfire maps) + */ +#define SYSREG_BASE 0x1e600000 + +/* Amount of SRAM required */ +#define SRAM_SIZE 0x1000 + +#define LAST_ADDR_INVALID 0x1 + +struct fsi_master_acf { + struct fsi_master master; + struct device *dev; + struct regmap *scu; + struct mutex lock; /* mutex for command ordering */ + struct gpio_desc *gpio_clk; + struct gpio_desc *gpio_data; + struct gpio_desc *gpio_trans; /* Voltage translator */ + struct gpio_desc *gpio_enable; /* FSI enable */ + struct gpio_desc *gpio_mux; /* Mux control */ + uint32_t cf_mem_addr; + size_t cf_mem_size; + void __iomem *cf_mem; + void __iomem *cvic; + struct gen_pool *sram_pool; + void __iomem *sram; + bool is_ast2500; + bool external_mode; + bool trace_enabled; + uint32_t last_addr; + uint8_t t_send_delay; + uint8_t t_echo_delay; + uint32_t cvic_sw_irq; +}; +#define to_fsi_master_acf(m) container_of(m, struct fsi_master_acf, master) + +struct fsi_msg { + uint64_t msg; + uint8_t bits; +}; + +#define CREATE_TRACE_POINTS +#include + +static void msg_push_bits(struct fsi_msg *msg, uint64_t data, int bits) +{ + msg->msg <<= bits; + msg->msg |= data & ((1ull << bits) - 1); + msg->bits += bits; +} + +static void msg_push_crc(struct fsi_msg *msg) +{ + uint8_t crc; + int top; + + top = msg->bits & 0x3; + + /* start bit, and any non-aligned top bits */ + crc = crc4(0, 1 << top | msg->msg >> (msg->bits - top), top + 1); + + /* aligned bits */ + crc = crc4(crc, msg->msg, msg->bits - top); + + msg_push_bits(msg, crc, 4); +} + +static void msg_finish_cmd(struct fsi_msg *cmd) +{ + /* Left align message */ + cmd->msg <<= (64 - cmd->bits); +} + +static bool check_same_address(struct fsi_master_acf *master, int id, + uint32_t addr) +{ + /* this will also handle LAST_ADDR_INVALID */ + return master->last_addr == (((id & 0x3) << 21) | (addr & ~0x3)); +} + +static bool check_relative_address(struct fsi_master_acf *master, int id, + uint32_t addr, uint32_t *rel_addrp) +{ + uint32_t last_addr = master->last_addr; + int32_t rel_addr; + + if (last_addr == LAST_ADDR_INVALID) + return false; + + /* We may be in 23-bit addressing mode, which uses the id as the + * top two address bits. So, if we're referencing a different ID, + * use absolute addresses. + */ + if (((last_addr >> 21) & 0x3) != id) + return false; + + /* remove the top two bits from any 23-bit addressing */ + last_addr &= (1 << 21) - 1; + + /* We know that the addresses are limited to 21 bits, so this won't + * overflow the signed rel_addr */ + rel_addr = addr - last_addr; + if (rel_addr > 255 || rel_addr < -256) + return false; + + *rel_addrp = (uint32_t)rel_addr; + + return true; +} + +static void last_address_update(struct fsi_master_acf *master, + int id, bool valid, uint32_t addr) +{ + if (!valid) + master->last_addr = LAST_ADDR_INVALID; + else + master->last_addr = ((id & 0x3) << 21) | (addr & ~0x3); +} + +/* + * Encode an Absolute/Relative/Same Address command + */ +static void build_ar_command(struct fsi_master_acf *master, + struct fsi_msg *cmd, uint8_t id, + uint32_t addr, size_t size, + const void *data) +{ + int i, addr_bits, opcode_bits; + bool write = !!data; + uint8_t ds, opcode; + uint32_t rel_addr; + + cmd->bits = 0; + cmd->msg = 0; + + /* we have 21 bits of address max */ + addr &= ((1 << 21) - 1); + + /* cmd opcodes are variable length - SAME_AR is only two bits */ + opcode_bits = 3; + + if (check_same_address(master, id, addr)) { + /* we still address the byte offset within the word */ + addr_bits = 2; + opcode_bits = 2; + opcode = FSI_CMD_SAME_AR; + trace_fsi_master_acf_cmd_same_addr(master); + + } else if (check_relative_address(master, id, addr, &rel_addr)) { + /* 8 bits plus sign */ + addr_bits = 9; + addr = rel_addr; + opcode = FSI_CMD_REL_AR; + trace_fsi_master_acf_cmd_rel_addr(master, rel_addr); + + } else { + addr_bits = 21; + opcode = FSI_CMD_ABS_AR; + trace_fsi_master_acf_cmd_abs_addr(master, addr); + } + + /* + * The read/write size is encoded in the lower bits of the address + * (as it must be naturally-aligned), and the following ds bit. + * + * size addr:1 addr:0 ds + * 1 x x 0 + * 2 x 0 1 + * 4 0 1 1 + * + */ + ds = size > 1 ? 1 : 0; + addr &= ~(size - 1); + if (size == 4) + addr |= 1; + + msg_push_bits(cmd, id, 2); + msg_push_bits(cmd, opcode, opcode_bits); + msg_push_bits(cmd, write ? 0 : 1, 1); + msg_push_bits(cmd, addr, addr_bits); + msg_push_bits(cmd, ds, 1); + for (i = 0; write && i < size; i++) + msg_push_bits(cmd, ((uint8_t *)data)[i], 8); + + msg_push_crc(cmd); + msg_finish_cmd(cmd); +} + +static void build_dpoll_command(struct fsi_msg *cmd, uint8_t slave_id) +{ + cmd->bits = 0; + cmd->msg = 0; + + msg_push_bits(cmd, slave_id, 2); + msg_push_bits(cmd, FSI_CMD_DPOLL, 3); + msg_push_crc(cmd); + msg_finish_cmd(cmd); +} + +static void build_epoll_command(struct fsi_msg *cmd, uint8_t slave_id) +{ + cmd->bits = 0; + cmd->msg = 0; + + msg_push_bits(cmd, slave_id, 2); + msg_push_bits(cmd, FSI_CMD_EPOLL, 3); + msg_push_crc(cmd); + msg_finish_cmd(cmd); +} + +static void build_term_command(struct fsi_msg *cmd, uint8_t slave_id) +{ + cmd->bits = 0; + cmd->msg = 0; + + msg_push_bits(cmd, slave_id, 2); + msg_push_bits(cmd, FSI_CMD_TERM, 6); + msg_push_crc(cmd); + msg_finish_cmd(cmd); +} + +static int do_copro_command(struct fsi_master_acf *master, uint32_t op) +{ + uint32_t timeout = 10000000; + uint8_t stat; + + trace_fsi_master_acf_copro_command(master, op); + + /* Send command */ + writel(cpu_to_be32(op), master->sram + CMD_STAT_REG); + + /* Read back to avoid ordering issue */ + (void)readl(master->sram + CMD_STAT_REG); + + /* Ring doorbell if any */ + if (master->cvic) + writel(0x2, master->cvic + CVIC_TRIG_REG); + + /* Wait for status to indicate completion (or error) */ + do { + if (timeout-- == 0) { + dev_warn(master->dev, + "Timeout waiting for coprocessor completion\n"); + return -ETIMEDOUT; + } + stat = readb(master->sram + CMD_STAT_REG); + } while(stat < STAT_COMPLETE || stat == 0xff); + + if (stat == STAT_COMPLETE) + return 0; + switch(stat) { + case STAT_ERR_INVAL_CMD: + return -EINVAL; + case STAT_ERR_INVAL_IRQ: + return -EIO; + case STAT_ERR_MTOE: + return -ESHUTDOWN; + } + return -ENXIO; +} + +static int clock_zeros(struct fsi_master_acf *master, int count) +{ + while (count) { + int rc, lcnt = min(count, 255); + + rc = do_copro_command(master, + CMD_IDLE_CLOCKS | (lcnt << CMD_REG_CLEN_SHIFT)); + if (rc) + return rc; + count -= lcnt; + } + return 0; +} + +static int send_request(struct fsi_master_acf *master, struct fsi_msg *cmd, + bool is_write) +{ + u32 op; + + trace_fsi_master_acf_send_request(master, cmd, is_write); + + /* Store message into SRAM */ + writel(cpu_to_be32(cmd->msg >> 32), master->sram + CMD_DATA); + writel(cpu_to_be32(cmd->msg & 0xffffffff), master->sram + CMD_DATA + 4); + + op = CMD_COMMAND; + op |= cmd->bits << CMD_REG_CLEN_SHIFT; + if (!is_write) + op |= 32 << CMD_REG_RLEN_SHIFT; + + return do_copro_command(master, op); +} + +static int read_copro_response(struct fsi_master_acf *master, uint8_t size, + __be32 *response, u8 *tag) +{ + u8 rtag = readb(master->sram + STAT_RTAG); + u8 rcrc = readb(master->sram + STAT_RCRC); + __be32 rdata = 0; + u32 crc; + u8 ack; + + *tag = ack = rtag & 3; + + /* we have a whole message now; check CRC */ + crc = crc4(0, 1, 1); + crc = crc4(crc, rtag, 4); + if (ack == FSI_RESP_ACK && size) { + rdata = readl(master->sram + RSP_DATA); + crc = crc4(crc, be32_to_cpu(rdata), 32); + if (response) + *response = rdata; + } + crc = crc4(crc, rcrc, 4); + + trace_fsi_master_acf_copro_response(master, rtag, rcrc, rdata, crc == 0); + + if (crc) { + /* + * Check if it's all 1's or all 0's, that probably means + * the host is off + */ + if ((rtag == 0xf && rcrc == 0xf) || (rtag == 0 && rcrc == 0)) + return -ENODEV; + dev_dbg(master->dev, "Bad response CRC !\n"); + return -EAGAIN; + } + return 0; +} + +static int send_term(struct fsi_master_acf *master, uint8_t slave) +{ + struct fsi_msg cmd; + uint8_t tag; + int rc; + + build_term_command(&cmd, slave); + + rc = send_request(master, &cmd, true); + if (rc) { + dev_warn(master->dev, "Error %d sending term\n", rc); + return rc; + } + + rc = read_copro_response(master, 0, NULL, &tag); + if (rc < 0) { + dev_err(master->dev, + "TERM failed; lost communication with slave\n"); + return -EIO; + } else if (tag != FSI_RESP_ACK) { + dev_err(master->dev, "TERM failed; response %d\n", tag); + return -EIO; + } + return 0; +} + +static void dump_trace(struct fsi_master_acf *master) +{ + char trbuf[52]; + char *p; + int i; + + dev_dbg(master->dev, + "CMDSTAT:%08x RTAG=%02x RCRC=%02x RDATA=%02x #INT=%08x\n", + be32_to_cpu(readl(master->sram + CMD_STAT_REG)), + readb(master->sram + STAT_RTAG), + readb(master->sram + STAT_RCRC), + be32_to_cpu(readl(master->sram + RSP_DATA)), + be32_to_cpu(readl(master->sram + INT_CNT))); + + for (i = 0; i < 512; i++) { + uint8_t v; + if ((i % 16) == 0) + p = trbuf; + v = readb(master->sram + TRACEBUF + i); + p += sprintf(p, "%02x ", v); + if (((i % 16) == 15) || v == TR_END) + dev_dbg(master->dev, "%s\n", trbuf); + if (v == TR_END) + break; + } +} + +static int handle_response(struct fsi_master_acf *master, + uint8_t slave, uint8_t size, void *data) +{ + int busy_count = 0, rc; + int crc_err_retries = 0; + struct fsi_msg cmd; + __be32 response; + uint8_t tag; +retry: + rc = read_copro_response(master, size, &response, &tag); + + /* Handle retries on CRC errors */ + if (rc == -EAGAIN) { + /* Too many retries ? */ + if (crc_err_retries++ > FSI_CRC_ERR_RETRIES) { + /* + * Pass it up as a -EIO otherwise upper level will retry + * the whole command which isn't what we want here. + */ + rc = -EIO; + goto bail; + } + trace_fsi_master_acf_crc_rsp_error(master, crc_err_retries); + if (master->trace_enabled) + dump_trace(master); + rc = clock_zeros(master, FSI_MASTER_EPOLL_CLOCKS); + if (rc) { + dev_warn(master->dev, + "Error %d clocking zeros for E_POLL\n", rc); + return rc; + } + build_epoll_command(&cmd, slave); + rc = send_request(master, &cmd, size == 0); + if (rc) { + dev_warn(master->dev, "Error %d sending E_POLL\n", rc); + return -EIO; + } + goto retry; + } + if (rc) + return rc; + + switch (tag) { + case FSI_RESP_ACK: + if (size && data) { + if (size == 4) + *(__be32 *)data = response; + else if (size == 2) + *(__be16 *)data = response; + else + *(u8 *)data = response; + } + break; + case FSI_RESP_BUSY: + /* + * Its necessary to clock slave before issuing + * d-poll, not indicated in the hardware protocol + * spec. < 20 clocks causes slave to hang, 21 ok. + */ + dev_dbg(master->dev, "Busy, retrying...\n"); + if (master->trace_enabled) + dump_trace(master); + rc = clock_zeros(master, FSI_MASTER_DPOLL_CLOCKS); + if (rc) { + dev_warn(master->dev, + "Error %d clocking zeros for D_POLL\n", rc); + break; + } + if (busy_count++ < FSI_MASTER_MAX_BUSY) { + build_dpoll_command(&cmd, slave); + rc = send_request(master, &cmd, size == 0); + if (rc) { + dev_warn(master->dev, "Error %d sending D_POLL\n", rc); + break; + } + goto retry; + } + dev_dbg(master->dev, + "ERR slave is stuck in busy state, issuing TERM\n"); + send_term(master, slave); + rc = -EIO; + break; + + case FSI_RESP_ERRA: + dev_dbg(master->dev, "ERRA received\n"); + if (master->trace_enabled) + dump_trace(master); + rc = -EIO; + break; + case FSI_RESP_ERRC: + dev_dbg(master->dev, "ERRC received\n"); + if (master->trace_enabled) + dump_trace(master); + rc = -EAGAIN; + break; + } + bail: + if (busy_count > 0) { + trace_fsi_master_acf_poll_response_busy(master, busy_count); + } + + return rc; +} + +static int fsi_master_acf_xfer(struct fsi_master_acf *master, uint8_t slave, + struct fsi_msg *cmd, size_t resp_len, void *resp) +{ + int rc = -EAGAIN, retries = 0; + + while ((retries++) < FSI_CRC_ERR_RETRIES) { + rc = send_request(master, cmd, resp_len == 0); + if (rc) { + if (rc != -ESHUTDOWN) + dev_warn(master->dev, "Error %d sending command\n", rc); + break; + } + rc = handle_response(master, slave, resp_len, resp); + if (rc != -EAGAIN) + break; + rc = -EIO; + dev_dbg(master->dev, "ECRC retry %d\n", retries); + + /* Pace it a bit before retry */ + msleep(1); + } + + return rc; +} + +static int fsi_master_acf_read(struct fsi_master *_master, int link, + uint8_t id, uint32_t addr, void *val, + size_t size) +{ + struct fsi_master_acf *master = to_fsi_master_acf(_master); + struct fsi_msg cmd; + int rc; + + if (link != 0) + return -ENODEV; + + mutex_lock(&master->lock); + dev_dbg(master->dev, "read id %d addr %x size %d\n", id, addr, size); + build_ar_command(master, &cmd, id, addr, size, NULL); + rc = fsi_master_acf_xfer(master, id, &cmd, size, val); + last_address_update(master, id, rc == 0, addr); + if (rc) + dev_dbg(master->dev, "read id %d addr 0x%08x err: %d\n", + id, addr, rc); + mutex_unlock(&master->lock); + + return rc; +} + +static int fsi_master_acf_write(struct fsi_master *_master, int link, + uint8_t id, uint32_t addr, const void *val, + size_t size) +{ + struct fsi_master_acf *master = to_fsi_master_acf(_master); + struct fsi_msg cmd; + int rc; + + if (link != 0) + return -ENODEV; + + mutex_lock(&master->lock); + build_ar_command(master, &cmd, id, addr, size, val); + dev_dbg(master->dev, "write id %d addr %x size %d raw_data: %08x\n", + id, addr, size, *(u32 *)val); + rc = fsi_master_acf_xfer(master, id, &cmd, 0, NULL); + last_address_update(master, id, rc == 0, addr); + if (rc) + dev_dbg(master->dev, "write id %d addr 0x%08x err: %d\n", + id, addr, rc); + mutex_unlock(&master->lock); + + return rc; +} + +static int fsi_master_acf_term(struct fsi_master *_master, + int link, uint8_t id) +{ + struct fsi_master_acf *master = to_fsi_master_acf(_master); + struct fsi_msg cmd; + int rc; + + if (link != 0) + return -ENODEV; + + mutex_lock(&master->lock); + build_term_command(&cmd, id); + dev_dbg(master->dev, "term id %d\n", id); + rc = fsi_master_acf_xfer(master, id, &cmd, 0, NULL); + last_address_update(master, id, false, 0); + mutex_unlock(&master->lock); + + return rc; +} + +static int fsi_master_acf_break(struct fsi_master *_master, int link) +{ + struct fsi_master_acf *master = to_fsi_master_acf(_master); + int rc; + + if (link != 0) + return -ENODEV; + + mutex_lock(&master->lock); + if (master->external_mode) { + mutex_unlock(&master->lock); + return -EBUSY; + } + dev_dbg(master->dev, "sending BREAK\n"); + rc = do_copro_command(master, CMD_BREAK); + last_address_update(master, 0, false, 0); + mutex_unlock(&master->lock); + + /* Wait for logic reset to take effect */ + udelay(200); + + return rc; +} + +static void reset_cf(struct fsi_master_acf *master) +{ + regmap_write(master->scu, SCU_COPRO_CTRL, SCU_COPRO_RESET); + usleep_range(20,20); + regmap_write(master->scu, SCU_COPRO_CTRL, 0); + usleep_range(20,20); +} + +static void start_cf(struct fsi_master_acf *master) +{ + regmap_write(master->scu, SCU_COPRO_CTRL, SCU_COPRO_CLK_EN); +} + +static void setup_ast2500_cf_maps(struct fsi_master_acf *master) +{ + /* + * Note about byteswap setting: the bus is wired backwards, + * so setting the byteswap bit actually makes the ColdFire + * work "normally" for a BE processor, ie, put the MSB in + * the lowest address byte. + * + * We thus need to set the bit for our main memory which + * contains our program code. We create two mappings for + * the register, one with each setting. + * + * Segments 2 and 3 has a "swapped" mapping (BE) + * and 6 and 7 have a non-swapped mapping (LE) which allows + * us to avoid byteswapping register accesses since the + * registers are all LE. + */ + + /* Setup segment 0 to our memory region */ + regmap_write(master->scu, SCU_2500_COPRO_SEG0, master->cf_mem_addr | + SCU_2500_COPRO_SEG_SWAP); + + /* Segments 2 and 3 to sysregs with byteswap (for SRAM) */ + regmap_write(master->scu, SCU_2500_COPRO_SEG2, SYSREG_BASE | + SCU_2500_COPRO_SEG_SWAP); + regmap_write(master->scu, SCU_2500_COPRO_SEG3, SYSREG_BASE | 0x100000 | + SCU_2500_COPRO_SEG_SWAP); + + /* And segment 6 and 7 to sysregs no byteswap */ + regmap_write(master->scu, SCU_2500_COPRO_SEG6, SYSREG_BASE); + regmap_write(master->scu, SCU_2500_COPRO_SEG7, SYSREG_BASE | 0x100000); + + /* Memory cachable, regs and SRAM not cachable */ + regmap_write(master->scu, SCU_2500_COPRO_CACHE_CTL, + SCU_2500_COPRO_SEG0_CACHE_EN | SCU_2500_COPRO_CACHE_EN); +} + +static void setup_ast2400_cf_maps(struct fsi_master_acf *master) +{ + /* Setup segment 0 to our memory region */ + regmap_write(master->scu, SCU_2400_COPRO_SEG0, master->cf_mem_addr | + SCU_2400_COPRO_SEG_SWAP); + + /* Segments 2 to sysregs with byteswap (for SRAM) */ + regmap_write(master->scu, SCU_2400_COPRO_SEG2, SYSREG_BASE | + SCU_2400_COPRO_SEG_SWAP); + + /* And segment 6 to sysregs no byteswap */ + regmap_write(master->scu, SCU_2400_COPRO_SEG6, SYSREG_BASE); + + /* Memory cachable, regs and SRAM not cachable */ + regmap_write(master->scu, SCU_2400_COPRO_CACHE_CTL, + SCU_2400_COPRO_SEG0_CACHE_EN | SCU_2400_COPRO_CACHE_EN); +} + +static int setup_gpios_for_copro(struct fsi_master_acf *master) +{ + + int rc; + + /* This aren't under ColdFire control, just set them up appropriately */ + gpiod_direction_output(master->gpio_mux, 1); + gpiod_direction_output(master->gpio_enable, 1); + + /* Those are under ColdFire control, let it configure them */ + rc = aspeed_gpio_copro_grab_gpio(master->gpio_clk); + if (rc) { + dev_err(master->dev, "failed to assign clock gpio to coprocessor\n"); + return rc; + } + rc = aspeed_gpio_copro_grab_gpio(master->gpio_data); + if (rc) { + dev_err(master->dev, "failed to assign data gpio to coprocessor\n"); + aspeed_gpio_copro_release_gpio(master->gpio_clk); + return rc; + } + rc = aspeed_gpio_copro_grab_gpio(master->gpio_trans); + if (rc) { + dev_err(master->dev, "failed to assign trans gpio to coprocessor\n"); + aspeed_gpio_copro_release_gpio(master->gpio_clk); + aspeed_gpio_copro_release_gpio(master->gpio_data); + return rc; + } + return 0; +} + +static void release_copro_gpios(struct fsi_master_acf *master) +{ + aspeed_gpio_copro_release_gpio(master->gpio_clk); + aspeed_gpio_copro_release_gpio(master->gpio_data); + aspeed_gpio_copro_release_gpio(master->gpio_trans); +} + +static int load_copro_firmware(struct fsi_master_acf *master) +{ +#define MAX_FW_NAME 32 + char name[MAX_FW_NAME + 1] = {0}; + const struct firmware *fw; + const char *pl_name; + int rc; + + pl_name = of_get_property(dev_of_node(master->dev), "fw-name", NULL); + if (!pl_name) { + dev_err(master->dev, "Missing 'fw-name' property !\n"); + return -ENODEV; + } + snprintf(name, MAX_FW_NAME, "cf-fsi-%s.bin", pl_name); + rc = request_firmware(&fw, name, master->dev); + if (rc) { + dev_err(master->dev, "Error %d to load firwmare '%s' !\n", rc, name); + return rc; + } + if (fw->size > master->cf_mem_size) { + dev_err(master->dev, "FW size (%zd) bigger than memory reserve (%zd)\n", + fw->size, master->cf_mem_size); + rc = -ENOMEM; + } else { + memcpy_toio(master->cf_mem, fw->data, fw->size); + } + release_firmware(fw); + + return rc; +} + +static int check_firmware_image(struct fsi_master_acf *master) +{ + u32 platform_sig, fw_sig, fw_vers, fw_api, fw_options; + int rc; + + rc = of_property_read_u32(dev_of_node(master->dev), "fw-platform-sig", &platform_sig); + if (rc) { + dev_err(master->dev, "Missing 'fw-platform-sig' property\n"); + return -ENODEV; + } + + fw_sig = be16_to_cpu(readw(master->cf_mem + HDR_OFFSET + HDR_SYS_SIG)); + fw_vers = be16_to_cpu(readw(master->cf_mem + HDR_OFFSET + HDR_FW_VERS)); + fw_api = be16_to_cpu(readw(master->cf_mem + HDR_OFFSET + HDR_API_VERS)); + fw_options = be32_to_cpu(readl(master->cf_mem + HDR_OFFSET + HDR_FW_OPTIONS)); + master->trace_enabled = !!(fw_options & FW_OPTION_TRACE_EN); + + /* Check version and signature */ + dev_info(master->dev, "ColdFire initialized, firmware v%d API v%d.%d (trace %s)\n", + fw_vers, fw_api >> 8, fw_api & 0xff, + master->trace_enabled ? "enabled" : "disabled"); + + if ((fw_api >> 8) != API_VERSION_MAJ) { + dev_err(master->dev, "Unsupported coprocessor API version !\n"); + return -ENODEV; + } + + if (platform_sig != fw_sig) { + dev_err(master->dev, "Platform signature mismatch ! Want %04x got %04x\n", + platform_sig, fw_sig); + return -ENODEV; + } + return 0; +} + +static int copro_enable_sw_irq(struct fsi_master_acf *master) +{ + int timeout; + u32 val; + /* + * Enable coprocessor interrupt input. I've had problems getting the + * value to stick, so try in a loop + */ + for (timeout = 0; timeout < 10; timeout++) { + writel(0x2, master->cvic + CVIC_EN_REG); + val = readl(master->cvic + CVIC_EN_REG); + if (val & 2) + break; + msleep(1); + } + if (!(val & 2)) { + dev_err(master->dev, "Failed to enable coprocessor interrupt !\n"); + return -ENODEV; + } + return 0; +} + +static int fsi_master_acf_setup(struct fsi_master_acf *master) +{ + int timeout, rc; + u32 val; + + /* Make sure the ColdFire is stopped */ + reset_cf(master); + + /* + * Clear SRAM. This needs to happen before we setup the GPIOs + * as we might start trying to arbitrate as soon as that happens. + */ + memset_io(master->sram, 0, SRAM_SIZE); + + /* Configure GPIOs */ + rc = setup_gpios_for_copro(master); + if (rc) + return rc; + + /* Load the firmware into the reserved memory */ + rc = load_copro_firmware(master); + if (rc) + return rc; + + /* Read signature and check versions */ + rc = check_firmware_image(master); + if (rc) + return rc; + + /* Setup coldfire memory map */ + if (master->is_ast2500) + setup_ast2500_cf_maps(master); + else + setup_ast2400_cf_maps(master); + + /* Start the ColdFire */ + start_cf(master); + + /* Wait for status register to indicate command completion + * which signals the initialization is complete + */ + for (timeout = 0; timeout < 10; timeout++) { + val = readb(master->sram + CF_STARTED); + if (val) + break; + msleep(1); + }; + if (!val) { + dev_err(master->dev, "Coprocessor startup timeout !\n"); + rc = -ENODEV; + goto err; + } + + /* Configure echo & send delay */ + writeb(master->t_send_delay, master->sram + SEND_DLY_REG); + writeb(master->t_echo_delay, master->sram + ECHO_DLY_REG); + + /* Enable SW interrupt to copro if any */ + if (master->cvic) { + rc = copro_enable_sw_irq(master); + if (rc) + goto err; + } + return 0; + err: + /* An error occurred, don't leave the coprocessor running */ + reset_cf(master); + + /* Release the GPIOs */ + release_copro_gpios(master); + + return rc; +} + + +static void fsi_master_acf_terminate(struct fsi_master_acf *master) +{ + unsigned long flags; + + /* + * A GPIO arbitration requestion could come in while this is + * happening. To avoid problems, we disable interrupts so it + * cannot preempt us on this CPU + */ + + local_irq_save(flags); + + /* Stop the coprocessor */ + reset_cf(master); + + /* We mark the copro not-started */ + writel(0, master->sram + CF_STARTED); + + /* We mark the ARB register as having given up arbitration to + * deal with a potential race with the arbitration request + */ + writeb(ARB_ARM_ACK, master->sram + ARB_REG); + + local_irq_restore(flags); + + /* Return the GPIOs to the ARM */ + release_copro_gpios(master); +} + +static void fsi_master_acf_setup_external(struct fsi_master_acf *master) +{ + /* Setup GPIOs for external FSI master (FSP box) */ + gpiod_direction_output(master->gpio_mux, 0); + gpiod_direction_output(master->gpio_trans, 0); + gpiod_direction_output(master->gpio_enable, 1); + gpiod_direction_input(master->gpio_clk); + gpiod_direction_input(master->gpio_data); +} + +static int fsi_master_acf_link_enable(struct fsi_master *_master, int link) +{ + struct fsi_master_acf *master = to_fsi_master_acf(_master); + int rc = -EBUSY; + + if (link != 0) + return -ENODEV; + + mutex_lock(&master->lock); + if (!master->external_mode) { + gpiod_set_value(master->gpio_enable, 1); + rc = 0; + } + mutex_unlock(&master->lock); + + return rc; +} + +static int fsi_master_acf_link_config(struct fsi_master *_master, int link, + u8 t_send_delay, u8 t_echo_delay) +{ + struct fsi_master_acf *master = to_fsi_master_acf(_master); + + if (link != 0) + return -ENODEV; + + mutex_lock(&master->lock); + master->t_send_delay = t_send_delay; + master->t_echo_delay = t_echo_delay; + dev_dbg(master->dev, "Changing delays: send=%d echo=%d\n", + t_send_delay, t_echo_delay); + writeb(master->t_send_delay, master->sram + SEND_DLY_REG); + writeb(master->t_echo_delay, master->sram + ECHO_DLY_REG); + mutex_unlock(&master->lock); + + return 0; +} + +static ssize_t external_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fsi_master_acf *master = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE - 1, "%u\n", + master->external_mode ? 1 : 0); +} + +static ssize_t external_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct fsi_master_acf *master = dev_get_drvdata(dev); + unsigned long val; + bool external_mode; + int err; + + err = kstrtoul(buf, 0, &val); + if (err) + return err; + + external_mode = !!val; + + mutex_lock(&master->lock); + + if (external_mode == master->external_mode) { + mutex_unlock(&master->lock); + return count; + } + + master->external_mode = external_mode; + if (master->external_mode) { + fsi_master_acf_terminate(master); + fsi_master_acf_setup_external(master); + } else + fsi_master_acf_setup(master); + + mutex_unlock(&master->lock); + + fsi_master_rescan(&master->master); + + return count; +} + +static DEVICE_ATTR(external_mode, 0664, + external_mode_show, external_mode_store); + +static int fsi_master_acf_gpio_request(void *data) +{ + struct fsi_master_acf *master = data; + int timeout; + u8 val; + + /* Note: This doesn't require holding out mutex */ + + /* Write reqest */ + writeb(ARB_ARM_REQ, master->sram + ARB_REG); + + /* Read back to avoid ordering issue */ + (void)readb(master->sram + ARB_REG); + + /* + * There is a race (which does happen at boot time) when we get an + * arbitration request as we are either about to or just starting + * the coprocessor. + * + * To handle it, we first check if we are running. If not yet we + * check whether the copro is started in the SCU. + * + * If it's not started, we can basically just assume we have arbitration + * and return. Otherwise, we wait normally expecting for the arbitration + * to eventually complete. + */ + if (readl(master->sram + CF_STARTED) == 0) { + unsigned int reg = 0; + + regmap_read(master->scu, SCU_COPRO_CTRL, ®); + if (!reg & SCU_COPRO_CLK_EN) + return 0; + } + + /* Ring doorbell if any */ + if (master->cvic) + writel(0x2, master->cvic + CVIC_TRIG_REG); + + for (timeout = 0; timeout < 10000; timeout++) { + val = readb(master->sram + ARB_REG); + if (val != ARB_ARM_REQ) + break; + udelay(1); + } + + /* If it failed, override anyway */ + if (val != ARB_ARM_ACK) + dev_warn(master->dev, "GPIO request arbitration timeout\n"); + + return 0; +} + +static int fsi_master_acf_gpio_release(void *data) +{ + struct fsi_master_acf *master = data; + + /* Write release */ + writeb(0, master->sram + ARB_REG); + + /* Ring doorbell if any */ + if (master->cvic) + writel(0x2, master->cvic + CVIC_TRIG_REG); + + return 0; +} + +static void fsi_master_acf_release(struct device *dev) +{ + struct fsi_master_acf *master = to_fsi_master_acf(dev_to_fsi_master(dev)); + + /* Cleanup, stop coprocessor */ + mutex_lock(&master->lock); + fsi_master_acf_terminate(master); + aspeed_gpio_copro_set_ops(NULL, NULL); + mutex_unlock(&master->lock); + + /* Free resources */ + gen_pool_free(master->sram_pool, (unsigned long)master->sram, SRAM_SIZE); + of_node_put(dev_of_node(master->dev)); + + kfree(dev); +} + +static const struct aspeed_gpio_copro_ops fsi_master_acf_gpio_ops = { + .request_access = fsi_master_acf_gpio_request, + .release_access = fsi_master_acf_gpio_release, +}; + +static int fsi_master_acf_probe(struct platform_device *pdev) +{ + struct device_node *np, *mnode = dev_of_node(&pdev->dev); + struct genpool_data_fixed gpdf; + struct fsi_master_acf *master; + struct gpio_desc *gpio; + struct resource res; + u32 cf_mem_align; + int rc; + + master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL); + if (!master) + return -ENOMEM; + + master->dev = &pdev->dev; + master->master.dev.parent = master->dev; + master->last_addr = LAST_ADDR_INVALID; + + /* AST2400 vs. AST2500 */ + master->is_ast2500 = of_device_is_compatible(mnode, "ibm,fsi-master-ast2500-cf"); + + /* Grab the SCU, we'll need to access it to configure the coprocessor */ + if (master->is_ast2500) + master->scu = syscon_regmap_lookup_by_compatible("aspeed,ast2500-scu"); + else + master->scu = syscon_regmap_lookup_by_compatible("aspeed,ast2400-scu"); + if (IS_ERR(master->scu)) { + dev_err(&pdev->dev, "failed to find SCU regmap\n"); + return PTR_ERR(master->scu); + } + + /* Grab all the GPIOs we need */ + gpio = devm_gpiod_get(&pdev->dev, "clock", 0); + if (IS_ERR(gpio)) { + dev_err(&pdev->dev, "failed to get clock gpio\n"); + return PTR_ERR(gpio); + } + master->gpio_clk = gpio; + + gpio = devm_gpiod_get(&pdev->dev, "data", 0); + if (IS_ERR(gpio)) { + dev_err(&pdev->dev, "failed to get data gpio\n"); + return PTR_ERR(gpio); + } + master->gpio_data = gpio; + + /* Optional GPIOs */ + gpio = devm_gpiod_get_optional(&pdev->dev, "trans", 0); + if (IS_ERR(gpio)) { + dev_err(&pdev->dev, "failed to get trans gpio\n"); + return PTR_ERR(gpio); + } + master->gpio_trans = gpio; + + gpio = devm_gpiod_get_optional(&pdev->dev, "enable", 0); + if (IS_ERR(gpio)) { + dev_err(&pdev->dev, "failed to get enable gpio\n"); + return PTR_ERR(gpio); + } + master->gpio_enable = gpio; + + gpio = devm_gpiod_get_optional(&pdev->dev, "mux", 0); + if (IS_ERR(gpio)) { + dev_err(&pdev->dev, "failed to get mux gpio\n"); + return PTR_ERR(gpio); + } + master->gpio_mux = gpio; + + /* Grab the reserved memory region (use DMA API instead ?) */ + np = of_parse_phandle(mnode, "memory-region", 0); + if (!np) { + dev_err(&pdev->dev, "Didn't find reserved memory\n"); + return -EINVAL; + } + rc = of_address_to_resource(np, 0, &res); + of_node_put(np); + if (rc) { + dev_err(&pdev->dev, "Couldn't address to resource for reserved memory\n"); + return -ENOMEM; + } + master->cf_mem_size = resource_size(&res); + master->cf_mem_addr = (u32)res.start; + cf_mem_align = master->is_ast2500 ? 0x00100000 : 0x00200000; + if (master->cf_mem_addr & (cf_mem_align - 1)) { + dev_err(&pdev->dev, "Reserved memory has insufficient alignment\n"); + return -ENOMEM; + } + master->cf_mem = devm_ioremap_resource(&pdev->dev, &res); + if (IS_ERR(master->cf_mem)) { + rc = PTR_ERR(master->cf_mem); + dev_err(&pdev->dev, "Error %d mapping coldfire memory\n", rc); + return rc; + } + dev_dbg(&pdev->dev, "DRAM allocation @%x\n", master->cf_mem_addr); + + /* AST2500 has a SW interrupt to the coprocessor */ + if (master->is_ast2500) { + /* Grab the CVIC (ColdFire interrupts controller) */ + np = of_parse_phandle(mnode, "cvic", 0); + if (!np) { + dev_err(&pdev->dev, "Didn't find CVIC\n"); + return -EINVAL; + } + master->cvic = devm_of_iomap(&pdev->dev, np, 0, NULL); + if (IS_ERR(master->cvic)) { + rc = PTR_ERR(master->cvic); + dev_err(&pdev->dev, "Error %d mapping CVIC\n", rc); + return rc; + } + rc = of_property_read_u32(np, "copro-sw-interrupts", + &master->cvic_sw_irq); + if (rc) { + dev_err(&pdev->dev, "Can't find coprocessor SW interrupt\n"); + return rc; + } + } + + /* Grab the SRAM */ + master->sram_pool = of_gen_pool_get(dev_of_node(&pdev->dev), "sram", 0); + if (!master->sram_pool) { + rc = -ENODEV; + dev_err(&pdev->dev, "Can't find sram pool\n"); + return rc; + } + + /* Current microcode only deals with fixed location in SRAM */ + gpdf.offset = 0; + master->sram = (void __iomem *)gen_pool_alloc_algo(master->sram_pool, SRAM_SIZE, + gen_pool_fixed_alloc, &gpdf); + if (!master->sram) { + rc = -ENOMEM; + dev_err(&pdev->dev, "Failed to allocate sram from pool\n"); + return rc; + } + dev_dbg(&pdev->dev, "SRAM allocation @%lx\n", + (unsigned long)gen_pool_virt_to_phys(master->sram_pool, + (unsigned long)master->sram)); + + /* + * Hookup with the GPIO driver for arbitration of GPIO banks + * ownership. + */ + aspeed_gpio_copro_set_ops(&fsi_master_acf_gpio_ops, master); + + /* Default FSI command delays */ + master->t_send_delay = FSI_SEND_DELAY_CLOCKS; + master->t_echo_delay = FSI_ECHO_DELAY_CLOCKS; + + master->master.n_links = 1; + master->master.flags = FSI_MASTER_FLAG_SWCLOCK; + master->master.read = fsi_master_acf_read; + master->master.write = fsi_master_acf_write; + master->master.term = fsi_master_acf_term; + master->master.send_break = fsi_master_acf_break; + master->master.link_enable = fsi_master_acf_link_enable; + master->master.link_config = fsi_master_acf_link_config; + master->master.dev.of_node = of_node_get(dev_of_node(master->dev)); + master->master.dev.release = fsi_master_acf_release; + platform_set_drvdata(pdev, master); + mutex_init(&master->lock); + + mutex_lock(&master->lock); + rc = fsi_master_acf_setup(master); + mutex_unlock(&master->lock); + if (rc) + goto release_dev; + + rc = device_create_file(&pdev->dev, &dev_attr_external_mode); + if (rc) + goto stop_copro; + + rc = fsi_master_register(&master->master); + if (!rc) + return 0; + + device_remove_file(master->dev, &dev_attr_external_mode); + + stop_copro: + fsi_master_acf_terminate(master); + release_dev: + aspeed_gpio_copro_set_ops(NULL, NULL); + gen_pool_free(master->sram_pool, (unsigned long)master->sram, SRAM_SIZE); + of_node_put(dev_of_node(master->dev)); + + return rc; +} + + +static int fsi_master_acf_remove(struct platform_device *pdev) +{ + struct fsi_master_acf *master = platform_get_drvdata(pdev); + + device_remove_file(master->dev, &dev_attr_external_mode); + + fsi_master_unregister(&master->master); + + return 0; +} + +static const struct of_device_id fsi_master_acf_match[] = { + { .compatible = "ibm,fsi-master-ast2400-cf" }, + { .compatible = "ibm,fsi-master-ast2500-cf" }, + { }, +}; + +static struct platform_driver fsi_master_acf = { + .driver = { + .name = "fsi-master-acf", + .of_match_table = fsi_master_acf_match, + }, + .probe = fsi_master_acf_probe, + .remove = fsi_master_acf_remove, +}; + +module_platform_driver(fsi_master_acf); +MODULE_LICENSE("GPL"); diff --git a/include/trace/events/fsi_master_ast_cf.h b/include/trace/events/fsi_master_ast_cf.h new file mode 100644 index 000000000000..424da0172cdd --- /dev/null +++ b/include/trace/events/fsi_master_ast_cf.h @@ -0,0 +1,150 @@ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM fsi_master_ast_cf + +#if !defined(_TRACE_FSI_MASTER_ACF_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_FSI_MASTER_ACF_H + +#include + +TRACE_EVENT(fsi_master_acf_copro_command, + TP_PROTO(const struct fsi_master_acf *master, uint32_t op), + TP_ARGS(master, op), + TP_STRUCT__entry( + __field(int, master_idx) + __field(uint32_t, op) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->op = op; + ), + TP_printk("fsi-acf%d command %08x", + __entry->master_idx, __entry->op + ) +); + +TRACE_EVENT(fsi_master_acf_send_request, + TP_PROTO(const struct fsi_master_acf *master, const struct fsi_msg *cmd, bool is_write), + TP_ARGS(master, cmd, is_write), + TP_STRUCT__entry( + __field(int, master_idx) + __field(uint64_t, msg) + __field(u8, bits) + __field(bool, is_write) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->msg = cmd->msg; + __entry->bits = cmd->bits; + __entry->is_write = is_write; + ), + TP_printk("fsi-acf%d cmd: %016llx/%d (%c)", + __entry->master_idx, (unsigned long long)__entry->msg, + __entry->bits, __entry->is_write ? 'W' : 'R' + ) +); + +TRACE_EVENT(fsi_master_acf_copro_response, + TP_PROTO(const struct fsi_master_acf *master, u8 rtag, u8 rcrc, __be32 rdata, bool crc_ok), + TP_ARGS(master, rtag, rcrc, rdata, crc_ok), + TP_STRUCT__entry( + __field(int, master_idx) + __field(u8, rtag) + __field(u8, rcrc) + __field(u32, rdata) + __field(bool, crc_ok) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->rtag = rtag; + __entry->rcrc = rcrc; + __entry->rdata = be32_to_cpu(rdata); + __entry->crc_ok = crc_ok; + ), + TP_printk("fsi-acf%d rsp: tag=%04x crc=%04x data=%08x %c\n", + __entry->master_idx, __entry->rtag, __entry->rcrc, + __entry->rdata, __entry->crc_ok ? ' ' : '!' + ) +); + +TRACE_EVENT(fsi_master_acf_crc_rsp_error, + TP_PROTO(const struct fsi_master_acf *master, int retries), + TP_ARGS(master, retries), + TP_STRUCT__entry( + __field(int, master_idx) + __field(int, retries) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->retries = retries; + ), + TP_printk("fsi-acf%d CRC error in response retry %d", + __entry->master_idx, __entry->retries + ) +); + +TRACE_EVENT(fsi_master_acf_poll_response_busy, + TP_PROTO(const struct fsi_master_acf *master, int busy_count), + TP_ARGS(master, busy_count), + TP_STRUCT__entry( + __field(int, master_idx) + __field(int, busy_count) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->busy_count = busy_count; + ), + TP_printk("fsi-acf%d: device reported busy %d times", + __entry->master_idx, __entry->busy_count + ) +); + +TRACE_EVENT(fsi_master_acf_cmd_abs_addr, + TP_PROTO(const struct fsi_master_acf *master, u32 addr), + TP_ARGS(master, addr), + TP_STRUCT__entry( + __field(int, master_idx) + __field(u32, addr) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->addr = addr; + ), + TP_printk("fsi-acf%d: Sending ABS_ADR %06x", + __entry->master_idx, __entry->addr + ) +); + +TRACE_EVENT(fsi_master_acf_cmd_rel_addr, + TP_PROTO(const struct fsi_master_acf *master, u32 rel_addr), + TP_ARGS(master, rel_addr), + TP_STRUCT__entry( + __field(int, master_idx) + __field(u32, rel_addr) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->rel_addr = rel_addr; + ), + TP_printk("fsi-acf%d: Sending REL_ADR %03x", + __entry->master_idx, __entry->rel_addr + ) +); + +TRACE_EVENT(fsi_master_acf_cmd_same_addr, + TP_PROTO(const struct fsi_master_acf *master), + TP_ARGS(master), + TP_STRUCT__entry( + __field(int, master_idx) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + ), + TP_printk("fsi-acf%d: Sending SAME_ADR", + __entry->master_idx + ) +); + +#endif /* _TRACE_FSI_MASTER_ACF_H */ + +#include From patchwork Tue Jun 26 23:26:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 935164 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41FjJH2wwPz9s0n for ; Wed, 27 Jun 2018 09:42:23 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41FjJH1fXlzF1LJ for ; Wed, 27 Jun 2018 09:42:23 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41Fj083mJtzF1LK; Wed, 27 Jun 2018 09:28:23 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6qk022979; Tue, 26 Jun 2018 18:27:39 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 13/14] arm: dts: OpenPower Romulus system can use coprocessor for FSI Date: Wed, 27 Jun 2018 09:26:04 +1000 Message-Id: <20180626232605.13420-14-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" Signed-off-by: Benjamin Herrenschmidt --- arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts b/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts index 347938673c83..070b8f8f1d62 100644 --- a/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts +++ b/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts @@ -37,6 +37,11 @@ compatible = "shared-dma-pool"; reusable; }; + + coldfire_memory: codefire_memory@9ef00000 { + reg = <0x9ef00000 0x00100000>; + no-map; + }; }; leds { @@ -56,10 +61,16 @@ }; fsi: gpio-fsi { - compatible = "fsi-master-gpio", "fsi-master"; + compatible = "ibm,fsi-master-ast2500-cf", "fsi-master"; #address-cells = <2>; #size-cells = <0>; - no-gpio-delays; + + memory-region = <&coldfire_memory>; + sram = <&sram>; + cvic = <&cvic>; + + fw-name = "romulus"; + fw-platform-sig = <0x526d>; clock-gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_HIGH>; data-gpios = <&gpio ASPEED_GPIO(AA, 2) GPIO_ACTIVE_HIGH>; From patchwork Tue Jun 26 23:26:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 935208 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41FknT0LnSz9s1B for ; Wed, 27 Jun 2018 10:49:17 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41FknS5MzKzF1Hw for ; Wed, 27 Jun 2018 10:49:16 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: linux-aspeed@lists.ozlabs.org Delivered-To: linux-aspeed@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41FknL6RdXzF1D5; Wed, 27 Jun 2018 10:49:10 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w5QNQ6ql022979; Tue, 26 Jun 2018 18:27:46 -0500 From: Benjamin Herrenschmidt To: Joel Stanley Subject: [PATCH 14/14] arm: dts: OpenPower Palmetto system can use coprocessor for FSI Date: Wed, 27 Jun 2018 09:26:05 +1000 Message-Id: <20180626232605.13420-15-benh@kernel.crashing.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180626232605.13420-1-benh@kernel.crashing.org> References: <20180626232605.13420-1-benh@kernel.crashing.org> X-BeenThere: linux-aspeed@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Linux ASPEED SoC development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-aspeed@lists.ozlabs.org, openbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org Errors-To: linux-aspeed-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Linux-aspeed" This switches away from userspace bitbanging to kernel FSI using the coprocessor. Signed-off-by: Benjamin Herrenschmidt --- arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts index e6095f51ecf5..ba49b812e0bd 100644 --- a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts +++ b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts @@ -31,6 +31,11 @@ no-map; reg = <0x98000000 0x01000000>; /* 16MB */ }; + + coldfire_memory: codefire_memory@5ee00000 { + reg = <0x5ee00000 0x00200000>; + no-map; + }; }; leds { @@ -49,6 +54,25 @@ }; }; + fsi: gpio-fsi { + compatible = "ibm,fsi-master-ast2400-cf", "fsi-master"; + #address-cells = <2>; + #size-cells = <0>; + + memory-region = <&coldfire_memory>; + sram = <&sram>; + cvic = <&cvic>; + + fw-name = "palmetto"; + fw-platform-sig = <0x5061>; + + clock-gpios = <&gpio ASPEED_GPIO(A, 4) GPIO_ACTIVE_HIGH>; + data-gpios = <&gpio ASPEED_GPIO(A, 5) GPIO_ACTIVE_HIGH>; + mux-gpios = <&gpio ASPEED_GPIO(A, 6) GPIO_ACTIVE_HIGH>; + enable-gpios = <&gpio ASPEED_GPIO(D, 0) GPIO_ACTIVE_HIGH>; + trans-gpios = <&gpio ASPEED_GPIO(H, 6) GPIO_ACTIVE_HIGH>; + }; + gpio-keys { compatible = "gpio-keys"; @@ -323,13 +347,6 @@ line-name = "SYS_PWROK_BMC"; }; - pin_gpio_h6 { - gpio-hog; - gpios = ; - output-high; - line-name = "SCM1_FSI0_DATA_EN"; - }; - pin_gpio_h7 { gpio-hog; gpios = ;