hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/gpu/drm/nouveau/dispnv50/wndw.c
....@@ -21,28 +21,37 @@
2121 */
2222 #include "wndw.h"
2323 #include "wimm.h"
24
+#include "handles.h"
2425
2526 #include <nvif/class.h>
2627 #include <nvif/cl0002.h>
2728
29
+#include <nvhw/class/cl507c.h>
30
+#include <nvhw/class/cl507e.h>
31
+#include <nvhw/class/clc37e.h>
32
+
2833 #include <drm/drm_atomic_helper.h>
34
+#include <drm/drm_fourcc.h>
35
+
2936 #include "nouveau_bo.h"
37
+#include "nouveau_gem.h"
3038
3139 static void
3240 nv50_wndw_ctxdma_del(struct nv50_wndw_ctxdma *ctxdma)
3341 {
34
- nvif_object_fini(&ctxdma->object);
42
+ nvif_object_dtor(&ctxdma->object);
3543 list_del(&ctxdma->head);
3644 kfree(ctxdma);
3745 }
3846
3947 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)
4149 {
42
- struct nouveau_drm *drm = nouveau_drm(fb->base.dev);
50
+ struct nouveau_drm *drm = nouveau_drm(fb->dev);
4351 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;
4655 struct {
4756 struct nv_dma_v0 base;
4857 union {
....@@ -53,6 +62,9 @@
5362 } args = {};
5463 u32 argc = sizeof(args.base);
5564 int ret;
65
+
66
+ nouveau_framebuffer_get_layout(fb, &unused, &kind);
67
+ handle = NV50_DISP_HANDLE_WNDW_CTX(kind);
5668
5769 list_for_each_entry(ctxdma, &wndw->ctxdma.list, head) {
5870 if (ctxdma->object.handle == handle)
....@@ -86,8 +98,8 @@
8698 argc += sizeof(args.gf119);
8799 }
88100
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);
91103 if (ret) {
92104 nv50_wndw_ctxdma_del(ctxdma);
93105 return ERR_PTR(ret);
....@@ -118,6 +130,7 @@
118130 if (clr.sema ) wndw->func-> sema_clr(wndw);
119131 if (clr.ntfy ) wndw->func-> ntfy_clr(wndw);
120132 if (clr.xlut ) wndw->func-> xlut_clr(wndw);
133
+ if (clr.csc ) wndw->func-> csc_clr(wndw);
121134 if (clr.image) wndw->func->image_clr(wndw);
122135
123136 interlock[wndw->interlock.type] |= wndw->interlock.data;
....@@ -127,8 +140,8 @@
127140 nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock,
128141 struct nv50_wndw_atom *asyw)
129142 {
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;
132145 asyw->image.interval = 1;
133146 }
134147
....@@ -139,15 +152,15 @@
139152 if (asyw->set.xlut ) {
140153 if (asyw->ilut) {
141154 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);
146157 }
147158 wndw->func->xlut_set(wndw, asyw);
148159 }
149160
161
+ if (asyw->set.csc ) wndw->func->csc_set (wndw, asyw);
150162 if (asyw->set.scale) wndw->func->scale_set(wndw, asyw);
163
+ if (asyw->set.blend) wndw->func->blend_set(wndw, asyw);
151164 if (asyw->set.point) {
152165 if (asyw->set.point = false, asyw->set.mask)
153166 interlock[wndw->interlock.type] |= wndw->interlock.data;
....@@ -184,19 +197,26 @@
184197 wndw->func->release(wndw, asyw, asyh);
185198 asyw->ntfy.handle = 0;
186199 asyw->sema.handle = 0;
200
+ asyw->xlut.handle = 0;
201
+ memset(asyw->image.handle, 0x00, sizeof(asyw->image.handle));
187202 }
188203
189204 static int
190205 nv50_wndw_atomic_check_acquire_yuv(struct nv50_wndw_atom *asyw)
191206 {
192207 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;
195214 default:
196215 WARN_ON(1);
197216 return -EINVAL;
198217 }
199
- asyw->image.colorspace = 1;
218
+
219
+ asyw->image.colorspace = NV507E_SURFACE_SET_PARAMS_COLOR_SPACE_YUV_601;
200220 return 0;
201221 }
202222
....@@ -204,22 +224,41 @@
204224 nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw)
205225 {
206226 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;
213241 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;
217249 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;
219257 default:
220258 return -EINVAL;
221259 }
222
- asyw->image.colorspace = 0;
260
+
261
+ asyw->image.colorspace = NV507E_SURFACE_SET_PARAMS_COLOR_SPACE_RGB;
223262 return 0;
224263 }
225264
....@@ -229,16 +268,20 @@
229268 struct nv50_wndw_atom *asyw,
230269 struct nv50_head_atom *asyh)
231270 {
232
- struct nouveau_framebuffer *fb = nouveau_framebuffer(asyw->state.fb);
271
+ struct drm_framebuffer *fb = asyw->state.fb;
233272 struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev);
273
+ uint8_t kind;
274
+ uint32_t tile_mode;
234275 int ret;
235276
236277 NV_ATOMIC(drm, "%s acquire\n", wndw->plane.name);
237278
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;
242285
243286 ret = nv50_wndw_atomic_check_acquire_rgb(asyw);
244287 if (ret) {
....@@ -248,25 +291,30 @@
248291 }
249292
250293 if (asyw->image.kind) {
251
- asyw->image.layout = 0;
294
+ asyw->image.layout = NV507C_SURFACE_SET_STORAGE_MEMORY_LAYOUT_BLOCKLINEAR;
252295 if (drm->client.device.info.chipset >= 0xc0)
253
- asyw->image.blockh = fb->nvbo->mode >> 4;
296
+ asyw->image.blockh = tile_mode >> 4;
254297 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;
257300 asyw->image.pitch[0] = 0;
258301 } 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;
261304 asyw->image.blocks[0] = 0;
262
- asyw->image.pitch[0] = fb->base.pitches[0];
305
+ asyw->image.pitch[0] = fb->pitches[0];
263306 }
264307
265
- if (!(asyh->state.pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC))
308
+ if (!asyh->state.async_flip)
266309 asyw->image.interval = 1;
267310 else
268311 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
+
270318 asyw->set.image = wndw->func->image_set != NULL;
271319 }
272320
....@@ -281,6 +329,28 @@
281329 asyw->set.scale = true;
282330 }
283331
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
+
284354 if (wndw->immd) {
285355 asyw->point.x = asyw->state.crtc_x;
286356 asyw->point.y = asyw->state.crtc_y;
....@@ -291,7 +361,7 @@
291361 return wndw->func->acquire(wndw, asyw, asyh);
292362 }
293363
294
-static void
364
+static int
295365 nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw,
296366 struct nv50_wndw_atom *armw,
297367 struct nv50_wndw_atom *asyw,
....@@ -313,7 +383,7 @@
313383 */
314384 if (!(ilut = asyh->state.gamma_lut)) {
315385 asyw->visible = false;
316
- return;
386
+ return 0;
317387 }
318388
319389 if (wndw->func->ilut)
....@@ -322,13 +392,25 @@
322392 asyh->wndw.olut &= ~BIT(wndw->id);
323393 }
324394
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
+
325402 /* Recalculate LUT state. */
326403 memset(&asyw->xlut, 0x00, sizeof(asyw->xlut));
327404 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
+ }
329409 asyw->xlut.handle = wndw->wndw.vram.handle;
330410 asyw->xlut.i.buffer = !asyw->xlut.i.buffer;
331411 asyw->set.xlut = true;
412
+ } else {
413
+ asyw->clr.xlut = armw->xlut.handle != 0;
332414 }
333415
334416 /* Handle setting base SET_OUTPUT_LUT_LO_ENABLE_USE_CORE_LUT. */
....@@ -336,8 +418,19 @@
336418 (!armw->visible || (armw->xlut.handle && !asyw->xlut.handle)))
337419 asyw->set.xlut = true;
338420
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
+
339431 /* 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;
341434 }
342435
343436 static int
....@@ -378,8 +471,11 @@
378471 (!armw->visible ||
379472 asyh->state.color_mgmt_changed ||
380473 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
+ }
383479
384480 /* Calculate new window state. */
385481 if (asyw->visible) {
....@@ -407,6 +503,7 @@
407503 asyw->clr.xlut = armw->xlut.handle != 0;
408504 if (asyw->clr.xlut && asyw->visible)
409505 asyw->set.xlut = asyw->xlut.handle != 0;
506
+ asyw->clr.csc = armw->csc.valid;
410507 if (wndw->func->image_clr)
411508 asyw->clr.image = armw->image.handle[0] != 0;
412509 }
....@@ -417,47 +514,51 @@
417514 static void
418515 nv50_wndw_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *old_state)
419516 {
420
- struct nouveau_framebuffer *fb = nouveau_framebuffer(old_state->fb);
421517 struct nouveau_drm *drm = nouveau_drm(plane->dev);
518
+ struct nouveau_bo *nvbo;
422519
423520 NV_ATOMIC(drm, "%s cleanup: %p\n", plane->name, old_state->fb);
424521 if (!old_state->fb)
425522 return;
426523
427
- nouveau_bo_unpin(fb->nvbo);
524
+ nvbo = nouveau_gem_object(old_state->fb->obj[0]);
525
+ nouveau_bo_unpin(nvbo);
428526 }
429527
430528 static int
431529 nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state)
432530 {
433
- struct nouveau_framebuffer *fb = nouveau_framebuffer(state->fb);
531
+ struct drm_framebuffer *fb = state->fb;
434532 struct nouveau_drm *drm = nouveau_drm(plane->dev);
435533 struct nv50_wndw *wndw = nv50_wndw(plane);
436534 struct nv50_wndw_atom *asyw = nv50_wndw_atom(state);
535
+ struct nouveau_bo *nvbo;
437536 struct nv50_head_atom *asyh;
438537 struct nv50_wndw_ctxdma *ctxdma;
439538 int ret;
440539
441
- NV_ATOMIC(drm, "%s prepare: %p\n", plane->name, state->fb);
540
+ NV_ATOMIC(drm, "%s prepare: %p\n", plane->name, fb);
442541 if (!asyw->state.fb)
443542 return 0;
444543
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);
446546 if (ret)
447547 return ret;
448548
449549 if (wndw->ctxdma.parent) {
450550 ctxdma = nv50_wndw_ctxdma_new(wndw, fb);
451551 if (IS_ERR(ctxdma)) {
452
- nouveau_bo_unpin(fb->nvbo);
552
+ nouveau_bo_unpin(nvbo);
453553 return PTR_ERR(ctxdma);
454554 }
455555
456
- asyw->image.handle[0] = ctxdma->object.handle;
556
+ if (asyw->visible)
557
+ asyw->image.handle[0] = ctxdma->object.handle;
457558 }
458559
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;
461562
462563 if (wndw->func->prepare) {
463564 asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc);
....@@ -498,11 +599,19 @@
498599 asyw->ntfy = armw->ntfy;
499600 asyw->ilut = NULL;
500601 asyw->xlut = armw->xlut;
602
+ asyw->csc = armw->csc;
501603 asyw->image = armw->image;
502604 asyw->point = armw->point;
503605 asyw->clr.mask = 0;
504606 asyw->set.mask = 0;
505607 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;
506615 }
507616
508617 static void
....@@ -515,9 +624,10 @@
515624
516625 if (plane->state)
517626 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);
521631 }
522632
523633 static void
....@@ -530,7 +640,7 @@
530640 nv50_wndw_ctxdma_del(ctxdma);
531641 }
532642
533
- nvif_notify_fini(&wndw->notify);
643
+ nvif_notify_dtor(&wndw->notify);
534644 nv50_dmac_destroy(&wndw->wimm);
535645 nv50_dmac_destroy(&wndw->wndw);
536646
....@@ -538,6 +648,29 @@
538648
539649 drm_plane_cleanup(&wndw->plane);
540650 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;
541674 }
542675
543676 const struct drm_plane_funcs
....@@ -548,6 +681,7 @@
548681 .reset = nv50_wndw_reset,
549682 .atomic_duplicate_state = nv50_wndw_atomic_duplicate_state,
550683 .atomic_destroy_state = nv50_wndw_atomic_destroy_state,
684
+ .format_mod_supported = nv50_plane_format_mod_supported,
551685 };
552686
553687 static int
....@@ -556,17 +690,10 @@
556690 return NVIF_NOTIFY_KEEP;
557691 }
558692
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
+};
570697
571698 int
572699 nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
....@@ -579,6 +706,7 @@
579706 struct nvif_mmu *mmu = &drm->client.mmu;
580707 struct nv50_disp *disp = nv50_disp(dev);
581708 struct nv50_wndw *wndw;
709
+ const u64 *format_modifiers;
582710 int nformat;
583711 int ret;
584712
....@@ -594,9 +722,13 @@
594722
595723 for (nformat = 0; format[nformat]; nformat++);
596724
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);
600732 if (ret) {
601733 kfree(*pwndw);
602734 *pwndw = NULL;
....@@ -612,6 +744,30 @@
612744 }
613745
614746 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
+
615771 return 0;
616772 }
617773
....@@ -625,6 +781,7 @@
625781 int (*new)(struct nouveau_drm *, enum drm_plane_type,
626782 int, s32, struct nv50_wndw **);
627783 } wndws[] = {
784
+ { TU102_DISP_WINDOW_CHANNEL_DMA, 0, wndwc57e_new },
628785 { GV100_DISP_WINDOW_CHANNEL_DMA, 0, wndwc37e_new },
629786 {}
630787 };