aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/nvidia
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/nvidia')
-rw-r--r--drivers/video/nvidia/nv_accel.c12
-rw-r--r--drivers/video/nvidia/nv_type.h1
-rw-r--r--drivers/video/nvidia/nvidia.c115
3 files changed, 97 insertions, 31 deletions
diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/nvidia/nv_accel.c
index f377a29ec97a..4aefb8f41637 100644
--- a/drivers/video/nvidia/nv_accel.c
+++ b/drivers/video/nvidia/nv_accel.c
@@ -300,6 +300,9 @@ int nvidiafb_sync(struct fb_info *info)
300{ 300{
301 struct nvidia_par *par = info->par; 301 struct nvidia_par *par = info->par;
302 302
303 if (info->state != FBINFO_STATE_RUNNING)
304 return 0;
305
303 if (!par->lockup) 306 if (!par->lockup)
304 NVFlush(par); 307 NVFlush(par);
305 308
@@ -313,6 +316,9 @@ void nvidiafb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
313{ 316{
314 struct nvidia_par *par = info->par; 317 struct nvidia_par *par = info->par;
315 318
319 if (info->state != FBINFO_STATE_RUNNING)
320 return;
321
316 if (par->lockup) 322 if (par->lockup)
317 return cfb_copyarea(info, region); 323 return cfb_copyarea(info, region);
318 324
@@ -329,6 +335,9 @@ void nvidiafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
329 struct nvidia_par *par = info->par; 335 struct nvidia_par *par = info->par;
330 u32 color; 336 u32 color;
331 337
338 if (info->state != FBINFO_STATE_RUNNING)
339 return;
340
332 if (par->lockup) 341 if (par->lockup)
333 return cfb_fillrect(info, rect); 342 return cfb_fillrect(info, rect);
334 343
@@ -412,6 +421,9 @@ void nvidiafb_imageblit(struct fb_info *info, const struct fb_image *image)
412{ 421{
413 struct nvidia_par *par = info->par; 422 struct nvidia_par *par = info->par;
414 423
424 if (info->state != FBINFO_STATE_RUNNING)
425 return;
426
415 if (image->depth == 1 && !par->lockup) 427 if (image->depth == 1 && !par->lockup)
416 nvidiafb_mono_color_expand(info, image); 428 nvidiafb_mono_color_expand(info, image);
417 else 429 else
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index e4a5b1da71c4..acdc26693402 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -129,6 +129,7 @@ struct nvidia_par {
129 int fpHeight; 129 int fpHeight;
130 int PanelTweak; 130 int PanelTweak;
131 int paneltweak; 131 int paneltweak;
132 int pm_state;
132 u32 crtcSync_read; 133 u32 crtcSync_read;
133 u32 fpSyncs; 134 u32 fpSyncs;
134 u32 dmaPut; 135 u32 dmaPut;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index a7c4e5e8ead6..c758b386f146 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -21,6 +21,7 @@
21#include <linux/fb.h> 21#include <linux/fb.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/console.h>
24#ifdef CONFIG_MTRR 25#ifdef CONFIG_MTRR
25#include <asm/mtrr.h> 26#include <asm/mtrr.h>
26#endif 27#endif
@@ -615,6 +616,30 @@ static int nvidia_panel_tweak(struct nvidia_par *par,
615 return tweak; 616 return tweak;
616} 617}
617 618
619static void nvidia_vga_protect(struct nvidia_par *par, int on)
620{
621 unsigned char tmp;
622
623 if (on) {
624 /*
625 * Turn off screen and disable sequencer.
626 */
627 tmp = NVReadSeq(par, 0x01);
628
629 NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
630 NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
631 } else {
632 /*
633 * Reenable sequencer, then turn on screen.
634 */
635
636 tmp = NVReadSeq(par, 0x01);
637
638 NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
639 NVWriteSeq(par, 0x00, 0x03); /* End Reset */
640 }
641}
642
618static void nvidia_save_vga(struct nvidia_par *par, 643static void nvidia_save_vga(struct nvidia_par *par,
619 struct _riva_hw_state *state) 644 struct _riva_hw_state *state)
620{ 645{
@@ -643,9 +668,9 @@ static void nvidia_save_vga(struct nvidia_par *par,
643 668
644#undef DUMP_REG 669#undef DUMP_REG
645 670
646static void nvidia_write_regs(struct nvidia_par *par) 671static void nvidia_write_regs(struct nvidia_par *par,
672 struct _riva_hw_state *state)
647{ 673{
648 struct _riva_hw_state *state = &par->ModeReg;
649 int i; 674 int i;
650 675
651 NVTRACE_ENTER(); 676 NVTRACE_ENTER();
@@ -694,32 +719,6 @@ static void nvidia_write_regs(struct nvidia_par *par)
694 NVTRACE_LEAVE(); 719 NVTRACE_LEAVE();
695} 720}
696 721
697static void nvidia_vga_protect(struct nvidia_par *par, int on)
698{
699 unsigned char tmp;
700
701 if (on) {
702 /*
703 * Turn off screen and disable sequencer.
704 */
705 tmp = NVReadSeq(par, 0x01);
706
707 NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
708 NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
709 } else {
710 /*
711 * Reenable sequencer, then turn on screen.
712 */
713
714 tmp = NVReadSeq(par, 0x01);
715
716 NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
717 NVWriteSeq(par, 0x00, 0x03); /* End Reset */
718 }
719}
720
721
722
723static int nvidia_calc_regs(struct fb_info *info) 722static int nvidia_calc_regs(struct fb_info *info)
724{ 723{
725 struct nvidia_par *par = info->par; 724 struct nvidia_par *par = info->par;
@@ -1068,7 +1067,8 @@ static int nvidiafb_set_par(struct fb_info *info)
1068 1067
1069 nvidia_vga_protect(par, 1); 1068 nvidia_vga_protect(par, 1);
1070 1069
1071 nvidia_write_regs(par); 1070 nvidia_write_regs(par, &par->ModeReg);
1071 NVSetStartAddress(par, 0);
1072 1072
1073#if defined (__BIG_ENDIAN) 1073#if defined (__BIG_ENDIAN)
1074 /* turn on LFB swapping */ 1074 /* turn on LFB swapping */
@@ -1377,6 +1377,57 @@ static struct fb_ops nvidia_fb_ops = {
1377 .fb_sync = nvidiafb_sync, 1377 .fb_sync = nvidiafb_sync,
1378}; 1378};
1379 1379
1380#ifdef CONFIG_PM
1381static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t state)
1382{
1383 struct fb_info *info = pci_get_drvdata(dev);
1384 struct nvidia_par *par = info->par;
1385
1386 acquire_console_sem();
1387 par->pm_state = state.event;
1388
1389 if (state.event == PM_EVENT_FREEZE) {
1390 dev->dev.power.power_state = state;
1391 } else {
1392 fb_set_suspend(info, 1);
1393 nvidiafb_blank(FB_BLANK_POWERDOWN, info);
1394 nvidia_write_regs(par, &par->SavedReg);
1395 pci_save_state(dev);
1396 pci_disable_device(dev);
1397 pci_set_power_state(dev, pci_choose_state(dev, state));
1398 }
1399
1400 release_console_sem();
1401 return 0;
1402}
1403
1404static int nvidiafb_resume(struct pci_dev *dev)
1405{
1406 struct fb_info *info = pci_get_drvdata(dev);
1407 struct nvidia_par *par = info->par;
1408
1409 acquire_console_sem();
1410 pci_set_power_state(dev, PCI_D0);
1411
1412 if (par->pm_state != PM_EVENT_FREEZE) {
1413 pci_restore_state(dev);
1414 pci_enable_device(dev);
1415 pci_set_master(dev);
1416 }
1417
1418 par->pm_state = PM_EVENT_ON;
1419 nvidiafb_set_par(info);
1420 fb_set_suspend (info, 0);
1421 nvidiafb_blank(FB_BLANK_UNBLANK, info);
1422
1423 release_console_sem();
1424 return 0;
1425}
1426#else
1427#define nvidiafb_suspend NULL
1428#define nvidiafb_resume NULL
1429#endif
1430
1380static int __devinit nvidia_set_fbinfo(struct fb_info *info) 1431static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1381{ 1432{
1382 struct fb_monspecs *specs = &info->monspecs; 1433 struct fb_monspecs *specs = &info->monspecs;
@@ -1798,8 +1849,10 @@ static int __devinit nvidiafb_setup(char *options)
1798static struct pci_driver nvidiafb_driver = { 1849static struct pci_driver nvidiafb_driver = {
1799 .name = "nvidiafb", 1850 .name = "nvidiafb",
1800 .id_table = nvidiafb_pci_tbl, 1851 .id_table = nvidiafb_pci_tbl,
1801 .probe = nvidiafb_probe, 1852 .probe = nvidiafb_probe,
1802 .remove = __exit_p(nvidiafb_remove), 1853 .suspend = nvidiafb_suspend,
1854 .resume = nvidiafb_resume,
1855 .remove = __exit_p(nvidiafb_remove),
1803}; 1856};
1804 1857
1805/* ------------------------------------------------------------------------- * 1858/* ------------------------------------------------------------------------- *