Patchwork [U-Boot,v2] powerpc: 'monitor' environment variable contains full video configuration

login
register
mail settings
Submitter Timur Tabi
Date March 14, 2011, 8:19 p.m.
Message ID <1300133949-1115-1-git-send-email-timur@freescale.com>
Download mbox | patch
Permalink /patch/86813/
State Superseded
Headers show

Comments

Timur Tabi - March 14, 2011, 8:19 p.m.
Update the "monitor" environment variable (for Freescale chips that have a
DIU display controller) to designate the full video configuration, instead
of just the output monitor.

The old definition of the "monitor" environment variable only determines
which video port to use for output.  This variable is set to a number (0,
1, or sometimes 2) to specify a DVI, LVDS, or Dual-LVDS port.  The
resolution is hard-coded into board-specific code.  The Linux command-line
arguments need to be hard-coded to the proper video definition string.

Instead, the "monitor" variable is now set to a string that indicates not
only the part name, but also the resolution, color depth, and refresh rate.
This string is then parsed for all needed information, and can be passed to
the kernel via the 'diubootargs' environment variable.

Signed-off-by: Timur Tabi <timur@freescale.com>
---

This patch depends on my previous patch, "[v4] powerpc: clean up DIU macro
definitions for Freescale reference boards".

 README                                        |    9 +-
 board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c |   73 +-
 board/freescale/p1022ds/diu.c                 |   29 +-
 doc/README.video                              |   29 +
 drivers/video/fsl_diu_fb.c                    | 1019 ++++++++++++-------------
 include/configs/MPC8610HPCD.h                 |   16 +-
 include/configs/P1022DS.h                     |   12 +-
 include/fsl_diu_fb.h                          |   91 +--
 8 files changed, 631 insertions(+), 647 deletions(-)
 rewrite drivers/video/fsl_diu_fb.c (63%)
 rewrite include/fsl_diu_fb.h (62%)
Wolfgang Denk - March 14, 2011, 11:33 p.m.
Dear Timur Tabi,

In message <1300133949-1115-1-git-send-email-timur@freescale.com> you wrote:
> Update the "monitor" environment variable (for Freescale chips that have a
> DIU display controller) to designate the full video configuration, instead
> of just the output monitor.
> 
> The old definition of the "monitor" environment variable only determines
> which video port to use for output.  This variable is set to a number (0,
> 1, or sometimes 2) to specify a DVI, LVDS, or Dual-LVDS port.  The
> resolution is hard-coded into board-specific code.  The Linux command-line
> arguments need to be hard-coded to the proper video definition string.
> 
> Instead, the "monitor" variable is now set to a string that indicates not
> only the part name, but also the resolution, color depth, and refresh rate.
> This string is then parsed for all needed information, and can be passed to
> the kernel via the 'diubootargs' environment variable.

Looks as if this was a Freescale specific implementation?

Can this not be turned into generic code, usable for other boards /
systems as well?

Please see the discussion we had about video modes for the i.MX
systems.

I want to see handled most of this with generic code, not with
processor / architecture specific one.


Best regards,

Wolfgang Denk
Tabi Timur-B04825 - March 14, 2011, 11:39 p.m.
Wolfgang Denk wrote:
> Looks as if this was a Freescale specific implementation?

Yes.

> Can this not be turned into generic code, usable for other boards /
> systems as well?

Possibly, but I would like to fix one bug at a time.

> Please see the discussion we had about video modes for the i.MX
> systems.

Can you point me to the thread or at least tell me the subject line?  I have no idea what you're talking about.

> I want to see handled most of this with generic code, not with
> processor / architecture specific one.

This patch also cleans up a lot of the DIU code to make it handle more generic options.
Wolfgang Denk - March 15, 2011, 9:05 a.m.
Dear Tabi Timur-B04825,

In message <4D7EA72C.9040603@freescale.com> you wrote:
>
> > Can this not be turned into generic code, usable for other boards /
> > systems as well?
> 
> Possibly, but I would like to fix one bug at a time.

Agreed, but please not by introducing lots of new, probably later
incompatible code.

> > Please see the discussion we had about video modes for the i.MX
> > systems.
> 
> Can you point me to the thread or at least tell me the subject line?  I have
> no idea what you're talking about.

See http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/88169/focus=88240

> > I want to see handled most of this with generic code, not with
> > processor / architecture specific one.
> 
> This patch also cleans up a lot of the DIU code to make it handle more gene-
> ric options.

OK, so please split that patch:  one patch should do this cleanup, and
another one should contain the rest.

Instead of a non-standard and undocumented 'diubootargs' environment
variable please use something (probably called "video-mode" :-) that
can be passed as "video-mode=" boot argument to Linux.

At this point I wonder which use ther eis left for your "monitor"
variable - it should be completely redundant now?

Best regards,

Wolfgang Denk
Timur Tabi - March 15, 2011, 2:50 p.m.
Wolfgang Denk wrote:
> Agreed, but please not by introducing lots of new, probably later
> incompatible code.

Fair enough.

>> > Can you point me to the thread or at least tell me the subject line?  I have
>> > no idea what you're talking about.

> See http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/88169/focus=88240

Ok, so what I get from that thread is to change the name of the variables
("monitor" -> "video" and "diubootargs" -> something else more generic) and
update the videomodes.c code to parse the same video string that the kernel
uses.  I also gathered that no one has chosen to update videomodes.c, so I would
have to do it.

Do I have that right?

> OK, so please split that patch:  one patch should do this cleanup, and
> another one should contain the rest.

I can't make any promises, since a lot of the code is intermingled.

> Instead of a non-standard and undocumented 'diubootargs' environment
> variable please use something (probably called "video-mode" :-) that
> can be passed as "video-mode=" boot argument to Linux.
> 
> At this point I wonder which use ther eis left for your "monitor"
> variable - it should be completely redundant now?

Well, it may still be necessary to have two variables.  One for the mode that
U-Boot parses, and one for the string that is passed to the kernel.  This is
because the kernel also needs to see "console=tty0" on the command line only if
video is supposed to be enabled.  I want to make video mode completely dynamic,
so that if the 'video-mode' variable is set, then the console is switched to the
video device, and the kernel is told to do the same.  Otherwise, all output will
go to the serial port.
Wolfgang Denk - March 15, 2011, 3:15 p.m.
Dear Timur Tabi,

In message <4D7F7CB9.8090005@freescale.com> you wrote:
>
> ("monitor" -> "video" and "diubootargs" -> something else more generic) and

video-mode ?

> update the videomodes.c code to parse the same video string that the kernel
> uses.  I also gathered that no one has chosen to update videomodes.c, so I would
> have to do it.
> 
> Do I have that right?

I think so.

Anatolij?
Stefano?

> > At this point I wonder which use ther eis left for your "monitor"
> > variable - it should be completely redundant now?
> 
> Well, it may still be necessary to have two variables.  One for the mode that

No, this is exactly what should be avoided.

> U-Boot parses, and one for the string that is passed to the kernel.  This is

U-Boot and the Kernel should parse exactly the same variable.

> because the kernel also needs to see "console=tty0" on the command line only if

This may or may not be the case.  Frequently we still use a serial
console even when booting with a graphics display enabled.

This is a different option, and does not belong into that setting.

> video is supposed to be enabled.  I want to make video mode completely dynamic,
> so that if the 'video-mode' variable is set, then the console is switched to the
> video device, and the kernel is told to do the same.  Otherwise, all output will
> go to the serial port.

NAK. video-mode settings and console settings are two separate things
and must not be mangled into a single variable.

Best regards,

Wolfgang Denk
Timur Tabi - March 15, 2011, 3:21 p.m.
Wolfgang Denk wrote:
>> > because the kernel also needs to see "console=tty0" on the command line only if
> This may or may not be the case.  Frequently we still use a serial
> console even when booting with a graphics display enabled.
> 
> This is a different option, and does not belong into that setting.
> 
>> > video is supposed to be enabled.  I want to make video mode completely dynamic,
>> > so that if the 'video-mode' variable is set, then the console is switched to the
>> > video device, and the kernel is told to do the same.  Otherwise, all output will
>> > go to the serial port.

> NAK. video-mode settings and console settings are two separate things
> and must not be mangled into a single variable.

Well, that's why I have two variables.  My patch has the ability to set the
kernel command line appropriately if the video display is configured and enabled
in U-Boot.  The second variable is used to assist in setting the actual kernel
command-line, because that's the easiest and safest way to do it.  An
alternative that I tried to implement is to have do_bootm_linux() edit the
kernel command line directly, removing any existing video= option and putting a
new one in, but I found that to be too intrusive, especially since we don't have
any good string editing functions already in U-Boot.

There are three things that need to be done:

1) The video mode needs to be configured
2) The video display needs to be enabled and the U-Boot console needs to be
routed to it
3) The kernel command line needs to be set

For #1, we use video-mode.  How do you want #2 and #3 handled?
Wolfgang Denk - March 15, 2011, 3:47 p.m.
Dear Timur Tabi,

In message <4D7F83EC.4050804@freescale.com> you wrote:
>
> > NAK. video-mode settings and console settings are two separate things
> > and must not be mangled into a single variable.
> 
> Well, that's why I have two variables.  My patch has the ability to set the
> kernel command line appropriately if the video display is configured and enabled
> in U-Boot.  The second variable is used to assist in setting the actual kernel
> command-line, because that's the easiest and safest way to do it.  An

