diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_fb.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_fb.c | 55 | 
1 files changed, 29 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 7b30b5c2c4e..981bdce3634 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -57,9 +57,10 @@ static struct fb_ops intelfb_ops = {  	.fb_debug_leave = drm_fb_helper_debug_leave,  }; -static int intelfb_create(struct intel_fbdev *ifbdev, +static int intelfb_create(struct drm_fb_helper *helper,  			  struct drm_fb_helper_surface_size *sizes)  { +	struct intel_fbdev *ifbdev = (struct intel_fbdev *)helper;  	struct drm_device *dev = ifbdev->helper.dev;  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct fb_info *info; @@ -83,7 +84,9 @@ static int intelfb_create(struct intel_fbdev *ifbdev,  	size = mode_cmd.pitches[0] * mode_cmd.height;  	size = ALIGN(size, PAGE_SIZE); -	obj = i915_gem_alloc_object(dev, size); +	obj = i915_gem_object_create_stolen(dev, size); +	if (obj == NULL) +		obj = i915_gem_alloc_object(dev, size);  	if (!obj) {  		DRM_ERROR("failed to allocate framebuffer\n");  		ret = -ENOMEM; @@ -133,14 +136,13 @@ static int intelfb_create(struct intel_fbdev *ifbdev,  		goto out_unpin;  	}  	info->apertures->ranges[0].base = dev->mode_config.fb_base; -	info->apertures->ranges[0].size = -		dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; +	info->apertures->ranges[0].size = dev_priv->gtt.mappable_end;  	info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset;  	info->fix.smem_len = size;  	info->screen_base = -		ioremap_wc(dev_priv->mm.gtt_base_addr + obj->gtt_offset, +		ioremap_wc(dev_priv->gtt.mappable_base + obj->gtt_offset,  			   size);  	if (!info->screen_base) {  		ret = -ENOSPC; @@ -153,6 +155,13 @@ static int intelfb_create(struct intel_fbdev *ifbdev,  	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);  	drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height); +	/* If the object is shmemfs backed, it will have given us zeroed pages. +	 * If the object is stolen however, it will be full of whatever +	 * garbage was left in there. +	 */ +	if (ifbdev->ifb.obj->stolen) +		memset_io(info->screen_base, 0, info->screen_size); +  	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */  	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", @@ -173,26 +182,10 @@ out:  	return ret;  } -static int intel_fb_find_or_create_single(struct drm_fb_helper *helper, -					  struct drm_fb_helper_surface_size *sizes) -{ -	struct intel_fbdev *ifbdev = (struct intel_fbdev *)helper; -	int new_fb = 0; -	int ret; - -	if (!helper->fb) { -		ret = intelfb_create(ifbdev, sizes); -		if (ret) -			return ret; -		new_fb = 1; -	} -	return new_fb; -} -  static struct drm_fb_helper_funcs intel_fb_helper_funcs = {  	.gamma_set = intel_crtc_fb_gamma_set,  	.gamma_get = intel_crtc_fb_gamma_get, -	.fb_probe = intel_fb_find_or_create_single, +	.fb_probe = intelfb_create,  };  static void intel_fbdev_destroy(struct drm_device *dev, @@ -212,6 +205,7 @@ static void intel_fbdev_destroy(struct drm_device *dev,  	drm_fb_helper_fini(&ifbdev->helper); +	drm_framebuffer_unregister_private(&ifb->base);  	drm_framebuffer_cleanup(&ifb->base);  	if (ifb->obj) {  		drm_gem_object_unreference_unlocked(&ifb->obj->base); @@ -241,10 +235,18 @@ int intel_fbdev_init(struct drm_device *dev)  	}  	drm_fb_helper_single_add_all_connectors(&ifbdev->helper); -	drm_fb_helper_initial_config(&ifbdev->helper, 32); +  	return 0;  } +void intel_fbdev_initial_config(struct drm_device *dev) +{ +	drm_i915_private_t *dev_priv = dev->dev_private; + +	/* Due to peculiar init order wrt to hpd handling this is separate. */ +	drm_fb_helper_initial_config(&dev_priv->fbdev->helper, 32); +} +  void intel_fbdev_fini(struct drm_device *dev)  {  	drm_i915_private_t *dev_priv = dev->dev_private; @@ -280,7 +282,7 @@ void intel_fb_restore_mode(struct drm_device *dev)  	struct drm_mode_config *config = &dev->mode_config;  	struct drm_plane *plane; -	mutex_lock(&dev->mode_config.mutex); +	drm_modeset_lock_all(dev);  	ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);  	if (ret) @@ -288,7 +290,8 @@ void intel_fb_restore_mode(struct drm_device *dev)  	/* Be sure to shut off any planes that may be active */  	list_for_each_entry(plane, &config->plane_list, head) -		plane->funcs->disable_plane(plane); +		if (plane->enabled) +			plane->funcs->disable_plane(plane); -	mutex_unlock(&dev->mode_config.mutex); +	drm_modeset_unlock_all(dev);  }  |