[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: kernel 2.6.0-test8 console



> > I'd not recommend 2.6.0-test(7,8) for anyone unfamiliar with some
> > basic kernel hacking.
>
> I wouldn't call myself familiar with kernel hacking, but I upgraded
> painlessly from 2.4 to 2.6 by simply following the instructions at
> <URL:http://www.codemonkey.org.uk/post-halloween-2.5.txt>.

Color yourself lucky. You appear to have hardware well supported in 2.6
(and perhaps, used the benh tree anyway).

Anybody interested in testing 2.6.0-test7-benh on Powermacs with NVidia
display chipsets? Ben asked for more testing (works on a flat panel iMac,
untested otherwise). Patch attached.

	Michael
--- drivers/video/riva/fbdev.c.org	2003-10-18 18:20:03.000000000 +0200
+++ drivers/video/riva/fbdev.c	2003-10-20 08:12:23.000000000 +0200
@@ -52,6 +52,11 @@
 #error This driver requires PCI support.
 #endif
 
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+
 /* version number of this driver */
 #define RIVAFB_VERSION "0.9.5b"
 
@@ -348,6 +353,95 @@
 	0xEB							/* MISC */
 };
 
+/*
+ * Here is some specific support for the eMac machine
+ * 
+ * This machine is "special" because of it's ivad2 display
+ * controller and fixed horizontal timing requirements.
+ * 
+ * Right now, all I do is to set a fixed working 1024x768
+ * mode at boot (I also have a 1280x960 at hand, if you
+ * prefer...).
+ * 
+ * I expect to do things better in a future 2.5 version
+ * though.
+ * 
+ * I also turn off the screen during blanking using IVAD
+ * i2c accesses, that's the basis we can use to later
+ * implement full IVAD support (geometry setting,
+ * brightness, ...).
+ */
+#if defined(CONFIG_ALL_PPC) && defined(CONFIG_ADB_PMU)
+
+static int ivad_iic_addr = -1;
+
+/* Default mode for eMac */
+static struct fb_var_screeninfo emac_default_var = {
+	xres:		1024,
+	yres:		768,
+	xres_virtual:	1024,
+	yres_virtual:	768,
+	xoffset:	0,
+	yoffset:	0,
+	bits_per_pixel:	8,
+	grayscale:	0,
+	red:		{0, 6, 0},
+	green:		{0, 6, 0},
+	blue:		{0, 6, 0},
+	transp:		{0, 0, 0},
+	nonstd:		0,
+	activate:	0,
+	height:		-1,
+	width:		-1,
+	accel_flags:	0,
+	pixclock:	10081,
+	left_margin:	208,
+	right_margin:	48,
+	upper_margin:	31,
+	lower_margin:	1,
+	hsync_len:	96,
+	vsync_len:	3,
+	sync:		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	vmode:		FB_VMODE_NONINTERLACED
+};
+
+static void
+init_ivad(void)
+{
+	if (machine_is_compatible("PowerMac4,4")) {
+		struct device_node* np = find_devices("ivad2");
+		unsigned int* prop;
+		
+		if (np == NULL)
+			return;
+		prop = (unsigned int*)get_property(np, "iic-address", NULL);
+		if (np == NULL) {
+			printk(KERN_INFO "IVAD2 found but has no iic-address property !\n");
+			return;
+		}
+		ivad_iic_addr = *prop;
+		printk(KERN_INFO "Found IVAD2, iic address is: 0x%02x\n", ivad_iic_addr);
+		rivafb_default_var = emac_default_var;
+	}
+}
+
+#define IVAD_CONTRAST_REG	0x00
+
+static void
+set_ivad_contrast(u8 contrast)
+{
+	int rc;
+
+	if (ivad_iic_addr < 0)
+		return;
+	rc = pmu_i2c_stdsub_write(PMU_I2C_BUS_POWER, ivad_iic_addr, IVAD_CONTRAST_REG, &contrast, 1);
+	if (rc < 0)
+		printk(KERN_ERR "IVAD2: Can't set contrast !\n");
+}
+
+#endif /* defined(CONFIG_ALL_PPC) && defined(CONFIG_ADB_PMU) */
+
+
 /* ------------------------------------------------------------------------- *
  *
  * MMIO access macros
@@ -927,6 +1021,7 @@
 /* acceleration routines */
 inline void wait_for_idle(struct riva_par *par)
 {
+	mb();
 	while (par->riva.Busy(&par->riva));
 }
 
