2007-08-26 19:17:30

by Michal Januszewski

[permalink] [raw]
Subject: Re: [Linux-fbdev-devel] [PATCH] fbdev: find mode with highest refresh rate in fb_find_mode()

On Wed, Jul 18, 2007 at 11:18:15PM +0800, Antonino A. Daplas wrote:

> > > Currently if the refresh rate is not specified fb_find_mode() returns
> > > the first known video mode with the requested resoluion, which provides
> > > no guarantees wrt the refresh rate. Change this so that the mode with
> > > the highest refresh rate is returned instead.
> >
> > What refresh rate it sets when used on card or monitor without DDC?
>
> Yes, I noted this also while reviewing patches. fb_find_mode() is used
> predominantly with the 'generic' modedb which contains modes that are
> not specific to the card or monitor. And fb_try_mode() is not a
> guarantee that the returned refresh rate will be safe (we have a lot of
> drivers that do not check the timings against the display capabilities).
>
> It would be best that fb_find_mode() return the safest refresh rate
> (60Hz) instead of the highest.

How about modifying it so that it looks for a mode with the highest
refresh rate if either a non-generic modedb is used or
info.monspecs.{vfmin,vfmax,hfmin,hfmax,dclkmax} are all non-zero,
and for a mode with refresh rate closest to 60 Hz otherwise?

I'm sorry for the delayed reply.

Best regards.
--
Michal Januszewski JID: [email protected]
Gentoo Linux Developer http://people.gentoo.org/spock


2007-08-26 22:50:29

by Antonino A. Daplas

[permalink] [raw]
Subject: Re: [Linux-fbdev-devel] [PATCH] fbdev: find mode with highest refresh rate in fb_find_mode()

On Sun, 2007-08-26 at 21:09 +0200, Michal Januszewski wrote:
> On Wed, Jul 18, 2007 at 11:18:15PM +0800, Antonino A. Daplas wrote:
>
> How about modifying it so that it looks for a mode with the highest
> refresh rate if either a non-generic modedb is used or
> info.monspecs.{vfmin,vfmax,hfmin,hfmax,dclkmax} are all non-zero,
> and for a mode with refresh rate closest to 60 Hz otherwise?

I would opt for combining the two, return the highest refresh rate only
if the modedb was built by the driver and with the mode checked against
the display's operating limits.

Tony


2007-08-29 22:51:18

by Michal Januszewski

[permalink] [raw]
Subject: [PATCH] fbdev: find mode with the highest/safest refresh rate in fb_find_mode()

Currently, if the refresh rate is not specified, fb_find_mode() returns
the first known video mode with the requested resolution, which provides
no guarantees wrt the refresh rate. Change this so that the mode with
the highest refresh rate is returned when the driver provides a custom
video mode database and the monitor limits, and a mode with the safe
60 Hz refresh rate otherwise.

Signed-off-by: Michal Januszewski <[email protected]>
---
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 3741ad7..9598c46 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -606,26 +606,43 @@ done:
DPRINTK("Trying specified video mode%s %ix%i\n",
refresh_specified ? "" : " (ignoring refresh rate)", xres, yres);

- diff = refresh;
+ if (!refresh_specified) {
+ /*
+ * If the caller has provided a custom mode database and a
+ * valid monspecs structure, we look for the mode with the
+ * highest refresh rate. Otherwise we play it safe it and
+ * try to find a mode with a refresh rate closest to the
+ * standard 60 Hz.
+ */
+ if (db != modedb &&
+ info->monspecs.vfmin && info->monspecs.vfmax &&
+ info->monspecs.hfmin && info->monspecs.hfmax &&
+ info->monspecs.dclkmax) {
+ refresh = 1000;
+ } else {
+ refresh = 60;
+ }
+ }
+
+ diff = -1;
best = -1;
for (i = 0; i < dbsize; i++) {
- if (name_matches(db[i], name, namelen) ||
- (res_specified && res_matches(db[i], xres, yres))) {
- if(!fb_try_mode(var, info, &db[i], bpp)) {
- if(!refresh_specified || db[i].refresh == refresh)
- return 1;
- else {
- if(diff > abs(db[i].refresh - refresh)) {
- diff = abs(db[i].refresh - refresh);
- best = i;
- }
+ if ((name_matches(db[i], name, namelen) ||
+ (res_specified && res_matches(db[i], xres, yres))) &&
+ !fb_try_mode(var, info, &db[i], bpp)) {
+ if (refresh_specified && db[i].refresh == refresh) {
+ return 1;
+ } else {
+ if (abs(db[i].refresh - refresh) < diff) {
+ diff = abs(db[i].refresh - refresh);
+ best = i;
}
}
}
}
if (best != -1) {
fb_try_mode(var, info, &db[best], bpp);
- return 2;
+ return (refresh_specified) ? 2 : 1;
}

diff = xres + yres;