Martin Peres
2010-Sep-29 13:11 UTC
[PATCH 2/3] Add pause/unpause methods to the PGRAPH engine
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 | 39 +++++++++++++++++++++++++++++++ 4 files changed, 57 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..a32cb2d 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -381,6 +381,45 @@ 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 = 0xffffffff; + + nv_wr32(dev, NV50_PGRAPH_CONTROL, 0); + start = nv04_timer_read(dev); + 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 >= 2000000000) { + /* 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)); + + nv50_graph_unpause(dev); + return 1; + } + } + 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 --------------020605050507080803020700 Content-Type: text/x-patch; name="0003-Idle-PGRAPH-and-PFIFO-before-changing-the-clocks.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0003-Idle-PGRAPH-and-PFIFO-before-changing-the-clocks.patch"