#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)
        enum pl330_dstcachectrl dcctl;
        enum pl330_srccachectrl scctl;
        enum pl330_byteswap swap;
+       struct pl330_config *pcfg;
 };
 
 /*
        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)
 {
                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;
        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);