diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_fbdev.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_fbdev.c | 72 | 
1 files changed, 28 insertions, 44 deletions
| diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 0c4cde6b2e6f..262e75c00dd2 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -232,7 +232,6 @@ static int intelfb_create(struct drm_fb_helper *helper,  	strcpy(info->fix.id, "inteldrmfb"); -	info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;  	info->fbops = &intelfb_ops;  	/* setup aperture base/size for vesafb takeover */ @@ -281,27 +280,6 @@ out_unlock:  	return ret;  } -/** Sets the color ramps on behalf of RandR */ -static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, -				    u16 blue, int regno) -{ -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - -	intel_crtc->lut_r[regno] = red >> 8; -	intel_crtc->lut_g[regno] = green >> 8; -	intel_crtc->lut_b[regno] = blue >> 8; -} - -static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, -				    u16 *blue, int regno) -{ -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - -	*red = intel_crtc->lut_r[regno] << 8; -	*green = intel_crtc->lut_g[regno] << 8; -	*blue = intel_crtc->lut_b[regno] << 8; -} -  static struct drm_fb_helper_crtc *  intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)  { @@ -352,14 +330,20 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,  	unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG);  	int i, j;  	bool *save_enabled; -	bool fallback = true; +	bool fallback = true, ret = true;  	int num_connectors_enabled = 0;  	int num_connectors_detected = 0; +	struct drm_modeset_acquire_ctx ctx;  	save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);  	if (!save_enabled)  		return false; +	drm_modeset_acquire_init(&ctx, 0); + +	while (drm_modeset_lock_all_ctx(fb_helper->dev, &ctx) != 0) +		drm_modeset_backoff(&ctx); +  	memcpy(save_enabled, enabled, count);  	mask = GENMASK(count - 1, 0);  	conn_configured = 0; @@ -370,7 +354,6 @@ retry:  		struct drm_connector *connector;  		struct drm_encoder *encoder;  		struct drm_fb_helper_crtc *new_crtc; -		struct intel_crtc *intel_crtc;  		fb_conn = fb_helper->connector_info[i];  		connector = fb_conn->connector; @@ -412,13 +395,6 @@ retry:  		num_connectors_enabled++; -		intel_crtc = to_intel_crtc(connector->state->crtc); -		for (j = 0; j < 256; j++) { -			intel_crtc->lut_r[j] = j; -			intel_crtc->lut_g[j] = j; -			intel_crtc->lut_b[j] = j; -		} -  		new_crtc = intel_fb_helper_crtc(fb_helper,  						connector->state->crtc); @@ -509,18 +485,18 @@ retry:  bail:  		DRM_DEBUG_KMS("Not using firmware configuration\n");  		memcpy(enabled, save_enabled, count); -		kfree(save_enabled); -		return false; +		ret = false;  	} +	drm_modeset_drop_locks(&ctx); +	drm_modeset_acquire_fini(&ctx); +  	kfree(save_enabled); -	return true; +	return ret;  }  static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {  	.initial_config = intel_fb_initial_config, -	.gamma_set = intel_crtc_fb_gamma_set, -	.gamma_get = intel_crtc_fb_gamma_get,  	.fb_probe = intelfb_create,  }; @@ -531,8 +507,6 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)  	 * trying to rectify all the possible error paths leading here.  	 */ -	drm_fb_helper_unregister_fbi(&ifbdev->helper); -  	drm_fb_helper_fini(&ifbdev->helper);  	if (ifbdev->vma) { @@ -720,8 +694,10 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)  	/* Due to peculiar init order wrt to hpd handling this is separate. */  	if (drm_fb_helper_initial_config(&ifbdev->helper, -					 ifbdev->preferred_bpp)) -		intel_fbdev_fini(ifbdev->helper.dev); +					 ifbdev->preferred_bpp)) { +		intel_fbdev_unregister(to_i915(ifbdev->helper.dev)); +		intel_fbdev_fini(to_i915(ifbdev->helper.dev)); +	}  }  void intel_fbdev_initial_config_async(struct drm_device *dev) @@ -744,9 +720,8 @@ static void intel_fbdev_sync(struct intel_fbdev *ifbdev)  	ifbdev->cookie = 0;  } -void intel_fbdev_fini(struct drm_device *dev) +void intel_fbdev_unregister(struct drm_i915_private *dev_priv)  { -	struct drm_i915_private *dev_priv = to_i915(dev);  	struct intel_fbdev *ifbdev = dev_priv->fbdev;  	if (!ifbdev) @@ -756,8 +731,17 @@ void intel_fbdev_fini(struct drm_device *dev)  	if (!current_is_async())  		intel_fbdev_sync(ifbdev); +	drm_fb_helper_unregister_fbi(&ifbdev->helper); +} + +void intel_fbdev_fini(struct drm_i915_private *dev_priv) +{ +	struct intel_fbdev *ifbdev = fetch_and_zero(&dev_priv->fbdev); + +	if (!ifbdev) +		return; +  	intel_fbdev_destroy(ifbdev); -	dev_priv->fbdev = NULL;  }  void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous) @@ -813,7 +797,7 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)  {  	struct intel_fbdev *ifbdev = to_i915(dev)->fbdev; -	if (ifbdev && ifbdev->vma) +	if (ifbdev)  		drm_fb_helper_hotplug_event(&ifbdev->helper);  } |