diff options
Diffstat (limited to 'drivers/video/nvidia')
-rw-r--r-- | drivers/video/nvidia/nv_hw.c | 82 | ||||
-rw-r--r-- | drivers/video/nvidia/nv_i2c.c | 12 | ||||
-rw-r--r-- | drivers/video/nvidia/nv_proto.h | 2 | ||||
-rw-r--r-- | drivers/video/nvidia/nv_setup.c | 37 | ||||
-rw-r--r-- | drivers/video/nvidia/nvidia.c | 117 |
5 files changed, 187 insertions, 63 deletions
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c index b989358437b3..99c3a8e6a237 100644 --- a/drivers/video/nvidia/nv_hw.c +++ b/drivers/video/nvidia/nv_hw.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/pci.h> | 52 | #include <linux/pci.h> |
53 | #include "nv_type.h" | 53 | #include "nv_type.h" |
54 | #include "nv_local.h" | 54 | #include "nv_local.h" |
55 | #include "nv_proto.h" | ||
55 | 56 | ||
56 | void NVLockUnlock(struct nvidia_par *par, int Lock) | 57 | void NVLockUnlock(struct nvidia_par *par, int Lock) |
57 | { | 58 | { |
@@ -848,7 +849,7 @@ void NVCalcStateExt(struct nvidia_par *par, | |||
848 | int width, | 849 | int width, |
849 | int hDisplaySize, int height, int dotClock, int flags) | 850 | int hDisplaySize, int height, int dotClock, int flags) |
850 | { | 851 | { |
851 | int pixelDepth, VClk; | 852 | int pixelDepth, VClk = 0; |
852 | /* | 853 | /* |
853 | * Save mode parameters. | 854 | * Save mode parameters. |
854 | */ | 855 | */ |
@@ -938,15 +939,24 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) | |||
938 | 939 | ||
939 | if (par->Architecture == NV_ARCH_04) { | 940 | if (par->Architecture == NV_ARCH_04) { |
940 | NV_WR32(par->PFB, 0x0200, state->config); | 941 | NV_WR32(par->PFB, 0x0200, state->config); |
941 | } else if ((par->Chipset & 0xfff0) == 0x0090) { | 942 | } else if ((par->Architecture < NV_ARCH_40) || |
942 | for (i = 0; i < 15; i++) { | 943 | (par->Chipset & 0xfff0) == 0x0040) { |
943 | NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0); | ||
944 | NV_WR32(par->PFB, 0x0604 + (i * 0x10), par->FbMapSize - 1); | ||
945 | } | ||
946 | } else { | ||
947 | for (i = 0; i < 8; i++) { | 944 | for (i = 0; i < 8; i++) { |
948 | NV_WR32(par->PFB, 0x0240 + (i * 0x10), 0); | 945 | NV_WR32(par->PFB, 0x0240 + (i * 0x10), 0); |
949 | NV_WR32(par->PFB, 0x0244 + (i * 0x10), par->FbMapSize - 1); | 946 | NV_WR32(par->PFB, 0x0244 + (i * 0x10), |
947 | par->FbMapSize - 1); | ||
948 | } | ||
949 | } else { | ||
950 | int regions = 12; | ||
951 | |||
952 | if (((par->Chipset & 0xfff0) == 0x0090) || | ||
953 | ((par->Chipset & 0xfff0) == 0x01D0) || | ||
954 | ((par->Chipset & 0xfff0) == 0x0290)) | ||
955 | regions = 15; | ||
956 | for(i = 0; i < regions; i++) { | ||
957 | NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0); | ||
958 | NV_WR32(par->PFB, 0x0604 + (i * 0x10), | ||
959 | par->FbMapSize - 1); | ||
950 | } | 960 | } |
951 | } | 961 | } |
952 | 962 | ||
@@ -1182,11 +1192,17 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) | |||
1182 | NV_WR32(par->PGRAPH, 0x0608, 0xFFFFFFFF); | 1192 | NV_WR32(par->PGRAPH, 0x0608, 0xFFFFFFFF); |
1183 | } else { | 1193 | } else { |
1184 | if (par->Architecture >= NV_ARCH_40) { | 1194 | if (par->Architecture >= NV_ARCH_40) { |
1195 | u32 tmp; | ||
1196 | |||
1185 | NV_WR32(par->PGRAPH, 0x0084, 0x401287c0); | 1197 | NV_WR32(par->PGRAPH, 0x0084, 0x401287c0); |
1186 | NV_WR32(par->PGRAPH, 0x008C, 0x60de8051); | 1198 | NV_WR32(par->PGRAPH, 0x008C, 0x60de8051); |
1187 | NV_WR32(par->PGRAPH, 0x0090, 0x00008000); | 1199 | NV_WR32(par->PGRAPH, 0x0090, 0x00008000); |
1188 | NV_WR32(par->PGRAPH, 0x0610, 0x00be3c5f); | 1200 | NV_WR32(par->PGRAPH, 0x0610, 0x00be3c5f); |
1189 | 1201 | ||
1202 | tmp = NV_RD32(par->REGS, 0x1540) & 0xff; | ||
1203 | for(i = 0; tmp && !(tmp & 1); tmp >>= 1, i++); | ||
1204 | NV_WR32(par->PGRAPH, 0x5000, i); | ||
1205 | |||
1190 | if ((par->Chipset & 0xfff0) == 0x0040) { | 1206 | if ((par->Chipset & 0xfff0) == 0x0040) { |
1191 | NV_WR32(par->PGRAPH, 0x09b0, | 1207 | NV_WR32(par->PGRAPH, 0x09b0, |
1192 | 0x83280fff); | 1208 | 0x83280fff); |
@@ -1211,6 +1227,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) | |||
1211 | 0xffff7fff); | 1227 | 0xffff7fff); |
1212 | break; | 1228 | break; |
1213 | case 0x00C0: | 1229 | case 0x00C0: |
1230 | case 0x0120: | ||
1214 | NV_WR32(par->PGRAPH, 0x0828, | 1231 | NV_WR32(par->PGRAPH, 0x0828, |
1215 | 0x007596ff); | 1232 | 0x007596ff); |
1216 | NV_WR32(par->PGRAPH, 0x082C, | 1233 | NV_WR32(par->PGRAPH, 0x082C, |
@@ -1245,6 +1262,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) | |||
1245 | 0x00100000); | 1262 | 0x00100000); |
1246 | break; | 1263 | break; |
1247 | case 0x0090: | 1264 | case 0x0090: |
1265 | case 0x0290: | ||
1248 | NV_WR32(par->PRAMDAC, 0x0608, | 1266 | NV_WR32(par->PRAMDAC, 0x0608, |
1249 | NV_RD32(par->PRAMDAC, 0x0608) | | 1267 | NV_RD32(par->PRAMDAC, 0x0608) | |
1250 | 0x00100000); | 1268 | 0x00100000); |
@@ -1310,14 +1328,44 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) | |||
1310 | } | 1328 | } |
1311 | } | 1329 | } |
1312 | 1330 | ||
1313 | if ((par->Chipset & 0xfff0) == 0x0090) { | 1331 | if ((par->Architecture < NV_ARCH_40) || |
1314 | for (i = 0; i < 60; i++) | 1332 | ((par->Chipset & 0xfff0) == 0x0040)) { |
1315 | NV_WR32(par->PGRAPH, 0x0D00 + i, | 1333 | for (i = 0; i < 32; i++) { |
1316 | NV_RD32(par->PFB, 0x0600 + i)); | 1334 | NV_WR32(par->PGRAPH, 0x0900 + i*4, |
1335 | NV_RD32(par->PFB, 0x0240 +i*4)); | ||
1336 | NV_WR32(par->PGRAPH, 0x6900 + i*4, | ||
1337 | NV_RD32(par->PFB, 0x0240 +i*4)); | ||
1338 | } | ||
1317 | } else { | 1339 | } else { |
1318 | for (i = 0; i < 32; i++) | 1340 | if (((par->Chipset & 0xfff0) == 0x0090) || |
1319 | NV_WR32(par->PGRAPH, 0x0900 + i, | 1341 | ((par->Chipset & 0xfff0) == 0x01D0) || |
1320 | NV_RD32(par->PFB, 0x0240 + i)); | 1342 | ((par->Chipset & 0xfff0) == 0x0290)) { |
1343 | for (i = 0; i < 60; i++) { | ||
1344 | NV_WR32(par->PGRAPH, | ||
1345 | 0x0D00 + i*4, | ||
1346 | NV_RD32(par->PFB, | ||
1347 | 0x0600 + i*4)); | ||
1348 | NV_WR32(par->PGRAPH, | ||
1349 | 0x6900 + i*4, | ||
1350 | NV_RD32(par->PFB, | ||
1351 | 0x0600 + i*4)); | ||
1352 | } | ||
1353 | } else { | ||
1354 | for (i = 0; i < 48; i++) { | ||
1355 | NV_WR32(par->PGRAPH, | ||
1356 | 0x0900 + i*4, | ||
1357 | NV_RD32(par->PFB, | ||
1358 | 0x0600 + i*4)); | ||
1359 | if(((par->Chipset & 0xfff0) | ||
1360 | != 0x0160) && | ||
1361 | ((par->Chipset & 0xfff0) | ||
1362 | != 0x0220)) | ||
1363 | NV_WR32(par->PGRAPH, | ||
1364 | 0x6900 + i*4, | ||
1365 | NV_RD32(par->PFB, | ||
1366 | 0x0600 + i*4)); | ||
1367 | } | ||
1368 | } | ||
1321 | } | 1369 | } |
1322 | 1370 | ||
1323 | if (par->Architecture >= NV_ARCH_40) { | 1371 | if (par->Architecture >= NV_ARCH_40) { |
@@ -1338,7 +1386,9 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) | |||
1338 | NV_WR32(par->PGRAPH, 0x0868, | 1386 | NV_WR32(par->PGRAPH, 0x0868, |
1339 | par->FbMapSize - 1); | 1387 | par->FbMapSize - 1); |
1340 | } else { | 1388 | } else { |
1341 | if((par->Chipset & 0xfff0) == 0x0090) { | 1389 | if ((par->Chipset & 0xfff0) == 0x0090 || |
1390 | (par->Chipset & 0xfff0) == 0x01D0 || | ||
1391 | (par->Chipset & 0xfff0) == 0x0290) { | ||
1342 | NV_WR32(par->PGRAPH, 0x0DF0, | 1392 | NV_WR32(par->PGRAPH, 0x0DF0, |
1343 | NV_RD32(par->PFB, 0x0200)); | 1393 | NV_RD32(par->PFB, 0x0200)); |
1344 | NV_WR32(par->PGRAPH, 0x0DF4, | 1394 | NV_WR32(par->PGRAPH, 0x0DF4, |
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c index 12f2884d3f0b..bd9eca05e146 100644 --- a/drivers/video/nvidia/nv_i2c.c +++ b/drivers/video/nvidia/nv_i2c.c | |||
@@ -46,7 +46,7 @@ static void nvidia_gpio_setscl(void *data, int state) | |||
46 | 46 | ||
47 | static void nvidia_gpio_setsda(void *data, int state) | 47 | static void nvidia_gpio_setsda(void *data, int state) |
48 | { | 48 | { |
49 | struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data; | 49 | struct nvidia_i2c_chan *chan = data; |
50 | struct nvidia_par *par = chan->par; | 50 | struct nvidia_par *par = chan->par; |
51 | u32 val; | 51 | u32 val; |
52 | 52 | ||
@@ -64,7 +64,7 @@ static void nvidia_gpio_setsda(void *data, int state) | |||
64 | 64 | ||
65 | static int nvidia_gpio_getscl(void *data) | 65 | static int nvidia_gpio_getscl(void *data) |
66 | { | 66 | { |
67 | struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data; | 67 | struct nvidia_i2c_chan *chan = data; |
68 | struct nvidia_par *par = chan->par; | 68 | struct nvidia_par *par = chan->par; |
69 | u32 val = 0; | 69 | u32 val = 0; |
70 | 70 | ||
@@ -79,7 +79,7 @@ static int nvidia_gpio_getscl(void *data) | |||
79 | 79 | ||
80 | static int nvidia_gpio_getsda(void *data) | 80 | static int nvidia_gpio_getsda(void *data) |
81 | { | 81 | { |
82 | struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data; | 82 | struct nvidia_i2c_chan *chan = data; |
83 | struct nvidia_par *par = chan->par; | 83 | struct nvidia_par *par = chan->par; |
84 | u32 val = 0; | 84 | u32 val = 0; |
85 | 85 | ||
@@ -136,13 +136,13 @@ void nvidia_create_i2c_busses(struct nvidia_par *par) | |||
136 | par->chan[2].par = par; | 136 | par->chan[2].par = par; |
137 | 137 | ||
138 | par->chan[0].ddc_base = 0x3e; | 138 | par->chan[0].ddc_base = 0x3e; |
139 | nvidia_setup_i2c_bus(&par->chan[0], "BUS1"); | 139 | nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0"); |
140 | 140 | ||
141 | par->chan[1].ddc_base = 0x36; | 141 | par->chan[1].ddc_base = 0x36; |
142 | nvidia_setup_i2c_bus(&par->chan[1], "BUS2"); | 142 | nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1"); |
143 | 143 | ||
144 | par->chan[2].ddc_base = 0x50; | 144 | par->chan[2].ddc_base = 0x50; |
145 | nvidia_setup_i2c_bus(&par->chan[2], "BUS3"); | 145 | nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2"); |
146 | } | 146 | } |
147 | 147 | ||
148 | void nvidia_delete_i2c_busses(struct nvidia_par *par) | 148 | void nvidia_delete_i2c_busses(struct nvidia_par *par) |
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h index 3353103e8b0b..b149a690ee0f 100644 --- a/drivers/video/nvidia/nv_proto.h +++ b/drivers/video/nvidia/nv_proto.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #define __NV_PROTO_H__ | 4 | #define __NV_PROTO_H__ |
5 | 5 | ||
6 | /* in nv_setup.c */ | 6 | /* in nv_setup.c */ |
7 | void NVCommonSetup(struct fb_info *info); | 7 | int NVCommonSetup(struct fb_info *info); |
8 | void NVWriteCrtc(struct nvidia_par *par, u8 index, u8 value); | 8 | void NVWriteCrtc(struct nvidia_par *par, u8 index, u8 value); |
9 | u8 NVReadCrtc(struct nvidia_par *par, u8 index); | 9 | u8 NVReadCrtc(struct nvidia_par *par, u8 index); |
10 | void NVWriteGr(struct nvidia_par *par, u8 index, u8 value); | 10 | void NVWriteGr(struct nvidia_par *par, u8 index, u8 value); |
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c index 1f06a9f1bd0f..a18a9aebf05f 100644 --- a/drivers/video/nvidia/nv_setup.c +++ b/drivers/video/nvidia/nv_setup.c | |||
@@ -285,28 +285,34 @@ static void nv10GetConfig(struct nvidia_par *par) | |||
285 | par->CrystalFreqKHz = 27000; | 285 | par->CrystalFreqKHz = 27000; |
286 | } | 286 | } |
287 | 287 | ||
288 | par->CursorStart = (par->RamAmountKBytes - 96) * 1024; | ||
289 | par->CURSOR = NULL; /* can't set this here */ | 288 | par->CURSOR = NULL; /* can't set this here */ |
290 | par->MinVClockFreqKHz = 12000; | 289 | par->MinVClockFreqKHz = 12000; |
291 | par->MaxVClockFreqKHz = par->twoStagePLL ? 400000 : 350000; | 290 | par->MaxVClockFreqKHz = par->twoStagePLL ? 400000 : 350000; |
292 | } | 291 | } |
293 | 292 | ||
294 | void NVCommonSetup(struct fb_info *info) | 293 | int NVCommonSetup(struct fb_info *info) |
295 | { | 294 | { |
296 | struct nvidia_par *par = info->par; | 295 | struct nvidia_par *par = info->par; |
297 | struct fb_var_screeninfo var; | 296 | struct fb_var_screeninfo *var; |
298 | u16 implementation = par->Chipset & 0x0ff0; | 297 | u16 implementation = par->Chipset & 0x0ff0; |
299 | u8 *edidA = NULL, *edidB = NULL; | 298 | u8 *edidA = NULL, *edidB = NULL; |
300 | struct fb_monspecs monitorA, monitorB; | 299 | struct fb_monspecs *monitorA, *monitorB; |
301 | struct fb_monspecs *monA = NULL, *monB = NULL; | 300 | struct fb_monspecs *monA = NULL, *monB = NULL; |
302 | int mobile = 0; | 301 | int mobile = 0; |
303 | int tvA = 0; | 302 | int tvA = 0; |
304 | int tvB = 0; | 303 | int tvB = 0; |
305 | int FlatPanel = -1; /* really means the CRTC is slaved */ | 304 | int FlatPanel = -1; /* really means the CRTC is slaved */ |
306 | int Television = 0; | 305 | int Television = 0; |
306 | int err = 0; | ||
307 | 307 | ||
308 | memset(&monitorA, 0, sizeof(struct fb_monspecs)); | 308 | var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); |
309 | memset(&monitorB, 0, sizeof(struct fb_monspecs)); | 309 | monitorA = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL); |
310 | monitorB = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL); | ||
311 | |||
312 | if (!var || !monitorA || !monitorB) { | ||
313 | err = -ENOMEM; | ||
314 | goto done; | ||
315 | } | ||
310 | 316 | ||
311 | par->PRAMIN = par->REGS + (0x00710000 / 4); | 317 | par->PRAMIN = par->REGS + (0x00710000 / 4); |
312 | par->PCRTC0 = par->REGS + (0x00600000 / 4); | 318 | par->PCRTC0 = par->REGS + (0x00600000 / 4); |
@@ -382,6 +388,8 @@ void NVCommonSetup(struct fb_info *info) | |||
382 | case 0x0146: | 388 | case 0x0146: |
383 | case 0x0147: | 389 | case 0x0147: |
384 | case 0x0148: | 390 | case 0x0148: |
391 | case 0x0098: | ||
392 | case 0x0099: | ||
385 | mobile = 1; | 393 | mobile = 1; |
386 | break; | 394 | break; |
387 | default: | 395 | default: |
@@ -406,9 +414,9 @@ void NVCommonSetup(struct fb_info *info) | |||
406 | par->CRTCnumber = 0; | 414 | par->CRTCnumber = 0; |
407 | if (nvidia_probe_i2c_connector(info, 1, &edidA)) | 415 | if (nvidia_probe_i2c_connector(info, 1, &edidA)) |
408 | nvidia_probe_of_connector(info, 1, &edidA); | 416 | nvidia_probe_of_connector(info, 1, &edidA); |
409 | if (edidA && !fb_parse_edid(edidA, &var)) { | 417 | if (edidA && !fb_parse_edid(edidA, var)) { |
410 | printk("nvidiafb: EDID found from BUS1\n"); | 418 | printk("nvidiafb: EDID found from BUS1\n"); |
411 | monA = &monitorA; | 419 | monA = monitorA; |
412 | fb_edid_to_monspecs(edidA, monA); | 420 | fb_edid_to_monspecs(edidA, monA); |
413 | FlatPanel = (monA->input & FB_DISP_DDI) ? 1 : 0; | 421 | FlatPanel = (monA->input & FB_DISP_DDI) ? 1 : 0; |
414 | 422 | ||
@@ -494,17 +502,17 @@ void NVCommonSetup(struct fb_info *info) | |||
494 | 502 | ||
495 | if (nvidia_probe_i2c_connector(info, 1, &edidA)) | 503 | if (nvidia_probe_i2c_connector(info, 1, &edidA)) |
496 | nvidia_probe_of_connector(info, 1, &edidA); | 504 | nvidia_probe_of_connector(info, 1, &edidA); |
497 | if (edidA && !fb_parse_edid(edidA, &var)) { | 505 | if (edidA && !fb_parse_edid(edidA, var)) { |
498 | printk("nvidiafb: EDID found from BUS1\n"); | 506 | printk("nvidiafb: EDID found from BUS1\n"); |
499 | monA = &monitorA; | 507 | monA = monitorA; |
500 | fb_edid_to_monspecs(edidA, monA); | 508 | fb_edid_to_monspecs(edidA, monA); |
501 | } | 509 | } |
502 | 510 | ||
503 | if (nvidia_probe_i2c_connector(info, 2, &edidB)) | 511 | if (nvidia_probe_i2c_connector(info, 2, &edidB)) |
504 | nvidia_probe_of_connector(info, 2, &edidB); | 512 | nvidia_probe_of_connector(info, 2, &edidB); |
505 | if (edidB && !fb_parse_edid(edidB, &var)) { | 513 | if (edidB && !fb_parse_edid(edidB, var)) { |
506 | printk("nvidiafb: EDID found from BUS2\n"); | 514 | printk("nvidiafb: EDID found from BUS2\n"); |
507 | monB = &monitorB; | 515 | monB = monitorB; |
508 | fb_edid_to_monspecs(edidB, monB); | 516 | fb_edid_to_monspecs(edidB, monB); |
509 | } | 517 | } |
510 | 518 | ||
@@ -639,4 +647,9 @@ void NVCommonSetup(struct fb_info *info) | |||
639 | 647 | ||
640 | kfree(edidA); | 648 | kfree(edidA); |
641 | kfree(edidB); | 649 | kfree(edidB); |
650 | done: | ||
651 | kfree(var); | ||
652 | kfree(monitorA); | ||
653 | kfree(monitorB); | ||
654 | return err; | ||
642 | } | 655 | } |
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index bee09c6e48f6..dbcb8962e57d 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -284,6 +284,16 @@ static struct pci_device_id nvidiafb_pci_tbl[] = { | |||
284 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 284 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
285 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200, | 285 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200, |
286 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 286 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
287 | {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1, | ||
288 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
289 | {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT1, | ||
290 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
291 | {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT2, | ||
292 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
293 | {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6200_ALT1, | ||
294 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
295 | {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT, | ||
296 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
287 | {PCI_VENDOR_ID_NVIDIA, 0x0252, | 297 | {PCI_VENDOR_ID_NVIDIA, 0x0252, |
288 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 298 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
289 | {PCI_VENDOR_ID_NVIDIA, 0x0313, | 299 | {PCI_VENDOR_ID_NVIDIA, 0x0313, |
@@ -418,6 +428,7 @@ static int noaccel __devinitdata = 0; | |||
418 | static int noscale __devinitdata = 0; | 428 | static int noscale __devinitdata = 0; |
419 | static int paneltweak __devinitdata = 0; | 429 | static int paneltweak __devinitdata = 0; |
420 | static int vram __devinitdata = 0; | 430 | static int vram __devinitdata = 0; |
431 | static int bpp __devinitdata = 8; | ||
421 | #ifdef CONFIG_MTRR | 432 | #ifdef CONFIG_MTRR |
422 | static int nomtrr __devinitdata = 0; | 433 | static int nomtrr __devinitdata = 0; |
423 | #endif | 434 | #endif |
@@ -485,7 +496,7 @@ static int nvidia_backlight_levels[] = { | |||
485 | 496 | ||
486 | static int nvidia_set_backlight_enable(int on, int level, void *data) | 497 | static int nvidia_set_backlight_enable(int on, int level, void *data) |
487 | { | 498 | { |
488 | struct nvidia_par *par = (struct nvidia_par *)data; | 499 | struct nvidia_par *par = data; |
489 | u32 tmp_pcrt, tmp_pmc, fpcontrol; | 500 | u32 tmp_pcrt, tmp_pmc, fpcontrol; |
490 | 501 | ||
491 | tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF; | 502 | tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF; |
@@ -1382,24 +1393,36 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info) | |||
1382 | info->monspecs.modedb_len, &info->modelist); | 1393 | info->monspecs.modedb_len, &info->modelist); |
1383 | fb_var_to_videomode(&modedb, &nvidiafb_default_var); | 1394 | fb_var_to_videomode(&modedb, &nvidiafb_default_var); |
1384 | 1395 | ||
1396 | switch (bpp) { | ||
1397 | case 0 ... 8: | ||
1398 | bpp = 8; | ||
1399 | break; | ||
1400 | case 9 ... 16: | ||
1401 | bpp = 16; | ||
1402 | break; | ||
1403 | default: | ||
1404 | bpp = 32; | ||
1405 | break; | ||
1406 | } | ||
1407 | |||
1385 | if (specs->modedb != NULL) { | 1408 | if (specs->modedb != NULL) { |
1386 | struct fb_videomode *modedb; | 1409 | struct fb_videomode *modedb; |
1387 | 1410 | ||
1388 | modedb = fb_find_best_display(specs, &info->modelist); | 1411 | modedb = fb_find_best_display(specs, &info->modelist); |
1389 | fb_videomode_to_var(&nvidiafb_default_var, modedb); | 1412 | fb_videomode_to_var(&nvidiafb_default_var, modedb); |
1390 | nvidiafb_default_var.bits_per_pixel = 8; | 1413 | nvidiafb_default_var.bits_per_pixel = bpp; |
1391 | } else if (par->fpWidth && par->fpHeight) { | 1414 | } else if (par->fpWidth && par->fpHeight) { |
1392 | char buf[16]; | 1415 | char buf[16]; |
1393 | 1416 | ||
1394 | memset(buf, 0, 16); | 1417 | memset(buf, 0, 16); |
1395 | snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight); | 1418 | snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight); |
1396 | fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb, | 1419 | fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb, |
1397 | specs->modedb_len, &modedb, 8); | 1420 | specs->modedb_len, &modedb, bpp); |
1398 | } | 1421 | } |
1399 | 1422 | ||
1400 | if (mode_option) | 1423 | if (mode_option) |
1401 | fb_find_mode(&nvidiafb_default_var, info, mode_option, | 1424 | fb_find_mode(&nvidiafb_default_var, info, mode_option, |
1402 | specs->modedb, specs->modedb_len, &modedb, 8); | 1425 | specs->modedb, specs->modedb_len, &modedb, bpp); |
1403 | 1426 | ||
1404 | info->var = nvidiafb_default_var; | 1427 | info->var = nvidiafb_default_var; |
1405 | info->fix.visual = (info->var.bits_per_pixel == 8) ? | 1428 | info->fix.visual = (info->var.bits_per_pixel == 8) ? |
@@ -1448,11 +1471,34 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info) | |||
1448 | return nvidiafb_check_var(&info->var, info); | 1471 | return nvidiafb_check_var(&info->var, info); |
1449 | } | 1472 | } |
1450 | 1473 | ||
1451 | static u32 __devinit nvidia_get_arch(struct pci_dev *pd) | 1474 | static u32 __devinit nvidia_get_chipset(struct fb_info *info) |
1452 | { | 1475 | { |
1476 | struct nvidia_par *par = info->par; | ||
1477 | u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device; | ||
1478 | |||
1479 | printk("nvidiafb: PCI id - %x\n", id); | ||
1480 | if ((id & 0xfff0) == 0x00f0) { | ||
1481 | /* pci-e */ | ||
1482 | printk("nvidiafb: PCI-E card\n"); | ||
1483 | id = NV_RD32(par->REGS, 0x1800); | ||
1484 | |||
1485 | if ((id & 0x0000ffff) == 0x000010DE) | ||
1486 | id = 0x10DE0000 | (id >> 16); | ||
1487 | else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */ | ||
1488 | id = 0x10DE0000 | ((id << 8) & 0x0000ff00) | | ||
1489 | ((id >> 8) & 0x000000ff); | ||
1490 | } | ||
1491 | |||
1492 | printk("nvidiafb: Actual id - %x\n", id); | ||
1493 | return id; | ||
1494 | } | ||
1495 | |||
1496 | static u32 __devinit nvidia_get_arch(struct fb_info *info) | ||
1497 | { | ||
1498 | struct nvidia_par *par = info->par; | ||
1453 | u32 arch = 0; | 1499 | u32 arch = 0; |
1454 | 1500 | ||
1455 | switch (pd->device & 0x0ff0) { | 1501 | switch (par->Chipset & 0x0ff0) { |
1456 | case 0x0100: /* GeForce 256 */ | 1502 | case 0x0100: /* GeForce 256 */ |
1457 | case 0x0110: /* GeForce2 MX */ | 1503 | case 0x0110: /* GeForce2 MX */ |
1458 | case 0x0150: /* GeForce2 */ | 1504 | case 0x0150: /* GeForce2 */ |
@@ -1485,6 +1531,8 @@ static u32 __devinit nvidia_get_arch(struct pci_dev *pd) | |||
1485 | case 0x0210: | 1531 | case 0x0210: |
1486 | case 0x0220: | 1532 | case 0x0220: |
1487 | case 0x0230: | 1533 | case 0x0230: |
1534 | case 0x0290: | ||
1535 | case 0x0390: | ||
1488 | arch = NV_ARCH_40; | 1536 | arch = NV_ARCH_40; |
1489 | break; | 1537 | break; |
1490 | case 0x0020: /* TNT, TNT2 */ | 1538 | case 0x0020: /* TNT, TNT2 */ |
@@ -1513,7 +1561,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1513 | if (!info) | 1561 | if (!info) |
1514 | goto err_out; | 1562 | goto err_out; |
1515 | 1563 | ||
1516 | par = (struct nvidia_par *)info->par; | 1564 | par = info->par; |
1517 | par->pci_dev = pd; | 1565 | par->pci_dev = pd; |
1518 | 1566 | ||
1519 | info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL); | 1567 | info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL); |
@@ -1533,18 +1581,6 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1533 | goto err_out_request; | 1581 | goto err_out_request; |
1534 | } | 1582 | } |
1535 | 1583 | ||
1536 | par->Architecture = nvidia_get_arch(pd); | ||
1537 | |||
1538 | par->Chipset = (pd->vendor << 16) | pd->device; | ||
1539 | printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset); | ||
1540 | |||
1541 | if (par->Architecture == 0) { | ||
1542 | printk(KERN_ERR PFX "unknown NV_ARCH\n"); | ||
1543 | goto err_out_free_base0; | ||
1544 | } | ||
1545 | |||
1546 | sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4); | ||
1547 | |||
1548 | par->FlatPanel = flatpanel; | 1584 | par->FlatPanel = flatpanel; |
1549 | if (flatpanel == 1) | 1585 | if (flatpanel == 1) |
1550 | printk(KERN_INFO PFX "flatpanel support enabled\n"); | 1586 | printk(KERN_INFO PFX "flatpanel support enabled\n"); |
@@ -1570,7 +1606,19 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1570 | goto err_out_free_base0; | 1606 | goto err_out_free_base0; |
1571 | } | 1607 | } |
1572 | 1608 | ||
1573 | NVCommonSetup(info); | 1609 | par->Chipset = nvidia_get_chipset(info); |
1610 | printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset); | ||
1611 | par->Architecture = nvidia_get_arch(info); | ||
1612 | |||
1613 | if (par->Architecture == 0) { | ||
1614 | printk(KERN_ERR PFX "unknown NV_ARCH\n"); | ||
1615 | goto err_out_arch; | ||
1616 | } | ||
1617 | |||
1618 | sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4); | ||
1619 | |||
1620 | if (NVCommonSetup(info)) | ||
1621 | goto err_out_arch; | ||
1574 | 1622 | ||
1575 | par->FbAddress = nvidiafb_fix.smem_start; | 1623 | par->FbAddress = nvidiafb_fix.smem_start; |
1576 | par->FbMapSize = par->RamAmountKBytes * 1024; | 1624 | par->FbMapSize = par->RamAmountKBytes * 1024; |
@@ -1581,10 +1629,15 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1581 | if (par->FbMapSize > 64 * 1024 * 1024) | 1629 | if (par->FbMapSize > 64 * 1024 * 1024) |
1582 | par->FbMapSize = 64 * 1024 * 1024; | 1630 | par->FbMapSize = 64 * 1024 * 1024; |
1583 | 1631 | ||
1584 | par->FbUsableSize = par->FbMapSize - (128 * 1024); | 1632 | if(par->Architecture >= NV_ARCH_40) |
1633 | par->FbUsableSize = par->FbMapSize - (560 * 1024); | ||
1634 | else | ||
1635 | par->FbUsableSize = par->FbMapSize - (128 * 1024); | ||
1585 | par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 : | 1636 | par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 : |
1586 | 16 * 1024; | 1637 | 16 * 1024; |
1587 | par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize; | 1638 | par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize; |
1639 | par->CursorStart = par->FbUsableSize + (32 * 1024); | ||
1640 | |||
1588 | info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize); | 1641 | info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize); |
1589 | info->screen_size = par->FbUsableSize; | 1642 | info->screen_size = par->FbUsableSize; |
1590 | nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024; | 1643 | nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024; |
@@ -1640,21 +1693,22 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1640 | NVTRACE_LEAVE(); | 1693 | NVTRACE_LEAVE(); |
1641 | return 0; | 1694 | return 0; |
1642 | 1695 | ||
1643 | err_out_iounmap_fb: | 1696 | err_out_iounmap_fb: |
1644 | iounmap(info->screen_base); | 1697 | iounmap(info->screen_base); |
1645 | err_out_free_base1: | 1698 | err_out_free_base1: |
1646 | fb_destroy_modedb(info->monspecs.modedb); | 1699 | fb_destroy_modedb(info->monspecs.modedb); |
1647 | nvidia_delete_i2c_busses(par); | 1700 | nvidia_delete_i2c_busses(par); |
1701 | err_out_arch: | ||
1648 | iounmap(par->REGS); | 1702 | iounmap(par->REGS); |
1649 | err_out_free_base0: | 1703 | err_out_free_base0: |
1650 | pci_release_regions(pd); | 1704 | pci_release_regions(pd); |
1651 | err_out_request: | 1705 | err_out_request: |
1652 | pci_disable_device(pd); | 1706 | pci_disable_device(pd); |
1653 | err_out_enable: | 1707 | err_out_enable: |
1654 | kfree(info->pixmap.addr); | 1708 | kfree(info->pixmap.addr); |
1655 | err_out_kfree: | 1709 | err_out_kfree: |
1656 | framebuffer_release(info); | 1710 | framebuffer_release(info); |
1657 | err_out: | 1711 | err_out: |
1658 | return -ENODEV; | 1712 | return -ENODEV; |
1659 | } | 1713 | } |
1660 | 1714 | ||
@@ -1729,6 +1783,8 @@ static int __devinit nvidiafb_setup(char *options) | |||
1729 | #endif | 1783 | #endif |
1730 | } else if (!strncmp(this_opt, "fpdither:", 9)) { | 1784 | } else if (!strncmp(this_opt, "fpdither:", 9)) { |
1731 | fpdither = simple_strtol(this_opt+9, NULL, 0); | 1785 | fpdither = simple_strtol(this_opt+9, NULL, 0); |
1786 | } else if (!strncmp(this_opt, "bpp:", 4)) { | ||
1787 | bpp = simple_strtoul(this_opt+4, NULL, 0); | ||
1732 | } else | 1788 | } else |
1733 | mode_option = this_opt; | 1789 | mode_option = this_opt; |
1734 | } | 1790 | } |
@@ -1804,6 +1860,11 @@ module_param(vram, int, 0); | |||
1804 | MODULE_PARM_DESC(vram, | 1860 | MODULE_PARM_DESC(vram, |
1805 | "amount of framebuffer memory to remap in MiB" | 1861 | "amount of framebuffer memory to remap in MiB" |
1806 | "(default=0 - remap entire memory)"); | 1862 | "(default=0 - remap entire memory)"); |
1863 | module_param(mode_option, charp, 0); | ||
1864 | MODULE_PARM_DESC(mode_option, "Specify initial video mode"); | ||
1865 | module_param(bpp, int, 0); | ||
1866 | MODULE_PARM_DESC(bpp, "pixel width in bits" | ||
1867 | "(default=8)"); | ||
1807 | #ifdef CONFIG_MTRR | 1868 | #ifdef CONFIG_MTRR |
1808 | module_param(nomtrr, bool, 0); | 1869 | module_param(nomtrr, bool, 0); |
1809 | MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " | 1870 | MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " |