Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 74f482cc authored by Paul Mundt's avatar Paul Mundt Committed by Linus Torvalds
Browse files

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: default avatarPaul Mundt <lethal@linux-sh.org>
Cc: Antonino A. Daplas <adaplas@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 2e975027
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -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))
					      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;