drm/vc4: Add a getparam ioctl for getting the V3D identity regs.
authorEric Anholt <eric@anholt.net>
Fri, 1 Jul 2016 20:10:38 +0000 (13:10 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 14 Jul 2016 15:08:35 +0000 (08:08 -0700)
As I extend the driver to support different V3D revisions, userspace
needs to know what version it's targeting.  This is most easily
detected using the V3D identity registers.

v2: Make sure V3D is runtime PM on when reading the registers.
v3: Switch to a 64-bit param value (suggested by Rob Clark in review)

Signed-off-by: Eric Anholt <eric@anholt.net>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v2)
Reviewed-by: Rob Clark <robdclark@gmail.com> (v3, over irc)
drivers/gpu/drm/vc4/vc4_drv.c
include/uapi/drm/vc4_drm.h

index 2f30214ee8107b29f744a55b34b6588b172c189e..047d7a265ceb77094f501bece5f70abcae5a9202 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include "drm_fb_cma_helper.h"
 
 #include "uapi/drm/vc4_drm.h"
@@ -43,6 +44,46 @@ void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index)
        return map;
 }
 
+static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
+                              struct drm_file *file_priv)
+{
+       struct vc4_dev *vc4 = to_vc4_dev(dev);
+       struct drm_vc4_get_param *args = data;
+       int ret;
+
+       if (args->pad != 0)
+               return -EINVAL;
+
+       switch (args->param) {
+       case DRM_VC4_PARAM_V3D_IDENT0:
+               ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
+               if (ret)
+                       return ret;
+               args->value = V3D_READ(V3D_IDENT0);
+               pm_runtime_put(&vc4->v3d->pdev->dev);
+               break;
+       case DRM_VC4_PARAM_V3D_IDENT1:
+               ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
+               if (ret)
+                       return ret;
+               args->value = V3D_READ(V3D_IDENT1);
+               pm_runtime_put(&vc4->v3d->pdev->dev);
+               break;
+       case DRM_VC4_PARAM_V3D_IDENT2:
+               ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
+               if (ret)
+                       return ret;
+               args->value = V3D_READ(V3D_IDENT2);
+               pm_runtime_put(&vc4->v3d->pdev->dev);
+               break;
+       default:
+               DRM_DEBUG("Unknown parameter %d\n", args->param);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static void vc4_lastclose(struct drm_device *dev)
 {
        struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -74,6 +115,7 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
        DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl,
                          DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF_DRV(VC4_GET_PARAM, vc4_get_param_ioctl, DRM_RENDER_ALLOW),
 };
 
 static struct drm_driver vc4_drm_driver = {
index af12e8a184c82b890968dfc8d45bcfa97ccb3e4f..1143e954048d1f8192142361315531066c9ac9af 100644 (file)
@@ -37,6 +37,7 @@ extern "C" {
 #define DRM_VC4_MMAP_BO                           0x04
 #define DRM_VC4_CREATE_SHADER_BO                  0x05
 #define DRM_VC4_GET_HANG_STATE                    0x06
+#define DRM_VC4_GET_PARAM                         0x07
 
 #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)
@@ -45,6 +46,7 @@ extern "C" {
 #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)
+#define DRM_IOCTL_VC4_GET_PARAM           DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param)
 
 struct drm_vc4_submit_rcl_surface {
        __u32 hindex; /* Handle index, or ~0 if not present. */
@@ -280,6 +282,16 @@ struct drm_vc4_get_hang_state {
        __u32 pad[16];
 };
 
+#define DRM_VC4_PARAM_V3D_IDENT0               0
+#define DRM_VC4_PARAM_V3D_IDENT1               1
+#define DRM_VC4_PARAM_V3D_IDENT2               2
+
+struct drm_vc4_get_param {
+       __u32 param;
+       __u32 pad;
+       __u64 value;
+};
+
 #if defined(__cplusplus)
 }
 #endif