All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] drm/nv50: align size of buffer object to the right boundaries.
@ 2010-02-01 18:34 Maarten Maathuis
       [not found] ` <1265049275-7680-1-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 7+ messages in thread
From: Maarten Maathuis @ 2010-02-01 18:34 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

- Depth and stencil buffers are supposed to be large enough in general.

Signed-off-by: Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/gpu/drm/nouveau/nouveau_bo.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index db0ed4c..028719f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -65,8 +65,10 @@ nouveau_bo_fixup_align(struct drm_device *dev,
 
 	/*
 	 * Some of the tile_flags have a periodic structure of N*4096 bytes,
-	 * align to to that as well as the page size. Overallocate memory to
-	 * avoid corruption of other buffer objects.
+	 * align to to that as well as the page size. Align the size to the
+	 * appropriate boundaries. This does imply that sizes are rounded up
+	 * 3-7 pages, so be aware of this and do not waste memory by allocating
+	 * many small buffers.
 	 */
 	if (dev_priv->card_type == NV_50) {
 		uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15;
@@ -77,22 +79,20 @@ nouveau_bo_fixup_align(struct drm_device *dev,
 		case 0x2800:
 		case 0x4800:
 		case 0x7a00:
-			*size = roundup(*size, block_size);
 			if (is_power_of_2(block_size)) {
-				*size += 3 * block_size;
 				for (i = 1; i < 10; i++) {
 					*align = 12 * i * block_size;
 					if (!(*align % 65536))
 						break;
 				}
 			} else {
-				*size += 6 * block_size;
 				for (i = 1; i < 10; i++) {
 					*align = 8 * i * block_size;
 					if (!(*align % 65536))
 						break;
 				}
 			}
+			*size = roundup(*size, *align);
 			break;
 		default:
 			break;
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/4] drm/nv50: make the pgraph irq handler loop like the pre-nv50 version
       [not found] ` <1265049275-7680-1-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2010-02-01 18:34   ` Maarten Maathuis
       [not found]     ` <1265049275-7680-2-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 7+ messages in thread
From: Maarten Maathuis @ 2010-02-01 18:34 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/gpu/drm/nouveau/nouveau_irq.c |  140 ++++++++++++++++++---------------
 1 files changed, 76 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
index baa9b3e..475d0f2 100644
--- a/drivers/gpu/drm/nouveau/nouveau_irq.c
+++ b/drivers/gpu/drm/nouveau/nouveau_irq.c
@@ -580,83 +580,95 @@ nouveau_pgraph_irq_handler(struct drm_device *dev)
 static void
 nv50_pgraph_irq_handler(struct drm_device *dev)
 {
-	uint32_t status, nsource;
+	uint32_t status;
 
-	status = nv_rd32(dev, NV03_PGRAPH_INTR);
-	nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
+	while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) {
+		uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
 
-	if (status & 0x00000001) {
-		nouveau_pgraph_intr_notify(dev, nsource);
-		status &= ~0x00000001;
-		nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001);
-	}
+		if (status & 0x00000001) {
+			nouveau_pgraph_intr_notify(dev, nsource);
+			status &= ~0x00000001;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001);
+		}
 
-	if (status & 0x00000010) {
-		nouveau_pgraph_intr_error(dev, nsource |
-					  NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD);
+		if (status & 0x00000010) {
+			nouveau_pgraph_intr_error(dev, nsource |
+						  NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD);
 
-		status &= ~0x00000010;
-		nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010);
-	}
+			status &= ~0x00000010;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010);
+		}
 
-	if (status & 0x00001000) {
-		nv_wr32(dev, 0x400500, 0x00000000);
-		nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
-		nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev,
-			NV40_PGRAPH_INTR_EN) & ~NV_PGRAPH_INTR_CONTEXT_SWITCH);
-		nv_wr32(dev, 0x400500, 0x00010001);
+		if (status & 0x00001000) {
+			nv_wr32(dev, 0x400500, 0x00000000);
+			nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
+			nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev,
+				NV40_PGRAPH_INTR_EN) & ~NV_PGRAPH_INTR_CONTEXT_SWITCH);
+			nv_wr32(dev, 0x400500, 0x00010001);
 
-		nv50_graph_context_switch(dev);
+			nv50_graph_context_switch(dev);
 
-		status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
-	}
+			status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+		}
 
-	if (status & 0x00100000) {
-		nouveau_pgraph_intr_error(dev, nsource |
-					  NV03_PGRAPH_NSOURCE_DATA_ERROR);
+		if (status & 0x00100000) {
+			nouveau_pgraph_intr_error(dev, nsource |
+						  NV03_PGRAPH_NSOURCE_DATA_ERROR);
 
-		status &= ~0x00100000;
-		nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000);
-	}
+			status &= ~0x00100000;
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000);
+		}
 
-	if (status & 0x00200000) {
-		int r;
-
-		nouveau_pgraph_intr_error(dev, nsource |
-					  NV03_PGRAPH_NSOURCE_PROTECTION_ERROR);
-
-		NV_ERROR(dev, "magic set 1:\n");
-		for (r = 0x408900; r <= 0x408910; r += 4)
-			NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
-		nv_wr32(dev, 0x408900, nv_rd32(dev, 0x408904) | 0xc0000000);
-		for (r = 0x408e08; r <= 0x408e24; r += 4)
-			NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
-		nv_wr32(dev, 0x408e08, nv_rd32(dev, 0x408e08) | 0xc0000000);
-
-		NV_ERROR(dev, "magic set 2:\n");
-		for (r = 0x409900; r <= 0x409910; r += 4)
-			NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
-		nv_wr32(dev, 0x409900, nv_rd32(dev, 0x409904) | 0xc0000000);
-		for (r = 0x409e08; r <= 0x409e24; r += 4)
-			NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
-		nv_wr32(dev, 0x409e08, nv_rd32(dev, 0x409e08) | 0xc0000000);
-
-		status &= ~0x00200000;
-		nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource);
-		nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000);
-	}
+		if (status & 0x00200000) {
+			int r;
+
+			nouveau_pgraph_intr_error(dev, nsource |
+					NV03_PGRAPH_NSOURCE_PROTECTION_ERROR);
+
+			NV_ERROR(dev, "magic set 1:\n");
+			for (r = 0x408900; r <= 0x408910; r += 4)
+				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+					nv_rd32(dev, r));
+			nv_wr32(dev, 0x408900,
+				nv_rd32(dev, 0x408904) | 0xc0000000);
+			for (r = 0x408e08; r <= 0x408e24; r += 4)
+				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+							nv_rd32(dev, r));
+			nv_wr32(dev, 0x408e08,
+				nv_rd32(dev, 0x408e08) | 0xc0000000);
+
+			NV_ERROR(dev, "magic set 2:\n");
+			for (r = 0x409900; r <= 0x409910; r += 4)
+				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+					nv_rd32(dev, r));
+			nv_wr32(dev, 0x409900,
+				nv_rd32(dev, 0x409904) | 0xc0000000);
+			for (r = 0x409e08; r <= 0x409e24; r += 4)
+				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+					nv_rd32(dev, r));
+			nv_wr32(dev, 0x409e08,
+				nv_rd32(dev, 0x409e08) | 0xc0000000);
+
+			status &= ~0x00200000;
+			nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource);
+			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000);
+		}
 
-	if (status) {
-		NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status);
-		nv_wr32(dev, NV03_PGRAPH_INTR, status);
-	}
+		if (status) {
+			NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n",
+				status);
+			nv_wr32(dev, NV03_PGRAPH_INTR, status);
+		}
 
-	{
-		const int isb = (1 << 16) | (1 << 0);
+		{
+			const int isb = (1 << 16) | (1 << 0);
 
-		if ((nv_rd32(dev, 0x400500) & isb) != isb)
-			nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | isb);
-		nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));
+			if ((nv_rd32(dev, 0x400500) & isb) != isb)
+				nv_wr32(dev, 0x400500,
+					nv_rd32(dev, 0x400500) | isb);
+			nv_wr32(dev, 0x400824,
+				nv_rd32(dev, 0x400824) & ~(1 << 31));
+		}
 	}
 
 	nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/4] drm/nv50: avoid unloading pgraph context when ctxprog is running
       [not found]     ` <1265049275-7680-2-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2010-02-01 18:34       ` Maarten Maathuis
       [not found]         ` <1265049275-7680-3-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2010-02-01 22:26       ` [PATCH 2/4] drm/nv50: make the pgraph irq handler loop like the pre-nv50 version Maarten Maathuis
  1 sibling, 1 reply; 7+ messages in thread
