diff mbox

[9/9] drm/vc4: Add an interface for capturing the GPU state after a hang.

Message ID 1449002158-19156-9-git-send-email-eric@anholt.net (mailing list archive)
State New, archived
Headers show

Commit Message

Eric Anholt Dec. 1, 2015, 8:35 p.m. UTC
This can be parsed with vc4-gpu-tools tools for trying to figure out
what was going on.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/gpu/drm/vc4/vc4_drv.c |   2 +
 drivers/gpu/drm/vc4/vc4_drv.h |   4 +
 drivers/gpu/drm/vc4/vc4_gem.c | 185 ++++++++++++++++++++++++++++++++++++++++++
 include/uapi/drm/vc4_drm.h    |  45 ++++++++++
 4 files changed, 236 insertions(+)

Comments

Emil Velikov Dec. 2, 2015, 11:45 a.m. UTC | #1
On 1 December 2015 at 20:35, Eric Anholt <eric@anholt.net> wrote:
> This can be parsed with vc4-gpu-tools tools for trying to figure out
> what was going on.
>
I might be pushing my luck here ... have you thought about basing
(forking) vc4-gpu-tools of intel-gpu-tools ? I'd imagine that the
macros and helpers will come in handy, despite that some are quite
intel specific.

On a related note - with the above project in place I'd imagine you
have (re)considered about having libdrm-vc4 ? Copying hunks around
might lead to interesting moments (as you have already noticed :-P)

On that note I'll stop now with beating the libdrm drum :-)

Thanks
Emil
Eric Anholt Dec. 2, 2015, 7:35 p.m. UTC | #2
Emil Velikov <emil.l.velikov@gmail.com> writes:

> On 1 December 2015 at 20:35, Eric Anholt <eric@anholt.net> wrote:
>> This can be parsed with vc4-gpu-tools tools for trying to figure out
>> what was going on.
>>
> I might be pushing my luck here ... have you thought about basing
> (forking) vc4-gpu-tools of intel-gpu-tools ? I'd imagine that the
> macros and helpers will come in handy, despite that some are quite
> intel specific.
>
> On a related note - with the above project in place I'd imagine you
> have (re)considered about having libdrm-vc4 ? Copying hunks around
> might lead to interesting moments (as you have already noticed :-P)
>
> On that note I'll stop now with beating the libdrm drum :-)

The headers and code that I copy between the two userspace locations
will go in libdrm when I have a kernel ABI, but vc4_drm.h can't go in
until merging to the kernel, and there's not a whole lot of point
without that.

Yes, I have thought about basing vc4-gpu-tools off of intel-gpu-tools.
I've actually tried to build and use the kms testing stuff on vc4, and
it was a total bust.  Someone needs to do a lot of work to make igt
useful for non-intel.  If you'd like me to build my vc4 testing inside
of igt, I'd someone to demo one of my tests building inside of igt, with
the test runner working and none of the intel-specific tests reporting
failure, and get me permission to just push code to that repository
(It's hard enough getting piglit tests reviewed, vc4-specific tests and
tools would never get review).
Daniel Vetter Dec. 2, 2015, 10:26 p.m. UTC | #3
On Wed, Dec 02, 2015 at 11:35:16AM -0800, Eric Anholt wrote:
> Emil Velikov <emil.l.velikov@gmail.com> writes:
> 
> > On 1 December 2015 at 20:35, Eric Anholt <eric@anholt.net> wrote:
> >> This can be parsed with vc4-gpu-tools tools for trying to figure out
> >> what was going on.
> >>
> > I might be pushing my luck here ... have you thought about basing
> > (forking) vc4-gpu-tools of intel-gpu-tools ? I'd imagine that the
> > macros and helpers will come in handy, despite that some are quite
> > intel specific.
> >
> > On a related note - with the above project in place I'd imagine you
> > have (re)considered about having libdrm-vc4 ? Copying hunks around
> > might lead to interesting moments (as you have already noticed :-P)
> >
> > On that note I'll stop now with beating the libdrm drum :-)
> 
> The headers and code that I copy between the two userspace locations
> will go in libdrm when I have a kernel ABI, but vc4_drm.h can't go in
> until merging to the kernel, and there's not a whole lot of point
> without that.
> 
> Yes, I have thought about basing vc4-gpu-tools off of intel-gpu-tools.
> I've actually tried to build and use the kms testing stuff on vc4, and
> it was a total bust.  Someone needs to do a lot of work to make igt
> useful for non-intel.  If you'd like me to build my vc4 testing inside
> of igt, I'd someone to demo one of my tests building inside of igt, with
> the test runner working and none of the intel-specific tests reporting
> failure, and get me permission to just push code to that repository
> (It's hard enough getting piglit tests reviewed, vc4-specific tests and
> tools would never get review).

