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 b4d44e62f0c7..088fe9378a4c 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);  }  |