diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index be491908..e0c85cef 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1110,13 +1110,17 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, /* We should be able to check here if the fb has the same properties * and then just flip_or_move it */ if (crtc->fb != fb) - changed = true; + flip_or_move = true; if (crtc_info->x != crtc->x || crtc_info->y != crtc->y) flip_or_move = true; - if (new_mode && !drm_mode_equal(new_mode, &crtc->mode)) + if (new_mode && !drm_mode_equal(new_mode, &crtc->mode)) { + DRM_DEBUG("modes are different\n"); + drm_mode_debug_printmodeline(dev, &crtc->mode); + drm_mode_debug_printmodeline(dev, new_mode); changed = true; + } list_for_each_entry(output, &dev->mode_config.output_list, head) { save_crtcs[count++] = output->crtc; @@ -1161,6 +1165,8 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, } drm_disable_unused_functions(dev); } else if (flip_or_move) { + if (crtc->fb != fb) + crtc->fb = fb; crtc->funcs->mode_set_base(crtc, crtc_info->x, crtc_info->y); } diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c index e33494c6..931bc1b6 100644 --- a/linux-core/intel_fb.c +++ b/linux-core/intel_fb.c @@ -228,6 +228,7 @@ static int intelfb_set_par(struct fb_info *info) struct drm_output *output = NULL; struct fb_var_screeninfo *var = &info->var; int found = 0; + int changed = 0; DRM_DEBUG("\n"); @@ -310,11 +311,22 @@ static int intelfb_set_par(struct fb_info *info) } /* re-attach fb */ - if (!par->crtc->fb) + if (!par->crtc->fb) { par->crtc->fb = par->fb; + changed = 1; + } - if (!drm_crtc_set_mode(par->crtc, drm_mode, var->xoffset, var->yoffset)) - return -EINVAL; + if (par->crtc->x != var->xoffset || par->crtc->y != var->yoffset) + changed = 1; + + drm_mode_debug_printmodeline(dev, drm_mode); + drm_mode_debug_printmodeline(dev, &par->crtc->mode); + if (!drm_mode_equal(drm_mode, &par->crtc->mode)) + changed = 1; + + if (changed) + if (!drm_crtc_set_mode(par->crtc, drm_mode, var->xoffset, var->yoffset)) + return -EINVAL; return 0; } @@ -469,16 +481,21 @@ static int intelfb_pan_display(struct fb_var_screeninfo *var, { struct intelfb_par *par = info->par; struct drm_crtc *crtc = par->crtc; - + int changed = 0; DRM_DEBUG("\n"); /* TODO add check size and pos*/ + if (par->crtc->x != var->xoffset || par->crtc->y != var->yoffset) + changed = 1; /* re-attach fb */ - if (!crtc->fb) + if (!crtc->fb) { crtc->fb = par->fb; + changed = 1; + } - drm_crtc_set_mode(crtc, &crtc->mode, var->xoffset, var->yoffset); + if (changed) + drm_crtc_set_mode(crtc, &crtc->mode, var->xoffset, var->yoffset); info->var.xoffset = var->xoffset; info->var.yoffset = var->yoffset;