File 0001-drm-merged-fixes-5-sans-nv04_graph-change.patch of Package nouveau
From 44a0b8ce4d9c937c74eea5de50f242a970edab71 Mon Sep 17 00:00:00 2001
From: root <root@gdp.(none)>
Date: Tue, 6 May 2008 23:04:55 +0100
Subject: [PATCH] merged fixes 5, sans nv04_graph change
---
shared-core/nouveau_drm.h | 2 +
shared-core/nouveau_fifo.c | 141 ++++++++++++++++++++++++++++++++++++++++++++
shared-core/nouveau_mem.c | 3 +-
shared-core/nv20_graph.c | 4 +
4 files changed, 149 insertions(+), 1 deletions(-)
diff --git drm/shared-core/nouveau_drm.h drm/shared-core/nouveau_drm.h
index 4b5869a..487308b 100644
--- drm/shared-core/nouveau_drm.h
+++ drm/shared-core/nouveau_drm.h
@@ -167,6 +167,8 @@ struct drm_nouveau_sarea {
unsigned int nbox;
};
+#define DRM_NOUVEAU_SUSPEND 0x10
+#define DRM_NOUVEAU_RESUME 0x11
#define DRM_NOUVEAU_CARD_INIT 0x00
#define DRM_NOUVEAU_GETPARAM 0x01
#define DRM_NOUVEAU_SETPARAM 0x02
diff --git drm/shared-core/nouveau_fifo.c drm/shared-core/nouveau_fifo.c
index 5ec2bc3..e2fb038 100644
--- drm/shared-core/nouveau_fifo.c
+++ drm/shared-core/nouveau_fifo.c
@@ -27,6 +27,16 @@
#include "nouveau_drv.h"
#include "nouveau_drm.h"
+static struct {
+ u32 fifo_mode;
+ u32 graph_ctx_control;
+ u32 graph_state;
+ u32 *ramin_copy;
+ u32 *dchan_pushbuf;
+ bool resume_allowed;
+} susres = {
+ .resume_allowed = false
+};
/* returns the size of fifo context */
int nouveau_fifo_ctx_size(struct drm_device *dev)
@@ -578,11 +588,142 @@ static int nouveau_ioctl_fifo_free(struct drm_device *dev, void *data,
return 0;
}
+static int nouveau_ioctl_suspend(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_engine *engine = &dev_priv->Engine;
+ int i;
+
+ if (!susres.resume_allowed) {
+ susres.ramin_copy = vmalloc(dev_priv->ramin->size);
+ susres.dchan_pushbuf = vmalloc(0x8000);
+ susres.resume_allowed = true;
+ }
+
+ NV_WRITE(NV04_PGRAPH_FIFO, 0);
+ /* disable the fifo caches */
+ NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
+ NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH,
+ NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) & ~1);
+ NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000);
+ NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000);
+
+ susres.fifo_mode = NV_READ(NV04_PFIFO_MODE);
+
+ if (dev_priv->card_type >= NV_10) {
+ susres.graph_state = NV_READ(NV10_PGRAPH_STATE);
+ susres.graph_ctx_control = NV_READ(NV10_PGRAPH_CTX_CONTROL);
+ } else {
+ susres.graph_state = NV_READ(NV04_PGRAPH_STATE);
+ susres.graph_ctx_control = NV_READ(NV04_PGRAPH_CTX_CONTROL);
+ }
+
+ engine->fifo.save_context(dev_priv->fifos[engine->fifo.channel_id(dev)]);
+ engine->graph.save_context(dev_priv->fifos[engine->fifo.channel_id(dev)]);
+ nouveau_wait_for_idle(dev);
+
+ /* XXX copying all of RAMIN is probably overkill */
+ if (susres.ramin_copy)
+ for (i = 0; i < dev_priv->ramin->size / 4; i++)
+ susres.ramin_copy[i] = NV_RI32(i << 2);
+ else
+ DRM_ERROR("No suspend RAMIN\n");
+ /* XXX don't know if this is necessary; is there any chance of the drm
+ * fifo being non-empty on suspend?
+ */
+ if (susres.dchan_pushbuf)
+ for (i = 0; i < 0x2000; i++)
+ susres.dchan_pushbuf[i] = dev_priv->channel.pushbuf[i];
+ else
+ DRM_ERROR("No suspend DRM pushbuf\n");
+
+ /* reenable the fifo caches */
+ NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH,
+ NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
+ NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000001);
+ NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000001);
+ NV_WRITE(NV03_PFIFO_CACHES, 0x00000001);
+ NV_WRITE(NV04_PGRAPH_FIFO, 1);
+
+ return 0;
+}
+
+static int nouveau_ioctl_resume(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_engine *engine = &dev_priv->Engine;
+ int i;
+
+ if (!susres.resume_allowed)
+ return 0;
+
+ DRM_DEBUG("Doing resume\n");
+
+ if (susres.dchan_pushbuf)
+ for (i = 0; i < 0x2000; i++)
+ dev_priv->channel.pushbuf[i] = susres.dchan_pushbuf[i];
+ if (susres.ramin_copy)
+ for (i = 0; i < dev_priv->ramin->size / 4; i++)
+ NV_WI32(i << 2, susres.ramin_copy[i]);
+
+ engine->mc.init(dev);
+ engine->timer.init(dev);
+ engine->fb.init(dev);
+ engine->graph.init(dev);
+ engine->fifo.init(dev);
+
+ NV_WRITE(NV04_PGRAPH_FIFO, 0);
+ /* disable the fifo caches */
+ NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
+ NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH,
+ NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) & ~1);
+ NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000);
+ NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000);
+
+ /* PMC power cycling PFIFO in init clobbers some of the stuff stored in
+ * RAMIN (such as NV04_PFIFO_CACHE1_DMA_INSTANCE). this is unhelpful
+ */
+ if (susres.ramin_copy)
+ for (i = 0; i < dev_priv->ramin->size / 4; i++)
+ NV_WI32(i << 2, susres.ramin_copy[i]);
+
+ engine->fifo.load_context(dev_priv->fifos[0]);
+ NV_WRITE(NV04_PFIFO_MODE, susres.fifo_mode);
+
+ engine->graph.load_context(dev_priv->fifos[0]);
+ nouveau_wait_for_idle(dev);
+
+ if (dev_priv->card_type >= NV_10) {
+ NV_WRITE(NV10_PGRAPH_STATE, susres.graph_state);
+ NV_WRITE(NV10_PGRAPH_CTX_CONTROL, susres.graph_ctx_control);
+ } else {
+ NV_WRITE(NV04_PGRAPH_STATE, susres.graph_state);
+ NV_WRITE(NV04_PGRAPH_CTX_CONTROL, susres.graph_ctx_control);
+ }
+
+ /* reenable the fifo caches */
+ NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH,
+ NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
+ NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000001);
+ NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000001);
+ NV_WRITE(NV03_PFIFO_CACHES, 0x00000001);
+ NV_WRITE(NV04_PGRAPH_FIFO, 0x1);
+
+ if (dev->irq_enabled)
+ nouveau_irq_postinstall(dev);
+
+ return 0;
+}
+
/***********************************
* finally, the ioctl table
***********************************/
struct drm_ioctl_desc nouveau_ioctls[] = {
+ DRM_IOCTL_DEF(DRM_NOUVEAU_SUSPEND, nouveau_ioctl_suspend, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_RESUME, nouveau_ioctl_resume, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_CARD_INIT, nouveau_ioctl_card_init, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
diff --git drm/shared-core/nouveau_mem.c drm/shared-core/nouveau_mem.c
index d79c1a5..4b35dcb 100644
--- drm/shared-core/nouveau_mem.c
+++ drm/shared-core/nouveau_mem.c
@@ -507,7 +507,8 @@ int nouveau_mem_init(struct drm_device *dev)
dev_priv->fb_nomap_heap=NULL;
}
-#if !defined(__powerpc__) && !defined(__ia64__)
+#if 0
+!defined(__powerpc__) && !defined(__ia64__)
/* Init AGP / NV50 PCIEGART */
if (drm_device_is_agp(dev) && dev->agp) {
if ((ret = nouveau_mem_init_agp(dev, 0)))
diff --git drm/shared-core/nv20_graph.c drm/shared-core/nv20_graph.c
index ad73ea9..e06536d 100644
--- drm/shared-core/nv20_graph.c
+++ drm/shared-core/nv20_graph.c
@@ -694,6 +694,7 @@ int nv20_graph_init(struct drm_device *dev) {
NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
NV_PMC_ENABLE_PGRAPH);
+ if (!dev_priv->ctx_table) {
/* Create Context Pointer Table */
dev_priv->ctx_table_size = 32 * 4;
if ((ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0,
@@ -701,6 +702,7 @@ int nv20_graph_init(struct drm_device *dev) {
NVOBJ_FLAG_ZERO_ALLOC,
&dev_priv->ctx_table)))
return ret;
+ }
NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_TABLE,
dev_priv->ctx_table->instance >> 4);
@@ -812,6 +814,7 @@ int nv30_graph_init(struct drm_device *dev)
NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
NV_PMC_ENABLE_PGRAPH);
+ if (!dev_priv->ctx_table) {
/* Create Context Pointer Table */
dev_priv->ctx_table_size = 32 * 4;
if ((ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0,
@@ -819,6 +822,7 @@ int nv30_graph_init(struct drm_device *dev)
NVOBJ_FLAG_ZERO_ALLOC,
&dev_priv->ctx_table)))
return ret;
+ }
NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_TABLE,
dev_priv->ctx_table->instance >> 4);
--
1.5.4.4