From: Maarten Maathuis @ 2010-02-01 18:34 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

- We need to disable pgraph fifo access before checking the current channel,
otherwise we could still hit a running ctxprog.
- The writes to 0x400500 are already handled by pgraph->fifo_access and are
therefore redundant, moreover pgraph fifo access should not be reenabled before
current context is set as invalid. So remove them altogether.

Signed-off-by: Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/gpu/drm/nouveau/nouveau_channel.c |    7 +++----
 drivers/gpu/drm/nouveau/nv50_graph.c      |   10 +++++++---
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
index 343d718..2281f99 100644
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -278,12 +278,11 @@ nouveau_channel_free(struct nouveau_channel *chan)
 	/* Ensure the channel is no longer active on the GPU */
 	pfifo->reassign(dev, false);
 
-	if (pgraph->channel(dev) == chan) {
-		pgraph->fifo_access(dev, false);
+	pgraph->fifo_access(dev, false);
+	if (pgraph->channel(dev) == chan)
 		pgraph->unload_context(dev);
-		pgraph->fifo_access(dev, true);
-	}
 	pgraph->destroy_context(chan);
+	pgraph->fifo_access(dev, true);
 
 	if (pfifo->channel_id(dev) == chan->id) {
 		pfifo->disable(dev);
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
index 20319e5..6d50480 100644
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
@@ -165,6 +165,12 @@ nv50_graph_channel(struct drm_device *dev)
 	uint32_t inst;
 	int i;
 
+	/* Be sure we're not in the middle of a context switch or bad things
+	 * will happen, such as unloading the wrong pgraph context.
+	 */
+	if (!nv_wait(0x400300, 0x00000001, 0x00000000))
+		NV_ERROR(dev, "Ctxprog is still running\n");
+
 	inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
 	if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
 		return NULL;
@@ -275,7 +281,7 @@ nv50_graph_load_context(struct nouveau_channel *chan)
 int
 nv50_graph_unload_context(struct drm_device *dev)
 {
-	uint32_t inst, fifo = nv_rd32(dev, 0x400500);
+	uint32_t inst;
 
 	inst  = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
 	if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
@@ -283,12 +289,10 @@ nv50_graph_unload_context(struct drm_device *dev)
 	inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE;
 
 	nouveau_wait_for_idle(dev);
-	nv_wr32(dev, 0x400500, fifo & ~1);
 	nv_wr32(dev, 0x400784, inst);
 	nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x20);
 	nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 0x01);
 	nouveau_wait_for_idle(dev);
