linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] drm/v3d: Fix debugfs reads of MMU regs.
@ 2019-04-19  0:10 Eric Anholt
  2019-04-19  0:10 ` [PATCH 2/4] drm/v3d: Set the correct DMA mask according to the MMU's limits Eric Anholt
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Eric Anholt @ 2019-04-19  0:10 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-kernel, Paul Kocialkowski, Maxime Ripard, david.emett,
	thomas.spurden, Eric Anholt

They're in the hub, not the individual cores.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/gpu/drm/v3d/v3d_debugfs.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/v3d/v3d_debugfs.c b/drivers/gpu/drm/v3d/v3d_debugfs.c
index a2dc4262955e..356a8acfa72d 100644
--- a/drivers/gpu/drm/v3d/v3d_debugfs.c
+++ b/drivers/gpu/drm/v3d/v3d_debugfs.c
@@ -26,6 +26,10 @@ static const struct v3d_reg_def v3d_hub_reg_defs[] = {
 	REGDEF(V3D_HUB_IDENT3),
 	REGDEF(V3D_HUB_INT_STS),
 	REGDEF(V3D_HUB_INT_MSK_STS),
+
+	REGDEF(V3D_MMU_CTL),
+	REGDEF(V3D_MMU_VIO_ADDR),
+	REGDEF(V3D_MMU_VIO_ID),
 };
 
 static const struct v3d_reg_def v3d_gca_reg_defs[] = {
@@ -50,9 +54,6 @@ static const struct v3d_reg_def v3d_core_reg_defs[] = {
 	REGDEF(V3D_PTB_BPCA),
 	REGDEF(V3D_PTB_BPCS),
 
-	REGDEF(V3D_MMU_CTL),
-	REGDEF(V3D_MMU_VIO_ADDR),
-
 	REGDEF(V3D_GMP_STATUS),
 	REGDEF(V3D_GMP_CFG),
 	REGDEF(V3D_GMP_VIO_ADDR),
-- 
2.20.1


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

* [PATCH 2/4] drm/v3d: Set the correct DMA mask according to the MMU's limits.
  2019-04-19  0:10 [PATCH 1/4] drm/v3d: Fix debugfs reads of MMU regs Eric Anholt
@ 2019-04-19  0:10 ` Eric Anholt
  2019-04-19  8:47   ` Paul Kocialkowski
  2019-04-19  0:10 ` [PATCH 3/4] drm/v3d: Dump V3D error debug registers in debugfs, and one at reset Eric Anholt
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Eric Anholt @ 2019-04-19  0:10 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-kernel, Paul Kocialkowski, Maxime Ripard, david.emett,
	thomas.spurden, Eric Anholt

On 7278, we've got 40 bits to work with.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/gpu/drm/v3d/v3d_debugfs.c | 1 +
 drivers/gpu/drm/v3d/v3d_drv.c     | 6 +++++-
 drivers/gpu/drm/v3d/v3d_regs.h    | 8 ++++++++
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/v3d/v3d_debugfs.c b/drivers/gpu/drm/v3d/v3d_debugfs.c
index 356a8acfa72d..ab652a034959 100644
--- a/drivers/gpu/drm/v3d/v3d_debugfs.c
+++ b/drivers/gpu/drm/v3d/v3d_debugfs.c
@@ -30,6 +30,7 @@ static const struct v3d_reg_def v3d_hub_reg_defs[] = {
 	REGDEF(V3D_MMU_CTL),
 	REGDEF(V3D_MMU_VIO_ADDR),
 	REGDEF(V3D_MMU_VIO_ID),
+	REGDEF(V3D_MMU_DEBUG_INFO),
 };
 
 static const struct v3d_reg_def v3d_gca_reg_defs[] = {
diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
index f8d1d2569c1f..7ab36192e6bc 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.c
+++ b/drivers/gpu/drm/v3d/v3d_drv.c
@@ -472,9 +472,9 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
 	struct drm_device *drm;
 	struct v3d_dev *v3d;
 	int ret;
+	u32 mmu_debug;
 	u32 ident1;
 
-	dev->coherent_dma_mask = DMA_BIT_MASK(36);
 
 	v3d = kzalloc(sizeof(*v3d), GFP_KERNEL);
 	if (!v3d)
@@ -491,6 +491,10 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
 	if (ret)
 		goto dev_free;
 
+	mmu_debug = V3D_READ(V3D_MMU_DEBUG_INFO);
+	dev->coherent_dma_mask =
+		DMA_BIT_MASK(30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_PA_WIDTH));
+
 	ident1 = V3D_READ(V3D_HUB_IDENT1);
 	v3d->ver = (V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_TVER) * 10 +
 		    V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_REV));
diff --git a/drivers/gpu/drm/v3d/v3d_regs.h b/drivers/gpu/drm/v3d/v3d_regs.h
index 9a8ff0ce648e..54c8c4320da0 100644
--- a/drivers/gpu/drm/v3d/v3d_regs.h
+++ b/drivers/gpu/drm/v3d/v3d_regs.h
@@ -191,6 +191,14 @@
 /* Address that faulted */
 #define V3D_MMU_VIO_ADDR                               0x01234
 
