From patchwork Thu Mar 11 19:12: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: 1451474 X-Patchwork-Delegate: tudor.ambarus@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; helo=desiato.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=desiato.20200630 header.b=Ltyplzkh; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=E+B4oiSt; dkim-atps=neutral Received: from desiato.infradead.org (desiato.infradead.org [IPv6:2001:8b0:10b:1:d65d:64ff:fe57:4e05]) (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 4DxJWd31dXz9sCD for ; Fri, 12 Mar 2021 06:13:33 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:CC:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=OMNqLZUzOY7ZcN+MaFXg8mNEh1Lh3QRhHbNGprwQJD4=; b=Ltyplzkh+27Q1Myi/rFZ6Whcv UdBW+aVTwFphpBLbkwX3SbnIU8aQTMg18ebJOqFgYv468cP6amRYThAF+ZfG1fk8jjXhr1OrxYVDD 5GUjLp0tMBPRV9QfpZuNifxytGN1ngEh2+Sg2kpPxPCwihwG5jIapoJUPV0AMQptBF60lp1gfYn2g chbOv2tgpGgMnW7eZvrs0SYdmWRhsTX46pH02Mcj9JxebfcSv21/lwdsWJuV4H7reQD3le/43Vkmr BNop370z+9K9C3LoYa6VV1jWkS6nyjQ0rjUJLTQjVrLkts/wajK04V45KHEaJIxwKm0GAXC4Pjqh0 0vMDX8nWA==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lKQjv-009wlK-So; Thu, 11 Mar 2021 19:12:55 +0000 Received: from fllv0016.ext.ti.com ([198.47.19.142]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lKQjY-009whf-63; Thu, 11 Mar 2021 19:12:34 +0000 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 12BJCR4m072855; Thu, 11 Mar 2021 13:12:27 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1615489947; bh=TFMbG/HskxSKnHoLH+CdmpXxIxc/DBKy8fugLnBgIIQ=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=E+B4oiStGriEF7CnmhCLKl4uVexnuAYuBP7aDkkQqhdRG6jso4Mr3ZEurqVwyHFiL lOViZaAKaRcUmjN+ZT1nB0QOKE5F3L8ZaM9Nx074O2kYxalzXFHnNcyMEMkJi1oBD8 Zyi6ScQdJ2/mOOgI96rf6NR0I+j7kh1SxSTqcOmg= Received: from DLEE114.ent.ti.com (dlee114.ent.ti.com [157.170.170.25]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 12BJCQaS110401 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 11 Mar 2021 13:12:26 -0600 Received: from DLEE103.ent.ti.com (157.170.170.33) 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; Thu, 11 Mar 2021 13:12:26 -0600 Received: from fllv0039.itg.ti.com (10.64.41.19) 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; Thu, 11 Mar 2021 13:12:26 -0600 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by fllv0039.itg.ti.com (8.15.2/8.15.2) with ESMTP id 12BJCHvS080816; Thu, 11 Mar 2021 13:12:22 -0600 From: Pratyush Yadav To: Nishanth Menon , Tero Kristo , Rob Herring , Tudor Ambarus , Michael Walle , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mark Brown , , , , , CC: Pratyush Yadav , Lokesh Vutla Subject: [RFC PATCH 1/6] spi: spi-mem: Tell controller when device is ready for calibration Date: Fri, 12 Mar 2021 00:42:11 +0530 Message-ID: <20210311191216.7363-2-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210311191216.7363-1-p.yadav@ti.com> References: <20210311191216.7363-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210311_191232_555453_42AEEA00 X-CRM114-Status: GOOD ( 18.01 ) X-Spam-Score: -2.8 (--) X-Spam-Report: Spam detection software, running on the system "desiato.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Some controllers like the Cadence OSPI controller need to perform a calibration sequence to operate at high clock speeds. This calibration should happen after the flash is fully initialized otherwise [...] Content analysis details: (-2.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [198.47.19.142 listed in wl.mailspike.net] -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [198.47.19.142 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders -0.3 DKIMWL_WL_HIGH DKIMwl.org - High trust sender X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Some controllers like the Cadence OSPI controller need to perform a calibration sequence to operate at high clock speeds. This calibration should happen after the flash is fully initialized otherwise the calibration might happen in a different SPI mode from the one the flash is finally set to. Add a hook that can be used to tell the controller when the flash is ready for calibration. Whether calibration is needed depends on the controller. Signed-off-by: Pratyush Yadav --- drivers/spi/spi-mem.c | 12 ++++++++++++ include/linux/spi/spi-mem.h | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index dc713b0c3c4d..e2f05ad3f4dc 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -464,6 +464,18 @@ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) } EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size); +int spi_mem_do_calibration(struct spi_mem *mem, struct spi_mem_op *op) +{ + struct spi_controller *ctlr = mem->spi->controller; + + if (!ctlr->mem_ops || !ctlr->mem_ops->do_calibration) + return -EOPNOTSUPP; + + ctlr->mem_ops->do_calibration(mem, op); + return 0; +} +EXPORT_SYMBOL_GPL(spi_mem_do_calibration); + static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, void *buf) { diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 2b65c9edc34e..97a2d280f2d0 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -250,6 +250,12 @@ static inline void *spi_mem_get_drvdata(struct spi_mem *mem) * the currently mapped area), and the caller of * spi_mem_dirmap_write() is responsible for calling it again in * this case. + * @do_calibration: perform calibration needed for high SPI clock speed + * operation. Should be called after the SPI memory device has + * been completely initialized. The op passed should contain + * a template for the read operation used for the device so + * the controller can decide what type of calibration is + * required for this type of read. * * This interface should be implemented by SPI controllers providing an * high-level interface to execute SPI memory operation, which is usually the @@ -274,6 +280,7 @@ struct spi_controller_mem_ops { u64 offs, size_t len, void *buf); ssize_t (*dirmap_write)(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, const void *buf); + void (*do_calibration)(struct spi_mem *mem, struct spi_mem_op *op); }; /** @@ -346,6 +353,7 @@ bool spi_mem_dtr_supports_op(struct spi_mem *mem, #endif /* CONFIG_SPI_MEM */ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op); +int spi_mem_do_calibration(struct spi_mem *mem, struct spi_mem_op *op); bool spi_mem_supports_op(struct spi_mem *mem, const struct spi_mem_op *op); From patchwork Thu Mar 11 19:12: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: 1451476 X-Patchwork-Delegate: tudor.ambarus@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; helo=desiato.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=desiato.20200630 header.b=TEt+4bAV; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=uuc5i95s; dkim-atps=neutral Received: from desiato.infradead.org (desiato.infradead.org [IPv6:2001:8b0:10b:1:d65d:64ff:fe57:4e05]) (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 4DxJXY3RFnz9sCD for ; Fri, 12 Mar 2021 06:14:21 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:CC:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=8/UNFjRsFeuIYk2QkNzmXU4kygU3/Su2viXV5+YBEGI=; b=TEt+4bAVBzV1n3KjGRnom6QLJ SJj5Ndc7CZk8SeTWQZ/vnN4M1TuOA2VPaXQ4pVvJnvDEL95FclBPrsxRNfudLn3wQzPXImNmZ2rQL dofrsxFOoabWqPYnAaYbL+cpDlX8dP6GC1uRb8IPcTa+Mku3HIVUN/f1ntGgyOVNjeXdWWeRIKQkW ZSSGMAjc14BtKyGppS2TqVt/WNz81dfXugyYrl9MFqDvDN53rlLcjYnCxzxm+pKS4ZBZSahJUYauu CKDC5+cPgNSsqqmiSCuz2qoJbLFDZ8j5oh1qAi6Kkb6eY+v2wH2lm5fDypXL8GVObU5fbZhVULyiO SKEvA7qZQ==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lKQkM-009wr9-1T; Thu, 11 Mar 2021 19:13:22 +0000 Received: from fllv0016.ext.ti.com ([198.47.19.142]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lKQjc-009wiH-24; Thu, 11 Mar 2021 19:12:38 +0000 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 12BJCVCb072885; Thu, 11 Mar 2021 13:12:31 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1615489951; bh=D5mUrZ0LNwosvF5ATru7HapQyEd98umXGOgLCaoP3sw=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=uuc5i95sn4KgiTb/lI14qNmWTK3ywbnDfpsffrVSKfIeXKzkU3D8y9QeVH9OfS0Vj 45Ka76C5qkhfyRgWs0H2yvHUmd9qQP4+LXNL9vRPA5CnVZvhIIaIxf7SYw52NtPQkb hdeyZ0IB9CAoeSAcNYOMdL1CitHsRnkRkoH+YEGo= 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 12BJCVUV110439 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 11 Mar 2021 13:12:31 -0600 Received: from DLEE111.ent.ti.com (157.170.170.22) 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; Thu, 11 Mar 2021 13:12:31 -0600 Received: from fllv0039.itg.ti.com (10.64.41.19) 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; Thu, 11 Mar 2021 13:12:31 -0600 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by fllv0039.itg.ti.com (8.15.2/8.15.2) with ESMTP id 12BJCHvT080816; Thu, 11 Mar 2021 13:12:27 -0600 From: Pratyush Yadav To: Nishanth Menon , Tero Kristo , Rob Herring , Tudor Ambarus , Michael Walle , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mark Brown , , , , , CC: Pratyush Yadav , Lokesh Vutla Subject: [RFC PATCH 2/6] mtd: spi-nor: core: consolidate read op creation Date: Fri, 12 Mar 2021 00:42:12 +0530 Message-ID: <20210311191216.7363-3-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210311191216.7363-1-p.yadav@ti.com> References: <20210311191216.7363-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210311_191236_987048_437DF6D8 X-CRM114-Status: GOOD ( 16.46 ) X-Spam-Score: -2.8 (--) X-Spam-Report: Spam detection software, running on the system "desiato.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Currently the spi_mem_op to read from the flash is used in two places: spi_nor_create_read_dirmap() and spi_nor_spimem_read_data(). In a later commit this number will increase to three. Instead of rep [...] Content analysis details: (-2.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [198.47.19.142 listed in wl.mailspike.net] -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [198.47.19.142 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders -0.3 DKIMWL_WL_HIGH DKIMwl.org - High trust sender X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Currently the spi_mem_op to read from the flash is used in two places: spi_nor_create_read_dirmap() and spi_nor_spimem_read_data(). In a later commit this number will increase to three. Instead of repeating the same code thrice, add a function that returns a template of the read op. The callers can then fill in the details like address, data length, data buffer location. Signed-off-by: Pratyush Yadav Reviewed-by: Michael Walle --- drivers/mtd/spi-nor/core.c | 62 ++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 4a315cb1c4db..88888df009f0 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -183,6 +183,33 @@ static int spi_nor_controller_ops_erase(struct spi_nor *nor, loff_t offs) return nor->controller_ops->erase(nor, offs); } +/** + * spi_nor_spimem_get_read_op() - return a template for the spi_mem_op used for + * reading data from the flash via spi-mem. + * @nor: pointer to 'struct spi_nor' + * + * Return: A template of the 'struct spi_mem_op' for used for reading data from + * the flash. The caller is expected to fill in the address, data length, and + * the data buffer. + */ +static struct spi_mem_op spi_nor_spimem_get_read_op(struct spi_nor *nor) +{ + struct spi_mem_op op = + SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0), + SPI_MEM_OP_ADDR(nor->addr_width, 0, 0), + SPI_MEM_OP_DUMMY(nor->read_dummy, 0), + SPI_MEM_OP_DATA_IN(1, NULL, 0)); + + spi_nor_spimem_setup_op(nor, &op, nor->read_proto); + + /* convert the dummy cycles to the number of bytes */ + op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8; + if (spi_nor_protocol_is_dtr(nor->read_proto)) + op.dummy.nbytes *= 2; + + return op; +} + /** * spi_nor_spimem_read_data() - read data from flash's memory region via * spi-mem @@ -196,21 +223,14 @@ static int spi_nor_controller_ops_erase(struct spi_nor *nor, loff_t offs) static ssize_t spi_nor_spimem_read_data(struct spi_nor *nor, loff_t from, size_t len, u8 *buf) { - struct spi_mem_op op = - 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)); + struct spi_mem_op op = spi_nor_spimem_get_read_op(nor); bool usebouncebuf; ssize_t nbytes; int error; - spi_nor_spimem_setup_op(nor, &op, nor->read_proto); - - /* convert the dummy cycles to the number of bytes */ - op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8; - if (spi_nor_protocol_is_dtr(nor->read_proto)) - op.dummy.nbytes *= 2; + op.addr.val = from; + op.data.nbytes = len; + op.data.buf.in = buf; usebouncebuf = spi_nor_spimem_bounce(nor, &op); @@ -3581,28 +3601,10 @@ EXPORT_SYMBOL_GPL(spi_nor_scan); static int spi_nor_create_read_dirmap(struct spi_nor *nor) { struct spi_mem_dirmap_info info = { - .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0), - SPI_MEM_OP_ADDR(nor->addr_width, 0, 0), - SPI_MEM_OP_DUMMY(nor->read_dummy, 0), - SPI_MEM_OP_DATA_IN(0, NULL, 0)), + .op_tmpl = spi_nor_spimem_get_read_op(nor), .offset = 0, .length = nor->mtd.size, }; - struct spi_mem_op *op = &info.op_tmpl; - - spi_nor_spimem_setup_op(nor, op, nor->read_proto); - - /* convert the dummy cycles to the number of bytes */ - op->dummy.nbytes = (nor->read_dummy * op->dummy.buswidth) / 8; - if (spi_nor_protocol_is_dtr(nor->read_proto)) - op->dummy.nbytes *= 2; - - /* - * Since spi_nor_spimem_setup_op() only sets buswidth when the number - * of data bytes is non-zero, the data buswidth won't be set here. So, - * do it explicitly. - */ - op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto); nor->dirmap.rdesc = devm_spi_mem_dirmap_create(nor->dev, nor->spimem, &info); From patchwork Thu Mar 11 19:12: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: 1451477 X-Patchwork-Delegate: tudor.ambarus@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; helo=desiato.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=desiato.20200630 header.b=lBAAbtUJ; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=b5kYp6YS; dkim-atps=neutral Received: from desiato.infradead.org (desiato.infradead.org [IPv6:2001:8b0:10b:1:d65d:64ff:fe57:4e05]) (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 4DxJY90x7Kz9sRR for ; Fri, 12 Mar 2021 06:14:53 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:CC:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=WkcV4UgzEgaqamSkIshGK2HFZtzZ01fCpg+ZvwZ6t6w=; b=lBAAbtUJgT9rv5iw9/IHnYU3b agazJXztzs95H8zcPwiZQf5JY8OhzrllAq1fMxiCLetXQYRwikr1Ustd+/pJzYRkYXOsZknHhVbdB bzuU3NUmNukUXcdAGy6OkAhv7w60w2AgRSXJs3g3ORy+NFd9J2E/pO3KWrcRklj9KcYnWxgxQpuFe 6w318wkJ4S/EBQi2PbtLlFVlNFS3lGMDa23gAnB4qgqZJutto8d1EaN/ZVKDB7j5sn/IcLQp0s8VS oUttDWOkdjXlAqqdwSgLOJAzh6E/FBRN1I4WVQTz/v4TqzUXeytInymQ9SF0NliMTsdQMzwSyCQLQ +b1VKjhaQ==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lKQkr-009x12-DF; Thu, 11 Mar 2021 19:13:53 +0000 Received: from fllv0016.ext.ti.com ([198.47.19.142]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lKQjf-009wif-KV; Thu, 11 Mar 2021 19:12:41 +0000 Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 12BJCanU072953; Thu, 11 Mar 2021 13:12:36 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1615489956; bh=n3DRjCff2C4yzirXTzPuZEGe7eZhKiV8GXaya6kJgQM=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=b5kYp6YSfZpL/Ff+Z70SDQnez/A3FB8SSfTxS0cqixG2nzCWjraR+Btzj1a7B7m9V WvAflg74iWVQhjGQLXFA1IhaT3XT1o8HOdWeqqCwA/mFZavToyue+bBayuh1cgbsNU BfrQEdYAThM7P2qi7edmn0cztlpke12CwcNMW550= Received: from DFLE100.ent.ti.com (dfle100.ent.ti.com [10.64.6.21]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 12BJCaog113136 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 11 Mar 2021 13:12:36 -0600 Received: from DFLE107.ent.ti.com (10.64.6.28) 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; Thu, 11 Mar 2021 13:12:35 -0600 Received: from fllv0039.itg.ti.com (10.64.41.19) by DFLE107.ent.ti.com (10.64.6.28) 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; Thu, 11 Mar 2021 13:12:35 -0600 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by fllv0039.itg.ti.com (8.15.2/8.15.2) with ESMTP id 12BJCHvU080816; Thu, 11 Mar 2021 13:12:31 -0600 From: Pratyush Yadav To: Nishanth Menon , Tero Kristo , Rob Herring , Tudor Ambarus , Michael Walle , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mark Brown , , , , , CC: Pratyush Yadav , Lokesh Vutla Subject: [RFC PATCH 3/6] mtd: spi-nor: core: run calibration when initialization is done Date: Fri, 12 Mar 2021 00:42:13 +0530 Message-ID: <20210311191216.7363-4-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210311191216.7363-1-p.yadav@ti.com> References: <20210311191216.7363-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210311_191240_069744_3EB33222 X-CRM114-Status: GOOD ( 12.45 ) X-Spam-Score: -2.8 (--) X-Spam-Report: Spam detection software, running on the system "desiato.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Once the flash is initialized tell the controller it can run calibration procedures if needed. This can be useful when calibration is needed to run at higher clock speeds. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi-nor/core.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) Content analysis details: (-2.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [198.47.19.142 listed in wl.mailspike.net] -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [198.47.19.142 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders -0.3 DKIMWL_WL_HIGH DKIMwl.org - High trust sender X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Once the flash is initialized tell the controller it can run calibration procedures if needed. This can be useful when calibration is needed to run at higher clock speeds. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi-nor/core.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 88888df009f0..e0cbcaf1be89 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -3650,6 +3650,7 @@ static int spi_nor_probe(struct spi_mem *spimem) * checking what's really supported using spi_mem_supports_op(). */ const struct spi_nor_hwcaps hwcaps = { .mask = SNOR_HWCAPS_ALL }; + struct spi_mem_op op; char *flash_name; int ret; @@ -3709,8 +3710,15 @@ static int spi_nor_probe(struct spi_mem *spimem) if (ret) return ret; - return mtd_device_register(&nor->mtd, data ? data->parts : NULL, - data ? data->nr_parts : 0); + ret = mtd_device_register(&nor->mtd, data ? data->parts : NULL, + data ? data->nr_parts : 0); + if (ret) + return ret; + + op = spi_nor_spimem_get_read_op(nor); + spi_mem_do_calibration(nor->spimem, &op); + + return 0; } static int spi_nor_remove(struct spi_mem *spimem) From patchwork Thu Mar 11 19:12: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: 1451478 X-Patchwork-Delegate: tudor.ambarus@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; helo=desiato.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=desiato.20200630 header.b=gcsG8rrC; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=eh4R1oMJ; dkim-atps=neutral Received: from desiato.infradead.org (desiato.infradead.org [IPv6:2001:8b0:10b:1:d65d:64ff:fe57:4e05]) (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 4DxJZM0ts4z9sCD for ; Fri, 12 Mar 2021 06:15:55 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:CC:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=4ZZ6rE/aYTid9yUakvRyaMp+utmcFedZMVh3FVSopCs=; b=gcsG8rrCRIf+mLOHBT+o6Ohkf MPNnNsePOuAshVk0T+3SZjLCKWd3/9xCTBKkRS1I4GLLJ6vuzIszwAmN6nSdkJFb1pl8hrlXAIRCp 7NDGyuY34/NiPmmaIjMrruKiR4LpdxVJ0KmlHWcZ3dvkWYbYfjVVAJbo4YmlqnXh7IzcBSVkPdmW1 Y9TqFK43XP3yx1wIgGcyddVsIeZ/l/zWSH75+bEw4/rjtMYOJMMIITjSEsMWKcizeUZ/TmkTWrRwJ 9fRUa6F5QcJOETQivM61knreyZarcyf1lxQSYOf9pfSZoltf6M7afqL+W9g1RezvYmobz1CYzwnX6 4c4Z/ebhg==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lKQlj-009xHC-1J; Thu, 11 Mar 2021 19:14:47 +0000 Received: from fllv0016.ext.ti.com ([198.47.19.142]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lKQjl-009wjW-Ht; Thu, 11 Mar 2021 19:12:47 +0000 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 12BJCfkl072981; Thu, 11 Mar 2021 13:12:41 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1615489961; bh=OhuGeU0Ap5BT7Sl9DsCYa3Ndt+hNk93fO4NJx/FnSKQ=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=eh4R1oMJGkaqFg1L4275raVqJ9xVf1hbgZPsbamWqIk8KgE7V1NMVLV7l4w6FInhU /JIJzZLvrn54QL9PKimr5fDbtS434AM70iLss7Nebgo+S5FMFs9A3kD7NslJ4APae8 wecIOPirp1su8cXZ+CEQ5eEFNuIug2+eEAyj7S48= Received: from DFLE102.ent.ti.com (dfle102.ent.ti.com [10.64.6.23]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 12BJCf5p110575 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 11 Mar 2021 13:12:41 -0600 Received: from DFLE113.ent.ti.com (10.64.6.34) 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; Thu, 11 Mar 2021 13:12:40 -0600 Received: from fllv0039.itg.ti.com (10.64.41.19) 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 via Frontend Transport; Thu, 11 Mar 2021 13:12:40 -0600 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by fllv0039.itg.ti.com (8.15.2/8.15.2) with ESMTP id 12BJCHvV080816; Thu, 11 Mar 2021 13:12:36 -0600 From: Pratyush Yadav To: Nishanth Menon , Tero Kristo , Rob Herring , Tudor Ambarus , Michael Walle , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mark Brown , , , , , CC: Pratyush Yadav , Lokesh Vutla Subject: [RFC PATCH 4/6] spi: cadence-qspi: Use PHY for DAC reads if possible Date: Fri, 12 Mar 2021 00:42:14 +0530 Message-ID: <20210311191216.7363-5-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210311191216.7363-1-p.yadav@ti.com> References: <20210311191216.7363-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210311_191245_881008_0E9FB005 X-CRM114-Status: GOOD ( 23.01 ) X-Spam-Score: -2.8 (--) X-Spam-Report: Spam detection software, running on the system "desiato.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Check if a read is eligible for PHY and if it is, enable PHY and DQS. Since PHY reads only work at an address that is 16-byte aligned and of size that is a multiple of 16 bytes, read the starting and ending unaligned portions without PHY, and only enable PHY for the mid [...] Content analysis details: (-2.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [198.47.19.142 listed in wl.mailspike.net] -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [198.47.19.142 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders -0.3 DKIMWL_WL_HIGH DKIMwl.org - High trust sender X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Check if a read is eligible for PHY and if it is, enable PHY and DQS. Since PHY reads only work at an address that is 16-byte aligned and of size that is a multiple of 16 bytes, read the starting and ending unaligned portions without PHY, and only enable PHY for the middle part. Signed-off-by: Pratyush Yadav --- drivers/spi/spi-cadence-quadspi.c | 203 ++++++++++++++++++++++++++---- 1 file changed, 182 insertions(+), 21 deletions(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index e2d6ea833423..e64d8e125263 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -41,19 +41,27 @@ struct cqspi_st; +struct phy_setting { + u8 rx; + u8 tx; + u8 read_delay; +}; + struct cqspi_flash_pdata { - struct cqspi_st *cqspi; - u32 clk_rate; - u32 read_delay; - u32 tshsl_ns; - u32 tsd2d_ns; - u32 tchsh_ns; - u32 tslch_ns; - u8 inst_width; - u8 addr_width; - u8 data_width; - bool dtr; - u8 cs; + struct cqspi_st *cqspi; + u32 clk_rate; + u32 read_delay; + u32 tshsl_ns; + u32 tsd2d_ns; + u32 tchsh_ns; + u32 tslch_ns; + u8 inst_width; + u8 addr_width; + u8 data_width; + bool dtr; + u8 cs; + bool use_phy; + struct phy_setting phy_setting; }; struct cqspi_st { @@ -108,12 +116,14 @@ struct cqspi_driver_platdata { /* Register map */ #define CQSPI_REG_CONFIG 0x00 #define CQSPI_REG_CONFIG_ENABLE_MASK BIT(0) +#define CQSPI_REG_CONFIG_PHY_EN BIT(3) #define CQSPI_REG_CONFIG_ENB_DIR_ACC_CTRL BIT(7) #define CQSPI_REG_CONFIG_DECODE_MASK BIT(9) #define CQSPI_REG_CONFIG_CHIPSELECT_LSB 10 #define CQSPI_REG_CONFIG_DMA_MASK BIT(15) #define CQSPI_REG_CONFIG_BAUD_LSB 19 #define CQSPI_REG_CONFIG_DTR_PROTO BIT(24) +#define CQSPI_REG_CONFIG_PHY_PIPELINE BIT(25) #define CQSPI_REG_CONFIG_DUAL_OPCODE BIT(30) #define CQSPI_REG_CONFIG_IDLE_LSB 31 #define CQSPI_REG_CONFIG_CHIPSELECT_MASK 0xF @@ -150,6 +160,7 @@ struct cqspi_driver_platdata { #define CQSPI_REG_READCAPTURE_BYPASS_LSB 0 #define CQSPI_REG_READCAPTURE_DELAY_LSB 1 #define CQSPI_REG_READCAPTURE_DELAY_MASK 0xF +#define CQSPI_REG_READCAPTURE_DQS_LSB 8 #define CQSPI_REG_SIZE 0x14 #define CQSPI_REG_SIZE_ADDRESS_LSB 0 @@ -999,6 +1010,7 @@ static void cqspi_config_baudrate_div(struct cqspi_st *cqspi) static void cqspi_readdata_capture(struct cqspi_st *cqspi, const bool bypass, + const bool dqs, const unsigned int delay) { void __iomem *reg_base = cqspi->iobase; @@ -1017,6 +1029,11 @@ static void cqspi_readdata_capture(struct cqspi_st *cqspi, reg |= (delay & CQSPI_REG_READCAPTURE_DELAY_MASK) << CQSPI_REG_READCAPTURE_DELAY_LSB; + if (dqs) + reg |= (1 << CQSPI_REG_READCAPTURE_DQS_LSB); + else + reg &= ~(1 << CQSPI_REG_READCAPTURE_DQS_LSB); + writel(reg, reg_base + CQSPI_REG_READCAPTURE); } @@ -1035,6 +1052,64 @@ static void cqspi_controller_enable(struct cqspi_st *cqspi, bool enable) writel(reg, reg_base + CQSPI_REG_CONFIG); } +static void cqspi_phy_enable(struct cqspi_flash_pdata *f_pdata, bool enable) +{ + struct cqspi_st *cqspi = f_pdata->cqspi; + void __iomem *reg_base = cqspi->iobase; + u32 reg; + u8 dummy; + + if (enable) { + cqspi_readdata_capture(cqspi, 1, true, + f_pdata->phy_setting.read_delay); + + reg = readl(reg_base + CQSPI_REG_CONFIG); + reg |= CQSPI_REG_CONFIG_PHY_EN | + CQSPI_REG_CONFIG_PHY_PIPELINE; + writel(reg, reg_base + CQSPI_REG_CONFIG); + + /* + * Reduce dummy cycle by 1. This is a requirement of PHY mode + * operation for correctly reading the data. + */ + reg = readl(reg_base + CQSPI_REG_RD_INSTR); + dummy = (reg >> CQSPI_REG_RD_INSTR_DUMMY_LSB) & + CQSPI_REG_RD_INSTR_DUMMY_MASK; + dummy--; + reg &= ~(CQSPI_REG_RD_INSTR_DUMMY_MASK << + CQSPI_REG_RD_INSTR_DUMMY_LSB); + + reg |= (dummy & CQSPI_REG_RD_INSTR_DUMMY_MASK) + << CQSPI_REG_RD_INSTR_DUMMY_LSB; + writel(reg, reg_base + CQSPI_REG_RD_INSTR); + } else { + cqspi_readdata_capture(cqspi, !cqspi->rclk_en, false, + f_pdata->read_delay); + + reg = readl(reg_base + CQSPI_REG_CONFIG); + reg &= ~(CQSPI_REG_CONFIG_PHY_EN | + CQSPI_REG_CONFIG_PHY_PIPELINE); + writel(reg, reg_base + CQSPI_REG_CONFIG); + + /* + * Dummy cycles were decremented when enabling PHY. Increment + * dummy cycle by 1 to restore the original value. + */ + reg = readl(reg_base + CQSPI_REG_RD_INSTR); + dummy = (reg >> CQSPI_REG_RD_INSTR_DUMMY_LSB) & + CQSPI_REG_RD_INSTR_DUMMY_MASK; + dummy++; + reg &= ~(CQSPI_REG_RD_INSTR_DUMMY_MASK << + CQSPI_REG_RD_INSTR_DUMMY_LSB); + + reg |= (dummy & CQSPI_REG_RD_INSTR_DUMMY_MASK) + << CQSPI_REG_RD_INSTR_DUMMY_LSB; + writel(reg, reg_base + CQSPI_REG_RD_INSTR); + } + + cqspi_wait_idle(cqspi); +} + static void cqspi_configure(struct cqspi_flash_pdata *f_pdata, unsigned long sclk) { @@ -1056,7 +1131,7 @@ static void cqspi_configure(struct cqspi_flash_pdata *f_pdata, cqspi->sclk = sclk; cqspi_config_baudrate_div(cqspi); cqspi_delay(f_pdata); - cqspi_readdata_capture(cqspi, !cqspi->rclk_en, + cqspi_readdata_capture(cqspi, !cqspi->rclk_en, false, f_pdata->read_delay); } @@ -1098,6 +1173,39 @@ static ssize_t cqspi_write(struct cqspi_flash_pdata *f_pdata, return cqspi_indirect_write_execute(f_pdata, to, buf, len); } +/* + * Check if PHY mode can be used on the given op. This is assuming it will be a + * DAC mode read, since PHY won't work on any other type of operation anyway. + */ +static bool cqspi_phy_op_eligible(const struct spi_mem_op *op) +{ + /* PHY is only tuned for 8D-8D-8D. */ + if (!(op->cmd.dtr && op->addr.dtr && op->dummy.dtr && op->data.dtr)) + return false; + if (op->cmd.buswidth != 8) + return false; + if (op->addr.nbytes && op->addr.buswidth != 8) + return false; + if (op->dummy.nbytes && op->dummy.buswidth != 8) + return false; + if (op->data.nbytes && op->data.buswidth != 8) + return false; + + return true; +} + +static bool cqspi_use_phy(struct cqspi_flash_pdata *f_pdata, + const struct spi_mem_op *op) +{ + if (!f_pdata->use_phy) + return false; + + if (op->data.nbytes < 16) + return false; + + return cqspi_phy_op_eligible(op); +} + static void cqspi_rx_dma_callback(void *param) { struct cqspi_st *cqspi = param; @@ -1105,8 +1213,8 @@ static void cqspi_rx_dma_callback(void *param) complete(&cqspi->rx_dma_complete); } -static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata, - u_char *buf, loff_t from, size_t len) +static int cqspi_direct_read_dma(struct cqspi_flash_pdata *f_pdata, + u_char *buf, loff_t from, size_t len) { struct cqspi_st *cqspi = f_pdata->cqspi; struct device *dev = &cqspi->pdev->dev; @@ -1118,11 +1226,6 @@ static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata, dma_addr_t dma_dst; struct device *ddev; - if (!cqspi->rx_chan || !virt_addr_valid(buf)) { - memcpy_fromio(buf, cqspi->ahb_base + from, len); - return 0; - } - ddev = cqspi->rx_chan->device->dev; dma_dst = dma_map_single(ddev, buf, len, DMA_FROM_DEVICE); if (dma_mapping_error(ddev, dma_dst)) { @@ -1164,6 +1267,64 @@ static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata, return ret; } +static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata, + const struct spi_mem_op *op) +{ + struct cqspi_st *cqspi = f_pdata->cqspi; + loff_t from = op->addr.val; + loff_t from_aligned, to_aligned; + size_t len = op->data.nbytes; + size_t len_aligned; + u_char *buf = op->data.buf.in; + int ret; + + if (!cqspi->rx_chan || !virt_addr_valid(buf)) { + memcpy_fromio(buf, cqspi->ahb_base + from, len); + return 0; + } + + if (!cqspi_use_phy(f_pdata, op)) + return cqspi_direct_read_dma(f_pdata, buf, from, len); + + /* + * PHY reads must be 16-byte aligned, and they must be a multiple of 16 + * bytes. + */ + from_aligned = (from + 0xF) & ~0xF; + to_aligned = (from + len) & ~0xF; + len_aligned = to_aligned - from_aligned; + + /* Read the unaligned part at the start. */ + if (from != from_aligned) { + ret = cqspi_direct_read_dma(f_pdata, buf, from, + from_aligned - from); + if (ret) + return ret; + buf += from_aligned - from; + } + + if (len_aligned) { + cqspi_phy_enable(f_pdata, true); + ret = cqspi_direct_read_dma(f_pdata, buf, from_aligned, + len_aligned); + cqspi_phy_enable(f_pdata, false); + if (ret) + return ret; + buf += len_aligned; + } + + /* Now read the remaining part, if any. */ + if (to_aligned != (from + len)) { + ret = cqspi_direct_read_dma(f_pdata, buf, to_aligned, + (from + len) - to_aligned); + if (ret) + return ret; + buf += (from + len) - to_aligned; + } + + return 0; +} + static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata, const struct spi_mem_op *op) { @@ -1182,7 +1343,7 @@ static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata, return ret; if (cqspi->use_direct_mode && ((from + len) <= cqspi->ahb_size)) - return cqspi_direct_read_execute(f_pdata, buf, from, len); + return cqspi_direct_read_execute(f_pdata, op); return cqspi_indirect_read_execute(f_pdata, buf, from, len); } From patchwork Thu Mar 11 19:12: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: 1451479 X-Patchwork-Delegate: tudor.ambarus@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; helo=desiato.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=desiato.20200630 header.b=Fgf8THAA; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=VUA1S0pZ; dkim-atps=neutral Received: from desiato.infradead.org (desiato.infradead.org [IPv6:2001:8b0:10b:1:d65d:64ff:fe57:4e05]) (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 4DxJbM4pdYz9sCD for ; Fri, 12 Mar 2021 06:16:47 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:CC:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=7V448I/oIvyO4qBc8B4UG/Lq0nuCvRG6f9+MUyn9ckc=; b=Fgf8THAAU5RiIAe+VuSmvllNR N1+cMZ7JuNMK7Qxo9UYUoSt1IVXJlufyBFn72dQ/OwZZ5vyi7E4Eoe3O4CaQkjbCU/BrSCtsmTgvl KK2d+DG7N0g9UMDWdxUDVX5lf7RdkPjj0YnjEbNr7p6tXwzJk4dao3TFuPNlCz0tKkm/Z2FXeu5o8 dQ75+EeLIBy5R0nkkb28xnIvM2nbL/IfcNELZXljNtE0fl5wQixx35lHg1nNWw2B6FDwGxQBKQwDx IOG48J21/HZVRaazBXuwwWk81cyVPSbV0K+OnZMSmKRa83/TnaampU9XFi6prLVBERa0Ku6S7+S/t NR1U/IA6g==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lKQmx-009xZR-Bq; Thu, 11 Mar 2021 19:16:03 +0000 Received: from fllv0015.ext.ti.com ([198.47.19.141]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lKQjp-009wkA-9a; Thu, 11 Mar 2021 19:12:54 +0000 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 12BJCjjR123950; Thu, 11 Mar 2021 13:12:45 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1615489965; bh=TUi2WHK3M2rDM2J87pAt68xPOpINrGhVEr8Jkhg2JPY=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=VUA1S0pZMh49E+FybBpMjIZq0wduLyW/Uxig+WKs+4CEHMcf4Ist7B0Jw81gP7u3T LWhimlx5WuzQDEcB0MqTILgxo2ixiklwMRIGF3Ed9eAoAHE0kao0wpNg4RqUxkR/Mu F/uaTCNd7hbFfVpmFEXqRmE4o2puFwZsGcPhBmo4= Received: from DFLE104.ent.ti.com (dfle104.ent.ti.com [10.64.6.25]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 12BJCjZA110617 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 11 Mar 2021 13:12:45 -0600 Received: from DFLE101.ent.ti.com (10.64.6.22) 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; Thu, 11 Mar 2021 13:12:45 -0600 Received: from fllv0039.itg.ti.com (10.64.41.19) 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; Thu, 11 Mar 2021 13:12:45 -0600 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by fllv0039.itg.ti.com (8.15.2/8.15.2) with ESMTP id 12BJCHvW080816; Thu, 11 Mar 2021 13:12:41 -0600 From: Pratyush Yadav To: Nishanth Menon , Tero Kristo , Rob Herring , Tudor Ambarus , Michael Walle , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mark Brown , , , , , CC: Pratyush Yadav , Lokesh Vutla Subject: [RFC PATCH 5/6] spi: cadence-qspi: Tune PHY to allow running at higher frequencies Date: Fri, 12 Mar 2021 00:42:15 +0530 Message-ID: <20210311191216.7363-6-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210311191216.7363-1-p.yadav@ti.com> References: <20210311191216.7363-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210311_191251_472964_E747341A X-CRM114-Status: GOOD ( 26.51 ) X-Spam-Score: -2.8 (--) X-Spam-Report: Spam detection software, running on the system "desiato.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: The controller can only run at 1/8 ref clock speed without PHY. With PHY, it can run at the ref clock speed. So, to enable higher speed operations, perform the PHY tuning algorithm and determine the R [...] Content analysis details: (-2.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_MSPIKE_H4 RBL: Very Good reputation (+4) [198.47.19.141 listed in wl.mailspike.net] -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [198.47.19.141 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders -0.3 DKIMWL_WL_HIGH DKIMwl.org - High trust sender X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org The controller can only run at 1/8 ref clock speed without PHY. With PHY, it can run at the ref clock speed. So, to enable higher speed operations, perform the PHY tuning algorithm and determine the RX, TX, and read delay values for optimal performance. The details of the tuning algorithm can be found at [0]. To allow this tuning to happen, pre-determined data must be programmed to the flash at some location. This location is then advertised via a nvmem cell. Without this data being available, the tuning would fail. The tuning algorithm is a multi-variable search. The RX and TX delays need to be found, along with the read delay that would work across a temperature range. To do that, first the upper and lower RX values at which the tuning pattern is readable are looked for. This is called the passing region. The search is performed with Tx = 16 incrementing the read delay with each iteration. If the two RX values have the same read delay, the same search is performed with TX = 48. Once the RX boundaries are found, the TX boundaries are searched for in a similar fashion with RX set to 1/4 of the RX window (the difference between the highest and lowest values). And similarly, if the TX boundaries have the same read delay, the same search is performed with RX set to 3/4 of the RX window. There is a region around the boundary of the two passing regions. It is called the failing region. PHY reads will not work in this region so the PHY should be tuned as far from it as possible to allow for temperature variations. This region is found using binary search where the window is progressively narrowed down until it arrives at the final boundary's lower and upper limits. Once PHY is successfully tuned, mark it as usable to allow eligible operations to run at high speeds. PHY can only be used with DAC mode reads, and only in chunks of 16 bytes. For all other operations, PHY mode should be turned off. [0] https://www.ti.com/lit/pdf/spract2/ Signed-off-by: Pratyush Yadav --- drivers/spi/spi-cadence-quadspi.c | 617 ++++++++++++++++++++++++++++++ 1 file changed, 617 insertions(+) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index e64d8e125263..d304148a4722 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -28,6 +28,7 @@ #include #include #include +#include #define CQSPI_NAME "cadence-qspi" #define CQSPI_MAX_CHIPSELECT 16 @@ -62,6 +63,9 @@ struct cqspi_flash_pdata { u8 cs; bool use_phy; struct phy_setting phy_setting; + struct spi_mem_op phy_read_op; + u32 phy_tx_start; + u32 phy_tx_end; }; struct cqspi_st { @@ -237,6 +241,13 @@ struct cqspi_driver_platdata { #define CQSPI_REG_POLLING_STATUS 0xB0 #define CQSPI_REG_POLLING_STATUS_DUMMY_LSB 16 +#define CQSPI_REG_PHY_CONFIG 0xB4 +#define CQSPI_REG_PHY_CONFIG_RX_DEL_LSB 0 +#define CQSPI_REG_PHY_CONFIG_RX_DEL_MASK 0x7F +#define CQSPI_REG_PHY_CONFIG_TX_DEL_LSB 16 +#define CQSPI_REG_PHY_CONFIG_TX_DEL_MASK 0x7F +#define CQSPI_REG_PHY_CONFIG_RESYNC BIT(31) + #define CQSPI_REG_OP_EXT_LOWER 0xE0 #define CQSPI_REG_OP_EXT_READ_LSB 24 #define CQSPI_REG_OP_EXT_WRITE_LSB 16 @@ -262,6 +273,570 @@ struct cqspi_driver_platdata { #define CQSPI_IRQ_STATUS_MASK 0x1FFFF +#define CQSPI_PHY_INIT_RD 1 +#define CQSPI_PHY_MAX_RD 4 +#define CQSPI_PHY_MAX_RX 63 +#define CQSPI_PHY_MAX_TX 63 +#define CQSPI_PHY_LOW_RX_BOUND 15 +#define CQSPI_PHY_HIGH_RX_BOUND 25 +#define CQSPI_PHY_LOW_TX_BOUND 32 +#define CQSPI_PHY_HIGH_TX_BOUND 48 +#define CQSPI_PHY_TX_LOOKUP_LOW_BOUND 24 +#define CQSPI_PHY_TX_LOOKUP_HIGH_BOUND 38 + +#define CQSPI_PHY_DEFAULT_TEMP 45 +#define CQSPI_PHY_MIN_TEMP -45 +#define CQSPI_PHY_MAX_TEMP 130 +#define CQSPI_PHY_MID_TEMP (CQSPI_PHY_MIN_TEMP + \ + ((CQSPI_PHY_MAX_TEMP - CQSPI_PHY_MIN_TEMP) / 2)) + +static const u8 phy_tuning_pattern[] = { +0xFE, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xFE, 0xFE, 0x01, 0x01, +0x01, 0x01, 0x00, 0x00, 0xFE, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, +0x00, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0xFF, 0x01, +0x01, 0x01, 0x01, 0x01, 0xFE, 0x00, 0xFE, 0xFE, 0x01, 0x01, 0x01, 0x01, 0xFE, +0x00, 0xFE, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFE, 0xFE, +0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFE, 0xFE, 0xFF, 0x01, 0x01, 0x01, 0x01, +0x01, 0x00, 0xFE, 0xFE, 0xFE, 0x01, 0x01, 0x01, 0x01, 0x00, 0xFE, 0xFE, 0xFE, +0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, +0xFF, 0x00, 0xFE, 0xFE, 0xFE, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFE, +0xFE, 0xFE, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFE, 0xFE, 0xFE, 0x01, +}; + +static void cqspi_set_tx_dll(void __iomem *reg_base, u8 dll) +{ + unsigned int reg; + + reg = readl(reg_base + CQSPI_REG_PHY_CONFIG); + reg &= ~(CQSPI_REG_PHY_CONFIG_TX_DEL_MASK << + CQSPI_REG_PHY_CONFIG_TX_DEL_LSB); + reg |= (dll & CQSPI_REG_PHY_CONFIG_TX_DEL_MASK) << + CQSPI_REG_PHY_CONFIG_TX_DEL_LSB; + reg |= CQSPI_REG_PHY_CONFIG_RESYNC; + writel(reg, reg_base + CQSPI_REG_PHY_CONFIG); +} + +static void cqspi_set_rx_dll(void __iomem *reg_base, u8 dll) +{ + unsigned int reg; + + reg = readl(reg_base + CQSPI_REG_PHY_CONFIG); + reg &= ~(CQSPI_REG_PHY_CONFIG_RX_DEL_MASK << + CQSPI_REG_PHY_CONFIG_RX_DEL_LSB); + reg |= (dll & CQSPI_REG_PHY_CONFIG_RX_DEL_MASK) << + CQSPI_REG_PHY_CONFIG_RX_DEL_LSB; + reg |= CQSPI_REG_PHY_CONFIG_RESYNC; + writel(reg, reg_base + CQSPI_REG_PHY_CONFIG); +} + +/* TODO: Figure out how to get the temperature here. */ +static int cqspi_get_temp(int *temp) +{ + return -EOPNOTSUPP; +} + +static void cqspi_phy_apply_setting(struct cqspi_flash_pdata *f_pdata, + struct phy_setting *phy) +{ + struct cqspi_st *cqspi = f_pdata->cqspi; + + cqspi_set_rx_dll(cqspi->iobase, phy->rx); + cqspi_set_tx_dll(cqspi->iobase, phy->tx); + f_pdata->phy_setting.read_delay = phy->read_delay; +} + +static int cqspi_phy_check_pattern(struct cqspi_flash_pdata *f_pdata, + struct nvmem_cell *cell) +{ + u8 *read_data; + size_t len; + int ret; + + read_data = nvmem_cell_read(cell, &len); + if (IS_ERR(read_data)) + return PTR_ERR(read_data); + if (len != ARRAY_SIZE(phy_tuning_pattern)) + return -EIO; + + if (memcmp(read_data, phy_tuning_pattern, + ARRAY_SIZE(phy_tuning_pattern))) { + ret = -EAGAIN; + goto out; + } + + ret = 0; + +out: + kfree(read_data); + return ret; +} + +static int cqspi_find_rx_low(struct cqspi_flash_pdata *f_pdata, + struct nvmem_cell *cell, struct phy_setting *phy) +{ + struct device *dev = &f_pdata->cqspi->pdev->dev; + int ret; + + do { + phy->rx = 0; + do { + cqspi_phy_apply_setting(f_pdata, phy); + ret = cqspi_phy_check_pattern(f_pdata, cell); + if (!ret) + return 0; + + phy->rx++; + } while (phy->rx <= CQSPI_PHY_LOW_RX_BOUND); + + phy->read_delay++; + } while (phy->read_delay <= CQSPI_PHY_MAX_RD); + + dev_dbg(dev, "Unable to find RX low\n"); + return -ENOENT; +} + +static int cqspi_find_rx_high(struct cqspi_flash_pdata *f_pdata, + struct nvmem_cell *cell, struct phy_setting *phy) +{ + struct device *dev = &f_pdata->cqspi->pdev->dev; + int ret; + + do { + phy->rx = CQSPI_PHY_MAX_RX; + do { + cqspi_phy_apply_setting(f_pdata, phy); + ret = cqspi_phy_check_pattern(f_pdata, cell); + if (!ret) + return 0; + + phy->rx--; + } while (phy->rx >= CQSPI_PHY_HIGH_RX_BOUND); + + phy->read_delay++; + } while (phy->read_delay <= CQSPI_PHY_MAX_RD); + + dev_dbg(dev, "Unable to find RX high\n"); + return -ENOENT; +} + +static int cqspi_find_tx_low(struct cqspi_flash_pdata *f_pdata, + struct nvmem_cell *cell, struct phy_setting *phy) +{ + struct device *dev = &f_pdata->cqspi->pdev->dev; + int ret; + + do { + phy->tx = 0; + do { + cqspi_phy_apply_setting(f_pdata, phy); + ret = cqspi_phy_check_pattern(f_pdata, cell); + if (!ret) + return 0; + + phy->tx++; + } while (phy->tx <= CQSPI_PHY_LOW_TX_BOUND); + + phy->read_delay++; + } while (phy->read_delay <= CQSPI_PHY_MAX_RD); + + dev_dbg(dev, "Unable to find TX low\n"); + return -ENOENT; +} + +static int cqspi_find_tx_high(struct cqspi_flash_pdata *f_pdata, + struct nvmem_cell *cell, struct phy_setting *phy) +{ + struct device *dev = &f_pdata->cqspi->pdev->dev; + int ret; + + do { + phy->tx = CQSPI_PHY_MAX_TX; + do { + cqspi_phy_apply_setting(f_pdata, phy); + ret = cqspi_phy_check_pattern(f_pdata, cell); + if (!ret) + return 0; + + phy->tx--; + } while (phy->tx >= CQSPI_PHY_HIGH_TX_BOUND); + + phy->read_delay++; + } while (phy->read_delay <= CQSPI_PHY_MAX_RD); + + dev_dbg(dev, "Unable to find TX high\n"); + return -ENOENT; +} + +static int cqspi_phy_find_gaplow(struct cqspi_flash_pdata *f_pdata, + struct nvmem_cell *cell, + struct phy_setting *bottomleft, + struct phy_setting *topright, + struct phy_setting *gaplow) +{ + struct phy_setting left, right, mid; + int ret; + + left = *bottomleft; + right = *topright; + + mid.tx = left.tx + ((right.tx - left.tx) / 2); + mid.rx = left.rx + ((right.rx - left.rx) / 2); + mid.read_delay = left.read_delay; + + do { + cqspi_phy_apply_setting(f_pdata, &mid); + ret = cqspi_phy_check_pattern(f_pdata, cell); + if (ret) { + /* The pattern was not found. Go to the lower half. */ + right.tx = mid.tx; + right.rx = mid.rx; + + mid.tx = left.tx + ((mid.tx - left.tx) / 2); + mid.rx = left.rx + ((mid.rx - left.rx) / 2); + } else { + /* The pattern was found. Go to the upper half. */ + left.tx = mid.tx; + left.rx = mid.rx; + + mid.tx = mid.tx + ((right.tx - mid.tx) / 2); + mid.rx = mid.rx + ((right.rx - mid.rx) / 2); + } + + /* Break the loop if the window has closed. */ + } while ((right.tx - left.tx >= 2) && (right.rx - left.rx >= 2)); + + *gaplow = mid; + return 0; +} + +static int cqspi_phy_find_gaphigh(struct cqspi_flash_pdata *f_pdata, + struct nvmem_cell *cell, + struct phy_setting *bottomleft, + struct phy_setting *topright, + struct phy_setting *gaphigh) +{ + struct phy_setting left, right, mid; + int ret; + + left = *bottomleft; + right = *topright; + + mid.tx = left.tx + ((right.tx - left.tx) / 2); + mid.rx = left.rx + ((right.rx - left.rx) / 2); + mid.read_delay = right.read_delay; + + do { + cqspi_phy_apply_setting(f_pdata, &mid); + ret = cqspi_phy_check_pattern(f_pdata, cell); + if (ret) { + /* The pattern was not found. Go to the upper half. */ + left.tx = mid.tx; + left.rx = mid.rx; + + mid.tx = mid.tx + ((right.tx - mid.tx) / 2); + mid.rx = mid.rx + ((right.rx - mid.rx) / 2); + } else { + /* The pattern was found. Go to the lower half. */ + right.tx = mid.tx; + right.rx = mid.rx; + + mid.tx = left.tx + ((mid.tx - left.tx) / 2); + mid.rx = left.rx + ((mid.rx - left.rx) / 2); + } + + /* Break the loop if the window has closed. */ + } while ((right.tx - left.tx >= 2) && (right.rx - left.rx >= 2)); + + *gaphigh = mid; + return 0; +} + +static int cqspi_phy_calibrate(struct cqspi_flash_pdata *f_pdata, + struct nvmem_cell *cell) +{ + struct cqspi_st *cqspi = f_pdata->cqspi; + struct device *dev = &cqspi->pdev->dev; + struct phy_setting rxlow, rxhigh, txlow, txhigh, temp; + struct phy_setting bottomleft, topright, searchpoint, gaplow, gaphigh; + int ret, tmp; + + f_pdata->use_phy = true; + + /* Look for RX boundaries at lower TX range. */ + rxlow.tx = f_pdata->phy_tx_start; + + do { + dev_dbg(dev, "Searching for rxlow on TX = %d\n", rxlow.tx); + rxlow.read_delay = CQSPI_PHY_INIT_RD; + ret = cqspi_find_rx_low(f_pdata, cell, &rxlow); + } while (ret && ++rxlow.tx <= CQSPI_PHY_TX_LOOKUP_LOW_BOUND); + + if (ret) + goto out; + dev_dbg(dev, "rxlow: RX: %d TX: %d RD: %d\n", rxlow.rx, rxlow.tx, + rxlow.read_delay); + + rxhigh.tx = rxlow.tx; + rxhigh.read_delay = rxlow.read_delay; + cqspi_find_rx_high(f_pdata, cell, &rxhigh); + if (ret) + goto out; + dev_dbg(dev, "rxhigh: RX: %d TX: %d RD: %d\n", rxhigh.rx, rxhigh.tx, + rxhigh.read_delay); + + /* + * Check a different point if rxlow and rxhigh are on the same read + * delay. This avoids mistaking the failing region for an RX boundary. + */ + if (rxlow.read_delay == rxhigh.read_delay) { + dev_dbg(dev, + "rxlow and rxhigh at the same read delay.\n"); + + /* Look for RX boundaries at upper TX range. */ + temp.tx = f_pdata->phy_tx_end; + + do { + dev_dbg(dev, "Searching for rxlow on TX = %d\n", + temp.tx); + temp.read_delay = CQSPI_PHY_INIT_RD; + ret = cqspi_find_rx_low(f_pdata, cell, &temp); + } while (ret && --temp.tx >= CQSPI_PHY_TX_LOOKUP_HIGH_BOUND); + + if (ret) + goto out; + dev_dbg(dev, "rxlow: RX: %d TX: %d RD: %d\n", temp.rx, temp.tx, + temp.read_delay); + + if (temp.rx < rxlow.rx) { + rxlow = temp; + dev_dbg(dev, "Updating rxlow to the one at TX = 48\n"); + } + + /* Find RX max. */ + ret = cqspi_find_rx_high(f_pdata, cell, &temp); + if (ret) + goto out; + dev_dbg(dev, "rxhigh: RX: %d TX: %d RD: %d\n", temp.rx, temp.tx, + temp.read_delay); + + if (temp.rx < rxhigh.rx) { + rxhigh = temp; + dev_dbg(dev, "Updating rxhigh to the one at TX = 48\n"); + } + } + + /* Look for TX boundaries at 1/4 of RX window. */ + txlow.rx = rxlow.rx + ((rxhigh.rx - rxlow.rx) / 4); + txhigh.rx = txlow.rx; + + txlow.read_delay = CQSPI_PHY_INIT_RD; + ret = cqspi_find_tx_low(f_pdata, cell, &txlow); + if (ret) + goto out; + dev_dbg(dev, "txlow: RX: %d TX: %d RD: %d\n", txlow.rx, txlow.tx, + txlow.read_delay); + + txhigh.read_delay = txlow.read_delay; + ret = cqspi_find_tx_high(f_pdata, cell, &txhigh); + if (ret) + goto out; + dev_dbg(dev, "txhigh: RX: %d TX: %d RD: %d\n", txhigh.rx, txhigh.tx, + txhigh.read_delay); + + /* + * Check a different point if txlow and txhigh are on the same read + * delay. This avoids mistaking the failing region for an TX boundary. + */ + if (txlow.read_delay == txhigh.read_delay) { + /* Look for TX boundaries at 3/4 of RX window. */ + temp.rx = rxlow.rx + (3 * (rxhigh.rx - rxlow.rx) / 4); + temp.read_delay = CQSPI_PHY_INIT_RD; + dev_dbg(dev, + "txlow and txhigh at the same read delay. Searching at RX = %d\n", + temp.rx); + + ret = cqspi_find_tx_low(f_pdata, cell, &temp); + if (ret) + goto out; + dev_dbg(dev, "txlow: RX: %d TX: %d RD: %d\n", temp.rx, temp.tx, + temp.read_delay); + + if (temp.tx < txlow.tx) { + txlow = temp; + dev_dbg(dev, "Updating txlow with the one at RX = %d\n", + txlow.rx); + } + + ret = cqspi_find_tx_high(f_pdata, cell, &temp); + if (ret) + goto out; + dev_dbg(dev, "txhigh: RX: %d TX: %d RD: %d\n", temp.rx, temp.tx, + temp.read_delay); + + if (temp.tx < txhigh.tx) { + txhigh = temp; + dev_dbg(dev, "Updating txhigh with the one at RX = %d\n", + txhigh.rx); + } + } + + /* + * Set bottom left and top right corners. These are theoretical + * corners. They may not actually be "good" points. But the longest + * diagonal will be between these corners. + */ + bottomleft.tx = txlow.tx; + bottomleft.rx = rxlow.rx; + if (txlow.read_delay <= rxlow.read_delay) + bottomleft.read_delay = txlow.read_delay; + else + bottomleft.read_delay = rxlow.read_delay; + + temp = bottomleft; + temp.tx += 4; + temp.rx += 4; + cqspi_phy_apply_setting(f_pdata, &temp); + ret = cqspi_phy_check_pattern(f_pdata, cell); + if (ret) { + temp.read_delay--; + cqspi_phy_apply_setting(f_pdata, &temp); + ret = cqspi_phy_check_pattern(f_pdata, cell); + } + + if (!ret) + bottomleft.read_delay = temp.read_delay; + + topright.tx = txhigh.tx; + topright.rx = rxhigh.rx; + if (txhigh.read_delay >= rxhigh.read_delay) + topright.read_delay = txhigh.read_delay; + else + topright.read_delay = rxhigh.read_delay; + + temp = topright; + temp.tx -= 4; + temp.rx -= 4; + cqspi_phy_apply_setting(f_pdata, &temp); + ret = cqspi_phy_check_pattern(f_pdata, cell); + if (ret) { + temp.read_delay++; + cqspi_phy_apply_setting(f_pdata, &temp); + ret = cqspi_phy_check_pattern(f_pdata, cell); + } + + if (!ret) + topright.read_delay = temp.read_delay; + + dev_dbg(dev, "topright: RX: %d TX: %d RD: %d\n", topright.rx, + topright.tx, topright.read_delay); + dev_dbg(dev, "bottomleft: RX: %d TX: %d RD: %d\n", bottomleft.rx, + bottomleft.tx, bottomleft.read_delay); + + ret = cqspi_phy_find_gaplow(f_pdata, cell, &bottomleft, &topright, + &gaplow); + if (ret) + goto out; + dev_dbg(dev, "gaplow: RX: %d TX: %d RD: %d\n", gaplow.rx, gaplow.tx, + gaplow.read_delay); + + if (bottomleft.read_delay == topright.read_delay) { + /* + * If there is only one passing region, it means that the "true" + * topright is too small to find, so the start of the failing + * region is a good approximation. Put the tuning point in the + * middle and adjust for temperature. + */ + topright = gaplow; + searchpoint.read_delay = bottomleft.read_delay; + searchpoint.tx = bottomleft.tx + + ((topright.tx - bottomleft.tx) / 2); + searchpoint.rx = bottomleft.rx + + ((topright.rx - bottomleft.rx) / 2); + + ret = cqspi_get_temp(&tmp); + if (ret) { + /* + * Assume room temperature if it couldn't be obtained + * from the thermal sensor. + * + * TODO: Change it to dev_warn once support for finding + * out the temperature is added. + */ + dev_dbg(dev, + "Unable to get temperature. Assuming room temperature\n"); + tmp = CQSPI_PHY_DEFAULT_TEMP; + } + + if (tmp < CQSPI_PHY_MIN_TEMP || tmp > CQSPI_PHY_MAX_TEMP) { + dev_err(dev, + "Temperature outside operating range: %dC\n", + tmp); + ret = -EINVAL; + goto out; + } + + /* Avoid a divide-by-zero. */ + if (tmp == CQSPI_PHY_MID_TEMP) + tmp++; + dev_dbg(dev, "Temperature: %dC\n", tmp); + + searchpoint.tx += (topright.tx - bottomleft.tx) / + (330 / (tmp - CQSPI_PHY_MID_TEMP)); + searchpoint.rx += (topright.rx - bottomleft.rx) / + (330 / (tmp - CQSPI_PHY_MID_TEMP)); + } else { + /* + * If there are two passing regions, find the start and end of + * the second one. + */ + ret = cqspi_phy_find_gaphigh(f_pdata, cell, &bottomleft, + &topright, &gaphigh); + if (ret) + goto out; + dev_dbg(dev, "gaphigh: RX: %d TX: %d RD: %d\n", gaphigh.rx, + gaphigh.tx, gaphigh.read_delay); + + /* + * Place the final tuning point in the corner furthest from the + * failing region but leave some margin for temperature changes. + */ + if ((abs(gaplow.tx - bottomleft.tx) + + abs(gaplow.rx - bottomleft.rx)) < + (abs(gaphigh.tx - topright.tx) + + abs(gaphigh.rx - topright.rx))) { + searchpoint = topright; + searchpoint.tx -= 16; + searchpoint.rx -= (16 * (topright.rx - bottomleft.rx)) / + (topright.tx - bottomleft.tx); + } else { + searchpoint = bottomleft; + searchpoint.tx += 16; + searchpoint.rx += (16 * (topright.rx - bottomleft.rx)) / + (topright.tx - bottomleft.tx); + } + } + + /* Set the final PHY settings and check if they are working. */ + cqspi_phy_apply_setting(f_pdata, &searchpoint); + dev_dbg(dev, "Final tuning point: RX: %d TX: %d RD: %d\n", + searchpoint.rx, searchpoint.tx, searchpoint.read_delay); + + ret = cqspi_phy_check_pattern(f_pdata, cell); + if (ret) { + dev_err(dev, + "Failed to find pattern at final calibration point\n"); + ret = -EINVAL; + goto out; + } + + ret = 0; + f_pdata->phy_setting.read_delay = searchpoint.read_delay; +out: + if (ret) + f_pdata->use_phy = false; + return ret; +} + static int cqspi_wait_for_bit(void __iomem *reg, const u32 mask, bool clr) { u32 val; @@ -1400,6 +1975,41 @@ static bool cqspi_supports_mem_op(struct spi_mem *mem, return spi_mem_default_supports_op(mem, op); } +static void cqspi_mem_do_calibration(struct spi_mem *mem, struct spi_mem_op *op) +{ + struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master); + struct cqspi_flash_pdata *f_pdata; + struct nvmem_cell *cell; + struct device *dev = &cqspi->pdev->dev; + int ret; + + f_pdata = &cqspi->f_pdata[mem->spi->chip_select]; + + /* Check if the op is eligible for PHY mode operation. */ + if (!cqspi_phy_op_eligible(op)) + return; + + cell = nvmem_cell_get(dev, "calibration"); + if (IS_ERR_OR_NULL(cell)) { + dev_dbg(dev, "Failed to get calibration data nvmem: %ld\n", + PTR_ERR(cell)); + return; + } + + ret = cqspi_phy_check_pattern(f_pdata, cell); + if (ret) { + dev_dbg(dev, "Pattern not found. Skipping calibration.\n"); + nvmem_cell_put(cell); + return; + } + + ret = cqspi_phy_calibrate(f_pdata, cell); + if (ret) + dev_info(&cqspi->pdev->dev, "PHY calibration failed: %d\n", ret); + + nvmem_cell_put(cell); +} + static int cqspi_of_get_flash_pdata(struct platform_device *pdev, struct cqspi_flash_pdata *f_pdata, struct device_node *np) @@ -1434,6 +2044,12 @@ static int cqspi_of_get_flash_pdata(struct platform_device *pdev, return -ENXIO; } + if (of_property_read_u32(np, "cdns,phy-tx-start", &f_pdata->phy_tx_start)) + f_pdata->phy_tx_start = 16; + + if (of_property_read_u32(np, "cdns,phy-tx-end", &f_pdata->phy_tx_end)) + f_pdata->phy_tx_end = 48; + return 0; } @@ -1534,6 +2150,7 @@ static const struct spi_controller_mem_ops cqspi_mem_ops = { .exec_op = cqspi_exec_mem_op, .get_name = cqspi_get_name, .supports_op = cqspi_supports_mem_op, + .do_calibration = cqspi_mem_do_calibration, }; static int cqspi_setup_flash(struct cqspi_st *cqspi) From patchwork Thu Mar 11 19:12: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: 1451480 X-Patchwork-Delegate: tudor.ambarus@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; helo=desiato.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=desiato.20200630 header.b=qeED4C6I; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=QfCzBFDo; dkim-atps=neutral Received: from desiato.infradead.org (desiato.infradead.org [IPv6:2001:8b0:10b:1:d65d:64ff:fe57:4e05]) (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 4DxJcx4LRmz9sCD for ; Fri, 12 Mar 2021 06:18:09 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:CC:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=N67XPzla65dhipvrTCEeGn9BYboZFWUJg9us2IkvSNk=; b=qeED4C6Ibo3QnzUXsQEhd0B3K mWt0n4U4J/ISpOlZBTsEFzIbiWFcHyTZEOIjWix990W6Yu/0/6w9tMATkLqT5s6j8Bw2i4EgDMZud s3baBUL2AP//6JqzxjLOZ/NfJ2pkV9W2zlhHkE7/MYDCJHJf+Y9VH66Pn720EG7cmKZq6x1ieCNUy tgaGRVPyqyL3ABloc9V61GQsFQIoTczmkIEdJyTO5/PFOmQOhrb5DzMDa0jjPDz1w1P9pNyUXFc/V uyLC8JbNk9u1XVweLlIUogSQU3xYIpDMynboVvyxjg5a7sKIRxqB2Otqd15VxGfyzq2EFVNVA0KyI cVcURm17w==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lKQoL-009xsU-Nx; Thu, 11 Mar 2021 19:17:31 +0000 Received: from fllv0015.ext.ti.com ([198.47.19.141]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lKQjt-009wkt-SS; Thu, 11 Mar 2021 19:12:56 +0000 Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 12BJCos3123972; Thu, 11 Mar 2021 13:12:50 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1615489970; bh=O1hbhr2KTh0yRrzhm4nwwGvK8OQhgZuCTONHf0rb8Ag=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=QfCzBFDoeuiSH69Phe/HCtElVibJmQm4ktfYSqvbFwlnuuDyahU5PIZ5g4Kn3uJt8 nxoJQDBpFwNKikAze0vS84/DXyHWtPHfzRtg//cM/T7TxWWwGLMIxKVBmKeIgeyIu0 4sEYRAqFlAW4koBwCmbmctPLqLOrJYPaFLVOpggc= Received: from DFLE102.ent.ti.com (dfle102.ent.ti.com [10.64.6.23]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 12BJCok6005602 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 11 Mar 2021 13:12:50 -0600 Received: from DFLE113.ent.ti.com (10.64.6.34) 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; Thu, 11 Mar 2021 13:12:50 -0600 Received: from fllv0039.itg.ti.com (10.64.41.19) 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 via Frontend Transport; Thu, 11 Mar 2021 13:12:50 -0600 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by fllv0039.itg.ti.com (8.15.2/8.15.2) with ESMTP id 12BJCHvX080816; Thu, 11 Mar 2021 13:12:45 -0600 From: Pratyush Yadav To: Nishanth Menon , Tero Kristo , Rob Herring , Tudor Ambarus , Michael Walle , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mark Brown , , , , , CC: Pratyush Yadav , Lokesh Vutla Subject: [RFC PATCH 6/6] arm64: dts: ti: k3-j721e-som-p0: Enable PHY calibration Date: Fri, 12 Mar 2021 00:42:16 +0530 Message-ID: <20210311191216.7363-7-p.yadav@ti.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210311191216.7363-1-p.yadav@ti.com> References: <20210311191216.7363-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210311_191254_336475_E4B654D8 X-CRM114-Status: GOOD ( 11.26 ) X-Spam-Score: -2.8 (--) X-Spam-Report: Spam detection software, running on the system "desiato.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: For running the flash in 8D-8D-8D mode at 166 MHz (controller ref clock speed), PHY calibration procedure needs to run to calculate the proper line delays. To perform this calibration, the controller needs to know the location of the pre-determined calibration pattern on the flash. Add a fixed partition table that contains the calibration partition, alon [...] Content analysis details: (-2.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_MSPIKE_H4 RBL: Very Good reputation (+4) [198.47.19.141 listed in wl.mailspike.net] -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [198.47.19.141 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders -0.3 DKIMWL_WL_HIGH DKIMwl.org - High trust sender X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org For running the flash in 8D-8D-8D mode at 166 MHz (controller ref clock speed), PHY calibration procedure needs to run to calculate the proper line delays. To perform this calibration, the controller needs to know the location of the pre-determined calibration pattern on the flash. Add a fixed partition table that contains the calibration partition, along with the rest of the partitions for the platform. Also add a nvmem cell that points to the calibration partition. Signed-off-by: Pratyush Yadav --- Based on patch https://patchwork.kernel.org/project/linux-arm-kernel/patch/20210305153926.3479-2-p.yadav@ti.com/ arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi | 55 +++++++++++++++++++++ 1 file changed, 55 insertions(+) -- 2.30.0 diff --git a/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi index 2fee2906183d..6013ebb45517 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi @@ -170,6 +170,8 @@ J721E_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) /* MCU_OSPI0_CSn0 */ &ospi0 { pinctrl-names = "default"; pinctrl-0 = <&mcu_fss0_ospi0_pins_default>; + nvmem-cells = <&ospi_calibration_data>; + nvmem-cell-names = "calibration"; flash@0{ compatible = "jedec,spi-nor"; @@ -184,6 +186,59 @@ flash@0{ cdns,read-delay = <0>; #address-cells = <1>; #size-cells = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partiiton@0 { + label = "ospi.tiboot3"; + reg = <0x0 0x80000>; + }; + + partition@80000 { + label = "ospi.tispl"; + reg = <0x80000 0x200000>; + }; + + partition@280000 { + label = "ospi.u-boot"; + reg = <0x280000 0x400000>; + }; + + partition@680000 { + label = "ospi.env"; + reg = <0x680000 0x20000>; + }; + + partition@6a0000 { + label = "ospi.env.backup"; + reg = <0x6a0000 0x20000>; + }; + + partition@0x6c0000 { + label = "ospi.sysfw"; + reg = <0x6c0000 0x100000>; + }; + + partition@800000 { + label = "ospi.rootfs"; + reg = <0x800000 0x37e0000>; + }; + + calibration_partition: partition@3fe0000 { + compatible = "nvmem-cells"; + label = "ospi.phypattern"; + reg = <0x3fe0000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; + + ospi_calibration_data: ospi-calibration-cell@0 { + reg = <0x0 0x80>; + }; + }; + }; }; };