Subversion Repositories Kolibri OS

Rev

Rev 5060 | Rev 6084 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5060 Rev 5354
Line 35... Line 35...
35
#include 
35
#include 
36
#include "intel_drv.h"
36
#include "intel_drv.h"
37
#include 
37
#include 
38
#include "i915_drv.h"
38
#include "i915_drv.h"
Line -... Line 39...
-
 
39
 
-
 
40
static bool
-
 
41
format_is_yuv(uint32_t format)
-
 
42
{
-
 
43
	switch (format) {
-
 
44
	case DRM_FORMAT_YUYV:
-
 
45
	case DRM_FORMAT_UYVY:
-
 
46
	case DRM_FORMAT_VYUY:
-
 
47
	case DRM_FORMAT_YVYU:
-
 
48
		return true;
-
 
49
	default:
-
 
50
		return false;
-
 
51
	}
-
 
52
}
39
 
53
 
40
static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs)
54
static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs)
41
{
55
{
42
	/* paranoia */
56
	/* paranoia */
43
	if (!mode->crtc_htotal)
57
	if (!mode->crtc_htotal)
Line 44... Line 58...
44
		return 1;
58
		return 1;
45
 
59
 
Line -... Line 60...
-
 
60
	return DIV_ROUND_UP(usecs * mode->crtc_clock, 1000 * mode->crtc_htotal);
-
 
61
}
-
 
62
 
-
 
63
/**
-
 
64
 * intel_pipe_update_start() - start update of a set of display registers
-
 
65
 * @crtc: the crtc of which the registers are going to be updated
-
 
66
 * @start_vbl_count: vblank counter return pointer used for error checking
-
 
67
 *
-
 
68
 * Mark the start of an update to pipe registers that should be updated
-
 
69
 * atomically regarding vblank. If the next vblank will happens within
-
 
70
 * the next 100 us, this function waits until the vblank passes.
-
 
71
 *
-
 
72
 * After a successful call to this function, interrupts will be disabled
-
 
73
 * until a subsequent call to intel_pipe_update_end(). That is done to
-
 
74
 * avoid random delays. The value written to @start_vbl_count should be
-
 
75
 * supplied to intel_pipe_update_end() for error checking.
46
	return DIV_ROUND_UP(usecs * mode->crtc_clock, 1000 * mode->crtc_htotal);
76
 *
47
}
77
 * Return: true if the call was successful
48
 
78
 */
49
static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
79
bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
50
{
80
{
51
	struct drm_device *dev = crtc->base.dev;
81
	struct drm_device *dev = crtc->base.dev;
52
	const struct drm_display_mode *mode = &crtc->config.adjusted_mode;
82
	const struct drm_display_mode *mode = &crtc->config.adjusted_mode;
-
 
83
	enum pipe pipe = crtc->pipe;
53
	enum pipe pipe = crtc->pipe;
84
	long timeout = msecs_to_jiffies_timeout(1);
Line 54... Line -...
54
	long timeout = msecs_to_jiffies_timeout(1);
-
 
55
	int scanline, min, max, vblank_start;
-
 
56
	DEFINE_WAIT(wait);
85
	int scanline, min, max, vblank_start;
57
 
86
	wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
58
	WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex));
87
	DEFINE_WAIT(wait);
Line 59... Line 88...
59
 
88
 
Line 79... Line 108...
79
		/*
108
		/*
80
		 * prepare_to_wait() has a memory barrier, which guarantees
109
		 * prepare_to_wait() has a memory barrier, which guarantees
81
		 * other CPUs can see the task state update by the time we
110
		 * other CPUs can see the task state update by the time we
82
		 * read the scanline.
111
		 * read the scanline.
83
		 */
112
		 */
84
		prepare_to_wait(&crtc->vbl_wait, &wait, TASK_UNINTERRUPTIBLE);
113
		prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
Line 85... Line 114...
85
 
114
 
86
		scanline = intel_get_crtc_scanline(crtc);
115
		scanline = intel_get_crtc_scanline(crtc);
87
		if (scanline < min || scanline > max)
116
		if (scanline < min || scanline > max)
Line 98... Line 127...
98
        schedule_timeout(timeout);
127
        schedule_timeout(timeout);
99
        timeout = 0;
128
        timeout = 0;
100
//       local_irq_disable();
129
//       local_irq_disable();
101
	}
130
	}
Line 102... Line 131...
102
 
131
 
Line 103... Line 132...
103
	finish_wait(&crtc->vbl_wait, &wait);
132
	finish_wait(wq, &wait);
Line 104... Line 133...
104
 
133
 
Line 105... Line 134...
105
//   drm_vblank_put(dev, pipe);
134
//   drm_vblank_put(dev, pipe);
Line 106... Line 135...
106
 
135
 
107
	*start_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
136
	*start_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
Line -... Line 137...
-
 
137
 
-
 
138
//   trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count);
-
 
139
 
-
 
140
	return true;
-
 
141
}
-
 
142
 
-
 
143
/**
-
 
144
 * intel_pipe_update_end() - end update of a set of display registers
-
 
145
 * @crtc: the crtc of which the registers were updated
108
 
146
 * @start_vbl_count: start vblank counter (used for error checking)
109
//   trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count);
147
 *
110
 
148
 * Mark the end of an update started with intel_pipe_update_start(). This
111
	return true;
149
 * re-enables interrupts and verifies the update was actually completed
112
}
150
 * before a vblank using the value of @start_vbl_count.
Line 136... Line 174...
136
	else
174
	else
137
		I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
175
		I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
138
}
176
}
Line 139... Line 177...
139
 
177
 
-
 
178
static void
-
 
179
skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
-
 
180
		 struct drm_framebuffer *fb,
-
 
181
		 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
-
 
182
		 unsigned int crtc_w, unsigned int crtc_h,
-
 
183
		 uint32_t x, uint32_t y,
-
 
184
		 uint32_t src_w, uint32_t src_h)
-
 
185
{
-
 
186
	struct drm_device *dev = drm_plane->dev;
-
 
187
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
188
	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
-
 
189
	const int pipe = intel_plane->pipe;
-
 
190
	const int plane = intel_plane->plane + 1;
-
 
191
	u32 plane_ctl, stride;
-
 
192
	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
-
 
193
 
-
 
194
	plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
-
 
195
 
-
 
196
	/* Mask out pixel format bits in case we change it */
-
 
197
	plane_ctl &= ~PLANE_CTL_FORMAT_MASK;
-
 
198
	plane_ctl &= ~PLANE_CTL_ORDER_RGBX;
-
 
199
	plane_ctl &= ~PLANE_CTL_YUV422_ORDER_MASK;
-
 
200
	plane_ctl &= ~PLANE_CTL_TILED_MASK;
