diff options
author | Dave Airlie <airlied@redhat.com> | 2020-04-22 10:40:34 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2020-04-22 10:41:35 +1000 |
commit | 1aa63ddf726ea049279989b93b69b57ce6efd75b (patch) | |
tree | b2850db923425621e7830918569572de9a22c86b /drivers/gpu/drm/drm_mode_config.c | |
parent | 774f1eeb18b016eee460e060a786eee83b14d007 (diff) | |
parent | 14d0066b8477775971db7d0ef03c86fefe4d5bf2 (diff) |
Merge tag 'drm-misc-next-2020-04-14' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.8:
UAPI Changes:
- drm: error out with EBUSY when device has existing master
- drm: rework SET_MASTER and DROP_MASTER perm handling
Cross-subsystem Changes:
- mm: export two symbols from slub/slob
- fbdev: savage: fix -Wextra build warning
- video: omap2: Use scnprintf() for avoiding potential buffer overflow
Core Changes:
- Remove drm_pci.h
- drm_pci_{alloc/free)() are now legacy
- Introduce managed DRM resourcesA
- Allow drivers to subclass struct drm_framebuffer
- Introduce struct drm_afbc_framebuffer and helpers
- fbdev: remove return value from generic fbdev setup
- Introduce simple-encoder helper
- vram-helpers: set fence on plane
- dp_mst: ACT timeout improvements
- dp_mst: Remove drm_dp_mst_has_audio()
- TTM: ttm_trace_dma_{map/unmap}() cleanups
- dma-buf: add flag for PCIP2P support
- EDID: Various improvements
- Encoder: cleanup semantics of possible_clones and possible_crtcs
- VBLANK documentation updates
- Writeback documentation updates
Driver Changes:
- Convert several drivers to i2c_new_client_device()
- Drop explicit drm_mode_config_cleanup() calls from drivers
- Auto-release device structures with drmm_add_final_kfree()
- Init bfdev console after registering DRM device
- Make various .debugfs functions return 0 unconditionally; ignore errors
- video: Use scnprintf() to avoid buffer overflows
- Convert drivers to simple encoders
- drm/amdgpu: note that we can handle peer2peer DMA-buf
- drm/amdgpu: add support for exporting VRAM using DMA-buf v3
- drm/kirin: Revert change to register connectors
- drm/lima: Add optional devfreq and cooling device support
- drm/lima: Various improvements wrt. task handling
- drm/panel: nt39016: Support multiple modes and 50Hz
- drm/panel: Support Leadtek LTK050H3146W
- drm/rockchip: Add support for afbc
- drm/virtio: Various cleanups
- drm/hisilicon/hibmc: Enforce 128-byte stride alignment
- drm/qxl: Fix notify port address of cursor ring buffer
- drm/sun4i: Improvements to format handling
- drm/bridge: dw-hdmi: Various improvements
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20200414090738.GA16827@linux-uq9g
Diffstat (limited to 'drivers/gpu/drm/drm_mode_config.c')
-rw-r--r-- | drivers/gpu/drm/drm_mode_config.c | 110 |
1 files changed, 107 insertions, 3 deletions
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 08e6eff6a179..5761f838a057 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -25,6 +25,7 @@ #include <drm/drm_drv.h> #include <drm/drm_encoder.h> #include <drm/drm_file.h> +#include <drm/drm_managed.h> #include <drm/drm_mode_config.h> #include <drm/drm_print.h> #include <linux/dma-resv.h> @@ -373,8 +374,14 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return 0; } +static void drm_mode_config_init_release(struct drm_device *dev, void *ptr) +{ + drm_mode_config_cleanup(dev); +} + /** - * drm_mode_config_init - initialize DRM mode_configuration structure + * drmm_mode_config_init - managed DRM mode_configuration structure + * initialization * @dev: DRM device * * Initialize @dev's mode_config structure, used for tracking the graphics @@ -384,8 +391,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) * problem, since this should happen single threaded at init time. It is the * driver's problem to ensure this guarantee. * + * Cleanup is automatically handled through registering drm_mode_config_cleanup + * with drmm_add_action(). + * + * Returns: 0 on success, negative error value on failure. */ -void drm_mode_config_init(struct drm_device *dev) +int drmm_mode_config_init(struct drm_device *dev) { mutex_init(&dev->mode_config.mutex); drm_modeset_lock_init(&dev->mode_config.connection_mutex); @@ -443,8 +454,11 @@ void drm_mode_config_init(struct drm_device *dev) drm_modeset_acquire_fini(&modeset_ctx); dma_resv_fini(&resv); } + + return drmm_add_action_or_reset(dev, drm_mode_config_init_release, + NULL); } -EXPORT_SYMBOL(drm_mode_config_init); +EXPORT_SYMBOL(drmm_mode_config_init); /** * drm_mode_config_cleanup - free up DRM mode_config info @@ -456,6 +470,9 @@ EXPORT_SYMBOL(drm_mode_config_init); * Note that since this /should/ happen single-threaded at driver/device * teardown time, no locking is required. It's the driver's job to ensure that * this guarantee actually holds true. + * + * FIXME: With the managed drmm_mode_config_init() it is no longer necessary for + * drivers to explicitly call this function. */ void drm_mode_config_cleanup(struct drm_device *dev) { @@ -532,3 +549,90 @@ void drm_mode_config_cleanup(struct drm_device *dev) drm_modeset_lock_fini(&dev->mode_config.connection_mutex); } EXPORT_SYMBOL(drm_mode_config_cleanup); + +static u32 full_encoder_mask(struct drm_device *dev) +{ + struct drm_encoder *encoder; + u32 encoder_mask = 0; + + drm_for_each_encoder(encoder, dev) + encoder_mask |= drm_encoder_mask(encoder); + + return encoder_mask; +} + +/* + * For some reason we want the encoder itself included in + * possible_clones. Make life easy for drivers by allowing them + * to leave possible_clones unset if no cloning is possible. + */ +static void fixup_encoder_possible_clones(struct drm_encoder *encoder) +{ + if (encoder->possible_clones == 0) + encoder->possible_clones = drm_encoder_mask(encoder); +} + +static void validate_encoder_possible_clones(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + u32 encoder_mask = full_encoder_mask(dev); + struct drm_encoder *other; + + drm_for_each_encoder(other, dev) { + WARN(!!(encoder->possible_clones & drm_encoder_mask(other)) != + !!(other->possible_clones & drm_encoder_mask(encoder)), + "possible_clones mismatch: " + "[ENCODER:%d:%s] mask=0x%x possible_clones=0x%x vs. " + "[ENCODER:%d:%s] mask=0x%x possible_clones=0x%x\n", + encoder->base.id, encoder->name, + drm_encoder_mask(encoder), encoder->possible_clones, + other->base.id, other->name, + drm_encoder_mask(other), other->possible_clones); + } + + WARN((encoder->possible_clones & drm_encoder_mask(encoder)) == 0 || + (encoder->possible_clones & ~encoder_mask) != 0, + "Bogus possible_clones: " + "[ENCODER:%d:%s] possible_clones=0x%x (full encoder mask=0x%x)\n", + encoder->base.id, encoder->name, + encoder->possible_clones, encoder_mask); +} + +static u32 full_crtc_mask(struct drm_device *dev) +{ + struct drm_crtc *crtc; + u32 crtc_mask = 0; + + drm_for_each_crtc(crtc, dev) + crtc_mask |= drm_crtc_mask(crtc); + + return crtc_mask; +} + +static void validate_encoder_possible_crtcs(struct drm_encoder *encoder) +{ + u32 crtc_mask = full_crtc_mask(encoder->dev); + + WARN((encoder->possible_crtcs & crtc_mask) == 0 || + (encoder->possible_crtcs & ~crtc_mask) != 0, + "Bogus possible_crtcs: " + "[ENCODER:%d:%s] possible_crtcs=0x%x (full crtc mask=0x%x)\n", + encoder->base.id, encoder->name, + encoder->possible_crtcs, crtc_mask); +} + +void drm_mode_config_validate(struct drm_device *dev) +{ + struct drm_encoder *encoder; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return; + + drm_for_each_encoder(encoder, dev) + fixup_encoder_possible_clones(encoder); + + drm_for_each_encoder(encoder, dev) { + validate_encoder_possible_clones(encoder); + validate_encoder_possible_crtcs(encoder); + } +} |