Don't try to be more clever than the user.  Instead of helping, you
restrict him. That's bad.

> alternative that I tried to implement is to have do_bootm_linux() edit the
> kernel command line directly, removing any existing video= option and putting a

NAK, NAK, NAK.  All such automatic and unconditional editing is bad
and should strictly be avoided.

Leave the decision which device to use as console to the user.

> There are three things that need to be done:
> 
> 1) The video mode needs to be configured

ACK.

> 2) The video display needs to be enabled and the U-Boot console needs to be
> routed to it

NAK.

Wether the U-Boot console is attached to the serial port or the video
console or netconsole or anything else should be left to the user.

A default setting is OK, but the user must be able to set anything he
likes.

> 3) The kernel command line needs to be set

ACK.  Again, the user must have free choice of options.

> For #1, we use video-mode.  How do you want #2 and #3 handled?

See above.

Best regards,

Wolfgang Denk
Timur Tabi - March 15, 2011, 3:52 p.m.
Wolfgang Denk wrote:
>> Well, that's why I have two variables.  My patch has the ability to set the
>> > kernel command line appropriately if the video display is configured and enabled
>> > in U-Boot.  The second variable is used to assist in setting the actual kernel
>> > command-line, because that's the easiest and safest way to do it.  An

> Don't try to be more clever than the user.  Instead of helping, you
> restrict him. That's bad.

I'm not being more clever.  The code is setting a variable (diubootargs) that is
guaranteed to be the same video mode that U-Boot is running.  If you want to
ensure that Linux set to the same video mode, then use the variable.  Otherwise,
don't use the variable and set the command line manually.

>> > alternative that I tried to implement is to have do_bootm_linux() edit the
>> > kernel command line directly, removing any existing video= option and putting a

> NAK, NAK, NAK.  All such automatic and unconditional editing is bad
> and should strictly be avoided.

You didn't understand my post.  I was saying that I tried to implement it, but
gave up because it got too complicated.

> Leave the decision which device to use as console to the user.

That's what the 'monitor' environment variable is for.

>> > There are three things that need to be done:
>> > 
>> > 1) The video mode needs to be configured
> ACK.
> 
>> > 2) The video display needs to be enabled and the U-Boot console needs to be
>> > routed to it
> NAK.
> 
> Wether the U-Boot console is attached to the serial port or the video
> console or netconsole or anything else should be left to the user.

Again, that's what the variable is for.  What's the point of configuring the
video display if you're not going to enable it?

> A default setting is OK, but the user must be able to set anything he
> likes.

Are we speaking the same language?  It doesn't appear that you're understanding
anything I'm saying.

>> > 3) The kernel command line needs to be set
> ACK.  Again, the user must have free choice of options.
> 
>> > For #1, we use video-mode.  How do you want #2 and #3 handled?
> See above.

I still don't understand what you actually want.
Wolfgang Denk - March 15, 2011, 7:02 p.m.
Dear Timur Tabi,

In message <4D7F8B3C.4080307@freescale.com> you wrote:
>
> > Don't try to be more clever than the user.  Instead of helping, you
> > restrict him. That's bad.
> 
> I'm not being more clever.  The code is setting a variable (diubootargs) that is
> guaranteed to be the same video mode that U-Boot is running.  If you want to
> ensure that Linux set to the same video mode, then use the variable.  Otherwise,
> don't use the variable and set the command line manually.

You don't need another variable for setting the video mode, because we
(will) have "video-mode" for that very purpose, that can and shall be
used both in U-Boot and Linux.

> > NAK, NAK, NAK.  All such automatic and unconditional editing is bad
> > and should strictly be avoided.
> 
> You didn't understand my post.  I was saying that I tried to implement it, but
> gave up because it got too complicated.

I did understand your posting. I wanted to tell you that you should
not even try doing such things.

> > Leave the decision which device to use as console to the user.
> 
> That's what the 'monitor' environment variable is for.

"monitor" has nothing to do with the console, right?

typically we (here at DENX) use helper macros like

	setenv addcons 'setenv bootargs ${bootargs} console=${consdev},${baudrate}'
	setenv consdev ttyS0

Then you can have the "addcons" in some command sequence that builds
up the bootargs.

"monitor"? No, this has _nothing_ to do with any console settings.

> >> > 2) The video display needs to be enabled and the U-Boot console needs to be
> >> > routed to it
> > NAK.
> > 
> > Wether the U-Boot console is attached to the serial port or the video
> > console or netconsole or anything else should be left to the user.
> 
> Again, that's what the variable is for.  What's the point of configuring the
> video display if you're not going to enable it?

You misinterpret what I wrote.  Of course we're going to enable the
video display then.

But there is no reason to always and unconditionally put the console
on that device - that is a completely separate and independent
decision.

> > A default setting is OK, but the user must be able to set anything he
> > likes.
> 
> Are we speaking the same language?  It doesn't appear that you're understanding
> anything I'm saying.

And vice versa.  Probably you don't read what I'm writing either.

> I still don't understand what you actually want.

I want that you keep the console settings out of this topic. It has
nothing to do with it.

And I want to make sure that we don't have several environment
variables doing more or less the same thing.

Best regards,

Wolfgang Denk
Timur Tabi - March 15, 2011, 7:09 p.m.
Wolfgang Denk wrote:

> You misinterpret what I wrote.  Of course we're going to enable the
> video display then.
> 
> But there is no reason to always and unconditionally put the console
> on that device - that is a completely separate and independent
> decision.

I still don't understand the point of enabling the video display in U-Boot if
we're not going to put the U-Boot console on it.  The monitor will just have a
blank screen.

We don't need to enable it for Linux' sake, because Linux can enable the monitor
itself if it wants to.  It just needs to be told what resolution to use.
Wolfgang Denk - March 15, 2011, 7:38 p.m.
Dear Timur Tabi,

In message <4D7FB987.20100@freescale.com> you wrote:
> 
> > But there is no reason to always and unconditionally put the console
> > on that device - that is a completely separate and independent
> > decision.
> 
> I still don't understand the point of enabling the video display in U-Boot if
> we're not going to put the U-Boot console on it.  The monitor will just have a
> blank screen.

It may be a blank screen, or a (previously loaded) splash screen, or
(a bit later) some graphics application outputting data.

It's up to the user to decide that.

Best regards,

Wolfgang Denk
Timur Tabi - March 15, 2011, 7:49 p.m.
Wolfgang Denk wrote:
> It may be a blank screen, or a (previously loaded) splash screen, or
> (a bit later) some graphics application outputting data.
> 
> It's up to the user to decide that.

Ok, I think I get it.  But I'm going to miss this merge window, because now I
have to rewrite half of my patch.

What is the standard mechanism for enabling the console on the video display?
From what I can tell, if video_hw_init() returns non-NULL, then the console is
set to the video display, regardless as to what the "stdout" environment
variable says.
Wolfgang Denk - March 15, 2011, 8:41 p.m.
Dear Timur Tabi,

In message <4D7FC2C5.2020406@freescale.com> you wrote:
>
> Ok, I think I get it.  But I'm going to miss this merge window, because now I
> have to rewrite half of my patch.

You won't. We have a delay of at least 2 weeks.

> What is the standard mechanism for enabling the console on the video display?
> From what I can tell, if video_hw_init() returns non-NULL, then the console is
> set to the video display, regardless as to what the "stdout" environment
> variable says.

That's the default. Users can overwrite it, for example in "preboot".
See also CONFIG_ENV_OVERWRITE

Best regards,

Wolfgang Denk
Timur Tabi - March 15, 2011, 8:48 p.m.
Wolfgang Denk wrote:
>> > What is the standard mechanism for enabling the console on the video display?
>> > From what I can tell, if video_hw_init() returns non-NULL, then the console is
>> > set to the video display, regardless as to what the "stdout" environment
>> > variable says.

> That's the default. Users can overwrite it, for example in "preboot".
> See also CONFIG_ENV_OVERWRITE

Then I'm confused, because video_hw_init() is what configures and enables the
video display.  So if that function succeeds (i.e. returns non-NULL), then
U-Boot will put the console onto the video display.  You said you wanted me to
implement some mechanism where I enable the display, based on the value of the
video-mode variable, without putting console on the display.  However, from you
just said, it appears that this mechanism already exists.
Wolfgang Denk - March 15, 2011, 9:47 p.m.
Dear Timur Tabi,

In message <4D7FD08C.2020406@freescale.com> you wrote:
>
> Then I'm confused, because video_hw_init() is what configures and enables the
> video display.  So if that function succeeds (i.e. returns non-NULL), then
> U-Boot will put the console onto the video display.  You said you wanted me to
> implement some mechanism where I enable the display, based on the value of the
> video-mode variable, without putting console on the display.  However, from you
> just said, it appears that this mechanism already exists.

Please re-read the conversation then. Mind the context (U-Boot versus
Linux). Mind what I wrote about defaults and users being able to
chose the behaviour they want. And keep in mind what I wrote about
enforcing desicions "in the best interest" of your users (who may
happen to disagree).

Best regards,

Wolfgang Denk
Timur Tabi - March 15, 2011, 10:32 p.m.
Wolfgang Denk wrote:
> Please re-read the conversation then. Mind the context (U-Boot versus
> Linux). Mind what I wrote about defaults and users being able to
> chose the behaviour they want. And keep in mind what I wrote about
> enforcing desicions "in the best interest" of your users (who may
> happen to disagree).

After re-reading it, I've come to the conclusion is that as far as my patch is
concerned, I just need to make the following changes:

1) Modify video_get_params() (in videomodes.c) to parse the "video-mode
"environment variable, using the same format that Linux uses.  Right now, it
parses the variable "video", so that variable is now deprecated.

2) Update the DIU driver to use this feature of videomodes.c.  This means taking
the functionality of my function diu_get_video_params() and putting it into
video_get_params().

3) Remove the code that sets diubootargs.  If the user wants to pass parameters
to Linux, he has to add "video=$video-mode console=tty0" to his command-line.
If "video-mode" is not set, then he must *not* add "video=$video-mode
console=tty0" to his command-line, otherwise the kernel will get confused.
There is no way to automate this for the user.

And that's it.  If this is wrong, please be detailed in what I have wrong,
because I can't guess any more what you want.

So I have one concern:

My patch has a function called diu_get_video_params() which is like
video_get_params(), but it returns a lot more information.  video_get_params()
is currently used by several other drivers, none of which I can test.  I'm very
hesitant to rewrite video_get_params() so that it returns the same data that
diu_get_video_params() returns, because I can't test these other boards.

Patch

diff --git a/README b/README
index 9597fed..4fc35f4 100644
--- a/README
+++ b/README
@@ -1072,12 +1072,9 @@  The following options need to be configured:
 			CONFIG_VIDEO_BMP_LOGO
 
 		The DIU driver will look for the 'monitor' environment variable,
-		and if defined, enable the DIU as a console during boot.  This
-		variable should be set to one of these values:
-
-			'0'	Output video to the DVI connector
-			'1'	Output video to the LVDS connector
-			'2'	Output video to the Dual-Link LVDS connector
+		and if defined, enable the DIU as a console during boot.  See
+		the documentation file README.video for a description of this
+		variable.
 
 - Keyboard Support:
 		CONFIG_KEYBOARD
diff --git a/board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c b/board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c
index 81e53e7..6ffe457 100644
--- a/board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c
+++ b/board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c
@@ -1,6 +1,7 @@ 
 /*
- * Copyright 2007 Freescale Semiconductor, Inc.
- * York Sun <yorksun@freescale.com>
+ * Copyright 2007-2011 Freescale Semiconductor, Inc.
+ * Authors: York Sun <yorksun@freescale.com>
+ *          Timur Tabi <timur@freescale.com>
  *
  * FSL DIU Framebuffer driver
  *
@@ -27,6 +28,10 @@ 
 #include <command.h>
 #include <asm/io.h>
 #include <fsl_diu_fb.h>
+#include "../common/pixis.h"
+
+#define PX_BRDCFG0_DLINK	0x10
+#define PX_BRDCFG0_DVISEL	0x08
 
 void diu_set_pixel_clock(unsigned int pixclock)
 {
@@ -49,50 +54,36 @@  void diu_set_pixel_clock(unsigned int pixclock)
 	debug("DIU: Modified value of CLKDVDR = 0x%08x\n", *guts_clkdvdr);
 }
 
-int platform_diu_init(unsigned int *xres, unsigned int *yres)
+int platform_diu_init(unsigned int xres, unsigned int yres)
 {
-	char *monitor_port;
-	int gamma_fix;
-	unsigned int pixel_format;
-	unsigned char tmp_val;
-	unsigned char pixis_arch;
-	u8 *pixis_base = (u8 *)PIXIS_BASE;
+	const char *monitor_port;
+	const char *name;
+	int gamma_fix = 0;
+	u32 pixel_format = 0x88883316;
+	u8 temp;
 
-	tmp_val = in_8(pixis_base + PIXIS_BRDCFG0);
-	pixis_arch = in_8(pixis_base + PIXIS_VER);
+	temp = in_8(&pixis->brdcfg0);
 
 	monitor_port = getenv("monitor");
-	if (!strncmp(monitor_port, "0", 1)) {	/* 0 - DVI */
-		*xres = 1280;
-		*yres = 1024;
-		if (pixis_arch == 0x01)
-			pixel_format = 0x88882317;
-		else
-			pixel_format = 0x88883316;
-		gamma_fix = 0;
-		out_8(pixis_base + PIXIS_BRDCFG0, tmp_val | 0x08);
-
-	} else if (!strncmp(monitor_port, "1", 1)) { /* 1 - Single link LVDS */
-		*xres = 1024;
-		*yres = 768;
-		pixel_format = 0x88883316;
-		gamma_fix = 0;
-		out_8(pixis_base + PIXIS_BRDCFG0, (tmp_val & 0xf7) | 0x10);
-
-	} else if (!strncmp(monitor_port, "2", 1)) { /* 2 - Double link LVDS */
-		*xres = 1280;
-		*yres = 1024;
-		pixel_format = 0x88883316;
+	if (strncmp(monitor_port, "dlvds", 5) == 0) {
+		/* Dual link LVDS */
 		gamma_fix = 1;
-		out_8(pixis_base + PIXIS_BRDCFG0, tmp_val & 0xe7);
-
-	} else {	/* DVI */
-		*xres = 1280;
-		*yres = 1024;
-		pixel_format = 0x88882317;
-		gamma_fix = 0;
-		out_8(pixis_base + PIXIS_BRDCFG0, tmp_val | 0x08);
+		temp &= ~(PX_BRDCFG0_DLINK | PX_BRDCFG0_DVISEL);
+		name = "Dual-Link LVDS";
+	} else if (strncmp(monitor_port, "lvds", 4) == 0) {
+		/* Single link LVDS */
+		temp = (temp & ~PX_BRDCFG0_DVISEL) | PX_BRDCFG0_DLINK;
+		name = "Single-Link LVDS";
+	} else {
+		/* DVI */
+		if (in_8(&pixis->ver) == 1)	/* Board version */
+			pixel_format = 0x88882317;
+		temp |= PX_BRDCFG0_DVISEL;
+		name = "DVI";
 	}
 
-	return fsl_diu_init(*xres, pixel_format, gamma_fix);
+	printf("DIU:   Switching to %s monitor @ %ux%u\n", name, xres, yres);
+	out_8(&pixis->brdcfg0, temp);
+
+	return fsl_diu_init(xres, pixel_format, gamma_fix);
 }
diff --git a/board/freescale/p1022ds/diu.c b/board/freescale/p1022ds/diu.c
index 8f5305c..544f254 100644
--- a/board/freescale/p1022ds/diu.c
+++ b/board/freescale/p1022ds/diu.c
@@ -1,5 +1,5 @@ 
 /*
- * Copyright 2010 Freescale Semiconductor, Inc.
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
  * Authors: Timur Tabi <timur@freescale.com>
  *
  * FSL DIU Framebuffer driver
@@ -12,6 +12,7 @@ 
 
 #include <common.h>
 #include <command.h>
+#include <linux/ctype.h>
 #include <asm/io.h>
 #include <stdio_dev.h>
 #include <video_fb.h>
@@ -81,10 +82,11 @@  void diu_set_pixel_clock(unsigned int pixclock)
 	out_be32(&gur->clkdvdr, temp | 0x80000000 | ((pixval & 0x1F) << 16));
 }
 
-int platform_diu_init(unsigned int *xres, unsigned int *yres)
+int platform_diu_init(unsigned int xres, unsigned int yres)
 {
 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
-	char *monitor_port;
+	const char *monitor_port;
+	const char *name;
 	u32 pixel_format;
 	u8 temp;
 
@@ -101,20 +103,23 @@  int platform_diu_init(unsigned int *xres, unsigned int *yres)
 	temp = in_8(&pixis->brdcfg1);
 
 	monitor_port = getenv("monitor");
-	if (!strncmp(monitor_port, "1", 1)) { /* 1 - Single link LVDS */
-		*xres = 1024;
-		*yres = 768;
-		/* Enable the DFP port, disable the DVI and the backlight */
-		temp &= ~(PX_BRDCFG1_DVIEN | PX_BRDCFG1_BACKLIGHT);
-		temp |= PX_BRDCFG1_DFPEN;
+	if (strncmp(monitor_port, "lvds", 4) == 0) {
+		/* Single link LVDS */
+		temp &= ~PX_BRDCFG1_DVIEN;
+		/*
+		 * LVDS also needs backlight enabled, otherwise the display
+		 * will be blank.
+		 */
+		temp |= (PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT);
+		name = "Single-Link LVDS";
 	} else {	/* DVI */
-		*xres = 1280;
-		*yres = 1024;
 		/* Enable the DVI port, disable the DFP and the backlight */
 		temp &= ~(PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT);
 		temp |= PX_BRDCFG1_DVIEN;
+		name = "DVI";
 	}
 
