From patchwork Fri Jun 25 19:17:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497395 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=xy7/+wUA; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRbs3YjYz9sW6 for ; Sat, 26 Jun 2021 05:18:00 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id A419C82C13; Fri, 25 Jun 2021 21:17:45 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="xy7/+wUA"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 82D9282C09; Fri, 25 Jun 2021 21:17:41 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id F263E82C03 for ; Fri, 25 Jun 2021 21:17:37 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJHadi078259; Fri, 25 Jun 2021 14:17:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648656; bh=Q3D5fXVQIwK+nTF8kIsH+UDkkjlugLwaIocrv26NLp0=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=xy7/+wUA2w58F6ZPTPq/848clYd+PcdU/tNfh3HrgzjTo1UwYfnyQ4rwOGR0cRUDL zE78XNh9Pkufg1LOC6IVgu1bmaWeyliRp+uvZc0al4weqzEwjd9+KTkBqUy9CIlkSe tdmXldfB6nM7AiDLyT+nEbjX003wQpSSjMNH9VqI= Received: from DFLE104.ent.ti.com (dfle104.ent.ti.com [10.64.6.25]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJHaVZ023085 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:17:36 -0500 Received: from DFLE112.ent.ti.com (10.64.6.33) by DFLE104.ent.ti.com (10.64.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2; Fri, 25 Jun 2021 14:17:36 -0500 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:17:36 -0500 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 15PJHURH076530; Fri, 25 Jun 2021 14:17:33 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 01/27] spi: spi-mem: allow specifying whether an op is DTR or not Date: Sat, 26 Jun 2021 00:47:03 +0530 Message-ID: <20210625191729.31798-2-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Each phase is given a separate 'dtr' field so mixed protocols like 4S-4D-4D can be supported. Signed-off-by: Pratyush Yadav --- drivers/spi/spi-mem.c | 3 +++ include/spi-mem.h | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index c095ae9505..427f7c13c5 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -164,6 +164,9 @@ bool spi_mem_default_supports_op(struct spi_slave *slave, op->data.dir == SPI_MEM_DATA_OUT)) return false; + if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr) + return false; + return true; } EXPORT_SYMBOL_GPL(spi_mem_default_supports_op); diff --git a/include/spi-mem.h b/include/spi-mem.h index e354c38897..8bd4459674 100644 --- a/include/spi-mem.h +++ b/include/spi-mem.h @@ -71,6 +71,7 @@ enum spi_mem_data_dir { * 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.dtr: whether the command opcode should be sent in DTR mode or not * @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 @@ -78,10 +79,13 @@ enum spi_mem_data_dir { * Note that only @addr.nbytes are taken into account in this * address value, so users should make sure the value fits in the * assigned number of bytes. + * @addr.dtr: whether the address should be sent in DTR mode or not * @dummy.nbytes: number of dummy bytes to send after an opcode or address. Can * be zero if the operation does not require dummy bytes * @dummy.buswidth: number of IO lanes used to transmit the dummy bytes + * @dummy.dtr: whether the dummy bytes should be sent in DTR mode or not * @data.buswidth: number of IO lanes used to send/receive the data + * @data.dtr: whether the data should be sent in DTR mode or not * @data.dir: direction of the transfer * @data.buf.in: input buffer * @data.buf.out: output buffer @@ -90,21 +94,25 @@ struct spi_mem_op { struct { u8 buswidth; u8 opcode; + u8 dtr : 1; } cmd; struct { u8 nbytes; u8 buswidth; + u8 dtr : 1; u64 val; } addr; struct { u8 nbytes; u8 buswidth; + u8 dtr : 1; } dummy; struct { u8 buswidth; + u8 dtr : 1; enum spi_mem_data_dir dir; unsigned int nbytes; /* buf.{in,out} must be DMA-able. */ From patchwork Fri Jun 25 19:17:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497397 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=mm8MU1Vt; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRcD4PVvz9sW8 for ; Sat, 26 Jun 2021 05:18:20 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 6ED1F82C1C; Fri, 25 Jun 2021 21:17:58 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="mm8MU1Vt"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 5EAB682C15; Fri, 25 Jun 2021 21:17:48 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 2042882BF4 for ; Fri, 25 Jun 2021 21:17:41 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJHe1f078286; Fri, 25 Jun 2021 14:17:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648660; bh=mAKFx6htHB7aXFi+HxNMtrTALLApKDlPR+Wi+NlK8S4=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=mm8MU1Vtu/Drd0RIEfeJP/R3PBtIzH/mFKxLpUtQXxi+SA9c+hI1kDzrLrA/XIwaF yUhgRsuayIZAZbHZ/Ip4hkITMJUlChVjxHfBjkN57IvsDDFHx9tHfw9evkvRwOvROl ItaZtm1fcj3rHiJrja5CDXsR4ifaj9Gx4iDV733g= Received: from DLEE103.ent.ti.com (dlee103.ent.ti.com [157.170.170.33]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJHeqk048416 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:17:40 -0500 Received: from DLEE111.ent.ti.com (157.170.170.22) 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.2176.2; Fri, 25 Jun 2021 14:17:38 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE111.ent.ti.com (157.170.170.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:17:38 -0500 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 15PJHURI076530; Fri, 25 Jun 2021 14:17:36 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 02/27] spi: spi-mem: allow specifying a command's extension Date: Sat, 26 Jun 2021 00:47:04 +0530 Message-ID: <20210625191729.31798-3-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean 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. So, make opcode a 16-bit value and add a 'nbytes', similar to how multiple address widths are handled. All usages of sizeof(op->cmd.opcode) also need to be changed to be op->cmd.nbytes because that is the actual indicator of opcode size. Signed-off-by: Pratyush Yadav --- drivers/spi/mtk_snfi_spi.c | 3 +-- drivers/spi/spi-mem-nodm.c | 4 ++-- drivers/spi/spi-mem.c | 13 +++++++------ include/spi-mem.h | 6 +++++- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/spi/mtk_snfi_spi.c b/drivers/spi/mtk_snfi_spi.c index b6ab5fa3ad..65d0ce0981 100644 --- a/drivers/spi/mtk_snfi_spi.c +++ b/drivers/spi/mtk_snfi_spi.c @@ -64,8 +64,7 @@ static int mtk_snfi_adjust_op_size(struct spi_slave *slave, * or the output+input data must not exceed the GPRAM size. */ - nbytes = sizeof(op->cmd.opcode) + op->addr.nbytes + - op->dummy.nbytes; + nbytes = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes; if (nbytes + op->data.nbytes <= SNFI_GPRAM_SIZE) return 0; diff --git a/drivers/spi/spi-mem-nodm.c b/drivers/spi/spi-mem-nodm.c index 765f05fe54..db54101383 100644 --- a/drivers/spi/spi-mem-nodm.c +++ b/drivers/spi/spi-mem-nodm.c @@ -27,7 +27,7 @@ int spi_mem_exec_op(struct spi_slave *slave, tx_buf = op->data.buf.out; } - op_len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes; + op_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes; op_buf = calloc(1, op_len); ret = spi_claim_bus(slave); @@ -89,7 +89,7 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, { unsigned int len; - len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes; + len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes; if (slave->max_write_size && len > slave->max_write_size) return -EINVAL; diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 427f7c13c5..541cd0e5a7 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -167,6 +167,9 @@ bool spi_mem_default_supports_op(struct spi_slave *slave, if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr) return false; + if (op->cmd.nbytes != 1) + return false; + return true; } EXPORT_SYMBOL_GPL(spi_mem_default_supports_op); @@ -273,8 +276,7 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) } #ifndef __UBOOT__ - tmpbufsize = sizeof(op->cmd.opcode) + op->addr.nbytes + - op->dummy.nbytes; + tmpbufsize = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes; /* * Allocate a buffer to transmit the CMD, ADDR cycles with kmalloc() so @@ -289,7 +291,7 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) tmpbuf[0] = op->cmd.opcode; xfers[xferpos].tx_buf = tmpbuf; - xfers[xferpos].len = sizeof(op->cmd.opcode); + xfers[xferpos].len = op->cmd.nbytes; xfers[xferpos].tx_nbits = op->cmd.buswidth; spi_message_add_tail(&xfers[xferpos], &msg); xferpos++; @@ -353,7 +355,7 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) tx_buf = op->data.buf.out; } - op_len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes; + op_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes; /* * Avoid using malloc() here so that we can use this code in SPL where @@ -442,8 +444,7 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, struct spi_mem_op *op) if (!ops->mem_ops || !ops->mem_ops->exec_op) { unsigned int len; - len = sizeof(op->cmd.opcode) + op->addr.nbytes + - op->dummy.nbytes; + len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes; if (slave->max_write_size && len > slave->max_write_size) return -EINVAL; diff --git a/include/spi-mem.h b/include/spi-mem.h index 8bd4459674..fe249f77ba 100644 --- a/include/spi-mem.h +++ b/include/spi-mem.h @@ -17,6 +17,7 @@ struct udevice; { \ .buswidth = __buswidth, \ .opcode = __opcode, \ + .nbytes = 1, \ } #define SPI_MEM_OP_ADDR(__nbytes, __val, __buswidth) \ @@ -69,6 +70,8 @@ enum spi_mem_data_dir { /** * struct spi_mem_op - describes a SPI memory operation + * @cmd.nbytes: number of opcode bytes (only 1 or 2 are valid). The opcode is + * sent MSB-first. * @cmd.buswidth: number of IO lines used to transmit the command * @cmd.opcode: operation opcode * @cmd.dtr: whether the command opcode should be sent in DTR mode or not @@ -92,9 +95,10 @@ enum spi_mem_data_dir { */ struct spi_mem_op { struct { + u8 nbytes; u8 buswidth; - u8 opcode; u8 dtr : 1; + u16 opcode; } cmd; struct { From patchwork Fri Jun 25 19:17:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497396 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=YvnTDEG5; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRc14CQrz9sW8 for ; Sat, 26 Jun 2021 05:18:09 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id A62FB82C0A; Fri, 25 Jun 2021 21:17:54 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="YvnTDEG5"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D911C82C1A; Fri, 25 Jun 2021 21:17:46 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 5815882C0F for ; Fri, 25 Jun 2021 21:17:43 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJHf7P078291; Fri, 25 Jun 2021 14:17:41 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648661; bh=cc1+D8qQveGRVhqWcuiw47h+3I2vYXfa4aOiZdibED0=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=YvnTDEG5TmaioMknubXCRQGCOTS484bM5WAj9Q5+HiHZsdaxeRbF6YfbD4LxoqSXH dXBHoUDJc84U7BWVf9G/CPSZJRK+caS3cEXE2cx69ADUkydXNk2rjkviUpUrz6gcNW 5RI74fTOTmJr9S0tKFyVAmNqTHZTuTNKi9AkT+lM= 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 15PJHfdI048442 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:17:41 -0500 Received: from DLEE103.ent.ti.com (157.170.170.33) 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.2176.2; Fri, 25 Jun 2021 14:17:41 -0500 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:17:41 -0500 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 15PJHURJ076530; Fri, 25 Jun 2021 14:17:39 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 03/27] spi: spi-mem: export spi_mem_default_supports_op() Date: Sat, 26 Jun 2021 00:47:05 +0530 Message-ID: <20210625191729.31798-4-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Controllers can use this function to perform basic sanity checking on the spi-mem op. Reviewed-by: Sean Anderson Signed-off-by: Pratyush Yadav --- include/spi-mem.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/spi-mem.h b/include/spi-mem.h index fe249f77ba..de3c11c8e2 100644 --- a/include/spi-mem.h +++ b/include/spi-mem.h @@ -250,6 +250,9 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, struct spi_mem_op *op); bool spi_mem_supports_op(struct spi_slave *slave, const struct spi_mem_op *op); +bool spi_mem_default_supports_op(struct spi_slave *slave, + const struct spi_mem_op *op); + int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op); bool spi_mem_default_supports_op(struct spi_slave *mem, From patchwork Fri Jun 25 19:17:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497398 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=o6B7ggeS; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRcS5K5nz9sW8 for ; Sat, 26 Jun 2021 05:18:32 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 6DCFF82C2C; Fri, 25 Jun 2021 21:18:01 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="o6B7ggeS"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 26C2282C1D; Fri, 25 Jun 2021 21:17:51 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id D913882C14 for ; Fri, 25 Jun 2021 21:17:45 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJHigS128371; Fri, 25 Jun 2021 14:17:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648664; bh=Sr9l9ACaKz9AG+74SwFQVSPhzsGTXQQMU6LLx1L3YAY=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=o6B7ggeSJ4g3WI7LeGztMhsRG6dsrexcv+vpnvhs4Kib+BHtzO/A0oX3QJGk+ta9/ baDPo9aAgmBYEnoo+wBBXKxwqwnX1OBJGiB7DJ4DdcHCMaS4qJyGNeQCNJzC5thHA3 FEI/h3YatAlN91Pj7ubmUfptffkM3W22G1hRNTbY= Received: from DLEE108.ent.ti.com (dlee108.ent.ti.com [157.170.170.38]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJHiPT023154 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:17:44 -0500 Received: from DLEE112.ent.ti.com (157.170.170.23) 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.2176.2; Fri, 25 Jun 2021 14:17:43 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:17:44 -0500 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 15PJHURK076530; Fri, 25 Jun 2021 14:17:41 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 04/27] spi: spi-mem: add spi_mem_dtr_supports_op() Date: Sat, 26 Jun 2021 00:47:06 +0530 Message-ID: <20210625191729.31798-5-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean spi_mem_default_supports_op() rejects DTR ops by default to ensure that the controller drivers that haven't been updated with DTR support continue to reject them. It also makes sure that controllers that don't support DTR mode at all (which is most of them at the moment) also reject them. This means that controller drivers that want to support DTR mode can't use spi_mem_default_supports_op(). Driver authors have to roll their own supports_op() function and mimic the buswidth checks. Or even worse, driver authors might skip it completely or get it wrong. Add spi_mem_dtr_supports_op(). It provides a basic sanity check for DTR ops and performs the buswidth requirement check. Move the logic for checking buswidth in spi_mem_default_supports_op() to a separate function so the logic is not repeated twice. Signed-off-by: Pratyush Yadav --- drivers/spi/spi-mem.c | 32 +++++++++++++++++++++++++++++--- include/spi-mem.h | 2 ++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 541cd0e5a7..9c1ede1b61 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -145,8 +145,8 @@ static int spi_check_buswidth_req(struct spi_slave *slave, u8 buswidth, bool tx) return -ENOTSUPP; } -bool spi_mem_default_supports_op(struct spi_slave *slave, - const struct spi_mem_op *op) +static bool spi_mem_check_buswidth(struct spi_slave *slave, + const struct spi_mem_op *op) { if (spi_check_buswidth_req(slave, op->cmd.buswidth, true)) return false; @@ -164,13 +164,39 @@ bool spi_mem_default_supports_op(struct spi_slave *slave, op->data.dir == SPI_MEM_DATA_OUT)) return false; + return true; +} + +bool spi_mem_dtr_supports_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + if (op->cmd.buswidth == 8 && op->cmd.nbytes % 2) + return false; + + if (op->addr.nbytes && op->addr.buswidth == 8 && op->addr.nbytes % 2) + return false; + + if (op->dummy.nbytes && op->dummy.buswidth == 8 && op->dummy.nbytes % 2) + return false; + + if (op->data.dir != SPI_MEM_NO_DATA && + op->dummy.buswidth == 8 && op->data.nbytes % 2) + return false; + + return spi_mem_check_buswidth(slave, op); +} +EXPORT_SYMBOL_GPL(spi_mem_dtr_supports_op); + +bool spi_mem_default_supports_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr) return false; if (op->cmd.nbytes != 1) return false; - return true; + return spi_mem_check_buswidth(slave, op); } EXPORT_SYMBOL_GPL(spi_mem_default_supports_op); diff --git a/include/spi-mem.h b/include/spi-mem.h index de3c11c8e2..32ffdc2e0f 100644 --- a/include/spi-mem.h +++ b/include/spi-mem.h @@ -249,6 +249,8 @@ spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr, int spi_mem_adjust_op_size(struct spi_slave *slave, struct spi_mem_op *op); bool spi_mem_supports_op(struct spi_slave *slave, const struct spi_mem_op *op); +bool spi_mem_dtr_supports_op(struct spi_slave *slave, + const struct spi_mem_op *op); bool spi_mem_default_supports_op(struct spi_slave *slave, const struct spi_mem_op *op); From patchwork Fri Jun 25 19:17:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497399 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=ReFAMje0; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRcj1BYvz9sW8 for ; Sat, 26 Jun 2021 05:18:45 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E772282C28; Fri, 25 Jun 2021 21:18:15 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="ReFAMje0"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 29D5282C1F; Fri, 25 Jun 2021 21:17:53 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id BFE7D82C0F for ; Fri, 25 Jun 2021 21:17:48 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJHlvk078311; Fri, 25 Jun 2021 14:17:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648667; bh=ogyVxZEHaugC8MdH/vgfaKgza12zqzh24WkLl1mlN5s=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=ReFAMje0ljPxQo5dI4G/ANXBrceiRGwFOr9I8Gp51PNvc4J19vNsOCOWmzgFVQyes bce2OYTeNqxZsAs77IwTSS/MqdobbYegCVAaKlGYF563MZzLdgJmkdBQP3mFWAUHdP qxDR0Qv2gCy60Krm4PqTdpxD5Yd3dNd8CgPt2kQw= Received: from DFLE113.ent.ti.com (dfle113.ent.ti.com [10.64.6.34]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJHko4062925 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:17:46 -0500 Received: from DFLE100.ent.ti.com (10.64.6.21) 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.2176.2; Fri, 25 Jun 2021 14:17:46 -0500 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:17:46 -0500 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 15PJHURL076530; Fri, 25 Jun 2021 14:17:44 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 05/27] spi: cadence-qspi: Do not calibrate when device tree sets read delay Date: Sat, 26 Jun 2021 00:47:07 +0530 Message-ID: <20210625191729.31798-6-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean If the device tree provides a read delay value, use that directly and do not perform the calibration procedure. This allows the device tree to over-ride the read delay value in cases where the read delay value obtained via calibration is incorrect. One such example is the Cypress Semper flash. It needs a read delay of 4 in octal DTR mode. But since the calibration procedure is run before the flash is switched in octal DTR mode, it yields a read delay of 2. A value of 4 works for both octal DTR and legacy modes. Signed-off-by: Pratyush Yadav --- drivers/spi/cadence_qspi.c | 26 +++++++++++++++++++++----- drivers/spi/cadence_qspi.h | 1 + 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index 67980431ba..de7628de27 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -141,12 +141,20 @@ static int cadence_spi_set_speed(struct udevice *bus, uint hz) cadence_qspi_apb_controller_disable(priv->regbase); /* - * Calibration required for different current SCLK speed, requested - * SCLK speed or chip select + * If the device tree already provides a read delay value, use that + * instead of calibrating. */ - if (priv->previous_hz != hz || - priv->qspi_calibrated_hz != hz || - priv->qspi_calibrated_cs != spi_chip_select(bus)) { + if (plat->read_delay >= 0) { + cadence_spi_write_speed(bus, hz); + cadence_qspi_apb_readdata_capture(priv->regbase, 1, + plat->read_delay); + } else if (priv->previous_hz != hz || + priv->qspi_calibrated_hz != hz || + priv->qspi_calibrated_cs != spi_chip_select(bus)) { + /* + * Calibration required for different current SCLK speed, + * requested SCLK speed or chip select + */ err = spi_calibration(bus, hz); if (err) return err; @@ -320,6 +328,14 @@ static int cadence_spi_of_to_plat(struct udevice *bus) 255); plat->tchsh_ns = ofnode_read_u32_default(subnode, "cdns,tchsh-ns", 20); plat->tslch_ns = ofnode_read_u32_default(subnode, "cdns,tslch-ns", 20); + /* + * Read delay should be an unsigned value but we use a signed integer + * so that negative values can indicate that the device tree did not + * specify any signed values and we need to perform the calibration + * sequence to find it out. + */ + plat->read_delay = ofnode_read_s32_default(subnode, "cdns,read-delay", + -1); debug("%s: regbase=%p ahbbase=%p max-frequency=%d page-size=%d\n", __func__, plat->regbase, plat->ahbbase, plat->max_hz, diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index 64c5867609..b06d7750e2 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -26,6 +26,7 @@ struct cadence_spi_plat { u32 trigger_address; fdt_addr_t ahbsize; bool use_dac_mode; + int read_delay; /* Flash parameters */ u32 page_size; From patchwork Fri Jun 25 19:17:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497400 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=H0Bf1/S6; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRcx0BLzz9sW8 for ; Sat, 26 Jun 2021 05:18:56 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5B28B82C2F; Fri, 25 Jun 2021 21:18:20 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="H0Bf1/S6"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id BEA5382C14; Fri, 25 Jun 2021 21:17:56 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 2931582C14 for ; Fri, 25 Jun 2021 21:17:51 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJHnFn128395; Fri, 25 Jun 2021 14:17:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648669; bh=RReUGtGpNnNXCc0ZMLSDsReheXlQwCHWX+DRZvoinoc=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=H0Bf1/S65QMxKQPe17Ng5AycNwAAyCXaQ7M9bBVLGH0MD0ej/wAWBfaOBTI2uyMNu yaaX4Tlo4F7Ka4dSAUY6X2ucDNJ1sgGl93GgQwAIGUe006sipk3RS19djRBhcnRsio GMRfdSj8BMd+9mO6l7Z5t5laljBZ98OG2FQm0Gug= 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 15PJHnvw122930 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:17:49 -0500 Received: from DFLE102.ent.ti.com (10.64.6.23) 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.2176.2; Fri, 25 Jun 2021 14:17:49 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DFLE102.ent.ti.com (10.64.6.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:17:49 -0500 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 15PJHURM076530; Fri, 25 Jun 2021 14:17:47 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 06/27] spi: cadence-qspi: Add a small delay before indirect writes Date: Sat, 26 Jun 2021 00:47:08 +0530 Message-ID: <20210625191729.31798-7-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Once the start bit is toggled it takes a small amount of time before it is internally synchronized. This means we can't start writing during that part. So add a small delay to allow the bit to be synchronized. Signed-off-by: Pratyush Yadav --- drivers/spi/cadence_qspi.c | 4 ++++ drivers/spi/cadence_qspi.h | 1 + drivers/spi/cadence_qspi_apb.c | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index de7628de27..a961193cdc 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -20,6 +20,8 @@ #include #include "cadence_qspi.h" +#define NSEC_PER_SEC 1000000000L + #define CQSPI_STIG_READ 0 #define CQSPI_STIG_WRITE 1 #define CQSPI_READ 2 @@ -208,6 +210,8 @@ static int cadence_spi_probe(struct udevice *bus) priv->qspi_is_init = 1; } + plat->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC, plat->ref_clk_hz); + return 0; } diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index b06d7750e2..5c745541a6 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -27,6 +27,7 @@ struct cadence_spi_plat { fdt_addr_t ahbsize; bool use_dac_mode; int read_delay; + u32 wr_delay; /* Flash parameters */ u32 page_size; diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index b051f462ed..92e57730bd 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -730,6 +730,12 @@ cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat, writel(CQSPI_REG_INDIRECTWR_START, plat->regbase + CQSPI_REG_INDIRECTWR); + /* + * Some delay is required for the above bit to be internally + * synchronized by the QSPI module. + */ + ndelay(plat->wr_delay); + while (remaining > 0) { write_bytes = remaining > page_size ? page_size : remaining; writesl(plat->ahbbase, bb_txbuf, write_bytes >> 2); From patchwork Fri Jun 25 19:17:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497402 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=H7/nNra7; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRdP39vVz9sW8 for ; Sat, 26 Jun 2021 05:19:21 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 2C58382C27; Fri, 25 Jun 2021 21:18:28 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="H7/nNra7"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 70A4A82C2D; Fri, 25 Jun 2021 21:18:03 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id CFBB782C1D for ; Fri, 25 Jun 2021 21:17:53 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJHqUU078336; Fri, 25 Jun 2021 14:17:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648672; bh=mQTT0m53SH1msRzEvpANldw+6hkLpRZtyYMfk6DUpTQ=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=H7/nNra7DlYhx3wxspiQTqkwDhKyaFc+XJ8DYn6siptxG5rIMahP705/PvnsUYeTc jdqoySBf/dIXMAZvldB7TPRHly/T+Q1/pWVBjQvjnxh/d6i9GbXGvrz2Iw30HDXqrS bCQWsMuoeRUgvcj/MvcnQAsPpHjjNKkpYNNfv0Bg= Received: from DFLE100.ent.ti.com (dfle100.ent.ti.com [10.64.6.21]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJHqeA048520 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:17:52 -0500 Received: from DFLE108.ent.ti.com (10.64.6.29) 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.2176.2; Fri, 25 Jun 2021 14:17:51 -0500 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:17:52 -0500 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 15PJHURN076530; Fri, 25 Jun 2021 14:17:49 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 07/27] spi: cadence-qspi: Add support for octal DTR flashes Date: Sat, 26 Jun 2021 00:47:09 +0530 Message-ID: <20210625191729.31798-8-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Set up opcode extension and enable/disable DTR mode based on whether the command is DTR or not. xSPI flashes can have a 4-byte dummy address associated with some commands like the Read Status Register command in octal DTR mode. Since the flash does not support sending the dummy address, we can not use automatic write completion polling in DTR mode. Further, no write completion polling makes it impossible to use DAC mode for DTR writes. In that mode, the controller does not know beforehand how long a write will be and so it can de-assert Chip Select (CS#) at any time. Once CS# is de-assert, the flash will go into burning phase. But since the controller does not do write completion polling, it does not know when the flash is busy and might send in writes while the flash is not ready. So, disable write completion polling and make writes go through indirect mode for DTR writes and let spi-mem take care of polling the SR. Signed-off-by: Pratyush Yadav --- drivers/spi/cadence_qspi.c | 39 ++++- drivers/spi/cadence_qspi.h | 14 +- drivers/spi/cadence_qspi_apb.c | 286 ++++++++++++++++++++++++++++++--- 3 files changed, 313 insertions(+), 26 deletions(-) diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index a961193cdc..d1b3808c4d 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -43,20 +43,22 @@ static int cadence_spi_write_speed(struct udevice *bus, uint hz) return 0; } -static int cadence_spi_read_id(void *reg_base, u8 len, u8 *idcode) +static int cadence_spi_read_id(struct cadence_spi_plat *plat, u8 len, + u8 *idcode) { struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0x9F, 1), SPI_MEM_OP_NO_ADDR, SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_IN(len, idcode, 1)); - return cadence_qspi_apb_command_read(reg_base, &op); + return cadence_qspi_apb_command_read(plat, &op); } /* Calibration sequence to determine the read data capture delay register */ static int spi_calibration(struct udevice *bus, uint hz) { struct cadence_spi_priv *priv = dev_get_priv(bus); + struct cadence_spi_plat *plat = dev_get_plat(bus); void *base = priv->regbase; unsigned int idcode = 0, temp = 0; int err = 0, i, range_lo = -1, range_hi = -1; @@ -71,7 +73,7 @@ static int spi_calibration(struct udevice *bus, uint hz) cadence_qspi_apb_controller_enable(base); /* read the ID which will be our golden value */ - err = cadence_spi_read_id(base, 3, (u8 *)&idcode); + err = cadence_spi_read_id(plat, 3, (u8 *)&idcode); if (err) { puts("SF: Calibration failed (read)\n"); return err; @@ -90,7 +92,7 @@ static int spi_calibration(struct udevice *bus, uint hz) cadence_qspi_apb_controller_enable(base); /* issue a RDID to get the ID value */ - err = cadence_spi_read_id(base, 3, (u8 *)&temp); + err = cadence_spi_read_id(plat, 3, (u8 *)&temp); if (err) { puts("SF: Calibration failed (read)\n"); return err; @@ -271,10 +273,14 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi, switch (mode) { case CQSPI_STIG_READ: - err = cadence_qspi_apb_command_read(base, op); + err = cadence_qspi_apb_command_read_setup(plat, op); + if (!err) + err = cadence_qspi_apb_command_read(plat, op); break; case CQSPI_STIG_WRITE: - err = cadence_qspi_apb_command_write(base, op); + err = cadence_qspi_apb_command_write_setup(plat, op); + if (!err) + err = cadence_qspi_apb_command_write(plat, op); break; case CQSPI_READ: err = cadence_qspi_apb_read_setup(plat, op); @@ -294,6 +300,26 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi, return err; } +static bool cadence_spi_mem_supports_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + bool all_true, all_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; + + if (all_true) + return spi_mem_dtr_supports_op(slave, op); + else + return spi_mem_default_supports_op(slave, op); +} + static int cadence_spi_of_to_plat(struct udevice *bus) { struct cadence_spi_plat *plat = dev_get_plat(bus); @@ -350,6 +376,7 @@ static int cadence_spi_of_to_plat(struct udevice *bus) static const struct spi_controller_mem_ops cadence_spi_mem_ops = { .exec_op = cadence_spi_mem_exec_op, + .supports_op = cadence_spi_mem_supports_op, }; static const struct dm_spi_ops cadence_spi_ops = { diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index 5c745541a6..49b401168f 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -36,6 +36,12 @@ struct cadence_spi_plat { u32 tsd2d_ns; u32 tchsh_ns; u32 tslch_ns; + + /* Transaction protocol parameters. */ + u8 inst_width; + u8 addr_width; + u8 data_width; + bool dtr; }; struct cadence_spi_priv { @@ -59,9 +65,13 @@ void cadence_qspi_apb_controller_enable(void *reg_base_addr); void cadence_qspi_apb_controller_disable(void *reg_base_addr); void cadence_qspi_apb_dac_mode_enable(void *reg_base); -int cadence_qspi_apb_command_read(void *reg_base_addr, +int cadence_qspi_apb_command_read_setup(struct cadence_spi_plat *plat, + const struct spi_mem_op *op); +int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat, const struct spi_mem_op *op); -int cadence_qspi_apb_command_write(void *reg_base_addr, +int cadence_qspi_apb_command_write_setup(struct cadence_spi_plat *plat, + const struct spi_mem_op *op); +int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat, const struct spi_mem_op *op); int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat, diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index 92e57730bd..c36a652211 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -51,7 +51,7 @@ #define CQSPI_STIG_DATA_LEN_MAX 8 #define CQSPI_DUMMY_CLKS_PER_BYTE 8 -#define CQSPI_DUMMY_BYTES_MAX 4 +#define CQSPI_DUMMY_CLKS_MAX 31 /**************************************************************************** * Controller's configuration and status register (offset from QSPI_BASE) @@ -65,6 +65,8 @@ #define CQSPI_REG_CONFIG_XIP_IMM BIT(18) #define CQSPI_REG_CONFIG_CHIPSELECT_LSB 10 #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 @@ -83,6 +85,7 @@ #define CQSPI_REG_WR_INSTR 0x08 #define CQSPI_REG_WR_INSTR_OPCODE_LSB 0 +#define CQSPI_REG_WR_INSTR_TYPE_ADDR_LSB 12 #define CQSPI_REG_WR_INSTR_TYPE_DATA_LSB 16 #define CQSPI_REG_DELAY 0x0C @@ -120,6 +123,9 @@ #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 @@ -166,6 +172,11 @@ #define CQSPI_REG_CMDWRITEDATALOWER 0xA8 #define CQSPI_REG_CMDWRITEDATAUPPER 0xAC +#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 + #define CQSPI_REG_IS_IDLE(base) \ ((readl(base + CQSPI_REG_CONFIG) >> \ CQSPI_REG_CONFIG_IDLE_LSB) & 0x1) @@ -203,6 +214,75 @@ void cadence_qspi_apb_dac_mode_enable(void *reg_base) writel(reg, reg_base + CQSPI_REG_CONFIG); } +static unsigned int cadence_qspi_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 u32 cadence_qspi_calc_rdreg(struct cadence_spi_plat *plat) +{ + u32 rdreg = 0; + + rdreg |= plat->inst_width << CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB; + rdreg |= plat->addr_width << CQSPI_REG_RD_INSTR_TYPE_ADDR_LSB; + rdreg |= plat->data_width << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB; + + return rdreg; +} + +static int cadence_qspi_buswidth_to_inst_type(u8 buswidth) +{ + switch (buswidth) { + case 0: + case 1: + return CQSPI_INST_TYPE_SINGLE; + + case 2: + return CQSPI_INST_TYPE_DUAL; + + case 4: + return CQSPI_INST_TYPE_QUAD; + + case 8: + return CQSPI_INST_TYPE_OCTAL; + + default: + return -ENOTSUPP; + } +} + +static int cadence_qspi_set_protocol(struct cadence_spi_plat *plat, + const struct spi_mem_op *op) +{ + int ret; + + plat->dtr = op->data.dtr && op->cmd.dtr && op->addr.dtr; + + ret = cadence_qspi_buswidth_to_inst_type(op->cmd.buswidth); + if (ret < 0) + return ret; + plat->inst_width = ret; + + ret = cadence_qspi_buswidth_to_inst_type(op->addr.buswidth); + if (ret < 0) + return ret; + plat->addr_width = ret; + + ret = cadence_qspi_buswidth_to_inst_type(op->data.buswidth); + if (ret < 0) + return ret; + plat->data_width = ret; + + return 0; +} + /* Return 1 if idle, otherwise return 0 (busy). */ static unsigned int cadence_qspi_wait_idle(void *reg_base) { @@ -434,21 +514,109 @@ static int cadence_qspi_apb_exec_flash_cmd(void *reg_base, return 0; } +static int cadence_qspi_setup_opcode_ext(struct cadence_spi_plat *plat, + const struct spi_mem_op *op, + unsigned int shift) +{ + unsigned int reg; + u8 ext; + + if (op->cmd.nbytes != 2) + return -EINVAL; + + /* Opcode extension is the LSB. */ + ext = op->cmd.opcode & 0xff; + + reg = readl(plat->regbase + CQSPI_REG_OP_EXT_LOWER); + reg &= ~(0xff << shift); + reg |= ext << shift; + writel(reg, plat->regbase + CQSPI_REG_OP_EXT_LOWER); + + return 0; +} + +static int cadence_qspi_enable_dtr(struct cadence_spi_plat *plat, + const struct spi_mem_op *op, + unsigned int shift, + bool enable) +{ + unsigned int reg; + int ret; + + reg = readl(plat->regbase + CQSPI_REG_CONFIG); + + if (enable) { + reg |= CQSPI_REG_CONFIG_DTR_PROTO; + reg |= CQSPI_REG_CONFIG_DUAL_OPCODE; + + /* Set up command opcode extension. */ + ret = cadence_qspi_setup_opcode_ext(plat, op, shift); + if (ret) + return ret; + } else { + reg &= ~CQSPI_REG_CONFIG_DTR_PROTO; + reg &= ~CQSPI_REG_CONFIG_DUAL_OPCODE; + } + + writel(reg, plat->regbase + CQSPI_REG_CONFIG); + + return 0; +} + +int cadence_qspi_apb_command_read_setup(struct cadence_spi_plat *plat, + const struct spi_mem_op *op) +{ + int ret; + unsigned int reg; + + ret = cadence_qspi_set_protocol(plat, op); + if (ret) + return ret; + + ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_STIG_LSB, + plat->dtr); + if (ret) + return ret; + + reg = cadence_qspi_calc_rdreg(plat); + writel(reg, plat->regbase + CQSPI_REG_RD_INSTR); + + return 0; +} + /* For command RDID, RDSR. */ -int cadence_qspi_apb_command_read(void *reg_base, const struct spi_mem_op *op) +int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat, + const struct spi_mem_op *op) { + void *reg_base = plat->regbase; unsigned int reg; unsigned int read_len; int status; unsigned int rxlen = op->data.nbytes; void *rxbuf = op->data.buf.in; + unsigned int dummy_clk; + u8 opcode; if (rxlen > CQSPI_STIG_DATA_LEN_MAX || !rxbuf) { printf("QSPI: Invalid input arguments rxlen %u\n", rxlen); return -EINVAL; } - reg = op->cmd.opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB; + if (plat->dtr) + opcode = op->cmd.opcode >> 8; + else + opcode = op->cmd.opcode; + + reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB; + + /* Set up dummy cycles. */ + dummy_clk = cadence_qspi_calc_dummy(op, plat->dtr); + if (dummy_clk > CQSPI_DUMMY_CLKS_MAX) + return -ENOTSUPP; + + if (dummy_clk) + reg |= (dummy_clk & CQSPI_REG_CMDCTRL_DUMMY_MASK) + << CQSPI_REG_CMDCTRL_DUMMY_LSB; reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB); @@ -475,15 +643,39 @@ int cadence_qspi_apb_command_read(void *reg_base, const struct spi_mem_op *op) return 0; } +int cadence_qspi_apb_command_write_setup(struct cadence_spi_plat *plat, + const struct spi_mem_op *op) +{ + int ret; + unsigned int reg; + + ret = cadence_qspi_set_protocol(plat, op); + if (ret) + return ret; + + ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_STIG_LSB, + plat->dtr); + if (ret) + return ret; + + reg = cadence_qspi_calc_rdreg(plat); + writel(reg, plat->regbase + CQSPI_REG_RD_INSTR); + + return 0; +} + /* For commands: WRSR, WREN, WRDI, CHIP_ERASE, BE, etc. */ -int cadence_qspi_apb_command_write(void *reg_base, const struct spi_mem_op *op) +int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat, + const struct spi_mem_op *op) { unsigned int reg = 0; unsigned int wr_data; unsigned int wr_len; unsigned int txlen = op->data.nbytes; const void *txbuf = op->data.buf.out; + void *reg_base = plat->regbase; u32 addr; + u8 opcode; /* Reorder address to SPI bus order if only transferring address */ if (!txlen) { @@ -499,7 +691,12 @@ int cadence_qspi_apb_command_write(void *reg_base, const struct spi_mem_op *op) return -EINVAL; } - reg |= op->cmd.opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB; + if (plat->dtr) + opcode = op->cmd.opcode >> 8; + else + opcode = op->cmd.opcode; + + reg |= opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB; if (txlen) { /* writing data = yes */ @@ -533,29 +730,39 @@ int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat, unsigned int rd_reg; unsigned int dummy_clk; unsigned int dummy_bytes = op->dummy.nbytes; + int ret; + u8 opcode; + + ret = cadence_qspi_set_protocol(plat, op); + if (ret) + return ret; + + ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_READ_LSB, + plat->dtr); + if (ret) + return ret; /* Setup the indirect trigger address */ writel(plat->trigger_address, plat->regbase + CQSPI_REG_INDIRECTTRIGGER); /* Configure the opcode */ - rd_reg = op->cmd.opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB; + if (plat->dtr) + opcode = op->cmd.opcode >> 8; + else + opcode = op->cmd.opcode; - if (op->data.buswidth == 8) - /* Instruction and address at DQ0, data at DQ0-7. */ - rd_reg |= CQSPI_INST_TYPE_OCTAL << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB; - else if (op->data.buswidth == 4) - /* Instruction and address at DQ0, data at DQ0-3. */ - rd_reg |= CQSPI_INST_TYPE_QUAD << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB; + rd_reg = opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB; + rd_reg |= cadence_qspi_calc_rdreg(plat); writel(op->addr.val, plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR); if (dummy_bytes) { - if (dummy_bytes > CQSPI_DUMMY_BYTES_MAX) - dummy_bytes = CQSPI_DUMMY_BYTES_MAX; - /* Convert to clock cycles. */ - dummy_clk = dummy_bytes * CQSPI_DUMMY_CLKS_PER_BYTE; + dummy_clk = cadence_qspi_calc_dummy(op, plat->dtr); + + if (dummy_clk > CQSPI_DUMMY_CLKS_MAX) + return -ENOTSUPP; if (dummy_clk) rd_reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK) @@ -682,17 +889,52 @@ int cadence_qspi_apb_write_setup(struct cadence_spi_plat *plat, const struct spi_mem_op *op) { unsigned int reg; + int ret; + u8 opcode; + + ret = cadence_qspi_set_protocol(plat, op); + if (ret) + return ret; + + ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_WRITE_LSB, + plat->dtr); + if (ret) + return ret; /* Setup the indirect trigger address */ writel(plat->trigger_address, plat->regbase + CQSPI_REG_INDIRECTTRIGGER); /* Configure the opcode */ - reg = op->cmd.opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB; + if (plat->dtr) + opcode = op->cmd.opcode >> 8; + else + opcode = op->cmd.opcode; + + reg = opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB; + reg |= plat->data_width << CQSPI_REG_WR_INSTR_TYPE_DATA_LSB; + reg |= plat->addr_width << CQSPI_REG_WR_INSTR_TYPE_ADDR_LSB; writel(reg, plat->regbase + CQSPI_REG_WR_INSTR); + reg = cadence_qspi_calc_rdreg(plat); + writel(reg, plat->regbase + CQSPI_REG_RD_INSTR); + writel(op->addr.val, plat->regbase + CQSPI_REG_INDIRECTWRSTARTADDR); + if (plat->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(plat->regbase + CQSPI_REG_WR_COMPLETION_CTRL); + reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL; + writel(reg, plat->regbase + CQSPI_REG_WR_COMPLETION_CTRL); + } + reg = readl(plat->regbase + CQSPI_REG_SIZE); reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; reg |= (op->addr.nbytes - 1); @@ -787,7 +1029,15 @@ int cadence_qspi_apb_write_execute(struct cadence_spi_plat *plat, const void *buf = op->data.buf.out; size_t len = op->data.nbytes; - if (plat->use_dac_mode && (to + len < plat->ahbsize)) { + /* + * 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 (!plat->dtr && plat->use_dac_mode && (to + len < plat->ahbsize)) { memcpy_toio(plat->ahbbase + to, buf, len); if (!cadence_qspi_wait_idle(plat->regbase)) return -EIO; From patchwork Fri Jun 25 19:17:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497401 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=G/AiXP1i; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRd904pJz9sW8 for ; Sat, 26 Jun 2021 05:19:08 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1FB2982C37; Fri, 25 Jun 2021 21:18:24 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="G/AiXP1i"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 914D782C2A; Fri, 25 Jun 2021 21:18:00 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 73C5F82C15 for ; Fri, 25 Jun 2021 21:17:56 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJHtnv128407; Fri, 25 Jun 2021 14:17:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648675; bh=AxRGalmmT/NdNy1lxpZegi5inK5TXQyG1bqL38B/wIY=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=G/AiXP1ipDjqhjbuMotxFmfMdgZWuL7RX+/lUp91wEsL2MZRkM82WU9GcIbRUFEA6 WqJOrMw016xwF6gsatW0o8QnbM+irrs74nneokH/VYitQd9kmRNWH2rPRtbf75201n Mmhakpc3sCT7vWC0zxOr35jX2t3JFUA6jtg55iHg= Received: from DLEE107.ent.ti.com (dlee107.ent.ti.com [157.170.170.37]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJHttD062984 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:17:55 -0500 Received: from DLEE100.ent.ti.com (157.170.170.30) 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.2176.2; Fri, 25 Jun 2021 14:17:54 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE100.ent.ti.com (157.170.170.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:17:55 -0500 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 15PJHURO076530; Fri, 25 Jun 2021 14:17:52 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 08/27] mtd: spi-nor-core: Fix address width on flash chips > 16MB Date: Sat, 26 Jun 2021 00:47:10 +0530 Message-ID: <20210625191729.31798-9-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean If a flash chip has more than 16MB capacity but its BFPT reports BFPT_DWORD1_ADDRESS_BYTES_3_OR_4, the spi-nor framework defaults to 3. The check in spi_nor_scan() doesn't catch it because addr_width did get set. This fixes that check. Ported from Kernel commit 324f78dfb442b82365548b657ec4e6974c677502. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/spi-nor-core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 6af9c675a4..bfe7ea55c4 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -2603,7 +2603,11 @@ int spi_nor_scan(struct spi_nor *nor) /* already configured from SFDP */ } else if (info->addr_width) { nor->addr_width = info->addr_width; - } else if (mtd->size > SZ_16M) { + } else { + nor->addr_width = 3; + } + + if (nor->addr_width == 3 && mtd->size > SZ_16M) { #ifndef CONFIG_SPI_FLASH_BAR /* enable 4-byte addressing if the device exceeds 16MiB */ nor->addr_width = 4; @@ -2617,8 +2621,6 @@ int spi_nor_scan(struct spi_nor *nor) if (ret < 0) return ret; #endif - } else { - nor->addr_width = 3; } if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) { From patchwork Fri Jun 25 19:17:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497404 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=D8mmyN50; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRdt4q89z9sW8 for ; Sat, 26 Jun 2021 05:19:46 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id BB8AD82C49; Fri, 25 Jun 2021 21:18:34 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="D8mmyN50"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 55A1F82C26; Fri, 25 Jun 2021 21:18:08 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 0D95B82C24 for ; Fri, 25 Jun 2021 21:17:58 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJHvfK078348; Fri, 25 Jun 2021 14:17:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648677; bh=9puT19gVaPGFYzDkixM1kRjvR6vgZhRgdq7e3k7Mte4=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=D8mmyN505bPGorp3dQLNCVhtXIeCddf1HnkY3R4Yqdr2lvLh/d1FPCMrw2lVpo2zy BiH2hAQeOut4j71LJrjVtPHxL/7LRY44Dg2awDi8lI6EQ8gDJgJkXDhzBXYgkja+OR WKtzU9evg+y2WcqzVzRxf+PltFj0Uog1z04Hdfms= Received: from DLEE113.ent.ti.com (dlee113.ent.ti.com [157.170.170.24]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJHvjp023248 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:17:57 -0500 Received: from DLEE105.ent.ti.com (157.170.170.35) by DLEE113.ent.ti.com (157.170.170.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2; Fri, 25 Jun 2021 14:17:57 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:17:57 -0500 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 15PJHURP076530; Fri, 25 Jun 2021 14:17:55 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 09/27] mtd: spi-nor-core: Add a ->setup() hook Date: Sat, 26 Jun 2021 00:47:11 +0530 Message-ID: <20210625191729.31798-10-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean nor->setup() can be used by flashes to configure settings in case they have any peculiarities that can't be easily expressed by the generic spi-nor framework. This includes things like different opcodes, dummy cycles, page size, uniform/non-uniform sector sizes, etc. Move related declarations to avoid forward declarations. Inspired by the Linux kernel's setup() hook. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/spi-nor-core.c | 84 +++------------ drivers/mtd/spi/spi-nor-tiny.c | 22 ---- include/linux/mtd/spi-nor.h | 192 ++++++++++++++++++++++----------- 3 files changed, 147 insertions(+), 151 deletions(-) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index bfe7ea55c4..b782709f14 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -1451,71 +1451,6 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor) #endif /* CONFIG_SPI_FLASH_SFDP_SUPPORT */ #endif /* CONFIG_SPI_FLASH_SPANSION */ -struct spi_nor_read_command { - u8 num_mode_clocks; - u8 num_wait_states; - u8 opcode; - enum spi_nor_protocol proto; -}; - -struct spi_nor_pp_command { - u8 opcode; - enum spi_nor_protocol proto; -}; - -enum spi_nor_read_command_index { - SNOR_CMD_READ, - SNOR_CMD_READ_FAST, - SNOR_CMD_READ_1_1_1_DTR, - - /* Dual SPI */ - SNOR_CMD_READ_1_1_2, - SNOR_CMD_READ_1_2_2, - SNOR_CMD_READ_2_2_2, - SNOR_CMD_READ_1_2_2_DTR, - - /* Quad SPI */ - SNOR_CMD_READ_1_1_4, - SNOR_CMD_READ_1_4_4, - SNOR_CMD_READ_4_4_4, - SNOR_CMD_READ_1_4_4_DTR, - - /* Octo SPI */ - SNOR_CMD_READ_1_1_8, - SNOR_CMD_READ_1_8_8, - SNOR_CMD_READ_8_8_8, - SNOR_CMD_READ_1_8_8_DTR, - - SNOR_CMD_READ_MAX -}; - -enum spi_nor_pp_command_index { - SNOR_CMD_PP, - - /* Quad SPI */ - SNOR_CMD_PP_1_1_4, - SNOR_CMD_PP_1_4_4, - SNOR_CMD_PP_4_4_4, - - /* Octo SPI */ - SNOR_CMD_PP_1_1_8, - SNOR_CMD_PP_1_8_8, - SNOR_CMD_PP_8_8_8, - - SNOR_CMD_PP_MAX -}; - -struct spi_nor_flash_parameter { - u64 size; - u32 page_size; - - struct spi_nor_hwcaps hwcaps; - struct spi_nor_read_command reads[SNOR_CMD_READ_MAX]; - struct spi_nor_pp_command page_programs[SNOR_CMD_PP_MAX]; - - int (*quad_enable)(struct spi_nor *nor); -}; - static void spi_nor_set_read_settings(struct spi_nor_read_command *read, u8 num_mode_clocks, @@ -2377,9 +2312,10 @@ static int spi_nor_select_erase(struct spi_nor *nor, return 0; } -static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info, - const struct spi_nor_flash_parameter *params, - const struct spi_nor_hwcaps *hwcaps) +static int spi_nor_default_setup(struct spi_nor *nor, + const struct flash_info *info, + const struct spi_nor_flash_parameter *params, + const struct spi_nor_hwcaps *hwcaps) { u32 ignored_mask, shared_mask; bool enable_quad_io; @@ -2438,6 +2374,16 @@ static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info, return 0; } +static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info, + const struct spi_nor_flash_parameter *params, + const struct spi_nor_hwcaps *hwcaps) +{ + if (!nor->setup) + return 0; + + return nor->setup(nor, info, params, hwcaps); +} + static int spi_nor_init(struct spi_nor *nor) { int err; @@ -2504,6 +2450,8 @@ int spi_nor_scan(struct spi_nor *nor) nor->read_reg = spi_nor_read_reg; nor->write_reg = spi_nor_write_reg; + nor->setup = spi_nor_default_setup; + if (spi->mode & SPI_RX_OCTAL) { hwcaps.mask |= SNOR_HWCAPS_READ_1_1_8; diff --git a/drivers/mtd/spi/spi-nor-tiny.c b/drivers/mtd/spi/spi-nor-tiny.c index b0aa97d324..70061f1a61 100644 --- a/drivers/mtd/spi/spi-nor-tiny.c +++ b/drivers/mtd/spi/spi-nor-tiny.c @@ -555,28 +555,6 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor) } #endif /* CONFIG_SPI_FLASH_SPANSION */ -struct spi_nor_read_command { - u8 num_mode_clocks; - u8 num_wait_states; - u8 opcode; - enum spi_nor_protocol proto; -}; - -enum spi_nor_read_command_index { - SNOR_CMD_READ, - SNOR_CMD_READ_FAST, - - /* Quad SPI */ - SNOR_CMD_READ_1_1_4, - - SNOR_CMD_READ_MAX -}; - -struct spi_nor_flash_parameter { - struct spi_nor_hwcaps hwcaps; - struct spi_nor_read_command reads[SNOR_CMD_READ_MAX]; -}; - static void spi_nor_set_read_settings(struct spi_nor_read_command *read, u8 num_mode_clocks, diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index c3e38e499e..47a2eced69 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -249,6 +249,134 @@ enum spi_nor_option_flags { SNOR_F_BROKEN_RESET = BIT(6), }; +struct spi_nor; + +/** + * struct spi_nor_hwcaps - Structure for describing the hardware capabilies + * supported by the SPI controller (bus master). + * @mask: the bitmask listing all the supported hw capabilies + */ +struct spi_nor_hwcaps { + u32 mask; +}; + +/* + *(Fast) Read capabilities. + * MUST be ordered by priority: the higher bit position, the higher priority. + * As a matter of performances, it is relevant to use Octo SPI protocols first, + * 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 BIT(0) +#define SNOR_HWCAPS_READ_FAST BIT(1) +#define SNOR_HWCAPS_READ_1_1_1_DTR BIT(2) + +#define SNOR_HWCAPS_READ_DUAL GENMASK(6, 3) +#define SNOR_HWCAPS_READ_1_1_2 BIT(3) +#define SNOR_HWCAPS_READ_1_2_2 BIT(4) +#define SNOR_HWCAPS_READ_2_2_2 BIT(5) +#define SNOR_HWCAPS_READ_1_2_2_DTR BIT(6) + +#define SNOR_HWCAPS_READ_QUAD GENMASK(10, 7) +#define SNOR_HWCAPS_READ_1_1_4 BIT(7) +#define SNOR_HWCAPS_READ_1_4_4 BIT(8) +#define SNOR_HWCAPS_READ_4_4_4 BIT(9) +#define SNOR_HWCAPS_READ_1_4_4_DTR BIT(10) + +#define SNOR_HWCPAS_READ_OCTO GENMASK(14, 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) + +/* + * Page Program capabilities. + * MUST be ordered by priority: the higher bit position, the higher priority. + * Like (Fast) Read capabilities, Octo/Quad SPI protocols are preferred to the + * legacy SPI 1-1-1 protocol. + * Note that Dual Page Programs are not supported because there is no existing + * 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_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_OCTO 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) + +struct spi_nor_read_command { + u8 num_mode_clocks; + u8 num_wait_states; + u8 opcode; + enum spi_nor_protocol proto; +}; + +struct spi_nor_pp_command { + u8 opcode; + enum spi_nor_protocol proto; +}; + +enum spi_nor_read_command_index { + SNOR_CMD_READ, + SNOR_CMD_READ_FAST, + SNOR_CMD_READ_1_1_1_DTR, + + /* Dual SPI */ + SNOR_CMD_READ_1_1_2, + SNOR_CMD_READ_1_2_2, + SNOR_CMD_READ_2_2_2, + SNOR_CMD_READ_1_2_2_DTR, + + /* Quad SPI */ + SNOR_CMD_READ_1_1_4, + SNOR_CMD_READ_1_4_4, + SNOR_CMD_READ_4_4_4, + SNOR_CMD_READ_1_4_4_DTR, + + /* Octo SPI */ + SNOR_CMD_READ_1_1_8, + SNOR_CMD_READ_1_8_8, + SNOR_CMD_READ_8_8_8, + SNOR_CMD_READ_1_8_8_DTR, + + SNOR_CMD_READ_MAX +}; + +enum spi_nor_pp_command_index { + SNOR_CMD_PP, + + /* Quad SPI */ + SNOR_CMD_PP_1_1_4, + SNOR_CMD_PP_1_4_4, + SNOR_CMD_PP_4_4_4, + + /* Octo SPI */ + SNOR_CMD_PP_1_1_8, + SNOR_CMD_PP_1_8_8, + SNOR_CMD_PP_8_8_8, + + SNOR_CMD_PP_MAX +}; + +struct spi_nor_flash_parameter { + u64 size; + u32 page_size; + + struct spi_nor_hwcaps hwcaps; + struct spi_nor_read_command reads[SNOR_CMD_READ_MAX]; + struct spi_nor_pp_command page_programs[SNOR_CMD_PP_MAX]; + + int (*quad_enable)(struct spi_nor *nor); +}; + /** * struct flash_info - Forward declaration of a structure used internally by * spi_nor_scan() @@ -330,6 +458,9 @@ struct spi_nor { u32 flags; u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE]; + int (*setup)(struct spi_nor *nor, const struct flash_info *info, + const struct spi_nor_flash_parameter *params, + const struct spi_nor_hwcaps *hwcaps); int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops); void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops); int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len); @@ -368,67 +499,6 @@ device_node *spi_nor_get_flash_node(struct spi_nor *nor) } #endif /* __UBOOT__ */ -/** - * struct spi_nor_hwcaps - Structure for describing the hardware capabilies - * supported by the SPI controller (bus master). - * @mask: the bitmask listing all the supported hw capabilies - */ -struct spi_nor_hwcaps { - u32 mask; -}; - -/* - *(Fast) Read capabilities. - * MUST be ordered by priority: the higher bit position, the higher priority. - * As a matter of performances, it is relevant to use Octo SPI protocols first, - * 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 BIT(0) -#define SNOR_HWCAPS_READ_FAST BIT(1) -#define SNOR_HWCAPS_READ_1_1_1_DTR BIT(2) - -#define SNOR_HWCAPS_READ_DUAL GENMASK(6, 3) -#define SNOR_HWCAPS_READ_1_1_2 BIT(3) -#define SNOR_HWCAPS_READ_1_2_2 BIT(4) -#define SNOR_HWCAPS_READ_2_2_2 BIT(5) -#define SNOR_HWCAPS_READ_1_2_2_DTR BIT(6) - -#define SNOR_HWCAPS_READ_QUAD GENMASK(10, 7) -#define SNOR_HWCAPS_READ_1_1_4 BIT(7) -#define SNOR_HWCAPS_READ_1_4_4 BIT(8) -#define SNOR_HWCAPS_READ_4_4_4 BIT(9) -#define SNOR_HWCAPS_READ_1_4_4_DTR BIT(10) - -#define SNOR_HWCPAS_READ_OCTO GENMASK(14, 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) - -/* - * Page Program capabilities. - * MUST be ordered by priority: the higher bit position, the higher priority. - * Like (Fast) Read capabilities, Octo/Quad SPI protocols are preferred to the - * legacy SPI 1-1-1 protocol. - * Note that Dual Page Programs are not supported because there is no existing - * 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_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_OCTO 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) - /** * spi_nor_scan() - scan the SPI NOR * @nor: the spi_nor structure From patchwork Fri Jun 25 19:17:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497403 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=yi37f6Kj; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRdd3gZbz9sW8 for ; Sat, 26 Jun 2021 05:19:33 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id BF19482C3B; Fri, 25 Jun 2021 21:18:30 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="yi37f6Kj"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 28B3382C27; Fri, 25 Jun 2021 21:18:11 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 0C8C382C2E for ; Fri, 25 Jun 2021 21:18:01 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJI0C5128420; Fri, 25 Jun 2021 14:18:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648680; bh=kXeE1ceFvqTpfap3pFRC4SpEkeTUJNfxapFO0xy3Lvo=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=yi37f6KjolMoC6JjRVSHbcgJhN1i38J++dFr+//ZNiJe85HOk/MxzcJ/ibhDWUgdD XM0a+7uCqe0Ngs5zaZ7ntjvl2j4bYnPyYcoIJg8aP1+NDCMwXY4z720WASz9dSPg2o SUaasoINY2eeaIXXoJg7d80Jg7e/ypxGPKdgZVyo= 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 15PJI0V6048560 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:00 -0500 Received: from DLEE111.ent.ti.com (157.170.170.22) 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.2176.2; Fri, 25 Jun 2021 14:18:00 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE111.ent.ti.com (157.170.170.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:17:59 -0500 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 15PJHURQ076530; Fri, 25 Jun 2021 14:17:57 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 10/27] mtd: spi-nor-core: Move SFDP related declarations to top Date: Sat, 26 Jun 2021 00:47:12 +0530 Message-ID: <20210625191729.31798-11-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean These structures will be used in a later commit inside another structure definition. Also take the declarations out of the ifdef since they won't affect the final binary anyway and will be used in a later commit. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/spi-nor-core.c | 224 ++++++++++++++++----------------- 1 file changed, 112 insertions(+), 112 deletions(-) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index b782709f14..312628c080 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -40,6 +40,118 @@ #define DEFAULT_READY_WAIT_JIFFIES (40UL * HZ) +struct sfdp_parameter_header { + u8 id_lsb; + u8 minor; + u8 major; + u8 length; /* in double words */ + u8 parameter_table_pointer[3]; /* byte address */ + u8 id_msb; +}; + +#define SFDP_PARAM_HEADER_ID(p) (((p)->id_msb << 8) | (p)->id_lsb) +#define SFDP_PARAM_HEADER_PTP(p) \ + (((p)->parameter_table_pointer[2] << 16) | \ + ((p)->parameter_table_pointer[1] << 8) | \ + ((p)->parameter_table_pointer[0] << 0)) + +#define SFDP_BFPT_ID 0xff00 /* Basic Flash Parameter Table */ +#define SFDP_SECTOR_MAP_ID 0xff81 /* Sector Map Table */ +#define SFDP_SST_ID 0x01bf /* Manufacturer specific Table */ + +#define SFDP_SIGNATURE 0x50444653U +#define SFDP_JESD216_MAJOR 1 +#define SFDP_JESD216_MINOR 0 +#define SFDP_JESD216A_MINOR 5 +#define SFDP_JESD216B_MINOR 6 + +struct sfdp_header { + u32 signature; /* Ox50444653U <=> "SFDP" */ + u8 minor; + u8 major; + u8 nph; /* 0-base number of parameter headers */ + u8 unused; + + /* Basic Flash Parameter Table. */ + struct sfdp_parameter_header bfpt_header; +}; + +/* Basic Flash Parameter Table */ + +/* + * JESD216 rev B defines a Basic Flash Parameter Table of 16 DWORDs. + * They are indexed from 1 but C arrays are indexed from 0. + */ +#define BFPT_DWORD(i) ((i) - 1) +#define BFPT_DWORD_MAX 16 + +/* The first version of JESB216 defined only 9 DWORDs. */ +#define BFPT_DWORD_MAX_JESD216 9 + +/* 1st DWORD. */ +#define BFPT_DWORD1_FAST_READ_1_1_2 BIT(16) +#define BFPT_DWORD1_ADDRESS_BYTES_MASK GENMASK(18, 17) +#define BFPT_DWORD1_ADDRESS_BYTES_3_ONLY (0x0UL << 17) +#define BFPT_DWORD1_ADDRESS_BYTES_3_OR_4 (0x1UL << 17) +#define BFPT_DWORD1_ADDRESS_BYTES_4_ONLY (0x2UL << 17) +#define BFPT_DWORD1_DTR BIT(19) +#define BFPT_DWORD1_FAST_READ_1_2_2 BIT(20) +#define BFPT_DWORD1_FAST_READ_1_4_4 BIT(21) +#define BFPT_DWORD1_FAST_READ_1_1_4 BIT(22) + +/* 5th DWORD. */ +#define BFPT_DWORD5_FAST_READ_2_2_2 BIT(0) +#define BFPT_DWORD5_FAST_READ_4_4_4 BIT(4) + +/* 11th DWORD. */ +#define BFPT_DWORD11_PAGE_SIZE_SHIFT 4 +#define BFPT_DWORD11_PAGE_SIZE_MASK GENMASK(7, 4) + +/* 15th DWORD. */ + +/* + * (from JESD216 rev B) + * Quad Enable Requirements (QER): + * - 000b: Device does not have a QE bit. Device detects 1-1-4 and 1-4-4 + * reads based on instruction. DQ3/HOLD# functions are hold during + * instruction phase. + * - 001b: QE is bit 1 of status register 2. It is set via Write Status with + * two data bytes where bit 1 of the second byte is one. + * [...] + * Writing only one byte to the status register has the side-effect of + * clearing status register 2, including the QE bit. The 100b code is + * used if writing one byte to the status register does not modify + * status register 2. + * - 010b: QE is bit 6 of status register 1. It is set via Write Status with + * one data byte where bit 6 is one. + * [...] + * - 011b: QE is bit 7 of status register 2. It is set via Write status + * register 2 instruction 3Eh with one data byte where bit 7 is one. + * [...] + * The status register 2 is read using instruction 3Fh. + * - 100b: QE is bit 1 of status register 2. It is set via Write Status with + * two data bytes where bit 1 of the second byte is one. + * [...] + * In contrast to the 001b code, writing one byte to the status + * register does not modify status register 2. + * - 101b: QE is bit 1 of status register 2. Status register 1 is read using + * Read Status instruction 05h. Status register2 is read using + * instruction 35h. QE is set via Writ Status instruction 01h with + * two data bytes where bit 1 of the second byte is one. + * [...] + */ +#define BFPT_DWORD15_QER_MASK GENMASK(22, 20) +#define BFPT_DWORD15_QER_NONE (0x0UL << 20) /* Micron */ +#define BFPT_DWORD15_QER_SR2_BIT1_BUGGY (0x1UL << 20) +#define BFPT_DWORD15_QER_SR1_BIT6 (0x2UL << 20) /* Macronix */ +#define BFPT_DWORD15_QER_SR2_BIT7 (0x3UL << 20) +#define BFPT_DWORD15_QER_SR2_BIT1_NO_RD (0x4UL << 20) +#define BFPT_DWORD15_QER_SR2_BIT1 (0x5UL << 20) /* Spansion */ + +struct sfdp_bfpt { + u32 dwords[BFPT_DWORD_MAX]; +}; + static int spi_nor_read_write_reg(struct spi_nor *nor, struct spi_mem_op *op, void *buf) { @@ -1528,118 +1640,6 @@ read_err: return ret; } -struct sfdp_parameter_header { - u8 id_lsb; - u8 minor; - u8 major; - u8 length; /* in double words */ - u8 parameter_table_pointer[3]; /* byte address */ - u8 id_msb; -}; - -#define SFDP_PARAM_HEADER_ID(p) (((p)->id_msb << 8) | (p)->id_lsb) -#define SFDP_PARAM_HEADER_PTP(p) \ - (((p)->parameter_table_pointer[2] << 16) | \ - ((p)->parameter_table_pointer[1] << 8) | \ - ((p)->parameter_table_pointer[0] << 0)) - -#define SFDP_BFPT_ID 0xff00 /* Basic Flash Parameter Table */ -#define SFDP_SECTOR_MAP_ID 0xff81 /* Sector Map Table */ -#define SFDP_SST_ID 0x01bf /* Manufacturer specific Table */ - -#define SFDP_SIGNATURE 0x50444653U -#define SFDP_JESD216_MAJOR 1 -#define SFDP_JESD216_MINOR 0 -#define SFDP_JESD216A_MINOR 5 -#define SFDP_JESD216B_MINOR 6 - -struct sfdp_header { - u32 signature; /* Ox50444653U <=> "SFDP" */ - u8 minor; - u8 major; - u8 nph; /* 0-base number of parameter headers */ - u8 unused; - - /* Basic Flash Parameter Table. */ - struct sfdp_parameter_header bfpt_header; -}; - -/* Basic Flash Parameter Table */ - -/* - * JESD216 rev B defines a Basic Flash Parameter Table of 16 DWORDs. - * They are indexed from 1 but C arrays are indexed from 0. - */ -#define BFPT_DWORD(i) ((i) - 1) -#define BFPT_DWORD_MAX 16 - -/* The first version of JESB216 defined only 9 DWORDs. */ -#define BFPT_DWORD_MAX_JESD216 9 - -/* 1st DWORD. */ -#define BFPT_DWORD1_FAST_READ_1_1_2 BIT(16) -#define BFPT_DWORD1_ADDRESS_BYTES_MASK GENMASK(18, 17) -#define BFPT_DWORD1_ADDRESS_BYTES_3_ONLY (0x0UL << 17) -#define BFPT_DWORD1_ADDRESS_BYTES_3_OR_4 (0x1UL << 17) -#define BFPT_DWORD1_ADDRESS_BYTES_4_ONLY (0x2UL << 17) -#define BFPT_DWORD1_DTR BIT(19) -#define BFPT_DWORD1_FAST_READ_1_2_2 BIT(20) -#define BFPT_DWORD1_FAST_READ_1_4_4 BIT(21) -#define BFPT_DWORD1_FAST_READ_1_1_4 BIT(22) - -/* 5th DWORD. */ -#define BFPT_DWORD5_FAST_READ_2_2_2 BIT(0) -#define BFPT_DWORD5_FAST_READ_4_4_4 BIT(4) - -/* 11th DWORD. */ -#define BFPT_DWORD11_PAGE_SIZE_SHIFT 4 -#define BFPT_DWORD11_PAGE_SIZE_MASK GENMASK(7, 4) - -/* 15th DWORD. */ - -/* - * (from JESD216 rev B) - * Quad Enable Requirements (QER): - * - 000b: Device does not have a QE bit. Device detects 1-1-4 and 1-4-4 - * reads based on instruction. DQ3/HOLD# functions are hold during - * instruction phase. - * - 001b: QE is bit 1 of status register 2. It is set via Write Status with - * two data bytes where bit 1 of the second byte is one. - * [...] - * Writing only one byte to the status register has the side-effect of - * clearing status register 2, including the QE bit. The 100b code is - * used if writing one byte to the status register does not modify - * status register 2. - * - 010b: QE is bit 6 of status register 1. It is set via Write Status with - * one data byte where bit 6 is one. - * [...] - * - 011b: QE is bit 7 of status register 2. It is set via Write status - * register 2 instruction 3Eh with one data byte where bit 7 is one. - * [...] - * The status register 2 is read using instruction 3Fh. - * - 100b: QE is bit 1 of status register 2. It is set via Write Status with - * two data bytes where bit 1 of the second byte is one. - * [...] - * In contrast to the 001b code, writing one byte to the status - * register does not modify status register 2. - * - 101b: QE is bit 1 of status register 2. Status register 1 is read using - * Read Status instruction 05h. Status register2 is read using - * instruction 35h. QE is set via Writ Status instruction 01h with - * two data bytes where bit 1 of the second byte is one. - * [...] - */ -#define BFPT_DWORD15_QER_MASK GENMASK(22, 20) -#define BFPT_DWORD15_QER_NONE (0x0UL << 20) /* Micron */ -#define BFPT_DWORD15_QER_SR2_BIT1_BUGGY (0x1UL << 20) -#define BFPT_DWORD15_QER_SR1_BIT6 (0x2UL << 20) /* Macronix */ -#define BFPT_DWORD15_QER_SR2_BIT7 (0x3UL << 20) -#define BFPT_DWORD15_QER_SR2_BIT1_NO_RD (0x4UL << 20) -#define BFPT_DWORD15_QER_SR2_BIT1 (0x5UL << 20) /* Spansion */ - -struct sfdp_bfpt { - u32 dwords[BFPT_DWORD_MAX]; -}; - /* Fast Read settings. */ static void From patchwork Fri Jun 25 19:17:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497409 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=xabnub09; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRfy23HNz9sW8 for ; Sat, 26 Jun 2021 05:20:42 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id BFA8482C52; Fri, 25 Jun 2021 21:19:07 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="xabnub09"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id AA64582C26; Fri, 25 Jun 2021 21:18:14 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 37FCE82C19 for ; Fri, 25 Jun 2021 21:18:05 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJI3fK078362; Fri, 25 Jun 2021 14:18:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648683; bh=rxqMqdeFL6Go0MxEtSJn+eDTiSTOAK8suqe0m0Ybihs=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=xabnub09OOdotbnUpCJ4xGPTNny99O6uKlAN1NEbC9CCQar44bixeWSKbQuWJ/ZbT DqyrE3oj0rRBBgV/JT9s9RPvzEhr748VAQaVo6+5ZjAQbLerPJ5ACKFOum89sTmgou m9n8DjTTZ2Dk51OBkA1AmxhJR69avgRchyKA64I0= Received: from DFLE115.ent.ti.com (dfle115.ent.ti.com [10.64.6.36]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJI3nL063189 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:03 -0500 Received: from DFLE102.ent.ti.com (10.64.6.23) by DFLE115.ent.ti.com (10.64.6.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2; Fri, 25 Jun 2021 14:18:02 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DFLE102.ent.ti.com (10.64.6.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:02 -0500 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 15PJHURR076530; Fri, 25 Jun 2021 14:18:00 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 11/27] mtd: spi-nor-core: Introduce flash-specific fixup hooks Date: Sat, 26 Jun 2021 00:47:13 +0530 Message-ID: <20210625191729.31798-12-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Sometimes the information in a flash's SFDP tables is wrong. Sometimes some information just can't be expressed in the SFDP table. So, introduce the fixup hooks to allow tailoring settings for a specific flash. Three hooks are added: default_init, post_sfdp, and post_bfpt. These allow tweaking the flash settings at different point in the probe sequence. Since the hooks reside in nor->info, set that value just before the call to spi_nor_init_params(). The hooks and at what points they are executed mimics Linux's spi-nor framework. One major difference is that Linux puts the struct spi_nor_fixups in nor->info. This is not possible in U-Boot because the spi-nor-ids list is shared between spi-nor-core.c and spi-nor-tiny.c. Since spi-nor-tiny shouldn't have those fixup hooks populated, add a separate function that lets flashes populate their fixup hooks. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/spi-nor-core.c | 78 ++++++++++++++++++++++++++++++++-- include/linux/mtd/spi-nor.h | 2 + 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 312628c080..013a48d2ef 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -152,6 +152,31 @@ struct sfdp_bfpt { u32 dwords[BFPT_DWORD_MAX]; }; +/** + * struct spi_nor_fixups - SPI NOR fixup hooks + * @default_init: called after default flash parameters init. Used to tweak + * flash parameters when information provided by the flash_info + * table is incomplete or wrong. + * @post_bfpt: called after the BFPT table has been parsed + * @post_sfdp: called after SFDP has been parsed (is also called for SPI NORs + * that do not support RDSFDP). Typically used to tweak various + * parameters that could not be extracted by other means (i.e. + * when information provided by the SFDP/flash_info tables are + * incomplete or wrong). + * + * Those hooks can be used to tweak the SPI NOR configuration when the SFDP + * table is broken or not available. + */ +struct spi_nor_fixups { + void (*default_init)(struct spi_nor *nor); + int (*post_bfpt)(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt, + struct spi_nor_flash_parameter *params); + void (*post_sfdp)(struct spi_nor *nor, + struct spi_nor_flash_parameter *params); +}; + static int spi_nor_read_write_reg(struct spi_nor *nor, struct spi_mem_op *op, void *buf) { @@ -1751,6 +1776,18 @@ static const struct sfdp_bfpt_erase sfdp_bfpt_erases[] = { static int spi_nor_hwcaps_read2cmd(u32 hwcaps); +static int +spi_nor_post_bfpt_fixups(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt, + struct spi_nor_flash_parameter *params) +{ + if (nor->fixups && nor->fixups->post_bfpt) + return nor->fixups->post_bfpt(nor, bfpt_header, bfpt, params); + + return 0; +} + /** * spi_nor_parse_bfpt() - read and parse the Basic Flash Parameter Table. * @nor: pointer to a 'struct spi_nor' @@ -1889,7 +1926,8 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, /* Stop here if not JESD216 rev A or later. */ if (bfpt_header->length < BFPT_DWORD_MAX) - return 0; + return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, + params); /* Page size: this field specifies 'N' so the page size = 2^N bytes. */ params->page_size = bfpt.dwords[BFPT_DWORD(11)]; @@ -1922,7 +1960,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, return -EINVAL; } - return 0; + return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, params); } /** @@ -2085,6 +2123,29 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, } #endif /* SPI_FLASH_SFDP_SUPPORT */ +/** + * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings + * after SFDP has been parsed (is also called for SPI NORs that do not + * support RDSFDP). + * @nor: pointer to a 'struct spi_nor' + * + * Typically used to tweak various parameters that could not be extracted by + * other means (i.e. when information provided by the SFDP/flash_info tables + * are incomplete or wrong). + */ +static void spi_nor_post_sfdp_fixups(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + if (nor->fixups && nor->fixups->post_sfdp) + nor->fixups->post_sfdp(nor, params); +} + +static void spi_nor_default_init_fixups(struct spi_nor *nor) +{ + if (nor->fixups && nor->fixups->default_init) + nor->fixups->default_init(nor); +} + static int spi_nor_init_params(struct spi_nor *nor, const struct flash_info *info, struct spi_nor_flash_parameter *params) @@ -2164,6 +2225,8 @@ static int spi_nor_init_params(struct spi_nor *nor, } } + spi_nor_default_init_fixups(nor); + /* Override the parameters with data read from SFDP tables. */ nor->addr_width = 0; nor->mtd.erasesize = 0; @@ -2180,6 +2243,8 @@ static int spi_nor_init_params(struct spi_nor *nor, } } + spi_nor_post_sfdp_fixups(nor, params); + return 0; } @@ -2428,6 +2493,10 @@ static int spi_nor_init(struct spi_nor *nor) return 0; } +void spi_nor_set_fixups(struct spi_nor *nor) +{ +} + int spi_nor_scan(struct spi_nor *nor) { struct spi_nor_flash_parameter params; @@ -2476,6 +2545,10 @@ int spi_nor_scan(struct spi_nor *nor) info = spi_nor_read_id(nor); if (IS_ERR_OR_NULL(info)) return -ENOENT; + nor->info = info; + + spi_nor_set_fixups(nor); + /* Parse the Serial Flash Discoverable Parameters table. */ ret = spi_nor_init_params(nor, info, ¶ms); if (ret) @@ -2578,7 +2651,6 @@ int spi_nor_scan(struct spi_nor *nor) } /* Send all the required SPI flash commands to initialize device */ - nor->info = info; ret = spi_nor_init(nor); if (ret) return ret; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 47a2eced69..b2e9e0895b 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -416,6 +416,7 @@ struct spi_flash { * @write_proto: the SPI protocol for write operations * @reg_proto the SPI protocol for read_reg/write_reg/erase operations * @cmd_buf: used by the write_reg + * @fixups: flash-specific fixup hooks. * @prepare: [OPTIONAL] do some preparations for the * read/write/erase/lock/unlock operations * @unprepare: [OPTIONAL] do some post work after the @@ -457,6 +458,7 @@ struct spi_nor { bool sst_write_second; u32 flags; u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE]; + struct spi_nor_fixups *fixups; int (*setup)(struct spi_nor *nor, const struct flash_info *info, const struct spi_nor_flash_parameter *params, From patchwork Fri Jun 25 19:17:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497405 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=KFy2MAQZ; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRf765Gkz9sW8 for ; Sat, 26 Jun 2021 05:19:59 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 8D55C82C4F; Fri, 25 Jun 2021 21:18:51 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="KFy2MAQZ"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 5883082C2A; Fri, 25 Jun 2021 21:18:19 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 62C3582C2D for ; Fri, 25 Jun 2021 21:18:07 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJI5gO078368; Fri, 25 Jun 2021 14:18:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648685; bh=/C0v5dOZEjfB1oZ2rWE+jJtfxh8dRau+AVFdsSPpHTc=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=KFy2MAQZVDInG+i8WLW76re3k0cHnSH93ycOVezjK/LgvfNzX68ONBw01VnmXV0tL YXSMr6yEDSesumudcZCCxrBTig1XZg4ZWXRsKvn9U3/imXgc7W2Dn9TDccpnMZkUGZ 2RUKBnnXttUXF9cph4g8oTsBbL/Q5jb2G/OlzZ60= Received: from DLEE108.ent.ti.com (dlee108.ent.ti.com [157.170.170.38]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJI5RT123342 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:05 -0500 Received: from DLEE109.ent.ti.com (157.170.170.41) 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.2176.2; Fri, 25 Jun 2021 14:18:05 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE109.ent.ti.com (157.170.170.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:05 -0500 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 15PJHURS076530; Fri, 25 Jun 2021 14:18:03 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 12/27] mtd: spi-nor-core: Rework hwcaps selection Date: Sat, 26 Jun 2021 00:47:14 +0530 Message-ID: <20210625191729.31798-13-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean The spi-mem layer provides a spi_mem_supports_op() function to check whether a specific operation is supported by the controller or not. This is much more accurate than the hwcaps selection logic based on SPI_{RX,TX}_ flags. Rework the hwcaps selection logic to use spi_mem_supports_op(). To make sure the build doesn't break for boards not using CONFIG_DM_SPI, add a simple SPI_{RX,TX}_ based hwcaps selection logic in spi-mem-nodm similar to spi_mem_default_supports_op(). This change is only compile-tested. To avoid SPL size problems on the x530 board, the old hwcaps selection is still kept around. Leaving the code in-place was getting difficult to read and understand, so the code is restructured to have it all in one isolated function. As a result of this, the parameter hwcaps to spi_nor_setup() is no longer needed. Remove it. Based on the Linux commit c76f5089796a (mtd: spi-nor: Rework hwcaps selection for the spi-mem case, 2019-08-06) Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/Kconfig | 9 ++ drivers/mtd/spi/spi-nor-core.c | 244 ++++++++++++++++++++++++++------- drivers/spi/spi-mem-nodm.c | 62 +++++++++ include/linux/mtd/spi-nor.h | 17 ++- 4 files changed, 280 insertions(+), 52 deletions(-) diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index f8db8e5213..a701167dcc 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -88,6 +88,15 @@ config SPI_FLASH_SFDP_SUPPORT SPI NOR flashes using Serial Flash Discoverable Parameters (SFDP) tables as per JESD216 standard. +config SPI_FLASH_SMART_HWCAPS + bool "Smart hardware capability detection based on SPI MEM supports_op() hook" + default y + help + Enable support for smart hardware capability detection based on SPI + MEM supports_op() hook that lets controllers express whether they + can support a type of operation in a much more refined way compared + to using flags like SPI_RX_DUAL, SPI_TX_QUAD, etc. + config SPI_FLASH_BAR bool "SPI flash Bank/Extended address register support" help diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 013a48d2ef..24c6b8c4a3 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -2299,6 +2299,194 @@ static int spi_nor_hwcaps_pp2cmd(u32 hwcaps) ARRAY_SIZE(hwcaps_pp2cmd)); } +#ifdef CONFIG_SPI_FLASH_SMART_HWCAPS +/** + * spi_nor_check_op - check if the operation is supported by controller + * @nor: pointer to a 'struct spi_nor' + * @op: pointer to op template to be checked + * + * Returns 0 if operation is supported, -ENOTSUPP otherwise. + */ +static int spi_nor_check_op(struct spi_nor *nor, + struct spi_mem_op *op) +{ + /* + * First test with 4 address bytes. The opcode itself might be a 3B + * addressing opcode but we don't care, because SPI controller + * implementation should not check the opcode, but just the sequence. + */ + op->addr.nbytes = 4; + if (!spi_mem_supports_op(nor->spi, op)) { + if (nor->mtd.size > SZ_16M) + return -ENOTSUPP; + + /* If flash size <= 16MB, 3 address bytes are sufficient */ + op->addr.nbytes = 3; + if (!spi_mem_supports_op(nor->spi, op)) + return -ENOTSUPP; + } + + return 0; +} + +/** + * spi_nor_check_readop - check if the read op is supported by controller + * @nor: pointer to a 'struct spi_nor' + * @read: pointer to op template to be checked + * + * Returns 0 if operation is supported, -ENOTSUPP otherwise. + */ +static int spi_nor_check_readop(struct spi_nor *nor, + const struct spi_nor_read_command *read) +{ + struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(read->opcode, 1), + SPI_MEM_OP_ADDR(3, 0, 1), + 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; + + return spi_nor_check_op(nor, &op); +} + +/** + * spi_nor_check_pp - check if the page program op is supported by controller + * @nor: pointer to a 'struct spi_nor' + * @pp: pointer to op template to be checked + * + * Returns 0 if operation is supported, -ENOTSUPP otherwise. + */ +static int spi_nor_check_pp(struct spi_nor *nor, + const struct spi_nor_pp_command *pp) +{ + struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(pp->opcode, 1), + SPI_MEM_OP_ADDR(3, 0, 1), + 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); + + return spi_nor_check_op(nor, &op); +} + +/** + * spi_nor_adjust_hwcaps - Find optimal Read/Write protocol based on SPI + * controller capabilities + * @nor: pointer to a 'struct spi_nor' + * @params: pointer to the 'struct spi_nor_flash_parameter' + * representing SPI NOR flash capabilities + * @hwcaps: pointer to resulting capabilities after adjusting + * according to controller and flash's capability + * + * Discard caps based on what the SPI controller actually supports (using + * spi_mem_supports_op()). + */ +static void +spi_nor_adjust_hwcaps(struct spi_nor *nor, + const struct spi_nor_flash_parameter *params, + u32 *hwcaps) +{ + unsigned int cap; + + /* + * Enable all caps by default. We will mask them after checking what's + * really supported using spi_mem_supports_op(). + */ + *hwcaps = SNOR_HWCAPS_ALL; + + /* 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; + + for (cap = 0; cap < sizeof(*hwcaps) * BITS_PER_BYTE; cap++) { + int rdidx, ppidx; + + if (!(*hwcaps & BIT(cap))) + continue; + + rdidx = spi_nor_hwcaps_read2cmd(BIT(cap)); + if (rdidx >= 0 && + spi_nor_check_readop(nor, ¶ms->reads[rdidx])) + *hwcaps &= ~BIT(cap); + + ppidx = spi_nor_hwcaps_pp2cmd(BIT(cap)); + if (ppidx < 0) + continue; + + if (spi_nor_check_pp(nor, ¶ms->page_programs[ppidx])) + *hwcaps &= ~BIT(cap); + } +} +#else +/** + * spi_nor_adjust_hwcaps - Find optimal Read/Write protocol based on SPI + * controller capabilities + * @nor: pointer to a 'struct spi_nor' + * @params: pointer to the 'struct spi_nor_flash_parameter' + * representing SPI NOR flash capabilities + * @hwcaps: pointer to resulting capabilities after adjusting + * according to controller and flash's capability + * + * Select caps based on what the SPI controller and SPI flash both support. + */ +static void +spi_nor_adjust_hwcaps(struct spi_nor *nor, + const struct spi_nor_flash_parameter *params, + u32 *hwcaps) +{ + struct spi_slave *spi = nor->spi; + u32 ignored_mask = (SNOR_HWCAPS_READ_2_2_2 | + SNOR_HWCAPS_READ_4_4_4 | + SNOR_HWCAPS_READ_8_8_8 | + SNOR_HWCAPS_PP_4_4_4 | + SNOR_HWCAPS_PP_8_8_8); + u32 spi_hwcaps = (SNOR_HWCAPS_READ | SNOR_HWCAPS_READ_FAST | + SNOR_HWCAPS_PP); + + /* Get the hardware capabilities the SPI controller supports. */ + if (spi->mode & SPI_RX_OCTAL) { + spi_hwcaps |= SNOR_HWCAPS_READ_1_1_8; + + if (spi->mode & SPI_TX_OCTAL) + spi_hwcaps |= (SNOR_HWCAPS_READ_1_8_8 | + SNOR_HWCAPS_PP_1_1_8 | + SNOR_HWCAPS_PP_1_8_8); + } else if (spi->mode & SPI_RX_QUAD) { + spi_hwcaps |= SNOR_HWCAPS_READ_1_1_4; + + if (spi->mode & SPI_TX_QUAD) + spi_hwcaps |= (SNOR_HWCAPS_READ_1_4_4 | + SNOR_HWCAPS_PP_1_1_4 | + SNOR_HWCAPS_PP_1_4_4); + } else if (spi->mode & SPI_RX_DUAL) { + spi_hwcaps |= SNOR_HWCAPS_READ_1_1_2; + + if (spi->mode & SPI_TX_DUAL) + spi_hwcaps |= SNOR_HWCAPS_READ_1_2_2; + } + + /* + * Keep only the hardware capabilities supported by both the SPI + * controller and the SPI flash memory. + */ + *hwcaps = spi_hwcaps & params->hwcaps.mask; + if (*hwcaps & ignored_mask) { + dev_dbg(nor->dev, + "SPI n-n-n protocols are not supported yet.\n"); + *hwcaps &= ~ignored_mask; + } +} +#endif /* CONFIG_SPI_FLASH_SMART_HWCAPS */ + static int spi_nor_select_read(struct spi_nor *nor, const struct spi_nor_flash_parameter *params, u32 shared_hwcaps) @@ -2379,30 +2567,13 @@ static int spi_nor_select_erase(struct spi_nor *nor, static int spi_nor_default_setup(struct spi_nor *nor, const struct flash_info *info, - const struct spi_nor_flash_parameter *params, - const struct spi_nor_hwcaps *hwcaps) + const struct spi_nor_flash_parameter *params) { - u32 ignored_mask, shared_mask; + u32 shared_mask; bool enable_quad_io; int err; - /* - * Keep only the hardware capabilities supported by both the SPI - * controller and the SPI flash memory. - */ - shared_mask = hwcaps->mask & params->hwcaps.mask; - - /* SPI n-n-n protocols are not supported yet. */ - ignored_mask = (SNOR_HWCAPS_READ_2_2_2 | - SNOR_HWCAPS_READ_4_4_4 | - SNOR_HWCAPS_READ_8_8_8 | - SNOR_HWCAPS_PP_4_4_4 | - SNOR_HWCAPS_PP_8_8_8); - if (shared_mask & ignored_mask) { - dev_dbg(nor->dev, - "SPI n-n-n protocols are not supported yet.\n"); - shared_mask &= ~ignored_mask; - } + spi_nor_adjust_hwcaps(nor, params, &shared_mask); /* Select the (Fast) Read command. */ err = spi_nor_select_read(nor, params, shared_mask); @@ -2440,13 +2611,12 @@ static int spi_nor_default_setup(struct spi_nor *nor, } static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info, - const struct spi_nor_flash_parameter *params, - const struct spi_nor_hwcaps *hwcaps) + const struct spi_nor_flash_parameter *params) { if (!nor->setup) return 0; - return nor->setup(nor, info, params, hwcaps); + return nor->setup(nor, info, params); } static int spi_nor_init(struct spi_nor *nor) @@ -2502,11 +2672,6 @@ int spi_nor_scan(struct spi_nor *nor) struct spi_nor_flash_parameter params; const struct flash_info *info = NULL; struct mtd_info *mtd = &nor->mtd; - struct spi_nor_hwcaps hwcaps = { - .mask = SNOR_HWCAPS_READ | - SNOR_HWCAPS_READ_FAST | - SNOR_HWCAPS_PP, - }; struct spi_slave *spi = nor->spi; int ret; @@ -2521,27 +2686,6 @@ int spi_nor_scan(struct spi_nor *nor) nor->setup = spi_nor_default_setup; - if (spi->mode & SPI_RX_OCTAL) { - hwcaps.mask |= SNOR_HWCAPS_READ_1_1_8; - - if (spi->mode & SPI_TX_OCTAL) - hwcaps.mask |= (SNOR_HWCAPS_READ_1_8_8 | - SNOR_HWCAPS_PP_1_1_8 | - SNOR_HWCAPS_PP_1_8_8); - } else if (spi->mode & SPI_RX_QUAD) { - hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4; - - if (spi->mode & SPI_TX_QUAD) - hwcaps.mask |= (SNOR_HWCAPS_READ_1_4_4 | - SNOR_HWCAPS_PP_1_1_4 | - SNOR_HWCAPS_PP_1_4_4); - } else if (spi->mode & SPI_RX_DUAL) { - hwcaps.mask |= SNOR_HWCAPS_READ_1_1_2; - - if (spi->mode & SPI_TX_DUAL) - hwcaps.mask |= SNOR_HWCAPS_READ_1_2_2; - } - info = spi_nor_read_id(nor); if (IS_ERR_OR_NULL(info)) return -ENOENT; @@ -2616,7 +2760,7 @@ int spi_nor_scan(struct spi_nor *nor) * - set the SPI protocols for register and memory accesses. * - set the Quad Enable bit if needed (required by SPI x-y-4 protos). */ - ret = spi_nor_setup(nor, info, ¶ms, &hwcaps); + ret = spi_nor_setup(nor, info, ¶ms); if (ret) return ret; diff --git a/drivers/spi/spi-mem-nodm.c b/drivers/spi/spi-mem-nodm.c index db54101383..a228c808c7 100644 --- a/drivers/spi/spi-mem-nodm.c +++ b/drivers/spi/spi-mem-nodm.c @@ -105,3 +105,65 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, return 0; } + +static int spi_check_buswidth_req(struct spi_slave *slave, u8 buswidth, bool tx) +{ + u32 mode = slave->mode; + + switch (buswidth) { + case 1: + return 0; + + case 2: + if ((tx && (mode & (SPI_TX_DUAL | SPI_TX_QUAD))) || + (!tx && (mode & (SPI_RX_DUAL | SPI_RX_QUAD)))) + return 0; + + break; + + case 4: + if ((tx && (mode & SPI_TX_QUAD)) || + (!tx && (mode & SPI_RX_QUAD))) + return 0; + + break; + case 8: + if ((tx && (mode & SPI_TX_OCTAL)) || + (!tx && (mode & SPI_RX_OCTAL))) + return 0; + + break; + + default: + break; + } + + return -ENOTSUPP; +} + +bool spi_mem_supports_op(struct spi_slave *slave, const struct spi_mem_op *op) +{ + if (spi_check_buswidth_req(slave, op->cmd.buswidth, true)) + return false; + + if (op->addr.nbytes && + spi_check_buswidth_req(slave, op->addr.buswidth, true)) + return false; + + if (op->dummy.nbytes && + spi_check_buswidth_req(slave, op->dummy.buswidth, true)) + return false; + + if (op->data.nbytes && + spi_check_buswidth_req(slave, op->data.buswidth, + op->data.dir == SPI_MEM_DATA_OUT)) + return false; + + if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr) + return false; + + if (op->cmd.nbytes != 1) + return false; + + return true; +} diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index b2e9e0895b..90b75ec845 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -312,6 +312,20 @@ struct spi_nor_hwcaps { #define SNOR_HWCAPS_PP_1_8_8 BIT(21) #define SNOR_HWCAPS_PP_8_8_8 BIT(22) +#define SNOR_HWCAPS_X_X_X (SNOR_HWCAPS_READ_2_2_2 | \ + SNOR_HWCAPS_READ_4_4_4 | \ + SNOR_HWCAPS_READ_8_8_8 | \ + SNOR_HWCAPS_PP_4_4_4 | \ + SNOR_HWCAPS_PP_8_8_8) + +#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) + +#define SNOR_HWCAPS_ALL (SNOR_HWCAPS_READ_MASK | \ + SNOR_HWCAPS_PP_MASK) + struct spi_nor_read_command { u8 num_mode_clocks; u8 num_wait_states; @@ -461,8 +475,7 @@ struct spi_nor { struct spi_nor_fixups *fixups; int (*setup)(struct spi_nor *nor, const struct flash_info *info, - const struct spi_nor_flash_parameter *params, - const struct spi_nor_hwcaps *hwcaps); + const struct spi_nor_flash_parameter *params); int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops); void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops); int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len); From patchwork Fri Jun 25 19:17:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497410 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=Hja4GA3j; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRg86rFFz9sW8 for ; Sat, 26 Jun 2021 05:20:52 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1B21382C65; Fri, 25 Jun 2021 21:19:11 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="Hja4GA3j"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 727B782C27; Fri, 25 Jun 2021 21:18:15 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id BF3E282C28 for ; Fri, 25 Jun 2021 21:18:09 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJI8Mb078382; Fri, 25 Jun 2021 14:18:08 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648688; bh=o2aPR62GbwzMqhjYzbbhGRF//irrW4zIdRnmgYvHd7M=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=Hja4GA3j/29Ak0DYGd+gYuoZ9L+sVE51Vhsu6sYTE8yTd5Jw30jnGOhNAZSSpNWTa 7Hn9BSoZ/aDNMwJ1PquYcOD+qofrD8wndHNNlK8jc9amAyTSWuf0c55PU1iy1kRHzi Yp+YNAvOdQHF4TmgUQmEXw7tYnRyk10X2PIGNMHY= Received: from DLEE113.ent.ti.com (dlee113.ent.ti.com [157.170.170.24]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJI8lG049196 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:08 -0500 Received: from DLEE108.ent.ti.com (157.170.170.38) by DLEE113.ent.ti.com (157.170.170.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2; Fri, 25 Jun 2021 14:18:07 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:07 -0500 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 15PJHURT076530; Fri, 25 Jun 2021 14:18:05 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 13/27] mtd: spi-nor-core: Do not set data direction when there is no data Date: Sat, 26 Jun 2021 00:47:15 +0530 Message-ID: <20210625191729.31798-14-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Even when spi_nor_write_reg() has no data to write, like when executing a write enable operation, it sets the data direction to SPI_MEM_DATA_OUT. This trips up spi_mem_check_buswidth() because it expects a data phase when there is none. Make sure the data direction is set to SPI_MEM_NO_DATA when there is no data to write. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/spi-nor-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 24c6b8c4a3..d795ecbc9f 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -209,6 +209,9 @@ static int spi_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_OUT(len, NULL, 1)); + if (len == 0) + op.data.dir = SPI_MEM_NO_DATA; + return spi_nor_read_write_reg(nor, &op, buf); } From patchwork Fri Jun 25 19:17:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497406 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=pJZ0/CKL; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRfN3cQdz9sW8 for ; Sat, 26 Jun 2021 05:20:12 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 7AD6A82C3F; Fri, 25 Jun 2021 21:18:55 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="pJZ0/CKL"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A136B82C37; Fri, 25 Jun 2021 21:18:21 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 87DF682C32 for ; Fri, 25 Jun 2021 21:18:12 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJIArg128457; Fri, 25 Jun 2021 14:18:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648691; bh=V79iv49qSV240E7akupyomku3QWvMvcivs1H8isFz/Q=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=pJZ0/CKLJvmdYIXCE9tc0epwV4SOETL4+sjhCKPWpkLgzgUHaL4X/nOBmBmTcefgU 2bAJEriRhE902rUyK1atBsLWtY/oa97uFQX6LV6olDoxMWj6DT5QoJ+Su+oIHhnluC 5uf86TAiThTHRIvalQVbdYzjno3fpCac91c8DOtw= Received: from DFLE100.ent.ti.com (dfle100.ent.ti.com [10.64.6.21]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJIASH023649 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:10 -0500 Received: from DFLE103.ent.ti.com (10.64.6.24) 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.2176.2; Fri, 25 Jun 2021 14:18:10 -0500 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:10 -0500 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 15PJHURU076530; Fri, 25 Jun 2021 14:18:08 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 14/27] mtd: spi-nor-core: Add support for DTR protocol Date: Sat, 26 Jun 2021 00:47:16 +0530 Message-ID: <20210625191729.31798-15-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean 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/sf_internal.h | 1 + drivers/mtd/spi/spi-nor-core.c | 178 +++++++++++++++++++++++++-------- include/linux/mtd/spi-nor.h | 50 ++++++--- 3 files changed, 175 insertions(+), 54 deletions(-) diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 0b63e1bfc2..d3ef69ec74 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -68,6 +68,7 @@ struct flash_info { #define USE_CLSR BIT(14) /* use CLSR command */ #define SPI_NOR_HAS_SST26LOCK BIT(15) /* Flash supports lock/unlock via BPR */ #define SPI_NOR_OCTAL_READ BIT(16) /* Flash supports Octal Read */ +#define SPI_NOR_OCTAL_DTR_READ BIT(17) /* Flash supports Octal DTR Read */ }; extern const struct flash_info spi_nor_ids[]; diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index d795ecbc9f..c2eae885e4 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -177,6 +177,76 @@ struct spi_nor_fixups { struct spi_nor_flash_parameter *params); }; +/** + * spi_nor_get_cmd_ext() - Get the command opcode extension based on the + * extension type. + * @nor: pointer to a 'struct spi_nor' + * @op: pointer to the 'struct spi_mem_op' whose properties + * need to be initialized. + * + * Right now, only "repeat" and "invert" are supported. + * + * Return: The opcode extension. + */ +static u8 spi_nor_get_cmd_ext(const struct spi_nor *nor, + const struct spi_mem_op *op) +{ + switch (nor->cmd_ext_type) { + case SPI_NOR_EXT_INVERT: + return ~op->cmd.opcode; + + case SPI_NOR_EXT_REPEAT: + return op->cmd.opcode; + + default: + dev_dbg(nor->dev, "Unknown command extension type\n"); + return 0; + } +} + +/** + * spi_nor_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_setup_op(const struct spi_nor *nor, + struct spi_mem_op *op, + const enum spi_nor_protocol proto) +{ + u8 ext; + + 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.nbytes) + 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.dtr = op->addr.dtr = op->dummy.dtr = + op->data.dtr = true; + + /* 2 bytes per clock cycle in DTR mode. */ + op->dummy.nbytes *= 2; + + ext = spi_nor_get_cmd_ext(nor, op); + op->cmd.opcode = (op->cmd.opcode << 8) | ext; + op->cmd.nbytes = 2; + } +} + static int spi_nor_read_write_reg(struct spi_nor *nor, struct spi_mem_op *op, void *buf) { @@ -189,12 +259,14 @@ static int spi_nor_read_write_reg(struct spi_nor *nor, struct spi_mem_op static int spi_nor_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len) { - struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(code, 1), + struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(code, 0), SPI_MEM_OP_NO_ADDR, SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_IN(len, NULL, 1)); + SPI_MEM_OP_DATA_IN(len, NULL, 0)); int ret; + spi_nor_setup_op(nor, &op, nor->reg_proto); + ret = spi_nor_read_write_reg(nor, &op, val); if (ret < 0) dev_dbg(nor->dev, "error %d reading %x\n", ret, code); @@ -204,10 +276,12 @@ static int spi_nor_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len) static int spi_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) { - struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 1), + struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), SPI_MEM_OP_NO_ADDR, SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_OUT(len, NULL, 1)); + SPI_MEM_OP_DATA_OUT(len, NULL, 0)); + + spi_nor_setup_op(nor, &op, nor->reg_proto); if (len == 0) op.data.dir = SPI_MEM_NO_DATA; @@ -219,21 +293,19 @@ static ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len, u_char *buf) { struct spi_mem_op op = - SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 1), - SPI_MEM_OP_ADDR(nor->addr_width, from, 1), - SPI_MEM_OP_DUMMY(nor->read_dummy, 1), - SPI_MEM_OP_DATA_IN(len, buf, 1)); + SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0), + SPI_MEM_OP_ADDR(nor->addr_width, from, 0), + SPI_MEM_OP_DUMMY(nor->read_dummy, 0), + SPI_MEM_OP_DATA_IN(len, buf, 0)); size_t remaining = len; int ret; - /* 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_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; while (remaining) { op.data.nbytes = remaining < UINT_MAX ? remaining : UINT_MAX; @@ -257,20 +329,17 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len, const u_char *buf) { struct spi_mem_op op = - SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 1), - SPI_MEM_OP_ADDR(nor->addr_width, to, 1), + SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0), + SPI_MEM_OP_ADDR(nor->addr_width, to, 0), SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_OUT(len, buf, 1)); + SPI_MEM_OP_DATA_OUT(len, buf, 0)); int ret; - /* get transfer protocols. */ - 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_setup_op(nor, &op, nor->write_proto); + ret = spi_mem_adjust_op_size(nor->spi, &op); if (ret) return ret; @@ -668,11 +737,13 @@ static int read_bar(struct spi_nor *nor, const struct flash_info *info) static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) { struct spi_mem_op op = - SPI_MEM_OP(SPI_MEM_OP_CMD(nor->erase_opcode, 1), - SPI_MEM_OP_ADDR(nor->addr_width, addr, 1), + SPI_MEM_OP(SPI_MEM_OP_CMD(nor->erase_opcode, 0), + SPI_MEM_OP_ADDR(nor->addr_width, addr, 0), SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_NO_DATA); + spi_nor_setup_op(nor, &op, nor->write_proto); + if (nor->erase) return nor->erase(nor, addr); @@ -2194,11 +2265,25 @@ static int spi_nor_init_params(struct spi_nor *nor, SNOR_PROTO_1_1_8); } + if (info->flags & SPI_NOR_OCTAL_DTR_READ) { + params->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8_DTR; + spi_nor_set_read_settings(¶ms->reads[SNOR_CMD_READ_8_8_8_DTR], + 0, 20, SPINOR_OP_READ_FAST, + SNOR_PROTO_8_8_8_DTR); + } + /* Page Program settings. */ params->hwcaps.mask |= SNOR_HWCAPS_PP; 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); + if (info->flags & SPI_NOR_QUAD_READ) { params->hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4; spi_nor_set_pp_settings(¶ms->page_programs[SNOR_CMD_PP_1_1_4], @@ -2233,7 +2318,8 @@ static int spi_nor_init_params(struct spi_nor *nor, /* Override the parameters with data read from SFDP tables. */ nor->addr_width = 0; nor->mtd.erasesize = 0; - if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) && + if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_OCTAL_DTR_READ)) && !(info->flags & SPI_NOR_SKIP_SFDP)) { struct spi_nor_flash_parameter sfdp_params; @@ -2280,6 +2366,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, @@ -2296,6 +2383,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, @@ -2342,17 +2430,17 @@ static int spi_nor_check_op(struct spi_nor *nor, static int spi_nor_check_readop(struct spi_nor *nor, const struct spi_nor_read_command *read) { - struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(read->opcode, 1), - SPI_MEM_OP_ADDR(3, 0, 1), - SPI_MEM_OP_DUMMY(0, 1), - SPI_MEM_OP_DATA_IN(0, NULL, 1)); + struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(read->opcode, 0), + SPI_MEM_OP_ADDR(3, 0, 0), + SPI_MEM_OP_DUMMY(1, 0), + SPI_MEM_OP_DATA_IN(2, NULL, 0)); + + spi_nor_setup_op(nor, &op, read->proto); - 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; + if (spi_nor_protocol_is_dtr(nor->read_proto)) + op.dummy.nbytes *= 2; return spi_nor_check_op(nor, &op); } @@ -2367,14 +2455,12 @@ static int spi_nor_check_readop(struct spi_nor *nor, static int spi_nor_check_pp(struct spi_nor *nor, const struct spi_nor_pp_command *pp) { - struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(pp->opcode, 1), - SPI_MEM_OP_ADDR(3, 0, 1), + struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(pp->opcode, 0), + SPI_MEM_OP_ADDR(3, 0, 0), SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_OUT(0, NULL, 1)); + SPI_MEM_OP_DATA_OUT(2, NULL, 0)); - 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_setup_op(nor, &op, pp->proto); return spi_nor_check_op(nor, &op); } @@ -2404,12 +2490,16 @@ spi_nor_adjust_hwcaps(struct spi_nor *nor, */ *hwcaps = SNOR_HWCAPS_ALL; - /* 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; + /* + * If the reset line is broken, we do not want to enter a stateful + * mode. + */ + if (nor->flags & SNOR_F_BROKEN_RESET) + *hwcaps &= ~(SNOR_HWCAPS_X_X_X | SNOR_HWCAPS_X_X_X_DTR); + for (cap = 0; cap < sizeof(*hwcaps) * BITS_PER_BYTE; cap++) { int rdidx, ppidx; @@ -2649,6 +2739,7 @@ static int spi_nor_init(struct spi_nor *nor) } if (nor->addr_width == 4 && + !(nor->info->flags & SPI_NOR_OCTAL_DTR_READ) && (JEDEC_MFR(nor->info) != SNOR_MFR_SPANSION) && !(nor->info->flags & SPI_NOR_4B_OPCODES)) { /* @@ -2767,7 +2858,10 @@ int spi_nor_scan(struct spi_nor *nor) if (ret) return ret; - if (nor->addr_width) { + if (spi_nor_protocol_is_dtr(nor->read_proto)) { + /* Always use 4-byte addresses in DTR mode. */ + nor->addr_width = 4; + } else if (nor->addr_width) { /* already configured from SFDP */ } else if (info->addr_width) { nor->addr_width = info->addr_width; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 90b75ec845..4394cb6e16 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -200,6 +200,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) @@ -267,7 +268,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) @@ -284,11 +285,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_HWCPAS_READ_OCTO GENMASK(14, 11) +#define SNOR_HWCPAS_READ_OCTO 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. @@ -299,18 +301,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_OCTO 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_OCTO 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 | \ @@ -318,6 +321,9 @@ struct spi_nor_hwcaps { SNOR_HWCAPS_PP_4_4_4 | \ SNOR_HWCAPS_PP_8_8_8) +#define SNOR_HWCAPS_X_X_X_DTR (SNOR_HWCAPS_READ_8_8_8_DTR | \ + SNOR_HWCAPS_PP_8_8_8_DTR) + #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 | \ @@ -360,6 +366,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 }; @@ -376,6 +383,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 }; @@ -391,6 +399,22 @@ struct spi_nor_flash_parameter { int (*quad_enable)(struct spi_nor *nor); }; +/** + * enum spi_nor_cmd_ext - describes the command opcode extension in DTR mode + * @SPI_MEM_NOR_NONE: no extension. This is the default, and is used in Legacy + * SPI mode + * @SPI_MEM_NOR_REPEAT: the extension is same as the opcode + * @SPI_MEM_NOR_INVERT: the extension is the bitwise inverse of the opcode + * @SPI_MEM_NOR_HEX: the extension is any hex value. The command and opcode + * combine to form a 16-bit opcode. + */ +enum spi_nor_cmd_ext { + SPI_NOR_EXT_NONE = 0, + SPI_NOR_EXT_REPEAT, + SPI_NOR_EXT_INVERT, + SPI_NOR_EXT_HEX, +}; + /** * struct flash_info - Forward declaration of a structure used internally by * spi_nor_scan() @@ -430,6 +454,7 @@ struct spi_flash { * @write_proto: the SPI protocol for write operations * @reg_proto the SPI protocol for read_reg/write_reg/erase operations * @cmd_buf: used by the write_reg + * @cmd_ext_type: the command opcode extension for DTR mode. * @fixups: flash-specific fixup hooks. * @prepare: [OPTIONAL] do some preparations for the * read/write/erase/lock/unlock operations @@ -472,6 +497,7 @@ struct spi_nor { bool sst_write_second; u32 flags; u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE]; + enum spi_nor_cmd_ext cmd_ext_type; struct spi_nor_fixups *fixups; int (*setup)(struct spi_nor *nor, const struct flash_info *info, From patchwork Fri Jun 25 19:17:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497408 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=p30AosrM; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRfm5jrnz9sW8 for ; Sat, 26 Jun 2021 05:20:32 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1C7C882C5B; Fri, 25 Jun 2021 21:19:04 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="p30AosrM"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 9D2EB82C39; Fri, 25 Jun 2021 21:18:22 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 05B5082C1A for ; Fri, 25 Jun 2021 21:18:14 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJIDW6128468; Fri, 25 Jun 2021 14:18:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648693; bh=2HXBQHX+XUdzCfIy1tGBzVS+o4t9w+Y1mh07c8HfHy0=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=p30AosrMDtFlvMsZ75PyzyGWRskugRxG6HaTyylrZ6y9c2Ei2uAlYgaV/U51aBOqw QH6y/lerukiOk4OuIxF1XMNC+OiDV9oqADzlZNnL0aQQAjzgKwPSiiJ0QzqF6V1kP1 bg8ybiVrPQNOAVqMdRsswyfv+o17BCD5rukEAqvQ= Received: from DFLE100.ent.ti.com (dfle100.ent.ti.com [10.64.6.21]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJIDKG063551 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:13 -0500 Received: from DFLE112.ent.ti.com (10.64.6.33) 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.2176.2; Fri, 25 Jun 2021 14:18:13 -0500 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:13 -0500 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 15PJHURV076530; Fri, 25 Jun 2021 14:18:11 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 15/27] mtd: spi-nor-core: prepare BFPT parsing for JESD216 rev D Date: Sat, 26 Jun 2021 00:47:17 +0530 Message-ID: <20210625191729.31798-16-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean JESD216 rev D makes BFPT 20 DWORDs. Update the BFPT size define to reflect that. The check for rev A or later compared the BFPT header length with the maximum BFPT length, BFPT_DWORD_MAX. Since BFPT_DWORD_MAX was 16, and so was the BFPT length for both rev A and B, this check worked fine. But now, since BFPT_DWORD_MAX is 20, it means this check will also stop BFPT parsing for rev A or B, since their length is 16. So, instead check for BFPT_DWORD_MAX_JESD216 to stop BFPT parsing for the first JESD216 version, and check for BFPT_DWORD_MAX_JESD216B for the next two versions. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/spi-nor-core.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index c2eae885e4..5a65597616 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -79,14 +79,15 @@ struct sfdp_header { /* Basic Flash Parameter Table */ /* - * JESD216 rev B defines a Basic Flash Parameter Table of 16 DWORDs. + * JESD216 rev D defines a Basic Flash Parameter Table of 20 DWORDs. * They are indexed from 1 but C arrays are indexed from 0. */ #define BFPT_DWORD(i) ((i) - 1) -#define BFPT_DWORD_MAX 16 +#define BFPT_DWORD_MAX 20 /* The first version of JESB216 defined only 9 DWORDs. */ #define BFPT_DWORD_MAX_JESD216 9 +#define BFPT_DWORD_MAX_JESD216B 16 /* 1st DWORD. */ #define BFPT_DWORD1_FAST_READ_1_1_2 BIT(16) @@ -1999,7 +2000,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, } /* Stop here if not JESD216 rev A or later. */ - if (bfpt_header->length < BFPT_DWORD_MAX) + if (bfpt_header->length == BFPT_DWORD_MAX_JESD216) return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, params); @@ -2034,6 +2035,11 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, return -EINVAL; } + /* Stop here if JESD216 rev B. */ + if (bfpt_header->length == BFPT_DWORD_MAX_JESD216B) + return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, + params); + return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, params); } From patchwork Fri Jun 25 19:17:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497407 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=o3xBg7vn; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRfc0TFYz9sW8 for ; Sat, 26 Jun 2021 05:20:23 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 18B4E82C55; Fri, 25 Jun 2021 21:18:59 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="o3xBg7vn"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 2328B82C3B; Fri, 25 Jun 2021 21:18:23 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id E509282C35 for ; Fri, 25 Jun 2021 21:18:17 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJIGJD128478; Fri, 25 Jun 2021 14:18:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648696; bh=SgbN1tOf4g/caBjuEzutOWNOB5tHfdh04ahAAIW9NI0=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=o3xBg7vnmRHbVBP5DWCZidBbq4jF4SY8TNO6IDAvErGSJqxtGImH8NPiIbqBpHZNQ XZMxl7+cWMJLQVscO1SbXlOtAAxQKHSIC7stLvrI88fM9+MmR2bv55r/+NE2aXbz6r HZeOxzce5v3ooqrpqN1elB6z249uFM2uVY8quHXg= Received: from DFLE101.ent.ti.com (dfle101.ent.ti.com [10.64.6.22]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJIG4l023746 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:16 -0500 Received: from DFLE103.ent.ti.com (10.64.6.24) by DFLE101.ent.ti.com (10.64.6.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2; Fri, 25 Jun 2021 14:18:15 -0500 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:15 -0500 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 15PJHURW076530; Fri, 25 Jun 2021 14:18:13 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 16/27] mtd: spi-nor-core: Get command opcode extension type from BFPT Date: Sat, 26 Jun 2021 00:47:18 +0530 Message-ID: <20210625191729.31798-17-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Some devices in DTR mode expect an extra command byte called the extension. The extension can either be same as the opcode, bitwise inverse of the opcode, or another additional byte forming a 16-byte opcode. Get the extension type from the BFPT. For now, only flashes with "repeat" and "inverse" extensions are supported. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/spi-nor-core.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 5a65597616..d9af5cbf97 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -149,6 +149,12 @@ struct sfdp_header { #define BFPT_DWORD15_QER_SR2_BIT1_NO_RD (0x4UL << 20) #define BFPT_DWORD15_QER_SR2_BIT1 (0x5UL << 20) /* Spansion */ +#define BFPT_DWORD18_CMD_EXT_MASK GENMASK(30, 29) +#define BFPT_DWORD18_CMD_EXT_REP (0x0UL << 29) /* Repeat */ +#define BFPT_DWORD18_CMD_EXT_INV (0x1UL << 29) /* Invert */ +#define BFPT_DWORD18_CMD_EXT_RES (0x2UL << 29) /* Reserved */ +#define BFPT_DWORD18_CMD_EXT_16B (0x3UL << 29) /* 16-bit opcode */ + struct sfdp_bfpt { u32 dwords[BFPT_DWORD_MAX]; }; @@ -2040,6 +2046,24 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, params); + /* 8D-8D-8D command extension. */ + switch (bfpt.dwords[BFPT_DWORD(18)] & BFPT_DWORD18_CMD_EXT_MASK) { + case BFPT_DWORD18_CMD_EXT_REP: + nor->cmd_ext_type = SPI_NOR_EXT_REPEAT; + break; + + case BFPT_DWORD18_CMD_EXT_INV: + nor->cmd_ext_type = SPI_NOR_EXT_INVERT; + break; + + case BFPT_DWORD18_CMD_EXT_RES: + return -EINVAL; + + case BFPT_DWORD18_CMD_EXT_16B: + dev_err(nor->dev, "16-bit opcodes not supported\n"); + return -ENOTSUPP; + } + return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, params); } From patchwork Fri Jun 25 19:17:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497411 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=RvtEYEbx; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRgL1Zlcz9sW8 for ; Sat, 26 Jun 2021 05:21:02 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id AC93A82C69; Fri, 25 Jun 2021 21:19:13 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="RvtEYEbx"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 6110682C34; Fri, 25 Jun 2021 21:18:27 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 6B6E982C33 for ; Fri, 25 Jun 2021 21:18:20 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJIIeS128484; Fri, 25 Jun 2021 14:18:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648698; bh=NUxjpRMuww3K6QoHmRbsjcj9qjJBeCXSCWk3ryTi52o=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=RvtEYEbxpLKNEcK0xc6FoP3jiAoEb7pxrg4QmNwpHSyOTOcZV3YGdSVxFl43ebO+o EXZPgHTCek/qERdrmuqpebUctgmpuhLi2/LCGh2dH2C4RpndxsfdqXPraLQF4V0Zni Vuj1YHuBUwAc3DwuavxZf1w4K75MYEOwwa65aCWw= Received: from DFLE109.ent.ti.com (dfle109.ent.ti.com [10.64.6.30]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJII72063648 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:18 -0500 Received: from DFLE114.ent.ti.com (10.64.6.35) by DFLE109.ent.ti.com (10.64.6.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2; Fri, 25 Jun 2021 14:18:18 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:18 -0500 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 15PJHURX076530; Fri, 25 Jun 2021 14:18:16 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 17/27] mtd: spi-nor-core: Parse xSPI Profile 1.0 table Date: Sat, 26 Jun 2021 00:47:19 +0530 Message-ID: <20210625191729.31798-18-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean This table is indication that the flash is xSPI compliant and hence supports octal DTR mode. Extract information like the fast read opcode, the number of dummy cycles needed for a Read Status Register command, and the number of address bytes needed for a Read Status Register command. The default dummy cycles for a fast octal DTR read are set to 20. Since there is no simple way of determining the dummy cycles needed for the fast read command, flashes that use a different value should update it in their flash-specific hooks. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/spi-nor-core.c | 100 +++++++++++++++++++++++++++++++++ include/linux/mtd/spi-nor.h | 7 +++ 2 files changed, 107 insertions(+) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index d9af5cbf97..b3b04db8bf 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,8 @@ #define DEFAULT_READY_WAIT_JIFFIES (40UL * HZ) +#define ROUND_UP_TO(x, y) (((x) + (y) - 1) / (y) * (y)) + struct sfdp_parameter_header { u8 id_lsb; u8 minor; @@ -58,6 +61,7 @@ struct sfdp_parameter_header { #define SFDP_BFPT_ID 0xff00 /* Basic Flash Parameter Table */ #define SFDP_SECTOR_MAP_ID 0xff81 /* Sector Map Table */ #define SFDP_SST_ID 0x01bf /* Manufacturer specific Table */ +#define SFDP_PROFILE1_ID 0xff05 /* xSPI Profile 1.0 Table */ #define SFDP_SIGNATURE 0x50444653U #define SFDP_JESD216_MAJOR 1 @@ -155,6 +159,16 @@ struct sfdp_header { #define BFPT_DWORD18_CMD_EXT_RES (0x2UL << 29) /* Reserved */ #define BFPT_DWORD18_CMD_EXT_16B (0x3UL << 29) /* 16-bit opcode */ +/* xSPI Profile 1.0 table (from JESD216D.01). */ +#define PROFILE1_DWORD1_RD_FAST_CMD GENMASK(15, 8) +#define PROFILE1_DWORD1_RDSR_DUMMY BIT(28) +#define PROFILE1_DWORD1_RDSR_ADDR_BYTES BIT(29) +#define PROFILE1_DWORD4_DUMMY_200MHZ GENMASK(11, 7) +#define PROFILE1_DWORD5_DUMMY_166MHZ GENMASK(31, 27) +#define PROFILE1_DWORD5_DUMMY_133MHZ GENMASK(21, 17) +#define PROFILE1_DWORD5_DUMMY_100MHZ GENMASK(11, 7) +#define PROFILE1_DUMMY_DEFAULT 20 + struct sfdp_bfpt { u32 dwords[BFPT_DWORD_MAX]; }; @@ -2095,6 +2109,86 @@ spi_nor_parse_microchip_sfdp(struct spi_nor *nor, return ret; } +/** + * spi_nor_parse_profile1() - parse the xSPI Profile 1.0 table + * @nor: pointer to a 'struct spi_nor' + * @profile1_header: pointer to the 'struct sfdp_parameter_header' describing + * the 4-Byte Address Instruction Table length and version. + * @params: pointer to the 'struct spi_nor_flash_parameter' to be. + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_parse_profile1(struct spi_nor *nor, + const struct sfdp_parameter_header *profile1_header, + struct spi_nor_flash_parameter *params) +{ + u32 *table, opcode, addr; + size_t len; + int ret, i; + u8 dummy; + + len = profile1_header->length * sizeof(*table); + table = kmalloc(len, GFP_KERNEL); + if (!table) + return -ENOMEM; + + addr = SFDP_PARAM_HEADER_PTP(profile1_header); + ret = spi_nor_read_sfdp(nor, addr, len, table); + if (ret) + goto out; + + /* Fix endianness of the table DWORDs. */ + for (i = 0; i < profile1_header->length; i++) + table[i] = le32_to_cpu(table[i]); + + /* Get 8D-8D-8D fast read opcode and dummy cycles. */ + opcode = FIELD_GET(PROFILE1_DWORD1_RD_FAST_CMD, table[0]); + + /* + * We don't know what speed the controller is running at. Find the + * dummy cycles for the fastest frequency the flash can run at to be + * sure we are never short of dummy cycles. A value of 0 means the + * frequency is not supported. + * + * Default to PROFILE1_DUMMY_DEFAULT if we don't find anything, and let + * flashes set the correct value if needed in their fixup hooks. + */ + dummy = FIELD_GET(PROFILE1_DWORD4_DUMMY_200MHZ, table[3]); + if (!dummy) + dummy = FIELD_GET(PROFILE1_DWORD5_DUMMY_166MHZ, table[4]); + if (!dummy) + dummy = FIELD_GET(PROFILE1_DWORD5_DUMMY_133MHZ, table[4]); + if (!dummy) + dummy = FIELD_GET(PROFILE1_DWORD5_DUMMY_100MHZ, table[4]); + if (!dummy) + dummy = PROFILE1_DUMMY_DEFAULT; + + /* Round up to an even value to avoid tripping controllers up. */ + dummy = ROUND_UP_TO(dummy, 2); + + /* Update the fast read settings. */ + spi_nor_set_read_settings(¶ms->reads[SNOR_CMD_READ_8_8_8_DTR], + 0, dummy, opcode, + SNOR_PROTO_8_8_8_DTR); + + /* + * Set the Read Status Register dummy cycles and dummy address bytes. + */ + if (table[0] & PROFILE1_DWORD1_RDSR_DUMMY) + params->rdsr_dummy = 8; + else + params->rdsr_dummy = 4; + + if (table[0] & PROFILE1_DWORD1_RDSR_ADDR_BYTES) + params->rdsr_addr_nbytes = 4; + else + params->rdsr_addr_nbytes = 0; + +out: + kfree(table); + return ret; +} + /** * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters. * @nor: pointer to a 'struct spi_nor' @@ -2197,6 +2291,10 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, err = spi_nor_parse_microchip_sfdp(nor, param_header); break; + case SFDP_PROFILE1_ID: + err = spi_nor_parse_profile1(nor, param_header, params); + break; + default: break; } @@ -2926,6 +3024,8 @@ int spi_nor_scan(struct spi_nor *nor) if (ret) return ret; + nor->rdsr_dummy = params.rdsr_dummy; + nor->rdsr_addr_nbytes = params.rdsr_addr_nbytes; nor->name = mtd->name; nor->size = mtd->size; nor->erase_size = mtd->erasesize; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 4394cb6e16..295583ed29 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -391,6 +391,8 @@ enum spi_nor_pp_command_index { struct spi_nor_flash_parameter { u64 size; u32 page_size; + u8 rdsr_dummy; + u8 rdsr_addr_nbytes; struct spi_nor_hwcaps hwcaps; struct spi_nor_read_command reads[SNOR_CMD_READ_MAX]; @@ -445,6 +447,9 @@ struct spi_flash { * @read_opcode: the read opcode * @read_dummy: the dummy needed by the read operation * @program_opcode: the program opcode + * @rdsr_dummy dummy cycles needed for Read Status Register command. + * @rdsr_addr_nbytes: dummy address bytes needed for Read Status Register + * command. * @bank_read_cmd: Bank read cmd * @bank_write_cmd: Bank write cmd * @bank_curr: Current flash bank @@ -486,6 +491,8 @@ struct spi_nor { u8 read_opcode; u8 read_dummy; u8 program_opcode; + u8 rdsr_dummy; + u8 rdsr_addr_nbytes; #ifdef CONFIG_SPI_FLASH_BAR u8 bank_read_cmd; u8 bank_write_cmd; From patchwork Fri Jun 25 19:17:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497412 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=Kfk+xCZe; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRgX3Pcwz9sW8 for ; Sat, 26 Jun 2021 05:21:12 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1947182C60; Fri, 25 Jun 2021 21:19:16 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="Kfk+xCZe"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A612082C36; Fri, 25 Jun 2021 21:18:28 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 2241582C3A for ; Fri, 25 Jun 2021 21:18:23 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJILt7128498; Fri, 25 Jun 2021 14:18:21 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648701; bh=swqScFQR6o9jsV03ualwIYlJjx0HoYVMm39phSSIhK8=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=Kfk+xCZeLhraCQy343+71KHDpqmrKmI+3Fh37OUrJd1yaynW8qQVCUZJ3w2papxVv Wn/e8HBV1w12IrHUw1UyJAQ5Z9jJfTQQ8ivrHtqwI7sQx2ghV2KV98uOcorZqubAjk PAs6L24gQMJ25jmcboGItzoTGQyz+lLWH0FVi6Dk= Received: from DLEE105.ent.ti.com (dlee105.ent.ti.com [157.170.170.35]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJILQX023846 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:21 -0500 Received: from DLEE100.ent.ti.com (157.170.170.30) 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.2176.2; Fri, 25 Jun 2021 14:18:21 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE100.ent.ti.com (157.170.170.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:21 -0500 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 15PJHURY076530; Fri, 25 Jun 2021 14:18:19 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 18/27] mtd: spi-nor-core: Prepare Read SR and FSR for Octal DTR mode Date: Sat, 26 Jun 2021 00:47:20 +0530 Message-ID: <20210625191729.31798-19-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean The xSPI Profile 1.0 table specifies how many dummy cycles and address bytes are needed for the Read Status Register command in Octal DTR mode. Use that information to send the correct Read SR command. Some controllers might have trouble reading just 1 byte in DTR mode. So, when we are in DTR mode read 2 bytes and discard the second. This shows no side effects with the two flashes I tested: Micron mt35xu512aba and Cypress s28hs512t. Update Read FSR to mimic Read SR because they share the same characteristics. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/spi-nor-core.c | 60 ++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index b3b04db8bf..b9d3101d57 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -380,16 +380,40 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len, */ static int read_sr(struct spi_nor *nor) { + struct spi_mem_op op; int ret; - u8 val; + u8 val[2]; + u8 addr_nbytes, dummy; - ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val, 1); + if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) { + addr_nbytes = nor->rdsr_addr_nbytes; + dummy = nor->rdsr_dummy; + } else { + addr_nbytes = 0; + dummy = 0; + } + + op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR, 0), + SPI_MEM_OP_ADDR(addr_nbytes, 0, 0), + SPI_MEM_OP_DUMMY(dummy, 0), + SPI_MEM_OP_DATA_IN(1, NULL, 0)); + + spi_nor_setup_op(nor, &op, nor->reg_proto); + + /* + * We don't want to read only one byte in DTR mode. So, read 2 and then + * discard the second byte. + */ + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + op.data.nbytes = 2; + + ret = spi_nor_read_write_reg(nor, &op, val); if (ret < 0) { pr_debug("error %d reading SR\n", (int)ret); return ret; } - return val; + return *val; } /* @@ -399,16 +423,40 @@ static int read_sr(struct spi_nor *nor) */ static int read_fsr(struct spi_nor *nor) { + struct spi_mem_op op; int ret; - u8 val; + u8 val[2]; + u8 addr_nbytes, dummy; - ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val, 1); + if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) { + addr_nbytes = nor->rdsr_addr_nbytes; + dummy = nor->rdsr_dummy; + } else { + addr_nbytes = 0; + dummy = 0; + } + + op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDFSR, 0), + SPI_MEM_OP_ADDR(addr_nbytes, 0, 0), + SPI_MEM_OP_DUMMY(dummy, 0), + SPI_MEM_OP_DATA_IN(1, NULL, 0)); + + spi_nor_setup_op(nor, &op, nor->reg_proto); + + /* + * We don't want to read only one byte in DTR mode. So, read 2 and then + * discard the second byte. + */ + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + op.data.nbytes = 2; + + ret = spi_nor_read_write_reg(nor, &op, val); if (ret < 0) { pr_debug("error %d reading FSR\n", ret); return ret; } - return val; + return *val; } /* From patchwork Fri Jun 25 19:17:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497413 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=m+VYmNfY; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRgj5NMRz9sW8 for ; Sat, 26 Jun 2021 05:21:21 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 8685682C6D; Fri, 25 Jun 2021 21:19:18 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="m+VYmNfY"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 3850982C3C; Fri, 25 Jun 2021 21:18:31 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id C3A4182C40 for ; Fri, 25 Jun 2021 21:18:25 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJIOqH078467; Fri, 25 Jun 2021 14:18:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648704; bh=cpv8JJSHzlmcmoXyjhW6iJHxgnDCEH7J2jFTdIxcQe4=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=m+VYmNfYSr7ZqaPftn1rBEvuSzvf0+vBnuQzMjtCV/kUkIkUZW33Knob2oJZrBFuj nYD/sSfbbNpuVd21k/gXc1zN2T0mG7AZZfPWszwv4UIOh0yW2A8MSs/iiInNq/roin dNrMSRZmgpzJBwydpjr9KfnJCi2gyf3Nuusge7wk= Received: from DLEE103.ent.ti.com (dlee103.ent.ti.com [157.170.170.33]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJIOvR063724 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:24 -0500 Received: from DLEE105.ent.ti.com (157.170.170.35) 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.2176.2; Fri, 25 Jun 2021 14:18:23 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:24 -0500 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 15PJHURZ076530; Fri, 25 Jun 2021 14:18:21 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 19/27] mtd: spi-nor-core: Enable octal DTR mode when possible Date: Sat, 26 Jun 2021 00:47:21 +0530 Message-ID: <20210625191729.31798-20-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean 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/spi-nor-core.c | 31 +++++++++++++++++++++++++++++++ include/linux/mtd/spi-nor.h | 2 ++ 2 files changed, 33 insertions(+) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index b9d3101d57..cdb464813b 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -2888,10 +2888,41 @@ static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info, return nor->setup(nor, info, params); } +/** 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->octal_dtr_enable) + return 0; + + if (!(nor->read_proto == SNOR_PROTO_8_8_8_DTR && + nor->write_proto == SNOR_PROTO_8_8_8_DTR)) + return 0; + + ret = nor->octal_dtr_enable(nor); + if (ret) + return ret; + + nor->reg_proto = SNOR_PROTO_8_8_8_DTR; + + return 0; +} + 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 DTR mode not supported\n"); + return err; + } + /* * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up * with the software protection bits set diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 295583ed29..aae814f557 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -477,6 +477,7 @@ struct spi_flash { * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is * completely locked * @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode + * @octal_dtr_enable: [FLASH-SPECIFIC] enables SPI NOR octal DTR mode. * @priv: the private data */ struct spi_nor { @@ -524,6 +525,7 @@ struct spi_nor { int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len); int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len); int (*quad_enable)(struct spi_nor *nor); + int (*octal_dtr_enable)(struct spi_nor *nor); void *priv; /* Compatibility for spi_flash, remove once sf layer is merged with mtd */ From patchwork Fri Jun 25 19:17:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497414 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=GQyUyQkU; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRgt4RPfz9sW8 for ; Sat, 26 Jun 2021 05:21:30 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5341A82C72; Fri, 25 Jun 2021 21:19:21 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="GQyUyQkU"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 8D1D182C40; Fri, 25 Jun 2021 21:18:32 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 5FE0B82C33 for ; Fri, 25 Jun 2021 21:18:28 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJIQJt078545; Fri, 25 Jun 2021 14:18:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648706; bh=ZlIC4PVF/4GcuvazJnN72Vldru0/IrbNzE2pZvYWPv8=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=GQyUyQkUqx81AQfB2jgxUuRui+wzgfrycMgn/7KqaG3i9QrcV442kvzXro4RTvxi4 6B1OntYSk/2uCqVMvHsgiJhVlW3ivmw12cPJoQy/rvcaWATVpRhyplXM4KTQ0MFjI/ YJ9P8A88dBdw+RAXp8CIIbh+UUbUdnmTLAQ8fWSk= Received: from DLEE115.ent.ti.com (dlee115.ent.ti.com [157.170.170.26]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJIQ2V063776 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:26 -0500 Received: from DLEE110.ent.ti.com (157.170.170.21) 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.2176.2; Fri, 25 Jun 2021 14:18:26 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE110.ent.ti.com (157.170.170.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:26 -0500 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 15PJHURa076530; Fri, 25 Jun 2021 14:18:24 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 20/27] mtd: spi-nor-core: Do not make invalid quad enable fatal Date: Sat, 26 Jun 2021 00:47:22 +0530 Message-ID: <20210625191729.31798-21-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean The Micron MT35XU512ABA flash does not support the quad enable bit. But instead of programming the Quad Enable Require field to 000b ("Device does not have a QE bit"), it is programmed to 111b ("Reserved"). While this is technically incorrect, it is not reason enough to abort BFPT parsing. Instead, continue BFPT parsing assuming there is no quad enable bit present. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/spi-nor-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index cdb464813b..b5b1ac8b5b 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -2100,7 +2100,8 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, break; #endif default: - return -EINVAL; + dev_dbg(nor->dev, "BFPT QER reserved value used\n"); + break; } /* Stop here if JESD216 rev B. */ From patchwork Fri Jun 25 19:17:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497415 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=iqiP/UIn; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRh41kQFz9sWQ for ; Sat, 26 Jun 2021 05:21:39 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id CB86482C7C; Fri, 25 Jun 2021 21:19:25 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="iqiP/UIn"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 993F682C4C; Fri, 25 Jun 2021 21:18:35 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 205A282C3F for ; Fri, 25 Jun 2021 21:18:31 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJITSm078567; Fri, 25 Jun 2021 14:18:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648709; bh=RE1+fj+ORT+Vr0TAOSstPAdxyNbOKlrZL5JWnGyV97I=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=iqiP/UIngJ1GJxxoohO5JTeyh+TKzRolRZ6eWE6EwaM3SkLJrPFYWzqYAEj1Wtyj3 ffb+yH9sRUsHBVyeaG57r9NZWPySBwwaurLl6uo1IDAd/d0RHs3YEKtjuMeI/y415v ey+Nku63ZyveYL4R6v0LlIhjAQsjy43nZaKoNxAM= Received: from DLEE102.ent.ti.com (dlee102.ent.ti.com [157.170.170.32]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJIT7M123781 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:29 -0500 Received: from DLEE109.ent.ti.com (157.170.170.41) by DLEE102.ent.ti.com (157.170.170.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2; Fri, 25 Jun 2021 14:18:29 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE109.ent.ti.com (157.170.170.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:29 -0500 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 15PJHURb076530; Fri, 25 Jun 2021 14:18:27 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 21/27] mtd: spi-nor-core: Detect Soft Reset sequence support from BFPT Date: Sat, 26 Jun 2021 00:47:23 +0530 Message-ID: <20210625191729.31798-22-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean A Soft Reset sequence will return the flash to Power-on-Reset (POR) state. It consists of two commands: Soft Reset Enable and Soft Reset. Find out if the sequence is supported from BFPT DWORD 16. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/spi-nor-core.c | 6 ++++++ include/linux/mtd/spi-nor.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index b5b1ac8b5b..0d38ffc4f3 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -153,6 +153,8 @@ struct sfdp_header { #define BFPT_DWORD15_QER_SR2_BIT1_NO_RD (0x4UL << 20) #define BFPT_DWORD15_QER_SR2_BIT1 (0x5UL << 20) /* Spansion */ +#define BFPT_DWORD16_SOFT_RST BIT(12) + #define BFPT_DWORD18_CMD_EXT_MASK GENMASK(30, 29) #define BFPT_DWORD18_CMD_EXT_REP (0x0UL << 29) /* Repeat */ #define BFPT_DWORD18_CMD_EXT_INV (0x1UL << 29) /* Invert */ @@ -2104,6 +2106,10 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, break; } + /* Soft Reset support. */ + if (bfpt.dwords[BFPT_DWORD(16)] & BFPT_DWORD16_SOFT_RST) + nor->flags |= SNOR_F_SOFT_RESET; + /* Stop here if JESD216 rev B. */ if (bfpt_header->length == BFPT_DWORD_MAX_JESD216B) return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index aae814f557..b2159f6319 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -248,6 +248,7 @@ enum spi_nor_option_flags { SNOR_F_READY_XSR_RDY = BIT(4), SNOR_F_USE_CLSR = BIT(5), SNOR_F_BROKEN_RESET = BIT(6), + SNOR_F_SOFT_RESET = BIT(7), }; struct spi_nor; From patchwork Fri Jun 25 19:17:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497416 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=GYl4a6TN; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRhG2l75z9sW8 for ; Sat, 26 Jun 2021 05:21:50 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 9212B82C7E; Fri, 25 Jun 2021 21:19:29 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="GYl4a6TN"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 26B5F82C40; Fri, 25 Jun 2021 21:18:40 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id C218A82C3C for ; Fri, 25 Jun 2021 21:18:33 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJIWN5078619; Fri, 25 Jun 2021 14:18:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648712; bh=3b0paAay6lG91/QHf36Au120yClAQfFwt0IafSdDbuE=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=GYl4a6TNgK9I8uv9szlwuktpu935qm5W7hJ87oVTzXs00LvuSurx4Hit2LyRu+EyC vd5YUVpVh5vVT7snl/ks6lvnSFC7vEq3fKl7cY4jc5qr5qnfUfQf5VUG38cz9wh/X7 MYB7XKJa9QbfdmBaobB1fcGloIXDlFsY/3pnlki0= Received: from DLEE109.ent.ti.com (dlee109.ent.ti.com [157.170.170.41]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJIWqM063854 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:32 -0500 Received: from DLEE104.ent.ti.com (157.170.170.34) by DLEE109.ent.ti.com (157.170.170.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2; Fri, 25 Jun 2021 14:18:31 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE104.ent.ti.com (157.170.170.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:32 -0500 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 15PJHURc076530; Fri, 25 Jun 2021 14:18:29 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 22/27] mtd: spi-nor-core: Perform a Soft Reset on shutdown Date: Sat, 26 Jun 2021 00:47:24 +0530 Message-ID: <20210625191729.31798-23-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean On probe, the SPI NOR core will put a flash in 8D-8D-8D mode if it supports it. But Linux as of now expects to get the flash in 1S-1S-1S mode. Handing the flash to Linux in Octal DTR mode means the kernel will fail to detect the flash. So, we need to reset to Power-on-Reset (POR) state before handing off the flash. A Software Reset command can be used to do this. One limitation of the soft reset is that it will restore state from non-volatile registers in some flashes. This means that if the flash was set to 8D mode in a non-volatile configuration, a soft reset won't help. This commit assumes that we don't set any non-volatile bits anywhere, and the flash doesn't have any non-volatile Octal DTR mode configuration. Since spi-nor-tiny doesn't (and likely shouldn't) have spi_nor_soft_reset(), add a dummy spi_nor_remove() for it that does nothing. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/Kconfig | 7 ++++ drivers/mtd/spi/sf_probe.c | 6 +++ drivers/mtd/spi/spi-nor-core.c | 68 ++++++++++++++++++++++++++++++++++ include/linux/mtd/spi-nor.h | 17 +++++++++ 4 files changed, 98 insertions(+) diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index a701167dcc..185ebbeb02 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -97,6 +97,13 @@ config SPI_FLASH_SMART_HWCAPS can support a type of operation in a much more refined way compared to using flags like SPI_RX_DUAL, SPI_TX_QUAD, etc. +config SPI_FLASH_SOFT_RESET + bool "Software Reset support for SPI NOR flashes" + default n + help + Enable support for xSPI Software Reset. It will be used to switch from + Octal DTR mode to legacy mode on shutdown and boot (if enabled). + config SPI_FLASH_BAR bool "SPI flash Bank/Extended address register support" help diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 7edb8759fd..f461082e03 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -151,6 +151,11 @@ int spi_flash_std_probe(struct udevice *dev) static int spi_flash_std_remove(struct udevice *dev) { struct spi_flash *flash = dev_get_uclass_priv(dev); + int ret; + + ret = spi_nor_remove(flash); + if (ret) + return ret; if (CONFIG_IS_ENABLED(SPI_FLASH_MTD)) spi_flash_mtd_unregister(flash); @@ -178,6 +183,7 @@ U_BOOT_DRIVER(jedec_spi_nor) = { .remove = spi_flash_std_remove, .priv_auto = sizeof(struct spi_nor), .ops = &spi_flash_std_ops, + .flags = DM_FLAG_OS_PREPARE, }; DM_DRIVER_ALIAS(jedec_spi_nor, spansion_m25p16) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 0d38ffc4f3..642068a4e2 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -200,6 +201,8 @@ struct spi_nor_fixups { struct spi_nor_flash_parameter *params); }; +#define SPI_NOR_SRST_SLEEP_LEN 200 + /** * spi_nor_get_cmd_ext() - Get the command opcode extension based on the * extension type. @@ -2971,6 +2974,71 @@ static int spi_nor_init(struct spi_nor *nor) return 0; } +#ifdef CONFIG_SPI_FLASH_SOFT_RESET +/** + * spi_nor_soft_reset() - perform the JEDEC Software Reset sequence + * @nor: the spi_nor structure + * + * This function can be used to switch from Octal DTR mode to legacy mode on a + * flash that supports it. The soft reset is executed in Octal DTR mode. + * + * Return: 0 for success, -errno for failure. + */ +static int spi_nor_soft_reset(struct spi_nor *nor) +{ + struct spi_mem_op op; + int ret; + enum spi_nor_cmd_ext ext; + + ext = nor->cmd_ext_type; + nor->cmd_ext_type = SPI_NOR_EXT_REPEAT; + + op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_SRSTEN, 0), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DATA); + spi_nor_setup_op(nor, &op, SNOR_PROTO_8_8_8_DTR); + ret = spi_mem_exec_op(nor->spi, &op); + if (ret) { + dev_warn(nor->dev, "Software reset enable failed: %d\n", ret); + goto out; + } + + op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_SRST, 0), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DATA); + spi_nor_setup_op(nor, &op, SNOR_PROTO_8_8_8_DTR); + ret = spi_mem_exec_op(nor->spi, &op); + if (ret) { + dev_warn(nor->dev, "Software reset failed: %d\n", ret); + goto out; + } + + /* + * Software Reset is not instant, and the delay varies from flash to + * flash. Looking at a few flashes, most range somewhere below 100 + * microseconds. So, wait for 200ms just to be sure. + */ + udelay(SPI_NOR_SRST_SLEEP_LEN); + +out: + nor->cmd_ext_type = ext; + return ret; +} +#endif /* CONFIG_SPI_FLASH_SOFT_RESET */ + +int spi_nor_remove(struct spi_nor *nor) +{ +#ifdef CONFIG_SPI_FLASH_SOFT_RESET + if (nor->info->flags & SPI_NOR_OCTAL_DTR_READ && + nor->flags & SNOR_F_SOFT_RESET) + return spi_nor_soft_reset(nor); +#endif + + return 0; +} + void spi_nor_set_fixups(struct spi_nor *nor) { } diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index b2159f6319..29ce175156 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -67,6 +67,8 @@ #define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */ #define SPINOR_OP_RDEAR 0xc8 /* Read Extended Address Register */ #define SPINOR_OP_WREAR 0xc5 /* Write Extended Address Register */ +#define SPINOR_OP_SRSTEN 0x66 /* Software Reset Enable */ +#define SPINOR_OP_SRST 0x99 /* Software Reset */ /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ #define SPINOR_OP_READ_4B 0x13 /* Read data bytes (low frequency) */ @@ -562,4 +564,19 @@ device_node *spi_nor_get_flash_node(struct spi_nor *nor) */ int spi_nor_scan(struct spi_nor *nor); +#if CONFIG_IS_ENABLED(SPI_FLASH_TINY) +static inline int spi_nor_remove(struct spi_nor *nor) +{ + return 0; +} +#else +/** + * spi_nor_remove() - perform cleanup before booting to the next stage + * @nor: the spi_nor structure + * + * Return: 0 for success, -errno for failure. + */ +int spi_nor_remove(struct spi_nor *nor); +#endif + #endif From patchwork Fri Jun 25 19:17:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497417 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=HvWIp5tS; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRhR2mHfz9sW8 for ; Sat, 26 Jun 2021 05:21:59 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 4563A82C83; Fri, 25 Jun 2021 21:19:32 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="HvWIp5tS"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 1183D82C47; Fri, 25 Jun 2021 21:18:45 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 58BAA82C48 for ; Fri, 25 Jun 2021 21:18:36 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJIYJw078697; Fri, 25 Jun 2021 14:18:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648714; bh=FQMDnKgZZ1y4P2u77DRcTxkqsVMtT+A6nnEXK1teRDE=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=HvWIp5tSoUkCq6eT9W8lhbJgSxEnXJhFxJYOs19WqCsYpv8YTNiPOTUcT7LiuLLsX yNSYtA8DH1s/hUo8KCTjs09YhVOVFd01xUTHYQ6b6gwfumEnF8zf7YoTU5E8edvwCi TkADIjiXAaVhqNBQLH0hV2DZVGcpOVTO5QSROL2E= 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 15PJIY8V049668 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:34 -0500 Received: from DFLE101.ent.ti.com (10.64.6.22) 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.2176.2; Fri, 25 Jun 2021 14:18:34 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DFLE101.ent.ti.com (10.64.6.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:34 -0500 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 15PJHURd076530; Fri, 25 Jun 2021 14:18:32 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 23/27] mtd: spi-nor-core: Perform a Soft Reset on boot Date: Sat, 26 Jun 2021 00:47:25 +0530 Message-ID: <20210625191729.31798-24-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean When the flash is handed to us in a stateful mode like 8D-8D-8D, it is difficult to detect the mode the flash is in. One option is to read SFDP in all modes and see which one gives the correct "SFDP" signature, but not all flashes support SFDP in 8D-8D-8D mode. Further, even if you detect the mode of the flash via SFDP, you still have the problem of actually reading the ID. The Read ID command is not standardized across flash vendors. Flashes can have different dummy cycles needed for reading the ID. Some flashes even expect a 4-byte dummy address with the Read ID command. All this information cannot be obtained from the SFDP table. So, perform a Software Reset sequence before reading the ID and initializing the flash. A Soft Reset will bring back the flash in its default protocol mode assuming no non-volatile configuration was set. This will let us detect the flash even if ROM hands it to us in Octal DTR mode. To accommodate cases where there is more than one flash on a board, and only one of them needs a soft reset, failure to reset is not made fatal, and we still try to read ID if possible. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/Kconfig | 10 ++++++++++ drivers/mtd/spi/spi-nor-core.c | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index 185ebbeb02..b46035aee4 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -104,6 +104,16 @@ config SPI_FLASH_SOFT_RESET Enable support for xSPI Software Reset. It will be used to switch from Octal DTR mode to legacy mode on shutdown and boot (if enabled). +config SPI_FLASH_SOFT_RESET_ON_BOOT + bool "Perform a Software Reset on boot on flashes that boot in stateful mode" + depends on SPI_FLASH_SOFT_RESET + default n + help + Perform a Software Reset on boot to allow detecting flashes that are + handed to us in Octal DTR mode. Do not enable this config on flashes + that are not supposed to be handed to U-Boot in Octal DTR mode, even + if they _do_ support the Soft Reset sequence. + config SPI_FLASH_BAR bool "SPI flash Bank/Extended address register support" help diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 642068a4e2..3bf9404490 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -3062,6 +3062,33 @@ int spi_nor_scan(struct spi_nor *nor) nor->setup = spi_nor_default_setup; +#ifdef CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT + /* + * When the flash is handed to us in a stateful mode like 8D-8D-8D, it + * is difficult to detect the mode the flash is in. One option is to + * read SFDP in all modes and see which one gives the correct "SFDP" + * signature, but not all flashes support SFDP in 8D-8D-8D mode. + * + * Further, even if you detect the mode of the flash via SFDP, you + * still have the problem of actually reading the ID. The Read ID + * command is not standardized across flash vendors. Flashes can have + * different dummy cycles needed for reading the ID. Some flashes even + * expect a 4-byte dummy address with the Read ID command. All this + * information cannot be obtained from the SFDP table. + * + * So, perform a Software Reset sequence before reading the ID and + * initializing the flash. A Soft Reset will bring back the flash in + * its default protocol mode assuming no non-volatile configuration was + * set. This will let us detect the flash even if ROM hands it to us in + * Octal DTR mode. + * + * To accommodate cases where there is more than one flash on a board, + * and only one of them needs a soft reset, failure to reset is not + * made fatal, and we still try to read ID if possible. + */ + spi_nor_soft_reset(nor); +#endif /* CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT */ + info = spi_nor_read_id(nor); if (IS_ERR_OR_NULL(info)) return -ENOENT; From patchwork Fri Jun 25 19:17:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497419 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=aD4nrtL7; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRhp258Vz9sW8 for ; Sat, 26 Jun 2021 05:22:18 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D292F82C91; Fri, 25 Jun 2021 21:19:37 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="aD4nrtL7"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 2930B82C4F; Fri, 25 Jun 2021 21:18:50 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 6643982C42 for ; Fri, 25 Jun 2021 21:18:39 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJIbnr078800; Fri, 25 Jun 2021 14:18:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648717; bh=5NUKpMj1OvRlYBn7htdjN/7qY/9PhRCdb42jGnz0XYI=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=aD4nrtL7e6b+NEnzIw2FCDVnlUgbpVzcmxOkS8qUVUWps42baZZc9dWjSwSdh5r64 CDn14gZI8/kA839gj0WO9iJR+3MtHP2b/L9VSe+PDEJQSbdkQ+5Yy6bv9kBVhyvUeA G0NA365LLYadL0puzqGGSdYFWsUeeXW2TmPIB+Tg= 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 15PJIbGf049740 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:37 -0500 Received: from DLEE100.ent.ti.com (157.170.170.30) 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.2176.2; Fri, 25 Jun 2021 14:18:37 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE100.ent.ti.com (157.170.170.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:37 -0500 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 15PJHURe076530; Fri, 25 Jun 2021 14:18:35 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 24/27] mtd: spi-nor-core: allow truncated erases Date: Sat, 26 Jun 2021 00:47:26 +0530 Message-ID: <20210625191729.31798-25-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean On devices with non-uniform sector sizes like Spansion S25 or S28 family of flashes the sector under erase does not necessarily have to be mtd->erasesize bytes long. For example, on S28 flashes the first 128 KiB region is composed of 32 4 KiB sectors, then a 128 KiB sector, and then 256 KiB sectors till the end. Let the flash-specific erase functions erase less than the requested length in case of the 4 or 128 KiB sectors and report the number of bytes erased back to the calling function. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/spi-nor-core.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 3bf9404490..ece4bc9e84 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -806,7 +806,8 @@ static int read_bar(struct spi_nor *nor, const struct flash_info *info) #endif /* - * Initiate the erasure of a single sector + * Initiate the erasure of a single sector. Returns the number of bytes erased + * on success, a negative error code on error. */ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) { @@ -815,6 +816,7 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) SPI_MEM_OP_ADDR(nor->addr_width, addr, 0), SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_NO_DATA); + int ret; spi_nor_setup_op(nor, &op, nor->write_proto); @@ -825,7 +827,11 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) * Default implementation, if driver doesn't have a specialized HW * control */ - return spi_mem_exec_op(nor->spi, &op); + ret = spi_mem_exec_op(nor->spi, &op); + if (ret) + return ret; + + return nor->mtd.erasesize; } /* @@ -861,11 +867,11 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) write_enable(nor); ret = spi_nor_erase_sector(nor, addr); - if (ret) + if (ret < 0) goto erase_err; - addr += mtd->erasesize; - len -= mtd->erasesize; + addr += ret; + len -= ret; ret = spi_nor_wait_till_ready(nor); if (ret) From patchwork Fri Jun 25 19:17:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497418 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=GYMPK3nT; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRhc6yTDz9sWQ for ; Sat, 26 Jun 2021 05:22:08 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id CF9CA82C88; Fri, 25 Jun 2021 21:19:34 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="GYMPK3nT"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 6185282C54; Fri, 25 Jun 2021 21:18:46 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 9C8A382C0A for ; Fri, 25 Jun 2021 21:18:41 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJIem6078862; Fri, 25 Jun 2021 14:18:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648720; bh=/05Qxl8UuOUWUIEKFuRBhSrDowFyOwdjQEPMgv4zRKQ=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=GYMPK3nTAFm0DpW9jFxHpX3Odh/bN1TIJa6ACJzv8H5Y/PbLBAs2MeYq/fxpwcFBw AeSAVRGyt9xDwvs853R5WeEt+16KvWFucywBwRZJQOZz7BfnJc41a2kU5fmC0pjwYk oFfFxFaVkgRvb3fkmVS43JnwDJjUtWs0W5+RDets= Received: from DLEE114.ent.ti.com (dlee114.ent.ti.com [157.170.170.25]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJIeit024119 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:40 -0500 Received: from DLEE108.ent.ti.com (157.170.170.38) by DLEE114.ent.ti.com (157.170.170.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2; Fri, 25 Jun 2021 14:18:40 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:39 -0500 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 15PJHURf076530; Fri, 25 Jun 2021 14:18:37 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 25/27] mtd: spi-nor-core: Add non-uniform erase for Spansion/Cypress Date: Sat, 26 Jun 2021 00:47:27 +0530 Message-ID: <20210625191729.31798-26-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean From: Takahiro Kuwano Some of Spansion/Cypress chips have overlaid 4KB sectors at top and/or bottom, depending on the device configuration, while U-Boot supports uniform sector layout only. The spansion_erase_non_uniform() erases overlaid 4KB sectors, non-overlaid portion of normal sector, and remaining normal sectors, by selecting correct erase command and size based on the address to erase and size of overlaid portion in parameters. Since different Spansion flashes can use different opcode for erasing the 4K sectors, the opcode must be passed in as a parameter based on the flash being used. Signed-off-by: Takahiro Kuwano Signed-off-by: Pratyush Yadav [p.yadav@ti.com: Refactor the function to be compatible with nor->erase, make 4K opcode customizable, call spi_nor_setup_op() before executing the op.] --- drivers/mtd/spi/spi-nor-core.c | 61 ++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index ece4bc9e84..f2354fea7f 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -887,6 +887,67 @@ erase_err: return ret; } +#ifdef CONFIG_SPI_FLASH_S28HS512T +/** + * spansion_erase_non_uniform() - erase non-uniform sectors for Spansion/Cypress + * chips + * @nor: pointer to a 'struct spi_nor' + * @addr: address of the sector to erase + * @opcode_4k: opcode for 4K sector erase + * @ovlsz_top: size of overlaid portion at the top address + * @ovlsz_btm: size of overlaid portion at the bottom address + * + * Erase an address range on the nor chip that can contain 4KB sectors overlaid + * on top and/or bottom. The appropriate erase opcode and size are chosen by + * address to erase and size of overlaid portion. + * + * Return: number of bytes erased on success, -errno otherwise. + */ +static int spansion_erase_non_uniform(struct spi_nor *nor, u32 addr, + u8 opcode_4k, u32 ovlsz_top, + u32 ovlsz_btm) +{ + struct spi_mem_op op = + SPI_MEM_OP(SPI_MEM_OP_CMD(nor->erase_opcode, 0), + SPI_MEM_OP_ADDR(nor->addr_width, addr, 0), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_NO_DATA); + struct mtd_info *mtd = &nor->mtd; + u32 erasesize; + int ret; + + /* 4KB sectors */ + if (op.addr.val < ovlsz_btm || + op.addr.val >= mtd->size - ovlsz_top) { + op.cmd.opcode = opcode_4k; + erasesize = SZ_4K; + + /* Non-overlaid portion in the normal sector at the bottom */ + } else if (op.addr.val == ovlsz_btm) { + op.cmd.opcode = nor->erase_opcode; + erasesize = mtd->erasesize - ovlsz_btm; + + /* Non-overlaid portion in the normal sector at the top */ + } else if (op.addr.val == mtd->size - mtd->erasesize) { + op.cmd.opcode = nor->erase_opcode; + erasesize = mtd->erasesize - ovlsz_top; + + /* Normal sectors */ + } else { + op.cmd.opcode = nor->erase_opcode; + erasesize = mtd->erasesize; + } + + spi_nor_setup_op(nor, &op, nor->write_proto); + + ret = spi_mem_exec_op(nor->spi, &op); + if (ret) + return ret; + + return erasesize; +} +#endif + #if defined(CONFIG_SPI_FLASH_STMICRO) || defined(CONFIG_SPI_FLASH_SST) /* Write status register and ensure bits in mask match written values */ static int write_sr_and_check(struct spi_nor *nor, u8 status_new, u8 mask) From patchwork Fri Jun 25 19:17:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497420 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=anVXK1qe; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRhz6QVBz9sW8 for ; Sat, 26 Jun 2021 05:22:27 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id F06D882C8A; Fri, 25 Jun 2021 21:19:40 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="anVXK1qe"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id B998782C47; Fri, 25 Jun 2021 21:18:50 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 599DB82C40 for ; Fri, 25 Jun 2021 21:18:44 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJIguZ128884; Fri, 25 Jun 2021 14:18:42 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648722; bh=q81NJnRbXczWq7URpoBfJ5SVCfrc47c2RzxlU4nOUjQ=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=anVXK1qeQv5VaOPKYDFGGgmD6KSBqAfBlrMR11LoHtIpk2Gup0Sn7J7AJXyuCS/zK zszpM6lu2BhmCtxWVS4PUAMUI3hrJW9KCsqbjmfoWk+yXsVTBVFTJnBFkLYuBNZ0iS qXR/xpp140L/7zkclgRDmCNShAflrlCk2nKGuwb8= Received: from DLEE106.ent.ti.com (dlee106.ent.ti.com [157.170.170.36]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 15PJIg2B024163 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:42 -0500 Received: from DLEE110.ent.ti.com (157.170.170.21) by DLEE106.ent.ti.com (157.170.170.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2; Fri, 25 Jun 2021 14:18:42 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE110.ent.ti.com (157.170.170.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:42 -0500 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 15PJHURg076530; Fri, 25 Jun 2021 14:18:40 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 26/27] mtd: spi-nor-core: Add support for Cypress Semper flash Date: Sat, 26 Jun 2021 00:47:28 +0530 Message-ID: <20210625191729.31798-27-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean 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/Kconfig | 8 ++ drivers/mtd/spi/spi-nor-core.c | 187 +++++++++++++++++++++++++++++++++ drivers/mtd/spi/spi-nor-ids.c | 3 + include/linux/mtd/spi-nor.h | 13 +++ 4 files changed, 211 insertions(+) diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index b46035aee4..98c0b23478 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -167,6 +167,14 @@ config SPI_FLASH_SPANSION help Add support for various Spansion SPI flash chips (S25FLxxx) +config SPI_FLASH_S28HS512T + bool "Cypress S28HS512T chip support" + depends on SPI_FLASH_SPANSION + help + Add support for the Cypress S28HS512T chip. This is a separate config + because the fixup hooks for this flash add extra size overhead. Boards + that don't use the flash can disable this to save space. + config SPI_FLASH_STMICRO bool "STMicro SPI flash support" help diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index f2354fea7f..3a1060b04b 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -2965,6 +2965,189 @@ static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info, return nor->setup(nor, info, params); } +#ifdef CONFIG_SPI_FLASH_S28HS512T +/** + * spi_nor_cypress_octal_dtr_enable() - Enable octal DTR on Cypress flashes. + * @nor: pointer to a 'struct spi_nor' + * + * This also sets the memory access latency cycles to 24 to allow the flash to + * run at up to 200MHz. + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor) +{ + struct spi_mem_op op; + u8 buf; + u8 addr_width = 3; + int ret; + + /* Use 24 dummy cycles for memory array reads. */ + ret = write_enable(nor); + if (ret) + return ret; + + buf = SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24; + 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->spi, &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 = 24; + + /* Set the octal and DTR enable bits. */ + ret = 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->spi, &op); + if (ret) { + dev_warn(nor->dev, "Failed to enable octal DTR mode\n"); + return ret; + } + + return 0; +} + +static int s28hs512t_erase_non_uniform(struct spi_nor *nor, loff_t addr) +{ + /* Factory default configuration: 32 x 4 KiB sectors at bottom. */ + return spansion_erase_non_uniform(nor, addr, SPINOR_OP_S28_SE_4K, + 0, SZ_128K); +} + +static int s28hs512t_setup(struct spi_nor *nor, const struct flash_info *info, + const struct spi_nor_flash_parameter *params) +{ + struct spi_mem_op op; + u8 buf; + u8 addr_width = 3; + int ret; + + ret = spi_nor_wait_till_ready(nor); + if (ret) + return ret; + + /* + * Check CFR3V to check if non-uniform sector mode is selected. If it + * is, set the erase hook to the non-uniform erase procedure. + */ + 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->spi, &op); + if (ret) + return ret; + + if (!(buf & SPINOR_REG_CYPRESS_CFR3V_UNISECT)) + nor->erase = s28hs512t_erase_non_uniform; + + return spi_nor_default_setup(nor, info, params); +} + +static void s28hs512t_default_init(struct spi_nor *nor) +{ + nor->octal_dtr_enable = spi_nor_cypress_octal_dtr_enable; + nor->setup = s28hs512t_setup; +} + +static void s28hs512t_post_sfdp_fixup(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + /* + * 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 (params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode == 0) + params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode = + SPINOR_OP_CYPRESS_RD_FAST; + + params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR; + + /* This flash is also missing the 4-byte Page Program opcode bit. */ + spi_nor_set_pp_settings(¶ms->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(¶ms->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. + */ + 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; + 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->spi, &op); + if (ret) + return ret; + + if (buf & SPINOR_REG_CYPRESS_CFR3V_PGSZ) + params->page_size = 512; + else + params->page_size = 256; + + /* + * The BFPT advertises that it supports 4k erases, and the datasheet + * says the same. But 4k erases did not work when testing. So, use 256k + * erases for now. + */ + nor->erase_opcode = SPINOR_OP_SE_4B; + nor->mtd.erasesize = 0x40000; + + 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, +}; +#endif /* CONFIG_SPI_FLASH_S28HS512T */ + /** spi_nor_octal_dtr_enable() - enable Octal DTR I/O if needed * @nor: pointer to a 'struct spi_nor' * @@ -3108,6 +3291,10 @@ int spi_nor_remove(struct spi_nor *nor) void spi_nor_set_fixups(struct spi_nor *nor) { +#ifdef CONFIG_SPI_FLASH_S28HS512T + if (!strcmp(nor->info->name, "s28hs512t")) + nor->fixups = &s28hs512t_fixups; +#endif } int spi_nor_scan(struct spi_nor *nor) diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c index 8d2b73b676..bbed88a4b7 100644 --- a/drivers/mtd/spi/spi-nor-ids.c +++ b/drivers/mtd/spi/spi-nor-ids.c @@ -223,6 +223,9 @@ const struct flash_info spi_nor_ids[] = { { INFO("s25fl208k", 0x014014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) }, { INFO("s25fl064l", 0x016017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, { INFO("s25fl128l", 0x016018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, +#ifdef CONFIG_SPI_FLASH_S28HS512T + { INFO("s28hs512t", 0x345b1a, 0, 256 * 1024, 256, SPI_NOR_OCTAL_DTR_READ) }, +#endif #endif #ifdef CONFIG_SPI_FLASH_SST /* SST */ /* SST -- large erase sizes are "overlays", "sectors" are 4K */ diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 29ce175156..6ece401b37 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -157,6 +157,19 @@ /* Status Register 2 bits. */ #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_OP_S28_SE_4K 0x21 +#define SPINOR_REG_CYPRESS_CFR2V 0x00800003 +#define SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24 0xb +#define SPINOR_REG_CYPRESS_CFR3V 0x00800004 +#define SPINOR_REG_CYPRESS_CFR3V_PGSZ BIT(4) /* Page size. */ +#define SPINOR_REG_CYPRESS_CFR3V_UNISECT BIT(3) /* Uniform sector mode */ +#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 From patchwork Fri Jun 25 19:17:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1497421 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=zR+43fN1; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GBRjJ4vHPz9sW8 for ; Sat, 26 Jun 2021 05:22:44 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E4F5B82C1C; Fri, 25 Jun 2021 21:20:04 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="zR+43fN1"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id DE37682C48; Fri, 25 Jun 2021 21:18:55 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 0176D82C0A for ; Fri, 25 Jun 2021 21:18:46 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 15PJIjdX128957; Fri, 25 Jun 2021 14:18:45 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1624648725; bh=mrUtajmGkkBkHXyLH4Sn9ChiS6mSgLTp/WFxNQhrfOc=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=zR+43fN1eaGj2hZrW3sNDh8MEvjolzPDjBZssXa2JHaQ2F/7GHhloaHQ1Oe0ohgwz Sil5K32VTXNsnrTd2PZUgSuY5E0bTa17fGWFKYvwzUX1WSiR8zmmKI7TEZZSaKEOBb eiBljZYiroDXvcxQ1kjKkdfrM8lTKGM61R6lkgYs= 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 15PJIjGG049828 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 25 Jun 2021 14:18:45 -0500 Received: from DLEE105.ent.ti.com (157.170.170.35) 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.2176.2; Fri, 25 Jun 2021 14:18:45 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) 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.2176.2 via Frontend Transport; Fri, 25 Jun 2021 14:18:45 -0500 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 15PJHURh076530; Fri, 25 Jun 2021 14:18:43 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh R , Ryder Lee , Weijie Gao , Chunfeng Yun , GSS_MTK_Uboot_upstream , CC: Pratyush Yadav Subject: [PATCH v10 27/27] mtd: spi-nor-core: Allow using Micron mt35xu512aba in Octal DTR mode Date: Sat, 26 Jun 2021 00:47:29 +0530 Message-ID: <20210625191729.31798-28-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210625191729.31798-1-p.yadav@ti.com> References: <20210625191729.31798-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Since this flash doesn't have a Profile 1.0 table, the Octal DTR capabilities are enabled in the post SFDP fixup, along with the 8D-8D-8D fast read settings. Enable Octal DTR mode with 20 dummy cycles to allow running at the maximum supported frequency of 200Mhz. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/Kconfig | 8 ++++ drivers/mtd/spi/spi-nor-core.c | 87 ++++++++++++++++++++++++++++++++++ drivers/mtd/spi/spi-nor-ids.c | 4 +- include/linux/mtd/spi-nor.h | 6 +++ 4 files changed, 104 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index 98c0b23478..1b2ef37e92 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -180,6 +180,14 @@ config SPI_FLASH_STMICRO help Add support for various STMicro SPI flash chips (M25Pxxx and N25Qxxx) +config SPI_FLASH_MT35XU + bool "Micron MT35XU chip support" + depends on SPI_FLASH_STMICRO + help + Add support for the Micron MT35XU chip. This is a separate config + because the fixup hooks for this flash add extra size overhead. Boards + that don't use the flash can disable this to save space. + config SPI_FLASH_SST bool "SST SPI flash support" help diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 3a1060b04b..8dd44c0f1e 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -3148,6 +3148,88 @@ static struct spi_nor_fixups s28hs512t_fixups = { }; #endif /* CONFIG_SPI_FLASH_S28HS512T */ +#ifdef CONFIG_SPI_FLASH_MT35XU +static int spi_nor_micron_octal_dtr_enable(struct spi_nor *nor) +{ + struct spi_mem_op op; + u8 buf; + u8 addr_width = 3; + int ret; + + /* Set dummy cycles for Fast Read to the default of 20. */ + ret = write_enable(nor); + if (ret) + return ret; + + buf = 20; + op = (struct spi_mem_op) + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_MT_WR_ANY_REG, 1), + SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_MT_CFR1V, 1), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_OUT(1, &buf, 1)); + ret = spi_mem_exec_op(nor->spi, &op); + if (ret) + return ret; + + ret = spi_nor_wait_till_ready(nor); + if (ret) + return ret; + + nor->read_dummy = 20; + + ret = write_enable(nor); + if (ret) + return ret; + + buf = SPINOR_MT_OCT_DTR; + op = (struct spi_mem_op) + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_MT_WR_ANY_REG, 1), + SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_MT_CFR0V, 1), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_OUT(1, &buf, 1)); + ret = spi_mem_exec_op(nor->spi, &op); + if (ret) { + dev_err(nor->dev, "Failed to enable octal DTR mode\n"); + return ret; + } + + return 0; +} + +static void mt35xu512aba_default_init(struct spi_nor *nor) +{ + nor->octal_dtr_enable = spi_nor_micron_octal_dtr_enable; +} + +static void mt35xu512aba_post_sfdp_fixup(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + /* Set the Fast Read settings. */ + params->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8_DTR; + spi_nor_set_read_settings(¶ms->reads[SNOR_CMD_READ_8_8_8_DTR], + 0, 20, SPINOR_OP_MT_DTR_RD, + SNOR_PROTO_8_8_8_DTR); + + params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR; + + nor->cmd_ext_type = SPI_NOR_EXT_REPEAT; + params->rdsr_dummy = 8; + params->rdsr_addr_nbytes = 0; + + /* + * The BFPT quad enable field is set to a reserved value so the quad + * enable function is ignored by spi_nor_parse_bfpt(). Make sure we + * disable it. + */ + params->quad_enable = NULL; +} + +static struct spi_nor_fixups mt35xu512aba_fixups = { + .default_init = mt35xu512aba_default_init, + .post_sfdp = mt35xu512aba_post_sfdp_fixup, +}; +#endif /* CONFIG_SPI_FLASH_MT35XU */ + /** spi_nor_octal_dtr_enable() - enable Octal DTR I/O if needed * @nor: pointer to a 'struct spi_nor' * @@ -3295,6 +3377,11 @@ void spi_nor_set_fixups(struct spi_nor *nor) if (!strcmp(nor->info->name, "s28hs512t")) nor->fixups = &s28hs512t_fixups; #endif + +#ifdef CONFIG_SPI_FLASH_MT35XU + if (!strcmp(nor->info->name, "mt35xu512aba")) + nor->fixups = &mt35xu512aba_fixups; +#endif } int spi_nor_scan(struct spi_nor *nor) diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c index bbed88a4b7..59f2d3e4d6 100644 --- a/drivers/mtd/spi/spi-nor-ids.c +++ b/drivers/mtd/spi/spi-nor-ids.c @@ -193,7 +193,9 @@ const struct flash_info spi_nor_ids[] = { { INFO("n25q00a", 0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, { INFO("mt25ql01g", 0x21ba20, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, { INFO("mt25qu02g", 0x20bb22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, - { INFO("mt35xu512aba", 0x2c5b1a, 0, 128 * 1024, 512, USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) }, +#ifdef CONFIG_SPI_FLASH_MT35XU + { INFO("mt35xu512aba", 0x2c5b1a, 0, 128 * 1024, 512, USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES | SPI_NOR_OCTAL_DTR_READ) }, +#endif /* CONFIG_SPI_FLASH_MT35XU */ { INFO("mt35xu02g", 0x2c5b1c, 0, 128 * 1024, 2048, USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) }, #endif #ifdef CONFIG_SPI_FLASH_SPANSION /* SPANSION */ diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 6ece401b37..d68e48fd94 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -126,6 +126,12 @@ /* Used for Micron flashes only. */ #define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */ #define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */ +#define SPINOR_OP_MT_DTR_RD 0xfd /* Fast Read opcode in DTR mode */ +#define SPINOR_OP_MT_RD_ANY_REG 0x85 /* Read volatile register */ +#define SPINOR_OP_MT_WR_ANY_REG 0x81 /* Write volatile register */ +#define SPINOR_REG_MT_CFR0V 0x00 /* For setting octal DTR mode */ +#define SPINOR_REG_MT_CFR1V 0x01 /* For setting dummy cycles */ +#define SPINOR_MT_OCT_DTR 0xe7 /* Enable Octal DTR with DQS. */ /* Status Register bits. */ #define SR_WIP BIT(0) /* Write in progress */