.. | .. |
---|
21 | 21 | */ |
---|
22 | 22 | #include "wndw.h" |
---|
23 | 23 | #include "wimm.h" |
---|
| 24 | +#include "handles.h" |
---|
24 | 25 | |
---|
25 | 26 | #include <nvif/class.h> |
---|
26 | 27 | #include <nvif/cl0002.h> |
---|
27 | 28 | |
---|
| 29 | +#include <nvhw/class/cl507c.h> |
---|
| 30 | +#include <nvhw/class/cl507e.h> |
---|
| 31 | +#include <nvhw/class/clc37e.h> |
---|
| 32 | + |
---|
28 | 33 | #include <drm/drm_atomic_helper.h> |
---|
| 34 | +#include <drm/drm_fourcc.h> |
---|
| 35 | + |
---|
29 | 36 | #include "nouveau_bo.h" |
---|
| 37 | +#include "nouveau_gem.h" |
---|
30 | 38 | |
---|
31 | 39 | static void |
---|
32 | 40 | nv50_wndw_ctxdma_del(struct nv50_wndw_ctxdma *ctxdma) |
---|
33 | 41 | { |
---|
34 | | - nvif_object_fini(&ctxdma->object); |
---|
| 42 | + nvif_object_dtor(&ctxdma->object); |
---|
35 | 43 | list_del(&ctxdma->head); |
---|
36 | 44 | kfree(ctxdma); |
---|
37 | 45 | } |
---|
38 | 46 | |
---|
39 | 47 | static struct nv50_wndw_ctxdma * |
---|
40 | | -nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct nouveau_framebuffer *fb) |
---|
| 48 | +nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct drm_framebuffer *fb) |
---|
41 | 49 | { |
---|
42 | | - struct nouveau_drm *drm = nouveau_drm(fb->base.dev); |
---|
| 50 | + struct nouveau_drm *drm = nouveau_drm(fb->dev); |
---|
43 | 51 | struct nv50_wndw_ctxdma *ctxdma; |
---|
44 | | - const u8 kind = fb->nvbo->kind; |
---|
45 | | - const u32 handle = 0xfb000000 | kind; |
---|
| 52 | + u32 handle; |
---|
| 53 | + u32 unused; |
---|
| 54 | + u8 kind; |
---|
46 | 55 | struct { |
---|
47 | 56 | struct nv_dma_v0 base; |
---|
48 | 57 | union { |
---|
.. | .. |
---|
53 | 62 | } args = {}; |
---|
54 | 63 | u32 argc = sizeof(args.base); |
---|
55 | 64 | int ret; |
---|
| 65 | + |
---|
| 66 | + nouveau_framebuffer_get_layout(fb, &unused, &kind); |
---|
| 67 | + handle = NV50_DISP_HANDLE_WNDW_CTX(kind); |
---|
56 | 68 | |
---|
57 | 69 | list_for_each_entry(ctxdma, &wndw->ctxdma.list, head) { |
---|
58 | 70 | if (ctxdma->object.handle == handle) |
---|
.. | .. |
---|
86 | 98 | argc += sizeof(args.gf119); |
---|
87 | 99 | } |
---|
88 | 100 | |
---|
89 | | - ret = nvif_object_init(wndw->ctxdma.parent, handle, NV_DMA_IN_MEMORY, |
---|
90 | | - &args, argc, &ctxdma->object); |
---|
| 101 | + ret = nvif_object_ctor(wndw->ctxdma.parent, "kmsFbCtxDma", handle, |
---|
| 102 | + NV_DMA_IN_MEMORY, &args, argc, &ctxdma->object); |
---|
91 | 103 | if (ret) { |
---|
92 | 104 | nv50_wndw_ctxdma_del(ctxdma); |
---|
93 | 105 | return ERR_PTR(ret); |
---|
.. | .. |
---|
118 | 130 | if (clr.sema ) wndw->func-> sema_clr(wndw); |
---|
119 | 131 | if (clr.ntfy ) wndw->func-> ntfy_clr(wndw); |
---|
120 | 132 | if (clr.xlut ) wndw->func-> xlut_clr(wndw); |
---|
| 133 | + if (clr.csc ) wndw->func-> csc_clr(wndw); |
---|
121 | 134 | if (clr.image) wndw->func->image_clr(wndw); |
---|
122 | 135 | |
---|
123 | 136 | interlock[wndw->interlock.type] |= wndw->interlock.data; |
---|
.. | .. |
---|
127 | 140 | nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock, |
---|
128 | 141 | struct nv50_wndw_atom *asyw) |
---|
129 | 142 | { |
---|
130 | | - if (interlock) { |
---|
131 | | - asyw->image.mode = 0; |
---|
| 143 | + if (interlock[NV50_DISP_INTERLOCK_CORE]) { |
---|
| 144 | + asyw->image.mode = NV507C_SET_PRESENT_CONTROL_BEGIN_MODE_NON_TEARING; |
---|
132 | 145 | asyw->image.interval = 1; |
---|
133 | 146 | } |
---|
134 | 147 | |
---|
.. | .. |
---|
139 | 152 | if (asyw->set.xlut ) { |
---|
140 | 153 | if (asyw->ilut) { |
---|
141 | 154 | asyw->xlut.i.offset = |
---|
142 | | - nv50_lut_load(&wndw->ilut, |
---|
143 | | - asyw->xlut.i.mode <= 1, |
---|
144 | | - asyw->xlut.i.buffer, |
---|
145 | | - asyw->ilut); |
---|
| 155 | + nv50_lut_load(&wndw->ilut, asyw->xlut.i.buffer, |
---|
| 156 | + asyw->ilut, asyw->xlut.i.load); |
---|
146 | 157 | } |
---|
147 | 158 | wndw->func->xlut_set(wndw, asyw); |
---|
148 | 159 | } |
---|
149 | 160 | |
---|
| 161 | + if (asyw->set.csc ) wndw->func->csc_set (wndw, asyw); |
---|
150 | 162 | if (asyw->set.scale) wndw->func->scale_set(wndw, asyw); |
---|
| 163 | + if (asyw->set.blend) wndw->func->blend_set(wndw, asyw); |
---|
151 | 164 | if (asyw->set.point) { |
---|
152 | 165 | if (asyw->set.point = false, asyw->set.mask) |
---|
153 | 166 | interlock[wndw->interlock.type] |= wndw->interlock.data; |
---|
.. | .. |
---|
184 | 197 | wndw->func->release(wndw, asyw, asyh); |
---|
185 | 198 | asyw->ntfy.handle = 0; |
---|
186 | 199 | asyw->sema.handle = 0; |
---|
| 200 | + asyw->xlut.handle = 0; |
---|
| 201 | + memset(asyw->image.handle, 0x00, sizeof(asyw->image.handle)); |
---|
187 | 202 | } |
---|
188 | 203 | |
---|
189 | 204 | static int |
---|
190 | 205 | nv50_wndw_atomic_check_acquire_yuv(struct nv50_wndw_atom *asyw) |
---|
191 | 206 | { |
---|
192 | 207 | switch (asyw->state.fb->format->format) { |
---|
193 | | - case DRM_FORMAT_YUYV: asyw->image.format = 0x28; break; |
---|
194 | | - case DRM_FORMAT_UYVY: asyw->image.format = 0x29; break; |
---|
| 208 | + case DRM_FORMAT_YUYV: |
---|
| 209 | + asyw->image.format = NV507E_SURFACE_SET_PARAMS_FORMAT_VE8YO8UE8YE8; |
---|
| 210 | + break; |
---|
| 211 | + case DRM_FORMAT_UYVY: |
---|
| 212 | + asyw->image.format = NV507E_SURFACE_SET_PARAMS_FORMAT_YO8VE8YE8UE8; |
---|
| 213 | + break; |
---|
195 | 214 | default: |
---|
196 | 215 | WARN_ON(1); |
---|
197 | 216 | return -EINVAL; |
---|
198 | 217 | } |
---|
199 | | - asyw->image.colorspace = 1; |
---|
| 218 | + |
---|
| 219 | + asyw->image.colorspace = NV507E_SURFACE_SET_PARAMS_COLOR_SPACE_YUV_601; |
---|
200 | 220 | return 0; |
---|
201 | 221 | } |
---|
202 | 222 | |
---|
.. | .. |
---|
204 | 224 | nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw) |
---|
205 | 225 | { |
---|
206 | 226 | switch (asyw->state.fb->format->format) { |
---|
207 | | - case DRM_FORMAT_C8 : asyw->image.format = 0x1e; break; |
---|
208 | | - case DRM_FORMAT_XRGB8888 : |
---|
209 | | - case DRM_FORMAT_ARGB8888 : asyw->image.format = 0xcf; break; |
---|
210 | | - case DRM_FORMAT_RGB565 : asyw->image.format = 0xe8; break; |
---|
211 | | - case DRM_FORMAT_XRGB1555 : |
---|
212 | | - case DRM_FORMAT_ARGB1555 : asyw->image.format = 0xe9; break; |
---|
| 227 | + case DRM_FORMAT_C8: |
---|
| 228 | + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_I8; |
---|
| 229 | + break; |
---|
| 230 | + case DRM_FORMAT_XRGB8888: |
---|
| 231 | + case DRM_FORMAT_ARGB8888: |
---|
| 232 | + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_A8R8G8B8; |
---|
| 233 | + break; |
---|
| 234 | + case DRM_FORMAT_RGB565: |
---|
| 235 | + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_R5G6B5; |
---|
| 236 | + break; |
---|
| 237 | + case DRM_FORMAT_XRGB1555: |
---|
| 238 | + case DRM_FORMAT_ARGB1555: |
---|
| 239 | + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_A1R5G5B5; |
---|
| 240 | + break; |
---|
213 | 241 | case DRM_FORMAT_XBGR2101010: |
---|
214 | | - case DRM_FORMAT_ABGR2101010: asyw->image.format = 0xd1; break; |
---|
215 | | - case DRM_FORMAT_XBGR8888 : |
---|
216 | | - case DRM_FORMAT_ABGR8888 : asyw->image.format = 0xd5; break; |
---|
| 242 | + case DRM_FORMAT_ABGR2101010: |
---|
| 243 | + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_A2B10G10R10; |
---|
| 244 | + break; |
---|
| 245 | + case DRM_FORMAT_XBGR8888: |
---|
| 246 | + case DRM_FORMAT_ABGR8888: |
---|
| 247 | + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_A8B8G8R8; |
---|
| 248 | + break; |
---|
217 | 249 | case DRM_FORMAT_XRGB2101010: |
---|
218 | | - case DRM_FORMAT_ARGB2101010: asyw->image.format = 0xdf; break; |
---|
| 250 | + case DRM_FORMAT_ARGB2101010: |
---|
| 251 | + asyw->image.format = NVC37E_SET_PARAMS_FORMAT_A2R10G10B10; |
---|
| 252 | + break; |
---|
| 253 | + case DRM_FORMAT_XBGR16161616F: |
---|
| 254 | + case DRM_FORMAT_ABGR16161616F: |
---|
| 255 | + asyw->image.format = NV507C_SURFACE_SET_PARAMS_FORMAT_RF16_GF16_BF16_AF16; |
---|
| 256 | + break; |
---|
219 | 257 | default: |
---|
220 | 258 | return -EINVAL; |
---|
221 | 259 | } |
---|
222 | | - asyw->image.colorspace = 0; |
---|
| 260 | + |
---|
| 261 | + asyw->image.colorspace = NV507E_SURFACE_SET_PARAMS_COLOR_SPACE_RGB; |
---|
223 | 262 | return 0; |
---|
224 | 263 | } |
---|
225 | 264 | |
---|
.. | .. |
---|
229 | 268 | struct nv50_wndw_atom *asyw, |
---|
230 | 269 | struct nv50_head_atom *asyh) |
---|
231 | 270 | { |
---|
232 | | - struct nouveau_framebuffer *fb = nouveau_framebuffer(asyw->state.fb); |
---|
| 271 | + struct drm_framebuffer *fb = asyw->state.fb; |
---|
233 | 272 | struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); |
---|
| 273 | + uint8_t kind; |
---|
| 274 | + uint32_t tile_mode; |
---|
234 | 275 | int ret; |
---|
235 | 276 | |
---|
236 | 277 | NV_ATOMIC(drm, "%s acquire\n", wndw->plane.name); |
---|
237 | 278 | |
---|
238 | | - if (asyw->state.fb != armw->state.fb || !armw->visible || modeset) { |
---|
239 | | - asyw->image.w = fb->base.width; |
---|
240 | | - asyw->image.h = fb->base.height; |
---|
241 | | - asyw->image.kind = fb->nvbo->kind; |
---|
| 279 | + if (fb != armw->state.fb || !armw->visible || modeset) { |
---|
| 280 | + nouveau_framebuffer_get_layout(fb, &tile_mode, &kind); |
---|
| 281 | + |
---|
| 282 | + asyw->image.w = fb->width; |
---|
| 283 | + asyw->image.h = fb->height; |
---|
| 284 | + asyw->image.kind = kind; |
---|
242 | 285 | |
---|
243 | 286 | ret = nv50_wndw_atomic_check_acquire_rgb(asyw); |
---|
244 | 287 | if (ret) { |
---|
.. | .. |
---|
248 | 291 | } |
---|
249 | 292 | |
---|
250 | 293 | if (asyw->image.kind) { |
---|
251 | | - asyw->image.layout = 0; |
---|
| 294 | + asyw->image.layout = NV507C_SURFACE_SET_STORAGE_MEMORY_LAYOUT_BLOCKLINEAR; |
---|
252 | 295 | if (drm->client.device.info.chipset >= 0xc0) |
---|
253 | | - asyw->image.blockh = fb->nvbo->mode >> 4; |
---|
| 296 | + asyw->image.blockh = tile_mode >> 4; |
---|
254 | 297 | else |
---|
255 | | - asyw->image.blockh = fb->nvbo->mode; |
---|
256 | | - asyw->image.blocks[0] = fb->base.pitches[0] / 64; |
---|
| 298 | + asyw->image.blockh = tile_mode; |
---|
| 299 | + asyw->image.blocks[0] = fb->pitches[0] / 64; |
---|
257 | 300 | asyw->image.pitch[0] = 0; |
---|
258 | 301 | } else { |
---|
259 | | - asyw->image.layout = 1; |
---|
260 | | - asyw->image.blockh = 0; |
---|
| 302 | + asyw->image.layout = NV507C_SURFACE_SET_STORAGE_MEMORY_LAYOUT_PITCH; |
---|
| 303 | + asyw->image.blockh = NV507C_SURFACE_SET_STORAGE_BLOCK_HEIGHT_ONE_GOB; |
---|
261 | 304 | asyw->image.blocks[0] = 0; |
---|
262 | | - asyw->image.pitch[0] = fb->base.pitches[0]; |
---|
| 305 | + asyw->image.pitch[0] = fb->pitches[0]; |
---|
263 | 306 | } |
---|
264 | 307 | |
---|
265 | | - if (!(asyh->state.pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC)) |
---|
| 308 | + if (!asyh->state.async_flip) |
---|
266 | 309 | asyw->image.interval = 1; |
---|
267 | 310 | else |
---|
268 | 311 | asyw->image.interval = 0; |
---|
269 | | - asyw->image.mode = asyw->image.interval ? 0 : 1; |
---|
| 312 | + |
---|
| 313 | + if (asyw->image.interval) |
---|
| 314 | + asyw->image.mode = NV507C_SET_PRESENT_CONTROL_BEGIN_MODE_NON_TEARING; |
---|
| 315 | + else |
---|
| 316 | + asyw->image.mode = NV507C_SET_PRESENT_CONTROL_BEGIN_MODE_IMMEDIATE; |
---|
| 317 | + |
---|
270 | 318 | asyw->set.image = wndw->func->image_set != NULL; |
---|
271 | 319 | } |
---|
272 | 320 | |
---|
.. | .. |
---|
281 | 329 | asyw->set.scale = true; |
---|
282 | 330 | } |
---|
283 | 331 | |
---|
| 332 | + if (wndw->func->blend_set) { |
---|
| 333 | + asyw->blend.depth = 255 - asyw->state.normalized_zpos; |
---|
| 334 | + asyw->blend.k1 = asyw->state.alpha >> 8; |
---|
| 335 | + switch (asyw->state.pixel_blend_mode) { |
---|
| 336 | + case DRM_MODE_BLEND_PREMULTI: |
---|
| 337 | + asyw->blend.src_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_SRC_COLOR_FACTOR_MATCH_SELECT_K1; |
---|
| 338 | + asyw->blend.dst_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_DST_COLOR_FACTOR_MATCH_SELECT_NEG_K1_TIMES_SRC; |
---|
| 339 | + break; |
---|
| 340 | + case DRM_MODE_BLEND_COVERAGE: |
---|
| 341 | + asyw->blend.src_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_SRC_COLOR_FACTOR_MATCH_SELECT_K1_TIMES_SRC; |
---|
| 342 | + asyw->blend.dst_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_DST_COLOR_FACTOR_MATCH_SELECT_NEG_K1_TIMES_SRC; |
---|
| 343 | + break; |
---|
| 344 | + case DRM_MODE_BLEND_PIXEL_NONE: |
---|
| 345 | + default: |
---|
| 346 | + asyw->blend.src_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_SRC_COLOR_FACTOR_MATCH_SELECT_K1; |
---|
| 347 | + asyw->blend.dst_color = NVC37E_SET_COMPOSITION_FACTOR_SELECT_DST_COLOR_FACTOR_MATCH_SELECT_NEG_K1; |
---|
| 348 | + break; |
---|
| 349 | + } |
---|
| 350 | + if (memcmp(&armw->blend, &asyw->blend, sizeof(asyw->blend))) |
---|
| 351 | + asyw->set.blend = true; |
---|
| 352 | + } |
---|
| 353 | + |
---|
284 | 354 | if (wndw->immd) { |
---|
285 | 355 | asyw->point.x = asyw->state.crtc_x; |
---|
286 | 356 | asyw->point.y = asyw->state.crtc_y; |
---|
.. | .. |
---|
291 | 361 | return wndw->func->acquire(wndw, asyw, asyh); |
---|
292 | 362 | } |
---|
293 | 363 | |
---|
294 | | -static void |
---|
| 364 | +static int |
---|
295 | 365 | nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw, |
---|
296 | 366 | struct nv50_wndw_atom *armw, |
---|
297 | 367 | struct nv50_wndw_atom *asyw, |
---|
.. | .. |
---|
313 | 383 | */ |
---|
314 | 384 | if (!(ilut = asyh->state.gamma_lut)) { |
---|
315 | 385 | asyw->visible = false; |
---|
316 | | - return; |
---|
| 386 | + return 0; |
---|
317 | 387 | } |
---|
318 | 388 | |
---|
319 | 389 | if (wndw->func->ilut) |
---|
.. | .. |
---|
322 | 392 | asyh->wndw.olut &= ~BIT(wndw->id); |
---|
323 | 393 | } |
---|
324 | 394 | |
---|
| 395 | + if (!ilut && wndw->func->ilut_identity && |
---|
| 396 | + asyw->state.fb->format->format != DRM_FORMAT_XBGR16161616F && |
---|
| 397 | + asyw->state.fb->format->format != DRM_FORMAT_ABGR16161616F) { |
---|
| 398 | + static struct drm_property_blob dummy = {}; |
---|
| 399 | + ilut = &dummy; |
---|
| 400 | + } |
---|
| 401 | + |
---|
325 | 402 | /* Recalculate LUT state. */ |
---|
326 | 403 | memset(&asyw->xlut, 0x00, sizeof(asyw->xlut)); |
---|
327 | 404 | if ((asyw->ilut = wndw->func->ilut ? ilut : NULL)) { |
---|
328 | | - wndw->func->ilut(wndw, asyw); |
---|
| 405 | + if (!wndw->func->ilut(wndw, asyw, drm_color_lut_size(ilut))) { |
---|
| 406 | + DRM_DEBUG_KMS("Invalid ilut\n"); |
---|
| 407 | + return -EINVAL; |
---|
| 408 | + } |
---|
329 | 409 | asyw->xlut.handle = wndw->wndw.vram.handle; |
---|
330 | 410 | asyw->xlut.i.buffer = !asyw->xlut.i.buffer; |
---|
331 | 411 | asyw->set.xlut = true; |
---|
| 412 | + } else { |
---|
| 413 | + asyw->clr.xlut = armw->xlut.handle != 0; |
---|
332 | 414 | } |
---|
333 | 415 | |
---|
334 | 416 | /* Handle setting base SET_OUTPUT_LUT_LO_ENABLE_USE_CORE_LUT. */ |
---|
.. | .. |
---|
336 | 418 | (!armw->visible || (armw->xlut.handle && !asyw->xlut.handle))) |
---|
337 | 419 | asyw->set.xlut = true; |
---|
338 | 420 | |
---|
| 421 | + if (wndw->func->csc && asyh->state.ctm) { |
---|
| 422 | + const struct drm_color_ctm *ctm = asyh->state.ctm->data; |
---|
| 423 | + wndw->func->csc(wndw, asyw, ctm); |
---|
| 424 | + asyw->csc.valid = true; |
---|
| 425 | + asyw->set.csc = true; |
---|
| 426 | + } else { |
---|
| 427 | + asyw->csc.valid = false; |
---|
| 428 | + asyw->clr.csc = armw->csc.valid; |
---|
| 429 | + } |
---|
| 430 | + |
---|
339 | 431 | /* Can't do an immediate flip while changing the LUT. */ |
---|
340 | | - asyh->state.pageflip_flags &= ~DRM_MODE_PAGE_FLIP_ASYNC; |
---|
| 432 | + asyh->state.async_flip = false; |
---|
| 433 | + return 0; |
---|
341 | 434 | } |
---|
342 | 435 | |
---|
343 | 436 | static int |
---|
.. | .. |
---|
378 | 471 | (!armw->visible || |
---|
379 | 472 | asyh->state.color_mgmt_changed || |
---|
380 | 473 | asyw->state.fb->format->format != |
---|
381 | | - armw->state.fb->format->format)) |
---|
382 | | - nv50_wndw_atomic_check_lut(wndw, armw, asyw, asyh); |
---|
| 474 | + armw->state.fb->format->format)) { |
---|
| 475 | + ret = nv50_wndw_atomic_check_lut(wndw, armw, asyw, asyh); |
---|
| 476 | + if (ret) |
---|
| 477 | + return ret; |
---|
| 478 | + } |
---|
383 | 479 | |
---|
384 | 480 | /* Calculate new window state. */ |
---|
385 | 481 | if (asyw->visible) { |
---|
.. | .. |
---|
407 | 503 | asyw->clr.xlut = armw->xlut.handle != 0; |
---|
408 | 504 | if (asyw->clr.xlut && asyw->visible) |
---|
409 | 505 | asyw->set.xlut = asyw->xlut.handle != 0; |
---|
| 506 | + asyw->clr.csc = armw->csc.valid; |
---|
410 | 507 | if (wndw->func->image_clr) |
---|
411 | 508 | asyw->clr.image = armw->image.handle[0] != 0; |
---|
412 | 509 | } |
---|
.. | .. |
---|
417 | 514 | static void |
---|
418 | 515 | nv50_wndw_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *old_state) |
---|
419 | 516 | { |
---|
420 | | - struct nouveau_framebuffer *fb = nouveau_framebuffer(old_state->fb); |
---|
421 | 517 | struct nouveau_drm *drm = nouveau_drm(plane->dev); |
---|
| 518 | + struct nouveau_bo *nvbo; |
---|
422 | 519 | |
---|
423 | 520 | NV_ATOMIC(drm, "%s cleanup: %p\n", plane->name, old_state->fb); |
---|
424 | 521 | if (!old_state->fb) |
---|
425 | 522 | return; |
---|
426 | 523 | |
---|
427 | | - nouveau_bo_unpin(fb->nvbo); |
---|
| 524 | + nvbo = nouveau_gem_object(old_state->fb->obj[0]); |
---|
| 525 | + nouveau_bo_unpin(nvbo); |
---|
428 | 526 | } |
---|
429 | 527 | |
---|
430 | 528 | static int |
---|
431 | 529 | nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) |
---|
432 | 530 | { |
---|
433 | | - struct nouveau_framebuffer *fb = nouveau_framebuffer(state->fb); |
---|
| 531 | + struct drm_framebuffer *fb = state->fb; |
---|
434 | 532 | struct nouveau_drm *drm = nouveau_drm(plane->dev); |
---|
435 | 533 | struct nv50_wndw *wndw = nv50_wndw(plane); |
---|
436 | 534 | struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); |
---|
| 535 | + struct nouveau_bo *nvbo; |
---|
437 | 536 | struct nv50_head_atom *asyh; |
---|
438 | 537 | struct nv50_wndw_ctxdma *ctxdma; |
---|
439 | 538 | int ret; |
---|
440 | 539 | |
---|
441 | | - NV_ATOMIC(drm, "%s prepare: %p\n", plane->name, state->fb); |
---|
| 540 | + NV_ATOMIC(drm, "%s prepare: %p\n", plane->name, fb); |
---|
442 | 541 | if (!asyw->state.fb) |
---|
443 | 542 | return 0; |
---|
444 | 543 | |
---|
445 | | - ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM, true); |
---|
| 544 | + nvbo = nouveau_gem_object(fb->obj[0]); |
---|
| 545 | + ret = nouveau_bo_pin(nvbo, NOUVEAU_GEM_DOMAIN_VRAM, true); |
---|
446 | 546 | if (ret) |
---|
447 | 547 | return ret; |
---|
448 | 548 | |
---|
449 | 549 | if (wndw->ctxdma.parent) { |
---|
450 | 550 | ctxdma = nv50_wndw_ctxdma_new(wndw, fb); |
---|
451 | 551 | if (IS_ERR(ctxdma)) { |
---|
452 | | - nouveau_bo_unpin(fb->nvbo); |
---|
| 552 | + nouveau_bo_unpin(nvbo); |
---|
453 | 553 | return PTR_ERR(ctxdma); |
---|
454 | 554 | } |
---|
455 | 555 | |
---|
456 | | - asyw->image.handle[0] = ctxdma->object.handle; |
---|
| 556 | + if (asyw->visible) |
---|
| 557 | + asyw->image.handle[0] = ctxdma->object.handle; |
---|
457 | 558 | } |
---|
458 | 559 | |
---|
459 | | - asyw->state.fence = reservation_object_get_excl_rcu(fb->nvbo->bo.resv); |
---|
460 | | - asyw->image.offset[0] = fb->nvbo->bo.offset; |
---|
| 560 | + asyw->state.fence = dma_resv_get_excl_rcu(nvbo->bo.base.resv); |
---|
| 561 | + asyw->image.offset[0] = nvbo->offset; |
---|
461 | 562 | |
---|
462 | 563 | if (wndw->func->prepare) { |
---|
463 | 564 | asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc); |
---|
.. | .. |
---|
498 | 599 | asyw->ntfy = armw->ntfy; |
---|
499 | 600 | asyw->ilut = NULL; |
---|
500 | 601 | asyw->xlut = armw->xlut; |
---|
| 602 | + asyw->csc = armw->csc; |
---|
501 | 603 | asyw->image = armw->image; |
---|
502 | 604 | asyw->point = armw->point; |
---|
503 | 605 | asyw->clr.mask = 0; |
---|
504 | 606 | asyw->set.mask = 0; |
---|
505 | 607 | return &asyw->state; |
---|
| 608 | +} |
---|
| 609 | + |
---|
| 610 | +static int |
---|
| 611 | +nv50_wndw_zpos_default(struct drm_plane *plane) |
---|
| 612 | +{ |
---|
| 613 | + return (plane->type == DRM_PLANE_TYPE_PRIMARY) ? 0 : |
---|
| 614 | + (plane->type == DRM_PLANE_TYPE_OVERLAY) ? 1 : 255; |
---|
506 | 615 | } |
---|
507 | 616 | |
---|
508 | 617 | static void |
---|
.. | .. |
---|
515 | 624 | |
---|
516 | 625 | if (plane->state) |
---|
517 | 626 | plane->funcs->atomic_destroy_state(plane, plane->state); |
---|
518 | | - plane->state = &asyw->state; |
---|
519 | | - plane->state->plane = plane; |
---|
520 | | - plane->state->rotation = DRM_MODE_ROTATE_0; |
---|
| 627 | + |
---|
| 628 | + __drm_atomic_helper_plane_reset(plane, &asyw->state); |
---|
| 629 | + plane->state->zpos = nv50_wndw_zpos_default(plane); |
---|
| 630 | + plane->state->normalized_zpos = nv50_wndw_zpos_default(plane); |
---|
521 | 631 | } |
---|
522 | 632 | |
---|
523 | 633 | static void |
---|
.. | .. |
---|
530 | 640 | nv50_wndw_ctxdma_del(ctxdma); |
---|
531 | 641 | } |
---|
532 | 642 | |
---|
533 | | - nvif_notify_fini(&wndw->notify); |
---|
| 643 | + nvif_notify_dtor(&wndw->notify); |
---|
534 | 644 | nv50_dmac_destroy(&wndw->wimm); |
---|
535 | 645 | nv50_dmac_destroy(&wndw->wndw); |
---|
536 | 646 | |
---|
.. | .. |
---|
538 | 648 | |
---|
539 | 649 | drm_plane_cleanup(&wndw->plane); |
---|
540 | 650 | kfree(wndw); |
---|
| 651 | +} |
---|
| 652 | + |
---|
| 653 | +/* This function assumes the format has already been validated against the plane |
---|
| 654 | + * and the modifier was validated against the device-wides modifier list at FB |
---|
| 655 | + * creation time. |
---|
| 656 | + */ |
---|
| 657 | +static bool nv50_plane_format_mod_supported(struct drm_plane *plane, |
---|
| 658 | + u32 format, u64 modifier) |
---|
| 659 | +{ |
---|
| 660 | + struct nouveau_drm *drm = nouveau_drm(plane->dev); |
---|
| 661 | + uint8_t i; |
---|
| 662 | + |
---|
| 663 | + if (drm->client.device.info.chipset < 0xc0) { |
---|
| 664 | + const struct drm_format_info *info = drm_format_info(format); |
---|
| 665 | + const uint8_t kind = (modifier >> 12) & 0xff; |
---|
| 666 | + |
---|
| 667 | + if (!format) return false; |
---|
| 668 | + |
---|
| 669 | + for (i = 0; i < info->num_planes; i++) |
---|
| 670 | + if ((info->cpp[i] != 4) && kind != 0x70) return false; |
---|
| 671 | + } |
---|
| 672 | + |
---|
| 673 | + return true; |
---|
541 | 674 | } |
---|
542 | 675 | |
---|
543 | 676 | const struct drm_plane_funcs |
---|
.. | .. |
---|
548 | 681 | .reset = nv50_wndw_reset, |
---|
549 | 682 | .atomic_duplicate_state = nv50_wndw_atomic_duplicate_state, |
---|
550 | 683 | .atomic_destroy_state = nv50_wndw_atomic_destroy_state, |
---|
| 684 | + .format_mod_supported = nv50_plane_format_mod_supported, |
---|
551 | 685 | }; |
---|
552 | 686 | |
---|
553 | 687 | static int |
---|
.. | .. |
---|
556 | 690 | return NVIF_NOTIFY_KEEP; |
---|
557 | 691 | } |
---|
558 | 692 | |
---|
559 | | -void |
---|
560 | | -nv50_wndw_fini(struct nv50_wndw *wndw) |
---|
561 | | -{ |
---|
562 | | - nvif_notify_put(&wndw->notify); |
---|
563 | | -} |
---|
564 | | - |
---|
565 | | -void |
---|
566 | | -nv50_wndw_init(struct nv50_wndw *wndw) |
---|
567 | | -{ |
---|
568 | | - nvif_notify_get(&wndw->notify); |
---|
569 | | -} |
---|
| 693 | +static const u64 nv50_cursor_format_modifiers[] = { |
---|
| 694 | + DRM_FORMAT_MOD_LINEAR, |
---|
| 695 | + DRM_FORMAT_MOD_INVALID, |
---|
| 696 | +}; |
---|
570 | 697 | |
---|
571 | 698 | int |
---|
572 | 699 | nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, |
---|
.. | .. |
---|
579 | 706 | struct nvif_mmu *mmu = &drm->client.mmu; |
---|
580 | 707 | struct nv50_disp *disp = nv50_disp(dev); |
---|
581 | 708 | struct nv50_wndw *wndw; |
---|
| 709 | + const u64 *format_modifiers; |
---|
582 | 710 | int nformat; |
---|
583 | 711 | int ret; |
---|
584 | 712 | |
---|
.. | .. |
---|
594 | 722 | |
---|
595 | 723 | for (nformat = 0; format[nformat]; nformat++); |
---|
596 | 724 | |
---|
597 | | - ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw, |
---|
598 | | - format, nformat, NULL, |
---|
599 | | - type, "%s-%d", name, index); |
---|
| 725 | + if (type == DRM_PLANE_TYPE_CURSOR) |
---|
| 726 | + format_modifiers = nv50_cursor_format_modifiers; |
---|
| 727 | + else |
---|
| 728 | + format_modifiers = nouveau_display(dev)->format_modifiers; |
---|
| 729 | + |
---|
| 730 | + ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw, format, nformat, |
---|
| 731 | + format_modifiers, type, "%s-%d", name, index); |
---|
600 | 732 | if (ret) { |
---|
601 | 733 | kfree(*pwndw); |
---|
602 | 734 | *pwndw = NULL; |
---|
.. | .. |
---|
612 | 744 | } |
---|
613 | 745 | |
---|
614 | 746 | wndw->notify.func = nv50_wndw_notify; |
---|
| 747 | + |
---|
| 748 | + if (wndw->func->blend_set) { |
---|
| 749 | + ret = drm_plane_create_zpos_property(&wndw->plane, |
---|
| 750 | + nv50_wndw_zpos_default(&wndw->plane), 0, 254); |
---|
| 751 | + if (ret) |
---|
| 752 | + return ret; |
---|
| 753 | + |
---|
| 754 | + ret = drm_plane_create_alpha_property(&wndw->plane); |
---|
| 755 | + if (ret) |
---|
| 756 | + return ret; |
---|
| 757 | + |
---|
| 758 | + ret = drm_plane_create_blend_mode_property(&wndw->plane, |
---|
| 759 | + BIT(DRM_MODE_BLEND_PIXEL_NONE) | |
---|
| 760 | + BIT(DRM_MODE_BLEND_PREMULTI) | |
---|
| 761 | + BIT(DRM_MODE_BLEND_COVERAGE)); |
---|
| 762 | + if (ret) |
---|
| 763 | + return ret; |
---|
| 764 | + } else { |
---|
| 765 | + ret = drm_plane_create_zpos_immutable_property(&wndw->plane, |
---|
| 766 | + nv50_wndw_zpos_default(&wndw->plane)); |
---|
| 767 | + if (ret) |
---|
| 768 | + return ret; |
---|
| 769 | + } |
---|
| 770 | + |
---|
615 | 771 | return 0; |
---|
616 | 772 | } |
---|
617 | 773 | |
---|
.. | .. |
---|
625 | 781 | int (*new)(struct nouveau_drm *, enum drm_plane_type, |
---|
626 | 782 | int, s32, struct nv50_wndw **); |
---|
627 | 783 | } wndws[] = { |
---|
| 784 | + { TU102_DISP_WINDOW_CHANNEL_DMA, 0, wndwc57e_new }, |
---|
628 | 785 | { GV100_DISP_WINDOW_CHANNEL_DMA, 0, wndwc37e_new }, |
---|
629 | 786 | {} |
---|
630 | 787 | }; |
---|