Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp1973357pxu; Fri, 18 Dec 2020 02:23:00 -0800 (PST) X-Google-Smtp-Source: ABdhPJwJEFpaz/UI6GhIvjqc1+6dZfgEmXqZqV34uAbOERiF6Zt/OICMPjyeRCw3HQJOS3loiddL X-Received: by 2002:aa7:c603:: with SMTP id h3mr3716432edq.254.1608286980142; Fri, 18 Dec 2020 02:23:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1608286980; cv=none; d=google.com; s=arc-20160816; b=MheqvUpwk3QSLjLHCOzbY0UgRpu8G5Feh4vdBLfxQTNBWNkGLVPbUAu2ee5A2D+eiq Fzs68LNOZc8Ynu5Huaw1bw6QPqDMrMfxDYMWZ8OSuxuvDmhs6+Ej8BDaTdT2iuO3jSlH bqDGriNOe7XsszbthAxAK2q7KS29EnZqtwZeWK+ZiczfP6gD1WrRzhFjjlk2yvv9JRhV 5UeNYibqmMojiHup6aqq01nHTblbRi+EWriG50DbCdDD1cRVRYLRh9iODbN32+/v3wb1 /1L6f4mLyadKyV1NiJOsZgTjSxlZSoUBG8VCrfMwUF+cbdiRdNQO+kCrU4W8ULg02kMb /AGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :organization:references:in-reply-to:message-id:subject:cc:to:from :date; bh=M7onZcvRf8kLQ5r358R3v0omKNiyythpo4OMpOjKVaQ=; b=D26Tor+kq35D7RZWF7jiQ1LiGIbipKwvNP9qAanO4pUaInm3XZygY6GRTyfSE9jSdJ 4CjiDsk4J0yg6LcqZ5EUVjMOkUr/zhm78NhiCkh8do2vBkecSY+p1I81mYoPWo7RcXr4 fJ2oDO3G6wMMkOgm0qm9X6LJG3FWSvfL/jZLvMcFqanbZW4iOq2YfTWz05pNZc21BQvZ 6H6J3YDm89ZzH+YkKw1u7Kah0v7lB5Np15zlKtsBtagWnRFADAxRKTI11qKkkwjw7gSv 0KTlyOi61uCwj3TwXcJ6rocrueWQzO/3Mglw54CnWo/K0gAwaOwSxLneC8jXJE4b3KWK 1AbA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id a3si6232676edn.541.2020.12.18.02.22.37; Fri, 18 Dec 2020 02:23:00 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732951AbgLRKVX (ORCPT + 99 others); Fri, 18 Dec 2020 05:21:23 -0500 Received: from bhuna.collabora.co.uk ([46.235.227.227]:36940 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725897AbgLRKVW (ORCPT ); Fri, 18 Dec 2020 05:21:22 -0500 Received: from localhost (unknown [IPv6:2a01:e0a:2c:6930:5cf4:84a1:2763:fe0d]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: bbrezillon) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 4BC251F46188; Fri, 18 Dec 2020 10:20:40 +0000 (GMT) Date: Fri, 18 Dec 2020 11:20:37 +0100 From: Boris Brezillon To: Sowjanya Komatineni Cc: , , , , , , , , , , , Subject: Re: [PATCH v4 6/9] spi: tegra210-quad: Add support for hardware dummy cycles transfer Message-ID: <20201218112037.4465598a@collabora.com> In-Reply-To: <1608236927-28701-7-git-send-email-skomatineni@nvidia.com> References: <1608236927-28701-1-git-send-email-skomatineni@nvidia.com> <1608236927-28701-7-git-send-email-skomatineni@nvidia.com> Organization: Collabora X-Mailer: Claws Mail 3.17.8 (GTK+ 2.24.32; x86_64-redhat-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 17 Dec 2020 12:28:44 -0800 Sowjanya Komatineni wrote: > Tegra Quad SPI controller hardware supports sending dummy bytes based > on programmed dummy clock cycles after the actual transfer bytes. > > This patch adds this support of hardware dummy bytes transfer and > skips transfer of dummy bytes from the software. > > For dummy cycles more than Tegra Quad SPI hardware maximum dummy > cycles limit, driver transfers dummy bytes from the software. > > Signed-off-by: Sowjanya Komatineni > --- > drivers/spi/spi-tegra210-quad.c | 41 ++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 40 insertions(+), 1 deletion(-) > > diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c > index e7bee8d..695a296 100644 > --- a/drivers/spi/spi-tegra210-quad.c > +++ b/drivers/spi/spi-tegra210-quad.c > @@ -117,6 +117,7 @@ > > #define QSPI_MISC_REG 0x194 > #define QSPI_NUM_DUMMY_CYCLE(x) (((x) & 0xff) << 0) > +#define QSPI_DUMMY_CYCLES_MAX 0xff > > #define DATA_DIR_TX BIT(0) > #define DATA_DIR_RX BIT(1) > @@ -170,6 +171,7 @@ struct tegra_qspi { > u32 def_command2_reg; > u32 spi_cs_timing1; > u32 spi_cs_timing2; > + u8 dummy_cycles; > > struct completion xfer_completion; > struct spi_transfer *curr_xfer; > @@ -856,6 +858,8 @@ static int tegra_qspi_start_transfer_one(struct spi_device *spi, > > tqspi->command1_reg = command1; > > + tegra_qspi_writel(tqspi, QSPI_NUM_DUMMY_CYCLE(tqspi->dummy_cycles), QSPI_MISC_REG); > + > ret = tegra_qspi_flush_fifos(tqspi, false); > if (ret < 0) > return ret; > @@ -974,7 +978,8 @@ static int tegra_qspi_transfer_one_message(struct spi_master *master, struct spi > { > struct tegra_qspi *tqspi = spi_master_get_devdata(master); > struct spi_device *spi = msg->spi; > - struct spi_transfer *xfer; > + struct spi_transfer *xfer, *next_xfer; next_after should be declared where it's actually used. > + bool use_hw_dummy_cycles = false; I don't think you need this variable (see below). > bool is_first_msg = true; > int ret; > > @@ -984,8 +989,42 @@ static int tegra_qspi_transfer_one_message(struct spi_master *master, struct spi > tqspi->rx_status = 0; > > list_for_each_entry(xfer, &msg->transfers, transfer_list) { > + u8 dummy_cycles = 0; Should be declared where it's actually used, and you don't want it to be a u8 since you're checking that the result does not exceed 255 which will always be true with a u8. > u32 cmd1; > > + /* > + * Skip dummy bytes transfer if they are transferred by the hardware along > + * with previous transfer. > + */ > + if (xfer->dummy_data && use_hw_dummy_cycles) { > + msg->actual_length += xfer->len; > + continue; > + } > + > + /* > + * Tegra QSPI hardware supports dummy bytes transfer after actual transfer > + * bytes based on programmed dummy clock cycles in the QSPI_MISC register. > + * So, check if the next transfer is dummy data transfer and program dummy > + * clock cycles along with the current transfer. > + */ > + if (!list_is_last(&xfer->transfer_list, &msg->transfers)) { > + next_xfer = list_next_entry(xfer, transfer_list); > + if (next_xfer && next_xfer->dummy_data) { > + dummy_cycles = next_xfer->len * 8 / next_xfer->tx_nbits; > + use_hw_dummy_cycles = true; > + /* > + * Use software dummy bytes transfer if dummy cycles exceeds > + * Tegra QSPI hardware maximum dummy cycles limit. > + */ > + if (dummy_cycles > QSPI_DUMMY_CYCLES_MAX) { > + use_hw_dummy_cycles = false; > + dummy_cycles = 0; > + } > + } > + } > + > + tqspi->dummy_cycles = dummy_cycles; > + This can be simplified: /* * Skip dummy bytes transfer if they were issued with the * previous transfer. */ if (tqspi->dummy_cycles) { WARN_ON(!xfer->dummy_data); tqspi->dummy_cycles = 0; } /* * Tegra QSPI hardware supports dummy bytes transfer after actual * transfer bytes based on programmed dummy clock cycles in the * QSPI_MISC register. So, check if the next transfer is dummy * data transfer and program dummy clock cycles along with the * current transfer. */ if (!list_is_last(&xfer->transfer_list, &msg->transfers)) { struct spi_transfer *next_xfer; next_xfer = list_next_entry(xfer, transfer_list); if (next_xfer->dummy_data) { u32 dummy_cycles = next_xfer->len * 8 / next_xfer->tx_nbits; if (dummy_cycles <= QSPI_DUMMY_CYCLES_MAX) tqspi->dummy_cycles = dummy_cycles; } } > reinit_completion(&tqspi->xfer_completion); > > cmd1 = tegra_qspi_setup_transfer_one(spi, xfer, is_first_msg);