diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_fbdev.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_fbdev.c | 57 |
1 files changed, 38 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index b4d44e62f0c..088fe9378a4 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -132,6 +132,16 @@ static int intelfb_create(struct drm_fb_helper *helper, mutex_lock(&dev->struct_mutex); + if (intel_fb && + (sizes->fb_width > intel_fb->base.width || + sizes->fb_height > intel_fb->base.height)) { + DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d)," + " releasing it\n", + intel_fb->base.width, intel_fb->base.height, + sizes->fb_width, sizes->fb_height); + drm_framebuffer_unreference(&intel_fb->base); + intel_fb = ifbdev->fb = NULL; + } if (!intel_fb || WARN_ON(!intel_fb->obj)) { DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n"); ret = intelfb_alloc(helper, sizes); @@ -333,15 +343,15 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, num_connectors_detected++; if (!enabled[i]) { - DRM_DEBUG_KMS("connector %d not enabled, skipping\n", - connector->base.id); + DRM_DEBUG_KMS("connector %s not enabled, skipping\n", + connector->name); continue; } encoder = connector->encoder; if (!encoder || WARN_ON(!encoder->crtc)) { - DRM_DEBUG_KMS("connector %d has no encoder or crtc, skipping\n", - connector->base.id); + DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n", + connector->name); enabled[i] = false; continue; } @@ -363,20 +373,29 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, } } - DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n", - fb_conn->connector->base.id); + DRM_DEBUG_KMS("looking for cmdline mode on connector %s\n", + connector->name); /* go for command line mode first */ modes[i] = drm_pick_cmdline_mode(fb_conn, width, height); /* try for preferred next */ if (!modes[i]) { - DRM_DEBUG_KMS("looking for preferred mode on connector %d\n", - fb_conn->connector->base.id); + DRM_DEBUG_KMS("looking for preferred mode on connector %s\n", + connector->name); modes[i] = drm_has_preferred_mode(fb_conn, width, height); } + /* No preferred mode marked by the EDID? Are there any modes? */ + if (!modes[i] && !list_empty(&connector->modes)) { + DRM_DEBUG_KMS("using first mode listed on connector %s\n", + connector->name); + modes[i] = list_first_entry(&connector->modes, + struct drm_display_mode, + head); + } + /* last resort: use current mode */ if (!modes[i]) { /* @@ -390,16 +409,20 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, * since the fb helper layer wants a pointer to * something we own. */ + DRM_DEBUG_KMS("looking for current mode on connector %s\n", + connector->name); intel_mode_from_pipe_config(&encoder->crtc->hwmode, &to_intel_crtc(encoder->crtc)->config); modes[i] = &encoder->crtc->hwmode; } crtcs[i] = new_crtc; - DRM_DEBUG_KMS("connector %s on crtc %d: %s\n", - drm_get_connector_name(connector), + DRM_DEBUG_KMS("connector %s on pipe %d [CRTC:%d]: %dx%d%s\n", + connector->name, + pipe_name(to_intel_crtc(encoder->crtc)->pipe), encoder->crtc->base.id, - modes[i]->name); + modes[i]->hdisplay, modes[i]->vdisplay, + modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" :""); fallback = false; } @@ -478,7 +501,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, return false; /* Find the largest fb */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + for_each_crtc(dev, crtc) { intel_crtc = to_intel_crtc(crtc); if (!intel_crtc->active || !crtc->primary->fb) { @@ -502,7 +525,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, } /* Now make sure all the pipes will fit into it */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + for_each_crtc(dev, crtc) { unsigned int cur_size; intel_crtc = to_intel_crtc(crtc); @@ -567,7 +590,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, drm_framebuffer_reference(&ifbdev->fb->base); /* Final pass to check if any active pipes don't have fbs */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + for_each_crtc(dev, crtc) { intel_crtc = to_intel_crtc(crtc); if (!intel_crtc->active) @@ -673,11 +696,7 @@ void intel_fbdev_restore_mode(struct drm_device *dev) if (!dev_priv->fbdev) return; - drm_modeset_lock_all(dev); - - ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); + ret = drm_fb_helper_restore_fbdev_mode_unlocked(&dev_priv->fbdev->helper); if (ret) DRM_DEBUG("failed to restore crtc mode\n"); - - drm_modeset_unlock_all(dev); } |