From patchwork Wed Feb 26 09:36:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 204203 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=-9.9 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, 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 E9D92C4BA10 for ; Wed, 26 Feb 2020 09:38:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C22AD20732 for ; Wed, 26 Feb 2020 09:38:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="K6EPpPzR" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727880AbgBZJhh (ORCPT ); Wed, 26 Feb 2020 04:37:37 -0500 Received: from lelv0143.ext.ti.com ([198.47.23.248]:40056 "EHLO lelv0143.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726541AbgBZJhh (ORCPT ); Wed, 26 Feb 2020 04:37:37 -0500 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id 01Q9bHK2087084; Wed, 26 Feb 2020 03:37:17 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1582709837; bh=/RvMu+KBpcqEDFVBnIWtjiFPQ2qCDkAs2AiQIuWdFws=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=K6EPpPzRPSk4gsirOoI1fBp5truy0/o8R/d1P37k3XGPD9cbcVIhzmmEkU8XA4UO8 XCt4AtdJCY4rouVI64SzqfNU6w30qSYbkkVpf11Yo8Xoyi855W2yZMYDaIwCCOGMQc wJ/3zOV6EfUHDvbLVapgTz2frUoo/TmTXEqezsNI= Received: from DLEE115.ent.ti.com (dlee115.ent.ti.com [157.170.170.26]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 01Q9bHVR118717 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 26 Feb 2020 03:37:17 -0600 Received: from DLEE101.ent.ti.com (157.170.170.31) by DLEE115.ent.ti.com (157.170.170.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3; Wed, 26 Feb 2020 03:37:17 -0600 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE101.ent.ti.com (157.170.170.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3 via Frontend Transport; Wed, 26 Feb 2020 03:37:17 -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 01Q9b4A7110613; Wed, 26 Feb 2020 03:37:13 -0600 From: Pratyush Yadav To: Tudor Ambarus , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mark Brown , Rob Herring , Mark Rutland CC: Pratyush Yadav , , , , , Sekhar Nori Subject: [PATCH v2 02/11] spi: set mode bits for "spi-rx-dtr" and "spi-tx-dtr" Date: Wed, 26 Feb 2020 15:06:54 +0530 Message-ID: <20200226093703.19765-3-p.yadav@ti.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200226093703.19765-1-p.yadav@ti.com> References: <20200226093703.19765-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org These two DT properties express DTR receive and transmit capabilities of a SPI flash and controller. Introduce two new mode bits: SPI_RX_DTR and SPI_TX_DTR which correspond to the new DT properties. Set these bits when the two corresponding properties are present in the device tree. Also update the detection of unsupported mode bits to include the new bits. Signed-off-by: Pratyush Yadav --- drivers/spi/spi.c | 10 +++++++++- include/linux/spi/spi.h | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 38b4c78df506..25c8ed9343f9 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1927,6 +1927,13 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, } } + /* Device DTR mode. */ + if (of_property_read_bool(nc, "spi-tx-dtr")) + spi->mode |= SPI_TX_DTR; + + if (of_property_read_bool(nc, "spi-rx-dtr")) + spi->mode |= SPI_RX_DTR; + if (spi_controller_is_slave(ctlr)) { if (!of_node_name_eq(nc, "slave")) { dev_err(&ctlr->dev, "%pOF is not called 'slave'\n", @@ -3252,7 +3259,8 @@ int spi_setup(struct spi_device *spi) bad_bits &= ~SPI_CS_HIGH; ugly_bits = bad_bits & (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL | - SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL); + SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL | + SPI_TX_DTR | SPI_RX_DTR); if (ugly_bits) { dev_warn(&spi->dev, "setup: ignoring unsupported mode bits %x\n", diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 6d16ba01ff5a..bf1108318389 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -183,6 +183,8 @@ struct spi_device { #define SPI_TX_OCTAL 0x2000 /* transmit with 8 wires */ #define SPI_RX_OCTAL 0x4000 /* receive with 8 wires */ #define SPI_3WIRE_HIZ 0x8000 /* high impedance turnaround */ +#define SPI_RX_DTR 0x10000 /* receive in DTR mode */ +#define SPI_TX_DTR 0x20000 /* transmit in DTR mode */ int irq; void *controller_state; void *controller_data; From patchwork Wed Feb 26 09:36:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 204204 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=-9.9 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, 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 EE51FC4BA0E for ; Wed, 26 Feb 2020 09:38:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C5D3C24653 for ; Wed, 26 Feb 2020 09:38:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="GC3+4ikY" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728025AbgBZJh4 (ORCPT ); Wed, 26 Feb 2020 04:37:56 -0500 Received: from fllv0015.ext.ti.com ([198.47.19.141]:37304 "EHLO fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727998AbgBZJhv (ORCPT ); Wed, 26 Feb 2020 04:37:51 -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 01Q9bQ06108032; Wed, 26 Feb 2020 03:37:26 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1582709846; bh=UK9ViJ8/KnZTmqsh0WaZJUAW35YfoP4ZW7jL8CyJPoQ=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=GC3+4ikYVuIib89/kVsUWrJZzTCfta5uFhsQ1rmOJebR3ekvGJGeZ/1/IltvlnZ3b 1B7gis80R3HV0fd0WoUUl8MBUIm9j83v2hKHf1gn3oxlGbVRwx6L0/EUnWrtTHLrud uHENnCYDJ3D4byp3UnfSnxEEeMQh0Hbmkkz3SmfU= Received: from DLEE112.ent.ti.com (dlee112.ent.ti.com [157.170.170.23]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 01Q9bQqZ118902 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 26 Feb 2020 03:37:26 -0600 Received: from DLEE107.ent.ti.com (157.170.170.37) by DLEE112.ent.ti.com (157.170.170.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3; Wed, 26 Feb 2020 03:37:25 -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.1847.3 via Frontend Transport; Wed, 26 Feb 2020 03:37:25 -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 01Q9b4A9110613; Wed, 26 Feb 2020 03:37:22 -0600 From: Pratyush Yadav To: Tudor Ambarus , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mark Brown , Rob Herring , Mark Rutland CC: Pratyush Yadav , , , , , Sekhar Nori Subject: [PATCH v2 04/11] spi: spi-mem: allow specifying a command's extension Date: Wed, 26 Feb 2020 15:06:56 +0530 Message-ID: <20200226093703.19765-5-p.yadav@ti.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200226093703.19765-1-p.yadav@ti.com> References: <20200226093703.19765-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org In xSPI mode, flashes expect 2-byte opcodes. The second byte is called the "command extension". There can be 3 types of extensions in xSPI: repeat, invert, and hex. When the extension type is "repeat", the same opcode is sent twice. When it is "invert", the second byte is the inverse of the opcode. When it is "hex" an additional opcode byte based is sent with the command whose value can be anything. Signed-off-by: Pratyush Yadav --- drivers/spi/spi-mem.c | 23 +++++++++++++++++++++++ include/linux/spi/spi-mem.h | 24 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index cb13e0878b95..3838ddc9aeec 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -462,6 +462,29 @@ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) } EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size); +int spi_mem_get_cmd_ext(const struct spi_mem_op *op, u8 *ext) +{ + switch (op->cmd.ext_type) { + case SPI_MEM_EXT_INVERT: + *ext = ~op->cmd.opcode; + break; + + case SPI_MEM_EXT_REPEAT: + *ext = op->cmd.opcode; + break; + + case SPI_MEM_EXT_HEX: + *ext = op->cmd.ext; + break; + + default: + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(spi_mem_get_cmd_ext); + static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, void *buf) { diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 4669082b4e3b..06ccab17e4d0 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -67,11 +67,31 @@ enum spi_mem_data_dir { SPI_MEM_DATA_OUT, }; +/** + * enum spi_mem_cmd_ext - describes the command opcode extension in DTR mode + * @SPI_MEM_EXT_NONE: no extension. This is the default, and is used in Legacy + * SPI mode + * @SPI_MEM_EXT_REPEAT: the extension is same as the opcode + * @SPI_MEM_EXT_INVERT: the extension is the bitwise inverse of the opcode + * @SPI_MEM_EXT_HEX: the extension is any hex value. The command and opcode + * combine to form a 16-bit opcode. + */ +enum spi_mem_cmd_ext { + SPI_MEM_EXT_NONE = 0, + SPI_MEM_EXT_REPEAT, + SPI_MEM_EXT_INVERT, + SPI_MEM_EXT_HEX, +}; + /** * struct spi_mem_op - describes a SPI memory operation * @cmd.buswidth: number of IO lines used to transmit the command * @cmd.opcode: operation opcode * @cmd.is_dtr: whether the command opcode should be sent in DTR mode or not + * @cmd.ext_type: type of the command opcode extension in DTR mode + * @cmd.ext: value of the command opcode extension in DTR mode. It is + * only set when 'ext_type' is 'SPI_MEM_EXT_HEX'. In all other + * cases, the extension can be directly derived from the opcode. * @addr.nbytes: number of address bytes to send. Can be zero if the operation * does not need to send an address * @addr.buswidth: number of IO lines used to transmit the address cycles @@ -97,6 +117,8 @@ struct spi_mem_op { u8 buswidth; u8 opcode; bool is_dtr; + enum spi_mem_cmd_ext ext_type; + u8 ext; } cmd; struct { @@ -361,6 +383,8 @@ int spi_mem_driver_register_with_owner(struct spi_mem_driver *drv, void spi_mem_driver_unregister(struct spi_mem_driver *drv); +int spi_mem_get_cmd_ext(const struct spi_mem_op *op, u8 *ext); + #define spi_mem_driver_register(__drv) \ spi_mem_driver_register_with_owner(__drv, THIS_MODULE) From patchwork Wed Feb 26 09:36:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 204207 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=-9.9 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, 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 07848C4BA10 for ; Wed, 26 Feb 2020 09:37:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C86302467E for ; Wed, 26 Feb 2020 09:37:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="oQ8VOMpE" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727973AbgBZJht (ORCPT ); Wed, 26 Feb 2020 04:37:49 -0500 Received: from lelv0142.ext.ti.com ([198.47.23.249]:40650 "EHLO lelv0142.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727959AbgBZJhr (ORCPT ); Wed, 26 Feb 2020 04:37:47 -0500 Received: from fllv0035.itg.ti.com ([10.64.41.0]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id 01Q9bYnK019775; Wed, 26 Feb 2020 03:37:34 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1582709854; bh=im2SpjaQlIXYuNit+5LGQc96gvXnDWfnu+1Jlyi8jCs=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=oQ8VOMpEveaNjWNrvOdr4norJMwcWY/Ggi3pk8bCs87fuKMtQV8BZvP/7DAoLaA+D 0B3/7XqBjm/ZXf9Je2ShArpiVKWfYUpuXR8sjDu6zRKwoKKmgilnf6lHbgI5nEZQjw Fi68aho3SQXSkXSdGNWbxixOkgcLEU1C5GZPwnJg= Received: from DFLE105.ent.ti.com (dfle105.ent.ti.com [10.64.6.26]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTP id 01Q9bYFc086786; Wed, 26 Feb 2020 03:37:34 -0600 Received: from DFLE103.ent.ti.com (10.64.6.24) 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.1847.3; Wed, 26 Feb 2020 03:37:34 -0600 Received: from lelv0327.itg.ti.com (10.180.67.183) 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.1847.3 via Frontend Transport; Wed, 26 Feb 2020 03:37: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 01Q9b4AB110613; Wed, 26 Feb 2020 03:37:30 -0600 From: Pratyush Yadav To: Tudor Ambarus , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mark Brown , Rob Herring , Mark Rutland CC: Pratyush Yadav , , , , , Sekhar Nori Subject: [PATCH v2 06/11] mtd: spi-nor: add support for DTR protocol Date: Wed, 26 Feb 2020 15:06:58 +0530 Message-ID: <20200226093703.19765-7-p.yadav@ti.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200226093703.19765-1-p.yadav@ti.com> References: <20200226093703.19765-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Double Transfer Rate (DTR) is SPI protocol in which data is transferred on each clock edge as opposed to on each clock cycle. Make framework-level changes to allow supporting flashes in DTR mode. Right now, mixed DTR modes are not supported. So, for example a mode like 4S-4D-4D will not work. All phases need to be either DTR or STR. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi-nor/spi-nor.c | 245 ++++++++++++++++++++++++++-------- include/linux/mtd/spi-nor.h | 34 +++-- 2 files changed, 213 insertions(+), 66 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 4fc632ec18fe..6102520550a1 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -238,6 +238,7 @@ struct flash_info { * status register. Must be used with * SPI_NOR_HAS_TB. */ +#define SPI_NOR_OCTAL_DTR_READ BIT(18) /* Flash supports octal DTR Read. */ /* Part specific fixup hooks. */ const struct spi_nor_fixups *fixups; @@ -245,6 +246,46 @@ struct flash_info { #define JEDEC_MFR(info) ((info)->id[0]) +/** + * spi_nor_spimem_setup_op() - Set up common properties of a spi-mem op. + * @nor: pointer to a 'struct spi_nor' + * @op: pointer to the 'struct spi_mem_op' whose properties + * need to be initialized. + * @proto: the protocol from which the properties need to be set. + */ +static void spi_nor_spimem_setup_op(const struct spi_nor *nor, + struct spi_mem_op *op, + const enum spi_nor_protocol proto) +{ + + op->cmd.buswidth = spi_nor_get_protocol_inst_nbits(proto); + + if (op->addr.nbytes) + op->addr.buswidth = spi_nor_get_protocol_addr_nbits(proto); + + if (op->dummy.nbytes) + op->dummy.buswidth = spi_nor_get_protocol_addr_nbits(proto); + + if (op->data.buf.in || op->data.buf.out) + op->data.buswidth = spi_nor_get_protocol_data_nbits(proto); + + if (spi_nor_protocol_is_dtr(proto)) { + /* + * spi-mem supports mixed DTR modes, but right now we can only + * have all phases either DTR or STR. IOW, spi-mem can have + * something like 4S-4D-4D, but spi-nor can't. So, set all 4 + * phases to either DTR or STR. + */ + op->cmd.is_dtr = op->addr.is_dtr = op->dummy.is_dtr + = op->data.is_dtr = true; + + /* 2 bytes per clock cycle in DTR mode. */ + op->dummy.nbytes *= 2; + + op->cmd.ext_type = nor->cmd_ext; + } +} + /** * spi_nor_spimem_xfer_data() - helper function to read/write data to * flash's memory region @@ -316,14 +357,12 @@ static ssize_t spi_nor_spimem_read_data(struct spi_nor *nor, loff_t from, SPI_MEM_OP_DUMMY(nor->read_dummy, 1), SPI_MEM_OP_DATA_IN(len, buf, 1)); - /* get transfer protocols. */ - op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->read_proto); - op.addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->read_proto); - op.dummy.buswidth = op.addr.buswidth; - op.data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto); + spi_nor_spimem_setup_op(nor, &op, nor->read_proto); /* convert the dummy cycles to the number of bytes */ op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8; + if (spi_nor_protocol_is_dtr(nor->read_proto)) + op.dummy.nbytes *= 2; return spi_nor_spimem_xfer_data(nor, &op); } @@ -365,13 +404,11 @@ static ssize_t spi_nor_spimem_write_data(struct spi_nor *nor, loff_t to, SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_OUT(len, buf, 1)); - op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->write_proto); - op.addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->write_proto); - op.data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto); - if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second) op.addr.nbytes = 0; + spi_nor_spimem_setup_op(nor, &op, nor->write_proto); + return spi_nor_spimem_xfer_data(nor, &op); } @@ -410,10 +447,16 @@ static int spi_nor_write_enable(struct spi_nor *nor) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_NO_DATA); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WREN, - NULL, 0); + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->write_reg(nor, + SPINOR_OP_WREN, + NULL, 0); } if (ret) @@ -439,10 +482,16 @@ static int spi_nor_write_disable(struct spi_nor *nor) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_NO_DATA); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRDI, - NULL, 0); + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->write_reg(nor, + SPINOR_OP_WRDI, + NULL, 0); } if (ret) @@ -501,10 +550,15 @@ static int spi_nor_read_fsr(struct spi_nor *nor, u8 *fsr) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_IN(1, fsr, 1)); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDFSR, - fsr, 1); + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDFSR, + fsr, 1); } if (ret) @@ -533,9 +587,15 @@ static int spi_nor_read_cr(struct spi_nor *nor, u8 *cr) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_IN(1, cr, 1)); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDCR, cr, 1); + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDCR, + cr, 1); } if (ret) @@ -566,12 +626,17 @@ static int macronix_set_4byte(struct spi_nor *nor, bool enable) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_NO_DATA); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->write_reg(nor, - enable ? SPINOR_OP_EN4B : - SPINOR_OP_EX4B, - NULL, 0); + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->write_reg(nor, + enable ? SPINOR_OP_EN4B : + SPINOR_OP_EX4B, + NULL, 0); } if (ret) @@ -624,10 +689,15 @@ static int spansion_set_4byte(struct spi_nor *nor, bool enable) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_OUT(1, nor->bouncebuf, 1)); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->write_reg(nor, SPINOR_OP_BRWR, - nor->bouncebuf, 1); + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->write_reg(nor, SPINOR_OP_BRWR, + nor->bouncebuf, 1); } if (ret) @@ -656,10 +726,16 @@ static int spi_nor_write_ear(struct spi_nor *nor, u8 ear) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_OUT(1, nor->bouncebuf, 1)); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WREAR, - nor->bouncebuf, 1); + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->write_reg(nor, + SPINOR_OP_WREAR, + nor->bouncebuf, 1); } if (ret) @@ -719,10 +795,16 @@ static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_IN(1, sr, 1)); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->read_reg(nor, SPINOR_OP_XRDSR, - sr, 1); + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->read_reg(nor, + SPINOR_OP_XRDSR, + sr, 1); } if (ret) @@ -764,10 +846,16 @@ static void spi_nor_clear_sr(struct spi_nor *nor) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_NO_DATA); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->write_reg(nor, SPINOR_OP_CLSR, - NULL, 0); + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->write_reg(nor, + SPINOR_OP_CLSR, + NULL, 0); } if (ret) @@ -817,10 +905,16 @@ static void spi_nor_clear_fsr(struct spi_nor *nor) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_NO_DATA); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->write_reg(nor, SPINOR_OP_CLFSR, - NULL, 0); + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->write_reg(nor, + SPINOR_OP_CLFSR, + NULL, 0); } if (ret) @@ -950,10 +1044,16 @@ static int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_OUT(len, sr, 1)); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR, - sr, len); + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->write_reg(nor, + SPINOR_OP_WRSR, + sr, len); } if (ret) { @@ -1152,10 +1252,16 @@ static int spi_nor_write_sr2(struct spi_nor *nor, const u8 *sr2) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_OUT(1, sr2, 1)); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR2, - sr2, 1); + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->write_reg(nor, + SPINOR_OP_WRSR2, + sr2, 1); } if (ret) { @@ -1186,10 +1292,16 @@ static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_IN(1, sr2, 1)); + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR2, - sr2, 1); + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->read_reg(nor, + SPINOR_OP_RDSR2, + sr2, 1); } if (ret) @@ -1217,10 +1329,16 @@ static int spi_nor_erase_chip(struct spi_nor *nor) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_NO_DATA); + spi_nor_spimem_setup_op(nor, &op, nor->write_proto); + ret = spi_mem_exec_op(nor->spimem, &op); } else { - ret = nor->controller_ops->write_reg(nor, SPINOR_OP_CHIP_ERASE, - NULL, 0); + if (spi_nor_protocol_is_dtr(nor->write_proto)) + ret = -ENOTSUPP; + else + ret = nor->controller_ops->write_reg(nor, + SPINOR_OP_CHIP_ERASE, + NULL, 0); } if (ret) @@ -1379,7 +1497,11 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_NO_DATA); + spi_nor_spimem_setup_op(nor, &op, nor->write_proto); + return spi_mem_exec_op(nor->spimem, &op); + } else if (spi_nor_protocol_is_dtr(nor->write_proto)) { + return -ENOTSUPP; } else if (nor->controller_ops->erase) { return nor->controller_ops->erase(nor, addr); } @@ -3045,6 +3167,7 @@ static int spi_nor_hwcaps_read2cmd(u32 hwcaps) { SNOR_HWCAPS_READ_1_8_8, SNOR_CMD_READ_1_8_8 }, { SNOR_HWCAPS_READ_8_8_8, SNOR_CMD_READ_8_8_8 }, { SNOR_HWCAPS_READ_1_8_8_DTR, SNOR_CMD_READ_1_8_8_DTR }, + { SNOR_HWCAPS_READ_8_8_8_DTR, SNOR_CMD_READ_8_8_8_DTR }, }; return spi_nor_hwcaps2cmd(hwcaps, hwcaps_read2cmd, @@ -3061,6 +3184,7 @@ static int spi_nor_hwcaps_pp2cmd(u32 hwcaps) { SNOR_HWCAPS_PP_1_1_8, SNOR_CMD_PP_1_1_8 }, { SNOR_HWCAPS_PP_1_8_8, SNOR_CMD_PP_1_8_8 }, { SNOR_HWCAPS_PP_8_8_8, SNOR_CMD_PP_8_8_8 }, + { SNOR_HWCAPS_PP_8_8_8_DTR, SNOR_CMD_PP_8_8_8_DTR }, }; return spi_nor_hwcaps2cmd(hwcaps, hwcaps_pp2cmd, @@ -3184,13 +3308,11 @@ static int spi_nor_spimem_check_readop(struct spi_nor *nor, SPI_MEM_OP_DUMMY(0, 1), SPI_MEM_OP_DATA_IN(0, NULL, 1)); - op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(read->proto); - op.addr.buswidth = spi_nor_get_protocol_addr_nbits(read->proto); - op.data.buswidth = spi_nor_get_protocol_data_nbits(read->proto); - op.dummy.buswidth = op.addr.buswidth; op.dummy.nbytes = (read->num_mode_clocks + read->num_wait_states) * op.dummy.buswidth / 8; + spi_nor_spimem_setup_op(nor, &op, read->proto); + return spi_nor_spimem_check_op(nor, &op); } @@ -3210,9 +3332,7 @@ static int spi_nor_spimem_check_pp(struct spi_nor *nor, SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_OUT(0, NULL, 1)); - op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(pp->proto); - op.addr.buswidth = spi_nor_get_protocol_addr_nbits(pp->proto); - op.data.buswidth = spi_nor_get_protocol_data_nbits(pp->proto); + spi_nor_spimem_setup_op(nor, &op, pp->proto); return spi_nor_spimem_check_op(nor, &op); } @@ -3230,11 +3350,10 @@ spi_nor_spimem_adjust_hwcaps(struct spi_nor *nor, u32 *hwcaps) struct spi_nor_flash_parameter *params = &nor->params; unsigned int cap; - /* DTR modes are not supported yet, mask them all. */ - *hwcaps &= ~SNOR_HWCAPS_DTR; - - /* X-X-X modes are not supported yet, mask them all. */ - *hwcaps &= ~SNOR_HWCAPS_X_X_X; + /* 2-2-2 and 4-4-4 modes are not supported yet, mask them all. */ + *hwcaps &= ~(SNOR_HWCAPS_READ_2_2_2 | \ + SNOR_HWCAPS_READ_4_4_4 | \ + SNOR_HWCAPS_PP_4_4_4); for (cap = 0; cap < sizeof(*hwcaps) * BITS_PER_BYTE; cap++) { int rdidx, ppidx; @@ -4240,9 +4359,16 @@ static int spi_nor_parse_4bait(struct spi_nor *nor, } /* 4BAIT is the only SFDP table that indicates page program support. */ - if (pp_hwcaps & SNOR_HWCAPS_PP) + if (pp_hwcaps & SNOR_HWCAPS_PP) { spi_nor_set_pp_settings(¶ms_pp[SNOR_CMD_PP], SPINOR_OP_PP_4B, SNOR_PROTO_1_1_1); + /* + * Since xSPI Page Program opcode is backward compatible with + * Legacy SPI, use Legacy SPI opcode there as well. + */ + spi_nor_set_pp_settings(¶ms_pp[SNOR_CMD_PP_8_8_8_DTR], + SPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR); + } if (pp_hwcaps & SNOR_HWCAPS_PP_1_1_4) spi_nor_set_pp_settings(¶ms_pp[SNOR_CMD_PP_1_1_4], SPINOR_OP_PP_1_1_4_4B, @@ -4797,6 +4923,13 @@ static void spi_nor_info_init_params(struct spi_nor *nor) spi_nor_set_pp_settings(¶ms->page_programs[SNOR_CMD_PP], SPINOR_OP_PP, SNOR_PROTO_1_1_1); + /* + * Since xSPI Page Program opcode is backward compatible with + * Legacy SPI, use Legacy SPI opcode there as well. + */ + spi_nor_set_pp_settings(¶ms->page_programs[SNOR_CMD_PP_8_8_8_DTR], + SPINOR_OP_PP, SNOR_PROTO_8_8_8_DTR); + /* * Sector Erase settings. Sort Erase Types in ascending order, with the * smallest erase size starting at BIT(0). @@ -4924,7 +5057,8 @@ static void spi_nor_init_params(struct spi_nor *nor) spi_nor_manufacturer_init_params(nor); - if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) && + if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_OCTAL_READ | SPI_NOR_OCTAL_DTR_READ)) && !(nor->info->flags & SPI_NOR_SKIP_SFDP)) spi_nor_sfdp_init_params(nor); @@ -4984,7 +5118,9 @@ static int spi_nor_init(struct spi_nor *nor) return err; } - if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES)) { + if (nor->addr_width == 4 && + !(nor->info->flags & SPI_NOR_OCTAL_DTR_READ) && + !(nor->flags & SNOR_F_4B_OPCODES)) { /* * If the RESET# pin isn't hooked up properly, or the system * otherwise doesn't perform a reset command in the boot @@ -5038,6 +5174,9 @@ static int spi_nor_set_addr_width(struct spi_nor *nor) { if (nor->addr_width) { /* already configured from SFDP */ + } else if (spi_nor_protocol_is_dtr(nor->read_proto)) { + /* Always use 4-byte addresses in DTR mode. */ + nor->addr_width = 4; } else if (nor->info->addr_width) { nor->addr_width = nor->info->addr_width; } else if (nor->mtd.size > 0x1000000) { diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 5abd91cc6dfa..364f37276d78 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -195,6 +195,7 @@ enum spi_nor_protocol { SNOR_PROTO_1_2_2_DTR = SNOR_PROTO_DTR(1, 2, 2), SNOR_PROTO_1_4_4_DTR = SNOR_PROTO_DTR(1, 4, 4), SNOR_PROTO_1_8_8_DTR = SNOR_PROTO_DTR(1, 8, 8), + SNOR_PROTO_8_8_8_DTR = SNOR_PROTO_DTR(8, 8, 8), }; static inline bool spi_nor_protocol_is_dtr(enum spi_nor_protocol proto) @@ -345,7 +346,7 @@ struct spi_nor_hwcaps { * then Quad SPI protocols before Dual SPI protocols, Fast Read and lastly * (Slow) Read. */ -#define SNOR_HWCAPS_READ_MASK GENMASK(14, 0) +#define SNOR_HWCAPS_READ_MASK GENMASK(15, 0) #define SNOR_HWCAPS_READ BIT(0) #define SNOR_HWCAPS_READ_FAST BIT(1) #define SNOR_HWCAPS_READ_1_1_1_DTR BIT(2) @@ -362,11 +363,12 @@ struct spi_nor_hwcaps { #define SNOR_HWCAPS_READ_4_4_4 BIT(9) #define SNOR_HWCAPS_READ_1_4_4_DTR BIT(10) -#define SNOR_HWCAPS_READ_OCTAL GENMASK(14, 11) +#define SNOR_HWCAPS_READ_OCTAL GENMASK(15, 11) #define SNOR_HWCAPS_READ_1_1_8 BIT(11) #define SNOR_HWCAPS_READ_1_8_8 BIT(12) #define SNOR_HWCAPS_READ_8_8_8 BIT(13) #define SNOR_HWCAPS_READ_1_8_8_DTR BIT(14) +#define SNOR_HWCAPS_READ_8_8_8_DTR BIT(15) /* * Page Program capabilities. @@ -377,18 +379,19 @@ struct spi_nor_hwcaps { * JEDEC/SFDP standard to define them. Also at this moment no SPI flash memory * implements such commands. */ -#define SNOR_HWCAPS_PP_MASK GENMASK(22, 16) -#define SNOR_HWCAPS_PP BIT(16) +#define SNOR_HWCAPS_PP_MASK GENMASK(23, 16) +#define SNOR_HWCAPS_PP BIT(16) -#define SNOR_HWCAPS_PP_QUAD GENMASK(19, 17) -#define SNOR_HWCAPS_PP_1_1_4 BIT(17) -#define SNOR_HWCAPS_PP_1_4_4 BIT(18) -#define SNOR_HWCAPS_PP_4_4_4 BIT(19) +#define SNOR_HWCAPS_PP_QUAD GENMASK(19, 17) +#define SNOR_HWCAPS_PP_1_1_4 BIT(17) +#define SNOR_HWCAPS_PP_1_4_4 BIT(18) +#define SNOR_HWCAPS_PP_4_4_4 BIT(19) -#define SNOR_HWCAPS_PP_OCTAL GENMASK(22, 20) -#define SNOR_HWCAPS_PP_1_1_8 BIT(20) -#define SNOR_HWCAPS_PP_1_8_8 BIT(21) -#define SNOR_HWCAPS_PP_8_8_8 BIT(22) +#define SNOR_HWCAPS_PP_OCTAL GENMASK(23, 20) +#define SNOR_HWCAPS_PP_1_1_8 BIT(20) +#define SNOR_HWCAPS_PP_1_8_8 BIT(21) +#define SNOR_HWCAPS_PP_8_8_8 BIT(22) +#define SNOR_HWCAPS_PP_8_8_8_DTR BIT(23) #define SNOR_HWCAPS_X_X_X (SNOR_HWCAPS_READ_2_2_2 | \ SNOR_HWCAPS_READ_4_4_4 | \ @@ -399,7 +402,8 @@ struct spi_nor_hwcaps { #define SNOR_HWCAPS_DTR (SNOR_HWCAPS_READ_1_1_1_DTR | \ SNOR_HWCAPS_READ_1_2_2_DTR | \ SNOR_HWCAPS_READ_1_4_4_DTR | \ - SNOR_HWCAPS_READ_1_8_8_DTR) + SNOR_HWCAPS_READ_1_8_8_DTR | \ + SNOR_HWCAPS_READ_8_8_8_DTR) #define SNOR_HWCAPS_ALL (SNOR_HWCAPS_READ_MASK | \ SNOR_HWCAPS_PP_MASK) @@ -438,6 +442,7 @@ enum spi_nor_read_command_index { SNOR_CMD_READ_1_8_8, SNOR_CMD_READ_8_8_8, SNOR_CMD_READ_1_8_8_DTR, + SNOR_CMD_READ_8_8_8_DTR, SNOR_CMD_READ_MAX }; @@ -454,6 +459,7 @@ enum spi_nor_pp_command_index { SNOR_CMD_PP_1_1_8, SNOR_CMD_PP_1_8_8, SNOR_CMD_PP_8_8_8, + SNOR_CMD_PP_8_8_8_DTR, SNOR_CMD_PP_MAX }; @@ -570,6 +576,7 @@ struct flash_info; * @program_opcode: the program opcode * @sst_write_second: used by the SST write operation * @flags: flag options for the current SPI-NOR (SNOR_F_*) + * @cmd_ext: the command opcode extension for DTR mode. * @read_proto: the SPI protocol for read operations * @write_proto: the SPI protocol for write operations * @reg_proto the SPI protocol for read_reg/write_reg/erase operations @@ -599,6 +606,7 @@ struct spi_nor { enum spi_nor_protocol reg_proto; bool sst_write_second; u32 flags; + enum spi_mem_cmd_ext cmd_ext; const struct spi_nor_controller_ops *controller_ops; From patchwork Wed Feb 26 09:37:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 204206 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=-9.9 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, 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 64786C4BA10 for ; Wed, 26 Feb 2020 09:38:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3ADE124656 for ; Wed, 26 Feb 2020 09:38:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="No0k3OIx" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728080AbgBZJiD (ORCPT ); Wed, 26 Feb 2020 04:38:03 -0500 Received: from fllv0016.ext.ti.com ([198.47.19.142]:45698 "EHLO fllv0016.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727457AbgBZJiC (ORCPT ); Wed, 26 Feb 2020 04:38:02 -0500 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 01Q9bpYG048469; Wed, 26 Feb 2020 03:37:51 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1582709872; bh=f73KydanqCBfpggGnWafdMQaZ6wiesDHl1RvZlVeYSw=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=No0k3OIxU014MkfBvJ/fgCEQgTU7Z/CIgPHeLbBZuNxg97HCQabtuGeyb9bWOr/+H NBRwuOutUGuYTPlp9TIJ63sj5HHaz5l+8TMVBu76ri4gs1VS+EqUgVtcuc4F55DO+J 1sLHBaf1ZOvmd1rXzk0+7N8QkkBuz9qMjSA0Imuc= Received: from DFLE108.ent.ti.com (dfle108.ent.ti.com [10.64.6.29]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 01Q9bpPI119216 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 26 Feb 2020 03:37:51 -0600 Received: from DFLE113.ent.ti.com (10.64.6.34) 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.1847.3; Wed, 26 Feb 2020 03:37:51 -0600 Received: from lelv0327.itg.ti.com (10.180.67.183) by DFLE113.ent.ti.com (10.64.6.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3 via Frontend Transport; Wed, 26 Feb 2020 03:37:51 -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 01Q9b4AF110613; Wed, 26 Feb 2020 03:37:47 -0600 From: Pratyush Yadav To: Tudor Ambarus , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mark Brown , Rob Herring , Mark Rutland CC: Pratyush Yadav , , , , , Sekhar Nori Subject: [PATCH v2 10/11] mtd: spi-nor: enable octal DTR mode when possible Date: Wed, 26 Feb 2020 15:07:02 +0530 Message-ID: <20200226093703.19765-11-p.yadav@ti.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200226093703.19765-1-p.yadav@ti.com> References: <20200226093703.19765-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Allow flashes to specify a hook to enable octal DTR mode. Use this hook whenever possible to get optimal transfer speeds. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi-nor/spi-nor.c | 31 +++++++++++++++++++++++++++++++ include/linux/mtd/spi-nor.h | 2 ++ 2 files changed, 33 insertions(+) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 06cfc525260c..fdcc1b4abc3f 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -5184,6 +5184,31 @@ static void spi_nor_init_params(struct spi_nor *nor) spi_nor_late_init_params(nor); } +/** spi_nor_octal_dtr_enable() - enable Octal DTR I/O if needed + * @nor: pointer to a 'struct spi_nor' + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_octal_dtr_enable(struct spi_nor *nor) +{ + int ret; + + if (!nor->params.octal_dtr_enable) + return 0; + + if (!(spi_nor_get_protocol_width(nor->read_proto) == 8 || + spi_nor_get_protocol_width(nor->write_proto) == 8)) + return 0; + + ret = nor->params.octal_dtr_enable(nor); + if (ret) + return ret; + + nor->reg_proto = SNOR_PROTO_8_8_8_DTR; + + return 0; +} + /** * spi_nor_quad_enable() - enable Quad I/O if needed. * @nor: pointer to a 'struct spi_nor' @@ -5223,6 +5248,12 @@ static int spi_nor_init(struct spi_nor *nor) { int err; + err = spi_nor_octal_dtr_enable(nor); + if (err) { + dev_dbg(nor->dev, "octal mode not supported\n"); + return err; + } + err = spi_nor_quad_enable(nor); if (err) { dev_dbg(nor->dev, "quad mode not supported\n"); diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index f54dbd0f86ab..c653f6713cfc 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -526,6 +526,7 @@ struct spi_nor_locking_ops { * higher index in the array, the higher priority. * @erase_map: the erase map parsed from the SFDP Sector Map Parameter * Table. + * @octal_dtr_enable: enables SPI NOR octal DTR mode. * @quad_enable: enables SPI NOR quad mode. * @set_4byte: puts the SPI NOR in 4 byte addressing mode. * @convert_addr: converts an absolute address into something the flash @@ -549,6 +550,7 @@ struct spi_nor_flash_parameter { struct spi_nor_erase_map erase_map; + int (*octal_dtr_enable)(struct spi_nor *nor); int (*quad_enable)(struct spi_nor *nor); int (*set_4byte)(struct spi_nor *nor, bool enable); u32 (*convert_addr)(struct spi_nor *nor, u32 addr); From patchwork Wed Feb 26 09:37:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 204205 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=-9.9 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, 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 877F9C4BA10 for ; Wed, 26 Feb 2020 09:38:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4BBE224653 for ; Wed, 26 Feb 2020 09:38:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="K2dTe32y" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728097AbgBZJiJ (ORCPT ); Wed, 26 Feb 2020 04:38:09 -0500 Received: from lelv0143.ext.ti.com ([198.47.23.248]:40120 "EHLO lelv0143.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727457AbgBZJiI (ORCPT ); Wed, 26 Feb 2020 04:38:08 -0500 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id 01Q9bu9B087237; Wed, 26 Feb 2020 03:37:56 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1582709876; bh=lx7klmR18LxVuDBU/ZZOyd+LtXGNVESbcjfzd3wnbNA=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=K2dTe32y4kF8csHn6wb1hcbI0Z5frqIt9bEAjintcG/+wYvrOaf3bOwTQrQywvlO3 Gbmlj6Nxz6dljt9tOtgbN9rwLwxfJSp7Q5JvxcOo6pk6phoanGnVfmVhcFWaMdv2Fp EvLtOua8qL2OaTJJFOLfDh4/oMGVbEU3SVttE1eo= Received: from DLEE108.ent.ti.com (dlee108.ent.ti.com [157.170.170.38]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 01Q9buqo119249 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 26 Feb 2020 03:37:56 -0600 Received: from DLEE103.ent.ti.com (157.170.170.33) by DLEE108.ent.ti.com (157.170.170.38) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3; Wed, 26 Feb 2020 03:37:55 -0600 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE103.ent.ti.com (157.170.170.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3 via Frontend Transport; Wed, 26 Feb 2020 03:37:55 -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 01Q9b4AG110613; Wed, 26 Feb 2020 03:37:52 -0600 From: Pratyush Yadav To: Tudor Ambarus , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mark Brown , Rob Herring , Mark Rutland CC: Pratyush Yadav , , , , , Sekhar Nori Subject: [PATCH v2 11/11] mtd: spi-nor: add support for Cypress Semper flash Date: Wed, 26 Feb 2020 15:07:03 +0530 Message-ID: <20200226093703.19765-12-p.yadav@ti.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200226093703.19765-1-p.yadav@ti.com> References: <20200226093703.19765-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The Cypress Semper flash is an xSPI compliant octal DTR flash. Add support for using it in octal DTR mode. The flash by default boots in a hybrid sector mode. Switch to uniform sector mode on boot. Use the default 20 dummy cycles for a read fast command. The SFDP programming on some older versions of the flash was incorrect. Fixes for that are included in the fixup hooks. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi-nor/spi-nor.c | 191 ++++++++++++++++++++++++++++++++++ include/linux/mtd/spi-nor.h | 14 +++ 2 files changed, 205 insertions(+) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index fdcc1b4abc3f..a01acecaa568 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -260,6 +260,12 @@ struct flash_info { #define JEDEC_MFR(info) ((info)->id[0]) +/* Forward declarations that will be used by s28hs512t_setup(). */ +static int spi_nor_default_setup(struct spi_nor *nor, + const struct spi_nor_hwcaps *hwcaps); +static void spi_nor_set_pp_settings(struct spi_nor_pp_command *pp, + u8 opcode, enum spi_nor_protocol proto); + /** * spi_nor_spimem_setup_op() - Set up common properties of a spi-mem op. * @nor: pointer to a 'struct spi_nor' @@ -2241,6 +2247,64 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) return ret; } +/** + * spi_nor_cypress_octal_enable() - Enable octal DTR mode on Cypress flashes. + * @nor: pointer to a 'struct spi_nor' + * + * This also sets the memory access latency cycles to 20, which is the default + * in the spi-nor framework. + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_cypress_octal_enable(struct spi_nor *nor) +{ + struct spi_mem_op op; + u8 *buf = nor->bouncebuf; + u8 addr_width = 3; + int ret; + + /* Use 20 dummy cycles for memory array reads. */ + ret = spi_nor_write_enable(nor); + if (ret) + return ret; + + *buf = SPINOR_REG_CYPRESS_CFR2V_MEMLAT_8_20; + op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1), + SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR2V, 1), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_OUT(1, buf, 1)); + ret = spi_mem_exec_op(nor->spimem, &op); + if (ret) { + dev_warn(nor->dev, + "failed to set default memory latency value: %d\n", + ret); + return ret; + } + ret = spi_nor_wait_till_ready(nor); + if (ret) + return ret; + + nor->read_dummy = 20; + + /* Set the octal and DTR enable bits. */ + ret = spi_nor_write_enable(nor); + if (ret) + return ret; + + *buf = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN; + op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1), + SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR5V, 1), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_OUT(1, buf, 1)); + ret = spi_mem_exec_op(nor->spimem, &op); + if (ret) { + dev_warn(nor->dev, "Failed to enable octal DTR mode\n"); + return ret; + } + + return 0; +} + /** * spi_nor_sr1_bit6_quad_enable() - Set the Quad Enable BIT(6) in the Status * Register 1. @@ -2453,6 +2517,130 @@ static struct spi_nor_fixups gd25q256_fixups = { .default_init = gd25q256_default_init, }; +static int s28hs512t_setup(struct spi_nor *nor, + const struct spi_nor_hwcaps *hwcaps) +{ + struct spi_mem_op op; + u8 *buf = nor->bouncebuf; + u8 addr_width = 3; + int ret; + + if (!nor->spimem) { + dev_err(nor->dev, + "operation not supported for non-spimem drivers\n"); + return -ENOTSUPP; + } + + /* + * This Cypress flash also supports hybrid sector sizes. Make sure + * uniform sector mode is selected. This is done by setting the bit + * CFR3N[3]. + */ + op = (struct spi_mem_op) + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 1), + SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR3N, 1), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_IN(1, buf, 1)); + ret = spi_mem_exec_op(nor->spimem, &op); + if (ret) + return ret; + + ret = spi_nor_write_enable(nor); + if (ret) + return ret; + + /* Set the uniform sector mode bit. */ + *buf |= SPINOR_REG_CYPRESS_CFR3N_UNISECT; + op = (struct spi_mem_op) + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1), + SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR3N, 1), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_OUT(1, buf, 1)); + ret = spi_mem_exec_op(nor->spimem, &op); + if (ret) { + dev_err(nor->dev, "Failed to change to uniform sector mode\n"); + return ret; + } + + ret = spi_nor_wait_till_ready(nor); + if (ret) + return ret; + + return spi_nor_default_setup(nor, hwcaps); +} + +static void s28hs512t_default_init(struct spi_nor *nor) +{ + nor->params.octal_dtr_enable = spi_nor_cypress_octal_enable; + nor->params.setup = s28hs512t_setup; +} + +static void s28hs512t_post_sfdp_fixup(struct spi_nor *nor) +{ + /* + * On older versions of the flash the xSPI Profile 1.0 table has the + * 8D-8D-8D Fast Read opcode as 0x00. But it actually should be 0xEE. + */ + if (nor->params.reads[SNOR_CMD_READ_8_8_8_DTR].opcode == 0) + nor->params.reads[SNOR_CMD_READ_8_8_8_DTR].opcode = + SPINOR_OP_CYPRESS_RD_FAST; + + /* This flash is also missing the 4-byte Page Program opcode bit. */ + spi_nor_set_pp_settings(&nor->params.page_programs[SNOR_CMD_PP], + SPINOR_OP_PP_4B, SNOR_PROTO_1_1_1); + /* + * Since xSPI Page Program opcode is backward compatible with + * Legacy SPI, use Legacy SPI opcode there as well. + */ + spi_nor_set_pp_settings(&nor->params.page_programs[SNOR_CMD_PP_8_8_8_DTR], + SPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR); + + /* + * The xSPI Profile 1.0 table advertises the number of additional + * address bytes needed for Read Status Register command as 0 but the + * actual value for that is 4. + */ + nor->params.rdsr_addr_nbytes = 4; +} + +static int s28hs512t_post_bfpt_fixup(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt, + struct spi_nor_flash_parameter *params) +{ + struct spi_mem_op op; + u8 *buf = nor->bouncebuf; + u8 addr_width = 3; + int ret; + + /* + * The BFPT table advertises a 512B page size but the page size is + * actually configurable (with the default being 256B). Read from + * CFR3V[4] and set the correct size. + */ + op = (struct spi_mem_op) + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 1), + SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR3V, 1), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_IN(1, buf, 1)); + ret = spi_mem_exec_op(nor->spimem, &op); + if (ret) + return ret; + + if (*buf & SPINOR_REG_CYPRESS_CFR3V_PGSZ) + params->page_size = 512; + else + params->page_size = 256; + + return 0; +} + +static struct spi_nor_fixups s28hs512t_fixups = { + .default_init = s28hs512t_default_init, + .post_sfdp = s28hs512t_post_sfdp_fixup, + .post_bfpt = s28hs512t_post_bfpt_fixup, +}; + /* NOTE: double check command sets and memory organization when you add * more nor chips. This current list focusses on newer chips, which * have been converging on command sets which including JEDEC ID. @@ -2715,6 +2903,9 @@ static const struct flash_info spi_nor_ids[] = { { "s25fl064l", INFO(0x016017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, { "s25fl128l", INFO(0x016018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, { "s25fl256l", INFO(0x016019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, + { "s28hs512t", INFO(0x345b1a, 0, 256 * 1024, 256, SECT_4K | SPI_NOR_OCTAL_DTR_READ) + .fixups = &s28hs512t_fixups, + }, /* SST -- large erase sizes are "overlays", "sectors" are 4K */ { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index c653f6713cfc..e765272fc0f4 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -150,6 +150,20 @@ #define SR2_QUAD_EN_BIT1 BIT(1) #define SR2_QUAD_EN_BIT7 BIT(7) +/* For Cypress flash. */ +#define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */ +#define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */ +#define SPINOR_REG_CYPRESS_CFR2V 0x00800003 +#define SPINOR_REG_CYPRESS_CFR2V_MEMLAT_8_20 0x8 +#define SPINOR_REG_CYPRESS_CFR3N 0x00000004 +#define SPINOR_REG_CYPRESS_CFR3V 0x00800004 +#define SPINOR_REG_CYPRESS_CFR3V_PGSZ BIT(4) /* Page size. */ +#define SPINOR_REG_CYPRESS_CFR3N_UNISECT BIT(3) /* Uniform sector mode */ +#define SPINOR_REG_CYPRESS_CFR4V 0x00800005 +#define SPINOR_REG_CYPRESS_CFR5V 0x00800006 +#define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN 0x3 +#define SPINOR_OP_CYPRESS_RD_FAST 0xee + /* Supported SPI protocols */ #define SNOR_PROTO_INST_MASK GENMASK(23, 16) #define SNOR_PROTO_INST_SHIFT 16