Subversion Repositories Kolibri OS

Rev

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
}