diff options
author | Paul Mundt <lethal@linux-sh.org> | 2008-02-06 04:39:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-06 13:41:16 -0500 |
commit | 74f482cca5f76643e7f323e66cc38b1a882d5e6f (patch) | |
tree | 7b547bb4b139aa04983079359d4594b45a023af4 | |
parent | 2e9750272cd49732293b6fe771ae110be8d87273 (diff) |
fb: nvidiafb: Try harder at initial mode setting.
The current nvidiafb_check_var() simply bails out if the selected mode is
out of range of the panel dimensions. A good question would be why the
bogus mode is being selected in the first place -- the panel dimensions
that are read back are certainly bogus, but alas, I have no idea where to
even begin looking at the i2c/EDID/DDC mess:
nvidiafb: Device ID: 10de0165
nvidiafb: CRTC0 analog not found
nvidiafb: CRTC1 analog not found
nvidiafb: EDID found from BUS1
nvidiafb: CRTC 0 is currently programmed for DFP
nvidiafb: Using DFP on CRTC 0
nvidiafb: Panel size is 1280 x 1024
nvidiafb: Panel is TMDS
nvidiafb: unable to setup MTRR
nvidiafb: Flat panel dithering disabled
nvidiafb: PCI nVidia NV16 framebuffer (64MB @ 0xC0000000)
In my .config I presently have:
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_DDC=y
CONFIG_FB_NVIDIA_I2C=y
I've not tried fiddling with these options, as I haven't the vaguest idea
what I should be looking at.
As a workaround, simply groveling for a new mode based on the probed
dimensions seems to work ok. While it would be nice to debug this further
and sort out why the panel information is bogus, I think it's still worth
retrying the mode based on the panel information at hand as a last-ditch
effort, rather than simply bailing out completely.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Cc: Antonino A. Daplas <adaplas@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/video/nvidia/nvidia.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 30e14eb1f51e..74517b1b26a6 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -849,9 +849,27 @@ static int nvidiafb_check_var(struct fb_var_screeninfo *var, | |||
849 | if (!mode_valid && info->monspecs.modedb_len) | 849 | if (!mode_valid && info->monspecs.modedb_len) |
850 | return -EINVAL; | 850 | return -EINVAL; |
851 | 851 | ||
852 | /* | ||
853 | * If we're on a flat panel, check if the mode is outside of the | ||
854 | * panel dimensions. If so, cap it and try for the next best mode | ||
855 | * before bailing out. | ||
856 | */ | ||
852 | if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres || | 857 | if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres || |
853 | par->fpHeight < var->yres)) | 858 | par->fpHeight < var->yres)) { |
854 | return -EINVAL; | 859 | const struct fb_videomode *mode; |
860 | |||
861 | var->xres = par->fpWidth; | ||
862 | var->yres = par->fpHeight; | ||
863 | |||
864 | mode = fb_find_best_mode(var, &info->modelist); | ||
865 | if (!mode) { | ||
866 | printk(KERN_ERR PFX "mode out of range of flat " | ||
867 | "panel dimensions\n"); | ||
868 | return -EINVAL; | ||
869 | } | ||
870 | |||
871 | fb_videomode_to_var(var, mode); | ||
872 | } | ||
855 | 873 | ||
856 | if (var->yres_virtual < var->yres) | 874 | if (var->yres_virtual < var->yres) |
857 | var->yres_virtual = var->yres; | 875 | var->yres_virtual = var->yres; |