Skip to content

Commit

Permalink
[PATCH] nvidiafb: Fixes for new G5
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Benjamin Herrenschmidt authored and Linus Torvalds committed Jan 10, 2006
1 parent 2308acc commit 0137ecf
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 18 deletions.
81 changes: 65 additions & 16 deletions drivers/video/nvidia/nv_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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);
Expand All @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion drivers/video/nvidia/nv_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -382,6 +381,8 @@ void NVCommonSetup(struct fb_info *info)
case 0x0146:
case 0x0147:
case 0x0148:
case 0x0098:
case 0x0099:
mobile = 1;
break;
default:
Expand Down
9 changes: 8 additions & 1 deletion drivers/video/nvidia/nvidia.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 0137ecf

Please sign in to comment.