-
 
201
	plane_ctl &= ~PLANE_CTL_ALPHA_MASK;
-
 
202
	plane_ctl &= ~PLANE_CTL_ROTATE_MASK;
-
 
203
 
-
 
204
	/* Trickle feed has to be enabled */
-
 
205
	plane_ctl &= ~PLANE_CTL_TRICKLE_FEED_DISABLE;
-
 
206
 
-
 
207
	switch (fb->pixel_format) {
-
 
208
	case DRM_FORMAT_RGB565:
-
 
209
		plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
-
 
210
		break;
-
 
211
	case DRM_FORMAT_XBGR8888:
-
 
212
		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
-
 
213
		break;
-
 
214
	case DRM_FORMAT_XRGB8888:
-
 
215
		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
-
 
216
		break;
-
 
217
	/*
-
 
218
	 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
-
 
219
	 * to be already pre-multiplied. We need to add a knob (or a different
-
 
220
	 * DRM_FORMAT) for user-space to configure that.
-
 
221
	 */
-
 
222
	case DRM_FORMAT_ABGR8888:
-
 
223
		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
-
 
224
			     PLANE_CTL_ORDER_RGBX |
-
 
225
			     PLANE_CTL_ALPHA_SW_PREMULTIPLY;
-
 
226
		break;
-
 
227
	case DRM_FORMAT_ARGB8888:
-
 
228
		plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
-
 
229
			     PLANE_CTL_ALPHA_SW_PREMULTIPLY;
-
 
230
		break;
-
 
231
	case DRM_FORMAT_YUYV:
-
 
232
		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
-
 
233
		break;
-
 
234
	case DRM_FORMAT_YVYU:
-
 
235
		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
-
 
236
		break;
-
 
237
	case DRM_FORMAT_UYVY:
-
 
238
		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
-
 
239
		break;
-
 
240
	case DRM_FORMAT_VYUY:
-
 
241
		plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
-
 
242
		break;
-
 
243
	default:
-
 
244
		BUG();
-
 
245
	}
-
 
246
 
-
 
247
	switch (obj->tiling_mode) {
-
 
248
	case I915_TILING_NONE:
-
 
249
		stride = fb->pitches[0] >> 6;
-
 
250
		break;
-
 
251
	case I915_TILING_X:
-
 
252
		plane_ctl |= PLANE_CTL_TILED_X;
-
 
253
		stride = fb->pitches[0] >> 9;
-
 
254
		break;
-
 
255
	default:
-
 
256
		BUG();
-
 
257
	}
-
 
258
	if (intel_plane->rotation == BIT(DRM_ROTATE_180))
-
 
259
		plane_ctl |= PLANE_CTL_ROTATE_180;
-
 
260
 
-
 
261
	plane_ctl |= PLANE_CTL_ENABLE;
-
 
262
	plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
-
 
263
 
-
 
264
	intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h,
-
 
265
				       pixel_size, true,
-
 
266
				       src_w != crtc_w || src_h != crtc_h);
-
 
267
 
-
 
268
	/* Sizes are 0 based */
-
 
269
	src_w--;
-
 
270
	src_h--;
-
 
271
	crtc_w--;
-
 
272
	crtc_h--;
-
 
273
 
-
 
274
	I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x);
-
 
275
	I915_WRITE(PLANE_STRIDE(pipe, plane), stride);
-
 
276
	I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
-
 
277
	I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w);
-
 
278
	I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
-
 
279
	I915_WRITE(PLANE_SURF(pipe, plane), i915_gem_obj_ggtt_offset(obj));
-
 
280
	POSTING_READ(PLANE_SURF(pipe, plane));
-
 
281
}
-
 
282
 
-
 
283
static void
-
 
284
skl_disable_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc)
-
 
285
{
-
 
286
	struct drm_device *dev = drm_plane->dev;
-
 
287
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
288
	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
-
 
289
	const int pipe = intel_plane->pipe;
-
 
290
	const int plane = intel_plane->plane + 1;
-
 
291
 
-
 
292
	I915_WRITE(PLANE_CTL(pipe, plane),
-
 
293
		   I915_READ(PLANE_CTL(pipe, plane)) & ~PLANE_CTL_ENABLE);
-
 
294
 
-
 
295
	/* Activate double buffered register update */
-
 
296
	I915_WRITE(PLANE_CTL(pipe, plane), 0);
-
 
297
	POSTING_READ(PLANE_CTL(pipe, plane));
-
 
298
 
-
 
299
	intel_update_sprite_watermarks(drm_plane, crtc, 0, 0, 0, false, false);
-
 
300
}
-
 
301
 
-
 
302
static int
-
 
303
skl_update_colorkey(struct drm_plane *drm_plane,
-
 
304
		    struct drm_intel_sprite_colorkey *key)
-
 
305
{
-
 
306
	struct drm_device *dev = drm_plane->dev;
-
 
307
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
308
	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
-
 
309
	const int pipe = intel_plane->pipe;
-
 
310
	const int plane = intel_plane->plane;
-
 
311
	u32 plane_ctl;
-
 
312
 
-
 
313
	I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value);
-
 
314
	I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value);
-
 
315
	I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask);
-
 
316
 
-
 
317
	plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
-
 
318
	plane_ctl &= ~PLANE_CTL_KEY_ENABLE_MASK;
-
 
319
	if (key->flags & I915_SET_COLORKEY_DESTINATION)
-
 
320
		plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
-
 
321
	else if (key->flags & I915_SET_COLORKEY_SOURCE)
-
 
322
		plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
-
 
323
	I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
-
 
324
 
-
 
325
	POSTING_READ(PLANE_CTL(pipe, plane));
-
 
326
 
-
 
327
	return 0;
-
 
328
}
-
 
329
 
-
 
330
static void
-
 
331
skl_get_colorkey(struct drm_plane *drm_plane,
-
 
332
		 struct drm_intel_sprite_colorkey *key)
-
 
333
{
-
 
334
	struct drm_device *dev = drm_plane->dev;
-
 
335
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
336
	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
-
 
337
	const int pipe = intel_plane->pipe;
-
 
338
	const int plane = intel_plane->plane;
-
 
339
	u32 plane_ctl;
-
 
340
 
-
 
341
	key->min_value = I915_READ(PLANE_KEYVAL(pipe, plane));
-
 
342
	key->max_value = I915_READ(PLANE_KEYMAX(pipe, plane));
-
 
343
	key->channel_mask = I915_READ(PLANE_KEYMSK(pipe, plane));
-
 
344
 
-
 
345
	plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
-
 
346
 
-
 
347
	switch (plane_ctl & PLANE_CTL_KEY_ENABLE_MASK) {
-
 
348
	case PLANE_CTL_KEY_ENABLE_DESTINATION:
-
 
349
		key->flags = I915_SET_COLORKEY_DESTINATION;
-
 
350
		break;
-
 
351
	case PLANE_CTL_KEY_ENABLE_SOURCE:
-
 
352
		key->flags = I915_SET_COLORKEY_SOURCE;
-
 
353
		break;
-
 
354
	default:
-
 
355
		key->flags = I915_SET_COLORKEY_NONE;
-
 
356
	}
-
 
357
}
-
 
