From: khilman@deeprootsystems.com (Kevin Hilman)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 02/13] OMAP: DMA: Introduce errata handling feature
Date: Tue, 09 Nov 2010 14:12:50 -0800 [thread overview]
Message-ID: <87sjzakuxp.fsf@deeprootsystems.com> (raw)
In-Reply-To: <1288099513-1854-3-git-send-email-manjugk@ti.com> (Manjunath Kondaiah G.'s message of "Tue, 26 Oct 2010 18:55:02 +0530")
"G, Manjunath Kondaiah" <manjugk@ti.com> writes:
> Implement errata handling to use flags instead of cpu_is_*
> and cpu_class_* in the code.
>
> The errata flags are initialized at init time and during runtime
> we are using the errata variable (via the IS_DMA_ERRATA macro)
> to execute the required errata workaround.
>
> Reused errata handling patch from Peter Ujfalusi <peter.ujfalusi@nokia.com>
> https://patchwork.kernel.org/patch/231191/
When starting from someone else's work, would be very helpful to
reviewers (and original authors) if you summarized what you
changed/fixed/updated etc.
> Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
> Cc: Peter Ujfalusi <peter.ujfalusi@nokia.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
> arch/arm/plat-omap/dma.c | 134 ++++++++++++++++++++++----------
> arch/arm/plat-omap/include/plat/dma.h | 11 +++
> 2 files changed, 103 insertions(+), 42 deletions(-)
>
> diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
> index 77241e2..0ff82d0 100644
> --- a/arch/arm/plat-omap/dma.c
> +++ b/arch/arm/plat-omap/dma.c
> @@ -195,6 +195,7 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
> #define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
>
> static int enable_1510_mode;
> +static u32 errata;
>
> static struct omap_dma_global_context_registers {
> u32 dma_irqenable_l0;
> @@ -1216,12 +1217,8 @@ void omap_start_dma(int lch)
>
> cur_lch = next_lch;
> } while (next_lch != -1);
> - } else if (cpu_is_omap242x() ||
> - (cpu_is_omap243x() && omap_type() <= OMAP2430_REV_ES1_0)) {
> -
> - /* Errata: Need to write lch even if not using chaining */
> + } else if (IS_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS))
> dma_write(lch, CLNK_CTRL2, lch);
> - }
>
> omap_enable_channel_irq(lch);
>
> @@ -1231,17 +1228,8 @@ void omap_start_dma(int lch)
> dma_write(l, CCR1, lch);
> } else {
> l = dma_read(CCR2, lch);
> - /*
> - * Errata: Inter Frame DMA buffering issue (All OMAP2420 and
> - * OMAP2430ES1.0): DMA will wrongly buffer elements if packing
> - * and bursting is enabled. This might result in data gets
> - * stalled in FIFO at the end of the block.
> - * Workaround: DMA channels must have BUFFERING_DISABLED bit
> - * set to guarantee no data will stay in the DMA FIFO in case
> - * inter frame buffering occurs.
> - */
> - if (cpu_is_omap2420() || (cpu_is_omap2430() &&
> - (omap_type() == OMAP2430_REV_ES1_0)))
> +
> + if (IS_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING))
> l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
>
> l |= OMAP_DMA_CCR_EN;
> @@ -1253,14 +1241,14 @@ EXPORT_SYMBOL(omap_start_dma);
>
> void omap_stop_dma(int lch)
> {
> - u32 l;
> + u32 l = 0;
>
> /* Disable all interrupts on the channel */
> if (cpu_class_is_omap1())
> dma_write(0, CICR1, lch);
>
> - /* OMAP3 Errata i541: sDMA FIFO draining does not finish */
> - if (cpu_is_omap34xx() && (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
> + if (IS_DMA_ERRATA(DMA_ERRATA_i541) &&
> + (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
> int i = 0;
> u32 sys_cf;
>
> @@ -1367,11 +1355,7 @@ dma_addr_t omap_get_dma_src_pos(int lch)
> else
> offset = dma_read(CSAC2, lch);
>
> - /*
> - * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
> - * read before the DMA controller finished disabling the channel.
> - */
> - if (!cpu_is_omap15xx() && offset == 0) {
> + if (IS_DMA_ERRATA(DMA_ERRATA_3_3) && offset == 0) {
> if (cpu_class_is_omap1())
> offset = dma_read(CSAC1, lch);
> else
> @@ -1966,7 +1950,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
> {
> int *channels;
> u32 l, i;
> - u32 sys_cf;
> + u32 sys_cf = 0;
>
> /* Check for input params */
> if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
> @@ -1981,15 +1965,13 @@ int omap_stop_dma_chain_transfers(int chain_id)
> }
> channels = dma_linked_lch[chain_id].linked_dmach_q;
>
> - /*
> - * DMA Errata:
> - * Special programming model needed to disable DMA before end of block
> - */
> - sys_cf = dma_read(OCP_SYSCONFIG, 0);
> - l = sys_cf;
> - /* Middle mode reg set no Standby */
> - l &= ~((1 << 12)|(1 << 13));
> - dma_write(l, OCP_SYSCONFIG, 0);
> + if (IS_DMA_ERRATA(DMA_ERRATA_i88)) {
> + sys_cf = dma_read(OCP_SYSCONFIG, 0);
> + l = sys_cf;
> + /* Middle mode reg set no Standby */
> + l &= ~((1 << 12)|(1 << 13));
> + dma_write(l, OCP_SYSCONFIG, 0);
> + }
>
> for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
>
> @@ -2008,8 +1990,8 @@ int omap_stop_dma_chain_transfers(int chain_id)
> /* Reset the Queue pointers */
> OMAP_DMA_CHAIN_QINIT(chain_id);
>
> - /* Errata - put in the old value */
> - dma_write(sys_cf, OCP_SYSCONFIG, 0);
> + if (IS_DMA_ERRATA(DMA_ERRATA_i88))
> + dma_write(sys_cf, OCP_SYSCONFIG, 0);
> return 0;
> }
> @@ -2215,12 +2197,7 @@ static int omap2_dma_handle_ch(int ch)
> if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ)) {
> printk(KERN_INFO "DMA transaction error with device %d\n",
> dma_chan[ch].dev_id);
> - if (cpu_class_is_omap2()) {
> - /*
> - * Errata: sDMA Channel is not disabled
> - * after a transaction error. So we explicitely
> - * disable the channel
> - */
> + if (IS_DMA_ERRATA(DMA_ERRATA_i378)) {
> u32 ccr;
>
> ccr = dma_read(CCR2, ch);
> @@ -2332,6 +2309,76 @@ void omap_dma_global_context_restore(void)
> omap_clear_dma(ch);
> }
>
> +static void configure_dma_errata(void)
> +{
> +
> + /*
> + * Erratas applicable for OMAP2430ES1.0 and all omap2420
> + *
> + * I.
> + * Errata ID: XX Inter Frame DMA buffering issue DMA will wrongly
> + * buffer elements if packing and bursting is enabled. This might
> + * result in data gets stalled in FIFO at the end of the block.
> + * Workaround: DMA channels must have BUFFERING_DISABLED bit set to
> + * guarantee no data will stay in the DMA FIFO in case inter frame
> + * buffering occurs
> + *
> + * II.
> + * Errata ID: XX DMA may hang when several channels are used in parallel
> + * In the following configuration, DMA channel hanging can occur:
> + * a. Channel i, hardware synchronized, is enabled
> + * b. Another channel (Channel x), software synchronized, is enabled.
> + * c. Channel i is disabled before end of transfer
> + * d. Channel i is reenabled.
> + * e. Steps 1 to 4 are repeated a certain number of times.
> + * f. A third channel (Channel y), software synchronized, is enabled.
> + * Channel x and Channel y may hang immediately after step 'f'.
> + * Workaround:
> + * For any channel used - make sure NextLCH_ID is set to the value j.
> + */
> + if (cpu_is_omap2420() || (cpu_is_omap2430() &&
> + (omap_type() == OMAP2430_REV_ES1_0))) {
> +
> + SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING);
> + SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS);
> + }
> +
> + /*
> + * Errata ID: i378: OMAP2plus: sDMA Channel is not disabled
> + * after a transaction error.
> + * Workaround: SW should explicitely disable the channel.
> + */
> + if (cpu_class_is_omap2())
> + SET_DMA_ERRATA(DMA_ERRATA_i378);
> +
> + /*
> + * Errata ID: i541: sDMA FIFO draining does not finish
> + * If sDMA channel is disabled on the fly, sDMA enters standby even
> + * through FIFO Drain is still in progress
> + * Workaround: Put sDMA in NoStandby more before a logical channel is
> + * disabled, then put it back to SmartStandby right after the channel
> + * finishes FIFO draining.
> + */
> + if (cpu_is_omap34xx())
> + SET_DMA_ERRATA(DMA_ERRATA_i541);
> +
> + /*
> + * Errata ID: i88 : Special programming model needed to disable DMA
> + * before end of block.
> + * Workaround: software must ensure that the DMA is configured in No
> + * Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01")
> + */
> + if (omap_type() == OMAP3430_REV_ES1_0)
> + SET_DMA_ERRATA(DMA_ERRATA_i88);
> +
> + /*
> + * Errata 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
This doesn't look like a unique errata identifier. Chapter 3 is usually
the 'Cautions' section, and I don't listed in either the 34xx (v5.9),
36xx (v1.3) or 44xx (v1.3) errata docs under this number, and don't see
that number in either of the 24xx errata docs either. Please clarify.
> + * read before the DMA controller finished disabling the channel.
> + */
> + if (!cpu_is_omap15xx())
> + SET_DMA_ERRATA(DMA_ERRATA_3_3);
> +}
> +
> /*----------------------------------------------------------------------------*/
>
> static int __init omap_init_dma(void)
> @@ -2481,6 +2528,9 @@ static int __init omap_init_dma(void)
> }
> }
>
> + /* Configure errata handling for all omap's */
> + configure_dma_errata();
> +
> return 0;
>
> out_free:
> diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
> index 27578f3..5e28d26 100644
> --- a/arch/arm/plat-omap/include/plat/dma.h
> +++ b/arch/arm/plat-omap/include/plat/dma.h
> @@ -285,6 +285,17 @@
> #define DMA_CH_PRIO_HIGH 0x1
> #define DMA_CH_PRIO_LOW 0x0 /* Def */
>
> +/* Errata handling */
> +#define IS_DMA_ERRATA(id) (errata &= (id))
Why the '&=' here? I guess it should just be a '&' The '=' was not in
Peter's original.
> +#define SET_DMA_ERRATA(id) (errata |= (id))
> +
> +#define DMA_ERRATA_IFRAME_BUFFERING (1 << 0)
> +#define DMA_ERRATA_PARALLEL_CHANNELS (1 << 1)
> +#define DMA_ERRATA_i378 (1 << 2)
> +#define DMA_ERRATA_i541 (1 << 3)
> +#define DMA_ERRATA_i88 (1 << 4)
> +#define DMA_ERRATA_3_3 (1 << 5)
Please use BIT()
> enum omap_dma_burst_mode {
> OMAP_DMA_DATA_BURST_DIS = 0,
> OMAP_DMA_DATA_BURST_4,
Kevin
next prev parent reply other threads:[~2010-11-09 22:12 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-26 13:25 [PATCH v3 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
2010-10-26 13:25 ` [PATCH v3 01/13] OMAP: DMA: Replace read/write macros with functions G, Manjunath Kondaiah
2010-10-26 14:48 ` Nishanth Menon
2010-10-27 3:54 ` G, Manjunath Kondaiah
2010-10-27 14:26 ` Menon, Nishanth
2010-10-29 8:15 ` G, Manjunath Kondaiah
2010-11-09 21:37 ` Kevin Hilman
2010-11-10 14:01 ` G, Manjunath Kondaiah
2010-11-10 16:03 ` Kevin Hilman
2010-11-10 17:16 ` G, Manjunath Kondaiah
2010-11-10 17:35 ` Kevin Hilman
2010-10-26 13:25 ` [PATCH v3 02/13] OMAP: DMA: Introduce errata handling feature G, Manjunath Kondaiah
2010-11-09 22:12 ` Kevin Hilman [this message]
2010-11-10 14:02 ` G, Manjunath Kondaiah
2010-11-10 16:26 ` Kevin Hilman
2010-11-10 17:39 ` G, Manjunath Kondaiah
2010-10-26 13:25 ` [PATCH v3 03/13] OMAP: DMA: Introduce DMA device attributes G, Manjunath Kondaiah
2010-11-09 21:46 ` Kevin Hilman
2010-10-26 13:25 ` [PATCH v3 04/13] OMAP2420: DMA: hwmod: add system DMA G, Manjunath Kondaiah
2010-11-09 23:13 ` Kevin Hilman
2010-11-11 23:04 ` Kevin Hilman
2010-10-26 13:25 ` [PATCH v3 05/13] OMAP2430: " G, Manjunath Kondaiah
2010-10-26 13:25 ` [PATCH v3 06/13] OMAP3: " G, Manjunath Kondaiah
2010-11-03 12:59 ` G, Manjunath Kondaiah
2010-11-04 4:29 ` Cousson, Benoit
2010-11-04 7:01 ` G, Manjunath Kondaiah
2010-11-04 12:30 ` Cousson, Benoit
2010-11-04 15:48 ` Kevin Hilman
2010-10-26 13:25 ` [PATCH v3 07/13] OMAP4: " G, Manjunath Kondaiah
2010-10-26 13:25 ` [PATCH v3 08/13] OMAP1: DMA: Introduce DMA driver as platform device G, Manjunath Kondaiah
2010-11-09 22:23 ` Kevin Hilman
2010-11-10 14:02 ` G, Manjunath Kondaiah
2010-10-26 13:25 ` [PATCH v3 09/13] OMAP2+: DMA: hwmod: Device registration G, Manjunath Kondaiah
2010-10-26 13:25 ` [PATCH v3 10/13] OMAP: DMA: Convert DMA library into DMA platform Driver G, Manjunath Kondaiah
2010-11-09 22:26 ` Kevin Hilman
2010-11-10 14:02 ` G, Manjunath Kondaiah
2010-11-10 16:24 ` Kevin Hilman
2010-11-10 17:23 ` G, Manjunath Kondaiah
2010-11-10 17:56 ` Kevin Hilman
2010-11-09 23:29 ` Kevin Hilman
2010-11-10 14:02 ` G, Manjunath Kondaiah
2010-10-26 13:25 ` [PATCH v3 11/13] OMAP: DMA: Use DMA device attributes G, Manjunath Kondaiah
2010-10-26 13:25 ` [PATCH v3 12/13] OMAP2+: DMA: descriptor autoloading feature G, Manjunath Kondaiah
2010-10-26 13:25 ` [PATCH v3 13/13] OMAP: PM: DMA: Enable runtime pm G, Manjunath Kondaiah
2010-11-09 22:48 ` Kevin Hilman
2010-11-10 14:02 ` G, Manjunath Kondaiah
2010-11-10 16:14 ` Kevin Hilman
2010-10-27 4:57 ` [PATCH v3 00/13] OMAP: DMA: hwmod and DMA as platform device G, Manjunath Kondaiah
2010-11-09 23:11 ` Kevin Hilman
2010-11-10 14:02 ` G, Manjunath Kondaiah
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87sjzakuxp.fsf@deeprootsystems.com \
--to=khilman@deeprootsystems.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).