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: