> > 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 via email to