Rev 6660 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6660 | Rev 6937 | ||
---|---|---|---|
Line 116... | Line 116... | ||
116 | static int intelfb_alloc(struct drm_fb_helper *helper, |
116 | static int intelfb_alloc(struct drm_fb_helper *helper, |
117 | struct drm_fb_helper_surface_size *sizes) |
117 | struct drm_fb_helper_surface_size *sizes) |
118 | { |
118 | { |
119 | struct intel_fbdev *ifbdev = |
119 | struct intel_fbdev *ifbdev = |
120 | container_of(helper, struct intel_fbdev, helper); |
120 | container_of(helper, struct intel_fbdev, helper); |
121 | struct drm_framebuffer *fb; |
121 | struct drm_framebuffer *fb = NULL; |
122 | struct drm_device *dev = helper->dev; |
122 | struct drm_device *dev = helper->dev; |
123 | struct drm_i915_private *dev_priv = to_i915(dev); |
123 | struct drm_i915_private *dev_priv = to_i915(dev); |
124 | struct drm_mode_fb_cmd2 mode_cmd = {}; |
124 | struct drm_mode_fb_cmd2 mode_cmd = {}; |
125 | struct drm_i915_gem_object *obj = NULL; |
125 | struct drm_i915_gem_object *obj = NULL; |
126 | int size, ret; |
126 | int size, ret; |
Line 135... | Line 135... | ||
135 | mode_cmd.pitches[0] = ALIGN(mode_cmd.width * |
135 | mode_cmd.pitches[0] = ALIGN(mode_cmd.width * |
136 | DIV_ROUND_UP(sizes->surface_bpp, 8), 64); |
136 | DIV_ROUND_UP(sizes->surface_bpp, 8), 64); |
137 | mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, |
137 | mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, |
138 | sizes->surface_depth); |
138 | sizes->surface_depth); |
Line -... | Line 139... | ||
- | 139 | ||
- | 140 | mutex_lock(&dev->struct_mutex); |
|
139 | 141 | ||
140 | size = mode_cmd.pitches[0] * mode_cmd.height; |
142 | size = mode_cmd.pitches[0] * mode_cmd.height; |
Line 141... | Line 143... | ||
141 | size = PAGE_ALIGN(size); |
143 | size = PAGE_ALIGN(size); |
142 | 144 | ||
Line 153... | Line 155... | ||
153 | goto out; |
155 | goto out; |
154 | } |
156 | } |
Line 155... | Line 157... | ||
155 | 157 | ||
156 | fb = __intel_framebuffer_create(dev, &mode_cmd, obj); |
158 | fb = __intel_framebuffer_create(dev, &mode_cmd, obj); |
- | 159 | if (IS_ERR(fb)) { |
|
157 | if (IS_ERR(fb)) { |
160 | drm_gem_object_unreference(&obj->base); |
158 | ret = PTR_ERR(fb); |
161 | ret = PTR_ERR(fb); |
159 | goto out_unref; |
162 | goto out; |
Line 160... | Line -... | ||
160 | } |
- | |
161 | - | ||
162 | /* Flush everything out, we'll be doing GTT only from now on */ |
- | |
163 | ret = intel_pin_and_fence_fb_obj(NULL, fb, NULL, NULL, NULL); |
163 | } |
164 | if (ret) { |
- | |
165 | DRM_ERROR("failed to pin obj: %d\n", ret); |
- | |
Line 166... | Line 164... | ||
166 | goto out_fb; |
164 | |
Line 167... | Line 165... | ||
167 | } |
165 | mutex_unlock(&dev->struct_mutex); |
Line 168... | Line -... | ||
168 | - | ||
169 | ifbdev->fb = to_intel_framebuffer(fb); |
- | |
170 | - | ||
171 | return 0; |
- | |
172 | 166 | ||
- | 167 | ifbdev->fb = to_intel_framebuffer(fb); |
|
- | 168 | ||
- | 169 | return 0; |
|
173 | out_fb: |
170 | |
174 | drm_framebuffer_remove(fb); |
171 | out: |
Line 175... | Line 172... | ||
175 | out_unref: |
172 | mutex_unlock(&dev->struct_mutex); |
176 | drm_gem_object_unreference(&obj->base); |
173 | if (!IS_ERR_OR_NULL(fb)) |
Line 190... | Line 187... | ||
190 | struct drm_framebuffer *fb; |
187 | struct drm_framebuffer *fb; |
191 | struct drm_i915_gem_object *obj; |
188 | struct drm_i915_gem_object *obj; |
192 | int size, ret; |
189 | int size, ret; |
193 | bool prealloc = false; |
190 | bool prealloc = false; |
Line 194... | Line -... | ||
194 | - | ||
195 | mutex_lock(&dev->struct_mutex); |
- | |
196 | 191 | ||
197 | if (intel_fb && |
192 | if (intel_fb && |
198 | (sizes->fb_width > intel_fb->base.width || |
193 | (sizes->fb_width > intel_fb->base.width || |
199 | sizes->fb_height > intel_fb->base.height)) { |
194 | sizes->fb_height > intel_fb->base.height)) { |
200 | DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d)," |
195 | DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d)," |
Line 206... | Line 201... | ||
206 | } |
201 | } |
207 | if (!intel_fb || WARN_ON(!intel_fb->obj)) { |
202 | if (!intel_fb || WARN_ON(!intel_fb->obj)) { |
208 | DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n"); |
203 | DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n"); |
209 | ret = intelfb_alloc(helper, sizes); |
204 | ret = intelfb_alloc(helper, sizes); |
210 | if (ret) |
205 | if (ret) |
211 | goto out_unlock; |
206 | return ret; |
212 | intel_fb = ifbdev->fb; |
207 | intel_fb = ifbdev->fb; |
213 | } else { |
208 | } else { |
214 | DRM_DEBUG_KMS("re-using BIOS fb\n"); |
209 | DRM_DEBUG_KMS("re-using BIOS fb\n"); |
215 | prealloc = true; |
210 | prealloc = true; |
216 | sizes->fb_width = intel_fb->base.width; |
211 | sizes->fb_width = intel_fb->base.width; |
Line 218... | Line 213... | ||
218 | } |
213 | } |
Line 219... | Line 214... | ||
219 | 214 | ||
220 | obj = intel_fb->obj; |
215 | obj = intel_fb->obj; |
Line -... | Line 216... | ||
- | 216 | size = obj->base.size; |
|
- | 217 | ||
- | 218 | mutex_lock(&dev->struct_mutex); |
|
- | 219 | ||
- | 220 | /* Pin the GGTT vma for our access via info->screen_base. |
|
- | 221 | * This also validates that any existing fb inherited from the |
|
- | 222 | * BIOS is suitable for own access. |
|
- | 223 | */ |
|
- | 224 | ret = intel_pin_and_fence_fb_obj(NULL, &ifbdev->fb->base, NULL); |
|
- | 225 | if (ret) |
|
221 | size = obj->base.size; |
226 | goto out_unlock; |
222 | 227 | ||
- | 228 | info = drm_fb_helper_alloc_fbi(helper); |
|
223 | info = drm_fb_helper_alloc_fbi(helper); |
229 | if (IS_ERR(info)) { |
224 | if (IS_ERR(info)) { |
230 | DRM_ERROR("Failed to allocate fb_info\n"); |
225 | ret = PTR_ERR(info); |
231 | ret = PTR_ERR(info); |
Line 226... | Line 232... | ||
226 | goto out_unpin; |
232 | goto out_unpin; |
Line 264... | Line 270... | ||
264 | 270 | ||
265 | out_destroy_fbi: |
271 | out_destroy_fbi: |
266 | drm_fb_helper_release_fbi(helper); |
272 | drm_fb_helper_release_fbi(helper); |
267 | out_unpin: |
273 | out_unpin: |
268 | i915_gem_object_ggtt_unpin(obj); |
- | |
269 | drm_gem_object_unreference(&obj->base); |
274 | i915_gem_object_ggtt_unpin(obj); |
270 | out_unlock: |
275 | out_unlock: |
271 | mutex_unlock(&dev->struct_mutex); |
276 | mutex_unlock(&dev->struct_mutex); |
272 | return ret; |
277 | return ret; |
Line 503... | Line 508... | ||
503 | }; |
508 | }; |
Line 504... | Line 509... | ||
504 | 509 | ||
505 | static void intel_fbdev_destroy(struct drm_device *dev, |
510 | static void intel_fbdev_destroy(struct drm_device *dev, |
506 | struct intel_fbdev *ifbdev) |
511 | struct intel_fbdev *ifbdev) |
- | 512 | { |
|
- | 513 | /* We rely on the object-free to release the VMA pinning for |
|
- | 514 | * the info->screen_base mmaping. Leaking the VMA is simpler than |
|
- | 515 | * trying to rectify all the possible error paths leading here. |
|
Line 507... | Line 516... | ||
507 | { |
516 | */ |
508 | 517 | ||
Line 509... | Line 518... | ||
509 | drm_fb_helper_unregister_fbi(&ifbdev->helper); |
518 | drm_fb_helper_unregister_fbi(&ifbdev->helper); |
Line -... | Line 519... | ||
- | 519 | drm_fb_helper_release_fbi(&ifbdev->helper); |
|
510 | drm_fb_helper_release_fbi(&ifbdev->helper); |
520 | |
511 | 521 | drm_fb_helper_fini(&ifbdev->helper); |
|
512 | drm_fb_helper_fini(&ifbdev->helper); |
522 | |
- | 523 | if (ifbdev->fb) { |
|
Line 513... | Line 524... | ||
513 | 524 | drm_framebuffer_unregister_private(&ifbdev->fb->base); |
|
514 | drm_framebuffer_unregister_private(&ifbdev->fb->base); |
525 | drm_framebuffer_remove(&ifbdev->fb->base); |
515 | drm_framebuffer_remove(&ifbdev->fb->base); |
526 | } |
516 | } |
527 | } |