Re: [PATCH 09/11] viafb: Do not probe for LVDS/TMDS on OLPC XO-1.5

Previous thread: none

Next thread: none
From: Jonathan Corbet
Date: Sunday, April 18, 2010 - 11:21 am

The following patches are the beginning of an effort to move work done for
the OLPC XO 1.5 machine into the mainline.  What's here is basic support
for the VX855 chipset, I2C, and the OLPC panel display.  What's coming in
the future is a reworking of the viafb driver into something resembling a
proper multifunction device, GPIO support, and camera support.  But I'd
like to start here.

CHANGES FROM THE FIRST POSTING include fixes in response to a number of
Florian's comments and the removal of the suspend/resume patches.  The
patch series is also now based on 2.6.34-rc3.

If there's no objections, I'll start a tree and get it into linux-next in
the near future, with an eye toward a 2.6.35 merge.

Thanks,

jon

Chris Ball (2):
      viafb: Add 1200x900 DCON/LCD panel modes for OLPC XO-1.5
      viafb: Do not probe for LVDS/TMDS on OLPC XO-1.5

Harald Welte (4):
      [FB] viafb: Fix various resource leaks during module_init()
      viafb: use proper pci config API
      viafb: Determine type of 2D engine and store it in chip_info
      viafb: rework the I2C support in the VIA framebuffer driver

Jonathan Corbet (4):
      viafb: Unmap the frame buffer on initialization error
      viafb: Retain GEMODE reserved bits
      viafb: Unify duplicated set_bpp() code
      viafb: complete support for VX800/VX855 accelerated framebuffer

Paul Fox (1):
      suppress verbose debug messages:  change printk() to DEBUG_MSG()

 drivers/video/via/accel.c    |  111 +++++++++++++++++----------
 drivers/video/via/accel.h    |   40 ++++++++++
 drivers/video/via/chip.h     |    8 ++
 drivers/video/via/dvi.c      |   35 +++-----
 drivers/video/via/hw.c       |   85 +++++++++++++++------
 drivers/video/via/hw.h       |    4 -
 drivers/video/via/ioctl.h    |    2 
 drivers/video/via/lcd.c      |   35 ++++++--
 drivers/video/via/lcd.h      |    2 
 drivers/video/via/share.h    |    7 +
 drivers/video/via/via_i2c.c  |  171 ++++++++++++++++++++++++++-----------------
 ...
From: Jonathan Corbet
Date: Sunday, April 18, 2010 - 11:21 am

From: Harald Welte <laforge@gnumonks.org>

The current code executed from module_init() in viafb does not have
proper error checking and [partial] resoure release paths in case
an error happens half way through driver initialization.

This patch adresses the most obvious of those issues, such as a
leftover i2c bus if module_init (and thus module load) fails.

[jc: fixed merge conflicts]
[jc: also restored -ENOMEM return on ioremap() fail]

Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: ScottFang@viatech.com.cn
Cc: JosephChan@via.com.tw
Signed-off-by: Harald Welte <HaraldWelte@viatech.com>
---
 drivers/video/via/viafbdev.c |   52 +++++++++++++++++++++++++++++++----------
 1 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index ce7783b..b7018ef 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved.
  * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
 
  * This program is free software; you can redistribute it and/or
@@ -1737,6 +1737,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
 	u32 default_xres, default_yres;
 	struct VideoModeTable *vmode_entry;
 	struct fb_var_screeninfo default_var;
+	int rc;
 	u32 viafb_par_length;
 
 	DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n");
@@ -1751,7 +1752,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
 		&pdev->dev);
 	if (!viafbinfo) {
 		printk(KERN_ERR"Could not allocate memory for viafb_info.\n");
-		return -ENODEV;
+		return -ENOMEM;
 	}
 
 	viaparinfo = (struct viafb_par *)viafbinfo->par;
@@ -1774,7 +1775,9 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
 		viafb_dual_fb = 0;
 
 	/* Set up I2C bus stuff */
-	viafb_create_i2c_bus(viaparinfo);
+	rc = viafb_create_i2c_bus(viaparinfo);
+	if (rc)
+		goto ...
From: Jonathan Corbet
Date: Sunday, April 18, 2010 - 11:21 am

As suggested by Florian: make both mode-setting paths use the same code.

Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: ScottFang@viatech.com.cn
Cc: JosephChan@via.com.tw
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
---
 drivers/video/via/accel.c |   78 +++++++++++++++++++--------------------------
 1 files changed, 33 insertions(+), 45 deletions(-)

diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
index a52147c..7c1d9c4 100644
--- a/drivers/video/via/accel.c
+++ b/drivers/video/via/accel.c
@@ -20,12 +20,42 @@
  */
 #include "global.h"
 