+#define V3D_MMU_DEBUG_INFO                             0x01238
+# define V3D_MMU_PA_WIDTH_MASK                         V3D_MASK(11, 8)
+# define V3D_MMU_PA_WIDTH_SHIFT                        8
+# define V3D_MMU_VA_WIDTH_MASK                         V3D_MASK(7, 4)
+# define V3D_MMU_VA_WIDTH_SHIFT                        4
+# define V3D_MMU_VERSION_MASK                          V3D_MASK(3, 0)
+# define V3D_MMU_VERSION_SHIFT                         0
+
 /* Per-V3D-core registers */
 
 #define V3D_CTL_IDENT0                                 0x00000
-- 
2.20.1


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

* [PATCH 3/4] drm/v3d: Dump V3D error debug registers in debugfs, and one at reset.
  2019-04-19  0:10 [PATCH 1/4] drm/v3d: Fix debugfs reads of MMU regs Eric Anholt
  2019-04-19  0:10 ` [PATCH 2/4] drm/v3d: Set the correct DMA mask according to the MMU's limits Eric Anholt
@ 2019-04-19  0:10 ` Eric Anholt
  2019-04-19  8:48   ` Paul Kocialkowski
  2019-04-19  0:10 ` [PATCH 4/4] drm/v3d: Fix and extend MMU error handling Eric Anholt
  2019-04-19  8:47 ` [PATCH 1/4] drm/v3d: Fix debugfs reads of MMU regs Paul Kocialkowski
  3 siblings, 1 reply; 8+ messages in thread
From: Eric Anholt @ 2019-04-19  0:10 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-kernel, Paul Kocialkowski, Maxime Ripard, david.emett,
	thomas.spurden, Eric Anholt

Looking at a hang recently, I noticed these registers that might tell
me if something obvious was wrong.  They didn't help in this case, but
keep it around for the future.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/gpu/drm/v3d/v3d_debugfs.c |  5 ++++
 drivers/gpu/drm/v3d/v3d_gem.c     |  4 +++-
 drivers/gpu/drm/v3d/v3d_regs.h    | 38 +++++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/v3d/v3d_debugfs.c b/drivers/gpu/drm/v3d/v3d_debugfs.c
index ab652a034959..78a78938e81f 100644
--- a/drivers/gpu/drm/v3d/v3d_debugfs.c
+++ b/drivers/gpu/drm/v3d/v3d_debugfs.c
@@ -58,6 +58,11 @@ static const struct v3d_reg_def v3d_core_reg_defs[] = {
 	REGDEF(V3D_GMP_STATUS),
 	REGDEF(V3D_GMP_CFG),
 	REGDEF(V3D_GMP_VIO_ADDR),
+
+	REGDEF(V3D_ERR_FDBGO),
+	REGDEF(V3D_ERR_FDBGB),
+	REGDEF(V3D_ERR_FDBGS),
+	REGDEF(V3D_ERR_STAT),
 };
 
 static const struct v3d_reg_def v3d_csd_reg_defs[] = {
diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c
index f736e021467a..27e0f87075d9 100644
--- a/drivers/gpu/drm/v3d/v3d_gem.c
+++ b/drivers/gpu/drm/v3d/v3d_gem.c
@@ -109,7 +109,9 @@ v3d_reset(struct v3d_dev *v3d)
 {
 	struct drm_device *dev = &v3d->drm;
 
-	DRM_ERROR("Resetting GPU.\n");
+	DRM_DEV_ERROR(dev->dev, "Resetting GPU for hang.\n");
+	DRM_DEV_ERROR(dev->dev, "V3D_ERR_STAT: 0x%08x\n",
+		      V3D_CORE_READ(0, V3D_ERR_STAT));
 	trace_v3d_reset_begin(dev);
 
 	/* XXX: only needed for safe powerdown, not reset. */
diff --git a/drivers/gpu/drm/v3d/v3d_regs.h b/drivers/gpu/drm/v3d/v3d_regs.h
index 54c8c4320da0..eda1e289976f 100644
--- a/drivers/gpu/drm/v3d/v3d_regs.h
+++ b/drivers/gpu/drm/v3d/v3d_regs.h
@@ -455,4 +455,42 @@
 # define V3D_CSD_CURRENT_ID0_WG_Y_MASK                 V3D_MASK(15, 0)
 # define V3D_CSD_CURRENT_ID0_WG_Y_SHIFT                0
 
+#define V3D_ERR_FDBGO                                  0x00f04
+#define V3D_ERR_FDBGB                                  0x00f08
+#define V3D_ERR_FDBGR                                  0x00f0c
+
+#define V3D_ERR_FDBGS                                  0x00f10
+# define V3D_ERR_FDBGS_INTERPZ_IP_STALL                BIT(17)
+# define V3D_ERR_FDBGS_DEPTHO_FIFO_IP_STALL            BIT(16)
+# define V3D_ERR_FDBGS_XYNRM_IP_STALL                  BIT(14)
+# define V3D_ERR_FDBGS_EZREQ_FIFO_OP_VALID             BIT(13)
+# define V3D_ERR_FDBGS_QXYF_FIFO_OP_VALID              BIT(12)
+# define V3D_ERR_FDBGS_QXYF_FIFO_OP_LAST               BIT(11)
+# define V3D_ERR_FDBGS_EZTEST_ANYQVALID                BIT(7)
+# define V3D_ERR_FDBGS_EZTEST_PASS                     BIT(6)
+# define V3D_ERR_FDBGS_EZTEST_QREADY                   BIT(5)
+# define V3D_ERR_FDBGS_EZTEST_VLF_OKNOVALID            BIT(4)
+# define V3D_ERR_FDBGS_EZTEST_QSTALL                   BIT(3)
+# define V3D_ERR_FDBGS_EZTEST_IP_VLFSTALL              BIT(2)
+# define V3D_ERR_FDBGS_EZTEST_IP_PRSTALL               BIT(1)
+# define V3D_ERR_FDBGS_EZTEST_IP_QSTALL                BIT(0)
+
+#define V3D_ERR_STAT                                   0x00f20
+# define V3D_ERR_L2CARE                                BIT(15)
+# define V3D_ERR_VCMBE                                 BIT(14)
+# define V3D_ERR_VCMRE                                 BIT(13)
+# define V3D_ERR_VCDI                                  BIT(12)
+# define V3D_ERR_VCDE                                  BIT(11)
+# define V3D_ERR_VDWE                                  BIT(10)
+# define V3D_ERR_VPMEAS                                BIT(9)
+# define V3D_ERR_VPMEFNA                               BIT(8)
+# define V3D_ERR_VPMEWNA                               BIT(7)
+# define V3D_ERR_VPMERNA                               BIT(6)
+# define V3D_ERR_VPMERR                                BIT(5)
+# define V3D_ERR_VPMEWR                                BIT(4)
+# define V3D_ERR_VPAERRGL                              BIT(3)
+# define V3D_ERR_VPAEBRGL                              BIT(2)
+# define V3D_ERR_VPAERGS                               BIT(1)
+# define V3D_ERR_VPAEABB                               BIT(0)
+
 #endif /* V3D_REGS_H */
-- 
2.20.1


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

* [PATCH 4/4] drm/v3d: Fix and extend MMU error handling.
  2019-04-19  0:10 [PATCH 1/4] drm/v3d: Fix debugfs reads of MMU regs Eric Anholt
  2019-04-19  0:10 ` [PATCH 2/4] drm/v3d: Set the correct DMA mask according to the MMU's limits Eric Anholt
  2019-04-19  0:10 ` [PATCH 3/4] drm/v3d: Dump V3D error debug registers in debugfs, and one at reset Eric Anholt
@ 2019-04-19  0:10 ` Eric Anholt
  2019-04-19  8:52   ` Paul Kocialkowski
  2019-04-19  8:47 ` [PATCH 1/4] drm/v3d: Fix debugfs reads of MMU regs Paul Kocialkowski
  3 siblings, 1 reply; 8+ messages in thread
