]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
spi: mediatek: Fix package division error
authorzhichao.liu <zhichao.liu@mediatek.com>
Fri, 21 Oct 2022 09:16:53 +0000 (17:16 +0800)
committerMark Brown <broonie@kernel.org>
Mon, 31 Oct 2022 13:20:09 +0000 (13:20 +0000)
Commit 7e963fb2a33ce ("spi: mediatek: add ipm design support
for MT7986") makes a mistake on package dividing operation
(one change is missing), need to fix it.

Background:
Ipm design is expanding the HW capability of dma (adjust package
length from 1KB to 64KB), and using "dev_comp->ipm_support" flag
to indicate it.

Issue description:
Ipm support patch (said above) is missing to handle remainder at
package dividing operation.
One case, a transmission length is 65KB, is will divide to 1K
(package length) * 65(package loop) in non-ipm desgin case, and
will divide to 64K(package length) * 1(package loop) + 1K(remainder)
in ipm design case. And the 1K remainder will be lost with the
current SW flow, and the transmission will be failure.
So, it should be fixed.

Solution:
Add "ipm_design" flag in function "mtk_spi_get_mult_delta()" to
indicate HW capability, and modify the parameters corespondingly.

fixes: 7e963fb2a33ce ("spi: mediatek: add ipm design support for MT7986")
Signed-off-by: zhichao.liu <zhichao.liu@mediatek.com>
Link: https://lore.kernel.org/r/20221021091653.18297-1-zhichao.liu@mediatek.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-mt65xx.c

index 11aeae7fe7fc9fd59e7e40e0f1e3e162a1b54914..a33c9a3de395fd2972fd22fdf673b9975aa8b20f 100644 (file)
@@ -551,14 +551,17 @@ static void mtk_spi_enable_transfer(struct spi_master *master)
        writel(cmd, mdata->base + SPI_CMD_REG);
 }
 
-static int mtk_spi_get_mult_delta(u32 xfer_len)
+static int mtk_spi_get_mult_delta(struct mtk_spi *mdata, u32 xfer_len)
 {
-       u32 mult_delta;
+       u32 mult_delta = 0;
 
-       if (xfer_len > MTK_SPI_PACKET_SIZE)
-               mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
-       else
-               mult_delta = 0;
+       if (mdata->dev_comp->ipm_design) {
+               if (xfer_len > MTK_SPI_IPM_PACKET_SIZE)
+                       mult_delta = xfer_len % MTK_SPI_IPM_PACKET_SIZE;
+       } else {
+               if (xfer_len > MTK_SPI_PACKET_SIZE)
+                       mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
+       }
 
        return mult_delta;
 }
@@ -570,22 +573,22 @@ static void mtk_spi_update_mdata_len(struct spi_master *master)
 
        if (mdata->tx_sgl_len && mdata->rx_sgl_len) {
                if (mdata->tx_sgl_len > mdata->rx_sgl_len) {
-                       mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len);
+                       mult_delta = mtk_spi_get_mult_delta(mdata, mdata->rx_sgl_len);
                        mdata->xfer_len = mdata->rx_sgl_len - mult_delta;
                        mdata->rx_sgl_len = mult_delta;
                        mdata->tx_sgl_len -= mdata->xfer_len;
                } else {
-                       mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len);
+                       mult_delta = mtk_spi_get_mult_delta(mdata, mdata->tx_sgl_len);
                        mdata->xfer_len = mdata->tx_sgl_len - mult_delta;
                        mdata->tx_sgl_len = mult_delta;
                        mdata->rx_sgl_len -= mdata->xfer_len;
                }
        } else if (mdata->tx_sgl_len) {
-               mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len);
+               mult_delta = mtk_spi_get_mult_delta(mdata, mdata->tx_sgl_len);
                mdata->xfer_len = mdata->tx_sgl_len - mult_delta;
                mdata->tx_sgl_len = mult_delta;
        } else if (mdata->rx_sgl_len) {
-               mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len);
+               mult_delta = mtk_spi_get_mult_delta(mdata, mdata->rx_sgl_len);
                mdata->xfer_len = mdata->rx_sgl_len - mult_delta;
                mdata->rx_sgl_len = mult_delta;
        }