diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2016-11-04 17:20:36 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2016-11-07 14:05:01 +1000 |
commit | e1ef6b42d9014079e5ab71acd8669d39808c3c73 (patch) | |
tree | 654642467925a33cfe0be71f420e2fb68a05e565 /drivers/gpu/drm/nouveau | |
parent | c2d926aacc7eeaf39edbd0ab8d5fba33acbb168d (diff) | |
download | linux-stable-e1ef6b42d9014079e5ab71acd8669d39808c3c73.tar.gz linux-stable-e1ef6b42d9014079e5ab71acd8669d39808c3c73.tar.bz2 linux-stable-e1ef6b42d9014079e5ab71acd8669d39808c3c73.zip |
drm/nouveau/kms/nv50: remove code to support non-atomic page flips
Made completely unreachable (and broken) by atomic commits.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_display.c | 62 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fence.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv10_fence.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv10_fence.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 198 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_fence.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv84_fence.c | 22 |
8 files changed, 27 insertions, 288 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 9e16deffba86..62d75308c57c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -835,10 +835,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan, if (ret) goto fail; - if (drm->device.info.family < NV_DEVICE_INFO_V0_FERMI) - BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); - else - BEGIN_NVC0(chan, FermiSw, NV_SW_PAGE_FLIP, 1); + BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); OUT_RING (chan, 0x00000000); FIRE_RING (chan); @@ -867,6 +864,8 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct nouveau_channel *chan; struct nouveau_cli *cli; struct nouveau_fence *fence; + struct nv04_display *dispnv04 = nv04_display(dev); + int head = nouveau_crtc(crtc)->index; int ret; chan = drm->channel; @@ -913,32 +912,23 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, drm_crtc_vblank_get(crtc); /* Emit a page flip */ - if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { - ret = nv50_display_flip_next(crtc, fb, chan, swap_interval); + if (swap_interval) { + ret = RING_SPACE(chan, 8); if (ret) goto fail_unreserve; - } else { - struct nv04_display *dispnv04 = nv04_display(dev); - int head = nouveau_crtc(crtc)->index; - - if (swap_interval) { - ret = RING_SPACE(chan, 8); - if (ret) - goto fail_unreserve; - - BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1); - OUT_RING (chan, head); - BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1); - OUT_RING (chan, 0); - } - nouveau_bo_ref(new_bo, &dispnv04->image[head]); + BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1); + OUT_RING (chan, 0); + BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1); + OUT_RING (chan, head); + BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1); + OUT_RING (chan, 0); + BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1); + OUT_RING (chan, 0); } + nouveau_bo_ref(new_bo, &dispnv04->image[head]); + ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); if (ret) goto fail_unreserve; @@ -986,16 +976,8 @@ nouveau_finish_page_flip(struct nouveau_channel *chan, s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head); if (s->event) { - if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { - drm_crtc_arm_vblank_event(s->crtc, s->event); - } else { - drm_crtc_send_vblank_event(s->crtc, s->event); - - /* Give up ownership of vblank for page-flipped crtc */ - drm_crtc_vblank_put(s->crtc); - } - } - else { + drm_crtc_arm_vblank_event(s->crtc, s->event); + } else { /* Give up ownership of vblank for page-flipped crtc */ drm_crtc_vblank_put(s->crtc); } @@ -1017,12 +999,10 @@ nouveau_flip_complete(struct nvif_notify *notify) struct nouveau_page_flip_state state; if (!nouveau_finish_page_flip(chan, &state)) { - if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { - nv_set_crtc_base(drm->dev, drm_crtc_index(state.crtc), - state.offset + state.crtc->y * - state.pitch + state.crtc->x * - state.bpp / 8); - } + nv_set_crtc_base(drm->dev, drm_crtc_index(state.crtc), + state.offset + state.crtc->y * + state.pitch + state.crtc->x * + state.bpp / 8); } return NVIF_NOTIFY_KEEP; diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h index 41f3c019e534..ccdce1b4eec4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h @@ -92,7 +92,6 @@ struct nv84_fence_chan { struct nouveau_fence_chan base; struct nvkm_vma vma; struct nvkm_vma vma_gart; - struct nvkm_vma dispc_vma[4]; }; struct nv84_fence_priv { @@ -102,7 +101,6 @@ struct nv84_fence_priv { u32 *suspend; }; -u64 nv84_fence_crtc(struct nouveau_channel *, int); int nv84_fence_context_new(struct nouveau_channel *); #endif diff --git a/drivers/gpu/drm/nouveau/nv10_fence.c b/drivers/gpu/drm/nouveau/nv10_fence.c index bcf3a213d5d8..2998bde29211 100644 --- a/drivers/gpu/drm/nouveau/nv10_fence.c +++ b/drivers/gpu/drm/nouveau/nv10_fence.c @@ -57,10 +57,7 @@ void nv10_fence_context_del(struct nouveau_channel *chan) { struct nv10_fence_chan *fctx = chan->fence; - int i; nouveau_fence_context_del(&fctx->base); - for (i = 0; i < ARRAY_SIZE(fctx->head); i++) - nvif_object_fini(&fctx->head[i]); nvif_object_fini(&fctx->sema); chan->fence = NULL; nouveau_fence_context_free(&fctx->base); diff --git a/drivers/gpu/drm/nouveau/nv10_fence.h b/drivers/gpu/drm/nouveau/nv10_fence.h index a87259f3983a..b7a508585304 100644 --- a/drivers/gpu/drm/nouveau/nv10_fence.h +++ b/drivers/gpu/drm/nouveau/nv10_fence.h @@ -7,7 +7,6 @@ struct nv10_fence_chan { struct nouveau_fence_chan base; struct nvif_object sema; - struct nvif_object head[4]; }; struct nv10_fence_priv { diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 8d48ee475149..4b195cc32ec4 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -658,11 +658,8 @@ nv50_ovly_create(struct nvif_device *device, struct nvif_object *disp, struct nv50_head { struct nouveau_crtc base; - struct nouveau_bo *image; struct nv50_ovly ovly; struct nv50_oimm oimm; - - struct nv50_base *_base; }; #define nv50_head(c) ((struct nv50_head *)nouveau_crtc(c)) @@ -740,40 +737,6 @@ evo_kick(u32 *push, void *evoc) *((p)++) = _d; \ } while(0) -static bool -evo_sync_wait(void *data) -{ - if (nouveau_bo_rd32(data, EVO_MAST_NTFY) != 0x00000000) - return true; - usleep_range(1, 2); - return false; -} - -static int -evo_sync(struct drm_device *dev) -{ - struct nvif_device *device = &nouveau_drm(dev)->device; - struct nv50_disp *disp = nv50_disp(dev); - struct nv50_mast *mast = nv50_mast(dev); - u32 *push = evo_wait(mast, 8); - if (push) { - nouveau_bo_wr32(disp->sync, EVO_MAST_NTFY, 0x00000000); - evo_mthd(push, 0x0084, 1); - evo_data(push, 0x80000000 | EVO_MAST_NTFY); - evo_mthd(push, 0x0080, 2); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); - evo_kick(push, mast); - if (nvif_msec(device, 2000, - if (evo_sync_wait(disp->sync)) - break; - ) >= 0) - return 0; - } - - return -EBUSY; -} - /****************************************************************************** * Plane *****************************************************************************/ @@ -789,8 +752,6 @@ struct nv50_wndw { u16 ntfy; u16 sema; u32 data; - - struct nv50_wndw_atom asy; }; struct nv50_wndw_func { @@ -1582,151 +1543,6 @@ nv50_base_new(struct nouveau_drm *drm, struct nv50_head *head, } /****************************************************************************** - * Page flipping channel - *****************************************************************************/ -struct nouveau_bo * -nv50_display_crtc_sema(struct drm_device *dev, int crtc) -{ - return nv50_disp(dev)->sync; -} - -struct nv50_display_flip { - struct nv50_disp *disp; - struct nv50_base *base; -}; - -static bool -nv50_display_flip_wait(void *data) -{ - struct nv50_display_flip *flip = data; - if (nouveau_bo_rd32(flip->disp->sync, flip->base->wndw.sema / 4) == - flip->base->wndw.data) - return true; - usleep_range(1, 2); - return false; -} - -void -nv50_display_flip_stop(struct drm_crtc *crtc) -{ - struct nvif_device *device = &nouveau_drm(crtc->dev)->device; - struct nv50_base *base = nv50_head(crtc)->_base; - struct nv50_wndw *wndw = &base->wndw; - struct nv50_wndw_atom *asyw = &wndw->asy; - struct nv50_display_flip flip = { - .disp = nv50_disp(crtc->dev), - .base = base, - }; - - asyw->state.crtc = NULL; - asyw->state.fb = NULL; - nv50_wndw_atomic_check(&wndw->plane, &asyw->state); - nv50_wndw_flush_clr(wndw, 0, true, asyw); - - nvif_msec(device, 2000, - if (nv50_display_flip_wait(&flip)) - break; - ); -} - -int -nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, - struct nouveau_channel *chan, u32 swap_interval) -{ - struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct nv50_head *head = nv50_head(crtc); - struct nv50_base *base = nv50_head(crtc)->_base; - struct nv50_wndw *wndw = &base->wndw; - struct nv50_wndw_atom *asyw = &wndw->asy; - int ret; - - if (crtc->primary->fb->width != fb->width || - crtc->primary->fb->height != fb->height) - return -EINVAL; - - if (chan == NULL) - evo_sync(crtc->dev); - - if (chan && chan->user.oclass < G82_CHANNEL_GPFIFO) { - ret = RING_SPACE(chan, 8); - if (ret) - return ret; - - BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2); - OUT_RING (chan, NvEvoSema0 + nv_crtc->index); - OUT_RING (chan, base->wndw.sema ^ 0x10); - BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1); - OUT_RING (chan, base->wndw.data + 1); - BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_OFFSET, 2); - OUT_RING (chan, base->wndw.sema); - OUT_RING (chan, base->wndw.data); - } else - if (chan && chan->user.oclass < FERMI_CHANNEL_GPFIFO) { - u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + base->wndw.sema; - ret = RING_SPACE(chan, 12); - if (ret) - return ret; - - BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); - OUT_RING (chan, chan->vram.handle); - BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(addr ^ 0x10)); - OUT_RING (chan, lower_32_bits(addr ^ 0x10)); - OUT_RING (chan, base->wndw.data + 1); - OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG); - BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(addr)); - OUT_RING (chan, lower_32_bits(addr)); - OUT_RING (chan, base->wndw.data); - OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL); - } else - if (chan) { - u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + base->wndw.sema; - ret = RING_SPACE(chan, 10); - if (ret) - return ret; - - BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(addr ^ 0x10)); - OUT_RING (chan, lower_32_bits(addr ^ 0x10)); - OUT_RING (chan, base->wndw.data + 1); - OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG | - NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD); - BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(addr)); - OUT_RING (chan, lower_32_bits(addr)); - OUT_RING (chan, base->wndw.data); - OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL | - NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD); - } - - if (chan) { - base->wndw.sema ^= 0x10; - base->wndw.data++; - FIRE_RING (chan); - } - - /* queue the flip */ - asyw->state.crtc = &head->base.base; - asyw->state.fb = fb; - asyw->interval = swap_interval; - asyw->image.handle = nv_fb->r_handle; - asyw->image.offset = nv_fb->nvbo->bo.offset; - asyw->sema.handle = base->chan.base.sync.handle; - asyw->sema.offset = base->wndw.sema; - asyw->sema.acquire = base->wndw.data++; - asyw->sema.release = base->wndw.data; - nv50_wndw_atomic_check(&wndw->plane, &asyw->state); - asyw->set.sema = true; - nv50_wndw_flush_set(wndw, 0, asyw); - nv50_wndw_wait_armed(wndw, asyw); - - nouveau_bo_ref(nv_fb->nvbo, &head->image); - return 0; -} - -/****************************************************************************** * Head *****************************************************************************/ static void @@ -2610,8 +2426,6 @@ nv50_crtc_create(struct drm_device *dev, int index) } crtc = &head->base.base; - head->_base = base; - drm_crtc_init_with_planes(dev, crtc, &base->wndw.plane, &curs->wndw.plane, &nv50_crtc_func, "head-%d", head->base.index); @@ -4061,7 +3875,6 @@ nv50_display_fini(struct drm_device *dev) int nv50_display_init(struct drm_device *dev) { - struct nv50_disp *disp = nv50_disp(dev); struct drm_encoder *encoder; struct drm_plane *plane; struct drm_crtc *crtc; @@ -4071,13 +3884,6 @@ nv50_display_init(struct drm_device *dev) if (!push) return -EBUSY; - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct nv50_wndw *wndw = &nv50_head(crtc)->_base->wndw; - - nv50_crtc_lut_load(crtc); - nouveau_bo_wr32(disp->sync, wndw->sema / 4, wndw->data); - } - evo_mthd(push, 0x0088, 1); evo_data(push, nv50_mast(dev)->base.sync.handle); evo_kick(push, nv50_mast(dev)); @@ -4094,6 +3900,10 @@ nv50_display_init(struct drm_device *dev) } } + drm_for_each_crtc(crtc, dev) { + nv50_crtc_lut_load(crtc); + } + drm_for_each_plane(plane, dev) { struct nv50_wndw *wndw = nv50_wndw(plane); if (plane->funcs != &nv50_wndw) diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h index 70da347aa8c5..918187cee84b 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.h +++ b/drivers/gpu/drm/nouveau/nv50_display.h @@ -35,11 +35,4 @@ int nv50_display_create(struct drm_device *); void nv50_display_destroy(struct drm_device *); int nv50_display_init(struct drm_device *); void nv50_display_fini(struct drm_device *); - -void nv50_display_flip_stop(struct drm_crtc *); -int nv50_display_flip_next(struct drm_crtc *, struct drm_framebuffer *, - struct nouveau_channel *, u32 swap_interval); - -struct nouveau_bo *nv50_display_crtc_sema(struct drm_device *, int head); - #endif /* __NV50_DISPLAY_H__ */ diff --git a/drivers/gpu/drm/nouveau/nv50_fence.c b/drivers/gpu/drm/nouveau/nv50_fence.c index 8c5295414578..f68c7054fd53 100644 --- a/drivers/gpu/drm/nouveau/nv50_fence.c +++ b/drivers/gpu/drm/nouveau/nv50_fence.c @@ -35,13 +35,12 @@ static int nv50_fence_context_new(struct nouveau_channel *chan) { - struct drm_device *dev = chan->drm->dev; struct nv10_fence_priv *priv = chan->drm->fence; struct nv10_fence_chan *fctx; struct ttm_mem_reg *mem = &priv->bo->bo.mem; u32 start = mem->start * PAGE_SIZE; u32 limit = start + mem->size - 1; - int ret, i; + int ret; fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); if (!fctx) @@ -60,23 +59,6 @@ nv50_fence_context_new(struct nouveau_channel *chan) .limit = limit, }, sizeof(struct nv_dma_v0), &fctx->sema); - - /* dma objects for display sync channel semaphore blocks */ - for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) { - struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i); - u32 start = bo->bo.mem.start * PAGE_SIZE; - u32 limit = start + bo->bo.mem.size - 1; - - ret = nvif_object_init(&chan->user, NvEvoSema0 + i, - NV_DMA_IN_MEMORY, &(struct nv_dma_v0) { - .target = NV_DMA_V0_TARGET_VRAM, - .access = NV_DMA_V0_ACCESS_RDWR, - .start = start, - .limit = limit, - }, sizeof(struct nv_dma_v0), - &fctx->head[i]); - } - if (ret) nv10_fence_context_del(chan); return ret; diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c index 23ef04b4e0b2..52b87ae83e7b 100644 --- a/drivers/gpu/drm/nouveau/nv84_fence.c +++ b/drivers/gpu/drm/nouveau/nv84_fence.c @@ -28,13 +28,6 @@ #include "nv50_display.h" -u64 -nv84_fence_crtc(struct nouveau_channel *chan, int crtc) -{ - struct nv84_fence_chan *fctx = chan->fence; - return fctx->dispc_vma[crtc].offset; -} - static int nv84_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence) { @@ -110,15 +103,8 @@ nv84_fence_read(struct nouveau_channel *chan) static void nv84_fence_context_del(struct nouveau_channel *chan) { - struct drm_device *dev = chan->drm->dev; struct nv84_fence_priv *priv = chan->drm->fence; struct nv84_fence_chan *fctx = chan->fence; - int i; - - for (i = 0; i < dev->mode_config.num_crtc; i++) { - struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i); - nouveau_bo_vma_del(bo, &fctx->dispc_vma[i]); - } nouveau_bo_wr32(priv->bo, chan->chid * 16 / 4, fctx->base.sequence); nouveau_bo_vma_del(priv->bo, &fctx->vma_gart); @@ -134,7 +120,7 @@ nv84_fence_context_new(struct nouveau_channel *chan) struct nouveau_cli *cli = (void *)chan->user.client; struct nv84_fence_priv *priv = chan->drm->fence; struct nv84_fence_chan *fctx; - int ret, i; + int ret; fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); if (!fctx) @@ -154,12 +140,6 @@ nv84_fence_context_new(struct nouveau_channel *chan) &fctx->vma_gart); } - /* map display semaphore buffers into channel's vm */ - for (i = 0; !ret && i < chan->drm->dev->mode_config.num_crtc; i++) { - struct nouveau_bo *bo = nv50_display_crtc_sema(chan->drm->dev, i); - ret = nouveau_bo_vma_add(bo, cli->vm, &fctx->dispc_vma[i]); - } - if (ret) nv84_fence_context_del(chan); return ret; |