diff options
author | Dave Airlie <airlied@redhat.com> | 2017-03-07 13:59:53 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-03-07 13:59:53 +1000 |
commit | b558dfd56a5c1f915327967ecfe1181cf2a7a494 (patch) | |
tree | 28ed2b90b5d362eaf535b725a3f560eb645892f0 /include | |
parent | c1ae3cfa0e89fa1a7ecc4c99031f5e9ae99d9201 (diff) | |
parent | ca39b449f6d03e8235969f12f5dd25b8eb4304d6 (diff) | |
download | linux-b558dfd56a5c1f915327967ecfe1181cf2a7a494.tar.bz2 |
Merge tag 'drm-misc-next-2017-03-06' of git://anongit.freedesktop.org/git/drm-misc into drm-next
First slice of drm-misc-next for 4.12:
Core/subsystem-wide:
- link status core patch from Manasi, for signalling link train fail
to userspace. I also had the i915 patch in here, but that had a
small buglet in our CI, so reverted.
- more debugfs_remove removal from Noralf, almost there now (Noralf
said he'll try to follow up with the stragglers).
- drm todo moved into kerneldoc, for better visibility (see
Documentation/gpu/todo.rst), lots of starter tasks in there.
- devm_ of helpers + use it in sti (from Ben Gaignard, acked by Rob
Herring)
- extended framebuffer fbdev support (for fbdev flipping), and vblank
wait ioctl fbdev support (Maxime Ripard)
- misc small things all over, as usual
- add vblank callbacks to drm_crtc_funcs, plus make lots of good use
of this to simplify drivers (Shawn Guo)
- new atomic iterator macros to unconfuse old vs. new state
Small drivers:
- vc4 improvements from Eric
- vc4 kerneldocs (Eric)!
- tons of improvements for dw-mipi-dsi in rockchip from John Keeping
and Chris Zhong.
- MAINTAINERS entries for drivers managed in drm-misc. It's not yet
official, still an experiment, but definitely not complete fail and
better to avoid confusion. We kinda screwed that up with drm-misc a
bit when we started committers last year.
- qxl atomic conversion (Gabriel Krisman)
- bunch of virtual driver polish (qxl, virgl, ...)
- misc tiny patches all over
This is the first time we've done the same merge-window blackout for
drm-misc as we've done for drm-intel for ages, hence why we have a
_lot_ of stuff queued already. But it's still only half of drm-intel
(room to grow!), and the drivers in drm-misc experiment seems to work
at least insofar as that you also get lots of driver updates here
alredy.
* tag 'drm-misc-next-2017-03-06' of git://anongit.freedesktop.org/git/drm-misc: (141 commits)
drm/vc4: Fix OOPSes from trying to cache a partially constructed BO.
drm/vc4: Fulfill user BO creation requests from the kernel BO cache.
Revert "drm/i915: Implement Link Rate fallback on Link training failure"
drm/fb-helper: implement ioctl FBIO_WAITFORVSYNC
drm: Update drm_fbdev_cma_init documentation
drm/rockchip/dsi: add dw-mipi power domain support
drm/rockchip/dsi: fix insufficient bandwidth of some panel
dt-bindings: add power domain node for dw-mipi-rockchip
drm/rockchip/dsi: remove mode_valid function
drm/rockchip/dsi: dw-mipi: correct the coding style
drm/rockchip/dsi: dw-mipi: support RK3399 mipi dsi
dt-bindings: add rk3399 support for dw-mipi-rockchip
drm/rockchip: dw-mipi-dsi: add reset control
drm/rockchip: dw-mipi-dsi: support non-burst modes
drm/rockchip: dw-mipi-dsi: defer probe if panel is not loaded
drm/rockchip: vop: test for P{H,V}SYNC
drm/rockchip: dw-mipi-dsi: use positive check for N{H, V}SYNC
drm/rockchip: dw-mipi-dsi: use specific poll helper
drm/rockchip: dw-mipi-dsi: improve PLL configuration
drm/rockchip: dw-mipi-dsi: properly configure PHY timing
...
Diffstat (limited to 'include')
-rw-r--r-- | include/drm/drm_atomic.h | 81 | ||||
-rw-r--r-- | include/drm/drm_atomic_helper.h | 2 | ||||
-rw-r--r-- | include/drm/drm_connector.h | 75 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 53 | ||||
-rw-r--r-- | include/drm/drm_drv.h | 16 | ||||
-rw-r--r-- | include/drm/drm_edid.h | 7 | ||||
-rw-r--r-- | include/drm/drm_fb_helper.h | 16 | ||||
-rw-r--r-- | include/drm/drm_framebuffer.h | 49 | ||||
-rw-r--r-- | include/drm/drm_gem.h | 80 | ||||
-rw-r--r-- | include/drm/drm_irq.h | 1 | ||||
-rw-r--r-- | include/drm/drm_mm.h | 5 | ||||
-rw-r--r-- | include/drm/drm_mode_config.h | 13 | ||||
-rw-r--r-- | include/drm/drm_mode_object.h | 36 | ||||
-rw-r--r-- | include/drm/drm_print.h | 3 | ||||
-rw-r--r-- | include/drm/drm_property.h | 35 | ||||
-rw-r--r-- | include/linux/of_platform.h | 11 | ||||
-rw-r--r-- | include/linux/reservation.h | 20 | ||||
-rw-r--r-- | include/uapi/drm/drm_mode.h | 4 |
18 files changed, 433 insertions, 74 deletions
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 052ab161b239..c6f355a970d2 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -138,12 +138,12 @@ struct drm_crtc_commit { struct __drm_planes_state { struct drm_plane *ptr; - struct drm_plane_state *state; + struct drm_plane_state *state, *old_state, *new_state; }; struct __drm_crtcs_state { struct drm_crtc *ptr; - struct drm_crtc_state *state; + struct drm_crtc_state *state, *old_state, *new_state; struct drm_crtc_commit *commit; s32 __user *out_fence_ptr; unsigned last_vblank_count; @@ -151,7 +151,7 @@ struct __drm_crtcs_state { struct __drm_connnectors_state { struct drm_connector *ptr; - struct drm_connector_state *state; + struct drm_connector_state *state, *old_state, *new_state; }; /** @@ -398,6 +398,31 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (__i)++) \ for_each_if (connector) +#define for_each_oldnew_connector_in_state(__state, connector, old_connector_state, new_connector_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->num_connector && \ + ((connector) = (__state)->connectors[__i].ptr, \ + (old_connector_state) = (__state)->connectors[__i].old_state, \ + (new_connector_state) = (__state)->connectors[__i].new_state, 1); \ + (__i)++) \ + for_each_if (connector) + +#define for_each_old_connector_in_state(__state, connector, old_connector_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->num_connector && \ + ((connector) = (__state)->connectors[__i].ptr, \ + (old_connector_state) = (__state)->connectors[__i].old_state, 1); \ + (__i)++) \ + for_each_if (connector) + +#define for_each_new_connector_in_state(__state, connector, new_connector_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->num_connector && \ + ((connector) = (__state)->connectors[__i].ptr, \ + (new_connector_state) = (__state)->connectors[__i].new_state, 1); \ + (__i)++) \ + for_each_if (connector) + #define for_each_crtc_in_state(__state, crtc, crtc_state, __i) \ for ((__i) = 0; \ (__i) < (__state)->dev->mode_config.num_crtc && \ @@ -406,6 +431,31 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (__i)++) \ for_each_if (crtc_state) +#define for_each_oldnew_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->dev->mode_config.num_crtc && \ + ((crtc) = (__state)->crtcs[__i].ptr, \ + (old_crtc_state) = (__state)->crtcs[__i].old_state, \ + (new_crtc_state) = (__state)->crtcs[__i].new_state, 1); \ + (__i)++) \ + for_each_if (crtc) + +#define for_each_old_crtc_in_state(__state, crtc, old_crtc_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->dev->mode_config.num_crtc && \ + ((crtc) = (__state)->crtcs[__i].ptr, \ + (old_crtc_state) = (__state)->crtcs[__i].old_state, 1); \ + (__i)++) \ + for_each_if (crtc) + +#define for_each_new_crtc_in_state(__state, crtc, new_crtc_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->dev->mode_config.num_crtc && \ + ((crtc) = (__state)->crtcs[__i].ptr, \ + (new_crtc_state) = (__state)->crtcs[__i].new_state, 1); \ + (__i)++) \ + for_each_if (crtc) + #define for_each_plane_in_state(__state, plane, plane_state, __i) \ for ((__i) = 0; \ (__i) < (__state)->dev->mode_config.num_total_plane && \ @@ -414,6 +464,31 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (__i)++) \ for_each_if (plane_state) +#define for_each_oldnew_plane_in_state(__state, plane, old_plane_state, new_plane_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->dev->mode_config.num_total_plane && \ + ((plane) = (__state)->planes[__i].ptr, \ + (old_plane_state) = (__state)->planes[__i].old_state, \ + (new_plane_state) = (__state)->planes[__i].new_state, 1); \ + (__i)++) \ + for_each_if (plane) + +#define for_each_old_plane_in_state(__state, plane, old_plane_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->dev->mode_config.num_total_plane && \ + ((plane) = (__state)->planes[__i].ptr, \ + (old_plane_state) = (__state)->planes[__i].old_state, 1); \ + (__i)++) \ + for_each_if (plane) + +#define for_each_new_plane_in_state(__state, plane, new_plane_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->dev->mode_config.num_total_plane && \ + ((plane) = (__state)->planes[__i].ptr, \ + (new_plane_state) = (__state)->planes[__i].new_state, 1); \ + (__i)++) \ + for_each_if (plane) + /** * drm_atomic_crtc_needs_modeset - compute combined modeset need * @state: &drm_crtc_state for the CRTC diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index d066e9491ae3..9ceda379ce58 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -105,6 +105,8 @@ int __drm_atomic_helper_set_config(struct drm_mode_set *set, int drm_atomic_helper_disable_all(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx); struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev); +int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state, + struct drm_modeset_acquire_ctx *ctx); int drm_atomic_helper_resume(struct drm_device *dev, struct drm_atomic_state *state); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index e5e1eddd19fb..fabb35aba5f6 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -90,6 +90,22 @@ enum subpixel_order { }; /** + * enum drm_link_status - connector's link_status property value + * + * This enum is used as the connector's link status property value. + * It is set to the values defined in uapi. + * + * @DRM_LINK_STATUS_GOOD: DP Link is Good as a result of successful + * link training + * @DRM_LINK_STATUS_BAD: DP Link is BAD as a result of link training + * failure + */ +enum drm_link_status { + DRM_LINK_STATUS_GOOD = DRM_MODE_LINK_STATUS_GOOD, + DRM_LINK_STATUS_BAD = DRM_MODE_LINK_STATUS_BAD, +}; + +/** * struct drm_display_info - runtime data about the connected sink * * Describes a given display (e.g. CRT or flat panel) and its limitations. For @@ -243,6 +259,12 @@ struct drm_connector_state { struct drm_encoder *best_encoder; + /** + * @link_status: Connector link_status to keep track of whether link is + * GOOD or BAD to notify userspace if retraining is necessary. + */ + enum drm_link_status link_status; + struct drm_atomic_state *state; struct drm_tv_connector_state tv; @@ -795,25 +817,50 @@ static inline struct drm_connector *drm_connector_lookup(struct drm_device *dev, } /** - * drm_connector_reference - incr the connector refcnt - * @connector: connector + * drm_connector_get - acquire a connector reference + * @connector: DRM connector * * This function increments the connector's refcount. */ +static inline void drm_connector_get(struct drm_connector *connector) +{ + drm_mode_object_get(&connector->base); +} + +/** + * drm_connector_put - release a connector reference + * @connector: DRM connector + * + * This function decrements the connector's reference count and frees the + * object if the reference count drops to zero. + */ +static inline void drm_connector_put(struct drm_connector *connector) +{ + drm_mode_object_put(&connector->base); +} + +/** + * drm_connector_reference - acquire a connector reference + * @connector: DRM connector + * + * This is a compatibility alias for drm_connector_get() and should not be + * used by new code. + */ static inline void drm_connector_reference(struct drm_connector *connector) { - drm_mode_object_reference(&connector->base); + drm_connector_get(connector); } /** - * drm_connector_unreference - unref a connector - * @connector: connector to unref + * drm_connector_unreference - release a connector reference + * @connector: DRM connector * - * This function decrements the connector's refcount and frees it if it drops to zero. + * This is a compatibility alias for drm_connector_put() and should not be + * used by new code. */ static inline void drm_connector_unreference(struct drm_connector *connector) { - drm_mode_object_unreference(&connector->base); + drm_connector_put(connector); } const char *drm_get_connector_status_name(enum drm_connector_status status); @@ -837,6 +884,8 @@ int drm_mode_connector_set_path_property(struct drm_connector *connector, int drm_mode_connector_set_tile_property(struct drm_connector *connector); int drm_mode_connector_update_edid_property(struct drm_connector *connector, const struct edid *edid); +void drm_mode_connector_set_link_status_property(struct drm_connector *connector, + uint64_t link_status); /** * struct drm_tile_group - Tile group metadata @@ -882,7 +931,7 @@ void drm_mode_put_tile_group(struct drm_device *dev, * * This iterator tracks state needed to be able to walk the connector_list * within struct drm_mode_config. Only use together with - * drm_connector_list_iter_get(), drm_connector_list_iter_put() and + * drm_connector_list_iter_begin(), drm_connector_list_iter_end() and * drm_connector_list_iter_next() respectively the convenience macro * drm_for_each_connector_iter(). */ @@ -892,11 +941,11 @@ struct drm_connector_list_iter { struct drm_connector *conn; }; -void drm_connector_list_iter_get(struct drm_device *dev, - struct drm_connector_list_iter *iter); +void drm_connector_list_iter_begin(struct drm_device *dev, + struct drm_connector_list_iter *iter); struct drm_connector * drm_connector_list_iter_next(struct drm_connector_list_iter *iter); -void drm_connector_list_iter_put(struct drm_connector_list_iter *iter); +void drm_connector_list_iter_end(struct drm_connector_list_iter *iter); /** * drm_for_each_connector_iter - connector_list iterator macro @@ -904,8 +953,8 @@ void drm_connector_list_iter_put(struct drm_connector_list_iter *iter); * @iter: &struct drm_connector_list_iter * * Note that @connector is only valid within the list body, if you want to use - * @connector after calling drm_connector_list_iter_put() then you need to grab - * your own reference first using drm_connector_reference(). + * @connector after calling drm_connector_list_iter_end() then you need to grab + * your own reference first using drm_connector_begin(). */ #define drm_for_each_connector_iter(connector, iter) \ while ((connector = drm_connector_list_iter_next(iter))) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 8f0b195e4a59..bda9347554a1 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -155,10 +155,17 @@ struct drm_crtc_state { * Target vertical blank period when a page flip * should take effect. */ - u32 target_vblank; /** + * @pageflip_flags: + * + * DRM_MODE_PAGE_FLIP_* flags, as passed to the page flip ioctl. + * Zero in any other case. + */ + u32 pageflip_flags; + + /** * @event: * * Optional pointer to a DRM event to signal upon completion of the @@ -601,6 +608,50 @@ struct drm_crtc_funcs { */ void (*atomic_print_state)(struct drm_printer *p, const struct drm_crtc_state *state); + + /** + * @get_vblank_counter: + * + * Driver callback for fetching a raw hardware vblank counter for the + * CRTC. It's meant to be used by new drivers as the replacement of + * &drm_driver.get_vblank_counter hook. + * + * This callback is optional. If a device doesn't have a hardware + * counter, the driver can simply leave the hook as NULL. The DRM core + * will account for missed vblank events while interrupts where disabled + * based on system timestamps. + * + * Wraparound handling and loss of events due to modesetting is dealt + * with in the DRM core code, as long as drivers call + * drm_crtc_vblank_off() and drm_crtc_vblank_on() when disabling or + * enabling a CRTC. + * + * Returns: + * + * Raw vblank counter value. + */ + u32 (*get_vblank_counter)(struct drm_crtc *crtc); + + /** + * @enable_vblank: + * + * Enable vblank interrupts for the CRTC. It's meant to be used by + * new drivers as the replacement of &drm_driver.enable_vblank hook. + * + * Returns: + * + * Zero on success, appropriate errno if the vblank interrupt cannot + * be enabled. + */ + int (*enable_vblank)(struct drm_crtc *crtc); + + /** + * @disable_vblank: + * + * Disable vblank interrupts for the CRTC. It's meant to be used by + * new drivers as the replacement of &drm_driver.disable_vblank hook. + */ + void (*disable_vblank)(struct drm_crtc *crtc); }; /** diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 5699f42195fe..4e66fbb56773 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -120,16 +120,18 @@ struct drm_driver { * * Driver callback for fetching a raw hardware vblank counter for the * CRTC specified with the pipe argument. If a device doesn't have a - * hardware counter, the driver can simply use - * drm_vblank_no_hw_counter() function. The DRM core will account for - * missed vblank events while interrupts where disabled based on system - * timestamps. + * hardware counter, the driver can simply leave the hook as NULL. + * The DRM core will account for missed vblank events while interrupts + * where disabled based on system timestamps. * * Wraparound handling and loss of events due to modesetting is dealt * with in the DRM core code, as long as drivers call * drm_crtc_vblank_off() and drm_crtc_vblank_on() when disabling or * enabling a CRTC. * + * This is deprecated and should not be used by new drivers. + * Use &drm_crtc_funcs.get_vblank_counter instead. + * * Returns: * * Raw vblank counter value. @@ -142,6 +144,9 @@ struct drm_driver { * Enable vblank interrupts for the CRTC specified with the pipe * argument. * + * This is deprecated and should not be used by new drivers. + * Use &drm_crtc_funcs.enable_vblank instead. + * * Returns: * * Zero on success, appropriate errno if the given @crtc's vblank @@ -154,6 +159,9 @@ struct drm_driver { * * Disable vblank interrupts for the CRTC specified with the pipe * argument. + * + * This is deprecated and should not be used by new drivers. + * Use &drm_crtc_funcs.disable_vblank instead. */ void (*disable_vblank) (struct drm_device *dev, unsigned int pipe); diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 577d5063e63d..3ead84d93792 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -332,11 +332,12 @@ int drm_av_sync_delay(struct drm_connector *connector, const struct drm_display_mode *mode); #ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE -int drm_load_edid_firmware(struct drm_connector *connector); +struct edid *drm_load_edid_firmware(struct drm_connector *connector); #else -static inline int drm_load_edid_firmware(struct drm_connector *connector) +static inline struct edid * +drm_load_edid_firmware(struct drm_connector *connector) { - return 0; + return ERR_PTR(-ENOENT); } #endif diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 6f5acebb266a..119e5e4609c7 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -230,7 +230,8 @@ struct drm_fb_helper { .fb_blank = drm_fb_helper_blank, \ .fb_pan_display = drm_fb_helper_pan_display, \ .fb_debug_enter = drm_fb_helper_debug_enter, \ - .fb_debug_leave = drm_fb_helper_debug_leave + .fb_debug_leave = drm_fb_helper_debug_leave, \ + .fb_ioctl = drm_fb_helper_ioctl #ifdef CONFIG_DRM_FBDEV_EMULATION void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, @@ -249,7 +250,6 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper); struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper); void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper); -void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper); void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper, uint32_t fb_width, uint32_t fb_height); void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, @@ -285,6 +285,9 @@ void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); +int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, + unsigned long arg); + int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper); int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel); int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper); @@ -354,9 +357,6 @@ drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper) static inline void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper) { } -static inline void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper) -{ -} static inline void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper, @@ -375,6 +375,12 @@ static inline int drm_fb_helper_setcmap(struct fb_cmap *cmap, return 0; } +static inline int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, + unsigned long arg) +{ + return 0; +} + static inline void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) { } diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h index dd1e3e99dcff..5244f059d23a 100644 --- a/include/drm/drm_framebuffer.h +++ b/include/drm/drm_framebuffer.h @@ -101,8 +101,8 @@ struct drm_framebuffer_funcs { * cleanup (like releasing the reference(s) on the backing GEM bo(s)) * should be deferred. In cases like this, the driver would like to * hold a ref to the fb even though it has already been removed from - * userspace perspective. See drm_framebuffer_reference() and - * drm_framebuffer_unreference(). + * userspace perspective. See drm_framebuffer_get() and + * drm_framebuffer_put(). * * The refcount is stored inside the mode object @base. */ @@ -204,25 +204,50 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb); void drm_framebuffer_unregister_private(struct drm_framebuffer *fb); /** - * drm_framebuffer_reference - incr the fb refcnt - * @fb: framebuffer + * drm_framebuffer_get - acquire a framebuffer reference + * @fb: DRM framebuffer + * + * This function increments the framebuffer's reference count. + */ +static inline void drm_framebuffer_get(struct drm_framebuffer *fb) +{ + drm_mode_object_get(&fb->base); +} + +/** + * drm_framebuffer_put - release a framebuffer reference + * @fb: DRM framebuffer + * + * This function decrements the framebuffer's reference count and frees the + * framebuffer if the reference count drops to zero. + */ +static inline void drm_framebuffer_put(struct drm_framebuffer *fb) +{ + drm_mode_object_put(&fb->base); +} + +/** + * drm_framebuffer_reference - acquire a framebuffer reference + * @fb: DRM framebuffer * - * This functions increments the fb's refcount. + * This is a compatibility alias for drm_framebuffer_get() and should not be + * used by new code. */ static inline void drm_framebuffer_reference(struct drm_framebuffer *fb) { - drm_mode_object_reference(&fb->base); + drm_framebuffer_get(fb); } /** - * drm_framebuffer_unreference - unref a framebuffer - * @fb: framebuffer to unref + * drm_framebuffer_unreference - release a framebuffer reference + * @fb: DRM framebuffer * - * This functions decrements the fb's refcount and frees it if it drops to zero. + * This is a compatibility alias for drm_framebuffer_put() and should not be + * used by new code. */ static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb) { - drm_mode_object_unreference(&fb->base); + drm_framebuffer_put(fb); } /** @@ -248,9 +273,9 @@ static inline void drm_framebuffer_assign(struct drm_framebuffer **p, struct drm_framebuffer *fb) { if (fb) - drm_framebuffer_reference(fb); + drm_framebuffer_get(fb); if (*p) - drm_framebuffer_unreference(*p); + drm_framebuffer_put(*p); *p = fb; } diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index 449a41b56ffc..3b2a28f7f49f 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -48,9 +48,9 @@ struct drm_gem_object { * * Reference count of this object * - * Please use drm_gem_object_reference() to acquire and - * drm_gem_object_unreference() or drm_gem_object_unreference_unlocked() - * to release a reference to a GEM buffer object. + * Please use drm_gem_object_get() to acquire and drm_gem_object_put() + * or drm_gem_object_put_unlocked() to release a reference to a GEM + * buffer object. */ struct kref refcount; @@ -187,42 +187,90 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size, int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); /** - * drm_gem_object_reference - acquire a GEM BO reference + * drm_gem_object_get - acquire a GEM buffer object reference * @obj: GEM buffer object * - * This acquires additional reference to @obj. It is illegal to call this - * without already holding a reference. No locks required. + * This function acquires an additional reference to @obj. It is illegal to + * call this without already holding a reference. No locks required. */ -static inline void -drm_gem_object_reference(struct drm_gem_object *obj) +static inline void drm_gem_object_get(struct drm_gem_object *obj) { kref_get(&obj->refcount); } /** - * __drm_gem_object_unreference - raw function to release a GEM BO reference + * __drm_gem_object_put - raw function to release a GEM buffer object reference * @obj: GEM buffer object * * This function is meant to be used by drivers which are not encumbered with * &drm_device.struct_mutex legacy locking and which are using the * gem_free_object_unlocked callback. It avoids all the locking checks and - * locking overhead of drm_gem_object_unreference() and - * drm_gem_object_unreference_unlocked(). + * locking overhead of drm_gem_object_put() and drm_gem_object_put_unlocked(). * * Drivers should never call this directly in their code. Instead they should - * wrap it up into a ``driver_gem_object_unreference(struct driver_gem_object - * *obj)`` wrapper function, and use that. Shared code should never call this, to + * wrap it up into a ``driver_gem_object_put(struct driver_gem_object *obj)`` + * wrapper function, and use that. Shared code should never call this, to * avoid breaking drivers by accident which still depend upon * &drm_device.struct_mutex locking. */ static inline void -__drm_gem_object_unreference(struct drm_gem_object *obj) +__drm_gem_object_put(struct drm_gem_object *obj) { kref_put(&obj->refcount, drm_gem_object_free); } -void drm_gem_object_unreference_unlocked(struct drm_gem_object *obj); -void drm_gem_object_unreference(struct drm_gem_object *obj); +void drm_gem_object_put_unlocked(struct drm_gem_object *obj); +void drm_gem_object_put(struct drm_gem_object *obj); + +/** + * drm_gem_object_reference - acquire a GEM buffer object reference + * @obj: GEM buffer object + * + * This is a compatibility alias for drm_gem_object_get() and should not be + * used by new code. + */ +static inline void drm_gem_object_reference(struct drm_gem_object *obj) +{ + drm_gem_object_get(obj); +} + +/** + * __drm_gem_object_unreference - raw function to release a GEM buffer object + * reference + * @obj: GEM buffer object + * + * This is a compatibility alias for __drm_gem_object_put() and should not be + * used by new code. + */ +static inline void __drm_gem_object_unreference(struct drm_gem_object *obj) +{ + __drm_gem_object_put(obj); +} + +/** + * drm_gem_object_unreference_unlocked - release a GEM buffer object reference + * @obj: GEM buffer object + * + * This is a compatibility alias for drm_gem_object_put_unlocked() and should + * not be used by new code. + */ +static inline void +drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) +{ + drm_gem_object_put_unlocked(obj); +} + +/** + * drm_gem_object_unreference - release a GEM buffer object reference + * @obj: GEM buffer object + * + * This is a compatibility alias for drm_gem_object_put() and should not be + * used by new code. + */ +static inline void drm_gem_object_unreference(struct drm_gem_object *obj) +{ + drm_gem_object_put(obj); +} int drm_gem_handle_create(struct drm_file *file_priv, struct drm_gem_object *obj, diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index 2fb880462a57..cf0be6594c8c 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -152,7 +152,6 @@ void drm_crtc_vblank_reset(struct drm_crtc *crtc); 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); -u32 drm_vblank_no_hw_counter(struct drm_device *dev, unsigned int pipe); int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error, diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index 2ef16bf25826..49b292e98fec 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -460,10 +460,13 @@ __drm_mm_interval_first(const struct drm_mm *mm, u64 start, u64 last); * but using the internal interval tree to accelerate the search for the * starting node, and so not safe against removal of elements. It assumes * that @end is within (or is the upper limit of) the drm_mm allocator. + * If [@start, @end] are beyond the range of the drm_mm, the iterator may walk + * over the special _unallocated_ &drm_mm.head_node, and may even continue + * indefinitely. */ #define drm_mm_for_each_node_in_range(node__, mm__, start__, end__) \ for (node__ = __drm_mm_interval_first((mm__), (start__), (end__)-1); \ - node__ && node__->start < (end__); \ + node__->start < (end__); \ node__ = list_next_entry(node__, node_list)) void drm_mm_scan_init_with_range(struct drm_mm_scan *scan, diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 26ff46ab26fb..ea169a90b3c4 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -267,7 +267,7 @@ struct drm_mode_config_funcs { * passed-in &drm_atomic_state. This hook is called when the caller * encountered a &drm_modeset_lock deadlock and needs to drop all * already acquired locks as part of the deadlock avoidance dance - * implemented in drm_modeset_lock_backoff(). + * implemented in drm_modeset_backoff(). * * Any duplicated state must be invalidated since a concurrent atomic * update might change it, and the drm atomic interfaces always apply @@ -285,8 +285,8 @@ struct drm_mode_config_funcs { * itself. Note that the core first calls drm_atomic_state_clear() to * avoid code duplicate between the clear and free hooks. * - * Drivers that implement this must call drm_atomic_state_default_free() - * to release common resources. + * Drivers that implement this must call + * drm_atomic_state_default_release() to release common resources. */ void (*atomic_state_free)(struct drm_atomic_state *state); }; @@ -439,6 +439,11 @@ struct drm_mode_config { */ struct drm_property *tile_property; /** + * @link_status_property: Default connector property for link status + * of a connector + */ + struct drm_property *link_status_property; + /** * @plane_type_property: Default plane property to differentiate * CURSOR, PRIMARY and OVERLAY legacy uses of planes. */ @@ -661,7 +666,7 @@ struct drm_mode_config { /* cursor size */ uint32_t cursor_width, cursor_height; - struct drm_mode_config_helper_funcs *helper_private; + const struct drm_mode_config_helper_funcs *helper_private; }; void drm_mode_config_init(struct drm_device *dev); diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h index 2c017adf6d74..a767b4a30a6d 100644 --- a/include/drm/drm_mode_object.h +++ b/include/drm/drm_mode_object.h @@ -45,10 +45,10 @@ struct drm_device; * drm_object_attach_property() before the object is visible to userspace. * * - For objects with dynamic lifetimes (as indicated by a non-NULL @free_cb) it - * provides reference counting through drm_mode_object_reference() and - * drm_mode_object_unreference(). This is used by &drm_framebuffer, - * &drm_connector and &drm_property_blob. These objects provide specialized - * reference counting wrappers. + * provides reference counting through drm_mode_object_get() and + * drm_mode_object_put(). This is used by &drm_framebuffer, &drm_connector + * and &drm_property_blob. These objects provide specialized reference + * counting wrappers. */ struct drm_mode_object { uint32_t id; @@ -114,8 +114,32 @@ struct drm_object_properties { struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type); -void drm_mode_object_reference(struct drm_mode_object *obj); -void drm_mode_object_unreference(struct drm_mode_object *obj); +void drm_mode_object_get(struct drm_mode_object *obj); +void drm_mode_object_put(struct drm_mode_object *obj); + +/** + * drm_mode_object_reference - acquire a mode object reference + * @obj: DRM mode object + * + * This is a compatibility alias for drm_mode_object_get() and should not be + * used by new code. + */ +static inline void drm_mode_object_reference(struct drm_mode_object *obj) +{ + drm_mode_object_get(obj); +} + +/** + * drm_mode_object_unreference - release a mode object reference + * @obj: DRM mode object + * + * This is a compatibility alias for drm_mode_object_put() and should not be + * used by new code. + */ +static inline void drm_mode_object_unreference(struct drm_mode_object *obj) +{ + drm_mode_object_put(obj); +} int drm_object_property_set_value(struct drm_mode_object *obj, struct drm_property *property, diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 7d98763c0444..ca4d7c6321f2 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -26,6 +26,8 @@ #ifndef DRM_PRINT_H_ #define DRM_PRINT_H_ +#include <linux/compiler.h> +#include <linux/printk.h> #include <linux/seq_file.h> #include <linux/device.h> @@ -75,6 +77,7 @@ void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf); void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf); void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf); +__printf(2, 3) void drm_printf(struct drm_printer *p, const char *f, ...); diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h index f66fdb47551c..13e8c17d1c79 100644 --- a/include/drm/drm_property.h +++ b/include/drm/drm_property.h @@ -200,9 +200,8 @@ struct drm_property { * Blobs are used to store bigger values than what fits directly into the 64 * bits available for a &drm_property. * - * Blobs are reference counted using drm_property_reference_blob() and - * drm_property_unreference_blob(). They are created using - * drm_property_create_blob(). + * Blobs are reference counted using drm_property_blob_get() and + * drm_property_blob_put(). They are created using drm_property_create_blob(). */ struct drm_property_blob { struct drm_mode_object base; @@ -274,8 +273,34 @@ int drm_property_replace_global_blob(struct drm_device *dev, const void *data, struct drm_mode_object *obj_holds_id, struct drm_property *prop_holds_id); -struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob); -void drm_property_unreference_blob(struct drm_property_blob *blob); +struct drm_property_blob *drm_property_blob_get(struct drm_property_blob *blob); +void drm_property_blob_put(struct drm_property_blob *blob); + +/** + * drm_property_reference_blob - acquire a blob property reference + * @blob: DRM blob property + * + * This is a compatibility alias for drm_property_blob_get() and should not be + * used by new code. + */ +static inline struct drm_property_blob * +drm_property_reference_blob(struct drm_property_blob *blob) +{ + return drm_property_blob_get(blob); +} + +/** + * drm_property_unreference_blob - release a blob property reference + * @blob: DRM blob property + * + * This is a compatibility alias for drm_property_blob_put() and should not be + * used by new code. + */ +static inline void +drm_property_unreference_blob(struct drm_property_blob *blob) +{ + drm_property_blob_put(blob); +} /** * drm_connector_find - find property object diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 956a1006aefc..dc8224ae28d5 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -76,6 +76,10 @@ extern int of_platform_default_populate(struct device_node *root, const struct of_dev_auxdata *lookup, struct device *parent); extern void of_platform_depopulate(struct device *parent); + +extern int devm_of_platform_populate(struct device *dev); + +extern void devm_of_platform_depopulate(struct device *dev); #else static inline int of_platform_populate(struct device_node *root, const struct of_device_id *matches, @@ -91,6 +95,13 @@ static inline int of_platform_default_populate(struct device_node *root, return -ENODEV; } static inline void of_platform_depopulate(struct device *parent) { } + +static inline int devm_of_platform_populate(struct device *dev) +{ + return -ENODEV; +} + +static inline void devm_of_platform_depopulate(struct device *dev) { } #endif #if defined(CONFIG_OF_DYNAMIC) && defined(CONFIG_OF_ADDRESS) diff --git a/include/linux/reservation.h b/include/linux/reservation.h index 2b5a4679daea..156cfd330b66 100644 --- a/include/linux/reservation.h +++ b/include/linux/reservation.h @@ -167,6 +167,26 @@ reservation_object_lock(struct reservation_object *obj, } /** + * reservation_object_trylock - trylock the reservation object + * @obj: the reservation object + * + * Tries to lock the reservation object for exclusive access and modification. + * Note, that the lock is only against other writers, readers will run + * concurrently with a writer under RCU. The seqlock is used to notify readers + * if they overlap with a writer. + * + * Also note that since no context is provided, no deadlock protection is + * possible. + * + * Returns true if the lock was acquired, false otherwise. + */ +static inline bool __must_check +reservation_object_trylock(struct reservation_object *obj) +{ + return ww_mutex_trylock(&obj->lock); +} + +/** * reservation_object_unlock - unlock the reservation object * @obj: the reservation object * diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index ce7efe2e8a5e..8c67fc03d53d 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -123,6 +123,10 @@ extern "C" { #define DRM_MODE_DIRTY_ON 1 #define DRM_MODE_DIRTY_ANNOTATE 2 +/* Link Status options */ +#define DRM_MODE_LINK_STATUS_GOOD 0 +#define DRM_MODE_LINK_STATUS_BAD 1 + struct drm_mode_modeinfo { __u32 clock; __u16 hdisplay; |