From patchwork Mon Dec 14 08:11:14 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcus Weseloh X-Patchwork-Id: 7841971 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 603119F1C2 for ; Mon, 14 Dec 2015 08:11:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6490E203DF for ; Mon, 14 Dec 2015 08:11:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5A2B1203AC for ; Mon, 14 Dec 2015 08:11:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752093AbbLNIL0 (ORCPT ); Mon, 14 Dec 2015 03:11:26 -0500 Received: from mail-wm0-f48.google.com ([74.125.82.48]:34197 "EHLO mail-wm0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751280AbbLNILZ (ORCPT ); Mon, 14 Dec 2015 03:11:25 -0500 Received: by mail-wm0-f48.google.com with SMTP id p66so49804322wmp.1; Mon, 14 Dec 2015 00:11:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=9wbb5PqEkPe/q2GgbLCLb8lXN7PDbu/C9XeS6u4zwQc=; b=Ho1j/Y+HDefH8C+87ogoj5BA7Tqw9z05Py5tBLLH+NDAJmfsU3NOYjFfISessdRKOJ jS8OtvaaNEA4ZMJB23tAj3dnr1vf7i0EPmPBG3lTVCrzC5S6PyvIcsmANHQGuRjOWFUt gegJ7mORF13Qg3b35GMWmbXmWorLtprwcYk76u7WPWZwnk5CHqLIf123PwUvHffiWf5p UzkQUw+XkZ3sKksuPVgXW3ZZdZIsFuiNf9KLAbSdwRwEVMSUAuwEUaUQvHEYi0U5X3Mx Cbz6IC/EcVLo0+m9TFCp4XB5ZOuKVmdOfz0Ce1M+RtxvwBxduSISJerY5MB/nuYcvLWA 9nfg== X-Received: by 10.194.9.7 with SMTP id v7mr35235544wja.25.1450080683610; Mon, 14 Dec 2015 00:11:23 -0800 (PST) Received: from speedy.fritz.box (p578E9C34.dip0.t-ipconnect.de. [87.142.156.52]) by smtp.gmail.com with ESMTPSA id 197sm14971920wmt.19.2015.12.14.00.11.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 14 Dec 2015 00:11:22 -0800 (PST) From: Marcus Weseloh To: linux-sunxi@googlegroups.com Cc: Marcus Weseloh , Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala , Mark Brown , Maxime Ripard , Chen-Yu Tsai , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH v4] spi: dts: sun4i: Add support for wait time between word transmissions Date: Mon, 14 Dec 2015 09:11:14 +0100 Message-Id: <1450080676-6704-1-git-send-email-mweseloh42@gmail.com> X-Mailer: git-send-email 1.9.1 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Adds a new property "spi-word-wait-ns" to the spi-bus binding that allows SPI slave devices to set a wait time between the transmission of words. Modifies the spi_device struct and slave device probing to read and store the new property. Also modifies the sun4i SPI master driver to make use of the new property. This specific SPI controller needs 3 clock cycles to set up the delay, which makes the minimum non-zero wait time on this hardware 4 clock cycles. Signed-off-by: Marcus Weseloh --- Changes from v1: * renamed the property for more clarity * wait time is set in nanoseconds instead of number of clock cycles * transparently handle the 3 setup clock cycles Changes from v2: * fixed typo in comment * moved parameter to spi-bus binding, dropping the vendor prefix * changed commit summary and description to reflect the changes Changes from v3: * remove reference to "hardware" in comments and description, as the wait time could also be implemented in software * read and set property value in spi core As I am now changing SPI core, the sun4i driver and the spi-bus binding, I should probably split the patch into smaller parts (spi core + binding, sun4i changes). I will do that as soon as you are satisfied with the actual approach. --- Documentation/devicetree/bindings/spi/spi-bus.txt | 2 ++ drivers/spi/spi-sun4i.c | 23 +++++++++++++++++++++++ drivers/spi/spi.c | 2 ++ include/linux/spi/spi.h | 2 ++ 4 files changed, 29 insertions(+) diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt index bbaa857..434d321 100644 --- a/Documentation/devicetree/bindings/spi/spi-bus.txt +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt @@ -61,6 +61,8 @@ contain the following properties. used for MOSI. Defaults to 1 if not present. - spi-rx-bus-width - (optional) The bus width(number of data wires) that used for MISO. Defaults to 1 if not present. +- spi-word-wait-ns - (optional) Delay between transmission of words + in nanoseconds Some SPI controllers and devices support Dual and Quad SPI transfer mode. It allows data in the SPI system to be transferred in 2 wires(DUAL) or 4 wires(QUAD). diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c index f60a6d6..c1a33dc 100644 --- a/drivers/spi/spi-sun4i.c +++ b/drivers/spi/spi-sun4i.c @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -84,6 +85,7 @@ struct sun4i_spi { const u8 *tx_buf; u8 *rx_buf; int len; + u32 word_wait_ns; }; static inline u32 sun4i_spi_read(struct sun4i_spi *sspi, u32 reg) @@ -173,6 +175,8 @@ static int sun4i_spi_transfer_one(struct spi_master *master, unsigned int tx_len = 0; int ret = 0; u32 reg; + int wait_clk = 0; + int clk_ns = 0; /* We don't support transfer larger than the FIFO */ if (tfr->len > SUN4I_FIFO_DEPTH) @@ -261,6 +265,25 @@ static int sun4i_spi_transfer_one(struct spi_master *master, sun4i_spi_write(sspi, SUN4I_CLK_CTL_REG, reg); + /* + * Setup wait time between words. + * + * Wait time is set in SPI_CLK cycles. The SPI hardware needs 3 + * additional cycles to setup the wait counter, so the minimum delay + * time is 4 cycles. + */ + if (spi->word_wait_ns) { + clk_ns = DIV_ROUND_UP(1000000000, tfr->speed_hz); + wait_clk = DIV_ROUND_UP(spi->word_wait_ns, clk_ns) - 3; + if (wait_clk < 1) { + wait_clk = 1; + dev_info(&spi->dev, + "using minimum of 4 word wait cycles (%uns)", + 4 * clk_ns); + } + } + sun4i_spi_write(sspi, SUN4I_WAIT_REG, (u16)wait_clk); + /* Setup the transfer now... */ if (sspi->tx_buf) tx_len = tfr->len; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 2b0a8ec..186373b 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1467,6 +1467,8 @@ of_register_spi_device(struct spi_master *master, struct device_node *nc) if (of_find_property(nc, "spi-lsb-first", NULL)) spi->mode |= SPI_LSB_FIRST; + of_property_read_u32(nc, "spi-word-wait-ns", &spi->word_wait_ns); + /* Device DUAL/QUAD mode */ if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) { switch (value) { diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index cce80e6..ea3037f 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -118,6 +118,7 @@ void spi_statistics_add_transfer_stats(struct spi_statistics *stats, * for driver coldplugging, and in uevents used for hotplugging * @cs_gpio: gpio number of the chipselect line (optional, -ENOENT when * when not using a GPIO line) + * @word_wait_ns: A wait time between word transfers in nanoseconds * * @statistics: statistics for the spi_device * @@ -158,6 +159,7 @@ struct spi_device { void *controller_data; char modalias[SPI_NAME_SIZE]; int cs_gpio; /* chip select gpio */ + u32 word_wait_ns; /* wait time between words */ /* the statistics */ struct spi_statistics statistics;