-	nv_wr32(dev, 0x400500, fifo);
 
 	nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst);
 	return 0;
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/4] drm/nv50: delete ramfc object after disabling fifo, not before
       [not found]         ` <1265049275-7680-3-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2010-02-01 18:34           ` Maarten Maathuis
  2010-02-01 18:40           ` [PATCH 3/4] drm/nv50: avoid unloading pgraph context when ctxprog is running Maarten Maathuis
  1 sibling, 0 replies; 7+ messages in thread
From: Maarten Maathuis @ 2010-02-01 18:34 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

- ramfc is zero'ed upon destruction, so it's safer to do things in the right
order.

Signed-off-by: Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/gpu/drm/nouveau/nv50_fifo.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c
index 32b244b..204a79f 100644
--- a/drivers/gpu/drm/nouveau/nv50_fifo.c
+++ b/drivers/gpu/drm/nouveau/nv50_fifo.c
@@ -317,17 +317,20 @@ void
 nv50_fifo_destroy_context(struct nouveau_channel *chan)
 {
 	struct drm_device *dev = chan->dev;
+	struct nouveau_gpuobj_ref *ramfc = chan->ramfc;
 
 	NV_DEBUG(dev, "ch%d\n", chan->id);
 
-	nouveau_gpuobj_ref_del(dev, &chan->ramfc);
-	nouveau_gpuobj_ref_del(dev, &chan->cache);
-
+	/* This will ensure the channel is seen as disabled. */
+	chan->ramfc = NULL;
 	nv50_fifo_channel_disable(dev, chan->id, false);
 
 	/* Dummy channel, also used on ch 127 */
 	if (chan->id == 0)
 		nv50_fifo_channel_disable(dev, 127, false);
+
+	nouveau_gpuobj_ref_del(dev, &ramfc);
+	nouveau_gpuobj_ref_del(dev, &chan->cache);
 }
 
 int
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/4] drm/nv50: avoid unloading pgraph context when ctxprog is running
       [not found]         ` <1265049275-7680-3-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2010-02-01 18:34           ` [PATCH 4/4] drm/nv50: delete ramfc object after disabling fifo, not before Maarten Maathuis
@ 2010-02-01 18:40           ` Maarten Maathuis
       [not found]             ` <6d4bc9fc1002011040i538bda6o7f4eb24ac4a4579a-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  1 sibling, 1 reply; 7+ messages in thread
From: Maarten Maathuis @ 2010-02-01 18:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Someone should probably check this out on earlier cards as well.

On Mon, Feb 1, 2010 at 7:34 PM, Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> - We need to disable pgraph fifo access before checking the current channel,
> otherwise we could still hit a running ctxprog.
> - The writes to 0x400500 are already handled by pgraph->fifo_access and are
> therefore redundant, moreover pgraph fifo access should not be reenabled before
> current context is set as invalid. So remove them altogether.
>
> Signed-off-by: Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>  drivers/gpu/drm/nouveau/nouveau_channel.c |    7 +++----
>  drivers/gpu/drm/nouveau/nv50_graph.c      |   10 +++++++---
>  2 files changed, 10 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
> index 343d718..2281f99 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_channel.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
> @@ -278,12 +278,11 @@ nouveau_channel_free(struct nouveau_channel *chan)
>        /* Ensure the channel is no longer active on the GPU */
>        pfifo->reassign(dev, false);
>
> -       if (pgraph->channel(dev) == chan) {
> -               pgraph->fifo_access(dev, false);
> +       pgraph->fifo_access(dev, false);
> +       if (pgraph->channel(dev) == chan)
>                pgraph->unload_context(dev);
> -               pgraph->fifo_access(dev, true);
> -       }
>        pgraph->destroy_context(chan);
> +       pgraph->fifo_access(dev, true);
>
>        if (pfifo->channel_id(dev) == chan->id) {
>                pfifo->disable(dev);
> diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
> index 20319e5..6d50480 100644
> --- a/drivers/gpu/drm/nouveau/nv50_graph.c
> +++ b/drivers/gpu/drm/nouveau/nv50_graph.c
> @@ -165,6 +165,12 @@ nv50_graph_channel(struct drm_device *dev)
>        uint32_t inst;
>        int i;
>
> +       /* Be sure we're not in the middle of a context switch or bad things
> +        * will happen, such as unloading the wrong pgraph context.
> +        */
> +       if (!nv_wait(0x400300, 0x00000001, 0x00000000))
> +               NV_ERROR(dev, "Ctxprog is still running\n");
> +
>        inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
>        if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
>                return NULL;
> @@ -275,7 +281,7 @@ nv50_graph_load_context(struct nouveau_channel *chan)
>  int
>  nv50_graph_unload_context(struct drm_device *dev)
>  {
> -       uint32_t inst, fifo = nv_rd32(dev, 0x400500);
> +       uint32_t inst;
>
>        inst  = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
>        if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
> @@ -283,12 +289,10 @@ nv50_graph_unload_context(struct drm_device *dev)
>        inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE;
>
>        nouveau_wait_for_idle(dev);
> -       nv_wr32(dev, 0x400500, fifo & ~1);
>        nv_wr32(dev, 0x400784, inst);
>        nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x20);
>        nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 0x01);
>        nouveau_wait_for_idle(dev);
> -       nv_wr32(dev, 0x400500, fifo);
>
>        nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst);
>        return 0;
> --
> 1.6.6.1
>
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/4] drm/nv50: make the pgraph irq handler loop like the pre-nv50 version
       [not found]     ` <1265049275-7680-2-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2010-02-01 18:34       ` [PATCH 3/4] drm/nv50: avoid unloading pgraph context when ctxprog is running Maarten Maathuis
@ 2010-02-01 22:26       ` Maarten Maathuis
  1 sibling, 0 replies; 7+ messages in thread