358
 
-
 
359
static void
-
 
360
chv_update_csc(struct intel_plane *intel_plane, uint32_t format)
-
 
361
{
-
 
362
	struct drm_i915_private *dev_priv = intel_plane->base.dev->dev_private;
-
 
363
	int plane = intel_plane->plane;
-
 
364
 
-
 
365
	/* Seems RGB data bypasses the CSC always */
-
 
366
	if (!format_is_yuv(format))
-
 
367
		return;
-
 
368
 
-
 
369
	/*
-
 
370
	 * BT.601 limited range YCbCr -> full range RGB
-
 
371
	 *
-
 
372
	 * |r|   | 6537 4769     0|   |cr  |
-
 
373
	 * |g| = |-3330 4769 -1605| x |y-64|
-
 
374
	 * |b|   |    0 4769  8263|   |cb  |
-
 
375
	 *
-
 
376
	 * Cb and Cr apparently come in as signed already, so no
-
 
377
	 * need for any offset. For Y we need to remove the offset.
-
 
378
	 */
-
 
379
	I915_WRITE(SPCSCYGOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(-64));
-
 
380
	I915_WRITE(SPCSCCBOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0));
-
 
381
	I915_WRITE(SPCSCCROFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0));
-
 
382
 
-
 
383
	I915_WRITE(SPCSCC01(plane), SPCSC_C1(4769) | SPCSC_C0(6537));
-
 
384
	I915_WRITE(SPCSCC23(plane), SPCSC_C1(-3330) | SPCSC_C0(0));
-
 
385
	I915_WRITE(SPCSCC45(plane), SPCSC_C1(-1605) | SPCSC_C0(4769));
-
 
386
	I915_WRITE(SPCSCC67(plane), SPCSC_C1(4769) | SPCSC_C0(0));
-
 
387
	I915_WRITE(SPCSCC8(plane), SPCSC_C0(8263));
-
 
388
 
-
 
389
	I915_WRITE(SPCSCYGICLAMP(plane), SPCSC_IMAX(940) | SPCSC_IMIN(64));
-
 
390
	I915_WRITE(SPCSCCBICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
-
 
391
	I915_WRITE(SPCSCCRICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
-
 
392
 
-
 
393
	I915_WRITE(SPCSCYGOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
-
 
394
	I915_WRITE(SPCSCCBOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
-
 
395
	I915_WRITE(SPCSCCROCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
-
 
396
}
-
 
397
 
140
static void
398
static void
141
vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
399
vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
142
		 struct drm_framebuffer *fb,
400
		 struct drm_framebuffer *fb,
143
		 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
401
		 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
144
		 unsigned int crtc_w, unsigned int crtc_h,
402
		 unsigned int crtc_w, unsigned int crtc_h,
Line 161... Line 419...
161
 
419
 
162
	/* Mask out pixel format bits in case we change it */
420
	/* Mask out pixel format bits in case we change it */
163
	sprctl &= ~SP_PIXFORMAT_MASK;
421
	sprctl &= ~SP_PIXFORMAT_MASK;
164
	sprctl &= ~SP_YUV_BYTE_ORDER_MASK;
422
	sprctl &= ~SP_YUV_BYTE_ORDER_MASK;
-
 
423
	sprctl &= ~SP_TILED;
Line 165... Line 424...
165
	sprctl &= ~SP_TILED;
424
	sprctl &= ~SP_ROTATE_180;
166
 
425
 
167
	switch (fb->pixel_format) {
426
	switch (fb->pixel_format) {
168
	case DRM_FORMAT_YUYV:
427
	case DRM_FORMAT_YUYV:
Line 233... Line 492...
233
							obj->tiling_mode,
492
							obj->tiling_mode,
234
							pixel_size,
493
							pixel_size,
235
							fb->pitches[0]);
494
							fb->pitches[0]);
236
	linear_offset -= sprsurf_offset;
495
	linear_offset -= sprsurf_offset;
Line -... Line 496...
-
 
496
 
-
 
497
	if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
-
 
498
		sprctl |= SP_ROTATE_180;
-
 
499
 
-
 
500
		x += src_w;
-
 
501
		y += src_h;
-
 
502
		linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
-
 
503
	}
237
 
504
 
Line 238... Line 505...
238
	atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
505
	atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
Line -... Line 506...
-
 
506
 
-
 
507
	intel_update_primary_plane(intel_crtc);
-
 
508
 
239
 
509
	if (IS_CHERRYVIEW(dev) && pipe == PIPE_B)
240
	intel_update_primary_plane(intel_crtc);
510
		chv_update_csc(intel_plane, fb->pixel_format);
Line 241... Line 511...
241
 
511
 
242
	I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
512
	I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
243
	I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
513
	I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
244
 
514
 
Line -... Line 515...
-
 
515
	if (obj->tiling_mode != I915_TILING_NONE)
-
 
516
		I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
245
	if (obj->tiling_mode != I915_TILING_NONE)
517
	else
246
		I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
518
		I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
247
	else
519
 
248
		I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
520
	I915_WRITE(SPCONSTALPHA(pipe, plane), 0);
Line 362... Line 634...
362
	/* Mask out pixel format bits in case we change it */
634
	/* Mask out pixel format bits in case we change it */
363
	sprctl &= ~SPRITE_PIXFORMAT_MASK;
635
	sprctl &= ~SPRITE_PIXFORMAT_MASK;
364
	sprctl &= ~SPRITE_RGB_ORDER_RGBX;
636
	sprctl &= ~SPRITE_RGB_ORDER_RGBX;
365
	sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
637
	sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
366
	sprctl &= ~SPRITE_TILED;
638
	sprctl &= ~SPRITE_TILED;
-
 
639
	sprctl &= ~SPRITE_ROTATE_180;
Line 367... Line 640...
367
 
640
 
368
	switch (fb->pixel_format) {
641
	switch (fb->pixel_format) {
369
	case DRM_FORMAT_XBGR8888:
642
	case DRM_FORMAT_XBGR8888:
370
		sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
643
		sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
Line 424... Line 697...
424
	sprsurf_offset =
697
	sprsurf_offset =
425
		intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
698
		intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
426
						 pixel_size, fb->pitches[0]);
699
						 pixel_size, fb->pitches[0]);
427
	linear_offset -= sprsurf_offset;
700
	linear_offset -= sprsurf_offset;
Line -... Line 701...
-
 
701
 
-
 
702
	if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
-
 
703
		sprctl |= SPRITE_ROTATE_180;
-
 
704
 
-
 
705
		/* HSW and BDW does this automagically in hardware */
-
 
706
		if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
-
 
707
			x += src_w;
-
 
708
			y += src_h;
-
 
709
			linear_offset += src_h * fb->pitches[0] +
-
 
710
				src_w * pixel_size;
-
 
711
		}
-
 
712
	}
428
 
713
 
Line 429... Line 714...
429
	atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
714
	atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
Line 430... Line 715...
430
 
715
 
Line 569... Line 854...
569
	/* Mask out pixel format bits in case we change it */
854
	/* Mask out pixel format bits in case we change it */
570
	dvscntr &= ~DVS_PIXFORMAT_MASK;
855
	dvscntr &= ~DVS_PIXFORMAT_MASK;
571
	dvscntr &= ~DVS_RGB_ORDER_XBGR;
856
	dvscntr &= ~DVS_RGB_ORDER_XBGR;
572
	dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
857
	dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
573
	dvscntr &= ~DVS_TILED;
858
	dvscntr &= ~DVS_TILED;
-
 
859
	dvscntr &= ~DVS_ROTATE_180;
Line 574... Line 860...
574
 
860
 
575
	switch (fb->pixel_format) {
861
	switch (fb->pixel_format) {
576
	case DRM_FORMAT_XBGR8888:
862
	case DRM_FORMAT_XBGR8888:
577
		dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
863
		dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
Line 626... Line 912...
626
	dvssurf_offset =
912
	dvssurf_offset =
627
		intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
913
		intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
628
						 pixel_size, fb->pitches[0]);
914
						 pixel_size, fb->pitches[0]);
629
	linear_offset -= dvssurf_offset;
915
	linear_offset -= dvssurf_offset;
Line -... Line 916...
-
 
916
 
-
 
917
	if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
-
 
918
		dvscntr |= DVS_ROTATE_180;
-
 
919
 
-
 
920
		x += src_w;
-
 
921
		y += src_h;
-
 
922
		linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
-
 
923
	}
630
 
924
 
Line 631... Line 925...
631
	atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
925
	atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
Line 632... Line 926...
632
 
926
 
Line 692... Line 986...
692
{
986
{
693
	struct drm_device *dev = crtc->dev;
987
	struct drm_device *dev = crtc->dev;
694
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
988
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Line 695... Line 989...
695
 
989
 
-
 
990
	/*
-
 
991
	 * BDW signals flip done immediately if the plane
-
 
992
	 * is disabled, even if the plane enable is already
-
 
993
	 * armed to occur at the next vblank :(
-
 
994
	 */
-
 
995
	if (IS_BROADWELL(dev))
-
 
996
		intel_wait_for_vblank(dev, intel_crtc->pipe);
-
 
997
 
696
	/*
998
	/*
697
	 * FIXME IPS should be fine as long as one plane is
999
	 * FIXME IPS should be fine as long as one plane is
698
	 * enabled, but in practice it seems to have problems
1000
	 * enabled, but in practice it seems to have problems
699
	 * when going from primary only to sprite only and vice
1001
	 * when going from primary only to sprite only and vice
700
	 * versa.
1002
	 * versa.
Line 779... Line 1081...
779
		key->flags = I915_SET_COLORKEY_SOURCE;
1081
		key->flags = I915_SET_COLORKEY_SOURCE;
780
	else
1082
	else
781
		key->flags = I915_SET_COLORKEY_NONE;
1083
		key->flags = I915_SET_COLORKEY_NONE;
782
}
1084
}
Line 783... Line -...
783
 
-
 
784
static bool
-
 
785
format_is_yuv(uint32_t format)
-
 
786
{
-
 
787
	switch (format) {
-
 
788
	case DRM_FORMAT_YUYV:
-
 
789
	case DRM_FORMAT_UYVY:
-
 
790
	case DRM_FORMAT_VYUY:
-
 
791
	case DRM_FORMAT_YVYU:
-
 
792
		return true;
-
 
793
	default:
-
 
794
		return false;
-
 
795
	}
-
 
796
}
-
 
797
 
1085
 
798
static bool colorkey_enabled(struct intel_plane *intel_plane)
1086
static bool colorkey_enabled(struct intel_plane *intel_plane)
799
{
1087
{
Line 800... Line 1088...
800
	struct drm_intel_sprite_colorkey key;
1088
	struct drm_intel_sprite_colorkey key;
Line 801... Line 1089...
801
 
1089
 
802
	intel_plane->get_colorkey(&intel_plane->base, &key);
1090
	intel_plane->get_colorkey(&intel_plane->base, &key);
Line 803... Line 1091...
803
 
1091
 
804
	return key.flags != I915_SET_COLORKEY_NONE;
1092
	return key.flags != I915_SET_COLORKEY_NONE;
805
}
-
 
806
 
-
 
807
static int
-
 
808
intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
1093
}
809
		   struct drm_framebuffer *fb, int crtc_x, int crtc_y,
1094
 
810
		   unsigned int crtc_w, unsigned int crtc_h,
-
 
811
		   uint32_t src_x, uint32_t src_y,
1095
static int
812
		   uint32_t src_w, uint32_t src_h)
1096
intel_check_sprite_plane(struct drm_plane *plane,
813
{
-
 
814
	struct drm_device *dev = plane->dev;
1097
			 struct intel_plane_state *state)
815
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1098
{
816
	struct intel_plane *intel_plane = to_intel_plane(plane);
-
 
817
	enum pipe pipe = intel_crtc->pipe;
-
 
818
	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-
 
819
	struct drm_i915_gem_object *obj = intel_fb->obj;
-
 
820
	struct drm_i915_gem_object *old_obj = intel_plane->obj;
-
 
821
	int ret;
-
 
822
	bool primary_enabled;
-
 
823
	bool visible;
-
 
824
	int hscale, vscale;
-
 
825
	int max_scale, min_scale;
-
 
826
	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
-
 
827
	struct drm_rect src = {
-
 
828
		/* sample coordinates in 16.16 fixed point */
-
 
829
		.x1 = src_x,
-
 
830
		.x2 = src_x + src_w,
-
 
831
		.y1 = src_y,
-
 
832
		.y2 = src_y + src_h,
-
 
833
	};
-
 
834
	struct drm_rect dst = {
-
 
835
		/* integer pixels */
-
 
836
		.x1 = crtc_x,
-
 
837
		.x2 = crtc_x + crtc_w,
-
 
838
		.y1 = crtc_y,
-
 
839
		.y2 = crtc_y + crtc_h,
-
 
840
	};
-
 
841
	const struct drm_rect clip = {
-
 
842
		.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
1099
	struct intel_crtc *intel_crtc = to_intel_crtc(state->crtc);
843
		.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
1100
	struct intel_plane *intel_plane = to_intel_plane(plane);
844
	};
1101
	struct drm_framebuffer *fb = state->fb;
845
	const struct {
-
 
846
		int crtc_x, crtc_y;
1102
	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
847
		unsigned int crtc_w, crtc_h;
1103
	int crtc_x, crtc_y;
848
		uint32_t src_x, src_y, src_w, src_h;
1104
	unsigned int crtc_w, crtc_h;
849
	} orig = {
1105
	uint32_t src_x, src_y, src_w, src_h;
850
		.crtc_x = crtc_x,
-
 
851
		.crtc_y = crtc_y,
1106
	struct drm_rect *src = &state->src;
852
		.crtc_w = crtc_w,
1107
	struct drm_rect *dst = &state->dst;
853
		.crtc_h = crtc_h,
1108
	struct drm_rect *orig_src = &state->orig_src;
854
		.src_x = src_x,
-
 
Line 855... Line 1109...
855
		.src_y = src_y,
1109
	const struct drm_rect *clip = &state->clip;
856
		.src_w = src_w,
1110
	int hscale, vscale;
857
		.src_h = src_h,
1111
	int max_scale, min_scale;
858
	};
1112
	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
Line 885... Line 1139...
885
	 * more strict checking should be done instead.
1139
	 * more strict checking should be done instead.
886
	 */
1140
	 */
887
	max_scale = intel_plane->max_downscale << 16;
1141
	max_scale = intel_plane->max_downscale << 16;
888
	min_scale = intel_plane->can_scale ? 1 : (1 << 16);
1142
	min_scale = intel_plane->can_scale ? 1 : (1 << 16);
Line -... Line 1143...
-
 
1143
 
-
 
1144
	drm_rect_rotate(src, fb->width << 16, fb->height << 16,
-
 
1145
			intel_plane->rotation);
889
 
1146
 
890
	hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale);
