From patchwork Thu Apr 13 15:29:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Bastian Krause X-Patchwork-Id: 9679647 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6391860381 for ; Thu, 13 Apr 2017 15:29:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5726A2866A for ; Thu, 13 Apr 2017 15:29:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 49C622866E; Thu, 13 Apr 2017 15:29:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E1CA828664 for ; Thu, 13 Apr 2017 15:29:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754659AbdDMP3U (ORCPT ); Thu, 13 Apr 2017 11:29:20 -0400 Received: from metis.ext.4.pengutronix.de ([92.198.50.35]:45081 "EHLO metis.ext.4.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754470AbdDMP3T (ORCPT ); Thu, 13 Apr 2017 11:29:19 -0400 Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7] helo=dude.pengutronix.de.) by metis.ext.pengutronix.de with esmtp (Exim 4.84_2) (envelope-from ) id 1cyggQ-00010f-8X; Thu, 13 Apr 2017 17:29:18 +0200 From: Bastian Stender To: Joshua Clayton Cc: kernel@pengutronix.de, linux-fpga@vger.kernel.org, Bastian Stender Subject: [PATCH] HACK: fpga: cyclone-ps-spi: adapt to Arria 10 specifics Date: Thu, 13 Apr 2017 17:29:16 +0200 Message-Id: <20170413152916.19896-2-bst@pengutronix.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170413152916.19896-1-bst@pengutronix.de> References: <94f1d92f502b64669467c467038c3aa766b312ad.1485295905.git.stillcompiling@gmail.com> <20170413152916.19896-1-bst@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: bst@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-fpga@vger.kernel.org Sender: linux-fpga-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fpga@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP --- drivers/fpga/cyclone-ps-spi.c | 51 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/drivers/fpga/cyclone-ps-spi.c b/drivers/fpga/cyclone-ps-spi.c index 56c385347bb7..175370d27404 100644 --- a/drivers/fpga/cyclone-ps-spi.c +++ b/drivers/fpga/cyclone-ps-spi.c @@ -22,12 +22,12 @@ #include #include -#define FPGA_RESET_TIME 50 /* time in usecs to trigger FPGA config */ -#define FPGA_MIN_DELAY 50 /* min usecs to wait for config status */ -#define FPGA_MAX_DELAY 1000 /* max usecs to wait for config status */ +#define FPGA_MIN_DELAY 268 /* min usecs to wait for config status -> min(t_STATUS) */ +#define FPGA_MAX_DELAY 3000 /* max usecs to wait for config status -> max(t_STATUS) */ struct cyclonespi_conf { struct gpio_desc *config; + struct gpio_desc *confd; struct gpio_desc *status; struct spi_device *spi; }; @@ -48,6 +48,15 @@ static enum fpga_mgr_states cyclonespi_state(struct fpga_manager *mgr) return FPGA_MGR_STATE_UNKNOWN; } +/* | Arria 10 | + * t_CF2ST0 | [; 600] | ns + * t_CFG | [2;] | µs + * t_STATUS | [268; 3000] | µs + * t_CF2ST1 | [; 3000] | µs + * t_CF2CK | [3010 µs;] | µs + * t_ST2CK | [10;] | µs + * t_CD2UM | [175; 830] | µs + */ static int cyclonespi_write_init(struct fpga_manager *mgr, struct fpga_image_info *info, const char *buf, size_t count) @@ -61,17 +70,25 @@ static int cyclonespi_write_init(struct fpga_manager *mgr, } gpiod_set_value(conf->config, 1); - usleep_range(FPGA_RESET_TIME, FPGA_RESET_TIME + 20); + /* max { min(t_CFG), max(tCF2ST0) } */ + udelay(2); if (!gpiod_get_value(conf->status)) { dev_err(&mgr->dev, "Status pin failed to show a reset\n"); return -EIO; } gpiod_set_value(conf->config, 0); + + /* wait for max { max(t_STATUS), max(t_CF2ST1) } */ for (i = 0; i < (FPGA_MAX_DELAY / FPGA_MIN_DELAY); i++) { usleep_range(FPGA_MIN_DELAY, FPGA_MIN_DELAY + 20); - if (!gpiod_get_value(conf->status)) + if (!gpiod_get_value(conf->status)) { + /* + * wait for min(t_ST2CK) + */ + udelay(10); return 0; + } } dev_err(&mgr->dev, "Status pin not ready.\n"); @@ -117,12 +134,29 @@ static int cyclonespi_write_complete(struct fpga_manager *mgr, struct fpga_image_info *info) { struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv; + const char dummy[] = {0, 0}; + int ret; if (gpiod_get_value(conf->status)) { dev_err(&mgr->dev, "Error during configuration.\n"); return -EIO; } + if (gpiod_get_value(conf->confd)) { + dev_err(&mgr->dev, "CONF_DONE is high!\n"); + return -EIO; + } + + /* + * After CONF_DONE goes high, send two additional falling edges on DCLK + * to begin initialization and enter user mode + */ + ret = spi_write(conf->spi, dummy, 2); + if (ret) { + dev_err(&mgr->dev, "spi error during end sequence: %d\n", ret); + return ret; + } + return 0; } @@ -149,6 +183,13 @@ static int cyclonespi_probe(struct spi_device *spi) return PTR_ERR(conf->config); } + conf->confd = devm_gpiod_get(&spi->dev, "confd", GPIOD_IN); + if (IS_ERR(conf->confd)) { + dev_err(&spi->dev, "Failed to get confd gpio: %ld\n", + PTR_ERR(conf->confd)); + return PTR_ERR(conf->confd); + } + conf->status = devm_gpiod_get(&spi->dev, "nstat", GPIOD_IN); if (IS_ERR(conf->status)) { dev_err(&spi->dev, "Failed to get status gpio: %ld\n",