aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2008-02-06 04:39:18 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-06 13:41:16 -0500
commit74f482cca5f76643e7f323e66cc38b1a882d5e6f (patch)
tree7b547bb4b139aa04983079359d4594b45a023af4
parent2e9750272cd49732293b6fe771ae110be8d87273 (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.c22
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;