diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-01-10 07:51:27 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-10 19:01:24 +0300 |
commit | 0137ecfdc3453f58a9beee95152ff61e8bad97b1 (patch) | |
tree | e7dc8fe3047c7d0df1cf9d514ea2a25b6efc737e /drivers/video/nvidia/nv_hw.c | |
parent | 2308acca656c3625c46b671b348fb04b6b006cad (diff) | |
download | linux-0137ecfdc3453f58a9beee95152ff61e8bad97b1.tar.xz |
[PATCH] nvidiafb: Fixes for new G5
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>
Diffstat (limited to 'drivers/video/nvidia/nv_hw.c')
-rw-r--r-- | drivers/video/nvidia/nv_hw.c | 81 |
1 files changed, 65 insertions, 16 deletions
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c index b989358437b3..454283f9bdac 100644 --- a/drivers/video/nvidia/nv_hw.c +++ b/drivers/video/nvidia/nv_hw.c @@ -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, |