From nobody Thu Oct 9 02:53:17 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 55D5628C86C; Fri, 20 Jun 2025 13:29:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750426192; cv=none; b=OPu1Na3Dx/7MmC0JVc1Bz/c64NYye/+zfr201GppXVqfEWRrOmctYlt+bI7u7ePiQ9CyDMJ/3zMJP1VJsFrkou3O82D1Ter7f7H5Anm0NgO7+SWHFkPqHZDzYxfCkytOfPI2XaSGhhSifTuYazySDpE+EyDYYb3o+HLQyxwwbEY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750426192; c=relaxed/simple; bh=wMCEdueOEnPJnfKEZa6a6pKrV+7m581v06Tv718kKM0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CrWTaJFDEIN1S3nM2momT0k9ySrDvkhLKmnjIi9ZoM7BjLN69Hr5r/1CgFWG7wB19CTF5cUMOgbLOvsRAWfnRe1LGHGAOrmH8f2njINJ4YcRXd7639IvgYfz7WGOkiNu8npHRdWxZCEubQs+u21KDYpUnREU1quq9RGAw6IVE8Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VCN2peOM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VCN2peOM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 97958C4CEE3; Fri, 20 Jun 2025 13:29:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1750426191; bh=wMCEdueOEnPJnfKEZa6a6pKrV+7m581v06Tv718kKM0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VCN2peOMYLJqNpdwFSUtBPShcuxG8BtAI8IRABDA/fypiOS+xFvsZ6IhExue1gWLv PBipcaVhkX+NZ7VRI79wxKfo4GujJ3z5EkXI8wvj9NNkUi0kR/WAA8eEMpEEbrFwfZ nLPs2eWD+apqvIBLOzHxWxxj0rr0QTA8AZMS+1+Y1r5Q8U/xNY2mX1y6Npx9VOKtwC oEzaElmLFp513E+WPGC5yJ8mLN6ZF2pA6dgTaF6I6TApHP9sIL8KqQNw6jOa9Mn7AZ T3yz3cscIapFNwJil3CpvamFaMUY7mNGJPM8pEgvWTHDJqp+kAWjpVMICmDWABIBRF Hi5S+x6XU3Sxw== From: Conor Dooley To: linux-spi@vger.kernel.org Cc: conor@kernel.org, Conor Dooley , Daire McNamara , Mark Brown , linux-kernel@vger.kernel.org Subject: [PATCH v2 1/3] spi: microchip-core-qspi: set min_speed_hz during probe Date: Fri, 20 Jun 2025 14:28:24 +0100 Message-ID: <20250620-drained-widen-ac311bd5f172@spud> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250620-finer-yoyo-0bcae988a299@spud> References: <20250620-finer-yoyo-0bcae988a299@spud> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=942; i=conor.dooley@microchip.com; h=from:subject:message-id; bh=orpLnRq5nmIm7nv6mr3mpjzM37qOjt84M3FbOzOJkXo=; b=owGbwMvMwCFWscWwfUFT0iXG02pJDBmhid8bP3fJW/l5vP1SwfjXJnilUbrBBKvVgtEvOJLtF 0UmPnvXUcrCIMbBICumyJJ4u69Fav0flx3OPW9h5rAygQxh4OIUgInMt2dkmMW7znRe+GzW6mP7 2szrwnXyXvzyeXmI//DFEqWT/ZvK9RkZ3j9ucpBP3dr4x6wr84H4Yp9ntnN3HjsaxrEkrMCUt6S AFwA= X-Developer-Key: i=conor.dooley@microchip.com; a=openpgp; fpr=F9ECA03CF54F12CD01F1655722E2C55B37CF380C Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Conor Dooley The controller's minimum possible bus clock is 1/30 the rate of the input clock. Naively set the minimum bus clock speed the controller is capable of during probe, assuming that the rate will never reduce further. Signed-off-by: Conor Dooley --- drivers/spi/spi-microchip-core-qspi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spi-microchip-core-qspi.c b/drivers/spi/spi-microc= hip-core-qspi.c index fa828fcaaef2d..111ae6519ff41 100644 --- a/drivers/spi/spi-microchip-core-qspi.c +++ b/drivers/spi/spi-microchip-core-qspi.c @@ -562,6 +562,7 @@ static int mchp_coreqspi_probe(struct platform_device *= pdev) ctlr->mode_bits =3D SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD; ctlr->dev.of_node =3D np; + ctlr->min_speed_hz =3D clk_get_rate(qspi->clk) / 30; =20 ret =3D devm_spi_register_controller(&pdev->dev, ctlr); if (ret) --=20 2.45.2 From nobody Thu Oct 9 02:53:17 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 A424E28DF13; Fri, 20 Jun 2025 13:29:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750426194; cv=none; b=OleiF17FcOrfZy0fbfVY6N2jsG9Pu36JMGsNQDq3CqZ3ukWc0tZJ8rvpVgRScO0jtW3sRCbj20r6xmUlUrMfpMZUcuq8QzKpd60BZlV3KDLLDXfAZ5TOnCMm9zM4RZeJqx8jLzmdaDVuj4spxJVRmyDxMUNPIPW1dl0AIysKRNo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750426194; c=relaxed/simple; bh=lT0wgIbA3b77ZdRhZSsA5m4vTiNAehbZpJBs1x1u0Nw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=c66LRa8Lml3d6PKvXjoltasnOiAdz3SRZ0ACEFqeOJOKdUbPZrV7vz2P3tIS8aKmWo2pIsQq5weEv4lG1dtTv47nCtKaCWeiqKSIIJnacMv9SVUxKPUw8LHwyo/VoSNmnmKFEAPKZTi/ek6m4vzz5VNoRE7I+VHJ+iGjUY/stco= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GU8Lfl0H; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GU8Lfl0H" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E86E5C4CEE3; Fri, 20 Jun 2025 13:29:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1750426194; bh=lT0wgIbA3b77ZdRhZSsA5m4vTiNAehbZpJBs1x1u0Nw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GU8Lfl0HaC2B1QPDrOEWh6S8bQUBMkXehTHnP3rRaxkQoZV62tmRRLnp2/ECv2dmS T2OOFz507YiqgsH9rPdUChkcEv/zLbhwz9QGlKHi+UETI2HJAXifUO0OAeDc6DQgqR VnsZA0JUds4mDL1PpZo4Ktl81Qf45Dm3qsB3nAFyq/DDPbtCnBRWnTTQ2j0AKBBatB zlMQlAy1DPKorOSbnU/xpF5G9gzuJNNMPmXY38ZnmupwSaXnGQssde04dyyax9SwuL tFgnB0ImKJZl21VzhKQduMy3qCyphvgY3V6Z7pmdq2NNND1RRztRg60gdJUYvJCwqf O4FPB6dD45GLQ== From: Conor Dooley To: linux-spi@vger.kernel.org Cc: conor@kernel.org, Conor Dooley , Daire McNamara , Mark Brown , linux-kernel@vger.kernel.org Subject: [PATCH v2 2/3] spi: microchip-core-qspi: remove unused param from mchp_coreqspi_write_op() Date: Fri, 20 Jun 2025 14:28:25 +0100 Message-ID: <20250620-starry-excusably-25e6be957d9d@spud> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250620-finer-yoyo-0bcae988a299@spud> References: <20250620-finer-yoyo-0bcae988a299@spud> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1686; i=conor.dooley@microchip.com; h=from:subject:message-id; bh=WCMOD6G4q2tu4R6buWvkebNETPu2QyAxdrWPdw4+wbA=; b=owGbwMvMwCFWscWwfUFT0iXG02pJDBmhid+XnCxsPtUhW232NMQ1d03R6mtie41yvjK8u2BQF bB94utdHaUsDGIcDLJiiiyJt/tapNb/cdnh3PMWZg4rE8gQBi5OAZjIyR8M/+xmdt8u1mwOtG96 r21SLPv4o0jpydh/7P+TBG2lsx5xWzIyTLVScLdbd8+Pf7uOU9dG8abT7ItWSy87316m+WbR59Q zjAA= X-Developer-Key: i=conor.dooley@microchip.com; a=openpgp; fpr=F9ECA03CF54F12CD01F1655722E2C55B37CF380C Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Conor Dooley "word" is unused in mchp_coreqspi_write_op(), so delete it. Signed-off-by: Conor Dooley --- drivers/spi/spi-microchip-core-qspi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-microchip-core-qspi.c b/drivers/spi/spi-microc= hip-core-qspi.c index 111ae6519ff41..67ff5f8aa84d0 100644 --- a/drivers/spi/spi-microchip-core-qspi.c +++ b/drivers/spi/spi-microchip-core-qspi.c @@ -194,7 +194,7 @@ static inline void mchp_coreqspi_read_op(struct mchp_co= reqspi *qspi) } } =20 -static inline void mchp_coreqspi_write_op(struct mchp_coreqspi *qspi, bool= word) +static inline void mchp_coreqspi_write_op(struct mchp_coreqspi *qspi) { u32 control, data; =20 @@ -415,7 +415,7 @@ static int mchp_coreqspi_exec_op(struct spi_mem *mem, c= onst struct spi_mem_op *o qspi->rxbuf =3D NULL; qspi->tx_len =3D op->cmd.nbytes; qspi->rx_len =3D 0; - mchp_coreqspi_write_op(qspi, false); + mchp_coreqspi_write_op(qspi); } =20 qspi->txbuf =3D &opaddr[0]; @@ -426,7 +426,7 @@ static int mchp_coreqspi_exec_op(struct spi_mem *mem, c= onst struct spi_mem_op *o qspi->rxbuf =3D NULL; qspi->tx_len =3D op->addr.nbytes; qspi->rx_len =3D 0; - mchp_coreqspi_write_op(qspi, false); + mchp_coreqspi_write_op(qspi); } =20 if (op->data.nbytes) { @@ -435,7 +435,7 @@ static int mchp_coreqspi_exec_op(struct spi_mem *mem, c= onst struct spi_mem_op *o qspi->rxbuf =3D NULL; qspi->rx_len =3D 0; qspi->tx_len =3D op->data.nbytes; - mchp_coreqspi_write_op(qspi, true); + mchp_coreqspi_write_op(qspi); } else { qspi->txbuf =3D NULL; qspi->rxbuf =3D (u8 *)op->data.buf.in; --=20 2.45.2 From nobody Thu Oct 9 02:53:17 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 55D2F28A71B; Fri, 20 Jun 2025 13:29:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750426197; cv=none; b=ZFU6TAR013sBAIeZwrnXeoqRBMhpXC2fyTJpUd0/qd9VMv84Z05SkdNdSPrYFo9pdsjTcordzQv27N3rZszXzc9p7E5vMMr+MFBf1Ne1miW6oYyKgKwipydgjrR67bPibhZOvacgDtL3IuhtK70/8SkQRDFye9cmIjETtnVP9/w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750426197; c=relaxed/simple; bh=oWZq8aHxoc/AYd0TeBWtl/V2VXdCuqI5kEwoI43IORQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=F3iTfos0D+5Z4oS7/35e8GfxRe+XcKxUqP2JFB0TxSSUx6wE5lzA/ehfc0pZKEa5e0dP32k3cHT/WUex8cOjG3Oy7l1n+xuLDM1JiDGANRVhKkD6HEYjRCAuLbZkSYGXhm9FJpE9wbuv+XjQJbdrMVSUeGKIn+afUZUrcroaX2k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=teoIhE3b; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="teoIhE3b" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BA05EC4CEEE; Fri, 20 Jun 2025 13:29:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1750426197; bh=oWZq8aHxoc/AYd0TeBWtl/V2VXdCuqI5kEwoI43IORQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=teoIhE3b69B20cXfAnxZDTU8IeYgJQqBp5sv3+i3ikg53kah4GZrT7tfidWxFXDMy 8xbhaMug9gurh0D2cNPJNQCI/VAh9BvzpRUSU903ZveVUhU6kkBQcNAXPN4VPUca5a AykcwGI6fc0Pprk7MQyvmcnkaHtaTcfz0Hkn5IYonPuZZtzohQdcE+vbsXv0vZQFMu ac/Djz+Zq8IKs2wbpq9x8qEbpZAY8GNpdaNg2KD5pSNSkaB5p7arg5HxcZeDj4fl3g REWv+NoW11Z8TkWGnCstejqZsQiJD/1O3fsfJJa6u/5H59A2jW+SlVPGRgFMWtmlcb aE79GU8NGCtFQ== From: Conor Dooley To: linux-spi@vger.kernel.org Cc: conor@kernel.org, Conor Dooley , Daire McNamara , Mark Brown , linux-kernel@vger.kernel.org, Cyril Jean Subject: [PATCH v2 3/3] spi: microchip-core-qspi: Add regular transfers Date: Fri, 20 Jun 2025 14:28:26 +0100 Message-ID: <20250620-splice-shelter-310771564886@spud> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250620-finer-yoyo-0bcae988a299@spud> References: <20250620-finer-yoyo-0bcae988a299@spud> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=9361; i=conor.dooley@microchip.com; h=from:subject:message-id; bh=B/q2ukzJYNYor7gOpnDgWbzzJt0rZvSzVJ1H4vtiFaw=; b=owGbwMvMwCFWscWwfUFT0iXG02pJDBmhiT+aGD79Yf3you3GoyaJoA1PCzbuklkWL3vi/xSby P/yocsbOkpZGMQ4GGTFFFkSb/e1SK3/47LDuectzBxWJpAhDFycAjCRawGMDHNFNedVPbJ7l76u zfPQoa4QCeOZB7U2SjsKvDjDILNFT5zhv3tHhseln8+tfTRSTsw4s0LZasbOScue6C13uqmkHmR vygcA X-Developer-Key: i=conor.dooley@microchip.com; a=openpgp; fpr=F9ECA03CF54F12CD01F1655722E2C55B37CF380C Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Cyril Jean The driver for CoreQSPI only supports memory operations at present, so add support for regular transfers so that the SD card slot and ADC on the BeagleV Fire can be used. Signed-off-by: Cyril Jean Co-developed-by: Conor Dooley Signed-off-by: Conor Dooley --- drivers/spi/spi-microchip-core-qspi.c | 217 +++++++++++++++++++++++--- 1 file changed, 199 insertions(+), 18 deletions(-) diff --git a/drivers/spi/spi-microchip-core-qspi.c b/drivers/spi/spi-microc= hip-core-qspi.c index 67ff5f8aa84d0..d13a9b755c7f8 100644 --- a/drivers/spi/spi-microchip-core-qspi.c +++ b/drivers/spi/spi-microchip-core-qspi.c @@ -222,6 +222,87 @@ static inline void mchp_coreqspi_write_op(struct mchp_= coreqspi *qspi) } } =20 +static inline void mchp_coreqspi_write_read_op(struct mchp_coreqspi *qspi) +{ + u32 control, data; + + qspi->rx_len =3D qspi->tx_len; + + control =3D readl_relaxed(qspi->regs + REG_CONTROL); + control |=3D CONTROL_FLAGSX4; + writel_relaxed(control, qspi->regs + REG_CONTROL); + + while (qspi->tx_len >=3D 4) { + while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_TXFIFOFULL) + ; + + data =3D qspi->txbuf ? *((u32 *)qspi->txbuf) : 0xaa; + if (qspi->txbuf) + qspi->txbuf +=3D 4; + qspi->tx_len -=3D 4; + writel_relaxed(data, qspi->regs + REG_X4_TX_DATA); + + /* + * The rx FIFO is twice the size of the tx FIFO, so there is + * no requirement to block transmission if receive data is not + * ready, and it is fine to let the tx FIFO completely fill + * without reading anything from the rx FIFO. Once the tx FIFO + * has been filled and becomes non-full due to a transmission + * occurring there will always be something to receive. + * IOW, this is safe as TX_FIFO_SIZE + 4 < 2 * TX_FIFO_SIZE + */ + if (qspi->rx_len >=3D 4) { + if (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_RXAVAILABLE) { + data =3D readl_relaxed(qspi->regs + REG_X4_RX_DATA); + *(u32 *)qspi->rxbuf =3D data; + qspi->rxbuf +=3D 4; + qspi->rx_len -=3D 4; + } + } + } + + /* + * Since transmission is not being blocked by clearing the rx FIFO, + * loop here until all received data "leaked" by the loop above has + * been dealt with. + */ + while (qspi->rx_len >=3D 4) { + while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_RXFIFOEMPTY) + ; + data =3D readl_relaxed(qspi->regs + REG_X4_RX_DATA); + *(u32 *)qspi->rxbuf =3D data; + qspi->rxbuf +=3D 4; + qspi->rx_len -=3D 4; + } + + /* + * Since rx_len and tx_len must be < 4 bytes at this point, there's no + * concern about overflowing the rx or tx FIFOs any longer. It's + * therefore safe to loop over the remainder of the transmit data before + * handling the remaining receive data. + */ + if (!qspi->tx_len) + return; + + control &=3D ~CONTROL_FLAGSX4; + writel_relaxed(control, qspi->regs + REG_CONTROL); + + while (qspi->tx_len--) { + while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_TXFIFOFULL) + ; + data =3D qspi->txbuf ? *qspi->txbuf : 0xaa; + qspi->txbuf++; + writel_relaxed(data, qspi->regs + REG_TX_DATA); + } + + while (qspi->rx_len--) { + while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_RXFIFOEMPTY) + ; + data =3D readl_relaxed(qspi->regs + REG_RX_DATA); + *qspi->rxbuf++ =3D (data & 0xFF); + } +} + static void mchp_coreqspi_enable_ints(struct mchp_coreqspi *qspi) { u32 mask =3D IEN_TXDONE | @@ -266,7 +347,7 @@ static irqreturn_t mchp_coreqspi_isr(int irq, void *dev= _id) } =20 static int mchp_coreqspi_setup_clock(struct mchp_coreqspi *qspi, struct sp= i_device *spi, - const struct spi_mem_op *op) + u32 max_freq) { unsigned long clk_hz; u32 control, baud_rate_val =3D 0; @@ -275,11 +356,11 @@ static int mchp_coreqspi_setup_clock(struct mchp_core= qspi *qspi, struct spi_devi if (!clk_hz) return -EINVAL; =20 - baud_rate_val =3D DIV_ROUND_UP(clk_hz, 2 * op->max_freq); + baud_rate_val =3D DIV_ROUND_UP(clk_hz, 2 * max_freq); if (baud_rate_val > MAX_DIVIDER || baud_rate_val < MIN_DIVIDER) { dev_err(&spi->dev, "could not configure the clock for spi clock %d Hz & system clock %ld H= z\n", - op->max_freq, clk_hz); + max_freq, clk_hz); return -EINVAL; } =20 @@ -367,23 +448,13 @@ static inline void mchp_coreqspi_config_op(struct mch= p_coreqspi *qspi, const str writel_relaxed(frames, qspi->regs + REG_FRAMES); } =20 -static int mchp_qspi_wait_for_ready(struct spi_mem *mem) +static int mchp_coreqspi_wait_for_ready(struct mchp_coreqspi *qspi) { - struct mchp_coreqspi *qspi =3D spi_controller_get_devdata - (mem->spi->controller); u32 status; - int ret; =20 - ret =3D readl_poll_timeout(qspi->regs + REG_STATUS, status, + return readl_poll_timeout(qspi->regs + REG_STATUS, status, (status & STATUS_READY), 0, TIMEOUT_MS); - if (ret) { - dev_err(&mem->spi->dev, - "Timeout waiting on QSPI ready.\n"); - return -ETIMEDOUT; - } - - return ret; } =20 static int mchp_coreqspi_exec_op(struct spi_mem *mem, const struct spi_mem= _op *op) @@ -396,11 +467,13 @@ static int mchp_coreqspi_exec_op(struct spi_mem *mem,= const struct spi_mem_op *o int err, i; =20 mutex_lock(&qspi->op_lock); - err =3D mchp_qspi_wait_for_ready(mem); - if (err) + err =3D mchp_coreqspi_wait_for_ready(qspi); + if (err) { + dev_err(&mem->spi->dev, "Timeout waiting on QSPI ready.\n"); goto error; + } =20 - err =3D mchp_coreqspi_setup_clock(qspi, mem->spi, op); + err =3D mchp_coreqspi_setup_clock(qspi, mem->spi, op->max_freq); if (err) goto error; =20 @@ -515,6 +588,109 @@ static const struct spi_controller_mem_caps mchp_core= qspi_mem_caps =3D { .per_op_freq =3D true, }; =20 +static int mchp_coreqspi_unprepare_message(struct spi_controller *ctlr, st= ruct spi_message *m) +{ + struct mchp_coreqspi *qspi =3D spi_controller_get_devdata(ctlr); + + /* + * This delay is required for the driver to function correctly, + * but no explanation has been determined for why it is required. + */ + udelay(750); + + mutex_unlock(&qspi->op_lock); + + return 0; +} + +static int mchp_coreqspi_prepare_message(struct spi_controller *ctlr, stru= ct spi_message *m) +{ + struct mchp_coreqspi *qspi =3D spi_controller_get_devdata(ctlr); + struct spi_transfer *t =3D NULL; + u32 control, frames; + u32 total_bytes =3D 0, cmd_bytes =3D 0, idle_cycles =3D 0; + int ret; + bool quad =3D false, dual =3D false; + + mutex_lock(&qspi->op_lock); + ret =3D mchp_coreqspi_wait_for_ready(qspi); + if (ret) { + mutex_unlock(&qspi->op_lock); + dev_err(&ctlr->dev, "Timeout waiting on QSPI ready.\n"); + return ret; + } + + ret =3D mchp_coreqspi_setup_clock(qspi, m->spi, m->spi->max_speed_hz); + if (ret) { + mutex_unlock(&qspi->op_lock); + return ret; + } + + control =3D readl_relaxed(qspi->regs + REG_CONTROL); + control &=3D ~(CONTROL_MODE12_MASK | CONTROL_MODE0); + writel_relaxed(control, qspi->regs + REG_CONTROL); + + reinit_completion(&qspi->data_completion); + + list_for_each_entry(t, &m->transfers, transfer_list) { + total_bytes +=3D t->len; + if (!cmd_bytes && !(t->tx_buf && t->rx_buf)) + cmd_bytes =3D t->len; + if (!t->rx_buf) + cmd_bytes =3D total_bytes; + if (t->tx_nbits =3D=3D SPI_NBITS_QUAD || t->rx_nbits =3D=3D SPI_NBITS_QU= AD) + quad =3D true; + else if (t->tx_nbits =3D=3D SPI_NBITS_DUAL || t->rx_nbits =3D=3D SPI_NBI= TS_DUAL) + dual =3D true; + } + + control =3D readl_relaxed(qspi->regs + REG_CONTROL); + if (quad) { + control |=3D (CONTROL_MODE0 | CONTROL_MODE12_EX_RW); + } else if (dual) { + control &=3D ~CONTROL_MODE0; + control |=3D CONTROL_MODE12_FULL; + } else { + control &=3D ~(CONTROL_MODE12_MASK | CONTROL_MODE0); + } + writel_relaxed(control, qspi->regs + REG_CONTROL); + + frames =3D total_bytes & BYTESUPPER_MASK; + writel_relaxed(frames, qspi->regs + REG_FRAMESUP); + frames =3D total_bytes & BYTESLOWER_MASK; + frames |=3D cmd_bytes << FRAMES_CMDBYTES_SHIFT; + frames |=3D idle_cycles << FRAMES_IDLE_SHIFT; + control =3D readl_relaxed(qspi->regs + REG_CONTROL); + if (control & CONTROL_MODE12_MASK) + frames |=3D (1 << FRAMES_SHIFT); + + frames |=3D FRAMES_FLAGWORD; + writel_relaxed(frames, qspi->regs + REG_FRAMES); + + return 0; +}; + +static int mchp_coreqspi_transfer_one(struct spi_controller *ctlr, struct = spi_device *spi, + struct spi_transfer *t) +{ + struct mchp_coreqspi *qspi =3D spi_controller_get_devdata(ctlr); + + qspi->tx_len =3D t->len; + + if (t->tx_buf) + qspi->txbuf =3D (u8 *)t->tx_buf; + + if (!t->rx_buf) { + mchp_coreqspi_write_op(qspi); + } else { + qspi->rxbuf =3D (u8 *)t->rx_buf; + qspi->rx_len =3D t->len; + mchp_coreqspi_write_read_op(qspi); + } + + return 0; +} + static int mchp_coreqspi_probe(struct platform_device *pdev) { struct spi_controller *ctlr; @@ -563,6 +739,11 @@ static int mchp_coreqspi_probe(struct platform_device = *pdev) SPI_TX_DUAL | SPI_TX_QUAD; ctlr->dev.of_node =3D np; ctlr->min_speed_hz =3D clk_get_rate(qspi->clk) / 30; + ctlr->prepare_message =3D mchp_coreqspi_prepare_message; + ctlr->unprepare_message =3D mchp_coreqspi_unprepare_message; + ctlr->transfer_one =3D mchp_coreqspi_transfer_one; + ctlr->num_chipselect =3D 2; + ctlr->use_gpio_descriptors =3D true; =20 ret =3D devm_spi_register_controller(&pdev->dev, ctlr); if (ret) --=20 2.45.2