From bd2f2037a42d4657ead3be2918db22e63626cd35 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 Feb 2011 15:16:23 +1000 Subject: [PATCH] drm/nvc0: support for sw methods + enable page flipping Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_display.c | 10 +++++++--- drivers/gpu/drm/nouveau/nouveau_state.c | 2 +- drivers/gpu/drm/nouveau/nvc0_graph.c | 18 +++++++++++++++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index d6da139..c42d84e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -224,6 +224,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan, struct nouveau_page_flip_state *s, struct nouveau_fence **pfence) { + struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct drm_device *dev = chan->dev; unsigned long flags; int ret; @@ -243,9 +244,12 @@ nouveau_page_flip_emit(struct nouveau_channel *chan, if (ret) goto fail; - BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); - OUT_RING(chan, 0); - FIRE_RING(chan); + if (dev_priv->card_type < NV_C0) + BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); + else + BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0500, 1); + OUT_RING (chan, 0); + FIRE_RING (chan); ret = nouveau_fence_new(chan, pfence, true); if (ret) diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index e03cd34..43acfc2a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -1118,7 +1118,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, getparam->value = 1; break; case NOUVEAU_GETPARAM_HAS_PAGEFLIP: - getparam->value = (dev_priv->card_type < NV_C0) ? 1 : 0; + getparam->value = 1; break; case NOUVEAU_GETPARAM_GRAPH_UNITS: /* NV40 and NV50 versions are quite different, but register diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c index afa7afe..3de9b72 100644 --- a/drivers/gpu/drm/nouveau/nvc0_graph.c +++ b/drivers/gpu/drm/nouveau/nvc0_graph.c @@ -299,6 +299,14 @@ nvc0_graph_takedown(struct drm_device *dev) } static int +nvc0_graph_mthd_page_flip(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) +{ + nouveau_finish_page_flip(chan, NULL); + return 0; +} + +static int nvc0_graph_create(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -395,6 +403,7 @@ nvc0_graph_create(struct drm_device *dev) nouveau_irq_register(dev, 25, nvc0_runk140_isr); NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */ NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */ + NVOBJ_MTHD (dev, 0x9039, 0x0500, nvc0_graph_mthd_page_flip); NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */ NVOBJ_CLASS(dev, 0x90c0, GR); /* COMPUTE */ return 0; @@ -728,9 +737,12 @@ nvc0_graph_isr(struct drm_device *dev) u32 class = nv_rd32(dev, 0x404200 + (subc * 4)); if (stat & 0x00000010) { - NV_INFO(dev, "PGRAPH: ILLEGAL_MTHD ch %d [0x%010llx] subc %d " - "class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, inst, subc, class, mthd, data); + if (nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) { + NV_INFO(dev, "PGRAPH: ILLEGAL_MTHD ch %d [0x%010llx] " + "subc %d class 0x%04x mthd 0x%04x " + "data 0x%08x\n", + chid, inst, subc, class, mthd, data); + } nv_wr32(dev, 0x400100, 0x00000010); stat &= ~0x00000010; } -- 2.7.4