From d81934cded89b20cf305e5afb5c2de9b22d02904 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 11 Jul 2016 17:55:33 -0700 Subject: [PATCH] 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. --- src/gallium/drivers/vc4/vc4_screen.c | 60 ++++++++++++++++++++++++++++ src/gallium/drivers/vc4/vc4_screen.h | 2 + 2 files changed, 62 insertions(+) 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; -- 2.30.2