spi: mediatek: Fix package division error

[ Upstream commit cf82d0ecb8 ]

Commit 7e963fb2a3 ("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: 7e963fb2a3 ("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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
zhichao.liu 2022-10-21 17:16:53 +08:00 committed by Greg Kroah-Hartman
parent 9acd65bdf6
commit 3cc59b35fc
1 changed files with 13 additions and 10 deletions

View 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;
}