From: Eric Anholt @ 2019-04-19  0:10 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-kernel, Paul Kocialkowski, Maxime Ripard, david.emett,
	thomas.spurden, Eric Anholt

We were setting the wrong flags to enable PTI errors, so we were
seeing reads to invalid PTEs show up as write errors.  Also, we
weren't turning on the interrupts.  The AXI IDs we were dumping
included the outstanding write number and so they looked basically
random.  And the VIO_ADDR decoding was based on the MMU VA_WIDTH for
the first platform I worked on and was wrong on others.  In short,
this was a thorough mess from early HW enabling.

Tested on V3D 4.1 and 4.2 with intentional L2T, CLE, PTB, and TLB
faults.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/gpu/drm/v3d/v3d_drv.c  |  1 +
 drivers/gpu/drm/v3d/v3d_drv.h  |  2 ++
 drivers/gpu/drm/v3d/v3d_irq.c  | 31 +++++++++++++++++++++++++++----
 drivers/gpu/drm/v3d/v3d_mmu.c  |  7 +++++--
 drivers/gpu/drm/v3d/v3d_regs.h |  3 ++-
 5 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
index 7ab36192e6bc..9ce2e4ef6c2a 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.c
+++ b/drivers/gpu/drm/v3d/v3d_drv.c
@@ -494,6 +494,7 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
 	mmu_debug = V3D_READ(V3D_MMU_DEBUG_INFO);
 	dev->coherent_dma_mask =
 		DMA_BIT_MASK(30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_PA_WIDTH));
+	v3d->va_width = 30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_VA_WIDTH);
 
 	ident1 = V3D_READ(V3D_HUB_IDENT1);
 	v3d->ver = (V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_TVER) * 10 +
diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h
index 6d31a6a5a08e..64682923018d 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.h
+++ b/drivers/gpu/drm/v3d/v3d_drv.h
@@ -63,6 +63,8 @@ struct v3d_dev {
 	 */
 	void *mmu_scratch;
 	dma_addr_t mmu_scratch_paddr;
+	/* virtual address bits from V3D to the MMU. */
+	int va_width;
 
 	/* Number of V3D cores. */
 	u32 cores;
diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c
index fac3c542860b..268d8a889ac5 100644
--- a/drivers/gpu/drm/v3d/v3d_irq.c
+++ b/drivers/gpu/drm/v3d/v3d_irq.c
@@ -162,10 +162,33 @@ v3d_hub_irq(int irq, void *arg)
 		      V3D_HUB_INT_MMU_PTI |
 		      V3D_HUB_INT_MMU_CAP)) {
 		u32 axi_id = V3D_READ(V3D_MMU_VIO_ID);
-		u64 vio_addr = (u64)V3D_READ(V3D_MMU_VIO_ADDR) << 8;
-
-		dev_err(v3d->dev, "MMU error from client %d at 0x%08llx%s%s%s\n",
-			axi_id, (long long)vio_addr,
+		u64 vio_addr = ((u64)V3D_READ(V3D_MMU_VIO_ADDR) <<
+				(v3d->va_width - 32));
+		static const char *const v3d41_axi_ids[] = {
+			"L2T",
+			"PTB",
+			"PSE",
+			"TLB",
+			"CLE",
+			"TFU",
+			"MMU",
+			"GMP",
+		};
+		const char *client = "?";
+
+		V3D_WRITE(V3D_MMU_CTL,
+			  V3D_READ(V3D_MMU_CTL) & (V3D_MMU_CTL_CAP_EXCEEDED |
+						   V3D_MMU_CTL_PT_INVALID |
+						   V3D_MMU_CTL_WRITE_VIOLATION));
+
+		if (v3d->ver >= 41) {
+			axi_id = axi_id >> 5;
+			if (axi_id < ARRAY_SIZE(v3d41_axi_ids))
+				client = v3d41_axi_ids[axi_id];
+		}
+
+		dev_err(v3d->dev, "MMU error from client %s (%d) at 0x%llx%s%s%s\n",
+			client, axi_id, (long long)vio_addr,
 			((intsts & V3D_HUB_INT_MMU_WRV) ?
 			 ", write violation" : ""),
 			((intsts & V3D_HUB_INT_MMU_PTI) ?
diff --git a/drivers/gpu/drm/v3d/v3d_mmu.c b/drivers/gpu/drm/v3d/v3d_mmu.c
index 7a21f1787ab1..395e81d97163 100644
--- a/drivers/gpu/drm/v3d/v3d_mmu.c
+++ b/drivers/gpu/drm/v3d/v3d_mmu.c
@@ -69,10 +69,13 @@ int v3d_mmu_set_page_table(struct v3d_dev *v3d)
 	V3D_WRITE(V3D_MMU_PT_PA_BASE, v3d->pt_paddr >> V3D_MMU_PAGE_SHIFT);
 	V3D_WRITE(V3D_MMU_CTL,
 		  V3D_MMU_CTL_ENABLE |
-		  V3D_MMU_CTL_PT_INVALID |
+		  V3D_MMU_CTL_PT_INVALID_ENABLE |
 		  V3D_MMU_CTL_PT_INVALID_ABORT |
+		  V3D_MMU_CTL_PT_INVALID_INT |
 		  V3D_MMU_CTL_WRITE_VIOLATION_ABORT |
-		  V3D_MMU_CTL_CAP_EXCEEDED_ABORT);
+		  V3D_MMU_CTL_WRITE_VIOLATION_INT |
+		  V3D_MMU_CTL_CAP_EXCEEDED_ABORT |
+		  V3D_MMU_CTL_CAP_EXCEEDED_INT);
 	V3D_WRITE(V3D_MMU_ILLEGAL_ADDR,
 		  (v3d->mmu_scratch_paddr >> V3D_MMU_PAGE_SHIFT) |
 		  V3D_MMU_ILLEGAL_ADDR_ENABLE);
diff --git a/drivers/gpu/drm/v3d/v3d_regs.h b/drivers/gpu/drm/v3d/v3d_regs.h
index eda1e289976f..9bcb57781d31 100644
--- a/drivers/gpu/drm/v3d/v3d_regs.h
+++ b/drivers/gpu/drm/v3d/v3d_regs.h
@@ -152,7 +152,8 @@
 # define V3D_MMU_CTL_PT_INVALID_ABORT                  BIT(19)
 # define V3D_MMU_CTL_PT_INVALID_INT                    BIT(18)
 # define V3D_MMU_CTL_PT_INVALID_EXCEPTION              BIT(17)
-# define V3D_MMU_CTL_WRITE_VIOLATION                   BIT(16)
+# define V3D_MMU_CTL_PT_INVALID_ENABLE                 BIT(16)
+# define V3D_MMU_CTL_WRITE_VIOLATION                   BIT(12)
 # define V3D_MMU_CTL_WRITE_VIOLATION_ABORT             BIT(11)
 # define V3D_MMU_CTL_WRITE_VIOLATION_INT               BIT(10)
 # define V3D_MMU_CTL_WRITE_VIOLATION_EXCEPTION         BIT(9)
-- 
2.20.1


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

* Re: [PATCH 1/4] drm/v3d: Fix debugfs reads of MMU regs.
  2019-04-19  0:10 [PATCH 1/4] drm/v3d: Fix debugfs reads of MMU regs Eric Anholt
                   ` (2 preceding siblings ...)
  2019-04-19  0:10 ` [PATCH 4/4] drm/v3d: Fix and extend MMU error handling Eric Anholt
@ 2019-04-19  8:47 ` Paul Kocialkowski
  3 siblings, 0 replies; 8+ messages in thread
From: Paul Kocialkowski @ 2019-04-19  8:47 UTC (permalink / raw)
  To: Eric Anholt, dri-devel
  Cc: linux-kernel, Maxime Ripard, david.emett, thomas.spurden

Hi,

On Thu, 2019-04-18 at 17:10 -0700, Eric Anholt wrote:
> They're in the hub, not the individual cores.

Although I don't have docs to check, looks sane:

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>

Cheers,

Paul

> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
>  drivers/gpu/drm/v3d/v3d_debugfs.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/v3d/v3d_debugfs.c b/drivers/gpu/drm/v3d/v3d_debugfs.c
> index a2dc4262955e..356a8acfa72d 100644
> --- a/drivers/gpu/drm/v3d/v3d_debugfs.c
> +++ b/drivers/gpu/drm/v3d/v3d_debugfs.c
> @@ -26,6 +26,10 @@ static const struct v3d_reg_def v3d_hub_reg_defs[] = {
>  	REGDEF(V3D_HUB_IDENT3),
>  	REGDEF(V3D_HUB_INT_STS),
>  	REGDEF(V3D_HUB_INT_MSK_STS),
> +
> +	REGDEF(V3D_MMU_CTL),
> +	REGDEF(V3D_MMU_VIO_ADDR),
> +	REGDEF(V3D_MMU_VIO_ID),
>  };
>  
>  static const struct v3d_reg_def v3d_gca_reg_defs[] = {
> @@ -50,9 +54,6 @@ static const struct v3d_reg_def v3d_core_reg_defs[] = {
>  	REGDEF(V3D_PTB_BPCA),
>  	REGDEF(V3D_PTB_BPCS),
>  
> -	REGDEF(V3D_MMU_CTL),
> -	REGDEF(V3D_MMU_VIO_ADDR),
> -
>  	REGDEF(V3D_GMP_STATUS),
>  	REGDEF(V3D_GMP_CFG),
>  	REGDEF(V3D_GMP_VIO_ADDR),
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com


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

* Re: [PATCH 2/4] drm/v3d: Set the correct DMA mask according to the MMU's limits.
  2019-04-19  0:10 ` [PATCH 2/4] drm/v3d: Set the correct DMA mask according to the MMU's limits Eric Anholt
@ 2019-04-19  8:47   ` Paul Kocialkowski
  0 siblings, 0 replies; 8+ messages in thread
From: Paul Kocialkowski @ 2019-04-19  8:47 UTC (permalink / raw)
  To: Eric Anholt, dri-devel
  Cc: linux-kernel, Maxime Ripard, david.emett, thomas.spurden

Hi,

On Thu, 2019-04-18 at 17:10 -0700, Eric Anholt wrote:
> On 7278, we've got 40 bits to work with.

Although I don't have docs to check, looks sane:

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>

Cheers,

Paul

> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
>  drivers/gpu/drm/v3d/v3d_debugfs.c | 1 +
>  drivers/gpu/drm/v3d/v3d_drv.c     | 6 +++++-
>  drivers/gpu/drm/v3d/v3d_regs.h    | 8 ++++++++
>  3 files changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/v3d/v3d_debugfs.c b/drivers/gpu/drm/v3d/v3d_debugfs.c
> index 356a8acfa72d..ab652a034959 100644
> --- a/drivers/gpu/drm/v3d/v3d_debugfs.c
> +++ b/drivers/gpu/drm/v3d/v3d_debugfs.c
> @@ -30,6 +30,7 @@ static const struct v3d_reg_def v3d_hub_reg_defs[] = {
>  	REGDEF(V3D_MMU_CTL),
>  	REGDEF(V3D_MMU_VIO_ADDR),
>  	REGDEF(V3D_MMU_VIO_ID),
> +	REGDEF(V3D_MMU_DEBUG_INFO),
>  };
>  
>  static const struct v3d_reg_def v3d_gca_reg_defs[] = {
> diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
> index f8d1d2569c1f..7ab36192e6bc 100644
> --- a/drivers/gpu/drm/v3d/v3d_drv.c
> +++ b/drivers/gpu/drm/v3d/v3d_drv.c
> @@ -472,9 +472,9 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
>  	struct drm_device *drm;
>  	struct v3d_dev *v3d;
>  	int ret;
> +	u32 mmu_debug;
>  	u32 ident1;
>  
> -	dev->coherent_dma_mask = DMA_BIT_MASK(36);
>  
>  	v3d = kzalloc(sizeof(*v3d), GFP_KERNEL);
>  	if (!v3d)
> @@ -491,6 +491,10 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto dev_free;
>  
> +	mmu_debug = V3D_READ(V3D_MMU_DEBUG_INFO);
> +	dev->coherent_dma_mask =
> +		DMA_BIT_MASK(30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_PA_WIDTH));
> +
>  	ident1 = V3D_READ(V3D_HUB_IDENT1);
>  	v3d->ver = (V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_TVER) * 10 +
>  		    V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_REV));
> diff --git a/drivers/gpu/drm/v3d/v3d_regs.h b/drivers/gpu/drm/v3d/v3d_regs.h
> index 9a8ff0ce648e..54c8c4320da0 100644
> --- a/drivers/gpu/drm/v3d/v3d_regs.h
> +++ b/drivers/gpu/drm/v3d/v3d_regs.h
> @@ -191,6 +191,14 @@
>  /* Address that faulted */
>  #define V3D_MMU_VIO_ADDR                               0x01234
>  
> +#define V3D_MMU_DEBUG_INFO                             0x01238
> +# define V3D_MMU_PA_WIDTH_MASK                         V3D_MASK(11, 8)
> +# define V3D_MMU_PA_WIDTH_SHIFT                        8
> +# define V3D_MMU_VA_WIDTH_MASK                         V3D_MASK(7, 4)
> +# define V3D_MMU_VA_WIDTH_SHIFT                        4
> +# define V3D_MMU_VERSION_MASK                          V3D_MASK(3, 0)
> +# define V3D_MMU_VERSION_SHIFT                         0
> +
>  /* Per-V3D-core registers */
>  
>  #define V3D_CTL_IDENT0                                 0x00000
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com


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

* Re: [PATCH 3/4] drm/v3d: Dump V3D error debug registers in debugfs, and one at reset.
  2019-04-19  0:10 ` [PATCH 3/4] drm/v3d: Dump V3D error debug registers in debugfs, and one at reset Eric Anholt
@ 2019-04-19  8:48   ` Paul Kocialkowski
  0 siblings, 0 replies; 8+ messages in thread
From: Paul Kocialkowski @ 2019-04-19  8:48 UTC (permalink / raw)
  To: Eric Anholt, dri-devel
  Cc: linux-kernel, Maxime Ripard, david.emett, thomas.spurden

Hi,

On Thu, 2019-04-18 at 17:10 -0700, Eric Anholt wrote:
> Looking at a hang recently, I noticed these registers that might tell
> me if something obvious was wrong.  They didn't help in this case, but
> keep it around for the future.

Although I don't have docs to check, looks sane:

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>

Cheers,

Paul

> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
>  drivers/gpu/drm/v3d/v3d_debugfs.c |  5 ++++
>  drivers/gpu/drm/v3d/v3d_gem.c     |  4 +++-
>  drivers/gpu/drm/v3d/v3d_regs.h    | 38 +++++++++++++++++++++++++++++++
>  3 files changed, 46 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/v3d/v3d_debugfs.c b/drivers/gpu/drm/v3d/v3d_debugfs.c
> index ab652a034959..78a78938e81f 100644
> --- a/drivers/gpu/drm/v3d/v3d_debugfs.c
> +++ b/drivers/gpu/drm/v3d/v3d_debugfs.c
> @@ -58,6 +58,11 @@ static const struct v3d_reg_def v3d_core_reg_defs[] = {
>  	REGDEF(V3D_GMP_STATUS),
>  	REGDEF(V3D_GMP_CFG),
>  	REGDEF(V3D_GMP_VIO_ADDR),
> +
> +	REGDEF(V3D_ERR_FDBGO),
> +	REGDEF(V3D_ERR_FDBGB),
> +	REGDEF(V3D_ERR_FDBGS),
> +	REGDEF(V3D_ERR_STAT),
>  };
>  
>  static const struct v3d_reg_def v3d_csd_reg_defs[] = {
> diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c
> index f736e021467a..27e0f87075d9 100644
> --- a/drivers/gpu/drm/v3d/v3d_gem.c
> +++ b/drivers/gpu/drm/v3d/v3d_gem.c
> @@ -109,7 +109,9 @@ v3d_reset(struct v3d_dev *v3d)
>  {
>  	struct drm_device *dev = &v3d->drm;
>  
> -	DRM_ERROR("Resetting GPU.\n");
> +	DRM_DEV_ERROR(dev->dev, "Resetting GPU for hang.\n");
> +	DRM_DEV_ERROR(dev->dev, "V3D_ERR_STAT: 0x%08x\n",
> +		      V3D_CORE_READ(0, V3D_ERR_STAT));
>  	trace_v3d_reset_begin(dev);
>  
>  	/* XXX: only needed for safe powerdown, not reset. */
> diff --git a/drivers/gpu/drm/v3d/v3d_regs.h b/drivers/gpu/drm/v3d/v3d_regs.h
> index 54c8c4320da0..eda1e289976f 100644
> --- a/drivers/gpu/drm/v3d/v3d_regs.h
> +++ b/drivers/gpu/drm/v3d/v3d_regs.h
> @@ -455,4 +455,42 @@
>  # define V3D_CSD_CURRENT_ID0_WG_Y_MASK                 V3D_MASK(15, 0)
>  # define V3D_CSD_CURRENT_ID0_WG_Y_SHIFT                0
>  
> +#define V3D_ERR_FDBGO                                  0x00f04
> +#define V3D_ERR_FDBGB                                  0x00f08
> +#define V3D_ERR_FDBGR                                  0x00f0c
> +
> +#define V3D_ERR_FDBGS                                  0x00f10
> +# define V3D_ERR_FDBGS_INTERPZ_IP_STALL                BIT(17)
> +# define V3D_ERR_FDBGS_DEPTHO_FIFO_IP_STALL            BIT(16)
> +# define V3D_ERR_FDBGS_XYNRM_IP_STALL                  BIT(14)
> +# define V3D_ERR_FDBGS_EZREQ_FIFO_OP_VALID             BIT(13)
> +# define V3D_ERR_FDBGS_QXYF_FIFO_OP_VALID              BIT(12)
> +# define V3D_ERR_FDBGS_QXYF_FIFO_OP_LAST               BIT(11)
> +# define V3D_ERR_FDBGS_EZTEST_ANYQVALID                BIT(7)
> +# define V3D_ERR_FDBGS_EZTEST_PASS                     BIT(6)
> +# define V3D_ERR_FDBGS_EZTEST_QREADY                   BIT(5)
> +# define V3D_ERR_FDBGS_EZTEST_VLF_OKNOVALID            BIT(4)
> +# define V3D_ERR_FDBGS_EZTEST_QSTALL                   BIT(3)
> +# define V3D_ERR_FDBGS_EZTEST_IP_VLFSTALL              BIT(2)
> +# define V3D_ERR_FDBGS_EZTEST_IP_PRSTALL               BIT(1)
> +# define V3D_ERR_FDBGS_EZTEST_IP_QSTALL                BIT(0)
> +
> +#define V3D_ERR_STAT                                   0x00f20
> +# define V3D_ERR_L2CARE                                BIT(15)
> +# define V3D_ERR_VCMBE                                 BIT(14)
> +# define V3D_ERR_VCMRE                                 BIT(13)
> +# define V3D_ERR_VCDI                                  BIT(12)
> +# define V3D_ERR_VCDE                                  BIT(11)
> +# define V3D_ERR_VDWE                                  BIT(10)
> +# define V3D_ERR_VPMEAS                                BIT(9)
> +# define V3D_ERR_VPMEFNA                               BIT(8)
> +# define V3D_ERR_VPMEWNA                               BIT(7)
> +# define V3D_ERR_VPMERNA                               BIT(6)
> +# define V3D_ERR_VPMERR                                BIT(5)
> +# define V3D_ERR_VPMEWR                                BIT(4)
> +# define V3D_ERR_VPAERRGL                              BIT(3)
> +# define V3D_ERR_VPAEBRGL                              BIT(2)
> +# define V3D_ERR_VPAERGS                               BIT(1)
> +# define V3D_ERR_VPAEABB                               BIT(0)
> +
>  #endif /* V3D_REGS_H */
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com


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

* Re: [PATCH 4/4] drm/v3d: Fix and extend MMU error handling.
  2019-04-19  0:10 ` [PATCH 4/4] drm/v3d: Fix and extend MMU error handling Eric Anholt
@ 2019-04-19  8:52   ` Paul Kocialkowski
  0 siblings, 0 replies; 8+ messages in thread
From: Paul Kocialkowski @ 2019-04-19  8:52 UTC (permalink / raw)
  To: Eric Anholt, dri-devel
  Cc: linux-kernel, Maxime Ripard, david.emett, thomas.spurden

Hi,

On Thu, 2019-04-18 at 17:10 -0700, Eric Anholt wrote:
> We were setting the wrong flags to enable PTI errors, so we were
> seeing reads to invalid PTEs show up as write errors.  Also, we
> weren't turning on the interrupts.  The AXI IDs we were dumping
> included the outstanding write number and so they looked basically
> random.  And the VIO_ADDR decoding was based on the MMU VA_WIDTH for
> the first platform I worked on and was wrong on others.  In short,
> this was a thorough mess from early HW enabling.
> 
> Tested on V3D 4.1 and 4.2 with intentional L2T, CLE, PTB, and TLB
> faults.

Didn't check the docs but looks sane too!

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>

Cheers,

Paul

> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
>  drivers/gpu/drm/v3d/v3d_drv.c  |  1 +
>  drivers/gpu/drm/v3d/v3d_drv.h  |  2 ++
>  drivers/gpu/drm/v3d/v3d_irq.c  | 31 +++++++++++++++++++++++++++----
>  drivers/gpu/drm/v3d/v3d_mmu.c  |  7 +++++--
>  drivers/gpu/drm/v3d/v3d_regs.h |  3 ++-
>  5 files changed, 37 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
> index 7ab36192e6bc..9ce2e4ef6c2a 100644
> --- a/drivers/gpu/drm/v3d/v3d_drv.c
> +++ b/drivers/gpu/drm/v3d/v3d_drv.c
> @@ -494,6 +494,7 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
>  	mmu_debug = V3D_READ(V3D_MMU_DEBUG_INFO);
>  	dev->coherent_dma_mask =
>  		DMA_BIT_MASK(30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_PA_WIDTH));
> +	v3d->va_width = 30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_VA_WIDTH);
>  
>  	ident1 = V3D_READ(V3D_HUB_IDENT1);
>  	v3d->ver = (V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_TVER) * 10 +
> diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h
> index 6d31a6a5a08e..64682923018d 100644
> --- a/drivers/gpu/drm/v3d/v3d_drv.h
> +++ b/drivers/gpu/drm/v3d/v3d_drv.h
> @@ -63,6 +63,8 @@ struct v3d_dev {
>  	 */
>  	void *mmu_scratch;
>  	dma_addr_t mmu_scratch_paddr;
> +	/* virtual address bits from V3D to the MMU. */
> +	int va_width;
>  
>  	/* Number of V3D cores. */
>  	u32 cores;
> diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c
> index fac3c542860b..268d8a889ac5 100644
> --- a/drivers/gpu/drm/v3d/v3d_irq.c
> +++ b/drivers/gpu/drm/v3d/v3d_irq.c
> @@ -162,10 +162,33 @@ v3d_hub_irq(int irq, void *arg)
>  		      V3D_HUB_INT_MMU_PTI |
>  		      V3D_HUB_INT_MMU_CAP)) {
>  		u32 axi_id = V3D_READ(V3D_MMU_VIO_ID);
> -		u64 vio_addr = (u64)V3D_READ(V3D_MMU_VIO_ADDR) << 8;
> -
> -		dev_err(v3d->dev, "MMU error from client %d at 0x%08llx%s%s%s\n",
> -			axi_id, (long long)vio_addr,
> +		u64 vio_addr = ((u64)V3D_READ(V3D_MMU_VIO_ADDR) <<
> +				(v3d->va_width - 32));
> +		static const char *const v3d41_axi_ids[] = {
> +			"L2T",
> +			"PTB",
> +			"PSE",
> +			"TLB",
> +			"CLE",
> +			"TFU",
> +			"MMU",
> +			"GMP",
> +		};
> +		const char *client = "?";
> +
> +		V3D_WRITE(V3D_MMU_CTL,
> +			  V3D_READ(V3D_MMU_CTL) & (V3D_MMU_CTL_CAP_EXCEEDED |
> +						   V3D_MMU_CTL_PT_INVALID |
> +						   V3D_MMU_CTL_WRITE_VIOLATION));
> +
> +		if (v3d->ver >= 41) {
> +			axi_id = axi_id >> 5;
> +			if (axi_id < ARRAY_SIZE(v3d41_axi_ids))
> +				client = v3d41_axi_ids[axi_id];
> +		}
> +
> +		dev_err(v3d->dev, "MMU error from client %s (%d) at 0x%llx%s%s%s\n",
> +			client, axi_id, (long long)vio_addr,
>  			((intsts & V3D_HUB_INT_MMU_WRV) ?
>  			 ", write violation" : ""),
>  			((intsts & V3D_HUB_INT_MMU_PTI) ?
> diff --git a/drivers/gpu/drm/v3d/v3d_mmu.c b/drivers/gpu/drm/v3d/v3d_mmu.c
> index 7a21f1787ab1..395e81d97163 100644
> --- a/drivers/gpu/drm/v3d/v3d_mmu.c
> +++ b/drivers/gpu/drm/v3d/v3d_mmu.c
> @@ -69,10 +69,13 @@ int v3d_mmu_set_page_table(struct v3d_dev *v3d)
>  	V3D_WRITE(V3D_MMU_PT_PA_BASE, v3d->pt_paddr >> V3D_MMU_PAGE_SHIFT);
>  	V3D_WRITE(V3D_MMU_CTL,
>  		  V3D_MMU_CTL_ENABLE |
> -		  V3D_MMU_CTL_PT_INVALID |
> +		  V3D_MMU_CTL_PT_INVALID_ENABLE |
>  		  V3D_MMU_CTL_PT_INVALID_ABORT |
> +		  V3D_MMU_CTL_PT_INVALID_INT |
>  		  V3D_MMU_CTL_WRITE_VIOLATION_ABORT |
> -		  V3D_MMU_CTL_CAP_EXCEEDED_ABORT);
> +		  V3D_MMU_CTL_WRITE_VIOLATION_INT |
> +		  V3D_MMU_CTL_CAP_EXCEEDED_ABORT |
> +		  V3D_MMU_CTL_CAP_EXCEEDED_INT);
>  	V3D_WRITE(V3D_MMU_ILLEGAL_ADDR,
>  		  (v3d->mmu_scratch_paddr >> V3D_MMU_PAGE_SHIFT) |
>  		  V3D_MMU_ILLEGAL_ADDR_ENABLE);
> diff --git a/drivers/gpu/drm/v3d/v3d_regs.h b/drivers/gpu/drm/v3d/v3d_regs.h
> index eda1e289976f..9bcb57781d31 100644
> --- a/drivers/gpu/drm/v3d/v3d_regs.h
> +++ b/drivers/gpu/drm/v3d/v3d_regs.h
> @@ -152,7 +152,8 @@
>  # define V3D_MMU_CTL_PT_INVALID_ABORT                  BIT(19)
>  # define V3D_MMU_CTL_PT_INVALID_INT                    BIT(18)
>  # define V3D_MMU_CTL_PT_INVALID_EXCEPTION              BIT(17)
> -# define V3D_MMU_CTL_WRITE_VIOLATION                   BIT(16)
> +# define V3D_MMU_CTL_PT_INVALID_ENABLE                 BIT(16)
> +# define V3D_MMU_CTL_WRITE_VIOLATION                   BIT(12)
>  # define V3D_MMU_CTL_WRITE_VIOLATION_ABORT             BIT(11)
>  # define V3D_MMU_CTL_WRITE_VIOLATION_INT               BIT(10)
>  # define V3D_MMU_CTL_WRITE_VIOLATION_EXCEPTION         BIT(9)
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com


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

end of thread, other threads:[~2019-04-19 20:04 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-19  0:10 [PATCH 1/4] drm/v3d: Fix debugfs reads of MMU regs Eric Anholt
2019-04-19  0:10 ` [PATCH 2/4] drm/v3d: Set the correct DMA mask according to the MMU's limits Eric Anholt
2019-04-19  8:47   ` Paul Kocialkowski
2019-04-19  0:10 ` [PATCH 3/4] drm/v3d: Dump V3D error debug registers in debugfs, and one at reset Eric Anholt
2019-04-19  8:48   ` Paul Kocialkowski
2019-04-19  0:10 ` [PATCH 4/4] drm/v3d: Fix and extend MMU error handling Eric Anholt
2019-04-19  8:52   ` Paul Kocialkowski
2019-04-19  8:47 ` [PATCH 1/4] drm/v3d: Fix debugfs reads of MMU regs Paul Kocialkowski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).