From: Maarten Maathuis @ 2010-02-01 22:26 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

I'm wondering if the write to 0x400824 should be outside the loop,
since it's a flag blocking a ctxprog from continuing.
Anyone know why this one wasn't looping but the pre-nv50 one is?

On Mon, Feb 1, 2010 at 7:34 PM, Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Signed-off-by: Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>  drivers/gpu/drm/nouveau/nouveau_irq.c |  140 ++++++++++++++++++---------------
>  1 files changed, 76 insertions(+), 64 deletions(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
> index baa9b3e..475d0f2 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_irq.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c
> @@ -580,83 +580,95 @@ nouveau_pgraph_irq_handler(struct drm_device *dev)
>  static void
>  nv50_pgraph_irq_handler(struct drm_device *dev)
>  {
> -       uint32_t status, nsource;
> +       uint32_t status;
>
> -       status = nv_rd32(dev, NV03_PGRAPH_INTR);
> -       nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
> +       while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) {
> +               uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
>
> -       if (status & 0x00000001) {
> -               nouveau_pgraph_intr_notify(dev, nsource);
> -               status &= ~0x00000001;
> -               nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001);
> -       }
> +               if (status & 0x00000001) {
> +                       nouveau_pgraph_intr_notify(dev, nsource);
> +                       status &= ~0x00000001;
> +                       nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001);
> +               }
>
> -       if (status & 0x00000010) {
> -               nouveau_pgraph_intr_error(dev, nsource |
> -                                         NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD);
> +               if (status & 0x00000010) {
> +                       nouveau_pgraph_intr_error(dev, nsource |
> +                                                 NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD);
>
> -               status &= ~0x00000010;
> -               nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010);
> -       }
> +                       status &= ~0x00000010;
> +                       nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010);
> +               }
>
> -       if (status & 0x00001000) {
> -               nv_wr32(dev, 0x400500, 0x00000000);
> -               nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
> -               nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev,
> -                       NV40_PGRAPH_INTR_EN) & ~NV_PGRAPH_INTR_CONTEXT_SWITCH);
> -               nv_wr32(dev, 0x400500, 0x00010001);
> +               if (status & 0x00001000) {
> +                       nv_wr32(dev, 0x400500, 0x00000000);
> +                       nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
> +                       nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev,
> +                               NV40_PGRAPH_INTR_EN) & ~NV_PGRAPH_INTR_CONTEXT_SWITCH);
> +                       nv_wr32(dev, 0x400500, 0x00010001);
>
> -               nv50_graph_context_switch(dev);
> +                       nv50_graph_context_switch(dev);
>
> -               status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
> -       }
> +                       status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
> +               }
>
> -       if (status & 0x00100000) {
> -               nouveau_pgraph_intr_error(dev, nsource |
> -                                         NV03_PGRAPH_NSOURCE_DATA_ERROR);
> +               if (status & 0x00100000) {
> +                       nouveau_pgraph_intr_error(dev, nsource |
> +                                                 NV03_PGRAPH_NSOURCE_DATA_ERROR);
>
> -               status &= ~0x00100000;
> -               nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000);
> -       }
> +                       status &= ~0x00100000;
> +                       nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000);
> +               }
>
> -       if (status & 0x00200000) {
> -               int r;
> -
> -               nouveau_pgraph_intr_error(dev, nsource |
> -                                         NV03_PGRAPH_NSOURCE_PROTECTION_ERROR);
> -
> -               NV_ERROR(dev, "magic set 1:\n");
> -               for (r = 0x408900; r <= 0x408910; r += 4)
> -                       NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
> -               nv_wr32(dev, 0x408900, nv_rd32(dev, 0x408904) | 0xc0000000);
> -               for (r = 0x408e08; r <= 0x408e24; r += 4)
> -                       NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
> -               nv_wr32(dev, 0x408e08, nv_rd32(dev, 0x408e08) | 0xc0000000);
> -
> -               NV_ERROR(dev, "magic set 2:\n");
> -               for (r = 0x409900; r <= 0x409910; r += 4)
> -                       NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
> -               nv_wr32(dev, 0x409900, nv_rd32(dev, 0x409904) | 0xc0000000);
> -               for (r = 0x409e08; r <= 0x409e24; r += 4)
> -                       NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r));
> -               nv_wr32(dev, 0x409e08, nv_rd32(dev, 0x409e08) | 0xc0000000);
> -
> -               status &= ~0x00200000;
> -               nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource);
> -               nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000);
> -       }
> +               if (status & 0x00200000) {
> +                       int r;
> +
> +                       nouveau_pgraph_intr_error(dev, nsource |
> +                                       NV03_PGRAPH_NSOURCE_PROTECTION_ERROR);
> +
> +                       NV_ERROR(dev, "magic set 1:\n");
> +                       for (r = 0x408900; r <= 0x408910; r += 4)
> +                               NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
> +                                       nv_rd32(dev, r));
> +                       nv_wr32(dev, 0x408900,
> +                               nv_rd32(dev, 0x408904) | 0xc0000000);
> +                       for (r = 0x408e08; r <= 0x408e24; r += 4)
> +                               NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
> +                                                       nv_rd32(dev, r));
> +                       nv_wr32(dev, 0x408e08,
> +                               nv_rd32(dev, 0x408e08) | 0xc0000000);
> +
> +                       NV_ERROR(dev, "magic set 2:\n");
> +                       for (r = 0x409900; r <= 0x409910; r += 4)
> +                               NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
> +                                       nv_rd32(dev, r));
> +                       nv_wr32(dev, 0x409900,
> +                               nv_rd32(dev, 0x409904) | 0xc0000000);
> +                       for (r = 0x409e08; r <= 0x409e24; r += 4)
> +                               NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
> +                                       nv_rd32(dev, r));
> +                       nv_wr32(dev, 0x409e08,
> +                               nv_rd32(dev, 0x409e08) | 0xc0000000);
> +
> +                       status &= ~0x00200000;
> +                       nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource);
> +                       nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000);
> +               }
>
> -       if (status) {
> -               NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status);
> -               nv_wr32(dev, NV03_PGRAPH_INTR, status);
> -       }
> +               if (status) {
> +                       NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n",
> +                               status);
> +                       nv_wr32(dev, NV03_PGRAPH_INTR, status);
> +               }
>
> -       {
> -               const int isb = (1 << 16) | (1 << 0);
> +               {
> +                       const int isb = (1 << 16) | (1 << 0);
>
> -               if ((nv_rd32(dev, 0x400500) & isb) != isb)
> -                       nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | isb);
> -               nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));
> +                       if ((nv_rd32(dev, 0x400500) & isb) != isb)
> +                               nv_wr32(dev, 0x400500,
> +                                       nv_rd32(dev, 0x400500) | isb);
> +                       nv_wr32(dev, 0x400824,
> +                               nv_rd32(dev, 0x400824) & ~(1 << 31));
> +               }
>        }
>
>        nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
> --
> 1.6.6.1
>
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/4] drm/nv50: avoid unloading pgraph context when ctxprog is running
       [not found]             ` <6d4bc9fc1002011040i538bda6o7f4eb24ac4a4579a-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2010-02-01 22:28               ` Maarten Maathuis
  0 siblings, 0 replies; 7+ messages in thread
