diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2018-01-12 02:10:49 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2018-02-02 00:24:06 -0500 |
commit | 11fc017dfb1efffa93d803f7182d026962ea2aae (patch) | |
tree | 3fc4eae59bc63cc115e12b33c2b6c3bd29d5c1e3 | |
parent | 561464ea543c2f39f07ac2da91043555fa133601 (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.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 37 |
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 | ||
661 | struct nv50_head { | 661 | struct 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 | |||
2204 | nv50_head_lut_load(struct drm_crtc *crtc) | 2207 | nv50_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) | |||
2296 | static void | 2299 | static void |
2297 | nv50_head_destroy(struct drm_crtc *crtc) | 2300 | nv50_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) |