From 7a07cd786dbd0111b9dd977e114438220cb4eee5 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Mon, 27 Mar 2006 01:17:22 -0800 Subject: [PATCH] nvidiafb: add suspend and resume hooks Add suspend and resume hooks to make software suspend more reliable. Resuming from standby should generally work. Resuming from mem and from disk requires that the GPU is disabled. Adding these to the suspend script... fbset -accel false -a /* suspend here */ fbset -accel true -a ... should generally work. In addition, resuming from mem requires that the video card has to be POSTed by the BIOS or some other utility. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/nvidia/nvidia.c | 115 ++++++++++++++++++++++++++++++------------ 1 file changed, 84 insertions(+), 31 deletions(-) (limited to 'drivers/video/nvidia/nvidia.c') diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index a7c4e5e8ead..c758b386f14 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef CONFIG_MTRR #include #endif @@ -615,6 +616,30 @@ static int nvidia_panel_tweak(struct nvidia_par *par, return tweak; } +static void nvidia_vga_protect(struct nvidia_par *par, int on) +{ + unsigned char tmp; + + if (on) { + /* + * Turn off screen and disable sequencer. + */ + tmp = NVReadSeq(par, 0x01); + + NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */ + NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */ + } else { + /* + * Reenable sequencer, then turn on screen. + */ + + tmp = NVReadSeq(par, 0x01); + + NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */ + NVWriteSeq(par, 0x00, 0x03); /* End Reset */ + } +} + static void nvidia_save_vga(struct nvidia_par *par, struct _riva_hw_state *state) { @@ -643,9 +668,9 @@ static void nvidia_save_vga(struct nvidia_par *par, #undef DUMP_REG -static void nvidia_write_regs(struct nvidia_par *par) +static void nvidia_write_regs(struct nvidia_par *par, + struct _riva_hw_state *state) { - struct _riva_hw_state *state = &par->ModeReg; int i; NVTRACE_ENTER(); @@ -694,32 +719,6 @@ static void nvidia_write_regs(struct nvidia_par *par) NVTRACE_LEAVE(); } -static void nvidia_vga_protect(struct nvidia_par *par, int on) -{ - unsigned char tmp; - - if (on) { - /* - * Turn off screen and disable sequencer. - */ - tmp = NVReadSeq(par, 0x01); - - NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */ - NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */ - } else { - /* - * Reenable sequencer, then turn on screen. - */ - - tmp = NVReadSeq(par, 0x01); - - NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */ - NVWriteSeq(par, 0x00, 0x03); /* End Reset */ - } -} - - - static int nvidia_calc_regs(struct fb_info *info) { struct nvidia_par *par = info->par; @@ -1068,7 +1067,8 @@ static int nvidiafb_set_par(struct fb_info *info) nvidia_vga_protect(par, 1); - nvidia_write_regs(par); + nvidia_write_regs(par, &par->ModeReg); + NVSetStartAddress(par, 0); #if defined (__BIG_ENDIAN) /* turn on LFB swapping */ @@ -1377,6 +1377,57 @@ static struct fb_ops nvidia_fb_ops = { .fb_sync = nvidiafb_sync, }; +#ifdef CONFIG_PM +static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t state) +{ + struct fb_info *info = pci_get_drvdata(dev); + struct nvidia_par *par = info->par; + + acquire_console_sem(); + par->pm_state = state.event; + + if (state.event == PM_EVENT_FREEZE) { + dev->dev.power.power_state = state; + } else { + fb_set_suspend(info, 1); + nvidiafb_blank(FB_BLANK_POWERDOWN, info); + nvidia_write_regs(par, &par->SavedReg); + pci_save_state(dev); + pci_disable_device(dev); + pci_set_power_state(dev, pci_choose_state(dev, state)); + } + + release_console_sem(); + return 0; +} + +static int nvidiafb_resume(struct pci_dev *dev) +{ + struct fb_info *info = pci_get_drvdata(dev); + struct nvidia_par *par = info->par; + + acquire_console_sem(); + pci_set_power_state(dev, PCI_D0); + + if (par->pm_state != PM_EVENT_FREEZE) { + pci_restore_state(dev); + pci_enable_device(dev); + pci_set_master(dev); + } + + par->pm_state = PM_EVENT_ON; + nvidiafb_set_par(info); + fb_set_suspend (info, 0); + nvidiafb_blank(FB_BLANK_UNBLANK, info); + + release_console_sem(); + return 0; +} +#else +#define nvidiafb_suspend NULL +#define nvidiafb_resume NULL +#endif + static int __devinit nvidia_set_fbinfo(struct fb_info *info) { struct fb_monspecs *specs = &info->monspecs; @@ -1798,8 +1849,10 @@ static int __devinit nvidiafb_setup(char *options) static struct pci_driver nvidiafb_driver = { .name = "nvidiafb", .id_table = nvidiafb_pci_tbl, - .probe = nvidiafb_probe, - .remove = __exit_p(nvidiafb_remove), + .probe = nvidiafb_probe, + .suspend = nvidiafb_suspend, + .resume = nvidiafb_resume, + .remove = __exit_p(nvidiafb_remove), }; /* ------------------------------------------------------------------------- * -- cgit v1.2.3 From 8ff7727d2a92f8b99cc709b827859da5d3c46a8a Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Mon, 27 Mar 2006 01:17:32 -0800 Subject: [PATCH] nvidiafb: Remove NULL check Remove unnecessary NULL check, as struct info will never be NULL. Coverity Bug 835 Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/nvidia/nvidia.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/video/nvidia/nvidia.c') diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index c758b386f14..018dd8174c7 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -1771,8 +1771,6 @@ static void __exit nvidiafb_remove(struct pci_dev *pd) struct nvidia_par *par = info->par; NVTRACE_ENTER(); - if (!info) - return; unregister_framebuffer(info); #ifdef CONFIG_MTRR -- cgit v1.2.3 From ed49843b897da9969e349c279ffc832efcb93213 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Mon, 27 Mar 2006 01:17:36 -0800 Subject: [PATCH] Add ID for Quadro NVS280 Quadro NVS280 is a dual-head PCIe card with PCI ID 10de:00fd and subsystem ID 10de:0215. Signed-off-by: Pavel Roskin Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/nvidia/nvidia.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/video/nvidia/nvidia.c') diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 018dd8174c7..6d3e4890cb4 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -297,6 +297,8 @@ static struct pci_device_id nvidiafb_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_QUADRO_NVS280, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_NVIDIA, 0x0252, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_NVIDIA, 0x0313, -- cgit v1.2.3