+	printf("DIU:   Switching to %s monitor @ %ux%u\n", name, xres, yres);
 	out_8(&pixis->brdcfg1, temp);
 
 	/*
@@ -136,7 +141,7 @@  int platform_diu_init(unsigned int *xres, unsigned int *yres)
 	clrsetbits_be32(&gur->pmuxcr, PMUXCR_ELBCDIU_MASK, PMUXCR_ELBCDIU_DIU);
 	pmuxcr = in_be32(&gur->pmuxcr);
 
-	return fsl_diu_init(*xres, pixel_format, 0);
+	return fsl_diu_init(xres, pixel_format, 0);
 }
 
 #ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
diff --git a/doc/README.video b/doc/README.video
index 34e199c..c0d5170 100644
--- a/doc/README.video
+++ b/doc/README.video
@@ -28,3 +28,32 @@  The driver has been tested with the following configurations:
 
 - MPC823FADS with AD7176 on a PAL TV (YCbYCr)	- arsenio@tin.it
 - GENIETV    with AD7177 on a PAL TV (YCbYCr)	- arsenio@tin.it
+
+
+Freescale DIU video controller
+===============================
+
+This controller is found on some Freescale PowerPC SOCs, such as the MPC8610
+and the P1022.  Currently, setting the 'stdout' environment variable to 'video'
+will *not* work with this controller.  Instead, the 'monitor' environment
+variable can be used to enable and configure the driver.
+
+	monitor=<port>,<xres>x<yres>-<depth>@<freq>
+
+Example: monitor=dvi,1280x1024-32@60
+
+	<port>	The monitor port, usually either "lvds" or "dvi".  This
+		is a board-specific value.
+
+	<xres>	The X resolution (in pixels) to use.
+
+	<yres>	The Y resolution (in pixels) to use.
+
+	<depth>	The color depth (in bits) to use.
+
+	<freq>	The frequency (in Hz) to use.
+
+The "diubootargs" environment variable is also set to the string
+"console=tty0 video=fslfb:<xres>x<yres>-<depth>@<freq>,monitor=<port>".  This
+variable allows the string to be passed to the Linux kernel via the kernel
+command line.
diff --git a/drivers/video/fsl_diu_fb.c b/drivers/video/fsl_diu_fb.c
dissimilarity index 63%
index 35ed938..87556e7 100644
--- a/drivers/video/fsl_diu_fb.c
+++ b/drivers/video/fsl_diu_fb.c
@@ -1,513 +1,506 @@ 
-/*
- * Copyright 2007, 2010 Freescale Semiconductor, Inc.
- * York Sun <yorksun@freescale.com>
- *
- * FSL DIU Framebuffer driver
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
- */
-
-#include <common.h>
-#include <i2c.h>
-#include <malloc.h>
-#include <asm/io.h>
-
-#include <fsl_diu_fb.h>
-
-struct fb_videomode {
-	const char *name;	/* optional */
-	unsigned int refresh;		/* optional */
-	unsigned int xres;
-	unsigned int yres;
-	unsigned int pixclock;
-	unsigned int left_margin;
-	unsigned int right_margin;
-	unsigned int upper_margin;
-	unsigned int lower_margin;
-	unsigned int hsync_len;
-	unsigned int vsync_len;
-	unsigned int sync;
-	unsigned int vmode;
-	unsigned int flag;
-};
-
-#define FB_SYNC_VERT_HIGH_ACT	2	/* vertical sync high active	*/
-#define FB_SYNC_COMP_HIGH_ACT	8	/* composite sync high active   */
-#define FB_VMODE_NONINTERLACED  0	/* non interlaced */
-
-/* This setting is used for the ifm pdm360ng with PRIMEVIEW PM070WL3 */
-static struct fb_videomode fsl_diu_mode_800 = {
-	.refresh	= 60,
-	.xres		= 800,
-	.yres		= 480,
-	.pixclock	= 31250,
-	.left_margin	= 86,
-	.right_margin	= 42,
-	.upper_margin	= 33,
-	.lower_margin	= 10,
-	.hsync_len	= 128,
-	.vsync_len	= 2,
-	.sync		= 0,
-	.vmode		= FB_VMODE_NONINTERLACED
-};
-
-/*
- * These parameters give default parameters
- * for video output 1024x768,
- * FIXME - change timing to proper amounts
- * hsync 31.5kHz, vsync 60Hz
- */
-static struct fb_videomode fsl_diu_mode_1024 = {
-	.refresh	= 60,
-	.xres		= 1024,
-	.yres		= 768,
-	.pixclock	= 15385,
-	.left_margin	= 160,
-	.right_margin	= 24,
-	.upper_margin	= 29,
-	.lower_margin	= 3,
-	.hsync_len	= 136,
-	.vsync_len	= 6,
-	.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-	.vmode		= FB_VMODE_NONINTERLACED
-};
-
-static struct fb_videomode fsl_diu_mode_1280 = {
-	.name		= "1280x1024-60",
-	.refresh	= 60,
-	.xres		= 1280,
-	.yres		= 1024,
-	.pixclock	= 9375,
-	.left_margin	= 38,
-	.right_margin	= 128,
-	.upper_margin	= 2,
-	.lower_margin	= 7,
-	.hsync_len	= 216,
-	.vsync_len	= 37,
-	.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-	.vmode		= FB_VMODE_NONINTERLACED
-};
-
-/*
- * These are the fields of area descriptor(in DDR memory) for every plane
- */
-struct diu_ad {
-	/* Word 0(32-bit) in DDR memory */
-	unsigned int pix_fmt; /* hard coding pixel format */
-	/* Word 1(32-bit) in DDR memory */
-	unsigned int addr;
-	/* Word 2(32-bit) in DDR memory */
-	unsigned int src_size_g_alpha;
-	/* Word 3(32-bit) in DDR memory */
-	unsigned int aoi_size;
-	/* Word 4(32-bit) in DDR memory */
-	unsigned int offset_xyi;
-	/* Word 5(32-bit) in DDR memory */
-	unsigned int offset_xyd;
-	/* Word 6(32-bit) in DDR memory */
-	unsigned int ckmax_r:8;
-	unsigned int ckmax_g:8;
-	unsigned int ckmax_b:8;
-	unsigned int res9:8;
-	/* Word 7(32-bit) in DDR memory */
-	unsigned int ckmin_r:8;
-	unsigned int ckmin_g:8;
-	unsigned int ckmin_b:8;
-	unsigned int res10:8;
-	/* Word 8(32-bit) in DDR memory */
-	unsigned int next_ad;
-	/* Word 9(32-bit) in DDR memory, just for 64-bit aligned */
-	unsigned int res1;
-	unsigned int res2;
-	unsigned int res3;
-}__attribute__ ((packed));
-
-/*
- * DIU register map
- */
-struct diu {
-	unsigned int desc[3];
-	unsigned int gamma;
-	unsigned int pallete;
-	unsigned int cursor;
-	unsigned int curs_pos;
-	unsigned int diu_mode;
-	unsigned int bgnd;
-	unsigned int bgnd_wb;
-	unsigned int disp_size;
-	unsigned int wb_size;
-	unsigned int wb_mem_addr;
-	unsigned int hsyn_para;
-	unsigned int vsyn_para;
-	unsigned int syn_pol;
-	unsigned int thresholds;
-	unsigned int int_status;
-	unsigned int int_mask;
-	unsigned int colorbar[8];
-	unsigned int filling;
-	unsigned int plut;
-} __attribute__ ((packed));
-
-struct diu_hw {
-	struct diu *diu_reg;
-	volatile unsigned int mode;		/* DIU operation mode */
-};
-
-struct diu_addr {
-	unsigned char  *  paddr;	/* Virtual address */
-	unsigned int	   offset;
-};
-
-/*
- * Modes of operation of DIU
- */
-#define MFB_MODE0	0	/* DIU off */
-#define MFB_MODE1	1	/* All three planes output to display */
-#define MFB_MODE2	2	/* Plane 1 to display,
-				 * planes 2+3 written back to memory */
-#define MFB_MODE3	3	/* All three planes written back to memory */
-#define MFB_MODE4	4	/* Color bar generation */
-
-#define MAX_CURS		32
-
-static struct fb_info fsl_fb_info;
-static struct diu_addr gamma, cursor;
-static struct diu_ad fsl_diu_fb_ad __attribute__ ((aligned(32)));
-static struct diu_ad dummy_ad __attribute__ ((aligned(32)));
-static unsigned char *dummy_fb;
-static struct diu_hw dr = {
-	.mode = MFB_MODE1,
-};
-
-int fb_enabled = 0;
-int fb_initialized = 0;
-const int default_xres = 1280;
-const int default_pixel_format = 0x88882317;
-
-static int map_video_memory(struct fb_info *info, unsigned long bytes_align);
-static void enable_lcdc(void);
-static void disable_lcdc(void);
-static int fsl_diu_enable_panel(struct fb_info *info);
-static int fsl_diu_disable_panel(struct fb_info *info);
-static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align);
-void diu_set_pixel_clock(unsigned int pixclock);
-
-int fsl_diu_init(int xres, unsigned int pixel_format, int gamma_fix)
-{
-	struct fb_videomode *fsl_diu_mode_db;
-	struct diu_ad *ad = &fsl_diu_fb_ad;
-	struct diu *hw;
-	struct fb_info *info = &fsl_fb_info;
-	struct fb_var_screeninfo *var = &info->var;
-	unsigned char *gamma_table_base;
-	unsigned int i, j;
-
-	debug("Enter fsl_diu_init\n");
-	dr.diu_reg = (struct diu *) (CONFIG_SYS_DIU_ADDR);
-	hw = (struct diu *) dr.diu_reg;
-
-	disable_lcdc();
-
-	switch (xres) {
-	case 800:
-		fsl_diu_mode_db = &fsl_diu_mode_800;
-		break;
-	case 1280:
-		fsl_diu_mode_db = &fsl_diu_mode_1280;
-		break;
-	default:
-		fsl_diu_mode_db = &fsl_diu_mode_1024;
-	}
-
-	if (0 == fb_initialized) {
-		allocate_buf(&gamma, 768, 32);
-		debug("gamma is allocated @ 0x%x\n",
-			(unsigned int)gamma.paddr);
-		allocate_buf(&cursor, MAX_CURS * MAX_CURS * 2, 32);
-		debug("curosr is allocated @ 0x%x\n",
-			(unsigned int)cursor.paddr);
-
-		/* create a dummy fb and dummy ad */
-		dummy_fb = malloc(64);
-		if (NULL == dummy_fb) {
-			printf("Cannot allocate dummy fb\n");
-			return -1;
-		}
-		dummy_ad.addr = cpu_to_le32((unsigned int)dummy_fb);
-		dummy_ad.pix_fmt = 0x88882317;
-		dummy_ad.src_size_g_alpha = 0x04400000;	/* alpha = 0 */
-		dummy_ad.aoi_size = 0x02000400;
-		dummy_ad.offset_xyi = 0;
-		dummy_ad.offset_xyd = 0;
-		dummy_ad.next_ad = 0;
-		/* Memory allocation for framebuffer */
-		if (map_video_memory(info, 32)) {
-			printf("Unable to allocate fb memory 1\n");
-			return -1;
-		}
-	}
-
-	memset(info->screen_base, 0, info->smem_len);
-
-	out_be32(&dr.diu_reg->desc[0], (int)&dummy_ad);
-	out_be32(&dr.diu_reg->desc[1], (int)&dummy_ad);
-	out_be32(&dr.diu_reg->desc[2], (int)&dummy_ad);
-	debug("dummy dr.diu_reg->desc[0] = 0x%x\n", dr.diu_reg->desc[0]);
-	debug("dummy desc[0] = 0x%x\n", hw->desc[0]);
-
-	/* read mode info */
-	var->xres = fsl_diu_mode_db->xres;
-	var->yres = fsl_diu_mode_db->yres;
-	var->bits_per_pixel = 32;
-	var->pixclock = fsl_diu_mode_db->pixclock;
-	var->left_margin = fsl_diu_mode_db->left_margin;
-	var->right_margin = fsl_diu_mode_db->right_margin;
-	var->upper_margin = fsl_diu_mode_db->upper_margin;
-	var->lower_margin = fsl_diu_mode_db->lower_margin;
-	var->hsync_len = fsl_diu_mode_db->hsync_len;
-	var->vsync_len = fsl_diu_mode_db->vsync_len;
-	var->sync = fsl_diu_mode_db->sync;
-	var->vmode = fsl_diu_mode_db->vmode;
-	info->line_length = var->xres * var->bits_per_pixel / 8;
-
-	ad->pix_fmt = pixel_format;
-	ad->addr    = cpu_to_le32((unsigned int)info->screen_base);
-	ad->src_size_g_alpha
-			= cpu_to_le32((var->yres << 12) | var->xres);
-	/* fix me. AOI should not be greater than display size */
-	ad->aoi_size	= cpu_to_le32(( var->yres << 16) |  var->xres);
-	ad->offset_xyi = 0;
-	ad->offset_xyd = 0;
-
-	/* Disable chroma keying function */
-	ad->ckmax_r = 0;
-	ad->ckmax_g = 0;
-	ad->ckmax_b = 0;
-
-	ad->ckmin_r = 255;
-	ad->ckmin_g = 255;
-	ad->ckmin_b = 255;
-
-	gamma_table_base = gamma.paddr;
-	debug("gamma_table_base is allocated @ 0x%x\n",
-		(unsigned int)gamma_table_base);
-
-	/* Prep for DIU init  - gamma table */
-
-	for (i = 0; i <= 2; i++)
-		for (j = 0; j <= 255; j++)
-			*gamma_table_base++ = j;
-
-	if (gamma_fix == 1) {	/* fix the gamma */
-		debug("Fix gamma table\n");
-		gamma_table_base = gamma.paddr;
-		for (i = 0; i < 256*3; i++) {
-			gamma_table_base[i] = (gamma_table_base[i] << 2)
-				| ((gamma_table_base[i] >> 6) & 0x03);
-		}
-	}
-
-	debug("update-lcdc: HW - %p\n Disabling DIU\n", hw);
-
-	/* Program DIU registers */
-
-	out_be32(&hw->gamma, (int)gamma.paddr);
-	out_be32(&hw->cursor, (int)cursor.paddr);
-	out_be32(&hw->bgnd, 0x007F7F7F);
-	out_be32(&hw->bgnd_wb, 0);				/* BGND_WB */
-	out_be32(&hw->disp_size, var->yres << 16 | var->xres);	/* DISP SIZE */
-	out_be32(&hw->wb_size, 0);				/* WB SIZE */
-	out_be32(&hw->wb_mem_addr, 0);				/* WB MEM ADDR */
-	out_be32(&hw->hsyn_para, var->left_margin << 22 |	/* BP_H */
-			var->hsync_len << 11   |	/* PW_H */
-			var->right_margin);		/* FP_H */
-
-	out_be32(&hw->vsyn_para, var->upper_margin << 22 |	/* BP_V */
-			var->vsync_len << 11    |	/* PW_V  */
-			var->lower_margin);		/* FP_V  */
-
-	out_be32(&hw->syn_pol, 0);			/* SYNC SIGNALS POLARITY */
-	out_be32(&hw->thresholds, 0x00037800);		/* The Thresholds */
-	out_be32(&hw->int_status, 0);			/* INTERRUPT STATUS */
-	out_be32(&hw->int_mask, 0);			/* INT MASK */
-	out_be32(&hw->plut, 0x01F5F666);
-	/* Pixel Clock configuration */
-	debug("DIU pixclock in ps - %d\n", var->pixclock);
-	diu_set_pixel_clock(var->pixclock);
-
-	fb_initialized = 1;
-
-	/* Enable the DIU */
-	fsl_diu_enable_panel(info);
-	enable_lcdc();
-
-	return 0;
-}
-
-char *fsl_fb_open(struct fb_info **info)
-{
-	*info = &fsl_fb_info;
-	return fsl_fb_info.screen_base;
-}
-
-void fsl_diu_close(void)
-{
-	struct fb_info *info = &fsl_fb_info;
-	fsl_diu_disable_panel(info);
-}
-
-static int fsl_diu_enable_panel(struct fb_info *info)
-{
-	struct diu *hw = dr.diu_reg;
-	struct diu_ad *ad = &fsl_diu_fb_ad;
-
-	debug("Entered: enable_panel\n");
-	if (in_be32(&hw->desc[0]) != (unsigned)ad)
-		out_be32(&hw->desc[0], (unsigned)ad);
-	debug("desc[0] = 0x%x\n", hw->desc[0]);
-	return 0;
-}
-
-static int fsl_diu_disable_panel(struct fb_info *info)
-{
-	struct diu *hw = dr.diu_reg;
-
-	debug("Entered: disable_panel\n");
-	if (in_be32(&hw->desc[0]) != (unsigned)&dummy_ad)
-		out_be32(&hw->desc[0], (unsigned)&dummy_ad);
-	return 0;
-}
-
-static int map_video_memory(struct fb_info *info, unsigned long bytes_align)
-{
-	unsigned long offset;
-	unsigned long mask;
-
-	debug("Entered: map_video_memory\n");
-	/* allocate maximum 1280*1024 with 32bpp */
-	info->smem_len = 1280 * 4 *1024 + bytes_align;
-	debug("MAP_VIDEO_MEMORY: smem_len = %d\n", info->smem_len);
-	info->screen_base = malloc(info->smem_len);
-	if (info->screen_base == NULL) {
-		printf("Unable to allocate fb memory\n");
-		return -1;
-	}
-	info->smem_start = (unsigned int) info->screen_base;
-	mask = bytes_align - 1;
-	offset = (unsigned long)info->screen_base & mask;
-	if (offset) {
-		info->screen_base += (bytes_align - offset);
-		info->smem_len = info->smem_len - (bytes_align - offset);
-	} else
-		info->smem_len = info->smem_len - bytes_align;
-
-	info->screen_size = info->smem_len;
-
-	debug("Allocated fb @ 0x%08lx, size=%d.\n",
-		info->smem_start, info->smem_len);
-
-	return 0;
-}
-
-static void enable_lcdc(void)
-{
-	struct diu *hw = dr.diu_reg;
-
-	debug("Entered: enable_lcdc, fb_enabled = %d\n", fb_enabled);
-	if (!fb_enabled) {
-		out_be32(&hw->diu_mode, dr.mode);
-		fb_enabled++;
-	}
-	debug("diu_mode = %d\n", hw->diu_mode);
-}
-
-static void disable_lcdc(void)
-{
-	struct diu *hw = dr.diu_reg;
-
-	debug("Entered: disable_lcdc, fb_enabled = %d\n", fb_enabled);
-	if (fb_enabled) {
-		out_be32(&hw->diu_mode, 0);
-		fb_enabled = 0;
-	}
-}
-
-/*
- * Align to 64-bit(8-byte), 32-byte, etc.
- */
-static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align)
-{
-	u32 offset, ssize;
-	u32 mask;
-
-	debug("Entered: allocate_buf\n");
-	ssize = size + bytes_align;
-	buf->paddr = malloc(ssize);
-	if (!buf->paddr)
-		return -1;
-
-	memset(buf->paddr, 0, ssize);
-	mask = bytes_align - 1;
-	offset = (u32)buf->paddr & mask;
-	if (offset) {
-		buf->offset = bytes_align - offset;
-		buf->paddr = (unsigned char *) ((u32)buf->paddr + offset);
-	} else
-		buf->offset = 0;
-	return 0;
-}
-
-#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)
-#include <stdio_dev.h>
-#include <video_fb.h>
-/*
- * The Graphic Device
- */
-static GraphicDevice ctfb;
-
-void *video_hw_init(void)
-{
-	struct fb_info *info;
-
-	if (platform_diu_init(&ctfb.winSizeX, &ctfb.winSizeY) < 0)
-		return NULL;
-
-	/* fill in Graphic device struct */
-	sprintf(ctfb.modeIdent, "%ix%ix%i %ikHz %iHz",
-		ctfb.winSizeX, ctfb.winSizeY, 32, 64, 60);
-
-	ctfb.frameAdrs = (unsigned int)fsl_fb_open(&info);
-	ctfb.plnSizeX = ctfb.winSizeX;
-	ctfb.plnSizeY = ctfb.winSizeY;
-
-	ctfb.gdfBytesPP = 4;
-	ctfb.gdfIndex = GDF_32BIT_X888RGB;
-
-	ctfb.isaBase = 0;
-	ctfb.pciBase = 0;
-	ctfb.memSize = info->screen_size;
-
-	/* Cursor Start Address */
-	ctfb.dprBase = 0;
-	ctfb.vprBase = 0;
-	ctfb.cprBase = 0;
-
-	return &ctfb;
-}
-#endif /* defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE) */
+/*
+ * Copyright 2007, 2010-2011 Freescale Semiconductor, Inc.
+ * Authors: York Sun <yorksun@freescale.com>
+ *          Timur Tabi <timur@freescale.com>
+ *
+ * FSL DIU Framebuffer driver
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <linux/ctype.h>
+
+#include <video_fb.h>
+#include <fsl_diu_fb.h>
+
+struct fb_var_screeninfo {
+	unsigned int xres;		/* visible resolution		*/
+	unsigned int yres;
+
+	unsigned int bits_per_pixel;	/* guess what			*/
+
+	/* Timing: All values in pixclocks, except pixclock (of course) */
+	unsigned int pixclock;		/* pixel clock in ps (pico seconds) */
+	unsigned int left_margin;	/* time from sync to picture	*/
+	unsigned int right_margin;	/* time from picture to sync	*/
+	unsigned int upper_margin;	/* time from sync to picture	*/
+	unsigned int lower_margin;
+	unsigned int hsync_len;		/* length of horizontal sync	*/
+	unsigned int vsync_len;		/* length of vertical sync	*/
+	unsigned int sync;		/* see FB_SYNC_*		*/
+	unsigned int vmode;		/* see FB_VMODE_*		*/
+	unsigned int rotate;		/* angle we rotate counter clockwise */
+};
+
+struct fb_info {
+	struct fb_var_screeninfo var;	/* Current var */
+	unsigned int smem_len;		/* Length of frame buffer mem */
+	unsigned int type;		/* see FB_TYPE_*		*/
+	unsigned int line_length;	/* length of a line in bytes    */
+
+	void *screen_base;
+	unsigned long screen_size;
+};
+
+struct fb_videomode {
+	const char *name;	/* optional */
+	unsigned int refresh;		/* optional */
+	unsigned int xres;
+	unsigned int yres;
+	unsigned int pixclock;
+	unsigned int left_margin;
+	unsigned int right_margin;
+	unsigned int upper_margin;
+	unsigned int lower_margin;
+	unsigned int hsync_len;
+	unsigned int vsync_len;
+	unsigned int sync;
+	unsigned int vmode;
+	unsigned int flag;
+};
+
+#define FB_SYNC_VERT_HIGH_ACT	2	/* vertical sync high active	*/
+#define FB_SYNC_COMP_HIGH_ACT	8	/* composite sync high active   */
+#define FB_VMODE_NONINTERLACED  0	/* non interlaced */
+
+/* This setting is used for the ifm pdm360ng with PRIMEVIEW PM070WL3 */
+static struct fb_videomode fsl_diu_mode_800 = {
+	.name		= "800x600-60",
+	.refresh	= 60,
+	.xres		= 800,
+	.yres		= 480,
+	.pixclock	= 31250,
+	.left_margin	= 86,
+	.right_margin	= 42,
+	.upper_margin	= 33,
+	.lower_margin	= 10,
+	.hsync_len	= 128,
+	.vsync_len	= 2,
+	.sync		= 0,
+	.vmode		= FB_VMODE_NONINTERLACED
+};
+
+/*
+ * These parameters give default parameters
+ * for video output 1024x768,
+ * FIXME - change timing to proper amounts
+ * hsync 31.5kHz, vsync 60Hz
+ */
+static struct fb_videomode fsl_diu_mode_1024 = {
+	.name		= "1024x768-60",
+	.refresh	= 60,
+	.xres		= 1024,
+	.yres		= 768,
+	.pixclock	= 15385,
+	.left_margin	= 160,
+	.right_margin	= 24,
+	.upper_margin	= 29,
+	.lower_margin	= 3,
+	.hsync_len	= 136,
+	.vsync_len	= 6,
+	.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.vmode		= FB_VMODE_NONINTERLACED
+};
+
+static struct fb_videomode fsl_diu_mode_1280 = {
+	.name		= "1280x1024-60",
+	.refresh	= 60,
+	.xres		= 1280,
+	.yres		= 1024,
+	.pixclock	= 9375,
+	.left_margin	= 38,
+	.right_margin	= 128,
+	.upper_margin	= 2,
+	.lower_margin	= 7,
+	.hsync_len	= 216,
+	.vsync_len	= 37,
+	.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.vmode		= FB_VMODE_NONINTERLACED
+};
+
+/*
+ * These are the fields of area descriptor(in DDR memory) for every plane
+ */
+struct diu_ad {
+	/* Word 0(32-bit) in DDR memory */
+	__le32 pix_fmt; /* hard coding pixel format */
+	/* Word 1(32-bit) in DDR memory */
+	__le32 addr;
+	/* Word 2(32-bit) in DDR memory */
+	__le32 src_size_g_alpha;
+	/* Word 3(32-bit) in DDR memory */
+	__le32 aoi_size;
+	/* Word 4(32-bit) in DDR memory */
+	__le32 offset_xyi;
+	/* Word 5(32-bit) in DDR memory */
+	__le32 offset_xyd;
+	/* Word 6(32-bit) in DDR memory */
+	__le32 ckmax_r:8;
+	__le32 ckmax_g:8;
+	__le32 ckmax_b:8;
+	__le32 res9:8;
+	/* Word 7(32-bit) in DDR memory */
+	__le32 ckmin_r:8;
+	__le32 ckmin_g:8;
+	__le32 ckmin_b:8;
+	__le32 res10:8;
+	/* Word 8(32-bit) in DDR memory */
+	__le32 next_ad;
+	/* Word 9(32-bit) in DDR memory, just for 64-bit aligned */
+	__le32 res[3];
+}__attribute__ ((packed));
+
+/*
+ * DIU register map
+ */
+struct diu {
+	__be32 desc[3];
+	__be32 gamma;
+	__be32 pallete;
+	__be32 cursor;
+	__be32 curs_pos;
+	__be32 diu_mode;
+	__be32 bgnd;
+	__be32 bgnd_wb;
+	__be32 disp_size;
+	__be32 wb_size;
+	__be32 wb_mem_addr;
+	__be32 hsyn_para;
+	__be32 vsyn_para;
+	__be32 syn_pol;
+	__be32 thresholds;
+	__be32 int_status;
+	__be32 int_mask;
+	__be32 colorbar[8];
+	__be32 filling;
+	__be32 plut;
+} __attribute__ ((packed));
+
+struct diu_addr {
+	void *vaddr;		/* Virtual address */
+	u32 paddr;		/* 32-bit physical address */
+	unsigned int offset;	/* Alignment offset */
+};
+
+static struct fb_info info;
+
+/*
+ * Align to 64-bit(8-byte), 32-byte, etc.
+ */
+static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align)
+{
+	u32 offset, ssize;
+	u32 mask;
+
+	ssize = size + bytes_align;
+	buf->vaddr = malloc(ssize);
+	if (!buf->vaddr)
+		return -1;
+
+	memset(buf->vaddr, 0, ssize);
+	mask = bytes_align - 1;
+	offset = (u32)buf->vaddr & mask;
+	if (offset) {
+		buf->offset = bytes_align - offset;
+		buf->vaddr += offset;
+	} else
+		buf->offset = 0;
+
+	buf->paddr = virt_to_phys(buf->vaddr);
+	return 0;
+}
+
+/*
+ * Allocate a framebuffer and an Area Descriptor that points to it.  Both
+ * are created in the same memory block.  The Area Descriptor is updated to
+ * point to the framebuffer memory. Memory is aligned as needed.
+ */
+static struct diu_ad *allocate_fb(unsigned int xres, unsigned int yres,
+				  unsigned int depth, void **fb)
+{
+	unsigned long size = xres * yres * depth;
+	struct diu_addr addr;
+	struct diu_ad *ad;
+	size_t ad_size = roundup(sizeof(struct diu_ad), 32);
+
+	/*
+	 * Allocate a memory block that holds the Area Descriptor and the
+	 * frame buffer right behind it.  To keep the code simple, everything
+	 * is aligned on a 32-byte address.
+	 */
+	if (allocate_buf(&addr, ad_size + size, 32) < 0)
+		return NULL;
+
+	ad = addr.vaddr;
+	ad->addr = cpu_to_le32(addr.paddr + ad_size);
+	ad->aoi_size = cpu_to_le32((yres << 16) | xres);
+	ad->src_size_g_alpha = cpu_to_le32((yres << 12) | xres);
+	ad->offset_xyi = 0;
+	ad->offset_xyd = 0;
+
+	if (fb)
+		*fb = addr.vaddr + ad_size;
+
+	return ad;
+}
+
+int fsl_diu_init(int xres, u32 pixel_format, int gamma_fix)
+{
+	struct fb_videomode *fsl_diu_mode_db;
+	struct diu_ad *ad;
+	struct diu *hw = (struct diu *)CONFIG_SYS_DIU_ADDR;
+	u8 *gamma_table_base;
+	unsigned int i, j;
+	struct diu_ad *dummy_ad;
+	struct diu_addr gamma;
+
+	switch (xres) {
+	case 800:
+		fsl_diu_mode_db = &fsl_diu_mode_800;
+		break;
+	case 1280:
+		fsl_diu_mode_db = &fsl_diu_mode_1280;
+		break;
+	default:
+		fsl_diu_mode_db = &fsl_diu_mode_1024;
+	}
+
+	/* The AD struct for the dummy framebuffer and the FB itself */
+	dummy_ad = allocate_fb(2, 4, 4, NULL);
+	if (!dummy_ad) {
+		printf("DIU:   Out of memory\n");
+		return -1;
+	}
+	dummy_ad->pix_fmt = 0x88883316;
+
+	/* read mode info */
+	info.var.xres = fsl_diu_mode_db->xres;
+	info.var.yres = fsl_diu_mode_db->yres;
+	info.var.bits_per_pixel = 32;
+	info.var.pixclock = fsl_diu_mode_db->pixclock;
+	info.var.left_margin = fsl_diu_mode_db->left_margin;
+	info.var.right_margin = fsl_diu_mode_db->right_margin;
+	info.var.upper_margin = fsl_diu_mode_db->upper_margin;
+	info.var.lower_margin = fsl_diu_mode_db->lower_margin;
+	info.var.hsync_len = fsl_diu_mode_db->hsync_len;
+	info.var.vsync_len = fsl_diu_mode_db->vsync_len;
+	info.var.sync = fsl_diu_mode_db->sync;
+	info.var.vmode = fsl_diu_mode_db->vmode;
+	info.line_length = info.var.xres * info.var.bits_per_pixel / 8;
+
+	/* Memory allocation for framebuffer */
+	info.smem_len =
+		info.var.xres * info.var.yres * (info.var.bits_per_pixel / 8);
+	ad = allocate_fb(info.var.xres, info.var.yres,
+			 info.var.bits_per_pixel / 8, &info.screen_base);
+	if (!ad) {
+		printf("DIU:   Out of memory\n");
+		return -1;
+	}
+
+	ad->pix_fmt = pixel_format;
+
+	/* Disable chroma keying function */
+	ad->ckmax_r = 0;
+	ad->ckmax_g = 0;
+	ad->ckmax_b = 0;
+
+	ad->ckmin_r = 255;
+	ad->ckmin_g = 255;
+	ad->ckmin_b = 255;
+
+	/* Initialize the gamma table */
+	if (allocate_buf(&gamma, 256 * 3, 32) < 0) {
+		printf("DIU:   Out of memory\n");
+		return -1;
+	}
+	gamma_table_base = gamma.vaddr;
+	for (i = 0; i <= 2; i++)
+		for (j = 0; j < 256; j++)
+			*gamma_table_base++ = j;
+
+	if (gamma_fix == 1) {	/* fix the gamma */
+		gamma_table_base = gamma.vaddr;
+		for (i = 0; i < 256 * 3; i++) {
+			gamma_table_base[i] = (gamma_table_base[i] << 2)
+				| ((gamma_table_base[i] >> 6) & 0x03);
+		}
+	}
+
+	/* Program DIU registers */
+	out_be32(&hw->diu_mode, 0);	/* Temporarily disable the DIU */
+
+	out_be32(&hw->gamma, gamma.paddr);
+	out_be32(&hw->bgnd, 0x007F7F7F);
+	out_be32(&hw->bgnd_wb, 0);
+	out_be32(&hw->disp_size, info.var.yres << 16 | info.var.xres);
+	out_be32(&hw->wb_size, 0);
+	out_be32(&hw->wb_mem_addr, 0);
+	out_be32(&hw->hsyn_para, info.var.left_margin << 22 |
+			info.var.hsync_len << 11 |
+			info.var.right_margin);
+
+	out_be32(&hw->vsyn_para, info.var.upper_margin << 22 |
+			info.var.vsync_len << 11 |
+			info.var.lower_margin);
+
+	out_be32(&hw->syn_pol, 0);
+	out_be32(&hw->thresholds, 0x00037800);
+	out_be32(&hw->int_status, 0);
+	out_be32(&hw->int_mask, 0);
+	out_be32(&hw->plut, 0x01F5F666);
+	/* Pixel Clock configuration */
+	diu_set_pixel_clock(info.var.pixclock);
+
+	/* Set the frame buffers */
+	out_be32(&hw->desc[0], virt_to_phys(ad));
+	out_be32(&hw->desc[1], virt_to_phys(dummy_ad));
+	out_be32(&hw->desc[2], virt_to_phys(dummy_ad));
+
+	/* Enable the DIU, set display to all three planes */
+	out_be32(&hw->diu_mode, 1);
+
+	return 0;
+}
+
+/*
+ * Parse the 'monitor' environment variable
+ *
+ * Example: "monitor=dvi,1280x1024-32@60".  See doc/README.video for more
+ * information on how to set the variable.
+ *
+ * @port: pointer to a caller buffer that will hold the port name
+ * @length: size of the 'port' buffer, should be at least 8
+ * @xres: returned value of X-resolution
+ * @yres: returned value of Y-resolution
+ * @depth: returned value of color depth
+ * @freq: returned value of monitor frequency
+ *
+ * Returns 1 if valid values were found, 0 otherwise
+ *
+ * On older U-Boot installations, the 'monitor' environment variable
+ * only contains the port, but this is no longer supported.
+ */
+static int diu_get_video_params(char *port, size_t length, unsigned int *xres,
+			 unsigned int *yres, unsigned int *depth,
+			 unsigned int *freq)
+{
+	char *p, *p2;
+
+	p = getenv("monitor");
+	if (!p) {
+		/* 'monitor' variable is not defined, so don't enable video */
+		return 0;
+	}
+
+	/*
+	 * Get the port name.  This is clunky because we want to skip over any
+	 * non-alpha characters that happen to be in the beginning of the
+	 * string, but we also need to copy only up to the comma after the
+	 * port name, and then we need to make the string null-terminated.
+	 */
+	p2 = p;
+	while (*p2 && !isalpha(*p2))
+		p2++;
+	p = p2;
+	while (*p2 && isalpha(*p2))
+		p2++;
+
+	if ((p2 - p) > (length - 1)) {
+		/* port name is too long */
+		return 0;
+	}
+	strncpy(port, p, p2 - p);
+	port[p2 - p] = 0;
+
+	/* Get the X-resolution*/
+	p = p2;
+	while (*p && !isdigit(*p))
+		p++;
+	*xres = simple_strtoul(p, &p, 10);
+	if (!*xres)
+		return 0;
+
+	/* Get the Y-resolution */
+	while (*p && !isdigit(*p))
+		p++;
+	*yres = simple_strtoul(p, &p, 10);
+	if (!*yres)
+		return 0;
+
+	/* Get the depth */
+	while (*p && !isdigit(*p))
+		p++;
+	*depth = simple_strtoul(p, &p, 10);
+	if (!*depth)
+		return 0;
+
+	/* Get the frequency */
+	while (*p && !isdigit(*p))
+		p++;
+	*freq = simple_strtoul(p, &p, 10);
+	if (!*freq)
+		return 0;
+
+	return 1;
+}
+
+void *video_hw_init(void)
+{
+	static GraphicDevice ctfb;
+	char port[8], diubootargs[64];
+	unsigned int depth = 0, freq = 0;
+
+	if (!diu_get_video_params(port, sizeof(port), &ctfb.winSizeX,
+				  &ctfb.winSizeY, &depth, &freq))
+		return NULL;
+
+	if (platform_diu_init(ctfb.winSizeX, ctfb.winSizeY) < 0)
+		return NULL;
+
+	/* fill in Graphic device struct */
+	sprintf(ctfb.modeIdent, "%ix%ix%i %ikHz %iHz",
+		ctfb.winSizeX, ctfb.winSizeY, depth, 64, freq);
+
+	ctfb.frameAdrs = (unsigned int)info.screen_base;
+	ctfb.plnSizeX = ctfb.winSizeX;
+	ctfb.plnSizeY = ctfb.winSizeY;
+
+	ctfb.gdfBytesPP = 4;
+	ctfb.gdfIndex = GDF_32BIT_X888RGB;
+
+	ctfb.isaBase = 0;
+	ctfb.pciBase = 0;
+	ctfb.memSize = info.screen_size;
+
+	/* Cursor Start Address */
+	ctfb.dprBase = 0;
+	ctfb.vprBase = 0;
+	ctfb.cprBase = 0;
+
+	/* Set the 'diubootargs' environment variable */
+	sprintf(diubootargs, "console=tty0 video=fslfb:%ux%u-%u@%u,monitor=%s",
+		ctfb.winSizeX, ctfb.winSizeY, depth, freq, port);
+	setenv("diubootargs", diubootargs);
+
+	return &ctfb;
+}
diff --git a/include/configs/MPC8610HPCD.h b/include/configs/MPC8610HPCD.h
index de01c31..60f2a16 100644
--- a/include/configs/MPC8610HPCD.h
+++ b/include/configs/MPC8610HPCD.h
@@ -1,5 +1,5 @@ 
 /*
- * Copyright 2007, 2010 Freescale Semiconductor, Inc.
+ * Copyright 2007-2011 Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -23,6 +23,8 @@ 
 
 
 /* video */
+#define CONFIG_FSL_DIU_FB
+
 #ifdef CONFIG_FSL_DIU_FB
 #define CONFIG_SYS_DIU_ADDR	(CONFIG_SYS_CCSRBAR + 0x2c000)
 #define CONFIG_VIDEO
@@ -625,8 +627,6 @@ 
  "diuregs=md e002c000 1d\0" \
  "dium=mw e002c01c\0" \
  "diuerr=md e002c014 1\0" \
- "othbootargs=diufb=15M video=fslfb:1280x1024-32@60,monitor=0 debug\0" \
- "monitor=0-DVI\0" \
  "pmregs=md e00e1000 2b\0" \
  "lawregs=md e0000c08 4b\0" \
  "lbcregs=md e0005000 36\0" \
@@ -646,23 +646,21 @@ 
  "ramdiskfile=8610hpcd/ramdisk.uboot\0"                         \
  "fdtaddr=c00000\0"                                             \
  "fdtfile=8610hpcd/mpc8610_hpcd.dtb\0"                          \
- "bdev=sda3\0"							\
- "othbootargs=diufb=15M video=fslfb:1280x1024-32@60,monitor=0\0"\
- "monitor=0-DVI\0"
+ "bdev=sda3\0"
 #endif
 
 #define CONFIG_NFSBOOTCOMMAND					\
  "setenv bootargs root=/dev/nfs rw "				\
 	"nfsroot=$serverip:$rootpath "				\
 	"ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \
-	"console=$consoledev,$baudrate $othbootargs;"		\
+	"console=$consoledev,$baudrate $diubootargs $othbootargs;"	\
  "tftp $loadaddr $bootfile;"					\
  "tftp $fdtaddr $fdtfile;"					\
  "bootm $loadaddr - $fdtaddr"
 
 #define CONFIG_RAMBOOTCOMMAND \
  "setenv bootargs root=/dev/ram rw "				\
-	"console=$consoledev,$baudrate $othbootargs;"		\
+	"console=$consoledev,$baudrate $diubootargs $othbootargs;"	\
  "tftp $ramdiskaddr $ramdiskfile;"				\
  "tftp $loadaddr $bootfile;"					\
  "tftp $fdtaddr $fdtfile;"					\
@@ -670,7 +668,7 @@ 
 
 #define CONFIG_BOOTCOMMAND		\
  "setenv bootargs root=/dev/$bdev rw "	\
-	"console=$consoledev,$baudrate $othbootargs;"	\
+	"console=$consoledev,$baudrate $diubootargs $othbootargs;"	\
  "tftp $loadaddr $bootfile;"		\
  "tftp $fdtaddr $fdtfile;"		\
  "bootm $loadaddr - $fdtaddr"
diff --git a/include/configs/P1022DS.h b/include/configs/P1022DS.h
index ed2bada..29380a1 100644
--- a/include/configs/P1022DS.h
+++ b/include/configs/P1022DS.h
@@ -185,6 +185,8 @@ 
 #define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
 
 /* Video */
+#define CONFIG_FSL_DIU_FB
+
 #ifdef CONFIG_FSL_DIU_FB
 #define CONFIG_SYS_DIU_ADDR	(CONFIG_SYS_CCSRBAR + 0x10000)
 #define CONFIG_VIDEO
@@ -445,13 +447,11 @@ 
 	"bdev=sda3\0"		  			      		\
 	"diuregs=md e002c000 1d\0"			 		\
 	"dium=mw e002c01c\0" 						\
-	"diuerr=md e002c014 1\0" 					\
-	"othbootargs=diufb=15M video=fslfb:1280x1024-32@60,monitor=0 tty0\0" \
-	"monitor=0-DVI\0"
+	"diuerr=md e002c014 1\0"
 
 #define CONFIG_HDBOOT					\
 	"setenv bootargs root=/dev/$bdev rw "		\
-	"console=$consoledev,$baudrate $othbootargs;"	\
+	"console=$consoledev,$baudrate $diubootargs $othbootargs;"	\
 	"tftp $loadaddr $bootfile;"			\
 	"tftp $fdtaddr $fdtfile;"			\
 	"bootm $loadaddr - $fdtaddr"
@@ -460,14 +460,14 @@ 
 	"setenv bootargs root=/dev/nfs rw "				\
 	"nfsroot=$serverip:$rootpath "					\
 	"ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \
-	"console=$consoledev,$baudrate $othbootargs;"			\
+	"console=$consoledev,$baudrate $diubootargs $othbootargs;"	\
 	"tftp $loadaddr $bootfile;"					\
 	"tftp $fdtaddr $fdtfile;"					\
 	"bootm $loadaddr - $fdtaddr"
 
 #define CONFIG_RAMBOOTCOMMAND						\
 	"setenv bootargs root=/dev/ram rw "				\
-	"console=$consoledev,$baudrate $othbootargs;"			\
+	"console=$consoledev,$baudrate $diubootargs $othbootargs;"	\
 	"tftp $ramdiskaddr $ramdiskfile;"				\
 	"tftp $loadaddr $bootfile;"					\
 	"tftp $fdtaddr $fdtfile;"					\
diff --git a/include/fsl_diu_fb.h b/include/fsl_diu_fb.h
dissimilarity index 62%
index 87443e1..ee94cb3 100644
--- a/include/fsl_diu_fb.h
+++ b/include/fsl_diu_fb.h
@@ -1,60 +1,31 @@ 
-/*
- * Copyright 2007 Freescale Semiconductor, Inc.
- * York Sun <yorksun@freescale.com>
- *
- * FSL DIU Framebuffer driver
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
- */
-
-struct fb_var_screeninfo {
-	unsigned int xres;		/* visible resolution		*/
-	unsigned int yres;
-
-	unsigned int bits_per_pixel;	/* guess what			*/
-
-	/* Timing: All values in pixclocks, except pixclock (of course) */
-	unsigned int pixclock;		/* pixel clock in ps (pico seconds) */
-	unsigned int left_margin;	/* time from sync to picture	*/
-	unsigned int right_margin;	/* time from picture to sync	*/
-	unsigned int upper_margin;	/* time from sync to picture	*/
-	unsigned int lower_margin;
-	unsigned int hsync_len;		/* length of horizontal sync	*/
-	unsigned int vsync_len;		/* length of vertical sync	*/
-	unsigned int sync;		/* see FB_SYNC_*		*/
-	unsigned int vmode;		/* see FB_VMODE_*		*/
-	unsigned int rotate;		/* angle we rotate counter clockwise */
-};
-
-struct fb_info {
-	struct fb_var_screeninfo var;	/* Current var */
-	unsigned long smem_start;	/* Start of frame buffer mem */
-					/* (physical address) */
-	unsigned int smem_len;		/* Length of frame buffer mem */
-	unsigned int type;		/* see FB_TYPE_*		*/
-	unsigned int line_length;	/* length of a line in bytes    */
-
-	char *screen_base;
-	unsigned long screen_size;
-};
-
-
-extern char *fsl_fb_open(struct fb_info **info);
-int fsl_diu_init(int xres, unsigned int pixel_format, int gamma_fix);
-int platform_diu_init(unsigned int *xres, unsigned int *yres);
+/*
+ * Copyright 2007, 2011 Freescale Semiconductor, Inc.
+ * Authors: York Sun <yorksun@freescale.com>
+ *          Timur Tabi <timur@freescale.com>
+ *
+ * FSL DIU Framebuffer driver
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+int fsl_diu_init(int xres, u32 pixel_format, int gamma_fix);
+
+/* Prototypes for external board-specific functions */
+int platform_diu_init(unsigned int xres, unsigned int yres);
+void diu_set_pixel_clock(unsigned int pixclock);