Received: by 2002:ac0:bc90:0:0:0:0:0 with SMTP id a16csp4984473img; Tue, 26 Mar 2019 22:58:51 -0700 (PDT) X-Google-Smtp-Source: APXvYqwoeLCjXY4IlnXRQSQZRLB5X18pkKbEtqMSQ3JJ14DOQJkXaWOykpyIHU2ndffGXeZM0KE0 X-Received: by 2002:a63:570d:: with SMTP id l13mr25083993pgb.55.1553666331296; Tue, 26 Mar 2019 22:58:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553666331; cv=none; d=google.com; s=arc-20160816; b=vMKuhKEtmjBaE0cRfgK+pNyiso0s3d9FTj5wjsXKKB4oBvIaa8yrD+OyRX9VbSvoSo gDLOtO0JUR56Mz5bIgE7Rq1ItOzbXNMOrZFOUzGUkevq1UPQc2NlRO7Su6rDoohvbAa7 nQ1jw60PEau9jpQietTmxIeEj82urcikFmOg79Hlx/iIASchSK5tY6CGD1MwozfLwNHW GlK5lzi3b4HUqOm382MqWDvvW+LZ0ncXomujuK6LxeILxqvvAkAndwVvLbaI+ZmJ7POq 3I6P8ccuF7TuGHq87DyWmoYqMVLcc6WQRtFpJg/Ht4Wd+mtF0djI8P7lte+0+ftpexaz +omg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:dkim-signature:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from; bh=1fDrF2d8T+/5SvtPC6xRUMYUQdbIEgGT9t99Qqtc3BE=; b=Sa/1mMOVXEu1WtbmXYHylo3yrHwdm/T36LYx0+DgtNf18uy08F9x84AH73Tsd4rtHt pIW4zW8riHQnn9mFrY7J8Trw40biuTR/mlOiX2UFxZY+LYkkJgUKBHQ6PtORY+doXV6S 7SJxkT96iOdW31pHWi1knDRb71m0OA2zuxsUF5c5vspZg6FaPUumcQynwuEM7Tq3yiw7 EHvQrsqqK6PutKx1q/5O9Sj/HvO3Uu6G5WzS4xVSgXwHtT5s1COiqJpzjKxbvrBtWrkG MYe5ptzErX+1pTrb97modYmaKWS6seTsayql5FLl1OgfHcCZv6LcISnUAwJnMY40K+Sk ehkQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@nvidia.com header.s=n1 header.b="p/BhiLl5"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j3si17200618pfi.279.2019.03.26.22.58.36; Tue, 26 Mar 2019 22:58:51 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@nvidia.com header.s=n1 header.b="p/BhiLl5"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733265AbfC0F5j (ORCPT + 99 others); Wed, 27 Mar 2019 01:57:39 -0400 Received: from hqemgate14.nvidia.com ([216.228.121.143]:17620 "EHLO hqemgate14.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733198AbfC0F5e (ORCPT ); Wed, 27 Mar 2019 01:57:34 -0400 Received: from hqpgpgate102.nvidia.com (Not Verified[216.228.121.13]) by hqemgate14.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Tue, 26 Mar 2019 22:57:36 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate102.nvidia.com (PGP Universal service); Tue, 26 Mar 2019 22:57:33 -0700 X-PGP-Universal: processed; by hqpgpgate102.nvidia.com on Tue, 26 Mar 2019 22:57:33 -0700 Received: from HQMAIL112.nvidia.com (172.18.146.18) by HQMAIL103.nvidia.com (172.20.187.11) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 27 Mar 2019 05:57:32 +0000 Received: from HQMAIL104.nvidia.com (172.18.146.11) by HQMAIL112.nvidia.com (172.18.146.18) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 27 Mar 2019 05:57:32 +0000 Received: from hqnvemgw01.nvidia.com (172.20.150.20) by HQMAIL104.nvidia.com (172.18.146.11) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 27 Mar 2019 05:57:32 +0000 Received: from skomatineni-linux.nvidia.com (Not Verified[10.2.161.83]) by hqnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Tue, 26 Mar 2019 22:57:32 -0700 From: Sowjanya Komatineni To: , , , , , , , CC: , , , , Subject: [PATCH V1 18/26] spi: tegra114: add support for hw based cs Date: Tue, 26 Mar 2019 22:56:39 -0700 Message-ID: <1553666207-11414-18-git-send-email-skomatineni@nvidia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1553666207-11414-1-git-send-email-skomatineni@nvidia.com> References: <1553666207-11414-1-git-send-email-skomatineni@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 Content-Type: text/plain DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1553666256; bh=1fDrF2d8T+/5SvtPC6xRUMYUQdbIEgGT9t99Qqtc3BE=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:X-NVConfidentiality:MIME-Version: Content-Type; b=p/BhiLl50hNFlMai4+2DOVG82gV7Xc3hY+WG4DS8XwDTX+fYXii69GMk2KM4npOyY ShgJRg39w5wIxn6QbQMiC3eRgbZOwkCwsNnptnEnbS6CHkAxrqSd2hiBjJkRWeo49T uoSaRlIuHiAMQpEjl8Vl5o57NQF0RHPzT8ZzI41Ch6NoCHly1uNGP46SaoXMAUloi5 PJ0fEXCmmTyHRpBj7RPPTG/0C6SdfhKYuPElk8dqHw+6Ez3Yuv2hS2EZNJ5EAQ4ajK hq46VWPDOMMD1Uxbf0dJewqE/Y+haGWViuofHBEO9k0BTrHDn/7ZzqzXfXoQib+tao fy4w7fS2HadFA== Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds support for HW based CS control. Tegra SPI controller supports both HW and SW based CS control transfers. Tegra SPI driver default uses SW CS control for transfers and HW CS control can be enabled through SPI client device node DT property nvidia,enable-hw-based-cs and is used only for single transfers. Signed-off-by: Sowjanya Komatineni --- drivers/spi/spi-tegra114.c | 71 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index 68fee474580b..86c34f02d13a 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -167,6 +167,10 @@ struct tegra_spi_soc_data { bool has_intr_mask_reg; }; +struct tegra_spi_client_data { + bool is_hw_based_cs; +}; + struct tegra_spi_data { struct device *dev; struct spi_master *master; @@ -193,6 +197,7 @@ struct tegra_spi_data { unsigned dma_buf_size; unsigned max_buf_size; bool is_curr_dma_xfer; + bool use_hw_based_cs; struct completion rx_dma_complete; struct completion tx_dma_complete; @@ -723,9 +728,11 @@ static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi, } static u32 tegra_spi_setup_transfer_one(struct spi_device *spi, - struct spi_transfer *t, bool is_first_of_msg) + struct spi_transfer *t, bool is_first_of_msg, + bool is_single_xfer) { struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master); + struct tegra_spi_client_data *cdata = spi->controller_data; u32 speed = t->speed_hz; u8 bits_per_word = t->bits_per_word; u32 command1; @@ -776,11 +783,19 @@ static u32 tegra_spi_setup_transfer_one(struct spi_device *spi, } else tegra_spi_writel(tspi, command1, SPI_COMMAND1); - command1 |= SPI_CS_SW_HW; - if (spi->mode & SPI_CS_HIGH) - command1 |= SPI_CS_SW_VAL; - else - command1 &= ~SPI_CS_SW_VAL; + tspi->use_hw_based_cs = false; + if (cdata && cdata->is_hw_based_cs && is_single_xfer) + tspi->use_hw_based_cs = true; + + if (!tspi->use_hw_based_cs) { + command1 |= SPI_CS_SW_HW; + if (spi->mode & SPI_CS_HIGH) + command1 |= SPI_CS_SW_VAL; + else + command1 &= ~SPI_CS_SW_VAL; + } else { + command1 &= ~(SPI_CS_SW_HW | SPI_CS_SW_VAL); + } tegra_spi_writel(tspi, 0, SPI_COMMAND2); } else { @@ -838,9 +853,41 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi, return ret; } +static struct tegra_spi_client_data + *tegra_spi_parse_cdata_dt(struct spi_device *spi) +{ + struct tegra_spi_client_data *cdata; + struct device_node *slave_np; + + slave_np = spi->dev.of_node; + if (!slave_np) { + dev_dbg(&spi->dev, "device node not found\n"); + return NULL; + } + + cdata = kzalloc(sizeof(*cdata), GFP_KERNEL); + if (!cdata) + return NULL; + + if (of_property_read_bool(slave_np, "nvidia,enable-hw-based-cs")) + cdata->is_hw_based_cs = true; + + return cdata; +} + +static void tegra_spi_cleanup(struct spi_device *spi) +{ + struct tegra_spi_client_data *cdata = spi->controller_data; + + spi->controller_data = NULL; + if (spi->dev.of_node) + kfree(cdata); +} + static int tegra_spi_setup(struct spi_device *spi) { struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master); + struct tegra_spi_client_data *cdata = spi->controller_data; u32 val; unsigned long flags; int ret; @@ -851,9 +898,15 @@ static int tegra_spi_setup(struct spi_device *spi) spi->mode & SPI_CPHA ? "" : "~", spi->max_speed_hz); + if (!cdata) { + cdata = tegra_spi_parse_cdata_dt(spi); + spi->controller_data = cdata; + } + ret = pm_runtime_get_sync(tspi->dev); if (ret < 0) { dev_err(tspi->dev, "pm runtime failed, e = %d\n", ret); + tegra_spi_cleanup(spi); return ret; } @@ -909,18 +962,21 @@ static int tegra_spi_transfer_one_message(struct spi_master *master, struct tegra_spi_data *tspi = spi_master_get_devdata(master); struct spi_transfer *xfer; struct spi_device *spi = msg->spi; + int single_xfer; int ret; bool skip = false; msg->status = 0; msg->actual_length = 0; + single_xfer = list_is_singular(&msg->transfers); list_for_each_entry(xfer, &msg->transfers, transfer_list) { u32 cmd1; reinit_completion(&tspi->xfer_completion); - cmd1 = tegra_spi_setup_transfer_one(spi, xfer, is_first_msg); + cmd1 = tegra_spi_setup_transfer_one(spi, xfer, is_first_msg, + single_xfer); if (!xfer->len) { ret = 0; @@ -1193,6 +1249,7 @@ static int tegra_spi_probe(struct platform_device *pdev) SPI_TX_DUAL | SPI_RX_DUAL | SPI_3WIRE; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); master->setup = tegra_spi_setup; + master->cleanup = tegra_spi_cleanup; master->transfer_one_message = tegra_spi_transfer_one_message; master->num_chipselect = MAX_CHIP_SELECT; master->auto_runtime_pm = true; -- 2.7.4