@@ -1194,7 +1289,15 @@
 			vesa |= 0xc0;
 			break;
 		}
+#if defined(CONFIG_ALL_PPC) && defined(CONFIG_ADB_PMU)
+		set_ivad_contrast(0);
+#endif
+	} else {
+#if defined(CONFIG_ALL_PPC) && defined(CONFIG_ADB_PMU)
+		set_ivad_contrast(0xff);
+#endif
 	}
+
 	SEQout(par, 0x01, tmp);
 	CRTCout(par, 0x1a, vesa);
 	return 0;
@@ -1325,6 +1428,7 @@
 
 	RIVA_FIFO_FREE(par->riva, Rop, 1);
 	par->riva.Rop->Rop3 = rop;
+	wmb(); //??
 
 	RIVA_FIFO_FREE(par->riva, Bitmap, 1);
 	par->riva.Bitmap->Color1A = color;
@@ -1332,10 +1436,13 @@
 	RIVA_FIFO_FREE(par->riva, Bitmap, 2);
 	par->riva.Bitmap->UnclippedRectangle[0].TopLeft =
 			(rect->dx << 16) | rect->dy;
+	wmb();
 	par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
 			(rect->width << 16) | rect->height;
+	wmb();
 	RIVA_FIFO_FREE(par->riva, Rop, 1);
 	par->riva.Rop->Rop3 = 0xCC;	// back to COPY
+	wmb(); // ??
 }
 
 /**
@@ -1356,6 +1463,7 @@
 	RIVA_FIFO_FREE(par->riva, Blt, 3);
 	par->riva.Blt->TopLeftSrc  = (region->sy << 16) | region->sx;
 	par->riva.Blt->TopLeftDst  = (region->dy << 16) | region->dx;
+	wmb();
 	par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
 	wait_for_idle(par);
 }
@@ -1427,8 +1535,10 @@
 		(image->height << 16) | ((image->width + 31) & ~31);
 	par->riva.Bitmap->WidthHeightOutE   = 
 		(image->height << 16) | ((image->width + 31) & ~31);
+	wmb();
 	par->riva.Bitmap->PointE            = 
 		(image->dy << 16) | (image->dx & 0xFFFF);
+	wmb();
 
 	d = &par->riva.Bitmap->MonochromeData01E;
 
@@ -1611,15 +1721,29 @@
 {
 	struct device_node *dp;
 	unsigned char *pedid = NULL;
+	unsigned char *disptype = NULL;
+	static char *propnames[] = {
+		"DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL };
+	int i;  
 
 	dp = pci_device_to_OF_node(pd);
-	pedid = (unsigned char *)get_property(dp, "EDID,B", 0);
 
-	if (pedid) {
-		par->EDID = pedid;
-		return 1;
-	} else
-		return 0;
+        for (; dp != NULL; dp = dp->child) {
+               	disptype = (unsigned char *)get_property(dp, "display-type", NULL);
+                if (disptype == NULL)
+                	continue;
+                if (strncmp(disptype, "LCD", 3) != 0)
+                	continue;
+                for (i = 0; propnames[i] != NULL; ++i) {
+                        pedid = (unsigned char *)
+                                get_property(dp, propnames[i], NULL);
+                        if (pedid != NULL) {
+				par->EDID = pedid;
+				return 1;
+			}
+		}
+	}
+	return 0;
 }
 #endif /* CONFIG_PPC_OF */
 
@@ -1700,7 +1824,8 @@
 static void riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
 {
 #ifdef CONFIG_PPC_OF
-	if (!riva_get_EDID_OF(info, pdev))
+	struct riva_par *par = (struct riva_par *) info->par;
+	if (!riva_get_EDID_OF(par, pdev))
 		printk("rivafb: could not retrieve EDID from OF\n");
 #else
 	/* XXX use other methods later */
@@ -1993,8 +2118,12 @@
 
 int __init rivafb_init(void)
 {
-	if (pci_register_driver(&rivafb_driver) > 0)
+	if (pci_register_driver(&rivafb_driver) > 0) {
+#if defined(CONFIG_ALL_PPC) && defined(CONFIG_ADB_PMU)
+		init_ivad();
+#endif	
 		return 0;
+	}
 	pci_unregister_driver(&rivafb_driver);
 	return -ENODEV;
 }
--- drivers/video/riva/riva_hw.c.org	2003-10-19 12:37:42.000000000 +0200
+++ drivers/video/riva/riva_hw.c	2003-10-19 12:39:28.000000000 +0200
@@ -2061,7 +2061,8 @@
 
 #ifdef __BIG_ENDIAN
     /* turn on big endian register access */
-    chip->PMC[0x00000004/4] = 0x01000001;
+    if(!(chip->PMC[0x00000004/4] & 0x01000001))
+        chip->PMC[0x00000004/4] = 0x01000001;
 #endif
 
     /*
@@ -2122,6 +2123,11 @@
     case 0x01F0:
     case 0x0250:
     case 0x0280:
+    case 0x0300:
+    case 0x0310:
+    case 0x0320:
+    case 0x0330:
+    case 0x0340:
        if(chip->PEXTDEV[0x0000/4] & (1 << 22))
            chip->CrystalFreqKHz = 27000;
        break;
@@ -2153,6 +2159,11 @@
     case 0x01F0:
     case 0x0250:
     case 0x0280:
+    case 0x0300:
+    case 0x0310:
+    case 0x0320:
+    case 0x0330:
+    case 0x0340:
         chip->twoHeads = TRUE;
         break;
     default:
--- drivers/video/riva/riva_hw.h.org	2003-10-19 12:42:48.000000000 +0200
+++ drivers/video/riva/riva_hw.h	2003-10-19 12:44:28.000000000 +0200
@@ -537,10 +537,18 @@
  * FIFO Free Count. Should attempt to yield processor if RIVA is busy.
  */
 
+/*
+ * The mb()'s work around some lockup problems I experienced with some
+ * GeForceII MX cards, neither I nor Mark Vojkovich knows for sure what's
+ * going on there. --BenH
+ */ 
 #define RIVA_FIFO_FREE(hwinst,hwptr,cnt)                            \
 {                                                                   \
-    while ((hwinst).FifoFreeCount < (cnt))                          \
+    while ((hwinst).FifoFreeCount < (cnt)) {                        \
+    	mb();                                                       \
+    	mb();	                                                    \
         (hwinst).FifoFreeCount = (hwinst).hwptr->FifoFree >> 2;     \
+    } \
     (hwinst).FifoFreeCount -= (cnt);                                \
 }
 #endif /* __RIVA_HW_H__ */
--- drivers/video/riva/nv_driver.c.org	2003-10-19 12:40:45.000000000 +0200
+++ drivers/video/riva/nv_driver.c	2003-10-19 12:41:25.000000000 +0200
@@ -337,6 +337,11 @@
 	case 0x01F0:
 	case 0x0250:
 	case 0x0280:
+	case 0x0300:
+	case 0x0310:
+	case 0x0320:
+	case 0x0330:
+	case 0x0340:
 		riva_is_second(par);
 		break;
 	default:

Reply to: