Sat Oct 31 04:05:42 2020 UTC ()
Match linux here and wait without interrupts.

>From David H. Gutteridge in PR port-amd64/55555
There's a second part to the patch, but "make our code behave the way
the upstream code does" is very welcome.
Also PR kern/54515 and possibly others.


(maya)
diff -r1.10 -r1.11 src/sys/external/bsd/drm2/dist/drm/i915/intel_sprite.c

cvs diff -r1.10 -r1.11 src/sys/external/bsd/drm2/dist/drm/i915/Attic/intel_sprite.c (switch to unified diff)

--- src/sys/external/bsd/drm2/dist/drm/i915/Attic/intel_sprite.c 2020/02/14 04:36:12 1.10
+++ src/sys/external/bsd/drm2/dist/drm/i915/Attic/intel_sprite.c 2020/10/31 04:05:42 1.11
@@ -1,1126 +1,1126 @@ @@ -1,1126 +1,1126 @@
1/* $NetBSD: intel_sprite.c,v 1.10 2020/02/14 04:36:12 riastradh Exp $ */ 1/* $NetBSD: intel_sprite.c,v 1.11 2020/10/31 04:05:42 maya Exp $ */
2 2
3/* 3/*
4 * Copyright © 2011 Intel Corporation 4 * Copyright © 2011 Intel Corporation
5 * 5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a 6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"), 7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation 8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the 10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions: 11 * Software is furnished to do so, subject to the following conditions:
12 * 12 *
13 * The above copyright notice and this permission notice (including the next 13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the 14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software. 15 * Software.
16 * 16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE. 23 * SOFTWARE.
24 * 24 *
25 * Authors: 25 * Authors:
26 * Jesse Barnes <jbarnes@virtuousgeek.org> 26 * Jesse Barnes <jbarnes@virtuousgeek.org>
27 * 27 *
28 * New plane/sprite handling. 28 * New plane/sprite handling.
29 * 29 *
30 * The older chips had a separate interface for programming plane related 30 * The older chips had a separate interface for programming plane related
31 * registers; newer ones are much simpler and we can use the new DRM plane 31 * registers; newer ones are much simpler and we can use the new DRM plane
32 * support. 32 * support.
33 */ 33 */
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: intel_sprite.c,v 1.10 2020/02/14 04:36:12 riastradh Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: intel_sprite.c,v 1.11 2020/10/31 04:05:42 maya Exp $");
36 36
37#include <drm/drmP.h> 37#include <drm/drmP.h>
38#include <drm/drm_crtc.h> 38#include <drm/drm_crtc.h>
39#include <drm/drm_fourcc.h> 39#include <drm/drm_fourcc.h>
40#include <drm/drm_rect.h> 40#include <drm/drm_rect.h>
41#include <drm/drm_atomic.h> 41#include <drm/drm_atomic.h>
42#include <drm/drm_plane_helper.h> 42#include <drm/drm_plane_helper.h>
43#include "intel_drv.h" 43#include "intel_drv.h"
44#include <drm/i915_drm.h> 44#include <drm/i915_drm.h>
45#include "i915_drv.h" 45#include "i915_drv.h"
46#include "i915_trace.h" 46#include "i915_trace.h"
47 47
48static bool 48static bool
49format_is_yuv(uint32_t format) 49format_is_yuv(uint32_t format)
50{ 50{
51 switch (format) { 51 switch (format) {
52 case DRM_FORMAT_YUYV: 52 case DRM_FORMAT_YUYV:
53 case DRM_FORMAT_UYVY: 53 case DRM_FORMAT_UYVY:
54 case DRM_FORMAT_VYUY: 54 case DRM_FORMAT_VYUY:
55 case DRM_FORMAT_YVYU: 55 case DRM_FORMAT_YVYU:
56 return true; 56 return true;
57 default: 57 default:
58 return false; 58 return false;
59 } 59 }
60} 60}
61 61
62static int usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, 62static int usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
63 int usecs) 63 int usecs)
64{ 64{
65 /* paranoia */ 65 /* paranoia */
66 if (!adjusted_mode->crtc_htotal) 66 if (!adjusted_mode->crtc_htotal)
67 return 1; 67 return 1;
68 68
69 return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock, 69 return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
70 1000 * adjusted_mode->crtc_htotal); 70 1000 * adjusted_mode->crtc_htotal);
71} 71}
72 72
73/** 73/**
74 * intel_pipe_update_start() - start update of a set of display registers 74 * intel_pipe_update_start() - start update of a set of display registers
75 * @crtc: the crtc of which the registers are going to be updated 75 * @crtc: the crtc of which the registers are going to be updated
76 * @start_vbl_count: vblank counter return pointer used for error checking 76 * @start_vbl_count: vblank counter return pointer used for error checking
77 * 77 *
78 * Mark the start of an update to pipe registers that should be updated 78 * Mark the start of an update to pipe registers that should be updated
79 * atomically regarding vblank. If the next vblank will happens within 79 * atomically regarding vblank. If the next vblank will happens within
80 * the next 100 us, this function waits until the vblank passes. 80 * the next 100 us, this function waits until the vblank passes.
81 * 81 *
82 * After a successful call to this function, interrupts will be disabled 82 * After a successful call to this function, interrupts will be disabled
83 * until a subsequent call to intel_pipe_update_end(). That is done to 83 * until a subsequent call to intel_pipe_update_end(). That is done to
84 * avoid random delays. The value written to @start_vbl_count should be 84 * avoid random delays. The value written to @start_vbl_count should be
85 * supplied to intel_pipe_update_end() for error checking. 85 * supplied to intel_pipe_update_end() for error checking.
86 */ 86 */
87void intel_pipe_update_start(struct intel_crtc *crtc) 87void intel_pipe_update_start(struct intel_crtc *crtc)
88{ 88{
89 struct drm_device *dev = crtc->base.dev; 89 struct drm_device *dev = crtc->base.dev;
90 const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; 90 const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
91 enum pipe pipe = crtc->pipe; 91 enum pipe pipe = crtc->pipe;
92 long timeout = msecs_to_jiffies_timeout(1); 92 long timeout = msecs_to_jiffies_timeout(1);
93 int scanline, min, max, vblank_start; 93 int scanline, min, max, vblank_start;
94#ifdef __NetBSD__ 94#ifdef __NetBSD__
95 drm_waitqueue_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); 95 drm_waitqueue_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
96 int ret; 96 int ret;
97#else 97#else
98 wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); 98 wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
99 DEFINE_WAIT(wait); 99 DEFINE_WAIT(wait);
100#endif 100#endif
101 101
102 vblank_start = adjusted_mode->crtc_vblank_start; 102 vblank_start = adjusted_mode->crtc_vblank_start;
103 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) 103 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
104 vblank_start = DIV_ROUND_UP(vblank_start, 2); 104 vblank_start = DIV_ROUND_UP(vblank_start, 2);
105 105
106 /* FIXME needs to be calibrated sensibly */ 106 /* FIXME needs to be calibrated sensibly */
107 min = vblank_start - usecs_to_scanlines(adjusted_mode, 100); 107 min = vblank_start - usecs_to_scanlines(adjusted_mode, 100);
108 max = vblank_start - 1; 108 max = vblank_start - 1;
109 109
110#ifdef __NetBSD__ 110#ifdef __NetBSD__
111 spin_lock(&dev->vbl_lock); 111 spin_lock(&dev->vbl_lock);
112#else 112#else
113 local_irq_disable(); 113 local_irq_disable();
114#endif 114#endif
115 115
116 if (min <= 0 || max <= 0) 116 if (min <= 0 || max <= 0)
117 return; 117 return;
118 118
119 if (WARN_ON(drm_crtc_vblank_get_locked(&crtc->base))) 119 if (WARN_ON(drm_crtc_vblank_get_locked(&crtc->base)))
120 return; 120 return;
121 121
122 crtc->debug.min_vbl = min; 122 crtc->debug.min_vbl = min;
123 crtc->debug.max_vbl = max; 123 crtc->debug.max_vbl = max;
124 trace_i915_pipe_update_start(crtc); 124 trace_i915_pipe_update_start(crtc);
125 125
126#ifdef __NetBSD__ 126#ifdef __NetBSD__
127 DRM_SPIN_TIMED_WAIT_UNTIL(ret, wq, &dev->vbl_lock, timeout, 127 DRM_SPIN_TIMED_WAIT_NOINTR_UNTIL(ret, wq, &dev->vbl_lock, timeout,
128 (scanline = intel_get_crtc_scanline(crtc), 128 (scanline = intel_get_crtc_scanline(crtc),
129 scanline < min || scanline > max)); 129 scanline < min || scanline > max));
130 if (ret <= 0) 130 if (ret <= 0)
131 DRM_ERROR("Potential atomic update failure on pipe %c: %d\n", 131 DRM_ERROR("Potential atomic update failure on pipe %c: %d\n",
132 pipe_name(crtc->pipe), ret ? ret : -EWOULDBLOCK); 132 pipe_name(crtc->pipe), ret ? ret : -EWOULDBLOCK);
133 drm_crtc_vblank_put_locked(&crtc->base); 133 drm_crtc_vblank_put_locked(&crtc->base);
134#else 134#else
135 for (;;) { 135 for (;;) {
136 /* 136 /*
137 * prepare_to_wait() has a memory barrier, which guarantees 137 * prepare_to_wait() has a memory barrier, which guarantees
138 * other CPUs can see the task state update by the time we 138 * other CPUs can see the task state update by the time we
139 * read the scanline. 139 * read the scanline.
140 */ 140 */
141 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); 141 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
142 142
143 scanline = intel_get_crtc_scanline(crtc); 143 scanline = intel_get_crtc_scanline(crtc);
144 if (scanline < min || scanline > max) 144 if (scanline < min || scanline > max)
145 break; 145 break;
146 146
147 if (timeout <= 0) { 147 if (timeout <= 0) {
148 DRM_ERROR("Potential atomic update failure on pipe %c\n", 148 DRM_ERROR("Potential atomic update failure on pipe %c\n",
149 pipe_name(crtc->pipe)); 149 pipe_name(crtc->pipe));
150 break; 150 break;
151 } 151 }
152 152
153 local_irq_enable(); 153 local_irq_enable();
154 154
155 timeout = schedule_timeout(timeout); 155 timeout = schedule_timeout(timeout);
156 156
157 local_irq_disable(); 157 local_irq_disable();
158 } 158 }
159 159
160 finish_wait(wq, &wait); 160 finish_wait(wq, &wait);
161 161
162 drm_crtc_vblank_put(&crtc->base); 162 drm_crtc_vblank_put(&crtc->base);
163#endif 163#endif
164 164
165 crtc->debug.scanline_start = scanline; 165 crtc->debug.scanline_start = scanline;
166 crtc->debug.start_vbl_time = ktime_get(); 166 crtc->debug.start_vbl_time = ktime_get();
167 crtc->debug.start_vbl_count = 167 crtc->debug.start_vbl_count =
168 dev->driver->get_vblank_counter(dev, pipe); 168 dev->driver->get_vblank_counter(dev, pipe);
169 169
170 trace_i915_pipe_update_vblank_evaded(crtc); 170 trace_i915_pipe_update_vblank_evaded(crtc);
171} 171}
172 172
173/** 173/**
174 * intel_pipe_update_end() - end update of a set of display registers 174 * intel_pipe_update_end() - end update of a set of display registers
175 * @crtc: the crtc of which the registers were updated 175 * @crtc: the crtc of which the registers were updated
176 * @start_vbl_count: start vblank counter (used for error checking) 176 * @start_vbl_count: start vblank counter (used for error checking)
177 * 177 *
178 * Mark the end of an update started with intel_pipe_update_start(). This 178 * Mark the end of an update started with intel_pipe_update_start(). This
179 * re-enables interrupts and verifies the update was actually completed 179 * re-enables interrupts and verifies the update was actually completed
180 * before a vblank using the value of @start_vbl_count. 180 * before a vblank using the value of @start_vbl_count.
181 */ 181 */
182void intel_pipe_update_end(struct intel_crtc *crtc) 182void intel_pipe_update_end(struct intel_crtc *crtc)
183{ 183{
184 struct drm_device *dev = crtc->base.dev; 184 struct drm_device *dev = crtc->base.dev;
185 enum pipe pipe = crtc->pipe; 185 enum pipe pipe = crtc->pipe;
186 int scanline_end = intel_get_crtc_scanline(crtc); 186 int scanline_end = intel_get_crtc_scanline(crtc);
187 u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe); 187 u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
188 ktime_t end_vbl_time = ktime_get(); 188 ktime_t end_vbl_time = ktime_get();
189 189
190 trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end); 190 trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
191 191
192#ifdef __NetBSD__ 192#ifdef __NetBSD__
193 spin_unlock(&dev->vbl_lock); 193 spin_unlock(&dev->vbl_lock);
194#else 194#else
195 local_irq_enable(); 195 local_irq_enable();
196#endif 196#endif
197 197
198 if (crtc->debug.start_vbl_count && 198 if (crtc->debug.start_vbl_count &&
199 crtc->debug.start_vbl_count != end_vbl_count) { 199 crtc->debug.start_vbl_count != end_vbl_count) {
200 DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %"PRIdMAX" us, min %d, max %d, scanline start %d, end %d\n", 200 DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %"PRIdMAX" us, min %d, max %d, scanline start %d, end %d\n",
201 pipe_name(pipe), crtc->debug.start_vbl_count, 201 pipe_name(pipe), crtc->debug.start_vbl_count,
202 end_vbl_count, 202 end_vbl_count,
203 ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time), 203 ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
204 crtc->debug.min_vbl, crtc->debug.max_vbl, 204 crtc->debug.min_vbl, crtc->debug.max_vbl,
205 crtc->debug.scanline_start, scanline_end); 205 crtc->debug.scanline_start, scanline_end);
206 } 206 }
207} 207}
208 208
209static void 209static void
210skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, 210skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
211 struct drm_framebuffer *fb, 211 struct drm_framebuffer *fb,
212 int crtc_x, int crtc_y, 212 int crtc_x, int crtc_y,
213 unsigned int crtc_w, unsigned int crtc_h, 213 unsigned int crtc_w, unsigned int crtc_h,
214 uint32_t x, uint32_t y, 214 uint32_t x, uint32_t y,
215 uint32_t src_w, uint32_t src_h) 215 uint32_t src_w, uint32_t src_h)
216{ 216{
217 struct drm_device *dev = drm_plane->dev; 217 struct drm_device *dev = drm_plane->dev;
218 struct drm_i915_private *dev_priv = dev->dev_private; 218 struct drm_i915_private *dev_priv = dev->dev_private;
219 struct intel_plane *intel_plane = to_intel_plane(drm_plane); 219 struct intel_plane *intel_plane = to_intel_plane(drm_plane);
220 struct drm_i915_gem_object *obj = intel_fb_obj(fb); 220 struct drm_i915_gem_object *obj = intel_fb_obj(fb);
221 const int pipe = intel_plane->pipe; 221 const int pipe = intel_plane->pipe;
222 const int plane = intel_plane->plane + 1; 222 const int plane = intel_plane->plane + 1;
223 u32 plane_ctl, stride_div, stride; 223 u32 plane_ctl, stride_div, stride;
224 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 224 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
225 const struct drm_intel_sprite_colorkey *key = 225 const struct drm_intel_sprite_colorkey *key =
226 &to_intel_plane_state(drm_plane->state)->ckey; 226 &to_intel_plane_state(drm_plane->state)->ckey;
227 u32 surf_addr; 227 u32 surf_addr;
228 u32 tile_height, plane_offset, plane_size; 228 u32 tile_height, plane_offset, plane_size;
229 unsigned int rotation; 229 unsigned int rotation;
230 int x_offset, y_offset; 230 int x_offset, y_offset;
231 struct intel_crtc_state *crtc_state = to_intel_crtc(crtc)->config; 231 struct intel_crtc_state *crtc_state = to_intel_crtc(crtc)->config;
232 int scaler_id; 232 int scaler_id;
233 233
234 plane_ctl = PLANE_CTL_ENABLE | 234 plane_ctl = PLANE_CTL_ENABLE |
235 PLANE_CTL_PIPE_GAMMA_ENABLE | 235 PLANE_CTL_PIPE_GAMMA_ENABLE |
236 PLANE_CTL_PIPE_CSC_ENABLE; 236 PLANE_CTL_PIPE_CSC_ENABLE;
237 237
238 plane_ctl |= skl_plane_ctl_format(fb->pixel_format); 238 plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
239 plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]); 239 plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
240 240
241 rotation = drm_plane->state->rotation; 241 rotation = drm_plane->state->rotation;
242 plane_ctl |= skl_plane_ctl_rotation(rotation); 242 plane_ctl |= skl_plane_ctl_rotation(rotation);
243 243
244 intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h, 244 intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h,
245 pixel_size, true, 245 pixel_size, true,
246 src_w != crtc_w || src_h != crtc_h); 246 src_w != crtc_w || src_h != crtc_h);
247 247
248 stride_div = intel_fb_stride_alignment(dev, fb->modifier[0], 248 stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
249 fb->pixel_format); 249 fb->pixel_format);
250 250
251 scaler_id = to_intel_plane_state(drm_plane->state)->scaler_id; 251 scaler_id = to_intel_plane_state(drm_plane->state)->scaler_id;
252 252
253 /* Sizes are 0 based */ 253 /* Sizes are 0 based */
254 src_w--; 254 src_w--;
255 src_h--; 255 src_h--;
256 crtc_w--; 256 crtc_w--;
257 crtc_h--; 257 crtc_h--;
258 258
259 if (key->flags) { 259 if (key->flags) {
260 I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value); 260 I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value);
261 I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value); 261 I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value);
262 I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask); 262 I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask);
263 } 263 }
264 264
265 if (key->flags & I915_SET_COLORKEY_DESTINATION) 265 if (key->flags & I915_SET_COLORKEY_DESTINATION)
266 plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION; 266 plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
267 else if (key->flags & I915_SET_COLORKEY_SOURCE) 267 else if (key->flags & I915_SET_COLORKEY_SOURCE)
268 plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE; 268 plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
269 269
270 surf_addr = intel_plane_obj_offset(intel_plane, obj, 0); 270 surf_addr = intel_plane_obj_offset(intel_plane, obj, 0);
271 271
272 if (intel_rotation_90_or_270(rotation)) { 272 if (intel_rotation_90_or_270(rotation)) {
273 /* stride: Surface height in tiles */ 273 /* stride: Surface height in tiles */
274 tile_height = intel_tile_height(dev, fb->pixel_format, 274 tile_height = intel_tile_height(dev, fb->pixel_format,
275 fb->modifier[0], 0); 275 fb->modifier[0], 0);
276 stride = DIV_ROUND_UP(fb->height, tile_height); 276 stride = DIV_ROUND_UP(fb->height, tile_height);
277 plane_size = (src_w << 16) | src_h; 277 plane_size = (src_w << 16) | src_h;
278 x_offset = stride * tile_height - y - (src_h + 1); 278 x_offset = stride * tile_height - y - (src_h + 1);
279 y_offset = x; 279 y_offset = x;
280 } else { 280 } else {
281 stride = fb->pitches[0] / stride_div; 281 stride = fb->pitches[0] / stride_div;
282 plane_size = (src_h << 16) | src_w; 282 plane_size = (src_h << 16) | src_w;
283 x_offset = x; 283 x_offset = x;
284 y_offset = y; 284 y_offset = y;
285 } 285 }
286 plane_offset = y_offset << 16 | x_offset; 286 plane_offset = y_offset << 16 | x_offset;
287 287
288 I915_WRITE(PLANE_OFFSET(pipe, plane), plane_offset); 288 I915_WRITE(PLANE_OFFSET(pipe, plane), plane_offset);
289 I915_WRITE(PLANE_STRIDE(pipe, plane), stride); 289 I915_WRITE(PLANE_STRIDE(pipe, plane), stride);
290 I915_WRITE(PLANE_SIZE(pipe, plane), plane_size); 290 I915_WRITE(PLANE_SIZE(pipe, plane), plane_size);
291 291
292 /* program plane scaler */ 292 /* program plane scaler */
293 if (scaler_id >= 0) { 293 if (scaler_id >= 0) {
294 uint32_t ps_ctrl = 0; 294 uint32_t ps_ctrl = 0;
295 295
296 DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n", plane, 296 DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n", plane,
297 PS_PLANE_SEL(plane)); 297 PS_PLANE_SEL(plane));
298 ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane) | 298 ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane) |
299 crtc_state->scaler_state.scalers[scaler_id].mode; 299 crtc_state->scaler_state.scalers[scaler_id].mode;
300 I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl); 300 I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
301 I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0); 301 I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
302 I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y); 302 I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
303 I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), 303 I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id),
304 ((crtc_w + 1) << 16)|(crtc_h + 1)); 304 ((crtc_w + 1) << 16)|(crtc_h + 1));
305 305
306 I915_WRITE(PLANE_POS(pipe, plane), 0); 306 I915_WRITE(PLANE_POS(pipe, plane), 0);
307 } else { 307 } else {
308 I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x); 308 I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
309 } 309 }
310 310
311 I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl); 311 I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
312 I915_WRITE(PLANE_SURF(pipe, plane), surf_addr); 312 I915_WRITE(PLANE_SURF(pipe, plane), surf_addr);
313 POSTING_READ(PLANE_SURF(pipe, plane)); 313 POSTING_READ(PLANE_SURF(pipe, plane));
314} 314}
315 315
316static void 316static void
317skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) 317skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
318{ 318{
319 struct drm_device *dev = dplane->dev; 319 struct drm_device *dev = dplane->dev;
320 struct drm_i915_private *dev_priv = dev->dev_private; 320 struct drm_i915_private *dev_priv = dev->dev_private;
321 struct intel_plane *intel_plane = to_intel_plane(dplane); 321 struct intel_plane *intel_plane = to_intel_plane(dplane);
322 const int pipe = intel_plane->pipe; 322 const int pipe = intel_plane->pipe;
323 const int plane = intel_plane->plane + 1; 323 const int plane = intel_plane->plane + 1;
324 324
325 I915_WRITE(PLANE_CTL(pipe, plane), 0); 325 I915_WRITE(PLANE_CTL(pipe, plane), 0);
326 326
327 I915_WRITE(PLANE_SURF(pipe, plane), 0); 327 I915_WRITE(PLANE_SURF(pipe, plane), 0);
328 POSTING_READ(PLANE_SURF(pipe, plane)); 328 POSTING_READ(PLANE_SURF(pipe, plane));
329 329
330 intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false); 330 intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false);
331} 331}
332 332
333static void 333static void
334chv_update_csc(struct intel_plane *intel_plane, uint32_t format) 334chv_update_csc(struct intel_plane *intel_plane, uint32_t format)
335{ 335{
336 struct drm_i915_private *dev_priv = intel_plane->base.dev->dev_private; 336 struct drm_i915_private *dev_priv = intel_plane->base.dev->dev_private;
337 int plane = intel_plane->plane; 337 int plane = intel_plane->plane;
338 338
339 /* Seems RGB data bypasses the CSC always */ 339 /* Seems RGB data bypasses the CSC always */
340 if (!format_is_yuv(format)) 340 if (!format_is_yuv(format))
341 return; 341 return;
342 342
343 /* 343 /*
344 * BT.601 limited range YCbCr -> full range RGB 344 * BT.601 limited range YCbCr -> full range RGB
345 * 345 *
346 * |r| | 6537 4769 0| |cr | 346 * |r| | 6537 4769 0| |cr |
347 * |g| = |-3330 4769 -1605| x |y-64| 347 * |g| = |-3330 4769 -1605| x |y-64|
348 * |b| | 0 4769 8263| |cb | 348 * |b| | 0 4769 8263| |cb |
349 * 349 *
350 * Cb and Cr apparently come in as signed already, so no 350 * Cb and Cr apparently come in as signed already, so no
351 * need for any offset. For Y we need to remove the offset. 351 * need for any offset. For Y we need to remove the offset.
352 */ 352 */
353 I915_WRITE(SPCSCYGOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(-64)); 353 I915_WRITE(SPCSCYGOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(-64));
354 I915_WRITE(SPCSCCBOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 354 I915_WRITE(SPCSCCBOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0));
355 I915_WRITE(SPCSCCROFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 355 I915_WRITE(SPCSCCROFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0));
356 356
357 I915_WRITE(SPCSCC01(plane), SPCSC_C1(4769) | SPCSC_C0(6537)); 357 I915_WRITE(SPCSCC01(plane), SPCSC_C1(4769) | SPCSC_C0(6537));
358 I915_WRITE(SPCSCC23(plane), SPCSC_C1(-3330) | SPCSC_C0(0)); 358 I915_WRITE(SPCSCC23(plane), SPCSC_C1(-3330) | SPCSC_C0(0));
359 I915_WRITE(SPCSCC45(plane), SPCSC_C1(-1605) | SPCSC_C0(4769)); 359 I915_WRITE(SPCSCC45(plane), SPCSC_C1(-1605) | SPCSC_C0(4769));
360 I915_WRITE(SPCSCC67(plane), SPCSC_C1(4769) | SPCSC_C0(0)); 360 I915_WRITE(SPCSCC67(plane), SPCSC_C1(4769) | SPCSC_C0(0));
361 I915_WRITE(SPCSCC8(plane), SPCSC_C0(8263)); 361 I915_WRITE(SPCSCC8(plane), SPCSC_C0(8263));
362 362
363 I915_WRITE(SPCSCYGICLAMP(plane), SPCSC_IMAX(940) | SPCSC_IMIN(64)); 363 I915_WRITE(SPCSCYGICLAMP(plane), SPCSC_IMAX(940) | SPCSC_IMIN(64));
364 I915_WRITE(SPCSCCBICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); 364 I915_WRITE(SPCSCCBICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
365 I915_WRITE(SPCSCCRICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); 365 I915_WRITE(SPCSCCRICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
366 366
367 I915_WRITE(SPCSCYGOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 367 I915_WRITE(SPCSCYGOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
368 I915_WRITE(SPCSCCBOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 368 I915_WRITE(SPCSCCBOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
369 I915_WRITE(SPCSCCROCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 369 I915_WRITE(SPCSCCROCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
370} 370}
371 371
372static void 372static void
373vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, 373vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
374 struct drm_framebuffer *fb, 374 struct drm_framebuffer *fb,
375 int crtc_x, int crtc_y, 375 int crtc_x, int crtc_y,
376 unsigned int crtc_w, unsigned int crtc_h, 376 unsigned int crtc_w, unsigned int crtc_h,
377 uint32_t x, uint32_t y, 377 uint32_t x, uint32_t y,
378 uint32_t src_w, uint32_t src_h) 378 uint32_t src_w, uint32_t src_h)
379{ 379{
380 struct drm_device *dev = dplane->dev; 380 struct drm_device *dev = dplane->dev;
381 struct drm_i915_private *dev_priv = dev->dev_private; 381 struct drm_i915_private *dev_priv = dev->dev_private;
382 struct intel_plane *intel_plane = to_intel_plane(dplane); 382 struct intel_plane *intel_plane = to_intel_plane(dplane);
383 struct drm_i915_gem_object *obj = intel_fb_obj(fb); 383 struct drm_i915_gem_object *obj = intel_fb_obj(fb);
384 int pipe = intel_plane->pipe; 384 int pipe = intel_plane->pipe;
385 int plane = intel_plane->plane; 385 int plane = intel_plane->plane;
386 u32 sprctl; 386 u32 sprctl;
387 unsigned long sprsurf_offset, linear_offset; 387 unsigned long sprsurf_offset, linear_offset;
388 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 388 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
389 const struct drm_intel_sprite_colorkey *key = 389 const struct drm_intel_sprite_colorkey *key =
390 &to_intel_plane_state(dplane->state)->ckey; 390 &to_intel_plane_state(dplane->state)->ckey;
391 391
392 sprctl = SP_ENABLE; 392 sprctl = SP_ENABLE;
393 393
394 switch (fb->pixel_format) { 394 switch (fb->pixel_format) {
395 case DRM_FORMAT_YUYV: 395 case DRM_FORMAT_YUYV:
396 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV; 396 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
397 break; 397 break;
398 case DRM_FORMAT_YVYU: 398 case DRM_FORMAT_YVYU:
399 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU; 399 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
400 break; 400 break;
401 case DRM_FORMAT_UYVY: 401 case DRM_FORMAT_UYVY:
402 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY; 402 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
403 break; 403 break;
404 case DRM_FORMAT_VYUY: 404 case DRM_FORMAT_VYUY:
405 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY; 405 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
406 break; 406 break;
407 case DRM_FORMAT_RGB565: 407 case DRM_FORMAT_RGB565:
408 sprctl |= SP_FORMAT_BGR565; 408 sprctl |= SP_FORMAT_BGR565;
409 break; 409 break;
410 case DRM_FORMAT_XRGB8888: 410 case DRM_FORMAT_XRGB8888:
411 sprctl |= SP_FORMAT_BGRX8888; 411 sprctl |= SP_FORMAT_BGRX8888;
412 break; 412 break;
413 case DRM_FORMAT_ARGB8888: 413 case DRM_FORMAT_ARGB8888:
414 sprctl |= SP_FORMAT_BGRA8888; 414 sprctl |= SP_FORMAT_BGRA8888;
415 break; 415 break;
416 case DRM_FORMAT_XBGR2101010: 416 case DRM_FORMAT_XBGR2101010:
417 sprctl |= SP_FORMAT_RGBX1010102; 417 sprctl |= SP_FORMAT_RGBX1010102;
418 break; 418 break;
419 case DRM_FORMAT_ABGR2101010: 419 case DRM_FORMAT_ABGR2101010:
420 sprctl |= SP_FORMAT_RGBA1010102; 420 sprctl |= SP_FORMAT_RGBA1010102;
421 break; 421 break;
422 case DRM_FORMAT_XBGR8888: 422 case DRM_FORMAT_XBGR8888:
423 sprctl |= SP_FORMAT_RGBX8888; 423 sprctl |= SP_FORMAT_RGBX8888;
424 break; 424 break;
425 case DRM_FORMAT_ABGR8888: 425 case DRM_FORMAT_ABGR8888:
426 sprctl |= SP_FORMAT_RGBA8888; 426 sprctl |= SP_FORMAT_RGBA8888;
427 break; 427 break;
428 default: 428 default:
429 /* 429 /*
430 * If we get here one of the upper layers failed to filter 430 * If we get here one of the upper layers failed to filter
431 * out the unsupported plane formats 431 * out the unsupported plane formats
432 */ 432 */
433 BUG(); 433 BUG();
434 break; 434 break;
435 } 435 }
436 436
437 /* 437 /*
438 * Enable gamma to match primary/cursor plane behaviour. 438 * Enable gamma to match primary/cursor plane behaviour.
439 * FIXME should be user controllable via propertiesa. 439 * FIXME should be user controllable via propertiesa.
440 */ 440 */
441 sprctl |= SP_GAMMA_ENABLE; 441 sprctl |= SP_GAMMA_ENABLE;
442 442
443 if (obj->tiling_mode != I915_TILING_NONE) 443 if (obj->tiling_mode != I915_TILING_NONE)
444 sprctl |= SP_TILED; 444 sprctl |= SP_TILED;
445 445
446 /* Sizes are 0 based */ 446 /* Sizes are 0 based */
447 src_w--; 447 src_w--;
448 src_h--; 448 src_h--;
449 crtc_w--; 449 crtc_w--;
450 crtc_h--; 450 crtc_h--;
451 451
452 linear_offset = y * fb->pitches[0] + x * pixel_size; 452 linear_offset = y * fb->pitches[0] + x * pixel_size;
453 sprsurf_offset = intel_gen4_compute_page_offset(dev_priv, 453 sprsurf_offset = intel_gen4_compute_page_offset(dev_priv,
454 &x, &y, 454 &x, &y,
455 obj->tiling_mode, 455 obj->tiling_mode,
456 pixel_size, 456 pixel_size,
457 fb->pitches[0]); 457 fb->pitches[0]);
458 linear_offset -= sprsurf_offset; 458 linear_offset -= sprsurf_offset;
459 459
460 if (dplane->state->rotation == BIT(DRM_ROTATE_180)) { 460 if (dplane->state->rotation == BIT(DRM_ROTATE_180)) {
461 sprctl |= SP_ROTATE_180; 461 sprctl |= SP_ROTATE_180;
462 462
463 x += src_w; 463 x += src_w;
464 y += src_h; 464 y += src_h;
465 linear_offset += src_h * fb->pitches[0] + src_w * pixel_size; 465 linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
466 } 466 }
467 467
468 if (key->flags) { 468 if (key->flags) {
469 I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value); 469 I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value);
470 I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value); 470 I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value);
471 I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask); 471 I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask);
472 } 472 }
473 473
474 if (key->flags & I915_SET_COLORKEY_SOURCE) 474 if (key->flags & I915_SET_COLORKEY_SOURCE)
475 sprctl |= SP_SOURCE_KEY; 475 sprctl |= SP_SOURCE_KEY;
476 476
477 if (IS_CHERRYVIEW(dev) && pipe == PIPE_B) 477 if (IS_CHERRYVIEW(dev) && pipe == PIPE_B)
478 chv_update_csc(intel_plane, fb->pixel_format); 478 chv_update_csc(intel_plane, fb->pixel_format);
479 479
480 I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); 480 I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
481 I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); 481 I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
482 482
483 if (obj->tiling_mode != I915_TILING_NONE) 483 if (obj->tiling_mode != I915_TILING_NONE)
484 I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x); 484 I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
485 else 485 else
486 I915_WRITE(SPLINOFF(pipe, plane), linear_offset); 486 I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
487 487
488 I915_WRITE(SPCONSTALPHA(pipe, plane), 0); 488 I915_WRITE(SPCONSTALPHA(pipe, plane), 0);
489 489
490 I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); 490 I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w);
491 I915_WRITE(SPCNTR(pipe, plane), sprctl); 491 I915_WRITE(SPCNTR(pipe, plane), sprctl);
492 I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + 492 I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) +
493 sprsurf_offset); 493 sprsurf_offset);
494 POSTING_READ(SPSURF(pipe, plane)); 494 POSTING_READ(SPSURF(pipe, plane));
495} 495}
496 496
497static void 497static void
498vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) 498vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
499{ 499{
500 struct drm_device *dev = dplane->dev; 500 struct drm_device *dev = dplane->dev;
501 struct drm_i915_private *dev_priv = dev->dev_private; 501 struct drm_i915_private *dev_priv = dev->dev_private;
502 struct intel_plane *intel_plane = to_intel_plane(dplane); 502 struct intel_plane *intel_plane = to_intel_plane(dplane);
503 int pipe = intel_plane->pipe; 503 int pipe = intel_plane->pipe;
504 int plane = intel_plane->plane; 504 int plane = intel_plane->plane;
505 505
506 I915_WRITE(SPCNTR(pipe, plane), 0); 506 I915_WRITE(SPCNTR(pipe, plane), 0);
507 507
508 I915_WRITE(SPSURF(pipe, plane), 0); 508 I915_WRITE(SPSURF(pipe, plane), 0);
509 POSTING_READ(SPSURF(pipe, plane)); 509 POSTING_READ(SPSURF(pipe, plane));
510} 510}
511 511
512static void 512static void
513ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 513ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
514 struct drm_framebuffer *fb, 514 struct drm_framebuffer *fb,
515 int crtc_x, int crtc_y, 515 int crtc_x, int crtc_y,
516 unsigned int crtc_w, unsigned int crtc_h, 516 unsigned int crtc_w, unsigned int crtc_h,
517 uint32_t x, uint32_t y, 517 uint32_t x, uint32_t y,
518 uint32_t src_w, uint32_t src_h) 518 uint32_t src_w, uint32_t src_h)
519{ 519{
520 struct drm_device *dev = plane->dev; 520 struct drm_device *dev = plane->dev;
521 struct drm_i915_private *dev_priv = dev->dev_private; 521 struct drm_i915_private *dev_priv = dev->dev_private;
522 struct intel_plane *intel_plane = to_intel_plane(plane); 522 struct intel_plane *intel_plane = to_intel_plane(plane);
523 struct drm_i915_gem_object *obj = intel_fb_obj(fb); 523 struct drm_i915_gem_object *obj = intel_fb_obj(fb);
524 enum pipe pipe = intel_plane->pipe; 524 enum pipe pipe = intel_plane->pipe;
525 u32 sprctl, sprscale = 0; 525 u32 sprctl, sprscale = 0;
526 unsigned long sprsurf_offset, linear_offset; 526 unsigned long sprsurf_offset, linear_offset;
527 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 527 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
528 const struct drm_intel_sprite_colorkey *key = 528 const struct drm_intel_sprite_colorkey *key =
529 &to_intel_plane_state(plane->state)->ckey; 529 &to_intel_plane_state(plane->state)->ckey;
530 530
531 sprctl = SPRITE_ENABLE; 531 sprctl = SPRITE_ENABLE;
532 532
533 switch (fb->pixel_format) { 533 switch (fb->pixel_format) {
534 case DRM_FORMAT_XBGR8888: 534 case DRM_FORMAT_XBGR8888:
535 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; 535 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
536 break; 536 break;
537 case DRM_FORMAT_XRGB8888: 537 case DRM_FORMAT_XRGB8888:
538 sprctl |= SPRITE_FORMAT_RGBX888; 538 sprctl |= SPRITE_FORMAT_RGBX888;
539 break; 539 break;
540 case DRM_FORMAT_YUYV: 540 case DRM_FORMAT_YUYV:
541 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; 541 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
542 break; 542 break;
543 case DRM_FORMAT_YVYU: 543 case DRM_FORMAT_YVYU:
544 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; 544 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
545 break; 545 break;
546 case DRM_FORMAT_UYVY: 546 case DRM_FORMAT_UYVY:
547 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; 547 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
548 break; 548 break;
549 case DRM_FORMAT_VYUY: 549 case DRM_FORMAT_VYUY:
550 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; 550 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
551 break; 551 break;
552 default: 552 default:
553 BUG(); 553 BUG();
554 } 554 }
555 555
556 /* 556 /*
557 * Enable gamma to match primary/cursor plane behaviour. 557 * Enable gamma to match primary/cursor plane behaviour.
558 * FIXME should be user controllable via propertiesa. 558 * FIXME should be user controllable via propertiesa.
559 */ 559 */
560 sprctl |= SPRITE_GAMMA_ENABLE; 560 sprctl |= SPRITE_GAMMA_ENABLE;
561 561
562 if (obj->tiling_mode != I915_TILING_NONE) 562 if (obj->tiling_mode != I915_TILING_NONE)
563 sprctl |= SPRITE_TILED; 563 sprctl |= SPRITE_TILED;
564 564
565 if (IS_HASWELL(dev) || IS_BROADWELL(dev)) 565 if (IS_HASWELL(dev) || IS_BROADWELL(dev))
566 sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE; 566 sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE;
567 else 567 else
568 sprctl |= SPRITE_TRICKLE_FEED_DISABLE; 568 sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
569 569
570 if (IS_HASWELL(dev) || IS_BROADWELL(dev)) 570 if (IS_HASWELL(dev) || IS_BROADWELL(dev))
571 sprctl |= SPRITE_PIPE_CSC_ENABLE; 571 sprctl |= SPRITE_PIPE_CSC_ENABLE;
572 572
573 intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size, 573 intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size,
574 true, 574 true,
575 src_w != crtc_w || src_h != crtc_h); 575 src_w != crtc_w || src_h != crtc_h);
576 576
577 /* Sizes are 0 based */ 577 /* Sizes are 0 based */
578 src_w--; 578 src_w--;
579 src_h--; 579 src_h--;
580 crtc_w--; 580 crtc_w--;
581 crtc_h--; 581 crtc_h--;
582 582
583 if (crtc_w != src_w || crtc_h != src_h) 583 if (crtc_w != src_w || crtc_h != src_h)
584 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; 584 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
585 585
586 linear_offset = y * fb->pitches[0] + x * pixel_size; 586 linear_offset = y * fb->pitches[0] + x * pixel_size;
587 sprsurf_offset = 587 sprsurf_offset =
588 intel_gen4_compute_page_offset(dev_priv, 588 intel_gen4_compute_page_offset(dev_priv,
589 &x, &y, obj->tiling_mode, 589 &x, &y, obj->tiling_mode,
590 pixel_size, fb->pitches[0]); 590 pixel_size, fb->pitches[0]);
591 linear_offset -= sprsurf_offset; 591 linear_offset -= sprsurf_offset;
592 592
593 if (plane->state->rotation == BIT(DRM_ROTATE_180)) { 593 if (plane->state->rotation == BIT(DRM_ROTATE_180)) {
594 sprctl |= SPRITE_ROTATE_180; 594 sprctl |= SPRITE_ROTATE_180;
595 595
596 /* HSW and BDW does this automagically in hardware */ 596 /* HSW and BDW does this automagically in hardware */
597 if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) { 597 if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
598 x += src_w; 598 x += src_w;
599 y += src_h; 599 y += src_h;
600 linear_offset += src_h * fb->pitches[0] + 600 linear_offset += src_h * fb->pitches[0] +
601 src_w * pixel_size; 601 src_w * pixel_size;
602 } 602 }
603 } 603 }
604 604
605 if (key->flags) { 605 if (key->flags) {
606 I915_WRITE(SPRKEYVAL(pipe), key->min_value); 606 I915_WRITE(SPRKEYVAL(pipe), key->min_value);
607 I915_WRITE(SPRKEYMAX(pipe), key->max_value); 607 I915_WRITE(SPRKEYMAX(pipe), key->max_value);
608 I915_WRITE(SPRKEYMSK(pipe), key->channel_mask); 608 I915_WRITE(SPRKEYMSK(pipe), key->channel_mask);
609 } 609 }
610 610
611 if (key->flags & I915_SET_COLORKEY_DESTINATION) 611 if (key->flags & I915_SET_COLORKEY_DESTINATION)
612 sprctl |= SPRITE_DEST_KEY; 612 sprctl |= SPRITE_DEST_KEY;
613 else if (key->flags & I915_SET_COLORKEY_SOURCE) 613 else if (key->flags & I915_SET_COLORKEY_SOURCE)
614 sprctl |= SPRITE_SOURCE_KEY; 614 sprctl |= SPRITE_SOURCE_KEY;
615 615
616 I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); 616 I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
617 I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); 617 I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
618 618
619 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET 619 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
620 * register */ 620 * register */
621 if (IS_HASWELL(dev) || IS_BROADWELL(dev)) 621 if (IS_HASWELL(dev) || IS_BROADWELL(dev))
622 I915_WRITE(SPROFFSET(pipe), (y << 16) | x); 622 I915_WRITE(SPROFFSET(pipe), (y << 16) | x);
623 else if (obj->tiling_mode != I915_TILING_NONE) 623 else if (obj->tiling_mode != I915_TILING_NONE)
624 I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x); 624 I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
625 else 625 else
626 I915_WRITE(SPRLINOFF(pipe), linear_offset); 626 I915_WRITE(SPRLINOFF(pipe), linear_offset);
627 627
628 I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); 628 I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
629 if (intel_plane->can_scale) 629 if (intel_plane->can_scale)
630 I915_WRITE(SPRSCALE(pipe), sprscale); 630 I915_WRITE(SPRSCALE(pipe), sprscale);
631 I915_WRITE(SPRCTL(pipe), sprctl); 631 I915_WRITE(SPRCTL(pipe), sprctl);
632 I915_WRITE(SPRSURF(pipe), 632 I915_WRITE(SPRSURF(pipe),
633 i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); 633 i915_gem_obj_ggtt_offset(obj) + sprsurf_offset);
634 POSTING_READ(SPRSURF(pipe)); 634 POSTING_READ(SPRSURF(pipe));
635} 635}
636 636
637static void 637static void
638ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) 638ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
639{ 639{
640 struct drm_device *dev = plane->dev; 640 struct drm_device *dev = plane->dev;
641 struct drm_i915_private *dev_priv = dev->dev_private; 641 struct drm_i915_private *dev_priv = dev->dev_private;
642 struct intel_plane *intel_plane = to_intel_plane(plane); 642 struct intel_plane *intel_plane = to_intel_plane(plane);
643 int pipe = intel_plane->pipe; 643 int pipe = intel_plane->pipe;
644 644
645 I915_WRITE(SPRCTL(pipe), 0); 645 I915_WRITE(SPRCTL(pipe), 0);
646 /* Can't leave the scaler enabled... */ 646 /* Can't leave the scaler enabled... */
647 if (intel_plane->can_scale) 647 if (intel_plane->can_scale)
648 I915_WRITE(SPRSCALE(pipe), 0); 648 I915_WRITE(SPRSCALE(pipe), 0);
649 649
650 I915_WRITE(SPRSURF(pipe), 0); 650 I915_WRITE(SPRSURF(pipe), 0);
651 POSTING_READ(SPRSURF(pipe)); 651 POSTING_READ(SPRSURF(pipe));
652} 652}
653 653
654static void 654static void
655ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 655ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
656 struct drm_framebuffer *fb, 656 struct drm_framebuffer *fb,
657 int crtc_x, int crtc_y, 657 int crtc_x, int crtc_y,
658 unsigned int crtc_w, unsigned int crtc_h, 658 unsigned int crtc_w, unsigned int crtc_h,
659 uint32_t x, uint32_t y, 659 uint32_t x, uint32_t y,
660 uint32_t src_w, uint32_t src_h) 660 uint32_t src_w, uint32_t src_h)
661{ 661{
662 struct drm_device *dev = plane->dev; 662 struct drm_device *dev = plane->dev;
663 struct drm_i915_private *dev_priv = dev->dev_private; 663 struct drm_i915_private *dev_priv = dev->dev_private;
664 struct intel_plane *intel_plane = to_intel_plane(plane); 664 struct intel_plane *intel_plane = to_intel_plane(plane);
665 struct drm_i915_gem_object *obj = intel_fb_obj(fb); 665 struct drm_i915_gem_object *obj = intel_fb_obj(fb);
666 int pipe = intel_plane->pipe; 666 int pipe = intel_plane->pipe;
667 unsigned long dvssurf_offset, linear_offset; 667 unsigned long dvssurf_offset, linear_offset;
668 u32 dvscntr, dvsscale; 668 u32 dvscntr, dvsscale;
669 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 669 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
670 const struct drm_intel_sprite_colorkey *key = 670 const struct drm_intel_sprite_colorkey *key =
671 &to_intel_plane_state(plane->state)->ckey; 671 &to_intel_plane_state(plane->state)->ckey;
672 672
673 dvscntr = DVS_ENABLE; 673 dvscntr = DVS_ENABLE;
674 674
675 switch (fb->pixel_format) { 675 switch (fb->pixel_format) {
676 case DRM_FORMAT_XBGR8888: 676 case DRM_FORMAT_XBGR8888:
677 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; 677 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
678 break; 678 break;
679 case DRM_FORMAT_XRGB8888: 679 case DRM_FORMAT_XRGB8888:
680 dvscntr |= DVS_FORMAT_RGBX888; 680 dvscntr |= DVS_FORMAT_RGBX888;
681 break; 681 break;
682 case DRM_FORMAT_YUYV: 682 case DRM_FORMAT_YUYV:
683 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV; 683 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
684 break; 684 break;
685 case DRM_FORMAT_YVYU: 685 case DRM_FORMAT_YVYU:
686 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU; 686 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
687 break; 687 break;
688 case DRM_FORMAT_UYVY: 688 case DRM_FORMAT_UYVY:
689 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY; 689 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
690 break; 690 break;
691 case DRM_FORMAT_VYUY: 691 case DRM_FORMAT_VYUY:
692 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY; 692 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
693 break; 693 break;
694 default: 694 default:
695 BUG(); 695 BUG();
696 } 696 }
697 697
698 /* 698 /*
699 * Enable gamma to match primary/cursor plane behaviour. 699 * Enable gamma to match primary/cursor plane behaviour.
700 * FIXME should be user controllable via propertiesa. 700 * FIXME should be user controllable via propertiesa.
701 */ 701 */
702 dvscntr |= DVS_GAMMA_ENABLE; 702 dvscntr |= DVS_GAMMA_ENABLE;
703 703
704 if (obj->tiling_mode != I915_TILING_NONE) 704 if (obj->tiling_mode != I915_TILING_NONE)
705 dvscntr |= DVS_TILED; 705 dvscntr |= DVS_TILED;
706 706
707 if (IS_GEN6(dev)) 707 if (IS_GEN6(dev))
708 dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ 708 dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
709 709
710 intel_update_sprite_watermarks(plane, crtc, src_w, src_h, 710 intel_update_sprite_watermarks(plane, crtc, src_w, src_h,
711 pixel_size, true, 711 pixel_size, true,
712 src_w != crtc_w || src_h != crtc_h); 712 src_w != crtc_w || src_h != crtc_h);
713 713
714 /* Sizes are 0 based */ 714 /* Sizes are 0 based */
715 src_w--; 715 src_w--;
716 src_h--; 716 src_h--;
717 crtc_w--; 717 crtc_w--;
718 crtc_h--; 718 crtc_h--;
719 719
720 dvsscale = 0; 720 dvsscale = 0;
721 if (crtc_w != src_w || crtc_h != src_h) 721 if (crtc_w != src_w || crtc_h != src_h)
722 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; 722 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
723 723
724 linear_offset = y * fb->pitches[0] + x * pixel_size; 724 linear_offset = y * fb->pitches[0] + x * pixel_size;
725 dvssurf_offset = 725 dvssurf_offset =
726 intel_gen4_compute_page_offset(dev_priv, 726 intel_gen4_compute_page_offset(dev_priv,
727 &x, &y, obj->tiling_mode, 727 &x, &y, obj->tiling_mode,
728 pixel_size, fb->pitches[0]); 728 pixel_size, fb->pitches[0]);
729 linear_offset -= dvssurf_offset; 729 linear_offset -= dvssurf_offset;
730 730
731 if (plane->state->rotation == BIT(DRM_ROTATE_180)) { 731 if (plane->state->rotation == BIT(DRM_ROTATE_180)) {
732 dvscntr |= DVS_ROTATE_180; 732 dvscntr |= DVS_ROTATE_180;
733 733
734 x += src_w; 734 x += src_w;
735 y += src_h; 735 y += src_h;
736 linear_offset += src_h * fb->pitches[0] + src_w * pixel_size; 736 linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
737 } 737 }
738 738
739 if (key->flags) { 739 if (key->flags) {
740 I915_WRITE(DVSKEYVAL(pipe), key->min_value); 740 I915_WRITE(DVSKEYVAL(pipe), key->min_value);
741 I915_WRITE(DVSKEYMAX(pipe), key->max_value); 741 I915_WRITE(DVSKEYMAX(pipe), key->max_value);
742 I915_WRITE(DVSKEYMSK(pipe), key->channel_mask); 742 I915_WRITE(DVSKEYMSK(pipe), key->channel_mask);
743 } 743 }
744 744
745 if (key->flags & I915_SET_COLORKEY_DESTINATION) 745 if (key->flags & I915_SET_COLORKEY_DESTINATION)
746 dvscntr |= DVS_DEST_KEY; 746 dvscntr |= DVS_DEST_KEY;
747 else if (key->flags & I915_SET_COLORKEY_SOURCE) 747 else if (key->flags & I915_SET_COLORKEY_SOURCE)
748 dvscntr |= DVS_SOURCE_KEY; 748 dvscntr |= DVS_SOURCE_KEY;
749 749
750 I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); 750 I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
751 I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x); 751 I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
752 752
753 if (obj->tiling_mode != I915_TILING_NONE) 753 if (obj->tiling_mode != I915_TILING_NONE)
754 I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x); 754 I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
755 else 755 else
756 I915_WRITE(DVSLINOFF(pipe), linear_offset); 756 I915_WRITE(DVSLINOFF(pipe), linear_offset);
757 757
758 I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); 758 I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
759 I915_WRITE(DVSSCALE(pipe), dvsscale); 759 I915_WRITE(DVSSCALE(pipe), dvsscale);
760 I915_WRITE(DVSCNTR(pipe), dvscntr); 760 I915_WRITE(DVSCNTR(pipe), dvscntr);
761 I915_WRITE(DVSSURF(pipe), 761 I915_WRITE(DVSSURF(pipe),
762 i915_gem_obj_ggtt_offset(obj) + dvssurf_offset); 762 i915_gem_obj_ggtt_offset(obj) + dvssurf_offset);
763 POSTING_READ(DVSSURF(pipe)); 763 POSTING_READ(DVSSURF(pipe));
764} 764}
765 765
766static void 766static void
767ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) 767ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
768{ 768{
769 struct drm_device *dev = plane->dev; 769 struct drm_device *dev = plane->dev;
770 struct drm_i915_private *dev_priv = dev->dev_private; 770 struct drm_i915_private *dev_priv = dev->dev_private;
771 struct intel_plane *intel_plane = to_intel_plane(plane); 771 struct intel_plane *intel_plane = to_intel_plane(plane);
772 int pipe = intel_plane->pipe; 772 int pipe = intel_plane->pipe;
773 773
774 I915_WRITE(DVSCNTR(pipe), 0); 774 I915_WRITE(DVSCNTR(pipe), 0);
775 /* Disable the scaler */ 775 /* Disable the scaler */
776 I915_WRITE(DVSSCALE(pipe), 0); 776 I915_WRITE(DVSSCALE(pipe), 0);
777 777
778 I915_WRITE(DVSSURF(pipe), 0); 778 I915_WRITE(DVSSURF(pipe), 0);
779 POSTING_READ(DVSSURF(pipe)); 779 POSTING_READ(DVSSURF(pipe));
780} 780}
781 781
782static int 782static int
783intel_check_sprite_plane(struct drm_plane *plane, 783intel_check_sprite_plane(struct drm_plane *plane,
784 struct intel_crtc_state *crtc_state, 784 struct intel_crtc_state *crtc_state,
785 struct intel_plane_state *state) 785 struct intel_plane_state *state)
786{ 786{
787 struct drm_device *dev = plane->dev; 787 struct drm_device *dev = plane->dev;
788 struct drm_crtc *crtc = state->base.crtc; 788 struct drm_crtc *crtc = state->base.crtc;
789 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 789 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
790 struct intel_plane *intel_plane = to_intel_plane(plane); 790 struct intel_plane *intel_plane = to_intel_plane(plane);
791 struct drm_framebuffer *fb = state->base.fb; 791 struct drm_framebuffer *fb = state->base.fb;
792 int crtc_x, crtc_y; 792 int crtc_x, crtc_y;
793 unsigned int crtc_w, crtc_h; 793 unsigned int crtc_w, crtc_h;
794 uint32_t src_x, src_y, src_w, src_h; 794 uint32_t src_x, src_y, src_w, src_h;
795 struct drm_rect *src = &state->src; 795 struct drm_rect *src = &state->src;
796 struct drm_rect *dst = &state->dst; 796 struct drm_rect *dst = &state->dst;
797 const struct drm_rect *clip = &state->clip; 797 const struct drm_rect *clip = &state->clip;
798 int hscale, vscale; 798 int hscale, vscale;
799 int max_scale, min_scale; 799 int max_scale, min_scale;
800 bool can_scale; 800 bool can_scale;
801 int pixel_size; 801 int pixel_size;
802 802
803 if (!fb) { 803 if (!fb) {
804 state->visible = false; 804 state->visible = false;
805 return 0; 805 return 0;
806 } 806 }
807 807
808 /* Don't modify another pipe's plane */ 808 /* Don't modify another pipe's plane */
809 if (intel_plane->pipe != intel_crtc->pipe) { 809 if (intel_plane->pipe != intel_crtc->pipe) {
810 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n"); 810 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
811 return -EINVAL; 811 return -EINVAL;
812 } 812 }
813 813
814 /* FIXME check all gen limits */ 814 /* FIXME check all gen limits */
815 if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) { 815 if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) {
816 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n"); 816 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
817 return -EINVAL; 817 return -EINVAL;
818 } 818 }
819 819
820 /* setup can_scale, min_scale, max_scale */ 820 /* setup can_scale, min_scale, max_scale */
821 if (INTEL_INFO(dev)->gen >= 9) { 821 if (INTEL_INFO(dev)->gen >= 9) {
822 /* use scaler when colorkey is not required */ 822 /* use scaler when colorkey is not required */
823 if (state->ckey.flags == I915_SET_COLORKEY_NONE) { 823 if (state->ckey.flags == I915_SET_COLORKEY_NONE) {
824 can_scale = 1; 824 can_scale = 1;
825 min_scale = 1; 825 min_scale = 1;
826 max_scale = skl_max_scale(intel_crtc, crtc_state); 826 max_scale = skl_max_scale(intel_crtc, crtc_state);
827 } else { 827 } else {
828 can_scale = 0; 828 can_scale = 0;
829 min_scale = DRM_PLANE_HELPER_NO_SCALING; 829 min_scale = DRM_PLANE_HELPER_NO_SCALING;
830 max_scale = DRM_PLANE_HELPER_NO_SCALING; 830 max_scale = DRM_PLANE_HELPER_NO_SCALING;
831 } 831 }
832 } else { 832 } else {
833 can_scale = intel_plane->can_scale; 833 can_scale = intel_plane->can_scale;
834 max_scale = intel_plane->max_downscale << 16; 834 max_scale = intel_plane->max_downscale << 16;
835 min_scale = intel_plane->can_scale ? 1 : (1 << 16); 835 min_scale = intel_plane->can_scale ? 1 : (1 << 16);
836 } 836 }
837 837
838 /* 838 /*
839 * FIXME the following code does a bunch of fuzzy adjustments to the 839 * FIXME the following code does a bunch of fuzzy adjustments to the
840 * coordinates and sizes. We probably need some way to decide whether 840 * coordinates and sizes. We probably need some way to decide whether
841 * more strict checking should be done instead. 841 * more strict checking should be done instead.
842 */ 842 */
843 drm_rect_rotate(src, fb->width << 16, fb->height << 16, 843 drm_rect_rotate(src, fb->width << 16, fb->height << 16,
844 state->base.rotation); 844 state->base.rotation);
845 845
846 hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale); 846 hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
847 BUG_ON(hscale < 0); 847 BUG_ON(hscale < 0);
848 848
849 vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale); 849 vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
850 BUG_ON(vscale < 0); 850 BUG_ON(vscale < 0);
851 851
852 state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale); 852 state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
853 853
854 crtc_x = dst->x1; 854 crtc_x = dst->x1;
855 crtc_y = dst->y1; 855 crtc_y = dst->y1;
856 crtc_w = drm_rect_width(dst); 856 crtc_w = drm_rect_width(dst);
857 crtc_h = drm_rect_height(dst); 857 crtc_h = drm_rect_height(dst);
858 858
859 if (state->visible) { 859 if (state->visible) {
860 /* check again in case clipping clamped the results */ 860 /* check again in case clipping clamped the results */
861 hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); 861 hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
862 if (hscale < 0) { 862 if (hscale < 0) {
863 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n"); 863 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
864 drm_rect_debug_print(src, true); 864 drm_rect_debug_print(src, true);
865 drm_rect_debug_print(dst, false); 865 drm_rect_debug_print(dst, false);
866 866
867 return hscale; 867 return hscale;
868 } 868 }
869 869
870 vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale); 870 vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
871 if (vscale < 0) { 871 if (vscale < 0) {
872 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n"); 872 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
873 drm_rect_debug_print(src, true); 873 drm_rect_debug_print(src, true);
874 drm_rect_debug_print(dst, false); 874 drm_rect_debug_print(dst, false);
875 875
876 return vscale; 876 return vscale;
877 } 877 }
878 878
879 /* Make the source viewport size an exact multiple of the scaling factors. */ 879 /* Make the source viewport size an exact multiple of the scaling factors. */
880 drm_rect_adjust_size(src, 880 drm_rect_adjust_size(src,
881 drm_rect_width(dst) * hscale - drm_rect_width(src), 881 drm_rect_width(dst) * hscale - drm_rect_width(src),
882 drm_rect_height(dst) * vscale - drm_rect_height(src)); 882 drm_rect_height(dst) * vscale - drm_rect_height(src));
883 883
884 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, 884 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
885 state->base.rotation); 885 state->base.rotation);
886 886
887 /* sanity check to make sure the src viewport wasn't enlarged */ 887 /* sanity check to make sure the src viewport wasn't enlarged */
888 WARN_ON(src->x1 < (int) state->base.src_x || 888 WARN_ON(src->x1 < (int) state->base.src_x ||
889 src->y1 < (int) state->base.src_y || 889 src->y1 < (int) state->base.src_y ||
890 src->x2 > (int) state->base.src_x + state->base.src_w || 890 src->x2 > (int) state->base.src_x + state->base.src_w ||
891 src->y2 > (int) state->base.src_y + state->base.src_h); 891 src->y2 > (int) state->base.src_y + state->base.src_h);
892 892
893 /* 893 /*
894 * Hardware doesn't handle subpixel coordinates. 894 * Hardware doesn't handle subpixel coordinates.
895 * Adjust to (macro)pixel boundary, but be careful not to 895 * Adjust to (macro)pixel boundary, but be careful not to
896 * increase the source viewport size, because that could 896 * increase the source viewport size, because that could
897 * push the downscaling factor out of bounds. 897 * push the downscaling factor out of bounds.
898 */ 898 */
899 src_x = src->x1 >> 16; 899 src_x = src->x1 >> 16;
900 src_w = drm_rect_width(src) >> 16; 900 src_w = drm_rect_width(src) >> 16;
901 src_y = src->y1 >> 16; 901 src_y = src->y1 >> 16;
902 src_h = drm_rect_height(src) >> 16; 902 src_h = drm_rect_height(src) >> 16;
903 903
904 if (format_is_yuv(fb->pixel_format)) { 904 if (format_is_yuv(fb->pixel_format)) {
905 src_x &= ~1; 905 src_x &= ~1;
906 src_w &= ~1; 906 src_w &= ~1;
907 907
908 /* 908 /*
909 * Must keep src and dst the 909 * Must keep src and dst the
910 * same if we can't scale. 910 * same if we can't scale.
911 */ 911 */
912 if (!can_scale) 912 if (!can_scale)
913 crtc_w &= ~1; 913 crtc_w &= ~1;
914 914
915 if (crtc_w == 0) 915 if (crtc_w == 0)
916 state->visible = false; 916 state->visible = false;
917 } 917 }
918 } 918 }
919 919
920 /* Check size restrictions when scaling */ 920 /* Check size restrictions when scaling */
921 if (state->visible && (src_w != crtc_w || src_h != crtc_h)) { 921 if (state->visible && (src_w != crtc_w || src_h != crtc_h)) {
922 unsigned int width_bytes; 922 unsigned int width_bytes;
923 923
924 WARN_ON(!can_scale); 924 WARN_ON(!can_scale);
925 925
926 /* FIXME interlacing min height is 6 */ 926 /* FIXME interlacing min height is 6 */
927 927
928 if (crtc_w < 3 || crtc_h < 3) 928 if (crtc_w < 3 || crtc_h < 3)
929 state->visible = false; 929 state->visible = false;
930 930
931 if (src_w < 3 || src_h < 3) 931 if (src_w < 3 || src_h < 3)
932 state->visible = false; 932 state->visible = false;
933 933
934 pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 934 pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
935 width_bytes = ((src_x * pixel_size) & 63) + 935 width_bytes = ((src_x * pixel_size) & 63) +
936 src_w * pixel_size; 936 src_w * pixel_size;
937 937
938 if (INTEL_INFO(dev)->gen < 9 && (src_w > 2048 || src_h > 2048 || 938 if (INTEL_INFO(dev)->gen < 9 && (src_w > 2048 || src_h > 2048 ||
939 width_bytes > 4096 || fb->pitches[0] > 4096)) { 939 width_bytes > 4096 || fb->pitches[0] > 4096)) {
940 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n"); 940 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
941 return -EINVAL; 941 return -EINVAL;
942 } 942 }
943 } 943 }
944 944
945 if (state->visible) { 945 if (state->visible) {
946 src->x1 = src_x << 16; 946 src->x1 = src_x << 16;
947 src->x2 = (src_x + src_w) << 16; 947 src->x2 = (src_x + src_w) << 16;
948 src->y1 = src_y << 16; 948 src->y1 = src_y << 16;
949 src->y2 = (src_y + src_h) << 16; 949 src->y2 = (src_y + src_h) << 16;
950 } 950 }
951 951
952 dst->x1 = crtc_x; 952 dst->x1 = crtc_x;
953 dst->x2 = crtc_x + crtc_w; 953 dst->x2 = crtc_x + crtc_w;
954 dst->y1 = crtc_y; 954 dst->y1 = crtc_y;
955 dst->y2 = crtc_y + crtc_h; 955 dst->y2 = crtc_y + crtc_h;
956 956
957 return 0; 957 return 0;
958} 958}
959 959
960static void 960static void
961intel_commit_sprite_plane(struct drm_plane *plane, 961intel_commit_sprite_plane(struct drm_plane *plane,
962 struct intel_plane_state *state) 962 struct intel_plane_state *state)
963{ 963{
964 struct drm_crtc *crtc = state->base.crtc; 964 struct drm_crtc *crtc = state->base.crtc;
965 struct intel_plane *intel_plane = to_intel_plane(plane); 965 struct intel_plane *intel_plane = to_intel_plane(plane);
966 struct drm_framebuffer *fb = state->base.fb; 966 struct drm_framebuffer *fb = state->base.fb;
967 967
968 crtc = crtc ? crtc : plane->crtc; 968 crtc = crtc ? crtc : plane->crtc;
969 969
970 if (!crtc->state->active) 970 if (!crtc->state->active)
971 return; 971 return;
972 972
973 if (state->visible) { 973 if (state->visible) {
974 intel_plane->update_plane(plane, crtc, fb, 974 intel_plane->update_plane(plane, crtc, fb,
975 state->dst.x1, state->dst.y1, 975 state->dst.x1, state->dst.y1,
976 drm_rect_width(&state->dst), 976 drm_rect_width(&state->dst),
977 drm_rect_height(&state->dst), 977 drm_rect_height(&state->dst),
978 state->src.x1 >> 16, 978 state->src.x1 >> 16,
979 state->src.y1 >> 16, 979 state->src.y1 >> 16,
980 drm_rect_width(&state->src) >> 16, 980 drm_rect_width(&state->src) >> 16,
981 drm_rect_height(&state->src) >> 16); 981 drm_rect_height(&state->src) >> 16);
982 } else { 982 } else {
983 intel_plane->disable_plane(plane, crtc); 983 intel_plane->disable_plane(plane, crtc);
984 } 984 }
985} 985}
986 986
987int intel_sprite_set_colorkey(struct drm_device *dev, void *data, 987int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
988 struct drm_file *file_priv) 988 struct drm_file *file_priv)
989{ 989{
990 struct drm_intel_sprite_colorkey *set = data; 990 struct drm_intel_sprite_colorkey *set = data;
991 struct drm_plane *plane; 991 struct drm_plane *plane;
992 struct drm_plane_state *plane_state; 992 struct drm_plane_state *plane_state;
993 struct drm_atomic_state *state; 993 struct drm_atomic_state *state;
994 struct drm_modeset_acquire_ctx ctx; 994 struct drm_modeset_acquire_ctx ctx;
995 int ret = 0; 995 int ret = 0;
996 996
997 /* Make sure we don't try to enable both src & dest simultaneously */ 997 /* Make sure we don't try to enable both src & dest simultaneously */
998 if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 998 if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
999 return -EINVAL; 999 return -EINVAL;
1000 1000
1001 if (IS_VALLEYVIEW(dev) && 1001 if (IS_VALLEYVIEW(dev) &&
1002 set->flags & I915_SET_COLORKEY_DESTINATION) 1002 set->flags & I915_SET_COLORKEY_DESTINATION)
1003 return -EINVAL; 1003 return -EINVAL;
1004 1004
1005 plane = drm_plane_find(dev, set->plane_id); 1005 plane = drm_plane_find(dev, set->plane_id);
1006 if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) 1006 if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
1007 return -ENOENT; 1007 return -ENOENT;
1008 1008
1009 drm_modeset_acquire_init(&ctx, 0); 1009 drm_modeset_acquire_init(&ctx, 0);
1010 1010
1011 state = drm_atomic_state_alloc(plane->dev); 1011 state = drm_atomic_state_alloc(plane->dev);
1012 if (!state) { 1012 if (!state) {
1013 ret = -ENOMEM; 1013 ret = -ENOMEM;
1014 goto out; 1014 goto out;
1015 } 1015 }
1016 state->acquire_ctx = &ctx; 1016 state->acquire_ctx = &ctx;
1017 1017
1018 while (1) { 1018 while (1) {
1019 plane_state = drm_atomic_get_plane_state(state, plane); 1019 plane_state = drm_atomic_get_plane_state(state, plane);
1020 ret = PTR_ERR_OR_ZERO(plane_state); 1020 ret = PTR_ERR_OR_ZERO(plane_state);
1021 if (!ret) { 1021 if (!ret) {
1022 to_intel_plane_state(plane_state)->ckey = *set; 1022 to_intel_plane_state(plane_state)->ckey = *set;
1023 ret = drm_atomic_commit(state); 1023 ret = drm_atomic_commit(state);
1024 } 1024 }
1025 1025
1026 if (ret != -EDEADLK) 1026 if (ret != -EDEADLK)
1027 break; 1027 break;
1028 1028
1029 drm_atomic_state_clear(state); 1029 drm_atomic_state_clear(state);
1030 drm_modeset_backoff(&ctx); 1030 drm_modeset_backoff(&ctx);
1031 } 1031 }
1032 1032
1033 if (ret) 1033 if (ret)
1034 drm_atomic_state_free(state); 1034 drm_atomic_state_free(state);
1035 1035
1036out: 1036out:
1037 drm_modeset_drop_locks(&ctx); 1037 drm_modeset_drop_locks(&ctx);
1038 drm_modeset_acquire_fini(&ctx); 1038 drm_modeset_acquire_fini(&ctx);
1039 return ret; 1039 return ret;
1040} 1040}
1041 1041
1042static const uint32_t ilk_plane_formats[] = { 1042static const uint32_t ilk_plane_formats[] = {
1043 DRM_FORMAT_XRGB8888, 1043 DRM_FORMAT_XRGB8888,
1044 DRM_FORMAT_YUYV, 1044 DRM_FORMAT_YUYV,
1045 DRM_FORMAT_YVYU, 1045 DRM_FORMAT_YVYU,
1046 DRM_FORMAT_UYVY, 1046 DRM_FORMAT_UYVY,
1047 DRM_FORMAT_VYUY, 1047 DRM_FORMAT_VYUY,
1048}; 1048};
1049 1049
1050static const uint32_t snb_plane_formats[] = { 1050static const uint32_t snb_plane_formats[] = {
1051 DRM_FORMAT_XBGR8888, 1051 DRM_FORMAT_XBGR8888,
1052 DRM_FORMAT_XRGB8888, 1052 DRM_FORMAT_XRGB8888,
1053 DRM_FORMAT_YUYV, 1053 DRM_FORMAT_YUYV,
1054 DRM_FORMAT_YVYU, 1054 DRM_FORMAT_YVYU,
1055 DRM_FORMAT_UYVY, 1055 DRM_FORMAT_UYVY,
1056 DRM_FORMAT_VYUY, 1056 DRM_FORMAT_VYUY,
1057}; 1057};
1058 1058
1059static const uint32_t vlv_plane_formats[] = { 1059static const uint32_t vlv_plane_formats[] = {
1060 DRM_FORMAT_RGB565, 1060 DRM_FORMAT_RGB565,
1061 DRM_FORMAT_ABGR8888, 1061 DRM_FORMAT_ABGR8888,
1062 DRM_FORMAT_ARGB8888, 1062 DRM_FORMAT_ARGB8888,
1063 DRM_FORMAT_XBGR8888, 1063 DRM_FORMAT_XBGR8888,
1064 DRM_FORMAT_XRGB8888, 1064 DRM_FORMAT_XRGB8888,
1065 DRM_FORMAT_XBGR2101010, 1065 DRM_FORMAT_XBGR2101010,
1066 DRM_FORMAT_ABGR2101010, 1066 DRM_FORMAT_ABGR2101010,
1067 DRM_FORMAT_YUYV, 1067 DRM_FORMAT_YUYV,
1068 DRM_FORMAT_YVYU, 1068 DRM_FORMAT_YVYU,
1069 DRM_FORMAT_UYVY, 1069 DRM_FORMAT_UYVY,
1070 DRM_FORMAT_VYUY, 1070 DRM_FORMAT_VYUY,
1071}; 1071};
1072 1072
1073static uint32_t skl_plane_formats[] = { 1073static uint32_t skl_plane_formats[] = {
1074 DRM_FORMAT_RGB565, 1074 DRM_FORMAT_RGB565,
1075 DRM_FORMAT_ABGR8888, 1075 DRM_FORMAT_ABGR8888,
1076 DRM_FORMAT_ARGB8888, 1076 DRM_FORMAT_ARGB8888,
1077 DRM_FORMAT_XBGR8888, 1077 DRM_FORMAT_XBGR8888,
1078 DRM_FORMAT_XRGB8888, 1078 DRM_FORMAT_XRGB8888,
1079 DRM_FORMAT_YUYV, 1079 DRM_FORMAT_YUYV,
1080 DRM_FORMAT_YVYU, 1080 DRM_FORMAT_YVYU,
1081 DRM_FORMAT_UYVY, 1081 DRM_FORMAT_UYVY,
1082 DRM_FORMAT_VYUY, 1082 DRM_FORMAT_VYUY,
1083}; 1083};
1084 1084
1085int 1085int
1086intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) 1086intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
1087{ 1087{
1088 struct intel_plane *intel_plane; 1088 struct intel_plane *intel_plane;
1089 struct intel_plane_state *state; 1089 struct intel_plane_state *state;
1090 unsigned long possible_crtcs; 1090 unsigned long possible_crtcs;
1091 const uint32_t *plane_formats; 1091 const uint32_t *plane_formats;
1092 int num_plane_formats; 1092 int num_plane_formats;
1093 int ret; 1093 int ret;
1094 1094
1095 if (INTEL_INFO(dev)->gen < 5) 1095 if (INTEL_INFO(dev)->gen < 5)
1096 return -ENODEV; 1096 return -ENODEV;
1097 1097
1098 intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL); 1098 intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
1099 if (!intel_plane) 1099 if (!intel_plane)
1100 return -ENOMEM; 1100 return -ENOMEM;
1101 1101
1102 state = intel_create_plane_state(&intel_plane->base); 1102 state = intel_create_plane_state(&intel_plane->base);
1103 if (!state) { 1103 if (!state) {
1104 kfree(intel_plane); 1104 kfree(intel_plane);
1105 return -ENOMEM; 1105 return -ENOMEM;
1106 } 1106 }
1107 intel_plane->base.state = &state->base; 1107 intel_plane->base.state = &state->base;
1108 1108
1109 switch (INTEL_INFO(dev)->gen) { 1109 switch (INTEL_INFO(dev)->gen) {
1110 case 5: 1110 case 5:
1111 case 6: 1111 case 6:
1112 intel_plane->can_scale = true; 1112 intel_plane->can_scale = true;
1113 intel_plane->max_downscale = 16; 1113 intel_plane->max_downscale = 16;
1114 intel_plane->update_plane = ilk_update_plane; 1114 intel_plane->update_plane = ilk_update_plane;
1115 intel_plane->disable_plane = ilk_disable_plane; 1115 intel_plane->disable_plane = ilk_disable_plane;
1116 1116
1117 if (IS_GEN6(dev)) { 1117 if (IS_GEN6(dev)) {
1118 plane_formats = snb_plane_formats; 1118 plane_formats = snb_plane_formats;
1119 num_plane_formats = ARRAY_SIZE(snb_plane_formats); 1119 num_plane_formats = ARRAY_SIZE(snb_plane_formats);
1120 } else { 1120 } else {
1121 plane_formats = ilk_plane_formats; 1121 plane_formats = ilk_plane_formats;
1122 num_plane_formats = ARRAY_SIZE(ilk_plane_formats); 1122 num_plane_formats = ARRAY_SIZE(ilk_plane_formats);
1123 } 1123 }
1124 break; 1124 break;
1125 1125
1126 case 7: 1126 case 7: