From a1f1a79c51fd493887bb66d932ee66a23f8b1527 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 11 Oct 2014 22:08:57 -0700 Subject: drm: drm_err: Remove unnecessary __func__ argument Removing the unnecessary drm_err __func__ argument by using the equivalent %pf and __builtin_return_address(0) makes the code smaller for every use of the DRM_ERROR macro. For instance: (allmodconfig) $ size drivers/gpu/drm/i915/i915.o* text data bss dec hex filename 922447 193257 296736 1412440 158d58 drivers/gpu/drm/i915/i915.o.new 928111 193257 296736 1418104 15a378 drivers/gpu/drm/i915/i915.o.old Signed-off-by: Joe Perches Signed-off-by: Daniel Vetter --- include/drm/drmP.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 53ed87698a74..d7ebd7b207e3 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -125,8 +125,8 @@ struct dma_buf_attachment; extern __printf(2, 3) void drm_ut_debug_printk(const char *function_name, const char *format, ...); -extern __printf(2, 3) -void drm_err(const char *func, const char *format, ...); +extern __printf(1, 2) +void drm_err(const char *format, ...); /***********************************************************************/ /** \name DRM template customization defaults */ @@ -155,7 +155,7 @@ void drm_err(const char *func, const char *format, ...); * \param arg arguments */ #define DRM_ERROR(fmt, ...) \ - drm_err(__func__, fmt, ##__VA_ARGS__) + drm_err(fmt, ##__VA_ARGS__) /** * Rate limited error output. Like DRM_ERROR() but won't flood the log. @@ -170,7 +170,7 @@ void drm_err(const char *func, const char *format, ...); DEFAULT_RATELIMIT_BURST); \ \ if (__ratelimit(&_rs)) \ - drm_err(__func__, fmt, ##__VA_ARGS__); \ + drm_err(fmt, ##__VA_ARGS__); \ }) #define DRM_INFO(fmt, ...) \ -- cgit v1.2.3 From 32197aab0425dbecc38462a91bc5c8acf70b2036 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Mon, 20 Oct 2014 23:53:13 +0900 Subject: gpu:drm: Fix typo in Documentation/DocBook/drm.xml This patch fix spelling typos found in drm.xml. It is because the file is generated from comments in source codes, I have to fix the typos within source files. Signed-off-by: Masanari Iida Acked-by: Randy Dunlap Signed-off-by: Daniel Vetter --- include/drm/drm_dp_mst_helper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 9b446ada2532..3ecfcc143bdd 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -28,7 +28,7 @@ struct drm_dp_mst_branch; /** - * struct drm_dp_vcpi - Virtual Channel Payload Identifer + * struct drm_dp_vcpi - Virtual Channel Payload Identifier * @vcpi: Virtual channel ID. * @pbn: Payload Bandwidth Number for this channel * @aligned_pbn: PBN aligned with slot size -- cgit v1.2.3 From e45708976aea3a3c3aa959e3cc2b703fefbd758a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 22 Oct 2014 11:16:36 +0200 Subject: drm/dp-helper: Move the legacy helpers to gma500 Except for gma500 all drivers are converted to the new style helpers, which have much better abstraction of the underlying hw protocols and already much more helper functions (including the entire mst library) on top of them. Since no one seems to work on converting gma500 let's just move the code away so that new drivers don't end up accidentally using this. Cc: Patrik Jakobsson Reviewed-by: Patrik Jakobsson Reviewed-by: Alan Cox [danvet: Add __deprecated as requested by Alan. Also add a short FIXME comment and drop the EXPORT_SYMBOL which is no longer needed.] Signed-off-by: Daniel Vetter --- include/drm/drm_dp_helper.h | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'include') diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 9305c718d789..afebb08eee3a 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -404,26 +404,6 @@ #define MODE_I2C_READ 4 #define MODE_I2C_STOP 8 -/** - * struct i2c_algo_dp_aux_data - driver interface structure for i2c over dp - * aux algorithm - * @running: set by the algo indicating whether an i2c is ongoing or whether - * the i2c bus is quiescent - * @address: i2c target address for the currently ongoing transfer - * @aux_ch: driver callback to transfer a single byte of the i2c payload - */ -struct i2c_algo_dp_aux_data { - bool running; - u16 address; - int (*aux_ch) (struct i2c_adapter *adapter, - int mode, uint8_t write_byte, - uint8_t *read_byte); -}; - -int -i2c_dp_aux_add_bus(struct i2c_adapter *adapter); - - #define DP_LINK_STATUS_SIZE 6 bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE], int lane_count); -- cgit v1.2.3 From 3cb9ae4fd82ebc9759bc59998c88c385d35496fe Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 29 Oct 2014 10:03:57 +0100 Subject: drm: Move drm_crtc_init from drm_crtc.h to drm_plane_helper.h Just a bit of OCD cleanup on headers - this function isn't the core interface any more but just a helper for drivers who haven't yet transitioned to universal planes. Put the declaration at the right spot and sprinkle necessary #includes over all drivers. Maybe this helps to encourage driver maintainers to do the switch. v2: Fix #include ordering for tegra, reported by 0-day builder. v3: Include required headers, reported by Thierry. Cc: Matt Roper Cc: Thierry Reding Reviewed-by: Matt Roper Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- include/drm/drm_crtc.h | 3 --- include/drm/drm_plane_helper.h | 5 +++++ 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c40070a92d6b..c3baaee09498 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -880,9 +880,6 @@ extern int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_plane *primary, struct drm_plane *cursor, const struct drm_crtc_funcs *funcs); -extern int drm_crtc_init(struct drm_device *dev, - struct drm_crtc *crtc, - const struct drm_crtc_funcs *funcs); extern void drm_crtc_cleanup(struct drm_crtc *crtc); extern unsigned int drm_crtc_index(struct drm_crtc *crtc); diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h index 52e6870534b2..fa60d19f91c0 100644 --- a/include/drm/drm_plane_helper.h +++ b/include/drm/drm_plane_helper.h @@ -25,6 +25,7 @@ #define DRM_PLANE_HELPER_H #include +#include /* * Drivers that don't allow primary plane scaling may pass this macro in place @@ -42,6 +43,10 @@ * planes. */ +extern int drm_crtc_init(struct drm_device *dev, + struct drm_crtc *crtc, + const struct drm_crtc_funcs *funcs); + extern int drm_plane_helper_check_update(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, -- cgit v1.2.3 From 3bf0401cddc00e90bd07f24cbf3fed88be24c399 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 27 Oct 2014 16:54:27 +0100 Subject: drm: Pull drm_crtc.h into the kerneldoc template While writing atomic docs I've noticed that I don't get any errors for my screw-ups in drm_crtc.h. Fix this immediately. This just does the bare minimum to get starts, lots of stuff isn't properly documented yet unfortunately. v2: Fix adjacent spelling error Sean noticed. Reviewed-by: Sean Paul Cc: Sean Paul Reviewed-by: Thierry Reding Signed-off-by: Daniel Vetter --- include/drm/drm_crtc.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c3baaee09498..3a8060575628 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -142,8 +142,8 @@ struct drm_framebuffer_funcs { int (*create_handle)(struct drm_framebuffer *fb, struct drm_file *file_priv, unsigned int *handle); - /** - * Optinal callback for the dirty fb ioctl. + /* + * Optional callback for the dirty fb ioctl. * * Userspace can notify the driver via this callback * that a area of the framebuffer has changed and should @@ -226,7 +226,7 @@ struct drm_plane; struct drm_bridge; /** - * drm_crtc_funcs - control CRTCs for a given device + * struct drm_crtc_funcs - control CRTCs for a given device * @save: save CRTC state * @restore: restore CRTC state * @reset: reset CRTC after state has been invalidated (e.g. resume) @@ -290,7 +290,7 @@ struct drm_crtc_funcs { }; /** - * drm_crtc - central CRTC control structure + * struct drm_crtc - central CRTC control structure * @dev: parent DRM device * @head: list management * @mutex: per-CRTC locking @@ -322,7 +322,7 @@ struct drm_crtc { struct device_node *port; struct list_head head; - /** + /* * crtc mutex * * This provides a read lock for the overall crtc state (mode, dpms @@ -377,7 +377,7 @@ struct drm_crtc { /** - * drm_connector_funcs - control connectors on a given device + * struct drm_connector_funcs - control connectors on a given device * @dpms: set power state (see drm_crtc_funcs above) * @save: save connector state * @restore: restore connector state @@ -414,7 +414,7 @@ struct drm_connector_funcs { }; /** - * drm_encoder_funcs - encoder controls + * struct drm_encoder_funcs - encoder controls * @reset: reset state (e.g. at init or resume time) * @destroy: cleanup and free associated data * @@ -428,7 +428,7 @@ struct drm_encoder_funcs { #define DRM_CONNECTOR_MAX_ENCODER 3 /** - * drm_encoder - central DRM encoder structure + * struct drm_encoder - central DRM encoder structure * @dev: parent DRM device * @head: list management * @base: base KMS object @@ -472,7 +472,7 @@ struct drm_encoder { #define MAX_ELD_BYTES 128 /** - * drm_connector - central DRM connector control structure + * struct drm_connector - central DRM connector control structure * @dev: parent DRM device * @kdev: kernel device for sysfs attributes * @attr: sysfs attributes @@ -566,7 +566,7 @@ struct drm_connector { }; /** - * drm_plane_funcs - driver plane control functions + * struct drm_plane_funcs - driver plane control functions * @update_plane: update the plane configuration * @disable_plane: shut down the plane * @destroy: clean up plane resources @@ -594,7 +594,7 @@ enum drm_plane_type { }; /** - * drm_plane - central DRM plane control structure + * struct drm_plane - central DRM plane control structure * @dev: DRM device this plane belongs to * @head: for list management * @base: base mode object @@ -632,7 +632,7 @@ struct drm_plane { }; /** - * drm_bridge_funcs - drm_bridge control functions + * struct drm_bridge_funcs - drm_bridge control functions * @mode_fixup: Try to fixup (or reject entirely) proposed mode for this bridge * @disable: Called right before encoder prepare, disables the bridge * @post_disable: Called right after encoder prepare, for lockstepped disable @@ -656,7 +656,7 @@ struct drm_bridge_funcs { }; /** - * drm_bridge - central DRM bridge control structure + * struct drm_bridge - central DRM bridge control structure * @dev: DRM device this bridge belongs to * @head: list management * @base: base mode object @@ -674,7 +674,7 @@ struct drm_bridge { }; /** - * drm_mode_set - new values for a CRTC config change + * struct drm_mode_set - new values for a CRTC config change * @head: list management * @fb: framebuffer to use for new config * @crtc: CRTC whose configuration we're about to change -- cgit v1.2.3 From 2c0c33d41e0ecb46c37583a6179eeb1f16767296 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 27 Oct 2014 20:19:38 +0100 Subject: drm: fixup kerneldoc in drm_crtc.h I've tried to cc all the people who have recently added new stuff but forgotten to update documentation. I've also decided not to bother documenting the massive property list in struct drm_mode_config. If that beast keeps on growing we might want to extract it into a separate structure which we won't document. Cc: Thomas Wood Cc: Sean Paul Cc: Russell King Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- include/drm/drm_crtc.h | 51 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 3a8060575628..125bb7f290a1 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -231,6 +231,7 @@ struct drm_bridge; * @restore: restore CRTC state * @reset: reset CRTC after state has been invalidated (e.g. resume) * @cursor_set: setup the cursor + * @cursor_set2: setup the cursor with hotspot, superseeds @cursor_set if set * @cursor_move: move the cursor * @gamma_set: specify color ramp for CRTC * @destroy: deinit and free object @@ -292,11 +293,14 @@ struct drm_crtc_funcs { /** * struct drm_crtc - central CRTC control structure * @dev: parent DRM device + * @port: OF node used by drm_of_find_possible_crtcs() * @head: list management * @mutex: per-CRTC locking * @base: base KMS object for ID tracking etc. * @primary: primary plane for this CRTC * @cursor: cursor plane for this CRTC + * @cursor_x: current x position of the cursor, used for universal cursor planes + * @cursor_y: current y position of the cursor, used for universal cursor planes * @enabled: is this CRTC enabled? * @mode: current mode timings * @hwmode: mode timings as programmed to hw regs @@ -309,10 +313,12 @@ struct drm_crtc_funcs { * @gamma_size: size of gamma ramp * @gamma_store: gamma ramp values * @framedur_ns: precise frame timing - * @framedur_ns: precise line timing + * @linedur_ns: precise line timing * @pixeldur_ns: precise pixel timing * @helper_private: mid-layer private data * @properties: property tracking for this CRTC + * @acquire_ctx: per-CRTC implicit acquire context used by atomic drivers for + * legacy ioctls * * Each CRTC may have one or more connectors associated with it. This structure * allows the CRTC to be controlled. @@ -483,6 +489,7 @@ struct drm_encoder { * @connector_type_id: index into connector type enum * @interlace_allowed: can this connector handle interlaced modes? * @doublescan_allowed: can this connector handle doublescan? + * @stereo_allowed: can this connector handle stereo modes? * @modes: modes available on this connector (from fill_modes() + user) * @status: one of the drm_connector_status enums (connected, not, or unknown) * @probed_modes: list of modes derived directly from the display @@ -490,10 +497,13 @@ struct drm_encoder { * @funcs: connector control functions * @edid_blob_ptr: DRM property containing EDID if present * @properties: property tracking for this connector + * @path_blob_ptr: DRM blob property data for the DP MST path property * @polled: a %DRM_CONNECTOR_POLL_ value for core driven polling * @dpms: current dpms state * @helper_private: mid-layer private data + * @cmdline_mode: mode line parsed from the kernel cmdline for this connector * @force: a %DRM_FORCE_ state for forced mode sets + * @override_edid: has the EDID been overwritten through debugfs for testing? * @encoder_ids: valid encoders for this connector * @encoder: encoder driving this connector, if any * @eld: EDID-like data, if present @@ -503,6 +513,8 @@ struct drm_encoder { * @video_latency: video latency info from ELD, if found * @audio_latency: audio latency info from ELD, if found * @null_edid_counter: track sinks that give us all zeros for the EDID + * @bad_edid_counter: track sinks that give us an EDID with invalid checksum + * @debugfs_entry: debugfs directory for this connector * * Each connector may be connected to one or more CRTCs, or may be clonable by * another connector if they can share a CRTC. Each connector also has a specific @@ -570,6 +582,7 @@ struct drm_connector { * @update_plane: update the plane configuration * @disable_plane: shut down the plane * @destroy: clean up plane resources + * @reset: reset plane after state has been invalidated (e.g. resume) * @set_property: called when a property is changed */ struct drm_plane_funcs { @@ -603,6 +616,8 @@ enum drm_plane_type { * @format_count: number of formats supported * @crtc: currently bound CRTC * @fb: currently bound fb + * @old_fb: Temporary tracking of the old fb while a modeset is ongoing. Used by + * drm_mode_set_config_internal() to implement correct refcounting. * @funcs: helper functions * @properties: property tracking for this plane * @type: type of plane (overlay, primary, cursor) @@ -620,8 +635,6 @@ struct drm_plane { struct drm_crtc *crtc; struct drm_framebuffer *fb; - /* Temporary tracking of the old fb while a modeset is ongoing. Used - * by drm_mode_set_config_internal to implement correct refcounting. */ struct drm_framebuffer *old_fb; const struct drm_plane_funcs *funcs; @@ -675,7 +688,6 @@ struct drm_bridge { /** * struct drm_mode_set - new values for a CRTC config change - * @head: list management * @fb: framebuffer to use for new config * @crtc: CRTC whose configuration we're about to change * @mode: mode timings to use @@ -717,10 +729,11 @@ struct drm_mode_config_funcs { }; /** - * drm_mode_group - group of mode setting resources for potential sub-grouping + * struct drm_mode_group - group of mode setting resources for potential sub-grouping * @num_crtcs: CRTC count * @num_encoders: encoder count * @num_connectors: connector count + * @num_bridges: bridge count * @id_list: list of KMS object IDs in this group * * Currently this simply tracks the global mode setting state. But in the @@ -740,10 +753,14 @@ struct drm_mode_group { }; /** - * drm_mode_config - Mode configuration control structure + * struct drm_mode_config - Mode configuration control structure * @mutex: mutex protecting KMS related lists and structures + * @connection_mutex: ww mutex protecting connector state and routing + * @acquire_ctx: global implicit acquire context used by atomic drivers for + * legacy ioctls * @idr_mutex: mutex for KMS ID allocation and management * @crtc_idr: main KMS ID tracking object + * @fb_lock: mutex to protect fb state and lists * @num_fb: number of fbs available * @fb_list: list of framebuffers available * @num_connector: number of connectors on this device @@ -752,17 +769,28 @@ struct drm_mode_group { * @bridge_list: list of bridge objects * @num_encoder: number of encoders on this device * @encoder_list: list of encoder objects + * @num_overlay_plane: number of overlay planes on this device + * @num_total_plane: number of universal (i.e. with primary/curso) planes on this device + * @plane_list: list of plane objects * @num_crtc: number of CRTCs on this device * @crtc_list: list of CRTC objects + * @property_list: list of property objects * @min_width: minimum pixel width on this device * @min_height: minimum pixel height on this device * @max_width: maximum pixel width on this device * @max_height: maximum pixel height on this device * @funcs: core driver provided mode setting functions * @fb_base: base address of the framebuffer - * @poll_enabled: track polling status for this device + * @poll_enabled: track polling support for this device + * @poll_running: track polling status for this device * @output_poll_work: delayed work for polling in process context + * @property_blob_list: list of all the blob property objects * @*_property: core property tracking + * @preferred_depth: preferred RBG pixel depth, used by fb helpers + * @prefer_shadow: hint to userspace to prefer shadow-fb rendering + * @async_page_flip: does this device support async flips on the primary plane? + * @cursor_width: hint to userspace for max cursor width + * @cursor_height: hint to userspace for max cursor height * * Core mode resource tracking structure. All CRTC, encoders, and connectors * enumerated by the driver are added here, as are global properties. Some @@ -776,14 +804,7 @@ struct drm_mode_config { struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ /* this is limited to one for now */ - - /** - * fb_lock - mutex to protect fb state - * - * Besides the global fb list his also protects the fbs list in the - * file_priv - */ - struct mutex fb_lock; + struct mutex fb_lock; /* proctects global and per-file fb lists */ int num_fb; struct list_head fb_list; -- cgit v1.2.3 From e9cf6194ab0cdb8f40f1eca7b230751c2289557e Mon Sep 17 00:00:00 2001 From: Todd Previte Date: Tue, 4 Nov 2014 15:17:35 -0700 Subject: drm/dp: Add counters in the drm_dp_aux struct for I2C NACKs and DEFERs These counters are used for Displayort compliance testing to detect error conditions when executing tests 4.2.2.4 and 4.2.2.5 in the Displayport Link CTS specificaiton. They determine whether to use the preferred/requested mode or the failsafe mode during these tests. V2: - Addressed previous review feedback - Updated commit message - Changed from uint8_t to uint32_t Cc: dri-devel@lists.freedesktop.org Signed-off-by: Todd Previte [danvet: s/uint32_t/unsigned/ for clearer intent. Also drop the i915 from the subject, it's all core stuff.] Signed-off-by: Daniel Vetter --- include/drm/drm_dp_helper.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index afebb08eee3a..6041ad8c2f2d 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -530,6 +530,7 @@ struct drm_dp_aux { struct mutex hw_mutex; ssize_t (*transfer)(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg); + unsigned i2c_nack_count, i2c_defer_count; }; ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset, -- cgit v1.2.3 From babc94936b7a48f0411c85a63074c0e378b55761 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 28 Oct 2014 16:20:47 +0200 Subject: drm/edid: add #defines and helpers for ELD In the interest of reducing magic numbers and having to cross check with the specs all the time. Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- include/drm/drm_edid.h | 102 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to 'include') diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index b96031d947a0..c2f1bfa22010 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -207,6 +207,61 @@ struct detailed_timing { #define DRM_EDID_HDMI_DC_30 (1 << 4) #define DRM_EDID_HDMI_DC_Y444 (1 << 3) +/* ELD Header Block */ +#define DRM_ELD_HEADER_BLOCK_SIZE 4 + +#define DRM_ELD_VER 0 +# define DRM_ELD_VER_SHIFT 3 +# define DRM_ELD_VER_MASK (0x1f << 3) + +#define DRM_ELD_BASELINE_ELD_LEN 2 /* in dwords! */ + +/* ELD Baseline Block for ELD_Ver == 2 */ +#define DRM_ELD_CEA_EDID_VER_MNL 4 +# define DRM_ELD_CEA_EDID_VER_SHIFT 5 +# define DRM_ELD_CEA_EDID_VER_MASK (7 << 5) +# define DRM_ELD_CEA_EDID_VER_NONE (0 << 5) +# define DRM_ELD_CEA_EDID_VER_CEA861 (1 << 5) +# define DRM_ELD_CEA_EDID_VER_CEA861A (2 << 5) +# define DRM_ELD_CEA_EDID_VER_CEA861BCD (3 << 5) +# define DRM_ELD_MNL_SHIFT 0 +# define DRM_ELD_MNL_MASK (0x1f << 0) + +#define DRM_ELD_SAD_COUNT_CONN_TYPE 5 +# define DRM_ELD_SAD_COUNT_SHIFT 4 +# define DRM_ELD_SAD_COUNT_MASK (0xf << 4) +# define DRM_ELD_CONN_TYPE_SHIFT 2 +# define DRM_ELD_CONN_TYPE_MASK (3 << 2) +# define DRM_ELD_CONN_TYPE_HDMI (0 << 2) +# define DRM_ELD_CONN_TYPE_DP (1 << 2) +# define DRM_ELD_SUPPORTS_AI (1 << 1) +# define DRM_ELD_SUPPORTS_HDCP (1 << 0) + +#define DRM_ELD_AUD_SYNCH_DELAY 6 /* in units of 2 ms */ +# define DRM_ELD_AUD_SYNCH_DELAY_MAX 0xfa /* 500 ms */ + +#define DRM_ELD_SPEAKER 7 +# define DRM_ELD_SPEAKER_RLRC (1 << 6) +# define DRM_ELD_SPEAKER_FLRC (1 << 5) +# define DRM_ELD_SPEAKER_RC (1 << 4) +# define DRM_ELD_SPEAKER_RLR (1 << 3) +# define DRM_ELD_SPEAKER_FC (1 << 2) +# define DRM_ELD_SPEAKER_LFE (1 << 1) +# define DRM_ELD_SPEAKER_FLR (1 << 0) + +#define DRM_ELD_PORT_ID 8 /* offsets 8..15 inclusive */ +# define DRM_ELD_PORT_ID_LEN 8 + +#define DRM_ELD_MANUFACTURER_NAME0 16 +#define DRM_ELD_MANUFACTURER_NAME1 17 + +#define DRM_ELD_PRODUCT_CODE0 18 +#define DRM_ELD_PRODUCT_CODE1 19 + +#define DRM_ELD_MONITOR_NAME_STRING 20 /* offsets 20..(20+mnl-1) inclusive */ + +#define DRM_ELD_CEA_SAD(mnl, sad) (20 + (mnl) + 3 * (sad)) + struct edid { u8 header[8]; /* Vendor & product info */ @@ -279,4 +334,51 @@ int drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, const struct drm_display_mode *mode); +/** + * drm_eld_mnl - Get ELD monitor name length in bytes. + * @eld: pointer to an eld memory structure with mnl set + */ +static inline int drm_eld_mnl(const uint8_t *eld) +{ + return (eld[DRM_ELD_CEA_EDID_VER_MNL] & DRM_ELD_MNL_MASK) >> DRM_ELD_MNL_SHIFT; +} + +/** + * drm_eld_sad_count - Get ELD SAD count. + * @eld: pointer to an eld memory structure with sad_count set + */ +static inline int drm_eld_sad_count(const uint8_t *eld) +{ + return (eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_SAD_COUNT_MASK) >> + DRM_ELD_SAD_COUNT_SHIFT; +} + +/** + * drm_eld_calc_baseline_block_size - Calculate baseline block size in bytes + * @eld: pointer to an eld memory structure with mnl and sad_count set + * + * This is a helper for determining the payload size of the baseline block, in + * bytes, for e.g. setting the Baseline_ELD_Len field in the ELD header block. + */ +static inline int drm_eld_calc_baseline_block_size(const uint8_t *eld) +{ + return DRM_ELD_MONITOR_NAME_STRING - DRM_ELD_HEADER_BLOCK_SIZE + + drm_eld_mnl(eld) + drm_eld_sad_count(eld) * 3; +} + +/** + * drm_eld_size - Get ELD size in bytes + * @eld: pointer to a complete eld memory structure + * + * The returned value does not include the vendor block. It's vendor specific, + * and comprises of the remaining bytes in the ELD memory buffer after + * drm_eld_size() bytes of header and baseline block. + * + * The returned value is guaranteed to be a multiple of 4. + */ +static inline int drm_eld_size(const uint8_t *eld) +{ + return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4; +} + #endif /* __DRM_EDID_H__ */ -- cgit v1.2.3 From b7a1aafda61c27d54230ce7c8a4806a749ecf2f3 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 27 Oct 2014 20:37:37 +0100 Subject: drm/modeset_lock: document trylock_only in kerneldoc I've forgotten to do this in: commit cb597bb3a2fbfc871cc1c703fb330d247bd21394 Author: Daniel Vetter Date: Sun Jul 27 19:09:33 2014 +0200 drm: trylock modest locking for fbdev panics Oops, fix this asap. In my defense kerneldoc is really awful and there's no way it can pick up structured comments per struct member. Which means we need both since people won't scroll up even a few lines. Reviewed-by: Sean Paul Reviewed-by: Thierry Reding Signed-off-by: Daniel Vetter --- include/drm/drm_modeset_lock.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/drm/drm_modeset_lock.h b/include/drm/drm_modeset_lock.h index 75a5c45e21c7..28931a23d96c 100644 --- a/include/drm/drm_modeset_lock.h +++ b/include/drm/drm_modeset_lock.h @@ -33,6 +33,7 @@ struct drm_modeset_lock; * @ww_ctx: base acquire ctx * @contended: used internally for -EDEADLK handling * @locked: list of held locks + * @trylock_only: trylock mode used in atomic contexts/panic notifiers * * Each thread competing for a set of locks must use one acquire * ctx. And if any lock fxn returns -EDEADLK, it must backoff and -- cgit v1.2.3 From 144ecb97cd57d2a61cc455730a3337e413499cae Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 27 Oct 2014 20:28:44 +0100 Subject: drm: Add atomic driver interface definitions for objects Heavily based upon Rob Clark's atomic series. - Dropped the connector state from the crtc state, instead opting for a full-blown connector state. The only thing it has is the desired crtc, but drivers which have connector properties have now a data-structure to subclass. - Rename create_state to duplicate_state. Especially for legacy ioctls we want updates on top of existing state, so we need a way to get at the current state. We need to be careful to clear the backpointers to the global state correctly though. - Drop property values. Drivers with properties simply need to subclass the datastructures and track the decoded values in there. I also think that common properties (like rotation) should be decoded and stored in the core structures. - Create a new set of ->atomic_set_prop functions, for smoother transitions from legacy to atomic operations. - Pass the ->atomic_set_prop ioctl the right structure to avoid chasing pointers in drivers. - Drop temporary boolean state for now until we resurrect them with the helper functions. - Drop invert_dimensions. For now we don't need any checking since that's done by the higher-level legacy ioctls. But even then we should also add rotation/flip tracking to the core drm_crtc_state, not just whether the dimensions are inverted. - Track crtc state with an enable/disable. That's equivalent to mode_valid, but a bit clearer that it means the entire crtc. The global interface will follow in subsequent patches. v2: We need to allow drivers to somehow set up the initial state and clear it on resume. So add a plane->reset callback for that. Helpers will be provided with default behaviour for all these. v3: Split out the plane->reset into a separate patch. v4: Improve kerneldoc in drm_crtc.h v5: Remove unused inline functions for handling state objects, those callbacks are now mandatory for full atomic support. v6: Fix commit message nit Sean noticed. Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- include/drm/drm_crtc.h | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 125bb7f290a1..3554868dbf09 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -224,6 +224,25 @@ struct drm_encoder; struct drm_pending_vblank_event; struct drm_plane; struct drm_bridge; +struct drm_atomic_state; + +/** + * struct drm_crtc_state - mutable crtc state + * @enable: whether the CRTC should be enabled, gates all other state + * @mode: current mode timings + * @event: optional pointer to a DRM event to signal upon completion of the + * state update + * @state: backpointer to global drm_atomic_state + */ +struct drm_crtc_state { + bool enable : 1; + + struct drm_display_mode mode; + + struct drm_pending_vblank_event *event; + + struct drm_atomic_state *state; +}; /** * struct drm_crtc_funcs - control CRTCs for a given device @@ -238,6 +257,9 @@ struct drm_bridge; * @set_property: called when a property is changed * @set_config: apply a new CRTC configuration * @page_flip: initiate a page flip + * @atomic_duplicate_state: duplicate the atomic state for this CRTC + * @atomic_destroy_state: destroy an atomic state for this CRTC + * @atomic_set_property: set a property on an atomic state for this CRTC * * The drm_crtc_funcs structure is the central CRTC management structure * in the DRM. Each CRTC controls one or more connectors (note that the name @@ -288,6 +310,15 @@ struct drm_crtc_funcs { int (*set_property)(struct drm_crtc *crtc, struct drm_property *property, uint64_t val); + + /* atomic update handling */ + struct drm_crtc_state *(*atomic_duplicate_state)(struct drm_crtc *crtc); + void (*atomic_destroy_state)(struct drm_crtc *crtc, + struct drm_crtc_state *cstate); + int (*atomic_set_property)(struct drm_crtc *crtc, + struct drm_crtc_state *state, + struct drm_property *property, + uint64_t val); }; /** @@ -317,6 +348,7 @@ struct drm_crtc_funcs { * @pixeldur_ns: precise pixel timing * @helper_private: mid-layer private data * @properties: property tracking for this CRTC + * @state: current atomic state for this CRTC * @acquire_ctx: per-CRTC implicit acquire context used by atomic drivers for * legacy ioctls * @@ -374,6 +406,8 @@ struct drm_crtc { struct drm_object_properties properties; + struct drm_crtc_state *state; + /* * For legacy crtc ioctls so that atomic drivers can get at the locking * acquire context. @@ -381,6 +415,16 @@ struct drm_crtc { struct drm_modeset_acquire_ctx *acquire_ctx; }; +/** + * struct drm_connector_state - mutable connector state + * @crtc: crtc to connect connector to, NULL if disabled + * @state: backpointer to global drm_atomic_state + */ +struct drm_connector_state { + struct drm_crtc *crtc; + + struct drm_atomic_state *state; +}; /** * struct drm_connector_funcs - control connectors on a given device @@ -393,6 +437,10 @@ struct drm_crtc { * @set_property: property for this connector may need an update * @destroy: make object go away * @force: notify the driver that the connector is forced on + * @atomic_duplicate_state: duplicate the atomic state for this connector + * @atomic_destroy_state: destroy an atomic state for this connector + * @atomic_set_property: set a property on an atomic state for this connector + * * * Each CRTC may have one or more connectors attached to it. The functions * below allow the core DRM code to control connectors, enumerate available modes, @@ -417,6 +465,15 @@ struct drm_connector_funcs { uint64_t val); void (*destroy)(struct drm_connector *connector); void (*force)(struct drm_connector *connector); + + /* atomic update handling */ + struct drm_connector_state *(*atomic_duplicate_state)(struct drm_connector *connector); + void (*atomic_destroy_state)(struct drm_connector *connector, + struct drm_connector_state *cstate); + int (*atomic_set_property)(struct drm_connector *connector, + struct drm_connector_state *state, + struct drm_property *property, + uint64_t val); }; /** @@ -515,6 +572,7 @@ struct drm_encoder { * @null_edid_counter: track sinks that give us all zeros for the EDID * @bad_edid_counter: track sinks that give us an EDID with invalid checksum * @debugfs_entry: debugfs directory for this connector + * @state: current atomic state for this connector * * Each connector may be connected to one or more CRTCs, or may be clonable by * another connector if they can share a CRTC. Each connector also has a specific @@ -575,8 +633,42 @@ struct drm_connector { unsigned bad_edid_counter; struct dentry *debugfs_entry; + + struct drm_connector_state *state; +}; + +/** + * struct drm_plane_state - mutable plane state + * @crtc: currently bound CRTC, NULL if disabled + * @fb: currently bound fb + * @crtc_x: left position of visible portion of plane on crtc + * @crtc_y: upper position of visible portion of plane on crtc + * @crtc_w: width of visible portion of plane on crtc + * @crtc_h: height of visible portion of plane on crtc + * @src_x: left position of visible portion of plane within + * plane (in 16.16) + * @src_y: upper position of visible portion of plane within + * plane (in 16.16) + * @src_w: width of visible portion of plane (in 16.16) + * @src_h: height of visible portion of plane (in 16.16) + * @state: backpointer to global drm_atomic_state + */ +struct drm_plane_state { + struct drm_crtc *crtc; + struct drm_framebuffer *fb; + + /* Signed dest location allows it to be partially off screen */ + int32_t crtc_x, crtc_y; + uint32_t crtc_w, crtc_h; + + /* Source values are 16.16 fixed point */ + uint32_t src_x, src_y; + uint32_t src_h, src_w; + + struct drm_atomic_state *state; }; + /** * struct drm_plane_funcs - driver plane control functions * @update_plane: update the plane configuration @@ -584,6 +676,9 @@ struct drm_connector { * @destroy: clean up plane resources * @reset: reset plane after state has been invalidated (e.g. resume) * @set_property: called when a property is changed + * @atomic_duplicate_state: duplicate the atomic state for this plane + * @atomic_destroy_state: destroy an atomic state for this plane + * @atomic_set_property: set a property on an atomic state for this plane */ struct drm_plane_funcs { int (*update_plane)(struct drm_plane *plane, @@ -598,6 +693,15 @@ struct drm_plane_funcs { int (*set_property)(struct drm_plane *plane, struct drm_property *property, uint64_t val); + + /* atomic update handling */ + struct drm_plane_state *(*atomic_duplicate_state)(struct drm_plane *plane); + void (*atomic_destroy_state)(struct drm_plane *plane, + struct drm_plane_state *cstate); + int (*atomic_set_property)(struct drm_plane *plane, + struct drm_plane_state *state, + struct drm_property *property, + uint64_t val); }; enum drm_plane_type { @@ -621,6 +725,7 @@ enum drm_plane_type { * @funcs: helper functions * @properties: property tracking for this plane * @type: type of plane (overlay, primary, cursor) + * @state: current atomic state for this plane */ struct drm_plane { struct drm_device *dev; @@ -642,6 +747,8 @@ struct drm_plane { struct drm_object_properties properties; enum drm_plane_type type; + + struct drm_plane_state *state; }; /** -- cgit v1.2.3 From cc4ceb484b37b9369e0d4e8682b7ae1849ae4579 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 25 Jul 2014 21:30:38 +0200 Subject: drm: Global atomic state handling Some differences compared to Rob's patches again: - Dropped the committed and checked booleans. Checking will be internally enforced by always calling ->atomic_check before ->atomic_commit. And async handling needs to be solved differently because the current scheme completely side-steps ww mutex deadlock avoidance (and so either reinvents a new deadlock avoidance wheel or like the current code just deadlocks). - State for connectors needed to be added, since now they have a full-blown drm_connector_state (so that drivers have something to attach their own stuff to). - Refcounting is gone. I plane to solve async updates differently, since the lock-passing scheme doesn't cut it (since it abuses ww mutexes). Essentially what we need for async is a simple ownership transfer from the caller to the driver. That doesn't need full-blown refcounting. - The acquire ctx is a pointer. Real atomic callers should have that on their stack, legacy entry points need to put the right one (obtained by drm_modeset_legacy_acuire_ctx) in there. - I've dropped all hooks except check/commit. All the begin/end handling is done by core functions and is the same. - commit/check are just thin wrappers that ensure that ->check is always called. - To help out with locking in the legacy implementations I've added a helper to just grab all locks in the backoff case. v2: Add notices that check/commit can fail with EDEADLK. v3: - More consistent naming for state_alloc. - Add state_clear which is needed for backoff and retry. v4: Planes/connectors can switch between crtcs, and we need to be careful that we grab the state (and locks) for both the old and new crtc. Improve the interface functions to ensure this. v5: Add functions to grab affected connectors for a crtc and to recompute the crtc->enable state. This is useful for both helper and atomic ioctl code when e.g. removing a connector. v6: Squash in fixup from Fengguang to use ERR_CAST. v7: Add debug output. v8: Make checkpatch happy about kcalloc argument ordering. v9: Improve kerneldoc in drm_crtc.h v10: - Fix another kcalloc argument misorder I've missed. - More polish for kerneldoc. v11: Clarify the ownership rules for the state object. The new rule is that a successful drm_atomic_commit (whether synchronous or asnyc) always inherits the state and is responsible for the clean-up. That way async and sync ->commit functions are more similar. v12: A few bugfixes: - Assign state->state pointers correctly when grabbing state objects - we need to link them up with the global state. - Handle a NULL crtc in set_crtc_for_plane to simplify code flow a bit for the callers of this function. v13: Review from Sean: - kerneldoc spelling fixes - Don't overallocate states->planes. - Handle NULL crtc in set_crtc_for_connector. v14: Sprinkle __must_check over all functions which do wait/wound locking to make sure callers don't forget this. Since I have ;-) v15: Be more explicit in the kerneldoc when functions can return -EDEADLK what to do. And that every other -errno is fatal. v16: Indent with tabs instead of space, spotted by Ander. v17: Review from Thierry, small kerneldoc and other naming polish. Cc: Thierry Reding Cc: Ander Conselvan de Oliveira Cc: Daniel Thompson Cc: Fengguang Wu Cc: Sean Paul Cc: Matt Roper Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- include/drm/drm_atomic.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 50 +++++++++++++++++++++++++++++++------ 2 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 include/drm/drm_atomic.h (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h new file mode 100644 index 000000000000..5bb15f550c42 --- /dev/null +++ b/include/drm/drm_atomic.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2014 Red Hat + * Copyright (C) 2014 Intel Corp. + * + * 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 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 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: + * Rob Clark + * Daniel Vetter + */ + +#ifndef DRM_ATOMIC_H_ +#define DRM_ATOMIC_H_ + +struct drm_atomic_state * __must_check +drm_atomic_state_alloc(struct drm_device *dev); +void drm_atomic_state_clear(struct drm_atomic_state *state); +void drm_atomic_state_free(struct drm_atomic_state *state); + +struct drm_crtc_state * __must_check +drm_atomic_get_crtc_state(struct drm_atomic_state *state, + struct drm_crtc *crtc); +struct drm_plane_state * __must_check +drm_atomic_get_plane_state(struct drm_atomic_state *state, + struct drm_plane *plane); +struct drm_connector_state * __must_check +drm_atomic_get_connector_state(struct drm_atomic_state *state, + struct drm_connector *connector); + +int __must_check +drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, + struct drm_crtc *crtc); +int __must_check +drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, + struct drm_crtc *crtc); +int __must_check +drm_atomic_add_affected_connectors(struct drm_atomic_state *state, + struct drm_crtc *crtc); +int +drm_atomic_connectors_for_crtc(struct drm_atomic_state *state, + struct drm_crtc *crtc); + +void drm_atomic_legacy_backoff(struct drm_atomic_state *state); + +int __must_check drm_atomic_check_only(struct drm_atomic_state *state); +int __must_check drm_atomic_commit(struct drm_atomic_state *state); +int __must_check drm_atomic_async_commit(struct drm_atomic_state *state); + +#endif /* DRM_ATOMIC_H_ */ diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 3554868dbf09..c7a3400173a8 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -227,7 +227,7 @@ struct drm_bridge; struct drm_atomic_state; /** - * struct drm_crtc_state - mutable crtc state + * struct drm_crtc_state - mutable CRTC state * @enable: whether the CRTC should be enabled, gates all other state * @mode: current mode timings * @event: optional pointer to a DRM event to signal upon completion of the @@ -235,7 +235,7 @@ struct drm_atomic_state; * @state: backpointer to global drm_atomic_state */ struct drm_crtc_state { - bool enable : 1; + bool enable; struct drm_display_mode mode; @@ -314,7 +314,7 @@ struct drm_crtc_funcs { /* atomic update handling */ struct drm_crtc_state *(*atomic_duplicate_state)(struct drm_crtc *crtc); void (*atomic_destroy_state)(struct drm_crtc *crtc, - struct drm_crtc_state *cstate); + struct drm_crtc_state *state); int (*atomic_set_property)(struct drm_crtc *crtc, struct drm_crtc_state *state, struct drm_property *property, @@ -417,7 +417,7 @@ struct drm_crtc { /** * struct drm_connector_state - mutable connector state - * @crtc: crtc to connect connector to, NULL if disabled + * @crtc: CRTC to connect connector to, NULL if disabled * @state: backpointer to global drm_atomic_state */ struct drm_connector_state { @@ -441,7 +441,6 @@ struct drm_connector_state { * @atomic_destroy_state: destroy an atomic state for this connector * @atomic_set_property: set a property on an atomic state for this connector * - * * Each CRTC may have one or more connectors attached to it. The functions * below allow the core DRM code to control connectors, enumerate available modes, * etc. @@ -469,7 +468,7 @@ struct drm_connector_funcs { /* atomic update handling */ struct drm_connector_state *(*atomic_duplicate_state)(struct drm_connector *connector); void (*atomic_destroy_state)(struct drm_connector *connector, - struct drm_connector_state *cstate); + struct drm_connector_state *state); int (*atomic_set_property)(struct drm_connector *connector, struct drm_connector_state *state, struct drm_property *property, @@ -640,7 +639,7 @@ struct drm_connector { /** * struct drm_plane_state - mutable plane state * @crtc: currently bound CRTC, NULL if disabled - * @fb: currently bound fb + * @fb: currently bound framebuffer * @crtc_x: left position of visible portion of plane on crtc * @crtc_y: upper position of visible portion of plane on crtc * @crtc_w: width of visible portion of plane on crtc @@ -697,7 +696,7 @@ struct drm_plane_funcs { /* atomic update handling */ struct drm_plane_state *(*atomic_duplicate_state)(struct drm_plane *plane); void (*atomic_destroy_state)(struct drm_plane *plane, - struct drm_plane_state *cstate); + struct drm_plane_state *state); int (*atomic_set_property)(struct drm_plane *plane, struct drm_plane_state *state, struct drm_property *property, @@ -793,6 +792,32 @@ struct drm_bridge { void *driver_private; }; +/** + * struct struct drm_atomic_state - the global state object for atomic updates + * @dev: parent DRM device + * @flags: state flags like async update + * @planes: pointer to array of plane pointers + * @plane_states: pointer to array of plane states pointers + * @crtcs: pointer to array of CRTC pointers + * @crtc_states: pointer to array of CRTC states pointers + * @connectors: pointer to array of connector pointers + * @connector_states: pointer to array of connector states pointers + * @acquire_ctx: acquire context for this atomic modeset state update + */ +struct drm_atomic_state { + struct drm_device *dev; + uint32_t flags; + struct drm_plane **planes; + struct drm_plane_state **plane_states; + struct drm_crtc **crtcs; + struct drm_crtc_state **crtc_states; + struct drm_connector **connectors; + struct drm_connector_state **connector_states; + + struct drm_modeset_acquire_ctx *acquire_ctx; +}; + + /** * struct drm_mode_set - new values for a CRTC config change * @fb: framebuffer to use for new config @@ -824,6 +849,9 @@ struct drm_mode_set { * struct drm_mode_config_funcs - basic driver provided mode setting functions * @fb_create: create a new framebuffer object * @output_poll_changed: function to handle output configuration changes + * @atomic_check: check whether a give atomic state update is possible + * @atomic_commit: commit an atomic state update previously verified with + * atomic_check() * * Some global (i.e. not per-CRTC, connector, etc) mode setting functions that * involve drivers. @@ -833,6 +861,12 @@ struct drm_mode_config_funcs { struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd); void (*output_poll_changed)(struct drm_device *dev); + + int (*atomic_check)(struct drm_device *dev, + struct drm_atomic_state *a); + int (*atomic_commit)(struct drm_device *dev, + struct drm_atomic_state *a, + bool async); }; /** -- cgit v1.2.3 From c2fcd274bce521cd824d96d7f26dfa57ea06478c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 5 Nov 2014 00:14:14 +0100 Subject: drm: Add atomic/plane helpers This is the first cut of atomic helper code. As-is it's only useful to implement a pure atomic interface for plane updates. Later patches will integrate this with the crtc helpers so that full atomic updates are possible. We also need a pile of helpers to aid drivers in transitioning from the legacy world to the shiny new atomic age. Finally we need helpers to implement legacy ioctls on top of the atomic interface. The design of the overall helpers<->driver interaction is fairly simple, but has an unfortunate large interface: - We have ->atomic_check callbacks for crtcs and planes. The idea is that connectors don't need any checking, and if they do they can adjust the relevant crtc driver-private state. So no connector hooks should be needed. Also the crtc helpers integration will do the ->best_encoder checks, so no need for that. - Framebuffer pinning needs to be done before we can commit to the hw state. This is especially important for async updates where we must pin all buffers before returning to userspace, so that really only hw failures can happen in the asynchronous worker. Hence we add ->prepare_fb and ->cleanup_fb hooks for this resources management. - The actual atomic plane commit can't fail (except hw woes), so has void return type. It has three stages: 1. Prepare all affected crtcs with crtc->atomic_begin. Drivers can use this to unset the GO bit or similar latches to prevent plane updates. 2. Update plane state by looping over all changed planes and calling plane->atomic_update. Presuming the hardware is sane and has GO bits drivers can simply bash the state into the hardware in this function. Other drivers might use this to precompute hw state for the final step. 3. Finally latch the update for the next vblank with crtc->atomic_flush. Note that this function doesn't need to wait for the vblank to happen even for the synchronous case. v2: Clear drm__state->state to NULL when swapping in state. v3: Add TODO that we don't short-circuit plane updates for now. Likely no one will care. v4: Squash in a bit of polish that somehow landed in the wrong (later) patche. v5: Integrate atomic functions into the drm docbook and fixup the kerneldoc. v6: Fixup fixup patch squashing fumble. v7: Don't touch the legacy plane state plane->fb and plane->crtc. This is only used by the legacy ioctl code in the drm core, and that code already takes care of updating the pointers in all relevant cases. This is in stark contrast to connector->encoder->crtc links on the modeset side, which we still need to set since the core doesn't touch them. Also some more kerneldoc polish. v8: Drop outdated comment. v9: Handle the state->state pointer correctly: Only clearing the ->state pointer when assigning the state to the kms object isn't good enough. We also need to re-link the swapped out state into the drm_atomic_state structure. v10: Shuffle the misplaced docbook template hunk around that Sean spotted. Cc: Sean Paul Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- include/drm/drm_atomic_helper.h | 44 +++++++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 6 ++++++ include/drm/drm_crtc_helper.h | 6 ++++++ include/drm/drm_plane_helper.h | 22 +++++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 include/drm/drm_atomic_helper.h (limited to 'include') diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h new file mode 100644 index 000000000000..79938c62e7ad --- /dev/null +++ b/include/drm/drm_atomic_helper.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2014 Red Hat + * Copyright (C) 2014 Intel Corp. + * + * 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 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 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Authors: + * Rob Clark + * Daniel Vetter + */ + +#ifndef DRM_ATOMIC_HELPER_H_ +#define DRM_ATOMIC_HELPER_H_ + +int drm_atomic_helper_check(struct drm_device *dev, + struct drm_atomic_state *state); + +int drm_atomic_helper_prepare_planes(struct drm_device *dev, + struct drm_atomic_state *state); +void drm_atomic_helper_commit_planes(struct drm_device *dev, + struct drm_atomic_state *state); +void drm_atomic_helper_cleanup_planes(struct drm_device *dev, + struct drm_atomic_state *old_state); + +void drm_atomic_helper_swap_state(struct drm_device *dev, + struct drm_atomic_state *state); + +#endif /* DRM_ATOMIC_HELPER_H_ */ diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c7a3400173a8..56147409408d 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -229,6 +229,7 @@ struct drm_atomic_state; /** * struct drm_crtc_state - mutable CRTC state * @enable: whether the CRTC should be enabled, gates all other state + * @planes_changed: for use by helpers and drivers when computing state updates * @mode: current mode timings * @event: optional pointer to a DRM event to signal upon completion of the * state update @@ -237,6 +238,9 @@ struct drm_atomic_state; struct drm_crtc_state { bool enable; + /* computed state bits used by helpers and drivers */ + bool planes_changed : 1; + struct drm_display_mode mode; struct drm_pending_vblank_event *event; @@ -747,6 +751,8 @@ struct drm_plane { enum drm_plane_type type; + void *helper_private; + struct drm_plane_state *state; }; diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index a3d75fefd010..adec48b27aa5 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -81,6 +81,12 @@ struct drm_crtc_helper_funcs { /* disable crtc when not in use - more explicit than dpms off */ void (*disable)(struct drm_crtc *crtc); + + /* atomic helpers */ + int (*atomic_check)(struct drm_crtc *crtc, + struct drm_crtc_state *state); + void (*atomic_begin)(struct drm_crtc *crtc); + void (*atomic_flush)(struct drm_crtc *crtc); }; /** diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h index fa60d19f91c0..8577ec8f3e6c 100644 --- a/include/drm/drm_plane_helper.h +++ b/include/drm/drm_plane_helper.h @@ -47,6 +47,28 @@ extern int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, const struct drm_crtc_funcs *funcs); +/** + * drm_plane_helper_funcs - helper operations for CRTCs + * + * The helper operations are called by the mid-layer CRTC helper. + */ +struct drm_plane_helper_funcs { + int (*prepare_fb)(struct drm_plane *plane, + struct drm_framebuffer *fb); + void (*cleanup_fb)(struct drm_plane *plane, + struct drm_framebuffer *fb); + + int (*atomic_check)(struct drm_plane *plane, + struct drm_plane_state *state); + void (*atomic_update)(struct drm_plane *plane); +}; + +static inline void drm_plane_helper_add(struct drm_plane *plane, + const struct drm_plane_helper_funcs *funcs) +{ + plane->helper_private = (void *)funcs; +} + extern int drm_plane_helper_check_update(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, -- cgit v1.2.3 From acf24a395c5a9290189b080383564437101d411c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 29 Jul 2014 15:33:05 +0200 Subject: drm/plane-helper: transitional atomic plane helpers Converting a driver to the atomic interface can be a daunting undertaking. One of the prerequisites is to have full universal planes support. To make that transition a bit easier this patch provides plane helpers which use the new atomic helper callbacks just only for the plane changes. This way the plane update functionality can be tested without being forced to convert everything at once. Of course a real atomic update capable driver will implement the all plane properties through the atomic interface, so these helpers are mostly transitional. But they can be used to enable proper universal plane support, especially once the crtc helpers have also been adapted. v2: Use ->atomic_duplicate_state if available. v3: Don't forget to call ->atomic_destroy_state if available. v4: Fixup kerneldoc, reported by Paulo. v5: Extract a common plane_commit helper and fix some bugs in the plane_state setup of the plane_disable implementation. v6: Fix issues with the cleanup of the old fb. Since transitional helpers can be mixed we need to assume that the old fb has been set up by a legacy path (e.g. set_config or page_flip when the primary plane is converted to use these functions already). Hence pass an additional old_fb parameter to plane_commit to do that cleanup work correctly. v7: - Fix spurious WARNING (crtc helpers really love to disable stuff harder) and fix array index bonghits. - Correctly handle the lack of plane->state object, necessary for transitional use. - Don't indicate failure if drm_vblank_get doesn't work - that's expected when the pipe is in dpms off mode. v8: Review from Sean: - s/fail/out/ to make the meaning of a label more clear. - spelling fix in the commit message. Cc: Paulo Zanoni Cc: Sean Paul Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- include/drm/drm_plane_helper.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h index 8577ec8f3e6c..92bceccaa62a 100644 --- a/include/drm/drm_plane_helper.h +++ b/include/drm/drm_plane_helper.h @@ -95,4 +95,12 @@ extern struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev, int num_formats); +int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h); +int drm_plane_helper_disable(struct drm_plane *plane); + #endif -- cgit v1.2.3 From 2f324b42b7b24a48fe3f8a7af60ec3c9024255fa Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 29 Oct 2014 11:13:47 +0100 Subject: drm/crtc-helper: Transitional functions using atomic plane helpers These two functions allow drivers to reuse their atomic plane helpers functions for the primary plane to implement the interfaces required by the crtc helpers for the legacy ->set_config callback. This is purely transitional and won't be used once the driver is fully converted. But it allows partial conversions to the atomic plane helpers which are functional. v2: - Use ->atomic_duplicate_state if available. - Don't forget to run crtc_funcs->atomic_check. v3: Shift source coordinates correctly for 16.16 fixed point. v4: Don't forget to call ->atomic_destroy_state if available. v5: Fixup kerneldoc. v6: Reuse the plane_commit function from the transitional plane helpers to avoid too much duplication. v7: - Remove some stale comment. - Correctly handle the lack of plane->state object, necessary for transitional use. v8: Fixup an embarrassing h/vdisplay mixup. Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- include/drm/drm_crtc.h | 4 ++++ include/drm/drm_crtc_helper.h | 7 +++++++ include/drm/drm_plane_helper.h | 4 ++++ 3 files changed, 15 insertions(+) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 56147409408d..53c8638592d4 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -230,6 +230,7 @@ struct drm_atomic_state; * struct drm_crtc_state - mutable CRTC state * @enable: whether the CRTC should be enabled, gates all other state * @planes_changed: for use by helpers and drivers when computing state updates + * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings * @mode: current mode timings * @event: optional pointer to a DRM event to signal upon completion of the * state update @@ -241,6 +242,9 @@ struct drm_crtc_state { /* computed state bits used by helpers and drivers */ bool planes_changed : 1; + /* adjusted_mode: for use by helpers and drivers */ + struct drm_display_mode adjusted_mode; + struct drm_display_mode mode; struct drm_pending_vblank_event *event; diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index adec48b27aa5..7adbb65ea8ae 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -68,6 +68,7 @@ struct drm_crtc_helper_funcs { int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, int x, int y, struct drm_framebuffer *old_fb); + void (*mode_set_nofb)(struct drm_crtc *crtc); /* Move the crtc on the current fb to the given position *optional* */ int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, @@ -167,6 +168,12 @@ static inline void drm_connector_helper_add(struct drm_connector *connector, extern 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, + struct drm_framebuffer *old_fb); +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, diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h index 92bceccaa62a..c48f14d88690 100644 --- a/include/drm/drm_plane_helper.h +++ b/include/drm/drm_plane_helper.h @@ -103,4 +103,8 @@ int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, uint32_t src_w, uint32_t src_h); int drm_plane_helper_disable(struct drm_plane *plane); +/* For use by drm_crtc_helper.c */ +int drm_plane_helper_commit(struct drm_plane *plane, + struct drm_plane_state *plane_state, + struct drm_framebuffer *old_fb); #endif -- cgit v1.2.3 From 623369e533e8a5f85999d605723efa4523554bae Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 16 Sep 2014 17:50:47 +0200 Subject: drm: Atomic crtc/connector updates using crtc/plane helper interfaces So this is finally the integration of the crtc and plane helper interfaces into the atomic helper functions. In the check function we now have a few steps: - First we update the output routing and figure out which crtcs need a full mode set. Suitable encoders are selected using ->best_encoder, with the same semantics as the crtc helpers of implicitly disabling all connectors currently using the encoder. - Then we pull all other connectors into the state update which feed from a crtc which changes. This must be done do catch mode changes and similar updates - atomic updates are differences on top of the current state. - Then we call all the various ->mode_fixup to compute the adjusted mode. Note that here we have a slight semantic difference compared to the crtc helpers: We have not yet updated the encoder->crtc link when calling the encoder's ->mode_fixup function. But that's a requirement when converting to atomic since we want to prepare the entire state completely contained with the over drm_atomic_state structure. So this must be carefully checked when converting drivers over to atomic helpers. - Finally we do call the atomic_check functions on planes and crtcs. The commit function is also quite a beast: - The only step that can fail is done first, namely pinning the framebuffers. After that we cross the point of no return, an async commit would push all that into the worker thread. - The disabling of encoders and connectors is a bit tricky, since depending upon the final state we need to select different crtc helper functions. - Software tracking is a bit clarified compared to the crtc helpers: We commit the software state before starting to touch the hardware, like crtc helpers. But since we just swap them we still have the old state (i.e. the current hw state) around, which is really handy to write simple disable functions. So no more drm_crtc_helper_disable_all_unused_functions kind of fun because we're leaving unused crtcs/encoders behind. Everything gets shut down in-order now, which is one of the key differences of the i915 helpers compared to crtc helpers and a really nice additional guarantee. - Like with the plane helpers the atomic commit function waits for one vblank to pass before calling the framebuffer cleanup function. Compared to Rob's helper approach there's a bunch of upsides: - All the interfaces which can fail are called in the ->check hook (i.e. ->best_match and the various ->mode_fixup hooks). This means that drivers can just reuse those functions and don't need to move everything into ->atomic_check callbacks. If drivers have no need for additional constraint checking beyong their existing crtc helper callbacks they don't need to do anything. - The actual commit operation is properly stage: First we prepare framebuffers, which can potentially still fail (due to memory exhausting). This is important for the async case, where this must be done synchronously to correctly return errors. - The output configuration changes (done with crtc helper functions) and the plane update (using atomic plane helpers) are correctly interleaved: First we shut down any crtcs that need changing, then we update planes and finally we enable everything again. Hardware without GO bits must be more careful with ordering, which this sequence enables. - Also for hardware with shared output resources (like display PLLs) we first must shut down the old configuration before we can enable the new one. Otherwise we can hit an impossible intermediate state where there's not enough PLLs (which is the point behind atomic updates). v2: - Ensure that users of ->check update crtc_state->enable correctly. - Update the legacy state in crtc/plane structures. Eventually we want to remove that, but for now the drm core still expects this (especially the plane->fb pointer). v3: A few changes for better async handling: - Reorder the software side state commit so that it happens all before we touch the hardware. This way async support becomes very easy since we can punt all the actual hw touching to a worker thread. And as long as we synchronize with that thread (flushing or cancelling, depending upon what the driver can handle) before we commit the next software state there's no need for any locking in the worker thread at all. Which greatly simplifies things. And as long as we synchronize with all relevant threads we can have a lot of them (e.g. per-crtc for per-crtc updates) running in parallel. - Expose pre/post plane commit steps separately. We need to expose the actual hw commit step anyway for drivers to be able to implement asynchronous commit workers. But if we expose pre/post and plane commit steps individually we allow drivers to selectively use atomic helpers. - I've forgotten to call encoder/bridge ->mode_set functions, fix this. v4: Add debug output and fix a mixup between current and new state that resulted in crtcs not getting updated correctly. And in an Oops ... v5: - Be kind to driver writers in the vblank wait functions.. if thing aren't working yet, and vblank irq will never come, then let's not block forever.. especially under console-lock. - Correctly clear connector_state->best_encoder when disabling. Spotted while trying to understand a report from Rob Clark. - Only steal encoder if it actually changed, otherwise hilarity ensues if we steal from the current connector and so set the ->crtc pointer unexpectedly to NULL. Reported by Rob Clark. - Bail out in disable_outputs if an output currently doesn't have a best_encoder - this means it's already disabled. v6: Fixupe kerneldoc as reported by Paulo. And also fix up kerneldoc in drm_crtc.h. v7: Take ownership of the atomic state and clean it up with drm_atomic_state_free(). v8 Various improvements all over: - Polish code comments and kerneldoc. - Improve debug output to make sure all failure cases are logged. - Treat enabled crtc with no connectors as invalid input from userspace. - Don't ignore the return value from mode_fixup(). v9: - Improve debug output for crtc_state->mode_changed. v10: - Fixup the vblank waiting code to properly balance the vblank_get/put calls. - Better comments when checking/computing crtc->mode_changed v11: Fixup the encoder stealing logic: We can't look at encoder->crtc since that's not in the atomic state structures and might be updated asynchronously in and async commit. Instead we need to inspect all the connector states and check whether the encoder is currently in used and if so, on which crtc. v12: Review from Sean: - A few spelling fixes. - Flatten control flow indent by converting if blocks to early continue/return in 2 places. - Capture connectors_for_crtc return value in int num_connectors instead of bool has_connectors and do an explicit int->bool conversion with !!. I think the helper is more useful for drivers if it returns the number of connectors (e.g. to detect cloning configurations), so decided to keep that return value. Cc: Sean Paul Cc: Paulo Zanoni Cc: Rob Clark Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- include/drm/drm_atomic_helper.h | 8 ++++++++ include/drm/drm_crtc.h | 10 ++++++++++ 2 files changed, 18 insertions(+) (limited to 'include') diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 79938c62e7ad..9781ce739e10 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -30,6 +30,14 @@ int drm_atomic_helper_check(struct drm_device *dev, struct drm_atomic_state *state); +int drm_atomic_helper_commit(struct drm_device *dev, + struct drm_atomic_state *state, + bool async); + +void drm_atomic_helper_commit_pre_planes(struct drm_device *dev, + struct drm_atomic_state *state); +void drm_atomic_helper_commit_post_planes(struct drm_device *dev, + struct drm_atomic_state *old_state); int drm_atomic_helper_prepare_planes(struct drm_device *dev, struct drm_atomic_state *state); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 53c8638592d4..bc47d11cb126 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -229,6 +229,9 @@ struct drm_atomic_state; /** * struct drm_crtc_state - mutable CRTC state * @enable: whether the CRTC should be enabled, gates all other state + * @mode_changed: for use by helpers and drivers when computing state updates + * @last_vblank_count: for helpers and drivers to capture the vblank of the + * update to ensure framebuffer cleanup isn't done too early * @planes_changed: for use by helpers and drivers when computing state updates * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings * @mode: current mode timings @@ -241,6 +244,10 @@ struct drm_crtc_state { /* computed state bits used by helpers and drivers */ bool planes_changed : 1; + bool mode_changed : 1; + + /* last_vblank_count: for vblank waits before cleanup */ + u32 last_vblank_count; /* adjusted_mode: for use by helpers and drivers */ struct drm_display_mode adjusted_mode; @@ -426,11 +433,14 @@ struct drm_crtc { /** * struct drm_connector_state - mutable connector state * @crtc: CRTC to connect connector to, NULL if disabled + * @best_encoder: can be used by helpers and drivers to select the encoder * @state: backpointer to global drm_atomic_state */ struct drm_connector_state { struct drm_crtc *crtc; + struct drm_encoder *best_encoder; + struct drm_atomic_state *state; }; -- cgit v1.2.3 From 042652ed95996a9ef6dcddddc53b5d8bc7fa887e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 27 Jul 2014 13:46:52 +0200 Subject: drm/atomic-helper: implementatations for legacy interfaces Well, except page_flip since that requires async commit, which isn't there yet. For the functions which changes planes there's a bit of trickery involved to keep the fb refcounting working. But otherwise fairly straight-forward atomic updates. The property setting functions are still a bit incomplete. Once we have generic properties (e.g. rotation, but also all the properties needed by the atomic ioctl) we need to filter those out and parse them in the helper. Preferrably with the same function as used by the real atomic ioctl implementation. v2: Fixup kerneldoc, reported by Paulo. v3: Add missing EXPORT_SYMBOL. v4: We need to look at the crtc of the modeset, not some random leftover one from a previous loop when udpating the connector->crtc routing. Also push some local variables into inner loops to avoid these kinds of bugs. v5: Adjust semantics - drivers now own the atomic state upon successfully synchronous commit. v6: Use the set_crtc_for_plane function to assign the crtc, since otherwise the book-keeping is off. v7: - Improve comments. - Filter out the crtc of the ->set_config call when recomputing crtc_state->enabled: We should compute the same state, but not doing so will give us a good chance to catch bugs and inconsistencies - the atomic helper's atomic_check function re-validates this again. - Fix the set_config implementation logic when disabling the crtc: We still need to update the output routing to disable all the connectors properly in the state. Caught by the atomic_check functions, so at least that part worked ;-) Also add some WARN_ONs to ensure ->set_config preconditions all apply. v8: Fixup an embarrassing h/vdisplay mixup. v9: Shuffled bad squash to the right patch, spotted by Daniel v10: Use set_crtc_for_connector as suggested by Sean. v11: Daniel Thompson noticed that my error handling is inconsistent and that in a few cases I didn't handle fatal errors (i.e. not -EDEADLK). Fix this by consolidate the ww mutex backoff handling into one check in the fail: block and flatten the error control flow everywhere else. v12: Review and discussion with Sean: - One spelling fix. - Correctly skip the crtc from the set_config set when recomputing ->enable state. That should allow us to catch any bugs in higher levels in computing that state (which is supplied to the ->set_config implementation). I've screwed this up and Sean spotted that the current code is pointless. Cc: Sean Paul Cc: Daniel Thompson Cc: Sean Paul Cc: Daniel Thompson Cc: Paulo Zanoni Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- include/drm/drm_atomic_helper.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'include') diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 9781ce739e10..8cd6fe7a48e5 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -49,4 +49,25 @@ void drm_atomic_helper_cleanup_planes(struct drm_device *dev, void drm_atomic_helper_swap_state(struct drm_device *dev, struct drm_atomic_state *state); +/* implementations for legacy interfaces */ +int drm_atomic_helper_update_plane(struct drm_plane *plane, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h); +int drm_atomic_helper_disable_plane(struct drm_plane *plane); +int drm_atomic_helper_set_config(struct drm_mode_set *set); + +int drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc, + struct drm_property *property, + uint64_t val); +int drm_atomic_helper_plane_set_property(struct drm_plane *plane, + struct drm_property *property, + uint64_t val); +int drm_atomic_helper_connector_set_property(struct drm_connector *connector, + struct drm_property *property, + uint64_t val); + #endif /* DRM_ATOMIC_HELPER_H_ */ -- cgit v1.2.3 From e2330f0719515e41090a4d9685b931888b7c01d6 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 29 Oct 2014 11:34:56 +0100 Subject: drm/atomic: Integrate fence support This patch is for enabling async commits. It replaces an earlier approach which added an async boolean paramter to the ->prepare_fb callbacks. The idea is that prepare_fb picks up the right fence to synchronize against, which is then used by the synchronous commit helper. For async commits drivers can either register a callback to the fence or simply do the synchronous wait in their async work queue. v2: Remove unused variable. v3: Only wait for fences after the point of no return in the part of the commit function which can be run asynchronously. This is after the atomic state has been swapped in, hence now check plane->state->fence. Also add a WARN_ON to make sure we don't try to wait on a fence when there's no fb, just as a sanity check. Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- include/drm/drm_crtc.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index bc47d11cb126..bc1cc3ce05c4 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -42,6 +42,7 @@ struct drm_object_properties; struct drm_file; struct drm_clip_rect; struct device_node; +struct fence; #define DRM_MODE_OBJECT_CRTC 0xcccccccc #define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0 @@ -658,6 +659,7 @@ struct drm_connector { * struct drm_plane_state - mutable plane state * @crtc: currently bound CRTC, NULL if disabled * @fb: currently bound framebuffer + * @fence: optional fence to wait for before scanning out @fb * @crtc_x: left position of visible portion of plane on crtc * @crtc_y: upper position of visible portion of plane on crtc * @crtc_w: width of visible portion of plane on crtc @@ -673,6 +675,7 @@ struct drm_connector { struct drm_plane_state { struct drm_crtc *crtc; struct drm_framebuffer *fb; + struct fence *fence; /* Signed dest location allows it to be partially off screen */ int32_t crtc_x, crtc_y; -- cgit v1.2.3 From 8bc0f3126cc5d37c98d213171e71626536fd1e86 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 27 Jul 2014 18:42:37 +0200 Subject: drm/atomic-helper: implement ->page_flip Currently there is no way to implement async flips using atomic, that essentially requires us to be able to cancel pending requests mid-flight. To be able to do that (and I guess we want this since vblank synced updates which opportunistically cancel still pending updates seem to be wanted) we'd need to add a mandatory cancellation mode. Depending upon the exact semantics we decide upon that could mean that userspace will not get completion events, or will get them all stacked up. So reject async updates for now. Also async updates usually means not vblank synced at all, and I guess for drivers which want to support this they should simply add a special pageflip handler (since usually you need a special flip cmd to achieve this). That kind of async flip is pretty much exclusively just used for games and benchmarks where dropping just one frame means you'll get a headshot or something bad like that ... And so slight amounts of tearing is acceptable. v2: Fixup kerneldoc, reported by Paulo. v3: Use the set_crtc_for_plane function to assign the crtc, since otherwise the book-keeping is off. v4: Update crtc->primary->fb since ->page_flip is the only driver callback where the core won't do this itself. We might want to fix this inconsistency eventually. v5: Use set_crtc_for_connector as suggested by Sean. v6: Daniel Thompson noticed that my error handling is inconsistent and that in a few cases I didn't handle fatal errors (i.e. not -EDEADLK). Fix this by consolidate the ww mutex backoff handling into one check in the fail: block and flatten the error control flow everywhere else. v7: Fix spelling mistake in the commit message (Sean). Cc: Daniel Thompson Cc: Sean Paul Cc: Paulo Zanoni Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- include/drm/drm_atomic_helper.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 8cd6fe7a48e5..28a2f3a815fd 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -69,5 +69,10 @@ int drm_atomic_helper_plane_set_property(struct drm_plane *plane, int drm_atomic_helper_connector_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t val); +int drm_atomic_helper_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t flags); + #endif /* DRM_ATOMIC_HELPER_H_ */ -- cgit v1.2.3 From d461701c551efe92893b31d05906d51e2f1f8244 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 3 Nov 2014 15:56:43 +0100 Subject: drm/atomic-helpers: functions for state duplicate/destroy/reset The atomic users and helpers assume that there is always a obj->state structure around. Which means drivers need to somehow create that at driver load time. Also it should obviously reset hardware state, so needs to be reset upon resume. Finally the destroy/duplicate_state functions are an awful lot of boilerplate if the driver doesn't need anything beyond the default state objects. So add helper functions for all of this. v2: Somehow the plane/connector versions got lost in the first version. v3: Add kerneldoc. v4: Make duplicate_state functions a bit more robust, which is useful for debugging state tracking issues when transitioning to atomic. v5: Clear temporary variables in the crtc state when duplicating it, like ->mode_changed or ->planes_changed. If we don't do this stale values for these might pollute the next atomic modeset. v6: Also clear crtc_state->event in case the driver didn't (yet) clear this out. v7: Split out wrong squashed commit. Also improve the kerneldoc to mention that obj->state can be NULL and when. Both suggested by Daniel Thompson. Cc: Daniel Thompson Cc: Sean Paul Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- include/drm/drm_atomic_helper.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include') diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 28a2f3a815fd..67e3c4645ae0 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -74,5 +74,24 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc, struct drm_pending_vblank_event *event, uint32_t flags); +/* default implementations for state handling */ +void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc); +struct drm_crtc_state * +drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc); +void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, + struct drm_crtc_state *state); + +void drm_atomic_helper_plane_reset(struct drm_plane *plane); +struct drm_plane_state * +drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane); +void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, + struct drm_plane_state *state); + +void drm_atomic_helper_connector_reset(struct drm_connector *connector); +struct drm_connector_state * +drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector); +void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, + struct drm_connector_state *state); + #endif /* DRM_ATOMIC_HELPER_H_ */ -- cgit v1.2.3 From 321ebf04dc7ab5c54d658f93db0ffe35277664ab Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 4 Nov 2014 22:57:27 +0100 Subject: drm/atomic: Refcounting for plane_state->fb So my original plan was that the drm core refcounts framebuffers like with the legacy ioctls. But that doesn't work for a bunch of reasons: - State objects might live longer than until the next fb change happens for a plane. For example delayed cleanup work only happens _after_ the pageflip ioctl has completed. So this definitely doesn't work without the plane state holding its own references. - The other issue is transition from legacy to atomic implementations, where the driver works under a mix of both worlds. Which means legacy paths might not properly update the ->fb pointer under plane->state->fb. Which is a bit a problem when then someone comes around and _does_ try to clean it up when it's long gone. The second issue is just a bit a transition bug, since drivers should update plane->state->fb in all the paths that aren't converted yet. But a bit more robustness for the transition can't hurt - we pull similar tricks with cleaning up the old fb in the transitional helpers already. The pattern for drivers that transition is if (plane->state) drm_atomic_set_fb_for_plane(plane->state, plane->fb); inserted after the fb update has logically completed at the end of ->set_config (or ->set_base/mode_set if using the crtc helpers), ->page_flip, ->update_plane or any other entry point which updates plane->fb. v2: Update kerneldoc - copypasta fail. v3: Fix spelling in the commit message (Sean). Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter --- include/drm/drm_atomic.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 5bb15f550c42..9d919168bc11 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -46,6 +46,8 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, int __must_check drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, struct drm_crtc *crtc); +void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, + struct drm_framebuffer *fb); int __must_check drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, struct drm_crtc *crtc); -- cgit v1.2.3