spi: rockchip sfc: use bounce buffer to deal with data transfer between cpu and sfc in dma mode

Bounce buffer implementation takes care of proper data buffer alignemt
and correct flush/invalidation of data cache at once so we no longer
depend on input data variety and make sure CPU and SFC controller deal
with expected data in case of enabled data cache.

Bounce buffer requires to add its definition (CONFIG_BOUNCE_BUFFER) in
board configuration, otherwise corresponding library won't be compiled
and linker will fail to build resulting executable.

Change-Id: Idbd0499d7ce2baa9cbbb04ade97ddb5bf49952ac
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
This commit is contained in:
Andy Yan 2018-01-29 14:43:51 +08:00 committed by Kever Yang
parent 990d853794
commit 37911cf692
2 changed files with 17 additions and 4 deletions

View File

@ -8,6 +8,7 @@
*/
#include <common.h>
#include <bouncebuf.h>
#include <clk.h>
#include <dm.h>
#include <dt-structs.h>
@ -201,15 +202,25 @@ static void rockchip_sfc_setup_xfer(struct rockchip_sfc *sfc, u32 trb)
static int rockchip_sfc_do_dma_xfer(struct rockchip_sfc *sfc, u32 *buffer, u32 trb)
{
struct rockchip_sfc_reg *regs = sfc->regbase;
struct bounce_buffer bb;
unsigned int bb_flags;
int timeout = 1000;
int ret = 0;
int risr;
unsigned long tbase;
rockchip_sfc_setup_xfer(sfc, trb);
if (sfc->rw == SFC_WR)
bb_flags = GEN_BB_READ;
else
bb_flags = GEN_BB_WRITE;
ret = bounce_buffer_start(&bb, (void *)buffer, trb, bb_flags);
if (ret)
return ret;
rockchip_sfc_setup_xfer(sfc, bb.len_aligned);
writel(0xFFFFFFFF, &regs->iclr);
writel((u32)buffer, &regs->dmaaddr);
writel((u32)bb.bounce_buffer, &regs->dmaaddr);
writel(SFC_DMA_START, &regs->dmatr);
tbase = get_timer(0);
@ -225,6 +236,8 @@ static int rockchip_sfc_do_dma_xfer(struct rockchip_sfc *sfc, u32 *buffer, u32 t
writel(0xFFFFFFFF, &regs->iclr);
bounce_buffer_stop(&bb);
return ret;
}
@ -351,7 +364,7 @@ static int rockchip_sfc_do_xfer(struct rockchip_sfc *sfc, u32 *buf, u32 len)
u32 bytes = len & 0x3;
u32 dma_trans;
if (len >= SFC_MAX_TRB) {
if (len >= ARCH_DMA_MINALIGN) {
dma_trans = len - bytes;
} else {
dma_trans = 0;

View File

@ -82,6 +82,6 @@ check_member(rockchip_sfc_reg, data, 0x108);
#define RX_UF_INT BIT(1) /* Rx fifo underflow interrupt */
#define RX_FULL_INT BIT(0) /* Rx fifo full interrupt */
#define SFC_MAX_TRB (1024 << 3)
#define SFC_MAX_TRB (512 * 31)
#endif