From patchwork Thu Oct 26 15:23:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eberhard Stoll X-Patchwork-Id: 738635 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C5629C25B67 for ; Thu, 26 Oct 2023 15:24:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345441AbjJZPYP (ORCPT ); Thu, 26 Oct 2023 11:24:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49742 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345446AbjJZPYN (ORCPT ); Thu, 26 Oct 2023 11:24:13 -0400 Received: from mout.gmx.net (mout.gmx.net [212.227.15.15]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 12879D7; Thu, 26 Oct 2023 08:24:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=s31663417; t=1698333824; x=1698938624; i=estl@gmx.net; bh=hrkvAOte+Th3rpsByV7vWGNWnYjhb3jN9HoUWbKJ61c=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To: References; b=OLZANmlaBqktCjzeDAwa6XgaP5O8HNALrlBsXopEztBlFwCFqJ3Arz89BQwzEYpq 86vbRqblqhx9GGWy1eqy1xmH++Dt0Ymrukrbvembq4Bj8e67gi8AIhvkFyACmIwaL Mz5ACJ34KSvPZlZwm7o3SGl7hiW7zgG/xINCaFYj86oeDqNz3nkP1CLSMa6wQolfC Mf57KvFYBq9NM0vTx9kfpuze9PFGg1utXH+dKUEF4CqcUjIAkmFzIiyPU/jjdM9zo ai1Bj8xVGTo83r0ce2tHG1Ac1XFEvaSU+2j4uvPRyFkiglRhcHW+ylXdzoNaeouuE rD5LFo9Puv+6QlX1/A== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from localhost.localdomain ([77.246.119.226]) by mail.gmx.net (mrgmx005 [212.227.17.190]) with ESMTPSA (Nemesis) id 1M9nxn-1qt1Xh3eR3-005qmX; Thu, 26 Oct 2023 17:23:44 +0200 From: Eberhard Stoll To: linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, Mark Brown Cc: Eberhard Stoll , Frieder Schrempf , Amit Kumar Mahapatra , Andy Shevchenko , Christophe JAILLET , Geert Uytterhoeven , Krishna Yarlagadda , =?utf-8?q?Leonard_G=C3=B6hrs?= , Miquel Raynal , Yang Yingliang Subject: [PATCH 1/4] spi: Add parameter for clock to rx delay Date: Thu, 26 Oct 2023 17:23:02 +0200 Message-Id: <20231026152316.2729575-2-estl@gmx.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231026152316.2729575-1-estl@gmx.net> References: <20231026152316.2729575-1-estl@gmx.net> MIME-Version: 1.0 X-Provags-ID: V03:K1:ZjH2xhKzqHPS+vXFJ+4XQ4H7/hsilX8+hpIYcpOOyrNBd2VVTAp MIAdABQsqj9eI3Z2ADyQE1HeFdIIjm+NjEkIuKv4NSLvB+8floGvBVoi4G/Ss3BdIS1s+i8 J3e7NzN2fO2fSvhHzyI1MfoIg+pslsOhhHWsIT0VVgMP0zq3ElpBd464D98fu8ZEDFeE888 DLMJcj8cTGvdIp/LZ3GoA== UI-OutboundReport: notjunk:1;M01:P0:cVFpXz6rkM8=;b9OZjyEbm3a/50Q/VVJoLXW3AJK UOVel7zUZX+gvp9oIwgSYIW80wXXRZO/0HxPKNxPdVtf3CPMi3v72dD+aFjMWFdMdGlwZg/ga 2RHsqasDn0pc/iVTUbn+lKmWsNFy6Sfn4NhHMo8MvRFtejIyn29M3jmpRBQnonR9cA+usdG6e Ty0pTYliCv+skZ4lXsRiTTdBgIXIBCJdoqaRSs4ejDqPFC8H/H/WNk+LakJRZZHwJVIJ0cK5T w2kvj5Np0He7VWmdUU2Q43NW2W1U+oeCv2QAoH1yoGPVlApEv5r1Z/UJodLRFspeb1hg4mjPt M5hqP8BZytDpqekUBzh5m+/vyxLwoc7g4u9xIfEZJ6zUW739xVAvCbSigay+41F4e6gy07XZi ZmJujFIcevq8qYC+mQ86WhXrKIS2XilI7yN+sEo7Pv22e8XYh3+tdTX96bS5+F4k+BJkq+oxJ wRaIArvaV5QiFliCheogerfYKTNcswTmoTW0yDRdFCzt6V/F+5av23pVD5IuQa70ip6qmiHg/ YnbA7rwoheaKZtv7+55wt2iog6ry0+NL4iKnEBuLTUlChIaTXnzXJvxkPqOJhi7LXL7tK3cmB dF7v3aB6vJqQXIsxj09WlXZktsuSK5lSIv3+2yweD+l3MlAvLgNi7J0A5v+I+nFApmtE4s/6L qfuhffL0PZHfSOYo6EghNLaLaU28Pauwx+Bg0bbUOe44em5IOizO2xGYdU3npN7QntyQRxHzJ eXyEGCHVrDnShdR/KHgJHNIYYMhcdXbaG9lC1TTlIWE280nZeErm8/miyNbJOUwg6XElzPsGc 9/mL17gV8JJPmm+2gvkmntMTXgog0tc5PW+yZ+1BRydb+bmyo8vYDn82nBSFooeol3Mlne9fG qQLgeOrkKKPEaNBDc6zmQUWZbng7CYBgOypiOeo7L2IcRMWxfXIbG8RUWkZHw+1Fv17iF5Oiu A2yoThlxsILXrUMdO7ESHjp5xXM= Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org From: Eberhard Stoll For spi devices the master clock output defines the sampling point for receive data input stream (rising or falling edge). The receive data stream from the device is delayed in relation to the master clock output. For some devices this delay is larger than one half clock period, which is normally the sampling point for receive data. In this case receive data is sampled too early and the device fails to operate. In consequence the spi clock has to be reduced to match the delay characteristics and this reduces performance and is therefore not recommended. Some spi controllers implement a 'clock to receive data delay' compensation which shifts the receive sampling point. So we need a property to set this value for each spi device. Add a parameter 'rx_sample_delay_ns' to enable setting the clock to rx data delay for each spi device separately. The 'clock to receive data delay' value is often referenced as tCLQV in spi device data sheets. Signed-off-by: Eberhard Stoll Signed-off-by: Frieder Schrempf --- include/linux/spi/spi.h | 3 +++ 1 file changed, 3 insertions(+) -- 2.25.1 diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 7f8b478fdeb3..14622d47f44f 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -166,6 +166,7 @@ extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg, * @cs_inactive: delay to be introduced by the controller after CS is * deasserted. If @cs_change_delay is used from @spi_transfer, then the * two delays will be added up. + * @rx_sample_delay_ns: spi clk to spi rx data delay * @pcpu_statistics: statistics for the spi_device * * A @spi_device is used to interchange data between an SPI slave @@ -219,6 +220,8 @@ struct spi_device { struct spi_delay cs_setup; struct spi_delay cs_hold; struct spi_delay cs_inactive; + /* Transfer characteristics */ + u32 rx_sample_delay_ns; /* Clock to RX data delay */ /* The statistics */ struct spi_statistics __percpu *pcpu_statistics; From patchwork Thu Oct 26 15:23:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eberhard Stoll X-Patchwork-Id: 738634 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C564AC25B6B for ; Thu, 26 Oct 2023 15:24:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235130AbjJZPYc (ORCPT ); Thu, 26 Oct 2023 11:24:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235111AbjJZPY1 (ORCPT ); Thu, 26 Oct 2023 11:24:27 -0400 Received: from mout.gmx.net (mout.gmx.net [212.227.15.15]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 02731D42; Thu, 26 Oct 2023 08:24:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=s31663417; t=1698333839; x=1698938639; i=estl@gmx.net; bh=2ljegJ3y7s6VlC1UqoCKCA1HzgQE8KWII58XSk+iJp0=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To: References; b=txKTt2iXQCRDirSPt3HVRr8fypUYgpvSTOm5O/PTqKrchS1O8r1S0C5neKzLgTUn DDzRgScN26oYF9ljR/RtxbK3BrddDCipHDcig1r/DMBNZUGltXG3SUc+m/oDL3/cJ oDI7D57Ohe+E7G58htTl/yfaDwXW3i8iYG7CcrGeUYakLrBuNh/Q3IFhwBit52nrx cedpnWzlOx4JaFmw86Yssh/d36I5c5ZL/bAUpPnvAcdzQWjetJik2x16VfRWSUNUX bd/ObkR4QiVpjilfjygOPOt1PsHiAnCxa6RrnZNkbxelXAZ+UNF8vu4Pn8aWH96Gs HdmZR/0H3vP9v1LxCg== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from localhost.localdomain ([77.246.119.226]) by mail.gmx.net (mrgmx005 [212.227.17.190]) with ESMTPSA (Nemesis) id 1MCbEf-1qmzwC3Dvv-009kGF; Thu, 26 Oct 2023 17:23:59 +0200 From: Eberhard Stoll To: Han Xu , linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, Mark Brown Cc: Eberhard Stoll , Frieder Schrempf , Amit Kumar Mahapatra , Amit Kumar Mahapatra via Alsa-devel , Michal Simek , Rob Herring , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Yang Yingliang Subject: [PATCH 4/4] spi: spi-fsl-qspi: Add support for rx data sample point adjustment Date: Thu, 26 Oct 2023 17:23:05 +0200 Message-Id: <20231026152316.2729575-5-estl@gmx.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231026152316.2729575-1-estl@gmx.net> References: <20231026152316.2729575-1-estl@gmx.net> MIME-Version: 1.0 X-Provags-ID: V03:K1:owMvC+i5vRKRLGouxvuCJLHydYsjuznM+geq7F0GPloF00XKufi SiaKWrCzbYaVf/fF/tVMmUn7NJJDGchyLnlQM0BFAbm/s6D+3gtD+BlutR/1blQEOPIAD26 k0DiHURvO1eKfZZDR5h+PpNw3FmY6yupkbxpRtm//7DhHjffKW+HQOVfbVxkH1sUlrTJRkq ZNDFE/GeoDw6uVYwzvcew== UI-OutboundReport: notjunk:1;M01:P0:tr92El/r2ik=;spGlmyEPmic3IKUFaUVMZr0zzpZ 3RqBzGU5l/nBWJuauZ0NnlwhiGbse3MerR0ICtXfhZJFbxdcUA8Ek8tnK3aLHjb3ivphAYD17 1IM1tERfaV1nm+WHG8ZP8wntcLWukVgGe/f2psa4Q9xWsd59Ax+DI9D0JQCPA0/9g57tvq5df uPMuNsyQE5wGP1dzbxycJTCg7e4xaXglNTBxwXGpiP7UDtMTkYXnmZTPBBmAPzPa4HxeJMvyK n0nD5JeW4Lxcf/YRBN96TFw84kq9ZkkRZrP6NNbli8jwoEIPptkFA/xiHOgUQy5aW693o3Lci WE1ZJAXj1of6rcAH4unlrZ+C3BJJPk32rSqjx9uDHY5xoPJ3ycLmxCDZsCN/1oty+9QayqPm5 czciM1DGEz13LlQSbZStw1oNsGeJkCetdwYdP2MDTKB4CbfR0ruPBzp9sIOJhvxJsRsGY9SNv jfvOkbTB+RTxt8DZZC7+gCcHzARaF5z1ilLvlHSxpzTUHSsPe5siy5dDhdlpZ6SDN2f7gh1PL KHSOueFxniYIyo+AAmQLsam3SlhWcaxQ1MuQoyiz0eCZig7xSEDYDOeDEIQOuaXDRCjsAAYUR jWMU9taIA2lQVd4rXs2pepHkU6GM3A/axMB8/CG8Q5UdOnt7j8cAaqHVcPLNLvBtVdYTrw93Q mhN4fFjBAu5yOIsY2dM+5egapYymF6zOFcTkQj4pCYUAIAZS745l/74rIw2PnXeiz8zGjhAd7 Zobtx2TaCaZqbY1SU3+GPxAg/l9iGQNfQVYbfOmZq6MxvvAx9EIF9hRzmm2EyhQQ5RfDzDUaS tYmXkTN7AVZ1CgzL7GOvAnSMlZrmHI4E3fCfN8L6mW3v17MWASahUnSeTiI6bPm7jM+Kyew5N FWxIkBpUqm+CCnzQOYev54uD5bUOywO0XwVd5cTFw2nn3q5KbLczQ/AKAO08H0FwdX2ZR8M/z bR9cKQwBvKQ+rfiSLmGaSI1YwT4= Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org From: Eberhard Stoll This qspi controller supports shifting the spi rx data sampling point to compensate line or spi device response delays. It enables fast spi data transfers even for devices which have a noticeable delay in the rx data stream. Add support for the SMPR sampling functionality Signed-off-by: Eberhard Stoll Signed-off-by: Frieder Schrempf --- drivers/spi/spi-fsl-qspi.c | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) -- 2.25.1 diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c index 79bac30e79af..68801e08f997 100644 --- a/drivers/spi/spi-fsl-qspi.c +++ b/drivers/spi/spi-fsl-qspi.c @@ -274,6 +274,12 @@ struct fsl_qspi { int selected; }; +struct fsl_qspi_chip_data { + u32 rx_sample_delay_ns; + unsigned long rate; + u32 smpr_sampling; +}; + static inline int needs_swap_endian(struct fsl_qspi *q) { return q->devtype_data->quirks & QUADSPI_QUIRK_SWAP_ENDIAN; @@ -522,14 +528,63 @@ static void fsl_qspi_invalidate(struct fsl_qspi *q) qspi_writel(q, reg, q->iobase + QUADSPI_MCR); } +static void fsl_qspi_update_smpr_sampling(struct fsl_qspi *q, u32 smpr) +{ + void __iomem *base = q->iobase; + u32 reg; + + /* Disable the module */ + qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK, + base + QUADSPI_MCR); + + reg = qspi_readl(q, base + QUADSPI_SMPR) & + ~(QUADSPI_SMPR_FSPHS_MASK | QUADSPI_SMPR_FSDLY_MASK); + qspi_writel(q, reg | smpr, base + QUADSPI_SMPR); + + /* Enable the module */ + qspi_writel(q, QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK, + base + QUADSPI_MCR); +} + +const char *sampling_mode[] = { "N1", "I1", "N2", "I2"}; + static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_device *spi) { unsigned long rate = spi->max_speed_hz; int ret; + struct fsl_qspi_chip_data *chip = spi_get_ctldata(spi); + const char *sampling_ident = sampling_mode[0]; + + if (chip->rx_sample_delay_ns != spi->rx_sample_delay_ns | + chip->rate != rate) { + chip->rx_sample_delay_ns = spi->rx_sample_delay_ns; + chip->rate = rate; + + chip->smpr_sampling = + (2 * spi->rx_sample_delay_ns * (rate >> 10)) / (1000000000 >> 10); + dev_dbg(q->dev, "smpr_sampling = %u (delay %u ns)\n", + chip->smpr_sampling, spi->rx_sample_delay_ns); + + if (chip->smpr_sampling > 3) { + dev_err(q->dev, "rx sample delay for device %s exceeds hw capabilities! Clamp value to maximum setting.\n", + dev_name(&spi->dev)); + chip->smpr_sampling = 3; + sampling_ident = "(I2 clamped to max)"; + } else { + sampling_ident = sampling_mode[chip->smpr_sampling]; + } + + chip->smpr_sampling <<= 5; + dev_info(q->dev, "sampling point %s at %lu kHz used for device %s\n", + sampling_ident, rate / 1000, dev_name(&spi->dev)); + fsl_qspi_update_smpr_sampling(q, chip->smpr_sampling); + } if (q->selected == spi_get_chipselect(spi, 0)) return; + fsl_qspi_update_smpr_sampling(q, chip->smpr_sampling); + if (needs_4x_clock(q)) rate *= 4; @@ -839,6 +894,28 @@ static const struct spi_controller_mem_ops fsl_qspi_mem_ops = { .get_name = fsl_qspi_get_name, }; +static int fsl_qspi_setup(struct spi_device *spi) +{ + struct fsl_qspi_chip_data *chip = spi_get_ctldata(spi); + + if (!chip) { + chip = kzalloc(sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + spi_set_ctldata(spi, chip); + } + + return 0; +} + +static void fsl_qspi_cleanup(struct spi_device *spi) +{ + struct fsl_qspi_chip_data *chip = spi_get_ctldata(spi); + + kfree(chip); + spi_set_ctldata(spi, NULL); +} + static int fsl_qspi_probe(struct platform_device *pdev) { struct spi_controller *ctlr; @@ -865,6 +942,9 @@ static int fsl_qspi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, q); + ctlr->setup = fsl_qspi_setup; + ctlr->cleanup = fsl_qspi_cleanup; + /* find the resources */ q->iobase = devm_platform_ioremap_resource_byname(pdev, "QuadSPI"); if (IS_ERR(q->iobase)) {