+/*
+ * Figure out an appropriate bytes-per-pixel setting.
+ */
+static int viafb_set_bpp(void __iomem *engine, u8 bpp)
+{
+	u32 gemode;
+
+	/* Preserve the reserved bits */
+	/* Lowest 2 bits to zero gives us no rotation */
+	gemode = readl(engine + VIA_REG_GEMODE) & 0xfffffcfc;
+	switch (bpp) {
+	case 8:
+		gemode |= VIA_GEM_8bpp;
+		break;
+	case 16:
+		gemode |= VIA_GEM_16bpp;
+		break;
+	case 32:
+		gemode |= VIA_GEM_32bpp;
+		break;
+	default:
+		printk(KERN_WARNING "viafb_set_bpp: Unsupported bpp %d\n", bpp);
+		return -EINVAL;
+	}
+	writel(gemode, engine + VIA_REG_GEMODE);
+	return 0;
+}
+
+
 static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height,
 	u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
 	u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
 	u32 fg_color, u32 bg_color, u8 fill_rop)
 {
 	u32 ge_cmd = 0, tmp, i;
+	int ret;
 
 	if (!op || op > 3) {
 		printk(KERN_WARNING "hw_bitblt_1: Invalid operation: %d\n", op);
@@ -59,22 +89,9 @@ static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height,
 		}
 	}
 
-	switch (dst_bpp) {
-	case 8:
-		tmp = 0x00000000;
-		break;
-	case 16:
-		tmp = 0x00000100;
-		break;
-	case 32:
-		tmp = 0x00000300;
-		break;
-	default:
-		printk(KERN_WARNING "hw_bitblt_1: Unsupported bpp %d\n",
-			dst_bpp);
-		return -EINVAL;
-	}
-	writel(tmp, engine + 0x04);
+	ret = ...
From: Jonathan Corbet
Date: Sunday, April 18, 2010 - 11:21 am

From: Harald Welte <laforge@gnumonks.org>

This will help us for the upcoming support for 2D acceleration using
the M1 engine.

[jc: fixed merge conflicts]
Signed-off-by: Harald Welte <HaraldWelte@viatech.com>
---
 drivers/video/via/chip.h |    8 ++++++++
 drivers/video/via/hw.c   |   15 +++++++++++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h
index 8c06bd3..d9b6e06 100644
--- a/drivers/video/via/chip.h
+++ b/drivers/video/via/chip.h
@@ -121,9 +121,17 @@ struct lvds_chip_information {
 	int i2c_port;
 };
 
+/* The type of 2D engine */
+enum via_2d_engine {
+	VIA_2D_ENG_H2,
+	VIA_2D_ENG_H5,
+	VIA_2D_ENG_M1,
+};
+
 struct chip_information {
 	int gfx_chip_name;
 	int gfx_chip_revision;
+	enum via_2d_engine twod_engine;
 	struct tmds_chip_information tmds_chip_info;
 	struct lvds_chip_information lvds_chip_info;
 	struct lvds_chip_information lvds_chip_info2;
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 69acae1..d893695 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -2017,6 +2017,21 @@ static void init_gfx_chip_info(struct pci_dev *pdev,
 				CX700_REVISION_700;
 		}
 	}
+
+	/* Determine which 2D engine we have */
+	switch (viaparinfo->chip_info->gfx_chip_name) {
+	case UNICHROME_VX800:
+	case UNICHROME_VX855:
+		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1;
+		break;
+	case UNICHROME_K8M890:
+	case UNICHROME_P4M900:
+		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H5;
+		break;
+	default:
+		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H2;
+		break;
+	}
 }
 
 static void init_tmds_chip_info(void)
-- 
1.7.0.1

--

From: Jonathan Corbet
Date: Sunday, April 18, 2010 - 11:21 am

From: Paul Fox <pgf@laptop.org>

[jc: no signoff, added my own]
Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: ScottFang@viatech.com.cn
Cc: JosephChan@via.com.tw
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
---
 drivers/video/via/via_i2c.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
index 8f8e0bf..fe5535c 100644
--- a/drivers/video/via/via_i2c.c
+++ b/drivers/video/via/via_i2c.c
@@ -26,7 +26,7 @@ static void via_i2c_setscl(void *data, int state)
 	u8 val;
 	struct via_i2c_adap_cfg *adap_data = data;
 
-	printk(KERN_DEBUG "reading index 0x%02x from IO 0x%x\n",
+	DEBUG_MSG(KERN_DEBUG "reading index 0x%02x from IO 0x%x\n",
 		adap_data->ioport_index, adap_data->io_port);
 	val = viafb_read_reg(adap_data->io_port,
 			     adap_data->ioport_index) & 0xF0;
@@ -140,7 +140,7 @@ static int create_i2c_bus(struct i2c_adapter *adapter,
 			  struct via_i2c_adap_cfg *adap_cfg,
 			  struct pci_dev *pdev)
 {
-	printk(KERN_DEBUG "viafb: creating bus adap=0x%p, algo_bit_data=0x%p, adap_cfg=0x%p\n", adapter, algo, adap_cfg);
+	DEBUG_MSG(KERN_DEBUG "viafb: creating bus adap=0x%p, algo_bit_data=0x%p, adap_cfg=0x%p\n", adapter, algo, adap_cfg);
 
 	algo->setsda = via_i2c_setsda;
 	algo->setscl = via_i2c_setscl;
-- 
1.7.0.1

--

From: Jonathan Corbet
Date: Sunday, April 18, 2010 - 11:21 am

From: Harald Welte <laforge@gnumonks.org>

This patch changes the way how the various I2C busses are used internally
inside the viafb driver:  Previosuly, only a single i2c_adapter was created,
even though two different hardware I2C busses are accessed: A structure member
in a global variable was modified to indicate the bus to be used.

Now, all existing hardware busses are registered with the i2c core, and the
viafb_i2c_{read,write}byte[s]() function take the adapter number as function
call parameter, rather than referring to the global structure member.

[jc: even more painful merge with mainline changes ->2.6.34]
[jc: painful merge with OLPC changes]

Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: ScottFang@viatech.com.cn
Cc: JosephChan@via.com.tw
Signed-off-by: Harald Welte <HaraldWelte@viatech.com>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
---
 drivers/video/via/dvi.c      |   35 ++++-----
 drivers/video/via/lcd.c      |   19 ++---
 drivers/video/via/via_i2c.c  |  171 ++++++++++++++++++++++++++----------------
 drivers/video/via/via_i2c.h  |   43 +++++++----
 drivers/video/via/viafbdev.c |    6 +-
 drivers/video/via/viafbdev.h |    4 +-
 drivers/video/via/vt1636.c   |   36 ++++-----
 drivers/video/via/vt1636.h   |    2 +-
 8 files changed, 182 insertions(+), 134 deletions(-)

diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index abe59b8..be51370 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -96,7 +96,7 @@ int viafb_tmds_trasmitter_identify(void)
 	viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
 	viaparinfo->chip_info->
 		tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
-	viaparinfo->chip_info->tmds_chip_info.i2c_port = I2CPORTINDEX;
+	viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_I2C_ADAP_31;
 	if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) {
 		/*
 		 * Currently only support 12bits,dual edge,add 24bits mode later
@@ -110,7 +110,7 @@ int ...
From: Florian Tobias Schandinat
Date: Friday, April 23, 2010 - 2:12 pm

Hi,


as I did some runtime testing (VX800 only yet) I ran in 2 issues:

1. while the module loads the screen shows some strange colours. The 
colours itself do not worry me but it probably at least means that the 
module load time was increased significantly (2-3 seconds, I guess)

2. most annoyingly after this patch I can no longer get a working VGA 
console after unbinding the module. Normally I just do:

vbetool post
vbetool vbemode set 3
echo 0 >/sys/class/vtconsole/vtcon1/bind
clear
rmmod viafb

and have a working VGA console and can use another viafb. However after 
the patch I just get white out and strange colours. Reordering the 
commands does not help.

As the last one is especially annoying as it basically forces me to 
reboot for every viafb test and therefore makes development hell I tend 
to reject this patch, sorry. (and I don't have any idea what the cause 
is as I do not know I2C very well)


Thanks,


--

From: Jonathan Corbet
Date: Friday, April 23, 2010 - 2:57 pm

On Fri, 23 Apr 2010 23:12:54 +0200

Hmm...compiling the driver as a module is not really something that
makes sense on the OLPC platform, so I've never done it.

#1 is weird, there should be nothing there that slows initialization
down.  Putting in some prints and looking at the timing would be most
helpful here.

As for #2, I can certainly say that I've never unloaded this code, so
that's an untested path.  I'll have a look and see if I can see
anything obvious.

jon
--

From: Florian Tobias Schandinat
Date: Friday, April 23, 2010 - 3:40 pm

Actually that is probably a mistake on my side. I had the impression 
that it was much longer but didn't take into account that the old 
behaviour allowed the VGA console to work until viafb was completly 
loaded and fbcon took over while the new one immediately destroys the 
screen and shows random things until it is completely loaded. However 
the time between hitting enter for the module load command and getting a 

Well as for the behaviour change described above I think the problem 
might be in the load path. At least when I faked an exit as when memory 
size detection or ioremapping fails (which is a very common issue that 
really needs a workaround) I get the same unusable VGA console. This 
needs to be fixed.
This whole I2C stuff seems incredibly unstable I even have indicators 
that the current code might be to blame for freezing the machine on some 
configurations with P4M900 IGP. I just try to prevent it to get even 
worse...


Thanks,

Florian Tobias Schandinat
--

From: Jonathan Corbet
Date: Friday, April 23, 2010 - 3:52 pm

On Sat, 24 Apr 2010 00:40:39 +0200

"New one" being new relative to what?  Is that change the result of the

Interesting.  In the environment I've been working in the whole box is
a brick if the framebuffer doesn't come up right.  But things are

I have to say that i2c has often been the bane of my existence.  It
seems like something that just barely works most of the time.

That said, it's been a long time since I've seen any trouble I could
blame on i2c in the viafb driver.  It's *really* hard to imagine how
it could free machines.  Unless, maybe, you're hitting some sort of
race condition in all of those indexed I/O port operations.  But that
looks like something which would be hard to do on most machines that
would have these chipsets in them.

The second series adds some locking around i2c port operations, but has
not yet pushed that locking into the framebuffer side of the driver;
that would be a good thing to do.

Meanwhile, I'm a little unsure now...is there an action item for me
with regard to the i2c code?  I've been staring at it since your last
note, but I couldn't find any obvious problems.  I do have to say that
Harald's rework is far cleaner than what came before...

Thanks,

jon
--

From: Florian Tobias Schandinat
Date: Friday, April 23, 2010 - 4:21 pm

Relative to the patch we are talking about. With patches 01-09 applied 
it just works fine as it always did (no screen "destruction" on load, a 
working VGA console if unloaded as described earlier). With additionally 

Well the ioremapping fails when huge amount of video memory is available 
(128 MB and up) if no extra space is allocated the "vmalloc=" kernel 
option. To not require it we (a) should only remap the needed memory or 
(b) reduce the memory to be remapped until we succeed (or hit a too low 

I don't know but a freeze reported due to viafb with viafb itself 
exiting due to ioremap failure can't have so much causes. Either we do 
something terribly wrong on the error out side (this might be possible 
regarding the current condition of error handling) or in the I2C setup 
which is done prior to remapping. The full story can be read on

Well the main question is probably:
How does it change the behaviour towards the hardware?
I tend to think that OLPC might not be the only ones who did something 
weird with it....and we already know that we shouldn't trust the 
documentation too much.


Thanks,

Florian Tobias Schandinat
--

From: Florian Tobias Schandinat
Date: Saturday, April 24, 2010 - 3:47 am

I was able to narrow this issue down to the fourth bus. So with
if (i == 4)
	continue;
in the bus creation loop I'm able to get a working framebuffer which 
does not have the issues mentioned. Any ideas what should be done now?


Thanks,

Florian Tobias Schandinat

--

From: Jonathan Corbet
Date: Saturday, April 24, 2010 - 6:33 am

On Sat, 24 Apr 2010 12:47:34 +0200

That is useful information indeed, thanks.

This patch creates an i2c bus on every port which could conceivably
have one.  That's rather different from the original code, which
created a single bus (in the kernel) then swapped it between ports 31
and 2c in weird ways.  In particular, it takes over ports which,
conceivably, somebody else could be using for GPIO.  So, perhaps, there
is some contention going on there.

If my hypothesis is correct, this problem will go away with the
application of the second series, which doesn't create i2c buses on
ports used for GPIO.  But the problem should be fixed here so we don't
have things broken in the middle.

Harald, does this reasoning make sense to you?  If so, what I should do
is bring forward just enough of the via-core code to be able to
configure which ports actually get i2c buses created on them.  Easily
done.

Thanks,

jon
--

From: Harald Welte
Date: Saturday, April 24, 2010 - 6:53 am

Hi Jon,


It makes a lot of sense.  When I added all possible I2C busses, this was merely
the result of "let's try to make sure every possible configuration is
supported" rather than some kind of neccessity.

Simply converting the original two busses to the new code is definitely
the way to go.  Maybe we'll keep the code for the other two around, but
somehow keep them inactive and don't advertise them unless somebody explicitly
does so?

-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)
--

From: Jonathan Corbet
Date: Sunday, April 25, 2010 - 7:38 am

On Sat, 24 Apr 2010 15:53:16 +0200

OK, my proposal would be to add the following patch into the early part
of the series; that will help to avoid the creation of confusion in the
middle until the full i2c/gpio configuration code is in.

Look good?

Thanks,

jon

viafb: Only establish i2c busses on ports that always had them

...otherwise it seems we run into conflicts with shadowy other users which
don't expect to see i2c taking control of ports it never used to do
anything with.

Reported-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
---
 drivers/video/via/via_i2c.c |   19 +++++++++++++------
 drivers/video/via/via_i2c.h |    1 +
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
index fe5535c..b5253e3 100644
--- a/drivers/video/via/via_i2c.c
+++ b/drivers/video/via/via_i2c.c
@@ -170,13 +170,18 @@ static int create_i2c_bus(struct i2c_adapter *adapter,
 	return i2c_bit_add_bus(adapter);
 }
 
+/*
+ * By default, we only activate busses on ports 2c and 31 to avoid
+ * conflicts with other possible users; that default can be changed
+ * below.
+ */
 static struct via_i2c_adap_cfg adap_configs[] = {
-	[VIA_I2C_ADAP_26]	= { VIA_I2C_I2C,  VIASR, 0x26 },
-	[VIA_I2C_ADAP_31]	= { VIA_I2C_I2C,  VIASR, 0x31 },
-	[VIA_I2C_ADAP_25]	= { VIA_I2C_GPIO, VIASR, 0x25 },
-	[VIA_I2C_ADAP_2C]	= { VIA_I2C_GPIO, VIASR, 0x2c },
-	[VIA_I2C_ADAP_3D]	= { VIA_I2C_GPIO, VIASR, 0x3d },
-	{ 0, 0, 0 }
+	[VIA_I2C_ADAP_26]	= { VIA_I2C_I2C,  VIASR, 0x26, 0 },
+	[VIA_I2C_ADAP_31]	= { VIA_I2C_I2C,  VIASR, 0x31, 1 },
+	[VIA_I2C_ADAP_25]	= { VIA_I2C_GPIO, VIASR, 0x25, 0 },
+	[VIA_I2C_ADAP_2C]	= { VIA_I2C_GPIO, VIASR, 0x2c, 1 },
+	[VIA_I2C_ADAP_3D]	= { VIA_I2C_GPIO, VIASR, 0x3d, 0 },
+	{ 0, 0, 0, 0 }
 };
 
 int viafb_create_i2c_busses(struct viafb_par *viapar)
@@ -189,6 +194,8 @@ int viafb_create_i2c_busses(struct viafb_par *viapar)
 
 		if (adap_cfg->type == 0)
 ...
From: Florian Tobias Schandinat
Date: Sunday, April 25, 2010 - 8:56 am

Hi Jon,


Yes, it does. But it highlighted a bug in the original patch:

BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<c11df2db>] i2c_transfer+0x19/0xb0
*pdpt = 000000000af77001 *pde = 0000000000000000
Oops: 0000 [#1] PREEMPT
last sysfs file: /sys/devices/virtual/vtconsole/vtcon1/bind
Modules linked in: viafb(+) fbcon font bitblit softcursor fb 
i2c_algo_bit cfbcopyarea cfbimgblt cfbfillrect snd_hda_codec_realtek 
snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_timer mmc_block 
rtl8187 snd eeprom_93cx6 soundcore via_sdmmc snd_page_alloc i2c_viapro 
ehci_hcd uhci_hcd mmc_core video output [last unloaded: viafb]

Pid: 3561, comm: insmod Tainted: G        W  2.6.34-rc5 #1 IL1/
EIP: 0060:[<c11df2db>] EFLAGS: 00010296 CPU: 0
EIP is at i2c_transfer+0x19/0xb0
EAX: 00000000 EBX: ffffffa1 ECX: 00000002 EDX: c74f2d68
ESI: db034294 EDI: c74f2d96 EBP: c74f2d60 ESP: c74f2d48
  DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
Process insmod (pid: 3561, ti=c74f2000 task=db022000 task.ti=c74f2000)
Stack:
  00000002 c74f2d68 c74f2d97 c74f2d96 c74f2d97 c74f2d96 c74f2d88 dc7308f0
<0> 00000040 c74f0001 c74f2d83 00010040 c74f0001 c74f2d96 00000001 00000000
<0> c74f2da4 dc733a7f c74f2d96 00002db0 dc738a28 db0349a8 c74f2e84 c74f2db0
Call Trace:
  [<dc7308f0>] ? viafb_i2c_readbyte+0x60/0x68 [viafb]
  [<dc733a7f>] ? viafb_lvds_identify_vt1636+0x38/0xbc [viafb]
  [<dc732a7f>] ? viafb_lvds_trasmitter_identify+0x2c/0x10d [viafb]
  [<dc7304cc>] ? viafb_init_chip_info+0x15b/0x23f [viafb]
  [<dc7340c3>] ? via_pci_probe+0x155/0x81c [viafb]
  [<c111f1c0>] ? idr_get_empty_slot+0x152/0x226
  [<c112e1ee>] ? pci_match_device+0xbf/0xca
  [<c112e09c>] ? local_pci_probe+0xe/0x10
  [<c112e71a>] ? pci_device_probe+0x43/0x66
  [<c1186374>] ? driver_probe_device+0x78/0x103
  [<c1186442>] ? __driver_attach+0x43/0x5f
  [<c1185d79>] ? bus_for_each_dev+0x3d/0x67
  [<c118624e>] ? driver_attach+0x14/0x16
  [<c11863ff>] ? __driver_attach+0x0/0x5f
  [<c11857f3>] ? bus_add_driver+0xa2/0x1d4
  ...
From: Jonathan Corbet
Date: Monday, April 26, 2010 - 12:40 pm

On Sun, 25 Apr 2010 17:56:09 +0200

Two bugs, actually...I wouldn't expect things to work with the wrong
port, but neither should it crash.  The crash is fixed in the second
series (where I added checks to ensure that the adapter was active) so
I'll probably leave it as-is in between.  The port number needs to be
fixed, though, thanks for catching that.

jon
--

From: Jonathan Corbet
Date: Sunday, April 18, 2010 - 11:21 am

From: Chris Ball <cjb@laptop.org>

The i2c transactions involved in detecting LVDS (9 seconds) and TMDS
(16 seconds) add an extra 25 seconds to viafb load time on the XO-1.5.

[jc: minor merge conflict fixed, removed ifdefs]
Signed-off-by: Chris Ball <cjb@laptop.org>
---
 drivers/video/via/hw.c  |    7 +++++++
 drivers/video/via/lcd.c |    7 +++++++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 4aff0f7..bd5d5ce 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -2037,6 +2037,13 @@ static void init_gfx_chip_info(struct pci_dev *pdev,
 
 static void init_tmds_chip_info(void)
 {
+	/*
+	 * OLPC XO 1.5 systems are wired differently, so there is
+	 * no point in them here.
+	 */
+	if (machine_is_olpc())
+		return;
+
 	viafb_tmds_trasmitter_identify();
 
 	if (INTERFACE_NONE == viaparinfo->chip_info->tmds_chip_info.
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index b656e59..ce3f4b6 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -173,6 +173,13 @@ static bool lvds_identify_integratedlvds(void)
 
 int viafb_lvds_trasmitter_identify(void)
 {
+	/*
+	 * OLPC XO 1.5 systems are wired differently, so there is
+	 * no point in them here.
+	 */
+	if (machine_is_olpc())
+		return FAIL;
+
 	viaparinfo->shared->i2c_stuff.i2c_port = I2CPORTINDEX;
 	if (viafb_lvds_identify_vt1636()) {
 		viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX;
-- 
1.7.0.1

--

From: Florian Tobias Schandinat
Date: Friday, April 23, 2010 - 1:56 pm

Hi Jon,

I fear your analysis that the #ifdef's are not needed is wrong. At least 
with this patch applied I get:

drivers/video/via/hw.c: In function 'init_tmds_chip_info':
drivers/video/via/hw.c:2043: error: implicit declaration of function 
'machine_is_olpc'

drivers/video/via/lcd.c: In function 'viafb_lvds_trasmitter_identify':
drivers/video/via/lcd.c:179: error: implicit declaration of function 
'machine_is_olpc'

So I vote for taking the original patch but in the series that also adds 
the relevant config option.


Thanks,

Florian Tobias Schandinat


--

From: Jonathan Corbet
Date: Friday, April 23, 2010 - 2:09 pm

On Fri, 23 Apr 2010 22:56:46 +0200

No, the problem is the "embarrassing compilation error" I mentioned in
my other mail; it needs "#include <asm/olpc.h>" at the top of the file.

Sorry,

jon
--

From: Jonathan Corbet
Date: Sunday, April 18, 2010 - 11:21 am

From: Chris Ball <cjb@laptop.org>

[jc: extensive merge conflict fixes]
Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: ScottFang@viatech.com.cn
Cc: JosephChan@via.com.tw
Signed-off-by: Chris Ball <cjb@laptop.org>
---
 drivers/video/via/hw.c      |    1 +
 drivers/video/via/ioctl.h   |    2 +-
 drivers/video/via/lcd.c     |    9 +++++++++
 drivers/video/via/lcd.h     |    2 ++
 drivers/video/via/share.h   |    7 +++++++
 drivers/video/via/viamode.c |   14 ++++++++++++++
 6 files changed, 34 insertions(+), 1 deletions(-)

diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index d893695..4aff0f7 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -63,6 +63,7 @@ static struct pll_map pll_value[] = {
 	 CX700_52_977M,	VX855_52_977M},
 	{CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M,
 	 CX700_56_250M, VX855_56_250M},
+	{CLK_57_275M, 0, 0, 0, VX855_57_275M},
 	{CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M,
 	 CX700_60_466M, VX855_60_466M},
 	{CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M,
diff --git a/drivers/video/via/ioctl.h b/drivers/video/via/ioctl.h
index de89980..c430fa2 100644
--- a/drivers/video/via/ioctl.h
+++ b/drivers/video/via/ioctl.h
@@ -75,7 +75,7 @@
 /*SAMM operation flag*/
 #define OP_SAMM            0x80
 
-#define LCD_PANEL_ID_MAXIMUM	22
+#define LCD_PANEL_ID_MAXIMUM	23
 
 #define STATE_ON            0x1
 #define STATE_OFF           0x0
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 79c8c9d..b656e59 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -399,6 +399,15 @@ static void fp_id_to_vindex(int panel_id)
 		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
 		viaparinfo->lvds_setting_info->LCDDithering = 1;
 		break;
+	case 0x17:
+		/* OLPC XO-1.5 panel */
+		viaparinfo->lvds_setting_info->lcd_panel_hres = 1200;
+		viaparinfo->lvds_setting_info->lcd_panel_vres = 900;
+		viaparinfo->lvds_setting_info->lcd_panel_id ...
From: Jonathan Corbet
Date: Sunday, April 18, 2010 - 11:21 am

This patch is a painful merge of change
a90bab567ece3e915d0ccd55ab00c9bb333fa8c0 (viafb: Add support for 2D
accelerated framebuffer on VX800/VX855) in the OLPC tree, originally by
Harald Welte.  Harald's changelog read:

	The VX800/VX820 and the VX855/VX875 chipsets have a different 2D
    	acceleration engine called "M1".  The M1 engine has some subtle
    	(and some not-so-subtle) differences to the previous engines, so
    	support for accelerated framebuffer on those chipsets was disabled
    	so far.

This merge tries to preserve Harald's changes in the framework of the
much-changed 2.6.34 viafb code.

Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: ScottFang@viatech.com.cn
Cc: JosephChan@via.com.tw
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
---
 drivers/video/via/accel.c |   42 +++++++++++++++++++++++++++++++++---------
 drivers/video/via/accel.h |   40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 9 deletions(-)

diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
index 7c1d9c4..0d90c85 100644
--- a/drivers/video/via/accel.c
+++ b/drivers/video/via/accel.c
@@ -317,6 +317,7 @@ int viafb_init_engine(struct fb_info *info)
 {
 	struct viafb_par *viapar = info->par;
 	void __iomem *engine;
+	int highest_reg, i;
 	u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high,
 		vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name;
 
@@ -328,6 +329,18 @@ int viafb_init_engine(struct fb_info *info)
 		return -ENOMEM;
 	}
 
+	/* Initialize registers to reset the 2D engine */
+	switch (viapar->shared->chip_info.twod_engine) {
+	case VIA_2D_ENG_M1:
+		highest_reg = 0x5c;
+		break;
+	default:
+		highest_reg = 0x40;
+		break;
+	}
+	for (i = 0; i <= highest_reg; i += 4)
+		writel(0x0, engine + i);
+
 	switch (chip_name) {
 	case UNICHROME_CLE266:
 	case UNICHROME_K400:
@@ -357,13 +370,12 @@ int viafb_init_engine(struct fb_info *info)
 	viapar->shared->vq_vram_addr = viapar->fbmem_free;
 ...
From: Jonathan Corbet
Date: Sunday, April 18, 2010 - 11:21 am

Commit c3e25673843153ea75fda79a47cf12f10a25ca37 (viafb: 2D engine rewrite)
changed the setting of the GEMODE register so that the reserved bits are no
longer preserved.  Fix that; at the same time, move this code to its own
function and restore the use of symbolic constants.

Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: ScottFang@viatech.com.cn
Cc: JosephChan@via.com.tw
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
---
 drivers/video/via/accel.c |   49 ++++++++++++++++++++++++++++++--------------
 1 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
index d5077df..a52147c 100644
--- a/drivers/video/via/accel.c
+++ b/drivers/video/via/accel.c
@@ -165,12 +165,42 @@ static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height,
 	return 0;
 }
 
+/*
+ * Figure out an appropriate bytes-per-pixel setting.
+ */
+static int viafb_set_bpp(void __iomem *engine, u8 bpp)
+{
+	u32 gemode;
+
+	/* Preserve the reserved bits */
+	/* Lowest 2 bits to zero gives us no rotation */
+	gemode = readl(engine + VIA_REG_GEMODE) & 0xfffffcfc;
+	switch (bpp) {
+	case 8:
+		gemode |= VIA_GEM_8bpp;
+		break;
+	case 16:
+		gemode |= VIA_GEM_16bpp;
+		break;
+	case 32:
+		gemode |= VIA_GEM_32bpp;
+		break;
+	default:
+		printk(KERN_WARNING "hw_bitblt_2: Unsupported bpp %d\n", bpp);
+		return -EINVAL;
+	}
+	writel(gemode, engine + VIA_REG_GEMODE);
+	return 0;
+}
+
+
 static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
 	u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
 	u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
 	u32 fg_color, u32 bg_color, u8 fill_rop)
 {
 	u32 ge_cmd = 0, tmp, i;
+	int ret;
 
 	if (!op || op > 3) {
 		printk(KERN_WARNING "hw_bitblt_2: Invalid operation: %d\n", op);
@@ -204,22 +234,9 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
 		}
 	}
 
-	switch (dst_bpp) {
-	case ...
From: Jonathan Corbet
Date: Sunday, April 18, 2010 - 11:21 am

This was part of Harald's "make viafb a first-class citizen using
pci_driver" patch, but somehow got dropped when that patch went into
mainline.

Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: ScottFang@viatech.com.cn
Cc: JosephChan@via.com.tw
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
---
 drivers/video/via/viafbdev.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 8af405b..8955ab4 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -1870,7 +1870,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
 			printk(KERN_ERR
 			"allocate the second framebuffer struct error\n");
 			rc = -ENOMEM;
-			goto out_delete_i2c;
+			goto out_unmap_screen;
 		}
 		viaparinfo1 = viafbinfo1->par;
 		memcpy(viaparinfo1, viaparinfo, viafb_par_length);
@@ -1961,6 +1961,8 @@ out_dealloc_cmap:
 out_fb1_release:
 	if (viafbinfo1)
 		framebuffer_release(viafbinfo1);
+out_unmap_screen:
+	iounmap(viafbinfo->screen_base);
 out_delete_i2c:
 	viafb_delete_i2c_buss(viaparinfo);
 out_fb_release:
-- 
1.7.0.1

--

From: Jonathan Corbet
Date: Sunday, April 18, 2010 - 11:21 am

From: Harald Welte <laforge@gnumonks.org>

This patch alters viafb to use the proper Linux in-kernel API to access
PCI configuration space, rather than poking at I/O ports by itself.

Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: ScottFang@viatech.com.cn
Cc: JosephChan@via.com.tw
Signed-off-by: Harald Welte <HaraldWelte@viatech.com>
---
 drivers/video/via/hw.c       |   62 +++++++++++++++++++++++++----------------
 drivers/video/via/hw.h       |    4 +-
 drivers/video/via/viafbdev.c |    4 +++
 3 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index b1e6dc9..69acae1 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -2474,24 +2474,37 @@ static void disable_second_display_channel(void)
 	viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
 }
 
+static u_int16_t via_function3[] = {
+	CLE266_FUNCTION3, KM400_FUNCTION3, CN400_FUNCTION3, CN700_FUNCTION3,
+	CX700_FUNCTION3, KM800_FUNCTION3, KM890_FUNCTION3, P4M890_FUNCTION3,
+	P4M900_FUNCTION3, VX800_FUNCTION3, VX855_FUNCTION3,
+};
+
+/* Get the BIOS-configured framebuffer size from PCI configuration space
+ * of function 3 in the respective chipset */
 int viafb_get_fb_size_from_pci(void)
 {
-	unsigned long configid, deviceid, FBSize = 0;
-	int VideoMemSize;
-	int DeviceFound = false;
-
-	for (configid = 0x80000000; configid < 0x80010800; configid += 0x100) {
-		outl(configid, (unsigned long)0xCF8);
-		deviceid = (inl((unsigned long)0xCFC) >> 16) & 0xffff;
-
-		switch (deviceid) {
-		case CLE266:
-		case KM400:
-			outl(configid + 0xE0, (unsigned long)0xCF8);
-			FBSize = inl((unsigned long)0xCFC);
-			DeviceFound = true;	/* Found device id */
-			break;
+	int i;
+	u_int8_t offset = 0;
+	u_int32_t FBSize;
+	u_int32_t VideoMemSize;
+
+	/* search for the "FUNCTION3" device in this chipset */
+	for (i = 0; i < ARRAY_SIZE(via_function3); i++) {
+		struct pci_dev *pdev;
+
+		pdev = pci_get_device(PCI_VENDOR_ID_VIA, ...
Previous thread: none

Next thread: none