From nobody Sun Oct 5 00:14:15 2025 Received: from fllvem-ot03.ext.ti.com (fllvem-ot03.ext.ti.com [198.47.19.245]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4A9A24C7F; Mon, 11 Aug 2025 19:33:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.245 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940802; cv=none; b=dfWjjQthJlJjObBPjIDjauKQyNbig0GyIG81x5JHtMuJDKY3Jx3ZDxBI+iPXXJ2wHLUOpgCGNToMKgTqQTEp/jxOT+yD3KaFr7ENhiSACS7rR91BVb2L8X4Y15p4o7ohq3Pc/45SCk1tMgqU6Ms4m3mwhnD5uXyW3ZuQJyhnYHA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940802; c=relaxed/simple; bh=ImbvtDUXb1pTf8oPmUPiBZCqeCqvg1xqe1HCmHaQbQA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=uayvGDOChvJzwm+rtbvHX4qlV7H2cFe+ZJU+t2fs7VYqOQoV7aEdXla/F7DzdAQ4tx5bRQgq0f9RqcOZLzMMnxSAq2+6yGbsf/6Z8ZxqO13/fQf9JKkavrDhOQN5nWjDp8XG0a9hKh2lywEDzR9dedqr/OdTSvTabnZ5J3ILtL8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=oBKPVKhM; arc=none smtp.client-ip=198.47.19.245 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="oBKPVKhM" Received: from fllvem-sh04.itg.ti.com ([10.64.41.54]) by fllvem-ot03.ext.ti.com (8.15.2/8.15.2) with ESMTP id 57BJX2lo1180188; Mon, 11 Aug 2025 14:33:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1754940782; bh=APF5bHQmgG8ox+n+lb2Pf49z5+3ddAxHmRPYSNB3FA0=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=oBKPVKhMyIULKXmH9flNHB70B+IJZdXWkMHJzwL97rChVbMtZwMaG/idL4kqUoSFC VKFJI4J/XaiQn9bcgiC3jCxpiph5J70m+Z3545xNdmzjxOUzw3NUZ+sPaeNs/rDSA/ fsgFodGfSJcWZveHV/jaUalBxfsfUU7wirtcxWsc= Received: from DFLE105.ent.ti.com (dfle105.ent.ti.com [10.64.6.26]) by fllvem-sh04.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 57BJX2PX3941521 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Mon, 11 Aug 2025 14:33:02 -0500 Received: from DFLE101.ent.ti.com (10.64.6.22) by DFLE105.ent.ti.com (10.64.6.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.55; Mon, 11 Aug 2025 14:33:01 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) 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.2507.55 via Frontend Transport; Mon, 11 Aug 2025 14:33:01 -0500 Received: from santhoshkumark.dhcp.ti.com (santhoshkumark.dhcp.ti.com [172.24.233.254]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 57BJWq1o3690681; Mon, 11 Aug 2025 14:32:57 -0500 From: Santhosh Kumar K To: , , , , , , , CC: , , , , , , Subject: [RFC PATCH 01/10] spi: spi-mem: Introduce support for tuning controller Date: Tue, 12 Aug 2025 01:02:10 +0530 Message-ID: <20250811193219.731851-2-s-k6@ti.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250811193219.731851-1-s-k6@ti.com> References: <20250811193219.731851-1-s-k6@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" From: Pratyush Yadav Some controllers like the Cadence OSPI controller need to perform a tuning sequence to operate at high data rates. Tuning is needs to happen once the device is switched to appropriate mode (say 8S-8S-8S or 8D-8D-8D). Add a hook that spi-mem client devices can call in order to tune the controller to operate in a given mode and data rate. This is somewhat similar to eMMC/SD tuning for higher speed modes like HS200, but there isn't a standard specification around the same though. Signed-off-by: Pratyush Yadav Signed-off-by: Santhosh Kumar K --- drivers/spi/spi-mem.c | 11 +++++++++++ include/linux/spi/spi-mem.h | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 064b99204d9a..6c254291ee23 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -559,6 +559,17 @@ int spi_mem_adjust_op_size(struct spi_mem *mem, struct= spi_mem_op *op) } EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size); =20 +int spi_mem_execute_tuning(struct spi_mem *mem, const struct spi_mem_op *o= p) +{ + struct spi_controller *ctlr =3D mem->spi->controller; + + if (!ctlr->mem_ops || !ctlr->mem_ops->execute_tuning) + return -EOPNOTSUPP; + + return ctlr->mem_ops->execute_tuning(mem, op); +} +EXPORT_SYMBOL_GPL(spi_mem_execute_tuning); + /** * spi_mem_adjust_op_freq() - Adjust the frequency of a SPI mem operation = to * match controller, PCB and chip limitations diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 82390712794c..639fee61251c 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -314,6 +314,12 @@ static inline void *spi_mem_get_drvdata(struct spi_mem= *mem) * @poll_status: poll memory device status until (status & mask) =3D=3D ma= tch or * when the timeout has expired. It fills the data buffer wi= th * the last status value. + * @execute_tuning: perform PHY tuning to achieve high speed SPI operation= s. + * 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 tuning is required + * for the type of read op passed. * * This interface should be implemented by SPI controllers providing an * high-level interface to execute SPI memory operation, which is usually = the @@ -344,6 +350,8 @@ struct spi_controller_mem_ops { unsigned long initial_delay_us, unsigned long polling_rate_us, unsigned long timeout_ms); + int (*execute_tuning)(struct spi_mem *mem, + const struct spi_mem_op *op); }; =20 /** @@ -423,6 +431,7 @@ bool spi_mem_default_supports_op(struct spi_mem *mem, #endif /* CONFIG_SPI_MEM */ =20 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op); +int spi_mem_execute_tuning(struct spi_mem *mem, const struct spi_mem_op *o= p); void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op); u64 spi_mem_calc_op_duration(struct spi_mem *mem, struct spi_mem_op *op); =20 --=20 2.34.1 From nobody Sun Oct 5 00:14:15 2025 Received: from fllvem-ot04.ext.ti.com (fllvem-ot04.ext.ti.com [198.47.19.246]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3AD574C7F; Mon, 11 Aug 2025 19:33:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.246 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940807; cv=none; b=S/dyrwWIGh486PcuTUBUJSH1g6crABYi/BRScvy8c4xPrd+t3aXpXgdgyRFJPPMAbNoCiZTgC7hiY/9YUeqy105/OblVUXgOYqWTQPy0zTHxt3v0gMVSLrH54QnB9krYwOFy9Qck9iER8VETxkixWTLCXdmnTYrwNzkuYguMK5Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940807; c=relaxed/simple; bh=g7Ah1kkIryP4xwbXIfsxZ/qF01cVHEDxpMYQcjcLvC4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=GNqY4TEkEhfMs8mnvf0F57jHiDQ6NQd2lGVo0BmnbB6ZovHGr7RgEZKAUr5RHBKpWnpdmen8qT8iWn8G2p4U6q9L7fdWImKQCVA7P5HVDXlgDkCfKM/MoOsr7rBL9tuXjVu5oB3kJLWNu4GvXWKuugmgBLQURfLY0pih/17nHH8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=nBVmKFv3; arc=none smtp.client-ip=198.47.19.246 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="nBVmKFv3" Received: from lelvem-sh01.itg.ti.com ([10.180.77.71]) by fllvem-ot04.ext.ti.com (8.15.2/8.15.2) with ESMTP id 57BJX6Mr1609373; Mon, 11 Aug 2025 14:33:06 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1754940786; bh=GnCw4UgjQY0VUHwgVnP6axN/oo0k5HxGKufTviylG+k=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=nBVmKFv3COW40w1KPfoV2SJsPzFsOb8qPz5uKlRCJUU2uD/aFYKiRJkcxPNTpxIuo +K/RlK/2ejMNduU7cukySSup6Q4KhyvtfuGM9vj+iqLU7C05o8TyX3ZjPbnlNaO8YO 2NYp02GbwziBPx9LEIhAG3MB8Kw5Rv4zD+b+jp3s= Received: from DFLE105.ent.ti.com (dfle105.ent.ti.com [10.64.6.26]) by lelvem-sh01.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 57BJX6t22910817 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Mon, 11 Aug 2025 14:33:06 -0500 Received: from DFLE101.ent.ti.com (10.64.6.22) by DFLE105.ent.ti.com (10.64.6.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.55; Mon, 11 Aug 2025 14:33:06 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) 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.2507.55 via Frontend Transport; Mon, 11 Aug 2025 14:33:06 -0500 Received: from santhoshkumark.dhcp.ti.com (santhoshkumark.dhcp.ti.com [172.24.233.254]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 57BJWq1p3690681; Mon, 11 Aug 2025 14:33:02 -0500 From: Santhosh Kumar K To: , , , , , , , CC: , , , , , , Subject: [RFC PATCH 02/10] spi: spi-mem: Define spi_mem_tuning_params and spi_mem_get_tuning_params() Date: Tue, 12 Aug 2025 01:02:11 +0530 Message-ID: <20250811193219.731851-3-s-k6@ti.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250811193219.731851-1-s-k6@ti.com> References: <20250811193219.731851-1-s-k6@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" Define a structure 'spi_mem_tuning_params' to store the PHY tuning pattern and size of the pattern. Also, define a function 'spi_mem_get_tuning_params' to retrieve the information from SPI controller. This is required as different SPI controller may have different stress or attack pattern of different length that needs to be read in order to tune the controller correctly. In absence of such callback, spi-mem clients can use static tables on the flashes like SFDP or NAND param page values. Signed-off-by: Santhosh Kumar K --- drivers/spi/spi-mem.c | 11 +++++++++++ include/linux/spi/spi-mem.h | 14 ++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 6c254291ee23..cfee5288fc81 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -570,6 +570,17 @@ int spi_mem_execute_tuning(struct spi_mem *mem, const = struct spi_mem_op *op) } EXPORT_SYMBOL_GPL(spi_mem_execute_tuning); =20 +int spi_mem_get_tuning_params(struct spi_mem *mem, struct spi_mem_tuning_p= arams *tuning_params) +{ + struct spi_controller *ctlr =3D mem->spi->controller; + + if (!ctlr->mem_ops || !ctlr->mem_ops->get_tuning_params) + return -EOPNOTSUPP; + + return ctlr->mem_ops->get_tuning_params(mem, tuning_params); +} +EXPORT_SYMBOL_GPL(spi_mem_get_tuning_params); + /** * spi_mem_adjust_op_freq() - Adjust the frequency of a SPI mem operation = to * match controller, PCB and chip limitations diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 639fee61251c..f0e96cd4a6d4 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -238,6 +238,16 @@ struct spi_mem_dirmap_desc { void *priv; }; =20 +/** + * struct spi_mem_tuning_params - describes the Tuning parameters + * @pattern_ptr: pointer to the tuning pattern + * @pattern_size: size of the tuning pattern + */ +struct spi_mem_tuning_params { + u8 *pattern_ptr; + unsigned int pattern_size; +}; + /** * struct spi_mem - describes a SPI memory device * @spi: the underlying SPI device @@ -352,6 +362,8 @@ struct spi_controller_mem_ops { unsigned long timeout_ms); int (*execute_tuning)(struct spi_mem *mem, const struct spi_mem_op *op); + int (*get_tuning_params)(struct spi_mem *mem, + struct spi_mem_tuning_params *tuning_params); }; =20 /** @@ -434,6 +446,8 @@ int spi_mem_adjust_op_size(struct spi_mem *mem, struct = spi_mem_op *op); int spi_mem_execute_tuning(struct spi_mem *mem, const struct spi_mem_op *o= p); void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op); u64 spi_mem_calc_op_duration(struct spi_mem *mem, struct spi_mem_op *op); +int spi_mem_get_tuning_params(struct spi_mem *mem, + struct spi_mem_tuning_params *tuning_params); =20 bool spi_mem_supports_op(struct spi_mem *mem, const struct spi_mem_op *op); --=20 2.34.1 From nobody Sun Oct 5 00:14:15 2025 Received: from lelvem-ot02.ext.ti.com (lelvem-ot02.ext.ti.com [198.47.23.235]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 032DA207A22; Mon, 11 Aug 2025 19:33:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.235 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940829; cv=none; b=Eo9YeNZhlCAqPAorStenvMhYOJOoZVzhDDYRaecKQ3FCRYflxYk3kD4HXNj2UYqJK8PfgUALf3jzaCJVSs5aBWZzjyGLF4YehDTkK0hXRJvfI3mGBewYsn3C7LRN20XcJTSrRSRcVTPxJthlBaEI2cYWejlOENr8rDFJQ7M4+V0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940829; c=relaxed/simple; bh=pf5c+ZoVAYMGy0I3S72deyXTPHc0lFoJ/nL1xToERAU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dtR5KX9iJnubJcpr9EciyNtfgNoVgBz7TAIqS6Tg2Tgs3od88kJLTTOnRwnCmYs1olzHhvTetFwZ18I+2insmJ3x12lL3ms5ti7dne1lzS8OHtiGOM502TqqLD5E3aw2qDx8jvkpcukURbKPf7h2xLDeDsojagsrd8jd5nYbXY4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=f2B30xwH; arc=none smtp.client-ip=198.47.23.235 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="f2B30xwH" Received: from lelvem-sh01.itg.ti.com ([10.180.77.71]) by lelvem-ot02.ext.ti.com (8.15.2/8.15.2) with ESMTP id 57BJXBkB1678213; Mon, 11 Aug 2025 14:33:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1754940791; bh=YdngpaN6rCWaiPZrMnO8j4ato33z/K66hxWiRc0bfZs=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=f2B30xwHAzok/DYFLm6sq1Nht6Lr2fTlpiSwUCWeHbmcN7Xx9sb15htsqz1XnOlCc g1wgvSvJExN0JMF7m1E90zZfNjDOfmAvw3jy0ywXvWL1myHhxaRsxyDCqccAcTkJT2 KLZ+PWBcVm633QwamgtUX6VJMI6VOUmPtX9Wbz/4= Received: from DFLE115.ent.ti.com (dfle115.ent.ti.com [10.64.6.36]) by lelvem-sh01.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 57BJXBvX2910863 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Mon, 11 Aug 2025 14:33:11 -0500 Received: from DFLE112.ent.ti.com (10.64.6.33) 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.2507.55; Mon, 11 Aug 2025 14:33:10 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) 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.2507.55 via Frontend Transport; Mon, 11 Aug 2025 14:33:10 -0500 Received: from santhoshkumark.dhcp.ti.com (santhoshkumark.dhcp.ti.com [172.24.233.254]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 57BJWq1q3690681; Mon, 11 Aug 2025 14:33:06 -0500 From: Santhosh Kumar K To: , , , , , , , CC: , , , , , , Subject: [RFC PATCH 03/10] mtd: nand: spi: Introduce _execute_tuning for mtd devices Date: Tue, 12 Aug 2025 01:02:12 +0530 Message-ID: <20250811193219.731851-4-s-k6@ti.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250811193219.731851-1-s-k6@ti.com> References: <20250811193219.731851-1-s-k6@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" Add _execute_tuning to mtd_info allowing mtd devices to run their own PHY tuning procedure to run at higher frequencies. Signed-off-by: Santhosh Kumar K --- drivers/mtd/nand/spi/core.c | 61 +++++++++++++++++++++++++++++++++++++ include/linux/mtd/mtd.h | 1 + 2 files changed, 62 insertions(+) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index b0898990b2a5..c890a42cdb0a 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -1483,6 +1483,66 @@ static void spinand_mtd_resume(struct mtd_info *mtd) spinand_ecc_enable(spinand, false); } =20 +static int spinand_mtd_execute_tuning(struct mtd_info *mtd, struct mtd_par= t *part) +{ + struct spinand_device *spinand =3D mtd_to_spinand(mtd); + struct nand_device *nand =3D spinand_to_nand(spinand); + struct nand_pos page_pos; + struct nand_page_io_req page_req; + struct spi_mem_op read_page_op; + struct spi_mem_tuning_params *tuning_params; + int ret, pageoffs; + u8 status; + + tuning_params =3D kzalloc(sizeof(*tuning_params), GFP_KERNEL); + if (!tuning_params) + return -ENOMEM; + + ret =3D spi_mem_get_tuning_params(spinand->spimem, tuning_params); + if (ret) + goto err_free_tuning_params; + + /* + * TODO: + * Write the PHY pattern to cache using spinand_write_to_cache_op() + * and readback pattern from cache during tuning instead of using up + * the flash's space. + * + * For SPI NOR: + * Things remain same as done here, the PHY pattern will be preflashed to + * at an offset and will be readback during tuning. + */ + + pageoffs =3D nanddev_offs_to_pos(nand, part->offset, &page_pos); + page_req.pos =3D page_pos; + + read_page_op =3D *spinand->op_templates.read_cache; + read_page_op.addr.val =3D pageoffs; + read_page_op.data.nbytes =3D tuning_params->pattern_size; + + ret =3D spinand_load_page_op(spinand, &page_req); + if (ret) + goto err_free_tuning_params; + + ret =3D spinand_wait(spinand, SPINAND_READ_INITIAL_DELAY_US, + SPINAND_READ_POLL_DELAY_US, &status); + if (ret < 0) + goto err_free_tuning_params; + + spinand_ondie_ecc_save_status(nand, status); + ret =3D spi_mem_execute_tuning(spinand->spimem, &read_page_op); + + /* + * TODO: + * Fallback to a lower frequency and a less dummy cycle in case of + * PHY tuning failure + */ + +err_free_tuning_params: + kfree(tuning_params); + return ret; +} + static int spinand_init(struct spinand_device *spinand) { struct device *dev =3D &spinand->spimem->spi->dev; @@ -1551,6 +1611,7 @@ static int spinand_init(struct spinand_device *spinan= d) mtd->_erase =3D spinand_mtd_erase; mtd->_max_bad_blocks =3D nanddev_mtd_max_bad_blocks; mtd->_resume =3D spinand_mtd_resume; + mtd->_execute_tuning =3D spinand_mtd_execute_tuning; =20 if (spinand_user_otp_size(spinand) || spinand_fact_otp_size(spinand)) { ret =3D spinand_set_mtd_otp_ops(spinand); diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 8d10d9d2e830..5ac8dc02280d 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -355,6 +355,7 @@ struct mtd_info { int (*_suspend) (struct mtd_info *mtd); void (*_resume) (struct mtd_info *mtd); void (*_reboot) (struct mtd_info *mtd); + int (*_execute_tuning) (struct mtd_info *mtd, struct mtd_part *part); /* * If the driver is something smart, like UBI, it may need to maintain * its own reference counting. The below functions are only for driver. --=20 2.34.1 From nobody Sun Oct 5 00:14:15 2025 Received: from lelvem-ot02.ext.ti.com (lelvem-ot02.ext.ti.com [198.47.23.235]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D7B9B2D949C; Mon, 11 Aug 2025 19:33:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.235 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940831; cv=none; b=G88yJLI72tCNSLPbnLglo1Ro4hOXh7KwoFHbfLJyyTATjXOw0d2/m95oS+e6sxVzQDFQcgNDOH2TabWnHalbM9bTWBn+5HevZ5+IZKx7KltX3UBU2xKbr6jvnLuIq8CoT2hblIf10eyPvgi2jByZKKcWv7mvLZ8/FYzLgR24/Uc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940831; c=relaxed/simple; bh=3vK14E6SbeBnJWd93I8RGPb/B/hdo1aya9mqwBariFw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=RDQJLmnboragabwFA+GDX2qhXqpdV9n0itX9ZDDYd5MIFhuQQYtuO1ejIqNIJHT/3TiG0FPbaAbUe0EKGHEI8Jb9M2f9VBVAq7/h18QaSjVMuO4gpPTxIIUBd8Jk/Q5qptdiUGv9iCawOu7a0SThEfMSaH8XeCFJp55alZ538j0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=qfjpm+8E; arc=none smtp.client-ip=198.47.23.235 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="qfjpm+8E" Received: from lelvem-sh01.itg.ti.com ([10.180.77.71]) by lelvem-ot02.ext.ti.com (8.15.2/8.15.2) with ESMTP id 57BJXFEj1678217; Mon, 11 Aug 2025 14:33:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1754940795; bh=Mbm6XmTsVQep+WWUIidWCy6jZKFBV6BX76B/Uekl5C0=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=qfjpm+8E05PLNOAW/vc62xU1UTRIgM+5e6bKS4F22EGRXQbkd6ZGGwysE5q8h36QY JFSY7JnG0Id0wk5jBooI+tfoPaCFC3KK1U5T+YsOW71oSpSpdlPLyv7qUkgf5SjED8 gsOt5Tr/FbUd7wzUtZgFIvblBrg9kKoLGssKFwTI= Received: from DFLE112.ent.ti.com (dfle112.ent.ti.com [10.64.6.33]) by lelvem-sh01.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 57BJXFld2910894 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Mon, 11 Aug 2025 14:33:15 -0500 Received: from DFLE111.ent.ti.com (10.64.6.32) 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.2507.55; Mon, 11 Aug 2025 14:33:15 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) by DFLE111.ent.ti.com (10.64.6.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.55 via Frontend Transport; Mon, 11 Aug 2025 14:33:15 -0500 Received: from santhoshkumark.dhcp.ti.com (santhoshkumark.dhcp.ti.com [172.24.233.254]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 57BJWq1r3690681; Mon, 11 Aug 2025 14:33:11 -0500 From: Santhosh Kumar K To: , , , , , , , CC: , , , , , , Subject: [RFC PATCH 04/10] mtd: mtdcore: Call mtd_execute_tuning during mtd_register Date: Tue, 12 Aug 2025 01:02:13 +0530 Message-ID: <20250811193219.731851-5-s-k6@ti.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250811193219.731851-1-s-k6@ti.com> References: <20250811193219.731851-1-s-k6@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" Call mtd_execute_tuning() during the mtd_register() which redirects to the flash specific tuning procedure to run at higher frequencies. Signed-off-by: Santhosh Kumar K --- drivers/mtd/mtdcore.c | 19 +++++++++++++++++++ drivers/mtd/mtdcore.h | 1 + 2 files changed, 20 insertions(+) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 5ba9a741f5ac..f50cebcdb670 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -1023,6 +1023,22 @@ static int mtd_otp_nvmem_add(struct mtd_info *mtd) return dev_err_probe(dev, err, "Failed to register OTP NVMEM device\n"); } =20 +int mtd_execute_tuning(struct mtd_info *mtd) +{ + struct mtd_part *part; + + list_for_each_entry(part, &mtd->partitions, node) { + struct mtd_info *part_info =3D + container_of(part, struct mtd_info, part); + if (part_info->name && + !strcmp(part_info->name, "ospi.phypattern")) { + return mtd->_execute_tuning(mtd, part); + } + } + + return -ENODEV; +} + /** * mtd_device_parse_register - parse partitions and register an MTD device. * @@ -1087,6 +1103,9 @@ int mtd_device_parse_register(struct mtd_info *mtd, c= onst char * const *types, if (ret) goto out; =20 + if (mtd_execute_tuning(mtd) =3D=3D -ENODEV) + dev_info(&mtd->dev, "PHY pattern partition not found\n"); + /* * FIXME: some drivers unfortunately call this function more than once. * So we have to check if we've already assigned the reboot notifier. diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h index b014861a06a6..04055fcd2df8 100644 --- a/drivers/mtd/mtdcore.h +++ b/drivers/mtd/mtdcore.h @@ -13,6 +13,7 @@ int del_mtd_device(struct mtd_info *mtd); int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, in= t); int del_mtd_partitions(struct mtd_info *); void release_mtd_partition(struct mtd_info *mtd); +int mtd_execute_tuning(struct mtd_info *mtd); =20 struct mtd_partitions; =20 --=20 2.34.1 From nobody Sun Oct 5 00:14:15 2025 Received: from fllvem-ot04.ext.ti.com (fllvem-ot04.ext.ti.com [198.47.19.246]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8AB2E2D662E; Mon, 11 Aug 2025 19:33:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.246 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940815; cv=none; b=DKPT1mTqahRj0qV9WDFLKBmJw8xerHVIFtxJRWnqzFZuqnPlQnYPIDeBi+XVJ8i586aRNYkXh/h6HOgV76NCvuutHvGOP/Hh++YJ/S7+zUjawbFmXYp8JrPacuHl2l1xAbtBM2gyoW43DzzQgA+WL/7m5EDw+L+Hc6U3G/uovOc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940815; c=relaxed/simple; bh=o5mEf0wKLmJbk2hwJ6vSHDVbjiGp9Ghm5NGCX2ZXEIA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hlXWJ32fJFx1iLb+9dvutSx0HSMH7Hw1YD2YoipWPdntNl1TY/0/vpFj6uMNNNe2PHxLHIdbQB6e0OLFzWoa1FmKSDuoSdz5/515GNehdyuCG0qc/4UzQoFqJHpKpkQOd19wwZeAtqeH/kcxaNFQehNWjOZ8eK4HF0t/jdePgQ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=IJy263T4; arc=none smtp.client-ip=198.47.19.246 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="IJy263T4" Received: from lelvem-sh01.itg.ti.com ([10.180.77.71]) by fllvem-ot04.ext.ti.com (8.15.2/8.15.2) with ESMTP id 57BJXKl01609393; Mon, 11 Aug 2025 14:33:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1754940800; bh=11ROVwz5O/XLyUNvqIWUa8IJxyUhmbImPXBSiHjpbt4=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=IJy263T4ALh0QVjGntSpkJ1TZ4ELjhTQojCaFJbrjU+vBi2mABZuYEsxLiStA/ncv BLBG3hdk6+7NLRPRX18m9GxfyeccoWEXL1QogonvgCXMQkL1SPnk9yLpV28Q+3tLvc IiEZ0/6649b5OVQifbyrt4Q8cMlhWwbtM7ZJb4DE= Received: from DLEE109.ent.ti.com (dlee109.ent.ti.com [157.170.170.41]) by lelvem-sh01.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 57BJXKPM2910901 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Mon, 11 Aug 2025 14:33:20 -0500 Received: from DLEE102.ent.ti.com (157.170.170.32) 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.2507.55; Mon, 11 Aug 2025 14:33:19 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) 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.2507.55 via Frontend Transport; Mon, 11 Aug 2025 14:33:19 -0500 Received: from santhoshkumark.dhcp.ti.com (santhoshkumark.dhcp.ti.com [172.24.233.254]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 57BJWq1s3690681; Mon, 11 Aug 2025 14:33:15 -0500 From: Santhosh Kumar K To: , , , , , , , CC: , , , , , , Subject: [RFC PATCH 05/10] spi: cadence-quadspi: Move cqspi_readdata_capture() above all operations Date: Tue, 12 Aug 2025 01:02:14 +0530 Message-ID: <20250811193219.731851-6-s-k6@ti.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250811193219.731851-1-s-k6@ti.com> References: <20250811193219.731851-1-s-k6@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" Move the cqspi_readdata_capture() above all the read and write operations as PHY can be enabled for writes as well, in future. Signed-off-by: Santhosh Kumar K --- drivers/spi/spi-cadence-quadspi.c | 46 +++++++++++++++---------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-qu= adspi.c index bb90fbdd641f..da5823bcc1ea 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -444,6 +444,29 @@ static int cqspi_wait_idle(struct cqspi_st *cqspi) } } =20 +static void cqspi_readdata_capture(struct cqspi_st *cqspi, + const bool bypass, + const unsigned int delay) +{ + void __iomem *reg_base =3D cqspi->iobase; + unsigned int reg; + + reg =3D readl(reg_base + CQSPI_REG_READCAPTURE); + + if (bypass) + reg |=3D (1 << CQSPI_REG_READCAPTURE_BYPASS_LSB); + else + reg &=3D ~(1 << CQSPI_REG_READCAPTURE_BYPASS_LSB); + + reg &=3D ~(CQSPI_REG_READCAPTURE_DELAY_MASK + << CQSPI_REG_READCAPTURE_DELAY_LSB); + + reg |=3D (delay & CQSPI_REG_READCAPTURE_DELAY_MASK) + << CQSPI_REG_READCAPTURE_DELAY_LSB; + + writel(reg, reg_base + CQSPI_REG_READCAPTURE); +} + static int cqspi_exec_flash_cmd(struct cqspi_st *cqspi, unsigned int reg) { void __iomem *reg_base =3D cqspi->iobase; @@ -1259,29 +1282,6 @@ static void cqspi_config_baudrate_div(struct cqspi_s= t *cqspi) writel(reg, reg_base + CQSPI_REG_CONFIG); } =20 -static void cqspi_readdata_capture(struct cqspi_st *cqspi, - const bool bypass, - const unsigned int delay) -{ - void __iomem *reg_base =3D cqspi->iobase; - unsigned int reg; - - reg =3D readl(reg_base + CQSPI_REG_READCAPTURE); - - if (bypass) - reg |=3D (1 << CQSPI_REG_READCAPTURE_BYPASS_LSB); - else - reg &=3D ~(1 << CQSPI_REG_READCAPTURE_BYPASS_LSB); - - reg &=3D ~(CQSPI_REG_READCAPTURE_DELAY_MASK - << CQSPI_REG_READCAPTURE_DELAY_LSB); - - reg |=3D (delay & CQSPI_REG_READCAPTURE_DELAY_MASK) - << CQSPI_REG_READCAPTURE_DELAY_LSB; - - writel(reg, reg_base + CQSPI_REG_READCAPTURE); -} - static void cqspi_configure(struct cqspi_flash_pdata *f_pdata, unsigned long sclk) { --=20 2.34.1 From nobody Sun Oct 5 00:14:15 2025 Received: from fllvem-ot04.ext.ti.com (fllvem-ot04.ext.ti.com [198.47.19.246]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 07F322D63EF; Mon, 11 Aug 2025 19:33:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.246 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940814; cv=none; b=T4QjOHlB+IXpCdd1NDzCfpC5X4cOfYlNcrAu1VwSrxSL3OkhFEAtumKvB19zYkJYpj/ttIPQq/CeaN0c0FUld2b5H/pX0/o14kF4Kip8VkKV96DDmXqEyIDwR7TJKPD6zxCqKYJF1li0qObMC//U3eZ5TPuj5a3LN5yJs3dym6I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940814; c=relaxed/simple; bh=KEzWFBcwrXQMQm7m4doco1MeSg2Xh+gOQVNxD7S1psU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=bbvhPCyI5yZP7Fc1Qv3Yw18gsIuAQekhF53EmdBXOA3PeyXy8+23BeC0upQdc1k9m4MP98FkVUD9wpw6TXk+EXKAUEIzOcwqkjk5UHsUdwp1G2pFNF/+RI2aYCJGHeo0sg/MDMB6ipAVUbtTrfs69ej8jd2BQFfohlZFjQVeDDM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=cIHNiIc1; arc=none smtp.client-ip=198.47.19.246 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="cIHNiIc1" Received: from lelvem-sh01.itg.ti.com ([10.180.77.71]) by fllvem-ot04.ext.ti.com (8.15.2/8.15.2) with ESMTP id 57BJXOr41609411; Mon, 11 Aug 2025 14:33:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1754940804; bh=5gk44N9m+4BFJqlP2jfYY0PfWMGLlRjYM9wX9ai9Aag=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=cIHNiIc1qKSBLG53AFIj+g3eoBXDCHmk36So4EgJLdyix0/W4iAWxSeHMns9xYzIx Vw83pgdmq2CJajYGpU+jitAMHrfsrnPK+7MiM0kK6ONACoDGiEki0LL8iucYd/bc13 LF6NUbwvVw2hGobHRgpue8epZaQgzJtFcbRUDgzQ= Received: from DLEE109.ent.ti.com (dlee109.ent.ti.com [157.170.170.41]) by lelvem-sh01.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 57BJXO3s2910915 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Mon, 11 Aug 2025 14:33:24 -0500 Received: from DLEE105.ent.ti.com (157.170.170.35) 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.2507.55; Mon, 11 Aug 2025 14:33:23 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) 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.2507.55 via Frontend Transport; Mon, 11 Aug 2025 14:33:23 -0500 Received: from santhoshkumark.dhcp.ti.com (santhoshkumark.dhcp.ti.com [172.24.233.254]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 57BJWq1t3690681; Mon, 11 Aug 2025 14:33:19 -0500 From: Santhosh Kumar K To: , , , , , , , CC: , , , , , , Subject: [RFC PATCH 06/10] spi: cadence-quadspi: Use BIT() macro for CQSPI_REG_READCAPTURE_BYPASS Date: Tue, 12 Aug 2025 01:02:15 +0530 Message-ID: <20250811193219.731851-7-s-k6@ti.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250811193219.731851-1-s-k6@ti.com> References: <20250811193219.731851-1-s-k6@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" Simplify CQSPI_REG_READCAPTURE_BYPASS macro and add comment on Bypass bit. Signed-off-by: Santhosh Kumar K --- drivers/spi/spi-cadence-quadspi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-qu= adspi.c index da5823bcc1ea..1d86a7bc405e 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -180,7 +180,7 @@ struct cqspi_driver_platdata { #define CQSPI_REG_DELAY_TSHSL_MASK 0xFF =20 #define CQSPI_REG_READCAPTURE 0x10 -#define CQSPI_REG_READCAPTURE_BYPASS_LSB 0 +#define CQSPI_REG_READCAPTURE_BYPASS BIT(0) #define CQSPI_REG_READCAPTURE_DELAY_LSB 1 #define CQSPI_REG_READCAPTURE_DELAY_MASK 0xF =20 @@ -453,10 +453,15 @@ static void cqspi_readdata_capture(struct cqspi_st *c= qspi, =20 reg =3D readl(reg_base + CQSPI_REG_READCAPTURE); =20 + /* + * Bypass bit - to enable/disable the signal from adapted loopback + * clock circuit which is driven into Rx DLL and is used for data + * capturing rather than internally generated ref_clk. + */ if (bypass) - reg |=3D (1 << CQSPI_REG_READCAPTURE_BYPASS_LSB); + reg |=3D CQSPI_REG_READCAPTURE_BYPASS; else - reg &=3D ~(1 << CQSPI_REG_READCAPTURE_BYPASS_LSB); + reg &=3D ~CQSPI_REG_READCAPTURE_BYPASS; =20 reg &=3D ~(CQSPI_REG_READCAPTURE_DELAY_MASK << CQSPI_REG_READCAPTURE_DELAY_LSB); --=20 2.34.1 From nobody Sun Oct 5 00:14:15 2025 Received: from fllvem-ot03.ext.ti.com (fllvem-ot03.ext.ti.com [198.47.19.245]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 66E8B1F4CA1; Mon, 11 Aug 2025 19:33:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.245 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940830; cv=none; b=M57pqu6UYMj6H5qjvDPmrJUOKXxtzmvmxtdL39CdZugzryfiay1ECjt48Wj3PjRbVfD/34LD2menKOfW1JWPqRn3rUS46C5mR6rcJBB9sOc39E7c6mD5eyV3WYaat9qR5Orj6u17GdIDMAfamBs4qQ9d5x4pgUBlx7g8pQFYFXM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940830; c=relaxed/simple; bh=ZYw4nGminDovyQqY/ngO8wTPS+J9Jk3bwohpsb258og=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=FD644CSRMbwP5v6CMyUBSw8Edv7vDoV+Tk+/pl/hTx0VghZBRt/DTTwQrfnCuXccz0O1rGez3yI+0PFIZ5Id91A/quC/v3HGkA/7y5xOdLUfFUI6LDALLr3M9Hz8IaRBGAAQKB7x+1XZhYFH8SdvUl4IHvreA5kF/JgbAHW9YOQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=L8EouCty; arc=none smtp.client-ip=198.47.19.245 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="L8EouCty" Received: from fllvem-sh04.itg.ti.com ([10.64.41.54]) by fllvem-ot03.ext.ti.com (8.15.2/8.15.2) with ESMTP id 57BJXStN1180229; Mon, 11 Aug 2025 14:33:28 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1754940808; bh=h12tTv1cWWgw4+Y3SAdANJyY08YLVg7u64X0PKlD5cM=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=L8EouCtyhKn37Jfq8SjDgL9LqH0kz0u+5rJzQO16hHNrwTHsOKqBggrCUSmCtAqKf e3L/PA6LUWFihSvOjdO5U+gwlNcbcqvLI2uZ+WKWF2Oc04TrTiUh0Og5xwQP+SnmQR YKZ4VKBKH5z1PzqExdAVPA3M5LA+XEo68JxKQA68= Received: from DFLE103.ent.ti.com (dfle103.ent.ti.com [10.64.6.24]) by fllvem-sh04.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 57BJXSgx3941687 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Mon, 11 Aug 2025 14:33:28 -0500 Received: from DFLE100.ent.ti.com (10.64.6.21) by DFLE103.ent.ti.com (10.64.6.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.55; Mon, 11 Aug 2025 14:33:28 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) 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.2507.55 via Frontend Transport; Mon, 11 Aug 2025 14:33:28 -0500 Received: from santhoshkumark.dhcp.ti.com (santhoshkumark.dhcp.ti.com [172.24.233.254]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 57BJWq1u3690681; Mon, 11 Aug 2025 14:33:24 -0500 From: Santhosh Kumar K To: , , , , , , , CC: , , , , , , Subject: [RFC PATCH 07/10] spi: cadence-quadspi: Enable PHY for aligned DAC reads Date: Tue, 12 Aug 2025 01:02:16 +0530 Message-ID: <20250811193219.731851-8-s-k6@ti.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250811193219.731851-1-s-k6@ti.com> References: <20250811193219.731851-1-s-k6@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" From: Pratyush Yadav PHY reads only work at an address that is 16-byte aligned and of size that is a multiple of 16 bytes. So, enable PHY for the aligned middle part and read the unaligned start and end part without PHY. Also, in 8D mode an odd number of bytes cannot be read from the flash since they would result in half a cycle being left over. memcpy_fromio() doesn't guarantee of access width size. So, replace memcpy_fromio() with cqspi_memcpy_fromio(). Signed-off-by: Pratyush Yadav Signed-off-by: Santhosh Kumar K --- drivers/spi/spi-cadence-quadspi.c | 235 +++++++++++++++++++++++++++--- 1 file changed, 215 insertions(+), 20 deletions(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-qu= adspi.c index 1d86a7bc405e..2096027bca4c 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -61,15 +61,23 @@ enum { =20 struct cqspi_st; =20 +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 cs; + struct cqspi_st *cqspi; + u32 clk_rate; + u32 read_delay; + u32 tshsl_ns; + u32 tsd2d_ns; + u32 tchsh_ns; + u32 tslch_ns; + u8 cs; + bool use_phy; + struct phy_setting phy_setting; }; =20 struct cqspi_st { @@ -126,6 +134,7 @@ struct cqspi_driver_platdata { #define CQSPI_TIMEOUT_MS 500 #define CQSPI_READ_TIMEOUT_MS 10 #define CQSPI_BUSYWAIT_TIMEOUT_US 500 +#define CQSPI_PHY_FREQUENCY 166000000 =20 /* Runtime_pm autosuspend delay */ #define CQSPI_AUTOSUSPEND_TIMEOUT 2000 @@ -139,12 +148,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 @@ -472,6 +483,65 @@ static void cqspi_readdata_capture(struct cqspi_st *cq= spi, writel(reg, reg_base + CQSPI_REG_READCAPTURE); } =20 +static void cqspi_phy_enable(struct cqspi_flash_pdata *f_pdata, bool enabl= e) +{ + struct cqspi_st *cqspi =3D f_pdata->cqspi; + void __iomem *reg_base =3D cqspi->iobase; + u32 reg; + u8 dummy; + + if (enable) { + cqspi_readdata_capture(cqspi, true, + f_pdata->phy_setting.read_delay); + + reg =3D readl(reg_base + CQSPI_REG_CONFIG); + reg |=3D 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 =3D readl(reg_base + CQSPI_REG_RD_INSTR); + dummy =3D FIELD_GET(CQSPI_REG_RD_INSTR_DUMMY_MASK + << CQSPI_REG_RD_INSTR_DUMMY_LSB, + reg); + dummy--; + reg &=3D ~(CQSPI_REG_RD_INSTR_DUMMY_MASK + << CQSPI_REG_RD_INSTR_DUMMY_LSB); + reg |=3D FIELD_PREP(CQSPI_REG_RD_INSTR_DUMMY_MASK + << CQSPI_REG_RD_INSTR_DUMMY_LSB, + dummy); + writel(reg, reg_base + CQSPI_REG_RD_INSTR); + } else { + cqspi_readdata_capture(cqspi, !cqspi->rclk_en, + f_pdata->read_delay); + + reg =3D readl(reg_base + CQSPI_REG_CONFIG); + reg &=3D ~(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 =3D readl(reg_base + CQSPI_REG_RD_INSTR); + dummy =3D FIELD_GET(CQSPI_REG_RD_INSTR_DUMMY_MASK + << CQSPI_REG_RD_INSTR_DUMMY_LSB, + reg); + dummy++; + reg &=3D ~(CQSPI_REG_RD_INSTR_DUMMY_MASK + << CQSPI_REG_RD_INSTR_DUMMY_LSB); + reg |=3D FIELD_PREP(CQSPI_REG_RD_INSTR_DUMMY_MASK + << CQSPI_REG_RD_INSTR_DUMMY_LSB, + dummy); + writel(reg, reg_base + CQSPI_REG_RD_INSTR); + } + + cqspi_wait_idle(cqspi); +} + static int cqspi_exec_flash_cmd(struct cqspi_st *cqspi, unsigned int reg) { void __iomem *reg_base =3D cqspi->iobase; @@ -1346,6 +1416,35 @@ static ssize_t cqspi_write(struct cqspi_flash_pdata = *f_pdata, return cqspi_indirect_write_execute(f_pdata, to, buf, len); } =20 +static bool cqspi_phy_op_eligible_sdr(struct cqspi_flash_pdata *f_pdata, + const struct spi_mem_op *op) +{ + if (f_pdata->clk_rate !=3D CQSPI_PHY_FREQUENCY) + return false; + if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr) + return false; + if (!(op->addr.nbytes) || op->addr.buswidth < 1) + return false; + if (!(op->dummy.nbytes) || op->dummy.buswidth < 1) + return false; + if (!(op->data.nbytes) || op->data.buswidth < 1) + 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_sdr(f_pdata, op); +} + static void cqspi_rx_dma_callback(void *param) { struct cqspi_st *cqspi =3D param; @@ -1353,8 +1452,8 @@ static void cqspi_rx_dma_callback(void *param) complete(&cqspi->rx_dma_complete); } =20 -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 =3D f_pdata->cqspi; struct device *dev =3D &cqspi->pdev->dev; @@ -1366,19 +1465,14 @@ static int cqspi_direct_read_execute(struct cqspi_f= lash_pdata *f_pdata, dma_addr_t dma_dst; struct device *ddev; =20 - if (!cqspi->rx_chan || !virt_addr_valid(buf)) { - memcpy_fromio(buf, cqspi->ahb_base + from, len); - return 0; - } - ddev =3D cqspi->rx_chan->device->dev; dma_dst =3D dma_map_single(ddev, buf, len, DMA_FROM_DEVICE); if (dma_mapping_error(ddev, dma_dst)) { dev_err(dev, "dma mapping failed\n"); return -ENOMEM; } - tx =3D dmaengine_prep_dma_memcpy(cqspi->rx_chan, dma_dst, dma_src, - len, flags); + tx =3D dmaengine_prep_dma_memcpy(cqspi->rx_chan, dma_dst, dma_src, len, + flags); if (!tx) { dev_err(dev, "device_prep_dma_memcpy error\n"); ret =3D -EIO; @@ -1398,8 +1492,9 @@ static int cqspi_direct_read_execute(struct cqspi_fla= sh_pdata *f_pdata, } =20 dma_async_issue_pending(cqspi->rx_chan); - if (!wait_for_completion_timeout(&cqspi->rx_dma_complete, - msecs_to_jiffies(max_t(size_t, len, 500)))) { + if (!wait_for_completion_timeout( + &cqspi->rx_dma_complete, + msecs_to_jiffies(max_t(size_t, len, 500)))) { dmaengine_terminate_sync(cqspi->rx_chan); dev_err(dev, "DMA wait_for_completion_timeout\n"); ret =3D -ETIMEDOUT; @@ -1412,6 +1507,106 @@ static int cqspi_direct_read_execute(struct cqspi_f= lash_pdata *f_pdata, return ret; } =20 +static void cqspi_memcpy_fromio(const struct spi_mem_op *op, void *to, + const void __iomem *from, size_t count) +{ + if (op->data.buswidth =3D=3D 8 && op->data.dtr) { + /* + * 8D-8D-8D ops with odd length should be rejected by + * supports_op() so no need to worry about that. + */ + if (count && !IS_ALIGNED((unsigned long)from, 4)) { + *(u16 *)to =3D __raw_readw(from); + from +=3D 2; + to +=3D 2; + count -=3D 2; + } + + /* + * The controller can work with both 32-bit and 64-bit + * platforms. 32-bit platforms won't have a readq. So use a + * readl instead. + */ + if (count >=3D 4) { + int len =3D round_down(count, 4); + + memcpy_fromio(to, from, len); + from +=3D len; + to +=3D len; + count -=3D len; + } + + if (count) { + *(u16 *)to =3D __raw_readw(from); + from +=3D 2; + to +=3D 2; + count -=3D 2; + } + + return; + } + + memcpy_fromio(to, from, count); +} + +static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata, + const struct spi_mem_op *op) +{ + struct cqspi_st *cqspi =3D f_pdata->cqspi; + loff_t from =3D op->addr.val; + loff_t from_aligned, to_aligned; + size_t len =3D op->data.nbytes; + size_t len_aligned; + u_char *buf =3D op->data.buf.in; + int ret; + + if (!cqspi->rx_chan || !virt_addr_valid(buf) || len <=3D 16) { + cqspi_memcpy_fromio(op, 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 =3D (from + 0xF) & ~0xF; + to_aligned =3D (from + len) & ~0xF; + len_aligned =3D to_aligned - from_aligned; + + /* Read the unaligned part at the start. */ + if (from !=3D from_aligned) { + ret =3D cqspi_direct_read_dma(f_pdata, buf, from, + from_aligned - from); + if (ret) + return ret; + buf +=3D from_aligned - from; + } + + if (len_aligned) { + cqspi_phy_enable(f_pdata, true); + ret =3D cqspi_direct_read_dma(f_pdata, buf, from_aligned, + len_aligned); + cqspi_phy_enable(f_pdata, false); + if (ret) + return ret; + buf +=3D len_aligned; + } + + /* Now read the remaining part, if any. */ + if (to_aligned !=3D (from + len)) { + ret =3D cqspi_direct_read_dma(f_pdata, buf, to_aligned, + (from + len) - to_aligned); + if (ret) + return ret; + buf +=3D (from + len) - to_aligned; + } + + return 0; +} + static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata, const struct spi_mem_op *op) { @@ -1428,7 +1623,7 @@ static ssize_t cqspi_read(struct cqspi_flash_pdata *f= _pdata, return ret; =20 if (cqspi->use_direct_mode && ((from + len) <=3D cqspi->ahb_size)) - return cqspi_direct_read_execute(f_pdata, buf, from, len); + return cqspi_direct_read_execute(f_pdata, op); =20 if (cqspi->use_dma_read && ddata && ddata->indirect_read_dma && virt_addr_valid(buf) && ((dma_align & CQSPI_DMA_UNALIGN) =3D=3D 0)) --=20 2.34.1 From nobody Sun Oct 5 00:14:15 2025 Received: from fllvem-ot03.ext.ti.com (fllvem-ot03.ext.ti.com [198.47.19.245]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 544CE2D8DBD; Mon, 11 Aug 2025 19:33:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.245 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940822; cv=none; b=aMdtrFnlMgc/O+xw/3GKRgzB2X7nPxEIzoIMXUTCDFTthPwKGwexqZVkgPrVC67E38gLKNWLr5zr/5Kr+X/8XJbkwjF273W+WOJlOJhZep27kwmAKVQqb3YldYbMsUU4vvq3IB2fvmT64fqx3R9Oe2vBjzHTn3i87LrYz55Bw6o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754940822; c=relaxed/simple; bh=FeC0MWCqApQ7FM2kPzsZNiWDASSH962/7XVShOv6rDQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PYP8I241j2s4cjTN2Wu6DCL2KB7GysZI8bRM/uvP8mvknY1dwhYaV6+FYwL1Sqlo0FOSqQ4VVqAKvWakuIlEIO5KDQW01PA5+3GMmBHKzzoKWkwfyDcA7iRLdD8+96M24KuyNe6fP0SmzqA2G9Ip+loAff9paRRZ1m+E55pID4Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=lQ3+b6NS; arc=none smtp.client-ip=198.47.19.245 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="lQ3+b6NS" Received: from lelvem-sh01.itg.ti.com ([10.180.77.71]) by fllvem-ot03.ext.ti.com (8.15.2/8.15.2) with ESMTP id 57BJXXf81180243; Mon, 11 Aug 2025 14:33:33 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1754940813; bh=JNBUMqxnJPwUdETAbLE1uARqpWovKqp3PKZHw2LEmzU=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=lQ3+b6NSeYP1ttIrztc+ztRvjbjxSGVs779MY01FZgFCYaRkruQb7K0/OuwACNKLP Y5W/+EBne/UdMkl257KVEXd5X3v6v04YTVRygUWjDuYWbpEwqFGAN42sbK+akwupMc ZZxJ6BtGtzyd5ziYIW6Qk8ORGdsfd3ixmlALUUNo= Received: from DLEE112.ent.ti.com (dlee112.ent.ti.com [157.170.170.23]) by lelvem-sh01.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 57BJXXLf2910955 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Mon, 11 Aug 2025 14:33:33 -0500 Received: from DLEE108.ent.ti.com (157.170.170.38) 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.2507.55; Mon, 11 Aug 2025 14:33:32 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) 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.2507.55 via Frontend Transport; Mon, 11 Aug 2025 14:33:32 -0500 Received: from santhoshkumark.dhcp.ti.com (santhoshkumark.dhcp.ti.com [172.24.233.254]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 57BJWq1v3690681; Mon, 11 Aug 2025 14:33:28 -0500 From: Santhosh Kumar K To: , , , , , , , CC: , , , , , , Subject: [RFC PATCH 08/10] spi: cadence-quadspi: Enable PHY for data writes Date: Tue, 12 Aug 2025 01:02:17 +0530 Message-ID: <20250811193219.731851-9-s-k6@ti.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250811193219.731851-1-s-k6@ti.com> References: <20250811193219.731851-1-s-k6@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" PHY is tuned with optimal tuning point which allows controller to run at higher speeds. Hence, increase the data writes' throughput in OSPI/QSPI NAND flashes by enabling PHY for data writes to the NAND flash devices. The aim is to enable PHY only for the OSPI/QSPI NAND data writes, so, exclude other operations like register writes to NAND flashes, register and data writes to NOR flashes by introducing a check for the 'n_tx' (op->data.nbytes) value before enabling. Currently, OSPI/QSPI NOR's highest page size is 512 bytes, so, check whether 'n_tx' is greater than or equal to 1024 and 'f_pdata->use_phy' flag. Signed-off-by: Santhosh Kumar K --- drivers/spi/spi-cadence-quadspi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-qu= adspi.c index 2096027bca4c..6c1159435577 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1202,6 +1202,9 @@ static int cqspi_indirect_write_execute(struct cqspi_= flash_pdata *f_pdata, if (cqspi->apb_ahb_hazard) readl(reg_base + CQSPI_REG_INDIRECTWR); =20 + if (n_tx >=3D SZ_1K && f_pdata->use_phy) + cqspi_phy_enable(f_pdata, true); + while (remaining > 0) { size_t write_words, mod_bytes; =20 @@ -1242,6 +1245,9 @@ static int cqspi_indirect_write_execute(struct cqspi_= flash_pdata *f_pdata, goto failwr; } =20 + if (n_tx >=3D SZ_1K && f_pdata->use_phy) + cqspi_phy_enable(f_pdata, false); + /* Disable interrupt. */ writel(0, reg_base + CQSPI_REG_IRQMASK); =20 @@ -1253,6 +1259,9 @@ static int cqspi_indirect_write_execute(struct cqspi_= flash_pdata *f_pdata, return 0; =20 failwr: + if (n_tx >=3D SZ_1K && f_pdata->use_phy) + cqspi_phy_enable(f_pdata, false); + /* Disable interrupt. */ writel(0, reg_base + CQSPI_REG_IRQMASK); =20 --=20 2.34.1 From nobody Sun Oct 5 00:14:15 2025 Received: from lelvem-ot01.ext.ti.com (lelvem-ot01.ext.ti.com [198.47.23.234]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 54F392D877D; Mon, 11 Aug 2025 19:56:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754942221; cv=none; b=PR5x2HBm3xw+1hHr2fvszmbqeq82cIP617thq+wA5ePpNalFfmnClbwdca2M3n8B82OgJlfPb+eYwzbIKrTEwIKh0i3CepFXh4mgqeeJB0rBFUEtj2J9s/iKjGzY/H9rcvIY3dX7O4wv4w6njzlWU7bOFNsHga3NdBbIvFdWvGc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754942221; c=relaxed/simple; bh=O4EaQU0HFChYr2mDzig97tIGwA8DlYGaFZRjsARsY+w=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=bp3qOKf9cyabhVN/mFDbPZ+UDRNLR7UmenD2vtzqLaXbvGvE3r9Ju31PQGW/cqBdEObW0HqK0teW9Geysyr72lNnncDuY67B1OgGaKxHtqOFPO6q3T46M0efjfX7Ms7ngXjMNTlze85n3rwS4/m8xfaLNeLV/U/GHLBIfhdqQjE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=J4NwimF9; arc=none smtp.client-ip=198.47.23.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="J4NwimF9" Received: from fllvem-sh03.itg.ti.com ([10.64.41.86]) by lelvem-ot01.ext.ti.com (8.15.2/8.15.2) with ESMTP id 57BJXbcf1227833; Mon, 11 Aug 2025 14:33:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1754940817; bh=SZ2XoSFLc+CUe4UMFp0hfnljwVtUhJbdR1fBYVPzBio=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=J4NwimF9nUvQJTe865YlrrNhPksDVigzg4slzjK5x1tvByoF5PiROotXjGj/eW1nk vlNfzo/+FgrpmVdOaovEZXRB3ybC2nZKv4vaihS0Qxa4BtXvkLzTj358De4KrlZnAj X+CN4CFaDb4JuziPz1EqQR6RiH9MiufF9zRZNG5Y= Received: from DFLE104.ent.ti.com (dfle104.ent.ti.com [10.64.6.25]) by fllvem-sh03.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 57BJXbX23273494 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Mon, 11 Aug 2025 14:33:37 -0500 Received: from DFLE103.ent.ti.com (10.64.6.24) 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.2507.55; Mon, 11 Aug 2025 14:33:36 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) 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.2507.55 via Frontend Transport; Mon, 11 Aug 2025 14:33:37 -0500 Received: from santhoshkumark.dhcp.ti.com (santhoshkumark.dhcp.ti.com [172.24.233.254]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 57BJWq1w3690681; Mon, 11 Aug 2025 14:33:33 -0500 From: Santhosh Kumar K To: , , , , , , , CC: , , , , , , Subject: [RFC PATCH 09/10] spi: cadence-quadspi: Implement PHY for higher frequencies in SDR mode Date: Tue, 12 Aug 2025 01:02:18 +0530 Message-ID: <20250811193219.731851-10-s-k6@ti.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250811193219.731851-1-s-k6@ti.com> References: <20250811193219.731851-1-s-k6@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" With SDR mode, the controller can only process at 1/4th of the reference clock without PHY. So, add a SDR based tuning algorithm to enable higher speed operations. A known pattern (stress pattern) is flashed at a location in the flash device, which will be later used to read back and compare. Iterate through read_delay from 0 to 4, find first tuning point by setting tx=3D127. Find difference between rxlow and rxhigh and store it in window1. Find second tuning point with read_delay incremented by 1 and similarly calculate window2. Compare window1 and window2 to finalise the optimal tuning point. Write the final tuning point into PHY Configuration Register. With this OSPI can operate at up-to 200MHz SDR mode with internal loopback clocking scheme for sampling data inside the soft PHY Tuning for DDR mode with DQS will be added a later point. Signed-off-by: Santhosh Kumar K --- drivers/spi/spi-cadence-quadspi.c | 447 ++++++++++++++++++++++++++++++ 1 file changed, 447 insertions(+) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-qu= adspi.c index 6c1159435577..1626cb9a9700 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -78,6 +78,7 @@ struct cqspi_flash_pdata { u8 cs; bool use_phy; struct phy_setting phy_setting; + struct spi_mem_op phy_read_op; }; =20 struct cqspi_st { @@ -135,6 +136,7 @@ struct cqspi_driver_platdata { #define CQSPI_READ_TIMEOUT_MS 10 #define CQSPI_BUSYWAIT_TIMEOUT_US 500 #define CQSPI_PHY_FREQUENCY 166000000 +#define CQSPI_DLL_TIMEOUT_US 300 =20 /* Runtime_pm autosuspend delay */ #define CQSPI_AUTOSUSPEND_TIMEOUT 2000 @@ -194,6 +196,7 @@ struct cqspi_driver_platdata { #define CQSPI_REG_READCAPTURE_BYPASS BIT(0) #define CQSPI_REG_READCAPTURE_DELAY_LSB 1 #define CQSPI_REG_READCAPTURE_DELAY_MASK 0xF +#define CQSPI_REG_READCAPTURE_EDGE BIT(5) =20 #define CQSPI_REG_SIZE 0x14 #define CQSPI_REG_SIZE_ADDRESS_LSB 0 @@ -272,6 +275,26 @@ struct cqspi_driver_platdata { #define CQSPI_REG_POLLING_STATUS 0xB0 #define CQSPI_REG_POLLING_STATUS_DUMMY_LSB 16 =20 +#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_DLL_RESET BIT(30) +#define CQSPI_REG_PHY_CONFIG_RESYNC BIT(31) + +#define CQSPI_REG_PHY_DLL_MASTER 0xB8 +#define CQSPI_REG_PHY_DLL_MASTER_INIT_DELAY_LSB 0 +#define CQSPI_REG_PHY_DLL_MASTER_INIT_DELAY_VAL 16 +#define CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_LEN 0x7 +#define CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_LSB 20 +#define CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_3 0x2 +#define CQSPI_REG_PHY_DLL_MASTER_BYPASS BIT(23) +#define CQSPI_REG_PHY_DLL_MASTER_CYCLE BIT(24) + +#define CQSPI_REG_DLL_OBS_LOW 0xBC +#define CQSPI_REG_DLL_OBS_LOW_DLL_LOCK BIT(0) +#define CQSPI_REG_DLL_OBS_LOW_LOOPBACK_LOCK BIT(15) #define CQSPI_REG_OP_EXT_LOWER 0xE0 #define CQSPI_REG_OP_EXT_READ_LSB 24 #define CQSPI_REG_OP_EXT_WRITE_LSB 16 @@ -317,6 +340,46 @@ struct cqspi_driver_platdata { =20 #define CQSPI_REG_VERSAL_DMA_VAL 0x602 =20 +#define CQSPI_PHY_INIT_RD 1 +#define CQSPI_PHY_MAX_RD 4 +#define CQSPI_PHY_MAX_DELAY 127 +#define CQSPI_PHY_DDR_SEARCH_STEP 4 +#define CQSPI_PHY_MAX_RX 63 +#define CQSPI_PHY_MAX_TX 63 +#define CQSPI_PHY_TX_LOOKUP_LOW_START 28 +#define CQSPI_PHY_TX_LOOKUP_LOW_END 48 +#define CQSPI_PHY_TX_LOOKUP_HIGH_START 60 +#define CQSPI_PHY_TX_LOOKUP_HIGH_END 96 +#define CQSPI_PHY_RX_LOW_SEARCH_START 0 +#define CQSPI_PHY_RX_LOW_SEARCH_END 40 +#define CQSPI_PHY_RX_HIGH_SEARCH_START 24 +#define CQSPI_PHY_RX_HIGH_SEARCH_END 127 +#define CQSPI_PHY_TX_LOW_SEARCH_START 0 +#define CQSPI_PHY_TX_LOW_SEARCH_END 64 +#define CQSPI_PHY_TX_HIGH_SEARCH_START 78 +#define CQSPI_PHY_TX_HIGH_SEARCH_END 127 +#define CQSPI_PHY_SEARCH_OFFSET 8 + +#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 u8 phy_tuning_pattern[] =3D { + 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 int cqspi_wait_for_bit(const struct cqspi_driver_platdata *ddata, void __iomem *reg, const u32 mask, bool clr, bool busywait) @@ -455,6 +518,279 @@ static int cqspi_wait_idle(struct cqspi_st *cqspi) } } =20 +static void cqspi_set_tx_dll(void __iomem *reg_base, u8 dll) +{ + unsigned int reg; + + reg =3D readl(reg_base + CQSPI_REG_PHY_CONFIG); + reg &=3D ~(CQSPI_REG_PHY_CONFIG_TX_DEL_MASK + << CQSPI_REG_PHY_CONFIG_TX_DEL_LSB); + reg |=3D (dll & CQSPI_REG_PHY_CONFIG_TX_DEL_MASK) + << CQSPI_REG_PHY_CONFIG_TX_DEL_LSB; + reg |=3D 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 =3D readl(reg_base + CQSPI_REG_PHY_CONFIG); + reg &=3D ~(CQSPI_REG_PHY_CONFIG_RX_DEL_MASK + << CQSPI_REG_PHY_CONFIG_RX_DEL_LSB); + reg |=3D (dll & CQSPI_REG_PHY_CONFIG_RX_DEL_MASK) + << CQSPI_REG_PHY_CONFIG_RX_DEL_LSB; + reg |=3D CQSPI_REG_PHY_CONFIG_RESYNC; + writel(reg, reg_base + CQSPI_REG_PHY_CONFIG); +} + +static int cqspi_resync_dll(struct cqspi_st *cqspi) +{ + void __iomem *reg_base =3D cqspi->iobase; + unsigned int reg; + int ret; + + ret =3D cqspi_wait_idle(cqspi); + + if (!ret) { + reg =3D readl(reg_base + CQSPI_REG_CONFIG); + reg &=3D ~(CQSPI_REG_CONFIG_ENABLE_MASK); + writel(reg, reg_base + CQSPI_REG_CONFIG); + + reg =3D readl(reg_base + CQSPI_REG_PHY_CONFIG); + reg &=3D ~(CQSPI_REG_PHY_CONFIG_DLL_RESET | + CQSPI_REG_PHY_CONFIG_RESYNC); + writel(reg, reg_base + CQSPI_REG_PHY_CONFIG); + + reg =3D readl(reg_base + CQSPI_REG_PHY_DLL_MASTER); + reg |=3D (CQSPI_REG_PHY_DLL_MASTER_INIT_DELAY_VAL + << CQSPI_REG_PHY_DLL_MASTER_INIT_DELAY_LSB); + writel(reg, reg_base + CQSPI_REG_PHY_DLL_MASTER); + + reg =3D readl(reg_base + CQSPI_REG_PHY_CONFIG); + reg |=3D CQSPI_REG_PHY_CONFIG_DLL_RESET; + writel(reg, reg_base + CQSPI_REG_PHY_CONFIG); + + readl_poll_timeout(reg_base + CQSPI_REG_DLL_OBS_LOW, reg, + !(reg &=3D CQSPI_REG_DLL_OBS_LOW_DLL_LOCK), 0, + CQSPI_DLL_TIMEOUT_US); + + readl_poll_timeout(reg_base + CQSPI_REG_DLL_OBS_LOW, reg, + !(reg &=3D CQSPI_REG_DLL_OBS_LOW_LOOPBACK_LOCK), + 0, CQSPI_DLL_TIMEOUT_US); + + reg =3D readl(reg_base + CQSPI_REG_PHY_CONFIG); + reg |=3D CQSPI_REG_PHY_CONFIG_RESYNC; + writel(reg, reg_base + CQSPI_REG_PHY_CONFIG); + + reg =3D readl(reg_base + CQSPI_REG_CONFIG); + reg |=3D CQSPI_REG_CONFIG_ENABLE_MASK; + writel(reg, reg_base + CQSPI_REG_CONFIG); + } + + return ret; +} + +static int cqspi_phy_apply_setting(struct cqspi_flash_pdata *f_pdata, + struct phy_setting *phy) +{ + struct cqspi_st *cqspi =3D f_pdata->cqspi; + unsigned int reg; + + reg =3D readl(cqspi->iobase + CQSPI_REG_READCAPTURE); + reg |=3D CQSPI_REG_READCAPTURE_EDGE; + writel(reg, cqspi->iobase + CQSPI_REG_READCAPTURE); + + cqspi_set_rx_dll(cqspi->iobase, phy->rx); + cqspi_set_tx_dll(cqspi->iobase, phy->tx); + f_pdata->phy_setting.read_delay =3D phy->read_delay; + + return cqspi_resync_dll(cqspi); +} + +static int cqspi_phy_check_pattern(struct cqspi_flash_pdata *f_pdata, + struct spi_mem *mem) +{ + struct spi_mem_op op =3D f_pdata->phy_read_op; + u8 *read_data; + int ret; + + read_data =3D kmalloc(sizeof(phy_tuning_pattern), GFP_KERNEL); + if (!read_data) + return -ENOMEM; + + op.data.buf.in =3D read_data; + op.data.nbytes =3D sizeof(phy_tuning_pattern); + + ret =3D spi_mem_exec_op(mem, &op); + if (ret) + goto out; + + if (memcmp(read_data, phy_tuning_pattern, + ARRAY_SIZE(phy_tuning_pattern))) { + ret =3D -EAGAIN; + goto out; + } + + ret =3D 0; + +out: + kfree(read_data); + return ret; +} + +static int cqspi_find_rx_low_sdr(struct cqspi_flash_pdata *f_pdata, + struct spi_mem *mem, struct phy_setting *phy) +{ + struct device *dev =3D &f_pdata->cqspi->pdev->dev; + int ret; + + phy->rx =3D 0; + do { + ret =3D cqspi_phy_apply_setting(f_pdata, phy); + if (!ret) { + ret =3D cqspi_phy_check_pattern(f_pdata, mem); + if (!ret) + return 0; + } + phy->rx++; + } while (phy->rx < CQSPI_PHY_MAX_DELAY - 1); + + dev_dbg(dev, "Unable to find RX low\n"); + return -ENOENT; +} + +static int cqspi_find_rx_high_sdr(struct cqspi_flash_pdata *f_pdata, + struct spi_mem *mem, struct phy_setting *phy, + u8 lowerbound) +{ + struct device *dev =3D &f_pdata->cqspi->pdev->dev; + int ret; + + phy->rx =3D CQSPI_PHY_MAX_DELAY; + do { + ret =3D cqspi_phy_apply_setting(f_pdata, phy); + if (!ret) { + ret =3D cqspi_phy_check_pattern(f_pdata, mem); + if (!ret) + return 0; + } + phy->rx--; + } while (phy->rx > lowerbound); + + dev_dbg(dev, "Unable to find RX high\n"); + return -ENOENT; +} + +static void cqspi_phy_reset_setting(struct phy_setting *phy) +{ + phy->rx =3D 0; + phy->tx =3D 127; + phy->read_delay =3D 0; +} + +static int cqspi_phy_tuning_sdr(struct cqspi_flash_pdata *f_pdata, + struct spi_mem *mem) +{ + struct cqspi_st *cqspi =3D f_pdata->cqspi; + struct device *dev =3D &cqspi->pdev->dev; + struct phy_setting rxlow, rxhigh, first, second, final; + char window1 =3D 0; + char window2 =3D 0; + int ret; + + f_pdata->use_phy =3D true; + cqspi_phy_reset_setting(&rxlow); + cqspi_phy_reset_setting(&rxhigh); + cqspi_phy_reset_setting(&first); + + do { + ret =3D cqspi_find_rx_low_sdr(f_pdata, mem, &rxlow); + + if (ret) + rxlow.read_delay++; + } while (ret && rxlow.read_delay <=3D CQSPI_PHY_MAX_RD); + + rxhigh.read_delay =3D rxlow.read_delay; + ret =3D cqspi_find_rx_high_sdr(f_pdata, mem, &rxhigh, rxlow.rx); + if (ret) + goto out; + + first.read_delay =3D rxlow.read_delay; + window1 =3D rxhigh.rx - rxlow.rx; + first.rx =3D rxlow.rx + (window1 / 2); + + dev_dbg(dev, "First tuning point: RX: %d TX: %d RD: %d\n", first.rx, + first.tx, first.read_delay); + ret =3D cqspi_phy_apply_setting(f_pdata, &first); + if (!ret) + ret =3D cqspi_phy_check_pattern(f_pdata, mem); + + if (ret || first.read_delay > CQSPI_PHY_MAX_RD) + goto out; + + cqspi_phy_reset_setting(&rxlow); + cqspi_phy_reset_setting(&rxhigh); + cqspi_phy_reset_setting(&second); + + rxlow.read_delay =3D first.read_delay + 1; + if (rxlow.read_delay > CQSPI_PHY_MAX_RD) + goto compare; + + ret =3D cqspi_find_rx_low_sdr(f_pdata, mem, &rxlow); + if (ret) + goto compare; + + rxhigh.read_delay =3D rxlow.read_delay; + ret =3D cqspi_find_rx_high_sdr(f_pdata, mem, &rxhigh, rxlow.rx); + if (ret) + goto compare; + + window2 =3D rxhigh.rx - rxlow.rx; + second.rx =3D rxlow.rx + (window2 / 2); + second.read_delay =3D rxlow.read_delay; + + dev_dbg(dev, "Second tuning point: RX: %d TX: %d RD: %d\n", second.rx, + second.tx, second.read_delay); + ret =3D cqspi_phy_apply_setting(f_pdata, &second); + if (!ret) + ret =3D cqspi_phy_check_pattern(f_pdata, mem); + + if (ret || second.read_delay > CQSPI_PHY_MAX_RD) + window2 =3D 0; + +compare: + cqspi_phy_reset_setting(&final); + if (window2 > window1) { + final.rx =3D second.rx; + final.read_delay =3D second.read_delay; + } else { + final.rx =3D first.rx; + final.read_delay =3D first.read_delay; + } + + dev_dbg(dev, "Final tuning point: RX: %d TX: %d RD: %d\n", final.rx, + final.tx, final.read_delay); + ret =3D cqspi_phy_apply_setting(f_pdata, &final); + if (!ret) + ret =3D cqspi_phy_check_pattern(f_pdata, mem); + + if (ret) { + ret =3D -EINVAL; + goto out; + } + + f_pdata->phy_setting.read_delay =3D final.read_delay; + f_pdata->phy_setting.rx =3D final.rx; + f_pdata->phy_setting.tx =3D final.tx; + +out: + if (ret) + f_pdata->use_phy =3D false; + + return ret; +} + static void cqspi_readdata_capture(struct cqspi_st *cqspi, const bool bypass, const unsigned int delay) @@ -1366,6 +1702,83 @@ static void cqspi_config_baudrate_div(struct cqspi_s= t *cqspi) writel(reg, reg_base + CQSPI_REG_CONFIG); } =20 +static void cqspi_phy_set_dll_master(struct cqspi_st *cqspi) +{ + void __iomem *reg_base =3D cqspi->iobase; + unsigned int reg; + + reg =3D readl(reg_base + CQSPI_REG_PHY_DLL_MASTER); + reg &=3D ~((CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_LEN + << CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_LSB) | + CQSPI_REG_PHY_DLL_MASTER_BYPASS | + CQSPI_REG_PHY_DLL_MASTER_CYCLE); + reg |=3D ((CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_3 + << CQSPI_REG_PHY_DLL_MASTER_DLY_ELMTS_LSB) | + CQSPI_REG_PHY_DLL_MASTER_CYCLE); + + writel(reg, reg_base + CQSPI_REG_PHY_DLL_MASTER); +} + +static void cqspi_phy_pre_config(struct cqspi_st *cqspi, const bool bypass, + struct cqspi_flash_pdata *f_pdata) +{ + void __iomem *reg_base =3D cqspi->iobase; + unsigned int reg; + u8 dummy; + + cqspi_readdata_capture(cqspi, bypass, + f_pdata->phy_setting.read_delay); + + reg =3D readl(reg_base + CQSPI_REG_CONFIG); + reg &=3D ~(CQSPI_REG_CONFIG_PHY_EN | CQSPI_REG_CONFIG_PHY_PIPELINE); + reg |=3D CQSPI_REG_CONFIG_PHY_EN; + writel(reg, reg_base + CQSPI_REG_CONFIG); + + reg =3D readl(reg_base + CQSPI_REG_RD_INSTR); + dummy =3D FIELD_GET(CQSPI_REG_RD_INSTR_DUMMY_MASK + << CQSPI_REG_RD_INSTR_DUMMY_LSB, + reg); + dummy--; + reg &=3D ~(CQSPI_REG_RD_INSTR_DUMMY_MASK << CQSPI_REG_RD_INSTR_DUMMY_LSB); + reg |=3D FIELD_PREP(CQSPI_REG_RD_INSTR_DUMMY_MASK + << CQSPI_REG_RD_INSTR_DUMMY_LSB, + dummy); + writel(reg, reg_base + CQSPI_REG_RD_INSTR); + + cqspi_phy_set_dll_master(cqspi); +} + +static void cqspi_phy_post_config(struct cqspi_st *cqspi, + const unsigned int delay) +{ + void __iomem *reg_base =3D cqspi->iobase; + unsigned int reg; + u8 dummy; + + reg =3D readl(reg_base + CQSPI_REG_READCAPTURE); + reg &=3D ~(CQSPI_REG_READCAPTURE_DELAY_MASK + << CQSPI_REG_READCAPTURE_DELAY_LSB); + + reg |=3D (delay & CQSPI_REG_READCAPTURE_DELAY_MASK) + << CQSPI_REG_READCAPTURE_DELAY_LSB; + writel(reg, reg_base + CQSPI_REG_READCAPTURE); + + reg =3D readl(reg_base + CQSPI_REG_CONFIG); + reg &=3D ~(CQSPI_REG_CONFIG_PHY_EN | CQSPI_REG_CONFIG_PHY_PIPELINE); + writel(reg, reg_base + CQSPI_REG_CONFIG); + + reg =3D readl(reg_base + CQSPI_REG_RD_INSTR); + dummy =3D FIELD_GET(CQSPI_REG_RD_INSTR_DUMMY_MASK + << CQSPI_REG_RD_INSTR_DUMMY_LSB, + reg); + dummy++; + reg &=3D ~(CQSPI_REG_RD_INSTR_DUMMY_MASK << CQSPI_REG_RD_INSTR_DUMMY_LSB); + reg |=3D FIELD_PREP(CQSPI_REG_RD_INSTR_DUMMY_MASK + << CQSPI_REG_RD_INSTR_DUMMY_LSB, + dummy); + writel(reg, reg_base + CQSPI_REG_RD_INSTR); +} + static void cqspi_configure(struct cqspi_flash_pdata *f_pdata, unsigned long sclk) { @@ -1724,6 +2137,39 @@ static bool cqspi_supports_mem_op(struct spi_mem *me= m, return spi_mem_default_supports_op(mem, op); } =20 +static int cqspi_mem_execute_tuning(struct spi_mem *mem, + const struct spi_mem_op *op) +{ + struct cqspi_st *cqspi =3D + spi_controller_get_devdata(mem->spi->controller); + struct cqspi_flash_pdata *f_pdata; + struct device *dev =3D &cqspi->pdev->dev; + int ret; + + f_pdata =3D &cqspi->f_pdata[spi_get_chipselect(mem->spi, 0)]; + f_pdata->phy_read_op =3D *op; + + if (!cqspi_phy_op_eligible_sdr(f_pdata, op)) { + dev_warn(dev, + "Given read_op not eligible. Skipping PHY Tuning.\n"); + return -EOPNOTSUPP; + } + + ret =3D cqspi_phy_check_pattern(f_pdata, mem); + if (ret) { + dev_warn(dev, "Pattern not found. Skipping PHY Tuning.\n"); + return -EINVAL; + } + + cqspi_phy_pre_config(cqspi, true, f_pdata); + ret =3D cqspi_phy_tuning_sdr(f_pdata, mem); + if (ret) + dev_info(&cqspi->pdev->dev, "PHY Tuning failed: %d\n", ret); + + cqspi_phy_post_config(cqspi, f_pdata->read_delay); + return ret; +} + static int cqspi_of_get_flash_pdata(struct platform_device *pdev, struct cqspi_flash_pdata *f_pdata, struct device_node *np) @@ -1898,6 +2344,7 @@ static const struct spi_controller_mem_ops cqspi_mem_= ops =3D { .exec_op =3D cqspi_exec_mem_op, .get_name =3D cqspi_get_name, .supports_op =3D cqspi_supports_mem_op, + .execute_tuning =3D cqspi_mem_execute_tuning, }; =20 static const struct spi_controller_mem_caps cqspi_mem_caps =3D { --=20 2.34.1 From nobody Sun Oct 5 00:14:15 2025 Received: from lelvem-ot01.ext.ti.com (lelvem-ot01.ext.ti.com [198.47.23.234]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CDAF029BDA7; Mon, 11 Aug 2025 19:56:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754942219; cv=none; b=UxoYTL2BT/ALIJR8P36WBPYVSpNzB7DZgSO3vixveAHSTwLwvqdwvFxxlHnvSFi7PuOWDVI9AVt+CVi5i9/9rM8JEZfGVCEbMFt/1peEn7X7W0uv+P/OxlPLw+WsyxdHVmJHc22XtabXCT/TtDAOQaIAV1e4j3m0MYFFbIq+QiI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754942219; c=relaxed/simple; bh=UH866iIoV0BmgwOwOKmrPiamvqbnZJOQBXR1xx6vmt4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=JjPcLXIVa59QAL29RAB/4vORz7Yy/TkFUoM3/IBUyoWn/BazagPurzXk4cfSCATrC+xsIns8KmNoKawzR8Eowb08JR09YlU7r/VDT3WEKiKD6DFZ99wjmCvaSbTiNvNkKN2hGvTZ9wERGD/I7XVO9MBDY3xY/4jPFyaBiAfMs2U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=PQUSTZCp; arc=none smtp.client-ip=198.47.23.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="PQUSTZCp" Received: from lelvem-sh01.itg.ti.com ([10.180.77.71]) by lelvem-ot01.ext.ti.com (8.15.2/8.15.2) with ESMTP id 57BJXg1s1227857; Mon, 11 Aug 2025 14:33:42 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1754940822; bh=Gqtsu4C7TidETAVnE77OpIDvlXHGXv1Mz6JMhY6rGHo=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=PQUSTZCp5bneAU1Ct823nP1oieJ9HPFezrBrDy5PJQYcEHKWnQHhym+a3JXzM7k5B Lq/ZSTm2Ai6SxdgUtn38LXIvSnvZFMTFJzzTZPB6PKtvx3fCdizxk4Mq9nwIVgmBRw O3zN49zwyruOIovEyOZV4kbYyDb3mBhpKrFsW9rY= Received: from DLEE113.ent.ti.com (dlee113.ent.ti.com [157.170.170.24]) by lelvem-sh01.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 57BJXg2l2910990 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Mon, 11 Aug 2025 14:33:42 -0500 Received: from DLEE107.ent.ti.com (157.170.170.37) 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.2507.55; Mon, 11 Aug 2025 14:33:41 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) 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.2507.55 via Frontend Transport; Mon, 11 Aug 2025 14:33:41 -0500 Received: from santhoshkumark.dhcp.ti.com (santhoshkumark.dhcp.ti.com [172.24.233.254]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 57BJWq1x3690681; Mon, 11 Aug 2025 14:33:37 -0500 From: Santhosh Kumar K To: , , , , , , , CC: , , , , , , Subject: [RFC PATCH 10/10] spi: cadence-quadspi: Define cqspi_get_tuning_params() Date: Tue, 12 Aug 2025 01:02:19 +0530 Message-ID: <20250811193219.731851-11-s-k6@ti.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250811193219.731851-1-s-k6@ti.com> References: <20250811193219.731851-1-s-k6@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" Define cqspi_get_tuning_params() to extract information about the PHY tuning pattern and it's size from controller. Signed-off-by: Santhosh Kumar K --- drivers/spi/spi-cadence-quadspi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-qu= adspi.c index 1626cb9a9700..c9c4341d3275 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -2170,6 +2170,14 @@ static int cqspi_mem_execute_tuning(struct spi_mem *= mem, return ret; } =20 +static int cqspi_get_tuning_params(struct spi_mem *mem, + struct spi_mem_tuning_params *tuning_params) +{ + tuning_params->pattern_ptr =3D phy_tuning_pattern; + tuning_params->pattern_size =3D sizeof(phy_tuning_pattern); + return 0; +} + static int cqspi_of_get_flash_pdata(struct platform_device *pdev, struct cqspi_flash_pdata *f_pdata, struct device_node *np) @@ -2345,6 +2353,7 @@ static const struct spi_controller_mem_ops cqspi_mem_= ops =3D { .get_name =3D cqspi_get_name, .supports_op =3D cqspi_supports_mem_op, .execute_tuning =3D cqspi_mem_execute_tuning, + .get_tuning_params =3D cqspi_get_tuning_params, }; =20 static const struct spi_controller_mem_caps cqspi_mem_caps =3D { --=20 2.34.1