[PATCH 2/3] Add pause/unpause methods to the PGRAPH engine v2
Martin Peres
martin.peres at ensi-bourges.fr
Thu Sep 30 11:43:21 PDT 2010
Signed-off-by: Martin Peres <martin.peres at ensi-bourges.fr>
---
drivers/gpu/drm/nouveau/nouveau_drv.h | 2 +
drivers/gpu/drm/nouveau/nouveau_reg.h | 2 +
drivers/gpu/drm/nouveau/nouveau_state.c | 14 +++++++++
drivers/gpu/drm/nouveau/nv50_graph.c | 48 +++++++++++++++++++++++++++++++
4 files changed, 66 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index c256c0a..bed57d0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1121,6 +1121,8 @@ extern int nv50_graph_load_context(struct nouveau_channel *);
extern int nv50_graph_unload_context(struct drm_device *);
extern void nv50_graph_context_switch(struct drm_device *);
extern int nv50_grctx_init(struct nouveau_grctx *);
+extern int nv50_graph_pause(struct drm_device *dev);
+extern int nv50_graph_unpause(struct drm_device *dev);
/* nvc0_graph.c */
extern int nvc0_graph_init(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
index ee6dae1..346b77a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_reg.h
+++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
@@ -699,6 +699,8 @@
#define NV50_PROM__ESIZE 0x10000
#define NV50_PGRAPH 0x00400000
+#define NV50_PGRAPH_CONTROL 0x00400500
+#define NV50_PGRAPH_STATUS 0x00400700
#define NV50_PGRAPH__LEN 0x1
#define NV50_PGRAPH__ESIZE 0x10000
#define NV50_PFIFO_FREEZE 0x2504
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index cfc34f5..fc5fb46 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -74,6 +74,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->graph.destroy_context = nv04_graph_destroy_context;
engine->graph.load_context = nv04_graph_load_context;
engine->graph.unload_context = nv04_graph_unload_context;
+ engine->graph.pause = NULL;
+ engine->graph.unpause = NULL;
engine->fifo.channels = 16;
engine->fifo.init = nv04_fifo_init;
engine->fifo.takedown = nouveau_stub_takedown;
@@ -130,6 +132,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->graph.load_context = nv10_graph_load_context;
engine->graph.unload_context = nv10_graph_unload_context;
engine->graph.set_region_tiling = nv10_graph_set_region_tiling;
+ engine->graph.pause = NULL;
+ engine->graph.unpause = NULL;
engine->fifo.channels = 32;
engine->fifo.init = nv10_fifo_init;
engine->fifo.takedown = nouveau_stub_takedown;
@@ -186,6 +190,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->graph.load_context = nv20_graph_load_context;
engine->graph.unload_context = nv20_graph_unload_context;
engine->graph.set_region_tiling = nv20_graph_set_region_tiling;
+ engine->graph.pause = NULL;
+ engine->graph.unpause = NULL;
engine->fifo.channels = 32;
engine->fifo.init = nv10_fifo_init;
engine->fifo.takedown = nouveau_stub_takedown;
@@ -242,6 +248,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->graph.load_context = nv20_graph_load_context;
engine->graph.unload_context = nv20_graph_unload_context;
engine->graph.set_region_tiling = nv20_graph_set_region_tiling;
+ engine->graph.pause = NULL;
+ engine->graph.unpause = NULL;
engine->fifo.channels = 32;
engine->fifo.init = nv10_fifo_init;
engine->fifo.takedown = nouveau_stub_takedown;
@@ -301,6 +309,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->graph.load_context = nv40_graph_load_context;
engine->graph.unload_context = nv40_graph_unload_context;
engine->graph.set_region_tiling = nv40_graph_set_region_tiling;
+ engine->graph.pause = NULL;
+ engine->graph.unpause = NULL;
engine->fifo.channels = 32;
engine->fifo.init = nv40_fifo_init;
engine->fifo.takedown = nouveau_stub_takedown;
@@ -364,6 +374,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->graph.destroy_context = nv50_graph_destroy_context;
engine->graph.load_context = nv50_graph_load_context;
engine->graph.unload_context = nv50_graph_unload_context;
+ engine->graph.pause = nv50_graph_pause;
+ engine->graph.unpause = nv50_graph_unpause;
engine->fifo.channels = 128;
engine->fifo.init = nv50_fifo_init;
engine->fifo.takedown = nv50_fifo_takedown;
@@ -435,6 +447,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->graph.destroy_context = nvc0_graph_destroy_context;
engine->graph.load_context = nvc0_graph_load_context;
engine->graph.unload_context = nvc0_graph_unload_context;
+ engine->graph.pause = NULL;
+ engine->graph.unpause = NULL;
engine->fifo.channels = 128;
engine->fifo.init = nvc0_fifo_init;
engine->fifo.takedown = nvc0_fifo_takedown;
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
index cbf5ae2..252b432 100644
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
@@ -381,6 +381,54 @@ nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, int grclass,
return 0;
}
+
+
+int
+nv50_graph_pause(struct drm_device *dev)
+{
+ uint64_t start;
+ /* initial guess... */
+ uint32_t mask380 = 0xffffffff;
+ uint32_t mask384 = 0xffffffff;
+ uint32_t mask388 = 0xffffffff;
+ uint32_t mask700 = 0x00000001;
+
+ start = nv04_timer_read(dev);
+ nv_wr32(dev, NV50_PGRAPH_CONTROL, 0x10000);
+ while ((nv_rd32(dev, 0x400380) & mask380) ||
+ (nv_rd32(dev, 0x400384) & mask384) ||
+ (nv_rd32(dev, 0x400388) & mask388) ||
+ (nv_rd32(dev, NV50_PGRAPH_STATUS) & mask700)) {
+ if (nv04_timer_read(dev) - start >= 50000000) {
+ /* if you see this message, mask* above probably need to be adjusted
+ * to not contain the bits you see failing */
+ NV_ERROR(dev, "PGRAPH: wait for idle fail: %08x %08x %08x %08x!\n",
+ nv_rd32(dev, 0x400380), nv_rd32(dev, 0x400384),
+ nv_rd32(dev, 0x400388), nv_rd32(dev, NV50_PGRAPH_STATUS));
+
+ if (nv_rd32(dev, NV50_PGRAPH_STATUS) & 0x100)
+ NV_ERROR(dev, "PGRAPH: PGRAPH paused while running a ctxprog, "
+ "NV40_PGRAPH_CTXCTL_0310 = 0x%x\n",
+ nv_rd32(dev, NV40_PGRAPH_CTXCTL_0310));
+
+ nv50_graph_unpause(dev);
+ return -EIO;
+ }
+
+ /* After a 1ms wait, do not use all the */
+ if (nv04_timer_read(dev) - start >= 1000000)
+ schedule();
+ }
+ return 0;
+}
+
+int
+nv50_graph_unpause(struct drm_device *dev)
+{
+ nv_wr32(dev, NV50_PGRAPH_CONTROL, 0x10001);
+ return 0;
+}
+
static struct nouveau_pgraph_object_method nv50_graph_nvsw_methods[] = {
{ 0x018c, nv50_graph_nvsw_dma_vblsem },
{ 0x0400, nv50_graph_nvsw_vblsem_offset },
--
1.7.2
--------------060107090404080201010405
Content-Type: text/x-patch;
name="0003-Idle-PGRAPH-and-PFIFO-before-changing-the-clocks-v2.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename*0="0003-Idle-PGRAPH-and-PFIFO-before-changing-the-clocks-v2.pat";
filename*1="ch"
More information about the Nouveau
mailing list