From 18ace11f87e69454379a3a1247a657b70ca142fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Sep 2018 16:16:21 +0300 Subject: [PATCH 01/11] drm: Introduce per-device driver_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We wish to control certain driver_features flags on a per-device basis while still sharing a single drm_driver instance across all the devices. To that end introduce device.driver_features. By default it will be set to ~0 to not impose any limits beyond driver.driver_features. Drivers can then clear specific flags in the per-device bitmask to limit the capabilities of the device. An alternative approach would be to copy the driver_features from the driver into the device in drm_dev_init(), however that would require verifying that no driver is currently changing driver.driver_features after drm_dev_init(). Hence the ~0 apporach was easier. Ideally we'd also make drm_driver const but there is plenty of code left that wants to mutate it (eg. various vfunc assignments). We'll need to fix all that up before we can make it const. And while at it fix up the type of the feature flag passed to drm_core_check_feature(). v2: Streamline the && vs. & (Chris) s/int/u32/ in drm_core_check_feature() args Cc: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180913131622.17690-1-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson Reviewed-by: Daniel Vetter Reviewed-by: Michel Dänzer --- drivers/gpu/drm/drm_drv.c | 3 +++ include/drm/drm_device.h | 10 ++++++++++ include/drm/drm_drv.h | 8 ++++---- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index ea4941da9b27..36e8e9cbec52 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -506,6 +506,9 @@ int drm_dev_init(struct drm_device *dev, dev->dev = parent; dev->driver = driver; + /* no per-device feature limits by default */ + dev->driver_features = ~0u; + INIT_LIST_HEAD(&dev->filelist); INIT_LIST_HEAD(&dev->filelist_internal); INIT_LIST_HEAD(&dev->clientlist); diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index f9c6e0e3aec7..42411b3ea0c8 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -45,6 +45,16 @@ struct drm_device { /* currently active master for this device. Protected by master_mutex */ struct drm_master *master; + /** + * @driver_features: per-device driver features + * + * Drivers can clear specific flags here to disallow + * certain features on a per-device basis while still + * sharing a single &struct drm_driver instance across + * all devices. + */ + u32 driver_features; + /** * @unplugged: * diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 23b9678137a6..8830e3de3a86 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -653,14 +653,14 @@ static inline bool drm_dev_is_unplugged(struct drm_device *dev) * @dev: DRM device to check * @feature: feature flag * - * This checks @dev for driver features, see &drm_driver.driver_features and the - * various DRIVER_\* flags. + * This checks @dev for driver features, see &drm_driver.driver_features, + * &drm_device.driver_features, and the various DRIVER_\* flags. * * Returns true if the @feature is supported, false otherwise. */ -static inline bool drm_core_check_feature(struct drm_device *dev, int feature) +static inline bool drm_core_check_feature(struct drm_device *dev, u32 feature) { - return dev->driver->driver_features & feature; + return dev->driver->driver_features & dev->driver_features & feature; } /** From 1feb64c49d7f2a46dc7b1e4c92c85ead2775395e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Sep 2018 16:16:22 +0300 Subject: [PATCH 02/11] drm/i915: Clear DRIVER_ATOMIC on a per-device basis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we're clearing DRIVER_ATOMIC in driver.driver_features for older platforms. This will not work correctly should we ever have a system with and old and new GPU in it. While that is not possible currently let's make the code more correct and use the per-device driver_features instead. Cc: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180913131622.17690-2-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f8cfd16be534..61199defb470 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1336,10 +1336,6 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) struct drm_i915_private *dev_priv; int ret; - /* Enable nuclear pageflip on ILK+ */ - if (!i915_modparams.nuclear_pageflip && match_info->gen < 5) - driver.driver_features &= ~DRIVER_ATOMIC; - ret = -ENOMEM; dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); if (dev_priv) @@ -1352,6 +1348,10 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) dev_priv->drm.pdev = pdev; dev_priv->drm.dev_private = dev_priv; + /* Disable nuclear pageflip by default on pre-ILK */ + if (!i915_modparams.nuclear_pageflip && match_info->gen < 5) + dev_priv->drm.driver_features &= ~DRIVER_ATOMIC; + ret = pci_enable_device(pdev); if (ret) goto out_fini; From 351c4dbe4fae44b747dd97114a5983ec23a49f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 13 Sep 2018 19:31:47 +0300 Subject: [PATCH 03/11] drm/amdgpu: Use per-device driver_features to disable atomic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disable atomic on a per-device basis instead of for all devices. Made possible by the new device.driver_features thing. Cc: Alex Deucher Cc: "Christian König" Cc: "David (ChunMing) Zhou" Cc: Harry Wentland Cc: Michel Dänzer Suggested-by: Michel Dänzer Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180913163147.27900-2-ville.syrjala@linux.intel.com Reviewed-by: Michel Dänzer Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 6870909da926..8c1db96be070 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -816,17 +816,13 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, if (ret) return ret; - /* warn the user if they mix atomic and non-atomic capable GPUs */ - if ((kms_driver.driver_features & DRIVER_ATOMIC) && !supports_atomic) - DRM_ERROR("Mixing atomic and non-atomic capable GPUs!\n"); - /* support atomic early so the atomic debugfs stuff gets created */ - if (supports_atomic) - kms_driver.driver_features |= DRIVER_ATOMIC; - dev = drm_dev_alloc(&kms_driver, &pdev->dev); if (IS_ERR(dev)) return PTR_ERR(dev); + if (!supports_atomic) + dev->driver_features &= ~DRIVER_ATOMIC; + ret = pci_enable_device(pdev); if (ret) goto err_free; @@ -1078,7 +1074,7 @@ amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, static struct drm_driver kms_driver = { .driver_features = - DRIVER_USE_AGP | + DRIVER_USE_AGP | DRIVER_ATOMIC | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ, .load = amdgpu_driver_load_kms, From 6f19eb21a2ef9a2da938106ccc98e296ee02f4d3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 Sep 2018 09:56:15 +0300 Subject: [PATCH 04/11] udmabuf: fix error code in map_udmabuf() We accidentally forgot to set "ret" on this error path so it means we return NULL instead of an error pointer. The caller checks for NULL and changes it to an error pointer so it doesn't cause an issue at run time. Signed-off-by: Dan Carpenter Link: http://patchwork.freedesktop.org/patch/msgid/20180914065615.GA12043@mwanda Signed-off-by: Gerd Hoffmann --- drivers/dma-buf/udmabuf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 9edabce0b8ab..5b44ef226904 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -61,8 +61,10 @@ static struct sg_table *map_udmabuf(struct dma_buf_attachment *at, GFP_KERNEL); if (ret < 0) goto err; - if (!dma_map_sg(at->dev, sg->sgl, sg->nents, direction)) + if (!dma_map_sg(at->dev, sg->sgl, sg->nents, direction)) { + ret = -EINVAL; goto err; + } return sg; err: From 69fdf4206a8ba91a277b3d50a3a05b71247635b2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 13 Sep 2018 20:20:50 +0100 Subject: [PATCH 05/11] drm: Differentiate the lack of an interface from invalid parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the ioctl is not supported on a particular piece of HW/driver combination, report ENOTSUP (aka EOPNOTSUPP) so that it can be easily distinguished from both the lack of the ioctl and from a regular invalid parameter. v2: Across all the kms ioctls we had a mixture of reporting EINVAL, ENODEV and a few ENOTSUPP (most where EINVAL) for a failed drm_core_check_feature(). Update everybody to report ENOTSUPP. v3: ENOTSUPP is an internal errno! It's value (524) does not correspond to a POSIX errno, the one we want is ENOTSUP. However, uapi/asm-generic/errno.h doesn't include ENOTSUP but man errno says "ENOTSUP and EOPNOTSUPP have the same value on Linux, but according to POSIX.1 these error values should be distinct." so use EOPNOTSUPP as its equivalent. Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Ville Syrjälä Reviewed-by: Daniel Vetter #v2 Link: https://patchwork.freedesktop.org/patch/msgid/20180913192050.24812-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/drm_atomic_uapi.c | 2 +- drivers/gpu/drm/drm_bufs.c | 32 +++++++++++++++---------------- drivers/gpu/drm/drm_client.c | 2 +- drivers/gpu/drm/drm_color_mgmt.c | 4 ++-- drivers/gpu/drm/drm_connector.c | 2 +- drivers/gpu/drm/drm_context.c | 16 ++++++++-------- drivers/gpu/drm/drm_crtc.c | 4 ++-- drivers/gpu/drm/drm_encoder.c | 2 +- drivers/gpu/drm/drm_framebuffer.c | 13 ++++++++----- drivers/gpu/drm/drm_gem.c | 6 +++--- drivers/gpu/drm/drm_ioctl.c | 4 ++-- drivers/gpu/drm/drm_irq.c | 4 ++-- drivers/gpu/drm/drm_lease.c | 8 ++++---- drivers/gpu/drm/drm_lock.c | 4 ++-- drivers/gpu/drm/drm_mode_config.c | 3 +-- drivers/gpu/drm/drm_mode_object.c | 4 ++-- drivers/gpu/drm/drm_pci.c | 4 ++-- drivers/gpu/drm/drm_plane.c | 10 +++++----- drivers/gpu/drm/drm_prime.c | 4 ++-- drivers/gpu/drm/drm_property.c | 8 ++++---- drivers/gpu/drm/drm_scatter.c | 8 ++++---- drivers/gpu/drm/drm_syncobj.c | 14 +++++++------- drivers/gpu/drm/drm_vblank.c | 4 ++-- 23 files changed, 82 insertions(+), 80 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 26690a664ec6..d5b7f315098c 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -1251,7 +1251,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, /* disallow for drivers not supporting atomic: */ if (!drm_core_check_feature(dev, DRIVER_ATOMIC)) - return -EINVAL; + return -EOPNOTSUPP; /* disallow for userspace that has not enabled atomic cap (even * though this may be a bit overkill, since legacy userspace diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index ba8cfe65c65b..7412acaf3cde 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -398,7 +398,7 @@ int drm_legacy_addmap_ioctl(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && !drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; err = drm_addmap_core(dev, map->offset, map->size, map->type, map->flags, &maplist); @@ -444,7 +444,7 @@ int drm_legacy_getmap_ioctl(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && !drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; idx = map->offset; if (idx < 0) @@ -596,7 +596,7 @@ int drm_legacy_rmmap_ioctl(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && !drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; mutex_lock(&dev->struct_mutex); list_for_each_entry(r_list, &dev->maplist, head) { @@ -860,7 +860,7 @@ int drm_legacy_addbufs_pci(struct drm_device *dev, struct drm_buf **temp_buflist; if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) - return -EINVAL; + return -EOPNOTSUPP; if (!dma) return -EINVAL; @@ -1064,7 +1064,7 @@ static int drm_legacy_addbufs_sg(struct drm_device *dev, struct drm_buf **temp_buflist; if (!drm_core_check_feature(dev, DRIVER_SG)) - return -EINVAL; + return -EOPNOTSUPP; if (!dma) return -EINVAL; @@ -1221,10 +1221,10 @@ int drm_legacy_addbufs(struct drm_device *dev, void *data, int ret; if (!drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; + return -EOPNOTSUPP; #if IS_ENABLED(CONFIG_AGP) if (request->flags & _DRM_AGP_BUFFER) @@ -1267,10 +1267,10 @@ int __drm_legacy_infobufs(struct drm_device *dev, int count; if (!drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; + return -EOPNOTSUPP; if (!dma) return -EINVAL; @@ -1352,10 +1352,10 @@ int drm_legacy_markbufs(struct drm_device *dev, void *data, struct drm_buf_entry *entry; if (!drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; + return -EOPNOTSUPP; if (!dma) return -EINVAL; @@ -1400,10 +1400,10 @@ int drm_legacy_freebufs(struct drm_device *dev, void *data, struct drm_buf *buf; if (!drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; + return -EOPNOTSUPP; if (!dma) return -EINVAL; @@ -1455,10 +1455,10 @@ int __drm_legacy_mapbufs(struct drm_device *dev, void *data, int *p, int i; if (!drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; + return -EOPNOTSUPP; if (!dma) return -EINVAL; @@ -1545,7 +1545,7 @@ int drm_legacy_dma_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { if (!drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; if (dev->driver->dma_ioctl) return dev->driver->dma_ioctl(dev, data, file_priv); diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c index baff50a4c234..17d9a64e885e 100644 --- a/drivers/gpu/drm/drm_client.c +++ b/drivers/gpu/drm/drm_client.c @@ -82,7 +82,7 @@ int drm_client_new(struct drm_device *dev, struct drm_client_dev *client, if (!drm_core_check_feature(dev, DRIVER_MODESET) || !dev->driver->dumb_create || !dev->driver->gem_prime_vmap) - return -ENOTSUPP; + return -EOPNOTSUPP; if (funcs && !try_module_get(funcs->owner)) return -ENODEV; diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index b97e2de2c029..581cc3788223 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -242,7 +242,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev, int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; crtc = drm_crtc_find(dev, file_priv, crtc_lut->crtc_id); if (!crtc) @@ -320,7 +320,7 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; crtc = drm_crtc_find(dev, file_priv, crtc_lut->crtc_id); if (!crtc) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 526619f963e5..1e40e5decbe9 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1725,7 +1725,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, LIST_HEAD(export_list); if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c index f973d287696a..506663c69b0a 100644 --- a/drivers/gpu/drm/drm_context.c +++ b/drivers/gpu/drm/drm_context.c @@ -178,7 +178,7 @@ int drm_legacy_getsareactx(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && !drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; mutex_lock(&dev->struct_mutex); @@ -226,7 +226,7 @@ int drm_legacy_setsareactx(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && !drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; mutex_lock(&dev->struct_mutex); list_for_each_entry(r_list, &dev->maplist, head) { @@ -330,7 +330,7 @@ int drm_legacy_resctx(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && !drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; if (res->count >= DRM_RESERVED_CONTEXTS) { memset(&ctx, 0, sizeof(ctx)); @@ -364,7 +364,7 @@ int drm_legacy_addctx(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && !drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; ctx->handle = drm_legacy_ctxbitmap_next(dev); if (ctx->handle == DRM_KERNEL_CONTEXT) { @@ -411,7 +411,7 @@ int drm_legacy_getctx(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && !drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; /* This is 0, because we don't handle any context flags */ ctx->flags = 0; @@ -437,7 +437,7 @@ int drm_legacy_switchctx(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && !drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; DRM_DEBUG("%d\n", ctx->handle); return drm_context_switch(dev, dev->last_context, ctx->handle); @@ -461,7 +461,7 @@ int drm_legacy_newctx(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && !drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; DRM_DEBUG("%d\n", ctx->handle); drm_context_switch_complete(dev, file_priv, ctx->handle); @@ -487,7 +487,7 @@ int drm_legacy_rmctx(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && !drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; DRM_DEBUG("%d\n", ctx->handle); if (ctx->handle != DRM_KERNEL_CONTEXT) { diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 2f6c877299e4..5f488aa80bcd 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -405,7 +405,7 @@ int drm_mode_getcrtc(struct drm_device *dev, struct drm_plane *plane; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id); if (!crtc) @@ -580,7 +580,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, int i; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; /* * Universal plane src offsets are only 16.16, prevent havoc for diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c index 273e1c59c54a..b694fb57eaa4 100644 --- a/drivers/gpu/drm/drm_encoder.c +++ b/drivers/gpu/drm/drm_encoder.c @@ -222,7 +222,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data, struct drm_crtc *crtc; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; encoder = drm_encoder_find(dev, file_priv, enc_resp->encoder_id); if (!encoder) diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 6eaacd4eb8cc..1ee3d6b44280 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -113,6 +113,9 @@ int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or, struct drm_mode_fb_cmd2 r = {}; int ret; + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EOPNOTSUPP; + r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth); if (r.pixel_format == DRM_FORMAT_INVALID) { DRM_DEBUG("bad {bpp:%d, depth:%d}\n", or->bpp, or->depth); @@ -352,7 +355,7 @@ int drm_mode_addfb2(struct drm_device *dev, struct drm_framebuffer *fb; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; fb = drm_internal_framebuffer_create(dev, r, file_priv); if (IS_ERR(fb)) @@ -387,7 +390,7 @@ int drm_mode_addfb2_ioctl(struct drm_device *dev, * ADDFB. */ DRM_DEBUG_KMS("addfb2 broken on bigendian"); - return -EINVAL; + return -EOPNOTSUPP; } #endif return drm_mode_addfb2(dev, data, file_priv); @@ -432,7 +435,7 @@ int drm_mode_rmfb(struct drm_device *dev, u32 fb_id, int found = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; fb = drm_framebuffer_lookup(dev, file_priv, fb_id); if (!fb) @@ -509,7 +512,7 @@ int drm_mode_getfb(struct drm_device *dev, int ret; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id); if (!fb) @@ -582,7 +585,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, int ret; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id); if (!fb) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index bf90625df3c5..512078ebd97b 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -667,7 +667,7 @@ drm_gem_close_ioctl(struct drm_device *dev, void *data, int ret; if (!drm_core_check_feature(dev, DRIVER_GEM)) - return -ENODEV; + return -EOPNOTSUPP; ret = drm_gem_handle_delete(file_priv, args->handle); @@ -694,7 +694,7 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data, int ret; if (!drm_core_check_feature(dev, DRIVER_GEM)) - return -ENODEV; + return -EOPNOTSUPP; obj = drm_gem_object_lookup(file_priv, args->handle); if (obj == NULL) @@ -745,7 +745,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, u32 handle; if (!drm_core_check_feature(dev, DRIVER_GEM)) - return -ENODEV; + return -EOPNOTSUPP; mutex_lock(&dev->object_name_lock); obj = idr_find(&dev->object_name_idr, (int) args->name); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 6b4a633b4240..60dfbfae6a02 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -248,7 +248,7 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_ /* Other caps only work with KMS drivers */ if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENOTSUPP; + return -EOPNOTSUPP; switch (req->capability) { case DRM_CAP_DUMB_BUFFER: @@ -319,7 +319,7 @@ drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv) break; case DRM_CLIENT_CAP_ATOMIC: if (!drm_core_check_feature(dev, DRIVER_ATOMIC)) - return -EINVAL; + return -EOPNOTSUPP; if (req->value > 1) return -EINVAL; file_priv->atomic = req->value; diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 3b04c25100ae..45a07652fa00 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -104,7 +104,7 @@ int drm_irq_install(struct drm_device *dev, int irq) unsigned long sh_flags = 0; if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return -EINVAL; + return -EOPNOTSUPP; if (irq == 0) return -EINVAL; @@ -175,7 +175,7 @@ int drm_irq_uninstall(struct drm_device *dev) int i; if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return -EINVAL; + return -EOPNOTSUPP; irq_enabled = dev->irq_enabled; dev->irq_enabled = false; diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index b54fb78a283c..5894b4e144d7 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c @@ -506,7 +506,7 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, /* Can't lease without MODESET */ if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; /* Do not allow sub-leases */ if (lessor->lessor) @@ -615,7 +615,7 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev, /* Can't lease without MODESET */ if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; DRM_DEBUG_LEASE("List lessees for %d\n", lessor->lessee_id); @@ -671,7 +671,7 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev, /* Can't lease without MODESET */ if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; DRM_DEBUG_LEASE("get lease for %d\n", lessee->lessee_id); @@ -726,7 +726,7 @@ int drm_mode_revoke_lease_ioctl(struct drm_device *dev, /* Can't lease without MODESET */ if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; mutex_lock(&dev->mode_config.idr_mutex); diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index 96bb6badb818..67a1a2ca7174 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c @@ -166,7 +166,7 @@ int drm_legacy_lock(struct drm_device *dev, void *data, int ret = 0; if (!drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; ++file_priv->lock_count; @@ -256,7 +256,7 @@ int drm_legacy_unlock(struct drm_device *dev, void *data, struct drm_file *file_ struct drm_master *master = file_priv->master; if (!drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; if (lock->context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 21e353bd3948..ee80788f2c40 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -97,8 +97,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, struct drm_connector_list_iter conn_iter; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - + return -EOPNOTSUPP; mutex_lock(&file_priv->fbs_lock); count = 0; diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index fcb0ab0abb75..be8b754eaf60 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -381,7 +381,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; drm_modeset_lock_all(dev); @@ -504,7 +504,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, int ret = -EINVAL; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; arg_obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type); if (!arg_obj) diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 896e42a34895..48f615d38931 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -182,14 +182,14 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, struct drm_irq_busid *p = data; if (!drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; /* UMS was only ever support on PCI devices. */ if (WARN_ON(!dev->pdev)) return -EINVAL; if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return -EINVAL; + return -EOPNOTSUPP; return drm_pci_irq_by_busid(dev, p); } diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 4a72c6829d73..1fa98bd12003 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -477,7 +477,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, int count = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; plane_ptr = u64_to_user_ptr(plane_resp->plane_id_ptr); @@ -514,7 +514,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data, uint32_t __user *format_ptr; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; plane = drm_plane_find(dev, file_priv, plane_resp->plane_id); if (!plane) @@ -781,7 +781,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data, int ret; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; /* * First, find the plane, crtc, and fb objects. If not available, @@ -919,7 +919,7 @@ static int drm_mode_cursor_common(struct drm_device *dev, int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) return -EINVAL; @@ -1023,7 +1023,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, int ret = -EINVAL; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS) return -EINVAL; diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 186db2e4c57a..3f0205fc0a1a 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -844,7 +844,7 @@ int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, struct drm_prime_handle *args = data; if (!drm_core_check_feature(dev, DRIVER_PRIME)) - return -EINVAL; + return -EOPNOTSUPP; if (!dev->driver->prime_handle_to_fd) return -ENOSYS; @@ -863,7 +863,7 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, struct drm_prime_handle *args = data; if (!drm_core_check_feature(dev, DRIVER_PRIME)) - return -EINVAL; + return -EOPNOTSUPP; if (!dev->driver->prime_fd_to_handle) return -ENOSYS; diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c index cdb10f885a4f..79c77c3cad86 100644 --- a/drivers/gpu/drm/drm_property.c +++ b/drivers/gpu/drm/drm_property.c @@ -464,7 +464,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, uint64_t __user *values_ptr; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; property = drm_property_find(dev, file_priv, out_resp->prop_id); if (!property) @@ -757,7 +757,7 @@ int drm_mode_getblob_ioctl(struct drm_device *dev, int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; blob = drm_property_lookup_blob(dev, out_resp->blob_id); if (!blob) @@ -786,7 +786,7 @@ int drm_mode_createblob_ioctl(struct drm_device *dev, int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; blob = drm_property_create_blob(dev, out_resp->length, NULL); if (IS_ERR(blob)) @@ -823,7 +823,7 @@ int drm_mode_destroyblob_ioctl(struct drm_device *dev, int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; blob = drm_property_lookup_blob(dev, out_resp->blob_id); if (!blob) diff --git a/drivers/gpu/drm/drm_scatter.c b/drivers/gpu/drm/drm_scatter.c index 275bca44f38c..bb829a115fc6 100644 --- a/drivers/gpu/drm/drm_scatter.c +++ b/drivers/gpu/drm/drm_scatter.c @@ -89,10 +89,10 @@ int drm_legacy_sg_alloc(struct drm_device *dev, void *data, DRM_DEBUG("\n"); if (!drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; if (!drm_core_check_feature(dev, DRIVER_SG)) - return -EINVAL; + return -EOPNOTSUPP; if (dev->sg) return -EINVAL; @@ -202,10 +202,10 @@ int drm_legacy_sg_free(struct drm_device *dev, void *data, struct drm_sg_mem *entry; if (!drm_core_check_feature(dev, DRIVER_LEGACY)) - return -EINVAL; + return -EOPNOTSUPP; if (!drm_core_check_feature(dev, DRIVER_SG)) - return -EINVAL; + return -EOPNOTSUPP; entry = dev->sg; dev->sg = NULL; diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index e9ce623d049e..497729202bfe 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -573,7 +573,7 @@ drm_syncobj_create_ioctl(struct drm_device *dev, void *data, struct drm_syncobj_create *args = data; if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) - return -ENODEV; + return -EOPNOTSUPP; /* no valid flags yet */ if (args->flags & ~DRM_SYNCOBJ_CREATE_SIGNALED) @@ -590,7 +590,7 @@ drm_syncobj_destroy_ioctl(struct drm_device *dev, void *data, struct drm_syncobj_destroy *args = data; if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) - return -ENODEV; + return -EOPNOTSUPP; /* make sure padding is empty */ if (args->pad) @@ -605,7 +605,7 @@ drm_syncobj_handle_to_fd_ioctl(struct drm_device *dev, void *data, struct drm_syncobj_handle *args = data; if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) - return -ENODEV; + return -EOPNOTSUPP; if (args->pad) return -EINVAL; @@ -629,7 +629,7 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data, struct drm_syncobj_handle *args = data; if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) - return -ENODEV; + return -EOPNOTSUPP; if (args->pad) return -EINVAL; @@ -921,7 +921,7 @@ drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, int ret = 0; if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) - return -ENODEV; + return -EOPNOTSUPP; if (args->flags & ~(DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL | DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT)) @@ -955,7 +955,7 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, int ret; if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) - return -ENODEV; + return -EOPNOTSUPP; if (args->pad != 0) return -EINVAL; @@ -988,7 +988,7 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, int ret; if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) - return -ENODEV; + return -EOPNOTSUPP; if (args->pad != 0) return -EINVAL; diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index ec2dcfdac8ef..98e091175921 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -1771,7 +1771,7 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, int ret; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; if (!dev->irq_enabled) return -EINVAL; @@ -1829,7 +1829,7 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data, unsigned long spin_flags; if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; + return -EOPNOTSUPP; if (!dev->irq_enabled) return -EINVAL; From 5c5b3b0ebe6d78cad645cc010d7e8fb81ccd099b Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sun, 16 Sep 2018 12:34:07 +0800 Subject: [PATCH 06/11] dt-bindings: sun4i-drm: add compatible for R40 HDMI PHY The Allwinner R40 HDMI PHY is currently the only one that seems to be able to select between two PLL inputs. Add a compatible string for it, and the pll-1 clock input definition. Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20180916043409.62374-3-icenowy@aosc.io --- .../devicetree/bindings/display/sunxi/sun4i-drm.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index 0bbb5d47f228..22d6dda587c5 100644 --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt @@ -107,6 +107,7 @@ Required properties: - compatible: value must be one of: * allwinner,sun8i-a83t-hdmi-phy * allwinner,sun8i-h3-hdmi-phy + * allwinner,sun8i-r40-hdmi-phy * allwinner,sun50i-a64-hdmi-phy - reg: base address and size of memory-mapped region - clocks: phandles to the clocks feeding the HDMI PHY @@ -116,9 +117,9 @@ Required properties: - resets: phandle to the reset controller driving the PHY - reset-names: must be "phy" -H3 and A64 HDMI PHY require additional clocks: +H3, A64 and R40 HDMI PHY require additional clocks: - pll-0: parent of phy clock - - pll-1: second possible phy clock parent (A64 only) + - pll-1: second possible phy clock parent (A64/R40 only) TV Encoder ---------- From 3536faefc03d48e97891ed7fc542ff85ce00a4e1 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sun, 16 Sep 2018 12:34:08 +0800 Subject: [PATCH 07/11] drm/sun4i: add support for R40 HDMI PHY The R40 SoC has a HDMI PHY that is possible to mux two video PLLs. Add support for it. Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20180916043409.62374-4-icenowy@aosc.io --- drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index 82502b351aec..856124806353 100644 --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c @@ -417,6 +417,14 @@ static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = { .phy_config = &sun8i_hdmi_phy_config_h3, }; +static const struct sun8i_hdmi_phy_variant sun8i_r40_hdmi_phy = { + .has_phy_clk = true, + .has_second_pll = true, + .phy_init = &sun8i_hdmi_phy_init_h3, + .phy_disable = &sun8i_hdmi_phy_disable_h3, + .phy_config = &sun8i_hdmi_phy_config_h3, +}; + static const struct of_device_id sun8i_hdmi_phy_of_table[] = { { .compatible = "allwinner,sun50i-a64-hdmi-phy", @@ -430,6 +438,10 @@ static const struct of_device_id sun8i_hdmi_phy_of_table[] = { .compatible = "allwinner,sun8i-h3-hdmi-phy", .data = &sun8i_h3_hdmi_phy, }, + { + .compatible = "allwinner,sun8i-r40-hdmi-phy", + .data = &sun8i_r40_hdmi_phy, + }, { /* sentinel */ } }; From 8f44ca223345a7d02e18ed4e70ff95178434e137 Mon Sep 17 00:00:00 2001 From: Jiandi An Date: Wed, 19 Sep 2018 07:09:53 +0000 Subject: [PATCH 08/11] drm/virtio: add dma sync for dma mapped virtio gpu framebuffer pages With virtio gpu ttm-pages being dma mapped, dma sync is needed when swiotlb is used as bounce buffers, before TRANSFER_TO_HOST_2D/3D commands are sent. Signed-off-by: Jiandi An Link: http://patchwork.freedesktop.org/patch/msgid/20180919070931.91168-1-jiandi.an@amd.com Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_drv.h | 8 ++++++++ drivers/gpu/drm/virtio/virtgpu_fb.c | 7 ------- drivers/gpu/drm/virtio/virtgpu_vq.c | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index f8f4a40dd1b8..a2d79e18bda7 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -133,6 +134,13 @@ struct virtio_gpu_framebuffer { #define to_virtio_gpu_framebuffer(x) \ container_of(x, struct virtio_gpu_framebuffer, base) +struct virtio_gpu_fbdev { + struct drm_fb_helper helper; + struct virtio_gpu_framebuffer vgfb; + struct virtio_gpu_device *vgdev; + struct delayed_work work; +}; + struct virtio_gpu_mman { struct ttm_bo_global_ref bo_global_ref; struct drm_global_reference mem_global_ref; diff --git a/drivers/gpu/drm/virtio/virtgpu_fb.c b/drivers/gpu/drm/virtio/virtgpu_fb.c index b5cebc9a179a..b9678c4082ac 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fb.c +++ b/drivers/gpu/drm/virtio/virtgpu_fb.c @@ -29,13 +29,6 @@ #define VIRTIO_GPU_FBCON_POLL_PERIOD (HZ / 60) -struct virtio_gpu_fbdev { - struct drm_fb_helper helper; - struct virtio_gpu_framebuffer vgfb; - struct virtio_gpu_device *vgdev; - struct delayed_work work; -}; - static int virtio_gpu_dirty_update(struct virtio_gpu_framebuffer *fb, bool store, int x, int y, int width, int height) diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 5784c3ea8767..df32811f2c3e 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -490,6 +490,15 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, { struct virtio_gpu_transfer_to_host_2d *cmd_p; struct virtio_gpu_vbuffer *vbuf; + struct virtio_gpu_fbdev *vgfbdev = vgdev->vgfbdev; + struct virtio_gpu_framebuffer *fb = &vgfbdev->vgfb; + struct virtio_gpu_object *obj = gem_to_virtio_gpu_obj(fb->base.obj[0]); + bool use_dma_api = !virtio_has_iommu_quirk(vgdev->vdev); + + if (use_dma_api) + dma_sync_sg_for_device(vgdev->vdev->dev.parent, + obj->pages->sgl, obj->pages->nents, + DMA_TO_DEVICE); cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); memset(cmd_p, 0, sizeof(*cmd_p)); @@ -789,6 +798,15 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, { struct virtio_gpu_transfer_host_3d *cmd_p; struct virtio_gpu_vbuffer *vbuf; + struct virtio_gpu_fbdev *vgfbdev = vgdev->vgfbdev; + struct virtio_gpu_framebuffer *fb = &vgfbdev->vgfb; + struct virtio_gpu_object *obj = gem_to_virtio_gpu_obj(fb->base.obj[0]); + bool use_dma_api = !virtio_has_iommu_quirk(vgdev->vdev); + + if (use_dma_api) + dma_sync_sg_for_device(vgdev->vdev->dev.parent, + obj->pages->sgl, obj->pages->nents, + DMA_TO_DEVICE); cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); memset(cmd_p, 0, sizeof(*cmd_p)); From 0b49bbbd9f10dd5bcce126aa99041a44320767f7 Mon Sep 17 00:00:00 2001 From: "Lee, Shawn C" Date: Tue, 11 Sep 2018 23:22:49 -0700 Subject: [PATCH 09/11] drm: Add support for device_id based detection. DP quirk list just compare sink or branch device's OUI so far. That means particular vendor's products will be applied specific change. This change would confirm device_id the same or not. Then driver can implement some changes for branch/sink device that really need additional WA. v2: use sizeof instead of hard coded '6' v3: add lost commit messages back for version 2 v4: send patch to both intel-gfx and dri-devel Cc: Jani Nikula Cc: Cooper Chiou Cc: Matt Atwood Cc: Maarten Lankhorst Cc: Dhinakaran Pandiyan Cc: Clint Taylor Tested-by: Clint Taylor Signed-off-by: Lee, Shawn C Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1536733371-25004-2-git-send-email-shawn.c.lee@intel.com --- drivers/gpu/drm/drm_dp_helper.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 8c6b9fd89f8a..07167604e8cc 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -1257,15 +1257,20 @@ EXPORT_SYMBOL(drm_dp_stop_crc); struct dpcd_quirk { u8 oui[3]; + u8 device_id[6]; bool is_branch; u32 quirks; }; #define OUI(first, second, third) { (first), (second), (third) } +#define DEVICE_ID(first, second, third, fourth, fifth, sixth) \ + { (first), (second), (third), (fourth), (fifth), (sixth) } + +#define DEVICE_ID_ANY DEVICE_ID(0, 0, 0, 0, 0, 0) static const struct dpcd_quirk dpcd_quirk_list[] = { /* Analogix 7737 needs reduced M and N at HBR2 link rates */ - { OUI(0x00, 0x22, 0xb9), true, BIT(DP_DPCD_QUIRK_LIMITED_M_N) }, + { OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_LIMITED_M_N) }, }; #undef OUI @@ -1284,6 +1289,7 @@ drm_dp_get_quirks(const struct drm_dp_dpcd_ident *ident, bool is_branch) const struct dpcd_quirk *quirk; u32 quirks = 0; int i; + u8 any_device[] = DEVICE_ID_ANY; for (i = 0; i < ARRAY_SIZE(dpcd_quirk_list); i++) { quirk = &dpcd_quirk_list[i]; @@ -1294,12 +1300,19 @@ drm_dp_get_quirks(const struct drm_dp_dpcd_ident *ident, bool is_branch) if (memcmp(quirk->oui, ident->oui, sizeof(ident->oui)) != 0) continue; + if (memcmp(quirk->device_id, any_device, sizeof(any_device)) != 0 && + memcmp(quirk->device_id, ident->device_id, sizeof(ident->device_id)) != 0) + continue; + quirks |= quirk->quirks; } return quirks; } +#undef DEVICE_ID_ANY +#undef DEVICE_ID + /** * drm_dp_read_desc - read sink/branch descriptor from DPCD * @aux: DisplayPort AUX channel From 53ca2edcf033f3368b2dc0ef3cbcc2f47d556d13 Mon Sep 17 00:00:00 2001 From: "Lee, Shawn C" Date: Tue, 11 Sep 2018 23:22:50 -0700 Subject: [PATCH 10/11] drm: Change limited M/N quirk to constant N quirk. Some DP dongles in particular seem to be fussy about too large link M/N values. Set specific value for N divider can resolve this issue per dongle vendor's comment. So configure N as constant value (0x8000) to instead of reduce M/N formula when specific DP dongle connected. v2: add more comments for issue description and fix typo. v3: add lost commit messages back for version 2 v4: send patch to both intel-gfx and dri-devel Cc: Jani Nikula Cc: Cooper Chiou Cc: Matt Atwood Cc: Maarten Lankhorst Cc: Dhinakaran Pandiyan Cc: Clint Taylor Tested-by: Clint Taylor Signed-off-by: Lee, Shawn C Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1536733371-25004-3-git-send-email-shawn.c.lee@intel.com --- drivers/gpu/drm/drm_dp_helper.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 28 +++++++++++++--------------- drivers/gpu/drm/i915/intel_display.h | 2 +- drivers/gpu/drm/i915/intel_dp.c | 8 ++++---- drivers/gpu/drm/i915/intel_dp_mst.c | 6 +++--- include/drm/drm_dp_helper.h | 6 +++--- 6 files changed, 25 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 07167604e8cc..c1fe1713eaef 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -1270,7 +1270,7 @@ struct dpcd_quirk { static const struct dpcd_quirk dpcd_quirk_list[] = { /* Analogix 7737 needs reduced M and N at HBR2 link rates */ - { OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_LIMITED_M_N) }, + { OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_CONSTANT_N) }, }; #undef OUI diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c24bc848ac6c..611b425b50f1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6677,22 +6677,20 @@ intel_reduce_m_n_ratio(uint32_t *num, uint32_t *den) static void compute_m_n(unsigned int m, unsigned int n, uint32_t *ret_m, uint32_t *ret_n, - bool reduce_m_n) + bool constant_n) { /* - * Reduce M/N as much as possible without loss in precision. Several DP - * dongles in particular seem to be fussy about too large *link* M/N - * values. The passed in values are more likely to have the least - * significant bits zero than M after rounding below, so do this first. + * Several DP dongles in particular seem to be fussy about + * too large link M/N values. Give N value as 0x8000 that + * should be acceptable by specific devices. 0x8000 is the + * specified fixed N value for asynchronous clock mode, + * which the devices expect also in synchronous clock mode. */ - if (reduce_m_n) { - while ((m & 1) == 0 && (n & 1) == 0) { - m >>= 1; - n >>= 1; - } - } + if (constant_n) + *ret_n = 0x8000; + else + *ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX); - *ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX); *ret_m = div_u64((uint64_t) m * *ret_n, n); intel_reduce_m_n_ratio(ret_m, ret_n); } @@ -6701,18 +6699,18 @@ void intel_link_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, int link_clock, struct intel_link_m_n *m_n, - bool reduce_m_n) + bool constant_n) { m_n->tu = 64; compute_m_n(bits_per_pixel * pixel_clock, link_clock * nlanes * 8, &m_n->gmch_m, &m_n->gmch_n, - reduce_m_n); + constant_n); compute_m_n(pixel_clock, link_clock, &m_n->link_m, &m_n->link_n, - reduce_m_n); + constant_n); } static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h index 809c06ae4c07..58ba614862e5 100644 --- a/drivers/gpu/drm/i915/intel_display.h +++ b/drivers/gpu/drm/i915/intel_display.h @@ -382,6 +382,6 @@ struct intel_link_m_n { void intel_link_compute_m_n(int bpp, int nlanes, int pixel_clock, int link_clock, struct intel_link_m_n *m_n, - bool reduce_m_n); + bool constant_n); #endif diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cd0f649b57a5..29212d317f58 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1834,8 +1834,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, struct intel_connector *intel_connector = intel_dp->attached_connector; struct intel_digital_connector_state *intel_conn_state = to_intel_digital_connector_state(conn_state); - bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc, - DP_DPCD_QUIRK_LIMITED_M_N); + bool constant_n = drm_dp_has_quirk(&intel_dp->desc, + DP_DPCD_QUIRK_CONSTANT_N); if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A) pipe_config->has_pch_encoder = true; @@ -1900,7 +1900,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, adjusted_mode->crtc_clock, pipe_config->port_clock, &pipe_config->dp_m_n, - reduce_m_n); + constant_n); if (intel_connector->panel.downclock_mode != NULL && dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) { @@ -1910,7 +1910,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, intel_connector->panel.downclock_mode->clock, pipe_config->port_clock, &pipe_config->dp_m2_n2, - reduce_m_n); + constant_n); } if (!HAS_DDI(dev_priv)) diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 7e3e01607643..b7505879b1f7 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -45,8 +45,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, int lane_count, slots; const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; int mst_pbn; - bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc, - DP_DPCD_QUIRK_LIMITED_M_N); + bool constant_n = drm_dp_has_quirk(&intel_dp->desc, + DP_DPCD_QUIRK_CONSTANT_N); if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) return false; @@ -87,7 +87,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, adjusted_mode->crtc_clock, pipe_config->port_clock, &pipe_config->dp_m_n, - reduce_m_n); + constant_n); pipe_config->dp_m_n.tu = slots; diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 698082a02b97..2a3843f248cf 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -1261,12 +1261,12 @@ int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc, */ enum drm_dp_quirk { /** - * @DP_DPCD_QUIRK_LIMITED_M_N: + * @DP_DPCD_QUIRK_CONSTANT_N: * * The device requires main link attributes Mvid and Nvid to be limited - * to 16 bits. + * to 16 bits. So will give a constant value (0x8000) for compatability. */ - DP_DPCD_QUIRK_LIMITED_M_N, + DP_DPCD_QUIRK_CONSTANT_N, }; /** From e884818cc0edb9bd128de95e7ca6b569f4667c0f Mon Sep 17 00:00:00 2001 From: "Lee, Shawn C" Date: Tue, 11 Sep 2018 23:22:51 -0700 Subject: [PATCH 11/11] drm: add LG eDP panel to quirk database The N value was computed by kernel driver that based on synchronous clock mode. But only specific N value (0x8000) would be acceptable for LG LP140WF6-SPM1 eDP panel which is running at asynchronous clock mode. With the other N value, Tcon will enter BITS mode and display black screen. Add this panel into quirk database and give particular N value when calculate M/N divider. v2: no update v3: add lost commit messages back for version 2 v4: send patch to both intel-gfx and dri-devel Cc: Jani Nikula Cc: Cooper Chiou Cc: Matt Atwood Cc: Maarten Lankhorst Cc: Dhinakaran Pandiyan Cc: Clint Taylor Signed-off-by: Lee, Shawn C Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1536733371-25004-4-git-send-email-shawn.c.lee@intel.com --- drivers/gpu/drm/drm_dp_helper.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index c1fe1713eaef..37c01b6076ec 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -1271,6 +1271,8 @@ struct dpcd_quirk { static const struct dpcd_quirk dpcd_quirk_list[] = { /* Analogix 7737 needs reduced M and N at HBR2 link rates */ { OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_CONSTANT_N) }, + /* LG LP140WF6-SPM1 eDP panel */ + { OUI(0x00, 0x22, 0xb9), DEVICE_ID('s', 'i', 'v', 'a', 'r', 'T'), false, BIT(DP_DPCD_QUIRK_CONSTANT_N) }, }; #undef OUI