summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/dispnv04/crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/dispnv04/crtc.c')
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/crtc.c124
1 files changed, 60 insertions, 64 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
index ee92d576d277..c063756eaea3 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
@@ -24,6 +24,7 @@
*/
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fourcc.h>
+#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_vblank.h>
@@ -37,7 +38,6 @@
#include "nouveau_crtc.h"
#include "hw.h"
#include "nvreg.h"
-#include "nouveau_fbcon.h"
#include "disp.h"
#include "nouveau_dma.h"
@@ -118,8 +118,8 @@ static void nv_crtc_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mod
{
struct drm_device *dev = crtc->dev;
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nvkm_bios *bios = nvxx_bios(&drm->client.device);
- struct nvkm_clk *clk = nvxx_clk(&drm->client.device);
+ struct nvkm_bios *bios = nvxx_bios(drm);
+ struct nvkm_clk *clk = nvxx_clk(drm);
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct nv04_mode_state *state = &nv04_display(dev)->mode_reg;
struct nv04_crtc_reg *regp = &state->crtc_reg[nv_crtc->index];
@@ -449,7 +449,7 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode)
regp->Attribute[NV_CIO_AR_CSEL_INDEX] = 0x00;
}
-/**
+/*
* Sets up registers for the given mode/adjusted_mode pair.
*
* The clocks, CRTCs and outputs attached to this CRTC must be off.
@@ -617,15 +617,21 @@ nv_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb)
ret = nouveau_bo_pin(nvbo, NOUVEAU_GEM_DOMAIN_VRAM, false);
if (ret == 0) {
- if (disp->image[nv_crtc->index])
- nouveau_bo_unpin(disp->image[nv_crtc->index]);
- nouveau_bo_ref(nvbo, &disp->image[nv_crtc->index]);
+ if (disp->image[nv_crtc->index]) {
+ struct nouveau_bo *bo = disp->image[nv_crtc->index];
+
+ nouveau_bo_unpin(bo);
+ drm_gem_object_put(&bo->bo.base);
+ }
+
+ drm_gem_object_get(&nvbo->bo.base);
+ disp->image[nv_crtc->index] = nvbo;
}
return ret;
}
-/**
+/*
* Sets up registers for the given mode/adjusted_mode pair.
*
* The clocks, CRTCs and outputs attached to this CRTC must be off.
@@ -754,14 +760,17 @@ static void nv_crtc_destroy(struct drm_crtc *crtc)
drm_crtc_cleanup(crtc);
- if (disp->image[nv_crtc->index])
- nouveau_bo_unpin(disp->image[nv_crtc->index]);
- nouveau_bo_ref(NULL, &disp->image[nv_crtc->index]);
+ if (disp->image[nv_crtc->index]) {
+ struct nouveau_bo *bo = disp->image[nv_crtc->index];
+
+ nouveau_bo_unpin(bo);
+ drm_gem_object_put(&bo->bo.base);
+ disp->image[nv_crtc->index] = NULL;
+ }
- nouveau_bo_unmap(nv_crtc->cursor.nvbo);
- nouveau_bo_unpin(nv_crtc->cursor.nvbo);
- nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
- nvif_notify_dtor(&nv_crtc->vblank);
+ nouveau_bo_unpin_del(&nv_crtc->cursor.nvbo);
+ nvif_event_dtor(&nv_crtc->vblank);
+ nvif_head_dtor(&nv_crtc->head);
kfree(nv_crtc);
}
@@ -793,9 +802,14 @@ nv_crtc_disable(struct drm_crtc *crtc)
{
struct nv04_display *disp = nv04_display(crtc->dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- if (disp->image[nv_crtc->index])
- nouveau_bo_unpin(disp->image[nv_crtc->index]);
- nouveau_bo_ref(NULL, &disp->image[nv_crtc->index]);
+
+ if (disp->image[nv_crtc->index]) {
+ struct nouveau_bo *bo = disp->image[nv_crtc->index];
+
+ nouveau_bo_unpin(bo);
+ drm_gem_object_put(&bo->bo.base);
+ disp->image[nv_crtc->index] = NULL;
+ }
}
static int
@@ -914,14 +928,6 @@ nv04_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
int x, int y, enum mode_set_atomic state)
{
- struct nouveau_drm *drm = nouveau_drm(crtc->dev);
- struct drm_device *dev = drm->dev;
-
- if (state == ENTER_ATOMIC_MODE_SET)
- nouveau_fbcon_accel_save_disable(dev);
- else
- nouveau_fbcon_accel_restore(dev);
-
return nv04_crtc_do_mode_set_base(crtc, fb, x, y, true);
}
@@ -1049,7 +1055,7 @@ nv04_finish_page_flip(struct nouveau_channel *chan,
struct nv04_page_flip_state *ps)
{
struct nouveau_fence_chan *fctx = chan->fence;
- struct nouveau_drm *drm = chan->drm;
+ struct nouveau_drm *drm = chan->cli->drm;
struct drm_device *dev = drm->dev;
struct nv04_page_flip_state *s;
unsigned long flags;
@@ -1080,10 +1086,10 @@ nv04_finish_page_flip(struct nouveau_channel *chan,
}
int
-nv04_flip_complete(struct nvif_notify *notify)
+nv04_flip_complete(struct nvif_event *event, void *argv, u32 argc)
{
- struct nouveau_cli *cli = (void *)notify->object->client;
- struct nouveau_drm *drm = cli->drm;
+ struct nv04_display *disp = container_of(event, typeof(*disp), flip);
+ struct nouveau_drm *drm = disp->drm;
struct nouveau_channel *chan = drm->channel;
struct nv04_page_flip_state state;
@@ -1094,7 +1100,7 @@ nv04_flip_complete(struct nvif_notify *notify)
state.bpp / 8);
}
- return NVIF_NOTIFY_KEEP;
+ return NVIF_EVENT_KEEP;
}
static int
@@ -1105,9 +1111,9 @@ nv04_page_flip_emit(struct nouveau_channel *chan,
struct nouveau_fence **pfence)
{
struct nouveau_fence_chan *fctx = chan->fence;
- struct nouveau_drm *drm = chan->drm;
+ struct nouveau_drm *drm = chan->cli->drm;
struct drm_device *dev = drm->dev;
- struct nvif_push *push = chan->chan.push;
+ struct nvif_push *push = &chan->chan.push;
unsigned long flags;
int ret;
@@ -1129,7 +1135,7 @@ nv04_page_flip_emit(struct nouveau_channel *chan,
PUSH_NVSQ(push, NV_SW, NV_SW_PAGE_FLIP, 0x00000000);
PUSH_KICK(push);
- ret = nouveau_fence_new(chan, false, pfence);
+ ret = nouveau_fence_new(pfence, chan);
if (ret)
goto fail;
@@ -1164,8 +1170,8 @@ nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
chan = drm->channel;
if (!chan)
return -ENODEV;
- cli = (void *)chan->user.client;
- push = chan->chan.push;
+ cli = chan->cli;
+ push = &chan->chan.push;
s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
@@ -1217,7 +1223,11 @@ nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
PUSH_NVSQ(push, NV05F, 0x0130, 0);
}
- nouveau_bo_ref(new_bo, &dispnv04->image[head]);
+ if (dispnv04->image[head])
+ drm_gem_object_put(&dispnv04->image[head]->bo.base);
+
+ drm_gem_object_get(&new_bo->bo.base);
+ dispnv04->image[head] = new_bo;
ret = nv04_page_flip_emit(chan, old_bo, new_bo, s, &fence);
if (ret)
@@ -1279,18 +1289,19 @@ static const struct drm_plane_funcs nv04_primary_plane_funcs = {
DRM_PLANE_NON_ATOMIC_FUNCS,
};
-static int nv04_crtc_vblank_handler(struct nvif_notify *notify)
+static int
+nv04_crtc_vblank_handler(struct nvif_event *event, void *repv, u32 repc)
{
- struct nouveau_crtc *nv_crtc =
- container_of(notify, struct nouveau_crtc, vblank);
+ struct nouveau_crtc *nv_crtc = container_of(event, struct nouveau_crtc, vblank);
drm_crtc_handle_vblank(&nv_crtc->base);
- return NVIF_NOTIFY_KEEP;
+ return NVIF_EVENT_KEEP;
}
int
nv04_crtc_create(struct drm_device *dev, int crtc_num)
{
+ struct nouveau_cli *cli = &nouveau_drm(dev)->client;
struct nouveau_display *disp = nouveau_display(dev);
struct nouveau_crtc *nv_crtc;
struct drm_plane *primary;
@@ -1324,31 +1335,16 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs);
drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
- ret = nouveau_bo_new(&nouveau_drm(dev)->client, 64*64*4, 0x100,
- NOUVEAU_GEM_DOMAIN_VRAM, 0, 0x0000, NULL, NULL,
- &nv_crtc->cursor.nvbo);
- if (!ret) {
- ret = nouveau_bo_pin(nv_crtc->cursor.nvbo,
- NOUVEAU_GEM_DOMAIN_VRAM, false);
- if (!ret) {
- ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
- if (ret)
- nouveau_bo_unpin(nv_crtc->cursor.nvbo);
- }
- if (ret)
- nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
- }
+ ret = nouveau_bo_new_map(cli, NOUVEAU_GEM_DOMAIN_VRAM, 64 * 64 * 4, &nv_crtc->cursor.nvbo);
+ if (ret)
+ return ret;
nv04_cursor_init(nv_crtc);
- ret = nvif_notify_ctor(&disp->disp.object, "kmsVbl", nv04_crtc_vblank_handler,
- false, NV04_DISP_NTFY_VBLANK,
- &(struct nvif_notify_head_req_v0) {
- .head = nv_crtc->index,
- },
- sizeof(struct nvif_notify_head_req_v0),
- sizeof(struct nvif_notify_head_rep_v0),
- &nv_crtc->vblank);
+ ret = nvif_head_ctor(&disp->disp, nv_crtc->base.name, nv_crtc->index, &nv_crtc->head);
+ if (ret)
+ return ret;
- return ret;
+ return nvif_head_vblank_event_ctor(&nv_crtc->head, "kmsVbl", nv04_crtc_vblank_handler,
+ false, &nv_crtc->vblank);
}