PL330 r1p0 version fixed the lockup error being on r0p0.
This patch supports the DMA transmit without barrier operation
if the revision is the next of r0p0.

Signed-off-by: Boojin Kim <[email protected]>
---
 arch/arm/include/asm/hardware/pl330.h |    5 +++++
 drivers/dma/pl330.c                   |   26 +++++++++++++++++++++-----
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/hardware/pl330.h 
b/arch/arm/include/asm/hardware/pl330.h
index ed38e32..1f4d7cb 100644
--- a/arch/arm/include/asm/hardware/pl330.h
+++ b/arch/arm/include/asm/hardware/pl330.h
@@ -144,6 +144,11 @@ enum pl330_reqtype {
 #define CRD            0xe14
 
 #define PERIPH_ID      0xfe0
+#define PERIPH_REV_SHIFT       20
+#define PERIPH_REV_MASK                0xf
+#define PERIPH_REV_R0P0                0
+#define PERIPH_REV_R1P0                1
+#define PERIPH_REV_R1P1                2
 #define PCELL_ID       0xff0
 
 #define CR0_PERIPH_REQ_SET     (1 << 0)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 3214ced..d87d884 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -129,6 +129,7 @@ struct pl330_reqcfg {
        enum pl330_dstcachectrl dcctl;
        enum pl330_srccachectrl scctl;
        enum pl330_byteswap swap;
+       struct pl330_config *pcfg;
 };
 
 /*
@@ -438,6 +439,11 @@ static inline u32 get_id(struct pl330_info *pi, u32 off)
        return id;
 }
 
+static inline u32 get_revision(u32 periph_id)
+{
+       return (periph_id>>PERIPH_REV_SHIFT)&PERIPH_REV_MASK;
+}
+
 static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[],
                enum pl330_dst da, u16 val)
 {
@@ -1026,12 +1032,21 @@ static inline int _ldst_memtomem(unsigned dry_run, u8 
buf[],
                const struct _xfer_spec *pxs, int cyc)
 {
        int off = 0;
+       struct pl330_config *pcfg = pxs->r->cfg->pcfg;
 
-       while (cyc--) {
-               off += _emit_LD(dry_run, &buf[off], ALWAYS);
-               off += _emit_RMB(dry_run, &buf[off]);
-               off += _emit_ST(dry_run, &buf[off], ALWAYS);
-               off += _emit_WMB(dry_run, &buf[off]);
+       /* check lock-up free version */
+       if (get_revision(pcfg->periph_id)  >= PERIPH_REV_R1P0) {
+               while (cyc--) {
+                       off += _emit_LD(dry_run, &buf[off], ALWAYS);
+                       off += _emit_ST(dry_run, &buf[off], ALWAYS);
+               }
+       } else {
+               while (cyc--) {
+                       off += _emit_LD(dry_run, &buf[off], ALWAYS);
+                       off += _emit_RMB(dry_run, &buf[off]);
+                       off += _emit_ST(dry_run, &buf[off], ALWAYS);
+                       off += _emit_WMB(dry_run, &buf[off]);
+               }
        }
 
        return off;
@@ -2398,6 +2413,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct 
dma_pl330_chan *pch)
        async_tx_ack(&desc->txd);
 
        desc->req.peri = peri_id ? pch->chan.chan_id : 0;
+       desc->rqcfg.pcfg = &pch->dmac->pif.pcfg;
 
        dma_async_tx_descriptor_init(&desc->txd, &pch->chan);
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to