summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2016-07-11 17:55:33 -0700
committerEric Anholt <eric@anholt.net>2016-07-20 16:15:15 -0700
commitd81934cded89b20cf305e5afb5c2de9b22d02904 (patch)
tree890d94b47e130fb9c05090253faae44f56f71279
parent83b8ca58e12ee13c4d5cd51c30c0fd19bf4f8bd2 (diff)
vc4: Check the V3D version reported by the kernel.
We don't want to bring up an old userspace driver on a kernel for newer hardware. We'll also want to look at the other ident fields in the future.
-rw-r--r--src/gallium/drivers/vc4/vc4_screen.c60
-rw-r--r--src/gallium/drivers/vc4/vc4_screen.h2
2 files changed, 62 insertions, 0 deletions
diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c
index f295ae05431..96277dc4f92 100644
--- a/src/gallium/drivers/vc4/vc4_screen.c
+++ b/src/gallium/drivers/vc4/vc4_screen.c
@@ -517,6 +517,58 @@ vc4_supports_branches(struct vc4_screen *screen)
return p.value;
}
+static bool
+vc4_get_chip_info(struct vc4_screen *screen)
+{
+#if USE_VC4_SIMULATOR
+ screen->v3d_ver = 21;
+ return true;
+#endif
+
+ struct drm_vc4_get_param ident0 = {
+ .param = DRM_VC4_PARAM_V3D_IDENT0,
+ };
+ struct drm_vc4_get_param ident1 = {
+ .param = DRM_VC4_PARAM_V3D_IDENT1,
+ };
+ int ret;
+
+ ret = drmIoctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident0);
+ if (ret != 0) {
+ if (errno == EINVAL) {
+ /* Backwards compatibility with 2835 kernels which
+ * only do V3D 2.1.
+ */
+ screen->v3d_ver = 21;
+ return true;
+ } else {
+ fprintf(stderr, "Couldn't get V3D IDENT0: %s\n",
+ strerror(errno));
+ return false;
+ }
+ }
+ ret = drmIoctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident1);
+ if (ret != 0) {
+ fprintf(stderr, "Couldn't get V3D IDENT1: %s\n",
+ strerror(errno));
+ return false;
+ }
+
+ uint32_t major = (ident0.value >> 24) & 0xff;
+ uint32_t minor = (ident1.value >> 0) & 0xf;
+ screen->v3d_ver = major * 10 + minor;
+
+ if (screen->v3d_ver != 21) {
+ fprintf(stderr,
+ "V3D %d.%d not supported by this version of Mesa.\n",
+ screen->v3d_ver / 10,
+ screen->v3d_ver % 10);
+ return false;
+ }
+
+ return true;
+}
+
struct pipe_screen *
vc4_screen_create(int fd)
{
@@ -538,6 +590,9 @@ vc4_screen_create(int fd)
if (vc4_supports_branches(screen))
screen->has_control_flow = true;
+ if (!vc4_get_chip_info(screen))
+ goto fail;
+
vc4_fence_init(screen);
vc4_debug = debug_get_option_vc4_debug();
@@ -555,6 +610,11 @@ vc4_screen_create(int fd)
pscreen->get_device_vendor = vc4_screen_get_vendor;
return pscreen;
+
+fail:
+ close(fd);
+ ralloc_free(pscreen);
+ return NULL;
}
boolean
diff --git a/src/gallium/drivers/vc4/vc4_screen.h b/src/gallium/drivers/vc4/vc4_screen.h
index 6cecca63bc4..9bd2765031c 100644
--- a/src/gallium/drivers/vc4/vc4_screen.h
+++ b/src/gallium/drivers/vc4/vc4_screen.h
@@ -50,6 +50,8 @@ struct vc4_screen {
struct pipe_screen base;
int fd;
+ int v3d_ver;
+
void *simulator_mem_base;
uint32_t simulator_mem_size;