mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 09:19:51 +00:00
spi: mediatek: Fix package division error
[ Upstream commitcf82d0ecb8
] Commit7e963fb2a3
("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:
parent
9acd65bdf6
commit
3cc59b35fc
1 changed files with 13 additions and 10 deletions
|
@ -551,14 +551,17 @@ static void mtk_spi_enable_transfer(struct spi_master *master)
|
||||||
writel(cmd, mdata->base + SPI_CMD_REG);
|
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)
|
if (mdata->dev_comp->ipm_design) {
|
||||||
mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
|
if (xfer_len > MTK_SPI_IPM_PACKET_SIZE)
|
||||||
else
|
mult_delta = xfer_len % MTK_SPI_IPM_PACKET_SIZE;
|
||||||
mult_delta = 0;
|
} else {
|
||||||
|
if (xfer_len > MTK_SPI_PACKET_SIZE)
|
||||||
|
mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
return mult_delta;
|
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) {
|
||||||
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->xfer_len = mdata->rx_sgl_len - mult_delta;
|
||||||
mdata->rx_sgl_len = mult_delta;
|
mdata->rx_sgl_len = mult_delta;
|
||||||
mdata->tx_sgl_len -= mdata->xfer_len;
|
mdata->tx_sgl_len -= mdata->xfer_len;
|
||||||
} else {
|
} 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->xfer_len = mdata->tx_sgl_len - mult_delta;
|
||||||
mdata->tx_sgl_len = mult_delta;
|
mdata->tx_sgl_len = mult_delta;
|
||||||
mdata->rx_sgl_len -= mdata->xfer_len;
|
mdata->rx_sgl_len -= mdata->xfer_len;
|
||||||
}
|
}
|
||||||
} else if (mdata->tx_sgl_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->xfer_len = mdata->tx_sgl_len - mult_delta;
|
||||||
mdata->tx_sgl_len = mult_delta;
|
mdata->tx_sgl_len = mult_delta;
|
||||||
} else if (mdata->rx_sgl_len) {
|
} 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->xfer_len = mdata->rx_sgl_len - mult_delta;
|
||||||
mdata->rx_sgl_len = mult_delta;
|
mdata->rx_sgl_len = mult_delta;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue