]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
[PATCH] nvidiafb: Fixes for new G5
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tue, 10 Jan 2006 04:51:27 +0000 (20:51 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 10 Jan 2006 16:01:24 +0000 (08:01 -0800)
Recent X "nv" driver was fixed for various issues with modern 6xxx and 7xxx
cards.  This patch ports those fixes to nvidiafb.  This makes it work fine
on the 6600 bundled with the newest G5 macs.  I've verified it still works
on the 5200FX of the iMacG5.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/video/nvidia/nv_hw.c
drivers/video/nvidia/nv_setup.c
drivers/video/nvidia/nvidia.c

index b989358437b3723e4e26dddb4b597b85c411fccb..454283f9bdac2aafe2ca457b1f4608384a26f94c 100644 (file)
@@ -848,7 +848,7 @@ void NVCalcStateExt(struct nvidia_par *par,
                    int width,
                    int hDisplaySize, int height, int dotClock, int flags)
 {
-       int pixelDepth, VClk;
+       int pixelDepth, VClk = 0;
        /*
         * Save mode parameters.
         */
@@ -938,15 +938,24 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
 
        if (par->Architecture == NV_ARCH_04) {
                NV_WR32(par->PFB, 0x0200, state->config);
-       } else if ((par->Chipset & 0xfff0) == 0x0090) {
-               for (i = 0; i < 15; i++) {
-                       NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0);
-                       NV_WR32(par->PFB, 0x0604 + (i * 0x10), par->FbMapSize - 1);
-               }
-       } else {
+       } else if ((par->Architecture < NV_ARCH_40) ||
+                  (par->Chipset & 0xfff0) == 0x0040) {
                for (i = 0; i < 8; i++) {
                        NV_WR32(par->PFB, 0x0240 + (i * 0x10), 0);
-                       NV_WR32(par->PFB, 0x0244 + (i * 0x10), par->FbMapSize - 1);
+                       NV_WR32(par->PFB, 0x0244 + (i * 0x10),
+                               par->FbMapSize - 1);
+               }
+       } else {
+               int regions = 12;
+
+               if (((par->Chipset & 0xfff0) == 0x0090) ||
+                   ((par->Chipset & 0xfff0) == 0x01D0) ||
+                   ((par->Chipset & 0xfff0) == 0x0290))
+                       regions = 15;
+               for(i = 0; i < regions; i++) {
+                       NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0);
+                       NV_WR32(par->PFB, 0x0604 + (i * 0x10),
+                               par->FbMapSize - 1);
                }
        }
 
@@ -1182,11 +1191,17 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
                        NV_WR32(par->PGRAPH, 0x0608, 0xFFFFFFFF);
                } else {
                        if (par->Architecture >= NV_ARCH_40) {
+                               u32 tmp;
+
                                NV_WR32(par->PGRAPH, 0x0084, 0x401287c0);
                                NV_WR32(par->PGRAPH, 0x008C, 0x60de8051);
                                NV_WR32(par->PGRAPH, 0x0090, 0x00008000);
                                NV_WR32(par->PGRAPH, 0x0610, 0x00be3c5f);
 
+                               tmp = NV_RD32(par->REGS, 0x1540) & 0xff;
+                               for(i = 0; tmp && !(tmp & 1); tmp >>= 1, i++);
+                               NV_WR32(par->PGRAPH, 0x5000, i);
+
                                if ((par->Chipset & 0xfff0) == 0x0040) {
                                        NV_WR32(par->PGRAPH, 0x09b0,
                                                0x83280fff);
@@ -1211,6 +1226,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
                                                0xffff7fff);
                                        break;
                                case 0x00C0:
+                               case 0x0120:
                                        NV_WR32(par->PGRAPH, 0x0828,
                                                0x007596ff);
                                        NV_WR32(par->PGRAPH, 0x082C,
@@ -1245,6 +1261,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
                                                0x00100000);
                                        break;
                                case 0x0090:
+                               case 0x0290:
                                        NV_WR32(par->PRAMDAC, 0x0608,
                                                NV_RD32(par->PRAMDAC, 0x0608) |
                                                0x00100000);
@@ -1310,14 +1327,44 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
                                }
                        }
 
-                       if ((par->Chipset & 0xfff0) == 0x0090) {
-                               for (i = 0; i < 60; i++)
-                                       NV_WR32(par->PGRAPH, 0x0D00 + i,
-                                               NV_RD32(par->PFB, 0x0600 + i));
+                       if ((par->Architecture < NV_ARCH_40) ||
+                           ((par->Chipset & 0xfff0) == 0x0040)) {
+                               for (i = 0; i < 32; i++) {
+                                       NV_WR32(par->PGRAPH, 0x0900 + i*4,
+                                               NV_RD32(par->PFB, 0x0240 +i*4));
+                                       NV_WR32(par->PGRAPH, 0x6900 + i*4,
+                                               NV_RD32(par->PFB, 0x0240 +i*4));
+                               }
                        } else {
-                               for (i = 0; i < 32; i++)
-                                       NV_WR32(par->PGRAPH, 0x0900 + i,
-                                               NV_RD32(par->PFB, 0x0240 + i));
+                               if (((par->Chipset & 0xfff0) == 0x0090) ||
+                                   ((par->Chipset & 0xfff0) == 0x01D0) ||
+                                   ((par->Chipset & 0xfff0) == 0x0290)) {
+                                       for (i = 0; i < 60; i++) {
+                                               NV_WR32(par->PGRAPH,
+                                                       0x0D00 + i*4,
+                                                       NV_RD32(par->PFB,
+                                                               0x0600 + i*4));
+                                               NV_WR32(par->PGRAPH,
+                                                       0x6900 + i*4,
+                                                       NV_RD32(par->PFB,
+                                                               0x0600 + i*4));
+                                       }
+                               } else {
+                                       for (i = 0; i < 48; i++) {
+                                               NV_WR32(par->PGRAPH,
+                                                       0x0900 + i*4,
+                                                       NV_RD32(par->PFB,
+                                                               0x0600 + i*4));
+                                               if(((par->Chipset & 0xfff0)
+                                                   != 0x0160) &&
+                                                  ((par->Chipset & 0xfff0)
+                                                   != 0x0220))
+                                                       NV_WR32(par->PGRAPH,
+                                                               0x6900 + i*4,
+                                                               NV_RD32(par->PFB,
+                                                                       0x0600 + i*4));
+                                       }
+                               }
                        }
 
                        if (par->Architecture >= NV_ARCH_40) {
@@ -1338,7 +1385,9 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
                                        NV_WR32(par->PGRAPH, 0x0868,
                                                par->FbMapSize - 1);
                                } else {
-                                       if((par->Chipset & 0xfff0) == 0x0090) {
+                                       if ((par->Chipset & 0xfff0) == 0x0090 ||
+                                           (par->Chipset & 0xfff0) == 0x01D0 ||
+                                           (par->Chipset & 0xfff0) == 0x0290) {
                                                NV_WR32(par->PGRAPH, 0x0DF0,
                                                        NV_RD32(par->PFB, 0x0200));
                                                NV_WR32(par->PGRAPH, 0x0DF4,
index 1f06a9f1bd0f52d893e4233111174281a23f130e..2c024523c6222bb2100ed2c34eff39ba300c1912 100644 (file)
@@ -285,7 +285,6 @@ static void nv10GetConfig(struct nvidia_par *par)
                        par->CrystalFreqKHz = 27000;
        }
 
-       par->CursorStart = (par->RamAmountKBytes - 96) * 1024;
        par->CURSOR = NULL;     /* can't set this here */
        par->MinVClockFreqKHz = 12000;
        par->MaxVClockFreqKHz = par->twoStagePLL ? 400000 : 350000;
@@ -382,6 +381,8 @@ void NVCommonSetup(struct fb_info *info)
        case 0x0146:
        case 0x0147:
        case 0x0148:
+       case 0x0098:
+       case 0x0099:
                mobile = 1;
                break;
        default:
index bee09c6e48f61ce28224fa2282f6bd8f113f114a..f6d2440e84aaf4c0a7ea7df39b8d9fe1ccdcfa64 100644 (file)
@@ -1485,6 +1485,8 @@ static u32 __devinit nvidia_get_arch(struct pci_dev *pd)
        case 0x0210:
        case 0x0220:
        case 0x0230:
+       case 0x0290:
+       case 0x0390:
                arch = NV_ARCH_40;
                break;
        case 0x0020:            /* TNT, TNT2 */
@@ -1581,10 +1583,15 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
        if (par->FbMapSize > 64 * 1024 * 1024)
                par->FbMapSize = 64 * 1024 * 1024;
 
-       par->FbUsableSize = par->FbMapSize - (128 * 1024);
+       if(par->Architecture >= NV_ARCH_40)
+               par->FbUsableSize = par->FbMapSize - (560 * 1024);
+       else
+               par->FbUsableSize = par->FbMapSize - (128 * 1024);
        par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
            16 * 1024;
        par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
+       par->CursorStart = par->FbUsableSize + (32 * 1024);
+
        info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize);
        info->screen_size = par->FbUsableSize;
        nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;