public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set
@ 2009-10-29 22:39 Janusz Krzysztofik
  2009-10-29 23:47 ` Janusz Krzysztofik
  2009-10-30 14:42 ` Janusz Krzysztofik
  0 siblings, 2 replies; 17+ messages in thread
From: Janusz Krzysztofik @ 2009-10-29 22:39 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Jonathan McDowell, Tony Lindgren, linux-omap@vger.kernel.org,
	linux-arm-kernel, Imre Deak, linux-fbdev-devel, Paul Walmsley

With CONFIG_PM=y, the omapfb/lcd device on Amstrad Delta, after initially
starting correctly, breaks with the following error messages:

omapfb omapfb: resetting (status 0xffffff96,reset count 1)
...
omapfb omapfb: resetting (status 0xffffff96,reset count 100)
omapfb omapfb: too many reset attempts, giving up.

Looking closer at this I have found that it had been broken almost 2 years ago
with commit 2418996e3b100114edb2ae110d5d4acb928909d2, PM fixes for OMAP1.

The definite reason for broken omapfb/lcd_ams_delta in PM mode appeared to be
ARM_IDLECT1:IDLIF_ARM (bit 6) put into idle. The patch below fixes it.

Created and tested against linux-2.6.32-rc5

Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>

---
Hi,

I already reported this issue a few months ago, when
drivers/video/omap/lcd_ams_delta.c was proposed to get into mainline - see
http://www.spinics.net/lists/linux-omap/msg14546.html. Now I've found some
time to look at it again.

Since PM area is quite new to me, I am not sure if there may be a better
solution. AFAICS, the standard way to prevent an ARM_CLKCT1 bit being switched
to idle is to enable a clock that uses it (tipb_ck, dma_ck, or tc_ck or one of
its children in this case, right?).

I assume there is no bug in omapfb nor lcdc, as that would be already
detected. Maybe it would be better to fix drivers/video/omap/lcd_ams_delta.c
(or arch/arm/mach-omap1/board-ams-delta), but I don't know what clock should I
enable, if any.

--- linux-2.6.32-rc5/arch/arm/mach-omap1/pm.c.orig	2009-10-16 02:41:50.000000000 +0200
+++ linux-2.6.32-rc5/arch/arm/mach-omap1/pm.c	2009-10-29 22:07:58.000000000 +0100
@@ -45,6 +45,7 @@
 
 #include <asm/irq.h>
 #include <asm/atomic.h>
+#include <asm/mach-types.h>
 #include <asm/mach/time.h>
 #include <asm/mach/irq.h>
 
@@ -139,7 +140,7 @@ void omap1_pm_idle(void)
 	use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1);
 #endif
 
-	if (omap_dma_running())
+	if ((omap_dma_running()) || (machine_is_ams_delta()))
 		use_idlect1 &= ~(1 << 6);
 
 	/* We should be able to remove the do_sleep variable and multiple

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set
  2009-10-29 22:39 [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set Janusz Krzysztofik
@ 2009-10-29 23:47 ` Janusz Krzysztofik
  2009-10-30 14:42 ` Janusz Krzysztofik
  1 sibling, 0 replies; 17+ messages in thread
From: Janusz Krzysztofik @ 2009-10-29 23:47 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Jonathan McDowell, Tony Lindgren, linux-omap@vger.kernel.org,
	linux-arm-kernel, Imre Deak, linux-fbdev-devel, Paul Walmsley

Thursday 29 October 2009 23:39:44 Janusz Krzysztofik napisał(a):
>
> Since PM area is quite new to me, I am not sure if there may be a better
> solution. AFAICS, the standard way to prevent an ARM_CLKCT1 bit being

s/ARM_CLKCT1/ARM_IDLECT1/

> switched to idle is to enable a clock that uses it (tipb_ck, dma_ck, or
> tc_ck or one of its children in this case, right?).

Janusz
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set
  2009-10-29 22:39 [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set Janusz Krzysztofik
  2009-10-29 23:47 ` Janusz Krzysztofik
@ 2009-10-30 14:42 ` Janusz Krzysztofik
  2009-10-30 17:33   ` Tony Lindgren
  2009-11-10 10:50   ` Paul Walmsley
  1 sibling, 2 replies; 17+ messages in thread
From: Janusz Krzysztofik @ 2009-10-30 14:42 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kevin Hilman, Jonathan McDowell, linux-omap@vger.kernel.org,
	linux-arm-kernel, Imre Deak, linux-fbdev-devel, Paul Walmsley

Thursday 29 October 2009 23:39:44 Janusz Krzysztofik napisał(a):
> With CONFIG_PM=y, the omapfb/lcd device on Amstrad Delta, after initially
> starting correctly, breaks with the following error messages:
>
> omapfb omapfb: resetting (status 0xffffff96,reset count 1)
> ...
> omapfb omapfb: resetting (status 0xffffff96,reset count 100)
> omapfb omapfb: too many reset attempts, giving up.
>
> Looking closer at this I have found that it had been broken almost 2 years
> ago with commit 2418996e3b100114edb2ae110d5d4acb928909d2, PM fixes for
> OMAP1.
>
> The definite reason for broken omapfb/lcd_ams_delta in PM mode appeared to
> be ARM_IDLECT1:IDLIF_ARM (bit 6) put into idle. The patch below fixes it.
>
> Since PM area is quite new to me, I am not sure if there may be a better
> solution. AFAICS, the standard way to prevent an ARM_CLKCT1 bit being
> switched to idle is to enable a clock that uses it (tipb_ck, dma_ck, or
> tc_ck or one of its children in this case, right?).
>
> I assume there is no bug in omapfb nor lcdc, as that would be already
> detected. Maybe it would be better to fix
> drivers/video/omap/lcd_ams_delta.c (or
> arch/arm/mach-omap1/board-ams-delta), but I don't know what clock should I
> enable, if any.

More looking at it, I found that might be omap_dma_running() from 
arch/arm/plat-omap/dma.c that needs correction. It already checks for LCD dma 
running for OMAP1610, but does nothing similiar for 1510. I have revisited 
http://focus.ti.com/lit/ug/spru674/spru674.pdf, but found no hint how to do 
that in a 1610 similiar way.

Thanks,
Janusz
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set
  2009-10-30 14:42 ` Janusz Krzysztofik
@ 2009-10-30 17:33   ` Tony Lindgren
  2009-11-01  1:18     ` Janusz Krzysztofik
  2009-11-10 10:50   ` Paul Walmsley
  1 sibling, 1 reply; 17+ messages in thread
From: Tony Lindgren @ 2009-10-30 17:33 UTC (permalink / raw)
  To: Janusz Krzysztofik
  Cc: Kevin Hilman, Jonathan McDowell, linux-omap@vger.kernel.org,
	linux-arm-kernel, Imre Deak, linux-fbdev-devel, Paul Walmsley

* Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> [091030 07:43]:
> Thursday 29 October 2009 23:39:44 Janusz Krzysztofik napisał(a):
> > With CONFIG_PM=y, the omapfb/lcd device on Amstrad Delta, after initially
> > starting correctly, breaks with the following error messages:
> >
> > omapfb omapfb: resetting (status 0xffffff96,reset count 1)
> > ...
> > omapfb omapfb: resetting (status 0xffffff96,reset count 100)
> > omapfb omapfb: too many reset attempts, giving up.
> >
> > Looking closer at this I have found that it had been broken almost 2 years
> > ago with commit 2418996e3b100114edb2ae110d5d4acb928909d2, PM fixes for
> > OMAP1.
> >
> > The definite reason for broken omapfb/lcd_ams_delta in PM mode appeared to
> > be ARM_IDLECT1:IDLIF_ARM (bit 6) put into idle. The patch below fixes it.
> >
> > Since PM area is quite new to me, I am not sure if there may be a better
> > solution. AFAICS, the standard way to prevent an ARM_CLKCT1 bit being
> > switched to idle is to enable a clock that uses it (tipb_ck, dma_ck, or
> > tc_ck or one of its children in this case, right?).
> >
> > I assume there is no bug in omapfb nor lcdc, as that would be already
> > detected. Maybe it would be better to fix
> > drivers/video/omap/lcd_ams_delta.c (or
> > arch/arm/mach-omap1/board-ams-delta), but I don't know what clock should I
> > enable, if any.
> 
> More looking at it, I found that might be omap_dma_running() from 
> arch/arm/plat-omap/dma.c that needs correction. It already checks for LCD dma 
> running for OMAP1610, but does nothing similiar for 1510. I have revisited 
> http://focus.ti.com/lit/ug/spru674/spru674.pdf, but found no hint how to do 
> that in a 1610 similiar way.

Hmm to me it looks like the OMAP_DMA_CCR_EN should be set in one of the
channels if enabled. Maybe you need add a similar check somewhere in
the *_lcd_dma_* functions too in dma.c?

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set
  2009-10-30 17:33   ` Tony Lindgren
@ 2009-11-01  1:18     ` Janusz Krzysztofik
  2009-11-03 17:11       ` Tony Lindgren
  0 siblings, 1 reply; 17+ messages in thread
From: Janusz Krzysztofik @ 2009-11-01  1:18 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Kevin Hilman, Jonathan McDowell, linux-omap@vger.kernel.org,
	linux-arm-kernel, Imre Deak, linux-fbdev-devel, Paul Walmsley

Friday 30 October 2009 18:33:18 Tony Lindgren napisał(a):
> * Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> [091030 07:43]:
> > Thursday 29 October 2009 23:39:44 Janusz Krzysztofik napisał(a):
> > > With CONFIG_PM=y, the omapfb/lcd device on Amstrad Delta, after
> > > initially starting correctly, breaks with the following error messages:
> > >
> > > omapfb omapfb: resetting (status 0xffffff96,reset count 1)
> > > ...
> > > omapfb omapfb: resetting (status 0xffffff96,reset count 100)
> > > omapfb omapfb: too many reset attempts, giving up.
> > >
> > > Looking closer at this I have found that it had been broken almost 2
> > > years ago with commit 2418996e3b100114edb2ae110d5d4acb928909d2, PM
> > > fixes for OMAP1.
> > >
> > > The definite reason for broken omapfb/lcd_ams_delta in PM mode appeared
> > > to be ARM_IDLECT1:IDLIF_ARM (bit 6) put into idle. The patch below
> > > fixes it.
> > >
> > > Since PM area is quite new to me, I am not sure if there may be a
> > > better solution. AFAICS, the standard way to prevent an ARM_CLKCT1 bit
> > > being switched to idle is to enable a clock that uses it (tipb_ck,
> > > dma_ck, or tc_ck or one of its children in this case, right?).
> > >
> > > I assume there is no bug in omapfb nor lcdc, as that would be already
> > > detected. Maybe it would be better to fix
> > > drivers/video/omap/lcd_ams_delta.c (or
> > > arch/arm/mach-omap1/board-ams-delta), but I don't know what clock
> > > should I enable, if any.
> >
> > More looking at it, I found that might be omap_dma_running() from
> > arch/arm/plat-omap/dma.c that needs correction. It already checks for LCD
> > dma running for OMAP1610, but does nothing similiar for 1510. I have
> > revisited http://focus.ti.com/lit/ug/spru674/spru674.pdf, but found no
> > hint how to do that in a 1610 similiar way.
>
> Hmm to me it looks like the OMAP_DMA_CCR_EN should be set in one of the
> channels if enabled. Maybe you need add a similar check somewhere in
> the *_lcd_dma_* functions too in dma.c?

Tony,
It sounds reasonable, but the problem is that in the OMAP5910 documentation I 
can find no DMA_CCR equivalent in the LCD dedicated DMA channel register set, 
nor EN equivalent in the DMA_LCD_CTRL register.

I have had a look at *_lcd_dma_*, as you suggested, and found this:

        /*
         * Set the Enable bit only if an external controller is
         * connected. Otherwise the OMAP internal controller will
         * start the transfer when it gets enabled.
         */
        if (enable_1510_mode || !lcd_dma.ext_ctrl)
                return;

That may suggest checking for LCD controller, not DMA channel, enable bit 
could give an answer if LCD DMA is likely to be running or not. So maybe 
adding a function to drivers/video/omap/lcdc.c that would check for 
OMAP_LCDC_CONTROL:OMAP_LCDC_CTRL_LCD_EN, then invoke that function from 
omap_dma_running() in case of omap1510 could be a proper solution.

However, that would affect not only Amstrad Delta, but all 1510 based 
machines. Since there were no reports about broken LCD DMA on 1510, I'd 
rather get a confirmation from omap guys, more experienced than me, that the 
solution proposed is correct and should work not only for my Amstrad Delta 
before I get that way.

Thanks,
Janusz
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set
  2009-11-01  1:18     ` Janusz Krzysztofik
@ 2009-11-03 17:11       ` Tony Lindgren
  0 siblings, 0 replies; 17+ messages in thread
From: Tony Lindgren @ 2009-11-03 17:11 UTC (permalink / raw)
  To: Janusz Krzysztofik
  Cc: Kevin Hilman, Jonathan McDowell, linux-omap@vger.kernel.org,
	linux-arm-kernel, Imre Deak, linux-fbdev-devel, Paul Walmsley

* Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> [091031 18:20]:
> Friday 30 October 2009 18:33:18 Tony Lindgren napisał(a):
> > * Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> [091030 07:43]:
> > > Thursday 29 October 2009 23:39:44 Janusz Krzysztofik napisał(a):
> > > > With CONFIG_PM=y, the omapfb/lcd device on Amstrad Delta, after
> > > > initially starting correctly, breaks with the following error messages:
> > > >
> > > > omapfb omapfb: resetting (status 0xffffff96,reset count 1)
> > > > ...
> > > > omapfb omapfb: resetting (status 0xffffff96,reset count 100)
> > > > omapfb omapfb: too many reset attempts, giving up.
> > > >
> > > > Looking closer at this I have found that it had been broken almost 2
> > > > years ago with commit 2418996e3b100114edb2ae110d5d4acb928909d2, PM
> > > > fixes for OMAP1.
> > > >
> > > > The definite reason for broken omapfb/lcd_ams_delta in PM mode appeared
> > > > to be ARM_IDLECT1:IDLIF_ARM (bit 6) put into idle. The patch below
> > > > fixes it.
> > > >
> > > > Since PM area is quite new to me, I am not sure if there may be a
> > > > better solution. AFAICS, the standard way to prevent an ARM_CLKCT1 bit
> > > > being switched to idle is to enable a clock that uses it (tipb_ck,
> > > > dma_ck, or tc_ck or one of its children in this case, right?).
> > > >
> > > > I assume there is no bug in omapfb nor lcdc, as that would be already
> > > > detected. Maybe it would be better to fix
> > > > drivers/video/omap/lcd_ams_delta.c (or
> > > > arch/arm/mach-omap1/board-ams-delta), but I don't know what clock
> > > > should I enable, if any.
> > >
> > > More looking at it, I found that might be omap_dma_running() from
> > > arch/arm/plat-omap/dma.c that needs correction. It already checks for LCD
> > > dma running for OMAP1610, but does nothing similiar for 1510. I have
> > > revisited http://focus.ti.com/lit/ug/spru674/spru674.pdf, but found no
> > > hint how to do that in a 1610 similiar way.
> >
> > Hmm to me it looks like the OMAP_DMA_CCR_EN should be set in one of the
> > channels if enabled. Maybe you need add a similar check somewhere in
> > the *_lcd_dma_* functions too in dma.c?
> 
> Tony,
> It sounds reasonable, but the problem is that in the OMAP5910 documentation I 
> can find no DMA_CCR equivalent in the LCD dedicated DMA channel register set, 
> nor EN equivalent in the DMA_LCD_CTRL register.
> 
> I have had a look at *_lcd_dma_*, as you suggested, and found this:
> 
>         /*
>          * Set the Enable bit only if an external controller is
>          * connected. Otherwise the OMAP internal controller will
>          * start the transfer when it gets enabled.
>          */
>         if (enable_1510_mode || !lcd_dma.ext_ctrl)
>                 return;
> 
> That may suggest checking for LCD controller, not DMA channel, enable bit 
> could give an answer if LCD DMA is likely to be running or not. So maybe 
> adding a function to drivers/video/omap/lcdc.c that would check for 
> OMAP_LCDC_CONTROL:OMAP_LCDC_CTRL_LCD_EN, then invoke that function from 
> omap_dma_running() in case of omap1510 could be a proper solution.
> 
> However, that would affect not only Amstrad Delta, but all 1510 based 
> machines. Since there were no reports about broken LCD DMA on 1510, I'd 
> rather get a confirmation from omap guys, more experienced than me, that the 
> solution proposed is correct and should work not only for my Amstrad Delta 
> before I get that way.

That sounds like a reasonable way to fix it to me.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set
  2009-10-30 14:42 ` Janusz Krzysztofik
  2009-10-30 17:33   ` Tony Lindgren
@ 2009-11-10 10:50   ` Paul Walmsley
  2009-11-11  0:02     ` Janusz Krzysztofik
  2009-11-21 15:58     ` [RFC] [PATCH] OMAP: DMA: move LCD DMA related code from plat-omap to mach-omap1 (Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set) Janusz Krzysztofik
  1 sibling, 2 replies; 17+ messages in thread
From: Paul Walmsley @ 2009-11-10 10:50 UTC (permalink / raw)
  To: Janusz Krzysztofik
  Cc: Tony Lindgren, Kevin Hilman, Jonathan McDowell,
	linux-omap@vger.kernel.org, linux-arm-kernel, Imre Deak,
	linux-fbdev-devel

Hello Janusz et al,

On Fri, 30 Oct 2009, Janusz Krzysztofik wrote:

> More looking at it, I found that might be omap_dma_running() from 
> arch/arm/plat-omap/dma.c that needs correction. It already checks for LCD dma 
> running for OMAP1610, but does nothing similiar for 1510. I have revisited 
> http://focus.ti.com/lit/ug/spru674/spru674.pdf, but found no hint how to do 
> that in a 1610 similiar way.

Speaking of this code, here's a project suggestion if someone has some 
spare time.  All of the LCD DMA code in plat-omap/dma.c appears to be 
OMAP1-only (and apparently only is available on a subset of OMAP1 chips).  
It would be great if this code could be moved to mach-omap1/lcd_dma.c or 
a similar place.


- Paul

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set
  2009-11-10 10:50   ` Paul Walmsley
@ 2009-11-11  0:02     ` Janusz Krzysztofik
  2009-11-21 15:58     ` [RFC] [PATCH] OMAP: DMA: move LCD DMA related code from plat-omap to mach-omap1 (Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set) Janusz Krzysztofik
  1 sibling, 0 replies; 17+ messages in thread
From: Janusz Krzysztofik @ 2009-11-11  0:02 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Tony Lindgren, Kevin Hilman, Jonathan McDowell,
	linux-omap@vger.kernel.org, linux-arm-kernel, Imre Deak,
	linux-fbdev-devel

Tuesday 10 November 2009 11:50:52 Paul Walmsley napisał(a):
> Hello Janusz et al,
>
> On Fri, 30 Oct 2009, Janusz Krzysztofik wrote:
> > More looking at it, I found that might be omap_dma_running() from
> > arch/arm/plat-omap/dma.c that needs correction. It already checks for LCD
> > dma running for OMAP1610, but does nothing similiar for 1510. I have
> > revisited http://focus.ti.com/lit/ug/spru674/spru674.pdf, but found no
> > hint how to do that in a 1610 similiar way.
>
> Speaking of this code, here's a project suggestion if someone has some
> spare time.  All of the LCD DMA code in plat-omap/dma.c appears to be
> OMAP1-only (and apparently only is available on a subset of OMAP1 chips).
> It would be great if this code could be moved to mach-omap1/lcd_dma.c or
> a similar place.

Paul,

Thank you for putting me into right direction (I hope :-)). If there are no 
more comments, I'll try to take care of what you suggest after the situation 
with my pending patches AND Tomi Valkeinen's DSS2 patch series, that both 
more or less fiddle with LCD DMA related files, gets clear.

Thanks,
Janusz
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [RFC] [PATCH] OMAP: DMA: move LCD DMA related code from plat-omap to mach-omap1 (Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set)
  2009-11-10 10:50   ` Paul Walmsley
  2009-11-11  0:02     ` Janusz Krzysztofik
@ 2009-11-21 15:58     ` Janusz Krzysztofik
  2009-11-25  9:02       ` Paul Walmsley
  1 sibling, 1 reply; 17+ messages in thread
From: Janusz Krzysztofik @ 2009-11-21 15:58 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: Tony Lindgren, linux-omap@vger.kernel.org

(probably less interested persons and lists dropped)

Tuesday 10 November 2009 11:50:52 Paul Walmsley wrote:
> ...  All of the LCD DMA code in plat-omap/dma.c appears to be
> OMAP1-only (and apparently only is available on a subset of OMAP1 chips).
> It would be great if this code could be moved to mach-omap1/lcd_dma.c or
> a similar place.

The patch just tries to implement this idea.

Created against linux-omap for-next,
commit 2963c21fab52bfa8227da7f22864db393ebbc858

Tested on OMAP1510 Amstrad Delta.
Compile tested using omap_generic_2420_defconfig.

Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>

---
Hi Paul,

I hope the patch meets your suggestion closely enough.

Thanks,
Janusz

diff -uprN git.orig/arch/arm/mach-omap1/Makefile git/arch/arm/mach-omap1/Makefile
--- git.orig/arch/arm/mach-omap1/Makefile	2009-11-21 00:38:45.000000000 +0100
+++ git/arch/arm/mach-omap1/Makefile	2009-11-21 01:27:12.000000000 +0100
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := io.o id.o sram.o clock.o irq.o mux.o serial.o devices.o
+obj-y := io.o id.o sram.o clock.o irq.o lcd_dma.o mux.o serial.o devices.o
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
diff -uprN git.orig/arch/arm/mach-omap1/include/mach/lcd_dma.h git/arch/arm/mach-omap1/include/mach/lcd_dma.h
--- git.orig/arch/arm/mach-omap1/include/mach/lcd_dma.h	1970-01-01 01:00:00.000000000 +0100
+++ git/arch/arm/mach-omap1/include/mach/lcd_dma.h	2009-11-21 03:22:25.000000000 +0100
@@ -0,0 +1,78 @@
+/*
+ *  arch/arm/mach-omap1/include/mach/lcd_dma.h
+ *
+ * Extracted from arch/arm/plat-omap/include/plat/dma.h
+ *  Copyright (C) 2003 Nokia Corporation
+ *  Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __MACH_LCD_DMA_H__
+#define __MACH_LCD_DMA_H__
+
+/* Hardware registers for LCD DMA */
+#define OMAP1510_DMA_LCD_BASE		(0xfffedb00)
+#define OMAP1510_DMA_LCD_CTRL		(OMAP1510_DMA_LCD_BASE + 0x00)
+#define OMAP1510_DMA_LCD_TOP_F1_L	(OMAP1510_DMA_LCD_BASE + 0x02)
+#define OMAP1510_DMA_LCD_TOP_F1_U	(OMAP1510_DMA_LCD_BASE + 0x04)
+#define OMAP1510_DMA_LCD_BOT_F1_L	(OMAP1510_DMA_LCD_BASE + 0x06)
+#define OMAP1510_DMA_LCD_BOT_F1_U	(OMAP1510_DMA_LCD_BASE + 0x08)
+
+#define OMAP1610_DMA_LCD_BASE		(0xfffee300)
+#define OMAP1610_DMA_LCD_CSDP		(OMAP1610_DMA_LCD_BASE + 0xc0)
+#define OMAP1610_DMA_LCD_CCR		(OMAP1610_DMA_LCD_BASE + 0xc2)
+#define OMAP1610_DMA_LCD_CTRL		(OMAP1610_DMA_LCD_BASE + 0xc4)
+#define OMAP1610_DMA_LCD_TOP_B1_L	(OMAP1610_DMA_LCD_BASE + 0xc8)
+#define OMAP1610_DMA_LCD_TOP_B1_U	(OMAP1610_DMA_LCD_BASE + 0xca)
+#define OMAP1610_DMA_LCD_BOT_B1_L	(OMAP1610_DMA_LCD_BASE + 0xcc)
+#define OMAP1610_DMA_LCD_BOT_B1_U	(OMAP1610_DMA_LCD_BASE + 0xce)
+#define OMAP1610_DMA_LCD_TOP_B2_L	(OMAP1610_DMA_LCD_BASE + 0xd0)
+#define OMAP1610_DMA_LCD_TOP_B2_U	(OMAP1610_DMA_LCD_BASE + 0xd2)
+#define OMAP1610_DMA_LCD_BOT_B2_L	(OMAP1610_DMA_LCD_BASE + 0xd4)
+#define OMAP1610_DMA_LCD_BOT_B2_U	(OMAP1610_DMA_LCD_BASE + 0xd6)
+#define OMAP1610_DMA_LCD_SRC_EI_B1	(OMAP1610_DMA_LCD_BASE + 0xd8)
+#define OMAP1610_DMA_LCD_SRC_FI_B1_L	(OMAP1610_DMA_LCD_BASE + 0xda)
+#define OMAP1610_DMA_LCD_SRC_EN_B1	(OMAP1610_DMA_LCD_BASE + 0xe0)
+#define OMAP1610_DMA_LCD_SRC_FN_B1	(OMAP1610_DMA_LCD_BASE + 0xe4)
+#define OMAP1610_DMA_LCD_LCH_CTRL	(OMAP1610_DMA_LCD_BASE + 0xea)
+#define OMAP1610_DMA_LCD_SRC_FI_B1_U	(OMAP1610_DMA_LCD_BASE + 0xf4)
+
+/* LCD DMA block numbers */
+enum {
+	OMAP_LCD_DMA_B1_TOP,
+	OMAP_LCD_DMA_B1_BOTTOM,
+	OMAP_LCD_DMA_B2_TOP,
+	OMAP_LCD_DMA_B2_BOTTOM
+};
+
+/* LCD DMA functions */
+extern int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
+				void *data);
+extern void omap_free_lcd_dma(void);
+extern void omap_setup_lcd_dma(void);
+extern void omap_enable_lcd_dma(void);
+extern void omap_stop_lcd_dma(void);
+extern void omap_set_lcd_dma_ext_controller(int external);
+extern void omap_set_lcd_dma_single_transfer(int single);
+extern void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
+				int data_type);
+extern void omap_set_lcd_dma_b1_rotation(int rotate);
+extern void omap_set_lcd_dma_b1_vxres(unsigned long vxres);
+extern void omap_set_lcd_dma_b1_mirror(int mirror);
+extern void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale);
+
+extern int omap_lcd_dma_running(void);
+
+#endif /* __MACH_LCD_DMA_H__ */
diff -uprN git.orig/arch/arm/mach-omap1/lcd_dma.c git/arch/arm/mach-omap1/lcd_dma.c
--- git.orig/arch/arm/mach-omap1/lcd_dma.c	1970-01-01 01:00:00.000000000 +0100
+++ git/arch/arm/mach-omap1/lcd_dma.c	2009-11-21 14:36:59.000000000 +0100
@@ -0,0 +1,447 @@
+/*
+ * linux/arch/arm/mach-omap1/lcd_dma.c
+ *
+ * Extracted from arch/arm/plat-omap/dma.c
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
+ * Graphics DMA and LCD DMA graphics tranformations
+ * by Imre Deak <imre.deak@nokia.com>
+ * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
+ * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com>
+ * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Support functions for the OMAP internal DMA channels.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <plat/dma.h>
+
+int omap_lcd_dma_running(void)
+{
+	/*
+	 * On OMAP1510, internal LCD controller will start the transfer
+	 * when it gets enabled, so assume DMA running if LCD enabled.
+	 */
+	if (cpu_is_omap1510())
+		if (omap_readw(0xfffec000 + 0x00) & (1 << 0))
+			return 1;
+
+	/* Check if LCD DMA is running */
+	if (cpu_is_omap16xx())
+		if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
+			return 1;
+
+	return 0;
+}
+
+static struct lcd_dma_info {
+	spinlock_t lock;
+	int reserved;
+	void (*callback)(u16 status, void *data);
+	void *cb_data;
+
+	int active;
+	unsigned long addr, size;
+	int rotate, data_type, xres, yres;
+	int vxres;
+	int mirror;
+	int xscale, yscale;
+	int ext_ctrl;
+	int src_port;
+	int single_transfer;
+} lcd_dma;
+
+void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
+			 int data_type)
+{
+	lcd_dma.addr = addr;
+	lcd_dma.data_type = data_type;
+	lcd_dma.xres = fb_xres;
+	lcd_dma.yres = fb_yres;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1);
+
+void omap_set_lcd_dma_src_port(int port)
+{
+	lcd_dma.src_port = port;
+}
+
+void omap_set_lcd_dma_ext_controller(int external)
+{
+	lcd_dma.ext_ctrl = external;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
+
+void omap_set_lcd_dma_single_transfer(int single)
+{
+	lcd_dma.single_transfer = single;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
+
+void omap_set_lcd_dma_b1_rotation(int rotate)
+{
+	if (cpu_is_omap1510()) {
+		printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
+		BUG();
+		return;
+	}
+	lcd_dma.rotate = rotate;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
+
+void omap_set_lcd_dma_b1_mirror(int mirror)
+{
+	if (cpu_is_omap1510()) {
+		printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
+		BUG();
+	}
+	lcd_dma.mirror = mirror;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
+
+void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
+{
+	if (cpu_is_omap1510()) {
+		printk(KERN_ERR "DMA virtual resulotion is not supported "
+				"in 1510 mode\n");
+		BUG();
+	}
+	lcd_dma.vxres = vxres;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
+
+void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
+{
+	if (cpu_is_omap1510()) {
+		printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
+		BUG();
+	}
+	lcd_dma.xscale = xscale;
+	lcd_dma.yscale = yscale;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
+
+static void set_b1_regs(void)
+{
+	unsigned long top, bottom;
+	int es;
+	u16 w;
+	unsigned long en, fn;
+	long ei, fi;
+	unsigned long vxres;
+	unsigned int xscale, yscale;
+
+	switch (lcd_dma.data_type) {
+	case OMAP_DMA_DATA_TYPE_S8:
+		es = 1;
+		break;
+	case OMAP_DMA_DATA_TYPE_S16:
+		es = 2;
+		break;
+	case OMAP_DMA_DATA_TYPE_S32:
+		es = 4;
+		break;
+	default:
+		BUG();
+		return;
+	}
+
+	vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
+	xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
+	yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
+	BUG_ON(vxres < lcd_dma.xres);
+
+#define PIXADDR(x, y) (lcd_dma.addr +					\
+		((y) * vxres * yscale + (x) * xscale) * es)
+#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
+
+	switch (lcd_dma.rotate) {
+	case 0:
+		if (!lcd_dma.mirror) {
+			top = PIXADDR(0, 0);
+			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+			/* 1510 DMA requires the bottom address to be 2 more
+			 * than the actual last memory access location. */
+			if (cpu_is_omap1510() &&
+				lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
+					bottom += 2;
+			ei = PIXSTEP(0, 0, 1, 0);
+			fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
+		} else {
+			top = PIXADDR(lcd_dma.xres - 1, 0);
+			bottom = PIXADDR(0, lcd_dma.yres - 1);
+			ei = PIXSTEP(1, 0, 0, 0);
+			fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
+		}
+		en = lcd_dma.xres;
+		fn = lcd_dma.yres;
+		break;
+	case 90:
+		if (!lcd_dma.mirror) {
+			top = PIXADDR(0, lcd_dma.yres - 1);
+			bottom = PIXADDR(lcd_dma.xres - 1, 0);
+			ei = PIXSTEP(0, 1, 0, 0);
+			fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
+		} else {
+			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+			bottom = PIXADDR(0, 0);
+			ei = PIXSTEP(0, 1, 0, 0);
+			fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
+		}
+		en = lcd_dma.yres;
+		fn = lcd_dma.xres;
+		break;
+	case 180:
+		if (!lcd_dma.mirror) {
+			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+			bottom = PIXADDR(0, 0);
+			ei = PIXSTEP(1, 0, 0, 0);
+			fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
+		} else {
+			top = PIXADDR(0, lcd_dma.yres - 1);
+			bottom = PIXADDR(lcd_dma.xres - 1, 0);
+			ei = PIXSTEP(0, 0, 1, 0);
+			fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
+		}
+		en = lcd_dma.xres;
+		fn = lcd_dma.yres;
+		break;
+	case 270:
+		if (!lcd_dma.mirror) {
+			top = PIXADDR(lcd_dma.xres - 1, 0);
+			bottom = PIXADDR(0, lcd_dma.yres - 1);
+			ei = PIXSTEP(0, 0, 0, 1);
+			fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
+		} else {
+			top = PIXADDR(0, 0);
+			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+			ei = PIXSTEP(0, 0, 0, 1);
+			fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
+		}
+		en = lcd_dma.yres;
+		fn = lcd_dma.xres;
+		break;
+	default:
+		BUG();
+		return;	/* Suppress warning about uninitialized vars */
+	}
+
+	if (cpu_is_omap1510()) {
+		omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
+		omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
+		omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
+		omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L);
+
+		return;
+	}
+
+	/* 1610 regs */
+	omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U);
+	omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L);
+	omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U);
+	omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L);
+
+	omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1);
+	omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1);
+
+	w = omap_readw(OMAP1610_DMA_LCD_CSDP);
+	w &= ~0x03;
+	w |= lcd_dma.data_type;
+	omap_writew(w, OMAP1610_DMA_LCD_CSDP);
+
+	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+	/* Always set the source port as SDRAM for now*/
+	w &= ~(0x03 << 6);
+	if (lcd_dma.callback != NULL)
+		w |= 1 << 1;		/* Block interrupt enable */
+	else
+		w &= ~(1 << 1);
+	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+
+	if (!(lcd_dma.rotate || lcd_dma.mirror ||
+	      lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
+		return;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CCR);
+	/* Set the double-indexed addressing mode */
+	w |= (0x03 << 12);
+	omap_writew(w, OMAP1610_DMA_LCD_CCR);
+
+	omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
+	omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
+	omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
+}
+
+static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id)
+{
+	u16 w;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+	if (unlikely(!(w & (1 << 3)))) {
+		printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
+		return IRQ_NONE;
+	}
+	/* Ack the IRQ */
+	w |= (1 << 3);
+	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+	lcd_dma.active = 0;
+	if (lcd_dma.callback != NULL)
+		lcd_dma.callback(w, lcd_dma.cb_data);
+
+	return IRQ_HANDLED;
+}
+
+int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
+			 void *data)
+{
+	spin_lock_irq(&lcd_dma.lock);
+	if (lcd_dma.reserved) {
+		spin_unlock_irq(&lcd_dma.lock);
+		printk(KERN_ERR "LCD DMA channel already reserved\n");
+		BUG();
+		return -EBUSY;
+	}
+	lcd_dma.reserved = 1;
+	spin_unlock_irq(&lcd_dma.lock);
+	lcd_dma.callback = callback;
+	lcd_dma.cb_data = data;
+	lcd_dma.active = 0;
+	lcd_dma.single_transfer = 0;
+	lcd_dma.rotate = 0;
+	lcd_dma.vxres = 0;
+	lcd_dma.mirror = 0;
+	lcd_dma.xscale = 0;
+	lcd_dma.yscale = 0;
+	lcd_dma.ext_ctrl = 0;
+	lcd_dma.src_port = 0;
+
+	return 0;
+}
+EXPORT_SYMBOL(omap_request_lcd_dma);
+
+void omap_free_lcd_dma(void)
+{
+	spin_lock(&lcd_dma.lock);
+	if (!lcd_dma.reserved) {
+		spin_unlock(&lcd_dma.lock);
+		printk(KERN_ERR "LCD DMA is not reserved\n");
+		BUG();
+		return;
+	}
+	if (!cpu_is_omap1510())
+		omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1,
+			    OMAP1610_DMA_LCD_CCR);
+	lcd_dma.reserved = 0;
+	spin_unlock(&lcd_dma.lock);
+}
+EXPORT_SYMBOL(omap_free_lcd_dma);
+
+void omap_enable_lcd_dma(void)
+{
+	u16 w;
+
+	/*
+	 * Set the Enable bit only if an external controller is
+	 * connected. Otherwise the OMAP internal controller will
+	 * start the transfer when it gets enabled.
+	 */
+	if (cpu_is_omap1510() || !lcd_dma.ext_ctrl)
+		return;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+	w |= 1 << 8;
+	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+
+	lcd_dma.active = 1;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CCR);
+	w |= 1 << 7;
+	omap_writew(w, OMAP1610_DMA_LCD_CCR);
+}
+EXPORT_SYMBOL(omap_enable_lcd_dma);
+
+void omap_setup_lcd_dma(void)
+{
+	BUG_ON(lcd_dma.active);
+	if (!cpu_is_omap1510()) {
+		/* Set some reasonable defaults */
+		omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
+		omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
+		omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
+	}
+	set_b1_regs();
+	if (!cpu_is_omap1510()) {
+		u16 w;
+
+		w = omap_readw(OMAP1610_DMA_LCD_CCR);
+		/*
+		 * If DMA was already active set the end_prog bit to have
+		 * the programmed register set loaded into the active
+		 * register set.
+		 */
+		w |= 1 << 11;		/* End_prog */
+		if (!lcd_dma.single_transfer)
+			w |= (3 << 8);	/* Auto_init, repeat */
+		omap_writew(w, OMAP1610_DMA_LCD_CCR);
+	}
+}
+EXPORT_SYMBOL(omap_setup_lcd_dma);
+
+void omap_stop_lcd_dma(void)
+{
+	u16 w;
+
+	lcd_dma.active = 0;
+	if (cpu_is_omap1510() || !lcd_dma.ext_ctrl)
+		return;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CCR);
+	w &= ~(1 << 7);
+	omap_writew(w, OMAP1610_DMA_LCD_CCR);
+
+	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+	w &= ~(1 << 8);
+	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+}
+EXPORT_SYMBOL(omap_stop_lcd_dma);
+
+static int __init omap_init_lcd_dma(void)
+{
+	int r;
+
+	if (cpu_is_omap16xx()) {
+		u16 w;
+
+		/* this would prevent OMAP sleep */
+		w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+		w &= ~(1 << 8);
+		omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+	}
+
+	spin_lock_init(&lcd_dma.lock);
+
+	r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0,
+			"LCD DMA", NULL);
+	if (r != 0)
+		printk(KERN_ERR "unable to request IRQ for LCD DMA "
+			       "(error %d)\n", r);
+
+	return r;
+}
+
+arch_initcall(omap_init_lcd_dma);
+
diff -uprN git.orig/arch/arm/plat-omap/dma.c git/arch/arm/plat-omap/dma.c
--- git.orig/arch/arm/plat-omap/dma.c	2009-11-21 00:38:46.000000000 +0100
+++ git/arch/arm/plat-omap/dma.c	2009-11-21 03:34:23.000000000 +0100
@@ -47,7 +47,6 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTS
 #endif
 
 #define OMAP_DMA_ACTIVE			0x01
-#define OMAP_DMA_CCR_EN			(1 << 7)
 #define OMAP2_DMA_CSR_CLEAR_MASK	0xffe
 
 #define OMAP_FUNC_MUX_ARM_BASE		(0xfffe1000 + 0xec)
@@ -1120,17 +1119,8 @@ int omap_dma_running(void)
 {
 	int lch;
 
-	/*
-	 * On OMAP1510, internal LCD controller will start the transfer
-	 * when it gets enabled, so assume DMA running if LCD enabled.
-	 */
-	if (cpu_is_omap1510())
-		if (omap_readw(0xfffec000 + 0x00) & (1 << 0))
-			return 1;
-
-	/* Check if LCD DMA is running */
-	if (cpu_is_omap16xx())
-		if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
+	if (cpu_class_is_omap1())
+		if (omap_lcd_dma_running())
 			return 1;
 
 	for (lch = 0; lch < dma_chan_count; lch++)
@@ -1990,377 +1980,6 @@ static struct irqaction omap24xx_dma_irq
 
 /*----------------------------------------------------------------------------*/
 
-static struct lcd_dma_info {
-	spinlock_t lock;
-	int reserved;
-	void (*callback)(u16 status, void *data);
-	void *cb_data;
-
-	int active;
-	unsigned long addr, size;
-	int rotate, data_type, xres, yres;
-	int vxres;
-	int mirror;
-	int xscale, yscale;
-	int ext_ctrl;
-	int src_port;
-	int single_transfer;
-} lcd_dma;
-
-void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
-			 int data_type)
-{
-	lcd_dma.addr = addr;
-	lcd_dma.data_type = data_type;
-	lcd_dma.xres = fb_xres;
-	lcd_dma.yres = fb_yres;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_b1);
-
-void omap_set_lcd_dma_src_port(int port)
-{
-	lcd_dma.src_port = port;
-}
-
-void omap_set_lcd_dma_ext_controller(int external)
-{
-	lcd_dma.ext_ctrl = external;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
-
-void omap_set_lcd_dma_single_transfer(int single)
-{
-	lcd_dma.single_transfer = single;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
-
-void omap_set_lcd_dma_b1_rotation(int rotate)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
-		BUG();
-		return;
-	}
-	lcd_dma.rotate = rotate;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
-
-void omap_set_lcd_dma_b1_mirror(int mirror)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
-		BUG();
-	}
-	lcd_dma.mirror = mirror;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
-
-void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA virtual resulotion is not supported "
-				"in 1510 mode\n");
-		BUG();
-	}
-	lcd_dma.vxres = vxres;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
-
-void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
-		BUG();
-	}
-	lcd_dma.xscale = xscale;
-	lcd_dma.yscale = yscale;
-}
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
-
-static void set_b1_regs(void)
-{
-	unsigned long top, bottom;
-	int es;
-	u16 w;
-	unsigned long en, fn;
-	long ei, fi;
-	unsigned long vxres;
-	unsigned int xscale, yscale;
-
-	switch (lcd_dma.data_type) {
-	case OMAP_DMA_DATA_TYPE_S8:
-		es = 1;
-		break;
-	case OMAP_DMA_DATA_TYPE_S16:
-		es = 2;
-		break;
-	case OMAP_DMA_DATA_TYPE_S32:
-		es = 4;
-		break;
-	default:
-		BUG();
-		return;
-	}
-
-	vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
-	xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
-	yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
-	BUG_ON(vxres < lcd_dma.xres);
-
-#define PIXADDR(x, y) (lcd_dma.addr +					\
-		((y) * vxres * yscale + (x) * xscale) * es)
-#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
-
-	switch (lcd_dma.rotate) {
-	case 0:
-		if (!lcd_dma.mirror) {
-			top = PIXADDR(0, 0);
-			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
-			/* 1510 DMA requires the bottom address to be 2 more
-			 * than the actual last memory access location. */
-			if (omap_dma_in_1510_mode() &&
-				lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
-					bottom += 2;
-			ei = PIXSTEP(0, 0, 1, 0);
-			fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
-		} else {
-			top = PIXADDR(lcd_dma.xres - 1, 0);
-			bottom = PIXADDR(0, lcd_dma.yres - 1);
-			ei = PIXSTEP(1, 0, 0, 0);
-			fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
-		}
-		en = lcd_dma.xres;
-		fn = lcd_dma.yres;
-		break;
-	case 90:
-		if (!lcd_dma.mirror) {
-			top = PIXADDR(0, lcd_dma.yres - 1);
-			bottom = PIXADDR(lcd_dma.xres - 1, 0);
-			ei = PIXSTEP(0, 1, 0, 0);
-			fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
-		} else {
-			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
-			bottom = PIXADDR(0, 0);
-			ei = PIXSTEP(0, 1, 0, 0);
-			fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
-		}
-		en = lcd_dma.yres;
-		fn = lcd_dma.xres;
-		break;
-	case 180:
-		if (!lcd_dma.mirror) {
-			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
-			bottom = PIXADDR(0, 0);
-			ei = PIXSTEP(1, 0, 0, 0);
-			fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
-		} else {
-			top = PIXADDR(0, lcd_dma.yres - 1);
-			bottom = PIXADDR(lcd_dma.xres - 1, 0);
-			ei = PIXSTEP(0, 0, 1, 0);
-			fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
-		}
-		en = lcd_dma.xres;
-		fn = lcd_dma.yres;
-		break;
-	case 270:
-		if (!lcd_dma.mirror) {
-			top = PIXADDR(lcd_dma.xres - 1, 0);
-			bottom = PIXADDR(0, lcd_dma.yres - 1);
-			ei = PIXSTEP(0, 0, 0, 1);
-			fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
-		} else {
-			top = PIXADDR(0, 0);
-			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
-			ei = PIXSTEP(0, 0, 0, 1);
-			fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
-		}
-		en = lcd_dma.yres;
-		fn = lcd_dma.xres;
-		break;
-	default:
-		BUG();
-		return;	/* Suppress warning about uninitialized vars */
-	}
-
-	if (omap_dma_in_1510_mode()) {
-		omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
-		omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
-		omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
-		omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L);
-
-		return;
-	}
-
-	/* 1610 regs */
-	omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U);
-	omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L);
-	omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U);
-	omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L);
-
-	omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1);
-	omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1);
-
-	w = omap_readw(OMAP1610_DMA_LCD_CSDP);
-	w &= ~0x03;
-	w |= lcd_dma.data_type;
-	omap_writew(w, OMAP1610_DMA_LCD_CSDP);
-
-	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
-	/* Always set the source port as SDRAM for now*/
-	w &= ~(0x03 << 6);
-	if (lcd_dma.callback != NULL)
-		w |= 1 << 1;		/* Block interrupt enable */
-	else
-		w &= ~(1 << 1);
-	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
-
-	if (!(lcd_dma.rotate || lcd_dma.mirror ||
-	      lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
-		return;
-
-	w = omap_readw(OMAP1610_DMA_LCD_CCR);
-	/* Set the double-indexed addressing mode */
-	w |= (0x03 << 12);
-	omap_writew(w, OMAP1610_DMA_LCD_CCR);
-
-	omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
-	omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
-	omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
-}
-
-static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id)
-{
-	u16 w;
-
-	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
-	if (unlikely(!(w & (1 << 3)))) {
-		printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
-		return IRQ_NONE;
-	}
-	/* Ack the IRQ */
-	w |= (1 << 3);
-	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
-	lcd_dma.active = 0;
-	if (lcd_dma.callback != NULL)
-		lcd_dma.callback(w, lcd_dma.cb_data);
-
-	return IRQ_HANDLED;
-}
-
-int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
-			 void *data)
-{
-	spin_lock_irq(&lcd_dma.lock);
-	if (lcd_dma.reserved) {
-		spin_unlock_irq(&lcd_dma.lock);
-		printk(KERN_ERR "LCD DMA channel already reserved\n");
-		BUG();
-		return -EBUSY;
-	}
-	lcd_dma.reserved = 1;
-	spin_unlock_irq(&lcd_dma.lock);
-	lcd_dma.callback = callback;
-	lcd_dma.cb_data = data;
-	lcd_dma.active = 0;
-	lcd_dma.single_transfer = 0;
-	lcd_dma.rotate = 0;
-	lcd_dma.vxres = 0;
-	lcd_dma.mirror = 0;
-	lcd_dma.xscale = 0;
-	lcd_dma.yscale = 0;
-	lcd_dma.ext_ctrl = 0;
-	lcd_dma.src_port = 0;
-
-	return 0;
-}
-EXPORT_SYMBOL(omap_request_lcd_dma);
-
-void omap_free_lcd_dma(void)
-{
-	spin_lock(&lcd_dma.lock);
-	if (!lcd_dma.reserved) {
-		spin_unlock(&lcd_dma.lock);
-		printk(KERN_ERR "LCD DMA is not reserved\n");
-		BUG();
-		return;
-	}
-	if (!enable_1510_mode)
-		omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1,
-			    OMAP1610_DMA_LCD_CCR);
-	lcd_dma.reserved = 0;
-	spin_unlock(&lcd_dma.lock);
-}
-EXPORT_SYMBOL(omap_free_lcd_dma);
-
-void omap_enable_lcd_dma(void)
-{
-	u16 w;
-
-	/*
-	 * Set the Enable bit only if an external controller is
-	 * connected. Otherwise the OMAP internal controller will
-	 * start the transfer when it gets enabled.
-	 */
-	if (enable_1510_mode || !lcd_dma.ext_ctrl)
-		return;
-
-	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
-	w |= 1 << 8;
-	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
-
-	lcd_dma.active = 1;
-
-	w = omap_readw(OMAP1610_DMA_LCD_CCR);
-	w |= 1 << 7;
-	omap_writew(w, OMAP1610_DMA_LCD_CCR);
-}
-EXPORT_SYMBOL(omap_enable_lcd_dma);
-
-void omap_setup_lcd_dma(void)
-{
-	BUG_ON(lcd_dma.active);
-	if (!enable_1510_mode) {
-		/* Set some reasonable defaults */
-		omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
-		omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
-		omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
-	}
-	set_b1_regs();
-	if (!enable_1510_mode) {
-		u16 w;
-
-		w = omap_readw(OMAP1610_DMA_LCD_CCR);
-		/*
-		 * If DMA was already active set the end_prog bit to have
-		 * the programmed register set loaded into the active
-		 * register set.
-		 */
-		w |= 1 << 11;		/* End_prog */
-		if (!lcd_dma.single_transfer)
-			w |= (3 << 8);	/* Auto_init, repeat */
-		omap_writew(w, OMAP1610_DMA_LCD_CCR);
-	}
-}
-EXPORT_SYMBOL(omap_setup_lcd_dma);
-
-void omap_stop_lcd_dma(void)
-{
-	u16 w;
-
-	lcd_dma.active = 0;
-	if (enable_1510_mode || !lcd_dma.ext_ctrl)
-		return;
-
-	w = omap_readw(OMAP1610_DMA_LCD_CCR);
-	w &= ~(1 << 7);
-	omap_writew(w, OMAP1610_DMA_LCD_CCR);
-
-	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
-	w &= ~(1 << 8);
-	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
-}
-EXPORT_SYMBOL(omap_stop_lcd_dma);
-
 void omap_dma_global_context_save(void)
 {
 	omap_dma_global_context.dma_irqenable_l0 =
@@ -2465,14 +2084,6 @@ static int __init omap_init_dma(void)
 			dma_chan_count = 16;
 		} else
 			dma_chan_count = 9;
-		if (cpu_is_omap16xx()) {
-			u16 w;
-
-			/* this would prevent OMAP sleep */
-			w = omap_readw(OMAP1610_DMA_LCD_CTRL);
-			w &= ~(1 << 8);
-			omap_writew(w, OMAP1610_DMA_LCD_CTRL);
-		}
 	} else if (cpu_class_is_omap2()) {
 		u8 revision = dma_read(REVISION) & 0xff;
 		printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
@@ -2483,7 +2094,6 @@ static int __init omap_init_dma(void)
 		return 0;
 	}
 
-	spin_lock_init(&lcd_dma.lock);
 	spin_lock_init(&dma_chan_lock);
 
 	for (ch = 0; ch < dma_chan_count; ch++) {
@@ -2548,22 +2158,6 @@ static int __init omap_init_dma(void)
 		}
 	}
 
-
-	/* FIXME: Update LCD DMA to work on 24xx */
-	if (cpu_class_is_omap1()) {
-		r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0,
-				"LCD DMA", NULL);
-		if (r != 0) {
-			int i;
-
-			printk(KERN_ERR "unable to request IRQ for LCD DMA "
-			       "(error %d)\n", r);
-			for (i = 0; i < dma_chan_count; i++)
-				free_irq(omap1_dma_irq[i], (void *) (i + 1));
-			goto out_free;
-		}
-	}
-
 	return 0;
 
 out_free:
diff -uprN git.orig/arch/arm/plat-omap/include/plat/dma.h git/arch/arm/plat-omap/include/plat/dma.h
--- git.orig/arch/arm/plat-omap/include/plat/dma.h	2009-11-21 00:38:46.000000000 +0100
+++ git/arch/arm/plat-omap/include/plat/dma.h	2009-11-21 03:40:19.000000000 +0100
@@ -401,33 +401,6 @@
 
 /*----------------------------------------------------------------------------*/
 
-/* Hardware registers for LCD DMA */
-#define OMAP1510_DMA_LCD_BASE		(0xfffedb00)
-#define OMAP1510_DMA_LCD_CTRL		(OMAP1510_DMA_LCD_BASE + 0x00)
-#define OMAP1510_DMA_LCD_TOP_F1_L	(OMAP1510_DMA_LCD_BASE + 0x02)
-#define OMAP1510_DMA_LCD_TOP_F1_U	(OMAP1510_DMA_LCD_BASE + 0x04)
-#define OMAP1510_DMA_LCD_BOT_F1_L	(OMAP1510_DMA_LCD_BASE + 0x06)
-#define OMAP1510_DMA_LCD_BOT_F1_U	(OMAP1510_DMA_LCD_BASE + 0x08)
-
-#define OMAP1610_DMA_LCD_BASE		(0xfffee300)
-#define OMAP1610_DMA_LCD_CSDP		(OMAP1610_DMA_LCD_BASE + 0xc0)
-#define OMAP1610_DMA_LCD_CCR		(OMAP1610_DMA_LCD_BASE + 0xc2)
-#define OMAP1610_DMA_LCD_CTRL		(OMAP1610_DMA_LCD_BASE + 0xc4)
-#define OMAP1610_DMA_LCD_TOP_B1_L	(OMAP1610_DMA_LCD_BASE + 0xc8)
-#define OMAP1610_DMA_LCD_TOP_B1_U	(OMAP1610_DMA_LCD_BASE + 0xca)
-#define OMAP1610_DMA_LCD_BOT_B1_L	(OMAP1610_DMA_LCD_BASE + 0xcc)
-#define OMAP1610_DMA_LCD_BOT_B1_U	(OMAP1610_DMA_LCD_BASE + 0xce)
-#define OMAP1610_DMA_LCD_TOP_B2_L	(OMAP1610_DMA_LCD_BASE + 0xd0)
-#define OMAP1610_DMA_LCD_TOP_B2_U	(OMAP1610_DMA_LCD_BASE + 0xd2)
-#define OMAP1610_DMA_LCD_BOT_B2_L	(OMAP1610_DMA_LCD_BASE + 0xd4)
-#define OMAP1610_DMA_LCD_BOT_B2_U	(OMAP1610_DMA_LCD_BASE + 0xd6)
-#define OMAP1610_DMA_LCD_SRC_EI_B1	(OMAP1610_DMA_LCD_BASE + 0xd8)
-#define OMAP1610_DMA_LCD_SRC_FI_B1_L	(OMAP1610_DMA_LCD_BASE + 0xda)
-#define OMAP1610_DMA_LCD_SRC_EN_B1	(OMAP1610_DMA_LCD_BASE + 0xe0)
-#define OMAP1610_DMA_LCD_SRC_FN_B1	(OMAP1610_DMA_LCD_BASE + 0xe4)
-#define OMAP1610_DMA_LCD_LCH_CTRL	(OMAP1610_DMA_LCD_BASE + 0xea)
-#define OMAP1610_DMA_LCD_SRC_FI_B1_U	(OMAP1610_DMA_LCD_BASE + 0xf4)
-
 #define OMAP1_DMA_TOUT_IRQ		(1 << 0)
 #define OMAP_DMA_DROP_IRQ		(1 << 1)
 #define OMAP_DMA_HALF_IRQ		(1 << 2)
@@ -441,6 +414,8 @@
 #define OMAP2_DMA_SUPERVISOR_ERR_IRQ	(1 << 10)
 #define OMAP2_DMA_MISALIGNED_ERR_IRQ	(1 << 11)
 
+#define OMAP_DMA_CCR_EN			(1 << 7)
+
 #define OMAP_DMA_DATA_TYPE_S8		0x00
 #define OMAP_DMA_DATA_TYPE_S16		0x01
 #define OMAP_DMA_DATA_TYPE_S32		0x02
@@ -503,14 +478,6 @@
 #define DMA_CH_PRIO_HIGH		0x1
 #define DMA_CH_PRIO_LOW			0x0 /* Def */
 
-/* LCD DMA block numbers */
-enum {
-	OMAP_LCD_DMA_B1_TOP,
-	OMAP_LCD_DMA_B1_BOTTOM,
-	OMAP_LCD_DMA_B2_TOP,
-	OMAP_LCD_DMA_B2_BOTTOM
-};
-
 enum omap_dma_burst_mode {
 	OMAP_DMA_DATA_BURST_DIS = 0,
 	OMAP_DMA_DATA_BURST_4,
@@ -661,20 +628,13 @@ extern int omap_modify_dma_chain_params(
 extern int omap_dma_chain_status(int chain_id);
 #endif
 
-/* LCD DMA functions */
-extern int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
-				void *data);
-extern void omap_free_lcd_dma(void);
-extern void omap_setup_lcd_dma(void);
-extern void omap_enable_lcd_dma(void);
-extern void omap_stop_lcd_dma(void);
-extern void omap_set_lcd_dma_ext_controller(int external);
-extern void omap_set_lcd_dma_single_transfer(int single);
-extern void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
-				int data_type);
-extern void omap_set_lcd_dma_b1_rotation(int rotate);
-extern void omap_set_lcd_dma_b1_vxres(unsigned long vxres);
-extern void omap_set_lcd_dma_b1_mirror(int mirror);
-extern void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale);
+#ifdef CONFIG_ARCH_OMAP1
+#include <mach/lcd_dma.h>
+#else
+static inline int omap_lcd_dma_running(void)
+{
+	return 0;
+}
+#endif
 
 #endif /* __ASM_ARCH_DMA_H */
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] [PATCH] OMAP: DMA: move LCD DMA related code from plat-omap to mach-omap1 (Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set)
  2009-11-21 15:58     ` [RFC] [PATCH] OMAP: DMA: move LCD DMA related code from plat-omap to mach-omap1 (Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set) Janusz Krzysztofik
@ 2009-11-25  9:02       ` Paul Walmsley
  2009-11-25 13:54         ` Janusz Krzysztofik
  0 siblings, 1 reply; 17+ messages in thread
From: Paul Walmsley @ 2009-11-25  9:02 UTC (permalink / raw)
  To: Janusz Krzysztofik; +Cc: Tony Lindgren, linux-omap@vger.kernel.org

[-- Attachment #1: Type: TEXT/PLAIN, Size: 35993 bytes --]

Hello Janusz,

On Sat, 21 Nov 2009, Janusz Krzysztofik wrote:

> (probably less interested persons and lists dropped)
> 
> Tuesday 10 November 2009 11:50:52 Paul Walmsley wrote:
> > ...  All of the LCD DMA code in plat-omap/dma.c appears to be
> > OMAP1-only (and apparently only is available on a subset of OMAP1 chips).
> > It would be great if this code could be moved to mach-omap1/lcd_dma.c or
> > a similar place.
> 
> The patch just tries to implement this idea.
> 
> Created against linux-omap for-next,
> commit 2963c21fab52bfa8227da7f22864db393ebbc858
> 
> Tested on OMAP1510 Amstrad Delta.
> Compile tested using omap_generic_2420_defconfig.
> 
> Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
> 
> ---
> Hi Paul,
> 
> I hope the patch meets your suggestion closely enough.

Thanks, just scanned it quickly and it looks carefully done.  Two 
suggestions below, both minor:

> Thanks,
> Janusz
> 
> diff -uprN git.orig/arch/arm/mach-omap1/Makefile git/arch/arm/mach-omap1/Makefile
> --- git.orig/arch/arm/mach-omap1/Makefile	2009-11-21 00:38:45.000000000 +0100
> +++ git/arch/arm/mach-omap1/Makefile	2009-11-21 01:27:12.000000000 +0100
> @@ -3,7 +3,7 @@
>  #
>  
>  # Common support
> -obj-y := io.o id.o sram.o clock.o irq.o mux.o serial.o devices.o
> +obj-y := io.o id.o sram.o clock.o irq.o lcd_dma.o mux.o serial.o devices.o

It seems that this LCD DMA controller is not present on OMAPs prior to the 
1510, given all the references in the LCD DMA code to 1510 and 1610, etc.  
It might be good to add a Kconfig option so OMAP730/850 users can skip 
compiling it and save some memory.  The drivers that use these routines 
can then include Kconfig dependencies on that option so it is 
automatically included when those drivers are built.

>  obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
>  
> diff -uprN git.orig/arch/arm/mach-omap1/include/mach/lcd_dma.h git/arch/arm/mach-omap1/include/mach/lcd_dma.h
> --- git.orig/arch/arm/mach-omap1/include/mach/lcd_dma.h	1970-01-01 01:00:00.000000000 +0100
> +++ git/arch/arm/mach-omap1/include/mach/lcd_dma.h	2009-11-21 03:22:25.000000000 +0100
> @@ -0,0 +1,78 @@
> +/*
> + *  arch/arm/mach-omap1/include/mach/lcd_dma.h
> + *
> + * Extracted from arch/arm/plat-omap/include/plat/dma.h
> + *  Copyright (C) 2003 Nokia Corporation
> + *  Author: Juha Yrjölä <juha.yrjola@nokia.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + */
> +#ifndef __MACH_LCD_DMA_H__

Consider adding _OMAP1_ in this macro name.  I doubt that name collisions 
here will be a serious issue, but adding a few extra bytes here might 
avoid some bug-hunting frustration in the long run...

> +#define __MACH_LCD_DMA_H__
> +
> +/* Hardware registers for LCD DMA */
> +#define OMAP1510_DMA_LCD_BASE		(0xfffedb00)
> +#define OMAP1510_DMA_LCD_CTRL		(OMAP1510_DMA_LCD_BASE + 0x00)
> +#define OMAP1510_DMA_LCD_TOP_F1_L	(OMAP1510_DMA_LCD_BASE + 0x02)
> +#define OMAP1510_DMA_LCD_TOP_F1_U	(OMAP1510_DMA_LCD_BASE + 0x04)
> +#define OMAP1510_DMA_LCD_BOT_F1_L	(OMAP1510_DMA_LCD_BASE + 0x06)
> +#define OMAP1510_DMA_LCD_BOT_F1_U	(OMAP1510_DMA_LCD_BASE + 0x08)
> +
> +#define OMAP1610_DMA_LCD_BASE		(0xfffee300)
> +#define OMAP1610_DMA_LCD_CSDP		(OMAP1610_DMA_LCD_BASE + 0xc0)
> +#define OMAP1610_DMA_LCD_CCR		(OMAP1610_DMA_LCD_BASE + 0xc2)
> +#define OMAP1610_DMA_LCD_CTRL		(OMAP1610_DMA_LCD_BASE + 0xc4)
> +#define OMAP1610_DMA_LCD_TOP_B1_L	(OMAP1610_DMA_LCD_BASE + 0xc8)
> +#define OMAP1610_DMA_LCD_TOP_B1_U	(OMAP1610_DMA_LCD_BASE + 0xca)
> +#define OMAP1610_DMA_LCD_BOT_B1_L	(OMAP1610_DMA_LCD_BASE + 0xcc)
> +#define OMAP1610_DMA_LCD_BOT_B1_U	(OMAP1610_DMA_LCD_BASE + 0xce)
> +#define OMAP1610_DMA_LCD_TOP_B2_L	(OMAP1610_DMA_LCD_BASE + 0xd0)
> +#define OMAP1610_DMA_LCD_TOP_B2_U	(OMAP1610_DMA_LCD_BASE + 0xd2)
> +#define OMAP1610_DMA_LCD_BOT_B2_L	(OMAP1610_DMA_LCD_BASE + 0xd4)
> +#define OMAP1610_DMA_LCD_BOT_B2_U	(OMAP1610_DMA_LCD_BASE + 0xd6)
> +#define OMAP1610_DMA_LCD_SRC_EI_B1	(OMAP1610_DMA_LCD_BASE + 0xd8)
> +#define OMAP1610_DMA_LCD_SRC_FI_B1_L	(OMAP1610_DMA_LCD_BASE + 0xda)
> +#define OMAP1610_DMA_LCD_SRC_EN_B1	(OMAP1610_DMA_LCD_BASE + 0xe0)
> +#define OMAP1610_DMA_LCD_SRC_FN_B1	(OMAP1610_DMA_LCD_BASE + 0xe4)
> +#define OMAP1610_DMA_LCD_LCH_CTRL	(OMAP1610_DMA_LCD_BASE + 0xea)
> +#define OMAP1610_DMA_LCD_SRC_FI_B1_U	(OMAP1610_DMA_LCD_BASE + 0xf4)
> +
> +/* LCD DMA block numbers */
> +enum {
> +	OMAP_LCD_DMA_B1_TOP,
> +	OMAP_LCD_DMA_B1_BOTTOM,
> +	OMAP_LCD_DMA_B2_TOP,
> +	OMAP_LCD_DMA_B2_BOTTOM
> +};
> +
> +/* LCD DMA functions */
> +extern int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
> +				void *data);
> +extern void omap_free_lcd_dma(void);
> +extern void omap_setup_lcd_dma(void);
> +extern void omap_enable_lcd_dma(void);
> +extern void omap_stop_lcd_dma(void);
> +extern void omap_set_lcd_dma_ext_controller(int external);
> +extern void omap_set_lcd_dma_single_transfer(int single);
> +extern void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
> +				int data_type);
> +extern void omap_set_lcd_dma_b1_rotation(int rotate);
> +extern void omap_set_lcd_dma_b1_vxres(unsigned long vxres);
> +extern void omap_set_lcd_dma_b1_mirror(int mirror);
> +extern void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale);
> +
> +extern int omap_lcd_dma_running(void);
> +
> +#endif /* __MACH_LCD_DMA_H__ */
> diff -uprN git.orig/arch/arm/mach-omap1/lcd_dma.c git/arch/arm/mach-omap1/lcd_dma.c
> --- git.orig/arch/arm/mach-omap1/lcd_dma.c	1970-01-01 01:00:00.000000000 +0100
> +++ git/arch/arm/mach-omap1/lcd_dma.c	2009-11-21 14:36:59.000000000 +0100
> @@ -0,0 +1,447 @@
> +/*
> + * linux/arch/arm/mach-omap1/lcd_dma.c
> + *
> + * Extracted from arch/arm/plat-omap/dma.c
> + * Copyright (C) 2003 - 2008 Nokia Corporation
> + * Author: Juha Yrjölä <juha.yrjola@nokia.com>
> + * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
> + * Graphics DMA and LCD DMA graphics tranformations
> + * by Imre Deak <imre.deak@nokia.com>
> + * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
> + * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com>
> + * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
> + *
> + * Copyright (C) 2009 Texas Instruments
> + * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
> + *
> + * Support functions for the OMAP internal DMA channels.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/spinlock.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +
> +#include <mach/hardware.h>
> +#include <plat/dma.h>
> +
> +int omap_lcd_dma_running(void)
> +{
> +	/*
> +	 * On OMAP1510, internal LCD controller will start the transfer
> +	 * when it gets enabled, so assume DMA running if LCD enabled.
> +	 */
> +	if (cpu_is_omap1510())
> +		if (omap_readw(0xfffec000 + 0x00) & (1 << 0))
> +			return 1;
> +
> +	/* Check if LCD DMA is running */
> +	if (cpu_is_omap16xx())
> +		if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
> +			return 1;
> +
> +	return 0;
> +}
> +
> +static struct lcd_dma_info {
> +	spinlock_t lock;
> +	int reserved;
> +	void (*callback)(u16 status, void *data);
> +	void *cb_data;
> +
> +	int active;
> +	unsigned long addr, size;
> +	int rotate, data_type, xres, yres;
> +	int vxres;
> +	int mirror;
> +	int xscale, yscale;
> +	int ext_ctrl;
> +	int src_port;
> +	int single_transfer;
> +} lcd_dma;
> +
> +void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
> +			 int data_type)
> +{
> +	lcd_dma.addr = addr;
> +	lcd_dma.data_type = data_type;
> +	lcd_dma.xres = fb_xres;
> +	lcd_dma.yres = fb_yres;
> +}
> +EXPORT_SYMBOL(omap_set_lcd_dma_b1);
> +
> +void omap_set_lcd_dma_src_port(int port)
> +{
> +	lcd_dma.src_port = port;
> +}
> +
> +void omap_set_lcd_dma_ext_controller(int external)
> +{
> +	lcd_dma.ext_ctrl = external;
> +}
> +EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
> +
> +void omap_set_lcd_dma_single_transfer(int single)
> +{
> +	lcd_dma.single_transfer = single;
> +}
> +EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
> +
> +void omap_set_lcd_dma_b1_rotation(int rotate)
> +{
> +	if (cpu_is_omap1510()) {
> +		printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
> +		BUG();
> +		return;
> +	}
> +	lcd_dma.rotate = rotate;
> +}
> +EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
> +
> +void omap_set_lcd_dma_b1_mirror(int mirror)
> +{
> +	if (cpu_is_omap1510()) {
> +		printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
> +		BUG();
> +	}
> +	lcd_dma.mirror = mirror;
> +}
> +EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
> +
> +void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
> +{
> +	if (cpu_is_omap1510()) {
> +		printk(KERN_ERR "DMA virtual resulotion is not supported "
> +				"in 1510 mode\n");
> +		BUG();
> +	}
> +	lcd_dma.vxres = vxres;
> +}
> +EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
> +
> +void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
> +{
> +	if (cpu_is_omap1510()) {
> +		printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
> +		BUG();
> +	}
> +	lcd_dma.xscale = xscale;
> +	lcd_dma.yscale = yscale;
> +}
> +EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
> +
> +static void set_b1_regs(void)
> +{
> +	unsigned long top, bottom;
> +	int es;
> +	u16 w;
> +	unsigned long en, fn;
> +	long ei, fi;
> +	unsigned long vxres;
> +	unsigned int xscale, yscale;
> +
> +	switch (lcd_dma.data_type) {
> +	case OMAP_DMA_DATA_TYPE_S8:
> +		es = 1;
> +		break;
> +	case OMAP_DMA_DATA_TYPE_S16:
> +		es = 2;
> +		break;
> +	case OMAP_DMA_DATA_TYPE_S32:
> +		es = 4;
> +		break;
> +	default:
> +		BUG();
> +		return;
> +	}
> +
> +	vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
> +	xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
> +	yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
> +	BUG_ON(vxres < lcd_dma.xres);
> +
> +#define PIXADDR(x, y) (lcd_dma.addr +					\
> +		((y) * vxres * yscale + (x) * xscale) * es)
> +#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
> +
> +	switch (lcd_dma.rotate) {
> +	case 0:
> +		if (!lcd_dma.mirror) {
> +			top = PIXADDR(0, 0);
> +			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
> +			/* 1510 DMA requires the bottom address to be 2 more
> +			 * than the actual last memory access location. */
> +			if (cpu_is_omap1510() &&
> +				lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
> +					bottom += 2;
> +			ei = PIXSTEP(0, 0, 1, 0);
> +			fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
> +		} else {
> +			top = PIXADDR(lcd_dma.xres - 1, 0);
> +			bottom = PIXADDR(0, lcd_dma.yres - 1);
> +			ei = PIXSTEP(1, 0, 0, 0);
> +			fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
> +		}
> +		en = lcd_dma.xres;
> +		fn = lcd_dma.yres;
> +		break;
> +	case 90:
> +		if (!lcd_dma.mirror) {
> +			top = PIXADDR(0, lcd_dma.yres - 1);
> +			bottom = PIXADDR(lcd_dma.xres - 1, 0);
> +			ei = PIXSTEP(0, 1, 0, 0);
> +			fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
> +		} else {
> +			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
> +			bottom = PIXADDR(0, 0);
> +			ei = PIXSTEP(0, 1, 0, 0);
> +			fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
> +		}
> +		en = lcd_dma.yres;
> +		fn = lcd_dma.xres;
> +		break;
> +	case 180:
> +		if (!lcd_dma.mirror) {
> +			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
> +			bottom = PIXADDR(0, 0);
> +			ei = PIXSTEP(1, 0, 0, 0);
> +			fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
> +		} else {
> +			top = PIXADDR(0, lcd_dma.yres - 1);
> +			bottom = PIXADDR(lcd_dma.xres - 1, 0);
> +			ei = PIXSTEP(0, 0, 1, 0);
> +			fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
> +		}
> +		en = lcd_dma.xres;
> +		fn = lcd_dma.yres;
> +		break;
> +	case 270:
> +		if (!lcd_dma.mirror) {
> +			top = PIXADDR(lcd_dma.xres - 1, 0);
> +			bottom = PIXADDR(0, lcd_dma.yres - 1);
> +			ei = PIXSTEP(0, 0, 0, 1);
> +			fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
> +		} else {
> +			top = PIXADDR(0, 0);
> +			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
> +			ei = PIXSTEP(0, 0, 0, 1);
> +			fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
> +		}
> +		en = lcd_dma.yres;
> +		fn = lcd_dma.xres;
> +		break;
> +	default:
> +		BUG();
> +		return;	/* Suppress warning about uninitialized vars */
> +	}
> +
> +	if (cpu_is_omap1510()) {
> +		omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
> +		omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
> +		omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
> +		omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L);
> +
> +		return;
> +	}
> +
> +	/* 1610 regs */
> +	omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U);
> +	omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L);
> +	omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U);
> +	omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L);
> +
> +	omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1);
> +	omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1);
> +
> +	w = omap_readw(OMAP1610_DMA_LCD_CSDP);
> +	w &= ~0x03;
> +	w |= lcd_dma.data_type;
> +	omap_writew(w, OMAP1610_DMA_LCD_CSDP);
> +
> +	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
> +	/* Always set the source port as SDRAM for now*/
> +	w &= ~(0x03 << 6);
> +	if (lcd_dma.callback != NULL)
> +		w |= 1 << 1;		/* Block interrupt enable */
> +	else
> +		w &= ~(1 << 1);
> +	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
> +
> +	if (!(lcd_dma.rotate || lcd_dma.mirror ||
> +	      lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
> +		return;
> +
> +	w = omap_readw(OMAP1610_DMA_LCD_CCR);
> +	/* Set the double-indexed addressing mode */
> +	w |= (0x03 << 12);
> +	omap_writew(w, OMAP1610_DMA_LCD_CCR);
> +
> +	omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
> +	omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
> +	omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
> +}
> +
> +static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id)
> +{
> +	u16 w;
> +
> +	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
> +	if (unlikely(!(w & (1 << 3)))) {
> +		printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
> +		return IRQ_NONE;
> +	}
> +	/* Ack the IRQ */
> +	w |= (1 << 3);
> +	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
> +	lcd_dma.active = 0;
> +	if (lcd_dma.callback != NULL)
> +		lcd_dma.callback(w, lcd_dma.cb_data);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
> +			 void *data)
> +{
> +	spin_lock_irq(&lcd_dma.lock);
> +	if (lcd_dma.reserved) {
> +		spin_unlock_irq(&lcd_dma.lock);
> +		printk(KERN_ERR "LCD DMA channel already reserved\n");
> +		BUG();
> +		return -EBUSY;
> +	}
> +	lcd_dma.reserved = 1;
> +	spin_unlock_irq(&lcd_dma.lock);
> +	lcd_dma.callback = callback;
> +	lcd_dma.cb_data = data;
> +	lcd_dma.active = 0;
> +	lcd_dma.single_transfer = 0;
> +	lcd_dma.rotate = 0;
> +	lcd_dma.vxres = 0;
> +	lcd_dma.mirror = 0;
> +	lcd_dma.xscale = 0;
> +	lcd_dma.yscale = 0;
> +	lcd_dma.ext_ctrl = 0;
> +	lcd_dma.src_port = 0;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(omap_request_lcd_dma);
> +
> +void omap_free_lcd_dma(void)
> +{
> +	spin_lock(&lcd_dma.lock);
> +	if (!lcd_dma.reserved) {
> +		spin_unlock(&lcd_dma.lock);
> +		printk(KERN_ERR "LCD DMA is not reserved\n");
> +		BUG();
> +		return;
> +	}
> +	if (!cpu_is_omap1510())
> +		omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1,
> +			    OMAP1610_DMA_LCD_CCR);
> +	lcd_dma.reserved = 0;
> +	spin_unlock(&lcd_dma.lock);
> +}
> +EXPORT_SYMBOL(omap_free_lcd_dma);
> +
> +void omap_enable_lcd_dma(void)
> +{
> +	u16 w;
> +
> +	/*
> +	 * Set the Enable bit only if an external controller is
> +	 * connected. Otherwise the OMAP internal controller will
> +	 * start the transfer when it gets enabled.
> +	 */
> +	if (cpu_is_omap1510() || !lcd_dma.ext_ctrl)
> +		return;
> +
> +	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
> +	w |= 1 << 8;
> +	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
> +
> +	lcd_dma.active = 1;
> +
> +	w = omap_readw(OMAP1610_DMA_LCD_CCR);
> +	w |= 1 << 7;
> +	omap_writew(w, OMAP1610_DMA_LCD_CCR);
> +}
> +EXPORT_SYMBOL(omap_enable_lcd_dma);
> +
> +void omap_setup_lcd_dma(void)
> +{
> +	BUG_ON(lcd_dma.active);
> +	if (!cpu_is_omap1510()) {
> +		/* Set some reasonable defaults */
> +		omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
> +		omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
> +		omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
> +	}
> +	set_b1_regs();
> +	if (!cpu_is_omap1510()) {
> +		u16 w;
> +
> +		w = omap_readw(OMAP1610_DMA_LCD_CCR);
> +		/*
> +		 * If DMA was already active set the end_prog bit to have
> +		 * the programmed register set loaded into the active
> +		 * register set.
> +		 */
> +		w |= 1 << 11;		/* End_prog */
> +		if (!lcd_dma.single_transfer)
> +			w |= (3 << 8);	/* Auto_init, repeat */
> +		omap_writew(w, OMAP1610_DMA_LCD_CCR);
> +	}
> +}
> +EXPORT_SYMBOL(omap_setup_lcd_dma);
> +
> +void omap_stop_lcd_dma(void)
> +{
> +	u16 w;
> +
> +	lcd_dma.active = 0;
> +	if (cpu_is_omap1510() || !lcd_dma.ext_ctrl)
> +		return;
> +
> +	w = omap_readw(OMAP1610_DMA_LCD_CCR);
> +	w &= ~(1 << 7);
> +	omap_writew(w, OMAP1610_DMA_LCD_CCR);
> +
> +	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
> +	w &= ~(1 << 8);
> +	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
> +}
> +EXPORT_SYMBOL(omap_stop_lcd_dma);
> +
> +static int __init omap_init_lcd_dma(void)
> +{
> +	int r;
> +
> +	if (cpu_is_omap16xx()) {
> +		u16 w;
> +
> +		/* this would prevent OMAP sleep */
> +		w = omap_readw(OMAP1610_DMA_LCD_CTRL);
> +		w &= ~(1 << 8);
> +		omap_writew(w, OMAP1610_DMA_LCD_CTRL);
> +	}
> +
> +	spin_lock_init(&lcd_dma.lock);
> +
> +	r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0,
> +			"LCD DMA", NULL);
> +	if (r != 0)
> +		printk(KERN_ERR "unable to request IRQ for LCD DMA "
> +			       "(error %d)\n", r);
> +
> +	return r;
> +}
> +
> +arch_initcall(omap_init_lcd_dma);
> +
> diff -uprN git.orig/arch/arm/plat-omap/dma.c git/arch/arm/plat-omap/dma.c
> --- git.orig/arch/arm/plat-omap/dma.c	2009-11-21 00:38:46.000000000 +0100
> +++ git/arch/arm/plat-omap/dma.c	2009-11-21 03:34:23.000000000 +0100
> @@ -47,7 +47,6 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTS
>  #endif
>  
>  #define OMAP_DMA_ACTIVE			0x01
> -#define OMAP_DMA_CCR_EN			(1 << 7)
>  #define OMAP2_DMA_CSR_CLEAR_MASK	0xffe
>  
>  #define OMAP_FUNC_MUX_ARM_BASE		(0xfffe1000 + 0xec)
> @@ -1120,17 +1119,8 @@ int omap_dma_running(void)
>  {
>  	int lch;
>  
> -	/*
> -	 * On OMAP1510, internal LCD controller will start the transfer
> -	 * when it gets enabled, so assume DMA running if LCD enabled.
> -	 */
> -	if (cpu_is_omap1510())
> -		if (omap_readw(0xfffec000 + 0x00) & (1 << 0))
> -			return 1;
> -
> -	/* Check if LCD DMA is running */
> -	if (cpu_is_omap16xx())
> -		if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
> +	if (cpu_class_is_omap1())
> +		if (omap_lcd_dma_running())
>  			return 1;
>  
>  	for (lch = 0; lch < dma_chan_count; lch++)
> @@ -1990,377 +1980,6 @@ static struct irqaction omap24xx_dma_irq
>  
>  /*----------------------------------------------------------------------------*/
>  
> -static struct lcd_dma_info {
> -	spinlock_t lock;
> -	int reserved;
> -	void (*callback)(u16 status, void *data);
> -	void *cb_data;
> -
> -	int active;
> -	unsigned long addr, size;
> -	int rotate, data_type, xres, yres;
> -	int vxres;
> -	int mirror;
> -	int xscale, yscale;
> -	int ext_ctrl;
> -	int src_port;
> -	int single_transfer;
> -} lcd_dma;
> -
> -void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
> -			 int data_type)
> -{
> -	lcd_dma.addr = addr;
> -	lcd_dma.data_type = data_type;
> -	lcd_dma.xres = fb_xres;
> -	lcd_dma.yres = fb_yres;
> -}
> -EXPORT_SYMBOL(omap_set_lcd_dma_b1);
> -
> -void omap_set_lcd_dma_src_port(int port)
> -{
> -	lcd_dma.src_port = port;
> -}
> -
> -void omap_set_lcd_dma_ext_controller(int external)
> -{
> -	lcd_dma.ext_ctrl = external;
> -}
> -EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
> -
> -void omap_set_lcd_dma_single_transfer(int single)
> -{
> -	lcd_dma.single_transfer = single;
> -}
> -EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
> -
> -void omap_set_lcd_dma_b1_rotation(int rotate)
> -{
> -	if (omap_dma_in_1510_mode()) {
> -		printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
> -		BUG();
> -		return;
> -	}
> -	lcd_dma.rotate = rotate;
> -}
> -EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
> -
> -void omap_set_lcd_dma_b1_mirror(int mirror)
> -{
> -	if (omap_dma_in_1510_mode()) {
> -		printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
> -		BUG();
> -	}
> -	lcd_dma.mirror = mirror;
> -}
> -EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
> -
> -void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
> -{
> -	if (omap_dma_in_1510_mode()) {
> -		printk(KERN_ERR "DMA virtual resulotion is not supported "
> -				"in 1510 mode\n");
> -		BUG();
> -	}
> -	lcd_dma.vxres = vxres;
> -}
> -EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
> -
> -void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
> -{
> -	if (omap_dma_in_1510_mode()) {
> -		printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
> -		BUG();
> -	}
> -	lcd_dma.xscale = xscale;
> -	lcd_dma.yscale = yscale;
> -}
> -EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
> -
> -static void set_b1_regs(void)
> -{
> -	unsigned long top, bottom;
> -	int es;
> -	u16 w;
> -	unsigned long en, fn;
> -	long ei, fi;
> -	unsigned long vxres;
> -	unsigned int xscale, yscale;
> -
> -	switch (lcd_dma.data_type) {
> -	case OMAP_DMA_DATA_TYPE_S8:
> -		es = 1;
> -		break;
> -	case OMAP_DMA_DATA_TYPE_S16:
> -		es = 2;
> -		break;
> -	case OMAP_DMA_DATA_TYPE_S32:
> -		es = 4;
> -		break;
> -	default:
> -		BUG();
> -		return;
> -	}
> -
> -	vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
> -	xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
> -	yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
> -	BUG_ON(vxres < lcd_dma.xres);
> -
> -#define PIXADDR(x, y) (lcd_dma.addr +					\
> -		((y) * vxres * yscale + (x) * xscale) * es)
> -#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
> -
> -	switch (lcd_dma.rotate) {
> -	case 0:
> -		if (!lcd_dma.mirror) {
> -			top = PIXADDR(0, 0);
> -			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
> -			/* 1510 DMA requires the bottom address to be 2 more
> -			 * than the actual last memory access location. */
> -			if (omap_dma_in_1510_mode() &&
> -				lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
> -					bottom += 2;
> -			ei = PIXSTEP(0, 0, 1, 0);
> -			fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
> -		} else {
> -			top = PIXADDR(lcd_dma.xres - 1, 0);
> -			bottom = PIXADDR(0, lcd_dma.yres - 1);
> -			ei = PIXSTEP(1, 0, 0, 0);
> -			fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
> -		}
> -		en = lcd_dma.xres;
> -		fn = lcd_dma.yres;
> -		break;
> -	case 90:
> -		if (!lcd_dma.mirror) {
> -			top = PIXADDR(0, lcd_dma.yres - 1);
> -			bottom = PIXADDR(lcd_dma.xres - 1, 0);
> -			ei = PIXSTEP(0, 1, 0, 0);
> -			fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
> -		} else {
> -			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
> -			bottom = PIXADDR(0, 0);
> -			ei = PIXSTEP(0, 1, 0, 0);
> -			fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
> -		}
> -		en = lcd_dma.yres;
> -		fn = lcd_dma.xres;
> -		break;
> -	case 180:
> -		if (!lcd_dma.mirror) {
> -			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
> -			bottom = PIXADDR(0, 0);
> -			ei = PIXSTEP(1, 0, 0, 0);
> -			fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
> -		} else {
> -			top = PIXADDR(0, lcd_dma.yres - 1);
> -			bottom = PIXADDR(lcd_dma.xres - 1, 0);
> -			ei = PIXSTEP(0, 0, 1, 0);
> -			fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
> -		}
> -		en = lcd_dma.xres;
> -		fn = lcd_dma.yres;
> -		break;
> -	case 270:
> -		if (!lcd_dma.mirror) {
> -			top = PIXADDR(lcd_dma.xres - 1, 0);
> -			bottom = PIXADDR(0, lcd_dma.yres - 1);
> -			ei = PIXSTEP(0, 0, 0, 1);
> -			fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
> -		} else {
> -			top = PIXADDR(0, 0);
> -			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
> -			ei = PIXSTEP(0, 0, 0, 1);
> -			fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
> -		}
> -		en = lcd_dma.yres;
> -		fn = lcd_dma.xres;
> -		break;
> -	default:
> -		BUG();
> -		return;	/* Suppress warning about uninitialized vars */
> -	}
> -
> -	if (omap_dma_in_1510_mode()) {
> -		omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
> -		omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
> -		omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
> -		omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L);
> -
> -		return;
> -	}
> -
> -	/* 1610 regs */
> -	omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U);
> -	omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L);
> -	omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U);
> -	omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L);
> -
> -	omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1);
> -	omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1);
> -
> -	w = omap_readw(OMAP1610_DMA_LCD_CSDP);
> -	w &= ~0x03;
> -	w |= lcd_dma.data_type;
> -	omap_writew(w, OMAP1610_DMA_LCD_CSDP);
> -
> -	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
> -	/* Always set the source port as SDRAM for now*/
> -	w &= ~(0x03 << 6);
> -	if (lcd_dma.callback != NULL)
> -		w |= 1 << 1;		/* Block interrupt enable */
> -	else
> -		w &= ~(1 << 1);
> -	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
> -
> -	if (!(lcd_dma.rotate || lcd_dma.mirror ||
> -	      lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
> -		return;
> -
> -	w = omap_readw(OMAP1610_DMA_LCD_CCR);
> -	/* Set the double-indexed addressing mode */
> -	w |= (0x03 << 12);
> -	omap_writew(w, OMAP1610_DMA_LCD_CCR);
> -
> -	omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
> -	omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
> -	omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
> -}
> -
> -static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id)
> -{
> -	u16 w;
> -
> -	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
> -	if (unlikely(!(w & (1 << 3)))) {
> -		printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
> -		return IRQ_NONE;
> -	}
> -	/* Ack the IRQ */
> -	w |= (1 << 3);
> -	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
> -	lcd_dma.active = 0;
> -	if (lcd_dma.callback != NULL)
> -		lcd_dma.callback(w, lcd_dma.cb_data);
> -
> -	return IRQ_HANDLED;
> -}
> -
> -int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
> -			 void *data)
> -{
> -	spin_lock_irq(&lcd_dma.lock);
> -	if (lcd_dma.reserved) {
> -		spin_unlock_irq(&lcd_dma.lock);
> -		printk(KERN_ERR "LCD DMA channel already reserved\n");
> -		BUG();
> -		return -EBUSY;
> -	}
> -	lcd_dma.reserved = 1;
> -	spin_unlock_irq(&lcd_dma.lock);
> -	lcd_dma.callback = callback;
> -	lcd_dma.cb_data = data;
> -	lcd_dma.active = 0;
> -	lcd_dma.single_transfer = 0;
> -	lcd_dma.rotate = 0;
> -	lcd_dma.vxres = 0;
> -	lcd_dma.mirror = 0;
> -	lcd_dma.xscale = 0;
> -	lcd_dma.yscale = 0;
> -	lcd_dma.ext_ctrl = 0;
> -	lcd_dma.src_port = 0;
> -
> -	return 0;
> -}
> -EXPORT_SYMBOL(omap_request_lcd_dma);
> -
> -void omap_free_lcd_dma(void)
> -{
> -	spin_lock(&lcd_dma.lock);
> -	if (!lcd_dma.reserved) {
> -		spin_unlock(&lcd_dma.lock);
> -		printk(KERN_ERR "LCD DMA is not reserved\n");
> -		BUG();
> -		return;
> -	}
> -	if (!enable_1510_mode)
> -		omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1,
> -			    OMAP1610_DMA_LCD_CCR);
> -	lcd_dma.reserved = 0;
> -	spin_unlock(&lcd_dma.lock);
> -}
> -EXPORT_SYMBOL(omap_free_lcd_dma);
> -
> -void omap_enable_lcd_dma(void)
> -{
> -	u16 w;
> -
> -	/*
> -	 * Set the Enable bit only if an external controller is
> -	 * connected. Otherwise the OMAP internal controller will
> -	 * start the transfer when it gets enabled.
> -	 */
> -	if (enable_1510_mode || !lcd_dma.ext_ctrl)
> -		return;
> -
> -	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
> -	w |= 1 << 8;
> -	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
> -
> -	lcd_dma.active = 1;
> -
> -	w = omap_readw(OMAP1610_DMA_LCD_CCR);
> -	w |= 1 << 7;
> -	omap_writew(w, OMAP1610_DMA_LCD_CCR);
> -}
> -EXPORT_SYMBOL(omap_enable_lcd_dma);
> -
> -void omap_setup_lcd_dma(void)
> -{
> -	BUG_ON(lcd_dma.active);
> -	if (!enable_1510_mode) {
> -		/* Set some reasonable defaults */
> -		omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
> -		omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
> -		omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
> -	}
> -	set_b1_regs();
> -	if (!enable_1510_mode) {
> -		u16 w;
> -
> -		w = omap_readw(OMAP1610_DMA_LCD_CCR);
> -		/*
> -		 * If DMA was already active set the end_prog bit to have
> -		 * the programmed register set loaded into the active
> -		 * register set.
> -		 */
> -		w |= 1 << 11;		/* End_prog */
> -		if (!lcd_dma.single_transfer)
> -			w |= (3 << 8);	/* Auto_init, repeat */
> -		omap_writew(w, OMAP1610_DMA_LCD_CCR);
> -	}
> -}
> -EXPORT_SYMBOL(omap_setup_lcd_dma);
> -
> -void omap_stop_lcd_dma(void)
> -{
> -	u16 w;
> -
> -	lcd_dma.active = 0;
> -	if (enable_1510_mode || !lcd_dma.ext_ctrl)
> -		return;
> -
> -	w = omap_readw(OMAP1610_DMA_LCD_CCR);
> -	w &= ~(1 << 7);
> -	omap_writew(w, OMAP1610_DMA_LCD_CCR);
> -
> -	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
> -	w &= ~(1 << 8);
> -	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
> -}
> -EXPORT_SYMBOL(omap_stop_lcd_dma);
> -
>  void omap_dma_global_context_save(void)
>  {
>  	omap_dma_global_context.dma_irqenable_l0 =
> @@ -2465,14 +2084,6 @@ static int __init omap_init_dma(void)
>  			dma_chan_count = 16;
>  		} else
>  			dma_chan_count = 9;
> -		if (cpu_is_omap16xx()) {
> -			u16 w;
> -
> -			/* this would prevent OMAP sleep */
> -			w = omap_readw(OMAP1610_DMA_LCD_CTRL);
> -			w &= ~(1 << 8);
> -			omap_writew(w, OMAP1610_DMA_LCD_CTRL);
> -		}
>  	} else if (cpu_class_is_omap2()) {
>  		u8 revision = dma_read(REVISION) & 0xff;
>  		printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
> @@ -2483,7 +2094,6 @@ static int __init omap_init_dma(void)
>  		return 0;
>  	}
>  
> -	spin_lock_init(&lcd_dma.lock);
>  	spin_lock_init(&dma_chan_lock);
>  
>  	for (ch = 0; ch < dma_chan_count; ch++) {
> @@ -2548,22 +2158,6 @@ static int __init omap_init_dma(void)
>  		}
>  	}
>  
> -
> -	/* FIXME: Update LCD DMA to work on 24xx */
> -	if (cpu_class_is_omap1()) {
> -		r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0,
> -				"LCD DMA", NULL);
> -		if (r != 0) {
> -			int i;
> -
> -			printk(KERN_ERR "unable to request IRQ for LCD DMA "
> -			       "(error %d)\n", r);
> -			for (i = 0; i < dma_chan_count; i++)
> -				free_irq(omap1_dma_irq[i], (void *) (i + 1));
> -			goto out_free;
> -		}
> -	}
> -
>  	return 0;
>  
>  out_free:
> diff -uprN git.orig/arch/arm/plat-omap/include/plat/dma.h git/arch/arm/plat-omap/include/plat/dma.h
> --- git.orig/arch/arm/plat-omap/include/plat/dma.h	2009-11-21 00:38:46.000000000 +0100
> +++ git/arch/arm/plat-omap/include/plat/dma.h	2009-11-21 03:40:19.000000000 +0100
> @@ -401,33 +401,6 @@
>  
>  /*----------------------------------------------------------------------------*/
>  
> -/* Hardware registers for LCD DMA */
> -#define OMAP1510_DMA_LCD_BASE		(0xfffedb00)
> -#define OMAP1510_DMA_LCD_CTRL		(OMAP1510_DMA_LCD_BASE + 0x00)
> -#define OMAP1510_DMA_LCD_TOP_F1_L	(OMAP1510_DMA_LCD_BASE + 0x02)
> -#define OMAP1510_DMA_LCD_TOP_F1_U	(OMAP1510_DMA_LCD_BASE + 0x04)
> -#define OMAP1510_DMA_LCD_BOT_F1_L	(OMAP1510_DMA_LCD_BASE + 0x06)
> -#define OMAP1510_DMA_LCD_BOT_F1_U	(OMAP1510_DMA_LCD_BASE + 0x08)
> -
> -#define OMAP1610_DMA_LCD_BASE		(0xfffee300)
> -#define OMAP1610_DMA_LCD_CSDP		(OMAP1610_DMA_LCD_BASE + 0xc0)
> -#define OMAP1610_DMA_LCD_CCR		(OMAP1610_DMA_LCD_BASE + 0xc2)
> -#define OMAP1610_DMA_LCD_CTRL		(OMAP1610_DMA_LCD_BASE + 0xc4)
> -#define OMAP1610_DMA_LCD_TOP_B1_L	(OMAP1610_DMA_LCD_BASE + 0xc8)
> -#define OMAP1610_DMA_LCD_TOP_B1_U	(OMAP1610_DMA_LCD_BASE + 0xca)
> -#define OMAP1610_DMA_LCD_BOT_B1_L	(OMAP1610_DMA_LCD_BASE + 0xcc)
> -#define OMAP1610_DMA_LCD_BOT_B1_U	(OMAP1610_DMA_LCD_BASE + 0xce)
> -#define OMAP1610_DMA_LCD_TOP_B2_L	(OMAP1610_DMA_LCD_BASE + 0xd0)
> -#define OMAP1610_DMA_LCD_TOP_B2_U	(OMAP1610_DMA_LCD_BASE + 0xd2)
> -#define OMAP1610_DMA_LCD_BOT_B2_L	(OMAP1610_DMA_LCD_BASE + 0xd4)
> -#define OMAP1610_DMA_LCD_BOT_B2_U	(OMAP1610_DMA_LCD_BASE + 0xd6)
> -#define OMAP1610_DMA_LCD_SRC_EI_B1	(OMAP1610_DMA_LCD_BASE + 0xd8)
> -#define OMAP1610_DMA_LCD_SRC_FI_B1_L	(OMAP1610_DMA_LCD_BASE + 0xda)
> -#define OMAP1610_DMA_LCD_SRC_EN_B1	(OMAP1610_DMA_LCD_BASE + 0xe0)
> -#define OMAP1610_DMA_LCD_SRC_FN_B1	(OMAP1610_DMA_LCD_BASE + 0xe4)
> -#define OMAP1610_DMA_LCD_LCH_CTRL	(OMAP1610_DMA_LCD_BASE + 0xea)
> -#define OMAP1610_DMA_LCD_SRC_FI_B1_U	(OMAP1610_DMA_LCD_BASE + 0xf4)
> -
>  #define OMAP1_DMA_TOUT_IRQ		(1 << 0)
>  #define OMAP_DMA_DROP_IRQ		(1 << 1)
>  #define OMAP_DMA_HALF_IRQ		(1 << 2)
> @@ -441,6 +414,8 @@
>  #define OMAP2_DMA_SUPERVISOR_ERR_IRQ	(1 << 10)
>  #define OMAP2_DMA_MISALIGNED_ERR_IRQ	(1 << 11)
>  
> +#define OMAP_DMA_CCR_EN			(1 << 7)
> +
>  #define OMAP_DMA_DATA_TYPE_S8		0x00
>  #define OMAP_DMA_DATA_TYPE_S16		0x01
>  #define OMAP_DMA_DATA_TYPE_S32		0x02
> @@ -503,14 +478,6 @@
>  #define DMA_CH_PRIO_HIGH		0x1
>  #define DMA_CH_PRIO_LOW			0x0 /* Def */
>  
> -/* LCD DMA block numbers */
> -enum {
> -	OMAP_LCD_DMA_B1_TOP,
> -	OMAP_LCD_DMA_B1_BOTTOM,
> -	OMAP_LCD_DMA_B2_TOP,
> -	OMAP_LCD_DMA_B2_BOTTOM
> -};
> -
>  enum omap_dma_burst_mode {
>  	OMAP_DMA_DATA_BURST_DIS = 0,
>  	OMAP_DMA_DATA_BURST_4,
> @@ -661,20 +628,13 @@ extern int omap_modify_dma_chain_params(
>  extern int omap_dma_chain_status(int chain_id);
>  #endif
>  
> -/* LCD DMA functions */
> -extern int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
> -				void *data);
> -extern void omap_free_lcd_dma(void);
> -extern void omap_setup_lcd_dma(void);
> -extern void omap_enable_lcd_dma(void);
> -extern void omap_stop_lcd_dma(void);
> -extern void omap_set_lcd_dma_ext_controller(int external);
> -extern void omap_set_lcd_dma_single_transfer(int single);
> -extern void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
> -				int data_type);
> -extern void omap_set_lcd_dma_b1_rotation(int rotate);
> -extern void omap_set_lcd_dma_b1_vxres(unsigned long vxres);
> -extern void omap_set_lcd_dma_b1_mirror(int mirror);
> -extern void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale);
> +#ifdef CONFIG_ARCH_OMAP1
> +#include <mach/lcd_dma.h>
> +#else
> +static inline int omap_lcd_dma_running(void)
> +{
> +	return 0;
> +}
> +#endif
>  
>  #endif /* __ASM_ARCH_DMA_H */
> 


- Paul

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] [PATCH] OMAP: DMA: move LCD DMA related code from plat-omap to mach-omap1 (Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set)
  2009-11-25  9:02       ` Paul Walmsley
@ 2009-11-25 13:54         ` Janusz Krzysztofik
  2009-11-25 18:57           ` Paul Walmsley
  2009-11-25 22:57           ` Janusz Krzysztofik
  0 siblings, 2 replies; 17+ messages in thread
From: Janusz Krzysztofik @ 2009-11-25 13:54 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: Tony Lindgren, linux-omap@vger.kernel.org

Wednesday 25 November 2009 10:02:52 Paul Walmsley napisał(a):
> Hello Janusz,
>
> On Sat, 21 Nov 2009, Janusz Krzysztofik wrote:
> > (probably less interested persons and lists dropped)
> >
> > Tuesday 10 November 2009 11:50:52 Paul Walmsley wrote:
> > > ...  All of the LCD DMA code in plat-omap/dma.c appears to be
> > > OMAP1-only (and apparently only is available on a subset of OMAP1
> > > chips). It would be great if this code could be moved to
> > > mach-omap1/lcd_dma.c or a similar place.
> >
> > The patch just tries to implement this idea.
> >
> > Created against linux-omap for-next,
> > commit 2963c21fab52bfa8227da7f22864db393ebbc858
> >
> > Tested on OMAP1510 Amstrad Delta.
> > Compile tested using omap_generic_2420_defconfig.
> >
> > Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
> >
> > ---
> > Hi Paul,
> >
> > I hope the patch meets your suggestion closely enough.
>
> Thanks, just scanned it quickly and it looks carefully done.  Two
> suggestions below, both minor:

Paul,
Thanks for your review time.

Since I started with just duplicating files and then removing unnecessary
sections, I wondered how I could split that work into several subsequent
patches so it is more easy to verify how those chunks put into a new file
differ from those extracted from the old one, but didn't find a good solution
yet. 

> > diff -uprN git.orig/arch/arm/mach-omap1/Makefile git/arch/arm/mach-omap1/Makefile
> > --- git.orig/arch/arm/mach-omap1/Makefile	2009-11-21 00:38:45.000000000 +0100
> > +++ git/arch/arm/mach-omap1/Makefile	2009-11-21 01:27:12.000000000 +0100
> > @@ -3,7 +3,7 @@
> >  #
> >
> >  # Common support
> > -obj-y := io.o id.o sram.o clock.o irq.o mux.o serial.o devices.o
> > +obj-y := io.o id.o sram.o clock.o irq.o lcd_dma.o mux.o serial.o devices.o
>
> It seems that this LCD DMA controller is not present on OMAPs prior to the
> 1510, given all the references in the LCD DMA code to 1510 and 1610, etc.
> It might be good to add a Kconfig option so OMAP730/850 users can skip
> compiling it and save some memory.  The drivers that use these routines
> can then include Kconfig dependencies on that option so it is
> automatically included when those drivers are built.

OK, will prepare that for next iteration.

> > diff -uprN git.orig/arch/arm/mach-omap1/include/mach/lcd_dma.h git/arch/arm/mach-omap1/include/mach/lcd_dma.h
> > --- git.orig/arch/arm/mach-omap1/include/mach/lcd_dma.h	1970-01-01 01:00:00.000000000 +0100
> > +++ git/arch/arm/mach-omap1/include/mach/lcd_dma.h	2009-11-21 03:22:25.000000000 +0100
> > @@ -0,0 +1,78 @@ 
[snip]
> > +#ifndef __MACH_LCD_DMA_H__
>
> Consider adding _OMAP1_ in this macro name.  I doubt that name collisions
> here will be a serious issue, but adding a few extra bytes here might
> avoid some bug-hunting frustration in the long run...

OK, will do that too.

Thanks,
Janusz
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] [PATCH] OMAP: DMA: move LCD DMA related code from plat-omap to mach-omap1 (Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set)
  2009-11-25 13:54         ` Janusz Krzysztofik
@ 2009-11-25 18:57           ` Paul Walmsley
  2009-11-25 22:57           ` Janusz Krzysztofik
  1 sibling, 0 replies; 17+ messages in thread
From: Paul Walmsley @ 2009-11-25 18:57 UTC (permalink / raw)
  To: Janusz Krzysztofik; +Cc: Tony Lindgren, linux-omap@vger.kernel.org

On Wed, 25 Nov 2009, Janusz Krzysztofik wrote:

> Thanks for your review time.

Thank you for doing this work :-)

> Since I started with just duplicating files and then removing unnecessary
> sections, I wondered how I could split that work into several subsequent
> patches so it is more easy to verify how those chunks put into a new file
> differ from those extracted from the old one, but didn't find a good solution
> yet. 

Looking through the code, you've cleaned up several things that indicate 
that you've put some thought and care into doing it (e.g., all the 
cpu_class_is_omap1(), for example).  Plus, you mention that you've tested 
the code on OMAP1 and compile-tested on OMAP2.  So it seems fine to me 
after those two minor changes are made that I mentioned in the last 
E-mail.


- Paul

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] [PATCH] OMAP: DMA: move LCD DMA related code from plat-omap to mach-omap1 (Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set)
  2009-11-25 13:54         ` Janusz Krzysztofik
  2009-11-25 18:57           ` Paul Walmsley
@ 2009-11-25 22:57           ` Janusz Krzysztofik
  2009-11-26  2:08             ` Paul Walmsley
  1 sibling, 1 reply; 17+ messages in thread
From: Janusz Krzysztofik @ 2009-11-25 22:57 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: Tony Lindgren, linux-omap@vger.kernel.org

Wednesday 25 November 2009 14:54:47 Janusz Krzysztofik napisał(a):
> Wednesday 25 November 2009 10:02:52 Paul Walmsley napisał(a):
> > On Sat, 21 Nov 2009, Janusz Krzysztofik wrote:
> > >
> > > diff -uprN git.orig/arch/arm/mach-omap1/Makefile git/arch/arm/mach-omap1/Makefile
> > > --- git.orig/arch/arm/mach-omap1/Makefile	2009-11-21 00:38:45.000000000 +0100
> > > +++ git/arch/arm/mach-omap1/Makefile	2009-11-21 01:27:12.000000000 +0100
> > > @@ -3,7 +3,7 @@ 
> > >  #
> > >
> > >  # Common support
> > > -obj-y := io.o id.o sram.o clock.o irq.o mux.o serial.o devices.o
> > > +obj-y := io.o id.o sram.o clock.o irq.o lcd_dma.o mux.o serial.o devices.o
> >
> > It seems that this LCD DMA controller is not present on OMAPs prior to
> > the 1510, given all the references in the LCD DMA code to 1510 and 1610,
> > etc. It might be good to add a Kconfig option so OMAP730/850 users can
> > skip compiling it and save some memory.  The drivers that use these
> > routines can then include Kconfig dependencies on that option so it is
> > automatically included when those drivers are built.
>
> OK, will prepare that for next iteration.

Paul,

It turned out not that simple. Since arch/arm/mach-omap1/lcd_dma.c exports
several functions that are called unconditionaly from
drivers/video/omap/lcdc.c AND the latter is linked into the omapfb driver
based on CONFIG_ARCH_OMAP1=y, linking in the former can't be limited to
selected OMAP1 subarchs unless at least drivers/video/omap/{Kconfig,Makefile},
if not drivers/video/omap/lcdc.c itself either, are modified for that as well.
Am I missing something?

If not, I can see two options:
1. Keep arch/arm/mach-omap1/lcd_dma.c linked in for any OMAP1 subarch unless
CONFIG_FB_OMAP is not set. That can be cleaned up further after the 
drivers/video/omap/* stuff is ever modified.
2. Include drivers/video/omap/* modifications into this series.

What do you suggest?

Thanks,
Janusz
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] [PATCH] OMAP: DMA: move LCD DMA related code from plat-omap to mach-omap1 (Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set)
  2009-11-25 22:57           ` Janusz Krzysztofik
@ 2009-11-26  2:08             ` Paul Walmsley
  2009-11-26 14:30               ` Janusz Krzysztofik
  0 siblings, 1 reply; 17+ messages in thread
From: Paul Walmsley @ 2009-11-26  2:08 UTC (permalink / raw)
  To: Janusz Krzysztofik; +Cc: Tony Lindgren, linux-omap@vger.kernel.org

Hello Janusz,

On Wed, 25 Nov 2009, Janusz Krzysztofik wrote:

> It turned out not that simple. Since arch/arm/mach-omap1/lcd_dma.c 
> exports several functions that are called unconditionaly from 
> drivers/video/omap/lcdc.c AND the latter is linked into the omapfb 
> driver based on CONFIG_ARCH_OMAP1=y, linking in the former can't be 
> limited to selected OMAP1 subarchs unless at least 
> drivers/video/omap/{Kconfig,Makefile}, if not drivers/video/omap/lcdc.c 
> itself either, are modified for that as well. Am I missing something?
> 
> If not, I can see two options:
> 1. Keep arch/arm/mach-omap1/lcd_dma.c linked in for any OMAP1 subarch unless
> CONFIG_FB_OMAP is not set. That can be cleaned up further after the 
> drivers/video/omap/* stuff is ever modified.
> 2. Include drivers/video/omap/* modifications into this series.
> 
> What do you suggest?

Let's take option 1 for right now.  Maybe one of the htcwizard people 
might take that project up after the LCD DMA split is merged.



- Paul

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] [PATCH] OMAP: DMA: move LCD DMA related code from plat-omap to mach-omap1 (Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set)
  2009-11-26  2:08             ` Paul Walmsley
@ 2009-11-26 14:30               ` Janusz Krzysztofik
  2009-11-27  7:01                 ` Paul Walmsley
  0 siblings, 1 reply; 17+ messages in thread
From: Janusz Krzysztofik @ 2009-11-26 14:30 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: Tony Lindgren, linux-omap@vger.kernel.org

Thursday 26 November 2009 03:08:30 Paul Walmsley napisał(a):
> On Wed, 25 Nov 2009, Janusz Krzysztofik wrote:
> > It turned out not that simple. Since arch/arm/mach-omap1/lcd_dma.c
> > exports several functions that are called unconditionaly from
> > drivers/video/omap/lcdc.c AND the latter is linked into the omapfb
> > driver based on CONFIG_ARCH_OMAP1=y, linking in the former can't be
> > limited to selected OMAP1 subarchs unless at least
> > drivers/video/omap/{Kconfig,Makefile}, if not drivers/video/omap/lcdc.c
> > itself either, are modified for that as well. Am I missing something?
> >
> > If not, I can see two options:
> > 1. Keep arch/arm/mach-omap1/lcd_dma.c linked in for any OMAP1 subarch
> > unless CONFIG_FB_OMAP is not set. That can be cleaned up further after
> > the drivers/video/omap/* stuff is ever modified.
> > 2. Include drivers/video/omap/* modifications into this series.
> >
> > What do you suggest?
>
> Let's take option 1 for right now.  Maybe one of the htcwizard people
> might take that project up after the LCD DMA split is merged.

Paul,

I probably missed a third option: conditionally replacing declarations of 
those functions required by lcdc.c with coresponding fake static inline 
definitions inside an #ifdef block in lcd_dma.h. What do you think?

Thanks,
Janusz
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] [PATCH] OMAP: DMA: move LCD DMA related code from plat-omap to mach-omap1 (Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set)
  2009-11-26 14:30               ` Janusz Krzysztofik
@ 2009-11-27  7:01                 ` Paul Walmsley
  2009-11-27  8:08                   ` Belisko Marek
  0 siblings, 1 reply; 17+ messages in thread
From: Paul Walmsley @ 2009-11-27  7:01 UTC (permalink / raw)
  To: Janusz Krzysztofik; +Cc: Tony Lindgren, linux-omap@vger.kernel.org

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1724 bytes --]

On Thu, 26 Nov 2009, Janusz Krzysztofik wrote:

> Thursday 26 November 2009 03:08:30 Paul Walmsley napisał(a):
> > On Wed, 25 Nov 2009, Janusz Krzysztofik wrote:
> > > It turned out not that simple. Since arch/arm/mach-omap1/lcd_dma.c
> > > exports several functions that are called unconditionaly from
> > > drivers/video/omap/lcdc.c AND the latter is linked into the omapfb
> > > driver based on CONFIG_ARCH_OMAP1=y, linking in the former can't be
> > > limited to selected OMAP1 subarchs unless at least
> > > drivers/video/omap/{Kconfig,Makefile}, if not drivers/video/omap/lcdc.c
> > > itself either, are modified for that as well. Am I missing something?
> > >
> > > If not, I can see two options:
> > > 1. Keep arch/arm/mach-omap1/lcd_dma.c linked in for any OMAP1 subarch
> > > unless CONFIG_FB_OMAP is not set. That can be cleaned up further after
> > > the drivers/video/omap/* stuff is ever modified.
> > > 2. Include drivers/video/omap/* modifications into this series.
> > >
> > > What do you suggest?
> >
> > Let's take option 1 for right now.  Maybe one of the htcwizard people
> > might take that project up after the LCD DMA split is merged.
> 
> I probably missed a third option: conditionally replacing declarations of 
> those functions required by lcdc.c with coresponding fake static inline 
> definitions inside an #ifdef block in lcd_dma.h. What do you think?

Just took a quick look at that lcdc.c file; I think we'd better leave 
those functions in, since they are so tightly integrated to the code. 
Hopefully one of the OMAP730/750/850 people can tease them out, since 
they've got a platform to test on.  Sound reasonable?  Less work for us, 
anyway :-)

- Paul

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC] [PATCH] OMAP: DMA: move LCD DMA related code from plat-omap to mach-omap1 (Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set)
  2009-11-27  7:01                 ` Paul Walmsley
@ 2009-11-27  8:08                   ` Belisko Marek
  0 siblings, 0 replies; 17+ messages in thread
From: Belisko Marek @ 2009-11-27  8:08 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Janusz Krzysztofik, Tony Lindgren, linux-omap@vger.kernel.org

Hi,

On Fri, Nov 27, 2009 at 8:01 AM, Paul Walmsley <paul@pwsan.com> wrote:
> On Thu, 26 Nov 2009, Janusz Krzysztofik wrote:
>
>> Thursday 26 November 2009 03:08:30 Paul Walmsley napisał(a):
>> > On Wed, 25 Nov 2009, Janusz Krzysztofik wrote:
>> > > It turned out not that simple. Since arch/arm/mach-omap1/lcd_dma.c
>> > > exports several functions that are called unconditionaly from
>> > > drivers/video/omap/lcdc.c AND the latter is linked into the omapfb
>> > > driver based on CONFIG_ARCH_OMAP1=y, linking in the former can't be
>> > > limited to selected OMAP1 subarchs unless at least
>> > > drivers/video/omap/{Kconfig,Makefile}, if not drivers/video/omap/lcdc.c
>> > > itself either, are modified for that as well. Am I missing something?
>> > >
>> > > If not, I can see two options:
>> > > 1. Keep arch/arm/mach-omap1/lcd_dma.c linked in for any OMAP1 subarch
>> > > unless CONFIG_FB_OMAP is not set. That can be cleaned up further after
>> > > the drivers/video/omap/* stuff is ever modified.
>> > > 2. Include drivers/video/omap/* modifications into this series.
>> > >
>> > > What do you suggest?
>> >
>> > Let's take option 1 for right now.  Maybe one of the htcwizard people
>> > might take that project up after the LCD DMA split is merged.
>>
>> I probably missed a third option: conditionally replacing declarations of
>> those functions required by lcdc.c with coresponding fake static inline
>> definitions inside an #ifdef block in lcd_dma.h. What do you think?
>
> Just took a quick look at that lcdc.c file; I think we'd better leave
> those functions in, since they are so tightly integrated to the code.
> Hopefully one of the OMAP730/750/850 people can tease them out, since
> they've got a platform to test on.  Sound reasonable?  Less work for us,
> anyway :-)
I have htc wizard with omap850 I can test if patch will be finished :-)
>
> - Paul



Marek
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2009-11-27  8:08 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-29 22:39 [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set Janusz Krzysztofik
2009-10-29 23:47 ` Janusz Krzysztofik
2009-10-30 14:42 ` Janusz Krzysztofik
2009-10-30 17:33   ` Tony Lindgren
2009-11-01  1:18     ` Janusz Krzysztofik
2009-11-03 17:11       ` Tony Lindgren
2009-11-10 10:50   ` Paul Walmsley
2009-11-11  0:02     ` Janusz Krzysztofik
2009-11-21 15:58     ` [RFC] [PATCH] OMAP: DMA: move LCD DMA related code from plat-omap to mach-omap1 (Re: [PATCH] OMAP1: PM: Fix omapfb/lcd on Amstrad Delta broken when PM set) Janusz Krzysztofik
2009-11-25  9:02       ` Paul Walmsley
2009-11-25 13:54         ` Janusz Krzysztofik
2009-11-25 18:57           ` Paul Walmsley
2009-11-25 22:57           ` Janusz Krzysztofik
2009-11-26  2:08             ` Paul Walmsley
2009-11-26 14:30               ` Janusz Krzysztofik
2009-11-27  7:01                 ` Paul Walmsley
2009-11-27  8:08                   ` Belisko Marek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox