Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / drivers / gpu / drm / vc4 / vc4_drv.c
index 250ed7e..8b42d31 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,12 +44,54 @@ 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;
+       case DRM_VC4_PARAM_SUPPORTS_BRANCHES:
+               args->value = true;
+               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);
 
-       if (vc4->fbdev)
-               drm_fbdev_cma_restore_mode(vc4->fbdev);
+       drm_fbdev_cma_restore_mode(vc4->fbdev);
 }
 
 static const struct file_operations vc4_drm_fops = {
@@ -74,6 +117,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 = {
@@ -92,6 +136,8 @@ static struct drm_driver vc4_drm_driver = {
        .enable_vblank = vc4_enable_vblank,
        .disable_vblank = vc4_disable_vblank,
        .get_vblank_counter = drm_vblank_no_hw_counter,
+       .get_scanout_position = vc4_crtc_get_scanoutpos,
+       .get_vblank_timestamp = vc4_crtc_get_vblank_timestamp,
 
 #if defined(CONFIG_DEBUG_FS)
        .debugfs_init = vc4_debugfs_init,
@@ -99,7 +145,7 @@ static struct drm_driver vc4_drm_driver = {
 #endif
 
        .gem_create_object = vc4_create_object,
-       .gem_free_object = vc4_free_object,
+       .gem_free_object_unlocked = vc4_free_object,
        .gem_vm_ops = &drm_gem_cma_vm_ops,
 
        .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
@@ -176,7 +222,6 @@ static int vc4_drm_bind(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        struct drm_device *drm;
-       struct drm_connector *connector;
        struct vc4_dev *vc4;
        int ret = 0;
 
@@ -196,8 +241,6 @@ static int vc4_drm_bind(struct device *dev)
        vc4_bo_cache_init(drm);
 
        drm_mode_config_init(drm);
-       if (ret)
-               goto unref;
 
        vc4_gem_init(drm);
 
@@ -211,27 +254,14 @@ static int vc4_drm_bind(struct device *dev)
        if (ret < 0)
                goto unbind_all;
 
-       /* Connector registration has to occur after DRM device
-        * registration, because it creates sysfs entries based on the
-        * DRM device.
-        */
-       list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
-               ret = drm_connector_register(connector);
-               if (ret)
-                       goto unregister;
-       }
-
        vc4_kms_load(drm);
 
        return 0;
 
-unregister:
-       drm_dev_unregister(drm);
 unbind_all:
        component_unbind_all(dev, drm);
 gem_destroy:
        vc4_gem_destroy(drm);
-unref:
        drm_dev_unref(drm);
        vc4_bo_cache_destroy(drm);
        return ret;
@@ -259,8 +289,8 @@ static const struct component_master_ops vc4_drm_ops = {
 static struct platform_driver *const component_drivers[] = {
        &vc4_hdmi_driver,
        &vc4_dpi_driver,
-       &vc4_crtc_driver,
        &vc4_hvs_driver,
+       &vc4_crtc_driver,
        &vc4_v3d_driver,
 };