1147
	hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
Line 891... Line 1148...
891
	BUG_ON(hscale < 0);
1148
	BUG_ON(hscale < 0);
892
 
1149
 
Line 893... Line 1150...
893
	vscale = drm_rect_calc_vscale_relaxed(&src, &dst, min_scale, max_scale);
1150
	vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
Line 894... Line 1151...
894
	BUG_ON(vscale < 0);
1151
	BUG_ON(vscale < 0);
895
 
1152
 
896
	visible = drm_rect_clip_scaled(&src, &dst, &clip, hscale, vscale);
1153
	state->visible =  drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
897
 
1154
 
Line 898... Line 1155...
898
	crtc_x = dst.x1;
1155
	crtc_x = dst->x1;
899
	crtc_y = dst.y1;
1156
	crtc_y = dst->y1;
900
	crtc_w = drm_rect_width(&dst);
1157
	crtc_w = drm_rect_width(dst);
901
	crtc_h = drm_rect_height(&dst);
1158
	crtc_h = drm_rect_height(dst);
902
 
1159
 
903
	if (visible) {
1160
	if (state->visible) {
904
		/* check again in case clipping clamped the results */
1161
		/* check again in case clipping clamped the results */
Line 905... Line 1162...
905
		hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale);
1162
		hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
906
		if (hscale < 0) {
1163
		if (hscale < 0) {
Line 907... Line 1164...
907
			DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
1164
			DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
908
			drm_rect_debug_print(&src, true);
1165
			drm_rect_debug_print(src, true);
909
			drm_rect_debug_print(&dst, false);
1166
			drm_rect_debug_print(dst, false);
910
 
1167
 
911
			return hscale;
1168
			return hscale;
Line 912... Line 1169...
912
	}
1169
	}
913
 
1170
 
Line 914... Line 1171...
914
		vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale);
1171
		vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
915
		if (vscale < 0) {
1172
		if (vscale < 0) {
916
			DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
1173
			DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
917
			drm_rect_debug_print(&src, true);
1174
			drm_rect_debug_print(src, true);
-
 
1175
			drm_rect_debug_print(dst, false);
-
 
1176
 
-
 
1177
			return vscale;
Line 918... Line 1178...
918
			drm_rect_debug_print(&dst, false);
1178
	}
919
 
1179
 
920
			return vscale;
1180
		/* Make the source viewport size an exact multiple of the scaling factors. */
921
	}
1181
		drm_rect_adjust_size(src,
922
 
1182
				     drm_rect_width(dst) * hscale - drm_rect_width(src),
Line 923... Line 1183...
923
		/* Make the source viewport size an exact multiple of the scaling factors. */
1183
				     drm_rect_height(dst) * vscale - drm_rect_height(src));
924
		drm_rect_adjust_size(&src,
1184
 
925
				     drm_rect_width(&dst) * hscale - drm_rect_width(&src),
1185
		drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
926
				     drm_rect_height(&dst) * vscale - drm_rect_height(&src));
1186
				    intel_plane->rotation);
927
 
1187
 
928
		/* sanity check to make sure the src viewport wasn't enlarged */
1188
		/* sanity check to make sure the src viewport wasn't enlarged */
929
		WARN_ON(src.x1 < (int) src_x ||
1189
		WARN_ON(src->x1 < (int) orig_src->x1 ||
930
			src.y1 < (int) src_y ||
1190
			src->y1 < (int) orig_src->y1 ||
931
			src.x2 > (int) (src_x + src_w) ||
1191
			src->x2 > (int) orig_src->x2 ||
932
			src.y2 > (int) (src_y + src_h));
1192
			src->y2 > (int) orig_src->y2);
Line 933... Line 1193...
933
 
1193
 
934
	/*
1194
	/*
935
		 * Hardware doesn't handle subpixel coordinates.
1195
		 * Hardware doesn't handle subpixel coordinates.
Line 952... Line 1212...
952
	 */
1212
	 */
953
			if (!intel_plane->can_scale)
1213
			if (!intel_plane->can_scale)
954
				crtc_w &= ~1;
1214
				crtc_w &= ~1;
Line 955... Line 1215...
955
 
1215
 
956
			if (crtc_w == 0)
1216
			if (crtc_w == 0)
957
				visible = false;
1217
				state->visible = false;
958
		}
1218
		}
Line 959... Line 1219...
959
	}
1219
	}
960
 
1220
 
961
	/* Check size restrictions when scaling */
1221
	/* Check size restrictions when scaling */
Line 962... Line 1222...
962
	if (visible && (src_w != crtc_w || src_h != crtc_h)) {
1222
	if (state->visible && (src_w != crtc_w || src_h != crtc_h)) {
Line 963... Line 1223...
963
		unsigned int width_bytes;
1223
		unsigned int width_bytes;
Line 964... Line 1224...
964
 
1224
 
965
		WARN_ON(!intel_plane->can_scale);
1225
		WARN_ON(!intel_plane->can_scale);
Line 966... Line 1226...
966
 
1226
 
967
		/* FIXME interlacing min height is 6 */
1227
		/* FIXME interlacing min height is 6 */
Line 968... Line 1228...
968
 
1228
 
-
 
1229
		if (crtc_w < 3 || crtc_h < 3)
Line 969... Line 1230...
969
		if (crtc_w < 3 || crtc_h < 3)
1230
			state->visible = false;
970
			visible = false;
1231
 
971
 
1232
		if (src_w < 3 || src_h < 3)
972
		if (src_w < 3 || src_h < 3)
1233
			state->visible = false;
973
			visible = false;
1234
 
974
 
1235
		width_bytes = ((src_x * pixel_size) & 63) +
Line -... Line 1236...
-
 
1236
					src_w * pixel_size;
975
		width_bytes = ((src_x * pixel_size) & 63) + src_w * pixel_size;
1237
 
976
 
1238
		if (src_w > 2048 || src_h > 2048 ||
977
		if (src_w > 2048 || src_h > 2048 ||
1239
		    width_bytes > 4096 || fb->pitches[0] > 4096) {
978
		    width_bytes > 4096 || fb->pitches[0] > 4096) {
1240
			DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
-
 
1241
		return -EINVAL;
Line -... Line 1242...
-
 
1242
		}
-
 
1243
	}
-
 
1244
 
-
 
1245
	if (state->visible) {
-
 
1246
		src->x1 = src_x;
-
 
1247
		src->x2 = src_x + src_w;
979
			DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
1248
		src->y1 = src_y;
-
 
1249
		src->y2 = src_y + src_h;
-
 
1250
	}
980
		return -EINVAL;
1251
 
981
		}
1252
	dst->x1 = crtc_x;
982
	}
1253
	dst->x2 = crtc_x + crtc_w;
-
 
1254
	dst->y1 = crtc_y;
-
 
1255
	dst->y2 = crtc_y + crtc_h;
-
 
1256
 
983
 
1257
	return 0;
984
	dst.x1 = crtc_x;
1258
}
-
 
1259
 
-
 
1260
static int
-
 
1261
intel_prepare_sprite_plane(struct drm_plane *plane,
-
 
1262
			   struct intel_plane_state *state)
Line -... Line 1263...
-
 
1263
{
985
	dst.x2 = crtc_x + crtc_w;
1264
	struct drm_device *dev = plane->dev;
Line 986... Line 1265...
986
	dst.y1 = crtc_y;
1265
	struct drm_crtc *crtc = state->crtc;
987
	dst.y2 = crtc_y + crtc_h;
1266
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
988
 
1267
	struct intel_plane *intel_plane = to_intel_plane(plane);
989
	/*
1268
	enum pipe pipe = intel_crtc->pipe;
-
 
1269
	struct drm_framebuffer *fb = state->fb;
990
	 * If the sprite is completely covering the primary plane,
1270
	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
991
	 * we can disable the primary and save power.
1271
	struct drm_i915_gem_object *old_obj = intel_plane->obj;
992
	 */
1272
	int ret;
993
	primary_enabled = !drm_rect_equals(&dst, &clip) || colorkey_enabled(intel_plane);
1273
 
994
	WARN_ON(!primary_enabled && !visible && intel_crtc->active);
1274
	if (old_obj != obj) {
995
 
1275
	mutex_lock(&dev->struct_mutex);
996
	mutex_lock(&dev->struct_mutex);
-
 
997
 
1276
 
998
	/* Note that this will apply the VT-d workaround for scanouts,
1277
	/* Note that this will apply the VT-d workaround for scanouts,
-
 
1278
	 * which is more restrictive than required for sprites. (The
-
 
1279
	 * primary plane requires 256KiB alignment with 64 PTE padding,
-
 
1280
		 * the sprite planes only require 128KiB alignment and 32 PTE
-
 
1281
		 * padding.
-
 
1282
	 */
-
 
1283
		ret = intel_pin_and_fence_fb_obj(plane, fb, NULL);
-
 
1284
		if (ret == 0)
-
 
1285
	i915_gem_track_fb(old_obj, obj,
-
 
1286
			  INTEL_FRONTBUFFER_SPRITE(pipe));
-
 
1287
	mutex_unlock(&dev->struct_mutex);
-
 
1288
	if (ret)
-
 
1289
		return ret;
-
 
1290
	}
-
 
1291
 
-
 
1292
	return 0;
-
 
1293
}
-
 
1294
 
-
 
1295
static void
-
 
1296
intel_commit_sprite_plane(struct drm_plane *plane,
-
 
1297
			  struct intel_plane_state *state)
-
 
1298
{
-
 
1299
	struct drm_device *dev = plane->dev;
-
 
1300
	struct drm_crtc *crtc = state->crtc;
Line -... Line 1301...
-
 
1301
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
 
1302
	struct intel_plane *intel_plane = to_intel_plane(plane);
-
 
1303
	enum pipe pipe = intel_crtc->pipe;
-
 
1304
	struct drm_framebuffer *fb = state->fb;
-
 
1305
	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
-
 
1306
	struct drm_i915_gem_object *old_obj = intel_plane->obj;
-
 
1307
	int crtc_x, crtc_y;
999
	 * which is more restrictive than required for sprites. (The
1308
	unsigned int crtc_w, crtc_h;
1000
	 * primary plane requires 256KiB alignment with 64 PTE padding,
1309
	uint32_t src_x, src_y, src_w, src_h;
1001
	 * the sprite planes only require 128KiB alignment and 32 PTE padding.
1310
	struct drm_rect *dst = &state->dst;
1002
	 */
1311
	const struct drm_rect *clip = &state->clip;
1003
	ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
1312
	bool primary_enabled;
1004
 
1313
 
1005
	i915_gem_track_fb(old_obj, obj,
1314
	/*
1006
			  INTEL_FRONTBUFFER_SPRITE(pipe));
1315
	 * If the sprite is completely covering the primary plane,
1007
	mutex_unlock(&dev->struct_mutex);
1316
	 * we can disable the primary and save power.
Line 1008... Line 1317...
1008
 
1317
	 */
1009
	if (ret)
1318
	primary_enabled = !drm_rect_equals(dst, clip) || colorkey_enabled(intel_plane);
Line 1010... Line 1319...
1010
		return ret;
1319
	WARN_ON(!primary_enabled && !state->visible && intel_crtc->active);
Line 1011... Line 1320...
1011
 
1320
 
-
 
1321
	intel_plane->crtc_x = state->orig_dst.x1;
Line 1012... Line 1322...
1012
	intel_plane->crtc_x = orig.crtc_x;
1322
	intel_plane->crtc_y = state->orig_dst.y1;
1013
	intel_plane->crtc_y = orig.crtc_y;
1323
	intel_plane->crtc_w = drm_rect_width(&state->orig_dst);
Line 1014... Line 1324...
1014
	intel_plane->crtc_w = orig.crtc_w;
1324
	intel_plane->crtc_h = drm_rect_height(&state->orig_dst);
-
 
1325
	intel_plane->src_x = state->orig_src.x1;
-
 
1326
	intel_plane->src_y = state->orig_src.y1;
-
 
1327
	intel_plane->src_w = drm_rect_width(&state->orig_src);
-
 
1328
	intel_plane->src_h = drm_rect_height(&state->orig_src);
-
 
1329
	intel_plane->obj = obj;
-
 
1330
 
-
 
1331
	if (intel_crtc->active) {
-
 
1332
		bool primary_was_enabled = intel_crtc->primary_enabled;
1015
	intel_plane->crtc_h = orig.crtc_h;
1333
 
1016
	intel_plane->src_x = orig.src_x;
1334
		intel_crtc->primary_enabled = primary_enabled;
1017
	intel_plane->src_y = orig.src_y;
1335
 
1018
	intel_plane->src_w = orig.src_w;
1336
//       if (primary_was_enabled != primary_enabled)
1019
	intel_plane->src_h = orig.src_h;
1337
//           intel_crtc_wait_for_pending_flips(crtc);
-
 
1338
 
-
 
1339
		if (primary_was_enabled && !primary_enabled)
-
 
1340
			intel_pre_disable_primary(crtc);
-
 
1341
 
Line 1020... Line 1342...
1020
	intel_plane->obj = obj;
1342
		if (state->visible) {
1021
 
1343
			crtc_x = state->dst.x1;
1022
	if (intel_crtc->active) {
1344
			crtc_y = state->dst.y1;
Line 1023... Line 1345...
1023
		bool primary_was_enabled = intel_crtc->primary_enabled;
1345
			crtc_w = drm_rect_width(&state->dst);
1024
 
1346
			crtc_h = drm_rect_height(&state->dst);
-
 
1347
			src_x = state->src.x1;
1025
		intel_crtc->primary_enabled = primary_enabled;
1348
			src_y = state->src.y1;
1026
 
1349
			src_w = drm_rect_width(&state->src);
1027
//       if (primary_was_enabled != primary_enabled)
1350
			src_h = drm_rect_height(&state->src);
1028
 
1351
		intel_plane->update_plane(plane, crtc, fb, obj,
1029
		if (primary_was_enabled && !primary_enabled)
1352
					  crtc_x, crtc_y, crtc_w, crtc_h,
1030
			intel_pre_disable_primary(crtc);
1353
					  src_x, src_y, src_w, src_h);
1031
 
1354
		} else {
1032
	if (visible)
1355
		intel_plane->disable_plane(plane, crtc);
Line 1033... Line 1356...
1033
		intel_plane->update_plane(plane, crtc, fb, obj,
1356
		}
1034
					  crtc_x, crtc_y, crtc_w, crtc_h,
1357
 
1035
					  src_x, src_y, src_w, src_h);
1358
 
1036
	else
1359
		intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_SPRITE(pipe));
-
 
1360
 
Line -... Line 1361...
-
 
1361
		if (!primary_was_enabled && primary_enabled)
-
 
1362
			intel_post_enable_primary(crtc);
-
 
1363
	}
-
 
1364
 
-
 
1365
	/* Unpin old obj after new one is active to avoid ugliness */
-
 
1366
	if (old_obj && old_obj != obj) {
-
 
1367
 
-
 
1368
		/*
-
 
1369
		 * It's fairly common to simply update the position of
-
 
1370
		 * an existing object.  In that case, we don't need to
-
 
1371
		 * wait for vblank to avoid ugliness, we only need to
-
 
1372
		 * do the pin & ref bookkeeping.
-
 
1373
		 */
-
 
1374
		if (intel_crtc->active)
-
 
1375
			intel_wait_for_vblank(dev, intel_crtc->pipe);
-
 
1376
 
-
 
1377
			mutex_lock(&dev->struct_mutex);
-
 
1378
		intel_unpin_fb_obj(old_obj);
-
 
1379
		mutex_unlock(&dev->struct_mutex);
-
 
1380
	}
-
 
1381
}
-
 
1382
 
-
 
1383
static int
-
 
1384
intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
-
 
1385
		   struct drm_framebuffer *fb, int crtc_x, int crtc_y,
-
 
1386
		   unsigned int crtc_w, unsigned int crtc_h,
-
 
1387
		   uint32_t src_x, uint32_t src_y,
-
 
1388
		   uint32_t src_w, uint32_t src_h)
-
 
1389
{
-
 
1390
	struct intel_plane_state state;
-
 
1391
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
 
1392
	int ret;
-
 
1393
 
-
 
1394
	state.crtc = crtc;
-
 
1395
	state.fb = fb;
-
 
1396
 
-
 
1397
	/* sample coordinates in 16.16 fixed point */
-
 
1398
	state.src.x1 = src_x;
-
 
1399
	state.src.x2 = src_x + src_w;
-
 
1400
	state.src.y1 = src_y;
-
 
1401
	state.src.y2 = src_y + src_h;
-
 
1402
 
1037
		intel_plane->disable_plane(plane, crtc);
1403
	/* integer pixels */
1038
 
1404
	state.dst.x1 = crtc_x;
Line 1039... Line 1405...
1039
		if (!primary_was_enabled && primary_enabled)
1405
	state.dst.x2 = crtc_x + crtc_w;
1040
			intel_post_enable_primary(crtc);
1406
	state.dst.y1 = crtc_y;
Line 1167... Line 1533...
1167
out_unlock:
1533
out_unlock:
1168
	drm_modeset_unlock_all(dev);
1534
	drm_modeset_unlock_all(dev);
1169
	return ret;
1535
	return ret;
1170
}
1536
}
Line -... Line 1537...
-
 
1537
 
-
 
1538
int intel_plane_set_property(struct drm_plane *plane,
-
 
1539
			     struct drm_property *prop,
-
 
1540
			     uint64_t val)
-
 
