All of lore.kernel.org
 help / color / mirror / Atom feed
* Xorg doesn't work on the cg3
@ 2005-02-10 19:15 Tom 'spot' Callaway
  2005-02-12  6:10 ` Bob Breuer
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Tom 'spot' Callaway @ 2005-02-10 19:15 UTC (permalink / raw)
  To: sparclinux

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

I've been working with Bob Breuer & Peter Jones to try and track the
sparc32 Xorg problems down, and we have made some progress.

Initially, cg14 worked in X, and neither cg3 nor cg6 worked at all.

In order to make the cg3 framebuffer work (aka, console tux logo and
text), a patch was needed (attached as linux-2.6.10-sparc-framebuffer-
fixes.patch).
 
However, X still didn't work for the cg3 or cg6. With an additional
patch, X works for the cg6. This patch is attached as linux-2.6.10-
sparc-fix_putcmap.patch.

But the cg3 remains stubborn. Bob wrote an elaborate test case, attached
to this email as fbtest-new.c. 

In this code, there are 4 tests:
A) FBIOPUTCMAP_FBCON, red, ramp_up -- see the ramp_up.png image
B) FBIOPUTCMAP_FBCON, red, ramp_down -- see the ramp_down.png image
C) FBIOPUTCMAP_SPARC, green, ramp_up -- same pattern as A, but green
D) FBIOPUTCMAP_SPARC, green, ramp_down -- same pattern as B, but green

B should have a red background, and D should have a green background,
but none should be a solid color.

When this code is run on the cg3, the console jumps to tty7, the screen
goes blank, then we get a solid green screen, then back to tty1.

As Bob describes it: Since you never see any red, then A and B are
broken (fb driver problem?). And if you see nothing but solid black or
solid green, then C and D may only be setting the first palette entry,
or first few entries.

Dave, I don't fully understand how cg3 works, but I can't find any
gaping flaws in the cg3.c implementation. Does all of this data provide
you with any insight as to where the actual failure is?

Wli, please apply these two patches, since they get the cg3 console
working and cg6 Xorg functional.

Signed-off-by: Tom 'spot' Callaway <tcallawa@redhat.com>

~spot
---
Tom "spot" Callaway <tcallawa(a)redhat*com> LCA, RHCE 
Red Hat Sales Engineer || Aurora Linux Project Leader

"If you are going through hell, keep going."
-- Sir Winston Churchill

[-- Attachment #2: linux-2.6.10-sparc-framebuffer-fixes.patch --]
[-- Type: text/x-patch, Size: 708 bytes --]

--- linux-2.6.9/drivers/video/cg3.c.BAD	2004-12-19 15:51:01.011779676 -0500
+++ linux-2.6.9/drivers/video/cg3.c	2004-12-19 16:03:46.675381116 -0500
@@ -385,6 +385,9 @@ static void cg3_init_one(struct sbus_dev
 	all->par.physbase = sdev->reg_addrs[0].phys_addr;
 
 	sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+	all->info.var.red.length = 8;
+	all->info.var.green.length = 8;
+	all->info.var.blue.length = 8;
 	if (!strcmp(sdev->prom_name, "cgRDI"))
 		all->par.flags |= CG3_FLAG_RDI;
 	if (all->par.flags & CG3_FLAG_RDI)
@@ -419,6 +422,7 @@ static void cg3_init_one(struct sbus_dev
 		kfree(all);
 		return;
 	}
+	fb_set_cmap(&all->info.cmap, &all->info);
 
 	cg3_init_fix(&all->info, linebytes);
 

[-- Attachment #3: linux-2.6.10-sparc-fix_putcmap.patch --]
[-- Type: text/x-patch, Size: 1593 bytes --]

--- linux-2.6.10/drivers/video/sbuslib.c.sbuslib	2004-12-24 16:34:29.000000000 -0500
+++ linux-2.6.10/drivers/video/sbuslib.c	2005-02-08 23:23:42.941644262 -0500
@@ -108,6 +108,7 @@
 		struct fbcmap __user *c = (struct fbcmap __user *) arg;
 		struct fb_cmap cmap;
 		u16 red, green, blue;
+		u8 red8, green8, blue8;
 		unsigned char __user *ured;
 		unsigned char __user *ugreen;
 		unsigned char __user *ublue;
@@ -128,11 +129,15 @@
 		for (i = 0; i < count; i++) {
 			int err;
 
-			if (get_user(red, &ured[i]) ||
-			    get_user(green, &ugreen[i]) ||
-			    get_user(blue, &ublue[i]))
+			if (get_user(red8, &ured[i]) ||
+			    get_user(green8, &ugreen[i]) ||
+			    get_user(blue8, &ublue[i]))
 				return -EFAULT;
 
+			red = red8 << 8;
+			green = green8 << 8;
+			blue = blue8 << 8;
+
 			cmap.start = index + i;
 			err = fb_set_cmap(&cmap, info);
 			if (err)
@@ -147,6 +152,7 @@
 		unsigned char __user *ublue;
 		struct fb_cmap *cmap = &info->cmap;
 		int index, count, i;
+		u8 red, green, blue;
 
 		if (get_user(index, &c->index) ||
 		    __get_user(count, &c->count) ||
@@ -159,9 +165,12 @@
 			return -EINVAL;
 
 		for (i = 0; i < count; i++) {
-			if (put_user(cmap->red[index + i], &ured[i]) ||
-			    put_user(cmap->green[index + i], &ugreen[i]) ||
-			    put_user(cmap->blue[index + i], &ublue[i]))
+			red = cmap->red[index + i] >> 8;
+			green = cmap->green[index + i] >> 8;
+			blue = cmap->blue[index + i] >> 8;
+			if (put_user(red, &ured[i]) ||
+			    put_user(green, &ugreen[i]) ||
+			    put_user(blue, &ublue[i]))
 				return -EFAULT;
 		}
 		return 0;

[-- Attachment #4: fbtest-new.c --]
[-- Type: text/x-csrc, Size: 4339 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/vt.h>
#include <linux/kd.h>
#include <linux/fb.h>
#include <asm/fbio.h> /* sun framebuffer ioctl's */

__u16 old_red[256], old_green[256], old_blue[256];
__u16 dark[256];
__u8 ramp_up8[256], ramp_down8[256];
__u16 ramp_up16[256], ramp_down16[256];

/* avoid confusion, be explicit */
#undef FBIOGETCMAP
#undef FBIOPUTCMAP

#define FBIOGETCMAP_FBCON 0x4604
#define FBIOPUTCMAP_FBCON 0x4605

#define FBIOPUTCMAP_SPARC _IOW('F', 3, struct fbcmap)
#define FBIOGETCMAP_SPARC _IOW('F', 4, struct fbcmap)

int main(void)
{
	int tty, fb, my_vt;
	struct vt_stat vt_state;
	int old_kdmode;
	struct fb_fix_screeninfo fb_finfo;
	struct fb_var_screeninfo fb_vinfo;
	struct fbtype sparc_fbtype;
	struct fbcmap sparc_cmap;
	struct fb_cmap fbcon_cmap;
	char *fbmem, *data;
	int x, y;
	const char *str;
	int sunfb, mapoffset;

	if ((tty = open("/dev/tty", O_NOCTTY|O_RDWR)) == -1)
	{
		perror("open console");
		return -1;
	}

	if (ioctl(tty, VT_GETSTATE, &vt_state) < 0)
	{
		perror("get vt state");
		return -1;
	}
	if (ioctl(tty, VT_OPENQRY, &my_vt) < 0)
	{
		perror("query vt");
		return -1;
	}

	printf("Switching from tty%d to tty%d\n", vt_state.v_active, my_vt);
	if (ioctl(tty, VT_ACTIVATE, my_vt) < 0
	  || ioctl(tty, VT_WAITACTIVE, my_vt) < 0)
	{
		perror("switch vt");
		return -1;
	}

	/* prepare for graphics */
	if (ioctl(tty, KDGETMODE, &old_kdmode) < 0)
		perror("kdgetmode");
	else
		printf("old kdmode = %d\n", old_kdmode);
	if (ioctl(tty, KDSETMODE, KD_GRAPHICS) < 0)
		perror("kdsetmode");

	sunfb = 0;
	fbmem = NULL;
	if ((fb = open("/dev/fb0", O_RDWR)) == -1)
	{
		perror("open fb");
		goto err_nofb;
	}

	mapoffset = -1;
	if (ioctl(fb, FBIOGET_FSCREENINFO, &fb_finfo) < 0
	  || ioctl(fb, FBIOGET_VSCREENINFO, &fb_vinfo) < 0)
		perror("get fb info");

	if (ioctl(fb, FBIOGTYPE, &sparc_fbtype) < 0)
	{
		perror("FBIOGTYPE failed\n");
	}
	else
	{
		sunfb = 1;
		switch (sparc_fbtype.fb_type) {
		case FBTYPE_NOTYPE:
			str = "NOTYPE"; break;
		case FBTYPE_SUN3COLOR:
			mapoffset = 0x4000000;
			str = "SUN3COLOR (cg3)"; break;
		case FBTYPE_SUNFAST_COLOR:
			mapoffset = 0x800000;
			str = "SUNFAST_COLOR (cg6)"; break;
		case FBTYPE_MDICOLOR:
			mapoffset = 0x4000000;
			str = "MDICOLOR (cg14)"; break;
		default:
			str = "other"; break;
		}

		printf( "fbtype:\n"
			"  fb_type   = FBTYPE_%s\n"
			"  fb_height = %d\n"
			"  fb_width  = %d\n"
			"  fb_depth  = %d\n"
			"  fb_cmsize = %d\n"
			"  fb_size   = 0x%08x\n",
			str,
			sparc_fbtype.fb_height, sparc_fbtype.fb_width,
			sparc_fbtype.fb_depth, sparc_fbtype.fb_cmsize,
			sparc_fbtype.fb_size);
	}

	if (mapoffset == -1)
	{
		printf("Don't know mmap offset for framebuffer\n");
	}
	else
	{
		fbmem = (char*)mmap(NULL, 512*1024,
			PROT_READ|PROT_WRITE, MAP_SHARED, fb, mapoffset);
		if (fbmem == MAP_FAILED)
		{
			perror("map fb mem");
			fbmem = NULL;
		}
	}

	fbcon_cmap.start = 0;
	fbcon_cmap.len = 256;
	fbcon_cmap.red = old_red;
	fbcon_cmap.green = old_green;
	fbcon_cmap.blue = old_blue;
	ioctl(fb, FBIOGETCMAP_FBCON, &fbcon_cmap);

	if (fbmem)
	for (data=fbmem, y=0; y<256; y++, data+=fb_finfo.line_length)
		for (x=0; x<256; x++)
			data[x] = (x % 16) + (y & 0xf0);


	for (x=0; x<256; x++) {
		dark[x] = 0;
		ramp_up8[x] = x;
		ramp_down8[x] = 255-x;
		ramp_up16[x] = x << 8;
		ramp_down16[x] = (255-x) << 8;
	}

	/* red */
	fbcon_cmap.red = ramp_up16;
	fbcon_cmap.green = dark;
	fbcon_cmap.blue = dark;
	ioctl(fb, FBIOPUTCMAP_FBCON, &fbcon_cmap);
	sleep(2);

	fbcon_cmap.red = ramp_down16;
	ioctl(fb, FBIOPUTCMAP_FBCON, &fbcon_cmap);
	sleep(2);

	if (sunfb)
	{
		sparc_cmap.index = 0;
		sparc_cmap.count = 256;

		/* green */
		sparc_cmap.red = (__u8*)dark;
		sparc_cmap.blue = (__u8*)dark;
		sparc_cmap.green = ramp_up8;
		ioctl(fb, FBIOPUTCMAP_SPARC, &sparc_cmap);
		sleep(2);

		sparc_cmap.green = ramp_down8;
		ioctl(fb, FBIOPUTCMAP_SPARC, &sparc_cmap);
		sleep(2);
	}

	fbcon_cmap.red = old_red;
	fbcon_cmap.green = old_green;
	fbcon_cmap.blue = old_blue;
	ioctl(fb, FBIOPUTCMAP_FBCON, &fbcon_cmap);

	if (fbmem)
		munmap(fbmem, 512*1024);
	close(fb);
err_nofb:
	ioctl(tty, KDSETMODE, old_kdmode);
	ioctl(tty, VT_ACTIVATE, vt_state.v_active);

	close(tty);

	return 0;
}


[-- Attachment #5: ramp_down.png --]
[-- Type: image/png, Size: 2958 bytes --]

[-- Attachment #6: ramp_up.png --]
[-- Type: image/png, Size: 2958 bytes --]

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

* Re: Xorg doesn't work on the cg3
  2005-02-10 19:15 Xorg doesn't work on the cg3 Tom 'spot' Callaway
@ 2005-02-12  6:10 ` Bob Breuer
  2005-02-12  7:44 ` David S. Miller
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Bob Breuer @ 2005-02-12  6:10 UTC (permalink / raw)
  To: sparclinux

Tom 'spot' Callaway wrote:
> But the cg3 remains stubborn.

I came upon this when comparing the mmap address for cg14 and cg3:
cg14.c:	.voff	= CG3_MMAP_OFFSET,
cg3.c:	.poff	= CG3_MMAP_OFFSET,

I have appended a patch to squash this bug.  But a question remains,
how did this bug go undetected like this?  Either the mmap should
have returned an error, or we should have got a segmentation fault
on writes, but it seems that neither one happened.  Any ideas?

Bob


--- linux-2.6.10-clean/drivers/video/cg3.c	2005-01-12 00:11:02.000000000 -0600
+++ linux-2.6.10/drivers/video/cg3.c	2005-02-11 23:33:54.000000000 -0600
@@ -222,8 +222,8 @@ cg3_blank(int blank, struct fb_info *inf

  static struct sbus_mmap_map cg3_mmap_map[] = {
  	{
-		.poff	= CG3_MMAP_OFFSET,
-		.voff	= CG3_RAM_OFFSET,
+		.voff	= CG3_MMAP_OFFSET,
+		.poff	= CG3_RAM_OFFSET,
  		.size	= SBUS_MMAP_FBSIZE(1)
  	},
  	{ .size = 0 }

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

* Re: Xorg doesn't work on the cg3
  2005-02-10 19:15 Xorg doesn't work on the cg3 Tom 'spot' Callaway
  2005-02-12  6:10 ` Bob Breuer
@ 2005-02-12  7:44 ` David S. Miller
  2005-02-12 13:49 ` Tom 'spot' Callaway
  2005-02-12 19:47 ` David S. Miller
  3 siblings, 0 replies; 5+ messages in thread
From: David S. Miller @ 2005-02-12  7:44 UTC (permalink / raw)
  To: sparclinux

On Sat, 12 Feb 2005 00:10:00 -0600
Bob Breuer <breuerr@mc.net> wrote:

> Tom 'spot' Callaway wrote:
> > But the cg3 remains stubborn.
> 
> I came upon this when comparing the mmap address for cg14 and cg3:
> cg14.c:	.voff	= CG3_MMAP_OFFSET,
> cg3.c:	.poff	= CG3_MMAP_OFFSET,
> 
> I have appended a patch to squash this bug.  But a question remains,
> how did this bug go undetected like this?  Either the mmap should
> have returned an error, or we should have got a segmentation fault
> on writes, but it seems that neither one happened.  Any ideas?

Nasty.  Maybe X.org doesn't check the return value.  But you're
right in that it should have segfaulted afterwards if so.

One explanation is that X.out perhaps catches SIGSEGV and tries
to handle it somehow (for example, if the SIGSEGV is due to an
I/O register access which times out or is for an address the chip
refuses to respond to)

Oh I see what might be happening.  In drivers/video/sbuslib.c
the sbusfb_mmap_helper() just skips over addresses that don't
match one of the sbus_mmap_map entries.  No error is returned
even if none of the pages match an area in sbus_mmap_map.

As a result, the user just gets a bunch of anonymous memory
mapped there.  The faults generated here just map in normal
zeroed main memory.

We could have caught this sooner if sbusfb_mmap_helper() returned
errors in such a case.  But who knows what that might break. :-)

I'm applying this obvious cg3 fix.  There is a bunch of other
patches that are necessary to get X fully working on both cg14
and cg3 aren't there?  At a minimum there's that BUG() removal
in the srmmu code, right?

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

* Re: Xorg doesn't work on the cg3
  2005-02-10 19:15 Xorg doesn't work on the cg3 Tom 'spot' Callaway
  2005-02-12  6:10 ` Bob Breuer
  2005-02-12  7:44 ` David S. Miller
@ 2005-02-12 13:49 ` Tom 'spot' Callaway
  2005-02-12 19:47 ` David S. Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Tom 'spot' Callaway @ 2005-02-12 13:49 UTC (permalink / raw)
  To: sparclinux

On Fri, 2005-02-11 at 23:44 -0800, David S. Miller wrote:

>I'm applying this obvious cg3 fix.  There is a bunch of other
>patches that are necessary to get X fully working on both cg14
>and cg3 aren't there?  At a minimum there's that BUG() removal
>in the srmmu code, right?

Yes. We also need the other cg3 patch to make the framebuffer console
work, and the sbuslib patch to make cg6 work in X. Both of these are in
my previous post on this thread.

~spot
---
Tom "spot" Callaway <tcallawa(a)redhat*com> LCA, RHCE 
Red Hat Sales Engineer || Aurora Linux Project Leader

"If you are going through hell, keep going."
-- Sir Winston Churchill


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

* Re: Xorg doesn't work on the cg3
  2005-02-10 19:15 Xorg doesn't work on the cg3 Tom 'spot' Callaway
                   ` (2 preceding siblings ...)
  2005-02-12 13:49 ` Tom 'spot' Callaway
@ 2005-02-12 19:47 ` David S. Miller
  3 siblings, 0 replies; 5+ messages in thread
From: David S. Miller @ 2005-02-12 19:47 UTC (permalink / raw)
  To: sparclinux

On Sat, 12 Feb 2005 07:49:12 -0600
"Tom 'spot' Callaway" <tcallawa@redhat.com> wrote:

> On Fri, 2005-02-11 at 23:44 -0800, David S. Miller wrote:
> 
> >I'm applying this obvious cg3 fix.  There is a bunch of other
> >patches that are necessary to get X fully working on both cg14
> >and cg3 aren't there?  At a minimum there's that BUG() removal
> >in the srmmu code, right?
> 
> Yes. We also need the other cg3 patch to make the framebuffer console
> work, and the sbuslib patch to make cg6 work in X. Both of these are in
> my previous post on this thread.

Gotcha.  I think I have it all in my tree now.  Here is the
changelog manifest, and I'll push this to Linus today.

ChangeSet@1.2027, 2005-02-11 23:24:22-08:00, breuerr@mc.net
  [CG3]: FB mmap .voff and .poff were reversed.
  
  Signed-off-by: David S. Miller <davem@davemloft.net>

ChangeSet@1.2028, 2005-02-11 23:26:37-08:00, tcallawa@redhat.com
  [CG3]: Set framebuffer cmap correctly.
  
  Signed-off-by: David S. Miller <davem@davemloft.net>

ChangeSet@1.2029, 2005-02-11 23:28:08-08:00, tcallawa@redhat.com
  [SPARC]: fb: Fix putcmap handling in sbuslib
  
  Signed-off-by: David S. Miller <davem@davemloft.net>

ChangeSet@1.2030, 2005-02-12 11:14:59-08:00, davem@nuts.davemloft.net
  [SPARC]: Do not BUG() in srmmu_pte_pfn().
  
  For device memory, just return a value that will never
  cause pte_pfn() to return true.
  
  Noticed by Tom Callaway.
  
  Signed-off-by: David S. Miller <davem@davemloft.net>


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

end of thread, other threads:[~2005-02-12 19:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-10 19:15 Xorg doesn't work on the cg3 Tom 'spot' Callaway
2005-02-12  6:10 ` Bob Breuer
2005-02-12  7:44 ` David S. Miller
2005-02-12 13:49 ` Tom 'spot' Callaway
2005-02-12 19:47 ` David S. Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.