diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index fd4b4e268a22..078858178832 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -3119,6 +3119,27 @@ i915_gem_init_hws(struct drm_device *dev) | |||
3119 | return 0; | 3119 | return 0; |
3120 | } | 3120 | } |
3121 | 3121 | ||
3122 | static void | ||
3123 | i915_gem_cleanup_hws(struct drm_device *dev) | ||
3124 | { | ||
3125 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3126 | struct drm_gem_object *obj = dev_priv->hws_obj; | ||
3127 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
3128 | |||
3129 | if (dev_priv->hws_obj == NULL) | ||
3130 | return; | ||
3131 | |||
3132 | kunmap(obj_priv->page_list[0]); | ||
3133 | i915_gem_object_unpin(obj); | ||
3134 | drm_gem_object_unreference(obj); | ||
3135 | dev_priv->hws_obj = NULL; | ||
3136 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | ||
3137 | dev_priv->hw_status_page = NULL; | ||
3138 | |||
3139 | /* Write high address into HWS_PGA when disabling. */ | ||
3140 | I915_WRITE(HWS_PGA, 0x1ffff000); | ||
3141 | } | ||
3142 | |||
3122 | int | 3143 | int |
3123 | i915_gem_init_ringbuffer(struct drm_device *dev) | 3144 | i915_gem_init_ringbuffer(struct drm_device *dev) |
3124 | { | 3145 | { |
@@ -3136,6 +3157,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) | |||
3136 | obj = drm_gem_object_alloc(dev, 128 * 1024); | 3157 | obj = drm_gem_object_alloc(dev, 128 * 1024); |
3137 | if (obj == NULL) { | 3158 | if (obj == NULL) { |
3138 | DRM_ERROR("Failed to allocate ringbuffer\n"); | 3159 | DRM_ERROR("Failed to allocate ringbuffer\n"); |
3160 | i915_gem_cleanup_hws(dev); | ||
3139 | return -ENOMEM; | 3161 | return -ENOMEM; |
3140 | } | 3162 | } |
3141 | obj_priv = obj->driver_private; | 3163 | obj_priv = obj->driver_private; |
@@ -3143,6 +3165,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) | |||
3143 | ret = i915_gem_object_pin(obj, 4096); | 3165 | ret = i915_gem_object_pin(obj, 4096); |
3144 | if (ret != 0) { | 3166 | if (ret != 0) { |
3145 | drm_gem_object_unreference(obj); | 3167 | drm_gem_object_unreference(obj); |
3168 | i915_gem_cleanup_hws(dev); | ||
3146 | return ret; | 3169 | return ret; |
3147 | } | 3170 | } |
3148 | 3171 | ||
@@ -3162,6 +3185,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) | |||
3162 | memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); | 3185 | memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); |
3163 | i915_gem_object_unpin(obj); | 3186 | i915_gem_object_unpin(obj); |
3164 | drm_gem_object_unreference(obj); | 3187 | drm_gem_object_unreference(obj); |
3188 | i915_gem_cleanup_hws(dev); | ||
3165 | return -EINVAL; | 3189 | return -EINVAL; |
3166 | } | 3190 | } |
3167 | ring->ring_obj = obj; | 3191 | ring->ring_obj = obj; |
@@ -3241,20 +3265,7 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) | |||
3241 | dev_priv->ring.ring_obj = NULL; | 3265 | dev_priv->ring.ring_obj = NULL; |
3242 | memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); | 3266 | memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); |
3243 | 3267 | ||
3244 | if (dev_priv->hws_obj != NULL) { | 3268 | i915_gem_cleanup_hws(dev); |
3245 | struct drm_gem_object *obj = dev_priv->hws_obj; | ||
3246 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
3247 | |||
3248 | kunmap(obj_priv->page_list[0]); | ||
3249 | i915_gem_object_unpin(obj); | ||
3250 | drm_gem_object_unreference(obj); | ||
3251 | dev_priv->hws_obj = NULL; | ||
3252 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | ||
3253 | dev_priv->hw_status_page = NULL; | ||
3254 | |||
3255 | /* Write high address into HWS_PGA when disabling. */ | ||
3256 | I915_WRITE(HWS_PGA, 0x1ffff000); | ||
3257 | } | ||
3258 | } | 3269 | } |
3259 | 3270 | ||
3260 | int | 3271 | int |