vc4: Check the V3D version reported by the kernel.
authorEric Anholt <eric@anholt.net>
Tue, 12 Jul 2016 00:55:33 +0000 (17:55 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 20 Jul 2016 23:15:15 +0000 (16:15 -0700)
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.

src/gallium/drivers/vc4/vc4_screen.c
src/gallium/drivers/vc4/vc4_screen.h

index f295ae0543165fecb53a022cf01d5964decf7790..96277dc4f9297d92fc1ed9a2f4abe6353d7cedd7 100644 (file)
@@ -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
index 6cecca63bc486eeaed7a37585a0b959fe22bf0b9..9bd2765031c3517786add2924d1e2109933e0294 100644 (file)
@@ -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;