From patchwork Tue Dec 22 18:44:19 2020
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Pratyush Yadav
X-Patchwork-Id: 11987167
Return-Path:
X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
aws-us-west-2-korg-lkml-1.web.codeaurora.org
X-Spam-Level:
X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH,
DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,
INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,
USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0
Received: from mail.kernel.org (mail.kernel.org [198.145.29.99])
by smtp.lore.kernel.org (Postfix) with ESMTP id 52A05C433E0
for ; Tue, 22 Dec 2020 18:46:08 +0000 (UTC)
Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
by mail.kernel.org (Postfix) with ESMTP id 2270C229C5
for ; Tue, 22 Dec 2020 18:46:08 +0000 (UTC)
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
id S1726356AbgLVSqH (ORCPT );
Tue, 22 Dec 2020 13:46:07 -0500
Received: from fllv0015.ext.ti.com ([198.47.19.141]:54356 "EHLO
fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
with ESMTP id S1726557AbgLVSqH (ORCPT
); Tue, 22 Dec 2020 13:46:07 -0500
Received: from lelv0265.itg.ti.com ([10.180.67.224])
by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIiU2Y015056;
Tue, 22 Dec 2020 12:44:30 -0600
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com;
s=ti-com-17Q1; t=1608662670;
bh=5tzANjfyu5Rj3wctVJuHxVcRtYnBIWKhBasMbV22tSs=;
h=From:To:CC:Subject:Date:In-Reply-To:References;
b=FKmpbofBaZ7GLJGhHsEgsQvGfGVFMUX+qYDVH5dhXXCMoWIv7qUQWfoL1HOHcRGBG
Gjlo2ZdyjaXjf7qRg2mTKAcmJOb52r4HoVzUYWiomD8+WwdsKznD/1dPgpx4R4gIH8
qdrkWEL7GWyYGxsz7iqfyRPRnxd4UxfeRcRG1e60=
Received: from DFLE114.ent.ti.com (dfle114.ent.ti.com [10.64.6.35])
by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 0BMIiUD8000502
(version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL);
Tue, 22 Dec 2020 12:44:30 -0600
Received: from DFLE110.ent.ti.com (10.64.6.31) by DFLE114.ent.ti.com
(10.64.6.35) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Tue, 22
Dec 2020 12:44:30 -0600
Received: from lelv0327.itg.ti.com (10.180.67.183) by DFLE110.ent.ti.com
(10.64.6.31) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via
Frontend Transport; Tue, 22 Dec 2020 12:44:30 -0600
Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com
[10.172.224.153])
by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIiQbZ003761;
Tue, 22 Dec 2020 12:44:28 -0600
From: Pratyush Yadav
To: Mark Brown ,
Vignesh Raghavendra
CC: Pratyush Yadav , ,
Subject: [PATCH 1/7] spi: cadence-quadspi: Set master max_speed_hz
Date: Wed, 23 Dec 2020 00:14:19 +0530
Message-ID: <20201222184425.7028-2-p.yadav@ti.com>
X-Mailer: git-send-email 2.28.0
In-Reply-To: <20201222184425.7028-1-p.yadav@ti.com>
References: <20201222184425.7028-1-p.yadav@ti.com>
MIME-Version: 1.0
X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180
Precedence: bulk
List-ID:
X-Mailing-List: linux-spi@vger.kernel.org
As of commit 9326e4f1e5dd ("spi: Limit the spi device max speed to
controller's max speed"), the SPI device max speed is set to the
controller's max speed if it is larger. The Cadence QSPI controller does
not set the controller's max speed so it is left at its initial value of
0. This means the SPI device max speed is always set to 0.
The SPI device max speed is used to calculate the baud rate divider when
performing an operation. If this speed is 0, the default divider of 32
is used. No matter what speed is specified by the device tree property
'spi-max-frequency', the device will always operate at ref_clk / 32.
Fix this by setting master->max_speed_hz to the ref clock speed so the
correct divider can be calculated.
Signed-off-by: Pratyush Yadav
---
drivers/spi/spi-cadence-quadspi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index ba7d40c2922f..ea3890c7d9ff 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -1279,6 +1279,7 @@ static int cqspi_probe(struct platform_device *pdev)
reset_control_deassert(rstc_ocp);
cqspi->master_ref_clk_hz = clk_get_rate(cqspi->clk);
+ master->max_speed_hz = cqspi->master_ref_clk_hz;
ddata = of_device_get_match_data(dev);
if (ddata) {
if (ddata->quirks & CQSPI_NEEDS_WR_DELAY)
From patchwork Tue Dec 22 18:44:20 2020
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Pratyush Yadav
X-Patchwork-Id: 11987173
Return-Path:
X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
aws-us-west-2-korg-lkml-1.web.codeaurora.org
X-Spam-Level:
X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH,
DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,
INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,
USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0
Received: from mail.kernel.org (mail.kernel.org [198.145.29.99])
by smtp.lore.kernel.org (Postfix) with ESMTP id E7D42C4332B
for ; Tue, 22 Dec 2020 18:46:31 +0000 (UTC)
Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
by mail.kernel.org (Postfix) with ESMTP id 9A6FD229C5
for ; Tue, 22 Dec 2020 18:46:31 +0000 (UTC)
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
id S1727169AbgLVSqK (ORCPT );
Tue, 22 Dec 2020 13:46:10 -0500
Received: from fllv0015.ext.ti.com ([198.47.19.141]:54408 "EHLO
fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
with ESMTP id S1726557AbgLVSqJ (ORCPT
); Tue, 22 Dec 2020 13:46:09 -0500
Received: from lelv0265.itg.ti.com ([10.180.67.224])
by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIiWMo015098;
Tue, 22 Dec 2020 12:44:32 -0600
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com;
s=ti-com-17Q1; t=1608662672;
bh=Cl95KK0DmwpZMTWIjZUAGICKHjvbYSLMRkQKI8fTV0Q=;
h=From:To:CC:Subject:Date:In-Reply-To:References;
b=gbYt/eu6v2w+MOIzkrGiz7Mu6q061kECXDDYLlC4udpJdPPX2gNW2FiwD5eKSmrFX
GNhi09l88sAp63kn3E6uYdqCuhnBNO9+aLVWbN0A5RBHYJnm0A3EayXZ3lcqwZfD1t
7STqoPDBE/PMsgTZvP3y3mU4K2PTIyFxYV/DcOqI=
Received: from DLEE105.ent.ti.com (dlee105.ent.ti.com [157.170.170.35])
by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 0BMIiWvT000527
(version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL);
Tue, 22 Dec 2020 12:44:32 -0600
Received: from DLEE107.ent.ti.com (157.170.170.37) by DLEE105.ent.ti.com
(157.170.170.35) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Tue, 22
Dec 2020 12:44:32 -0600
Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE107.ent.ti.com
(157.170.170.37) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via
Frontend Transport; Tue, 22 Dec 2020 12:44:32 -0600
Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com
[10.172.224.153])
by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIiQba003761;
Tue, 22 Dec 2020 12:44:30 -0600
From: Pratyush Yadav
To: Mark Brown ,
Vignesh Raghavendra
CC: Pratyush Yadav , ,
Subject: [PATCH 2/7] spi: cadence-quadspi: Abort read if dummy cycles required
are too many
Date: Wed, 23 Dec 2020 00:14:20 +0530
Message-ID: <20201222184425.7028-3-p.yadav@ti.com>
X-Mailer: git-send-email 2.28.0
In-Reply-To: <20201222184425.7028-1-p.yadav@ti.com>
References: <20201222184425.7028-1-p.yadav@ti.com>
MIME-Version: 1.0
X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180
Precedence: bulk
List-ID:
X-Mailing-List: linux-spi@vger.kernel.org
The controller can only support up to 31 dummy cycles. If the command
requires more it falls back to using 31. This command is likely to fail
because the correct number of cycles are not waited upon. Rather than
silently issuing an incorrect command, fail loudly so the caller can get
a chance to find out the command can't be supported by the controller.
Fixes: 140623410536 ("mtd: spi-nor: Add driver for Cadence Quad SPI Flash Controller")
Signed-off-by: Pratyush Yadav
---
drivers/spi/spi-cadence-quadspi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index ea3890c7d9ff..5efb1f929be0 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -461,7 +461,7 @@ static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
/* Setup dummy clock cycles */
dummy_clk = op->dummy.nbytes * 8;
if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
- dummy_clk = CQSPI_DUMMY_CLKS_MAX;
+ return -EOPNOTSUPP;
if (dummy_clk)
reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
From patchwork Tue Dec 22 18:44:21 2020
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Pratyush Yadav
X-Patchwork-Id: 11987161
Return-Path:
X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
aws-us-west-2-korg-lkml-1.web.codeaurora.org
X-Spam-Level:
X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH,
DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,
INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,
USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0
Received: from mail.kernel.org (mail.kernel.org [198.145.29.99])
by smtp.lore.kernel.org (Postfix) with ESMTP id 2D772C433E9
for ; Tue, 22 Dec 2020 18:45:27 +0000 (UTC)
Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
by mail.kernel.org (Postfix) with ESMTP id 062BD22B2D
for ; Tue, 22 Dec 2020 18:45:27 +0000 (UTC)
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
id S1725895AbgLVSpR (ORCPT );
Tue, 22 Dec 2020 13:45:17 -0500
Received: from fllv0016.ext.ti.com ([198.47.19.142]:59246 "EHLO
fllv0016.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
with ESMTP id S1725783AbgLVSpQ (ORCPT
); Tue, 22 Dec 2020 13:45:16 -0500
Received: from lelv0266.itg.ti.com ([10.180.67.225])
by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIiYed115127;
Tue, 22 Dec 2020 12:44:34 -0600
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com;
s=ti-com-17Q1; t=1608662674;
bh=weNOJvwMIdHweOu5YL8SzPFO6rkeFp0Tn3zpeGJXxW4=;
h=From:To:CC:Subject:Date:In-Reply-To:References;
b=OVqsAMm54Sf68CmcjFTAKn6XwMX9RHoBduLH/FeoS4IU4ZJaLwS5EeT6dxzNwDIMu
lFWyU+gX/vUruqQ6JlqIdGo+N5Gft5D8/UTtC104srolA6jAJ56YiPExVWxcSraFJh
gMv7pO1niEKBpo7cUNy5woTF0Jsurr5mRfZ2UwJI=
Received: from DFLE112.ent.ti.com (dfle112.ent.ti.com [10.64.6.33])
by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 0BMIiYP7122959
(version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL);
Tue, 22 Dec 2020 12:44:34 -0600
Received: from DFLE105.ent.ti.com (10.64.6.26) by DFLE112.ent.ti.com
(10.64.6.33) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Tue, 22
Dec 2020 12:44:34 -0600
Received: from lelv0327.itg.ti.com (10.180.67.183) by DFLE105.ent.ti.com
(10.64.6.26) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via
Frontend Transport; Tue, 22 Dec 2020 12:44:34 -0600
Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com
[10.172.224.153])
by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIiQbb003761;
Tue, 22 Dec 2020 12:44:32 -0600
From: Pratyush Yadav
To: Mark Brown ,
Vignesh Raghavendra
CC: Pratyush Yadav , ,
Subject: [PATCH 3/7] spi: cadence-quadspi: Set dummy cycles from STIG commands
Date: Wed, 23 Dec 2020 00:14:21 +0530
Message-ID: <20201222184425.7028-4-p.yadav@ti.com>
X-Mailer: git-send-email 2.28.0
In-Reply-To: <20201222184425.7028-1-p.yadav@ti.com>
References: <20201222184425.7028-1-p.yadav@ti.com>
MIME-Version: 1.0
X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180
Precedence: bulk
List-ID:
X-Mailing-List: linux-spi@vger.kernel.org
If a command does not have an address phase it goes via the STIG path.
The dummy cycles are not initialized for the STIG commands. As a result,
STIG commands with dummy cycles will not work.
Initialize the dummy cycle field before issuing the STIG command to make
sure it is sent correctly. Move the code to calculate dummy cycle value
to a separate function so it is not repeated twice. DTR support will add
some more logic here to it is worth it to extract it out in a function.
Signed-off-by: Pratyush Yadav
---
drivers/spi/spi-cadence-quadspi.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index 5efb1f929be0..6a778014ff60 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -188,6 +188,7 @@ struct cqspi_driver_platdata {
#define CQSPI_REG_CMDCTRL 0x90
#define CQSPI_REG_CMDCTRL_EXECUTE_MASK BIT(0)
#define CQSPI_REG_CMDCTRL_INPROGRESS_MASK BIT(1)
+#define CQSPI_REG_CMDCTRL_DUMMY_LSB 7
#define CQSPI_REG_CMDCTRL_WR_BYTES_LSB 12
#define CQSPI_REG_CMDCTRL_WR_EN_LSB 15
#define CQSPI_REG_CMDCTRL_ADD_BYTES_LSB 16
@@ -198,6 +199,7 @@ struct cqspi_driver_platdata {
#define CQSPI_REG_CMDCTRL_WR_BYTES_MASK 0x7
#define CQSPI_REG_CMDCTRL_ADD_BYTES_MASK 0x3
#define CQSPI_REG_CMDCTRL_RD_BYTES_MASK 0x7
+#define CQSPI_REG_CMDCTRL_DUMMY_MASK 0x1F
#define CQSPI_REG_INDIRECTWR 0x70
#define CQSPI_REG_INDIRECTWR_START_MASK BIT(0)
@@ -288,6 +290,15 @@ static unsigned int cqspi_calc_rdreg(struct cqspi_flash_pdata *f_pdata)
return rdreg;
}
+static unsigned int cqspi_calc_dummy(const struct spi_mem_op *op)
+{
+ unsigned int dummy_clk;
+
+ dummy_clk = op->dummy.nbytes * 8;
+
+ return dummy_clk;
+}
+
static int cqspi_wait_idle(struct cqspi_st *cqspi)
{
const unsigned int poll_idle_retry = 3;
@@ -355,6 +366,7 @@ static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
size_t n_rx = op->data.nbytes;
unsigned int rdreg;
unsigned int reg;
+ unsigned int dummy_clk;
size_t read_len;
int status;
@@ -370,6 +382,14 @@ static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
rdreg = cqspi_calc_rdreg(f_pdata);
writel(rdreg, reg_base + CQSPI_REG_RD_INSTR);
+ dummy_clk = cqspi_calc_dummy(op);
+ if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
+ return -EOPNOTSUPP;
+
+ if (dummy_clk)
+ reg |= (dummy_clk & CQSPI_REG_CMDCTRL_DUMMY_MASK)
+ << CQSPI_REG_CMDCTRL_DUMMY_LSB;
+
reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB);
/* 0 means 1 byte. */
@@ -459,7 +479,8 @@ static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
reg |= cqspi_calc_rdreg(f_pdata);
/* Setup dummy clock cycles */
- dummy_clk = op->dummy.nbytes * 8;
+ dummy_clk = cqspi_calc_dummy(op);
+
if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
return -EOPNOTSUPP;
From patchwork Tue Dec 22 18:44:22 2020
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Pratyush Yadav
X-Patchwork-Id: 11987171
Return-Path:
X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
aws-us-west-2-korg-lkml-1.web.codeaurora.org
X-Spam-Level:
X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH,
DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,
INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,
USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0
Received: from mail.kernel.org (mail.kernel.org [198.145.29.99])
by smtp.lore.kernel.org (Postfix) with ESMTP id 62B4FC433E6
for ; Tue, 22 Dec 2020 18:46:31 +0000 (UTC)
Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
by mail.kernel.org (Postfix) with ESMTP id 2741622AB9
for ; Tue, 22 Dec 2020 18:46:31 +0000 (UTC)
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
id S1727360AbgLVSqN (ORCPT );
Tue, 22 Dec 2020 13:46:13 -0500
Received: from fllv0015.ext.ti.com ([198.47.19.141]:54422 "EHLO
fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
with ESMTP id S1726557AbgLVSqN (ORCPT
); Tue, 22 Dec 2020 13:46:13 -0500
Received: from fllv0035.itg.ti.com ([10.64.41.0])
by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIiaV9015122;
Tue, 22 Dec 2020 12:44:36 -0600
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com;
s=ti-com-17Q1; t=1608662676;
bh=+5MUFx6m4aRjz+9UKgH8r17yzKrXbsPFbYTO9PLMrh0=;
h=From:To:CC:Subject:Date:In-Reply-To:References;
b=PHgffoGaDBO1NCMGl9e9rmXzQ0I9MFZ0zS+nwywnkZBvDIQV/zmmDJ/191cPhOjCL
5/oZiyzKkmpEdVVNK2oUV8t6DtJTc+r1vBLkE24YSQn6gSrWWZjrfNTLprA1/qipvW
EfVw6Y4JO50CpbLTxjbMcXqJ/kyiraHVRhphLtSE=
Received: from DFLE103.ent.ti.com (dfle103.ent.ti.com [10.64.6.24])
by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 0BMIiaEb098649
(version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL);
Tue, 22 Dec 2020 12:44:36 -0600
Received: from DFLE100.ent.ti.com (10.64.6.21) by DFLE103.ent.ti.com
(10.64.6.24) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Tue, 22
Dec 2020 12:44:36 -0600
Received: from lelv0327.itg.ti.com (10.180.67.183) by DFLE100.ent.ti.com
(10.64.6.21) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via
Frontend Transport; Tue, 22 Dec 2020 12:44:36 -0600
Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com
[10.172.224.153])
by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIiQbc003761;
Tue, 22 Dec 2020 12:44:34 -0600
From: Pratyush Yadav
To: Mark Brown ,
Vignesh Raghavendra
CC: Pratyush Yadav , ,
Subject: [PATCH 4/7] spi: cadence-quadspi: Fix dummy cycle calculation when
buswidth > 1
Date: Wed, 23 Dec 2020 00:14:22 +0530
Message-ID: <20201222184425.7028-5-p.yadav@ti.com>
X-Mailer: git-send-email 2.28.0
In-Reply-To: <20201222184425.7028-1-p.yadav@ti.com>
References: <20201222184425.7028-1-p.yadav@ti.com>
MIME-Version: 1.0
X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180
Precedence: bulk
List-ID:
X-Mailing-List: linux-spi@vger.kernel.org
SPI MEM deals with dummy bytes but the controller deals with dummy
cycles. Multiplying bytes by 8 is correct if the dummy phase uses 1S
mode since 1 byte will be sent in 8 cycles. But if the dummy phase uses
4S mode then 1 byte will be sent in 2 cycles.
To correctly translate dummy bytes to dummy cycles, the dummy buswidth
also needs to be taken into account. Divide 8 by the buswidth to get the
correct multiplier for getting the number of cycles.
Signed-off-by: Pratyush Yadav
---
drivers/spi/spi-cadence-quadspi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index 6a778014ff60..376abef43530 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -294,7 +294,7 @@ static unsigned int cqspi_calc_dummy(const struct spi_mem_op *op)
{
unsigned int dummy_clk;
- dummy_clk = op->dummy.nbytes * 8;
+ dummy_clk = op->dummy.nbytes * (8 / op->dummy.buswidth);
return dummy_clk;
}
From patchwork Tue Dec 22 18:44:23 2020
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Pratyush Yadav
X-Patchwork-Id: 11987165
Return-Path:
X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
aws-us-west-2-korg-lkml-1.web.codeaurora.org
X-Spam-Level:
X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH,
DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,
INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,
USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0
Received: from mail.kernel.org (mail.kernel.org [198.145.29.99])
by smtp.lore.kernel.org (Postfix) with ESMTP id BF031C433DB
for ; Tue, 22 Dec 2020 18:45:48 +0000 (UTC)
Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
by mail.kernel.org (Postfix) with ESMTP id 95252229C5
for ; Tue, 22 Dec 2020 18:45:48 +0000 (UTC)
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
id S1726709AbgLVSpU (ORCPT );
Tue, 22 Dec 2020 13:45:20 -0500
Received: from fllv0015.ext.ti.com ([198.47.19.141]:54430 "EHLO
fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
with ESMTP id S1725783AbgLVSpU (ORCPT
); Tue, 22 Dec 2020 13:45:20 -0500
Received: from lelv0266.itg.ti.com ([10.180.67.225])
by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIicTi015127;
Tue, 22 Dec 2020 12:44:38 -0600
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com;
s=ti-com-17Q1; t=1608662678;
bh=Du77HrhWi4pd+7wwLeZRYp75zCGbSn46ZKg0KfSr1pU=;
h=From:To:CC:Subject:Date:In-Reply-To:References;
b=oJQOXOtfFFuDUaluUaDzSSo8WD0x0qxbQBV4CBeOWZzEBX55A4moCGw5PJC6KfzBD
Td1KvhYiYSEbTSFTZdUDkS1mqcBCXykFHn+bSXst4L4LxIBk5C8xx9svMszZnL9nt/
SP9vnY0q20Bsnm5SsbwMG9o1RjEX1bK+J8KNb22Y=
Received: from DFLE114.ent.ti.com (dfle114.ent.ti.com [10.64.6.35])
by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 0BMIicZK123007
(version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL);
Tue, 22 Dec 2020 12:44:38 -0600
Received: from DFLE110.ent.ti.com (10.64.6.31) by DFLE114.ent.ti.com
(10.64.6.35) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Tue, 22
Dec 2020 12:44:38 -0600
Received: from lelv0327.itg.ti.com (10.180.67.183) by DFLE110.ent.ti.com
(10.64.6.31) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via
Frontend Transport; Tue, 22 Dec 2020 12:44:38 -0600
Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com
[10.172.224.153])
by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIiQbd003761;
Tue, 22 Dec 2020 12:44:36 -0600
From: Pratyush Yadav
To: Mark Brown ,
Vignesh Raghavendra
CC: Pratyush Yadav , ,
Subject: [PATCH 5/7] spi: cadence-quadspi: Implement a simple supports_op hook
Date: Wed, 23 Dec 2020 00:14:23 +0530
Message-ID: <20201222184425.7028-6-p.yadav@ti.com>
X-Mailer: git-send-email 2.28.0
In-Reply-To: <20201222184425.7028-1-p.yadav@ti.com>
References: <20201222184425.7028-1-p.yadav@ti.com>
MIME-Version: 1.0
X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180
Precedence: bulk
List-ID:
X-Mailing-List: linux-spi@vger.kernel.org
The default SPI MEM supports_op hook rejects DTR ops by default. Add a
simple supports_op hook that very closely imitates the SPI MEM one. It
will be extended in later commits to allow DTR ops.
Signed-off-by: Pratyush Yadav
---
drivers/spi/spi-cadence-quadspi.c | 61 +++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index 376abef43530..1781d4e94ebd 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -1031,6 +1031,66 @@ static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
return ret;
}
+static int cqspi_check_buswidth_req(struct spi_mem *mem, u8 buswidth, bool tx)
+{
+ u32 mode = mem->spi->mode;
+
+ switch (buswidth) {
+ case 1:
+ return 0;
+
+ case 2:
+ if ((tx &&
+ (mode & (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL))) ||
+ (!tx &&
+ (mode & (SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL))))
+ return 0;
+
+ break;
+
+ case 4:
+ if ((tx && (mode & (SPI_TX_QUAD | SPI_TX_OCTAL))) ||
+ (!tx && (mode & (SPI_RX_QUAD | SPI_RX_OCTAL))))
+ return 0;
+
+ break;
+
+ case 8:
+ if ((tx && (mode & SPI_TX_OCTAL)) ||
+ (!tx && (mode & SPI_RX_OCTAL)))
+ return 0;
+
+ break;
+
+ default:
+ break;
+ }
+
+ return -EOPNOTSUPP;
+}
+
+static bool cqspi_supports_mem_op(struct spi_mem *mem,
+ const struct spi_mem_op *op)
+{
+ if (cqspi_check_buswidth_req(mem, op->cmd.buswidth, true))
+ return false;
+
+ if (op->addr.nbytes &&
+ cqspi_check_buswidth_req(mem, op->addr.buswidth, true))
+ return false;
+
+ if (op->dummy.nbytes &&
+ cqspi_check_buswidth_req(mem, op->dummy.buswidth, true))
+ return false;
+
+ if (op->data.nbytes &&
+ cqspi_check_buswidth_req(mem, op->data.buswidth,
+ op->data.dir == SPI_MEM_DATA_OUT))
+ return false;
+
+ return true;
+}
+
static int cqspi_of_get_flash_pdata(struct platform_device *pdev,
struct cqspi_flash_pdata *f_pdata,
struct device_node *np)
@@ -1159,6 +1219,7 @@ static const char *cqspi_get_name(struct spi_mem *mem)
static const struct spi_controller_mem_ops cqspi_mem_ops = {
.exec_op = cqspi_exec_mem_op,
.get_name = cqspi_get_name,
+ .supports_op = cqspi_supports_mem_op,
};
static int cqspi_setup_flash(struct cqspi_st *cqspi)
From patchwork Tue Dec 22 18:44:24 2020
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Pratyush Yadav
X-Patchwork-Id: 11987169
Return-Path:
X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
aws-us-west-2-korg-lkml-1.web.codeaurora.org
X-Spam-Level:
X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH,
DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,
INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,
USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0
Received: from mail.kernel.org (mail.kernel.org [198.145.29.99])
by smtp.lore.kernel.org (Postfix) with ESMTP id A8ED1C43381
for ; Tue, 22 Dec 2020 18:46:31 +0000 (UTC)
Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
by mail.kernel.org (Postfix) with ESMTP id 6D15A22AB9
for ; Tue, 22 Dec 2020 18:46:31 +0000 (UTC)
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
id S1726557AbgLVSqR (ORCPT );
Tue, 22 Dec 2020 13:46:17 -0500
Received: from fllv0016.ext.ti.com ([198.47.19.142]:59260 "EHLO
fllv0016.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
with ESMTP id S1726039AbgLVSqR (ORCPT
); Tue, 22 Dec 2020 13:46:17 -0500
Received: from fllv0034.itg.ti.com ([10.64.40.246])
by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIie8V115152;
Tue, 22 Dec 2020 12:44:40 -0600
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com;
s=ti-com-17Q1; t=1608662680;
bh=4+hNG0HZ3CKHOOg7bbnIvHC3AH4Hy4lXYfvtHYthEak=;
h=From:To:CC:Subject:Date:In-Reply-To:References;
b=IbH8vb51Wr5IMLW9wAWeXp4Wb8Qhk2fCPF/L0Cshixa1ulFzJ2z0Mj0MFSOe64yKC
79qNnOxW+Fc25le717MAA9lmv7g+f74g8BOR/wLQdkCHww9XpTA5k7vovZy9yHYD0h
87E+u8bHAYgd2/XzR7IhmDQqH8qp9PYxj5RXvclk=
Received: from DFLE103.ent.ti.com (dfle103.ent.ti.com [10.64.6.24])
by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 0BMIieDQ017222
(version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL);
Tue, 22 Dec 2020 12:44:40 -0600
Received: from DFLE112.ent.ti.com (10.64.6.33) by DFLE103.ent.ti.com
(10.64.6.24) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Tue, 22
Dec 2020 12:44:40 -0600
Received: from lelv0327.itg.ti.com (10.180.67.183) by DFLE112.ent.ti.com
(10.64.6.33) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via
Frontend Transport; Tue, 22 Dec 2020 12:44:40 -0600
Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com
[10.172.224.153])
by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIiQbe003761;
Tue, 22 Dec 2020 12:44:38 -0600
From: Pratyush Yadav
To: Mark Brown ,
Vignesh Raghavendra
CC: Pratyush Yadav , ,
Subject: [PATCH 6/7] spi: cadence-quadspi: Wait at least 500 ms for direct
reads
Date: Wed, 23 Dec 2020 00:14:24 +0530
Message-ID: <20201222184425.7028-7-p.yadav@ti.com>
X-Mailer: git-send-email 2.28.0
In-Reply-To: <20201222184425.7028-1-p.yadav@ti.com>
References: <20201222184425.7028-1-p.yadav@ti.com>
MIME-Version: 1.0
X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180
Precedence: bulk
List-ID:
X-Mailing-List: linux-spi@vger.kernel.org
When performing a direct read via DMA the timeout for completion is set
equal to the read length. This is fine for larger reads. For a small
read like the Read Status Register command, the timeout would be 1 or 2
milliseconds. This is not enough to cover the overhead needed in setting
up DMA.
Make sure the timeout is at least 500 ms to allow DMA ample time to
finish. For reads larger than 500 bytes, the timeout will continue to be
equal to the read length.
Signed-off-by: Pratyush Yadav
Reported-by: kernel test robot
---
drivers/spi/spi-cadence-quadspi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index 1781d4e94ebd..90040664e1b9 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -963,7 +963,7 @@ static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
dma_async_issue_pending(cqspi->rx_chan);
if (!wait_for_completion_timeout(&cqspi->rx_dma_complete,
- msecs_to_jiffies(len))) {
+ msecs_to_jiffies(max(len, 500UL)))) {
dmaengine_terminate_sync(cqspi->rx_chan);
dev_err(dev, "DMA wait_for_completion_timeout\n");
ret = -ETIMEDOUT;
From patchwork Tue Dec 22 18:44:25 2020
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Pratyush Yadav
X-Patchwork-Id: 11987163
Return-Path:
X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
aws-us-west-2-korg-lkml-1.web.codeaurora.org
X-Spam-Level:
X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH,
DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,
INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,
USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0
Received: from mail.kernel.org (mail.kernel.org [198.145.29.99])
by smtp.lore.kernel.org (Postfix) with ESMTP id AAD25C433E6
for ; Tue, 22 Dec 2020 18:45:48 +0000 (UTC)
Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
by mail.kernel.org (Postfix) with ESMTP id 7374822AB9
for ; Tue, 22 Dec 2020 18:45:48 +0000 (UTC)
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
id S1726951AbgLVSpZ (ORCPT );
Tue, 22 Dec 2020 13:45:25 -0500
Received: from fllv0015.ext.ti.com ([198.47.19.141]:54434 "EHLO
fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
with ESMTP id S1725783AbgLVSpZ (ORCPT
); Tue, 22 Dec 2020 13:45:25 -0500
Received: from lelv0265.itg.ti.com ([10.180.67.224])
by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIigEZ015143;
Tue, 22 Dec 2020 12:44:42 -0600
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com;
s=ti-com-17Q1; t=1608662682;
bh=wtNjqX/SFi4ohW52XsC96ikubl1SuHs4kv1/95hv3uY=;
h=From:To:CC:Subject:Date:In-Reply-To:References;
b=uKMvGbsE1izcQ8NM8553L094l2Pl7XTfg6A5Jlu4vSK8dkcssrije7gWbxFjqTZls
8tJxJUsWzRLaF3t/phPPjmKIkCcv5zeOaUoP1RdSsz2bVqY79auIceQHKNkpRum+e3
UbWS+G0Q8zIf6CUVVcqGQcqT7Iyc4FFArVIiu2fA=
Received: from DFLE110.ent.ti.com (dfle110.ent.ti.com [10.64.6.31])
by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 0BMIigdJ000581
(version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL);
Tue, 22 Dec 2020 12:44:42 -0600
Received: from DFLE108.ent.ti.com (10.64.6.29) by DFLE110.ent.ti.com
(10.64.6.31) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Tue, 22
Dec 2020 12:44:42 -0600
Received: from lelv0327.itg.ti.com (10.180.67.183) by DFLE108.ent.ti.com
(10.64.6.29) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via
Frontend Transport; Tue, 22 Dec 2020 12:44:42 -0600
Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com
[10.172.224.153])
by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 0BMIiQbf003761;
Tue, 22 Dec 2020 12:44:40 -0600
From: Pratyush Yadav
To: Mark Brown ,
Vignesh Raghavendra
CC: Pratyush Yadav , ,
Subject: [PATCH 7/7] spi: cadence-quadspi: Add DTR support
Date: Wed, 23 Dec 2020 00:14:25 +0530
Message-ID: <20201222184425.7028-8-p.yadav@ti.com>
X-Mailer: git-send-email 2.28.0
In-Reply-To: <20201222184425.7028-1-p.yadav@ti.com>
References: <20201222184425.7028-1-p.yadav@ti.com>
MIME-Version: 1.0
X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180
Precedence: bulk
List-ID:
X-Mailing-List: linux-spi@vger.kernel.org
Double Transfer Rate (DTR) mode transfers data twice per clock cycle.
Add support for parsing DTR ops and set up the registers to allow it.
Most SPI NOR flashes expect 2 byte commands. Parse the 2-byte opcode
from SPI MEM and set it up in the CQSPI_REG_OP_EXT_LOWER register.
Increment the delay needed before issuing indirect writes because larger
delay is needed for DTR mode. With the current delay some writes end up
missing.
Signed-off-by: Pratyush Yadav
---
drivers/spi/spi-cadence-quadspi.c | 281 +++++++++++++++++++++++++-----
1 file changed, 242 insertions(+), 39 deletions(-)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index 90040664e1b9..06a65e9a8a60 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -52,6 +52,7 @@ struct cqspi_flash_pdata {
u8 inst_width;
u8 addr_width;
u8 data_width;
+ bool dtr;
u8 cs;
};
@@ -111,6 +112,8 @@ struct cqspi_driver_platdata {
#define CQSPI_REG_CONFIG_CHIPSELECT_LSB 10
#define CQSPI_REG_CONFIG_DMA_MASK BIT(15)
#define CQSPI_REG_CONFIG_BAUD_LSB 19
+#define CQSPI_REG_CONFIG_DTR_PROTO BIT(24)
+#define CQSPI_REG_CONFIG_DUAL_OPCODE BIT(30)
#define CQSPI_REG_CONFIG_IDLE_LSB 31
#define CQSPI_REG_CONFIG_CHIPSELECT_MASK 0xF
#define CQSPI_REG_CONFIG_BAUD_MASK 0xF
@@ -173,6 +176,9 @@ struct cqspi_driver_platdata {
#define CQSPI_REG_SDRAMLEVEL_RD_MASK 0xFFFF
#define CQSPI_REG_SDRAMLEVEL_WR_MASK 0xFFFF
+#define CQSPI_REG_WR_COMPLETION_CTRL 0x38
+#define CQSPI_REG_WR_DISABLE_AUTO_POLL BIT(14)
+
#define CQSPI_REG_IRQSTATUS 0x40
#define CQSPI_REG_IRQMASK 0x44
@@ -216,6 +222,14 @@ struct cqspi_driver_platdata {
#define CQSPI_REG_CMDWRITEDATALOWER 0xA8
#define CQSPI_REG_CMDWRITEDATAUPPER 0xAC
+#define CQSPI_REG_POLLING_STATUS 0xB0
+#define CQSPI_REG_POLLING_STATUS_DUMMY_LSB 16
+
+#define CQSPI_REG_OP_EXT_LOWER 0xE0
+#define CQSPI_REG_OP_EXT_READ_LSB 24
+#define CQSPI_REG_OP_EXT_WRITE_LSB 16
+#define CQSPI_REG_OP_EXT_STIG_LSB 0
+
/* Interrupt status bits */
#define CQSPI_REG_IRQ_MODE_ERR BIT(0)
#define CQSPI_REG_IRQ_UNDERFLOW BIT(1)
@@ -290,15 +304,80 @@ static unsigned int cqspi_calc_rdreg(struct cqspi_flash_pdata *f_pdata)
return rdreg;
}
-static unsigned int cqspi_calc_dummy(const struct spi_mem_op *op)
+static unsigned int cqspi_calc_dummy(const struct spi_mem_op *op, bool dtr)
{
unsigned int dummy_clk;
dummy_clk = op->dummy.nbytes * (8 / op->dummy.buswidth);
+ if (dtr)
+ dummy_clk /= 2;
return dummy_clk;
}
+static int cqspi_set_protocol(struct cqspi_flash_pdata *f_pdata,
+ const struct spi_mem_op *op)
+{
+ f_pdata->inst_width = CQSPI_INST_TYPE_SINGLE;
+ f_pdata->addr_width = CQSPI_INST_TYPE_SINGLE;
+ f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
+ f_pdata->dtr = op->data.dtr && op->cmd.dtr && op->addr.dtr;
+
+ switch (op->data.buswidth) {
+ case 0:
+ break;
+ case 1:
+ f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
+ break;
+ case 2:
+ f_pdata->data_width = CQSPI_INST_TYPE_DUAL;
+ break;
+ case 4:
+ f_pdata->data_width = CQSPI_INST_TYPE_QUAD;
+ break;
+ case 8:
+ f_pdata->data_width = CQSPI_INST_TYPE_OCTAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Right now we only support 8-8-8 DTR mode. */
+ if (f_pdata->dtr) {
+ switch (op->cmd.buswidth) {
+ case 0:
+ break;
+ case 8:
+ f_pdata->inst_width = CQSPI_INST_TYPE_OCTAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (op->addr.buswidth) {
+ case 0:
+ break;
+ case 8:
+ f_pdata->addr_width = CQSPI_INST_TYPE_OCTAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (op->data.buswidth) {
+ case 0:
+ break;
+ case 8:
+ f_pdata->data_width = CQSPI_INST_TYPE_OCTAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int cqspi_wait_idle(struct cqspi_st *cqspi)
{
const unsigned int poll_idle_retry = 3;
@@ -356,13 +435,69 @@ static int cqspi_exec_flash_cmd(struct cqspi_st *cqspi, unsigned int reg)
return cqspi_wait_idle(cqspi);
}
+static int cqspi_setup_opcode_ext(struct cqspi_flash_pdata *f_pdata,
+ const struct spi_mem_op *op,
+ unsigned int shift)
+{
+ struct cqspi_st *cqspi = f_pdata->cqspi;
+ void __iomem *reg_base = cqspi->iobase;
+ unsigned int reg;
+ u8 ext;
+
+ if (op->cmd.nbytes != 2)
+ return -EINVAL;
+
+ /* Opcode extension is the LSB. */
+ ext = op->cmd.opcode & 0xff;
+
+ reg = readl(reg_base + CQSPI_REG_OP_EXT_LOWER);
+ reg &= ~(0xff << shift);
+ reg |= ext << shift;
+ writel(reg, reg_base + CQSPI_REG_OP_EXT_LOWER);
+
+ return 0;
+}
+
+static int cqspi_enable_dtr(struct cqspi_flash_pdata *f_pdata,
+ const struct spi_mem_op *op, unsigned int shift,
+ bool enable)
+{
+ struct cqspi_st *cqspi = f_pdata->cqspi;
+ void __iomem *reg_base = cqspi->iobase;
+ unsigned int reg;
+ int ret;
+
+ reg = readl(reg_base + CQSPI_REG_CONFIG);
+
+ /*
+ * We enable dual byte opcode here. The callers have to set up the
+ * extension opcode based on which type of operation it is.
+ */
+ if (enable) {
+ reg |= CQSPI_REG_CONFIG_DTR_PROTO;
+ reg |= CQSPI_REG_CONFIG_DUAL_OPCODE;
+
+ /* Set up command opcode extension. */
+ ret = cqspi_setup_opcode_ext(f_pdata, op, shift);
+ if (ret)
+ return ret;
+ } else {
+ reg &= ~CQSPI_REG_CONFIG_DTR_PROTO;
+ reg &= ~CQSPI_REG_CONFIG_DUAL_OPCODE;
+ }
+
+ writel(reg, reg_base + CQSPI_REG_CONFIG);
+
+ return cqspi_wait_idle(cqspi);
+}
+
static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
const struct spi_mem_op *op)
{
struct cqspi_st *cqspi = f_pdata->cqspi;
void __iomem *reg_base = cqspi->iobase;
u8 *rxbuf = op->data.buf.in;
- u8 opcode = op->cmd.opcode;
+ u8 opcode;
size_t n_rx = op->data.nbytes;
unsigned int rdreg;
unsigned int reg;
@@ -370,6 +505,15 @@ static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
size_t read_len;
int status;
+ status = cqspi_set_protocol(f_pdata, op);
+ if (status)
+ return status;
+
+ status = cqspi_enable_dtr(f_pdata, op, CQSPI_REG_OP_EXT_STIG_LSB,
+ f_pdata->dtr);
+ if (status)
+ return status;
+
if (!n_rx || n_rx > CQSPI_STIG_DATA_LEN_MAX || !rxbuf) {
dev_err(&cqspi->pdev->dev,
"Invalid input argument, len %zu rxbuf 0x%p\n",
@@ -377,12 +521,17 @@ static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
return -EINVAL;
}
+ if (f_pdata->dtr)
+ opcode = op->cmd.opcode >> 8;
+ else
+ opcode = op->cmd.opcode;
+
reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
rdreg = cqspi_calc_rdreg(f_pdata);
writel(rdreg, reg_base + CQSPI_REG_RD_INSTR);
- dummy_clk = cqspi_calc_dummy(op);
+ dummy_clk = cqspi_calc_dummy(op, f_pdata->dtr);
if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
return -EOPNOTSUPP;
@@ -421,12 +570,22 @@ static int cqspi_command_write(struct cqspi_flash_pdata *f_pdata,
{
struct cqspi_st *cqspi = f_pdata->cqspi;
void __iomem *reg_base = cqspi->iobase;
- const u8 opcode = op->cmd.opcode;
+ u8 opcode;
const u8 *txbuf = op->data.buf.out;
size_t n_tx = op->data.nbytes;
unsigned int reg;
unsigned int data;
size_t write_len;
+ int ret;
+
+ ret = cqspi_set_protocol(f_pdata, op);
+ if (ret)
+ return ret;
+
+ ret = cqspi_enable_dtr(f_pdata, op, CQSPI_REG_OP_EXT_STIG_LSB,
+ f_pdata->dtr);
+ if (ret)
+ return ret;
if (n_tx > CQSPI_STIG_DATA_LEN_MAX || (n_tx && !txbuf)) {
dev_err(&cqspi->pdev->dev,
@@ -435,6 +594,14 @@ static int cqspi_command_write(struct cqspi_flash_pdata *f_pdata,
return -EINVAL;
}
+ reg = cqspi_calc_rdreg(f_pdata);
+ writel(reg, reg_base + CQSPI_REG_RD_INSTR);
+
+ if (f_pdata->dtr)
+ opcode = op->cmd.opcode >> 8;
+ else
+ opcode = op->cmd.opcode;
+
reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
if (op->addr.nbytes) {
@@ -474,12 +641,24 @@ static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
void __iomem *reg_base = cqspi->iobase;
unsigned int dummy_clk = 0;
unsigned int reg;
+ int ret;
+ u8 opcode;
- reg = op->cmd.opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
+ ret = cqspi_enable_dtr(f_pdata, op, CQSPI_REG_OP_EXT_READ_LSB,
+ f_pdata->dtr);
+ if (ret)
+ return ret;
+
+ if (f_pdata->dtr)
+ opcode = op->cmd.opcode >> 8;
+ else
+ opcode = op->cmd.opcode;
+
+ reg = opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
reg |= cqspi_calc_rdreg(f_pdata);
/* Setup dummy clock cycles */
- dummy_clk = cqspi_calc_dummy(op);
+ dummy_clk = cqspi_calc_dummy(op, f_pdata->dtr);
if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
return -EOPNOTSUPP;
@@ -594,15 +773,43 @@ static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata,
const struct spi_mem_op *op)
{
unsigned int reg;
+ int ret;
struct cqspi_st *cqspi = f_pdata->cqspi;
void __iomem *reg_base = cqspi->iobase;
+ u8 opcode;
+
+ ret = cqspi_enable_dtr(f_pdata, op, CQSPI_REG_OP_EXT_WRITE_LSB,
+ f_pdata->dtr);
+ if (ret)
+ return ret;
+
+ if (f_pdata->dtr)
+ opcode = op->cmd.opcode >> 8;
+ else
+ opcode = op->cmd.opcode;
/* Set opcode. */
- reg = op->cmd.opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
+ reg = opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
+ reg |= f_pdata->data_width << CQSPI_REG_WR_INSTR_TYPE_DATA_LSB;
+ reg |= f_pdata->addr_width << CQSPI_REG_WR_INSTR_TYPE_ADDR_LSB;
writel(reg, reg_base + CQSPI_REG_WR_INSTR);
reg = cqspi_calc_rdreg(f_pdata);
writel(reg, reg_base + CQSPI_REG_RD_INSTR);
+ if (f_pdata->dtr) {
+ /*
+ * Some flashes like the cypress Semper flash expect a 4-byte
+ * dummy address with the Read SR command in DTR mode, but this
+ * controller does not support sending address with the Read SR
+ * command. So, disable write completion polling on the
+ * controller's side. spi-nor will take care of polling the
+ * status register.
+ */
+ reg = readl(reg_base + CQSPI_REG_WR_COMPLETION_CTRL);
+ reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL;
+ writel(reg, reg_base + CQSPI_REG_WR_COMPLETION_CTRL);
+ }
+
reg = readl(reg_base + CQSPI_REG_SIZE);
reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
reg |= (op->addr.nbytes - 1);
@@ -856,35 +1063,6 @@ static void cqspi_configure(struct cqspi_flash_pdata *f_pdata,
cqspi_controller_enable(cqspi, 1);
}
-static int cqspi_set_protocol(struct cqspi_flash_pdata *f_pdata,
- const struct spi_mem_op *op)
-{
- f_pdata->inst_width = CQSPI_INST_TYPE_SINGLE;
- f_pdata->addr_width = CQSPI_INST_TYPE_SINGLE;
- f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
-
- if (op->data.dir == SPI_MEM_DATA_IN) {
- switch (op->data.buswidth) {
- case 1:
- f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
- break;
- case 2:
- f_pdata->data_width = CQSPI_INST_TYPE_DUAL;
- break;
- case 4:
- f_pdata->data_width = CQSPI_INST_TYPE_QUAD;
- break;
- case 8:
- f_pdata->data_width = CQSPI_INST_TYPE_OCTAL;
- break;
- default:
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
static ssize_t cqspi_write(struct cqspi_flash_pdata *f_pdata,
const struct spi_mem_op *op)
{
@@ -902,7 +1080,16 @@ static ssize_t cqspi_write(struct cqspi_flash_pdata *f_pdata,
if (ret)
return ret;
- if (cqspi->use_direct_mode && ((to + len) <= cqspi->ahb_size)) {
+ /*
+ * Some flashes like the Cypress Semper flash expect a dummy 4-byte
+ * address (all 0s) with the read status register command in DTR mode.
+ * But this controller does not support sending dummy address bytes to
+ * the flash when it is polling the write completion register in DTR
+ * mode. So, we can not use direct mode when in DTR mode for writing
+ * data.
+ */
+ if (!f_pdata->dtr && cqspi->use_direct_mode &&
+ ((to + len) <= cqspi->ahb_size)) {
memcpy_toio(cqspi->ahb_base + to, buf, len);
return cqspi_wait_idle(cqspi);
}
@@ -1072,6 +1259,8 @@ static int cqspi_check_buswidth_req(struct spi_mem *mem, u8 buswidth, bool tx)
static bool cqspi_supports_mem_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
+ bool all_true, all_false;
+
if (cqspi_check_buswidth_req(mem, op->cmd.buswidth, true))
return false;
@@ -1088,6 +1277,19 @@ static bool cqspi_supports_mem_op(struct spi_mem *mem,
op->data.dir == SPI_MEM_DATA_OUT))
return false;
+ all_true = op->cmd.dtr && op->addr.dtr && op->dummy.dtr &&
+ op->data.dtr;
+ all_false = !op->cmd.dtr && !op->addr.dtr && !op->dummy.dtr &&
+ !op->data.dtr;
+
+ /* Mixed DTR modes not supported. */
+ if (!(all_true || all_false))
+ return false;
+
+ /* DTR mode opcodes should be 2 bytes. */
+ if (all_true && op->cmd.nbytes != 2)
+ return false;
+
return true;
}
@@ -1365,10 +1567,10 @@ static int cqspi_probe(struct platform_device *pdev)
ddata = of_device_get_match_data(dev);
if (ddata) {
if (ddata->quirks & CQSPI_NEEDS_WR_DELAY)
- cqspi->wr_delay = 5 * DIV_ROUND_UP(NSEC_PER_SEC,
+ cqspi->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC,
cqspi->master_ref_clk_hz);
if (ddata->hwcaps_mask & CQSPI_SUPPORTS_OCTAL)
- master->mode_bits |= SPI_RX_OCTAL;
+ master->mode_bits |= SPI_RX_OCTAL | SPI_TX_OCTAL;
if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE))
cqspi->use_direct_mode = true;
}
@@ -1510,3 +1712,4 @@ MODULE_AUTHOR("Ley Foon Tan ");
MODULE_AUTHOR("Graham Moore ");
MODULE_AUTHOR("Vadivel Murugan R ");
MODULE_AUTHOR("Vignesh Raghavendra ");
+MODULE_AUTHOR("Pratyush Yadav ");