aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2018-01-12 02:10:49 -0500
committerBen Skeggs <bskeggs@redhat.com>2018-02-02 00:24:06 -0500
commit11fc017dfb1efffa93d803f7182d026962ea2aae (patch)
tree3fc4eae59bc63cc115e12b33c2b6c3bd29d5c1e3
parent561464ea543c2f39f07ac2da91043555fa133601 (diff)
drm/nouveau/kms/nv50: prepare for double-buffered LUTs
We need to double-buffer LUTs to handle their update atomically. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_crtc.h1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c37
2 files changed, 15 insertions, 23 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h
index b7a18fbee6dc..366acb928f57 100644
--- a/drivers/gpu/drm/nouveau/nouveau_crtc.h
+++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h
@@ -60,7 +60,6 @@ struct nouveau_crtc {
60 } cursor; 60 } cursor;
61 61
62 struct { 62 struct {
63 struct nouveau_bo *nvbo;
64 int depth; 63 int depth;
65 } lut; 64 } lut;
66 65
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index b22c37bde13f..2293b8ff56c6 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -660,6 +660,9 @@ nv50_ovly_create(struct nvif_device *device, struct nvif_object *disp,
660 660
661struct nv50_head { 661struct nv50_head {
662 struct nouveau_crtc base; 662 struct nouveau_crtc base;
663 struct {
664 struct nouveau_bo *nvbo[1];
665 } lut;
663 struct nv50_ovly ovly; 666 struct nv50_ovly ovly;
664 struct nv50_oimm oimm; 667 struct nv50_oimm oimm;
665}; 668};
@@ -2162,7 +2165,7 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
2162 asyh->core.block = 0; 2165 asyh->core.block = 0;
2163 asyh->core.pitch = ALIGN(asyh->core.w, 64) * 4; 2166 asyh->core.pitch = ALIGN(asyh->core.w, 64) * 4;
2164 asyh->lut.handle = disp->mast.base.vram.handle; 2167 asyh->lut.handle = disp->mast.base.vram.handle;
2165 asyh->lut.offset = head->base.lut.nvbo->bo.offset; 2168 asyh->lut.offset = head->lut.nvbo[0]->bo.offset;
2166 asyh->set.base = armh->base.cpp != asyh->base.cpp; 2169 asyh->set.base = armh->base.cpp != asyh->base.cpp;
2167 asyh->set.ovly = armh->ovly.cpp != asyh->ovly.cpp; 2170 asyh->set.ovly = armh->ovly.cpp != asyh->ovly.cpp;
2168 } else { 2171 } else {
@@ -2204,8 +2207,8 @@ static void
2204nv50_head_lut_load(struct drm_crtc *crtc) 2207nv50_head_lut_load(struct drm_crtc *crtc)
2205{ 2208{
2206 struct nv50_disp *disp = nv50_disp(crtc->dev); 2209 struct nv50_disp *disp = nv50_disp(crtc->dev);
2207 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 2210 struct nv50_head *head = nv50_head(crtc);
2208 void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo); 2211 void __iomem *lut = nvbo_kmap_obj_iovirtual(head->lut.nvbo[0]);
2209 u16 *r, *g, *b; 2212 u16 *r, *g, *b;
2210 int i; 2213 int i;
2211 2214
@@ -2296,17 +2299,15 @@ nv50_head_reset(struct drm_crtc *crtc)
2296static void 2299static void
2297nv50_head_destroy(struct drm_crtc *crtc) 2300nv50_head_destroy(struct drm_crtc *crtc)
2298{ 2301{
2299 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
2300 struct nv50_disp *disp = nv50_disp(crtc->dev); 2302 struct nv50_disp *disp = nv50_disp(crtc->dev);
2301 struct nv50_head *head = nv50_head(crtc); 2303 struct nv50_head *head = nv50_head(crtc);
2304 int i;
2302 2305
2303 nv50_dmac_destroy(&head->ovly.base, disp->disp); 2306 nv50_dmac_destroy(&head->ovly.base, disp->disp);
2304 nv50_pioc_destroy(&head->oimm.base); 2307 nv50_pioc_destroy(&head->oimm.base);
2305 2308
2306 nouveau_bo_unmap(nv_crtc->lut.nvbo); 2309 for (i = 0; i < ARRAY_SIZE(head->lut.nvbo); i++)
2307 if (nv_crtc->lut.nvbo) 2310 nouveau_bo_unmap_unpin_unref(&head->lut.nvbo[i]);
2308 nouveau_bo_unpin(nv_crtc->lut.nvbo);
2309 nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
2310 2311
2311 drm_crtc_cleanup(crtc); 2312 drm_crtc_cleanup(crtc);
2312 kfree(crtc); 2313 kfree(crtc);
@@ -2333,7 +2334,7 @@ nv50_head_create(struct drm_device *dev, int index)
2333 struct nv50_base *base; 2334 struct nv50_base *base;
2334 struct nv50_curs *curs; 2335 struct nv50_curs *curs;
2335 struct drm_crtc *crtc; 2336 struct drm_crtc *crtc;
2336 int ret; 2337 int ret, i;
2337 2338
2338 head = kzalloc(sizeof(*head), GFP_KERNEL); 2339 head = kzalloc(sizeof(*head), GFP_KERNEL);
2339 if (!head) 2340 if (!head)
@@ -2355,22 +2356,14 @@ nv50_head_create(struct drm_device *dev, int index)
2355 drm_crtc_helper_add(crtc, &nv50_head_help); 2356 drm_crtc_helper_add(crtc, &nv50_head_help);
2356 drm_mode_crtc_set_gamma_size(crtc, 256); 2357 drm_mode_crtc_set_gamma_size(crtc, 256);
2357 2358
2358 ret = nouveau_bo_new(&drm->client, 8192, 0x100, TTM_PL_FLAG_VRAM, 2359 for (i = 0; i < ARRAY_SIZE(head->lut.nvbo); i++) {
2359 0, 0x0000, NULL, NULL, &head->base.lut.nvbo); 2360 ret = nouveau_bo_new_pin_map(&drm->client, 1025 * 8, 0x100,
2360 if (!ret) { 2361 TTM_PL_FLAG_VRAM,
2361 ret = nouveau_bo_pin(head->base.lut.nvbo, TTM_PL_FLAG_VRAM, true); 2362 &head->lut.nvbo[i]);
2362 if (!ret) {
2363 ret = nouveau_bo_map(head->base.lut.nvbo);
2364 if (ret)
2365 nouveau_bo_unpin(head->base.lut.nvbo);
2366 }
2367 if (ret) 2363 if (ret)
2368 nouveau_bo_ref(NULL, &head->base.lut.nvbo); 2364 goto out;
2369 } 2365 }
2370 2366
2371 if (ret)
2372 goto out;
2373
2374 /* allocate overlay resources */ 2367 /* allocate overlay resources */
2375 ret = nv50_oimm_create(device, disp->disp, index, &head->oimm); 2368 ret = nv50_oimm_create(device, disp->disp, index, &head->oimm);
2376 if (ret) 2369 if (ret)