fb: nvidiafb: Try harder at initial mode setting.
PATCH 1/1 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=yCONFIG_FB_DDC=yCONFIG_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.
---
drivers/video/nvidia/nvidia.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
drivers/video/nvidia/nvidia.c +20 -2
@@ -849,9 +849,27 @@ static int nvidiafb_check_var(struct fb_var_screeninfo *var,if (!mode_valid && info->monspecs.modedb_len)return -EINVAL ; +/* +* If we're on a flat panel, check if the mode is outside of the +* panel dimensions. If so, cap it and try for the next best mode +* before bailing out. +*/ if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres || - par->fpHeight < var->yres)) -return -EINVAL ; + par->fpHeight < var->yres)) { +const struct fb_videomode *mode; + + var->xres = par->fpWidth; + var->yres = par->fpHeight; + + mode =fb_find_best_mode (var, &info->modelist); +if (!mode) { + printk(KERN_ERR PFX "mode out of range of flat " + "panel dimensions\n"); +return -EINVAL ; + } + +fb_videomode_to_var (var, mode); + }if (var->yres_virtual < var->yres) var->yres_virtual = var->yres;
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace