Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH 4/4] Drivers: video: sbuslib: fixed a brace coding style issue
From: Zac Storer @ 2011-11-18  4:38 UTC (permalink / raw)
  To: FlorianSchandinat; +Cc: linux-fbdev, linux-kernel, Zac Storer

Fixed a brace coding style issue.

Signed-off-by: Zac Storer <zac.3.14159@gmail.com>
---
 drivers/video/sbuslib.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
index 37d764a..3c1de98 100644
--- a/drivers/video/sbuslib.c
+++ b/drivers/video/sbuslib.c
@@ -76,7 +76,7 @@ int sbusfb_mmap_helper(struct sbus_mmap_map *map,
 				map_offset = (physbase + map[i].poff) & POFF_MASK;
 				break;
 			}
-		if (!map_size){
+		if (!map_size) {
 			page += PAGE_SIZE;
 			continue;
 		}
-- 
1.7.7.3


^ permalink raw reply related

* [PATCH 5/5] Drivers: video: riva: riva_hw: fixed a brace coding style issue
From: Zac Storer @ 2011-11-18  4:45 UTC (permalink / raw)
  To: FlorianSchandinat; +Cc: linux-fbdev, linux-kernel, Zac Storer

Fixed a brace coding style issue.

Signed-off-by: Zac Storer <zac.3.14159@gmail.com>
---
 drivers/video/riva/riva_hw.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/riva/riva_hw.c
index 78fdbf5..c4b8a6f 100644
--- a/drivers/video/riva/riva_hw.c
+++ b/drivers/video/riva/riva_hw.c
@@ -994,7 +994,7 @@ static void nv10CalcArbitration
               clwm = clwm_mt;
   */
           /* Finally, a heuristic check when width = 64 bits */
-          if(width = 1){
+          if(width = 1) {
               nvclk_fill = nvclk_freq * 8;
               if(crtc_drain_rate * 100 >= nvclk_fill * 102)
                       clwm = 0xfff; /*Large number to fail */
-- 
1.7.7.3


^ permalink raw reply related

* [PATCH 6/6] Drivers: video: riva: riva_hw: fixed a brace coding style issue
From: Zac Storer @ 2011-11-18  4:50 UTC (permalink / raw)
  To: adaplas; +Cc: linux-fbdev, linux-kernel, Zac Storer

Fixed a brace coding style issue.

Signed-off-by: Zac Storer <zac.3.14159@gmail.com>
---
 drivers/video/riva/riva_hw.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/riva/riva_hw.c
index c4b8a6f..5cd1d71 100644
--- a/drivers/video/riva/riva_hw.c
+++ b/drivers/video/riva/riva_hw.c
@@ -1038,7 +1038,7 @@ static void nv10CalcArbitration
             min_mclk_extra--;
           }
       } else {
-        if (clwm > 1023){ /* Have some margin */
+        if (clwm > 1023) { /* Have some margin */
           fifo->valid = 0;
           found = 0;
           if(min_mclk_extra = 0)   
-- 
1.7.7.3


^ permalink raw reply related

* [GIT PULL] OMAP DSS fixes for 3.2-rc
From: Tomi Valkeinen @ 2011-11-18  8:16 UTC (permalink / raw)
  To: florianschandinat; +Cc: linux-fbdev, linux-omap mailing list

[-- Attachment #1: Type: text/plain, Size: 829 bytes --]

Hi Florian,

Here are a few OMAP display subsystem fixes for 3.2-rc.

One for the old omapfb, which was missing include module.h, and two for
the omapdss fixing issues related to HDMI.

 Tomi

The following changes since commit cfcfc9eca2bcbd26a8e206baeb005b055dbf8e37:

  Linux 3.2-rc2 (2011-11-15 15:02:59 -0200)

are available in the git repository at:
  git://gitorious.org/linux-omap-dss2/linux.git for-3.2-rc

Tomi Valkeinen (3):
      OMAPDSS: HDMI: fix returned HDMI pixel clock
      OMAPFB: fix compilation warnings due to missing include
      OMAPDSS: DISPC: skip scaling calculations when not scaling

 drivers/video/omap/dispc.c      |    1 +
 drivers/video/omap2/dss/dispc.c |   11 +++++------
 drivers/video/omap2/dss/hdmi.c  |    2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* QVGA on a hardware which supports only >= VGA
From: Christian Gmeiner @ 2011-11-18 12:01 UTC (permalink / raw)
  To: linux-fbdev

Hi all,

I am currently in the process to get some local patches into mainline
and/or fix my
problems the right way. At the moment I am stuck with this problem:

I am on a device (x86), which is Geode lx800 based and there is a
panel connected to
it. The problem is that two different screen resolutions are used. QVGA and VGA.
Should not sound like a problem, but the lx800 can only do VGA. So get
it working,
I need to pass the correct resolution via kernel cmd to the lxfb
driver and I am using
this patch (based on 2.6.36.4 kernel):

--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1050,6 +1050,7 @@ static long do_fb_ioctl(struct fb_info *info,
unsigned int cmd,
 		ret = copy_to_user(argp, &var, sizeof(var)) ? -EFAULT : 0;
 		break;
 	case FBIOPUT_VSCREENINFO:
+#if 0
 		if (copy_from_user(&var, argp, sizeof(var)))
 			return -EFAULT;
 		if (!lock_fb_info(info))
@@ -1062,6 +1063,8 @@ static long do_fb_ioctl(struct fb_info *info,
unsigned int cmd,
 		unlock_fb_info(info);
 		if (!ret && copy_to_user(argp, &var, sizeof(var)))
 			ret = -EFAULT;
+#endif
+		ret = 0;
 		break;
 	case FBIOGET_FSCREENINFO:
 		if (!lock_fb_info(info))
@@ -1086,6 +1089,7 @@ static long do_fb_ioctl(struct fb_info *info,
unsigned int cmd,
 		ret = fb_cmap_to_user(&cmap_from, &cmap);
 		break;
 	case FBIOPAN_DISPLAY:
+#if 0
 		if (copy_from_user(&var, argp, sizeof(var)))
 			return -EFAULT;
 		if (!lock_fb_info(info))
@@ -1096,6 +1100,8 @@ static long do_fb_ioctl(struct fb_info *info,
unsigned int cmd,
 		unlock_fb_info(info);
 		if (ret = 0 && copy_to_user(argp, &var, sizeof(var)))
 			return -EFAULT;
+#endif
+		ret = 0;
 		break;
 	case FBIO_CURSOR:
 		ret = -EINVAL;

I need to mention that I am using a custom BIOS and Linux based
bootloader (kexec) in the
boot process. At the moment I am looking into coreboot, but I wanted
to know how to
solve this "problem" the correct way.

To sum it up: I want to use a QVGA panel with a hardware that only
supports >= VGA.

Thanks
--
Christian Gmeiner, MSc

^ permalink raw reply

* Re: Recent viafb changes break OLPC DCON freeze
From: Daniel Drake @ 2011-11-18 16:09 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <CAMLZHHQHZL9zZMsQgvXBi6MoG9_TXWqPN5D19sqeKSjsoV3unA@mail.gmail.com>

On Thu, Nov 17, 2011 at 8:14 PM, Florian Tobias Schandinat
<FlorianSchandinat@gmx.de> wrote:
> As you mentioned it, I had a look at this driver. It looks like viafb does it
> (polarity) just the other way around than geode. So it might be wort a try to
> change in
>
> drivers/video/via/share.h:
> /* 1200x900@60 Sync Polarity (DCON) */
> #define M1200X900_R60_HSP       NEGATIVE
> #define M1200X900_R60_VSP       NEGATIVE
>
> to
>
> /* 1200x900@60 Sync Polarity (DCON) */
> #define M1200X900_R60_HSP       POSITIVE
> #define M1200X900_R60_VSP       POSITIVE

That fixes the problem - thanks! Let me know if you'd like me to make
a patch with that change (I can do so on Monday).

It may still be worth you looking at the diagnosis - in particular I
think I may have found something that may clean up some of the
uncertainty in commit 32fab7bc

Thanks
Daniel

^ permalink raw reply

* [PATCH v3.1] [resend] Resurrect Intel740 driver: i740fb
From: Ondrej Zary @ 2011-11-18 20:54 UTC (permalink / raw)
  To: linux-fbdev
  Cc: Florian Tobias Schandinat, Paul Mundt, Kernel development list

Hello,
this is an v3 attempt to resurrect an old (like 2.4.19) out-of-tree driver for
Intel740 graphics cards and modify it for recent kernels. The old driver is
located at: http://sourceforge.net/projects/i740fbdev/files/

It was easier to create a new driver based on skeletonfb, using most of the
low level HW code from the old driver. The DDC code is completely new.

The driver was tested on two 8MB cards: Protac AG240D and Diamond Stealth II
G460.

Changes in v3:
 - added suspend/resume support
 - fixed x panning

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>

--- linux-2.6.39-rc2-orig/drivers/video/Makefile	2011-04-06 03:30:43.000000000 +0200
+++ linux-2.6.39-rc2/drivers/video/Makefile	2011-07-30 11:34:10.000000000 +0200
@@ -36,6 +36,7 @@ obj-$(CONFIG_FB_CYBER2000)        += cyb
 obj-$(CONFIG_FB_PM2)              += pm2fb.o
 obj-$(CONFIG_FB_PM3)		  += pm3fb.o
 
+obj-$(CONFIG_FB_I740)		  += i740fb.o
 obj-$(CONFIG_FB_MATROX)		  += matrox/
 obj-$(CONFIG_FB_RIVA)		  += riva/
 obj-$(CONFIG_FB_NVIDIA)		  += nvidia/
--- linux-2.6.39-rc2-orig/drivers/video/Kconfig	2011-04-06 03:30:43.000000000 +0200
+++ linux-2.6.39-rc2/drivers/video/Kconfig	2011-10-24 23:29:42.000000000 +0200
@@ -1117,6 +1117,17 @@ config FB_RIVA_BACKLIGHT
 	help
 	  Say Y here if you want to control the backlight of your display.
 
+config FB_I740
+	tristate "Intel740 support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && FB && PCI
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select VGASTATE
+	help
+	  This driver supports graphics cards based on Intel740 chip.
+
 config FB_I810
 	tristate "Intel 810/815 support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && FB && PCI && X86_32 && AGP_INTEL
--- /dev/null	2011-10-28 20:05:27.615214131 +0200
+++ linux-2.6.39-rc2/drivers/video/i740fb.c	2011-10-28 20:03:34.000000000 +0200
@@ -0,0 +1,1286 @@
+/*
+ * i740fb - framebuffer driver for Intel740
+ * Copyright (c) 2011 Ondrej Zary
+ *
+ * Based on old i740fb driver (c) 2001-2002 Andrey Ulanov <drey@rt.mipt.ru> which was partially based on:
+ *  VGA 16-color framebuffer driver (c) 1999 Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz>
+ *  i740 driver from XFree86 (c) 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+ *  i740fb by Patrick LERDA, v0.9
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/console.h>
+#include <video/vga.h>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include "i740_reg.h"
+
+static char *mode_option __devinitdata;
+
+#ifdef CONFIG_MTRR
+static int mtrr __devinitdata = 1;
+#endif
+
+struct i740fb_par {
+	unsigned char __iomem *regs;
+	bool has_sgram;
+#ifdef CONFIG_MTRR
+	int mtrr_reg;
+#endif
+	bool ddc_registered;
+	struct i2c_adapter ddc_adapter;
+	struct i2c_algo_bit_data ddc_algo;
+	u32 pseudo_palette[16];
+	struct mutex open_lock;
+	unsigned int ref_count;
+
+	u8 crtc[VGA_CRT_C];
+	u8 atc[VGA_ATT_C];
+	u8 gdc[VGA_GFX_C];
+	u8 seq[VGA_SEQ_C];
+	u8 misc;
+	u8 vss;
+
+	/* i740 specific registers */
+	u8 display_cntl;
+	u8 pixelpipe_cfg0;
+	u8 pixelpipe_cfg1;
+	u8 pixelpipe_cfg2;
+	u8 video_clk2_m;
+	u8 video_clk2_n;
+	u8 video_clk2_mn_msbs;
+	u8 video_clk2_div_sel;
+	u8 pll_cntl;
+	u8 address_mapping;
+	u8 io_cntl;
+	u8 bitblt_cntl;
+	u8 ext_vert_total;
+	u8 ext_vert_disp_end;
+	u8 ext_vert_sync_start;
+	u8 ext_vert_blank_start;
+	u8 ext_horiz_total;
+	u8 ext_horiz_blank;
+	u8 ext_offset;
+	u8 interlace_cntl;
+	u32 lmi_fifo_watermark;
+	u8 ext_start_addr;
+	u8 ext_start_addr_hi;
+};
+
+#define DACSPEED8	203
+#define DACSPEED16	163
+#define DACSPEED24_SG	136
+#define DACSPEED24_SD	128
+#define DACSPEED32	86
+
+static struct fb_fix_screeninfo i740fb_fix __devinitdata = {
+	.id =		"i740fb",
+	.type =		FB_TYPE_PACKED_PIXELS,
+	.visual =	FB_VISUAL_TRUECOLOR,
+	.xpanstep =	8,
+	.ypanstep =	1,
+	.accel =	FB_ACCEL_NONE,
+};
+
+static inline void i740outb(struct i740fb_par *par, u16 port, u8 val)
+{
+	vga_mm_w(par->regs, port, val);
+}
+static inline u8 i740inb(struct i740fb_par *par, u16 port)
+{
+	return vga_mm_r(par->regs, port);
+}
+static inline void i740outreg(struct i740fb_par *par, u16 port, u8 reg, u8 val)
+{
+	vga_mm_w_fast(par->regs, port, reg, val);
+}
+static inline u8 i740inreg(struct i740fb_par *par, u16 port, u8 reg)
+{
+	vga_mm_w(par->regs, port, reg);
+	return vga_mm_r(par->regs, port+1);
+}
+static inline void i740outreg_mask(struct i740fb_par *par, u16 port, u8 reg, u8 val, u8 mask)
+{
+	vga_mm_w_fast(par->regs, port, reg, (val & mask) | (i740inreg(par, port, reg) & ~mask));
+}
+static inline void i740outb_p(struct i740fb_par *par, u16 port, u8 val)
+{
+	vga_mm_w(par->regs, port, val);
+}
+static inline u8 i740inb_p(struct i740fb_par *par, unsigned short port)
+{
+	return vga_mm_r(par->regs, port);
+}
+
+#define REG_DDC_DRIVE	0x62
+#define REG_DDC_STATE	0x63
+#define DDC_SCL		(1 << 3)
+#define DDC_SDA		(1 << 2)
+
+static void i740fb_ddc_setscl(void *data, int val)
+{
+	struct i740fb_par *par = data;
+	unsigned char reg;
+
+	i740outreg(par, XRX, REG_DDC_DRIVE,
+		i740inreg(par, XRX, REG_DDC_DRIVE) | DDC_SCL);
+
+	reg = i740inreg(par, XRX, REG_DDC_STATE);
+	if (val)
+		reg |= DDC_SCL;
+	else
+		reg &= ~DDC_SCL;
+	i740outreg(par, XRX, REG_DDC_STATE, reg);
+}
+
+static void i740fb_ddc_setsda(void *data, int val)
+{
+	struct i740fb_par *par = data;
+	unsigned char reg;
+
+	i740outreg(par, XRX, REG_DDC_DRIVE,
+		i740inreg(par, XRX, REG_DDC_DRIVE) | DDC_SDA);
+
+	reg = i740inreg(par, XRX, REG_DDC_STATE);
+	if (val)
+		reg |= DDC_SDA;
+	else
+		reg &= ~DDC_SDA;
+	i740outreg(par, XRX, REG_DDC_STATE, reg);
+}
+
+static int i740fb_ddc_getscl(void *data)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg(par, XRX, REG_DDC_DRIVE,
+		i740inreg(par, XRX, REG_DDC_DRIVE) & ~DDC_SCL);
+
+	return !!(i740inreg(par, XRX, REG_DDC_STATE) & DDC_SCL);
+}
+
+static int i740fb_ddc_getsda(void *data)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg(par, XRX, REG_DDC_DRIVE,
+		i740inreg(par, XRX, REG_DDC_DRIVE) & ~DDC_SDA);
+
+	return !!(i740inreg(par, XRX, REG_DDC_STATE) & DDC_SDA);
+}
+
+static int __devinit i740fb_setup_ddc_bus(struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+
+	strlcpy(par->ddc_adapter.name, info->fix.id,
+		sizeof(par->ddc_adapter.name));
+	par->ddc_adapter.owner		= THIS_MODULE;
+	par->ddc_adapter.class		= I2C_CLASS_DDC;
+	par->ddc_adapter.algo_data	= &par->ddc_algo;
+	par->ddc_adapter.dev.parent	= info->device;
+	par->ddc_algo.setsda		= i740fb_ddc_setsda;
+	par->ddc_algo.setscl		= i740fb_ddc_setscl;
+	par->ddc_algo.getsda		= i740fb_ddc_getsda;
+	par->ddc_algo.getscl		= i740fb_ddc_getscl;
+	par->ddc_algo.udelay		= 10;
+	par->ddc_algo.timeout		= 20;
+	par->ddc_algo.data		= par;
+
+	i2c_set_adapdata(&par->ddc_adapter, par);
+
+	return i2c_bit_add_bus(&par->ddc_adapter);
+}
+
+static int i740fb_open(struct fb_info *info, int user)
+{
+	struct i740fb_par *par = info->par;
+
+	mutex_lock(&(par->open_lock));
+	par->ref_count++;
+	mutex_unlock(&(par->open_lock));
+
+	return 0;
+}
+
+static int i740fb_release(struct fb_info *info, int user)
+{
+	struct i740fb_par *par = info->par;
+
+	mutex_lock(&(par->open_lock));
+	if (par->ref_count = 0) {
+		mutex_unlock(&(par->open_lock));
+		return -EINVAL;
+	}
+
+	par->ref_count--;
+	mutex_unlock(&(par->open_lock));
+
+	return 0;
+}
+
+static u32 i740_calc_fifo(struct i740fb_par *par, u32 freq, int bpp)
+{
+	/*
+	 * Would like to calculate these values automatically, but a generic
+	 * algorithm does not seem possible.  Note: These FIFO water mark
+	 * values were tested on several cards and seem to eliminate the
+	 * all of the snow and vertical banding, but fine adjustments will
+	 * probably be required for other cards.
+	 */
+
+	u32 wm = 0x18120000;
+
+	switch (bpp) {
+	case 8:
+		if	(freq > 200) wm = 0x18120000;
+		else if (freq > 175) wm = 0x16110000;
+		else if (freq > 135) wm = 0x120E0000;
+		else		     wm = 0x100D0000;
+		break;
+	case 15:
+	case 16:
+		if (par->has_sgram) {
+			if	(freq > 140) wm = 0x2C1D0000;
+			else if (freq > 120) wm = 0x2C180000;
+			else if (freq > 100) wm = 0x24160000;
+			else if (freq >  90) wm = 0x18120000;
+			else if (freq >  50) wm = 0x16110000;
+			else if (freq >  32) wm = 0x13100000;
+			else		     wm = 0x120E0000;
+		} else {
+			if	(freq > 160) wm = 0x28200000;
+			else if (freq > 140) wm = 0x2A1E0000;
+			else if (freq > 130) wm = 0x2B1A0000;
+			else if (freq > 120) wm = 0x2C180000;
+			else if (freq > 100) wm = 0x24180000;
+			else if (freq >  90) wm = 0x18120000;
+			else if (freq >  50) wm = 0x16110000;
+			else if (freq >  32) wm = 0x13100000;
+			else		     wm = 0x120E0000;
+		}
+		break;
+	case 24:
+		if (par->has_sgram) {
+			if	(freq > 130) wm = 0x31200000;
+			else if (freq > 120) wm = 0x2E200000;
+			else if (freq > 100) wm = 0x2C1D0000;
+			else if (freq >  80) wm = 0x25180000;
+			else if (freq >  64) wm = 0x24160000;
+			else if (freq >  49) wm = 0x18120000;
+			else if (freq >  32) wm = 0x16110000;
+			else		     wm = 0x13100000;
+		} else {
+			if	(freq > 120) wm = 0x311F0000;
+			else if (freq > 100) wm = 0x2C1D0000;
+			else if (freq >  80) wm = 0x25180000;
+			else if (freq >  64) wm = 0x24160000;
+			else if (freq >  49) wm = 0x18120000;
+			else if (freq >  32) wm = 0x16110000;
+			else		     wm = 0x13100000;
+		}
+		break;
+	case 32:
+		if (par->has_sgram) {
+			if	(freq >  80) wm = 0x2A200000;
+			else if (freq >  60) wm = 0x281A0000;
+			else if (freq >  49) wm = 0x25180000;
+			else if (freq >  32) wm = 0x18120000;
+			else		     wm = 0x16110000;
+		} else {
+			if	(freq >  80) wm = 0x29200000;
+			else if (freq >  60) wm = 0x281A0000;
+			else if (freq >  49) wm = 0x25180000;
+			else if (freq >  32) wm = 0x18120000;
+			else		     wm = 0x16110000;
+		}
+		break;
+	}
+
+	return wm;
+}
+
+/* clock calculation from i740fb by Patrick LERDA */
+
+#define I740_RFREQ (1e6)
+#define TARGET_MAX_N 30
+
+#define I740_FFIX		8
+#define I740_REF_FREQ		(u32) (66.66666666667 * (1 << I740_FFIX) + 0.5)
+#define I740_MAX_VCO_FREQ	(u32)(450.00000000000 * (1 << I740_FFIX) + 0.5)
+
+#define I740_CALC_VCLKfix(m, n, p, d)   ((((((m) * I740_REF_FREQ * (4 << ((d) << 1)))) / (n)) + ((1 << (p)) / 2)) / (1 << (p)))
+
+static void i740_calc_vclk(u32 freq_hz, struct i740fb_par *par)
+{
+	u32 freq = freq_hz / (u32)(1e6 / I740_RFREQ);
+	const u32 err_max = freq / (u32)(I740_RFREQ / 0.005 / (1 << I740_FFIX) + 0.5);
+	const u32 err_target = freq / (u32)(I740_RFREQ / 0.001 / (1 << I740_FFIX) + 0.5);
+	u32 err_best = (u32)(512.0 * (1 << I740_FFIX));
+	u32 f_err, f_vco;
+	int m_best = 0, n_best = 0, p_best = 0, d_best = 0;
+	int m, n, i;
+
+	/* find log2(MAX_VCO_FREQ/f_target) */
+	for (i = 0; i < 16; i++)
+		if ((I740_MAX_VCO_FREQ) / (1 << i) < freq / (u32)(I740_RFREQ / (1 << I740_FFIX)))
+			break;
+	i--;
+	p_best = i;
+
+	d_best = 0;
+	f_vco = (freq * (1 << p_best)) / (u32)(I740_RFREQ / (1 << I740_FFIX));
+	freq = freq / (u32)(I740_RFREQ / (1 << I740_FFIX));
+
+	n = 2;
+	do {
+		n++;
+		m = ((f_vco * n) / I740_REF_FREQ + 2) / 4;
+
+		if (m < 3)
+			m = 3;
+
+		{
+			u32 f_out = I740_CALC_VCLKfix(m, n, p_best, d_best);
+
+			f_err = (freq - f_out);
+
+			if (abs(f_err) < err_max) {
+				m_best = m;
+				n_best = n;
+				err_best = f_err;
+			}
+		}
+	} while ((abs(f_err) >= err_target) &&
+		 ((n <= TARGET_MAX_N) || (abs(err_best) > err_max)));
+
+	if (abs(f_err) < err_target) {
+		m_best = m;
+		n_best = n;
+	}
+
+	par->video_clk2_m = (m_best-2) & 0xFF;
+	par->video_clk2_n = (n_best-2) & 0xFF;
+	par->video_clk2_mn_msbs = ((((n_best-2) >> 4) & VCO_N_MSBS) |
+				 (((m_best-2) >> 8) & VCO_M_MSBS));
+	par->video_clk2_div_sel = ((p_best << 4) | (d_best ? 4 : 0) | REF_DIV_1);
+}
+
+static int i740fb_decode_var(const struct fb_var_screeninfo *var, struct i740fb_par *par, struct fb_info *info)
+{
+	/*
+	 *  Get the video params out of 'var'. If a value doesn't fit, round it up,
+	 *  if it's too big, return -EINVAL.
+	 */
+
+	u32 xres, right, hslen, left, xtotal;
+	u32 yres, lower, vslen, upper, ytotal;
+	u32 vxres, xoffset, vyres, yoffset;
+	u32 bpp, base, dacspeed24;
+	u8 r7;
+	int i;
+
+	dev_dbg(info->device, "decode_var: xres: %i, yres: %i, xres_v: %i, xres_v: %i\n",
+		  var->xres, var->yres, var->xres_virtual, var->xres_virtual);
+	dev_dbg(info->device, "	xoff: %i, yoff: %i, bpp: %i, graysc: %i\n",
+		  var->xoffset, var->yoffset, var->bits_per_pixel, var->grayscale);
+	dev_dbg(info->device, "	activate: %i, nonstd: %i, vmode: %i\n",
+		  var->activate, var->nonstd, var->vmode);
+	dev_dbg(info->device, "	pixclock: %i, hsynclen:%i, vsynclen:%i\n",
+		  var->pixclock, var->hsync_len, var->vsync_len);
+	dev_dbg(info->device, "	left: %i, right: %i, up:%i, lower:%i\n",
+		  var->left_margin, var->right_margin, var->upper_margin, var->lower_margin);
+
+
+	bpp = var->bits_per_pixel;
+	switch (bpp) {
+	case 1 ... 8:
+		bpp = 8;
+		if ((((u32)1e6) / var->pixclock) > DACSPEED8) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 8bpp)\n", 1000000 / var->pixclock, DACSPEED8);
+			return -EINVAL;
+		}
+		break;
+	case 9 ... 15:
+		bpp = 15;
+	case 16:
+		if ((((u32)1e6) / var->pixclock) > DACSPEED16) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 15/16bpp)\n", 1000000 / var->pixclock, DACSPEED16);
+			return -EINVAL;
+		}
+		break;
+	case 17 ... 24:
+		bpp = 24;
+		dacspeed24 = par->has_sgram ? DACSPEED24_SG : DACSPEED24_SD;
+		if ((((u32)1e6) / var->pixclock) > dacspeed24) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 24bpp)\n", 1000000 / var->pixclock, dacspeed24);
+			return -EINVAL;
+		}
+		break;
+	case 25 ... 32:
+		bpp = 32;
+		if ((((u32)1e6) / var->pixclock) > DACSPEED32) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 32bpp)\n", 1000000 / var->pixclock, DACSPEED32);
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	xres = (var->xres + 7) & ~7;
+	vxres = (var->xres_virtual + 0xF) & ~0xF;
+	if (vxres < xres)
+		vxres = xres;
+
+	xoffset = (var->xoffset + 7) & ~7;
+	xoffset = var->xoffset;
+	if (xres + xoffset > vxres)
+		xoffset = vxres - xres;
+
+	left = (var->left_margin + 7) & ~7;
+	right = (var->right_margin + 7) & ~7;
+	hslen = (var->hsync_len + 7) & ~7;
+
+	yres = var->yres;
+	vyres = var->yres_virtual;
+	if (yres > vyres)
+		vyres = yres;
+
+	yoffset = var->yoffset;
+	if (yres + yoffset > vyres)
+		yoffset = vyres - yres;
+
+	lower = var->lower_margin;
+	vslen = var->vsync_len;
+	upper = var->upper_margin;
+
+	if (vxres * vyres * ((bpp + 1) / 8) > info->screen_size || vyres = yres) {
+		vyres = info->screen_size / vxres / ((bpp + 1) / 8);
+		if (vyres < yres)
+			return -ENOMEM;
+	}
+
+	if (yoffset + yres > vyres)
+		yoffset = vyres - yres;
+
+	xtotal = xres + right + hslen + left;
+	ytotal = yres + lower + vslen + upper;
+
+	par->crtc[VGA_CRTC_H_TOTAL] = (xtotal >> 3) - 5;
+	par->crtc[VGA_CRTC_H_DISP] = (xres >> 3) - 1;
+	par->crtc[VGA_CRTC_H_BLANK_START] = ((xres + right) >> 3) - 1;
+	par->crtc[VGA_CRTC_H_SYNC_START] = (xres + right) >> 3;
+	par->crtc[VGA_CRTC_H_SYNC_END] = (((xres + right + hslen) >> 3) & 0x1F)
+		| ((((xres + right + hslen) >> 3) & 0x20) << 2);
+	par->crtc[VGA_CRTC_H_BLANK_END] = ((xres + right + hslen) >> 3 & 0x1F) | 0x80;
+
+	par->crtc[VGA_CRTC_V_TOTAL] = ytotal - 2;
+
+	r7 = 0x10;	/* disable linecompare */
+	if (ytotal & 0x100)
+		r7 |= 0x01;
+	if (ytotal & 0x200)
+		r7 |= 0x20;
+
+	par->crtc[VGA_CRTC_PRESET_ROW] = 0;
+	par->crtc[VGA_CRTC_MAX_SCAN] = 0x40;	/* 1 scanline, no linecmp */
+	if (var->vmode & FB_VMODE_DOUBLE)
+		par->crtc[VGA_CRTC_MAX_SCAN] |= 0x80;
+	par->crtc[VGA_CRTC_CURSOR_START] = 0x00;
+	par->crtc[VGA_CRTC_CURSOR_END] = 0x00;
+	par->crtc[VGA_CRTC_CURSOR_HI] = 0x00;
+	par->crtc[VGA_CRTC_CURSOR_LO] = 0x00;
+	par->crtc[VGA_CRTC_V_DISP_END] = yres-1;
+	if ((yres-1) & 0x100)
+		r7 |= 0x02;
+	if ((yres-1) & 0x200)
+		r7 |= 0x40;
+
+	par->crtc[VGA_CRTC_V_BLANK_START] = yres + lower - 1;
+	par->crtc[VGA_CRTC_V_SYNC_START] = yres + lower - 1;
+	if ((yres + lower - 1) & 0x100)
+		r7 |= 0x0C;
+	if ((yres + lower - 1) & 0x200) {
+		par->crtc[VGA_CRTC_MAX_SCAN] |= 0x20;
+		r7 |= 0x80;
+	}
+
+	par->crtc[VGA_CRTC_V_SYNC_END] = ((yres + lower - 1 + vslen) & 0x0F) & ~0x10; /* disabled IRQ */
+	par->crtc[VGA_CRTC_V_BLANK_END] = (yres + lower - 1 + vslen) & 0xFF; /* 0x7F for original VGA, but some SVGA chips requires all 8 bits to set */
+
+	par->crtc[VGA_CRTC_UNDERLINE] = 0x00;
+	par->crtc[VGA_CRTC_MODE] = 0xC3 ;
+	par->crtc[VGA_CRTC_LINE_COMPARE] = 0xFF;
+	par->crtc[VGA_CRTC_OVERFLOW] = r7;
+
+	par->vss = 0x00;	/* 3DA */
+
+	for (i = 0x00; i < 0x10; i++)
+		par->atc[i] = i;
+	par->atc[VGA_ATC_MODE] = 0x81;
+	par->atc[VGA_ATC_OVERSCAN] = 0x00;	/* 0 for EGA, 0xFF for VGA */
+	par->atc[VGA_ATC_PLANE_ENABLE] = 0x0F;
+	/*par->atc[VGA_ATC_PEL] = xoffset & 7;*/
+	par->atc[VGA_ATC_COLOR_PAGE] = 0x00;
+
+	par->misc = 0xC3;
+	if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+		par->misc &= ~0x40;
+	if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+		par->misc &= ~0x80;
+
+	par->seq[VGA_SEQ_CLOCK_MODE] = 0x01;
+	par->seq[VGA_SEQ_PLANE_WRITE] = 0x0F;
+	par->seq[VGA_SEQ_CHARACTER_MAP] = 0x00;
+	par->seq[VGA_SEQ_MEMORY_MODE] = 0x06;
+
+	par->gdc[VGA_GFX_SR_VALUE] = 0x00;
+	par->gdc[VGA_GFX_SR_ENABLE] = 0x00;
+	par->gdc[VGA_GFX_COMPARE_VALUE] = 0x00;
+	par->gdc[VGA_GFX_DATA_ROTATE] = 0x00;
+	par->gdc[VGA_GFX_PLANE_READ] = 0;
+	par->gdc[VGA_GFX_MODE] = 0x02;
+	par->gdc[VGA_GFX_MISC] = 0x05;
+	par->gdc[VGA_GFX_COMPARE_MASK] = 0x0F;
+	par->gdc[VGA_GFX_BIT_MASK] = 0xFF;
+
+	base = (yoffset * vxres + (xoffset & ~7)) >> 2;
+	switch (bpp) {
+	case 8:
+		par->crtc[VGA_CRTC_OFFSET] = vxres >> 3;
+		par->ext_offset = vxres >> 11;
+		par->pixelpipe_cfg1 = DISPLAY_8BPP_MODE;
+		par->bitblt_cntl = COLEXP_8BPP;
+		break;
+	case 15: /* 0rrrrrgg gggbbbbb */
+	case 16: /* rrrrrggg gggbbbbb */
+		par->pixelpipe_cfg1 = (var->green.length = 6) ? DISPLAY_16BPP_MODE : DISPLAY_15BPP_MODE;
+		par->crtc[VGA_CRTC_OFFSET] = vxres >> 2;
+		par->ext_offset = vxres >> 10;
+		par->bitblt_cntl = COLEXP_16BPP;
+		base *= 2;
+		break;
+	case 24:
+		par->crtc[VGA_CRTC_OFFSET] = (vxres * 3) >> 3;
+		par->ext_offset = (vxres * 3) >> 11;
+		par->pixelpipe_cfg1 = DISPLAY_24BPP_MODE;
+		par->bitblt_cntl = COLEXP_24BPP;
+		base &= 0xFFFFFFFE; /* ...ignore the last bit. */
+		base *= 3;
+		break;
+	case 32:
+		par->crtc[VGA_CRTC_OFFSET] = vxres >> 1;
+		par->ext_offset = vxres >> 9;
+		par->pixelpipe_cfg1 = DISPLAY_32BPP_MODE;
+		par->bitblt_cntl = COLEXP_RESERVED; /* Not implemented on i740 */
+		base *= 4;
+		break;
+	}
+
+	par->crtc[VGA_CRTC_START_LO] = base & 0x000000FF;
+	par->crtc[VGA_CRTC_START_HI] = (base & 0x0000FF00) >>  8;
+	par->ext_start_addr = ((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE;
+	par->ext_start_addr_hi = (base & 0x3FC00000) >> 22;
+
+	par->pixelpipe_cfg0 = DAC_8_BIT;
+
+	par->pixelpipe_cfg2 = DISPLAY_GAMMA_ENABLE | OVERLAY_GAMMA_ENABLE;
+	par->io_cntl = EXTENDED_CRTC_CNTL;
+	par->address_mapping = LINEAR_MODE_ENABLE | PAGE_MAPPING_ENABLE;
+	par->display_cntl = HIRES_MODE;
+
+	/* Set the MCLK freq */
+	par->pll_cntl = PLL_MEMCLK_100000KHZ; /* 100 MHz -- use as default */
+
+	/* Calculate the extended CRTC regs */
+	par->ext_vert_total = (ytotal - 2) >> 8;
+	par->ext_vert_disp_end = (yres - 1) >> 8;
+	par->ext_vert_sync_start = (yres + lower) >> 8;
+	par->ext_vert_blank_start = (yres + lower) >> 8;
+	par->ext_horiz_total = ((xtotal >> 3) - 5) >> 8;
+	par->ext_horiz_blank = (((xres + right) >> 3) & 0x40) >> 6;
+
+	par->interlace_cntl = INTERLACE_DISABLE;
+
+	/* Set the overscan color to 0. (NOTE: This only affects >8bpp mode.) */
+	par->atc[VGA_ATC_OVERSCAN] = 0;
+
+	/* Calculate VCLK that most closely matches the requested dot clock */
+	i740_calc_vclk((((u32)1e9) / var->pixclock) * (u32)(1e3), par);
+
+	/* Since we program the clocks ourselves, always use VCLK2. */
+	par->misc |= 0x0C;
+
+	/* Calculate the FIFO Watermark and Burst Length. */
+	par->lmi_fifo_watermark = i740_calc_fifo(par, ((int)1e6) / var->pixclock, bpp);
+
+	/*if (!fbmon_valid_timings(var->pixclock, ytotal, xtotal, info))
+	return -EINVAL;*/
+
+	return 0;
+}
+
+static int i740fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	switch (var->bits_per_pixel) {
+	case 8:
+		var->red.offset	= var->green.offset = var->blue.offset = 0;
+		var->red.length	= var->green.length = var->blue.length = 8;
+		break;
+	case 16:
+		switch (var->green.length) {
+		default:
+		case 5:
+			var->red.offset = 10;
+			var->green.offset = 5;
+			var->blue.offset = 0;
+			var->red.length	= var->green.length = var->blue.length = 5;
+			break;
+		case 6:
+			var->red.offset = 11;
+			var->green.offset = 5;
+			var->blue.offset = 0;
+			var->green.length = 6;
+			var->red.length = var->blue.length = 5;
+			break;
+		}
+		break;
+	case 24:
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->red.length	= var->green.length = var->blue.length = 8;
+		break;
+	case 32:
+		var->transp.offset = 24;
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->transp.length = var->red.length = var->green.length = var->blue.length = 8;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (var->xres > var->xres_virtual)
+		var->xres_virtual = var->xres;
+
+	if (var->yres > var->yres_virtual)
+		var->yres_virtual = var->yres;
+
+	if (info->monspecs.hfmax && info->monspecs.vfmax &&
+	    info->monspecs.dclkmax && fb_validate_mode(var, info) < 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void vga_protect(struct i740fb_par *par)
+{
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, i740inreg(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE) | 0x20);	/* disable the display */
+
+	i740inb(par, 0x3DA);
+	i740outb(par, VGA_ATT_W, 0x00);	/* enable pallete access */
+}
+
+static void vga_unprotect(struct i740fb_par *par)
+{
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, i740inreg(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE) & 0xDF);	/* reenable display */
+
+	i740inb(par, 0x3DA);
+	i740outb(par, VGA_ATT_W, 0x20);	/* disable pallete access */
+}
+
+static int i740fb_set_par(struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+	u32 itemp;
+	int i;
+
+	i = i740fb_decode_var(&info->var, par, info);
+	if (i)
+		return i;
+
+	memset(info->screen_base, 0, info->screen_size);
+
+	vga_protect(par);
+
+	i740outreg(par, XRX, DRAM_EXT_CNTL, DRAM_REFRESH_DISABLE);
+
+	mdelay(1);
+
+	i740outreg(par, XRX, VCLK2_VCO_M, par->video_clk2_m);
+	i740outreg(par, XRX, VCLK2_VCO_N, par->video_clk2_n);
+	i740outreg(par, XRX, VCLK2_VCO_MN_MSBS, par->video_clk2_mn_msbs);
+	i740outreg(par, XRX, VCLK2_VCO_DIV_SEL, par->video_clk2_div_sel);
+
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_0, par->pixelpipe_cfg0 & DAC_8_BIT, 0x80);
+
+	i740inb(par, 0x3DA);
+	i740outb(par, 0x3C0, 0x00);
+
+	/* update misc output register */
+	i740outb(par, VGA_MIS_W, par->misc | 0x01);
+
+	/* synchronous reset on */
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_RESET, 0x01);
+	/* write sequencer registers */
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, par->seq[VGA_SEQ_CLOCK_MODE] | 0x20);
+	for (i = 2; i < VGA_SEQ_C; i++)
+		i740outreg(par, VGA_SEQ_I, i, par->seq[i]);
+
+	/* synchronous reset off */
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_RESET, 0x03);
+
+	/* deprotect CRT registers 0-7 */
+	i740outreg(par, VGA_CRT_IC, VGA_CRTC_V_SYNC_END, par->crtc[VGA_CRTC_V_SYNC_END]);
+
+	/* write CRT registers */
+	for (i = 0; i < VGA_CRT_C; i++)
+		i740outreg(par, VGA_CRT_IC, i, par->crtc[i]);
+
+	/* write graphics controller registers */
+	for (i = 0; i < VGA_GFX_C; i++)
+		i740outreg(par, VGA_GFX_I, i, par->gdc[i]);
+
+	/* write attribute controller registers */
+	for (i = 0; i < VGA_ATT_C; i++) {
+		i740inb_p(par, VGA_IS1_RC);		/* reset flip-flop */
+		i740outb_p(par, VGA_ATT_IW, i);
+		i740outb_p(par, VGA_ATT_IW, par->atc[i]);
+	}
+
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, par->seq[VGA_SEQ_CLOCK_MODE]);
+
+	i740inb(par, VGA_IS1_RC);
+	i740outb(par, VGA_ATT_IW, 0x20);
+
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_TOTAL, par->ext_vert_total);
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_DISPLAY, par->ext_vert_disp_end);
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_SYNC_START, par->ext_vert_sync_start);
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_BLANK_START, par->ext_vert_blank_start);
+	i740outreg(par, VGA_CRT_IC, EXT_HORIZ_TOTAL, par->ext_horiz_total);
+	i740outreg(par, VGA_CRT_IC, EXT_HORIZ_BLANK, par->ext_horiz_blank);
+	i740outreg(par, VGA_CRT_IC, EXT_OFFSET, par->ext_offset);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR_HI, par->ext_start_addr_hi);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR, par->ext_start_addr);
+
+	i740outreg_mask(par, VGA_CRT_IC, INTERLACE_CNTL, par->interlace_cntl, INTERLACE_ENABLE);
+	i740outreg_mask(par, XRX, ADDRESS_MAPPING, par->address_mapping, 0x1F);
+	i740outreg_mask(par, XRX, BITBLT_CNTL, par->bitblt_cntl, COLEXP_MODE);
+	i740outreg_mask(par, XRX, DISPLAY_CNTL, par->display_cntl, VGA_WRAP_MODE | GUI_MODE);
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_0, par->pixelpipe_cfg0, 0x9B);
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_2, par->pixelpipe_cfg2, 0x0C);
+
+	i740outreg(par, XRX, PLL_CNTL, par->pll_cntl);
+
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_1, par->pixelpipe_cfg1, DISPLAY_COLOR_MODE);
+
+	itemp = readl(par->regs + FWATER_BLC);
+	itemp &= ~(LMI_BURST_LENGTH | LMI_FIFO_WATERMARK);
+	itemp |= par->lmi_fifo_watermark;
+	writel(itemp, par->regs + FWATER_BLC);
+
+	i740outreg(par, XRX, DRAM_EXT_CNTL, DRAM_REFRESH_60HZ);
+
+	i740outreg_mask(par, MRX, COL_KEY_CNTL_1, 0, BLANK_DISP_OVERLAY);
+	i740outreg_mask(par, XRX, IO_CTNL, par->io_cntl, EXTENDED_ATTR_CNTL | EXTENDED_CRTC_CNTL);
+
+	if (par->pixelpipe_cfg1 != DISPLAY_8BPP_MODE) {
+		i740outb(par, VGA_PEL_MSK, 0xFF);
+		i740outb(par, VGA_PEL_IW, 0x00);
+		for (i = 0; i < 256; i++) {
+			i740outb_p(par, VGA_PEL_D, (par->pixelpipe_cfg0 & DAC_8_BIT) ? i : i >> 2);
+			i740outb_p(par, VGA_PEL_D, (par->pixelpipe_cfg0 & DAC_8_BIT) ? i : i >> 2);
+			i740outb_p(par, VGA_PEL_D, (par->pixelpipe_cfg0 & DAC_8_BIT) ? i : i >> 2);
+		}
+	}
+
+	/* Wait for screen to stabilize. */
+	mdelay(50);
+	vga_unprotect(par);
+
+	info->fix.line_length = info->var.xres_virtual * info->var.bits_per_pixel / 8;
+	if (info->var.bits_per_pixel = 8)
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+	else
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+	return 0;
+}
+
+static int i740fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp,
+			   struct fb_info *info)
+{
+	dev_dbg(info->device, "setcolreg: regno: %i, red=%d, green=%d, blue=%d, transp=%d, bpp=%d\n", regno, red, green, blue, transp, info->var.bits_per_pixel);
+
+	switch (info->var.bits_per_pixel) {
+	case 8:
+		if (regno >= 256)
+			return 1;
+		i740outb(info->par, VGA_PEL_IW, regno);
+		i740outb(info->par, VGA_PEL_D, red >> 8);
+		i740outb(info->par, VGA_PEL_D, green >> 8);
+		i740outb(info->par, VGA_PEL_D, blue >> 8);
+		break;
+	case 15:
+	case 16:
+		if (regno >= 16)
+			return 0;
+		if (info->var.green.length = 5)
+			((u32 *)info->pseudo_palette)[regno] = ((red & 0xF800) >> 1) | ((green & 0xF800) >> 6) | ((blue & 0xF800) >> 11);
+		else if (info->var.green.length = 6)
+			((u32 *)info->pseudo_palette)[regno] = (red & 0xF800) |	((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);
+		else
+			return -EINVAL;
+		break;
+	case 24:
+	case 32:
+		if (regno >= 16)
+			return 0;
+		((u32 *)info->pseudo_palette)[regno] = ((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int i740fb_pan_display(struct fb_var_screeninfo *var,
+				 struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+	u32 base = (var->yoffset * var->xres_virtual + (var->xoffset & ~7)) >> 2;
+
+	dev_dbg(info->device, "pan_display: xoffset: %i, yoffset: %i base: %i\n", var->xoffset, var->yoffset, base);
+
+	switch (var->bits_per_pixel) {
+	case 8:
+		break;
+	case 15:
+	case 16:
+		base *= 2;
+		break;
+	case 24:
+		/*
+		 * The last bit does not seem to have any effect on the start
+		 * address register in 24bpp mode, so...
+		 */
+		base &= 0xFFFFFFFE; /* ...ignore the last bit. */
+		base *= 3;
+		break;
+	case 32:
+		base *= 4;
+		break;
+	}
+
+	par->crtc[VGA_CRTC_START_LO] = base & 0x000000FF;
+	par->crtc[VGA_CRTC_START_HI] = (base & 0x0000FF00) >>  8;
+	par->ext_start_addr_hi = (base & 0x3FC00000) >> 22;
+	par->ext_start_addr = ((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE;
+	/*par->atc[VGA_ATC_PEL] = var->xoffset & 7;*/
+
+	i740outreg(par, VGA_CRT_IC, VGA_CRTC_START_LO,  base & 0x000000FF);
+	i740outreg(par, VGA_CRT_IC, VGA_CRTC_START_HI, (base & 0x0000FF00) >>  8);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR_HI, (base & 0x3FC00000) >> 22);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR, ((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE);
+	/*i740outreg(par, VGA_ATT_W, VGA_ATC_PEL, var->xoffset & 7);*/
+
+	return 0;
+}
+
+static int i740fb_blank(int blank_mode, struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+
+	unsigned char SEQ01;
+	int DPMSSyncSelect;
+
+	switch (blank_mode) {
+	case FB_BLANK_UNBLANK:
+	case FB_BLANK_NORMAL:
+		SEQ01 = 0x00;
+		DPMSSyncSelect = HSYNC_ON | VSYNC_ON;
+		break;
+	case FB_BLANK_VSYNC_SUSPEND:
+		SEQ01 = 0x20;
+		DPMSSyncSelect = HSYNC_ON | VSYNC_OFF;
+		break;
+	case FB_BLANK_HSYNC_SUSPEND:
+		SEQ01 = 0x20;
+		DPMSSyncSelect = HSYNC_OFF | VSYNC_ON;
+		break;
+	case FB_BLANK_POWERDOWN:
+		SEQ01 = 0x20;
+		DPMSSyncSelect = HSYNC_OFF | VSYNC_OFF;
+		break;
+	default:
+		return -EINVAL;
+	}
+	/* Turn the screen on/off */
+	i740outb(par, SRX, 0x01);
+	SEQ01 |= i740inb(par, SRX + 1) & ~0x20;
+	i740outb(par, SRX, 0x01);
+	i740outb(par, SRX + 1, SEQ01);
+
+	/* Set the DPMS mode */
+	i740outreg(par, XRX, DPMS_SYNC_SELECT, DPMSSyncSelect);
+
+	/* Let fbcon do a soft blank for us */
+	return (blank_mode = FB_BLANK_NORMAL) ? 1 : 0;
+}
+
+static struct fb_ops i740fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_open	= i740fb_open,
+	.fb_release	= i740fb_release,
+	.fb_check_var	= i740fb_check_var,
+	.fb_set_par	= i740fb_set_par,
+	.fb_setcolreg	= i740fb_setcolreg,
+	.fb_blank	= i740fb_blank,
+	.fb_pan_display	= i740fb_pan_display,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static int __devinit i740fb_probe(struct pci_dev *dev,
+				  const struct pci_device_id *ent)
+{
+	struct fb_info *info;
+	struct i740fb_par *par;
+	int ret;
+	bool found = false;
+	u8 *edid;
+
+	info = framebuffer_alloc(sizeof(struct i740fb_par), &(dev->dev));
+	if (!info) {
+		dev_err(&(dev->dev), "cannot allocate framebuffer\n");
+		return -ENOMEM;
+	}
+
+	par = info->par;
+	mutex_init(&par->open_lock);
+
+	info->var.activate = FB_ACTIVATE_NOW;
+	info->var.bits_per_pixel = 8;
+	info->fbops = &i740fb_ops;
+	info->pseudo_palette = par->pseudo_palette;
+
+	ret = pci_enable_device(dev);
+	if (ret) {
+		dev_err(info->device, "cannot enable PCI device\n");
+		goto err_enable_device;
+	}
+
+	ret = pci_request_regions(dev, info->fix.id);
+	if (ret) {
+		dev_err(info->device, "error requesting regions\n");
+		goto err_request_regions;
+	}
+
+	info->screen_base = pci_ioremap_bar(dev, 0);
+	if (!info->screen_base) {
+		dev_err(info->device, "error remapping base\n");
+		ret = -ENOMEM;
+		goto err_ioremap_1;
+	}
+
+	par->regs = pci_ioremap_bar(dev, 1);
+	if (!par->regs) {
+		dev_err(info->device, "error remapping MMIO\n");
+		ret = -ENOMEM;
+		goto err_ioremap_2;
+	}
+
+	/* detect memory size */
+	if ((i740inreg(par, XRX, DRAM_ROW_TYPE) & DRAM_ROW_1) = DRAM_ROW_1_SDRAM)
+		i740outb(par, XRX, DRAM_ROW_BNDRY_1);
+	else
+		i740outb(par, XRX, DRAM_ROW_BNDRY_0);
+	info->screen_size = i740inb(par, XRX + 1) * 1024 * 1024;
+	/* detect memory type */
+	par->has_sgram = i740inreg(par, XRX, DRAM_ROW_CNTL_LO);
+	par->has_sgram = !((par->has_sgram & DRAM_RAS_TIMING) ||
+			   (par->has_sgram & DRAM_RAS_PRECHARGE));
+
+	printk(KERN_INFO "fb%d: Intel740 on %s, %ld KB %s\n", info->node,
+		pci_name(dev), info->screen_size >> 10,
+		par->has_sgram ? "SGRAM" : "SDRAM");
+
+	info->fix = i740fb_fix;
+	info->fix.mmio_start = pci_resource_start(dev, 1);
+	info->fix.mmio_len = pci_resource_len(dev, 1);
+	info->fix.smem_start = pci_resource_start(dev, 0);
+	info->fix.smem_len = info->screen_size;
+	info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
+
+	if (i740fb_setup_ddc_bus(info) = 0) {
+		par->ddc_registered = true;
+		edid = fb_ddc_read(&par->ddc_adapter);
+		if (edid) {
+			fb_edid_to_monspecs(edid, &info->monspecs);
+			kfree(edid);
+			if (!info->monspecs.modedb)
+				dev_err(info->device, "error getting mode database\n");
+			else {
+				const struct fb_videomode *m;
+
+				fb_videomode_to_modelist(info->monspecs.modedb,
+							 info->monspecs.modedb_len,
+							 &info->modelist);
+				m = fb_find_best_display(&info->monspecs, &info->modelist);
+				if (m) {
+					fb_videomode_to_var(&info->var, m);
+					/* fill all other info->var's fields */
+					if (i740fb_check_var(&info->var, info) = 0)
+						found = true;
+				}
+			}
+		}
+	}
+
+	if (!mode_option && !found)
+		mode_option = "640x480-8@60";
+
+	if (mode_option) {
+		ret = fb_find_mode(&info->var, info, mode_option,
+				   info->monspecs.modedb, info->monspecs.modedb_len,
+				   NULL, info->var.bits_per_pixel);
+		if (!ret || ret = 4) {
+			dev_err(info->device, "mode %s not found\n", mode_option);
+			ret = -EINVAL;
+		}
+	}
+
+	fb_destroy_modedb(info->monspecs.modedb);
+	info->monspecs.modedb = NULL;
+
+	/* maximize virtual vertical size for fast scrolling */
+	info->var.yres_virtual = info->fix.smem_len * 8 /
+			(info->var.bits_per_pixel * info->var.xres_virtual);
+
+	if (ret = -EINVAL)
+		goto err_find_mode;
+
+	ret = fb_alloc_cmap(&info->cmap, 256, 0);
+	if (ret) {
+		dev_err(info->device, "cannot allocate colormap\n");
+		goto err_alloc_cmap;
+	}
+
+	ret = register_framebuffer(info);
+	if (ret) {
+		dev_err(info->device, "error registering framebuffer\n");
+		goto err_reg_framebuffer;
+	}
+
+	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
+	pci_set_drvdata(dev, info);
+#ifdef CONFIG_MTRR
+	if (mtrr) {
+		par->mtrr_reg = -1;
+		par->mtrr_reg = mtrr_add(info->fix.smem_start, info->fix.smem_len, MTRR_TYPE_WRCOMB, 1);
+	}
+#endif
+	return 0;
+
+err_reg_framebuffer:
+	fb_dealloc_cmap(&info->cmap);
+err_alloc_cmap:
+err_find_mode:
+	if (par->ddc_registered)
+		i2c_del_adapter(&par->ddc_adapter);
+	pci_iounmap(dev, par->regs);
+err_ioremap_2:
+	pci_iounmap(dev, info->screen_base);
+err_ioremap_1:
+	pci_release_regions(dev);
+err_request_regions:
+/*	pci_disable_device(dev); */
+err_enable_device:
+	framebuffer_release(info);
+	return ret;
+}
+
+static void __devexit i740fb_remove(struct pci_dev *dev)
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+
+	if (info) {
+#ifdef CONFIG_MTRR
+		struct i740fb_par *par = info->par;
+
+		if (par->mtrr_reg >= 0) {
+			mtrr_del(par->mtrr_reg, 0, 0);
+			par->mtrr_reg = -1;
+		}
+#endif
+		unregister_framebuffer(info);
+		fb_dealloc_cmap(&info->cmap);
+		if (par->ddc_registered)
+			i2c_del_adapter(&par->ddc_adapter);
+		pci_iounmap(dev, par->regs);
+		pci_iounmap(dev, info->screen_base);
+		pci_release_regions(dev);
+/*		pci_disable_device(dev); */
+		pci_set_drvdata(dev, NULL);
+		framebuffer_release(info);
+	}
+}
+
+#ifdef CONFIG_PM
+static int i740fb_suspend(struct pci_dev *dev, pm_message_t state)
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+	struct i740fb_par *par = info->par;
+
+	/* don't disable console during hibernation and wakeup from it */
+	if (state.event = PM_EVENT_FREEZE || state.event = PM_EVENT_PRETHAW)
+		return 0;
+
+	console_lock();
+	mutex_lock(&(par->open_lock));
+
+	/* do nothing if framebuffer is not active */
+	if (par->ref_count = 0) {
+		mutex_unlock(&(par->open_lock));
+		console_unlock();
+		return 0;
+	}
+
+	fb_set_suspend(info, 1);
+
+	pci_save_state(dev);
+	pci_disable_device(dev);
+	pci_set_power_state(dev, pci_choose_state(dev, state));
+
+	mutex_unlock(&(par->open_lock));
+	console_unlock();
+
+	return 0;
+}
+
+static int i740fb_resume(struct pci_dev *dev)
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+	struct i740fb_par *par = info->par;
+
+	console_lock();
+	mutex_lock(&(par->open_lock));
+
+	if (par->ref_count = 0)
+		goto fail;
+
+	pci_set_power_state(dev, PCI_D0);
+	pci_restore_state(dev);
+	if (pci_enable_device(dev))
+		goto fail;
+
+	i740fb_set_par(info);
+	fb_set_suspend(info, 0);
+
+fail:
+	mutex_unlock(&(par->open_lock));
+	console_unlock();
+	return 0;
+}
+#else
+#define i740fb_suspend NULL
+#define i740fb_resume NULL
+#endif /* CONFIG_PM */
+
+#define I740_ID_PCI 0x00d1
+#define I740_ID_AGP 0x7800
+
+static DEFINE_PCI_DEVICE_TABLE(i740fb_id_table) = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, I740_ID_PCI) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, I740_ID_AGP) },
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, i740fb_id_table);
+
+static struct pci_driver i740fb_driver = {
+	.name		= "i740fb",
+	.id_table	= i740fb_id_table,
+	.probe		= i740fb_probe,
+	.remove		= __devexit_p(i740fb_remove),
+	.suspend	= i740fb_suspend,
+	.resume		= i740fb_resume,
+};
+
+#ifndef MODULE
+static int  __init i740fb_setup(char *options)
+{
+	char *opt;
+
+	if (!options || !*options)
+		return 0;
+
+	while ((opt = strsep(&options, ",")) != NULL) {
+		if (!*opt)
+			continue;
+#ifdef CONFIG_MTRR
+		else if (!strncmp(opt, "mtrr:", 5))
+			mtrr = simple_strtoul(opt + 5, NULL, 0);
+#endif
+		else
+			mode_option = opt;
+	}
+
+	return 0;
+}
+#endif
+
+int __init i740fb_init(void)
+{
+#ifndef MODULE
+	char *option = NULL;
+
+	if (fb_get_options("i740fb", &option))
+		return -ENODEV;
+	i740fb_setup(option);
+#endif
+
+	return pci_register_driver(&i740fb_driver);
+}
+
+static void __exit i740fb_exit(void)
+{
+	pci_unregister_driver(&i740fb_driver);
+}
+
+module_init(i740fb_init);
+module_exit(i740fb_exit);
+
+MODULE_AUTHOR("(c) 2011 Ondrej Zary <linux@rainbow-software.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("fbdev driver for Intel740");
+
+module_param(mode_option, charp, 0444);
+MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
+
+#ifdef CONFIG_MTRR
+module_param(mtrr, int, 0444);
+MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
+#endif
--- /dev/null	2011-10-28 20:05:27.615214131 +0200
+++ linux-2.6.39-rc2/drivers/video/i740_reg.h	2011-08-14 23:47:48.000000000 +0200
@@ -0,0 +1,309 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Kevin E. Martin <kevin@precisioninsight.com>
+ */
+
+/* I/O register offsets */
+#define SRX VGA_SEQ_I
+#define GRX VGA_GFX_I
+#define ARX VGA_ATT_IW
+#define XRX 0x3D6
+#define MRX 0x3D2
+
+/* VGA Color Palette Registers */
+#define DACMASK		0x3C6
+#define DACSTATE	0x3C7
+#define DACRX		0x3C7
+#define DACWX		0x3C8
+#define DACDATA		0x3C9
+
+/* CRT Controller Registers (CRX) */
+#define START_ADDR_HI		0x0C
+#define START_ADDR_LO		0x0D
+#define VERT_SYNC_END		0x11
+#define EXT_VERT_TOTAL		0x30
+#define EXT_VERT_DISPLAY	0x31
+#define EXT_VERT_SYNC_START	0x32
+#define EXT_VERT_BLANK_START	0x33
+#define EXT_HORIZ_TOTAL		0x35
+#define EXT_HORIZ_BLANK		0x39
+#define EXT_START_ADDR		0x40
+#define EXT_START_ADDR_ENABLE	0x80
+#define EXT_OFFSET		0x41
+#define EXT_START_ADDR_HI	0x42
+#define INTERLACE_CNTL		0x70
+#define INTERLACE_ENABLE	0x80
+#define INTERLACE_DISABLE	0x00
+
+/* Miscellaneous Output Register */
+#define MSR_R		0x3CC
+#define MSR_W		0x3C2
+#define IO_ADDR_SELECT	0x01
+
+#define MDA_BASE	0x3B0
+#define CGA_BASE	0x3D0
+
+/* System Configuration Extension Registers (XRX) */
+#define IO_CTNL		0x09
+#define EXTENDED_ATTR_CNTL	0x02
+#define EXTENDED_CRTC_CNTL	0x01
+
+#define ADDRESS_MAPPING	0x0A
+#define PACKED_MODE_ENABLE	0x04
+#define LINEAR_MODE_ENABLE	0x02
+#define PAGE_MAPPING_ENABLE	0x01
+
+#define BITBLT_CNTL	0x20
+#define COLEXP_MODE		0x30
+#define COLEXP_8BPP		0x00
+#define COLEXP_16BPP		0x10
+#define COLEXP_24BPP		0x20
+#define COLEXP_RESERVED		0x30
+#define CHIP_RESET		0x02
+#define BITBLT_STATUS		0x01
+
+#define DISPLAY_CNTL	0x40
+#define VGA_WRAP_MODE		0x02
+#define VGA_WRAP_AT_256KB	0x00
+#define VGA_NO_WRAP		0x02
+#define GUI_MODE		0x01
+#define STANDARD_VGA_MODE	0x00
+#define HIRES_MODE		0x01
+
+#define DRAM_ROW_TYPE	0x50
+#define DRAM_ROW_0		0x07
+#define DRAM_ROW_0_SDRAM	0x00
+#define DRAM_ROW_0_EMPTY	0x07
+#define DRAM_ROW_1		0x38
+#define DRAM_ROW_1_SDRAM	0x00
+#define DRAM_ROW_1_EMPTY	0x38
+#define DRAM_ROW_CNTL_LO 0x51
+#define DRAM_CAS_LATENCY	0x10
+#define DRAM_RAS_TIMING		0x08
+#define DRAM_RAS_PRECHARGE	0x04
+#define DRAM_ROW_CNTL_HI 0x52
+#define DRAM_EXT_CNTL	0x53
+#define DRAM_REFRESH_RATE	0x03
+#define DRAM_REFRESH_DISABLE	0x00
+#define DRAM_REFRESH_60HZ	0x01
+#define DRAM_REFRESH_FAST_TEST	0x02
+#define DRAM_REFRESH_RESERVED	0x03
+#define DRAM_TIMING	0x54
+#define DRAM_ROW_BNDRY_0 0x55
+#define DRAM_ROW_BNDRY_1 0x56
+
+#define DPMS_SYNC_SELECT 0x61
+#define VSYNC_CNTL		0x08
+#define VSYNC_ON		0x00
+#define VSYNC_OFF		0x08
+#define HSYNC_CNTL		0x02
+#define HSYNC_ON		0x00
+#define HSYNC_OFF		0x02
+
+#define PIXPIPE_CONFIG_0 0x80
+#define DAC_8_BIT		0x80
+#define DAC_6_BIT		0x00
+#define HW_CURSOR_ENABLE	0x10
+#define EXTENDED_PALETTE	0x01
+
+#define PIXPIPE_CONFIG_1 0x81
+#define DISPLAY_COLOR_MODE	0x0F
+#define DISPLAY_VGA_MODE	0x00
+#define DISPLAY_8BPP_MODE	0x02
+#define DISPLAY_15BPP_MODE	0x04
+#define DISPLAY_16BPP_MODE	0x05
+#define DISPLAY_24BPP_MODE	0x06
+#define DISPLAY_32BPP_MODE	0x07
+
+#define PIXPIPE_CONFIG_2 0x82
+#define DISPLAY_GAMMA_ENABLE	0x08
+#define DISPLAY_GAMMA_DISABLE	0x00
+#define OVERLAY_GAMMA_ENABLE	0x04
+#define OVERLAY_GAMMA_DISABLE	0x00
+
+#define CURSOR_CONTROL	0xA0
+#define CURSOR_ORIGIN_SCREEN	0x00
+#define CURSOR_ORIGIN_DISPLAY	0x10
+#define CURSOR_MODE		0x07
+#define CURSOR_MODE_DISABLE	0x00
+#define CURSOR_MODE_32_4C_AX	0x01
+#define CURSOR_MODE_128_2C	0x02
+#define CURSOR_MODE_128_1C	0x03
+#define CURSOR_MODE_64_3C	0x04
+#define CURSOR_MODE_64_4C_AX	0x05
+#define CURSOR_MODE_64_4C	0x06
+#define CURSOR_MODE_RESERVED	0x07
+#define CURSOR_BASEADDR_LO 0xA2
+#define CURSOR_BASEADDR_HI 0xA3
+#define CURSOR_X_LO	0xA4
+#define CURSOR_X_HI	0xA5
+#define CURSOR_X_POS		0x00
+#define CURSOR_X_NEG		0x80
+#define CURSOR_Y_LO	0xA6
+#define CURSOR_Y_HI	0xA7
+#define CURSOR_Y_POS		0x00
+#define CURSOR_Y_NEG		0x80
+
+#define VCLK2_VCO_M	0xC8
+#define VCLK2_VCO_N	0xC9
+#define VCLK2_VCO_MN_MSBS 0xCA
+#define VCO_N_MSBS		0x30
+#define VCO_M_MSBS		0x03
+#define VCLK2_VCO_DIV_SEL 0xCB
+#define POST_DIV_SELECT		0x70
+#define POST_DIV_1		0x00
+#define POST_DIV_2		0x10
+#define POST_DIV_4		0x20
+#define POST_DIV_8		0x30
+#define POST_DIV_16		0x40
+#define POST_DIV_32		0x50
+#define VCO_LOOP_DIV_BY_4M	0x00
+#define VCO_LOOP_DIV_BY_16M	0x04
+#define REF_CLK_DIV_BY_5	0x02
+#define REF_DIV_4		0x00
+#define REF_DIV_1		0x01
+
+#define PLL_CNTL	0xCE
+#define PLL_MEMCLK_SEL		0x03
+#define PLL_MEMCLK__66667KHZ	0x00
+#define PLL_MEMCLK__75000KHZ	0x01
+#define PLL_MEMCLK__88889KHZ	0x02
+#define PLL_MEMCLK_100000KHZ	0x03
+
+/* Multimedia Extension Registers (MRX) */
+#define ACQ_CNTL_1	0x02
+#define ACQ_CNTL_2	0x03
+#define FRAME_CAP_MODE		0x01
+#define CONT_CAP_MODE		0x00
+#define SINGLE_CAP_MODE		0x01
+#define ACQ_CNTL_3	0x04
+#define COL_KEY_CNTL_1		0x3C
+#define BLANK_DISP_OVERLAY	0x20
+
+/* FIFOs */
+#define LP_FIFO		0x1000
+#define HP_FIFO		0x2000
+#define INSTPNT		0x3040
+#define LP_FIFO_COUNT	0x3040
+#define HP_FIFO_COUNT	0x3041
+
+/* FIFO Commands */
+#define CLIENT		0xE0000000
+#define CLIENT_2D	0x60000000
+
+/* Command Parser Mode Register */
+#define COMPARS		0x3038
+#define TWO_D_INST_DISABLE		0x08
+#define THREE_D_INST_DISABLE		0x04
+#define STATE_VAR_UPDATE_DISABLE	0x02
+#define PAL_STIP_DISABLE		0x01
+
+/* Interrupt Control Registers */
+#define IER		0x3030
+#define IIR		0x3032
+#define IMR		0x3034
+#define ISR		0x3036
+#define VMIINTB_EVENT		0x2000
+#define GPIO4_INT		0x1000
+#define DISP_FLIP_EVENT		0x0800
+#define DVD_PORT_DMA		0x0400
+#define DISP_VBLANK		0x0200
+#define FIFO_EMPTY_DMA_DONE	0x0100
+#define INST_PARSER_ERROR	0x0080
+#define USER_DEFINED		0x0040
+#define BREAKPOINT		0x0020
+#define DISP_HORIZ_COUNT	0x0010
+#define DISP_VSYNC		0x0008
+#define CAPTURE_HORIZ_COUNT	0x0004
+#define CAPTURE_VSYNC		0x0002
+#define THREE_D_PIPE_FLUSHED	0x0001
+
+/* FIFO Watermark and Burst Length Control Register */
+#define FWATER_BLC	0x00006000
+#define LMI_BURST_LENGTH	0x7F000000
+#define LMI_FIFO_WATERMARK	0x003F0000
+#define AGP_BURST_LENGTH	0x00007F00
+#define AGP_FIFO_WATERMARK	0x0000003F
+
+/* BitBLT Registers */
+#define SRC_DST_PITCH	0x00040000
+#define DST_PITCH		0x1FFF0000
+#define SRC_PITCH		0x00001FFF
+#define COLEXP_BG_COLOR	0x00040004
+#define COLEXP_FG_COLOR	0x00040008
+#define MONO_SRC_CNTL	0x0004000C
+#define MONO_USE_COLEXP		0x00000000
+#define MONO_USE_SRCEXP		0x08000000
+#define MONO_DATA_ALIGN		0x07000000
+#define MONO_BIT_ALIGN		0x01000000
+#define MONO_BYTE_ALIGN		0x02000000
+#define MONO_WORD_ALIGN		0x03000000
+#define MONO_DWORD_ALIGN	0x04000000
+#define MONO_QWORD_ALIGN	0x05000000
+#define MONO_SRC_INIT_DSCRD	0x003F0000
+#define MONO_SRC_RIGHT_CLIP	0x00003F00
+#define MONO_SRC_LEFT_CLIP	0x0000003F
+#define BITBLT_CONTROL	0x00040010
+#define BLTR_STATUS		0x80000000
+#define DYN_DEPTH		0x03000000
+#define DYN_DEPTH_8BPP		0x00000000
+#define DYN_DEPTH_16BPP		0x01000000
+#define DYN_DEPTH_24BPP		0x02000000
+#define DYN_DEPTH_32BPP		0x03000000	/* Not implemented on the i740 */
+#define DYN_DEPTH_ENABLE	0x00800000
+#define PAT_VERT_ALIGN		0x00700000
+#define SOLID_PAT_SELECT	0x00080000
+#define PAT_IS_IN_COLOR		0x00000000
+#define PAT_IS_MONO		0x00040000
+#define MONO_PAT_TRANSP		0x00020000
+#define COLOR_TRANSP_ROP	0x00000000
+#define COLOR_TRANSP_DST	0x00008000
+#define COLOR_TRANSP_EQ		0x00000000
+#define COLOR_TRANSP_NOT_EQ	0x00010000
+#define COLOR_TRANSP_ENABLE	0x00004000
+#define MONO_SRC_TRANSP		0x00002000
+#define SRC_IS_IN_COLOR		0x00000000
+#define SRC_IS_MONO		0x00001000
+#define SRC_USE_SRC_ADDR	0x00000000
+#define SRC_USE_BLTDATA		0x00000400
+#define BLT_TOP_TO_BOT		0x00000000
+#define BLT_BOT_TO_TOP		0x00000200
+#define BLT_LEFT_TO_RIGHT	0x00000000
+#define BLT_RIGHT_TO_LEFT	0x00000100
+#define BLT_ROP			0x000000FF
+#define BLT_PAT_ADDR	0x00040014
+#define BLT_SRC_ADDR	0x00040018
+#define BLT_DST_ADDR	0x0004001C
+#define BLT_DST_H_W	0x00040020
+#define BLT_DST_HEIGHT		0x1FFF0000
+#define BLT_DST_WIDTH		0x00001FFF
+#define SRCEXP_BG_COLOR	0x00040024
+#define SRCEXP_FG_COLOR	0x00040028
+#define BLTDATA		0x00050000


-- 
Ondrej Zary

^ permalink raw reply

* Re: [PATCH v3.1] [resend] Resurrect Intel740 driver: i740fb
From: Tabi Timur-B04825 @ 2011-11-18 23:53 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: linux-fbdev@vger.kernel.org, Florian Tobias Schandinat,
	Paul Mundt, Kernel development list
In-Reply-To: <201111182154.45139.linux@rainbow-software.org>

On Fri, Nov 18, 2011 at 2:54 PM, Ondrej Zary <linux@rainbow-software.org> wrote:
> Hello,
> this is an v3 attempt to resurrect an old (like 2.4.19) out-of-tree driver for
> Intel740 graphics cards and modify it for recent kernels. The old driver is
> located at: http://sourceforge.net/projects/i740fbdev/files/

Would you please run checkpatch.pl on the patch and fix the complaints
it has?  I get this:

total: 45 errors, 67 warnings, 1619 lines checked

This patch has tons of style problems.

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* Re: [PATCH] fb: split out framebuffer initialization from allocation
From: Florian Tobias Schandinat @ 2011-11-19  5:06 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1321308088-6327-1-git-send-email-timur@freescale.com>

Hi Timur,

On 11/17/2011 08:19 PM, Timur Tabi wrote:
> Timur Tabi wrote:
>> Introduce functions framebuffer_init() and framebuffer_cleanup() to allow
>> the initialization of a user-allocated fb_info object.
>>
>> framebuffer_alloc() allows for appending a private data structure when it
>> allocates the fb_info object.  However, a driver that registers multiple
>> framebuffers for one device may also need another private data structure
>> for the device itself.  framebuffer_init() allows such drivers to store
>> the fb_info objects in the device-specific private data structure,
>> thereby simplifying memory allocation.
>>
>> Signed-off-by: Timur Tabi <timur@freescale.com>
> 
> Florian,
> 
> Any comments on this patch?  If you're okay with the change, I want to take
> advantage of it in my framebuffer driver.

Of course you want, otherwise I'd be wondering why you are sending this patch
at all.

But I don't see any advantages of your approach. Instead of pointers to fb_info
with this patch you could embed fb_info directly in your data structure but that
is barely a difference for a programmer I'd think. You'd still have to call your
new functions on init/exit so the amount of function calls needed is the same
with or without the patch (I could see an advantage if alloc and release were
pure memory allocations). Or is this all about handling the case when fb_alloc
fails?
Historically some drivers don't even call alloc but have their own fb_info and
call only register. I do not want to add yet another way of doing framebuffer
initialization unless you can clearly show its benefits.


Best regards,

Florian Tobias Schandinat

^ permalink raw reply

* Re: [PATCH v3.1] [resend] Resurrect Intel740 driver: i740fb
From: Ondrej Zary @ 2011-11-19 11:11 UTC (permalink / raw)
  To: Tabi Timur-B04825
  Cc: linux-fbdev@vger.kernel.org, Florian Tobias Schandinat,
	Paul Mundt, Kernel development list
In-Reply-To: <CAOZdJXVx88nEAQkL13n1QXVw=kOe03QsD=pffHoZ8gecL7u8dA@mail.gmail.com>

On Saturday 19 November 2011 00:53:27 Tabi Timur-B04825 wrote:
> On Fri, Nov 18, 2011 at 2:54 PM, Ondrej Zary <linux@rainbow-software.org> 
wrote:
> > Hello,
> > this is an v3 attempt to resurrect an old (like 2.4.19) out-of-tree
> > driver for Intel740 graphics cards and modify it for recent kernels. The
> > old driver is located at:
> > http://sourceforge.net/projects/i740fbdev/files/
>
> Would you please run checkpatch.pl on the patch and fix the complaints
> it has?  I get this:
>
> total: 45 errors, 67 warnings, 1619 lines checked
>
> This patch has tons of style problems.

The 45 errors are in i740_calc_fifo(), which now looks good and is readable. 
Reformatting according to checkpatch makes it look bad and unredable. This 
was already discussed before.
The warnings are lines over 80 characters, which are common in most fb 
drivers. Splitting them makes code hard to read.

-- 
Ondrej Zary

^ permalink raw reply

* Re: [PATCH] fb: split out framebuffer initialization from
From: Bruno Prémont @ 2011-11-19 11:47 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1321308088-6327-1-git-send-email-timur@freescale.com>

Hi Florian, Timur,

On Sat, 19 November 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de> wrote:
> On 11/17/2011 08:19 PM, Timur Tabi wrote:
> > Timur Tabi wrote:
> >> Introduce functions framebuffer_init() and framebuffer_cleanup() to allow
> >> the initialization of a user-allocated fb_info object.
> >>
> >> framebuffer_alloc() allows for appending a private data structure when it
> >> allocates the fb_info object.  However, a driver that registers multiple
> >> framebuffers for one device may also need another private data structure
> >> for the device itself.  framebuffer_init() allows such drivers to store
> >> the fb_info objects in the device-specific private data structure,
> >> thereby simplifying memory allocation.
> >>
> >> Signed-off-by: Timur Tabi <timur@freescale.com>
> > 
> > Florian,
> > 
> > Any comments on this patch?  If you're okay with the change, I want to take
> > advantage of it in my framebuffer driver.
> 
> Of course you want, otherwise I'd be wondering why you are sending this patch
> at all.
> 
> But I don't see any advantages of your approach. Instead of pointers to fb_info
> with this patch you could embed fb_info directly in your data structure but that
> is barely a difference for a programmer I'd think. You'd still have to call your
> new functions on init/exit so the amount of function calls needed is the same
> with or without the patch (I could see an advantage if alloc and release were
> pure memory allocations). Or is this all about handling the case when fb_alloc
> fails?
> Historically some drivers don't even call alloc but have their own fb_info and
> call only register. I do not want to add yet another way of doing framebuffer
> initialization unless you can clearly show its benefits.

Wouldn't it even make sense to move some more of the initialization of fb_info
out of fb registration into this new init funtion? (I'm thinking about initializing
mutexes and the like)

This way fb_info could be used before being registered. Registration would then
be reduced to makeing the framebuffer visible to userspace and listed in
registered_fb[].

This way framebuffer_alloc() would be no more that kzalloc(), framebuffer_init()
would setup all "non-zero" fields of fb_info (including setup of all mutexes, one
of which is currently being done by framebuffer_alloc() and the rest by
do_register_framebuffer()!).

Bruno

> Best regards,
> 
> Florian Tobias Schandinat

^ permalink raw reply

* Re: [PATCH] fb: split out framebuffer initialization from allocation
From: Florian Tobias Schandinat @ 2011-11-19 12:08 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1321308088-6327-1-git-send-email-timur@freescale.com>

Hi Bruno,

On 11/19/2011 11:47 AM, Bruno Prémont wrote:
> Hi Florian, Timur,
> 
> On Sat, 19 November 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de> wrote:
>> On 11/17/2011 08:19 PM, Timur Tabi wrote:
>>> Timur Tabi wrote:
>>>> Introduce functions framebuffer_init() and framebuffer_cleanup() to allow
>>>> the initialization of a user-allocated fb_info object.
>>>>
>>>> framebuffer_alloc() allows for appending a private data structure when it
>>>> allocates the fb_info object.  However, a driver that registers multiple
>>>> framebuffers for one device may also need another private data structure
>>>> for the device itself.  framebuffer_init() allows such drivers to store
>>>> the fb_info objects in the device-specific private data structure,
>>>> thereby simplifying memory allocation.
>>>>
>>>> Signed-off-by: Timur Tabi <timur@freescale.com>
>>>
>>> Florian,
>>>
>>> Any comments on this patch?  If you're okay with the change, I want to take
>>> advantage of it in my framebuffer driver.
>>
>> Of course you want, otherwise I'd be wondering why you are sending this patch
>> at all.
>>
>> But I don't see any advantages of your approach. Instead of pointers to fb_info
>> with this patch you could embed fb_info directly in your data structure but that
>> is barely a difference for a programmer I'd think. You'd still have to call your
>> new functions on init/exit so the amount of function calls needed is the same
>> with or without the patch (I could see an advantage if alloc and release were
>> pure memory allocations). Or is this all about handling the case when fb_alloc
>> fails?
>> Historically some drivers don't even call alloc but have their own fb_info and
>> call only register. I do not want to add yet another way of doing framebuffer
>> initialization unless you can clearly show its benefits.
> 
> Wouldn't it even make sense to move some more of the initialization of fb_info
> out of fb registration into this new init funtion? (I'm thinking about initializing
> mutexes and the like)

This would require someone going through all framebuffers and change them to use
the new fb_init function if they don't use fb_alloc. I'd accept this patch as an
improvement iff someone would do this. Than the number of variation of doing
framebuffer initialization would remain the same. Of course the same should be
done for fb_cleanup.


Best regards,

Florian Tobias Schandinat

> This way fb_info could be used before being registered. Registration would then
> be reduced to makeing the framebuffer visible to userspace and listed in
> registered_fb[].
> 
> This way framebuffer_alloc() would be no more that kzalloc(), framebuffer_init()
> would setup all "non-zero" fields of fb_info (including setup of all mutexes, one
> of which is currently being done by framebuffer_alloc() and the rest by
> do_register_framebuffer()!).
> 
> Bruno
> 
>> Best regards,
>>
>> Florian Tobias Schandinat
> 


^ permalink raw reply

* Re: [PATCH] fb: split out framebuffer initialization from
From: Bruno Prémont @ 2011-11-19 12:35 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1321308088-6327-1-git-send-email-timur@freescale.com>

Hi Florian,

On Sat, 19 November 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de> wrote:
> On 11/19/2011 11:47 AM, Bruno Prémont wrote:
> > On Sat, 19 November 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de> wrote:
> >> On 11/17/2011 08:19 PM, Timur Tabi wrote:
> >>> Timur Tabi wrote:
> >>>> Introduce functions framebuffer_init() and framebuffer_cleanup() to allow
> >>>> the initialization of a user-allocated fb_info object.
> >>>>
> >>>> framebuffer_alloc() allows for appending a private data structure when it
> >>>> allocates the fb_info object.  However, a driver that registers multiple
> >>>> framebuffers for one device may also need another private data structure
> >>>> for the device itself.  framebuffer_init() allows such drivers to store
> >>>> the fb_info objects in the device-specific private data structure,
> >>>> thereby simplifying memory allocation.
> >>>>
> >>>> Signed-off-by: Timur Tabi <timur@freescale.com>
> >>>
> >>> Florian,
> >>>
> >>> Any comments on this patch?  If you're okay with the change, I want to take
> >>> advantage of it in my framebuffer driver.
> >>
> >> Of course you want, otherwise I'd be wondering why you are sending this patch
> >> at all.
> >>
> >> But I don't see any advantages of your approach. Instead of pointers to fb_info
> >> with this patch you could embed fb_info directly in your data structure but that
> >> is barely a difference for a programmer I'd think. You'd still have to call your
> >> new functions on init/exit so the amount of function calls needed is the same
> >> with or without the patch (I could see an advantage if alloc and release were
> >> pure memory allocations). Or is this all about handling the case when fb_alloc
> >> fails?
> >> Historically some drivers don't even call alloc but have their own fb_info and
> >> call only register. I do not want to add yet another way of doing framebuffer
> >> initialization unless you can clearly show its benefits.
> > 
> > Wouldn't it even make sense to move some more of the initialization of fb_info
> > out of fb registration into this new init funtion? (I'm thinking about initializing
> > mutexes and the like)
> 
> This would require someone going through all framebuffers and change them to use
> the new fb_init function if they don't use fb_alloc. I'd accept this patch as an
> improvement iff someone would do this. Than the number of variation of doing
> framebuffer initialization would remain the same. Of course the same should be
> done for fb_cleanup.

I agree, though (in a first step) alloc_framebuffer() could call init_framebuffer()
by itself (same goes for cleanup on release) so that only those doing the memory
allocation manually have to be changed (though I'm wondering if those are not already
wrong with regard to fb_info.bl_curve_mutex which is being initialized in
alloc_framebuffer() - but then again they will not use backlight).

I might give it a try once I'm no more busy with system administration.

Bruno

> > This way fb_info could be used before being registered. Registration would then
> > be reduced to makeing the framebuffer visible to userspace and listed in
> > registered_fb[].
> > 
> > This way framebuffer_alloc() would be no more that kzalloc(), framebuffer_init()
> > would setup all "non-zero" fields of fb_info (including setup of all mutexes, one
> > of which is currently being done by framebuffer_alloc() and the rest by
> > do_register_framebuffer()!).

^ permalink raw reply

* Re: [PATCH] video:da8xx-fb: Add 24bpp LCD configuration support
From: Florian Tobias Schandinat @ 2011-11-20  0:41 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1321358479-20390-1-git-send-email-prakash.pm@ti.com>

On 11/15/2011 12:01 PM, Manjunathappa, Prakash wrote:
> LCD controller on am335x supports 24bpp raster configuration
> in addition to ones on da850. LCDC also supports 24bpp in unpacked
> format having ARGB:8888 32bpp format data in DDR, but it doesn't
> interpret Alpha component of the data.
> 
> Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
> ---
>  drivers/video/da8xx-fb.c |   57 +++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 56 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index 55f91d9..e111971 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -82,6 +82,8 @@
>  #define LCD_V2_LIDD_CLK_EN		BIT(1)
>  #define LCD_V2_CORE_CLK_EN		BIT(0)
>  #define LCD_V2_LPP_B10			26
> +#define LCD_V2_TFT_24BPP_MODE		BIT(25)
> +#define LCD_V2_TFT_24BPP_UNPACK		BIT(26)
>  
>  /* LCD Raster Timing 2 Register */
>  #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x)	((x) << 16)
> @@ -151,7 +153,7 @@ struct da8xx_fb_par {
>  	unsigned int		dma_end;
>  	struct clk *lcdc_clk;
>  	int irq;
> -	unsigned short pseudo_palette[16];
> +	unsigned short pseudo_palette[32];

This looks wrong, include/linux/fb.h says:
"void *pseudo_palette;           /* Fake palette of 16 colors */"
This will probably also simplify the code below to write to the pseudo palette.
But I think you have to increase the data type of the palette, maybe to u32?


Best regards,

Florian Tobias Schandinat

>  	unsigned int palette_sz;
>  	unsigned int pxl_clk;
>  	int blank;
> @@ -458,6 +460,9 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
>  {
>  	u32 reg;
>  
> +	if ((bpp > 16) && (lcd_revision = LCD_VERSION_1))
> +		return -EINVAL;
> +
>  	/* Set the Panel Width */
>  	/* Pixels per line = (PPL + 1)*16 */
>  	if (lcd_revision = LCD_VERSION_1) {
> @@ -501,6 +506,13 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
>  	reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
>  	if (raster_order)
>  		reg |= LCD_RASTER_ORDER;
> +
> +	if (bpp = 24)
> +		reg |= (LCD_TFT_MODE | LCD_V2_TFT_24BPP_MODE);
> +	else if (bpp = 32)
> +		reg |= (LCD_TFT_MODE | LCD_V2_TFT_24BPP_MODE
> +				| LCD_V2_TFT_24BPP_UNPACK);
> +
>  	lcdc_write(reg, LCD_RASTER_CTRL_REG);
>  
>  	switch (bpp) {
> @@ -508,6 +520,8 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
>  	case 2:
>  	case 4:
>  	case 16:
> +	case 24:
> +	case 32:
>  		par->palette_sz = 16 * 2;
>  		break;
>  
> @@ -537,6 +551,9 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
>  	if (info->fix.visual = FB_VISUAL_DIRECTCOLOR)
>  		return 1;
>  
> +	if ((info->var.bits_per_pixel > 16) && (lcd_revision = LCD_VERSION_1))
> +		return 1;
> +
>  	if (info->var.bits_per_pixel = 8) {
>  		red >>= 4;
>  		green >>= 8;
> @@ -566,6 +583,23 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
>  			update_hw = 1;
>  			palette[0] = 0x4000;
>  		}
> +	} else if (((info->var.bits_per_pixel = 32) && regno < 32) ||
> +		    ((info->var.bits_per_pixel = 24) && regno < 24)) {
> +		red >>= (24 - info->var.red.length);
> +		red <<= info->var.red.offset;
> +
> +		green >>= (24 - info->var.green.length);
> +		green <<= info->var.green.offset;
> +
> +		blue >>= (24 - info->var.blue.length);
> +		blue <<= info->var.blue.offset;
> +
> +		par->pseudo_palette[regno] = red | green | blue;
> +
> +		if (palette[0] != 0x4000) {
> +			update_hw = 1;
> +			palette[0] = 0x4000;
> +		}
>  	}
>  
>  	/* Update the palette in the h/w as needed. */
> @@ -777,6 +811,9 @@ static int fb_check_var(struct fb_var_screeninfo *var,
>  {
>  	int err = 0;
>  
> +	if ((var->bits_per_pixel > 16) && (lcd_revision = LCD_VERSION_1))
> +		return -EINVAL;
> +
>  	switch (var->bits_per_pixel) {
>  	case 1:
>  	case 8:
> @@ -809,6 +846,24 @@ static int fb_check_var(struct fb_var_screeninfo *var,
>  		var->transp.offset = 0;
>  		var->transp.length = 0;
>  		break;
> +	case 24:
> +		var->red.offset = 16;
> +		var->red.length = 8;
> +		var->green.offset = 8;
> +		var->green.length = 8;
> +		var->blue.offset = 0;
> +		var->blue.length = 8;
> +		break;
> +	case 32:
> +		var->transp.offset = 24;
> +		var->transp.length = 8;
> +		var->red.offset = 16;
> +		var->red.length = 8;
> +		var->green.offset = 8;
> +		var->green.length = 8;
> +		var->blue.offset = 0;
> +		var->blue.length = 8;
> +		break;
>  	default:
>  		err = -EINVAL;
>  	}


^ permalink raw reply

* Re: [PATCH 5/5] Drivers: video: riva: riva_hw: fixed a brace coding
From: Florian Tobias Schandinat @ 2011-11-20  1:50 UTC (permalink / raw)
  To: Zac Storer; +Cc: linux-fbdev, linux-kernel
In-Reply-To: <1321591537-8475-1-git-send-email-zac.3.14159@gmail.com>

On 11/18/2011 04:45 AM, Zac Storer wrote:
> Fixed a brace coding style issue.

*sigh* You are fixing coding style, but I still get lots of warnings for the
single line you are changing. IF you are fixing coding style, at least do it
right. Or do you really expect me to be happy if you send me 3 patches that all
touch the same line?
Really, if you want to fix it, at least fix it in a way that checkpatch.pl does
no longer complain about your patch, at least regarding coding style issues. And
for such patches I think a per file patch or similar would be appropriate.


Regards,

Florian Tobias Schandinat

> 
> Signed-off-by: Zac Storer <zac.3.14159@gmail.com>
> ---
>  drivers/video/riva/riva_hw.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/riva/riva_hw.c
> index 78fdbf5..c4b8a6f 100644
> --- a/drivers/video/riva/riva_hw.c
> +++ b/drivers/video/riva/riva_hw.c
> @@ -994,7 +994,7 @@ static void nv10CalcArbitration
>                clwm = clwm_mt;
>    */
>            /* Finally, a heuristic check when width = 64 bits */
> -          if(width = 1){
> +          if(width = 1) {
>                nvclk_fill = nvclk_freq * 8;
>                if(crtc_drain_rate * 100 >= nvclk_fill * 102)
>                        clwm = 0xfff; /*Large number to fail */


^ permalink raw reply

* Re: [PATCH v3 1/3] fbdev: Add FOURCC-based format configuration API
From: Florian Tobias Schandinat @ 2011-11-20  2:00 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-fbdev, linux-media, magnus.damm
In-Reply-To: <1314789501-824-2-git-send-email-laurent.pinchart@ideasonboard.com>

Hi Laurent,

On 08/31/2011 11:18 AM, Laurent Pinchart wrote:
> This API will be used to support YUV frame buffer formats in a standard
> way.

looks like the union is causing problems. With this patch applied I get errors
like this:

  CC [M]  drivers/auxdisplay/cfag12864bfb.o
drivers/auxdisplay/cfag12864bfb.c:57: error: unknown field ‘red’ specified in
initializer
drivers/auxdisplay/cfag12864bfb.c:57: warning: missing braces around initializer
drivers/auxdisplay/cfag12864bfb.c:57: warning: (near initialization for
‘cfag12864bfb_var.<anonymous>.<anonymous>’)
drivers/auxdisplay/cfag12864bfb.c:58: error: unknown field ‘green’ specified in
initializer
drivers/auxdisplay/cfag12864bfb.c:58: warning: braces around scalar initializer
drivers/auxdisplay/cfag12864bfb.c:58: warning: (near initialization for
‘cfag12864bfb_var.nonstd’)
drivers/auxdisplay/cfag12864bfb.c:58: warning: excess elements in scalar initializer
drivers/auxdisplay/cfag12864bfb.c:58: warning: (near initialization for
‘cfag12864bfb_var.nonstd’)
drivers/auxdisplay/cfag12864bfb.c:58: warning: excess elements in scalar initializer
drivers/auxdisplay/cfag12864bfb.c:58: warning: (near initialization for
‘cfag12864bfb_var.nonstd’)
drivers/auxdisplay/cfag12864bfb.c:59: error: unknown field ‘blue’ specified in
initializer
drivers/auxdisplay/cfag12864bfb.c:59: warning: braces around scalar initializer
drivers/auxdisplay/cfag12864bfb.c:59: warning: (near initialization for
‘cfag12864bfb_var.activate’)
drivers/auxdisplay/cfag12864bfb.c:59: warning: excess elements in scalar initializer
drivers/auxdisplay/cfag12864bfb.c:59: warning: (near initialization for
‘cfag12864bfb_var.activate’)
drivers/auxdisplay/cfag12864bfb.c:59: warning: excess elements in scalar initializer
drivers/auxdisplay/cfag12864bfb.c:59: warning: (near initialization for
‘cfag12864bfb_var.activate’)
make[2]: *** [drivers/auxdisplay/cfag12864bfb.o] Error 1

Any idea?


Best regards,

Florian Tobias Schandinat

> 
> Last but not least, create a much needed fbdev API documentation and
> document the format setting APIs.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  Documentation/fb/api.txt |  317 ++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/fb.h       |   28 +++-
>  2 files changed, 339 insertions(+), 6 deletions(-)
>  create mode 100644 Documentation/fb/api.txt
> 
> diff --git a/Documentation/fb/api.txt b/Documentation/fb/api.txt
> new file mode 100644
> index 0000000..d842534
> --- /dev/null
> +++ b/Documentation/fb/api.txt
> @@ -0,0 +1,317 @@
> +			The Frame Buffer Device API
> +			---------------------------
> +
> +Last revised: June 21, 2011
> +
> +
> +0. Introduction
> +---------------
> +
> +This document describes the frame buffer API used by applications to interact
> +with frame buffer devices. In-kernel APIs between device drivers and the frame
> +buffer core are not described.
> +
> +Due to a lack of documentation in the original frame buffer API, drivers
> +behaviours differ in subtle (and not so subtle) ways. This document describes
> +the recommended API implementation, but applications should be prepared to
> +deal with different behaviours.
> +
> +
> +1. Capabilities
> +---------------
> +
> +Device and driver capabilities are reported in the fixed screen information
> +capabilities field.
> +
> +struct fb_fix_screeninfo {
> +	...
> +	__u16 capabilities;		/* see FB_CAP_*			*/
> +	...
> +};
> +
> +Application should use those capabilities to find out what features they can
> +expect from the device and driver.
> +
> +- FB_CAP_FOURCC
> +
> +The driver supports the four character code (FOURCC) based format setting API.
> +When supported, formats are configured using a FOURCC instead of manually
> +specifying color components layout.
> +
> +
> +2. Types and visuals
> +--------------------
> +
> +Pixels are stored in memory in hardware-dependent formats. Applications need
> +to be aware of the pixel storage format in order to write image data to the
> +frame buffer memory in the format expected by the hardware.
> +
> +Formats are described by frame buffer types and visuals. Some visuals require
> +additional information, which are stored in the variable screen information
> +bits_per_pixel, grayscale, fourcc, red, green, blue and transp fields.
> +
> +Visuals describe how color information is encoded and assembled to create
> +macropixels. Types describe how macropixels are stored in memory. The following
> +types and visuals are supported.
> +
> +- FB_TYPE_PACKED_PIXELS
> +
> +Macropixels are stored contiguously in a single plane. If the number of bits
> +per macropixel is not a multiple of 8, whether macropixels are padded to the
> +next multiple of 8 bits or packed together into bytes depends on the visual.
> +
> +Padding at end of lines may be present and is then reported through the fixed
> +screen information line_length field.
> +
> +- FB_TYPE_PLANES
> +
> +Macropixels are split across multiple planes. The number of planes is equal to
> +the number of bits per macropixel, with plane i'th storing i'th bit from all
> +macropixels.
> +
> +Planes are located contiguously in memory.
> +
> +- FB_TYPE_INTERLEAVED_PLANES
> +
> +Macropixels are split across multiple planes. The number of planes is equal to
> +the number of bits per macropixel, with plane i'th storing i'th bit from all
> +macropixels.
> +
> +Planes are interleaved in memory. The interleave factor, defined as the
> +distance in bytes between the beginning of two consecutive interleaved blocks
> +belonging to different planes, is stored in the fixed screen information
> +type_aux field.
> +
> +- FB_TYPE_FOURCC
> +
> +Macropixels are stored in memory as described by the format FOURCC identifier
> +stored in the variable screen information fourcc field.
> +
> +- FB_VISUAL_MONO01
> +
> +Pixels are black or white and stored on a number of bits (typically one)
> +specified by the variable screen information bpp field.
> +
> +Black pixels are represented by all bits set to 1 and white pixels by all bits
> +set to 0. When the number of bits per pixel is smaller than 8, several pixels
> +are packed together in a byte.
> +
> +FB_VISUAL_MONO01 is currently used with FB_TYPE_PACKED_PIXELS only.
> +
> +- FB_VISUAL_MONO10
> +
> +Pixels are black or white and stored on a number of bits (typically one)
> +specified by the variable screen information bpp field.
> +
> +Black pixels are represented by all bits set to 0 and white pixels by all bits
> +set to 1. When the number of bits per pixel is smaller than 8, several pixels
> +are packed together in a byte.
> +
> +FB_VISUAL_MONO01 is currently used with FB_TYPE_PACKED_PIXELS only.
> +
> +- FB_VISUAL_TRUECOLOR
> +
> +Pixels are broken into red, green and blue components, and each component
> +indexes a read-only lookup table for the corresponding value. Lookup tables
> +are device-dependent, and provide linear or non-linear ramps.
> +
> +Each component is stored in a macropixel according to the variable screen
> +information red, green, blue and transp fields.
> +
> +- FB_VISUAL_PSEUDOCOLOR and FB_VISUAL_STATIC_PSEUDOCOLOR
> +
> +Pixel values are encoded as indices into a colormap that stores red, green and
> +blue components. The colormap is read-only for FB_VISUAL_STATIC_PSEUDOCOLOR
> +and read-write for FB_VISUAL_PSEUDOCOLOR.
> +
> +Each pixel value is stored in the number of bits reported by the variable
> +screen information bits_per_pixel field.
> +
> +- FB_VISUAL_DIRECTCOLOR
> +
> +Pixels are broken into red, green and blue components, and each component
> +indexes a programmable lookup table for the corresponding value.
> +
> +Each component is stored in a macropixel according to the variable screen
> +information red, green, blue and transp fields.
> +
> +- FB_VISUAL_FOURCC
> +
> +Pixels are encoded and  interpreted as described by the format FOURCC
> +identifier stored in the variable screen information fourcc field.
> +
> +
> +3. Screen information
> +---------------------
> +
> +Screen information are queried by applications using the FBIOGET_FSCREENINFO
> +and FBIOGET_VSCREENINFO ioctls. Those ioctls take a pointer to a
> +fb_fix_screeninfo and fb_var_screeninfo structure respectively.
> +
> +struct fb_fix_screeninfo stores device independent unchangeable information
> +about the frame buffer device and the current format. Those information can't
> +be directly modified by applications, but can be changed by the driver when an
> +application modifies the format.
> +
> +struct fb_fix_screeninfo {
> +	char id[16];			/* identification string eg "TT Builtin" */
> +	unsigned long smem_start;	/* Start of frame buffer mem */
> +					/* (physical address) */
> +	__u32 smem_len;			/* Length of frame buffer mem */
> +	__u32 type;			/* see FB_TYPE_*		*/
> +	__u32 type_aux;			/* Interleave for interleaved Planes */
> +	__u32 visual;			/* see FB_VISUAL_*		*/
> +	__u16 xpanstep;			/* zero if no hardware panning  */
> +	__u16 ypanstep;			/* zero if no hardware panning  */
> +	__u16 ywrapstep;		/* zero if no hardware ywrap    */
> +	__u32 line_length;		/* length of a line in bytes    */
> +	unsigned long mmio_start;	/* Start of Memory Mapped I/O   */
> +					/* (physical address) */
> +	__u32 mmio_len;			/* Length of Memory Mapped I/O  */
> +	__u32 accel;			/* Indicate to driver which	*/
> +					/*  specific chip/card we have	*/
> +	__u16 capabilities;		/* see FB_CAP_*			*/
> +	__u16 reserved[2];		/* Reserved for future compatibility */
> +};
> +
> +struct fb_var_screeninfo stores device independent changeable information
> +about a frame buffer device, its current format and video mode, as well as
> +other miscellaneous parameters.
> +
> +struct fb_var_screeninfo {
> +	__u32 xres;			/* visible resolution		*/
> +	__u32 yres;
> +	__u32 xres_virtual;		/* virtual resolution		*/
> +	__u32 yres_virtual;
> +	__u32 xoffset;			/* offset from virtual to visible */
> +	__u32 yoffset;			/* resolution			*/
> +
> +	__u32 bits_per_pixel;		/* guess what			*/
> +	union {
> +		struct {		/* Legacy format API		*/
> +			__u32 grayscale; /* 0 = color, 1 = grayscale	*/
> +			/* bitfields in fb mem if true color, else only */
> +			/* length is significant			*/
> +			struct fb_bitfield red;
> +			struct fb_bitfield green;
> +			struct fb_bitfield blue;
> +			struct fb_bitfield transp;	/* transparency	*/
> +		};
> +		struct {		/* FOURCC-based format API	*/
> +			__u32 fourcc;		/* FOURCC format	*/
> +			__u32 colorspace;
> +			__u32 reserved[11];
> +		} fourcc;
> +	};
> +
> +	__u32 nonstd;			/* != 0 Non standard pixel format */
> +
> +	__u32 activate;			/* see FB_ACTIVATE_*		*/
> +
> +	__u32 height;			/* height of picture in mm    */
> +	__u32 width;			/* width of picture in mm     */
> +
> +	__u32 accel_flags;		/* (OBSOLETE) see fb_info.flags */
> +
> +	/* Timing: All values in pixclocks, except pixclock (of course) */
> +	__u32 pixclock;			/* pixel clock in ps (pico seconds) */
> +	__u32 left_margin;		/* time from sync to picture	*/
> +	__u32 right_margin;		/* time from picture to sync	*/
> +	__u32 upper_margin;		/* time from sync to picture	*/
> +	__u32 lower_margin;
> +	__u32 hsync_len;		/* length of horizontal sync	*/
> +	__u32 vsync_len;		/* length of vertical sync	*/
> +	__u32 sync;			/* see FB_SYNC_*		*/
> +	__u32 vmode;			/* see FB_VMODE_*		*/
> +	__u32 rotate;			/* angle we rotate counter clockwise */
> +	__u32 reserved[5];		/* Reserved for future compatibility */
> +};
> +
> +To modify variable information, applications call the FBIOPUT_VSCREENINFO
> +ioctl with a pointer to a fb_var_screeninfo structure. If the call is
> +successful, the driver will update the fixed screen information accordingly.
> +
> +Instead of filling the complete fb_var_screeninfo structure manually,
> +applications should call the FBIOGET_VSCREENINFO ioctl and modify only the
> +fields they care about.
> +
> +
> +4. Format configuration
> +-----------------------
> +
> +Frame buffer devices offer two ways to configure the frame buffer format: the
> +legacy API and the FOURCC-based API.
> +
> +
> +The legacy API has been the only frame buffer format configuration API for a
> +long time and is thus widely used by application. It is the recommended API
> +for applications when using RGB and grayscale formats, as well as legacy
> +non-standard formats.
> +
> +To select a format, applications set the fb_var_screeninfo bits_per_pixel field
> +to the desired frame buffer depth. Values up to 8 will usually map to
> +monochrome, grayscale or pseudocolor visuals, although this is not required.
> +
> +- For grayscale formats, applications set the grayscale field to one. The red,
> +  blue, green and transp fields must be set to 0 by applications and ignored by
> +  drivers. Drivers must fill the red, blue and green offsets to 0 and lengths
> +  to the bits_per_pixel value.
> +
> +- For pseudocolor formats, applications set the grayscale field to zero. The
> +  red, blue, green and transp fields must be set to 0 by applications and
> +  ignored by drivers. Drivers must fill the red, blue and green offsets to 0
> +  and lengths to the bits_per_pixel value.
> +
> +- For truecolor and directcolor formats, applications set the grayscale field
> +  to zero, and the red, blue, green and transp fields to describe the layout of
> +  color components in memory.
> +
> +struct fb_bitfield {
> +	__u32 offset;			/* beginning of bitfield	*/
> +	__u32 length;			/* length of bitfield		*/
> +	__u32 msb_right;		/* != 0 : Most significant bit is */
> +					/* right */
> +};
> +
> +  Pixel values are bits_per_pixel wide and are split in non-overlapping red,
> +  green, blue and alpha (transparency) components. Location and size of each
> +  component in the pixel value are described by the fb_bitfield offset and
> +  length fields. Offset are computed from the right.
> +
> +  Pixels are always stored in an integer number of bytes. If the number of
> +  bits per pixel is not a multiple of 8, pixel values are padded to the next
> +  multiple of 8 bits.
> +
> +Upon successful format configuration, drivers update the fb_fix_screeninfo
> +type, visual and line_length fields depending on the selected format.
> +
> +
> +The FOURCC-based API replaces format descriptions by four character codes
> +(FOURCC). FOURCCs are abstract identifiers that uniquely define a format
> +without explicitly describing it. This is the only API that supports YUV
> +formats. Drivers are also encouraged to implement the FOURCC-based API for RGB
> +and grayscale formats.
> +
> +Drivers that support the FOURCC-based API report this capability by setting
> +the FB_CAP_FOURCC bit in the fb_fix_screeninfo capabilities field.
> +
> +FOURCC definitions are located in the linux/videodev2.h header. However, and
> +despite starting with the V4L2_PIX_FMT_prefix, they are not restricted to V4L2
> +and don't require usage of the V4L2 subsystem. FOURCC documentation is
> +available in Documentation/DocBook/v4l/pixfmt.xml.
> +
> +To select a format, applications set the fourcc.fourcc field to the desired
> +FOURCC. For YUV formats, they should also select the appropriate colorspace by
> +setting the fourcc.colorspace field to one of the colorspaces listed in
> +linux/videodev2.h and documented in Documentation/DocBook/v4l/colorspaces.xml.
> +
> +For forward compatibility reasons applications must zero the fourcc reserved
> +fields by zeroing the whole fourcc structure before filling it. The reserved
> +fields must be ignored by drivers. Values other than 0 may get a meaning in
> +future extensions. Note that the grayscale, red, green, blue and transp field
> +share memory with the fourcc field. Application must thus not touch those
> +fields when using the FOURCC-based API.
> +
> +Upon successful format configuration, drivers update the fb_fix_screeninfo
> +type, visual and line_length fields depending on the selected format. The type
> +and visual fields are set to FB_TYPE_FOURCC and FB_VISUAL_FOURCC respectively.
> diff --git a/include/linux/fb.h b/include/linux/fb.h
> index 1d6836c..98b23e3 100644
> --- a/include/linux/fb.h
> +++ b/include/linux/fb.h
> @@ -45,6 +45,7 @@
>  #define FB_TYPE_INTERLEAVED_PLANES	2	/* Interleaved planes	*/
>  #define FB_TYPE_TEXT			3	/* Text/attributes	*/
>  #define FB_TYPE_VGA_PLANES		4	/* EGA/VGA planes	*/
> +#define FB_TYPE_FOURCC			5	/* Type identified by a V4L2 FOURCC */
>  
>  #define FB_AUX_TEXT_MDA		0	/* Monochrome text */
>  #define FB_AUX_TEXT_CGA		1	/* CGA/EGA/VGA Color text */
> @@ -69,6 +70,7 @@
>  #define FB_VISUAL_PSEUDOCOLOR		3	/* Pseudo color (like atari) */
>  #define FB_VISUAL_DIRECTCOLOR		4	/* Direct color */
>  #define FB_VISUAL_STATIC_PSEUDOCOLOR	5	/* Pseudo color readonly */
> +#define FB_VISUAL_FOURCC		6	/* Visual identified by a V4L2 FOURCC */
>  
>  #define FB_ACCEL_NONE		0	/* no hardware accelerator	*/
>  #define FB_ACCEL_ATARIBLITT	1	/* Atari Blitter		*/
> @@ -154,6 +156,8 @@
>  
>  #define FB_ACCEL_PUV3_UNIGFX	0xa0	/* PKUnity-v3 Unigfx		*/
>  
> +#define FB_CAP_FOURCC		1	/* Device supports FOURCC-based formats */
> +
>  struct fb_fix_screeninfo {
>  	char id[16];			/* identification string eg "TT Builtin" */
>  	unsigned long smem_start;	/* Start of frame buffer mem */
> @@ -171,7 +175,8 @@ struct fb_fix_screeninfo {
>  	__u32 mmio_len;			/* Length of Memory Mapped I/O  */
>  	__u32 accel;			/* Indicate to driver which	*/
>  					/*  specific chip/card we have	*/
> -	__u16 reserved[3];		/* Reserved for future compatibility */
> +	__u16 capabilities;		/* see FB_CAP_*			*/
> +	__u16 reserved[2];		/* Reserved for future compatibility */
>  };
>  
>  /* Interpretation of offset for color fields: All offsets are from the right,
> @@ -246,12 +251,23 @@ struct fb_var_screeninfo {
>  	__u32 yoffset;			/* resolution			*/
>  
>  	__u32 bits_per_pixel;		/* guess what			*/
> -	__u32 grayscale;		/* != 0 Graylevels instead of colors */
>  
> -	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
> -	struct fb_bitfield green;	/* else only length is significant */
> -	struct fb_bitfield blue;
> -	struct fb_bitfield transp;	/* transparency			*/	
> +	union {
> +		struct {		/* Legacy format API		*/
> +			__u32 grayscale; /* 0 = color, 1 = grayscale	*/
> +			/* bitfields in fb mem if true color, else only */
> +			/* length is significant			*/
> +			struct fb_bitfield red;
> +			struct fb_bitfield green;
> +			struct fb_bitfield blue;
> +			struct fb_bitfield transp;	/* transparency	*/
> +		};
> +		struct {		/* FOURCC-based format API	*/
> +			__u32 fourcc;		/* FOURCC format	*/
> +			__u32 colorspace;
> +			__u32 reserved[11];
> +		} fourcc;
> +	};
>  
>  	__u32 nonstd;			/* != 0 Non standard pixel format */
>  


^ permalink raw reply

* Re: Recent viafb changes break OLPC DCON freeze
From: Florian Tobias Schandinat @ 2011-11-20  2:16 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <CAMLZHHQHZL9zZMsQgvXBi6MoG9_TXWqPN5D19sqeKSjsoV3unA@mail.gmail.com>

Hi Daniel,

On 11/18/2011 04:09 PM, Daniel Drake wrote:
> On Thu, Nov 17, 2011 at 8:14 PM, Florian Tobias Schandinat
> <FlorianSchandinat@gmx.de> wrote:
>> As you mentioned it, I had a look at this driver. It looks like viafb does it
>> (polarity) just the other way around than geode. So it might be wort a try to
>> change in
>>
>> drivers/video/via/share.h:
>> /* 1200x900@60 Sync Polarity (DCON) */
>> #define M1200X900_R60_HSP       NEGATIVE
>> #define M1200X900_R60_VSP       NEGATIVE
>>
>> to
>>
>> /* 1200x900@60 Sync Polarity (DCON) */
>> #define M1200X900_R60_HSP       POSITIVE
>> #define M1200X900_R60_VSP       POSITIVE
> 
> That fixes the problem - thanks! Let me know if you'd like me to make
> a patch with that change (I can do so on Monday).

Yes, I'd appreciate it. Then I could queue this patch for 3.2, you might also
consider adding a "Cc: stable@kernel.org" to it so previous releases also get
fixed up.

> It may still be worth you looking at the diagnosis - in particular I
> think I may have found something that may clean up some of the
> uncertainty in commit 32fab7bc

True. Well I already know that it was required for some reason to get the
output, so I merged my branch with the fix before I merged the one with the
problematic patch, to make regression testing easier. So now we know the display
wiring on OLPC better than the driver did some releases ago, though I'd be
happier if I'd find a generic way to figure these display wiring out...


Thanks,

Florian Tobias Schandinat

> 
> Thanks
> Daniel
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" 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

* Re: [PATCH v3 1/3] fbdev: Add FOURCC-based format configuration API
From: Laurent Pinchart @ 2011-11-20 10:55 UTC (permalink / raw)
  To: Florian Tobias Schandinat; +Cc: linux-fbdev, linux-media, magnus.damm
In-Reply-To: <4EC85F41.50100@gmx.de>

Hi Florian,

On Sunday 20 November 2011 03:00:33 Florian Tobias Schandinat wrote:
> Hi Laurent,
> 
> On 08/31/2011 11:18 AM, Laurent Pinchart wrote:
> > This API will be used to support YUV frame buffer formats in a standard
> > way.
> 
> looks like the union is causing problems. With this patch applied I get
> errors like this:
> 
>   CC [M]  drivers/auxdisplay/cfag12864bfb.o
> drivers/auxdisplay/cfag12864bfb.c:57: error: unknown field ‘red’ specified
> in initializer

*ouch*

gcc < 4.6 chokes on anonymous unions initializers :-/

[snip]

> > @@ -246,12 +251,23 @@ struct fb_var_screeninfo {
> > 
> >  	__u32 yoffset;			/* resolution			*/
> >  	
> >  	__u32 bits_per_pixel;		/* guess what			*/
> > 
> > -	__u32 grayscale;		/* != 0 Graylevels instead of colors */
> > 
> > -	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
> > -	struct fb_bitfield green;	/* else only length is significant */
> > -	struct fb_bitfield blue;
> > -	struct fb_bitfield transp;	/* transparency			*/
> > +	union {
> > +		struct {		/* Legacy format API		*/
> > +			__u32 grayscale; /* 0 = color, 1 = grayscale	*/
> > +			/* bitfields in fb mem if true color, else only */
> > +			/* length is significant			*/
> > +			struct fb_bitfield red;
> > +			struct fb_bitfield green;
> > +			struct fb_bitfield blue;
> > +			struct fb_bitfield transp;	/* transparency	*/
> > +		};
> > +		struct {		/* FOURCC-based format API	*/
> > +			__u32 fourcc;		/* FOURCC format	*/
> > +			__u32 colorspace;
> > +			__u32 reserved[11];
> > +		} fourcc;
> > +	};

We can't name the union, otherwise this will change the userspace API.

We could "fix" the problem on the kernel side with

#ifdef __KERNEL__
	} color;
#else
	};
#endif

That's quite hackish though... What's your opinion ?

It would also not handle userspace code that initializes an fb_var_screeninfo 
structure with named initializers, but that shouldn't happen, as application 
should read fb_var_screeninfo , modify it and write it back.

> > 
> >  	__u32 nonstd;			/* != 0 Non standard pixel format */

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* [PATCH] video: Fix return value of fb_notifier_call_chain
From: Joonyoung Shim @ 2011-11-21  6:03 UTC (permalink / raw)
  To: FlorianSchandinat; +Cc: linux-fbdev, linux-kernel

The return value of blocking_notifier_call_chain isn't errno value, it
is just notify return value. The ret of fb_notifier_call_chain should is
restored to error value from notify return value using
notifier_to_errno().

Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
---
 drivers/video/fb_notify.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/video/fb_notify.c b/drivers/video/fb_notify.c
index 74c2da5..49a64a3 100644
--- a/drivers/video/fb_notify.c
+++ b/drivers/video/fb_notify.c
@@ -42,6 +42,8 @@ EXPORT_SYMBOL(fb_unregister_client);
  */
 int fb_notifier_call_chain(unsigned long val, void *v)
 {
-	return blocking_notifier_call_chain(&fb_notifier_list, val, v);
+	int ret = blocking_notifier_call_chain(&fb_notifier_list, val, v);
+
+	return notifier_to_errno(ret);
 }
 EXPORT_SYMBOL_GPL(fb_notifier_call_chain);
-- 
1.7.5.4


^ permalink raw reply related

* [PATCH] video: Fix return value of fb_notifier_call_chain
From: Joonyoung Shim @ 2011-11-21  6:55 UTC (permalink / raw)
  To: FlorianSchandinat; +Cc: linux-fbdev, linux-kernel
In-Reply-To: <1321855411-13730-1-git-send-email-jy0922.shim@samsung.com>

The return value of blocking_notifier_call_chain isn't errno value, it
is just notify return value. The ret of fb_notifier_call_chain should is
restored to error value from notify return value using
notifier_to_errno().

Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
---
 drivers/video/fb_notify.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/video/fb_notify.c b/drivers/video/fb_notify.c
index 74c2da5..49a64a3 100644
--- a/drivers/video/fb_notify.c
+++ b/drivers/video/fb_notify.c
@@ -42,6 +42,8 @@ EXPORT_SYMBOL(fb_unregister_client);
  */
 int fb_notifier_call_chain(unsigned long val, void *v)
 {
-	return blocking_notifier_call_chain(&fb_notifier_list, val, v);
+	int ret = blocking_notifier_call_chain(&fb_notifier_list, val, v);
+
+	return notifier_to_errno(ret);
 }
 EXPORT_SYMBOL_GPL(fb_notifier_call_chain);
-- 
1.7.5.4


^ permalink raw reply related

* Re: [PATCH 0/15] fbdev: sh_mipi_dsi: care un-explained register settings
From: Magnus Damm @ 2011-11-21 10:34 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <874nydc3vz.wl%kuninori.morimoto.gx@renesas.com>

Hi Florian,

On Sat, Nov 12, 2011 at 12:37 AM, Florian Tobias Schandinat
<FlorianSchandinat@gmx.de> wrote:
> Hi Guennadi, Magnus,
>
> On 11/09/2011 04:32 AM, kuninori.morimoto.gx@renesas.com wrote:
>> Dear Florian, Paul
>>
>> These are sh_mipi_dsi update patches.
>>
>> Kuninori Morimoto (15):
>>       fbdev: sh_mobile_lcdcfb: fixup LDHAJR :: HSYNPAJ needs mask
>>       fbdev: sh_mipi_dsi: tidyup dsip_clk
>>       fbdev: sh_mipi_dsi: typo fix of SH_MIPI_DSI_HBPBM
>>       fbdev: sh_mipi_dsi: tidyup VMCTR2 parameter expression
>>       fbdev: sh_mipi_dsi: add SH_MIPI_DSI_HFPBM flag
>>       fbdev: sh_mipi_dsi: add SH_MIPI_DSI_BL2E flag
>>       fbdev: sh_mipi_dsi: add lane control support
>>       fbdev: sh_mipi_dsi: add sync_pulses/sync_events/burst mode
>>       fbdev: sh_mipi_dsi: add VMLEN1/VMLEN2 calculation
>>       fbdev: sh_mipi_dsi: add set_dot_clock() for each platform
>>       fbdev: sh_mipi_dsi: add HSxxCLK support
>>       fbdev: sh_mipi_dsi: sh_mipi has pdata instead of dev
>>       fbdev: sh_mipi_dsi: fixup setup timing of sh_mipi_setup()
>>       fbdev: sh_mipi_dsi: fixup setup timing of SYSCONF
>>       fbdev: sh_mipi_dsi: fixup setup timing DSICTRL
>
> can you have a look at these patches?
> After a quick glance they look okay to me, but as this is all about hardware
> (which I don't know) I'd be happier if someone more qualified could have a look
> at it.

They all look fine to me. Please add:

Acked-by: Magnus Damm <damm@opensource.se>

Thanks for your help,

/ magnus

^ permalink raw reply

* [PATCH] viafb: correct sync polarity for OLPC DCON
From: Daniel Drake @ 2011-11-21 15:05 UTC (permalink / raw)
  To: linux-fbdev

While the OLPC display appears to be able to handle either positive
or negative sync, the Display Controller only recognises positive sync.

This brings viafb (for XO-1.5) in line with lxfb (for XO-1) and
fixes a recent regression where the XO-1.5 DCON could no longer be
frozen. Thanks to Florian Tobias Schandinat for helping identify
the fix.

Test case: from a vt,
	echo 1 > /sys/devices/platform/dcon/freeze
should cause the current screen contents to freeze, rather than garbage being
displayed.

Signed-off-by: Daniel Drake <dsd@laptop.org>
---
 drivers/video/via/share.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
index 69d882c..c01c1c1 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/via/share.h
@@ -559,8 +559,8 @@
 #define M1200X720_R60_VSP       POSITIVE
 
 /* 1200x900@60 Sync Polarity (DCON) */
-#define M1200X900_R60_HSP       NEGATIVE
-#define M1200X900_R60_VSP       NEGATIVE
+#define M1200X900_R60_HSP       POSITIVE
+#define M1200X900_R60_VSP       POSITIVE
 
 /* 1280x600@60 Sync Polarity (GTF Mode) */
 #define M1280x600_R60_HSP       NEGATIVE
-- 
1.7.7.3


^ permalink raw reply related

* Re: [PATCH] fb: split out framebuffer initialization from allocation
From: Timur Tabi @ 2011-11-21 16:22 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1321308088-6327-1-git-send-email-timur@freescale.com>

Florian Tobias Schandinat wrote:

>> Any comments on this patch?  If you're okay with the change, I want to take
>> advantage of it in my framebuffer driver.
> 
> Of course you want, otherwise I'd be wondering why you are sending this patch
> at all.

I frequently have to ping maintainers on patches that I've posted.  I've lost count how many times I've been told, "Oh sorry, I forgot all about your patch".

> But I don't see any advantages of your approach. Instead of pointers to fb_info
> with this patch you could embed fb_info directly in your data structure but that
> is barely a difference for a programmer I'd think. You'd still have to call your
> new functions on init/exit so the amount of function calls needed is the same
> with or without the patch (I could see an advantage if alloc and release were
> pure memory allocations). Or is this all about handling the case when fb_alloc
> fails?

It's all about reducing the number of kmalloc calls.  Here's an example of what my per-device data structure looks like:

struct fsl_diu_data {
	dma_addr_t phys;
	struct fb_info fsl_diu_info[NUM_AOIS];	<-----
	struct mfb_info mfb[NUM_AOIS];
	struct device_attribute dev_attr;
	unsigned int irq;
	int fb_enabled;
	enum fsl_diu_monitor_port monitor_port;
	struct diu __iomem *diu_reg;
	spinlock_t reg_lock;
	u8 dummy_aoi[4 * 4 * 4];
	struct diu_ad dummy_ad __aligned(8);
	struct diu_ad ad[NUM_AOIS] __aligned(8);
	u8 gamma[256 * 3] __aligned(32);
	u8 cursor[MAX_CURS * MAX_CURS * 2] __aligned(32);
} __aligned(32);

So this way, I have all of the memory I need allocated in one spot.  I know need to allocate one block of memory.

> Historically some drivers don't even call alloc but have their own fb_info and
> call only register.

That's exactly the same thing I want to do.  Do these drivers also initialize info->device and info->bl_curve_mutex by themselves?  How would they know if the fb_info structure got new members that also need to be initialized?

Perhaps we need to move the fb_info initialization code from framebuffer_alloc() into register_framebuffer()?  

> I do not want to add yet another way of doing framebuffer
> initialization unless you can clearly show its benefits.

I think the problem is that we already have two ways that framebuffers are initialized.

What do you think about this:


diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 67afa9c..ba47a38 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -57,12 +57,6 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
 	if (size)
 		info->par = p + fb_info_size;
 
-	info->device = dev;
-
-#ifdef CONFIG_FB_BACKLIGHT
-	mutex_init(&info->bl_curve_mutex);
-#endif
-
 	return info;
 #undef PADDING
 #undef BYTES_PER_LONG


diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index ad93629..ea35bf8 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1591,6 +1591,12 @@ static int do_register_framebuffer(struct fb_info *fb_info)
 	mutex_init(&fb_info->lock);
 	mutex_init(&fb_info->mm_lock);
 
+	fb_info->device = dev;
+
+#ifdef CONFIG_FB_BACKLIGHT
+	mutex_init(&fb_info->bl_curve_mutex);
+#endif
+
 	fb_info->dev = device_create(fb_class, fb_info->device,
 				     MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
 	if (IS_ERR(fb_info->dev)) {


There are a few instances where drivers use info->device after calling framebuffer_alloc() but before calling register_framebuffer().  These drivers will need to be fixed.  But otherwise, I think this is a good idea.

-- 
Timur Tabi
Linux kernel developer at Freescale


^ permalink raw reply related

* Re: [PATCH] fb: split out framebuffer initialization from allocation
From: Timur Tabi @ 2011-11-21 16:28 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1321308088-6327-1-git-send-email-timur@freescale.com>

Bruno Prémont wrote:

> Wouldn't it even make sense to move some more of the initialization of fb_info
> out of fb registration into this new init funtion? (I'm thinking about initializing
> mutexes and the like)

I was thinking the opposite.  See my reply to Florian's message.

> This way fb_info could be used before being registered. Registration would then
> be reduced to makeing the framebuffer visible to userspace and listed in
> registered_fb[].
> 
> This way framebuffer_alloc() would be no more that kzalloc(), framebuffer_init()
> would setup all "non-zero" fields of fb_info (including setup of all mutexes, one
> of which is currently being done by framebuffer_alloc() and the rest by
> do_register_framebuffer()!).

I think the problem is that it's unclear what the difference is between framebuffer_alloc() and register_framebuffer().  The problem is that register_framebuffer() also initializes the fb_info structure.  So some initialization is done in framebuffer_alloc(), some is done in register_framebuffer(), and some is done by the driver.  Not only that, but drivers that don't call framebuffer_alloc() can't really know what needs to be initialized before calling register_framebuffer().

Why is fb_info->lock initialized in register_framebuffer(), but fb_info->bl_curve_mutex is initialized in framebuffer_alloc()?  They're both mutexes.

-- 
Timur Tabi
Linux kernel developer at Freescale


^ permalink raw reply

* Re: [PATCH] fb: split out framebuffer initialization from
From: Bruno Prémont @ 2011-11-21 17:43 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1321308088-6327-1-git-send-email-timur@freescale.com>

On Mon, 21 November 2011 Timur Tabi wrote:
> Bruno Prémont wrote:
> 
> > Wouldn't it even make sense to move some more of the initialization of fb_info
> > out of fb registration into this new init funtion? (I'm thinking about initializing
> > mutexes and the like)
> 
> I was thinking the opposite.  See my reply to Florian's message.

Well, in there you don't mention a reason to put it in
register_framebuffer() rather than collect initialization into
a new function for exactly that task.

> > This way fb_info could be used before being registered. Registration would then
> > be reduced to makeing the framebuffer visible to userspace and listed in
> > registered_fb[].
> > 
> > This way framebuffer_alloc() would be no more that kzalloc(), framebuffer_init()
> > would setup all "non-zero" fields of fb_info (including setup of all mutexes, one
> > of which is currently being done by framebuffer_alloc() and the rest by
> > do_register_framebuffer()!).
> 
> I think the problem is that it's unclear what the difference is between
> framebuffer_alloc() and register_framebuffer().  The problem is that
> register_framebuffer() also initializes the fb_info structure.  So some
> initialization is done in framebuffer_alloc(), some is done in register_framebuffer(),
> and some is done by the driver.  Not only that, but drivers that don't call
> framebuffer_alloc() can't really know what needs to be initialized before
> calling register_framebuffer().
> 
> Why is fb_info->lock initialized in register_framebuffer(), but
> fb_info->bl_curve_mutex is initialized in framebuffer_alloc()?
>  They're both mutexes.

Exactly, thats why I would prefer to see all that initialization moved
out of registrer_framebuffer() into a init_framebuffer().

For simplicity any driver that uses framebuffer_alloc() should not need
to additionally call init_framebuffer() - framebuffer_alloc() should
call it just before returning.
All those drivers that don't call framebuffer_alloc() would then have to
call init_framebuffer().

I think register_framebuffer() is a bit too late to do the initialisation
of mutexes and other class state because driver cannot use the same code
for HW setup before registration and after registration as at least the lock
is in undefined state.


In pseudo-code my though would be:


// driver using their own memory allocation

struct driver_data {
   ...
   struct fb_info fb;
   ...
}

int driver_init() {
   struct driver_data *data;
   ...
   memset(&data->fb, 0, sizeof(data->fb));
   init_framebuffer(&data->fb);
   // fill in driver's settings for fb
   ...
   register_framebuffer(&data->fb);
   ...
}

// driver using alloc_framebuffer()

struct driver_data {
   ...
   struct fb_info *fb;
   ...
}

int driver_init() {
   struct driver_data *data;
   ...
   data->fb = alloc_framebuffer(0); // this implicitly calls init_framebuffer();
   // fill in driver's settings for fb
   ...
   register_framebuffer(&data->fb);
   ...
}




Bruno

^ permalink raw reply


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