Daniel Stone claimed that this Just Works but evidently it doesn't.
There's some autoconfig fail where igt wants too much intel crap that just
doesn't build on arm. Iirc Daniel had some patches floating around for
that.

Wrt building tests itself I think we should require libdrm_$vendor
everywhere, since without that you can embedded a vendor specific testcase
into a shared one (e.g. to test tiled pageflipping). And if that's not
possible then either we'll end up in #ifdef hell or code sharing is really
hard, rendering a shared testsuite pretty useless.

Wrt commit access I'm ok with that, atm rule for igt is to send to
intel-gfx and push after 24h of no complaints. For purely vc4-specific
stuff we should probably create a vc4 subdir.

Wrt tests failing: I sometimes run the entire suite here on a radeon, and
at least in the past that resulted in a perfect 100% skip score. So should
work, too.

Cheers, Daniel
Daniel Stone Dec. 2, 2015, 10:58 p.m. UTC | #4
Hey,

On 2 December 2015 at 22:26, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Wed, Dec 02, 2015 at 11:35:16AM -0800, Eric Anholt wrote:
>> Yes, I have thought about basing vc4-gpu-tools off of intel-gpu-tools.
>> I've actually tried to build and use the kms testing stuff on vc4, and
>> it was a total bust.  Someone needs to do a lot of work to make igt
>> useful for non-intel.  If you'd like me to build my vc4 testing inside
>> of igt, I'd someone to demo one of my tests building inside of igt, with
>> the test runner working and none of the intel-specific tests reporting
>> failure, and get me permission to just push code to that repository
>> (It's hard enough getting piglit tests reviewed, vc4-specific tests and
>> tools would never get review).
>
> Daniel Stone claimed that this Just Works but evidently it doesn't.
> There's some autoconfig fail where igt wants too much intel crap that just
> doesn't build on arm. Iirc Daniel had some patches floating around for
> that.

Yeah, it was working, though with my ARM farm still being in pieces, I
haven't been able to keep on top of it lately. Apparently the patch to
disable the ancilliary tools fixes the build, so I'll get that pushed
when I can actually test it, or for the meantime:
http://paste.fedoraproject.org/296836/09692714

This does still require libpciaccess and libdrm-intel to be built, but
they _are_ totally possible to build on ARM, without any stupid hacks.
My first cut at getting igt running on ARM (before Micah took over)
actually started by eviscerating those as well, but it ended up being
too much of a yak-shave.

If you can get past those, you get a skip for all but the core tests.
For the rest, they either need porting to just use dumb-buffers, or
split such that the bits exercising Intel-specific tiling modes can be
run separately, or left as Intel only.

Cheers,
Daniel
Emil Velikov Dec. 3, 2015, 11:46 a.m. UTC | #5
On 2 December 2015 at 19:35, Eric Anholt <eric@anholt.net> wrote:
> Emil Velikov <emil.l.velikov@gmail.com> writes:
>
>> On 1 December 2015 at 20:35, Eric Anholt <eric@anholt.net> wrote:
>>> This can be parsed with vc4-gpu-tools tools for trying to figure out
>>> what was going on.
>>>
>> I might be pushing my luck here ... have you thought about basing
>> (forking) vc4-gpu-tools of intel-gpu-tools ? I'd imagine that the
>> macros and helpers will come in handy, despite that some are quite
>> intel specific.
>>
>> On a related note - with the above project in place I'd imagine you
>> have (re)considered about having libdrm-vc4 ? Copying hunks around
>> might lead to interesting moments (as you have already noticed :-P)
>>
>> On that note I'll stop now with beating the libdrm drum :-)
>
> The headers and code that I copy between the two userspace locations
> will go in libdrm when I have a kernel ABI, but vc4_drm.h can't go in
> until merging to the kernel, and there's not a whole lot of point
> without that.
>
Definately - I wasn't suggesting about getting things in libdrm before
the kernel. On the ABI front you might want to follow
nouveau/freedreno/omap approach by using a (disabled by default)
experimental-vc4 switch and keeping both vc4_drm.h, vc4_qpu_defines.h
(and other?) in the separate libdrm-vc4 package. As things stabilise
vc4_drm.h can be moved to the core libdrm package.