From: Maarten Maathuis @ 2010-02-01 22:28 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

If there are no objections, please share them as soon as possible.

On Mon, Feb 1, 2010 at 7:40 PM, Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Someone should probably check this out on earlier cards as well.
>
> On Mon, Feb 1, 2010 at 7:34 PM, Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> - We need to disable pgraph fifo access before checking the current channel,
>> otherwise we could still hit a running ctxprog.
>> - The writes to 0x400500 are already handled by pgraph->fifo_access and are
>> therefore redundant, moreover pgraph fifo access should not be reenabled before
>> current context is set as invalid. So remove them altogether.
>>
>> Signed-off-by: Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> ---
>>  drivers/gpu/drm/nouveau/nouveau_channel.c |    7 +++----
>>  drivers/gpu/drm/nouveau/nv50_graph.c      |   10 +++++++---
>>  2 files changed, 10 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
>> index 343d718..2281f99 100644
>> --- a/drivers/gpu/drm/nouveau/nouveau_channel.c
>> +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
>> @@ -278,12 +278,11 @@ nouveau_channel_free(struct nouveau_channel *chan)
>>        /* Ensure the channel is no longer active on the GPU */
>>        pfifo->reassign(dev, false);
>>
>> -       if (pgraph->channel(dev) == chan) {
>> -               pgraph->fifo_access(dev, false);
>> +       pgraph->fifo_access(dev, false);
>> +       if (pgraph->channel(dev) == chan)
>>                pgraph->unload_context(dev);
>> -               pgraph->fifo_access(dev, true);
>> -       }
>>        pgraph->destroy_context(chan);
>> +       pgraph->fifo_access(dev, true);
>>
>>        if (pfifo->channel_id(dev) == chan->id) {
>>                pfifo->disable(dev);
>> diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
>> index 20319e5..6d50480 100644
>> --- a/drivers/gpu/drm/nouveau/nv50_graph.c
>> +++ b/drivers/gpu/drm/nouveau/nv50_graph.c
>> @@ -165,6 +165,12 @@ nv50_graph_channel(struct drm_device *dev)
>>        uint32_t inst;
>>        int i;
>>
>> +       /* Be sure we're not in the middle of a context switch or bad things
>> +        * will happen, such as unloading the wrong pgraph context.
>> +        */
>> +       if (!nv_wait(0x400300, 0x00000001, 0x00000000))
>> +               NV_ERROR(dev, "Ctxprog is still running\n");
>> +
>>        inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
>>        if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
>>                return NULL;
>> @@ -275,7 +281,7 @@ nv50_graph_load_context(struct nouveau_channel *chan)
>>  int
>>  nv50_graph_unload_context(struct drm_device *dev)
>>  {
>> -       uint32_t inst, fifo = nv_rd32(dev, 0x400500);
>> +       uint32_t inst;
>>
>>        inst  = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
>>        if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
>> @@ -283,12 +289,10 @@ nv50_graph_unload_context(struct drm_device *dev)
>>        inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE;
>>
>>        nouveau_wait_for_idle(dev);
>> -       nv_wr32(dev, 0x400500, fifo & ~1);
>>        nv_wr32(dev, 0x400784, inst);
>>        nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x20);
>>        nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 0x01);
>>        nouveau_wait_for_idle(dev);
>> -       nv_wr32(dev, 0x400500, fifo);
>>
>>        nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst);
>>        return 0;
>> --
>> 1.6.6.1
>>
>>
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-02-01 22:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-01 18:34 [PATCH 1/4] drm/nv50: align size of buffer object to the right boundaries Maarten Maathuis
     [not found] ` <1265049275-7680-1-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2010-02-01 18:34   ` [PATCH 2/4] drm/nv50: make the pgraph irq handler loop like the pre-nv50 version Maarten Maathuis
     [not found]     ` <1265049275-7680-2-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2010-02-01 18:34       ` [PATCH 3/4] drm/nv50: avoid unloading pgraph context when ctxprog is running Maarten Maathuis
     [not found]         ` <1265049275-7680-3-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2010-02-01 18:34           ` [PATCH 4/4] drm/nv50: delete ramfc object after disabling fifo, not before Maarten Maathuis
2010-02-01 18:40           ` [PATCH 3/4] drm/nv50: avoid unloading pgraph context when ctxprog is running Maarten Maathuis
     [not found]             ` <6d4bc9fc1002011040i538bda6o7f4eb24ac4a4579a-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-02-01 22:28               ` Maarten Maathuis
2010-02-01 22:26       ` [PATCH 2/4] drm/nv50: make the pgraph irq handler loop like the pre-nv50 version Maarten Maathuis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.