1541
{
-
 
1542
	struct drm_device *dev = plane->dev;
-
 
1543
	struct intel_plane *intel_plane = to_intel_plane(plane);
-
 
1544
	uint64_t old_val;
-
 
1545
	int ret = -ENOENT;
-
 
1546
 
-
 
1547
	if (prop == dev->mode_config.rotation_property) {
-
 
1548
		/* exactly one rotation angle please */
-
 
1549
		if (hweight32(val & 0xf) != 1)
-
 
1550
			return -EINVAL;
-
 
1551
 
-
 
1552
		if (intel_plane->rotation == val)
-
 
1553
			return 0;
-
 
1554
 
-
 
1555
		old_val = intel_plane->rotation;
-
 
1556
		intel_plane->rotation = val;
-
 
1557
		ret = intel_plane_restore(plane);
-
 
1558
		if (ret)
-
 
1559
			intel_plane->rotation = old_val;
-
 
1560
	}
-
 
1561
 
-
 
1562
	return ret;
-
 
1563
}
1171
 
1564
 
1172
void intel_plane_restore(struct drm_plane *plane)
1565
int intel_plane_restore(struct drm_plane *plane)
1173
{
1566
{
Line 1174... Line 1567...
1174
	struct intel_plane *intel_plane = to_intel_plane(plane);
1567
	struct intel_plane *intel_plane = to_intel_plane(plane);
1175
 
1568
 
Line 1176... Line 1569...
1176
	if (!plane->crtc || !plane->fb)
1569
	if (!plane->crtc || !plane->fb)
1177
		return;
1570
		return 0;
1178
 
1571
 
1179
	intel_update_plane(plane, plane->crtc, plane->fb,
1572
	return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
1180
			   intel_plane->crtc_x, intel_plane->crtc_y,
1573
			   intel_plane->crtc_x, intel_plane->crtc_y,
1181
			   intel_plane->crtc_w, intel_plane->crtc_h,
1574
			   intel_plane->crtc_w, intel_plane->crtc_h,
Line 1193... Line 1586...
1193
 
1586
 
1194
static const struct drm_plane_funcs intel_plane_funcs = {
1587
static const struct drm_plane_funcs intel_plane_funcs = {
1195
	.update_plane = intel_update_plane,
1588
	.update_plane = intel_update_plane,
1196
	.disable_plane = intel_disable_plane,
1589
	.disable_plane = intel_disable_plane,
-
 
1590
	.destroy = intel_destroy_plane,
1197
	.destroy = intel_destroy_plane,
1591
	.set_property = intel_plane_set_property,
Line 1198... Line 1592...
1198
};
1592
};
1199
 
1593
 
1200
static uint32_t ilk_plane_formats[] = {
1594
static uint32_t ilk_plane_formats[] = {
Line 1226... Line 1620...
1226
	DRM_FORMAT_YVYU,
1620
	DRM_FORMAT_YVYU,
1227
	DRM_FORMAT_UYVY,
1621
	DRM_FORMAT_UYVY,
1228
	DRM_FORMAT_VYUY,
1622
	DRM_FORMAT_VYUY,
1229
};
1623
};
Line -... Line 1624...
-
 
1624
 
-
 
1625
static uint32_t skl_plane_formats[] = {
-
 
1626
	DRM_FORMAT_RGB565,
-
 
1627
	DRM_FORMAT_ABGR8888,
-
 
1628
	DRM_FORMAT_ARGB8888,
-
 
1629
	DRM_FORMAT_XBGR8888,
-
 
1630
	DRM_FORMAT_XRGB8888,
-
 
1631
	DRM_FORMAT_YUYV,
-
 
1632
	DRM_FORMAT_YVYU,
-
 
1633
	DRM_FORMAT_UYVY,
-
 
1634
	DRM_FORMAT_VYUY,
-
 
1635
};
1230
 
1636
 
1231
int
1637
int
1232
intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
1638
intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
1233
{
1639
{
1234
	struct intel_plane *intel_plane;
1640
	struct intel_plane *intel_plane;
Line 1289... Line 1695...
1289
 
1695
 
1290
		plane_formats = snb_plane_formats;
1696
		plane_formats = snb_plane_formats;
1291
		num_plane_formats = ARRAY_SIZE(snb_plane_formats);
1697
		num_plane_formats = ARRAY_SIZE(snb_plane_formats);
1292
		}
1698
		}
-
 
1699
		break;
-
 
1700
	case 9:
-
 
1701
		/*
-
 
1702
		 * FIXME: Skylake planes can be scaled (with some restrictions),
-
 
1703
		 * but this is for another time.
-
 
1704
		 */
-
 
1705
		intel_plane->can_scale = false;
-
 
1706
		intel_plane->max_downscale = 1;
-
 
1707
		intel_plane->update_plane = skl_update_plane;
-
 
1708
		intel_plane->disable_plane = skl_disable_plane;
-
 
1709
		intel_plane->update_colorkey = skl_update_colorkey;
Line -... Line 1710...
-
 
1710
		intel_plane->get_colorkey = skl_get_colorkey;
-
 
1711
 
-
 
1712
		plane_formats = skl_plane_formats;
1293
		break;
1713
		num_plane_formats = ARRAY_SIZE(skl_plane_formats);
1294
 
1714
		break;
1295
	default:
1715
	default:
1296
		kfree(intel_plane);
1716
		kfree(intel_plane);
Line 1297... Line 1717...
1297
		return -ENODEV;
1717
		return -ENODEV;
1298
	}
1718
	}
-
 
1719
 
1299
 
1720
	intel_plane->pipe = pipe;
1300
	intel_plane->pipe = pipe;
1721
	intel_plane->plane = plane;
1301
	intel_plane->plane = plane;
1722
	intel_plane->rotation = BIT(DRM_ROTATE_0);
1302
	possible_crtcs = (1 << pipe);
1723
	possible_crtcs = (1 << pipe);
1303
	ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
1724
	ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs,
1304
			     &intel_plane_funcs,
1725
			     &intel_plane_funcs,
1305
			     plane_formats, num_plane_formats,
1726
			     plane_formats, num_plane_formats,
-
 
1727
				       DRM_PLANE_TYPE_OVERLAY);
-
 
1728
	if (ret) {
-
 
1729
		kfree(intel_plane);
-
 
1730
		goto out;
-
 
1731
	}
-
 
1732
 
-
 
1733
	if (!dev->mode_config.rotation_property)
-
 
1734
		dev->mode_config.rotation_property =
-
 
1735
			drm_mode_create_rotation_property(dev,
-
 
1736
							  BIT(DRM_ROTATE_0) |
-
 
1737
							  BIT(DRM_ROTATE_180));
-
 
1738
 
-
 
1739
	if (dev->mode_config.rotation_property)
Line -... Line 1740...
-
 
1740
		drm_object_attach_property(&intel_plane->base.base,
1306
			     false);
1741
					   dev->mode_config.rotation_property,
1307
	if (ret)
1742
					   intel_plane->rotation);