Hi all,
So yeah this takes a bit longer than I hoped, but here's a few more things split out from drmP.h and properly documented. The vblank stuff took a bit a detour, since I opted to refactor stuff away instead of documenting it.
What's now left in drmP.h is struct drm_device and all the various debug printing stuff.
Cheers, Daniel
Daniel Vetter (16): drm: drop extern from function decls drm: Extract drm_debugfs.h drm: document driver interface for CRC capturing drm/debugfs: Add kerneldoc drm: update todo.rst drm: Consolidate and document sysfs support drm: Extract drm_ioctl.h drm: document drm_ioctl.[hc] drm/todo: Add tinydrm refactoring ideas drm/vblank: Remove DRM_VBLANKTIME_IN_VBLANK drm/vblank: Switch drm_driver->get_vblank_timestamp to return a bool drm/vblank: Switch to bool in_vblank_irq in get_vblank_timestamp drm/vblank: Add FIXME comments about moving the vblank ts hooks drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos drm/vblank: Simplify the get_scanout_position helper hook drm/doc: Small markup fixup
Documentation/gpu/drm-internals.rst | 50 -------- Documentation/gpu/drm-uapi.rst | 36 ++++++ Documentation/gpu/todo.rst | 139 +++++++++++++++------- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 - drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 14 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 41 ------- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 3 + drivers/gpu/drm/drm_debugfs.c | 56 ++------- drivers/gpu/drm/drm_debugfs_crc.c | 17 +-- drivers/gpu/drm/drm_internal.h | 2 +- drivers/gpu/drm/drm_ioc32.c | 1 - drivers/gpu/drm/drm_ioctl.c | 46 ++++++++ drivers/gpu/drm/drm_irq.c | 121 ++++++++++--------- drivers/gpu/drm/drm_probe_helper.c | 2 +- drivers/gpu/drm/drm_sysfs.c | 70 +++++------ drivers/gpu/drm/i915/i915_irq.c | 52 ++------- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 45 ++----- drivers/gpu/drm/nouveau/nouveau_display.c | 37 ++---- drivers/gpu/drm/nouveau/nouveau_display.h | 8 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +- drivers/gpu/drm/radeon/radeon_drv.c | 18 ++- drivers/gpu/drm/radeon/radeon_kms.c | 37 ------ drivers/gpu/drm/radeon/radeon_mode.h | 3 + drivers/gpu/drm/vc4/vc4_crtc.c | 34 ++---- drivers/gpu/drm/vc4/vc4_drv.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 11 +- include/drm/drmP.h | 120 +------------------ include/drm/drm_crtc.h | 5 +- include/drm/drm_crtc_helper.h | 38 +++--- include/drm/drm_debugfs.h | 100 ++++++++++++++++ include/drm/drm_drv.h | 56 ++++----- include/drm/drm_global.h | 8 +- include/drm/drm_hashtab.h | 20 ++-- include/drm/drm_ioctl.h | 188 ++++++++++++++++++++++++++++++ include/drm/drm_irq.h | 21 +++- include/drm/drm_of.h | 24 ++-- include/drm/drm_pci.h | 22 ++-- include/drm/drm_plane.h | 20 ++-- include/drm/drm_prime.h | 30 ++--- include/drm/drm_sysfs.h | 12 +- 40 files changed, 785 insertions(+), 730 deletions(-) create mode 100644 include/drm/drm_debugfs.h create mode 100644 include/drm/drm_ioctl.h
It's the default storage class for functions, entirely redundant. And a lot of these headers are a bit inconsistent due to organically grown.
Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch --- include/drm/drm_crtc_helper.h | 38 +++++++++++++++++++------------------- include/drm/drm_drv.h | 4 ++-- include/drm/drm_global.h | 8 ++++---- include/drm/drm_hashtab.h | 20 ++++++++++---------- include/drm/drm_of.h | 24 ++++++++++++------------ include/drm/drm_pci.h | 22 +++++++++++----------- include/drm/drm_plane.h | 20 ++++++++++---------- include/drm/drm_prime.h | 30 +++++++++++++++--------------- include/drm/drm_sysfs.h | 4 ++-- 9 files changed, 85 insertions(+), 85 deletions(-)
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index d026f5017c33..7506a60df8b1 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -43,18 +43,18 @@ #include <drm/drm_modeset_helper_vtables.h> #include <drm/drm_modeset_helper.h>
-extern void drm_helper_disable_unused_functions(struct drm_device *dev); -extern int drm_crtc_helper_set_config(struct drm_mode_set *set); -extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, - struct drm_display_mode *mode, - int x, int y, - struct drm_framebuffer *old_fb); -extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); -extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder); +void drm_helper_disable_unused_functions(struct drm_device *dev); +int drm_crtc_helper_set_config(struct drm_mode_set *set); +bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, + struct drm_display_mode *mode, + int x, int y, + struct drm_framebuffer *old_fb); +bool drm_helper_crtc_in_use(struct drm_crtc *crtc); +bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
-extern int drm_helper_connector_dpms(struct drm_connector *connector, int mode); +int drm_helper_connector_dpms(struct drm_connector *connector, int mode);
-extern void drm_helper_resume_force_mode(struct drm_device *dev); +void drm_helper_resume_force_mode(struct drm_device *dev);
int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, int x, int y, @@ -63,15 +63,15 @@ int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb);
/* drm_probe_helper.c */ -extern int drm_helper_probe_single_connector_modes(struct drm_connector - *connector, uint32_t maxX, - uint32_t maxY); -extern void drm_kms_helper_poll_init(struct drm_device *dev); -extern void drm_kms_helper_poll_fini(struct drm_device *dev); -extern bool drm_helper_hpd_irq_event(struct drm_device *dev); -extern void drm_kms_helper_hotplug_event(struct drm_device *dev); +int drm_helper_probe_single_connector_modes(struct drm_connector + *connector, uint32_t maxX, + uint32_t maxY); +void drm_kms_helper_poll_init(struct drm_device *dev); +void drm_kms_helper_poll_fini(struct drm_device *dev); +bool drm_helper_hpd_irq_event(struct drm_device *dev); +void drm_kms_helper_hotplug_event(struct drm_device *dev);
-extern void drm_kms_helper_poll_disable(struct drm_device *dev); -extern void drm_kms_helper_poll_enable(struct drm_device *dev); +void drm_kms_helper_poll_disable(struct drm_device *dev); +void drm_kms_helper_poll_enable(struct drm_device *dev);
#endif diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index fde343e0d581..d0b5f363bfa1 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -503,11 +503,11 @@ struct drm_driver { int dev_priv_size; };
-extern __printf(6, 7) +__printf(6, 7) void drm_dev_printk(const struct device *dev, const char *level, unsigned int category, const char *function_name, const char *prefix, const char *format, ...); -extern __printf(3, 4) +__printf(3, 4) void drm_printk(const char *level, unsigned int category, const char *format, ...); extern unsigned int drm_debug; diff --git a/include/drm/drm_global.h b/include/drm/drm_global.h index a06805eaf649..3a830602a2e4 100644 --- a/include/drm/drm_global.h +++ b/include/drm/drm_global.h @@ -45,9 +45,9 @@ struct drm_global_reference { void (*release) (struct drm_global_reference *); };
-extern void drm_global_init(void); -extern void drm_global_release(void); -extern int drm_global_item_ref(struct drm_global_reference *ref); -extern void drm_global_item_unref(struct drm_global_reference *ref); +void drm_global_init(void); +void drm_global_release(void); +int drm_global_item_ref(struct drm_global_reference *ref); +void drm_global_item_unref(struct drm_global_reference *ref);
#endif diff --git a/include/drm/drm_hashtab.h b/include/drm/drm_hashtab.h index fce2ef3fdfff..bb95ff011baf 100644 --- a/include/drm/drm_hashtab.h +++ b/include/drm/drm_hashtab.h @@ -49,17 +49,17 @@ struct drm_open_hash { u8 order; };
-extern int drm_ht_create(struct drm_open_hash *ht, unsigned int order); -extern int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item); -extern int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *item, - unsigned long seed, int bits, int shift, - unsigned long add); -extern int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key, struct drm_hash_item **item); +int drm_ht_create(struct drm_open_hash *ht, unsigned int order); +int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item); +int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *item, + unsigned long seed, int bits, int shift, + unsigned long add); +int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key, struct drm_hash_item **item);
-extern void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key); -extern int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key); -extern int drm_ht_remove_item(struct drm_open_hash *ht, struct drm_hash_item *item); -extern void drm_ht_remove(struct drm_open_hash *ht); +void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key); +int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key); +int drm_ht_remove_item(struct drm_open_hash *ht, struct drm_hash_item *item); +void drm_ht_remove(struct drm_open_hash *ht);
/* * RCU-safe interface diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h index 26a64805cc15..d1fc563f068a 100644 --- a/include/drm/drm_of.h +++ b/include/drm/drm_of.h @@ -11,18 +11,18 @@ struct drm_encoder; struct device_node;
#ifdef CONFIG_OF -extern uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, - struct device_node *port); -extern void drm_of_component_match_add(struct device *master, - struct component_match **matchptr, - int (*compare)(struct device *, void *), - struct device_node *node); -extern int drm_of_component_probe(struct device *dev, - int (*compare_of)(struct device *, void *), - const struct component_master_ops *m_ops); -extern int drm_of_encoder_active_endpoint(struct device_node *node, - struct drm_encoder *encoder, - struct of_endpoint *endpoint); +uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, + struct device_node *port); +void drm_of_component_match_add(struct device *master, + struct component_match **matchptr, + int (*compare)(struct device *, void *), + struct device_node *node); +int drm_of_component_probe(struct device *dev, + int (*compare_of)(struct device *, void *), + const struct component_master_ops *m_ops); +int drm_of_encoder_active_endpoint(struct device_node *node, + struct drm_encoder *encoder, + struct of_endpoint *endpoint); #else static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, struct device_node *port) diff --git a/include/drm/drm_pci.h b/include/drm/drm_pci.h index f5ebfcaf69e0..4579fac1080c 100644 --- a/include/drm/drm_pci.h +++ b/include/drm/drm_pci.h @@ -39,17 +39,17 @@ struct drm_device; struct drm_driver; struct drm_master;
-extern struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev, size_t size, - size_t align); -extern void drm_pci_free(struct drm_device *dev, struct drm_dma_handle * dmah); +struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev, size_t size, + size_t align); +void drm_pci_free(struct drm_device *dev, struct drm_dma_handle * dmah);
-extern int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver); -extern void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver); +int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver); +void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver); #ifdef CONFIG_PCI -extern int drm_get_pci_dev(struct pci_dev *pdev, - const struct pci_device_id *ent, - struct drm_driver *driver); -extern int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master); +int drm_get_pci_dev(struct pci_dev *pdev, + const struct pci_device_id *ent, + struct drm_driver *driver); +int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master); #else static inline int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, @@ -69,7 +69,7 @@ static inline int drm_pci_set_busid(struct drm_device *dev, #define DRM_PCIE_SPEED_50 2 #define DRM_PCIE_SPEED_80 4
-extern int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *speed_mask); -extern int drm_pcie_get_max_link_width(struct drm_device *dev, u32 *mlw); +int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *speed_mask); +int drm_pcie_get_max_link_width(struct drm_device *dev, u32 *mlw);
#endif /* _DRM_PCI_H_ */ diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 20867b4371ab..31da9f0c4ad2 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -510,7 +510,7 @@ struct drm_plane {
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
-extern __printf(8, 9) +__printf(8, 9) int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, uint32_t possible_crtcs, @@ -519,13 +519,13 @@ int drm_universal_plane_init(struct drm_device *dev, unsigned int format_count, enum drm_plane_type type, const char *name, ...); -extern int drm_plane_init(struct drm_device *dev, - struct drm_plane *plane, - uint32_t possible_crtcs, - const struct drm_plane_funcs *funcs, - const uint32_t *formats, unsigned int format_count, - bool is_primary); -extern void drm_plane_cleanup(struct drm_plane *plane); +int drm_plane_init(struct drm_device *dev, + struct drm_plane *plane, + uint32_t possible_crtcs, + const struct drm_plane_funcs *funcs, + const uint32_t *formats, unsigned int format_count, + bool is_primary); +void drm_plane_cleanup(struct drm_plane *plane);
/** * drm_plane_index - find the index of a registered plane @@ -538,8 +538,8 @@ static inline unsigned int drm_plane_index(struct drm_plane *plane) { return plane->index; } -extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx); -extern void drm_plane_force_disable(struct drm_plane *plane); +struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx); +void drm_plane_force_disable(struct drm_plane *plane);
int drm_mode_plane_set_obj_prop(struct drm_plane *plane, struct drm_property *property, diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h index d09563ecc4b7..0b2a235c4be0 100644 --- a/include/drm/drm_prime.h +++ b/include/drm/drm_prime.h @@ -57,24 +57,24 @@ struct drm_device; struct drm_gem_object; struct drm_file;
-extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev, - struct drm_gem_object *obj, - int flags); -extern int drm_gem_prime_handle_to_fd(struct drm_device *dev, - struct drm_file *file_priv, uint32_t handle, uint32_t flags, - int *prime_fd); -extern struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, - struct dma_buf *dma_buf); -extern int drm_gem_prime_fd_to_handle(struct drm_device *dev, - struct drm_file *file_priv, int prime_fd, uint32_t *handle); +struct dma_buf *drm_gem_prime_export(struct drm_device *dev, + struct drm_gem_object *obj, + int flags); +int drm_gem_prime_handle_to_fd(struct drm_device *dev, + struct drm_file *file_priv, uint32_t handle, uint32_t flags, + int *prime_fd); +struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, + struct dma_buf *dma_buf); +int drm_gem_prime_fd_to_handle(struct drm_device *dev, + struct drm_file *file_priv, int prime_fd, uint32_t *handle); struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev, struct dma_buf_export_info *exp_info); -extern void drm_gem_dmabuf_release(struct dma_buf *dma_buf); +void drm_gem_dmabuf_release(struct dma_buf *dma_buf);
-extern int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, - dma_addr_t *addrs, int max_pages); -extern struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages); -extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg); +int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, + dma_addr_t *addrs, int max_pages); +struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages); +void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg);
#endif /* __DRM_PRIME_H__ */ diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h index 1d8e033fde67..23418c1f10d1 100644 --- a/include/drm/drm_sysfs.h +++ b/include/drm/drm_sysfs.h @@ -6,7 +6,7 @@ * don't want to include the full drmP.h file. */
-extern int drm_class_device_register(struct device *dev); -extern void drm_class_device_unregister(struct device *dev); +int drm_class_device_register(struct device *dev); +void drm_class_device_unregister(struct device *dev);
#endif
Daniel Vetter daniel.vetter@ffwll.ch writes:
It's the default storage class for functions, entirely redundant. And a lot of these headers are a bit inconsistent due to organically grown.
Reviewed-by: Gabriel Krisman Bertazi krisman@collabora.co.uk
Doc polish will follow in the next patch.
Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_debugfs.c | 5 ++- include/drm/drmP.h | 44 +------------------------ include/drm/drm_debugfs.h | 76 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 44 deletions(-) create mode 100644 include/drm/drm_debugfs.h
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 1d2d18d82d2e..4b02f4230562 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -34,9 +34,12 @@ #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/export.h> -#include <drm/drmP.h> + +#include <drm/drm_debugfs.h> #include <drm/drm_edid.h> #include <drm/drm_atomic.h> +#include <drm/drmP.h> + #include "drm_internal.h" #include "drm_crtc_internal.h"
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 0e383438f793..60f3255c43a8 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -78,6 +78,7 @@ #include <drm/drm_prime.h> #include <drm/drm_pci.h> #include <drm/drm_file.h> +#include <drm/drm_debugfs.h>
struct module;
@@ -371,27 +372,6 @@ struct drm_ioctl_desc { #define DRM_SCANOUTPOS_ACCURATE (1 << 2)
/** - * Info file list entry. This structure represents a debugfs or proc file to - * be created by the drm core - */ -struct drm_info_list { - const char *name; /** file name */ - int (*show)(struct seq_file*, void*); /** show callback */ - u32 driver_features; /**< Required driver features for this entry */ - void *data; -}; - -/** - * debugfs node structure. This structure represents a debugfs file. - */ -struct drm_info_node { - struct list_head list; - struct drm_minor *minor; - const struct drm_info_list *info_ent; - struct dentry *dent; -}; - -/** * DRM device structure. This structure represent a complete card that * may contain multiple heads. */ @@ -592,28 +572,6 @@ int drm_invalid_op(struct drm_device *dev, void *data, * DMA quiscent + idle. DMA quiescent usually requires the hardware lock. */
- /* Debugfs support */ -#if defined(CONFIG_DEBUG_FS) -extern int drm_debugfs_create_files(const struct drm_info_list *files, - int count, struct dentry *root, - struct drm_minor *minor); -extern int drm_debugfs_remove_files(const struct drm_info_list *files, - int count, struct drm_minor *minor); -#else -static inline int drm_debugfs_create_files(const struct drm_info_list *files, - int count, struct dentry *root, - struct drm_minor *minor) -{ - return 0; -} - -static inline int drm_debugfs_remove_files(const struct drm_info_list *files, - int count, struct drm_minor *minor) -{ - return 0; -} -#endif - /* sysfs support (drm_sysfs.c) */ extern void drm_sysfs_hotplug_event(struct drm_device *dev);
diff --git a/include/drm/drm_debugfs.h b/include/drm/drm_debugfs.h new file mode 100644 index 000000000000..17e47c073fa9 --- /dev/null +++ b/include/drm/drm_debugfs.h @@ -0,0 +1,76 @@ +/* + * Internal Header for the Direct Rendering Manager + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * Copyright (c) 2009-2010, Code Aurora Forum. + * All rights reserved. + * + * Author: Rickard E. (Rik) Faith faith@valinux.com + * Author: Gareth Hughes gareth@valinux.com + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DRM_DEBUGFS_H_ +#define _DRM_DEBUGFS_H_ + +/** + * Info file list entry. This structure represents a debugfs or proc file to + * be created by the drm core + */ +struct drm_info_list { + const char *name; /** file name */ + int (*show)(struct seq_file*, void*); /** show callback */ + u32 driver_features; /**< Required driver features for this entry */ + void *data; +}; + +/** + * debugfs node structure. This structure represents a debugfs file. + */ +struct drm_info_node { + struct list_head list; + struct drm_minor *minor; + const struct drm_info_list *info_ent; + struct dentry *dent; +}; + +#endif /* _DRM_DEBUGFS_H_ */ +#if defined(CONFIG_DEBUG_FS) +int drm_debugfs_create_files(const struct drm_info_list *files, + int count, struct dentry *root, + struct drm_minor *minor); +int drm_debugfs_remove_files(const struct drm_info_list *files, + int count, struct drm_minor *minor); +#else +static inline int drm_debugfs_create_files(const struct drm_info_list *files, + int count, struct dentry *root, + struct drm_minor *minor) +{ + return 0; +} + +static inline int drm_debugfs_remove_files(const struct drm_info_list *files, + int count, struct drm_minor *minor) +{ + return 0; +} +#endif
On Wed, Mar 22, 2017 at 09:36:03AM +0100, Daniel Vetter wrote:
Doc polish will follow in the next patch.
Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_debugfs.c | 5 ++- include/drm/drmP.h | 44 +------------------------ include/drm/drm_debugfs.h | 76 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 44 deletions(-) create mode 100644 include/drm/drm_debugfs.h
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 1d2d18d82d2e..4b02f4230562 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -34,9 +34,12 @@ #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/export.h> -#include <drm/drmP.h>
+#include <drm/drm_debugfs.h> #include <drm/drm_edid.h> #include <drm/drm_atomic.h> +#include <drm/drmP.h>
#include "drm_internal.h" #include "drm_crtc_internal.h"
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 0e383438f793..60f3255c43a8 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -78,6 +78,7 @@ #include <drm/drm_prime.h> #include <drm/drm_pci.h> #include <drm/drm_file.h> +#include <drm/drm_debugfs.h>
Why do we need this?
struct module;
@@ -371,27 +372,6 @@ struct drm_ioctl_desc { #define DRM_SCANOUTPOS_ACCURATE (1 << 2)
/**
- Info file list entry. This structure represents a debugfs or proc file to
- be created by the drm core
- */
-struct drm_info_list {
- const char *name; /** file name */
- int (*show)(struct seq_file*, void*); /** show callback */
- u32 driver_features; /**< Required driver features for this entry */
- void *data;
-};
-/**
- debugfs node structure. This structure represents a debugfs file.
- */
-struct drm_info_node {
- struct list_head list;
- struct drm_minor *minor;
- const struct drm_info_list *info_ent;
- struct dentry *dent;
-};
-/**
- DRM device structure. This structure represent a complete card that
- may contain multiple heads.
*/ @@ -592,28 +572,6 @@ int drm_invalid_op(struct drm_device *dev, void *data,
- DMA quiscent + idle. DMA quiescent usually requires the hardware lock.
*/
/* Debugfs support */
-#if defined(CONFIG_DEBUG_FS) -extern int drm_debugfs_create_files(const struct drm_info_list *files,
int count, struct dentry *root,
struct drm_minor *minor);
-extern int drm_debugfs_remove_files(const struct drm_info_list *files,
int count, struct drm_minor *minor);
-#else -static inline int drm_debugfs_create_files(const struct drm_info_list *files,
int count, struct dentry *root,
struct drm_minor *minor)
-{
- return 0;
-}
-static inline int drm_debugfs_remove_files(const struct drm_info_list *files,
int count, struct drm_minor *minor)
-{
- return 0;
-} -#endif
/* sysfs support (drm_sysfs.c) */
extern void drm_sysfs_hotplug_event(struct drm_device *dev);
diff --git a/include/drm/drm_debugfs.h b/include/drm/drm_debugfs.h new file mode 100644 index 000000000000..17e47c073fa9 --- /dev/null +++ b/include/drm/drm_debugfs.h @@ -0,0 +1,76 @@ +/*
- Internal Header for the Direct Rendering Manager
- Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- Copyright (c) 2009-2010, Code Aurora Forum.
- All rights reserved.
- Author: Rickard E. (Rik) Faith faith@valinux.com
- Author: Gareth Hughes gareth@valinux.com
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the "Software"),
- to deal in the Software without restriction, including without limitation
- the rights to use, copy, modify, merge, publish, distribute, sublicense,
- and/or sell copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice (including the next
- paragraph) shall be included in all copies or substantial portions of the
- Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- */
+#ifndef _DRM_DEBUGFS_H_ +#define _DRM_DEBUGFS_H_
Do we want to make headers standalone? If we do then we would need a few includes and forward declarations.
+/**
- Info file list entry. This structure represents a debugfs or proc file to
- be created by the drm core
- */
+struct drm_info_list {
- const char *name; /** file name */
- int (*show)(struct seq_file*, void*); /** show callback */
- u32 driver_features; /**< Required driver features for this entry */
- void *data;
+};
+/**
- debugfs node structure. This structure represents a debugfs file.
- */
+struct drm_info_node {
- struct list_head list;
- struct drm_minor *minor;
- const struct drm_info_list *info_ent;
- struct dentry *dent;
+};
+#endif /* _DRM_DEBUGFS_H_ */
Why is this guy in the middle of the file?
+#if defined(CONFIG_DEBUG_FS) +int drm_debugfs_create_files(const struct drm_info_list *files,
int count, struct dentry *root,
struct drm_minor *minor);
+int drm_debugfs_remove_files(const struct drm_info_list *files,
int count, struct drm_minor *minor);
+#else +static inline int drm_debugfs_create_files(const struct drm_info_list *files,
int count, struct dentry *root,
struct drm_minor *minor)
+{
- return 0;
+}
+static inline int drm_debugfs_remove_files(const struct drm_info_list *files,
int count, struct drm_minor *minor)
+{
- return 0;
+}
+#endif
2.11.0
Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
On Wed, Mar 22, 2017 at 03:34:10PM +0200, Ville Syrjälä wrote:
On Wed, Mar 22, 2017 at 09:36:03AM +0100, Daniel Vetter wrote:
Doc polish will follow in the next patch.
Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_debugfs.c | 5 ++- include/drm/drmP.h | 44 +------------------------ include/drm/drm_debugfs.h | 76 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 44 deletions(-) create mode 100644 include/drm/drm_debugfs.h
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 1d2d18d82d2e..4b02f4230562 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -34,9 +34,12 @@ #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/export.h> -#include <drm/drmP.h>
+#include <drm/drm_debugfs.h> #include <drm/drm_edid.h> #include <drm/drm_atomic.h> +#include <drm/drmP.h>
#include "drm_internal.h" #include "drm_crtc_internal.h"
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 0e383438f793..60f3255c43a8 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -78,6 +78,7 @@ #include <drm/drm_prime.h> #include <drm/drm_pci.h> #include <drm/drm_file.h> +#include <drm/drm_debugfs.h>
Why do we need this?
struct module;
@@ -371,27 +372,6 @@ struct drm_ioctl_desc { #define DRM_SCANOUTPOS_ACCURATE (1 << 2)
/**
- Info file list entry. This structure represents a debugfs or proc file to
- be created by the drm core
- */
-struct drm_info_list {
- const char *name; /** file name */
- int (*show)(struct seq_file*, void*); /** show callback */
- u32 driver_features; /**< Required driver features for this entry */
- void *data;
-};
-/**
- debugfs node structure. This structure represents a debugfs file.
- */
-struct drm_info_node {
- struct list_head list;
- struct drm_minor *minor;
- const struct drm_info_list *info_ent;
- struct dentry *dent;
-};
-/**
- DRM device structure. This structure represent a complete card that
- may contain multiple heads.
*/ @@ -592,28 +572,6 @@ int drm_invalid_op(struct drm_device *dev, void *data,
- DMA quiscent + idle. DMA quiescent usually requires the hardware lock.
*/
/* Debugfs support */
-#if defined(CONFIG_DEBUG_FS) -extern int drm_debugfs_create_files(const struct drm_info_list *files,
int count, struct dentry *root,
struct drm_minor *minor);
-extern int drm_debugfs_remove_files(const struct drm_info_list *files,
int count, struct drm_minor *minor);
-#else -static inline int drm_debugfs_create_files(const struct drm_info_list *files,
int count, struct dentry *root,
struct drm_minor *minor)
-{
- return 0;
-}
-static inline int drm_debugfs_remove_files(const struct drm_info_list *files,
int count, struct drm_minor *minor)
-{
- return 0;
-} -#endif
/* sysfs support (drm_sysfs.c) */
extern void drm_sysfs_hotplug_event(struct drm_device *dev);
diff --git a/include/drm/drm_debugfs.h b/include/drm/drm_debugfs.h new file mode 100644 index 000000000000..17e47c073fa9 --- /dev/null +++ b/include/drm/drm_debugfs.h @@ -0,0 +1,76 @@ +/*
- Internal Header for the Direct Rendering Manager
- Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- Copyright (c) 2009-2010, Code Aurora Forum.
- All rights reserved.
- Author: Rickard E. (Rik) Faith faith@valinux.com
- Author: Gareth Hughes gareth@valinux.com
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the "Software"),
- to deal in the Software without restriction, including without limitation
- the rights to use, copy, modify, merge, publish, distribute, sublicense,
- and/or sell copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice (including the next
- paragraph) shall be included in all copies or substantial portions of the
- Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- */
+#ifndef _DRM_DEBUGFS_H_ +#define _DRM_DEBUGFS_H_
Do we want to make headers standalone? If we do then we would need a few includes and forward declarations.
Yes, but it's hard to make this work properly in one go. I sometimes try when it's easy, but very often you end up in loops. I think better to first split things, then try to get rid of drmP.h, one .c file at a time.
+/**
- Info file list entry. This structure represents a debugfs or proc file to
- be created by the drm core
- */
+struct drm_info_list {
- const char *name; /** file name */
- int (*show)(struct seq_file*, void*); /** show callback */
- u32 driver_features; /**< Required driver features for this entry */
- void *data;
+};
+/**
- debugfs node structure. This structure represents a debugfs file.
- */
+struct drm_info_node {
- struct list_head list;
- struct drm_minor *minor;
- const struct drm_info_list *info_ent;
- struct dentry *dent;
+};
+#endif /* _DRM_DEBUGFS_H_ */
Why is this guy in the middle of the file?
Oops, misplaced, will fix up and resend. -Daniel
+#if defined(CONFIG_DEBUG_FS) +int drm_debugfs_create_files(const struct drm_info_list *files,
int count, struct dentry *root,
struct drm_minor *minor);
+int drm_debugfs_remove_files(const struct drm_info_list *files,
int count, struct drm_minor *minor);
+#else +static inline int drm_debugfs_create_files(const struct drm_info_list *files,
int count, struct dentry *root,
struct drm_minor *minor)
+{
- return 0;
+}
+static inline int drm_debugfs_remove_files(const struct drm_info_list *files,
int count, struct drm_minor *minor)
+{
- return 0;
+}
+#endif
2.11.0
Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
-- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Doc polish will follow in the next patch.
v2: Put the include guard #endif at the end (Ville).
Cc: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_debugfs.c | 5 ++- include/drm/drmP.h | 44 +------------------------ include/drm/drm_debugfs.h | 77 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 44 deletions(-) create mode 100644 include/drm/drm_debugfs.h
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 1d2d18d82d2e..4b02f4230562 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -34,9 +34,12 @@ #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/export.h> -#include <drm/drmP.h> + +#include <drm/drm_debugfs.h> #include <drm/drm_edid.h> #include <drm/drm_atomic.h> +#include <drm/drmP.h> + #include "drm_internal.h" #include "drm_crtc_internal.h"
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 0e383438f793..60f3255c43a8 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -78,6 +78,7 @@ #include <drm/drm_prime.h> #include <drm/drm_pci.h> #include <drm/drm_file.h> +#include <drm/drm_debugfs.h>
struct module;
@@ -371,27 +372,6 @@ struct drm_ioctl_desc { #define DRM_SCANOUTPOS_ACCURATE (1 << 2)
/** - * Info file list entry. This structure represents a debugfs or proc file to - * be created by the drm core - */ -struct drm_info_list { - const char *name; /** file name */ - int (*show)(struct seq_file*, void*); /** show callback */ - u32 driver_features; /**< Required driver features for this entry */ - void *data; -}; - -/** - * debugfs node structure. This structure represents a debugfs file. - */ -struct drm_info_node { - struct list_head list; - struct drm_minor *minor; - const struct drm_info_list *info_ent; - struct dentry *dent; -}; - -/** * DRM device structure. This structure represent a complete card that * may contain multiple heads. */ @@ -592,28 +572,6 @@ int drm_invalid_op(struct drm_device *dev, void *data, * DMA quiscent + idle. DMA quiescent usually requires the hardware lock. */
- /* Debugfs support */ -#if defined(CONFIG_DEBUG_FS) -extern int drm_debugfs_create_files(const struct drm_info_list *files, - int count, struct dentry *root, - struct drm_minor *minor); -extern int drm_debugfs_remove_files(const struct drm_info_list *files, - int count, struct drm_minor *minor); -#else -static inline int drm_debugfs_create_files(const struct drm_info_list *files, - int count, struct dentry *root, - struct drm_minor *minor) -{ - return 0; -} - -static inline int drm_debugfs_remove_files(const struct drm_info_list *files, - int count, struct drm_minor *minor) -{ - return 0; -} -#endif - /* sysfs support (drm_sysfs.c) */ extern void drm_sysfs_hotplug_event(struct drm_device *dev);
diff --git a/include/drm/drm_debugfs.h b/include/drm/drm_debugfs.h new file mode 100644 index 000000000000..56924196d08d --- /dev/null +++ b/include/drm/drm_debugfs.h @@ -0,0 +1,77 @@ +/* + * Internal Header for the Direct Rendering Manager + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * Copyright (c) 2009-2010, Code Aurora Forum. + * All rights reserved. + * + * Author: Rickard E. (Rik) Faith faith@valinux.com + * Author: Gareth Hughes gareth@valinux.com + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DRM_DEBUGFS_H_ +#define _DRM_DEBUGFS_H_ + +/** + * Info file list entry. This structure represents a debugfs or proc file to + * be created by the drm core + */ +struct drm_info_list { + const char *name; /** file name */ + int (*show)(struct seq_file*, void*); /** show callback */ + u32 driver_features; /**< Required driver features for this entry */ + void *data; +}; + +/** + * debugfs node structure. This structure represents a debugfs file. + */ +struct drm_info_node { + struct list_head list; + struct drm_minor *minor; + const struct drm_info_list *info_ent; + struct dentry *dent; +}; + +#if defined(CONFIG_DEBUG_FS) +int drm_debugfs_create_files(const struct drm_info_list *files, + int count, struct dentry *root, + struct drm_minor *minor); +int drm_debugfs_remove_files(const struct drm_info_list *files, + int count, struct drm_minor *minor); +#else +static inline int drm_debugfs_create_files(const struct drm_info_list *files, + int count, struct dentry *root, + struct drm_minor *minor) +{ + return 0; +} + +static inline int drm_debugfs_remove_files(const struct drm_info_list *files, + int count, struct drm_minor *minor) +{ + return 0; +} +#endif + +#endif /* _DRM_DEBUGFS_H_ */
On Wed, Mar 22, 2017 at 09:53:36PM +0100, Daniel Vetter wrote:
Doc polish will follow in the next patch.
v2: Put the include guard #endif at the end (Ville).
Cc: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch
Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com
drivers/gpu/drm/drm_debugfs.c | 5 ++- include/drm/drmP.h | 44 +------------------------ include/drm/drm_debugfs.h | 77 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 44 deletions(-) create mode 100644 include/drm/drm_debugfs.h
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 1d2d18d82d2e..4b02f4230562 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -34,9 +34,12 @@ #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/export.h> -#include <drm/drmP.h>
+#include <drm/drm_debugfs.h> #include <drm/drm_edid.h> #include <drm/drm_atomic.h> +#include <drm/drmP.h>
#include "drm_internal.h" #include "drm_crtc_internal.h"
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 0e383438f793..60f3255c43a8 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -78,6 +78,7 @@ #include <drm/drm_prime.h> #include <drm/drm_pci.h> #include <drm/drm_file.h> +#include <drm/drm_debugfs.h>
struct module;
@@ -371,27 +372,6 @@ struct drm_ioctl_desc { #define DRM_SCANOUTPOS_ACCURATE (1 << 2)
/**
- Info file list entry. This structure represents a debugfs or proc file to
- be created by the drm core
- */
-struct drm_info_list {
- const char *name; /** file name */
- int (*show)(struct seq_file*, void*); /** show callback */
- u32 driver_features; /**< Required driver features for this entry */
- void *data;
-};
-/**
- debugfs node structure. This structure represents a debugfs file.
- */
-struct drm_info_node {
- struct list_head list;
- struct drm_minor *minor;
- const struct drm_info_list *info_ent;
- struct dentry *dent;
-};
-/**
- DRM device structure. This structure represent a complete card that
- may contain multiple heads.
*/ @@ -592,28 +572,6 @@ int drm_invalid_op(struct drm_device *dev, void *data,
- DMA quiscent + idle. DMA quiescent usually requires the hardware lock.
*/
/* Debugfs support */
-#if defined(CONFIG_DEBUG_FS) -extern int drm_debugfs_create_files(const struct drm_info_list *files,
int count, struct dentry *root,
struct drm_minor *minor);
-extern int drm_debugfs_remove_files(const struct drm_info_list *files,
int count, struct drm_minor *minor);
-#else -static inline int drm_debugfs_create_files(const struct drm_info_list *files,
int count, struct dentry *root,
struct drm_minor *minor)
-{
- return 0;
-}
-static inline int drm_debugfs_remove_files(const struct drm_info_list *files,
int count, struct drm_minor *minor)
-{
- return 0;
-} -#endif
/* sysfs support (drm_sysfs.c) */
extern void drm_sysfs_hotplug_event(struct drm_device *dev);
diff --git a/include/drm/drm_debugfs.h b/include/drm/drm_debugfs.h new file mode 100644 index 000000000000..56924196d08d --- /dev/null +++ b/include/drm/drm_debugfs.h @@ -0,0 +1,77 @@ +/*
- Internal Header for the Direct Rendering Manager
- Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- Copyright (c) 2009-2010, Code Aurora Forum.
- All rights reserved.
- Author: Rickard E. (Rik) Faith faith@valinux.com
- Author: Gareth Hughes gareth@valinux.com
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the "Software"),
- to deal in the Software without restriction, including without limitation
- the rights to use, copy, modify, merge, publish, distribute, sublicense,
- and/or sell copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice (including the next
- paragraph) shall be included in all copies or substantial portions of the
- Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- */
+#ifndef _DRM_DEBUGFS_H_ +#define _DRM_DEBUGFS_H_
+/**
- Info file list entry. This structure represents a debugfs or proc file to
- be created by the drm core
- */
+struct drm_info_list {
- const char *name; /** file name */
- int (*show)(struct seq_file*, void*); /** show callback */
- u32 driver_features; /**< Required driver features for this entry */
- void *data;
+};
+/**
- debugfs node structure. This structure represents a debugfs file.
- */
+struct drm_info_node {
- struct list_head list;
- struct drm_minor *minor;
- const struct drm_info_list *info_ent;
- struct dentry *dent;
+};
+#if defined(CONFIG_DEBUG_FS) +int drm_debugfs_create_files(const struct drm_info_list *files,
int count, struct dentry *root,
struct drm_minor *minor);
+int drm_debugfs_remove_files(const struct drm_info_list *files,
int count, struct drm_minor *minor);
+#else +static inline int drm_debugfs_create_files(const struct drm_info_list *files,
int count, struct dentry *root,
struct drm_minor *minor)
+{
- return 0;
+}
+static inline int drm_debugfs_remove_files(const struct drm_info_list *files,
int count, struct drm_minor *minor)
+{
- return 0;
+} +#endif
+#endif /* _DRM_DEBUGFS_H_ */
2.11.0
This was missed in Tomeu's patch. Also remove the kerneldoc for the internal function, we don't document that in general.
While at it word-smith the docs slightly for more clarity.
Cc: Tomeu Vizoso tomeu.vizoso@collabora.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- Documentation/gpu/drm-uapi.rst | 3 +++ drivers/gpu/drm/drm_debugfs_crc.c | 17 ++++++----------- include/drm/drm_crtc.h | 5 ++++- 3 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 352652810dab..369e8ca12b8e 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -207,6 +207,9 @@ Display CRC Support .. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c :doc: CRC ABI
+.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c + :export: + VBlank event handling =====================
diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c index 96891c4a6e23..1722d8f21449 100644 --- a/drivers/gpu/drm/drm_debugfs_crc.c +++ b/drivers/gpu/drm/drm_debugfs_crc.c @@ -36,7 +36,7 @@ * DOC: CRC ABI * * DRM device drivers can provide to userspace CRC information of each frame as - * it reached a given hardware component (a "source"). + * it reached a given hardware component (a CRC sampling "source"). * * Userspace can control generation of CRCs in a given CRTC by writing to the * file dri/0/crtc-N/crc/control in debugfs, with N being the index of the CRTC. @@ -57,6 +57,11 @@ * rely on being able to generate matching CRC values for the frame contents that * it submits. In this general case, the maximum userspace can do is to compare * the reported CRCs of frames that should have the same contents. + * + * On the driver side the implementation effort is minimal, drivers only need to + * implement &drm_crtc_funcs.set_crc_source. The debugfs files are automatically + * set up if that vfunc is set. CRC samples need to be captured in the driver by + * calling drm_crtc_add_crc_entry(). */
static int crc_control_show(struct seq_file *m, void *data) @@ -280,16 +285,6 @@ static const struct file_operations drm_crtc_crc_data_fops = { .release = crtc_crc_release, };
-/** - * drm_debugfs_crtc_crc_add - Add files to debugfs for capture of frame CRCs - * @crtc: CRTC to whom the frames will belong - * - * Adds files to debugfs directory that allows userspace to control the - * generation of frame CRCs and to read them. - * - * Returns: - * Zero on success, error code on failure. - */ int drm_debugfs_crtc_crc_add(struct drm_crtc *crtc) { struct dentry *crc_ent, *ent; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 6ef59da3fd8e..24dcb121bad4 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -590,9 +590,12 @@ struct drm_crtc_funcs { * When CRC generation is enabled, the driver should call * drm_crtc_add_crc_entry() at each frame, providing any information * that characterizes the frame contents in the crcN arguments, as - * provided from the configured source. Drivers must accept a "auto" + * provided from the configured source. Drivers must accept an "auto" * source name that will select a default source for this CRTC. * + * Note that "auto" can depend upon the current modeset configuration, + * e.g. it could pick an encoder or output specific CRC sampling point. + * * This callback is optional if the driver does not support any CRC * generation functionality. *
Thanks for doing this.
Reviewed-by: Tomeu Vizoso tomeu.vizoso@collabora.com
On 22 March 2017 at 09:36, Daniel Vetter daniel.vetter@ffwll.ch wrote:
This was missed in Tomeu's patch. Also remove the kerneldoc for the internal function, we don't document that in general.
While at it word-smith the docs slightly for more clarity.
Cc: Tomeu Vizoso tomeu.vizoso@collabora.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com
Documentation/gpu/drm-uapi.rst | 3 +++ drivers/gpu/drm/drm_debugfs_crc.c | 17 ++++++----------- include/drm/drm_crtc.h | 5 ++++- 3 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 352652810dab..369e8ca12b8e 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -207,6 +207,9 @@ Display CRC Support .. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c :doc: CRC ABI
+.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c
- :export:
VBlank event handling
diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c index 96891c4a6e23..1722d8f21449 100644 --- a/drivers/gpu/drm/drm_debugfs_crc.c +++ b/drivers/gpu/drm/drm_debugfs_crc.c @@ -36,7 +36,7 @@
- DOC: CRC ABI
- DRM device drivers can provide to userspace CRC information of each frame as
- it reached a given hardware component (a "source").
- it reached a given hardware component (a CRC sampling "source").
- Userspace can control generation of CRCs in a given CRTC by writing to the
- file dri/0/crtc-N/crc/control in debugfs, with N being the index of the CRTC.
@@ -57,6 +57,11 @@
- rely on being able to generate matching CRC values for the frame contents that
- it submits. In this general case, the maximum userspace can do is to compare
- the reported CRCs of frames that should have the same contents.
- On the driver side the implementation effort is minimal, drivers only need to
- implement &drm_crtc_funcs.set_crc_source. The debugfs files are automatically
- set up if that vfunc is set. CRC samples need to be captured in the driver by
*/
- calling drm_crtc_add_crc_entry().
static int crc_control_show(struct seq_file *m, void *data) @@ -280,16 +285,6 @@ static const struct file_operations drm_crtc_crc_data_fops = { .release = crtc_crc_release, };
-/**
- drm_debugfs_crtc_crc_add - Add files to debugfs for capture of frame CRCs
- @crtc: CRTC to whom the frames will belong
- Adds files to debugfs directory that allows userspace to control the
- generation of frame CRCs and to read them.
- Returns:
- Zero on success, error code on failure.
- */
int drm_debugfs_crtc_crc_add(struct drm_crtc *crtc) { struct dentry *crc_ent, *ent; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 6ef59da3fd8e..24dcb121bad4 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -590,9 +590,12 @@ struct drm_crtc_funcs { * When CRC generation is enabled, the driver should call * drm_crtc_add_crc_entry() at each frame, providing any information * that characterizes the frame contents in the crcN arguments, as
* provided from the configured source. Drivers must accept a "auto"
* provided from the configured source. Drivers must accept an "auto" * source name that will select a default source for this CRTC. *
* Note that "auto" can depend upon the current modeset configuration,
* e.g. it could pick an encoder or output specific CRC sampling point.
* * This callback is optional if the driver does not support any CRC * generation functionality. *
-- 2.11.0
Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
I've decided to not document drm_debugfs_remove_files, it's on the way out.
The biggest part is a huge todor.rst entry with what all should be improved.
Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch --- Documentation/gpu/drm-uapi.rst | 9 ++++++++ Documentation/gpu/todo.rst | 26 +++++++++++++++++++++ drivers/gpu/drm/drm_debugfs.c | 51 ++++++------------------------------------ drivers/gpu/drm/drm_internal.h | 2 +- include/drm/drm_debugfs.h | 38 +++++++++++++++++++++++++------ 5 files changed, 74 insertions(+), 52 deletions(-)
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 369e8ca12b8e..76356c86e358 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -210,6 +210,15 @@ Display CRC Support .. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c :export:
+Debugfs Support +--------------- + +.. kernel-doc:: include/drm/drm_debugfs.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_debugfs.c + :export: + VBlank event handling =====================
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 64e9d16170ce..9ecd2ebb8dd8 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -272,6 +272,32 @@ This is a really varied tasks with lots of little bits and pieces:
Contact: Daniel Vetter
+Clean up the debugfs support +---------------------------- + +There's a bunch of issues with it: + +- The drm_info_list -> show function doesn't even bother to cast to the drm + structure for you. This is lazy. + +- We probably want to have some support for debugfs files on crtc/connectors and + maybe other kms objects directly in core. There's even drm_print support in + the funcs for these objects to dump kms state, so it's all there. And then the + ->show functions should obviously give you a pointer to the right object. + +- The drm_info_list stuff is centered on drm_minor instead of drm_device. For + anything we want to print drm_device (or maybe drm_file) is the right thing. + +- The drm_driver->debugfs_init hooks we have is just an artifact of the old + midlayered load sequence. DRM debugfs should work more like sysfs, where you + can create properties/files for an object anytime you want, and the core + takes care of publishing/unpuplishing all the files at register/unregister + time. Drivers shouldn't need to worry about these technicalities, and fixing + this (together with the drm_minor->drm_device move) would allow us to remove + debugfs_init. + +Contact: Daniel Vetter + Better Testing ==============
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 4b02f4230562..c1807d5754b2 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -1,10 +1,3 @@ -/** - * \file drm_debugfs.c - * debugfs support for DRM - * - * \author Ben Gamari bgamari@gmail.com - */ - /* * Created: Sun Dec 21 13:08:50 2008 by bgamari@gmail.com * @@ -75,16 +68,15 @@ static const struct file_operations drm_debugfs_fops = {
/** - * Initialize a given set of debugfs files for a device - * - * \param files The array of files to create - * \param count The number of files given - * \param root DRI debugfs dir entry. - * \param minor device minor number - * \return Zero on success, non-zero on failure + * drm_debugfs_create_files - Initialize a given set of debugfs files for DRM + * minor + * @files: The array of files to create + * @count: The number of files given + * @root: DRI debugfs dir entry. + * @minor: device minor number * * Create a given set of debugfs files represented by an array of - * &drm_info_list in the given root directory. These files will be removed + * &struct drm_info_list in the given root directory. These files will be removed * automatically on drm_debugfs_cleanup(). */ int drm_debugfs_create_files(const struct drm_info_list *files, int count, @@ -133,17 +125,6 @@ int drm_debugfs_create_files(const struct drm_info_list *files, int count, } EXPORT_SYMBOL(drm_debugfs_create_files);
-/** - * Initialize the DRI debugfs filesystem for a device - * - * \param dev DRM device - * \param minor device minor number - * \param root DRI debugfs dir entry. - * - * Create the DRI debugfs root entry "/sys/kernel/debug/dri", the device debugfs root entry - * "/sys/kernel/debug/dri/%minor%/", and each entry in debugfs_list as - * "/sys/kernel/debug/dri/%minor%/%name%". - */ int drm_debugfs_init(struct drm_minor *minor, int minor_id, struct dentry *root) { @@ -189,16 +170,6 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id, }
-/** - * Remove a list of debugfs files - * - * \param files The list of files - * \param count The number of files - * \param minor The minor of which we should remove the files - * \return always zero. - * - * Remove all debugfs entries created by debugfs_init(). - */ int drm_debugfs_remove_files(const struct drm_info_list *files, int count, struct drm_minor *minor) { @@ -235,14 +206,6 @@ static void drm_debugfs_remove_all_files(struct drm_minor *minor) mutex_unlock(&minor->debugfs_lock); }
-/** - * Cleanup the debugfs filesystem resources. - * - * \param minor device minor number. - * \return always zero. - * - * Remove all debugfs entries created by debugfs_init(). - */ int drm_debugfs_cleanup(struct drm_minor *minor) { if (!minor->debugfs_root) diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 92ff4b9393b1..3d8e8f878924 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -100,7 +100,7 @@ int drm_gem_open_ioctl(struct drm_device *dev, void *data, void drm_gem_open(struct drm_device *dev, struct drm_file *file_private); void drm_gem_release(struct drm_device *dev, struct drm_file *file_private);
-/* drm_debugfs.c */ +/* drm_debugfs.c drm_debugfs_crc.c */ #if defined(CONFIG_DEBUG_FS) int drm_debugfs_init(struct drm_minor *minor, int minor_id, struct dentry *root); diff --git a/include/drm/drm_debugfs.h b/include/drm/drm_debugfs.h index 17e47c073fa9..d45bc1879412 100644 --- a/include/drm/drm_debugfs.h +++ b/include/drm/drm_debugfs.h @@ -33,23 +33,47 @@ #define _DRM_DEBUGFS_H_
/** - * Info file list entry. This structure represents a debugfs or proc file to - * be created by the drm core + * struct drm_info_list - debugfs info list entry + * + * This structure represents a debugfs file to be created by the drm + * core. */ struct drm_info_list { - const char *name; /** file name */ - int (*show)(struct seq_file*, void*); /** show callback */ - u32 driver_features; /**< Required driver features for this entry */ + /** @name: file name */ + const char *name; + /** + * @show: + * + * Show callback. &seq_file->private will be set to the &struct + * drm_info_node corresponding to the instance of this info on a given + * &struct drm_minor. + */ + int (*show)(struct seq_file*, void*); + /** @driver_features: Required driver features for this entry */ + u32 driver_features; + /** @data: Driver-private data, should not be device-specific. */ void *data; };
/** - * debugfs node structure. This structure represents a debugfs file. + * struct drm_info_node - Per-minor debugfs node structure + * + * This structure represents a debugfs file, as an instantiation of a &struct + * drm_info_list on a &struct drm_minor. + * + * FIXME: + * + * No it doesn't make a hole lot of sense that we duplicate debugfs entries for + * both the render and the primary nodes, but that's how this has organically + * grown. It should probably be fixed, with a compatibility link, if needed. */ struct drm_info_node { - struct list_head list; + /** @minor: &struct drm_minor for this node. */ struct drm_minor *minor; + /** @info_ent: template for thise node. */ const struct drm_info_list *info_ent; + /* private: */ + struct list_head list; struct dentry *dent; };
Daniel Vetter daniel.vetter@ffwll.ch writes:
I've decided to not document drm_debugfs_remove_files, it's on the way out.
The biggest part is a huge todor.rst entry with what all should be improved.
todo.rst
Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch
Documentation/gpu/drm-uapi.rst | 9 ++++++++ Documentation/gpu/todo.rst | 26 +++++++++++++++++++++ drivers/gpu/drm/drm_debugfs.c | 51 ++++++------------------------------------ drivers/gpu/drm/drm_internal.h | 2 +- include/drm/drm_debugfs.h | 38 +++++++++++++++++++++++++------ 5 files changed, 74 insertions(+), 52 deletions(-)
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 369e8ca12b8e..76356c86e358 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -210,6 +210,15 @@ Display CRC Support .. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c :export:
+Debugfs Support +---------------
+.. kernel-doc:: include/drm/drm_debugfs.h
- :internal:
+.. kernel-doc:: drivers/gpu/drm/drm_debugfs.c
- :export:
VBlank event handling
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 64e9d16170ce..9ecd2ebb8dd8 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -272,6 +272,32 @@ This is a really varied tasks with lots of little bits and pieces:
Contact: Daniel Vetter
+Clean up the debugfs support +----------------------------
+There's a bunch of issues with it:
+- The drm_info_list -> show function doesn't even bother to cast to the drm
- structure for you. This is lazy.
+- We probably want to have some support for debugfs files on crtc/connectors and
- maybe other kms objects directly in core. There's even drm_print support in
- the funcs for these objects to dump kms state, so it's all there. And then the
- ->show functions should obviously give you a pointer to the right object.
should you use ->show() ? not sure. Either way, extra space on the previuous "->show" instance.
+- The drm_info_list stuff is centered on drm_minor instead of drm_device. For
- anything we want to print drm_device (or maybe drm_file) is the right thing.
+- The drm_driver->debugfs_init hooks we have is just an artifact of the old
- midlayered load sequence. DRM debugfs should work more like sysfs, where you
- can create properties/files for an object anytime you want, and the core
- takes care of publishing/unpuplishing all the files at register/unregister
- time. Drivers shouldn't need to worry about these technicalities, and fixing
- this (together with the drm_minor->drm_device move) would allow us to remove
- debugfs_init.
+Contact: Daniel Vetter
Better Testing
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 4b02f4230562..c1807d5754b2 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -1,10 +1,3 @@ -/**
- \file drm_debugfs.c
- debugfs support for DRM
- \author Ben Gamari bgamari@gmail.com
- */
/*
- Created: Sun Dec 21 13:08:50 2008 by bgamari@gmail.com
@@ -75,16 +68,15 @@ static const struct file_operations drm_debugfs_fops = {
/**
- Initialize a given set of debugfs files for a device
- \param files The array of files to create
- \param count The number of files given
- \param root DRI debugfs dir entry.
- \param minor device minor number
- \return Zero on success, non-zero on failure
- drm_debugfs_create_files - Initialize a given set of debugfs files for DRM
minor
- @files: The array of files to create
- @count: The number of files given
- @root: DRI debugfs dir entry.
- @minor: device minor number
- Create a given set of debugfs files represented by an array of
- &drm_info_list in the given root directory. These files will be removed
*/
- &struct drm_info_list in the given root directory. These files will be removed
- automatically on drm_debugfs_cleanup().
int drm_debugfs_create_files(const struct drm_info_list *files, int count, @@ -133,17 +125,6 @@ int drm_debugfs_create_files(const struct drm_info_list *files, int count, } EXPORT_SYMBOL(drm_debugfs_create_files);
-/**
- Initialize the DRI debugfs filesystem for a device
- \param dev DRM device
- \param minor device minor number
- \param root DRI debugfs dir entry.
- Create the DRI debugfs root entry "/sys/kernel/debug/dri", the device debugfs root entry
- "/sys/kernel/debug/dri/%minor%/", and each entry in debugfs_list as
- "/sys/kernel/debug/dri/%minor%/%name%".
- */
int drm_debugfs_init(struct drm_minor *minor, int minor_id, struct dentry *root) { @@ -189,16 +170,6 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id, }
-/**
- Remove a list of debugfs files
- \param files The list of files
- \param count The number of files
- \param minor The minor of which we should remove the files
- \return always zero.
- Remove all debugfs entries created by debugfs_init().
- */
int drm_debugfs_remove_files(const struct drm_info_list *files, int count, struct drm_minor *minor) { @@ -235,14 +206,6 @@ static void drm_debugfs_remove_all_files(struct drm_minor *minor) mutex_unlock(&minor->debugfs_lock); }
-/**
- Cleanup the debugfs filesystem resources.
- \param minor device minor number.
- \return always zero.
- Remove all debugfs entries created by debugfs_init().
- */
int drm_debugfs_cleanup(struct drm_minor *minor) { if (!minor->debugfs_root) diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 92ff4b9393b1..3d8e8f878924 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -100,7 +100,7 @@ int drm_gem_open_ioctl(struct drm_device *dev, void *data, void drm_gem_open(struct drm_device *dev, struct drm_file *file_private); void drm_gem_release(struct drm_device *dev, struct drm_file *file_private);
-/* drm_debugfs.c */ +/* drm_debugfs.c drm_debugfs_crc.c */ #if defined(CONFIG_DEBUG_FS) int drm_debugfs_init(struct drm_minor *minor, int minor_id, struct dentry *root); diff --git a/include/drm/drm_debugfs.h b/include/drm/drm_debugfs.h index 17e47c073fa9..d45bc1879412 100644 --- a/include/drm/drm_debugfs.h +++ b/include/drm/drm_debugfs.h @@ -33,23 +33,47 @@ #define _DRM_DEBUGFS_H_
/**
- Info file list entry. This structure represents a debugfs or proc file to
- be created by the drm core
- struct drm_info_list - debugfs info list entry
- This structure represents a debugfs file to be created by the drm
*/
- core.
struct drm_info_list {
- const char *name; /** file name */
- int (*show)(struct seq_file*, void*); /** show callback */
- u32 driver_features; /**< Required driver features for this entry */
- /** @name: file name */
- const char *name;
- /**
* @show:
*
* Show callback. &seq_file->private will be set to the &struct
* drm_info_node corresponding to the instance of this info on a given
* &struct drm_minor.
*/
- int (*show)(struct seq_file*, void*);
- /** @driver_features: Required driver features for this entry */
- u32 driver_features;
- /** @data: Driver-private data, should not be device-specific. */ void *data;
};
/**
- debugfs node structure. This structure represents a debugfs file.
- struct drm_info_node - Per-minor debugfs node structure
- This structure represents a debugfs file, as an instantiation of a &struct
- drm_info_list on a &struct drm_minor.
- FIXME:
- No it doesn't make a hole lot of sense that we duplicate debugfs entries for
- both the render and the primary nodes, but that's how this has organically
*/
- grown. It should probably be fixed, with a compatibility link, if needed.
struct drm_info_node {
- struct list_head list;
- /** @minor: &struct drm_minor for this node. */ struct drm_minor *minor;
- /** @info_ent: template for thise node. */
this node
With this nit-picks, feel free to add:
Reviewed-by: Gabriel Krisman Bertazi krisman@collabora.co.uk
const struct drm_info_list *info_ent;
- /* private: */
- struct list_head list; struct dentry *dent;
};
I've decided to not document drm_debugfs_remove_files, it's on the way out.
The biggest part is a huge todo.rst entry with what all should be improved.
v2: Nits from Gabriel.
Cc: Gabriel Krisman Bertazi krisman@collabora.co.uk Reviewed-by: Gabriel Krisman Bertazi krisman@collabora.co.uk Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch --- Documentation/gpu/drm-uapi.rst | 9 ++++++++ Documentation/gpu/todo.rst | 26 +++++++++++++++++++++ drivers/gpu/drm/drm_debugfs.c | 51 ++++++------------------------------------ drivers/gpu/drm/drm_internal.h | 2 +- include/drm/drm_debugfs.h | 38 +++++++++++++++++++++++++------ 5 files changed, 74 insertions(+), 52 deletions(-)
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 369e8ca12b8e..76356c86e358 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -210,6 +210,15 @@ Display CRC Support .. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c :export:
+Debugfs Support +--------------- + +.. kernel-doc:: include/drm/drm_debugfs.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_debugfs.c + :export: + VBlank event handling =====================
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 64e9d16170ce..0cdaddad2b9b 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -272,6 +272,32 @@ This is a really varied tasks with lots of little bits and pieces:
Contact: Daniel Vetter
+Clean up the debugfs support +---------------------------- + +There's a bunch of issues with it: + +- The drm_info_list ->show() function doesn't even bother to cast to the drm + structure for you. This is lazy. + +- We probably want to have some support for debugfs files on crtc/connectors and + maybe other kms objects directly in core. There's even drm_print support in + the funcs for these objects to dump kms state, so it's all there. And then the + ->show() functions should obviously give you a pointer to the right object. + +- The drm_info_list stuff is centered on drm_minor instead of drm_device. For + anything we want to print drm_device (or maybe drm_file) is the right thing. + +- The drm_driver->debugfs_init hooks we have is just an artifact of the old + midlayered load sequence. DRM debugfs should work more like sysfs, where you + can create properties/files for an object anytime you want, and the core + takes care of publishing/unpuplishing all the files at register/unregister + time. Drivers shouldn't need to worry about these technicalities, and fixing + this (together with the drm_minor->drm_device move) would allow us to remove + debugfs_init. + +Contact: Daniel Vetter + Better Testing ==============
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 4b02f4230562..c1807d5754b2 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -1,10 +1,3 @@ -/** - * \file drm_debugfs.c - * debugfs support for DRM - * - * \author Ben Gamari bgamari@gmail.com - */ - /* * Created: Sun Dec 21 13:08:50 2008 by bgamari@gmail.com * @@ -75,16 +68,15 @@ static const struct file_operations drm_debugfs_fops = {
/** - * Initialize a given set of debugfs files for a device - * - * \param files The array of files to create - * \param count The number of files given - * \param root DRI debugfs dir entry. - * \param minor device minor number - * \return Zero on success, non-zero on failure + * drm_debugfs_create_files - Initialize a given set of debugfs files for DRM + * minor + * @files: The array of files to create + * @count: The number of files given + * @root: DRI debugfs dir entry. + * @minor: device minor number * * Create a given set of debugfs files represented by an array of - * &drm_info_list in the given root directory. These files will be removed + * &struct drm_info_list in the given root directory. These files will be removed * automatically on drm_debugfs_cleanup(). */ int drm_debugfs_create_files(const struct drm_info_list *files, int count, @@ -133,17 +125,6 @@ int drm_debugfs_create_files(const struct drm_info_list *files, int count, } EXPORT_SYMBOL(drm_debugfs_create_files);
-/** - * Initialize the DRI debugfs filesystem for a device - * - * \param dev DRM device - * \param minor device minor number - * \param root DRI debugfs dir entry. - * - * Create the DRI debugfs root entry "/sys/kernel/debug/dri", the device debugfs root entry - * "/sys/kernel/debug/dri/%minor%/", and each entry in debugfs_list as - * "/sys/kernel/debug/dri/%minor%/%name%". - */ int drm_debugfs_init(struct drm_minor *minor, int minor_id, struct dentry *root) { @@ -189,16 +170,6 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id, }
-/** - * Remove a list of debugfs files - * - * \param files The list of files - * \param count The number of files - * \param minor The minor of which we should remove the files - * \return always zero. - * - * Remove all debugfs entries created by debugfs_init(). - */ int drm_debugfs_remove_files(const struct drm_info_list *files, int count, struct drm_minor *minor) { @@ -235,14 +206,6 @@ static void drm_debugfs_remove_all_files(struct drm_minor *minor) mutex_unlock(&minor->debugfs_lock); }
-/** - * Cleanup the debugfs filesystem resources. - * - * \param minor device minor number. - * \return always zero. - * - * Remove all debugfs entries created by debugfs_init(). - */ int drm_debugfs_cleanup(struct drm_minor *minor) { if (!minor->debugfs_root) diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 92ff4b9393b1..3d8e8f878924 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -100,7 +100,7 @@ int drm_gem_open_ioctl(struct drm_device *dev, void *data, void drm_gem_open(struct drm_device *dev, struct drm_file *file_private); void drm_gem_release(struct drm_device *dev, struct drm_file *file_private);
-/* drm_debugfs.c */ +/* drm_debugfs.c drm_debugfs_crc.c */ #if defined(CONFIG_DEBUG_FS) int drm_debugfs_init(struct drm_minor *minor, int minor_id, struct dentry *root); diff --git a/include/drm/drm_debugfs.h b/include/drm/drm_debugfs.h index 56924196d08d..ac0f75df1ac9 100644 --- a/include/drm/drm_debugfs.h +++ b/include/drm/drm_debugfs.h @@ -33,23 +33,47 @@ #define _DRM_DEBUGFS_H_
/** - * Info file list entry. This structure represents a debugfs or proc file to - * be created by the drm core + * struct drm_info_list - debugfs info list entry + * + * This structure represents a debugfs file to be created by the drm + * core. */ struct drm_info_list { - const char *name; /** file name */ - int (*show)(struct seq_file*, void*); /** show callback */ - u32 driver_features; /**< Required driver features for this entry */ + /** @name: file name */ + const char *name; + /** + * @show: + * + * Show callback. &seq_file->private will be set to the &struct + * drm_info_node corresponding to the instance of this info on a given + * &struct drm_minor. + */ + int (*show)(struct seq_file*, void*); + /** @driver_features: Required driver features for this entry */ + u32 driver_features; + /** @data: Driver-private data, should not be device-specific. */ void *data; };
/** - * debugfs node structure. This structure represents a debugfs file. + * struct drm_info_node - Per-minor debugfs node structure + * + * This structure represents a debugfs file, as an instantiation of a &struct + * drm_info_list on a &struct drm_minor. + * + * FIXME: + * + * No it doesn't make a hole lot of sense that we duplicate debugfs entries for + * both the render and the primary nodes, but that's how this has organically + * grown. It should probably be fixed, with a compatibility link, if needed. */ struct drm_info_node { - struct list_head list; + /** @minor: &struct drm_minor for this node. */ struct drm_minor *minor; + /** @info_ent: template for this node. */ const struct drm_info_list *info_ent; + /* private: */ + struct list_head list; struct dentry *dent; };
On Wed, Mar 22, 2017 at 09:54:01PM +0100, Daniel Vetter wrote:
I've decided to not document drm_debugfs_remove_files, it's on the way out.
The biggest part is a huge todo.rst entry with what all should be improved.
v2: Nits from Gabriel.
Cc: Gabriel Krisman Bertazi krisman@collabora.co.uk Reviewed-by: Gabriel Krisman Bertazi krisman@collabora.co.uk Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch
Merged up to this patch to drm-misc-next.
I will trade reviews for more reviews to help get the remaining in!
Thanks, Daniel
Documentation/gpu/drm-uapi.rst | 9 ++++++++ Documentation/gpu/todo.rst | 26 +++++++++++++++++++++ drivers/gpu/drm/drm_debugfs.c | 51 ++++++------------------------------------ drivers/gpu/drm/drm_internal.h | 2 +- include/drm/drm_debugfs.h | 38 +++++++++++++++++++++++++------ 5 files changed, 74 insertions(+), 52 deletions(-)
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 369e8ca12b8e..76356c86e358 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -210,6 +210,15 @@ Display CRC Support .. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c :export:
+Debugfs Support +---------------
+.. kernel-doc:: include/drm/drm_debugfs.h
- :internal:
+.. kernel-doc:: drivers/gpu/drm/drm_debugfs.c
- :export:
VBlank event handling
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 64e9d16170ce..0cdaddad2b9b 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -272,6 +272,32 @@ This is a really varied tasks with lots of little bits and pieces:
Contact: Daniel Vetter
+Clean up the debugfs support +----------------------------
+There's a bunch of issues with it:
+- The drm_info_list ->show() function doesn't even bother to cast to the drm
- structure for you. This is lazy.
+- We probably want to have some support for debugfs files on crtc/connectors and
- maybe other kms objects directly in core. There's even drm_print support in
- the funcs for these objects to dump kms state, so it's all there. And then the
- ->show() functions should obviously give you a pointer to the right object.
+- The drm_info_list stuff is centered on drm_minor instead of drm_device. For
- anything we want to print drm_device (or maybe drm_file) is the right thing.
+- The drm_driver->debugfs_init hooks we have is just an artifact of the old
- midlayered load sequence. DRM debugfs should work more like sysfs, where you
- can create properties/files for an object anytime you want, and the core
- takes care of publishing/unpuplishing all the files at register/unregister
- time. Drivers shouldn't need to worry about these technicalities, and fixing
- this (together with the drm_minor->drm_device move) would allow us to remove
- debugfs_init.
+Contact: Daniel Vetter
Better Testing
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 4b02f4230562..c1807d5754b2 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -1,10 +1,3 @@ -/**
- \file drm_debugfs.c
- debugfs support for DRM
- \author Ben Gamari bgamari@gmail.com
- */
/*
- Created: Sun Dec 21 13:08:50 2008 by bgamari@gmail.com
@@ -75,16 +68,15 @@ static const struct file_operations drm_debugfs_fops = {
/**
- Initialize a given set of debugfs files for a device
- \param files The array of files to create
- \param count The number of files given
- \param root DRI debugfs dir entry.
- \param minor device minor number
- \return Zero on success, non-zero on failure
- drm_debugfs_create_files - Initialize a given set of debugfs files for DRM
minor
- @files: The array of files to create
- @count: The number of files given
- @root: DRI debugfs dir entry.
- @minor: device minor number
- Create a given set of debugfs files represented by an array of
- &drm_info_list in the given root directory. These files will be removed
*/
- &struct drm_info_list in the given root directory. These files will be removed
- automatically on drm_debugfs_cleanup().
int drm_debugfs_create_files(const struct drm_info_list *files, int count, @@ -133,17 +125,6 @@ int drm_debugfs_create_files(const struct drm_info_list *files, int count, } EXPORT_SYMBOL(drm_debugfs_create_files);
-/**
- Initialize the DRI debugfs filesystem for a device
- \param dev DRM device
- \param minor device minor number
- \param root DRI debugfs dir entry.
- Create the DRI debugfs root entry "/sys/kernel/debug/dri", the device debugfs root entry
- "/sys/kernel/debug/dri/%minor%/", and each entry in debugfs_list as
- "/sys/kernel/debug/dri/%minor%/%name%".
- */
int drm_debugfs_init(struct drm_minor *minor, int minor_id, struct dentry *root) { @@ -189,16 +170,6 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id, }
-/**
- Remove a list of debugfs files
- \param files The list of files
- \param count The number of files
- \param minor The minor of which we should remove the files
- \return always zero.
- Remove all debugfs entries created by debugfs_init().
- */
int drm_debugfs_remove_files(const struct drm_info_list *files, int count, struct drm_minor *minor) { @@ -235,14 +206,6 @@ static void drm_debugfs_remove_all_files(struct drm_minor *minor) mutex_unlock(&minor->debugfs_lock); }
-/**
- Cleanup the debugfs filesystem resources.
- \param minor device minor number.
- \return always zero.
- Remove all debugfs entries created by debugfs_init().
- */
int drm_debugfs_cleanup(struct drm_minor *minor) { if (!minor->debugfs_root) diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 92ff4b9393b1..3d8e8f878924 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -100,7 +100,7 @@ int drm_gem_open_ioctl(struct drm_device *dev, void *data, void drm_gem_open(struct drm_device *dev, struct drm_file *file_private); void drm_gem_release(struct drm_device *dev, struct drm_file *file_private);
-/* drm_debugfs.c */ +/* drm_debugfs.c drm_debugfs_crc.c */ #if defined(CONFIG_DEBUG_FS) int drm_debugfs_init(struct drm_minor *minor, int minor_id, struct dentry *root); diff --git a/include/drm/drm_debugfs.h b/include/drm/drm_debugfs.h index 56924196d08d..ac0f75df1ac9 100644 --- a/include/drm/drm_debugfs.h +++ b/include/drm/drm_debugfs.h @@ -33,23 +33,47 @@ #define _DRM_DEBUGFS_H_
/**
- Info file list entry. This structure represents a debugfs or proc file to
- be created by the drm core
- struct drm_info_list - debugfs info list entry
- This structure represents a debugfs file to be created by the drm
*/
- core.
struct drm_info_list {
- const char *name; /** file name */
- int (*show)(struct seq_file*, void*); /** show callback */
- u32 driver_features; /**< Required driver features for this entry */
- /** @name: file name */
- const char *name;
- /**
* @show:
*
* Show callback. &seq_file->private will be set to the &struct
* drm_info_node corresponding to the instance of this info on a given
* &struct drm_minor.
*/
- int (*show)(struct seq_file*, void*);
- /** @driver_features: Required driver features for this entry */
- u32 driver_features;
- /** @data: Driver-private data, should not be device-specific. */ void *data;
};
/**
- debugfs node structure. This structure represents a debugfs file.
- struct drm_info_node - Per-minor debugfs node structure
- This structure represents a debugfs file, as an instantiation of a &struct
- drm_info_list on a &struct drm_minor.
- FIXME:
- No it doesn't make a hole lot of sense that we duplicate debugfs entries for
- both the render and the primary nodes, but that's how this has organically
*/
- grown. It should probably be fixed, with a compatibility link, if needed.
struct drm_info_node {
- struct list_head list;
- /** @minor: &struct drm_minor for this node. */ struct drm_minor *minor;
- /** @info_ent: template for this node. */ const struct drm_info_list *info_ent;
- /* private: */
- struct list_head list; struct dentry *dent;
};
-- 2.11.0
Just drive-by, but we have gsoc running so better to update it now.
Great news is that two entries can be removed because essentially all done.
Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch --- Documentation/gpu/todo.rst | 51 ++++------------------------------------------ 1 file changed, 4 insertions(+), 47 deletions(-)
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 9ecd2ebb8dd8..7dc6de07a3bc 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -16,7 +16,7 @@ De-midlayer drivers With the recent ``drm_bus`` cleanup patches for 3.17 it is no longer required to have a ``drm_bus`` structure set up. Drivers can directly set up the ``drm_device`` structure instead of relying on bus methods in ``drm_usb.c`` -and ``drm_platform.c``. The goal is to get rid of the driver's ``->load`` / +and ``drm_pci.c``. The goal is to get rid of the driver's ``->load`` / ``->unload`` callbacks and open-code the load/unload sequence properly, using the new two-stage ``drm_device`` setup/teardown.
@@ -151,7 +151,7 @@ fine-grained per-buffer object and per-context lockings scheme. Currently the following drivers still use ``struct_mutex``: ``msm``, ``omapdrm`` and ``udl``.
-Contact: Daniel Vetter +Contact: Daniel Vetter, respective driver maintainers
Switch to drm_connector_list_iter for any connector_list walking ---------------------------------------------------------------- @@ -193,6 +193,8 @@ plan is to switch to per-file driver API headers, which will also structure the kerneldoc better. This should also allow more fine-grained ``#include`` directives.
+In the end no .c file should need to include ``drmP.h`` anymore. + Contact: Daniel Vetter
Add missing kerneldoc for exported functions @@ -208,31 +210,6 @@ See https://dri.freedesktop.org/docs/drm/ for what's there already.
Contact: Daniel Vetter
-Hide legacy cruft better ------------------------- - -Way back DRM supported only drivers which shadow-attached to PCI devices with -userspace or fbdev drivers setting up outputs. Modern DRM drivers take charge -of the entire device, you can spot them with the DRIVER_MODESET flag. - -Unfortunately there's still large piles of legacy code around which needs to -be hidden so that driver writers don't accidentally end up using it. And to -prevent security issues in those legacy IOCTLs from being exploited on modern -drivers. This has multiple possible subtasks: - -* Make sure legacy IOCTLs can't be used on modern drivers. -* Extract support code for legacy features into a ``drm-legacy.ko`` kernel - module and compile it only when one of the legacy drivers is enabled. -* Extract legacy functions into their own headers and remove it that from the - monolithic ``drmP.h`` header. -* Remove any lingering cruft from the OS abstraction layer from modern - drivers. - -This is mostly done, the only thing left is to split up ``drm_irq.c`` into -legacy cruft and the parts needed by modern KMS drivers. - -Contact: Daniel Vetter - Make panic handling work ------------------------
@@ -338,23 +315,3 @@ Driver Specific
Outside DRM =========== - -Better kerneldoc ----------------- - -This is pretty much done, but there's some advanced topics: - -Come up with a way to hyperlink to struct members. Currently you can hyperlink -to the struct using ``#struct_name``, but not to a member within. Would need -buy-in from kerneldoc maintainers, and the big question is how to make it work -without totally unsightly -``drm_foo_bar_really_long_structure->even_longer_memeber`` all over the text -which breaks text flow. - -Figure out how to integrate the asciidoc support for ascii-diagrams. We have a -few of those (e.g. to describe mode timings), and asciidoc supports converting -some ascii-art dialect into pngs. Would be really pretty to make that work. - -Contact: Daniel Vetter, Jani Nikula - -Jani is working on this already, hopefully lands in 4.8.
Daniel Vetter daniel.vetter@ffwll.ch writes:
Just drive-by, but we have gsoc running so better to update it now.
Great news is that two entries can be removed because essentially all done.
Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch
Documentation/gpu/todo.rst | 51 ++++------------------------------------------ 1 file changed, 4 insertions(+), 47 deletions(-)
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 9ecd2ebb8dd8..7dc6de07a3bc 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -16,7 +16,7 @@ De-midlayer drivers With the recent ``drm_bus`` cleanup patches for 3.17 it is no longer required to have a ``drm_bus`` structure set up. Drivers can directly set up the ``drm_device`` structure instead of relying on bus methods in ``drm_usb.c`` -and ``drm_platform.c``. The goal is to get rid of the driver's ``->load`` / +and ``drm_pci.c``. The goal is to get rid of the driver's ``->load`` / ``->unload`` callbacks and open-code the load/unload sequence properly, using the new two-stage ``drm_device`` setup/teardown.
@@ -151,7 +151,7 @@ fine-grained per-buffer object and per-context lockings scheme. Currently the following drivers still use ``struct_mutex``: ``msm``, ``omapdrm`` and ``udl``.
-Contact: Daniel Vetter +Contact: Daniel Vetter, respective driver maintainers
Switch to drm_connector_list_iter for any connector_list walking
@@ -193,6 +193,8 @@ plan is to switch to per-file driver API headers, which will also structure the kerneldoc better. This should also allow more fine-grained ``#include`` directives.
+In the end no .c file should need to include ``drmP.h`` anymore.
Contact: Daniel Vetter
Add missing kerneldoc for exported functions @@ -208,31 +210,6 @@ See https://dri.freedesktop.org/docs/drm/ for what's there already.
Contact: Daniel Vetter
-Hide legacy cruft better
-Way back DRM supported only drivers which shadow-attached to PCI devices with -userspace or fbdev drivers setting up outputs. Modern DRM drivers take charge -of the entire device, you can spot them with the DRIVER_MODESET flag.
-Unfortunately there's still large piles of legacy code around which needs to -be hidden so that driver writers don't accidentally end up using it. And to -prevent security issues in those legacy IOCTLs from being exploited on modern -drivers. This has multiple possible subtasks:
-* Make sure legacy IOCTLs can't be used on modern drivers. -* Extract support code for legacy features into a ``drm-legacy.ko`` kernel
- module and compile it only when one of the legacy drivers is enabled.
I've been interested in taking up the work to split drm-legacy.ko from drm.ko. The plan is to make it an optional module that legacy drivers depend on, in a way that you don't need to recompile drm.ko to use it.
I think the issue with the current CONFIG_DRM_VM, for instance, which hid some of the code for legacy drivers is the downside of requiring recompilation of drm.ko before using a legacy driver.
Anyway, if you agree with this change, can you keep this entry until that is done?
On Wed, Mar 22, 2017 at 03:31:00PM -0300, Gabriel Krisman Bertazi wrote:
Daniel Vetter daniel.vetter@ffwll.ch writes:
Just drive-by, but we have gsoc running so better to update it now.
Great news is that two entries can be removed because essentially all done.
Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch
Documentation/gpu/todo.rst | 51 ++++------------------------------------------ 1 file changed, 4 insertions(+), 47 deletions(-)
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 9ecd2ebb8dd8..7dc6de07a3bc 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -16,7 +16,7 @@ De-midlayer drivers With the recent ``drm_bus`` cleanup patches for 3.17 it is no longer required to have a ``drm_bus`` structure set up. Drivers can directly set up the ``drm_device`` structure instead of relying on bus methods in ``drm_usb.c`` -and ``drm_platform.c``. The goal is to get rid of the driver's ``->load`` / +and ``drm_pci.c``. The goal is to get rid of the driver's ``->load`` / ``->unload`` callbacks and open-code the load/unload sequence properly, using the new two-stage ``drm_device`` setup/teardown.
@@ -151,7 +151,7 @@ fine-grained per-buffer object and per-context lockings scheme. Currently the following drivers still use ``struct_mutex``: ``msm``, ``omapdrm`` and ``udl``.
-Contact: Daniel Vetter +Contact: Daniel Vetter, respective driver maintainers
Switch to drm_connector_list_iter for any connector_list walking
@@ -193,6 +193,8 @@ plan is to switch to per-file driver API headers, which will also structure the kerneldoc better. This should also allow more fine-grained ``#include`` directives.
+In the end no .c file should need to include ``drmP.h`` anymore.
Contact: Daniel Vetter
Add missing kerneldoc for exported functions @@ -208,31 +210,6 @@ See https://dri.freedesktop.org/docs/drm/ for what's there already.
Contact: Daniel Vetter
-Hide legacy cruft better
-Way back DRM supported only drivers which shadow-attached to PCI devices with -userspace or fbdev drivers setting up outputs. Modern DRM drivers take charge -of the entire device, you can spot them with the DRIVER_MODESET flag.
-Unfortunately there's still large piles of legacy code around which needs to -be hidden so that driver writers don't accidentally end up using it. And to -prevent security issues in those legacy IOCTLs from being exploited on modern -drivers. This has multiple possible subtasks:
-* Make sure legacy IOCTLs can't be used on modern drivers. -* Extract support code for legacy features into a ``drm-legacy.ko`` kernel
- module and compile it only when one of the legacy drivers is enabled.
I've been interested in taking up the work to split drm-legacy.ko from drm.ko. The plan is to make it an optional module that legacy drivers depend on, in a way that you don't need to recompile drm.ko to use it.
I think the issue with the current CONFIG_DRM_VM, for instance, which hid some of the code for legacy drivers is the downside of requiring recompilation of drm.ko before using a legacy driver.
Anyway, if you agree with this change, can you keep this entry until that is done?
Yeah if you're working on this already I can keep it. But you could keep working on this also even if there's no todo entry, we're not going to reject good ideas :-)
I'll resend with only the first sub-task removed, since that is done. -Daniel
Just drive-by, but we have gsoc running so better to update it now.
Great news is that two entries can be removed because essentially all done.
v2: Keep a bunch of the todos, Gabriel is working on them.
Cc: Gabriel Krisman Bertazi krisman@collabora.co.uk Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch --- Documentation/gpu/todo.rst | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-)
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 0cdaddad2b9b..8f6943ccd834 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -16,7 +16,7 @@ De-midlayer drivers With the recent ``drm_bus`` cleanup patches for 3.17 it is no longer required to have a ``drm_bus`` structure set up. Drivers can directly set up the ``drm_device`` structure instead of relying on bus methods in ``drm_usb.c`` -and ``drm_platform.c``. The goal is to get rid of the driver's ``->load`` / +and ``drm_pci.c``. The goal is to get rid of the driver's ``->load`` / ``->unload`` callbacks and open-code the load/unload sequence properly, using the new two-stage ``drm_device`` setup/teardown.
@@ -151,7 +151,7 @@ fine-grained per-buffer object and per-context lockings scheme. Currently the following drivers still use ``struct_mutex``: ``msm``, ``omapdrm`` and ``udl``.
-Contact: Daniel Vetter +Contact: Daniel Vetter, respective driver maintainers
Switch to drm_connector_list_iter for any connector_list walking ---------------------------------------------------------------- @@ -193,6 +193,8 @@ plan is to switch to per-file driver API headers, which will also structure the kerneldoc better. This should also allow more fine-grained ``#include`` directives.
+In the end no .c file should need to include ``drmP.h`` anymore. + Contact: Daniel Vetter
Add missing kerneldoc for exported functions @@ -220,13 +222,8 @@ be hidden so that driver writers don't accidentally end up using it. And to prevent security issues in those legacy IOCTLs from being exploited on modern drivers. This has multiple possible subtasks:
-* Make sure legacy IOCTLs can't be used on modern drivers. * Extract support code for legacy features into a ``drm-legacy.ko`` kernel module and compile it only when one of the legacy drivers is enabled. -* Extract legacy functions into their own headers and remove it that from the - monolithic ``drmP.h`` header. -* Remove any lingering cruft from the OS abstraction layer from modern - drivers.
This is mostly done, the only thing left is to split up ``drm_irq.c`` into legacy cruft and the parts needed by modern KMS drivers. @@ -338,23 +335,3 @@ Driver Specific
Outside DRM =========== - -Better kerneldoc ----------------- - -This is pretty much done, but there's some advanced topics: - -Come up with a way to hyperlink to struct members. Currently you can hyperlink -to the struct using ``#struct_name``, but not to a member within. Would need -buy-in from kerneldoc maintainers, and the big question is how to make it work -without totally unsightly -``drm_foo_bar_really_long_structure->even_longer_memeber`` all over the text -which breaks text flow. - -Figure out how to integrate the asciidoc support for ascii-diagrams. We have a -few of those (e.g. to describe mode timings), and asciidoc supports converting -some ascii-art dialect into pngs. Would be really pretty to make that work. - -Contact: Daniel Vetter, Jani Nikula - -Jani is working on this already, hopefully lands in 4.8.
- remove docs for internal func, doesn't add value - add short overview snippet instead explaining that drivers don't have to bother themselves with reg/unreg concerns - drop the ttm comment about drmP.h, drmP.h is disappearing ...
Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch --- Documentation/gpu/drm-uapi.rst | 10 ++++++ drivers/gpu/drm/drm_sysfs.c | 70 ++++++++++++++++-------------------------- include/drm/drmP.h | 5 +-- include/drm/drm_sysfs.h | 8 ++--- 4 files changed, 42 insertions(+), 51 deletions(-)
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 76356c86e358..8b0f0e403f0c 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -219,6 +219,16 @@ Debugfs Support .. kernel-doc:: drivers/gpu/drm/drm_debugfs.c :export:
+Sysfs Support +============= + +.. kernel-doc:: drivers/gpu/drm/drm_sysfs.c + :doc: overview + +.. kernel-doc:: drivers/gpu/drm/drm_sysfs.c + :export: + + VBlank event handling =====================
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 513288b5c2f6..1c5b5ce1fd7f 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -25,6 +25,20 @@ #define to_drm_minor(d) dev_get_drvdata(d) #define to_drm_connector(d) dev_get_drvdata(d)
+/** + * DOC: overview + * + * DRM provides very little additional support to drivers for sysfs + * interactions, beyond just all the standard stuff. Drivers who want to expose + * additional sysfs properties and property groups can attach them at either + * &drm_device.dev or &drm_connector.kdev. + * + * Registration is automatically handled when calling drm_dev_register(), or + * drm_connector_register() in case of hot-plugged connectors. Unregistration is + * also automatically handled by drm_dev_unregister() and + * drm_connector_unregister(). + */ + static struct device_type drm_sysfs_device_minor = { .name = "drm_minor" }; @@ -250,15 +264,6 @@ static const struct attribute_group *connector_dev_groups[] = { NULL };
-/** - * drm_sysfs_connector_add - add a connector to sysfs - * @connector: connector to add - * - * Create a connector device in sysfs, along with its associated connector - * properties (so far, connection status, dpms, mode list and edid) and - * generate a hotplug event so userspace knows there's a new connector - * available. - */ int drm_sysfs_connector_add(struct drm_connector *connector) { struct drm_device *dev = connector->dev; @@ -285,19 +290,6 @@ int drm_sysfs_connector_add(struct drm_connector *connector) return 0; }
-/** - * drm_sysfs_connector_remove - remove an connector device from sysfs - * @connector: connector to remove - * - * Remove @connector and its associated attributes from sysfs. Note that - * the device model core will take care of sending the "remove" uevent - * at this time, so we don't need to do it. - * - * Note: - * This routine should only be called if the connector was previously - * successfully registered. If @connector hasn't been registered yet, - * you'll likely see a panic somewhere deep in sysfs code when called. - */ void drm_sysfs_connector_remove(struct drm_connector *connector) { if (!connector->kdev) @@ -333,20 +325,6 @@ static void drm_sysfs_release(struct device *dev) kfree(dev); }
-/** - * drm_sysfs_minor_alloc() - Allocate sysfs device for given minor - * @minor: minor to allocate sysfs device for - * - * This allocates a new sysfs device for @minor and returns it. The device is - * not registered nor linked. The caller has to use device_add() and - * device_del() to register and unregister it. - * - * Note that dev_get_drvdata() on the new device will return the minor. - * However, the device does not hold a ref-count to the minor nor to the - * underlying drm_device. This is unproblematic as long as you access the - * private data only in sysfs callbacks. device_del() disables those - * synchronously, so they cannot be called after you cleanup a minor. - */ struct device *drm_sysfs_minor_alloc(struct drm_minor *minor) { const char *minor_str; @@ -384,15 +362,13 @@ struct device *drm_sysfs_minor_alloc(struct drm_minor *minor) }
/** - * drm_class_device_register - Register a struct device in the drm class. + * drm_class_device_register - register new device with the DRM sysfs class + * @dev: device to register * - * @dev: pointer to struct device to register. - * - * @dev should have all relevant members pre-filled with the exception - * of the class member. In particular, the device_type member must - * be set. + * Registers a new &struct device within the DRM sysfs class. Essentially only + * used by ttm to have a place for its global settings. Drivers should never use + * this. */ - int drm_class_device_register(struct device *dev) { if (!drm_class || IS_ERR(drm_class)) @@ -403,6 +379,14 @@ int drm_class_device_register(struct device *dev) } EXPORT_SYMBOL_GPL(drm_class_device_register);
+/** + * drm_class_device_unregister - unregister device with the DRM sysfs class + * @dev: device to unregister + * + * Unregisters a &struct device from the DRM sysfs class. Essentially only used + * by ttm to have a place for its global settings. Drivers should never use + * this. + */ void drm_class_device_unregister(struct device *dev) { return device_unregister(dev); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 60f3255c43a8..fc2a0744413d 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -79,6 +79,7 @@ #include <drm/drm_pci.h> #include <drm/drm_file.h> #include <drm/drm_debugfs.h> +#include <drm/drm_sysfs.h>
struct module;
@@ -572,10 +573,6 @@ int drm_invalid_op(struct drm_device *dev, void *data, * DMA quiscent + idle. DMA quiescent usually requires the hardware lock. */
- /* sysfs support (drm_sysfs.c) */ -extern void drm_sysfs_hotplug_event(struct drm_device *dev); - - /*@}*/
/* returns true if currently okay to sleep */ diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h index 23418c1f10d1..70c9a1074aca 100644 --- a/include/drm/drm_sysfs.h +++ b/include/drm/drm_sysfs.h @@ -1,12 +1,12 @@ #ifndef _DRM_SYSFS_H_ #define _DRM_SYSFS_H_
-/** - * This minimalistic include file is intended for users (read TTM) that - * don't want to include the full drmP.h file. - */ +struct drm_device; +struct device;
int drm_class_device_register(struct device *dev); void drm_class_device_unregister(struct device *dev);
+void drm_sysfs_hotplug_event(struct drm_device *dev); + #endif
To match the drm_ioctl.c we already have.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/drm_ioctl.c | 1 + include/drm/drmP.h | 61 +------------------------- include/drm/drm_ioctl.h | 102 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 60 deletions(-) create mode 100644 include/drm/drm_ioctl.h
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 601bb0ded9d2..7f4f4f48e390 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -28,6 +28,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */
+#include <drm/drm_ioctl.h> #include <drm/drmP.h> #include <drm/drm_auth.h> #include "drm_legacy.h" diff --git a/include/drm/drmP.h b/include/drm/drmP.h index fc2a0744413d..248d2408e56b 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -80,6 +80,7 @@ #include <drm/drm_file.h> #include <drm/drm_debugfs.h> #include <drm/drm_sysfs.h> +#include <drm/drm_ioctl.h>
struct module;
@@ -318,49 +319,6 @@ struct pci_controller;
#define DRM_IF_VERSION(maj, min) (maj << 16 | min)
-/** - * Ioctl function type. - * - * \param inode device inode. - * \param file_priv DRM file private pointer. - * \param cmd command. - * \param arg argument. - */ -typedef int drm_ioctl_t(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, - unsigned long arg); - -#define DRM_IOCTL_NR(n) _IOC_NR(n) -#define DRM_MAJOR 226 - -#define DRM_AUTH 0x1 -#define DRM_MASTER 0x2 -#define DRM_ROOT_ONLY 0x4 -#define DRM_CONTROL_ALLOW 0x8 -#define DRM_UNLOCKED 0x10 -#define DRM_RENDER_ALLOW 0x20 - -struct drm_ioctl_desc { - unsigned int cmd; - int flags; - drm_ioctl_t *func; - const char *name; -}; - -/** - * Creates a driver or general drm_ioctl_desc array entry for the given - * ioctl, for use by drm_ioctl(). - */ - -#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \ - [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \ - .cmd = DRM_IOCTL_##ioctl, \ - .func = _func, \ - .flags = _flags, \ - .name = #ioctl \ - }
/* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 @@ -550,23 +508,6 @@ static inline int drm_device_is_unplugged(struct drm_device *dev) /*@{*/
/* Driver support (drm_drv.h) */ -extern int drm_ioctl_permit(u32 flags, struct drm_file *file_priv); -extern long drm_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg); -#ifdef CONFIG_COMPAT -extern long drm_compat_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg); -#else -/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */ -#define drm_compat_ioctl NULL -#endif -extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags); - -/* Misc. IOCTL support (drm_ioctl.c) */ -int drm_noop(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_invalid_op(struct drm_device *dev, void *data, - struct drm_file *file_priv);
/* * These are exported to drivers so that they can implement fencing using diff --git a/include/drm/drm_ioctl.h b/include/drm/drm_ioctl.h new file mode 100644 index 000000000000..3c3677b5bdb2 --- /dev/null +++ b/include/drm/drm_ioctl.h @@ -0,0 +1,102 @@ +/* + * Internal Header for the Direct Rendering Manager + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * Copyright (c) 2009-2010, Code Aurora Forum. + * All rights reserved. + * + * Author: Rickard E. (Rik) Faith faith@valinux.com + * Author: Gareth Hughes gareth@valinux.com + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DRM_IOCTL_H_ +#define _DRM_IOCTL_H_ + +#include <linux/types.h> + +#include <asm/ioctl.h> + +struct drm_device; +struct drm_file; +struct file; + +/** + * Ioctl function type. + * + * \param inode device inode. + * \param file_priv DRM file private pointer. + * \param cmd command. + * \param arg argument. + */ +typedef int drm_ioctl_t(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, + unsigned long arg); + +#define DRM_IOCTL_NR(n) _IOC_NR(n) +#define DRM_MAJOR 226 + +#define DRM_AUTH 0x1 +#define DRM_MASTER 0x2 +#define DRM_ROOT_ONLY 0x4 +#define DRM_CONTROL_ALLOW 0x8 +#define DRM_UNLOCKED 0x10 +#define DRM_RENDER_ALLOW 0x20 + +struct drm_ioctl_desc { + unsigned int cmd; + int flags; + drm_ioctl_t *func; + const char *name; +}; + +/** + * Creates a driver or general drm_ioctl_desc array entry for the given + * ioctl, for use by drm_ioctl(). + */ + +#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \ + [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \ + .cmd = DRM_IOCTL_##ioctl, \ + .func = _func, \ + .flags = _flags, \ + .name = #ioctl \ + } + +int drm_ioctl_permit(u32 flags, struct drm_file *file_priv); +long drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_COMPAT +long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#else +/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */ +#define drm_compat_ioctl NULL +#endif +bool drm_ioctl_flags(unsigned int nr, unsigned int *flags); + +int drm_noop(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int drm_invalid_op(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +#endif /* _DRM_IOCTL_H_ */
On Wed, Mar 22, 2017 at 09:36:08AM +0100, Daniel Vetter wrote:
To match the drm_ioctl.c we already have.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/drm_ioctl.c | 1 + include/drm/drmP.h | 61 +------------------------- include/drm/drm_ioctl.h | 102 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 60 deletions(-) create mode 100644 include/drm/drm_ioctl.h
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 601bb0ded9d2..7f4f4f48e390 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -28,6 +28,7 @@
- OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <drm/drm_ioctl.h> #include <drm/drmP.h> #include <drm/drm_auth.h> #include "drm_legacy.h" diff --git a/include/drm/drmP.h b/include/drm/drmP.h index fc2a0744413d..248d2408e56b 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -80,6 +80,7 @@ #include <drm/drm_file.h> #include <drm/drm_debugfs.h> #include <drm/drm_sysfs.h> +#include <drm/drm_ioctl.h>
Same question as for the debugfs thing. Why do we need this?
struct module;
@@ -318,49 +319,6 @@ struct pci_controller;
#define DRM_IF_VERSION(maj, min) (maj << 16 | min)
-/**
- Ioctl function type.
- \param inode device inode.
- \param file_priv DRM file private pointer.
- \param cmd command.
- \param arg argument.
- */
-typedef int drm_ioctl_t(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
unsigned long arg);
-#define DRM_IOCTL_NR(n) _IOC_NR(n) -#define DRM_MAJOR 226
-#define DRM_AUTH 0x1 -#define DRM_MASTER 0x2 -#define DRM_ROOT_ONLY 0x4 -#define DRM_CONTROL_ALLOW 0x8 -#define DRM_UNLOCKED 0x10 -#define DRM_RENDER_ALLOW 0x20
-struct drm_ioctl_desc {
- unsigned int cmd;
- int flags;
- drm_ioctl_t *func;
- const char *name;
-};
-/**
- Creates a driver or general drm_ioctl_desc array entry for the given
- ioctl, for use by drm_ioctl().
- */
-#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \
- [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \
.cmd = DRM_IOCTL_##ioctl, \
.func = _func, \
.flags = _flags, \
.name = #ioctl \
}
/* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 @@ -550,23 +508,6 @@ static inline int drm_device_is_unplugged(struct drm_device *dev) /*@{*/
/* Driver support (drm_drv.h) */
-extern int drm_ioctl_permit(u32 flags, struct drm_file *file_priv); -extern long drm_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
-#ifdef CONFIG_COMPAT -extern long drm_compat_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
-#else -/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */ -#define drm_compat_ioctl NULL -#endif -extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
-/* Misc. IOCTL support (drm_ioctl.c) */ -int drm_noop(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-int drm_invalid_op(struct drm_device *dev, void *data,
struct drm_file *file_priv);
/*
- These are exported to drivers so that they can implement fencing using
diff --git a/include/drm/drm_ioctl.h b/include/drm/drm_ioctl.h new file mode 100644 index 000000000000..3c3677b5bdb2 --- /dev/null +++ b/include/drm/drm_ioctl.h @@ -0,0 +1,102 @@ +/*
- Internal Header for the Direct Rendering Manager
- Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- Copyright (c) 2009-2010, Code Aurora Forum.
- All rights reserved.
- Author: Rickard E. (Rik) Faith faith@valinux.com
- Author: Gareth Hughes gareth@valinux.com
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the "Software"),
- to deal in the Software without restriction, including without limitation
- the rights to use, copy, modify, merge, publish, distribute, sublicense,
- and/or sell copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice (including the next
- paragraph) shall be included in all copies or substantial portions of the
- Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- */
+#ifndef _DRM_IOCTL_H_ +#define _DRM_IOCTL_H_
+#include <linux/types.h>
+#include <asm/ioctl.h>
+struct drm_device; +struct drm_file; +struct file;
+/**
- Ioctl function type.
- \param inode device inode.
- \param file_priv DRM file private pointer.
- \param cmd command.
- \param arg argument.
- */
+typedef int drm_ioctl_t(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
unsigned long arg);
+#define DRM_IOCTL_NR(n) _IOC_NR(n)
I wonder what's the point of this wrapper. Maybe leftovers from the out-of-tree days? Maybe nuke it while you're touching this stuff?
+#define DRM_MAJOR 226
+#define DRM_AUTH 0x1 +#define DRM_MASTER 0x2 +#define DRM_ROOT_ONLY 0x4 +#define DRM_CONTROL_ALLOW 0x8 +#define DRM_UNLOCKED 0x10 +#define DRM_RENDER_ALLOW 0x20
+struct drm_ioctl_desc {
- unsigned int cmd;
- int flags;
- drm_ioctl_t *func;
- const char *name;
+};
+/**
s/**/*/ ?
- Creates a driver or general drm_ioctl_desc array entry for the given
- ioctl, for use by drm_ioctl().
- */
+#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \
- [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \
.cmd = DRM_IOCTL_##ioctl, \
.func = _func, \
.flags = _flags, \
.name = #ioctl \
}
^
Spurious space
Otherwise looks sane so Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com
+int drm_ioctl_permit(u32 flags, struct drm_file *file_priv); +long drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_COMPAT +long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#else +/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */ +#define drm_compat_ioctl NULL +#endif +bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
+int drm_noop(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int drm_invalid_op(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+#endif /* _DRM_IOCTL_H_ */
2.11.0
Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
On Wed, Mar 22, 2017 at 03:47:31PM +0200, Ville Syrjälä wrote:
On Wed, Mar 22, 2017 at 09:36:08AM +0100, Daniel Vetter wrote:
To match the drm_ioctl.c we already have.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/drm_ioctl.c | 1 + include/drm/drmP.h | 61 +------------------------- include/drm/drm_ioctl.h | 102 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 60 deletions(-) create mode 100644 include/drm/drm_ioctl.h
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 601bb0ded9d2..7f4f4f48e390 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -28,6 +28,7 @@
- OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <drm/drm_ioctl.h> #include <drm/drmP.h> #include <drm/drm_auth.h> #include "drm_legacy.h" diff --git a/include/drm/drmP.h b/include/drm/drmP.h index fc2a0744413d..248d2408e56b 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -80,6 +80,7 @@ #include <drm/drm_file.h> #include <drm/drm_debugfs.h> #include <drm/drm_sysfs.h> +#include <drm/drm_ioctl.h>
Same question as for the debugfs thing. Why do we need this?
Try fixing up the drmP.h include hell, and you know that it'd take a few hundred patches. And right now it's impossible, because the most central structure (struct drm_device) is in here, so defacto we still have a monolithic header which needs everything.
First we need to split it completely, then all places that include drmP.h need to switch to individual headers (each time fixing up a pile of fallout), and then eventually (after fixing the few hundred places or so) we can remove all these include lines here (or well, get rid of drmP.h entirely). But not before. I tried. -Daniel
struct module;
@@ -318,49 +319,6 @@ struct pci_controller;
#define DRM_IF_VERSION(maj, min) (maj << 16 | min)
-/**
- Ioctl function type.
- \param inode device inode.
- \param file_priv DRM file private pointer.
- \param cmd command.
- \param arg argument.
- */
-typedef int drm_ioctl_t(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
unsigned long arg);
-#define DRM_IOCTL_NR(n) _IOC_NR(n) -#define DRM_MAJOR 226
-#define DRM_AUTH 0x1 -#define DRM_MASTER 0x2 -#define DRM_ROOT_ONLY 0x4 -#define DRM_CONTROL_ALLOW 0x8 -#define DRM_UNLOCKED 0x10 -#define DRM_RENDER_ALLOW 0x20
-struct drm_ioctl_desc {
- unsigned int cmd;
- int flags;
- drm_ioctl_t *func;
- const char *name;
-};
-/**
- Creates a driver or general drm_ioctl_desc array entry for the given
- ioctl, for use by drm_ioctl().
- */
-#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \
- [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \
.cmd = DRM_IOCTL_##ioctl, \
.func = _func, \
.flags = _flags, \
.name = #ioctl \
}
/* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 @@ -550,23 +508,6 @@ static inline int drm_device_is_unplugged(struct drm_device *dev) /*@{*/
/* Driver support (drm_drv.h) */
-extern int drm_ioctl_permit(u32 flags, struct drm_file *file_priv); -extern long drm_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
-#ifdef CONFIG_COMPAT -extern long drm_compat_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
-#else -/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */ -#define drm_compat_ioctl NULL -#endif -extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
-/* Misc. IOCTL support (drm_ioctl.c) */ -int drm_noop(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-int drm_invalid_op(struct drm_device *dev, void *data,
struct drm_file *file_priv);
/*
- These are exported to drivers so that they can implement fencing using
diff --git a/include/drm/drm_ioctl.h b/include/drm/drm_ioctl.h new file mode 100644 index 000000000000..3c3677b5bdb2 --- /dev/null +++ b/include/drm/drm_ioctl.h @@ -0,0 +1,102 @@ +/*
- Internal Header for the Direct Rendering Manager
- Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- Copyright (c) 2009-2010, Code Aurora Forum.
- All rights reserved.
- Author: Rickard E. (Rik) Faith faith@valinux.com
- Author: Gareth Hughes gareth@valinux.com
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the "Software"),
- to deal in the Software without restriction, including without limitation
- the rights to use, copy, modify, merge, publish, distribute, sublicense,
- and/or sell copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice (including the next
- paragraph) shall be included in all copies or substantial portions of the
- Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- */
+#ifndef _DRM_IOCTL_H_ +#define _DRM_IOCTL_H_
+#include <linux/types.h>
+#include <asm/ioctl.h>
+struct drm_device; +struct drm_file; +struct file;
+/**
- Ioctl function type.
- \param inode device inode.
- \param file_priv DRM file private pointer.
- \param cmd command.
- \param arg argument.
- */
+typedef int drm_ioctl_t(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
unsigned long arg);
+#define DRM_IOCTL_NR(n) _IOC_NR(n)
I wonder what's the point of this wrapper. Maybe leftovers from the out-of-tree days? Maybe nuke it while you're touching this stuff?
+#define DRM_MAJOR 226
+#define DRM_AUTH 0x1 +#define DRM_MASTER 0x2 +#define DRM_ROOT_ONLY 0x4 +#define DRM_CONTROL_ALLOW 0x8 +#define DRM_UNLOCKED 0x10 +#define DRM_RENDER_ALLOW 0x20
+struct drm_ioctl_desc {
- unsigned int cmd;
- int flags;
- drm_ioctl_t *func;
- const char *name;
+};
+/**
s/**/*/ ?
- Creates a driver or general drm_ioctl_desc array entry for the given
- ioctl, for use by drm_ioctl().
- */
+#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \
- [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \
.cmd = DRM_IOCTL_##ioctl, \
.func = _func, \
.flags = _flags, \
.name = #ioctl \
}
^
Spurious space
Otherwise looks sane so Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com
+int drm_ioctl_permit(u32 flags, struct drm_file *file_priv); +long drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_COMPAT +long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#else +/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */ +#define drm_compat_ioctl NULL +#endif +bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
+int drm_noop(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int drm_invalid_op(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+#endif /* _DRM_IOCTL_H_ */
2.11.0
Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
-- Ville Syrjälä Intel OTC
On Wed, Mar 22, 2017 at 06:56:32PM +0100, Daniel Vetter wrote:
On Wed, Mar 22, 2017 at 03:47:31PM +0200, Ville Syrjälä wrote:
On Wed, Mar 22, 2017 at 09:36:08AM +0100, Daniel Vetter wrote:
To match the drm_ioctl.c we already have.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/drm_ioctl.c | 1 + include/drm/drmP.h | 61 +------------------------- include/drm/drm_ioctl.h | 102 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 60 deletions(-) create mode 100644 include/drm/drm_ioctl.h
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 601bb0ded9d2..7f4f4f48e390 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -28,6 +28,7 @@
- OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <drm/drm_ioctl.h> #include <drm/drmP.h> #include <drm/drm_auth.h> #include "drm_legacy.h" diff --git a/include/drm/drmP.h b/include/drm/drmP.h index fc2a0744413d..248d2408e56b 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -80,6 +80,7 @@ #include <drm/drm_file.h> #include <drm/drm_debugfs.h> #include <drm/drm_sysfs.h> +#include <drm/drm_ioctl.h>
Same question as for the debugfs thing. Why do we need this?
Try fixing up the drmP.h include hell, and you know that it'd take a few hundred patches. And right now it's impossible, because the most central structure (struct drm_device) is in here, so defacto we still have a monolithic header which needs everything.
First we need to split it completely, then all places that include drmP.h need to switch to individual headers (each time fixing up a pile of fallout), and then eventually (after fixing the few hundred places or so) we can remove all these include lines here (or well, get rid of drmP.h entirely). But not before. I tried.
OK. I thought this stuff wouldn't have spread that far beyond the ioctl implementations, but I guess not.
Hmm. Had I spent any thought on this I would have realized that at least DRM_IOCTL_DEF_DRV() is used in pretty much every driver.
On Wed, Mar 22, 2017 at 03:47:31PM +0200, Ville Syrjälä wrote:
On Wed, Mar 22, 2017 at 09:36:08AM +0100, Daniel Vetter wrote:
To match the drm_ioctl.c we already have.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/drm_ioctl.c | 1 + include/drm/drmP.h | 61 +------------------------- include/drm/drm_ioctl.h | 102 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 60 deletions(-) create mode 100644 include/drm/drm_ioctl.h
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 601bb0ded9d2..7f4f4f48e390 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -28,6 +28,7 @@
- OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <drm/drm_ioctl.h> #include <drm/drmP.h> #include <drm/drm_auth.h> #include "drm_legacy.h" diff --git a/include/drm/drmP.h b/include/drm/drmP.h index fc2a0744413d..248d2408e56b 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -80,6 +80,7 @@ #include <drm/drm_file.h> #include <drm/drm_debugfs.h> #include <drm/drm_sysfs.h> +#include <drm/drm_ioctl.h>
Same question as for the debugfs thing. Why do we need this?
I forgot to scroll down, oops :(
struct module;
@@ -318,49 +319,6 @@ struct pci_controller;
#define DRM_IF_VERSION(maj, min) (maj << 16 | min)
-/**
- Ioctl function type.
- \param inode device inode.
- \param file_priv DRM file private pointer.
- \param cmd command.
- \param arg argument.
- */
-typedef int drm_ioctl_t(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
unsigned long arg);
-#define DRM_IOCTL_NR(n) _IOC_NR(n) -#define DRM_MAJOR 226
-#define DRM_AUTH 0x1 -#define DRM_MASTER 0x2 -#define DRM_ROOT_ONLY 0x4 -#define DRM_CONTROL_ALLOW 0x8 -#define DRM_UNLOCKED 0x10 -#define DRM_RENDER_ALLOW 0x20
-struct drm_ioctl_desc {
- unsigned int cmd;
- int flags;
- drm_ioctl_t *func;
- const char *name;
-};
-/**
- Creates a driver or general drm_ioctl_desc array entry for the given
- ioctl, for use by drm_ioctl().
- */
-#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \
- [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \
.cmd = DRM_IOCTL_##ioctl, \
.func = _func, \
.flags = _flags, \
.name = #ioctl \
}
/* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 @@ -550,23 +508,6 @@ static inline int drm_device_is_unplugged(struct drm_device *dev) /*@{*/
/* Driver support (drm_drv.h) */
-extern int drm_ioctl_permit(u32 flags, struct drm_file *file_priv); -extern long drm_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
-#ifdef CONFIG_COMPAT -extern long drm_compat_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
-#else -/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */ -#define drm_compat_ioctl NULL -#endif -extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
-/* Misc. IOCTL support (drm_ioctl.c) */ -int drm_noop(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-int drm_invalid_op(struct drm_device *dev, void *data,
struct drm_file *file_priv);
/*
- These are exported to drivers so that they can implement fencing using
diff --git a/include/drm/drm_ioctl.h b/include/drm/drm_ioctl.h new file mode 100644 index 000000000000..3c3677b5bdb2 --- /dev/null +++ b/include/drm/drm_ioctl.h @@ -0,0 +1,102 @@ +/*
- Internal Header for the Direct Rendering Manager
- Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- Copyright (c) 2009-2010, Code Aurora Forum.
- All rights reserved.
- Author: Rickard E. (Rik) Faith faith@valinux.com
- Author: Gareth Hughes gareth@valinux.com
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the "Software"),
- to deal in the Software without restriction, including without limitation
- the rights to use, copy, modify, merge, publish, distribute, sublicense,
- and/or sell copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice (including the next
- paragraph) shall be included in all copies or substantial portions of the
- Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- */
+#ifndef _DRM_IOCTL_H_ +#define _DRM_IOCTL_H_
+#include <linux/types.h>
+#include <asm/ioctl.h>
+struct drm_device; +struct drm_file; +struct file;
+/**
- Ioctl function type.
- \param inode device inode.
- \param file_priv DRM file private pointer.
- \param cmd command.
- \param arg argument.
- */
+typedef int drm_ioctl_t(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
unsigned long arg);
+#define DRM_IOCTL_NR(n) _IOC_NR(n)
I wonder what's the point of this wrapper. Maybe leftovers from the out-of-tree days? Maybe nuke it while you're touching this stuff?
It's used in a lot of places (all the 32 bit compat code). I guess we could nuke it (it does smell like *bsd compat cruft), but separate (big) patch.
+#define DRM_MAJOR 226
+#define DRM_AUTH 0x1 +#define DRM_MASTER 0x2 +#define DRM_ROOT_ONLY 0x4 +#define DRM_CONTROL_ALLOW 0x8 +#define DRM_UNLOCKED 0x10 +#define DRM_RENDER_ALLOW 0x20
+struct drm_ioctl_desc {
- unsigned int cmd;
- int flags;
- drm_ioctl_t *func;
- const char *name;
+};
+/**
s/**/*/ ?
It'll get addressed in the next patch, where I clean up the kernel-doc. I assume I can still get your r-b for this patch here?
- Creates a driver or general drm_ioctl_desc array entry for the given
- ioctl, for use by drm_ioctl().
- */
+#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \
- [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \
.cmd = DRM_IOCTL_##ioctl, \
.func = _func, \
.flags = _flags, \
.name = #ioctl \
}
^
Spurious space
Will fix, thx a lot for reviewing. -Daniel
Otherwise looks sane so Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com
+int drm_ioctl_permit(u32 flags, struct drm_file *file_priv); +long drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_COMPAT +long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#else +/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */ +#define drm_compat_ioctl NULL +#endif +bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
+int drm_noop(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int drm_invalid_op(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+#endif /* _DRM_IOCTL_H_ */
2.11.0
Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
-- Ville Syrjälä Intel OTC
On Wed, Mar 22, 2017 at 09:15:23PM +0100, Daniel Vetter wrote:
On Wed, Mar 22, 2017 at 03:47:31PM +0200, Ville Syrjälä wrote:
On Wed, Mar 22, 2017 at 09:36:08AM +0100, Daniel Vetter wrote:
To match the drm_ioctl.c we already have.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/drm_ioctl.c | 1 + include/drm/drmP.h | 61 +------------------------- include/drm/drm_ioctl.h | 102 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 60 deletions(-) create mode 100644 include/drm/drm_ioctl.h
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 601bb0ded9d2..7f4f4f48e390 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c
<snip>
+#define DRM_MAJOR 226
+#define DRM_AUTH 0x1 +#define DRM_MASTER 0x2 +#define DRM_ROOT_ONLY 0x4 +#define DRM_CONTROL_ALLOW 0x8 +#define DRM_UNLOCKED 0x10 +#define DRM_RENDER_ALLOW 0x20
+struct drm_ioctl_desc {
- unsigned int cmd;
- int flags;
- drm_ioctl_t *func;
- const char *name;
+};
+/**
s/**/*/ ?
It'll get addressed in the next patch, where I clean up the kernel-doc. I assume I can still get your r-b for this patch here?
Sure thing.
To match the drm_ioctl.c we already have.
v2: Remove spurious space (Ville).
Cc: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/drm_ioctl.c | 1 + include/drm/drmP.h | 61 +------------------------- include/drm/drm_ioctl.h | 102 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 60 deletions(-) create mode 100644 include/drm/drm_ioctl.h
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 601bb0ded9d2..7f4f4f48e390 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -28,6 +28,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */
+#include <drm/drm_ioctl.h> #include <drm/drmP.h> #include <drm/drm_auth.h> #include "drm_legacy.h" diff --git a/include/drm/drmP.h b/include/drm/drmP.h index fc2a0744413d..248d2408e56b 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -80,6 +80,7 @@ #include <drm/drm_file.h> #include <drm/drm_debugfs.h> #include <drm/drm_sysfs.h> +#include <drm/drm_ioctl.h>
struct module;
@@ -318,49 +319,6 @@ struct pci_controller;
#define DRM_IF_VERSION(maj, min) (maj << 16 | min)
-/** - * Ioctl function type. - * - * \param inode device inode. - * \param file_priv DRM file private pointer. - * \param cmd command. - * \param arg argument. - */ -typedef int drm_ioctl_t(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, - unsigned long arg); - -#define DRM_IOCTL_NR(n) _IOC_NR(n) -#define DRM_MAJOR 226 - -#define DRM_AUTH 0x1 -#define DRM_MASTER 0x2 -#define DRM_ROOT_ONLY 0x4 -#define DRM_CONTROL_ALLOW 0x8 -#define DRM_UNLOCKED 0x10 -#define DRM_RENDER_ALLOW 0x20 - -struct drm_ioctl_desc { - unsigned int cmd; - int flags; - drm_ioctl_t *func; - const char *name; -}; - -/** - * Creates a driver or general drm_ioctl_desc array entry for the given - * ioctl, for use by drm_ioctl(). - */ - -#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \ - [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \ - .cmd = DRM_IOCTL_##ioctl, \ - .func = _func, \ - .flags = _flags, \ - .name = #ioctl \ - }
/* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 @@ -550,23 +508,6 @@ static inline int drm_device_is_unplugged(struct drm_device *dev) /*@{*/
/* Driver support (drm_drv.h) */ -extern int drm_ioctl_permit(u32 flags, struct drm_file *file_priv); -extern long drm_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg); -#ifdef CONFIG_COMPAT -extern long drm_compat_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg); -#else -/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */ -#define drm_compat_ioctl NULL -#endif -extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags); - -/* Misc. IOCTL support (drm_ioctl.c) */ -int drm_noop(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int drm_invalid_op(struct drm_device *dev, void *data, - struct drm_file *file_priv);
/* * These are exported to drivers so that they can implement fencing using diff --git a/include/drm/drm_ioctl.h b/include/drm/drm_ioctl.h new file mode 100644 index 000000000000..f17ee077f649 --- /dev/null +++ b/include/drm/drm_ioctl.h @@ -0,0 +1,102 @@ +/* + * Internal Header for the Direct Rendering Manager + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * Copyright (c) 2009-2010, Code Aurora Forum. + * All rights reserved. + * + * Author: Rickard E. (Rik) Faith faith@valinux.com + * Author: Gareth Hughes gareth@valinux.com + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DRM_IOCTL_H_ +#define _DRM_IOCTL_H_ + +#include <linux/types.h> + +#include <asm/ioctl.h> + +struct drm_device; +struct drm_file; +struct file; + +/** + * Ioctl function type. + * + * \param inode device inode. + * \param file_priv DRM file private pointer. + * \param cmd command. + * \param arg argument. + */ +typedef int drm_ioctl_t(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, + unsigned long arg); + +#define DRM_IOCTL_NR(n) _IOC_NR(n) +#define DRM_MAJOR 226 + +#define DRM_AUTH 0x1 +#define DRM_MASTER 0x2 +#define DRM_ROOT_ONLY 0x4 +#define DRM_CONTROL_ALLOW 0x8 +#define DRM_UNLOCKED 0x10 +#define DRM_RENDER_ALLOW 0x20 + +struct drm_ioctl_desc { + unsigned int cmd; + int flags; + drm_ioctl_t *func; + const char *name; +}; + +/** + * Creates a driver or general drm_ioctl_desc array entry for the given + * ioctl, for use by drm_ioctl(). + */ + +#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \ + [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \ + .cmd = DRM_IOCTL_##ioctl, \ + .func = _func, \ + .flags = _flags, \ + .name = #ioctl \ + } + +int drm_ioctl_permit(u32 flags, struct drm_file *file_priv); +long drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_COMPAT +long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#else +/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */ +#define drm_compat_ioctl NULL +#endif +bool drm_ioctl_flags(unsigned int nr, unsigned int *flags); + +int drm_noop(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int drm_invalid_op(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +#endif /* _DRM_IOCTL_H_ */
Also unify/merge with the existing stuff.
I was a bit torn where to put this, but in the end I decided to put all the ioctl/sysfs/debugfs stuff into drm-uapi.rst. That means we have a bit a split with the other uapi related stuff used internally, like drm_file.[hc], but I think overall this makes more sense.
If it's too confusing we can always add more cross-links to make it more discoverable. But the auto-sprinkling of links kernel-doc already does seems sufficient.
Also for prettier docs and more cross-links, switch the internal defines over to an enum, as usual.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- Documentation/gpu/drm-internals.rst | 50 ---------------- Documentation/gpu/drm-uapi.rst | 14 +++++ drivers/gpu/drm/drm_ioc32.c | 1 - drivers/gpu/drm/drm_ioctl.c | 45 ++++++++++++++ include/drm/drm_ioctl.h | 116 +++++++++++++++++++++++++++++++----- 5 files changed, 160 insertions(+), 66 deletions(-)
diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index a09c721f9e89..babfb6143bd9 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -255,56 +255,6 @@ File Operations .. kernel-doc:: drivers/gpu/drm/drm_file.c :export:
-IOCTLs ------- - -struct drm_ioctl_desc *ioctls; int num_ioctls; - Driver-specific ioctls descriptors table. - -Driver-specific ioctls numbers start at DRM_COMMAND_BASE. The ioctls -descriptors table is indexed by the ioctl number offset from the base -value. Drivers can use the DRM_IOCTL_DEF_DRV() macro to initialize -the table entries. - -:: - - DRM_IOCTL_DEF_DRV(ioctl, func, flags) - -``ioctl`` is the ioctl name. Drivers must define the DRM_##ioctl and -DRM_IOCTL_##ioctl macros to the ioctl number offset from -DRM_COMMAND_BASE and the ioctl number respectively. The first macro is -private to the device while the second must be exposed to userspace in a -public header. - -``func`` is a pointer to the ioctl handler function compatible with the -``drm_ioctl_t`` type. - -:: - - typedef int drm_ioctl_t(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -``flags`` is a bitmask combination of the following values. It restricts -how the ioctl is allowed to be called. - -- DRM_AUTH - Only authenticated callers allowed - -- DRM_MASTER - The ioctl can only be called on the master file handle - -- DRM_ROOT_ONLY - Only callers with the SYSADMIN capability allowed - -- DRM_CONTROL_ALLOW - The ioctl can only be called on a control - device - -- DRM_UNLOCKED - The ioctl handler will be called without locking the - DRM global mutex. This is the enforced default for kms drivers (i.e. - using the DRIVER_MODESET flag) and hence shouldn't be used any more - for new drivers. - -.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c - :export: - - Misc Utilities ==============
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 8b0f0e403f0c..858457567d3d 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -160,6 +160,20 @@ other hand, a driver requires shared state between clients which is visible to user-space and accessible beyond open-file boundaries, they cannot support render nodes.
+IOCTL Support on Device Nodes +============================= + +.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c + :doc: driver specific ioctls + +.. kernel-doc:: include/drm/drm_ioctl.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_ioc32.c + :export:
Testing and validation ====================== diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c index b134482f4022..aeca0214caa8 100644 --- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c @@ -1141,5 +1141,4 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return ret; } - EXPORT_SYMBOL(drm_compat_ioctl); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 7f4f4f48e390..e593c1047d1c 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -647,6 +647,51 @@ static const struct drm_ioctl_desc drm_ioctls[] = { #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
/** + * DOC: driver specific ioctls + * + * First things first, driver private IOCTLs should only be needed for drivers + * supporting rendering. Kernel modesetting is all standardized, and extended + * through properties. There are a few exceptions in some existing drivers, + * which define IOCTL for use by the display DRM master, but they all predate + * properties. + * + * Now if you do have a render driver you always have to support it through + * driver private properties. There's a few steps needed to wire all the things + * up. + * + * First you need to define the structure for your IOCTL in your driver private + * UAPI header in ``include/uapi/drm/my_driver_drm.h``:: + * + * struct my_driver_operation { + * u32 some_thing; + * u32 anther_thing; + * }; + * + * Please make sure that you follow all the best practices from + * ``Documentation/ioctl/botching-up-ioctls.txt``. Note that drm_ioctl() + * automatically zero-extends structures, hence make sure you can add more stuff + * at the end, i.e. don't put a variable sized array there. + * + * Then you need to define your IOCTL number, using one of DRM_IO(), DRM_IOR(), + * DRM_IOW() or DRM_IOWR(). It must start with the DRM_IOCTL_ prefix:: + * + * ##define DRM_IOCTL_MY_DRIVER_OPERATION \ + * DRM_IOW(DRM_COMMAND_BASE, struct my_driver_operation) + * + * DRM driver private IOCTL must be in the range from DRM_COMMAND_BASE to + * DRM_COMMAND_END. Finally you need an array of &struct drm_ioctl_desc to wire + * up the handlers and set the access rights: + * + * static const struct drm_ioctl_desc my_driver_ioctls[] = { + * DRM_IOCTL_DEF_DRV(MY_DRIVER_OPERATION, my_driver_operation, + * DRM_AUTH|DRM_RENDER_ALLO), + * }; + * + * And then assign this to the &drm_driver.ioctls field in your driver + * structure. + */ + +/** * drm_ioctl - ioctl callback implementation for DRM drivers * @filp: file this ioctl is called on * @cmd: ioctl cmd number diff --git a/include/drm/drm_ioctl.h b/include/drm/drm_ioctl.h index 3c3677b5bdb2..0ba041909afc 100644 --- a/include/drm/drm_ioctl.h +++ b/include/drm/drm_ioctl.h @@ -33,6 +33,7 @@ #define _DRM_IOCTL_H_
#include <linux/types.h> +#include <linux/bitops.h>
#include <asm/ioctl.h>
@@ -41,41 +42,126 @@ struct drm_file; struct file;
/** - * Ioctl function type. + * drm_ioctl_t - DRM ioctl function type. + * @dev: DRM device inode + * @data: private pointer of the ioctl call + * @file_priv: DRM file this ioctl was made on * - * \param inode device inode. - * \param file_priv DRM file private pointer. - * \param cmd command. - * \param arg argument. + * This is the DRM ioctl typedef. Note that drm_ioctl() has alrady copied @data + * into kernel-space, and will also copy it back, depending upon the read/write + * settings in the ioctl command code. */ typedef int drm_ioctl_t(struct drm_device *dev, void *data, struct drm_file *file_priv);
+/** + * drm_ioctl_compat_t - compatibility DRM ioctl function type. + * @filp: file pointer + * @cmd: ioctl command code + * @arg: DRM file this ioctl was made on + * + * Just a typedef to make declaring an array of compatibility handlers easier. + * New drivers shouldn't screw up the structure layout for their ioctl + * structures and hence never need this. + */ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, unsigned long arg);
#define DRM_IOCTL_NR(n) _IOC_NR(n) #define DRM_MAJOR 226
-#define DRM_AUTH 0x1 -#define DRM_MASTER 0x2 -#define DRM_ROOT_ONLY 0x4 -#define DRM_CONTROL_ALLOW 0x8 -#define DRM_UNLOCKED 0x10 -#define DRM_RENDER_ALLOW 0x20 +/** + * enum drm_ioctl_flags - DRM ioctl flags + * + * Various flags that can be set in &drm_ioctl_desc.flags to control how + * userspace can use a given ioctl. + */ +enum drm_ioctl_flags { + /** + * @DRM_AUTH: + * + * This is for ioctl which are used for rendering, and require that the + * file descriptor is either for a render node, or if it's a + * legacy/primary node, then it must be authenticated. + */ + DRM_AUTH = BIT(0), + /** + * @DRM_MASTER: + * + * This must be set for any ioctl which can change the modeset or + * display state. Userspace must call the ioctl through a primary node, + * while it is the active master. + * + * Note that read-only modeset ioctl can also be called by + * unauthenticated clients, or when a master is not the currently active + * one. + */ + DRM_MASTER = BIT(1), + /** + * @DRM_ROOT_ONLY: + * + * Anything that could potentially wreak a master file descriptor needs + * to have this flag set. Current that's only for the SETMASTER and + * DROPMASTER ioctl, which e.g. logind can call to force a non-behaving + * master (display compositor) into compliance. + * + * This is equivalent to callers with the SYSADMIN capability. + */ + DRM_ROOT_ONLY = BIT(2), + /** + * @DRM_CONTROL_ALLOW: + * + * Deprecated, do not use. Control nodes are in the process of getting + * removed. + */ + DRM_CONTROL_ALLOW = BIT(3), + /** + * @DRM_UNLOCKED: + * + * Whether &drm_ioctl_desc.func should be called with the DRM BKL held + * or not. Enforced as the default for all modern drivers, hence there + * should never be a need to set this flag. + */ + DRM_UNLOCKED = BIT(4), + /** + * @DRM_RENDER_ALLOW: + * + * This is used for all ioctl needed for rendering only, for drivers + * which support render nodes. This should be all new render drivers, + * and hence it should be always set for any ioctl with DRM_AUTH set. + * Note though that read-only query ioctl might have this set, but have + * not set DRM_AUTH because they do not require authentication. + */ + DRM_RENDER_ALLOW = BIT(5), +};
+/** + * struct drm_ioctl_desc - DRM driver ioctl entry + * @cmd: ioctl command number, without flags + * @flags: a bitmask of &enum drm_ioctl_flags + * @func: handler for this ioctl + * @name: user-readable name for debug output + * + * For convenience it's easier to create these using the DRM_IOCTL_DEF_DRV() + * macro. + */ struct drm_ioctl_desc { unsigned int cmd; - int flags; + enum drm_ioctl_flags flags; drm_ioctl_t *func; const char *name; };
/** - * Creates a driver or general drm_ioctl_desc array entry for the given - * ioctl, for use by drm_ioctl(). + * DRM_IOCTL_DEF_DRV() - helper macro to fill out a &struct drm_ioctl_desc + * @ioctl: ioctl command suffix + * @_func: handler for the ioctl + * @_flags: a bitmask of &enum drm_ioctl_flags + * + * Small helper macro to create a &struct drm_ioctl_desc entry. The ioctl + * command number is constructed by prepending ``DRM_IOCTL_`` and passing that + * to DRM_IOCTL_NR(). */ - #define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \ [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \ .cmd = DRM_IOCTL_##ioctl, \
Hi Daniel,
[auto build test WARNING on drm/drm-next] [cannot apply to v4.11-rc3 next-20170324] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Daniel-Vetter/more-drmP-h-cleanup/2... base: git://people.freedesktop.org/~airlied/linux.git drm-next reproduce: make htmldocs
All warnings (new ones prefixed by >>):
WARNING: convert(1) not found, for SVG to PDF conversion install ImageMagick (https://www.imagemagick.org) include/linux/init.h:1: warning: no structured comments found kernel/sched/core.c:2085: warning: No description found for parameter 'rf' kernel/sched/core.c:2085: warning: Excess function parameter 'cookie' description in 'try_to_wake_up_local' include/linux/kthread.h:26: warning: Excess function parameter '...' description in 'kthread_create' kernel/sys.c:1: warning: no structured comments found include/linux/device.h:969: warning: No description found for parameter 'dma_ops' drivers/dma-buf/seqno-fence.c:1: warning: no structured comments found include/linux/iio/iio.h:597: warning: No description found for parameter 'trig_readonly' include/linux/iio/trigger.h:151: warning: No description found for parameter 'indio_dev' include/linux/iio/trigger.h:151: warning: No description found for parameter 'trig' include/linux/device.h:970: warning: No description found for parameter 'dma_ops' drivers/regulator/core.c:1467: warning: Excess function parameter 'ret' description in 'regulator_dev_lookup' include/drm/drm_drv.h:524: warning: No description found for parameter 'set_busid' include/drm/drm_drv.h:524: warning: No description found for parameter 'irq_handler' include/drm/drm_drv.h:524: warning: No description found for parameter 'irq_preinstall' include/drm/drm_drv.h:524: warning: No description found for parameter 'irq_postinstall' include/drm/drm_drv.h:524: warning: No description found for parameter 'irq_uninstall' include/drm/drm_drv.h:524: warning: No description found for parameter 'debugfs_init' include/drm/drm_drv.h:524: warning: No description found for parameter 'gem_open_object' include/drm/drm_drv.h:524: warning: No description found for parameter 'gem_close_object' include/drm/drm_drv.h:524: warning: No description found for parameter 'prime_handle_to_fd' include/drm/drm_drv.h:524: warning: No description found for parameter 'prime_fd_to_handle' include/drm/drm_drv.h:524: warning: No description found for parameter 'gem_prime_export' include/drm/drm_drv.h:524: warning: No description found for parameter 'gem_prime_import' include/drm/drm_drv.h:524: warning: No description found for parameter 'gem_prime_pin' include/drm/drm_drv.h:524: warning: No description found for parameter 'gem_prime_unpin' include/drm/drm_drv.h:524: warning: No description found for parameter 'gem_prime_res_obj' include/drm/drm_drv.h:524: warning: No description found for parameter 'gem_prime_get_sg_table' include/drm/drm_drv.h:524: warning: No description found for parameter 'gem_prime_import_sg_table' include/drm/drm_drv.h:524: warning: No description found for parameter 'gem_prime_vmap' include/drm/drm_drv.h:524: warning: No description found for parameter 'gem_prime_vunmap' include/drm/drm_drv.h:524: warning: No description found for parameter 'gem_prime_mmap' include/drm/drm_drv.h:524: warning: No description found for parameter 'gem_vm_ops' include/drm/drm_drv.h:524: warning: No description found for parameter 'major' include/drm/drm_drv.h:524: warning: No description found for parameter 'minor' include/drm/drm_drv.h:524: warning: No description found for parameter 'patchlevel' include/drm/drm_drv.h:524: warning: No description found for parameter 'name' include/drm/drm_drv.h:524: warning: No description found for parameter 'desc' include/drm/drm_drv.h:524: warning: No description found for parameter 'date' include/drm/drm_drv.h:524: warning: No description found for parameter 'driver_features' include/drm/drm_drv.h:524: warning: No description found for parameter 'ioctls' include/drm/drm_drv.h:524: warning: No description found for parameter 'num_ioctls' include/drm/drm_drv.h:524: warning: No description found for parameter 'fops' include/drm/drm_connector.h:138: warning: No description found for parameter 'scdc' include/drm/drm_color_mgmt.h:1: warning: no structured comments found drivers/gpu/drm/drm_ioc32.c:3: warning: Cannot understand * \file drm_ioc32.c on line 3 - I thought it was a doc line
drivers/gpu/drm/drm_ioc32.c:1124: warning: No description found for parameter 'filp' drivers/gpu/drm/drm_ioc32.c:1124: warning: No description found for parameter 'cmd' drivers/gpu/drm/drm_ioc32.c:1124: warning: No description found for parameter 'arg'
drivers/gpu/drm/i915/intel_lpe_audio.c:342: warning: No description found for parameter 'pipe' drivers/gpu/drm/i915/intel_lpe_audio.c:342: warning: No description found for parameter 'dp_output' drivers/gpu/drm/i915/intel_lpe_audio.c:342: warning: No description found for parameter 'link_rate' drivers/gpu/drm/i915/intel_lpe_audio.c:343: warning: No description found for parameter 'pipe' drivers/gpu/drm/i915/intel_lpe_audio.c:343: warning: No description found for parameter 'dp_output' drivers/gpu/drm/i915/intel_lpe_audio.c:343: warning: No description found for parameter 'link_rate' drivers/media/dvb-core/dvb_frontend.h:677: warning: No description found for parameter 'refcount' Documentation/core-api/assoc_array.rst:13: WARNING: Enumerated list ends without a blank line; unexpected unindent. Documentation/doc-guide/sphinx.rst:126: ERROR: Unknown target name: "sphinx c domain". kernel/sched/fair.c:7616: WARNING: Inline emphasis start-string without end-string. kernel/time/timer.c:1200: ERROR: Unexpected indentation. kernel/time/timer.c:1202: ERROR: Unexpected indentation. kernel/time/timer.c:1203: WARNING: Block quote ends without a blank line; unexpected unindent. include/linux/wait.h:122: WARNING: Block quote ends without a blank line; unexpected unindent. include/linux/wait.h:125: ERROR: Unexpected indentation. include/linux/wait.h:127: WARNING: Block quote ends without a blank line; unexpected unindent. kernel/time/hrtimer.c:990: WARNING: Block quote ends without a blank line; unexpected unindent. kernel/signal.c:322: WARNING: Inline literal start-string without end-string. include/linux/iio/iio.h:219: ERROR: Unexpected indentation. include/linux/iio/iio.h:220: WARNING: Block quote ends without a blank line; unexpected unindent. include/linux/iio/iio.h:226: WARNING: Definition list ends without a blank line; unexpected unindent. drivers/iio/industrialio-core.c:639: ERROR: Unknown target name: "iio_val". drivers/iio/industrialio-core.c:646: ERROR: Unknown target name: "iio_val". drivers/message/fusion/mptbase.c:5051: WARNING: Definition list ends without a blank line; unexpected unindent. drivers/tty/serial/serial_core.c:1898: WARNING: Definition list ends without a blank line; unexpected unindent. include/linux/regulator/driver.h:271: ERROR: Unknown target name: "regulator_regmap_x_voltage". include/linux/spi/spi.h:369: ERROR: Unexpected indentation. drivers/usb/core/message.c:478: ERROR: Unexpected indentation. drivers/usb/core/message.c:479: WARNING: Block quote ends without a blank line; unexpected unindent. Documentation/driver-api/usb.rst:623: ERROR: Unknown target name: "usb_type". Documentation/driver-api/usb.rst:623: ERROR: Unknown target name: "usb_dir". Documentation/driver-api/usb.rst:623: ERROR: Unknown target name: "usb_recip". Documentation/driver-api/usb.rst:689: ERROR: Unknown target name: "usbdevfs_urb_type". drivers/gpu/drm/drm_scdc_helper.c:203: ERROR: Unexpected indentation. drivers/gpu/drm/drm_scdc_helper.c:204: WARNING: Block quote ends without a blank line; unexpected unindent. drivers/gpu/drm/drm_ioctl.c:687: WARNING: Definition list ends without a blank line; unexpected unindent. sound/soc/soc-core.c:2670: ERROR: Unknown target name: "snd_soc_daifmt". sound/core/jack.c:312: ERROR: Unknown target name: "snd_jack_btn". Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 43: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 56: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 69: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 82: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 96: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 109: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 122: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 133: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 164: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 193: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 43: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 56: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 69: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 82: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 96: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 109: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 122: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 133: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 164: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 193: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 43: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 56: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 69: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 82: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 96: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 109: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 122: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 133: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 164: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 193: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 43: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 56: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 69: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 82: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 96: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 109: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 122: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 133: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 164: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 193: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 43: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 56: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 69: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 82: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 96: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 109: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 122: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 133: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 164: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 193: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 43: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 56: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 69: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 82: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 96: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 109: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 122: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 133: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 164: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "~/.fonts.conf", line 193: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 43: Having multiple values in <test> isn't supported and may not work as expected Fontconfig warning: "/home/kbuild/.config/fontconfig/fonts.conf", line 56: Having multiple values in <test> isn't supported and may not work as expected
vim +3 drivers/gpu/drm/drm_ioc32.c
9a186645 drivers/char/drm/drm_ioc32.c Dave Airlie 2005-06-23 1 /** 9a186645 drivers/char/drm/drm_ioc32.c Dave Airlie 2005-06-23 2 * \file drm_ioc32.c 9a186645 drivers/char/drm/drm_ioc32.c Dave Airlie 2005-06-23 @3 * 9a186645 drivers/char/drm/drm_ioc32.c Dave Airlie 2005-06-23 4 * 32-bit ioctl compatibility routines for the DRM. 9a186645 drivers/char/drm/drm_ioc32.c Dave Airlie 2005-06-23 5 * 9a186645 drivers/char/drm/drm_ioc32.c Dave Airlie 2005-06-23 6 * \author Paul Mackerras paulus@samba.org 9a186645 drivers/char/drm/drm_ioc32.c Dave Airlie 2005-06-23 7 * 9a186645 drivers/char/drm/drm_ioc32.c Dave Airlie 2005-06-23 8 * Copyright (C) Paul Mackerras 2005. 9a186645 drivers/char/drm/drm_ioc32.c Dave Airlie 2005-06-23 9 * All Rights Reserved. 9a186645 drivers/char/drm/drm_ioc32.c Dave Airlie 2005-06-23 10 * 9a186645 drivers/char/drm/drm_ioc32.c Dave Airlie 2005-06-23 11 * Permission is hereby granted, free of charge, to any person obtaining a
:::::: The code at line 3 was first introduced by commit :::::: 9a18664506dbce5e23f3c5de7b1c5a042dd26520 drm: 32/64-bit DRM ioctl compatibility patch
:::::: TO: Dave Airlie <airlied@starflyer.(none)> :::::: CC: Dave Airlie airlied@linux.ie
--- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Also unify/merge with the existing stuff.
I was a bit torn where to put this, but in the end I decided to put all the ioctl/sysfs/debugfs stuff into drm-uapi.rst. That means we have a bit a split with the other uapi related stuff used internally, like drm_file.[hc], but I think overall this makes more sense.
If it's too confusing we can always add more cross-links to make it more discoverable. But the auto-sprinkling of links kernel-doc already does seems sufficient.
Also for prettier docs and more cross-links, switch the internal defines over to an enum, as usual.
v2: Update kerneldoc fro drm_compat_ioctl too (caught by 0day), plus a bit more drive-by polish.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- Documentation/gpu/drm-internals.rst | 50 ---------------- Documentation/gpu/drm-uapi.rst | 14 +++++ drivers/gpu/drm/drm_ioc32.c | 76 ++++++++++++----------- drivers/gpu/drm/drm_ioctl.c | 50 +++++++++++++++- include/drm/drm_ioctl.h | 116 +++++++++++++++++++++++++++++++----- 5 files changed, 203 insertions(+), 103 deletions(-)
diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index a09c721f9e89..babfb6143bd9 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -255,56 +255,6 @@ File Operations .. kernel-doc:: drivers/gpu/drm/drm_file.c :export:
-IOCTLs ------- - -struct drm_ioctl_desc *ioctls; int num_ioctls; - Driver-specific ioctls descriptors table. - -Driver-specific ioctls numbers start at DRM_COMMAND_BASE. The ioctls -descriptors table is indexed by the ioctl number offset from the base -value. Drivers can use the DRM_IOCTL_DEF_DRV() macro to initialize -the table entries. - -:: - - DRM_IOCTL_DEF_DRV(ioctl, func, flags) - -``ioctl`` is the ioctl name. Drivers must define the DRM_##ioctl and -DRM_IOCTL_##ioctl macros to the ioctl number offset from -DRM_COMMAND_BASE and the ioctl number respectively. The first macro is -private to the device while the second must be exposed to userspace in a -public header. - -``func`` is a pointer to the ioctl handler function compatible with the -``drm_ioctl_t`` type. - -:: - - typedef int drm_ioctl_t(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -``flags`` is a bitmask combination of the following values. It restricts -how the ioctl is allowed to be called. - -- DRM_AUTH - Only authenticated callers allowed - -- DRM_MASTER - The ioctl can only be called on the master file handle - -- DRM_ROOT_ONLY - Only callers with the SYSADMIN capability allowed - -- DRM_CONTROL_ALLOW - The ioctl can only be called on a control - device - -- DRM_UNLOCKED - The ioctl handler will be called without locking the - DRM global mutex. This is the enforced default for kms drivers (i.e. - using the DRIVER_MODESET flag) and hence shouldn't be used any more - for new drivers. - -.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c - :export: - - Misc Utilities ==============
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 8b0f0e403f0c..858457567d3d 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -160,6 +160,20 @@ other hand, a driver requires shared state between clients which is visible to user-space and accessible beyond open-file boundaries, they cannot support render nodes.
+IOCTL Support on Device Nodes +============================= + +.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c + :doc: driver specific ioctls + +.. kernel-doc:: include/drm/drm_ioctl.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_ioc32.c + :export:
Testing and validation ====================== diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c index b134482f4022..0fa7827cb0fd 100644 --- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c @@ -1,4 +1,4 @@ -/** +/* * \file drm_ioc32.c * * 32-bit ioctl compatibility routines for the DRM. @@ -72,15 +72,15 @@ #define DRM_IOCTL_MODE_ADDFB232 DRM_IOWR(0xb8, drm_mode_fb_cmd232_t)
typedef struct drm_version_32 { - int version_major; /**< Major version */ - int version_minor; /**< Minor version */ - int version_patchlevel; /**< Patch level */ - u32 name_len; /**< Length of name buffer */ - u32 name; /**< Name of driver */ - u32 date_len; /**< Length of date buffer */ - u32 date; /**< User-space buffer to hold date */ - u32 desc_len; /**< Length of desc buffer */ - u32 desc; /**< User-space buffer to hold desc */ + int version_major; /* Major version */ + int version_minor; /* Minor version */ + int version_patchlevel; /* Patch level */ + u32 name_len; /* Length of name buffer */ + u32 name; /* Name of driver */ + u32 date_len; /* Length of date buffer */ + u32 date; /* User-space buffer to hold date */ + u32 desc_len; /* Length of desc buffer */ + u32 desc; /* User-space buffer to hold desc */ } drm_version32_t;
static int compat_drm_version(struct file *file, unsigned int cmd, @@ -126,8 +126,8 @@ static int compat_drm_version(struct file *file, unsigned int cmd, }
typedef struct drm_unique32 { - u32 unique_len; /**< Length of unique */ - u32 unique; /**< Unique name for driver instantiation */ + u32 unique_len; /* Length of unique */ + u32 unique; /* Unique name for driver instantiation */ } drm_unique32_t;
static int compat_drm_getunique(struct file *file, unsigned int cmd, @@ -180,12 +180,12 @@ static int compat_drm_setunique(struct file *file, unsigned int cmd, }
typedef struct drm_map32 { - u32 offset; /**< Requested physical address (0 for SAREA)*/ - u32 size; /**< Requested physical size (bytes) */ - enum drm_map_type type; /**< Type of memory to map */ - enum drm_map_flags flags; /**< Flags */ - u32 handle; /**< User-space: "Handle" to pass to mmap() */ - int mtrr; /**< MTRR slot used */ + u32 offset; /* Requested physical address (0 for SAREA)*/ + u32 size; /* Requested physical size (bytes) */ + enum drm_map_type type; /* Type of memory to map */ + enum drm_map_flags flags; /* Flags */ + u32 handle; /* User-space: "Handle" to pass to mmap() */ + int mtrr; /* MTRR slot used */ } drm_map32_t;
static int compat_drm_getmap(struct file *file, unsigned int cmd, @@ -286,12 +286,12 @@ static int compat_drm_rmmap(struct file *file, unsigned int cmd, }
typedef struct drm_client32 { - int idx; /**< Which client desired? */ - int auth; /**< Is client authenticated? */ - u32 pid; /**< Process ID */ - u32 uid; /**< User ID */ - u32 magic; /**< Magic */ - u32 iocs; /**< Ioctl count */ + int idx; /* Which client desired? */ + int auth; /* Is client authenticated? */ + u32 pid; /* Process ID */ + u32 uid; /* User ID */ + u32 magic; /* Magic */ + u32 iocs; /* Ioctl count */ } drm_client32_t;
static int compat_drm_getclient(struct file *file, unsigned int cmd, @@ -366,12 +366,12 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd, }
typedef struct drm_buf_desc32 { - int count; /**< Number of buffers of this size */ - int size; /**< Size in bytes */ - int low_mark; /**< Low water mark */ - int high_mark; /**< High water mark */ + int count; /* Number of buffers of this size */ + int size; /* Size in bytes */ + int low_mark; /* Low water mark */ + int high_mark; /* High water mark */ int flags; - u32 agp_start; /**< Start address in the AGP aperture */ + u32 agp_start; /* Start address in the AGP aperture */ } drm_buf_desc32_t;
static int compat_drm_addbufs(struct file *file, unsigned int cmd, @@ -1111,13 +1111,18 @@ static drm_ioctl_compat_t *drm_compat_ioctls[] = { };
/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/drm. + * drm_compat_ioctl - 32bit IOCTL compatibility handler for DRM drivers + * @filp: file this ioctl is called on + * @cmd: ioctl cmd number + * @arg: user argument + * + * Compatibility handler for 32 bit userspace running on 64 kernels. All actual + * IOCTL handling is forwarded to drm_ioctl(), while marshalling structures as + * appropriate. Note that this only handles DRM core IOCTLs, if the driver has + * botched IOCTL itself, it must handle those by wrapping this function. * - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. + * Returns: + * Zero on success, negative error code on failure. */ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -1141,5 +1146,4 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return ret; } - EXPORT_SYMBOL(drm_compat_ioctl); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 7f4f4f48e390..4775c1628e03 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -647,13 +647,59 @@ static const struct drm_ioctl_desc drm_ioctls[] = { #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
/** + * DOC: driver specific ioctls + * + * First things first, driver private IOCTLs should only be needed for drivers + * supporting rendering. Kernel modesetting is all standardized, and extended + * through properties. There are a few exceptions in some existing drivers, + * which define IOCTL for use by the display DRM master, but they all predate + * properties. + * + * Now if you do have a render driver you always have to support it through + * driver private properties. There's a few steps needed to wire all the things + * up. + * + * First you need to define the structure for your IOCTL in your driver private + * UAPI header in ``include/uapi/drm/my_driver_drm.h``:: + * + * struct my_driver_operation { + * u32 some_thing; + * u32 anther_thing; + * }; + * + * Please make sure that you follow all the best practices from + * ``Documentation/ioctl/botching-up-ioctls.txt``. Note that drm_ioctl() + * automatically zero-extends structures, hence make sure you can add more stuff + * at the end, i.e. don't put a variable sized array there. + * + * Then you need to define your IOCTL number, using one of DRM_IO(), DRM_IOR(), + * DRM_IOW() or DRM_IOWR(). It must start with the DRM_IOCTL_ prefix:: + * + * ##define DRM_IOCTL_MY_DRIVER_OPERATION \ + * DRM_IOW(DRM_COMMAND_BASE, struct my_driver_operation) + * + * DRM driver private IOCTL must be in the range from DRM_COMMAND_BASE to + * DRM_COMMAND_END. Finally you need an array of &struct drm_ioctl_desc to wire + * up the handlers and set the access rights: + * + * static const struct drm_ioctl_desc my_driver_ioctls[] = { + * DRM_IOCTL_DEF_DRV(MY_DRIVER_OPERATION, my_driver_operation, + * DRM_AUTH|DRM_RENDER_ALLO), + * }; + * + * And then assign this to the &drm_driver.ioctls field in your driver + * structure. + */ + +/** * drm_ioctl - ioctl callback implementation for DRM drivers * @filp: file this ioctl is called on * @cmd: ioctl cmd number * @arg: user argument * - * Looks up the ioctl function in the ::ioctls table, checking for root - * previleges if so required, and dispatches to the respective function. + * Looks up the ioctl function in the DRM core and the driver dispatch table, + * stored in &drm_driver.ioctls. It checks for necessary permission by calling + * drm_ioctl_permit(), and dispatches to the respective function. * * Returns: * Zero on success, negative error code on failure. diff --git a/include/drm/drm_ioctl.h b/include/drm/drm_ioctl.h index f17ee077f649..ee03b3c44b3b 100644 --- a/include/drm/drm_ioctl.h +++ b/include/drm/drm_ioctl.h @@ -33,6 +33,7 @@ #define _DRM_IOCTL_H_
#include <linux/types.h> +#include <linux/bitops.h>
#include <asm/ioctl.h>
@@ -41,41 +42,126 @@ struct drm_file; struct file;
/** - * Ioctl function type. + * drm_ioctl_t - DRM ioctl function type. + * @dev: DRM device inode + * @data: private pointer of the ioctl call + * @file_priv: DRM file this ioctl was made on * - * \param inode device inode. - * \param file_priv DRM file private pointer. - * \param cmd command. - * \param arg argument. + * This is the DRM ioctl typedef. Note that drm_ioctl() has alrady copied @data + * into kernel-space, and will also copy it back, depending upon the read/write + * settings in the ioctl command code. */ typedef int drm_ioctl_t(struct drm_device *dev, void *data, struct drm_file *file_priv);
+/** + * drm_ioctl_compat_t - compatibility DRM ioctl function type. + * @filp: file pointer + * @cmd: ioctl command code + * @arg: DRM file this ioctl was made on + * + * Just a typedef to make declaring an array of compatibility handlers easier. + * New drivers shouldn't screw up the structure layout for their ioctl + * structures and hence never need this. + */ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, unsigned long arg);
#define DRM_IOCTL_NR(n) _IOC_NR(n) #define DRM_MAJOR 226
-#define DRM_AUTH 0x1 -#define DRM_MASTER 0x2 -#define DRM_ROOT_ONLY 0x4 -#define DRM_CONTROL_ALLOW 0x8 -#define DRM_UNLOCKED 0x10 -#define DRM_RENDER_ALLOW 0x20 +/** + * enum drm_ioctl_flags - DRM ioctl flags + * + * Various flags that can be set in &drm_ioctl_desc.flags to control how + * userspace can use a given ioctl. + */ +enum drm_ioctl_flags { + /** + * @DRM_AUTH: + * + * This is for ioctl which are used for rendering, and require that the + * file descriptor is either for a render node, or if it's a + * legacy/primary node, then it must be authenticated. + */ + DRM_AUTH = BIT(0), + /** + * @DRM_MASTER: + * + * This must be set for any ioctl which can change the modeset or + * display state. Userspace must call the ioctl through a primary node, + * while it is the active master. + * + * Note that read-only modeset ioctl can also be called by + * unauthenticated clients, or when a master is not the currently active + * one. + */ + DRM_MASTER = BIT(1), + /** + * @DRM_ROOT_ONLY: + * + * Anything that could potentially wreak a master file descriptor needs + * to have this flag set. Current that's only for the SETMASTER and + * DROPMASTER ioctl, which e.g. logind can call to force a non-behaving + * master (display compositor) into compliance. + * + * This is equivalent to callers with the SYSADMIN capability. + */ + DRM_ROOT_ONLY = BIT(2), + /** + * @DRM_CONTROL_ALLOW: + * + * Deprecated, do not use. Control nodes are in the process of getting + * removed. + */ + DRM_CONTROL_ALLOW = BIT(3), + /** + * @DRM_UNLOCKED: + * + * Whether &drm_ioctl_desc.func should be called with the DRM BKL held + * or not. Enforced as the default for all modern drivers, hence there + * should never be a need to set this flag. + */ + DRM_UNLOCKED = BIT(4), + /** + * @DRM_RENDER_ALLOW: + * + * This is used for all ioctl needed for rendering only, for drivers + * which support render nodes. This should be all new render drivers, + * and hence it should be always set for any ioctl with DRM_AUTH set. + * Note though that read-only query ioctl might have this set, but have + * not set DRM_AUTH because they do not require authentication. + */ + DRM_RENDER_ALLOW = BIT(5), +};
+/** + * struct drm_ioctl_desc - DRM driver ioctl entry + * @cmd: ioctl command number, without flags + * @flags: a bitmask of &enum drm_ioctl_flags + * @func: handler for this ioctl + * @name: user-readable name for debug output + * + * For convenience it's easier to create these using the DRM_IOCTL_DEF_DRV() + * macro. + */ struct drm_ioctl_desc { unsigned int cmd; - int flags; + enum drm_ioctl_flags flags; drm_ioctl_t *func; const char *name; };
/** - * Creates a driver or general drm_ioctl_desc array entry for the given - * ioctl, for use by drm_ioctl(). + * DRM_IOCTL_DEF_DRV() - helper macro to fill out a &struct drm_ioctl_desc + * @ioctl: ioctl command suffix + * @_func: handler for the ioctl + * @_flags: a bitmask of &enum drm_ioctl_flags + * + * Small helper macro to create a &struct drm_ioctl_desc entry. The ioctl + * command number is constructed by prepending ``DRM_IOCTL_`` and passing that + * to DRM_IOCTL_NR(). */ - #define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \ [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \ .cmd = DRM_IOCTL_##ioctl, \
Also unify/merge with the existing stuff.
I was a bit torn where to put this, but in the end I decided to put all the ioctl/sysfs/debugfs stuff into drm-uapi.rst. That means we have a bit a split with the other uapi related stuff used internally, like drm_file.[hc], but I think overall this makes more sense.
If it's too confusing we can always add more cross-links to make it more discoverable. But the auto-sprinkling of links kernel-doc already does seems sufficient.
Also for prettier docs and more cross-links, switch the internal defines over to an enum, as usual.
v2: Update kerneldoc fro drm_compat_ioctl too (caught by 0day), plus a bit more drive-by polish.
v3: Fix typo, spotted by xerpi on irc (Sergi).
Cc: Sergi Granell xerpi.g.12@gmail.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- Documentation/gpu/drm-internals.rst | 50 ---------------- Documentation/gpu/drm-uapi.rst | 14 +++++ drivers/gpu/drm/drm_ioc32.c | 76 ++++++++++++----------- drivers/gpu/drm/drm_ioctl.c | 50 +++++++++++++++- include/drm/drm_ioctl.h | 116 +++++++++++++++++++++++++++++++----- 5 files changed, 203 insertions(+), 103 deletions(-)
diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index a09c721f9e89..babfb6143bd9 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -255,56 +255,6 @@ File Operations .. kernel-doc:: drivers/gpu/drm/drm_file.c :export:
-IOCTLs ------- - -struct drm_ioctl_desc *ioctls; int num_ioctls; - Driver-specific ioctls descriptors table. - -Driver-specific ioctls numbers start at DRM_COMMAND_BASE. The ioctls -descriptors table is indexed by the ioctl number offset from the base -value. Drivers can use the DRM_IOCTL_DEF_DRV() macro to initialize -the table entries. - -:: - - DRM_IOCTL_DEF_DRV(ioctl, func, flags) - -``ioctl`` is the ioctl name. Drivers must define the DRM_##ioctl and -DRM_IOCTL_##ioctl macros to the ioctl number offset from -DRM_COMMAND_BASE and the ioctl number respectively. The first macro is -private to the device while the second must be exposed to userspace in a -public header. - -``func`` is a pointer to the ioctl handler function compatible with the -``drm_ioctl_t`` type. - -:: - - typedef int drm_ioctl_t(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -``flags`` is a bitmask combination of the following values. It restricts -how the ioctl is allowed to be called. - -- DRM_AUTH - Only authenticated callers allowed - -- DRM_MASTER - The ioctl can only be called on the master file handle - -- DRM_ROOT_ONLY - Only callers with the SYSADMIN capability allowed - -- DRM_CONTROL_ALLOW - The ioctl can only be called on a control - device - -- DRM_UNLOCKED - The ioctl handler will be called without locking the - DRM global mutex. This is the enforced default for kms drivers (i.e. - using the DRIVER_MODESET flag) and hence shouldn't be used any more - for new drivers. - -.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c - :export: - - Misc Utilities ==============
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 8b0f0e403f0c..858457567d3d 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -160,6 +160,20 @@ other hand, a driver requires shared state between clients which is visible to user-space and accessible beyond open-file boundaries, they cannot support render nodes.
+IOCTL Support on Device Nodes +============================= + +.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c + :doc: driver specific ioctls + +.. kernel-doc:: include/drm/drm_ioctl.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c + :export: + +.. kernel-doc:: drivers/gpu/drm/drm_ioc32.c + :export:
Testing and validation ====================== diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c index b134482f4022..0fa7827cb0fd 100644 --- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c @@ -1,4 +1,4 @@ -/** +/* * \file drm_ioc32.c * * 32-bit ioctl compatibility routines for the DRM. @@ -72,15 +72,15 @@ #define DRM_IOCTL_MODE_ADDFB232 DRM_IOWR(0xb8, drm_mode_fb_cmd232_t)
typedef struct drm_version_32 { - int version_major; /**< Major version */ - int version_minor; /**< Minor version */ - int version_patchlevel; /**< Patch level */ - u32 name_len; /**< Length of name buffer */ - u32 name; /**< Name of driver */ - u32 date_len; /**< Length of date buffer */ - u32 date; /**< User-space buffer to hold date */ - u32 desc_len; /**< Length of desc buffer */ - u32 desc; /**< User-space buffer to hold desc */ + int version_major; /* Major version */ + int version_minor; /* Minor version */ + int version_patchlevel; /* Patch level */ + u32 name_len; /* Length of name buffer */ + u32 name; /* Name of driver */ + u32 date_len; /* Length of date buffer */ + u32 date; /* User-space buffer to hold date */ + u32 desc_len; /* Length of desc buffer */ + u32 desc; /* User-space buffer to hold desc */ } drm_version32_t;
static int compat_drm_version(struct file *file, unsigned int cmd, @@ -126,8 +126,8 @@ static int compat_drm_version(struct file *file, unsigned int cmd, }
typedef struct drm_unique32 { - u32 unique_len; /**< Length of unique */ - u32 unique; /**< Unique name for driver instantiation */ + u32 unique_len; /* Length of unique */ + u32 unique; /* Unique name for driver instantiation */ } drm_unique32_t;
static int compat_drm_getunique(struct file *file, unsigned int cmd, @@ -180,12 +180,12 @@ static int compat_drm_setunique(struct file *file, unsigned int cmd, }
typedef struct drm_map32 { - u32 offset; /**< Requested physical address (0 for SAREA)*/ - u32 size; /**< Requested physical size (bytes) */ - enum drm_map_type type; /**< Type of memory to map */ - enum drm_map_flags flags; /**< Flags */ - u32 handle; /**< User-space: "Handle" to pass to mmap() */ - int mtrr; /**< MTRR slot used */ + u32 offset; /* Requested physical address (0 for SAREA)*/ + u32 size; /* Requested physical size (bytes) */ + enum drm_map_type type; /* Type of memory to map */ + enum drm_map_flags flags; /* Flags */ + u32 handle; /* User-space: "Handle" to pass to mmap() */ + int mtrr; /* MTRR slot used */ } drm_map32_t;
static int compat_drm_getmap(struct file *file, unsigned int cmd, @@ -286,12 +286,12 @@ static int compat_drm_rmmap(struct file *file, unsigned int cmd, }
typedef struct drm_client32 { - int idx; /**< Which client desired? */ - int auth; /**< Is client authenticated? */ - u32 pid; /**< Process ID */ - u32 uid; /**< User ID */ - u32 magic; /**< Magic */ - u32 iocs; /**< Ioctl count */ + int idx; /* Which client desired? */ + int auth; /* Is client authenticated? */ + u32 pid; /* Process ID */ + u32 uid; /* User ID */ + u32 magic; /* Magic */ + u32 iocs; /* Ioctl count */ } drm_client32_t;
static int compat_drm_getclient(struct file *file, unsigned int cmd, @@ -366,12 +366,12 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd, }
typedef struct drm_buf_desc32 { - int count; /**< Number of buffers of this size */ - int size; /**< Size in bytes */ - int low_mark; /**< Low water mark */ - int high_mark; /**< High water mark */ + int count; /* Number of buffers of this size */ + int size; /* Size in bytes */ + int low_mark; /* Low water mark */ + int high_mark; /* High water mark */ int flags; - u32 agp_start; /**< Start address in the AGP aperture */ + u32 agp_start; /* Start address in the AGP aperture */ } drm_buf_desc32_t;
static int compat_drm_addbufs(struct file *file, unsigned int cmd, @@ -1111,13 +1111,18 @@ static drm_ioctl_compat_t *drm_compat_ioctls[] = { };
/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/drm. + * drm_compat_ioctl - 32bit IOCTL compatibility handler for DRM drivers + * @filp: file this ioctl is called on + * @cmd: ioctl cmd number + * @arg: user argument + * + * Compatibility handler for 32 bit userspace running on 64 kernels. All actual + * IOCTL handling is forwarded to drm_ioctl(), while marshalling structures as + * appropriate. Note that this only handles DRM core IOCTLs, if the driver has + * botched IOCTL itself, it must handle those by wrapping this function. * - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. + * Returns: + * Zero on success, negative error code on failure. */ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -1141,5 +1146,4 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return ret; } - EXPORT_SYMBOL(drm_compat_ioctl); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 7f4f4f48e390..f908ea94b784 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -647,13 +647,59 @@ static const struct drm_ioctl_desc drm_ioctls[] = { #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
/** + * DOC: driver specific ioctls + * + * First things first, driver private IOCTLs should only be needed for drivers + * supporting rendering. Kernel modesetting is all standardized, and extended + * through properties. There are a few exceptions in some existing drivers, + * which define IOCTL for use by the display DRM master, but they all predate + * properties. + * + * Now if you do have a render driver you always have to support it through + * driver private properties. There's a few steps needed to wire all the things + * up. + * + * First you need to define the structure for your IOCTL in your driver private + * UAPI header in ``include/uapi/drm/my_driver_drm.h``:: + * + * struct my_driver_operation { + * u32 some_thing; + * u32 another_thing; + * }; + * + * Please make sure that you follow all the best practices from + * ``Documentation/ioctl/botching-up-ioctls.txt``. Note that drm_ioctl() + * automatically zero-extends structures, hence make sure you can add more stuff + * at the end, i.e. don't put a variable sized array there. + * + * Then you need to define your IOCTL number, using one of DRM_IO(), DRM_IOR(), + * DRM_IOW() or DRM_IOWR(). It must start with the DRM_IOCTL_ prefix:: + * + * ##define DRM_IOCTL_MY_DRIVER_OPERATION \ + * DRM_IOW(DRM_COMMAND_BASE, struct my_driver_operation) + * + * DRM driver private IOCTL must be in the range from DRM_COMMAND_BASE to + * DRM_COMMAND_END. Finally you need an array of &struct drm_ioctl_desc to wire + * up the handlers and set the access rights: + * + * static const struct drm_ioctl_desc my_driver_ioctls[] = { + * DRM_IOCTL_DEF_DRV(MY_DRIVER_OPERATION, my_driver_operation, + * DRM_AUTH|DRM_RENDER_ALLOW), + * }; + * + * And then assign this to the &drm_driver.ioctls field in your driver + * structure. + */ + +/** * drm_ioctl - ioctl callback implementation for DRM drivers * @filp: file this ioctl is called on * @cmd: ioctl cmd number * @arg: user argument * - * Looks up the ioctl function in the ::ioctls table, checking for root - * previleges if so required, and dispatches to the respective function. + * Looks up the ioctl function in the DRM core and the driver dispatch table, + * stored in &drm_driver.ioctls. It checks for necessary permission by calling + * drm_ioctl_permit(), and dispatches to the respective function. * * Returns: * Zero on success, negative error code on failure. diff --git a/include/drm/drm_ioctl.h b/include/drm/drm_ioctl.h index f17ee077f649..ee03b3c44b3b 100644 --- a/include/drm/drm_ioctl.h +++ b/include/drm/drm_ioctl.h @@ -33,6 +33,7 @@ #define _DRM_IOCTL_H_
#include <linux/types.h> +#include <linux/bitops.h>
#include <asm/ioctl.h>
@@ -41,41 +42,126 @@ struct drm_file; struct file;
/** - * Ioctl function type. + * drm_ioctl_t - DRM ioctl function type. + * @dev: DRM device inode + * @data: private pointer of the ioctl call + * @file_priv: DRM file this ioctl was made on * - * \param inode device inode. - * \param file_priv DRM file private pointer. - * \param cmd command. - * \param arg argument. + * This is the DRM ioctl typedef. Note that drm_ioctl() has alrady copied @data + * into kernel-space, and will also copy it back, depending upon the read/write + * settings in the ioctl command code. */ typedef int drm_ioctl_t(struct drm_device *dev, void *data, struct drm_file *file_priv);
+/** + * drm_ioctl_compat_t - compatibility DRM ioctl function type. + * @filp: file pointer + * @cmd: ioctl command code + * @arg: DRM file this ioctl was made on + * + * Just a typedef to make declaring an array of compatibility handlers easier. + * New drivers shouldn't screw up the structure layout for their ioctl + * structures and hence never need this. + */ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, unsigned long arg);
#define DRM_IOCTL_NR(n) _IOC_NR(n) #define DRM_MAJOR 226
-#define DRM_AUTH 0x1 -#define DRM_MASTER 0x2 -#define DRM_ROOT_ONLY 0x4 -#define DRM_CONTROL_ALLOW 0x8 -#define DRM_UNLOCKED 0x10 -#define DRM_RENDER_ALLOW 0x20 +/** + * enum drm_ioctl_flags - DRM ioctl flags + * + * Various flags that can be set in &drm_ioctl_desc.flags to control how + * userspace can use a given ioctl. + */ +enum drm_ioctl_flags { + /** + * @DRM_AUTH: + * + * This is for ioctl which are used for rendering, and require that the + * file descriptor is either for a render node, or if it's a + * legacy/primary node, then it must be authenticated. + */ + DRM_AUTH = BIT(0), + /** + * @DRM_MASTER: + * + * This must be set for any ioctl which can change the modeset or + * display state. Userspace must call the ioctl through a primary node, + * while it is the active master. + * + * Note that read-only modeset ioctl can also be called by + * unauthenticated clients, or when a master is not the currently active + * one. + */ + DRM_MASTER = BIT(1), + /** + * @DRM_ROOT_ONLY: + * + * Anything that could potentially wreak a master file descriptor needs + * to have this flag set. Current that's only for the SETMASTER and + * DROPMASTER ioctl, which e.g. logind can call to force a non-behaving + * master (display compositor) into compliance. + * + * This is equivalent to callers with the SYSADMIN capability. + */ + DRM_ROOT_ONLY = BIT(2), + /** + * @DRM_CONTROL_ALLOW: + * + * Deprecated, do not use. Control nodes are in the process of getting + * removed. + */ + DRM_CONTROL_ALLOW = BIT(3), + /** + * @DRM_UNLOCKED: + * + * Whether &drm_ioctl_desc.func should be called with the DRM BKL held + * or not. Enforced as the default for all modern drivers, hence there + * should never be a need to set this flag. + */ + DRM_UNLOCKED = BIT(4), + /** + * @DRM_RENDER_ALLOW: + * + * This is used for all ioctl needed for rendering only, for drivers + * which support render nodes. This should be all new render drivers, + * and hence it should be always set for any ioctl with DRM_AUTH set. + * Note though that read-only query ioctl might have this set, but have + * not set DRM_AUTH because they do not require authentication. + */ + DRM_RENDER_ALLOW = BIT(5), +};
+/** + * struct drm_ioctl_desc - DRM driver ioctl entry + * @cmd: ioctl command number, without flags + * @flags: a bitmask of &enum drm_ioctl_flags + * @func: handler for this ioctl + * @name: user-readable name for debug output + * + * For convenience it's easier to create these using the DRM_IOCTL_DEF_DRV() + * macro. + */ struct drm_ioctl_desc { unsigned int cmd; - int flags; + enum drm_ioctl_flags flags; drm_ioctl_t *func; const char *name; };
/** - * Creates a driver or general drm_ioctl_desc array entry for the given - * ioctl, for use by drm_ioctl(). + * DRM_IOCTL_DEF_DRV() - helper macro to fill out a &struct drm_ioctl_desc + * @ioctl: ioctl command suffix + * @_func: handler for the ioctl + * @_flags: a bitmask of &enum drm_ioctl_flags + * + * Small helper macro to create a &struct drm_ioctl_desc entry. The ioctl + * command number is constructed by prepending ``DRM_IOCTL_`` and passing that + * to DRM_IOCTL_NR(). */ - #define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \ [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \ .cmd = DRM_IOCTL_##ioctl, \
Discussed with Noralf on the list a bit.
An open question is tinydrm vs. drm_panel, but until we have a clear idea what's really needed in that space, I think it's best to just move forward with what we have.
Cc: Noralf Trønnes noralf@tronnes.org Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- Documentation/gpu/todo.rst | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+)
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 7dc6de07a3bc..479bb040f6d4 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -99,6 +99,30 @@ events for atomic commits correctly. But fixing these bugs is good anyway.
Contact: Daniel Vetter, respective driver maintainers
+Better manual-upload support for atomic +--------------------------------------- + +This would be especially useful for tinydrm: + +- Add a struct drm_rect dirty_clip to drm_crtc_state. When duplicating the + crtc state, clear that to the max values, x/y = 0 and w/h = MAX_INT, in + __drm_atomic_helper_crtc_duplicate_state(). + +- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm_ + prefix ofc and using drm_fb_. drm_framebuffer.c makes sense since this + is a function useful to implement the fb->dirty function. + +- Create a new drm_fb_dirty function which does essentially what e.g. + mipi_dbi_fb_dirty does. You can use e.g. drm_atomic_helper_update_plane as the + template. But instead of doing a simple full-screen plane update, this new + helper also sets crtc_state->dirty_clip to the right coordinates. And of + course it needs to check whether the fb is actually active (and maybe where), + so there's some book-keeping involved. There's also some good fun involved in + scaling things appropriately. For that case we might simply give up and + declare the entire area covered by the plane as dirty. + +Contact: Noralf Trønnes, Daniel Vetter + Fallout from atomic KMS -----------------------
@@ -313,5 +337,51 @@ Contact: Daniel Vetter Driver Specific ===============
+tinydrm +------- + +Tinydrm is the helper driver for really simple fb drivers. The goal is to make +those drivers as simple as possible, so lots of room for refactoring: + +- backlight helpers, probably best to put them into a new drm_backlight.c. + This is because drivers/video is de-facto unmaintained. We could also + move drivers/video/backlight to drivers/gpu/backlight and take it all + over within drm-misc, but that's more work. + +- spi helpers, probably best put into spi core/helper code. Thierry said + the spi maintainer is fast&reactive, so shouldn't be a big issue. + +- extract the mipi-dbi helper (well, the non-tinydrm specific parts at + least) into a separate helper, like we have for mipi-dsi already. Or follow + one of the ideas for having a shared dsi/dbi helper, abstracting away the + transport details more. + +- tinydrm_lastclose could be drm_fb_helper_lastclose. Only thing we need + for that is to store the drm_fb_helper pointer somewhere in + drm_device->mode_config. And then we could roll that out to all the + drivers. + +- tinydrm_gem_cma_prime_import_sg_table should probably go into the cma + helpers, as a _vmapped variant (since not every driver needs the vmap). + And tinydrm_gem_cma_free_object could the be merged into + drm_gem_cma_free_object(). + +- tinydrm_fb_create we could move into drm_simple_pipe, only need to add + the fb_create hook to drm_simple_pipe_funcs, which would again simplify a + bunch of things (since it gives you a one-stop vfunc for simple drivers). + +- Quick aside: The unregister devm stuff is kinda getting the lifetimes of + a drm_device wrong. Doesn't matter, since everyone else gets it wrong + too :-) + +- With the fbdev pointer in dev->mode_config we could also make + suspend/resume helpers entirely generic, at least if we add a + dev->mode_config.suspend_state. We could even provide a generic pm_ops + structure with those. + +- also rework the drm_framebuffer_funcs->dirty hook wire-up, see above. + +Contact: Noralf Trønnes, Daniel Vetter + Outside DRM ===========
Den 22.03.2017 09.36, skrev Daniel Vetter:
Discussed with Noralf on the list a bit.
An open question is tinydrm vs. drm_panel, but until we have a clear idea what's really needed in that space, I think it's best to just move forward with what we have.
Cc: Noralf Trønnes noralf@tronnes.org Signed-off-by: Daniel Vetter daniel.vetter@intel.com
Thanks Daniel, Acked-by: Noralf Trønnes noralf@tronnes.org
Documentation/gpu/todo.rst | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+)
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 7dc6de07a3bc..479bb040f6d4 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -99,6 +99,30 @@ events for atomic commits correctly. But fixing these bugs is good anyway.
Contact: Daniel Vetter, respective driver maintainers
+Better manual-upload support for atomic +---------------------------------------
+This would be especially useful for tinydrm:
+- Add a struct drm_rect dirty_clip to drm_crtc_state. When duplicating the
- crtc state, clear that to the max values, x/y = 0 and w/h = MAX_INT, in
- __drm_atomic_helper_crtc_duplicate_state().
+- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm_
- prefix ofc and using drm_fb_. drm_framebuffer.c makes sense since this
- is a function useful to implement the fb->dirty function.
+- Create a new drm_fb_dirty function which does essentially what e.g.
- mipi_dbi_fb_dirty does. You can use e.g. drm_atomic_helper_update_plane as the
- template. But instead of doing a simple full-screen plane update, this new
- helper also sets crtc_state->dirty_clip to the right coordinates. And of
- course it needs to check whether the fb is actually active (and maybe where),
- so there's some book-keeping involved. There's also some good fun involved in
- scaling things appropriately. For that case we might simply give up and
- declare the entire area covered by the plane as dirty.
+Contact: Noralf Trønnes, Daniel Vetter
Fallout from atomic KMS
@@ -313,5 +337,51 @@ Contact: Daniel Vetter Driver Specific ===============
+tinydrm +-------
+Tinydrm is the helper driver for really simple fb drivers. The goal is to make +those drivers as simple as possible, so lots of room for refactoring:
+- backlight helpers, probably best to put them into a new drm_backlight.c.
- This is because drivers/video is de-facto unmaintained. We could also
- move drivers/video/backlight to drivers/gpu/backlight and take it all
- over within drm-misc, but that's more work.
+- spi helpers, probably best put into spi core/helper code. Thierry said
- the spi maintainer is fast&reactive, so shouldn't be a big issue.
+- extract the mipi-dbi helper (well, the non-tinydrm specific parts at
- least) into a separate helper, like we have for mipi-dsi already. Or follow
- one of the ideas for having a shared dsi/dbi helper, abstracting away the
- transport details more.
+- tinydrm_lastclose could be drm_fb_helper_lastclose. Only thing we need
- for that is to store the drm_fb_helper pointer somewhere in
- drm_device->mode_config. And then we could roll that out to all the
- drivers.
+- tinydrm_gem_cma_prime_import_sg_table should probably go into the cma
- helpers, as a _vmapped variant (since not every driver needs the vmap).
- And tinydrm_gem_cma_free_object could the be merged into
- drm_gem_cma_free_object().
+- tinydrm_fb_create we could move into drm_simple_pipe, only need to add
- the fb_create hook to drm_simple_pipe_funcs, which would again simplify a
- bunch of things (since it gives you a one-stop vfunc for simple drivers).
+- Quick aside: The unregister devm stuff is kinda getting the lifetimes of
- a drm_device wrong. Doesn't matter, since everyone else gets it wrong
- too :-)
+- With the fbdev pointer in dev->mode_config we could also make
- suspend/resume helpers entirely generic, at least if we add a
- dev->mode_config.suspend_state. We could even provide a generic pm_ops
- structure with those.
+- also rework the drm_framebuffer_funcs->dirty hook wire-up, see above.
+Contact: Noralf Trønnes, Daniel Vetter
Outside DRM
The core code doesn't care at all about this, it's entirely dead.
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/drm_irq.c | 8 -------- include/drm/drmP.h | 1 - 2 files changed, 9 deletions(-)
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 53a526c7b24d..4b0c7475ed13 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -810,14 +810,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, /* Return upper bound of timestamp precision error. */ *max_error = duration_ns;
- /* Check if in vblank area: - * vpos is >=0 in video scanout area, but negative - * within vblank area, counting down the number of lines until - * start of scanout. - */ - if (vbl_status & DRM_SCANOUTPOS_IN_VBLANK) - ret |= DRM_VBLANKTIME_IN_VBLANK; - /* Convert scanout position into elapsed time at raw_time query * since start of scanout at first display scanline. delta_ns * can be negative if start of scanout hasn't happened yet. diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 248d2408e56b..27ecfcdbf752 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -323,7 +323,6 @@ struct pci_controller; /* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 #define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) -#define DRM_VBLANKTIME_IN_VBLANK (1 << 1)
/* get_scanout_position() return flags */ #define DRM_SCANOUTPOS_VALID (1 << 0)
On Wed, Mar 22, 2017 at 09:36:11AM +0100, Daniel Vetter wrote:
The core code doesn't care at all about this, it's entirely dead.
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/drm_irq.c | 8 -------- include/drm/drmP.h | 1 - 2 files changed, 9 deletions(-)
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 53a526c7b24d..4b0c7475ed13 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -810,14 +810,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, /* Return upper bound of timestamp precision error. */ *max_error = duration_ns;
- /* Check if in vblank area:
* vpos is >=0 in video scanout area, but negative
* within vblank area, counting down the number of lines until
* start of scanout.
*/
- if (vbl_status & DRM_SCANOUTPOS_IN_VBLANK)
ret |= DRM_VBLANKTIME_IN_VBLANK;
Indeed nothing seems to look at it. And dropping it shouldn't change anything as we still always set the other bit, so the 'ret > 0' check in the caller should still work correctly.
Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com
/* Convert scanout position into elapsed time at raw_time query * since start of scanout at first display scanline. delta_ns * can be negative if start of scanout hasn't happened yet. diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 248d2408e56b..27ecfcdbf752 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -323,7 +323,6 @@ struct pci_controller; /* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 #define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) -#define DRM_VBLANKTIME_IN_VBLANK (1 << 1)
/* get_scanout_position() return flags */
#define DRM_SCANOUTPOS_VALID (1 << 0)
2.11.0
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
There's really no reason for anything more: - Calling this while the crtc vblank stuff isn't set up is a driver bug. Those places arlready DRM_ERROR. - Calling this when the crtc is off is either a driver bug (callin drm_crtc_handle_vblank at the wrong time) or a core bug (for anything else). Again, we DRM_ERROR. - EINVAL is checked at higher levels already, and if we'd use struct drm_crtc * instead of (dev, pipe) it would be real obvious that those are again core bugs.
The only valid failure mode is crap hardware that couldn't sample a useful timestamp, to ask the core to just grab a not-so-accurate timestampe. Bool is perfectly fine for that.
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Cc: Eric Anholt eric@anholt.net Cc: Rob Clark robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Ben Skeggs bskeggs@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 +++---- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++++------ drivers/gpu/drm/drm_irq.c | 37 +++++++++++-------------------- drivers/gpu/drm/i915/i915_irq.c | 8 +++---- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 12 +++++----- drivers/gpu/drm/nouveau/nouveau_display.c | 4 ++-- drivers/gpu/drm/nouveau/nouveau_display.h | 4 ++-- drivers/gpu/drm/radeon/radeon_drv.c | 8 +++---- drivers/gpu/drm/radeon/radeon_kms.c | 14 ++++++------ drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- include/drm/drmP.h | 1 - include/drm/drm_drv.h | 7 +++--- include/drm/drm_irq.h | 10 ++++----- 14 files changed, 59 insertions(+), 72 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c8860f05bfb9..acd8631d8024 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1768,10 +1768,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags); +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags); long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 55f951bcc91f..ac42f707c046 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -838,19 +838,19 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) * * Gets the timestamp on the requested crtc based on the * scanout position. (all asics). - * Returns postive status flags on success, negative error on failure. + * Returns true on success, false on failure. */ -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags) +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags) { struct drm_crtc *crtc; struct amdgpu_device *adev = dev->dev_private;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; }
/* Get associated drm_crtc: */ @@ -859,7 +859,7 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, /* This can occur on driver load if some component fails to * initialize completely and driver is unloaded */ DRM_ERROR("Uninitialized crtc %d\n", pipe); - return -EINVAL; + return false; }
/* Helper routine in DRM core does all the work: */ diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 4b0c7475ed13..2121ea29e1b2 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -722,43 +722,32 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * active. Higher level code is expected to handle this. * * Returns: - * Negative value on error, failure or if not supported in current - * video mode: - * - * -EINVAL Invalid CRTC. - * -EAGAIN Temporary unavailable, e.g., called before initial modeset. - * -ENOTSUPP Function not supported in current display mode. - * -EIO Failed, e.g., due to failed scanout position query. - * - * Returns or'ed positive status flags on success: - * - * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. - * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. * + * Returns true on success, and false on failure, i.e. when no accurate + * timestamp could be acquired. */ -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags, - const struct drm_display_mode *mode) +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, + unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags, + const struct drm_display_mode *mode) { struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status; - int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD; int vpos, hpos, i; int delta_ns, duration_ns;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; }
/* Scanout position query not supported? Should not happen. */ if (!dev->driver->get_scanout_position) { DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); - return -EIO; + return false; }
/* If mode timing undefined, just return as no-op: @@ -766,7 +755,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, */ if (mode->crtc_clock == 0) { DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); - return -EAGAIN; + return false; }
/* Get current scanout position with system timestamp. @@ -790,7 +779,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", pipe, vbl_status); - return -EIO; + return false; }
/* Compute uncertainty in timestamp of scanout position query. */ @@ -834,7 +823,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i);
- return ret; + return true; } EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 26aa1c170b43..df149d159ce7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -964,7 +964,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; }
-static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, +static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags) @@ -974,19 +974,19 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; }
/* Get drm_crtc to timestamp: */ crtc = intel_get_crtc_for_pipe(dev_priv, pipe); if (crtc == NULL) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; }
if (!crtc->base.hwmode.crtc_clock) { DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); - return -EBUSY; + return false; }
/* Helper routine in DRM core does all the work: */ diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 41ccd2a15d3c..655700eb42ba 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -595,23 +595,23 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, return ret; }
-static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags) +static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags) { struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc;
if (pipe < 0 || pipe >= priv->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", pipe); - return -EINVAL; + return false; }
crtc = priv->crtcs[pipe]; if (!crtc) { DRM_ERROR("Invalid crtc %d\n", pipe); - return -EINVAL; + return false; }
return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 33269c7df30f..42f18b0b9c43 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -156,7 +156,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, return 0; }
-int +bool nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *time, unsigned flags) { @@ -174,7 +174,7 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, } }
- return -EINVAL; + return false; }
static void diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 4a75df06c139..bc9d1e7b0117 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -71,8 +71,8 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); -int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, - struct timeval *, unsigned); +bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, + struct timeval *, unsigned);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 312436a8d9e5..6d79b5c2805b 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,10 +114,10 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags); +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags); void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index a32a62e03a44..9afe72010c64 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -868,25 +868,25 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) * * Gets the timestamp on the requested crtc based on the * scanout position. (all asics). - * Returns postive status flags on success, negative error on failure. + * Returns true on success, false on failure. */ -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, - int *max_error, - struct timeval *vblank_time, - unsigned flags) +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, + int *max_error, + struct timeval *vblank_time, + unsigned flags) { struct drm_crtc *drmcrtc; struct radeon_device *rdev = dev->dev_private;
if (crtc < 0 || crtc >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", crtc); - return -EINVAL; + return false; }
/* Get associated drm_crtc: */ drmcrtc = &rdev->mode_info.crtcs[crtc]->base; if (!drmcrtc) - return -EINVAL; + return false;
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 24edd0c22cc9..74260990b6bf 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -270,7 +270,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, return ret; }
-int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags) { diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index dffce6293d87..8a5d0e12ee02 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -450,7 +450,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 27ecfcdbf752..6304de7e041e 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -322,7 +322,6 @@ struct pci_controller;
/* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 -#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0)
/* get_scanout_position() return flags */ #define DRM_SCANOUTPOS_VALID (1 << 0) diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index d0b5f363bfa1..da78e248d9d8 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -316,11 +316,10 @@ struct drm_driver { * * Returns: * - * Zero if timestamping isn't supported in current display mode or a - * negative number on failure. A positive status code on success, - * which describes how the vblank_time timestamp was computed. + * True on success, false on failure, which means the core should + * fallback to a simple timestamp taken in drm_crtc_handle_vblank(). */ - int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, + bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags); diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index cf0be6594c8c..f0d5ccf9b282 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -153,11 +153,11 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc); void drm_vblank_cleanup(struct drm_device *dev); u32 drm_accurate_vblank_count(struct drm_crtc *crtc);
-int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - unsigned int pipe, int *max_error, - struct timeval *vblank_time, - unsigned flags, - const struct drm_display_mode *mode); +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, + unsigned int pipe, int *max_error, + struct timeval *vblank_time, + unsigned flags, + const struct drm_display_mode *mode); void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode);
On Wed, 22 Mar 2017, Daniel Vetter daniel.vetter@ffwll.ch wrote:
There's really no reason for anything more:
- Calling this while the crtc vblank stuff isn't set up is a driver bug. Those places arlready DRM_ERROR.
- Calling this when the crtc is off is either a driver bug (callin drm_crtc_handle_vblank at the wrong time) or a core bug (for anything else). Again, we DRM_ERROR.
- EINVAL is checked at higher levels already, and if we'd use struct drm_crtc * instead of (dev, pipe) it would be real obvious that those are again core bugs.
The only valid failure mode is crap hardware that couldn't sample a useful timestamp, to ask the core to just grab a not-so-accurate timestampe. Bool is perfectly fine for that.
FWIW, I'm not all that thrilled about changing int returns to bools, because it changes the check for success from !ret to ret, and the compiler won't help you. Sure, there aren't many call sites for the function, but, case in point, you forgot to change that lone call site. Though it still works by coincidence.
BR, Jani.
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Cc: Eric Anholt eric@anholt.net Cc: Rob Clark robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Ben Skeggs bskeggs@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 +++---- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++++------ drivers/gpu/drm/drm_irq.c | 37 +++++++++++-------------------- drivers/gpu/drm/i915/i915_irq.c | 8 +++---- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 12 +++++----- drivers/gpu/drm/nouveau/nouveau_display.c | 4 ++-- drivers/gpu/drm/nouveau/nouveau_display.h | 4 ++-- drivers/gpu/drm/radeon/radeon_drv.c | 8 +++---- drivers/gpu/drm/radeon/radeon_kms.c | 14 ++++++------ drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- include/drm/drmP.h | 1 - include/drm/drm_drv.h | 7 +++--- include/drm/drm_irq.h | 10 ++++----- 14 files changed, 59 insertions(+), 72 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c8860f05bfb9..acd8631d8024 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1768,10 +1768,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
+bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 55f951bcc91f..ac42f707c046 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -838,19 +838,19 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe)
- Gets the timestamp on the requested crtc based on the
- scanout position. (all asics).
- Returns postive status flags on success, negative error on failure.
*/
- Returns true on success, false on failure.
-int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
+bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
{ struct drm_crtc *crtc; struct amdgpu_device *adev = dev->dev_private;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
/* Get associated drm_crtc: */
@@ -859,7 +859,7 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, /* This can occur on driver load if some component fails to * initialize completely and driver is unloaded */ DRM_ERROR("Uninitialized crtc %d\n", pipe);
return -EINVAL;
return false;
}
/* Helper routine in DRM core does all the work: */
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 4b0c7475ed13..2121ea29e1b2 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -722,43 +722,32 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
- active. Higher level code is expected to handle this.
- Returns:
- Negative value on error, failure or if not supported in current
- video mode:
- -EINVAL Invalid CRTC.
- -EAGAIN Temporary unavailable, e.g., called before initial modeset.
- -ENOTSUPP Function not supported in current display mode.
- -EIO Failed, e.g., due to failed scanout position query.
- Returns or'ed positive status flags on success:
- DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping.
- DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
- Returns true on success, and false on failure, i.e. when no accurate
*/
- timestamp could be acquired.
-int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode)
+bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode)
{ struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status;
int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD; int vpos, hpos, i; int delta_ns, duration_ns;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
/* Scanout position query not supported? Should not happen. */ if (!dev->driver->get_scanout_position) { DRM_ERROR("Called from driver w/o get_scanout_position()!?\n");
return -EIO;
return false;
}
/* If mode timing undefined, just return as no-op:
@@ -766,7 +755,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, */ if (mode->crtc_clock == 0) { DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe);
return -EAGAIN;
return false;
}
/* Get current scanout position with system timestamp.
@@ -790,7 +779,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", pipe, vbl_status);
return -EIO;
return false;
}
/* Compute uncertainty in timestamp of scanout position query. */
@@ -834,7 +823,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i);
- return ret;
- return true;
} EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 26aa1c170b43..df149d159ce7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -964,7 +964,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; }
-static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, +static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags) @@ -974,19 +974,19 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
/* Get drm_crtc to timestamp: */ crtc = intel_get_crtc_for_pipe(dev_priv, pipe); if (crtc == NULL) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
if (!crtc->base.hwmode.crtc_clock) { DRM_DEBUG_KMS("crtc %u is disabled\n", pipe);
return -EBUSY;
return false;
}
/* Helper routine in DRM core does all the work: */
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 41ccd2a15d3c..655700eb42ba 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -595,23 +595,23 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, return ret; }
-static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
+static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
{ struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc;
if (pipe < 0 || pipe >= priv->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", pipe);
return -EINVAL;
return false;
}
crtc = priv->crtcs[pipe]; if (!crtc) { DRM_ERROR("Invalid crtc %d\n", pipe);
return -EINVAL;
return false;
}
return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 33269c7df30f..42f18b0b9c43 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -156,7 +156,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, return 0; }
-int +bool nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *time, unsigned flags) { @@ -174,7 +174,7 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, } }
- return -EINVAL;
- return false;
}
static void diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 4a75df06c139..bc9d1e7b0117 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -71,8 +71,8 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); -int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *,
struct timeval *, unsigned);
+bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *,
struct timeval *, unsigned);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 312436a8d9e5..6d79b5c2805b 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,10 +114,10 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
+bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index a32a62e03a44..9afe72010c64 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -868,25 +868,25 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
- Gets the timestamp on the requested crtc based on the
- scanout position. (all asics).
- Returns postive status flags on success, negative error on failure.
*/
- Returns true on success, false on failure.
-int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
+bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
{ struct drm_crtc *drmcrtc; struct radeon_device *rdev = dev->dev_private;
if (crtc < 0 || crtc >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", crtc);
return -EINVAL;
return false;
}
/* Get associated drm_crtc: */ drmcrtc = &rdev->mode_info.crtcs[crtc]->base; if (!drmcrtc)
return -EINVAL;
return false;
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 24edd0c22cc9..74260990b6bf 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -270,7 +270,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, return ret; }
-int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags) { diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index dffce6293d87..8a5d0e12ee02 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -450,7 +450,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 27ecfcdbf752..6304de7e041e 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -322,7 +322,6 @@ struct pci_controller;
/* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 -#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0)
/* get_scanout_position() return flags */ #define DRM_SCANOUTPOS_VALID (1 << 0) diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index d0b5f363bfa1..da78e248d9d8 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -316,11 +316,10 @@ struct drm_driver { * * Returns: *
* Zero if timestamping isn't supported in current display mode or a
* negative number on failure. A positive status code on success,
* which describes how the vblank_time timestamp was computed.
* True on success, false on failure, which means the core should
*/* fallback to a simple timestamp taken in drm_crtc_handle_vblank().
- int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe,
- bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags);
diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index cf0be6594c8c..f0d5ccf9b282 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -153,11 +153,11 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc); void drm_vblank_cleanup(struct drm_device *dev); u32 drm_accurate_vblank_count(struct drm_crtc *crtc);
-int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe, int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode);
+bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe, int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode);
void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode);
On Wed, Mar 22, 2017 at 12:33:35PM +0200, Jani Nikula wrote:
On Wed, 22 Mar 2017, Daniel Vetter daniel.vetter@ffwll.ch wrote:
There's really no reason for anything more:
- Calling this while the crtc vblank stuff isn't set up is a driver bug. Those places arlready DRM_ERROR.
- Calling this when the crtc is off is either a driver bug (callin drm_crtc_handle_vblank at the wrong time) or a core bug (for anything else). Again, we DRM_ERROR.
- EINVAL is checked at higher levels already, and if we'd use struct drm_crtc * instead of (dev, pipe) it would be real obvious that those are again core bugs.
The only valid failure mode is crap hardware that couldn't sample a useful timestamp, to ask the core to just grab a not-so-accurate timestampe. Bool is perfectly fine for that.
FWIW, I'm not all that thrilled about changing int returns to bools, because it changes the check for success from !ret to ret, and the compiler won't help you. Sure, there aren't many call sites for the function, but, case in point, you forgot to change that lone call site. Though it still works by coincidence.
The old call site treated > 0 as success, and 0 or anything negative as failure. That the lone caller still works is the reason why I've switched to bool, because besides all the funny values that the caller gets and ignreos, it already is.
Or did I miss something? -Daniel
BR, Jani.
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Cc: Eric Anholt eric@anholt.net Cc: Rob Clark robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Ben Skeggs bskeggs@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 +++---- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++++------ drivers/gpu/drm/drm_irq.c | 37 +++++++++++-------------------- drivers/gpu/drm/i915/i915_irq.c | 8 +++---- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 12 +++++----- drivers/gpu/drm/nouveau/nouveau_display.c | 4 ++-- drivers/gpu/drm/nouveau/nouveau_display.h | 4 ++-- drivers/gpu/drm/radeon/radeon_drv.c | 8 +++---- drivers/gpu/drm/radeon/radeon_kms.c | 14 ++++++------ drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- include/drm/drmP.h | 1 - include/drm/drm_drv.h | 7 +++--- include/drm/drm_irq.h | 10 ++++----- 14 files changed, 59 insertions(+), 72 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c8860f05bfb9..acd8631d8024 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1768,10 +1768,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
+bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 55f951bcc91f..ac42f707c046 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -838,19 +838,19 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe)
- Gets the timestamp on the requested crtc based on the
- scanout position. (all asics).
- Returns postive status flags on success, negative error on failure.
*/
- Returns true on success, false on failure.
-int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
+bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
{ struct drm_crtc *crtc; struct amdgpu_device *adev = dev->dev_private;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
/* Get associated drm_crtc: */
@@ -859,7 +859,7 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, /* This can occur on driver load if some component fails to * initialize completely and driver is unloaded */ DRM_ERROR("Uninitialized crtc %d\n", pipe);
return -EINVAL;
return false;
}
/* Helper routine in DRM core does all the work: */
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 4b0c7475ed13..2121ea29e1b2 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -722,43 +722,32 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
- active. Higher level code is expected to handle this.
- Returns:
- Negative value on error, failure or if not supported in current
- video mode:
- -EINVAL Invalid CRTC.
- -EAGAIN Temporary unavailable, e.g., called before initial modeset.
- -ENOTSUPP Function not supported in current display mode.
- -EIO Failed, e.g., due to failed scanout position query.
- Returns or'ed positive status flags on success:
- DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping.
- DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
- Returns true on success, and false on failure, i.e. when no accurate
*/
- timestamp could be acquired.
-int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode)
+bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode)
{ struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status;
int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD; int vpos, hpos, i; int delta_ns, duration_ns;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
/* Scanout position query not supported? Should not happen. */ if (!dev->driver->get_scanout_position) { DRM_ERROR("Called from driver w/o get_scanout_position()!?\n");
return -EIO;
return false;
}
/* If mode timing undefined, just return as no-op:
@@ -766,7 +755,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, */ if (mode->crtc_clock == 0) { DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe);
return -EAGAIN;
return false;
}
/* Get current scanout position with system timestamp.
@@ -790,7 +779,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", pipe, vbl_status);
return -EIO;
return false;
}
/* Compute uncertainty in timestamp of scanout position query. */
@@ -834,7 +823,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i);
- return ret;
- return true;
} EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 26aa1c170b43..df149d159ce7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -964,7 +964,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; }
-static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, +static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags) @@ -974,19 +974,19 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
/* Get drm_crtc to timestamp: */ crtc = intel_get_crtc_for_pipe(dev_priv, pipe); if (crtc == NULL) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
if (!crtc->base.hwmode.crtc_clock) { DRM_DEBUG_KMS("crtc %u is disabled\n", pipe);
return -EBUSY;
return false;
}
/* Helper routine in DRM core does all the work: */
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 41ccd2a15d3c..655700eb42ba 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -595,23 +595,23 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, return ret; }
-static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
+static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
{ struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc;
if (pipe < 0 || pipe >= priv->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", pipe);
return -EINVAL;
return false;
}
crtc = priv->crtcs[pipe]; if (!crtc) { DRM_ERROR("Invalid crtc %d\n", pipe);
return -EINVAL;
return false;
}
return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 33269c7df30f..42f18b0b9c43 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -156,7 +156,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, return 0; }
-int +bool nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *time, unsigned flags) { @@ -174,7 +174,7 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, } }
- return -EINVAL;
- return false;
}
static void diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 4a75df06c139..bc9d1e7b0117 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -71,8 +71,8 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); -int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *,
struct timeval *, unsigned);
+bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *,
struct timeval *, unsigned);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 312436a8d9e5..6d79b5c2805b 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,10 +114,10 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
+bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index a32a62e03a44..9afe72010c64 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -868,25 +868,25 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
- Gets the timestamp on the requested crtc based on the
- scanout position. (all asics).
- Returns postive status flags on success, negative error on failure.
*/
- Returns true on success, false on failure.
-int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
+bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
{ struct drm_crtc *drmcrtc; struct radeon_device *rdev = dev->dev_private;
if (crtc < 0 || crtc >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", crtc);
return -EINVAL;
return false;
}
/* Get associated drm_crtc: */ drmcrtc = &rdev->mode_info.crtcs[crtc]->base; if (!drmcrtc)
return -EINVAL;
return false;
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 24edd0c22cc9..74260990b6bf 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -270,7 +270,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, return ret; }
-int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags) { diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index dffce6293d87..8a5d0e12ee02 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -450,7 +450,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 27ecfcdbf752..6304de7e041e 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -322,7 +322,6 @@ struct pci_controller;
/* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 -#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0)
/* get_scanout_position() return flags */ #define DRM_SCANOUTPOS_VALID (1 << 0) diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index d0b5f363bfa1..da78e248d9d8 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -316,11 +316,10 @@ struct drm_driver { * * Returns: *
* Zero if timestamping isn't supported in current display mode or a
* negative number on failure. A positive status code on success,
* which describes how the vblank_time timestamp was computed.
* True on success, false on failure, which means the core should
*/* fallback to a simple timestamp taken in drm_crtc_handle_vblank().
- int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe,
- bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags);
diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index cf0be6594c8c..f0d5ccf9b282 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -153,11 +153,11 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc); void drm_vblank_cleanup(struct drm_device *dev); u32 drm_accurate_vblank_count(struct drm_crtc *crtc);
-int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe, int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode);
+bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe, int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode);
void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode);
-- Jani Nikula, Intel Open Source Technology Center
On Wed, 22 Mar 2017, Daniel Vetter daniel@ffwll.ch wrote:
On Wed, Mar 22, 2017 at 12:33:35PM +0200, Jani Nikula wrote:
On Wed, 22 Mar 2017, Daniel Vetter daniel.vetter@ffwll.ch wrote:
There's really no reason for anything more:
- Calling this while the crtc vblank stuff isn't set up is a driver bug. Those places arlready DRM_ERROR.
- Calling this when the crtc is off is either a driver bug (callin drm_crtc_handle_vblank at the wrong time) or a core bug (for anything else). Again, we DRM_ERROR.
- EINVAL is checked at higher levels already, and if we'd use struct drm_crtc * instead of (dev, pipe) it would be real obvious that those are again core bugs.
The only valid failure mode is crap hardware that couldn't sample a useful timestamp, to ask the core to just grab a not-so-accurate timestampe. Bool is perfectly fine for that.
FWIW, I'm not all that thrilled about changing int returns to bools, because it changes the check for success from !ret to ret, and the compiler won't help you. Sure, there aren't many call sites for the function, but, case in point, you forgot to change that lone call site. Though it still works by coincidence.
The old call site treated > 0 as success, and 0 or anything negative as failure. That the lone caller still works is the reason why I've switched to bool, because besides all the funny values that the caller gets and ignreos, it already is.
Or did I miss something?
Don't you think you should fix the call site too, if you insist on changing the return type?
BR, Jani.
-Daniel
BR, Jani.
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Cc: Eric Anholt eric@anholt.net Cc: Rob Clark robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Ben Skeggs bskeggs@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 +++---- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++++------ drivers/gpu/drm/drm_irq.c | 37 +++++++++++-------------------- drivers/gpu/drm/i915/i915_irq.c | 8 +++---- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 12 +++++----- drivers/gpu/drm/nouveau/nouveau_display.c | 4 ++-- drivers/gpu/drm/nouveau/nouveau_display.h | 4 ++-- drivers/gpu/drm/radeon/radeon_drv.c | 8 +++---- drivers/gpu/drm/radeon/radeon_kms.c | 14 ++++++------ drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- include/drm/drmP.h | 1 - include/drm/drm_drv.h | 7 +++--- include/drm/drm_irq.h | 10 ++++----- 14 files changed, 59 insertions(+), 72 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c8860f05bfb9..acd8631d8024 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1768,10 +1768,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
+bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 55f951bcc91f..ac42f707c046 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -838,19 +838,19 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe)
- Gets the timestamp on the requested crtc based on the
- scanout position. (all asics).
- Returns postive status flags on success, negative error on failure.
*/
- Returns true on success, false on failure.
-int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
+bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
{ struct drm_crtc *crtc; struct amdgpu_device *adev = dev->dev_private;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
/* Get associated drm_crtc: */
@@ -859,7 +859,7 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, /* This can occur on driver load if some component fails to * initialize completely and driver is unloaded */ DRM_ERROR("Uninitialized crtc %d\n", pipe);
return -EINVAL;
return false;
}
/* Helper routine in DRM core does all the work: */
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 4b0c7475ed13..2121ea29e1b2 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -722,43 +722,32 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
- active. Higher level code is expected to handle this.
- Returns:
- Negative value on error, failure or if not supported in current
- video mode:
- -EINVAL Invalid CRTC.
- -EAGAIN Temporary unavailable, e.g., called before initial modeset.
- -ENOTSUPP Function not supported in current display mode.
- -EIO Failed, e.g., due to failed scanout position query.
- Returns or'ed positive status flags on success:
- DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping.
- DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
- Returns true on success, and false on failure, i.e. when no accurate
*/
- timestamp could be acquired.
-int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode)
+bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode)
{ struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status;
int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD; int vpos, hpos, i; int delta_ns, duration_ns;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
/* Scanout position query not supported? Should not happen. */ if (!dev->driver->get_scanout_position) { DRM_ERROR("Called from driver w/o get_scanout_position()!?\n");
return -EIO;
return false;
}
/* If mode timing undefined, just return as no-op:
@@ -766,7 +755,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, */ if (mode->crtc_clock == 0) { DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe);
return -EAGAIN;
return false;
}
/* Get current scanout position with system timestamp.
@@ -790,7 +779,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", pipe, vbl_status);
return -EIO;
return false;
}
/* Compute uncertainty in timestamp of scanout position query. */
@@ -834,7 +823,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i);
- return ret;
- return true;
} EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 26aa1c170b43..df149d159ce7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -964,7 +964,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; }
-static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, +static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags) @@ -974,19 +974,19 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
/* Get drm_crtc to timestamp: */ crtc = intel_get_crtc_for_pipe(dev_priv, pipe); if (crtc == NULL) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
if (!crtc->base.hwmode.crtc_clock) { DRM_DEBUG_KMS("crtc %u is disabled\n", pipe);
return -EBUSY;
return false;
}
/* Helper routine in DRM core does all the work: */
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 41ccd2a15d3c..655700eb42ba 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -595,23 +595,23 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, return ret; }
-static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
+static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
{ struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc;
if (pipe < 0 || pipe >= priv->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", pipe);
return -EINVAL;
return false;
}
crtc = priv->crtcs[pipe]; if (!crtc) { DRM_ERROR("Invalid crtc %d\n", pipe);
return -EINVAL;
return false;
}
return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 33269c7df30f..42f18b0b9c43 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -156,7 +156,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, return 0; }
-int +bool nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *time, unsigned flags) { @@ -174,7 +174,7 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, } }
- return -EINVAL;
- return false;
}
static void diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 4a75df06c139..bc9d1e7b0117 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -71,8 +71,8 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); -int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *,
struct timeval *, unsigned);
+bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *,
struct timeval *, unsigned);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 312436a8d9e5..6d79b5c2805b 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,10 +114,10 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
+bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index a32a62e03a44..9afe72010c64 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -868,25 +868,25 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
- Gets the timestamp on the requested crtc based on the
- scanout position. (all asics).
- Returns postive status flags on success, negative error on failure.
*/
- Returns true on success, false on failure.
-int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
+bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
{ struct drm_crtc *drmcrtc; struct radeon_device *rdev = dev->dev_private;
if (crtc < 0 || crtc >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", crtc);
return -EINVAL;
return false;
}
/* Get associated drm_crtc: */ drmcrtc = &rdev->mode_info.crtcs[crtc]->base; if (!drmcrtc)
return -EINVAL;
return false;
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 24edd0c22cc9..74260990b6bf 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -270,7 +270,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, return ret; }
-int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags) { diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index dffce6293d87..8a5d0e12ee02 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -450,7 +450,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 27ecfcdbf752..6304de7e041e 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -322,7 +322,6 @@ struct pci_controller;
/* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 -#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0)
/* get_scanout_position() return flags */ #define DRM_SCANOUTPOS_VALID (1 << 0) diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index d0b5f363bfa1..da78e248d9d8 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -316,11 +316,10 @@ struct drm_driver { * * Returns: *
* Zero if timestamping isn't supported in current display mode or a
* negative number on failure. A positive status code on success,
* which describes how the vblank_time timestamp was computed.
* True on success, false on failure, which means the core should
*/* fallback to a simple timestamp taken in drm_crtc_handle_vblank().
- int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe,
- bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags);
diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index cf0be6594c8c..f0d5ccf9b282 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -153,11 +153,11 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc); void drm_vblank_cleanup(struct drm_device *dev); u32 drm_accurate_vblank_count(struct drm_crtc *crtc);
-int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe, int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode);
+bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe, int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode);
void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode);
-- Jani Nikula, Intel Open Source Technology Center
On Wed, Mar 22, 2017 at 04:05:59PM +0200, Jani Nikula wrote:
On Wed, 22 Mar 2017, Daniel Vetter daniel@ffwll.ch wrote:
On Wed, Mar 22, 2017 at 12:33:35PM +0200, Jani Nikula wrote:
On Wed, 22 Mar 2017, Daniel Vetter daniel.vetter@ffwll.ch wrote:
There's really no reason for anything more:
- Calling this while the crtc vblank stuff isn't set up is a driver bug. Those places arlready DRM_ERROR.
- Calling this when the crtc is off is either a driver bug (callin drm_crtc_handle_vblank at the wrong time) or a core bug (for anything else). Again, we DRM_ERROR.
- EINVAL is checked at higher levels already, and if we'd use struct drm_crtc * instead of (dev, pipe) it would be real obvious that those are again core bugs.
The only valid failure mode is crap hardware that couldn't sample a useful timestamp, to ask the core to just grab a not-so-accurate timestampe. Bool is perfectly fine for that.
FWIW, I'm not all that thrilled about changing int returns to bools, because it changes the check for success from !ret to ret, and the compiler won't help you. Sure, there aren't many call sites for the function, but, case in point, you forgot to change that lone call site. Though it still works by coincidence.
The old call site treated > 0 as success, and 0 or anything negative as failure. That the lone caller still works is the reason why I've switched to bool, because besides all the funny values that the caller gets and ignreos, it already is.
Or did I miss something?
Don't you think you should fix the call site too, if you insist on changing the return type?
Oops, I thought I've done that. Will fix up. -Daniel
BR, Jani.
-Daniel
BR, Jani.
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Cc: Eric Anholt eric@anholt.net Cc: Rob Clark robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Ben Skeggs bskeggs@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 +++---- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++++------ drivers/gpu/drm/drm_irq.c | 37 +++++++++++-------------------- drivers/gpu/drm/i915/i915_irq.c | 8 +++---- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 12 +++++----- drivers/gpu/drm/nouveau/nouveau_display.c | 4 ++-- drivers/gpu/drm/nouveau/nouveau_display.h | 4 ++-- drivers/gpu/drm/radeon/radeon_drv.c | 8 +++---- drivers/gpu/drm/radeon/radeon_kms.c | 14 ++++++------ drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- include/drm/drmP.h | 1 - include/drm/drm_drv.h | 7 +++--- include/drm/drm_irq.h | 10 ++++----- 14 files changed, 59 insertions(+), 72 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c8860f05bfb9..acd8631d8024 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1768,10 +1768,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
+bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 55f951bcc91f..ac42f707c046 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -838,19 +838,19 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe)
- Gets the timestamp on the requested crtc based on the
- scanout position. (all asics).
- Returns postive status flags on success, negative error on failure.
*/
- Returns true on success, false on failure.
-int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
+bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
{ struct drm_crtc *crtc; struct amdgpu_device *adev = dev->dev_private;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
/* Get associated drm_crtc: */
@@ -859,7 +859,7 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, /* This can occur on driver load if some component fails to * initialize completely and driver is unloaded */ DRM_ERROR("Uninitialized crtc %d\n", pipe);
return -EINVAL;
return false;
}
/* Helper routine in DRM core does all the work: */
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 4b0c7475ed13..2121ea29e1b2 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -722,43 +722,32 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
- active. Higher level code is expected to handle this.
- Returns:
- Negative value on error, failure or if not supported in current
- video mode:
- -EINVAL Invalid CRTC.
- -EAGAIN Temporary unavailable, e.g., called before initial modeset.
- -ENOTSUPP Function not supported in current display mode.
- -EIO Failed, e.g., due to failed scanout position query.
- Returns or'ed positive status flags on success:
- DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping.
- DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
- Returns true on success, and false on failure, i.e. when no accurate
*/
- timestamp could be acquired.
-int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode)
+bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode)
{ struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status;
int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD; int vpos, hpos, i; int delta_ns, duration_ns;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
/* Scanout position query not supported? Should not happen. */ if (!dev->driver->get_scanout_position) { DRM_ERROR("Called from driver w/o get_scanout_position()!?\n");
return -EIO;
return false;
}
/* If mode timing undefined, just return as no-op:
@@ -766,7 +755,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, */ if (mode->crtc_clock == 0) { DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe);
return -EAGAIN;
return false;
}
/* Get current scanout position with system timestamp.
@@ -790,7 +779,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", pipe, vbl_status);
return -EIO;
return false;
}
/* Compute uncertainty in timestamp of scanout position query. */
@@ -834,7 +823,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i);
- return ret;
- return true;
} EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 26aa1c170b43..df149d159ce7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -964,7 +964,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; }
-static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, +static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags) @@ -974,19 +974,19 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
/* Get drm_crtc to timestamp: */ crtc = intel_get_crtc_for_pipe(dev_priv, pipe); if (crtc == NULL) { DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
return false;
}
if (!crtc->base.hwmode.crtc_clock) { DRM_DEBUG_KMS("crtc %u is disabled\n", pipe);
return -EBUSY;
return false;
}
/* Helper routine in DRM core does all the work: */
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 41ccd2a15d3c..655700eb42ba 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -595,23 +595,23 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, return ret; }
-static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
+static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
{ struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc;
if (pipe < 0 || pipe >= priv->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", pipe);
return -EINVAL;
return false;
}
crtc = priv->crtcs[pipe]; if (!crtc) { DRM_ERROR("Invalid crtc %d\n", pipe);
return -EINVAL;
return false;
}
return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 33269c7df30f..42f18b0b9c43 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -156,7 +156,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, return 0; }
-int +bool nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *time, unsigned flags) { @@ -174,7 +174,7 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, } }
- return -EINVAL;
- return false;
}
static void diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 4a75df06c139..bc9d1e7b0117 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -71,8 +71,8 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); -int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *,
struct timeval *, unsigned);
+bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *,
struct timeval *, unsigned);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 312436a8d9e5..6d79b5c2805b 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,10 +114,10 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
+bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags);
void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index a32a62e03a44..9afe72010c64 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -868,25 +868,25 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
- Gets the timestamp on the requested crtc based on the
- scanout position. (all asics).
- Returns postive status flags on success, negative error on failure.
*/
- Returns true on success, false on failure.
-int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
+bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
{ struct drm_crtc *drmcrtc; struct radeon_device *rdev = dev->dev_private;
if (crtc < 0 || crtc >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", crtc);
return -EINVAL;
return false;
}
/* Get associated drm_crtc: */ drmcrtc = &rdev->mode_info.crtcs[crtc]->base; if (!drmcrtc)
return -EINVAL;
return false;
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 24edd0c22cc9..74260990b6bf 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -270,7 +270,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, return ret; }
-int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags) { diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index dffce6293d87..8a5d0e12ee02 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -450,7 +450,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 27ecfcdbf752..6304de7e041e 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -322,7 +322,6 @@ struct pci_controller;
/* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 -#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0)
/* get_scanout_position() return flags */ #define DRM_SCANOUTPOS_VALID (1 << 0) diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index d0b5f363bfa1..da78e248d9d8 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -316,11 +316,10 @@ struct drm_driver { * * Returns: *
* Zero if timestamping isn't supported in current display mode or a
* negative number on failure. A positive status code on success,
* which describes how the vblank_time timestamp was computed.
* True on success, false on failure, which means the core should
*/* fallback to a simple timestamp taken in drm_crtc_handle_vblank().
- int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe,
- bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags);
diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index cf0be6594c8c..f0d5ccf9b282 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -153,11 +153,11 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc); void drm_vblank_cleanup(struct drm_device *dev); u32 drm_accurate_vblank_count(struct drm_crtc *crtc);
-int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe, int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode);
+bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe, int *max_error,
struct timeval *vblank_time,
unsigned flags,
const struct drm_display_mode *mode);
void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode);
-- Jani Nikula, Intel Open Source Technology Center
-- Jani Nikula, Intel Open Source Technology Center
There's really no reason for anything more: - Calling this while the crtc vblank stuff isn't set up is a driver bug. Those places arlready DRM_ERROR. - Calling this when the crtc is off is either a driver bug (callin drm_crtc_handle_vblank at the wrong time) or a core bug (for anything else). Again, we DRM_ERROR. - EINVAL is checked at higher levels already, and if we'd use struct drm_crtc * instead of (dev, pipe) it would be real obvious that those are again core bugs.
The only valid failure mode is crap hardware that couldn't sample a useful timestamp, to ask the core to just grab a not-so-accurate timestampe. Bool is perfectly fine for that.
v2: Also fix up the one caller, I lost that in the shuffling (Jani).
Cc: Jani Nikula jani.nikula@linux.intel.com Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Cc: Eric Anholt eric@anholt.net Cc: Rob Clark robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Ben Skeggs bskeggs@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 ++--- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 14 ++++----- drivers/gpu/drm/drm_irq.c | 49 ++++++++++++------------------- drivers/gpu/drm/i915/i915_irq.c | 8 ++--- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 12 ++++---- drivers/gpu/drm/nouveau/nouveau_display.c | 4 +-- drivers/gpu/drm/nouveau/nouveau_display.h | 4 +-- drivers/gpu/drm/radeon/radeon_drv.c | 8 ++--- drivers/gpu/drm/radeon/radeon_kms.c | 14 ++++----- drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- include/drm/drmP.h | 1 - include/drm/drm_drv.h | 7 ++--- include/drm/drm_irq.h | 10 +++---- 14 files changed, 64 insertions(+), 79 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c8860f05bfb9..acd8631d8024 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1768,10 +1768,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags); +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags); long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 55f951bcc91f..ac42f707c046 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -838,19 +838,19 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) * * Gets the timestamp on the requested crtc based on the * scanout position. (all asics). - * Returns postive status flags on success, negative error on failure. + * Returns true on success, false on failure. */ -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags) +bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags) { struct drm_crtc *crtc; struct amdgpu_device *adev = dev->dev_private;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; }
/* Get associated drm_crtc: */ @@ -859,7 +859,7 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, /* This can occur on driver load if some component fails to * initialize completely and driver is unloaded */ DRM_ERROR("Uninitialized crtc %d\n", pipe); - return -EINVAL; + return false; }
/* Helper routine in DRM core does all the work: */ diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 4b0c7475ed13..0996e6091bf9 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -722,43 +722,32 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * active. Higher level code is expected to handle this. * * Returns: - * Negative value on error, failure or if not supported in current - * video mode: - * - * -EINVAL Invalid CRTC. - * -EAGAIN Temporary unavailable, e.g., called before initial modeset. - * -ENOTSUPP Function not supported in current display mode. - * -EIO Failed, e.g., due to failed scanout position query. - * - * Returns or'ed positive status flags on success: - * - * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. - * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. * + * Returns true on success, and false on failure, i.e. when no accurate + * timestamp could be acquired. */ -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags, - const struct drm_display_mode *mode) +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, + unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags, + const struct drm_display_mode *mode) { struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status; - int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD; int vpos, hpos, i; int delta_ns, duration_ns;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; }
/* Scanout position query not supported? Should not happen. */ if (!dev->driver->get_scanout_position) { DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); - return -EIO; + return false; }
/* If mode timing undefined, just return as no-op: @@ -766,7 +755,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, */ if (mode->crtc_clock == 0) { DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); - return -EAGAIN; + return false; }
/* Get current scanout position with system timestamp. @@ -790,7 +779,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", pipe, vbl_status); - return -EIO; + return false; }
/* Compute uncertainty in timestamp of scanout position query. */ @@ -834,7 +823,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i);
- return ret; + return true; } EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
@@ -870,25 +859,23 @@ static bool drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, struct timeval *tvblank, unsigned flags) { - int ret; + bool ret = false;
/* Define requested maximum error on timestamps (nanoseconds). */ int max_error = (int) drm_timestamp_precision * 1000;
/* Query driver if possible and precision timestamping enabled. */ - if (dev->driver->get_vblank_timestamp && (max_error > 0)) { + if (dev->driver->get_vblank_timestamp && (max_error > 0)) ret = dev->driver->get_vblank_timestamp(dev, pipe, &max_error, tvblank, flags); - if (ret > 0) - return true; - }
/* GPU high precision timestamp query unsupported or failed. * Return current monotonic/gettimeofday timestamp as best estimate. */ - *tvblank = get_drm_timestamp(); + if (!ret) + *tvblank = get_drm_timestamp();
- return false; + return ret; }
/** diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 26aa1c170b43..df149d159ce7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -964,7 +964,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; }
-static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, +static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags) @@ -974,19 +974,19 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; }
/* Get drm_crtc to timestamp: */ crtc = intel_get_crtc_for_pipe(dev_priv, pipe); if (crtc == NULL) { DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; + return false; }
if (!crtc->base.hwmode.crtc_clock) { DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); - return -EBUSY; + return false; }
/* Helper routine in DRM core does all the work: */ diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 41ccd2a15d3c..655700eb42ba 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -595,23 +595,23 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, return ret; }
-static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags) +static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags) { struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc;
if (pipe < 0 || pipe >= priv->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", pipe); - return -EINVAL; + return false; }
crtc = priv->crtcs[pipe]; if (!crtc) { DRM_ERROR("Invalid crtc %d\n", pipe); - return -EINVAL; + return false; }
return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 33269c7df30f..42f18b0b9c43 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -156,7 +156,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, return 0; }
-int +bool nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *time, unsigned flags) { @@ -174,7 +174,7 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, } }
- return -EINVAL; + return false; }
static void diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 4a75df06c139..bc9d1e7b0117 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -71,8 +71,8 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); -int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, - struct timeval *, unsigned); +bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, + struct timeval *, unsigned);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 312436a8d9e5..6d79b5c2805b 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,10 +114,10 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags); +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, + int *max_error, + struct timeval *vblank_time, + unsigned flags); void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index a32a62e03a44..9afe72010c64 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -868,25 +868,25 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) * * Gets the timestamp on the requested crtc based on the * scanout position. (all asics). - * Returns postive status flags on success, negative error on failure. + * Returns true on success, false on failure. */ -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, - int *max_error, - struct timeval *vblank_time, - unsigned flags) +bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, + int *max_error, + struct timeval *vblank_time, + unsigned flags) { struct drm_crtc *drmcrtc; struct radeon_device *rdev = dev->dev_private;
if (crtc < 0 || crtc >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %d\n", crtc); - return -EINVAL; + return false; }
/* Get associated drm_crtc: */ drmcrtc = &rdev->mode_info.crtcs[crtc]->base; if (!drmcrtc) - return -EINVAL; + return false;
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 24edd0c22cc9..74260990b6bf 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -270,7 +270,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, return ret; }
-int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags) { diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index dffce6293d87..8a5d0e12ee02 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -450,7 +450,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); -int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, +bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, unsigned flags);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 27ecfcdbf752..6304de7e041e 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -322,7 +322,6 @@ struct pci_controller;
/* Flags and return codes for get_vblank_timestamp() driver function. */ #define DRM_CALLED_FROM_VBLIRQ 1 -#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0)
/* get_scanout_position() return flags */ #define DRM_SCANOUTPOS_VALID (1 << 0) diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index d0b5f363bfa1..da78e248d9d8 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -316,11 +316,10 @@ struct drm_driver { * * Returns: * - * Zero if timestamping isn't supported in current display mode or a - * negative number on failure. A positive status code on success, - * which describes how the vblank_time timestamp was computed. + * True on success, false on failure, which means the core should + * fallback to a simple timestamp taken in drm_crtc_handle_vblank(). */ - int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, + bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags); diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index cf0be6594c8c..f0d5ccf9b282 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -153,11 +153,11 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc); void drm_vblank_cleanup(struct drm_device *dev); u32 drm_accurate_vblank_count(struct drm_crtc *crtc);
-int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - unsigned int pipe, int *max_error, - struct timeval *vblank_time, - unsigned flags, - const struct drm_display_mode *mode); +bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, + unsigned int pipe, int *max_error, + struct timeval *vblank_time, + unsigned flags, + const struct drm_display_mode *mode); void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode);
It's overkill to have a flag parameter which is essentially used just as a boolean. This takes care of core + adjusting drivers.
Adjusting the scanout position callback is a bit harder, since radeon also supplies it's own driver-private flags in there.
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Cc: Eric Anholt eric@anholt.net Cc: Rob Clark robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Ben Skeggs bskeggs@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 6 ++--- drivers/gpu/drm/drm_irq.c | 41 +++++++++++++++++-------------- drivers/gpu/drm/i915/i915_irq.c | 4 +-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 4 +-- drivers/gpu/drm/nouveau/nouveau_display.c | 5 ++-- drivers/gpu/drm/nouveau/nouveau_display.h | 2 +- drivers/gpu/drm/radeon/radeon_drv.c | 2 +- drivers/gpu/drm/radeon/radeon_kms.c | 4 +-- drivers/gpu/drm/vc4/vc4_crtc.c | 4 +-- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- include/drm/drm_drv.h | 11 ++++----- include/drm/drm_irq.h | 2 +- 13 files changed, 46 insertions(+), 43 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index acd8631d8024..edb3bb83e1a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1771,7 +1771,7 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags); + bool in_vblank_irq); long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index ac42f707c046..ad295e822d45 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -834,7 +834,7 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) * @crtc: crtc to get the timestamp for * @max_error: max error * @vblank_time: time value - * @flags: flags passed to the driver + * @in_vblank_irq: called from drm_handle_vblank() * * Gets the timestamp on the requested crtc based on the * scanout position. (all asics). @@ -843,7 +843,7 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags) + bool in_vblank_irq) { struct drm_crtc *crtc; struct amdgpu_device *adev = dev->dev_private; @@ -864,7 +864,7 @@ bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, flags, + vblank_time, in_vblank_irq, &crtc->hwmode); }
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 2121ea29e1b2..059c3346db68 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -54,7 +54,7 @@
static bool drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, - struct timeval *tvblank, unsigned flags); + struct timeval *tvblank, bool in_vblank_irq);
static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */
@@ -138,7 +138,7 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe */ do { cur_vblank = __get_vblank_counter(dev, pipe); - rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, 0); + rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false); } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
/* @@ -171,7 +171,7 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe * device vblank fields. */ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, - unsigned long flags) + bool in_vblank_irq) { struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; u32 cur_vblank, diff; @@ -194,7 +194,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, */ do { cur_vblank = __get_vblank_counter(dev, pipe); - rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, flags); + rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, in_vblank_irq); } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
if (dev->max_vblank_count != 0) { @@ -214,13 +214,13 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, */ diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
- if (diff == 0 && flags & DRM_CALLED_FROM_VBLIRQ) + if (diff == 0 && in_vblank_irq) DRM_DEBUG_VBL("crtc %u: Redundant vblirq ignored." " diff_ns = %lld, framedur_ns = %d)\n", pipe, (long long) diff_ns, framedur_ns); } else { /* some kind of default for drivers w/o accurate vbl timestamping */ - diff = (flags & DRM_CALLED_FROM_VBLIRQ) != 0; + diff = in_vblank_irq ? 1 : 0; }
/* @@ -253,7 +253,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, * Otherwise reinitialize delayed at next vblank interrupt and assign 0 * for now, to mark the vblanktimestamp as invalid. */ - if (!rc && (flags & DRM_CALLED_FROM_VBLIRQ) == 0) + if (!rc && in_vblank_irq) t_vblank = (struct timeval) {0, 0};
store_vblank(dev, pipe, diff, &t_vblank, cur_vblank); @@ -291,7 +291,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc)
spin_lock_irqsave(&dev->vblank_time_lock, flags);
- drm_update_vblank_count(dev, pipe, 0); + drm_update_vblank_count(dev, pipe, false); vblank = drm_vblank_count(dev, pipe);
spin_unlock_irqrestore(&dev->vblank_time_lock, flags); @@ -347,7 +347,7 @@ static void vblank_disable_and_save(struct drm_device *dev, unsigned int pipe) * this time. This makes the count account for the entire time * between drm_crtc_vblank_on() and drm_crtc_vblank_off(). */ - drm_update_vblank_count(dev, pipe, 0); + drm_update_vblank_count(dev, pipe, false);
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); } @@ -698,9 +698,10 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * @max_error: Desired maximum allowable error in timestamps (nanosecs) * On return contains true maximum error of timestamp * @vblank_time: Pointer to struct timeval which should receive the timestamp - * @flags: Flags to pass to driver: - * 0 = Default, - * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler + * @in_vblank_irq: + * True when called from drm_crtc_handle_vblank(). Some drivers + * need to apply some workarounds for gpu-specific vblank irq quirks + * if flag is set. * @mode: mode which defines the scanout timings * * Implements calculation of exact vblank timestamps from given drm_display_mode @@ -730,7 +731,7 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags, + bool in_vblank_irq, const struct drm_display_mode *mode) { struct timeval tv_etime; @@ -738,6 +739,7 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int vbl_status; int vpos, hpos, i; int delta_ns, duration_ns; + unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe); @@ -841,9 +843,10 @@ static struct timeval get_drm_timestamp(void) * @dev: DRM device * @pipe: index of CRTC whose vblank timestamp to retrieve * @tvblank: Pointer to target struct timeval which should receive the timestamp - * @flags: Flags to pass to driver: - * 0 = Default, - * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler + * @in_vblank_irq: + * True when called from drm_crtc_handle_vblank(). Some drivers + * need to apply some workarounds for gpu-specific vblank irq quirks + * if flag is set. * * Fetches the system timestamp corresponding to the time of the most recent * vblank interval on specified CRTC. May call into kms-driver to @@ -857,7 +860,7 @@ static struct timeval get_drm_timestamp(void) */ static bool drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, - struct timeval *tvblank, unsigned flags) + struct timeval *tvblank, bool in_vblank_irq) { int ret;
@@ -867,7 +870,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, /* Query driver if possible and precision timestamping enabled. */ if (dev->driver->get_vblank_timestamp && (max_error > 0)) { ret = dev->driver->get_vblank_timestamp(dev, pipe, &max_error, - tvblank, flags); + tvblank, in_vblank_irq); if (ret > 0) return true; } @@ -1710,7 +1713,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe) return false; }
- drm_update_vblank_count(dev, pipe, DRM_CALLED_FROM_VBLIRQ); + drm_update_vblank_count(dev, pipe, true);
spin_unlock(&dev->vblank_time_lock);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index df149d159ce7..6c8a7e1284c3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -967,7 +967,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags) + bool in_vblank_irq) { struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc; @@ -991,7 +991,7 @@ static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, flags, + vblank_time, in_vblank_irq, &crtc->base.hwmode); }
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 655700eb42ba..16184ccbdd3b 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -598,7 +598,7 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags) + bool in_vblank_irq) { struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc; @@ -615,7 +615,7 @@ static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, }
return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, flags, + vblank_time, in_vblank_irq, &crtc->mode); }
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 42f18b0b9c43..be8ec18ba126 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -158,7 +158,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe,
bool nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, - int *max_error, struct timeval *time, unsigned flags) + int *max_error, struct timeval *time, bool in_vblank_irq) { struct drm_crtc *crtc;
@@ -170,7 +170,8 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, else mode = &crtc->hwmode; return drm_calc_vbltimestamp_from_scanoutpos(dev, - pipe, max_error, time, flags, mode); + pipe, max_error, time, in_vblank_irq, + mode); } }
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index bc9d1e7b0117..f821fc9e2de3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -72,7 +72,7 @@ int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, - struct timeval *, unsigned); + struct timeval *, bool);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 6d79b5c2805b..5fbbc6ac165d 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -117,7 +117,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags); + bool in_vblank_irq); void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 9afe72010c64..41765d18f863 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -873,7 +873,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, int *max_error, struct timeval *vblank_time, - unsigned flags) + bool in_vblank_irq) { struct drm_crtc *drmcrtc; struct radeon_device *rdev = dev->dev_private; @@ -890,7 +890,7 @@ bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, - vblank_time, flags, + vblank_time, in_vblank_irq, &drmcrtc->hwmode); }
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 74260990b6bf..18bd0d816fe3 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -272,14 +272,14 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, - unsigned flags) + bool in_vblank_irq) { struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); struct drm_crtc_state *state = crtc->state;
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc_id, max_error, - vblank_time, flags, + vblank_time, in_vblank_irq, &state->adjusted_mode); }
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 8a5d0e12ee02..815cdeb54971 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -452,7 +452,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, const struct drm_display_mode *mode); bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time, - unsigned flags); + bool in_vblank_irq);
/* vc4_debugfs.c */ int vc4_debugfs_init(struct drm_minor *minor); diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index da78e248d9d8..9fe6301edd6a 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -308,11 +308,10 @@ struct drm_driver { * Returns true upper bound on error for timestamp. * vblank_time: * Target location for returned vblank timestamp. - * flags: - * 0 = Defaults, no special treatment needed. - * DRM_CALLED_FROM_VBLIRQ = Function is called from vblank - * irq handler. Some drivers need to apply some workarounds - * for gpu-specific vblank irq quirks if flag is set. + * in_vblank_irq: + * True when called from drm_crtc_handle_vblank(). Some drivers + * need to apply some workarounds for gpu-specific vblank irq quirks + * if flag is set. * * Returns: * @@ -322,7 +321,7 @@ struct drm_driver { bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags); + bool in_vblank_irq);
/* these have to be filled in */
diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index f0d5ccf9b282..445406efb8dc 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -156,7 +156,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc); bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - unsigned flags, + bool in_vblank_irq, const struct drm_display_mode *mode); void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode);
On Wed, Mar 22, 2017 at 09:36:13AM +0100, Daniel Vetter wrote:
It's overkill to have a flag parameter which is essentially used just as a boolean. This takes care of core + adjusting drivers.
Adjusting the scanout position callback is a bit harder, since radeon also supplies it's own driver-private flags in there.
This part worried me, but indeed radeon only passes the custom flag to the scanout position hook. Patch lgtm
Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Cc: Eric Anholt eric@anholt.net Cc: Rob Clark robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Ben Skeggs bskeggs@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 6 ++--- drivers/gpu/drm/drm_irq.c | 41 +++++++++++++++++-------------- drivers/gpu/drm/i915/i915_irq.c | 4 +-- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 4 +-- drivers/gpu/drm/nouveau/nouveau_display.c | 5 ++-- drivers/gpu/drm/nouveau/nouveau_display.h | 2 +- drivers/gpu/drm/radeon/radeon_drv.c | 2 +- drivers/gpu/drm/radeon/radeon_kms.c | 4 +-- drivers/gpu/drm/vc4/vc4_crtc.c | 4 +-- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- include/drm/drm_drv.h | 11 ++++----- include/drm/drm_irq.h | 2 +- 13 files changed, 46 insertions(+), 43 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index acd8631d8024..edb3bb83e1a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1771,7 +1771,7 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time,
unsigned flags);
bool in_vblank_irq);
long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index ac42f707c046..ad295e822d45 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -834,7 +834,7 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe)
- @crtc: crtc to get the timestamp for
- @max_error: max error
- @vblank_time: time value
- @flags: flags passed to the driver
- @in_vblank_irq: called from drm_handle_vblank()
- Gets the timestamp on the requested crtc based on the
- scanout position. (all asics).
@@ -843,7 +843,7 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time,
unsigned flags)
bool in_vblank_irq)
{ struct drm_crtc *crtc; struct amdgpu_device *adev = dev->dev_private; @@ -864,7 +864,7 @@ bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
vblank_time, flags,
vblank_time, in_vblank_irq, &crtc->hwmode);
}
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 2121ea29e1b2..059c3346db68 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -54,7 +54,7 @@
static bool drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
struct timeval *tvblank, unsigned flags);
struct timeval *tvblank, bool in_vblank_irq);
static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */
@@ -138,7 +138,7 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe */ do { cur_vblank = __get_vblank_counter(dev, pipe);
rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, 0);
rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false);
} while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
/*
@@ -171,7 +171,7 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe
- device vblank fields.
*/ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
unsigned long flags)
bool in_vblank_irq)
{ struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; u32 cur_vblank, diff; @@ -194,7 +194,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, */ do { cur_vblank = __get_vblank_counter(dev, pipe);
rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, flags);
rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, in_vblank_irq);
} while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
if (dev->max_vblank_count != 0) {
@@ -214,13 +214,13 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, */ diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
if (diff == 0 && flags & DRM_CALLED_FROM_VBLIRQ)
} else { /* some kind of default for drivers w/o accurate vbl timestamping */if (diff == 0 && in_vblank_irq) DRM_DEBUG_VBL("crtc %u: Redundant vblirq ignored." " diff_ns = %lld, framedur_ns = %d)\n", pipe, (long long) diff_ns, framedur_ns);
diff = (flags & DRM_CALLED_FROM_VBLIRQ) != 0;
diff = in_vblank_irq ? 1 : 0;
}
/*
@@ -253,7 +253,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, * Otherwise reinitialize delayed at next vblank interrupt and assign 0 * for now, to mark the vblanktimestamp as invalid. */
- if (!rc && (flags & DRM_CALLED_FROM_VBLIRQ) == 0)
if (!rc && in_vblank_irq) t_vblank = (struct timeval) {0, 0};
store_vblank(dev, pipe, diff, &t_vblank, cur_vblank);
@@ -291,7 +291,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc)
spin_lock_irqsave(&dev->vblank_time_lock, flags);
- drm_update_vblank_count(dev, pipe, 0);
drm_update_vblank_count(dev, pipe, false); vblank = drm_vblank_count(dev, pipe);
spin_unlock_irqrestore(&dev->vblank_time_lock, flags);
@@ -347,7 +347,7 @@ static void vblank_disable_and_save(struct drm_device *dev, unsigned int pipe) * this time. This makes the count account for the entire time * between drm_crtc_vblank_on() and drm_crtc_vblank_off(). */
- drm_update_vblank_count(dev, pipe, 0);
drm_update_vblank_count(dev, pipe, false);
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
} @@ -698,9 +698,10 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
- @max_error: Desired maximum allowable error in timestamps (nanosecs)
On return contains true maximum error of timestamp
- @vblank_time: Pointer to struct timeval which should receive the timestamp
- @flags: Flags to pass to driver:
0 = Default,
DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler
- @in_vblank_irq:
True when called from drm_crtc_handle_vblank(). Some drivers
need to apply some workarounds for gpu-specific vblank irq quirks
if flag is set.
- @mode: mode which defines the scanout timings
- Implements calculation of exact vblank timestamps from given drm_display_mode
@@ -730,7 +731,7 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time,
unsigned flags,
bool in_vblank_irq, const struct drm_display_mode *mode)
{ struct timeval tv_etime; @@ -738,6 +739,7 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int vbl_status; int vpos, hpos, i; int delta_ns, duration_ns;
unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0;
if (pipe >= dev->num_crtcs) { DRM_ERROR("Invalid crtc %u\n", pipe);
@@ -841,9 +843,10 @@ static struct timeval get_drm_timestamp(void)
- @dev: DRM device
- @pipe: index of CRTC whose vblank timestamp to retrieve
- @tvblank: Pointer to target struct timeval which should receive the timestamp
- @flags: Flags to pass to driver:
0 = Default,
DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler
- @in_vblank_irq:
True when called from drm_crtc_handle_vblank(). Some drivers
need to apply some workarounds for gpu-specific vblank irq quirks
if flag is set.
- Fetches the system timestamp corresponding to the time of the most recent
- vblank interval on specified CRTC. May call into kms-driver to
@@ -857,7 +860,7 @@ static struct timeval get_drm_timestamp(void) */ static bool drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
struct timeval *tvblank, unsigned flags)
struct timeval *tvblank, bool in_vblank_irq)
{ int ret;
@@ -867,7 +870,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, /* Query driver if possible and precision timestamping enabled. */ if (dev->driver->get_vblank_timestamp && (max_error > 0)) { ret = dev->driver->get_vblank_timestamp(dev, pipe, &max_error,
tvblank, flags);
if (ret > 0) return true; }tvblank, in_vblank_irq);
@@ -1710,7 +1713,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe) return false; }
- drm_update_vblank_count(dev, pipe, DRM_CALLED_FROM_VBLIRQ);
drm_update_vblank_count(dev, pipe, true);
spin_unlock(&dev->vblank_time_lock);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index df149d159ce7..6c8a7e1284c3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -967,7 +967,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time,
unsigned flags)
bool in_vblank_irq)
{ struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc; @@ -991,7 +991,7 @@ static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
vblank_time, flags,
vblank_time, in_vblank_irq, &crtc->base.hwmode);
}
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 655700eb42ba..16184ccbdd3b 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -598,7 +598,7 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time,
unsigned flags)
bool in_vblank_irq)
{ struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc; @@ -615,7 +615,7 @@ static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, }
return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
vblank_time, flags,
vblank_time, in_vblank_irq, &crtc->mode);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 42f18b0b9c43..be8ec18ba126 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -158,7 +158,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe,
bool nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe,
int *max_error, struct timeval *time, unsigned flags)
int *max_error, struct timeval *time, bool in_vblank_irq)
{ struct drm_crtc *crtc;
@@ -170,7 +170,8 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, else mode = &crtc->hwmode; return drm_calc_vbltimestamp_from_scanoutpos(dev,
pipe, max_error, time, flags, mode);
pipe, max_error, time, in_vblank_irq,
} }mode);
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index bc9d1e7b0117..f821fc9e2de3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -72,7 +72,7 @@ int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *,
struct timeval *, unsigned);
struct timeval *, bool);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 6d79b5c2805b..5fbbc6ac165d 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -117,7 +117,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time,
unsigned flags);
bool in_vblank_irq);
void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 9afe72010c64..41765d18f863 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -873,7 +873,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, int *max_error, struct timeval *vblank_time,
unsigned flags)
bool in_vblank_irq)
{ struct drm_crtc *drmcrtc; struct radeon_device *rdev = dev->dev_private; @@ -890,7 +890,7 @@ bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
vblank_time, flags,
vblank_time, in_vblank_irq, &drmcrtc->hwmode);
}
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 74260990b6bf..18bd0d816fe3 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -272,14 +272,14 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time,
unsigned flags)
bool in_vblank_irq)
{ struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); struct drm_crtc_state *state = crtc->state;
/* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc_id, max_error,
vblank_time, flags,
vblank_time, in_vblank_irq, &state->adjusted_mode);
}
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 8a5d0e12ee02..815cdeb54971 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -452,7 +452,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, const struct drm_display_mode *mode); bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, int *max_error, struct timeval *vblank_time,
unsigned flags);
bool in_vblank_irq);
/* vc4_debugfs.c */ int vc4_debugfs_init(struct drm_minor *minor); diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index da78e248d9d8..9fe6301edd6a 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -308,11 +308,10 @@ struct drm_driver { * Returns true upper bound on error for timestamp. * vblank_time: * Target location for returned vblank timestamp.
* flags:
* 0 = Defaults, no special treatment needed.
* DRM_CALLED_FROM_VBLIRQ = Function is called from vblank
* irq handler. Some drivers need to apply some workarounds
* for gpu-specific vblank irq quirks if flag is set.
* in_vblank_irq:
* True when called from drm_crtc_handle_vblank(). Some drivers
* need to apply some workarounds for gpu-specific vblank irq quirks
* if flag is set.
- Returns:
@@ -322,7 +321,7 @@ struct drm_driver { bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time,
unsigned flags);
bool in_vblank_irq);
/* these have to be filled in */
diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index f0d5ccf9b282..445406efb8dc 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -156,7 +156,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc); bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time,
unsigned flags,
bool in_vblank_irq, const struct drm_display_mode *mode);
void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode); -- 2.11.0
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
This is going to be a bit too much, but good to have at least a small note about where this should all head towards.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- include/drm/drm_drv.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 9fe6301edd6a..0a367cf5d8d5 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -274,6 +274,11 @@ struct drm_driver { * constant but unknown small number of scanlines wrt. real scanout * position. * + * FIXME: + * + * Since this is a helper to implement @get_vblank_timestamp, we should + * move it to &struct drm_crtc_helper_funcs, like all the other + * helper-internal hooks. */ int (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, unsigned int flags, int *vpos, int *hpos, @@ -317,6 +322,11 @@ struct drm_driver { * * True on success, false on failure, which means the core should * fallback to a simple timestamp taken in drm_crtc_handle_vblank(). + * + * FIXME: + * + * We should move this hook to &struct drm_crtc_funcs like all the other + * vblank hooks. */ bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error,
If we restrict this helper to only kms drivers (which is the case) we can look up the correct mode easily ourselves. But it's a bit tricky:
- All legacy drivers look at crtc->hwmode. But that is update already at the beginning of the modeset helper, which means when we disable a pipe. Hence the final timestamps might be a bit off. But since this is an existing bug I'm not going to change it, but just try to be bug-for-bug compatible with the current code. This only applies to radeon&amdgpu.
- i915 tries to get it perfect by updating crtc->hwmode when the pipe is off (i.e. vblank->enabled = false).
- All other atomic drivers look at crtc->state->adjusted_mode. Those that look at state->requested_mode simply don't adjust their mode, so it's the same. That has two problems: Accessing crtc->state from interrupt handling code is unsafe, and it's updated before we shut down the pipe. For nonblocking modesets it's even worse.
For atomic drivers try to implement what i915 does. To do that we add a new hwmode field to the vblank structure, and update it from drm_calc_timestamping_constants(). For atomic drivers that's called from the right spot by the helper library already, so all fine. But for safety let's enforce that.
For legacy driver this function is only called at the end (oh the fun), which is broken, so again let's not bother and just stay bug-for-bug compatible.
The benefit is that we can use drm_calc_vbltimestamp_from_scanoutpos directly to implement ->get_vblank_timestamp in every driver, deleting a lot of code.
v2: Completely new approach, trying to mimick the i915 solution.
v3: Fixup kerneldoc.
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Cc: Eric Anholt eric@anholt.net Cc: Rob Clark robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Ben Skeggs bskeggs@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 41 ------------------------------- drivers/gpu/drm/drm_irq.c | 29 +++++++++++++++++++--- drivers/gpu/drm/i915/i915_irq.c | 33 +------------------------ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 26 +------------------- drivers/gpu/drm/nouveau/nouveau_display.c | 22 ----------------- drivers/gpu/drm/nouveau/nouveau_display.h | 2 -- drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +- drivers/gpu/drm/radeon/radeon_drv.c | 6 +---- drivers/gpu/drm/radeon/radeon_kms.c | 37 ---------------------------- drivers/gpu/drm/vc4/vc4_crtc.c | 13 ---------- drivers/gpu/drm/vc4/vc4_drv.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 3 --- include/drm/drm_irq.h | 15 +++++++++-- 15 files changed, 44 insertions(+), 193 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index edb3bb83e1a9..61bef9609b24 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1768,10 +1768,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq); long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 8a61296fd4cc..ba169a0699d5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -692,7 +692,7 @@ static struct drm_driver kms_driver = { .get_vblank_counter = amdgpu_get_vblank_counter_kms, .enable_vblank = amdgpu_enable_vblank_kms, .disable_vblank = amdgpu_disable_vblank_kms, - .get_vblank_timestamp = amdgpu_get_vblank_timestamp_kms, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .get_scanout_position = amdgpu_get_crtc_scanoutpos, #if defined(CONFIG_DEBUG_FS) .debugfs_init = amdgpu_debugfs_init, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index ad295e822d45..32a492bd4e51 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -827,47 +827,6 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) amdgpu_irq_put(adev, &adev->crtc_irq, idx); }
-/** - * amdgpu_get_vblank_timestamp_kms - get vblank timestamp - * - * @dev: drm dev pointer - * @crtc: crtc to get the timestamp for - * @max_error: max error - * @vblank_time: time value - * @in_vblank_irq: called from drm_handle_vblank() - * - * Gets the timestamp on the requested crtc based on the - * scanout position. (all asics). - * Returns true on success, false on failure. - */ -bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_crtc *crtc; - struct amdgpu_device *adev = dev->dev_private; - - if (pipe >= dev->num_crtcs) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return false; - } - - /* Get associated drm_crtc: */ - crtc = &adev->mode_info.crtcs[pipe]->base; - if (!crtc) { - /* This can occur on driver load if some component fails to - * initialize completely and driver is unloaded */ - DRM_ERROR("Uninitialized crtc %d\n", pipe); - return false; - } - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, in_vblank_irq, - &crtc->hwmode); -} - const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 059c3346db68..61d726b1f810 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -659,6 +659,8 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc, if (WARN_ON(pipe >= dev->num_crtcs)) return;
+ WARN_ON(drm_drv_uses_atomic_modeset(dev) && vblank->enabled); + /* Valid dotclock? */ if (dotclock > 0) { int frame_size = mode->crtc_htotal * mode->crtc_vtotal; @@ -682,6 +684,7 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
vblank->linedur_ns = linedur_ns; vblank->framedur_ns = framedur_ns; + vblank->hwmode = *mode;
DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n", crtc->base.id, mode->crtc_htotal, @@ -702,7 +705,6 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * True when called from drm_crtc_handle_vblank(). Some drivers * need to apply some workarounds for gpu-specific vblank irq quirks * if flag is set. - * @mode: mode which defines the scanout timings * * Implements calculation of exact vblank timestamps from given drm_display_mode * timings and current video scanout position of a CRTC. This can be called from @@ -722,6 +724,13 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * returns as no operation if a doublescan or interlaced video mode is * active. Higher level code is expected to handle this. * + * This function can be used to implement the &drm_driver.get_vblank_timestamp + * directly, if the driver implements the &drm_driver.get_scanout_position hook. + * + * Note that atomic drivers must call drm_calc_timestamping_constants() before + * enabling a CRTC. The atomic helpers already take care of that in + * drm_atomic_helper_update_legacy_modeset_state(). + * * Returns: * * Returns true on success, and false on failure, i.e. when no accurate @@ -731,17 +740,24 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - bool in_vblank_irq, - const struct drm_display_mode *mode) + bool in_vblank_irq) { struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status; + struct drm_crtc *crtc; + const struct drm_display_mode *mode; + struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; int vpos, hpos, i; int delta_ns, duration_ns; unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0;
- if (pipe >= dev->num_crtcs) { + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return false; + + crtc = drm_crtc_from_index(dev, pipe); + + if (pipe >= dev->num_crtcs || !crtc) { DRM_ERROR("Invalid crtc %u\n", pipe); return false; } @@ -752,6 +768,11 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, return false; }
+ if (drm_drv_uses_atomic_modeset(dev)) + mode = &vblank->hwmode; + else + mode = &crtc->hwmode; + /* If mode timing undefined, just return as no-op: * Happens during initial modesetting of a crtc. */ diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6c8a7e1284c3..feadfea77354 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -964,37 +964,6 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; }
-static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_crtc *crtc; - - if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return false; - } - - /* Get drm_crtc to timestamp: */ - crtc = intel_get_crtc_for_pipe(dev_priv, pipe); - if (crtc == NULL) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return false; - } - - if (!crtc->base.hwmode.crtc_clock) { - DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); - return false; - } - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, in_vblank_irq, - &crtc->base.hwmode); -} - static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) { u32 busy_up, busy_down, max_avg, min_avg; @@ -4328,7 +4297,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
dev_priv->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD;
- dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; + dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
if (IS_CHERRYVIEW(dev_priv)) { diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 16184ccbdd3b..6ba216b8bba9 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -595,30 +595,6 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, return ret; }
-static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct msm_drm_private *priv = dev->dev_private; - struct drm_crtc *crtc; - - if (pipe < 0 || pipe >= priv->num_crtcs) { - DRM_ERROR("Invalid crtc %d\n", pipe); - return false; - } - - crtc = priv->crtcs[pipe]; - if (!crtc) { - DRM_ERROR("Invalid crtc %d\n", pipe); - return false; - } - - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, in_vblank_irq, - &crtc->mode); -} - static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { struct msm_drm_private *priv = dev->dev_private; @@ -728,7 +704,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) dev->mode_config.max_width = 0xffff; dev->mode_config.max_height = 0xffff;
- dev->driver->get_vblank_timestamp = mdp5_get_vblank_timestamp; + dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; dev->driver->get_scanout_position = mdp5_get_scanoutpos; dev->driver->get_vblank_counter = mdp5_get_vblank_counter; dev->max_vblank_count = 0xffffffff; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index be8ec18ba126..e4bdac13d4e9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -156,28 +156,6 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, return 0; }
-bool -nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, - int *max_error, struct timeval *time, bool in_vblank_irq) -{ - struct drm_crtc *crtc; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (nouveau_crtc(crtc)->index == pipe) { - struct drm_display_mode *mode; - if (drm_drv_uses_atomic_modeset(dev)) - mode = &crtc->state->adjusted_mode; - else - mode = &crtc->hwmode; - return drm_calc_vbltimestamp_from_scanoutpos(dev, - pipe, max_error, time, in_vblank_irq, - mode); - } - } - - return false; -} - static void nouveau_display_vblank_fini(struct drm_device *dev) { diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index f821fc9e2de3..8360a85ed5ef 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -71,8 +71,6 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); -bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, - struct timeval *, bool);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index ec719df619a6..1f751a3f570c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -978,7 +978,7 @@ driver_stub = { .enable_vblank = nouveau_display_vblank_enable, .disable_vblank = nouveau_display_vblank_disable, .get_scanout_position = nouveau_display_scanoutpos, - .get_vblank_timestamp = nouveau_display_vblstamp, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
.ioctls = nouveau_ioctls, .num_ioctls = ARRAY_SIZE(nouveau_ioctls), diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 5fbbc6ac165d..a4bf09cd33f7 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,10 +114,6 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq); void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); @@ -543,7 +539,7 @@ static struct drm_driver kms_driver = { .get_vblank_counter = radeon_get_vblank_counter_kms, .enable_vblank = radeon_enable_vblank_kms, .disable_vblank = radeon_disable_vblank_kms, - .get_vblank_timestamp = radeon_get_vblank_timestamp_kms, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .get_scanout_position = radeon_get_crtc_scanoutpos, .irq_preinstall = radeon_driver_irq_preinstall_kms, .irq_postinstall = radeon_driver_irq_postinstall_kms, diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 41765d18f863..33b8b3d22969 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -857,43 +857,6 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) spin_unlock_irqrestore(&rdev->irq.lock, irqflags); }
-/** - * radeon_get_vblank_timestamp_kms - get vblank timestamp - * - * @dev: drm dev pointer - * @crtc: crtc to get the timestamp for - * @max_error: max error - * @vblank_time: time value - * @flags: flags passed to the driver - * - * Gets the timestamp on the requested crtc based on the - * scanout position. (all asics). - * Returns true on success, false on failure. - */ -bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_crtc *drmcrtc; - struct radeon_device *rdev = dev->dev_private; - - if (crtc < 0 || crtc >= dev->num_crtcs) { - DRM_ERROR("Invalid crtc %d\n", crtc); - return false; - } - - /* Get associated drm_crtc: */ - drmcrtc = &rdev->mode_info.crtcs[crtc]->base; - if (!drmcrtc) - return false; - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, - vblank_time, in_vblank_irq, - &drmcrtc->hwmode); -} - const struct drm_ioctl_desc radeon_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(RADEON_CP_START, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 18bd0d816fe3..2567d6c9a4ee 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -270,19 +270,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, return ret; }
-bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, - int *max_error, struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); - struct drm_crtc_state *state = crtc->state; - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc_id, max_error, - vblank_time, in_vblank_irq, - &state->adjusted_mode); -} - static void vc4_crtc_destroy(struct drm_crtc *crtc) { drm_crtc_cleanup(crtc); diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 61e674baf3a6..e864256e12e5 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -154,7 +154,7 @@ static struct drm_driver vc4_drm_driver = { .irq_uninstall = vc4_irq_uninstall,
.get_scanout_position = vc4_crtc_get_scanoutpos, - .get_vblank_timestamp = vc4_crtc_get_vblank_timestamp, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
#if defined(CONFIG_DEBUG_FS) .debugfs_init = vc4_debugfs_init, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 815cdeb54971..64c92e0eb8f7 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -450,9 +450,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); -bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, - int *max_error, struct timeval *vblank_time, - bool in_vblank_irq);
/* vc4_debugfs.c */ int vc4_debugfs_init(struct drm_minor *minor); diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index 445406efb8dc..b489cc856e7a 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -121,6 +121,18 @@ struct drm_vblank_crtc { * drm_calc_timestamping_constants(). */ int linedur_ns; + + /** + * @hwmode: + * + * Cache of the current hardware display mode. Only valide when @enabled + * is set. This is used by helpers like + * drm_calc_vbltimestamp_from_scanoutpos(). We can't just access the + * hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode, + * because that one is really hard to get at from interrupt context. + */ + struct drm_display_mode hwmode; + /** * @enabled: Tracks the enabling state of the corresponding &drm_crtc to * avoid double-disabling and hence corrupting saved state. Needed by @@ -156,8 +168,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc); bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - bool in_vblank_irq, - const struct drm_display_mode *mode); + bool in_vblank_irq); void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode);
If we restrict this helper to only kms drivers (which is the case) we can look up the correct mode easily ourselves. But it's a bit tricky:
- All legacy drivers look at crtc->hwmode. But that is update already at the beginning of the modeset helper, which means when we disable a pipe. Hence the final timestamps might be a bit off. But since this is an existing bug I'm not going to change it, but just try to be bug-for-bug compatible with the current code. This only applies to radeon&amdgpu.
- i915 tries to get it perfect by updating crtc->hwmode when the pipe is off (i.e. vblank->enabled = false).
- All other atomic drivers look at crtc->state->adjusted_mode. Those that look at state->requested_mode simply don't adjust their mode, so it's the same. That has two problems: Accessing crtc->state from interrupt handling code is unsafe, and it's updated before we shut down the pipe. For nonblocking modesets it's even worse.
For atomic drivers try to implement what i915 does. To do that we add a new hwmode field to the vblank structure, and update it from drm_calc_timestamping_constants(). For atomic drivers that's called from the right spot by the helper library already, so all fine. But for safety let's enforce that.
For legacy driver this function is only called at the end (oh the fun), which is broken, so again let's not bother and just stay bug-for-bug compatible.
The benefit is that we can use drm_calc_vbltimestamp_from_scanoutpos directly to implement ->get_vblank_timestamp in every driver, deleting a lot of code.
v2: Completely new approach, trying to mimick the i915 solution.
v3: Fixup kerneldoc.
v4: Drop the WARN_ON to check that the vblank is off, atomic helpers currently unconditionally call this. Recomputing the same stuff should be harmless.
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Cc: Eric Anholt eric@anholt.net Cc: Rob Clark robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Ben Skeggs bskeggs@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 41 ------------------------------- drivers/gpu/drm/drm_irq.c | 27 +++++++++++++++++--- drivers/gpu/drm/i915/i915_irq.c | 33 +------------------------ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 26 +------------------- drivers/gpu/drm/nouveau/nouveau_display.c | 22 ----------------- drivers/gpu/drm/nouveau/nouveau_display.h | 2 -- drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +- drivers/gpu/drm/radeon/radeon_drv.c | 6 +---- drivers/gpu/drm/radeon/radeon_kms.c | 37 ---------------------------- drivers/gpu/drm/vc4/vc4_crtc.c | 13 ---------- drivers/gpu/drm/vc4/vc4_drv.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 3 --- include/drm/drm_irq.h | 15 +++++++++-- 15 files changed, 42 insertions(+), 193 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index edb3bb83e1a9..61bef9609b24 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1768,10 +1768,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq); long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 8a61296fd4cc..ba169a0699d5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -692,7 +692,7 @@ static struct drm_driver kms_driver = { .get_vblank_counter = amdgpu_get_vblank_counter_kms, .enable_vblank = amdgpu_enable_vblank_kms, .disable_vblank = amdgpu_disable_vblank_kms, - .get_vblank_timestamp = amdgpu_get_vblank_timestamp_kms, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .get_scanout_position = amdgpu_get_crtc_scanoutpos, #if defined(CONFIG_DEBUG_FS) .debugfs_init = amdgpu_debugfs_init, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index ad295e822d45..32a492bd4e51 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -827,47 +827,6 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) amdgpu_irq_put(adev, &adev->crtc_irq, idx); }
-/** - * amdgpu_get_vblank_timestamp_kms - get vblank timestamp - * - * @dev: drm dev pointer - * @crtc: crtc to get the timestamp for - * @max_error: max error - * @vblank_time: time value - * @in_vblank_irq: called from drm_handle_vblank() - * - * Gets the timestamp on the requested crtc based on the - * scanout position. (all asics). - * Returns true on success, false on failure. - */ -bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_crtc *crtc; - struct amdgpu_device *adev = dev->dev_private; - - if (pipe >= dev->num_crtcs) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return false; - } - - /* Get associated drm_crtc: */ - crtc = &adev->mode_info.crtcs[pipe]->base; - if (!crtc) { - /* This can occur on driver load if some component fails to - * initialize completely and driver is unloaded */ - DRM_ERROR("Uninitialized crtc %d\n", pipe); - return false; - } - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, in_vblank_irq, - &crtc->hwmode); -} - const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index cdb064b46d04..46c923848c16 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -682,6 +682,7 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
vblank->linedur_ns = linedur_ns; vblank->framedur_ns = framedur_ns; + vblank->hwmode = *mode;
DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n", crtc->base.id, mode->crtc_htotal, @@ -702,7 +703,6 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * True when called from drm_crtc_handle_vblank(). Some drivers * need to apply some workarounds for gpu-specific vblank irq quirks * if flag is set. - * @mode: mode which defines the scanout timings * * Implements calculation of exact vblank timestamps from given drm_display_mode * timings and current video scanout position of a CRTC. This can be called from @@ -722,6 +722,13 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * returns as no operation if a doublescan or interlaced video mode is * active. Higher level code is expected to handle this. * + * This function can be used to implement the &drm_driver.get_vblank_timestamp + * directly, if the driver implements the &drm_driver.get_scanout_position hook. + * + * Note that atomic drivers must call drm_calc_timestamping_constants() before + * enabling a CRTC. The atomic helpers already take care of that in + * drm_atomic_helper_update_legacy_modeset_state(). + * * Returns: * * Returns true on success, and false on failure, i.e. when no accurate @@ -731,17 +738,24 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - bool in_vblank_irq, - const struct drm_display_mode *mode) + bool in_vblank_irq) { struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status; + struct drm_crtc *crtc; + const struct drm_display_mode *mode; + struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; int vpos, hpos, i; int delta_ns, duration_ns; unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0;
- if (pipe >= dev->num_crtcs) { + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return false; + + crtc = drm_crtc_from_index(dev, pipe); + + if (pipe >= dev->num_crtcs || !crtc) { DRM_ERROR("Invalid crtc %u\n", pipe); return false; } @@ -752,6 +766,11 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, return false; }
+ if (drm_drv_uses_atomic_modeset(dev)) + mode = &vblank->hwmode; + else + mode = &crtc->hwmode; + /* If mode timing undefined, just return as no-op: * Happens during initial modesetting of a crtc. */ diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6c8a7e1284c3..feadfea77354 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -964,37 +964,6 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; }
-static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_crtc *crtc; - - if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return false; - } - - /* Get drm_crtc to timestamp: */ - crtc = intel_get_crtc_for_pipe(dev_priv, pipe); - if (crtc == NULL) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return false; - } - - if (!crtc->base.hwmode.crtc_clock) { - DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); - return false; - } - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, in_vblank_irq, - &crtc->base.hwmode); -} - static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) { u32 busy_up, busy_down, max_avg, min_avg; @@ -4328,7 +4297,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
dev_priv->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD;
- dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; + dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
if (IS_CHERRYVIEW(dev_priv)) { diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 16184ccbdd3b..6ba216b8bba9 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -595,30 +595,6 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, return ret; }
-static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct msm_drm_private *priv = dev->dev_private; - struct drm_crtc *crtc; - - if (pipe < 0 || pipe >= priv->num_crtcs) { - DRM_ERROR("Invalid crtc %d\n", pipe); - return false; - } - - crtc = priv->crtcs[pipe]; - if (!crtc) { - DRM_ERROR("Invalid crtc %d\n", pipe); - return false; - } - - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, in_vblank_irq, - &crtc->mode); -} - static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { struct msm_drm_private *priv = dev->dev_private; @@ -728,7 +704,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) dev->mode_config.max_width = 0xffff; dev->mode_config.max_height = 0xffff;
- dev->driver->get_vblank_timestamp = mdp5_get_vblank_timestamp; + dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; dev->driver->get_scanout_position = mdp5_get_scanoutpos; dev->driver->get_vblank_counter = mdp5_get_vblank_counter; dev->max_vblank_count = 0xffffffff; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index be8ec18ba126..e4bdac13d4e9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -156,28 +156,6 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, return 0; }
-bool -nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, - int *max_error, struct timeval *time, bool in_vblank_irq) -{ - struct drm_crtc *crtc; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (nouveau_crtc(crtc)->index == pipe) { - struct drm_display_mode *mode; - if (drm_drv_uses_atomic_modeset(dev)) - mode = &crtc->state->adjusted_mode; - else - mode = &crtc->hwmode; - return drm_calc_vbltimestamp_from_scanoutpos(dev, - pipe, max_error, time, in_vblank_irq, - mode); - } - } - - return false; -} - static void nouveau_display_vblank_fini(struct drm_device *dev) { diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index f821fc9e2de3..8360a85ed5ef 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -71,8 +71,6 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); -bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, - struct timeval *, bool);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index ec719df619a6..1f751a3f570c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -978,7 +978,7 @@ driver_stub = { .enable_vblank = nouveau_display_vblank_enable, .disable_vblank = nouveau_display_vblank_disable, .get_scanout_position = nouveau_display_scanoutpos, - .get_vblank_timestamp = nouveau_display_vblstamp, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
.ioctls = nouveau_ioctls, .num_ioctls = ARRAY_SIZE(nouveau_ioctls), diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 5fbbc6ac165d..a4bf09cd33f7 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,10 +114,6 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq); void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); @@ -543,7 +539,7 @@ static struct drm_driver kms_driver = { .get_vblank_counter = radeon_get_vblank_counter_kms, .enable_vblank = radeon_enable_vblank_kms, .disable_vblank = radeon_disable_vblank_kms, - .get_vblank_timestamp = radeon_get_vblank_timestamp_kms, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .get_scanout_position = radeon_get_crtc_scanoutpos, .irq_preinstall = radeon_driver_irq_preinstall_kms, .irq_postinstall = radeon_driver_irq_postinstall_kms, diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 41765d18f863..33b8b3d22969 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -857,43 +857,6 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) spin_unlock_irqrestore(&rdev->irq.lock, irqflags); }
-/** - * radeon_get_vblank_timestamp_kms - get vblank timestamp - * - * @dev: drm dev pointer - * @crtc: crtc to get the timestamp for - * @max_error: max error - * @vblank_time: time value - * @flags: flags passed to the driver - * - * Gets the timestamp on the requested crtc based on the - * scanout position. (all asics). - * Returns true on success, false on failure. - */ -bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, - int *max_error, - struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_crtc *drmcrtc; - struct radeon_device *rdev = dev->dev_private; - - if (crtc < 0 || crtc >= dev->num_crtcs) { - DRM_ERROR("Invalid crtc %d\n", crtc); - return false; - } - - /* Get associated drm_crtc: */ - drmcrtc = &rdev->mode_info.crtcs[crtc]->base; - if (!drmcrtc) - return false; - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, - vblank_time, in_vblank_irq, - &drmcrtc->hwmode); -} - const struct drm_ioctl_desc radeon_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(RADEON_CP_START, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 18bd0d816fe3..2567d6c9a4ee 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -270,19 +270,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, return ret; }
-bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, - int *max_error, struct timeval *vblank_time, - bool in_vblank_irq) -{ - struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); - struct drm_crtc_state *state = crtc->state; - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc_id, max_error, - vblank_time, in_vblank_irq, - &state->adjusted_mode); -} - static void vc4_crtc_destroy(struct drm_crtc *crtc) { drm_crtc_cleanup(crtc); diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 61e674baf3a6..e864256e12e5 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -154,7 +154,7 @@ static struct drm_driver vc4_drm_driver = { .irq_uninstall = vc4_irq_uninstall,
.get_scanout_position = vc4_crtc_get_scanoutpos, - .get_vblank_timestamp = vc4_crtc_get_vblank_timestamp, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
#if defined(CONFIG_DEBUG_FS) .debugfs_init = vc4_debugfs_init, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 815cdeb54971..64c92e0eb8f7 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -450,9 +450,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); -bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, - int *max_error, struct timeval *vblank_time, - bool in_vblank_irq);
/* vc4_debugfs.c */ int vc4_debugfs_init(struct drm_minor *minor); diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index 445406efb8dc..b489cc856e7a 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -121,6 +121,18 @@ struct drm_vblank_crtc { * drm_calc_timestamping_constants(). */ int linedur_ns; + + /** + * @hwmode: + * + * Cache of the current hardware display mode. Only valide when @enabled + * is set. This is used by helpers like + * drm_calc_vbltimestamp_from_scanoutpos(). We can't just access the + * hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode, + * because that one is really hard to get at from interrupt context. + */ + struct drm_display_mode hwmode; + /** * @enabled: Tracks the enabling state of the corresponding &drm_crtc to * avoid double-disabling and hence corrupting saved state. Needed by @@ -156,8 +168,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc); bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, - bool in_vblank_irq, - const struct drm_display_mode *mode); + bool in_vblank_irq); void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode);
On Wed, Mar 22, 2017 at 09:56:12PM +0100, Daniel Vetter wrote:
If we restrict this helper to only kms drivers (which is the case) we can look up the correct mode easily ourselves. But it's a bit tricky:
All legacy drivers look at crtc->hwmode. But that is update already at the beginning of the modeset helper, which means when we disable a pipe. Hence the final timestamps might be a bit off. But since this is an existing bug I'm not going to change it, but just try to be bug-for-bug compatible with the current code. This only applies to radeon&amdgpu.
i915 tries to get it perfect by updating crtc->hwmode when the pipe is off (i.e. vblank->enabled = false).
All other atomic drivers look at crtc->state->adjusted_mode. Those that look at state->requested_mode simply don't adjust their mode, so it's the same. That has two problems: Accessing crtc->state from interrupt handling code is unsafe, and it's updated before we shut down the pipe. For nonblocking modesets it's even worse.
For atomic drivers try to implement what i915 does. To do that we add a new hwmode field to the vblank structure, and update it from drm_calc_timestamping_constants().
i915 clear crtc->hwmode.crtc_clock when turning the crtc off, which this does not do for the new vblank->hwmode. I guess no one should really end up in these codepaths with a disabled crtc, but parts of drm_irq.c sort of look like they're expecting it to happen.
So should we have some way to clear out the vblank->hwmode.crtc_clock for disabled crtcs? And then maybe make some of these crtc_clock checks WARN and eventually just nuke it all if it looks like nothing is hitting those?
For atomic drivers that's called from the right spot by the helper library already, so all fine. But for safety let's enforce that.
For legacy driver this function is only called at the end (oh the fun), which is broken, so again let's not bother and just stay bug-for-bug compatible.
The benefit is that we can use drm_calc_vbltimestamp_from_scanoutpos directly to implement ->get_vblank_timestamp in every driver, deleting a lot of code.
v2: Completely new approach, trying to mimick the i915 solution.
v3: Fixup kerneldoc.
v4: Drop the WARN_ON to check that the vblank is off, atomic helpers currently unconditionally call this. Recomputing the same stuff should be harmless.
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Cc: Eric Anholt eric@anholt.net Cc: Rob Clark robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Ben Skeggs bskeggs@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 41 ------------------------------- drivers/gpu/drm/drm_irq.c | 27 +++++++++++++++++--- drivers/gpu/drm/i915/i915_irq.c | 33 +------------------------ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 26 +------------------- drivers/gpu/drm/nouveau/nouveau_display.c | 22 ----------------- drivers/gpu/drm/nouveau/nouveau_display.h | 2 -- drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +- drivers/gpu/drm/radeon/radeon_drv.c | 6 +---- drivers/gpu/drm/radeon/radeon_kms.c | 37 ---------------------------- drivers/gpu/drm/vc4/vc4_crtc.c | 13 ---------- drivers/gpu/drm/vc4/vc4_drv.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 3 --- include/drm/drm_irq.h | 15 +++++++++-- 15 files changed, 42 insertions(+), 193 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index edb3bb83e1a9..61bef9609b24 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1768,10 +1768,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
bool in_vblank_irq);
long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 8a61296fd4cc..ba169a0699d5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -692,7 +692,7 @@ static struct drm_driver kms_driver = { .get_vblank_counter = amdgpu_get_vblank_counter_kms, .enable_vblank = amdgpu_enable_vblank_kms, .disable_vblank = amdgpu_disable_vblank_kms,
- .get_vblank_timestamp = amdgpu_get_vblank_timestamp_kms,
- .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .get_scanout_position = amdgpu_get_crtc_scanoutpos,
#if defined(CONFIG_DEBUG_FS) .debugfs_init = amdgpu_debugfs_init, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index ad295e822d45..32a492bd4e51 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -827,47 +827,6 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) amdgpu_irq_put(adev, &adev->crtc_irq, idx); }
-/**
- amdgpu_get_vblank_timestamp_kms - get vblank timestamp
- @dev: drm dev pointer
- @crtc: crtc to get the timestamp for
- @max_error: max error
- @vblank_time: time value
- @in_vblank_irq: called from drm_handle_vblank()
- Gets the timestamp on the requested crtc based on the
- scanout position. (all asics).
- Returns true on success, false on failure.
- */
-bool amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
bool in_vblank_irq)
-{
- struct drm_crtc *crtc;
- struct amdgpu_device *adev = dev->dev_private;
- if (pipe >= dev->num_crtcs) {
DRM_ERROR("Invalid crtc %u\n", pipe);
return false;
- }
- /* Get associated drm_crtc: */
- crtc = &adev->mode_info.crtcs[pipe]->base;
- if (!crtc) {
/* This can occur on driver load if some component fails to
* initialize completely and driver is unloaded */
DRM_ERROR("Uninitialized crtc %d\n", pipe);
return false;
- }
- /* Helper routine in DRM core does all the work: */
- return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
vblank_time, in_vblank_irq,
&crtc->hwmode);
-}
const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index cdb064b46d04..46c923848c16 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -682,6 +682,7 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
vblank->linedur_ns = linedur_ns; vblank->framedur_ns = framedur_ns;
vblank->hwmode = *mode;
DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n", crtc->base.id, mode->crtc_htotal,
@@ -702,7 +703,6 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
True when called from drm_crtc_handle_vblank(). Some drivers
need to apply some workarounds for gpu-specific vblank irq quirks
if flag is set.
- @mode: mode which defines the scanout timings
- Implements calculation of exact vblank timestamps from given drm_display_mode
- timings and current video scanout position of a CRTC. This can be called from
@@ -722,6 +722,13 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
- returns as no operation if a doublescan or interlaced video mode is
- active. Higher level code is expected to handle this.
- This function can be used to implement the &drm_driver.get_vblank_timestamp
- directly, if the driver implements the &drm_driver.get_scanout_position hook.
- Note that atomic drivers must call drm_calc_timestamping_constants() before
- enabling a CRTC. The atomic helpers already take care of that in
- drm_atomic_helper_update_legacy_modeset_state().
- Returns:
- Returns true on success, and false on failure, i.e. when no accurate
@@ -731,17 +738,24 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time,
bool in_vblank_irq,
const struct drm_display_mode *mode)
bool in_vblank_irq)
{ struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status;
- struct drm_crtc *crtc;
- const struct drm_display_mode *mode;
- struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; int vpos, hpos, i; int delta_ns, duration_ns; unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0;
- if (pipe >= dev->num_crtcs) {
- if (!drm_core_check_feature(dev, DRIVER_MODESET))
return false;
- crtc = drm_crtc_from_index(dev, pipe);
- if (pipe >= dev->num_crtcs || !crtc) { DRM_ERROR("Invalid crtc %u\n", pipe); return false; }
@@ -752,6 +766,11 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, return false; }
- if (drm_drv_uses_atomic_modeset(dev))
mode = &vblank->hwmode;
- else
mode = &crtc->hwmode;
- /* If mode timing undefined, just return as no-op:
*/
- Happens during initial modesetting of a crtc.
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6c8a7e1284c3..feadfea77354 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -964,37 +964,6 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; }
-static bool i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
bool in_vblank_irq)
-{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc *crtc;
- if (pipe >= INTEL_INFO(dev_priv)->num_pipes) {
DRM_ERROR("Invalid crtc %u\n", pipe);
return false;
- }
- /* Get drm_crtc to timestamp: */
- crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
- if (crtc == NULL) {
DRM_ERROR("Invalid crtc %u\n", pipe);
return false;
- }
- if (!crtc->base.hwmode.crtc_clock) {
DRM_DEBUG_KMS("crtc %u is disabled\n", pipe);
return false;
- }
- /* Helper routine in DRM core does all the work: */
- return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
vblank_time, in_vblank_irq,
&crtc->base.hwmode);
-}
static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) { u32 busy_up, busy_down, max_avg, min_avg; @@ -4328,7 +4297,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
dev_priv->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD;
- dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
if (IS_CHERRYVIEW(dev_priv)) {
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 16184ccbdd3b..6ba216b8bba9 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -595,30 +595,6 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, return ret; }
-static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
bool in_vblank_irq)
-{
- struct msm_drm_private *priv = dev->dev_private;
- struct drm_crtc *crtc;
- if (pipe < 0 || pipe >= priv->num_crtcs) {
DRM_ERROR("Invalid crtc %d\n", pipe);
return false;
- }
- crtc = priv->crtcs[pipe];
- if (!crtc) {
DRM_ERROR("Invalid crtc %d\n", pipe);
return false;
- }
- return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
vblank_time, in_vblank_irq,
&crtc->mode);
-}
static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { struct msm_drm_private *priv = dev->dev_private; @@ -728,7 +704,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) dev->mode_config.max_width = 0xffff; dev->mode_config.max_height = 0xffff;
- dev->driver->get_vblank_timestamp = mdp5_get_vblank_timestamp;
- dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; dev->driver->get_scanout_position = mdp5_get_scanoutpos; dev->driver->get_vblank_counter = mdp5_get_vblank_counter; dev->max_vblank_count = 0xffffffff;
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index be8ec18ba126..e4bdac13d4e9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -156,28 +156,6 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, return 0; }
-bool -nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe,
int *max_error, struct timeval *time, bool in_vblank_irq)
-{
- struct drm_crtc *crtc;
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if (nouveau_crtc(crtc)->index == pipe) {
struct drm_display_mode *mode;
if (drm_drv_uses_atomic_modeset(dev))
mode = &crtc->state->adjusted_mode;
else
mode = &crtc->hwmode;
return drm_calc_vbltimestamp_from_scanoutpos(dev,
pipe, max_error, time, in_vblank_irq,
mode);
}
- }
- return false;
-}
static void nouveau_display_vblank_fini(struct drm_device *dev) { diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index f821fc9e2de3..8360a85ed5ef 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -71,8 +71,6 @@ void nouveau_display_vblank_disable(struct drm_device *, unsigned int); int nouveau_display_scanoutpos(struct drm_device *, unsigned int, unsigned int, int *, int *, ktime_t *, ktime_t *, const struct drm_display_mode *); -bool nouveau_display_vblstamp(struct drm_device *, unsigned int, int *,
struct timeval *, bool);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index ec719df619a6..1f751a3f570c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -978,7 +978,7 @@ driver_stub = { .enable_vblank = nouveau_display_vblank_enable, .disable_vblank = nouveau_display_vblank_disable, .get_scanout_position = nouveau_display_scanoutpos,
- .get_vblank_timestamp = nouveau_display_vblstamp,
.get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
.ioctls = nouveau_ioctls, .num_ioctls = ARRAY_SIZE(nouveau_ioctls),
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 5fbbc6ac165d..a4bf09cd33f7 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,10 +114,6 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); -bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
bool in_vblank_irq);
void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); @@ -543,7 +539,7 @@ static struct drm_driver kms_driver = { .get_vblank_counter = radeon_get_vblank_counter_kms, .enable_vblank = radeon_enable_vblank_kms, .disable_vblank = radeon_disable_vblank_kms,
- .get_vblank_timestamp = radeon_get_vblank_timestamp_kms,
- .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .get_scanout_position = radeon_get_crtc_scanoutpos, .irq_preinstall = radeon_driver_irq_preinstall_kms, .irq_postinstall = radeon_driver_irq_postinstall_kms,
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 41765d18f863..33b8b3d22969 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -857,43 +857,6 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) spin_unlock_irqrestore(&rdev->irq.lock, irqflags); }
-/**
- radeon_get_vblank_timestamp_kms - get vblank timestamp
- @dev: drm dev pointer
- @crtc: crtc to get the timestamp for
- @max_error: max error
- @vblank_time: time value
- @flags: flags passed to the driver
- Gets the timestamp on the requested crtc based on the
- scanout position. (all asics).
- Returns true on success, false on failure.
- */
-bool radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
int *max_error,
struct timeval *vblank_time,
bool in_vblank_irq)
-{
- struct drm_crtc *drmcrtc;
- struct radeon_device *rdev = dev->dev_private;
- if (crtc < 0 || crtc >= dev->num_crtcs) {
DRM_ERROR("Invalid crtc %d\n", crtc);
return false;
- }
- /* Get associated drm_crtc: */
- drmcrtc = &rdev->mode_info.crtcs[crtc]->base;
- if (!drmcrtc)
return false;
- /* Helper routine in DRM core does all the work: */
- return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
vblank_time, in_vblank_irq,
&drmcrtc->hwmode);
-}
const struct drm_ioctl_desc radeon_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(RADEON_CP_START, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 18bd0d816fe3..2567d6c9a4ee 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -270,19 +270,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, return ret; }
-bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id,
int *max_error, struct timeval *vblank_time,
bool in_vblank_irq)
-{
- struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id);
- struct drm_crtc_state *state = crtc->state;
- /* Helper routine in DRM core does all the work: */
- return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc_id, max_error,
vblank_time, in_vblank_irq,
&state->adjusted_mode);
-}
static void vc4_crtc_destroy(struct drm_crtc *crtc) { drm_crtc_cleanup(crtc); diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 61e674baf3a6..e864256e12e5 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -154,7 +154,7 @@ static struct drm_driver vc4_drm_driver = { .irq_uninstall = vc4_irq_uninstall,
.get_scanout_position = vc4_crtc_get_scanoutpos,
- .get_vblank_timestamp = vc4_crtc_get_vblank_timestamp,
- .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
#if defined(CONFIG_DEBUG_FS) .debugfs_init = vc4_debugfs_init, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 815cdeb54971..64c92e0eb8f7 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -450,9 +450,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); -bool vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id,
int *max_error, struct timeval *vblank_time,
bool in_vblank_irq);
/* vc4_debugfs.c */ int vc4_debugfs_init(struct drm_minor *minor); diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index 445406efb8dc..b489cc856e7a 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -121,6 +121,18 @@ struct drm_vblank_crtc { * drm_calc_timestamping_constants(). */ int linedur_ns;
- /**
* @hwmode:
*
* Cache of the current hardware display mode. Only valide when @enabled
* is set. This is used by helpers like
* drm_calc_vbltimestamp_from_scanoutpos(). We can't just access the
* hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode,
* because that one is really hard to get at from interrupt context.
*/
- struct drm_display_mode hwmode;
- /**
- @enabled: Tracks the enabling state of the corresponding &drm_crtc to
- avoid double-disabling and hence corrupting saved state. Needed by
@@ -156,8 +168,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc); bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time,
bool in_vblank_irq,
const struct drm_display_mode *mode);
bool in_vblank_irq);
void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode);
-- 2.11.0
Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
On Thu, Mar 30, 2017 at 2:03 PM, Ville Syrjälä ville.syrjala@linux.intel.com wrote:
On Wed, Mar 22, 2017 at 09:56:12PM +0100, Daniel Vetter wrote:
If we restrict this helper to only kms drivers (which is the case) we can look up the correct mode easily ourselves. But it's a bit tricky:
All legacy drivers look at crtc->hwmode. But that is update already at the beginning of the modeset helper, which means when we disable a pipe. Hence the final timestamps might be a bit off. But since this is an existing bug I'm not going to change it, but just try to be bug-for-bug compatible with the current code. This only applies to radeon&amdgpu.
i915 tries to get it perfect by updating crtc->hwmode when the pipe is off (i.e. vblank->enabled = false).
All other atomic drivers look at crtc->state->adjusted_mode. Those that look at state->requested_mode simply don't adjust their mode, so it's the same. That has two problems: Accessing crtc->state from interrupt handling code is unsafe, and it's updated before we shut down the pipe. For nonblocking modesets it's even worse.
For atomic drivers try to implement what i915 does. To do that we add a new hwmode field to the vblank structure, and update it from drm_calc_timestamping_constants().
i915 clear crtc->hwmode.crtc_clock when turning the crtc off, which this does not do for the new vblank->hwmode. I guess no one should really end up in these codepaths with a disabled crtc, but parts of drm_irq.c sort of look like they're expecting it to happen.
So should we have some way to clear out the vblank->hwmode.crtc_clock for disabled crtcs? And then maybe make some of these crtc_clock checks WARN and eventually just nuke it all if it looks like nothing is hitting those?
So the trouble is that with a pile of dpms on/off/on/off you could run drm_crtc_vblank_on/off a lot, without ever calling the drm_calc_vbltimestamps helper again to re-upload the mode. So I don't think we can clear vblank->hwmode.crtc_clock unfortunately in drm_crtc_vblank_off.
But what we could do (at least with atomic) is WARN in the vblank helper if it's called outside of drm_vblank_on/off ... Not sure how useful that is (it won't catch when a driver outright forgets to call these) or whether we have enough checks already. Would be a separate patch (can do ofc if we agree on what exactly). -Daniel
On Thu, Mar 30, 2017 at 03:27:57PM +0200, Daniel Vetter wrote:
On Thu, Mar 30, 2017 at 2:03 PM, Ville Syrjälä ville.syrjala@linux.intel.com wrote:
On Wed, Mar 22, 2017 at 09:56:12PM +0100, Daniel Vetter wrote:
If we restrict this helper to only kms drivers (which is the case) we can look up the correct mode easily ourselves. But it's a bit tricky:
All legacy drivers look at crtc->hwmode. But that is update already at the beginning of the modeset helper, which means when we disable a pipe. Hence the final timestamps might be a bit off. But since this is an existing bug I'm not going to change it, but just try to be bug-for-bug compatible with the current code. This only applies to radeon&amdgpu.
i915 tries to get it perfect by updating crtc->hwmode when the pipe is off (i.e. vblank->enabled = false).
All other atomic drivers look at crtc->state->adjusted_mode. Those that look at state->requested_mode simply don't adjust their mode, so it's the same. That has two problems: Accessing crtc->state from interrupt handling code is unsafe, and it's updated before we shut down the pipe. For nonblocking modesets it's even worse.
For atomic drivers try to implement what i915 does. To do that we add a new hwmode field to the vblank structure, and update it from drm_calc_timestamping_constants().
i915 clear crtc->hwmode.crtc_clock when turning the crtc off, which this does not do for the new vblank->hwmode. I guess no one should really end up in these codepaths with a disabled crtc, but parts of drm_irq.c sort of look like they're expecting it to happen.
So should we have some way to clear out the vblank->hwmode.crtc_clock for disabled crtcs? And then maybe make some of these crtc_clock checks WARN and eventually just nuke it all if it looks like nothing is hitting those?
So the trouble is that with a pile of dpms on/off/on/off you could run drm_crtc_vblank_on/off a lot, without ever calling the drm_calc_vbltimestamps helper again to re-upload the mode. So I don't think we can clear vblank->hwmode.crtc_clock unfortunately in drm_crtc_vblank_off.
I was thinking that we'd just try to avoid making pontetially functional changes here. Ie. reset where we currently reset, which I think is somewhere in the atomic commit for i915, but definitely not in drm_crtc_vblank_off().
But what we could do (at least with atomic) is WARN in the vblank helper if it's called outside of drm_vblank_on/off ... Not sure how useful that is (it won't catch when a driver outright forgets to call these) or whether we have enough checks already. Would be a separate patch (can do ofc if we agree on what exactly).
-Daniel
Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
On Thu, Mar 30, 2017 at 04:41:57PM +0300, Ville Syrjälä wrote:
On Thu, Mar 30, 2017 at 03:27:57PM +0200, Daniel Vetter wrote:
On Thu, Mar 30, 2017 at 2:03 PM, Ville Syrjälä ville.syrjala@linux.intel.com wrote:
On Wed, Mar 22, 2017 at 09:56:12PM +0100, Daniel Vetter wrote:
If we restrict this helper to only kms drivers (which is the case) we can look up the correct mode easily ourselves. But it's a bit tricky:
All legacy drivers look at crtc->hwmode. But that is update already at the beginning of the modeset helper, which means when we disable a pipe. Hence the final timestamps might be a bit off. But since this is an existing bug I'm not going to change it, but just try to be bug-for-bug compatible with the current code. This only applies to radeon&amdgpu.
i915 tries to get it perfect by updating crtc->hwmode when the pipe is off (i.e. vblank->enabled = false).
All other atomic drivers look at crtc->state->adjusted_mode. Those that look at state->requested_mode simply don't adjust their mode, so it's the same. That has two problems: Accessing crtc->state from interrupt handling code is unsafe, and it's updated before we shut down the pipe. For nonblocking modesets it's even worse.
For atomic drivers try to implement what i915 does. To do that we add a new hwmode field to the vblank structure, and update it from drm_calc_timestamping_constants().
i915 clear crtc->hwmode.crtc_clock when turning the crtc off, which this does not do for the new vblank->hwmode. I guess no one should really end up in these codepaths with a disabled crtc, but parts of drm_irq.c sort of look like they're expecting it to happen.
So should we have some way to clear out the vblank->hwmode.crtc_clock for disabled crtcs? And then maybe make some of these crtc_clock checks WARN and eventually just nuke it all if it looks like nothing is hitting those?
So the trouble is that with a pile of dpms on/off/on/off you could run drm_crtc_vblank_on/off a lot, without ever calling the drm_calc_vbltimestamps helper again to re-upload the mode. So I don't think we can clear vblank->hwmode.crtc_clock unfortunately in drm_crtc_vblank_off.
I was thinking that we'd just try to avoid making pontetially functional changes here. Ie. reset where we currently reset, which I think is somewhere in the atomic commit for i915, but definitely not in drm_crtc_vblank_off().
Hm, sounds like a good idea. I'll try to shuffle things around. Upon re-reading all that stuff I also noticed that atm i915 only calls the helper that would update vblank->hwmode when we do a full modeset, but not when we just fastset. Shouldn't matter, because the hwmode will match, but better safe than sorry.
I'll re-read all that stuff again and will try to lock it down fully, like we have now, and remove the i915 crtc->hwmode access maybe entirely while at it. -Daniel
But what we could do (at least with atomic) is WARN in the vblank helper if it's called outside of drm_vblank_on/off ... Not sure how useful that is (it won't catch when a driver outright forgets to call these) or whether we have enough checks already. Would be a separate patch (can do ofc if we agree on what exactly).
-Daniel
Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
-- Ville Syrjälä Intel OTC
On Thu, Mar 30, 2017 at 08:27:40PM +0200, Daniel Vetter wrote:
On Thu, Mar 30, 2017 at 04:41:57PM +0300, Ville Syrjälä wrote:
On Thu, Mar 30, 2017 at 03:27:57PM +0200, Daniel Vetter wrote:
On Thu, Mar 30, 2017 at 2:03 PM, Ville Syrjälä ville.syrjala@linux.intel.com wrote:
On Wed, Mar 22, 2017 at 09:56:12PM +0100, Daniel Vetter wrote:
If we restrict this helper to only kms drivers (which is the case) we can look up the correct mode easily ourselves. But it's a bit tricky:
All legacy drivers look at crtc->hwmode. But that is update already at the beginning of the modeset helper, which means when we disable a pipe. Hence the final timestamps might be a bit off. But since this is an existing bug I'm not going to change it, but just try to be bug-for-bug compatible with the current code. This only applies to radeon&amdgpu.
i915 tries to get it perfect by updating crtc->hwmode when the pipe is off (i.e. vblank->enabled = false).
All other atomic drivers look at crtc->state->adjusted_mode. Those that look at state->requested_mode simply don't adjust their mode, so it's the same. That has two problems: Accessing crtc->state from interrupt handling code is unsafe, and it's updated before we shut down the pipe. For nonblocking modesets it's even worse.
For atomic drivers try to implement what i915 does. To do that we add a new hwmode field to the vblank structure, and update it from drm_calc_timestamping_constants().
i915 clear crtc->hwmode.crtc_clock when turning the crtc off, which this does not do for the new vblank->hwmode. I guess no one should really end up in these codepaths with a disabled crtc, but parts of drm_irq.c sort of look like they're expecting it to happen.
So should we have some way to clear out the vblank->hwmode.crtc_clock for disabled crtcs? And then maybe make some of these crtc_clock checks WARN and eventually just nuke it all if it looks like nothing is hitting those?
So the trouble is that with a pile of dpms on/off/on/off you could run drm_crtc_vblank_on/off a lot, without ever calling the drm_calc_vbltimestamps helper again to re-upload the mode. So I don't think we can clear vblank->hwmode.crtc_clock unfortunately in drm_crtc_vblank_off.
I was thinking that we'd just try to avoid making pontetially functional changes here. Ie. reset where we currently reset, which I think is somewhere in the atomic commit for i915, but definitely not in drm_crtc_vblank_off().
Hm, sounds like a good idea. I'll try to shuffle things around. Upon re-reading all that stuff I also noticed that atm i915 only calls the helper that would update vblank->hwmode when we do a full modeset, but not when we just fastset. Shouldn't matter, because the hwmode will match, but better safe than sorry.
I'll re-read all that stuff again and will try to lock it down fully, like we have now, and remove the i915 crtc->hwmode access maybe entirely while at it.
Ok, I stitched something together which I think should work well. Done as a follow-up patch though since this refactoring patch here was already pretty big. Resend the entire pile for CI to double-check, review from you on the vblank stuff would be much appreciated. -Daniel
- We can drop the different return value flags, the only caller only cares about whether the scanout position is valid or not. Also, it's entirely undefined what "accurate" means, if we'd really care we should probably wire the max_error through. But since we never even report this to userspace it's kinda moot.
- Drop all the fancy input flags, there's really only the "called from vblank irq" one. Well except for radeon/amdgpu, which added their own private flags.
Since amdgpu/radoen also use the scanoutposition function internally I just gave them a tiny wrapper, plus copies of all the old #defines they need. Everyone else gets simplified code.
Note how we could remove a lot of error conditions if we'd move this helper hook to drm_crtc_helper_funcs and would pass it a crtc directly.
v2: Make it compile on arm.
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Cc: Eric Anholt eric@anholt.net Cc: Rob Clark robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Ben Skeggs bskeggs@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 12 +++++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 3 +++ drivers/gpu/drm/drm_irq.c | 16 ++++++++-------- drivers/gpu/drm/i915/i915_irq.c | 19 ++++++------------- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 19 +++++++------------ drivers/gpu/drm/nouveau/nouveau_display.c | 16 +++++++--------- drivers/gpu/drm/nouveau/nouveau_display.h | 6 +++--- drivers/gpu/drm/radeon/radeon_drv.c | 12 +++++++++++- drivers/gpu/drm/radeon/radeon_mode.h | 3 +++ drivers/gpu/drm/vc4/vc4_crtc.c | 21 ++++++++++----------- drivers/gpu/drm/vc4/vc4_drv.h | 8 ++++---- include/drm/drmP.h | 8 -------- include/drm/drm_drv.h | 26 ++++++++++---------------- 13 files changed, 83 insertions(+), 86 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index ba169a0699d5..87910850e5dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -678,6 +678,16 @@ static const struct file_operations amdgpu_driver_kms_fops = { #endif };
+static bool +amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + return amdgpu_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, + stime, etime, mode); +} + static struct drm_driver kms_driver = { .driver_features = DRIVER_USE_AGP | @@ -693,7 +703,7 @@ static struct drm_driver kms_driver = { .enable_vblank = amdgpu_enable_vblank_kms, .disable_vblank = amdgpu_disable_vblank_kms, .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, - .get_scanout_position = amdgpu_get_crtc_scanoutpos, + .get_scanout_position = amdgpu_get_crtc_scanout_position, #if defined(CONFIG_DEBUG_FS) .debugfs_init = amdgpu_debugfs_init, #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index c12497bd3889..6b8f766a6a35 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -534,6 +534,9 @@ struct amdgpu_framebuffer { ((em) == ATOM_ENCODER_MODE_DP_MST))
/* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */ +#define DRM_SCANOUTPOS_VALID (1 << 0) +#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE (1 << 2) #define USE_REAL_VBLANKSTART (1 << 30) #define GET_DISTANCE_TO_VBLANKSTART (1 << 31)
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 61d726b1f810..00e26b4312cc 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -744,13 +744,12 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, { struct timeval tv_etime; ktime_t stime, etime; - unsigned int vbl_status; + bool vbl_status; struct drm_crtc *crtc; const struct drm_display_mode *mode; struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; int vpos, hpos, i; int delta_ns, duration_ns; - unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0;
if (!drm_core_check_feature(dev, DRIVER_MODESET)) return false; @@ -793,15 +792,16 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, * Get vertical and horizontal scanout position vpos, hpos, * and bounding timestamps stime, etime, pre/post query. */ - vbl_status = dev->driver->get_scanout_position(dev, pipe, flags, + vbl_status = dev->driver->get_scanout_position(dev, pipe, + in_vblank_irq, &vpos, &hpos, &stime, &etime, mode);
/* Return as no-op if scanout query unsupported or failed. */ - if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { - DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", - pipe, vbl_status); + if (!vbl_status) { + DRM_DEBUG("crtc %u : scanoutpos query failed.\n", + pipe); return false; }
@@ -840,8 +840,8 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, etime = ktime_sub_ns(etime, delta_ns); *vblank_time = ktime_to_timeval(etime);
- DRM_DEBUG_VBL("crtc %u : v 0x%x p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", - pipe, vbl_status, hpos, vpos, + DRM_DEBUG_VBL("crtc %u : v p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", + pipe, hpos, vpos, (long)tv_etime.tv_sec, (long)tv_etime.tv_usec, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index feadfea77354..a211f9d2e6ca 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -827,10 +827,10 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) return (position + crtc->scanline_offset) % vtotal; }
-static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv, @@ -838,13 +838,12 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, int position; int vbl_start, vbl_end, hsync_start, htotal, vtotal; bool in_vbl = true; - int ret = 0; unsigned long irqflags;
if (WARN_ON(!mode->crtc_clock)) { DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " "pipe %c\n", pipe_name(pipe)); - return 0; + return false; }
htotal = mode->crtc_htotal; @@ -859,8 +858,6 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, vtotal /= 2; }
- ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; - /* * Lock uncore.lock, as we will do multiple timing critical raw * register reads, potentially with preemption disabled, so the @@ -944,11 +941,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, *hpos = position - (*vpos * htotal); }
- /* In vblank? */ - if (in_vbl) - ret |= DRM_SCANOUTPOS_IN_VBLANK; - - return ret; + return true; }
int intel_get_crtc_scanline(struct intel_crtc *crtc) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 6ba216b8bba9..959b826123a2 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -530,31 +530,28 @@ static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc) return NULL; }
-static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +static bool mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc; struct drm_encoder *encoder; int line, vsw, vbp, vactive_start, vactive_end, vfp_end; - int ret = 0;
crtc = priv->crtcs[pipe]; if (!crtc) { DRM_ERROR("Invalid crtc %d\n", pipe); - return 0; + return false; }
encoder = get_encoder_from_crtc(crtc); if (!encoder) { DRM_ERROR("no encoder found for crtc %d\n", pipe); - return 0; + return false; }
- ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; - vsw = mode->crtc_vsync_end - mode->crtc_vsync_start; vbp = mode->crtc_vtotal - mode->crtc_vsync_end;
@@ -578,10 +575,8 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe,
if (line < vactive_start) { line -= vactive_start; - ret |= DRM_SCANOUTPOS_IN_VBLANK; } else if (line > vactive_end) { line = line - vfp_end - vactive_start; - ret |= DRM_SCANOUTPOS_IN_VBLANK; } else { line -= vactive_start; } @@ -592,7 +587,7 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, if (etime) *etime = ktime_get();
- return ret; + return true; }
static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index e4bdac13d4e9..8b3622afa530 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -98,7 +98,7 @@ calc(int blanks, int blanke, int total, int line) return line; }
-static int +static bool nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) { @@ -111,16 +111,16 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, }; struct nouveau_display *disp = nouveau_display(crtc->dev); struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)]; - int ret, retry = 1; + int retry = 1; + bool ret = false;
do { ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args)); if (ret != 0) - return 0; + return false;
if (args.scan.vline) { - ret |= DRM_SCANOUTPOS_ACCURATE; - ret |= DRM_SCANOUTPOS_VALID; + ret = true; break; }
@@ -133,14 +133,12 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, if (stime) *stime = ns_to_ktime(args.scan.time[0]); if (etime) *etime = ns_to_ktime(args.scan.time[1]);
- if (*vpos < 0) - ret |= DRM_SCANOUTPOS_IN_VBLANK; return ret; }
-int +bool nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, + bool in_vblank_irq, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode) { diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 8360a85ed5ef..b76b65c7c8da 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -68,9 +68,9 @@ int nouveau_display_suspend(struct drm_device *dev, bool runtime); void nouveau_display_resume(struct drm_device *dev, bool runtime); int nouveau_display_vblank_enable(struct drm_device *, unsigned int); void nouveau_display_vblank_disable(struct drm_device *, unsigned int); -int nouveau_display_scanoutpos(struct drm_device *, unsigned int, - unsigned int, int *, int *, ktime_t *, - ktime_t *, const struct drm_display_mode *); +bool nouveau_display_scanoutpos(struct drm_device *, unsigned int, + bool, int *, int *, ktime_t *, + ktime_t *, const struct drm_display_mode *);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index a4bf09cd33f7..669ebfda8038 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -525,6 +525,16 @@ static const struct file_operations radeon_driver_kms_fops = { #endif };
+static bool +radeon_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + return radeon_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, + stime, etime, mode); +} + static struct drm_driver kms_driver = { .driver_features = DRIVER_USE_AGP | @@ -540,7 +550,7 @@ static struct drm_driver kms_driver = { .enable_vblank = radeon_enable_vblank_kms, .disable_vblank = radeon_disable_vblank_kms, .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, - .get_scanout_position = radeon_get_crtc_scanoutpos, + .get_scanout_position = radeon_get_crtc_scanout_position, .irq_preinstall = radeon_driver_irq_preinstall_kms, .irq_postinstall = radeon_driver_irq_postinstall_kms, .irq_uninstall = radeon_driver_irq_uninstall_kms, diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index ad282648fc8b..00f5ec5c12c7 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -691,6 +691,9 @@ struct atom_voltage_table };
/* Driver internal use only flags of radeon_get_crtc_scanoutpos() */ +#define DRM_SCANOUTPOS_VALID (1 << 0) +#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE (1 << 2) #define USE_REAL_VBLANKSTART (1 << 30) #define GET_DISTANCE_TO_VBLANKSTART (1 << 31)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 2567d6c9a4ee..e871862a21b8 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -151,10 +151,10 @@ int vc4_crtc_debugfs_regs(struct seq_file *m, void *unused) } #endif
-int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { struct vc4_dev *vc4 = to_vc4_dev(dev); struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); @@ -162,7 +162,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, u32 val; int fifo_lines; int vblank_lines; - int ret = 0; + bool ret = false;
/* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
@@ -198,7 +198,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, fifo_lines = vc4_crtc->cob_size / mode->crtc_hdisplay;
if (fifo_lines > 0) - ret |= DRM_SCANOUTPOS_VALID; + ret = true;
/* HVS more than fifo_lines into frame for compositing? */ if (*vpos > fifo_lines) { @@ -216,7 +216,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, */ *vpos -= fifo_lines + 1;
- ret |= DRM_SCANOUTPOS_ACCURATE; return ret; }
@@ -229,10 +228,9 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, * We can't get meaningful readings wrt. scanline position of the PV * and need to make things up in a approximative but consistent way. */ - ret |= DRM_SCANOUTPOS_IN_VBLANK; vblank_lines = mode->vtotal - mode->vdisplay;
- if (flags & DRM_CALLED_FROM_VBLIRQ) { + if (in_vblank_irq) { /* * Assume the irq handler got called close to first * line of vblank, so PV has about a full vblank @@ -254,9 +252,10 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, * we are at the very beginning of vblank, as the hvs just * started refilling, and the stime and etime timestamps * truly correspond to start of vblank. + * + * Unfortunately there's no way to report this to upper levels + * and make it more useful. */ - if ((val & SCALER_DISPSTATX_FULL) != SCALER_DISPSTATX_FULL) - ret |= DRM_SCANOUTPOS_ACCURATE; } else { /* * No clue where we are inside vblank. Return a vpos of zero, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 64c92e0eb8f7..c34a0915e49d 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -446,10 +446,10 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *arg); extern struct platform_driver vc4_crtc_driver; bool vc4_event_pending(struct drm_crtc *crtc); int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg); -int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode); +bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode);
/* vc4_debugfs.c */ int vc4_debugfs_init(struct drm_minor *minor); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 6304de7e041e..952c080e6b28 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -320,14 +320,6 @@ struct pci_controller; #define DRM_IF_VERSION(maj, min) (maj << 16 | min)
-/* Flags and return codes for get_vblank_timestamp() driver function. */ -#define DRM_CALLED_FROM_VBLIRQ 1 - -/* get_scanout_position() return flags */ -#define DRM_SCANOUTPOS_VALID (1 << 0) -#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) -#define DRM_SCANOUTPOS_ACCURATE (1 << 2) - /** * DRM device structure. This structure represent a complete card that * may contain multiple heads. diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 0a367cf5d8d5..e64e33b9dd26 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -241,8 +241,10 @@ struct drm_driver { * DRM device. * pipe: * Id of the crtc to query. - * flags: - * Flags from the caller (DRM_CALLED_FROM_VBLIRQ or 0). + * in_vblank_irq: + * True when called from drm_crtc_handle_vblank(). Some drivers + * need to apply some workarounds for gpu-specific vblank irq quirks + * if flag is set. * vpos: * Target location for current vertical scanout position. * hpos: @@ -263,16 +265,8 @@ struct drm_driver { * * Returns: * - * Flags, or'ed together as follows: - * - * DRM_SCANOUTPOS_VALID: - * Query successful. - * DRM_SCANOUTPOS_INVBL: - * Inside vblank. - * DRM_SCANOUTPOS_ACCURATE: Returned position is accurate. A lack of - * this flag means that returned position may be offset by a - * constant but unknown small number of scanlines wrt. real scanout - * position. + * True on success, false if a reliable scanout position counter could + * not be read out. * * FIXME: * @@ -280,10 +274,10 @@ struct drm_driver { * move it to &struct drm_crtc_helper_funcs, like all the other * helper-internal hooks. */ - int (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode); + bool (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode);
/** * @get_vblank_timestamp:
drivers/gpu/drm/nouveau/nouveau_display.c:154:8-9: WARNING: return of 0/1 in function 'nouveau_display_scanoutpos' with return type bool
Return statements in functions returning bool should use true/false instead of 1/0. Generated by: scripts/coccinelle/misc/boolreturn.cocci
CC: Daniel Vetter daniel.vetter@ffwll.ch Signed-off-by: Fengguang Wu fengguang.wu@intel.com ---
nouveau_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -151,7 +151,7 @@ nouveau_display_scanoutpos(struct drm_de } }
- return 0; + return false; }
static void
Hi Daniel,
[auto build test WARNING on drm/drm-next] [cannot apply to v4.11-rc3 next-20170324] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Daniel-Vetter/more-drmP-h-cleanup/2... base: git://people.freedesktop.org/~airlied/linux.git drm-next
coccinelle warnings: (new ones prefixed by >>)
drivers/gpu/drm/nouveau/nouveau_display.c:154:8-9: WARNING: return of 0/1 in function 'nouveau_display_scanoutpos' with return type bool
Please review and possibly fold the followup patch.
--- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
- We can drop the different return value flags, the only caller only cares about whether the scanout position is valid or not. Also, it's entirely undefined what "accurate" means, if we'd really care we should probably wire the max_error through. But since we never even report this to userspace it's kinda moot.
- Drop all the fancy input flags, there's really only the "called from vblank irq" one. Well except for radeon/amdgpu, which added their own private flags.
Since amdgpu/radoen also use the scanoutposition function internally I just gave them a tiny wrapper, plus copies of all the old #defines they need. Everyone else gets simplified code.
Note how we could remove a lot of error conditions if we'd move this helper hook to drm_crtc_helper_funcs and would pass it a crtc directly.
v2: Make it compile on arm.
v3: Squash in fixup from 0day.
Cc: Mario Kleiner mario.kleiner@tuebingen.mpg.de Cc: Eric Anholt eric@anholt.net Cc: Rob Clark robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Ben Skeggs bskeggs@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 12 +++++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 3 +++ drivers/gpu/drm/drm_irq.c | 16 ++++++++-------- drivers/gpu/drm/i915/i915_irq.c | 19 ++++++------------- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 19 +++++++------------ drivers/gpu/drm/nouveau/nouveau_display.c | 18 ++++++++---------- drivers/gpu/drm/nouveau/nouveau_display.h | 6 +++--- drivers/gpu/drm/radeon/radeon_drv.c | 12 +++++++++++- drivers/gpu/drm/radeon/radeon_mode.h | 3 +++ drivers/gpu/drm/vc4/vc4_crtc.c | 21 ++++++++++----------- drivers/gpu/drm/vc4/vc4_drv.h | 8 ++++---- include/drm/drmP.h | 8 -------- include/drm/drm_drv.h | 26 ++++++++++---------------- 13 files changed, 84 insertions(+), 87 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 4b4861741d7f..9a0312aadf04 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -679,6 +679,16 @@ static const struct file_operations amdgpu_driver_kms_fops = { #endif };
+static bool +amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + return amdgpu_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, + stime, etime, mode); +} + static struct drm_driver kms_driver = { .driver_features = DRIVER_USE_AGP | @@ -694,7 +704,7 @@ static struct drm_driver kms_driver = { .enable_vblank = amdgpu_enable_vblank_kms, .disable_vblank = amdgpu_disable_vblank_kms, .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, - .get_scanout_position = amdgpu_get_crtc_scanoutpos, + .get_scanout_position = amdgpu_get_crtc_scanout_position, #if defined(CONFIG_DEBUG_FS) .debugfs_init = amdgpu_debugfs_init, #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index c12497bd3889..6b8f766a6a35 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -534,6 +534,9 @@ struct amdgpu_framebuffer { ((em) == ATOM_ENCODER_MODE_DP_MST))
/* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */ +#define DRM_SCANOUTPOS_VALID (1 << 0) +#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE (1 << 2) #define USE_REAL_VBLANKSTART (1 << 30) #define GET_DISTANCE_TO_VBLANKSTART (1 << 31)
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 46c923848c16..37541abac0d8 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -742,13 +742,12 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, { struct timeval tv_etime; ktime_t stime, etime; - unsigned int vbl_status; + bool vbl_status; struct drm_crtc *crtc; const struct drm_display_mode *mode; struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; int vpos, hpos, i; int delta_ns, duration_ns; - unsigned flags = in_vblank_irq ? DRM_CALLED_FROM_VBLIRQ : 0;
if (!drm_core_check_feature(dev, DRIVER_MODESET)) return false; @@ -791,15 +790,16 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, * Get vertical and horizontal scanout position vpos, hpos, * and bounding timestamps stime, etime, pre/post query. */ - vbl_status = dev->driver->get_scanout_position(dev, pipe, flags, + vbl_status = dev->driver->get_scanout_position(dev, pipe, + in_vblank_irq, &vpos, &hpos, &stime, &etime, mode);
/* Return as no-op if scanout query unsupported or failed. */ - if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { - DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", - pipe, vbl_status); + if (!vbl_status) { + DRM_DEBUG("crtc %u : scanoutpos query failed.\n", + pipe); return false; }
@@ -838,8 +838,8 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, etime = ktime_sub_ns(etime, delta_ns); *vblank_time = ktime_to_timeval(etime);
- DRM_DEBUG_VBL("crtc %u : v 0x%x p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", - pipe, vbl_status, hpos, vpos, + DRM_DEBUG_VBL("crtc %u : v p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", + pipe, hpos, vpos, (long)tv_etime.tv_sec, (long)tv_etime.tv_usec, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6d279b8e897f..c9b53c93b4ed 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -827,10 +827,10 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) return (position + crtc->scanline_offset) % vtotal; }
-static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv, @@ -838,13 +838,12 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, int position; int vbl_start, vbl_end, hsync_start, htotal, vtotal; bool in_vbl = true; - int ret = 0; unsigned long irqflags;
if (WARN_ON(!mode->crtc_clock)) { DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " "pipe %c\n", pipe_name(pipe)); - return 0; + return false; }
htotal = mode->crtc_htotal; @@ -859,8 +858,6 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, vtotal /= 2; }
- ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; - /* * Lock uncore.lock, as we will do multiple timing critical raw * register reads, potentially with preemption disabled, so the @@ -944,11 +941,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, *hpos = position - (*vpos * htotal); }
- /* In vblank? */ - if (in_vbl) - ret |= DRM_SCANOUTPOS_IN_VBLANK; - - return ret; + return true; }
int intel_get_crtc_scanline(struct intel_crtc *crtc) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 6ba216b8bba9..959b826123a2 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -530,31 +530,28 @@ static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc) return NULL; }
-static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +static bool mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc; struct drm_encoder *encoder; int line, vsw, vbp, vactive_start, vactive_end, vfp_end; - int ret = 0;
crtc = priv->crtcs[pipe]; if (!crtc) { DRM_ERROR("Invalid crtc %d\n", pipe); - return 0; + return false; }
encoder = get_encoder_from_crtc(crtc); if (!encoder) { DRM_ERROR("no encoder found for crtc %d\n", pipe); - return 0; + return false; }
- ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; - vsw = mode->crtc_vsync_end - mode->crtc_vsync_start; vbp = mode->crtc_vtotal - mode->crtc_vsync_end;
@@ -578,10 +575,8 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe,
if (line < vactive_start) { line -= vactive_start; - ret |= DRM_SCANOUTPOS_IN_VBLANK; } else if (line > vactive_end) { line = line - vfp_end - vactive_start; - ret |= DRM_SCANOUTPOS_IN_VBLANK; } else { line -= vactive_start; } @@ -592,7 +587,7 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, if (etime) *etime = ktime_get();
- return ret; + return true; }
static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index e4bdac13d4e9..e1829761fdf2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -98,7 +98,7 @@ calc(int blanks, int blanke, int total, int line) return line; }
-static int +static bool nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) { @@ -111,16 +111,16 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, }; struct nouveau_display *disp = nouveau_display(crtc->dev); struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)]; - int ret, retry = 1; + int retry = 1; + bool ret = false;
do { ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args)); if (ret != 0) - return 0; + return false;
if (args.scan.vline) { - ret |= DRM_SCANOUTPOS_ACCURATE; - ret |= DRM_SCANOUTPOS_VALID; + ret = true; break; }
@@ -133,14 +133,12 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, if (stime) *stime = ns_to_ktime(args.scan.time[0]); if (etime) *etime = ns_to_ktime(args.scan.time[1]);
- if (*vpos < 0) - ret |= DRM_SCANOUTPOS_IN_VBLANK; return ret; }
-int +bool nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, + bool in_vblank_irq, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode) { @@ -153,7 +151,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, } }
- return 0; + return false; }
static void diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 8360a85ed5ef..b76b65c7c8da 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -68,9 +68,9 @@ int nouveau_display_suspend(struct drm_device *dev, bool runtime); void nouveau_display_resume(struct drm_device *dev, bool runtime); int nouveau_display_vblank_enable(struct drm_device *, unsigned int); void nouveau_display_vblank_disable(struct drm_device *, unsigned int); -int nouveau_display_scanoutpos(struct drm_device *, unsigned int, - unsigned int, int *, int *, ktime_t *, - ktime_t *, const struct drm_display_mode *); +bool nouveau_display_scanoutpos(struct drm_device *, unsigned int, + bool, int *, int *, ktime_t *, + ktime_t *, const struct drm_display_mode *);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index a4bf09cd33f7..669ebfda8038 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -525,6 +525,16 @@ static const struct file_operations radeon_driver_kms_fops = { #endif };
+static bool +radeon_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + return radeon_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, + stime, etime, mode); +} + static struct drm_driver kms_driver = { .driver_features = DRIVER_USE_AGP | @@ -540,7 +550,7 @@ static struct drm_driver kms_driver = { .enable_vblank = radeon_enable_vblank_kms, .disable_vblank = radeon_disable_vblank_kms, .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, - .get_scanout_position = radeon_get_crtc_scanoutpos, + .get_scanout_position = radeon_get_crtc_scanout_position, .irq_preinstall = radeon_driver_irq_preinstall_kms, .irq_postinstall = radeon_driver_irq_postinstall_kms, .irq_uninstall = radeon_driver_irq_uninstall_kms, diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index ad282648fc8b..00f5ec5c12c7 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -691,6 +691,9 @@ struct atom_voltage_table };
/* Driver internal use only flags of radeon_get_crtc_scanoutpos() */ +#define DRM_SCANOUTPOS_VALID (1 << 0) +#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE (1 << 2) #define USE_REAL_VBLANKSTART (1 << 30) #define GET_DISTANCE_TO_VBLANKSTART (1 << 31)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 2567d6c9a4ee..e871862a21b8 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -151,10 +151,10 @@ int vc4_crtc_debugfs_regs(struct seq_file *m, void *unused) } #endif
-int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { struct vc4_dev *vc4 = to_vc4_dev(dev); struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); @@ -162,7 +162,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, u32 val; int fifo_lines; int vblank_lines; - int ret = 0; + bool ret = false;
/* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
@@ -198,7 +198,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, fifo_lines = vc4_crtc->cob_size / mode->crtc_hdisplay;
if (fifo_lines > 0) - ret |= DRM_SCANOUTPOS_VALID; + ret = true;
/* HVS more than fifo_lines into frame for compositing? */ if (*vpos > fifo_lines) { @@ -216,7 +216,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, */ *vpos -= fifo_lines + 1;
- ret |= DRM_SCANOUTPOS_ACCURATE; return ret; }
@@ -229,10 +228,9 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, * We can't get meaningful readings wrt. scanline position of the PV * and need to make things up in a approximative but consistent way. */ - ret |= DRM_SCANOUTPOS_IN_VBLANK; vblank_lines = mode->vtotal - mode->vdisplay;
- if (flags & DRM_CALLED_FROM_VBLIRQ) { + if (in_vblank_irq) { /* * Assume the irq handler got called close to first * line of vblank, so PV has about a full vblank @@ -254,9 +252,10 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, * we are at the very beginning of vblank, as the hvs just * started refilling, and the stime and etime timestamps * truly correspond to start of vblank. + * + * Unfortunately there's no way to report this to upper levels + * and make it more useful. */ - if ((val & SCALER_DISPSTATX_FULL) != SCALER_DISPSTATX_FULL) - ret |= DRM_SCANOUTPOS_ACCURATE; } else { /* * No clue where we are inside vblank. Return a vpos of zero, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 64c92e0eb8f7..c34a0915e49d 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -446,10 +446,10 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *arg); extern struct platform_driver vc4_crtc_driver; bool vc4_event_pending(struct drm_crtc *crtc); int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg); -int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode); +bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode);
/* vc4_debugfs.c */ int vc4_debugfs_init(struct drm_minor *minor); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 6304de7e041e..952c080e6b28 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -320,14 +320,6 @@ struct pci_controller; #define DRM_IF_VERSION(maj, min) (maj << 16 | min)
-/* Flags and return codes for get_vblank_timestamp() driver function. */ -#define DRM_CALLED_FROM_VBLIRQ 1 - -/* get_scanout_position() return flags */ -#define DRM_SCANOUTPOS_VALID (1 << 0) -#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) -#define DRM_SCANOUTPOS_ACCURATE (1 << 2) - /** * DRM device structure. This structure represent a complete card that * may contain multiple heads. diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 0a367cf5d8d5..e64e33b9dd26 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -241,8 +241,10 @@ struct drm_driver { * DRM device. * pipe: * Id of the crtc to query. - * flags: - * Flags from the caller (DRM_CALLED_FROM_VBLIRQ or 0). + * in_vblank_irq: + * True when called from drm_crtc_handle_vblank(). Some drivers + * need to apply some workarounds for gpu-specific vblank irq quirks + * if flag is set. * vpos: * Target location for current vertical scanout position. * hpos: @@ -263,16 +265,8 @@ struct drm_driver { * * Returns: * - * Flags, or'ed together as follows: - * - * DRM_SCANOUTPOS_VALID: - * Query successful. - * DRM_SCANOUTPOS_INVBL: - * Inside vblank. - * DRM_SCANOUTPOS_ACCURATE: Returned position is accurate. A lack of - * this flag means that returned position may be offset by a - * constant but unknown small number of scanlines wrt. real scanout - * position. + * True on success, false if a reliable scanout position counter could + * not be read out. * * FIXME: * @@ -280,10 +274,10 @@ struct drm_driver { * move it to &struct drm_crtc_helper_funcs, like all the other * helper-internal hooks. */ - int (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode); + bool (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode);
/** * @get_vblank_timestamp:
Drive-by cleanup.
Signed-off-by: Daniel Vetter daniel.vetter@intel.com --- drivers/gpu/drm/drm_probe_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 85005d57bde6..efb5e5e8ce62 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -44,7 +44,7 @@ * * This library provides some helper code for output probing. It provides an * implementation of the core &drm_connector_funcs.fill_modes interface with - * drm_helper_probe_single_connector_modes. + * drm_helper_probe_single_connector_modes(). * * It also provides support for polling connectors with a work item and for * generic hotplug interrupt handling where the driver doesn't or cannot keep
dri-devel@lists.freedesktop.org