Re: [PATCH v2 2/5] DMA: pl330: add quirk for broken no flushp
On Thu, Aug 27, 2015 at 5:38 PM, Shawn Lin wrote: > From: Addy Ke > > This patch add "arm,pl330-broken-no-flushp" quirk to avoid execute > DMAFLUSHP if Soc doesn't support it. > > Signed-off-by: Addy Ke > Signed-off-by: Shawn Lin > cc: Doug Anderson > cc: Heiko Stuebner > cc: Olof Johansson > > --- > > Changes in v2: > - amend the author > - amend Olof's mail address > > Changes in v1: > - rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested > by Krzysztof. > - remove Sunny's tag > > drivers/dma/pl330.c | 87 > ++--- > 1 file changed, 62 insertions(+), 25 deletions(-) > > diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c > index 0d544d2..3b9b426 100644 > --- a/drivers/dma/pl330.c > +++ b/drivers/dma/pl330.c > @@ -34,6 +34,8 @@ > #define PL330_MAX_IRQS 32 > #define PL330_MAX_PERI 32 > > +#define PL330_QUIRK_BROKEN_NO_FLUSHP BIT(0) > + > enum pl330_cachectrl { > CCTRL0, /* Noncacheable and nonbufferable */ > CCTRL1, /* Bufferable only */ > @@ -488,6 +490,17 @@ struct pl330_dmac { > /* Peripheral channels connected to this DMAC */ > unsigned int num_peripherals; > struct dma_pl330_chan *peripherals; /* keep at end */ > + int quirks; > +}; > + > +static struct pl330_of_quirks { > + char *quirk; > + int id; > +} of_quirks[] = { > + { > + .quirk = "arm,pl330-broken-no-flushp", > + .id = PL330_QUIRK_BROKEN_NO_FLUSHP, > + } > }; > > struct dma_pl330_desc { > @@ -1137,53 +1150,68 @@ static inline int _ldst_memtomem(unsigned dry_run, u8 > buf[], > return off; > } > > -static inline int _ldst_devtomem(unsigned dry_run, u8 buf[], > - const struct _xfer_spec *pxs, int cyc) > +static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run, > +u8 buf[], const struct _xfer_spec *pxs, > +int cyc) > { > int off = 0; > enum pl330_cond cond; > > - cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; > + if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) > + cond = BURST; > + else > + cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; > > while (cyc--) { > off += _emit_WFP(dry_run, [off], cond, pxs->desc->peri); > off += _emit_LDP(dry_run, [off], cond, pxs->desc->peri); > off += _emit_ST(dry_run, [off], ALWAYS); > - off += _emit_FLUSHP(dry_run, [off], pxs->desc->peri); > + > + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) > + off += _emit_FLUSHP(dry_run, [off], > + pxs->desc->peri); > } > > return off; > } > > -static inline int _ldst_memtodev(unsigned dry_run, u8 buf[], > - const struct _xfer_spec *pxs, int cyc) > +static inline int _ldst_memtodev(struct pl330_dmac *pl330, > +unsigned dry_run, u8 buf[], > +const struct _xfer_spec *pxs, int cyc) > { > int off = 0; > enum pl330_cond cond; > > - cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; > + if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) > + cond = BURST; > + else > + cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; > + > > while (cyc--) { > off += _emit_WFP(dry_run, [off], cond, pxs->desc->peri); > off += _emit_LD(dry_run, [off], ALWAYS); > off += _emit_STP(dry_run, [off], cond, pxs->desc->peri); > - off += _emit_FLUSHP(dry_run, [off], pxs->desc->peri); > + > + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) > + off += _emit_FLUSHP(dry_run, [off], > + pxs->desc->peri); > } > > return off; > } > > -static int _bursts(unsigned dry_run, u8 buf[], > +static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], > const struct _xfer_spec *pxs, int cyc) > { > int off = 0; > > switch (pxs->desc->rqtype) { > case DMA_MEM_TO_DEV: > - off += _ldst_memtodev(dry_run, [off], pxs, cyc); > + off += _ldst_memtodev(pl330, dry_run, [off], pxs, cyc); > break; > case DMA_DEV_TO_MEM: > - off += _ldst_devtomem(dry_run, [off], pxs, cyc); > + off += _ldst_devtomem(pl330, dry_run, [off], pxs, cyc); > break; > case DMA_MEM_TO_MEM: > off += _ldst_memtomem(dry_run, [off], pxs, cyc); > @@ -1197,7 +1225,7 @@ static int _bursts(unsigned dry_run, u8 buf[], > } > > /* Returns bytes consumed and updates bursts */ > -static inline int _loop(unsigned dry_run, u8
Re: [PATCH v2 2/5] DMA: pl330: add quirk for broken no flushp
On Thu, Aug 27, 2015 at 5:38 PM, Shawn Linwrote: > From: Addy Ke > > This patch add "arm,pl330-broken-no-flushp" quirk to avoid execute > DMAFLUSHP if Soc doesn't support it. > > Signed-off-by: Addy Ke > Signed-off-by: Shawn Lin > cc: Doug Anderson > cc: Heiko Stuebner > cc: Olof Johansson > > --- > > Changes in v2: > - amend the author > - amend Olof's mail address > > Changes in v1: > - rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested > by Krzysztof. > - remove Sunny's tag > > drivers/dma/pl330.c | 87 > ++--- > 1 file changed, 62 insertions(+), 25 deletions(-) > > diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c > index 0d544d2..3b9b426 100644 > --- a/drivers/dma/pl330.c > +++ b/drivers/dma/pl330.c > @@ -34,6 +34,8 @@ > #define PL330_MAX_IRQS 32 > #define PL330_MAX_PERI 32 > > +#define PL330_QUIRK_BROKEN_NO_FLUSHP BIT(0) > + > enum pl330_cachectrl { > CCTRL0, /* Noncacheable and nonbufferable */ > CCTRL1, /* Bufferable only */ > @@ -488,6 +490,17 @@ struct pl330_dmac { > /* Peripheral channels connected to this DMAC */ > unsigned int num_peripherals; > struct dma_pl330_chan *peripherals; /* keep at end */ > + int quirks; > +}; > + > +static struct pl330_of_quirks { > + char *quirk; > + int id; > +} of_quirks[] = { > + { > + .quirk = "arm,pl330-broken-no-flushp", > + .id = PL330_QUIRK_BROKEN_NO_FLUSHP, > + } > }; > > struct dma_pl330_desc { > @@ -1137,53 +1150,68 @@ static inline int _ldst_memtomem(unsigned dry_run, u8 > buf[], > return off; > } > > -static inline int _ldst_devtomem(unsigned dry_run, u8 buf[], > - const struct _xfer_spec *pxs, int cyc) > +static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run, > +u8 buf[], const struct _xfer_spec *pxs, > +int cyc) > { > int off = 0; > enum pl330_cond cond; > > - cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; > + if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) > + cond = BURST; > + else > + cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; > > while (cyc--) { > off += _emit_WFP(dry_run, [off], cond, pxs->desc->peri); > off += _emit_LDP(dry_run, [off], cond, pxs->desc->peri); > off += _emit_ST(dry_run, [off], ALWAYS); > - off += _emit_FLUSHP(dry_run, [off], pxs->desc->peri); > + > + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) > + off += _emit_FLUSHP(dry_run, [off], > + pxs->desc->peri); > } > > return off; > } > > -static inline int _ldst_memtodev(unsigned dry_run, u8 buf[], > - const struct _xfer_spec *pxs, int cyc) > +static inline int _ldst_memtodev(struct pl330_dmac *pl330, > +unsigned dry_run, u8 buf[], > +const struct _xfer_spec *pxs, int cyc) > { > int off = 0; > enum pl330_cond cond; > > - cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; > + if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) > + cond = BURST; > + else > + cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; > + > > while (cyc--) { > off += _emit_WFP(dry_run, [off], cond, pxs->desc->peri); > off += _emit_LD(dry_run, [off], ALWAYS); > off += _emit_STP(dry_run, [off], cond, pxs->desc->peri); > - off += _emit_FLUSHP(dry_run, [off], pxs->desc->peri); > + > + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) > + off += _emit_FLUSHP(dry_run, [off], > + pxs->desc->peri); > } > > return off; > } > > -static int _bursts(unsigned dry_run, u8 buf[], > +static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], > const struct _xfer_spec *pxs, int cyc) > { > int off = 0; > > switch (pxs->desc->rqtype) { > case DMA_MEM_TO_DEV: > - off += _ldst_memtodev(dry_run, [off], pxs, cyc); > + off += _ldst_memtodev(pl330, dry_run, [off], pxs, cyc); > break; > case DMA_DEV_TO_MEM: > - off += _ldst_devtomem(dry_run, [off], pxs, cyc); > + off += _ldst_devtomem(pl330, dry_run, [off], pxs, cyc); > break; > case DMA_MEM_TO_MEM: > off += _ldst_memtomem(dry_run, [off], pxs, cyc); > @@ -1197,7 +1225,7
[PATCH v2 2/5] DMA: pl330: add quirk for broken no flushp
From: Addy Ke This patch add "arm,pl330-broken-no-flushp" quirk to avoid execute DMAFLUSHP if Soc doesn't support it. Signed-off-by: Addy Ke Signed-off-by: Shawn Lin cc: Doug Anderson cc: Heiko Stuebner cc: Olof Johansson --- Changes in v2: - amend the author - amend Olof's mail address Changes in v1: - rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested by Krzysztof. - remove Sunny's tag drivers/dma/pl330.c | 87 ++--- 1 file changed, 62 insertions(+), 25 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 0d544d2..3b9b426 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -34,6 +34,8 @@ #define PL330_MAX_IRQS 32 #define PL330_MAX_PERI 32 +#define PL330_QUIRK_BROKEN_NO_FLUSHP BIT(0) + enum pl330_cachectrl { CCTRL0, /* Noncacheable and nonbufferable */ CCTRL1, /* Bufferable only */ @@ -488,6 +490,17 @@ struct pl330_dmac { /* Peripheral channels connected to this DMAC */ unsigned int num_peripherals; struct dma_pl330_chan *peripherals; /* keep at end */ + int quirks; +}; + +static struct pl330_of_quirks { + char *quirk; + int id; +} of_quirks[] = { + { + .quirk = "arm,pl330-broken-no-flushp", + .id = PL330_QUIRK_BROKEN_NO_FLUSHP, + } }; struct dma_pl330_desc { @@ -1137,53 +1150,68 @@ static inline int _ldst_memtomem(unsigned dry_run, u8 buf[], return off; } -static inline int _ldst_devtomem(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs, int cyc) +static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run, +u8 buf[], const struct _xfer_spec *pxs, +int cyc) { int off = 0; enum pl330_cond cond; - cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; + if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) + cond = BURST; + else + cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; while (cyc--) { off += _emit_WFP(dry_run, [off], cond, pxs->desc->peri); off += _emit_LDP(dry_run, [off], cond, pxs->desc->peri); off += _emit_ST(dry_run, [off], ALWAYS); - off += _emit_FLUSHP(dry_run, [off], pxs->desc->peri); + + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) + off += _emit_FLUSHP(dry_run, [off], + pxs->desc->peri); } return off; } -static inline int _ldst_memtodev(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs, int cyc) +static inline int _ldst_memtodev(struct pl330_dmac *pl330, +unsigned dry_run, u8 buf[], +const struct _xfer_spec *pxs, int cyc) { int off = 0; enum pl330_cond cond; - cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; + if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP) + cond = BURST; + else + cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST; + while (cyc--) { off += _emit_WFP(dry_run, [off], cond, pxs->desc->peri); off += _emit_LD(dry_run, [off], ALWAYS); off += _emit_STP(dry_run, [off], cond, pxs->desc->peri); - off += _emit_FLUSHP(dry_run, [off], pxs->desc->peri); + + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) + off += _emit_FLUSHP(dry_run, [off], + pxs->desc->peri); } return off; } -static int _bursts(unsigned dry_run, u8 buf[], +static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], const struct _xfer_spec *pxs, int cyc) { int off = 0; switch (pxs->desc->rqtype) { case DMA_MEM_TO_DEV: - off += _ldst_memtodev(dry_run, [off], pxs, cyc); + off += _ldst_memtodev(pl330, dry_run, [off], pxs, cyc); break; case DMA_DEV_TO_MEM: - off += _ldst_devtomem(dry_run, [off], pxs, cyc); + off += _ldst_devtomem(pl330, dry_run, [off], pxs, cyc); break; case DMA_MEM_TO_MEM: off += _ldst_memtomem(dry_run, [off], pxs, cyc); @@ -1197,7 +1225,7 @@ static int _bursts(unsigned dry_run, u8 buf[], } /* Returns bytes consumed and updates bursts */ -static inline int _loop(unsigned dry_run, u8 buf[], +static inline int _loop(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], unsigned long *bursts, const struct _xfer_spec *pxs) { int cyc, cycmax, szlp, szlpend, szbrst, off; @@ -1220,7 +1248,7 @@ static inline int _loop(unsigned dry_run, u8 buf[], }
[PATCH v2 2/5] DMA: pl330: add quirk for broken no flushp
From: Addy Ke addy...@rock-chips.com This patch add arm,pl330-broken-no-flushp quirk to avoid execute DMAFLUSHP if Soc doesn't support it. Signed-off-by: Addy Ke addy...@rock-chips.com Signed-off-by: Shawn Lin shawn@rock-chips.com cc: Doug Anderson diand...@chromium.org cc: Heiko Stuebner he...@sntech.de cc: Olof Johansson o...@lixom.net --- Changes in v2: - amend the author - amend Olof's mail address Changes in v1: - rename broken-no-flushp to arm,pl330-broken-no-flushp suggested by Krzysztof. - remove Sunny's tag drivers/dma/pl330.c | 87 ++--- 1 file changed, 62 insertions(+), 25 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 0d544d2..3b9b426 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -34,6 +34,8 @@ #define PL330_MAX_IRQS 32 #define PL330_MAX_PERI 32 +#define PL330_QUIRK_BROKEN_NO_FLUSHP BIT(0) + enum pl330_cachectrl { CCTRL0, /* Noncacheable and nonbufferable */ CCTRL1, /* Bufferable only */ @@ -488,6 +490,17 @@ struct pl330_dmac { /* Peripheral channels connected to this DMAC */ unsigned int num_peripherals; struct dma_pl330_chan *peripherals; /* keep at end */ + int quirks; +}; + +static struct pl330_of_quirks { + char *quirk; + int id; +} of_quirks[] = { + { + .quirk = arm,pl330-broken-no-flushp, + .id = PL330_QUIRK_BROKEN_NO_FLUSHP, + } }; struct dma_pl330_desc { @@ -1137,53 +1150,68 @@ static inline int _ldst_memtomem(unsigned dry_run, u8 buf[], return off; } -static inline int _ldst_devtomem(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs, int cyc) +static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run, +u8 buf[], const struct _xfer_spec *pxs, +int cyc) { int off = 0; enum pl330_cond cond; - cond = (pxs-desc-rqcfg.brst_len == 1) ? SINGLE : BURST; + if (pl330-quirks PL330_QUIRK_BROKEN_NO_FLUSHP) + cond = BURST; + else + cond = (pxs-desc-rqcfg.brst_len == 1) ? SINGLE : BURST; while (cyc--) { off += _emit_WFP(dry_run, buf[off], cond, pxs-desc-peri); off += _emit_LDP(dry_run, buf[off], cond, pxs-desc-peri); off += _emit_ST(dry_run, buf[off], ALWAYS); - off += _emit_FLUSHP(dry_run, buf[off], pxs-desc-peri); + + if (!(pl330-quirks PL330_QUIRK_BROKEN_NO_FLUSHP)) + off += _emit_FLUSHP(dry_run, buf[off], + pxs-desc-peri); } return off; } -static inline int _ldst_memtodev(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs, int cyc) +static inline int _ldst_memtodev(struct pl330_dmac *pl330, +unsigned dry_run, u8 buf[], +const struct _xfer_spec *pxs, int cyc) { int off = 0; enum pl330_cond cond; - cond = (pxs-desc-rqcfg.brst_len == 1) ? SINGLE : BURST; + if (pl330-quirks PL330_QUIRK_BROKEN_NO_FLUSHP) + cond = BURST; + else + cond = (pxs-desc-rqcfg.brst_len == 1) ? SINGLE : BURST; + while (cyc--) { off += _emit_WFP(dry_run, buf[off], cond, pxs-desc-peri); off += _emit_LD(dry_run, buf[off], ALWAYS); off += _emit_STP(dry_run, buf[off], cond, pxs-desc-peri); - off += _emit_FLUSHP(dry_run, buf[off], pxs-desc-peri); + + if (!(pl330-quirks PL330_QUIRK_BROKEN_NO_FLUSHP)) + off += _emit_FLUSHP(dry_run, buf[off], + pxs-desc-peri); } return off; } -static int _bursts(unsigned dry_run, u8 buf[], +static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], const struct _xfer_spec *pxs, int cyc) { int off = 0; switch (pxs-desc-rqtype) { case DMA_MEM_TO_DEV: - off += _ldst_memtodev(dry_run, buf[off], pxs, cyc); + off += _ldst_memtodev(pl330, dry_run, buf[off], pxs, cyc); break; case DMA_DEV_TO_MEM: - off += _ldst_devtomem(dry_run, buf[off], pxs, cyc); + off += _ldst_devtomem(pl330, dry_run, buf[off], pxs, cyc); break; case DMA_MEM_TO_MEM: off += _ldst_memtomem(dry_run, buf[off], pxs, cyc); @@ -1197,7 +1225,7 @@ static int _bursts(unsigned dry_run, u8 buf[], } /* Returns bytes consumed and updates bursts */ -static inline int _loop(unsigned dry_run, u8 buf[], +static inline int _loop(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], unsigned long *bursts, const struct _xfer_spec *pxs) { int cyc,