> Yes, I have thought about basing vc4-gpu-tools off of intel-gpu-tools.
> I've actually tried to build and use the kms testing stuff on vc4, and
> it was a total bust.  Someone needs to do a lot of work to make igt
> useful for non-intel.  If you'd like me to build my vc4 testing inside
> of igt, I'd someone to demo one of my tests building inside of igt, with
> the test runner working and none of the intel-specific tests reporting
> failure, and get me permission to just push code to that repository
> (It's hard enough getting piglit tests reviewed, vc4-specific tests and
> tools would never get review).

As Dan and Dan covered most of the concerns, can you elaborate which
of the following (and others?) are show stoppers:

 - libpciaccess requirement
 - libdrm-intel requirement
 - other misc requirements (xv x11 xext dri2proto cairo-xlib)
 - no clean "pass" when executed on non intel hardware

Thanks
Emil
Emil Velikov Dec. 3, 2015, 11:55 a.m. UTC | #6
Hi Dan,

On 2 December 2015 at 22:58, Daniel Stone <daniel@fooishbar.org> wrote:
> Hey,
>
> On 2 December 2015 at 22:26, Daniel Vetter <daniel@ffwll.ch> wrote:
>> On Wed, Dec 02, 2015 at 11:35:16AM -0800, Eric Anholt wrote:
>>> Yes, I have thought about basing vc4-gpu-tools off of intel-gpu-tools.
>>> I've actually tried to build and use the kms testing stuff on vc4, and
>>> it was a total bust.  Someone needs to do a lot of work to make igt
>>> useful for non-intel.  If you'd like me to build my vc4 testing inside
>>> of igt, I'd someone to demo one of my tests building inside of igt, with
>>> the test runner working and none of the intel-specific tests reporting
>>> failure, and get me permission to just push code to that repository
>>> (It's hard enough getting piglit tests reviewed, vc4-specific tests and
>>> tools would never get review).
>>
>> Daniel Stone claimed that this Just Works but evidently it doesn't.
>> There's some autoconfig fail where igt wants too much intel crap that just
>> doesn't build on arm. Iirc Daniel had some patches floating around for
>> that.
>
> Yeah, it was working, though with my ARM farm still being in pieces, I
> haven't been able to keep on top of it lately. Apparently the patch to
> disable the ancilliary tools fixes the build, so I'll get that pushed
> when I can actually test it, or for the meantime:
> http://paste.fedoraproject.org/296836/09692714
>
Afaict pretty much all of the binaries "disabled" with this patch are
intel specific. As such please throw a configure switch (enabled by
default) rather than the current build_x86 heuristic, otherwise things
are bound to get very ugly pretty quickly.

> This does still require libpciaccess and libdrm-intel to be built, but
> they _are_ totally possible to build on ARM, without any stupid hacks.
> My first cut at getting igt running on ARM (before Micah took over)
> actually started by eviscerating those as well, but it ended up being
> too much of a yak-shave.
>
The libpciaccess will be a pain although libdrm-intel should be
relatively easier. I doubt people will have major issues if the former
requirement stays forever.

Thanks
Emil
diff mbox

Patch

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 2cfee59..97226b6 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -80,6 +80,8 @@  static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
 	DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0),
 	DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0),
 	DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0),
+	DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl,
+			  DRM_ROOT_ONLY),
 };
 
 static struct drm_driver vc4_drm_driver = {
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 9a8ee23..cd3e243 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -19,6 +19,8 @@  struct vc4_dev {
 
 	struct drm_fbdev_cma *fbdev;
 
+	struct vc4_hang_state *hang_state;
+
 	/* The kernel-space BO cache.  Tracks buffers that have been
 	 * unreferenced by all other users (refcounts of 0!) but not
 	 * yet freed, so we can do cheap allocations.
@@ -369,6 +371,8 @@  int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
 			       struct drm_file *file_priv);
 int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
 		      struct drm_file *file_priv);
+int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
+			     struct drm_file *file_priv);
 int vc4_mmap(struct file *filp, struct vm_area_struct *vma);
 int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
 void *vc4_prime_vmap(struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index a62ca68..fb0b92d 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -40,6 +40,186 @@  vc4_queue_hangcheck(struct drm_device *dev)
 		  round_jiffies_up(jiffies + msecs_to_jiffies(100)));
 }
 
+struct vc4_hang_state {
+	struct drm_vc4_get_hang_state user_state;
+
+	u32 bo_count;
+	struct drm_gem_object **bo;
+};
+
+static void
+vc4_free_hang_state(struct drm_device *dev, struct vc4_hang_state *state)
+{
+	unsigned int i;
+
+	mutex_lock(&dev->struct_mutex);
+	for (i = 0; i < state->user_state.bo_count; i++)
+		drm_gem_object_unreference(state->bo[i]);
+	mutex_unlock(&dev->struct_mutex);
+
+	kfree(state);
+}
+
+int
+vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv)
+{
+	struct drm_vc4_get_hang_state *get_state = data;
+	struct drm_vc4_get_hang_state_bo *bo_state;
+	struct vc4_hang_state *kernel_state;
+	struct drm_vc4_get_hang_state *state;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	unsigned long irqflags;
+	u32 i;
+	int ret;
+
+	spin_lock_irqsave(&vc4->job_lock, irqflags);
+	kernel_state = vc4->hang_state;
+	if (!kernel_state) {
+		spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+		return -ENOENT;
+	}
+	state = &kernel_state->user_state;
+
+	/* If the user's array isn't big enough, just return the
+	 * required array size.
+	 */
+	if (get_state->bo_count < state->bo_count) {
+		get_state->bo_count = state->bo_count;
+		spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+		return 0;
+	}
+
+	vc4->hang_state = NULL;
+	spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+
+	/* Save the user's BO pointer, so we don't stomp it with the memcpy. */
+	state->bo = get_state->bo;
+	memcpy(get_state, state, sizeof(*state));
+
+	bo_state = kcalloc(state->bo_count, sizeof(*bo_state), GFP_KERNEL);
+	if (!bo_state) {
+		ret = -ENOMEM;
+		goto err_free;
+	}
+
+	for (i = 0; i < state->bo_count; i++) {
+		struct vc4_bo *vc4_bo = to_vc4_bo(kernel_state->bo[i]);
+		u32 handle;
+
+		ret = drm_gem_handle_create(file_priv, kernel_state->bo[i],
+					    &handle);
+
+		if (ret) {
+			state->bo_count = i - 1;
+			goto err;
+		}
+		bo_state[i].handle = handle;
+		bo_state[i].paddr = vc4_bo->base.paddr;
+		bo_state[i].size = vc4_bo->base.base.size;
+	}
+
+	ret = copy_to_user((void __user *)(uintptr_t)get_state->bo,
+			   bo_state,
+			   state->bo_count * sizeof(*bo_state));
+	kfree(bo_state);
+
+err_free:
+
+	vc4_free_hang_state(dev, kernel_state);
+
+err:
+	return ret;
+}
+
+static void
+vc4_save_hang_state(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct drm_vc4_get_hang_state *state;
+	struct vc4_hang_state *kernel_state;
+	struct vc4_exec_info *exec;
+	struct vc4_bo *bo;
+	unsigned long irqflags;
+	unsigned int i, unref_list_count;
+
+	kernel_state = kcalloc(1, sizeof(*state), GFP_KERNEL);
+	if (!kernel_state)
+		return;
+
+	state = &kernel_state->user_state;
+
+	spin_lock_irqsave(&vc4->job_lock, irqflags);
+	exec = vc4_first_job(vc4);
+	if (!exec) {
+		spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+		return;
+	}
+
+	unref_list_count = 0;
+	list_for_each_entry(bo, &exec->unref_list, unref_head)
+		unref_list_count++;
+
+	state->bo_count = exec->bo_count + unref_list_count;
+	kernel_state->bo = kcalloc(state->bo_count, sizeof(*kernel_state->bo),
+				   GFP_ATOMIC);
+	if (!kernel_state->bo) {
+		spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+		return;
+	}
+
+	for (i = 0; i < exec->bo_count; i++) {
+		drm_gem_object_reference(&exec->bo[i].bo->base);
+		kernel_state->bo[i] = &exec->bo[i].bo->base;
+	}
+
+	list_for_each_entry(bo, &exec->unref_list, unref_head) {
+		drm_gem_object_reference(&bo->base.base);
+		kernel_state->bo[i] = &bo->base.base;
+		i++;
+	}
+
+	state->start_bin = exec->ct0ca;
+	state->start_render = exec->ct1ca;
+
+	spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+
+	state->ct0ca = V3D_READ(V3D_CTNCA(0));
+	state->ct0ea = V3D_READ(V3D_CTNEA(0));
+
+	state->ct1ca = V3D_READ(V3D_CTNCA(1));
+	state->ct1ea = V3D_READ(V3D_CTNEA(1));
+
+	state->ct0cs = V3D_READ(V3D_CTNCS(0));
+	state->ct1cs = V3D_READ(V3D_CTNCS(1));
+
+	state->ct0ra0 = V3D_READ(V3D_CT00RA0);
+	state->ct1ra0 = V3D_READ(V3D_CT01RA0);
+
+	state->bpca = V3D_READ(V3D_BPCA);
+	state->bpcs = V3D_READ(V3D_BPCS);
+	state->bpoa = V3D_READ(V3D_BPOA);
+	state->bpos = V3D_READ(V3D_BPOS);
+
+	state->vpmbase = V3D_READ(V3D_VPMBASE);
+
+	state->dbge = V3D_READ(V3D_DBGE);
+	state->fdbgo = V3D_READ(V3D_FDBGO);
+	state->fdbgb = V3D_READ(V3D_FDBGB);
+	state->fdbgr = V3D_READ(V3D_FDBGR);
+	state->fdbgs = V3D_READ(V3D_FDBGS);
+	state->errstat = V3D_READ(V3D_ERRSTAT);
+
+	spin_lock_irqsave(&vc4->job_lock, irqflags);
+	if (vc4->hang_state) {
+		spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+		vc4_free_hang_state(dev, kernel_state);
+	} else {
+		vc4->hang_state = kernel_state;
+		spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+	}
+}
+
 static void
 vc4_reset(struct drm_device *dev)
 {
@@ -64,6 +244,8 @@  vc4_reset_work(struct work_struct *work)
 	struct vc4_dev *vc4 =
 		container_of(work, struct vc4_dev, hangcheck.reset_work);
 
+	vc4_save_hang_state(vc4->dev);
+
 	vc4_reset(vc4->dev);
 }
 
@@ -677,4 +859,7 @@  vc4_gem_destroy(struct drm_device *dev)
 	}
 
 	vc4_bo_cache_destroy(dev);
+
+	if (vc4->hang_state)
+		vc4_free_hang_state(dev, vc4->hang_state);
 }
diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h
index e711ec0..c548f43 100644
--- a/include/uapi/drm/vc4_drm.h
+++ b/include/uapi/drm/vc4_drm.h
@@ -32,6 +32,7 @@ 
 #define DRM_VC4_CREATE_BO                         0x03
 #define DRM_VC4_MMAP_BO                           0x04
 #define DRM_VC4_CREATE_SHADER_BO                  0x05
+#define DRM_VC4_GET_HANG_STATE                    0x06
 
 #define DRM_IOCTL_VC4_SUBMIT_CL           DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl)
 #define DRM_IOCTL_VC4_WAIT_SEQNO          DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno)
@@ -39,6 +40,7 @@ 
 #define DRM_IOCTL_VC4_CREATE_BO           DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_BO, struct drm_vc4_create_bo)
 #define DRM_IOCTL_VC4_MMAP_BO             DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_MMAP_BO, struct drm_vc4_mmap_bo)
 #define DRM_IOCTL_VC4_CREATE_SHADER_BO    DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo)
+#define DRM_IOCTL_VC4_GET_HANG_STATE      DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state)
 
 struct drm_vc4_submit_rcl_surface {
 	uint32_t hindex; /* Handle index, or ~0 if not present. */
@@ -231,4 +233,47 @@  struct drm_vc4_create_shader_bo {
 	uint32_t pad;
 };
 
+struct drm_vc4_get_hang_state_bo {
+	uint32_t handle;
+	uint32_t paddr;
+	uint32_t size;
+	uint32_t pad;
+};
+
+/**
+ * struct drm_vc4_hang_state - ioctl argument for collecting state
+ * from a GPU hang for analysis.
+*/
+struct drm_vc4_get_hang_state {
+	/** Pointer to array of struct drm_vc4_get_hang_state_bo. */
+	uint64_t bo;
+	/**
+	 * On input, the size of the bo array.  Output is the number
+	 * of bos to be returned.
+	 */
+	uint32_t bo_count;
+
+	uint32_t start_bin, start_render;
+
+	uint32_t ct0ca, ct0ea;
+	uint32_t ct1ca, ct1ea;
+	uint32_t ct0cs, ct1cs;
+	uint32_t ct0ra0, ct1ra0;
+
+	uint32_t bpca, bpcs;
+	uint32_t bpoa, bpos;
+
+	uint32_t vpmbase;
+
+	uint32_t dbge;
+	uint32_t fdbgo;
+	uint32_t fdbgb;
+	uint32_t fdbgr;
+	uint32_t fdbgs;
+	uint32_t errstat;
+
+	/* Pad that we may save more registers into in the future. */
+	uint32_t pad[16];
+};
+
 #endif /* _UAPI_VC4_DRM_H_ */