+ if (!strictmode) {
+ if (!fb_validate_mode(var, info))
+ mode_valid = 1;
+ }
+
+ /* find best mode from modedb */
+ if (!mode_valid && specs->modedb_len) {
+ int i, best, best_refresh, best_x, best_y, diff_x, diff_y;
+
+ best_refresh = best = best_x = best_y = 0;
+ diff_x = diff_y = -1;
+
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (var->xres <= specs->modedb[i].xres &&
+ !(specs->modedb[i].flag & FB_MODE_IS_CALCULATED) &&
+ specs->modedb[i].xres - var->xres < diff_x) {
+ best_x = specs->modedb[i].xres;
+ diff_x = best_x - var->xres;
+ }
+ if (!diff_x) break;
+ }
+
+ if (diff_x != -1) {
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (best_x == specs->modedb[i].xres &&
+ var->yres <= specs->modedb[i].yres &&
+ !(specs->modedb[i].flag &
+ FB_MODE_IS_CALCULATED) &&
+ specs->modedb[i].yres-var->yres < diff_y) {
+ best_y = specs->modedb[i].yres;
+ diff_y = best_y - var->yres;
+ }
+ if (!diff_y) break;
+ }
+ }
+
+ if (diff_y != -1) {
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (best_x == specs->modedb[i].xres &&
+ best_y == specs->modedb[i].yres &&
+ !(specs->modedb[i].flag &
+ FB_MODE_IS_CALCULATED) &&
+ specs->modedb[i].refresh > best_refresh) {
+ best_refresh=specs->modedb[i].refresh;
+ best = i;
+ }
+ }
+ }
+
+ if (best_refresh) {
+ riva_update_var(var, &specs->modedb[best]);
+ mode_valid = 1;
+ }
+ }
+
+ /* calculate modeline if supported by monitor */
+ if (!mode_valid && info->monspecs.gtf) {
+ if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
+ mode_valid = 1;
+ }
+ if (!mode_valid && info->monspecs.modedb_len)
+ return -EINVAL;
+
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ if (var->yres_virtual <= var->yres)
+ var->yres_virtual = -1;