diff options
Diffstat (limited to 'include/drm')
-rw-r--r-- | include/drm/drm_atomic.h | 76 | ||||
-rw-r--r-- | include/drm/drm_atomic_helper.h | 8 | ||||
-rw-r--r-- | include/drm/drm_atomic_state_helper.h | 13 | ||||
-rw-r--r-- | include/drm/drm_bridge.h | 179 | ||||
-rw-r--r-- | include/drm/drm_client.h | 7 | ||||
-rw-r--r-- | include/drm/drm_connector.h | 15 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 80 | ||||
-rw-r--r-- | include/drm/drm_device.h | 2 | ||||
-rw-r--r-- | include/drm/drm_dp_helper.h | 5 | ||||
-rw-r--r-- | include/drm/drm_dp_mst_helper.h | 6 | ||||
-rw-r--r-- | include/drm/drm_drv.h | 194 | ||||
-rw-r--r-- | include/drm/drm_file.h | 1 | ||||
-rw-r--r-- | include/drm/drm_gem_vram_helper.h | 9 | ||||
-rw-r--r-- | include/drm/drm_legacy.h | 6 | ||||
-rw-r--r-- | include/drm/drm_mipi_dbi.h | 12 | ||||
-rw-r--r-- | include/drm/drm_modes.h | 11 | ||||
-rw-r--r-- | include/drm/drm_modeset_helper_vtables.h | 63 | ||||
-rw-r--r-- | include/drm/drm_panel.h | 3 | ||||
-rw-r--r-- | include/drm/drm_print.h | 78 | ||||
-rw-r--r-- | include/drm/drm_simple_kms_helper.h | 7 | ||||
-rw-r--r-- | include/drm/drm_vblank.h | 36 | ||||
-rw-r--r-- | include/drm/ttm/ttm_bo_api.h | 11 | ||||
-rw-r--r-- | include/drm/ttm/ttm_bo_driver.h | 15 |
23 files changed, 539 insertions, 298 deletions
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 951dfb15c27b..52d65a055491 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -670,6 +670,9 @@ __drm_atomic_get_current_plane_state(struct drm_atomic_state *state, } int __must_check +drm_atomic_add_encoder_bridges(struct drm_atomic_state *state, + struct drm_encoder *encoder); +int __must_check drm_atomic_add_affected_connectors(struct drm_atomic_state *state, struct drm_crtc *crtc); int __must_check @@ -992,4 +995,77 @@ drm_atomic_crtc_effectively_active(const struct drm_crtc_state *state) return state->active || state->self_refresh_active; } +/** + * struct drm_bus_cfg - bus configuration + * + * This structure stores the configuration of a physical bus between two + * components in an output pipeline, usually between two bridges, an encoder + * and a bridge, or a bridge and a connector. + * + * The bus configuration is stored in &drm_bridge_state separately for the + * input and output buses, as seen from the point of view of each bridge. The + * bus configuration of a bridge output is usually identical to the + * configuration of the next bridge's input, but may differ if the signals are + * modified between the two bridges, for instance by an inverter on the board. + * The input and output configurations of a bridge may differ if the bridge + * modifies the signals internally, for instance by performing format + * conversion, or modifying signals polarities. + */ +struct drm_bus_cfg { + /** + * @format: format used on this bus (one of the MEDIA_BUS_FMT_* format) + * + * This field should not be directly modified by drivers + * (&drm_atomic_bridge_chain_select_bus_fmts() takes care of the bus + * format negotiation). + */ + u32 format; + + /** + * @flags: DRM_BUS_* flags used on this bus + */ + u32 flags; +}; + +/** + * struct drm_bridge_state - Atomic bridge state object + */ +struct drm_bridge_state { + /** + * @base: inherit from &drm_private_state + */ + struct drm_private_state base; + + /** + * @bridge: the bridge this state refers to + */ + struct drm_bridge *bridge; + + /** + * @input_bus_cfg: input bus configuration + */ + struct drm_bus_cfg input_bus_cfg; + + /** + * @output_bus_cfg: input bus configuration + */ + struct drm_bus_cfg output_bus_cfg; +}; + +static inline struct drm_bridge_state * +drm_priv_to_bridge_state(struct drm_private_state *priv) +{ + return container_of(priv, struct drm_bridge_state, base); +} + +struct drm_bridge_state * +drm_atomic_get_bridge_state(struct drm_atomic_state *state, + struct drm_bridge *bridge); +struct drm_bridge_state * +drm_atomic_get_old_bridge_state(struct drm_atomic_state *state, + struct drm_bridge *bridge); +struct drm_bridge_state * +drm_atomic_get_new_bridge_state(struct drm_atomic_state *state, + struct drm_bridge *bridge); + #endif /* DRM_ATOMIC_H_ */ diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 9db3cac48f4f..b268180c97eb 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -224,4 +224,12 @@ drm_atomic_plane_disabling(struct drm_plane_state *old_plane_state, return old_plane_state->crtc && !new_plane_state->crtc; } +u32 * +drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts); + #endif /* DRM_ATOMIC_HELPER_H_ */ diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h index 8171dea4cc22..3f8f1d627f7c 100644 --- a/include/drm/drm_atomic_state_helper.h +++ b/include/drm/drm_atomic_state_helper.h @@ -26,6 +26,8 @@ #include <linux/types.h> +struct drm_bridge; +struct drm_bridge_state; struct drm_crtc; struct drm_crtc_state; struct drm_plane; @@ -80,3 +82,14 @@ void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, struct drm_connector_state *state); void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, struct drm_private_state *state); + +void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge, + struct drm_bridge_state *state); +struct drm_bridge_state * +drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge); +void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge, + struct drm_bridge_state *state); +void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge, + struct drm_bridge_state *state); +struct drm_bridge_state * +drm_atomic_helper_bridge_reset(struct drm_bridge *bridge); diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 694e153a7531..45626ecf20f8 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -25,6 +25,8 @@ #include <linux/list.h> #include <linux/ctype.h> + +#include <drm/drm_atomic.h> #include <drm/drm_encoder.h> #include <drm/drm_mode_object.h> #include <drm/drm_modes.h> @@ -109,7 +111,9 @@ struct drm_bridge_funcs { * this function passes all other callbacks must succeed for this * configuration. * - * The @mode_fixup callback is optional. + * The mode_fixup callback is optional. &drm_bridge_funcs.mode_fixup() + * is not called when &drm_bridge_funcs.atomic_check() is implemented, + * so only one of them should be provided. * * NOTE: * @@ -263,7 +267,7 @@ struct drm_bridge_funcs { * The @atomic_pre_enable callback is optional. */ void (*atomic_pre_enable)(struct drm_bridge *bridge, - struct drm_atomic_state *old_state); + struct drm_bridge_state *old_bridge_state); /** * @atomic_enable: @@ -288,7 +292,7 @@ struct drm_bridge_funcs { * The @atomic_enable callback is optional. */ void (*atomic_enable)(struct drm_bridge *bridge, - struct drm_atomic_state *old_state); + struct drm_bridge_state *old_bridge_state); /** * @atomic_disable: * @@ -311,7 +315,7 @@ struct drm_bridge_funcs { * The @atomic_disable callback is optional. */ void (*atomic_disable)(struct drm_bridge *bridge, - struct drm_atomic_state *old_state); + struct drm_bridge_state *old_bridge_state); /** * @atomic_post_disable: @@ -337,7 +341,153 @@ struct drm_bridge_funcs { * The @atomic_post_disable callback is optional. */ void (*atomic_post_disable)(struct drm_bridge *bridge, - struct drm_atomic_state *old_state); + struct drm_bridge_state *old_bridge_state); + + /** + * @atomic_duplicate_state: + * + * Duplicate the current bridge state object (which is guaranteed to be + * non-NULL). + * + * The atomic_duplicate_state() is optional. When not implemented the + * core allocates a drm_bridge_state object and calls + * &__drm_atomic_helper_bridge_duplicate_state() to initialize it. + * + * RETURNS: + * A valid drm_bridge_state object or NULL if the allocation fails. + */ + struct drm_bridge_state *(*atomic_duplicate_state)(struct drm_bridge *bridge); + + /** + * @atomic_destroy_state: + * + * Destroy a bridge state object previously allocated by + * &drm_bridge_funcs.atomic_duplicate_state(). + * + * The atomic_destroy_state hook is optional. When not implemented the + * core calls kfree() on the state. + */ + void (*atomic_destroy_state)(struct drm_bridge *bridge, + struct drm_bridge_state *state); + + /** + * @atomic_get_output_bus_fmts: + * + * Return the supported bus formats on the output end of a bridge. + * The returned array must be allocated with kmalloc() and will be + * freed by the caller. If the allocation fails, NULL should be + * returned. num_output_fmts must be set to the returned array size. + * Formats listed in the returned array should be listed in decreasing + * preference order (the core will try all formats until it finds one + * that works). + * + * This method is only called on the last element of the bridge chain + * as part of the bus format negotiation process that happens in + * &drm_atomic_bridge_chain_select_bus_fmts(). + * This method is optional. When not implemented, the core will + * fall back to &drm_connector.display_info.bus_formats[0] if + * &drm_connector.display_info.num_bus_formats > 0, + * or to MEDIA_BUS_FMT_FIXED otherwise. + */ + u32 *(*atomic_get_output_bus_fmts)(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + unsigned int *num_output_fmts); + + /** + * @atomic_get_input_bus_fmts: + * + * Return the supported bus formats on the input end of a bridge for + * a specific output bus format. + * + * The returned array must be allocated with kmalloc() and will be + * freed by the caller. If the allocation fails, NULL should be + * returned. num_output_fmts must be set to the returned array size. + * Formats listed in the returned array should be listed in decreasing + * preference order (the core will try all formats until it finds one + * that works). When the format is not supported NULL should be + * returned and *num_output_fmts should be set to 0. + * + * This method is called on all elements of the bridge chain as part of + * the bus format negotiation process that happens in + * &drm_atomic_bridge_chain_select_bus_fmts(). + * This method is optional. When not implemented, the core will bypass + * bus format negotiation on this element of the bridge without + * failing, and the previous element in the chain will be passed + * MEDIA_BUS_FMT_FIXED as its output bus format. + * + * Bridge drivers that need to support being linked to bridges that are + * not supporting bus format negotiation should handle the + * output_fmt == MEDIA_BUS_FMT_FIXED case appropriately, by selecting a + * sensible default value or extracting this information from somewhere + * else (FW property, &drm_display_mode, &drm_display_info, ...) + * + * Note: Even if input format selection on the first bridge has no + * impact on the negotiation process (bus format negotiation stops once + * we reach the first element of the chain), drivers are expected to + * return accurate input formats as the input format may be used to + * configure the CRTC output appropriately. + */ + u32 *(*atomic_get_input_bus_fmts)(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts); + + /** + * @atomic_check: + * + * This method is responsible for checking bridge state correctness. + * It can also check the state of the surrounding components in chain + * to make sure the whole pipeline can work properly. + * + * &drm_bridge_funcs.atomic_check() hooks are called in reverse + * order (from the last to the first bridge). + * + * This method is optional. &drm_bridge_funcs.mode_fixup() is not + * called when &drm_bridge_funcs.atomic_check() is implemented, so only + * one of them should be provided. + * + * If drivers need to tweak &drm_bridge_state.input_bus_cfg.flags or + * &drm_bridge_state.output_bus_cfg.flags it should should happen in + * this function. By default the &drm_bridge_state.output_bus_cfg.flags + * field is set to the next bridge + * &drm_bridge_state.input_bus_cfg.flags value or + * &drm_connector.display_info.bus_flags if the bridge is the last + * element in the chain. + * + * RETURNS: + * zero if the check passed, a negative error code otherwise. + */ + int (*atomic_check)(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state); + + /** + * @atomic_reset: + * + * Reset the bridge to a predefined state (or retrieve its current + * state) and return a &drm_bridge_state object matching this state. + * This function is called at attach time. + * + * The atomic_reset hook is mandatory if the bridge implements any of + * the atomic hooks, and should be left unassigned otherwise. + * + * Note that the atomic_reset() semantics is not exactly matching the + * reset() semantics found on other components (connector, plane, ...). + * 1/ The reset operation happens when the bridge is attached, not when + * drm_mode_config_reset() is called + * 2/ It's meant to be used exclusively on bridges that have been + * converted to the ATOMIC API + * + * RETURNS: + * A valid drm_bridge_state object in case of success, an ERR_PTR() + * giving the reason of the failure otherwise. + */ + struct drm_bridge_state *(*atomic_reset)(struct drm_bridge *bridge); }; /** @@ -380,6 +530,8 @@ struct drm_bridge_timings { * struct drm_bridge - central DRM bridge control structure */ struct drm_bridge { + /** @base: inherit from &drm_private_object */ + struct drm_private_obj base; /** @dev: DRM device this bridge belongs to */ struct drm_device *dev; /** @encoder: encoder to which this bridge is connected */ @@ -404,6 +556,12 @@ struct drm_bridge { void *driver_private; }; +static inline struct drm_bridge * +drm_priv_to_bridge(struct drm_private_obj *priv) +{ + return container_of(priv, struct drm_bridge, base); +} + void drm_bridge_add(struct drm_bridge *bridge); void drm_bridge_remove(struct drm_bridge *bridge); struct drm_bridge *of_drm_find_bridge(struct device_node *np); @@ -482,6 +640,9 @@ void drm_bridge_chain_mode_set(struct drm_bridge *bridge, void drm_bridge_chain_pre_enable(struct drm_bridge *bridge); void drm_bridge_chain_enable(struct drm_bridge *bridge); +int drm_atomic_bridge_chain_check(struct drm_bridge *bridge, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state); void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge, struct drm_atomic_state *state); void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge, @@ -491,6 +652,14 @@ void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, struct drm_atomic_state *state); +u32 * +drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts); + #ifdef CONFIG_DRM_PANEL_BRIDGE struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel); struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel, diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index 5cf2c5dd8b1e..3ed5dee899fd 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -44,6 +44,11 @@ struct drm_client_funcs { * returns zero gets the privilege to restore and no more clients are * called. This callback is not called after @unregister has been called. * + * Note that the core does not guarantee exclusion against concurrent + * drm_open(). Clients need to ensure this themselves, for example by + * using drm_master_internal_acquire() and + * drm_master_internal_release(). + * * This callback is optional. */ int (*restore)(struct drm_client_dev *client); @@ -156,7 +161,7 @@ int drm_client_modeset_create(struct drm_client_dev *client); void drm_client_modeset_free(struct drm_client_dev *client); int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height); bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation); -int drm_client_modeset_commit_force(struct drm_client_dev *client); +int drm_client_modeset_commit_locked(struct drm_client_dev *client); int drm_client_modeset_commit(struct drm_client_dev *client); int drm_client_modeset_dpms(struct drm_client_dev *client, int mode); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 221910948b37..b3815371c271 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1357,6 +1357,12 @@ struct drm_connector { * rev1.1 4.2.2.6 */ bool edid_corrupt; + /** + * @real_edid_checksum: real edid checksum for corrupted edid block. + * Required in Displayport 1.4 compliance testing + * rev1.1 4.2.2.6 + */ + u8 real_edid_checksum; /** @debugfs_entry: debugfs directory for this connector */ struct dentry *debugfs_entry; @@ -1552,8 +1558,13 @@ void drm_connector_set_link_status_property(struct drm_connector *connector, uint64_t link_status); void drm_connector_set_vrr_capable_property( struct drm_connector *connector, bool capable); -int drm_connector_init_panel_orientation_property( - struct drm_connector *connector, int width, int height); +int drm_connector_set_panel_orientation( + struct drm_connector *connector, + enum drm_panel_orientation panel_orientation); +int drm_connector_set_panel_orientation_with_quirk( + struct drm_connector *connector, + enum drm_panel_orientation panel_orientation, + int width, int height); int drm_connector_attach_max_bpc_property(struct drm_connector *connector, int min, int max); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 5e9b15a0e8c5..59b51a09cae6 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -174,12 +174,25 @@ struct drm_crtc_state { * @no_vblank: * * Reflects the ability of a CRTC to send VBLANK events. This state - * usually depends on the pipeline configuration, and the main usuage - * is CRTCs feeding a writeback connector operating in oneshot mode. - * In this case the VBLANK event is only generated when a job is queued - * to the writeback connector, and we want the core to fake VBLANK - * events when this part of the pipeline hasn't changed but others had - * or when the CRTC and connectors are being disabled. + * usually depends on the pipeline configuration. If set to true, DRM + * atomic helpers will send out a fake VBLANK event during display + * updates after all hardware changes have been committed. This is + * implemented in drm_atomic_helper_fake_vblank(). + * + * One usage is for drivers and/or hardware without support for VBLANK + * interrupts. Such drivers typically do not initialize vblanking + * (i.e., call drm_vblank_init() with the number of CRTCs). For CRTCs + * without initialized vblanking, this field is set to true in + * drm_atomic_helper_check_modeset(), and a fake VBLANK event will be + * send out on each update of the display pipeline by + * drm_atomic_helper_fake_vblank(). + * + * Another usage is CRTCs feeding a writeback connector operating in + * oneshot mode. In this case the fake VBLANK event is only generated + * when a job is queued to the writeback connector, and we want the + * core to fake VBLANK events when this part of the pipeline hasn't + * changed but others had or when the CRTC and connectors are being + * disabled. * * __drm_atomic_helper_crtc_duplicate_state() will not reset the value * from the current state, the CRTC driver is then responsible for @@ -335,7 +348,14 @@ struct drm_crtc_state { * - Events for disabled CRTCs are not allowed, and drivers can ignore * that case. * - * This can be handled by the drm_crtc_send_vblank_event() function, + * For very simple hardware without VBLANK interrupt, enabling + * &struct drm_crtc_state.no_vblank makes DRM's atomic commit helpers + * send a fake VBLANK event at the end of the display update after all + * hardware changes have been applied. See + * drm_atomic_helper_fake_vblank(). + * + * For more complex hardware this + * can be handled by the drm_crtc_send_vblank_event() function, * which the driver should call on the provided event upon completion of * the atomic commit. Note that if the driver supports vblank signalling * and timestamping the vblank counters and timestamps must agree with @@ -867,6 +887,47 @@ struct drm_crtc_funcs { * new drivers as the replacement of &drm_driver.disable_vblank hook. */ void (*disable_vblank)(struct drm_crtc *crtc); + + /** + * @get_vblank_timestamp: + * + * Called by drm_get_last_vbltimestamp(). Should return a precise + * timestamp when the most recent vblank interval ended or will end. + * + * Specifically, the timestamp in @vblank_time should correspond as + * closely as possible to the time when the first video scanline of + * the video frame after the end of vblank will start scanning out, + * the time immediately after end of the vblank interval. If the + * @crtc is currently inside vblank, this will be a time in the future. + * If the @crtc is currently scanning out a frame, this will be the + * past start time of the current scanout. This is meant to adhere + * to the OpenML OML_sync_control extension specification. + * + * Parameters: + * + * crtc: + * CRTC for which timestamp should be returned. + * max_error: + * Maximum allowable timestamp error in nanoseconds. + * Implementation should strive to provide timestamp + * with an error of at most max_error nanoseconds. + * Returns true upper bound on error for timestamp. + * vblank_time: + * Target location for returned vblank timestamp. + * in_vblank_irq: + * True when called from drm_crtc_handle_vblank(). Some drivers + * need to apply some workarounds for gpu-specific vblank irq quirks + * if flag is set. + * + * Returns: + * + * True on success, false on failure, which means the core should + * fallback to a simple timestamp taken in drm_crtc_handle_vblank(). + */ + bool (*get_vblank_timestamp)(struct drm_crtc *crtc, + int *max_error, + ktime_t *vblank_time, + bool in_vblank_irq); }; /** @@ -974,11 +1035,12 @@ struct drm_crtc { * Programmed mode in hw, after adjustments for encoders, crtc, panel * scaling etc. Should only be used by legacy drivers, for high * precision vblank timestamps in - * drm_calc_vbltimestamp_from_scanoutpos(). + * drm_crtc_vblank_helper_get_vblank_timestamp(). * * Note that atomic drivers should not use this, but instead use * &drm_crtc_state.adjusted_mode. And for high-precision timestamps - * drm_calc_vbltimestamp_from_scanoutpos() used &drm_vblank_crtc.hwmode, + * drm_crtc_vblank_helper_get_vblank_timestamp() used + * &drm_vblank_crtc.hwmode, * which is filled out by calling drm_calc_timestamping_constants(). */ struct drm_display_mode hwmode; diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index 1acfc3bbd3fb..bb60a949f416 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -144,7 +144,7 @@ struct drm_device { * Usage counter for outstanding files open, * protected by drm_global_mutex */ - int open_count; + atomic_t open_count; /** @filelist_mutex: Protects @filelist. */ struct mutex filelist_mutex; diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index bc04467f7c3a..b8f6bac6341c 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -392,6 +392,8 @@ # define DP_DS_12BPC 2 # define DP_DS_16BPC 3 +#define DP_MAX_DOWNSTREAM_PORTS 0x10 + /* DP Forward error Correction Registers */ #define DP_FEC_CAPABILITY 0x090 /* 1.4 */ # define DP_FEC_CAPABLE (1 << 0) @@ -1457,6 +1459,9 @@ static inline ssize_t drm_dp_dpcd_writeb(struct drm_dp_aux *aux, int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux, u8 status[DP_LINK_STATUS_SIZE]); +bool drm_dp_send_real_edid_checksum(struct drm_dp_aux *aux, + u8 real_edid_checksum); + int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4]); int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index bcb39da9adb4..5483f888712a 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -635,11 +635,13 @@ struct drm_dp_mst_topology_mgr { struct mutex payload_lock; /** * @proposed_vcpis: Array of pointers for the new VCPI allocation. The - * VCPI structure itself is &drm_dp_mst_port.vcpi. + * VCPI structure itself is &drm_dp_mst_port.vcpi, and the size of + * this array is determined by @max_payloads. */ struct drm_dp_vcpi **proposed_vcpis; /** - * @payloads: Array of payloads. + * @payloads: Array of payloads. The size of this array is determined + * by @max_payloads. */ struct drm_dp_payload *payloads; /** diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index cf13470810a5..97109df5beac 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -269,159 +269,6 @@ struct drm_driver { void (*release) (struct drm_device *); /** - * @get_vblank_counter: - * - * 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 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. - */ - u32 (*get_vblank_counter) (struct drm_device *dev, unsigned int pipe); - - /** - * @enable_vblank: - * - * 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 - * interrupt cannot be enabled. - */ - int (*enable_vblank) (struct drm_device *dev, unsigned int pipe); - - /** - * @disable_vblank: - * - * 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); - - /** - * @get_scanout_position: - * - * Called by vblank timestamping code. - * - * Returns the current display scanout position from a crtc, and an - * optional accurate ktime_get() timestamp of when position was - * measured. Note that this is a helper callback which is only used if a - * driver uses drm_calc_vbltimestamp_from_scanoutpos() for the - * @get_vblank_timestamp callback. - * - * Parameters: - * - * dev: - * DRM device. - * pipe: - * Id of the crtc to query. - * in_vblank_irq: - * True when called from drm_crtc_handle_vblank(). Some drivers - * need to apply some workarounds for gpu-specific vblank irq quirks - * if flag is set. - * vpos: - * Target location for current vertical scanout position. - * hpos: - * Target location for current horizontal scanout position. - * stime: - * Target location for timestamp taken immediately before - * scanout position query. Can be NULL to skip timestamp. - * etime: - * Target location for timestamp taken immediately after - * scanout position query. Can be NULL to skip timestamp. - * mode: - * Current display timings. - * - * Returns vpos as a positive number while in active scanout area. - * Returns vpos as a negative number inside vblank, counting the number - * of scanlines to go until end of vblank, e.g., -1 means "one scanline - * until start of active scanout / end of vblank." - * - * Returns: - * - * True on success, false if a reliable scanout position counter could - * not be read out. - * - * FIXME: - * - * Since this is a helper to implement @get_vblank_timestamp, we should - * move it to &struct drm_crtc_helper_funcs, like all the other - * helper-internal hooks. - */ - bool (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, - bool in_vblank_irq, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode); - - /** - * @get_vblank_timestamp: - * - * Called by drm_get_last_vbltimestamp(). Should return a precise - * timestamp when the most recent VBLANK interval ended or will end. - * - * Specifically, the timestamp in @vblank_time should correspond as - * closely as possible to the time when the first video scanline of - * the video frame after the end of VBLANK will start scanning out, - * the time immediately after end of the VBLANK interval. If the - * @crtc is currently inside VBLANK, this will be a time in the future. - * If the @crtc is currently scanning out a frame, this will be the - * past start time of the current scanout. This is meant to adhere - * to the OpenML OML_sync_control extension specification. - * - * Paramters: - * - * dev: - * dev DRM device handle. - * pipe: - * crtc for which timestamp should be returned. - * max_error: - * Maximum allowable timestamp error in nanoseconds. - * Implementation should strive to provide timestamp - * with an error of at most max_error nanoseconds. - * Returns true upper bound on error for timestamp. - * vblank_time: - * Target location for returned vblank timestamp. - * in_vblank_irq: - * True when called from drm_crtc_handle_vblank(). Some drivers - * need to apply some workarounds for gpu-specific vblank irq quirks - * if flag is set. - * - * Returns: - * - * True on success, false on failure, which means the core should - * fallback to a simple timestamp taken in drm_crtc_handle_vblank(). - * - * FIXME: - * - * We should move this hook to &struct drm_crtc_funcs like all the other - * vblank hooks. - */ - bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, - int *max_error, - ktime_t *vblank_time, - bool in_vblank_irq); - - /** * @irq_handler: * * Interrupt handler called when using drm_irq_install(). Not used by @@ -458,20 +305,6 @@ struct drm_driver { void (*irq_uninstall) (struct drm_device *dev); /** - * @master_create: - * - * Called whenever a new master is created. Only used by vmwgfx. - */ - int (*master_create)(struct drm_device *dev, struct drm_master *master); - - /** - * @master_destroy: - * - * Called whenever a master is destroyed. Only used by vmwgfx. - */ - void (*master_destroy)(struct drm_device *dev, struct drm_master *master); - - /** * @master_set: * * Called whenever the minor master is set. Only used by vmwgfx. @@ -775,6 +608,9 @@ struct drm_driver { int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); int (*dma_quiescent) (struct drm_device *); int (*context_dtor) (struct drm_device *dev, int context); + u32 (*get_vblank_counter)(struct drm_device *dev, unsigned int pipe); + int (*enable_vblank)(struct drm_device *dev, unsigned int pipe); + void (*disable_vblank)(struct drm_device *dev, unsigned int pipe); int dev_priv_size; }; @@ -824,6 +660,25 @@ static inline bool drm_dev_is_unplugged(struct drm_device *dev) } /** + * drm_core_check_all_features - check driver feature flags mask + * @dev: DRM device to check + * @features: feature flag(s) mask + * + * This checks @dev for driver features, see &drm_driver.driver_features, + * &drm_device.driver_features, and the various &enum drm_driver_feature flags. + * + * Returns true if all features in the @features mask are supported, false + * otherwise. + */ +static inline bool drm_core_check_all_features(const struct drm_device *dev, + u32 features) +{ + u32 supported = dev->driver->driver_features & dev->driver_features; + + return features && (supported & features) == features; +} + +/** * drm_core_check_feature - check driver feature flags * @dev: DRM device to check * @feature: feature flag @@ -833,9 +688,10 @@ static inline bool drm_dev_is_unplugged(struct drm_device *dev) * * Returns true if the @feature is supported, false otherwise. */ -static inline bool drm_core_check_feature(const struct drm_device *dev, u32 feature) +static inline bool drm_core_check_feature(const struct drm_device *dev, + enum drm_driver_feature feature) { - return dev->driver->driver_features & dev->driver_features & feature; + return drm_core_check_all_features(dev, feature); } /** diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index 8b099b347817..19df8028a6c4 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -374,6 +374,7 @@ int drm_open(struct inode *inode, struct file *filp); ssize_t drm_read(struct file *filp, char __user *buffer, size_t count, loff_t *offset); int drm_release(struct inode *inode, struct file *filp); +int drm_release_noglobal(struct inode *inode, struct file *filp); __poll_t drm_poll(struct file *filp, struct poll_table_struct *wait); int drm_event_reserve_init_locked(struct drm_device *dev, struct drm_file *file_priv, diff --git a/include/drm/drm_gem_vram_helper.h b/include/drm/drm_gem_vram_helper.h index 573e9fd109bf..0f6e47213d8d 100644 --- a/include/drm/drm_gem_vram_helper.h +++ b/include/drm/drm_gem_vram_helper.h @@ -6,6 +6,7 @@ #include <drm/drm_file.h> #include <drm/drm_gem.h> #include <drm/drm_ioctl.h> +#include <drm/drm_modes.h> #include <drm/ttm/ttm_bo_api.h> #include <drm/ttm/ttm_bo_driver.h> #include <drm/ttm/ttm_placement.h> @@ -205,4 +206,12 @@ struct drm_vram_mm *drm_vram_helper_alloc_mm( struct drm_device *dev, uint64_t vram_base, size_t vram_size); void drm_vram_helper_release_mm(struct drm_device *dev); +/* + * Mode-config helpers + */ + +enum drm_mode_status +drm_vram_helper_mode_valid(struct drm_device *dev, + const struct drm_display_mode *mode); + #endif diff --git a/include/drm/drm_legacy.h b/include/drm/drm_legacy.h index 5745710453c8..dcef3598f49e 100644 --- a/include/drm/drm_legacy.h +++ b/include/drm/drm_legacy.h @@ -194,17 +194,11 @@ void drm_legacy_idlelock_release(struct drm_lock_data *lock); #ifdef CONFIG_PCI -void __drm_legacy_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah); int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver); void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver); #else -static inline void __drm_legacy_pci_free(struct drm_device *dev, - drm_dma_handle_t *dmah) -{ -} - static inline int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver) { diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h index 67c66f5ee591..33f325f5af2b 100644 --- a/include/drm/drm_mipi_dbi.h +++ b/include/drm/drm_mipi_dbi.h @@ -110,6 +110,18 @@ struct mipi_dbi_dev { unsigned int rotation; /** + * @left_offset: Horizontal offset of the display relative to the + * controller's driver array + */ + unsigned int left_offset; + + /** + * @top_offset: Vertical offset of the display relative to the + * controller's driver array + */ + unsigned int top_offset; + + /** * @backlight: backlight device (optional) */ struct backlight_device *backlight; diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index e946e20c61d8..99134d4f35eb 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -371,20 +371,13 @@ struct drm_display_mode { int crtc_vtotal; /** - * @private: + * @private_flags: * - * Pointer for driver private data. This can only be used for mode + * Driver private flags. private_flags can only be used for mode * objects passed to drivers in modeset operations. It shouldn't be used * by atomic drivers since they can store any additional data by * subclassing state structures. */ - int *private; - - /** - * @private_flags: - * - * Similar to @private, but just an integer. - */ int private_flags; /** diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index 5a87f1bd7a3f..7c20b1c8b6a7 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -450,6 +450,53 @@ struct drm_crtc_helper_funcs { */ void (*atomic_disable)(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state); + + /** + * @get_scanout_position: + * + * Called by vblank timestamping code. + * + * Returns the current display scanout position from a CRTC and an + * optional accurate ktime_get() timestamp of when the position was + * measured. Note that this is a helper callback which is only used + * if a driver uses drm_crtc_vblank_helper_get_vblank_timestamp() + * for the @drm_crtc_funcs.get_vblank_timestamp callback. + * + * Parameters: + * + * crtc: + * The CRTC. + * in_vblank_irq: + * True when called from drm_crtc_handle_vblank(). Some drivers + * need to apply some workarounds for gpu-specific vblank irq + * quirks if the flag is set. + * vpos: + * Target location for current vertical scanout position. + * hpos: + * Target location for current horizontal scanout position. + * stime: + * Target location for timestamp taken immediately before + * scanout position query. Can be NULL to skip timestamp. + * etime: + * Target location for timestamp taken immediately after + * scanout position query. Can be NULL to skip timestamp. + * mode: + * Current display timings. + * + * Returns vpos as a positive number while in active scanout area. + * Returns vpos as a negative number inside vblank, counting the number + * of scanlines to go until end of vblank, e.g., -1 means "one scanline + * until start of active scanout / end of vblank." + * + * Returns: + * + * True on success, false if a reliable scanout position counter could + * not be read out. + */ + bool (*get_scanout_position)(struct drm_crtc *crtc, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode); }; /** @@ -646,22 +693,6 @@ struct drm_encoder_helper_funcs { struct drm_connector_state *conn_state); /** - * @get_crtc: - * - * This callback is used by the legacy CRTC helpers to work around - * deficiencies in its own book-keeping. - * - * Do not use, use atomic helpers instead, which get the book keeping - * right. - * - * FIXME: - * - * Currently only nouveau is using this, and as soon as nouveau is - * atomic we can ditch this hook. - */ - struct drm_crtc *(*get_crtc)(struct drm_encoder *encoder); - - /** * @detect: * * This callback can be used by drivers who want to do detection on the diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h index 121f7aabccd1..6193cb555acc 100644 --- a/include/drm/drm_panel.h +++ b/include/drm/drm_panel.h @@ -198,7 +198,8 @@ static inline struct drm_panel *of_drm_find_panel(const struct device_node *np) } #endif -#if IS_REACHABLE(CONFIG_BACKLIGHT_CLASS_DEVICE) +#if IS_ENABLED(CONFIG_DRM_PANEL) && (IS_BUILTIN(CONFIG_BACKLIGHT_CLASS_DEVICE) || \ + (IS_MODULE(CONFIG_DRM) && IS_MODULE(CONFIG_BACKLIGHT_CLASS_DEVICE))) int drm_panel_of_backlight(struct drm_panel *panel); #else static inline int drm_panel_of_backlight(struct drm_panel *panel) diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 8f99d389792d..ca7cee8e728a 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -382,42 +382,6 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category, drm_dev_dbg(dev, DRM_UT_DRIVER, fmt, ##__VA_ARGS__) #define DRM_DEV_DEBUG_KMS(dev, fmt, ...) \ drm_dev_dbg(dev, DRM_UT_KMS, fmt, ##__VA_ARGS__) -#define DRM_DEV_DEBUG_PRIME(dev, fmt, ...) \ - drm_dev_dbg(dev, DRM_UT_PRIME, fmt, ##__VA_ARGS__) -#define DRM_DEV_DEBUG_ATOMIC(dev, fmt, ...) \ - drm_dev_dbg(dev, DRM_UT_ATOMIC, fmt, ##__VA_ARGS__) -#define DRM_DEV_DEBUG_VBL(dev, fmt, ...) \ - drm_dev_dbg(dev, DRM_UT_VBL, fmt, ##__VA_ARGS__) -#define DRM_DEV_DEBUG_DP(dev, fmt, ...) \ - drm_dev_dbg(dev, DRM_UT_DP, fmt, ## __VA_ARGS__) - -#define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, category, fmt, ...) \ -({ \ - static DEFINE_RATELIMIT_STATE(_rs, \ - DEFAULT_RATELIMIT_INTERVAL, \ - DEFAULT_RATELIMIT_BURST); \ - if (__ratelimit(&_rs)) \ - drm_dev_dbg(dev, category, fmt, ##__VA_ARGS__); \ -}) - -/** - * Rate limited debug output. Like DRM_DEBUG() but won't flood the log. - * - * @dev: device pointer - * @fmt: printf() like format string. - */ -#define DRM_DEV_DEBUG_RATELIMITED(dev, fmt, ...) \ - _DEV_DRM_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_CORE, \ - fmt, ##__VA_ARGS__) -#define DRM_DEV_DEBUG_DRIVER_RATELIMITED(dev, fmt, ...) \ - _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_DRIVER, \ - fmt, ##__VA_ARGS__) -#define DRM_DEV_DEBUG_KMS_RATELIMITED(dev, fmt, ...) \ - _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_KMS, \ - fmt, ##__VA_ARGS__) -#define DRM_DEV_DEBUG_PRIME_RATELIMITED(dev, fmt, ...) \ - _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_PRIME, \ - fmt, ##__VA_ARGS__) /* * struct drm_device based logging @@ -541,16 +505,42 @@ void __drm_err(const char *format, ...); __drm_dbg(DRM_UT_DP, fmt, ## __VA_ARGS__) -#define DRM_DEBUG_RATELIMITED(fmt, ...) \ - DRM_DEV_DEBUG_RATELIMITED(NULL, fmt, ##__VA_ARGS__) +#define DRM_DEBUG_KMS_RATELIMITED(fmt, ...) \ +({ \ + static DEFINE_RATELIMIT_STATE(_rs, \ + DEFAULT_RATELIMIT_INTERVAL, \ + DEFAULT_RATELIMIT_BURST); \ + if (__ratelimit(&_rs)) \ + drm_dev_dbg(NULL, DRM_UT_KMS, fmt, ##__VA_ARGS__); \ +}) + +/* + * struct drm_device based WARNs + * + * drm_WARN*() acts like WARN*(), but with the key difference of + * using device specific information so that we know from which device + * warning is originating from. + * + * Prefer drm_device based drm_WARN* over regular WARN* + */ -#define DRM_DEBUG_DRIVER_RATELIMITED(fmt, ...) \ - DRM_DEV_DEBUG_DRIVER_RATELIMITED(NULL, fmt, ##__VA_ARGS__) +/* Helper for struct drm_device based WARNs */ +#define drm_WARN(drm, condition, format, arg...) \ + WARN(condition, "%s %s: " format, \ + dev_driver_string((drm)->dev), \ + dev_name((drm)->dev), ## arg) -#define DRM_DEBUG_KMS_RATELIMITED(fmt, ...) \ - DRM_DEV_DEBUG_KMS_RATELIMITED(NULL, fmt, ##__VA_ARGS__) +#define drm_WARN_ONCE(drm, condition, format, arg...) \ + WARN_ONCE(condition, "%s %s: " format, \ + dev_driver_string((drm)->dev), \ + dev_name((drm)->dev), ## arg) + +#define drm_WARN_ON(drm, x) \ + drm_WARN((drm), (x), "%s", \ + "drm_WARN_ON(" __stringify(x) ")") -#define DRM_DEBUG_PRIME_RATELIMITED(fmt, ...) \ - DRM_DEV_DEBUG_PRIME_RATELIMITED(NULL, fmt, ##__VA_ARGS__) +#define drm_WARN_ON_ONCE(drm, x) \ + drm_WARN_ONCE((drm), (x), "%s", \ + "drm_WARN_ON_ONCE(" __stringify(x) ")") #endif /* DRM_PRINT_H_ */ diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h index 15afee9cf049..e253ba7bea9d 100644 --- a/include/drm/drm_simple_kms_helper.h +++ b/include/drm/drm_simple_kms_helper.h @@ -100,8 +100,11 @@ struct drm_simple_display_pipe_funcs { * This is the function drivers should submit the * &drm_pending_vblank_event from. Using either * drm_crtc_arm_vblank_event(), when the driver supports vblank - * interrupt handling, or drm_crtc_send_vblank_event() directly in case - * the hardware lacks vblank support entirely. + * interrupt handling, or drm_crtc_send_vblank_event() for more + * complex case. In case the hardware lacks vblank support entirely, + * drivers can set &struct drm_crtc_state.no_vblank in + * &struct drm_simple_display_pipe_funcs.check and let DRM's + * atomic helper fake a vblank event. */ void (*update)(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_plane_state); diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h index c16c44052b3d..dd9f5b9e56e4 100644 --- a/include/drm/drm_vblank.h +++ b/include/drm/drm_vblank.h @@ -174,13 +174,13 @@ struct drm_vblank_crtc { unsigned int pipe; /** * @framedur_ns: Frame/Field duration in ns, used by - * drm_calc_vbltimestamp_from_scanoutpos() and computed by + * drm_crtc_vblank_helper_get_vblank_timestamp() and computed by * drm_calc_timestamping_constants(). */ int framedur_ns; /** * @linedur_ns: Line duration in ns, used by - * drm_calc_vbltimestamp_from_scanoutpos() and computed by + * drm_crtc_vblank_helper_get_vblank_timestamp() and computed by * drm_calc_timestamping_constants(). */ int linedur_ns; @@ -190,8 +190,8 @@ struct drm_vblank_crtc { * * Cache of the current hardware display mode. Only valid when @enabled * is set. This is used by helpers like - * drm_calc_vbltimestamp_from_scanoutpos(). We can't just access the - * hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode, + * drm_crtc_vblank_helper_get_vblank_timestamp(). We can't just access + * the hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode, * because that one is really hard to get from interrupt context. */ struct drm_display_mode hwmode; @@ -206,6 +206,7 @@ struct drm_vblank_crtc { }; int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs); +bool drm_dev_has_vblank(const struct drm_device *dev); u64 drm_crtc_vblank_count(struct drm_crtc *crtc); u64 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, ktime_t *vblanktime); @@ -229,13 +230,32 @@ u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc); void drm_vblank_restore(struct drm_device *dev, unsigned int pipe); void drm_crtc_vblank_restore(struct drm_crtc *crtc); -bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - unsigned int pipe, int *max_error, - ktime_t *vblank_time, - bool in_vblank_irq); void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode); wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc); void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc, u32 max_vblank_count); + +/* + * Helpers for struct drm_crtc_funcs + */ + +typedef bool (*drm_vblank_get_scanout_position_func)(struct drm_crtc *crtc, + bool in_vblank_irq, + int *vpos, int *hpos, + ktime_t *stime, + ktime_t *etime, + const struct drm_display_mode *mode); + +bool +drm_crtc_vblank_helper_get_vblank_timestamp_internal(struct drm_crtc *crtc, + int *max_error, + ktime_t *vblank_time, + bool in_vblank_irq, + drm_vblank_get_scanout_position_func get_scanout_position); +bool drm_crtc_vblank_helper_get_vblank_timestamp(struct drm_crtc *crtc, + int *max_error, + ktime_t *vblank_time, + bool in_vblank_irq); + #endif diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 66ca49db9633..b9bc1b00142e 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -135,18 +135,14 @@ struct ttm_tt; * @num_pages: Actual number of pages. * @acc_size: Accounted size for this object. * @kref: Reference count of this buffer object. When this refcount reaches - * zero, the object is put on the delayed delete list. - * @list_kref: List reference count of this buffer object. This member is - * used to avoid destruction while the buffer object is still on a list. - * Lru lists may keep one refcount, the delayed delete list, and kref != 0 - * keeps one refcount. When this refcount reaches zero, - * the object is destroyed. + * zero, the object is destroyed or put on the delayed delete list. * @mem: structure describing current placement. * @persistent_swap_storage: Usually the swap storage is deleted for buffers * pinned in physical memory. If this behaviour is not desired, this member * holds a pointer to a persistent shmem object. * @ttm: TTM structure holding system pages. * @evicted: Whether the object was evicted without user-space knowing. + * @deleted: True if the object is only a zombie and already deleted. * @lru: List head for the lru list. * @ddestroy: List head for the delayed destroy list. * @swap: List head for swap LRU list. @@ -183,9 +179,7 @@ struct ttm_buffer_object { /** * Members not needing protection. */ - struct kref kref; - struct kref list_kref; /** * Members protected by the bo::resv::reserved lock. @@ -195,6 +189,7 @@ struct ttm_buffer_object { struct file *persistent_swap_storage; struct ttm_tt *ttm; bool evicted; + bool deleted; /** * Members protected by the bdev::lru_lock. diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index cac7a8a0825a..c9e0fd09f4b2 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -210,8 +210,6 @@ struct ttm_mem_type_manager { * struct ttm_bo_driver * * @create_ttm_backend_entry: Callback to create a struct ttm_backend. - * @invalidate_caches: Callback to invalidate read caches when a buffer object - * has been evicted. * @init_mem_type: Callback to initialize a struct ttm_mem_type_manager * structure. * @evict_flags: Callback to obtain placement flags when a buffer is evicted. @@ -256,19 +254,6 @@ struct ttm_bo_driver { */ void (*ttm_tt_unpopulate)(struct ttm_tt *ttm); - /** - * struct ttm_bo_driver member invalidate_caches - * - * @bdev: the buffer object device. - * @flags: new placement of the rebound buffer object. - * - * A previosly evicted buffer has been rebound in a - * potentially new location. Tell the driver that it might - * consider invalidating read (texture) caches on the next command - * submission as a consequence. - */ - - int (*invalidate_caches)(struct ttm_bo_device *bdev, uint32_t flags); int (*init_mem_type)(struct ttm_bo_device *bdev, uint32_t type, struct ttm_mem_type_manager *man); |