Add support to enable the DP tunnel BW allocation mode. Follow-up patches will call the required helpers added here to prepare for a modeset on a link with DP tunnels, the last change in the patchset actually enabling BWA. With BWA enabled, the driver will expose the full mode list a display supports, regardless of any BW limitation on a shared (Thunderbolt) link. Such BW limits will be checked against only during a modeset, when the driver has the full knowledge of each display's BW requirement. If the link BW changes in a way that a connector's modelist may also change, userspace will get a hotplug notification for all the connectors sharing the same link (so it can adjust the mode used for a display). The BW limitation can change at any point, asynchronously to modesets on a given connector, so a modeset can fail even though the atomic check for it passed. In such scenarios userspace will get a bad link notification and in response is supposed to retry the modeset. v2: - Fix old vs. new connector state in intel_dp_tunnel_atomic_check_state(). (Ville) - Fix propagating the error from intel_dp_tunnel_atomic_compute_stream_bw(). (Ville) - Move tunnel==NULL checks from driver to DRM core helpers. (Ville) - Simplify return flow from intel_dp_tunnel_detect(). (Ville) - s/dp_tunnel_state/inherited_dp_tunnels (Ville) - Simplify struct intel_dp_tunnel_inherited_state. (Ville) - Unconstify object pointers (vs. states) where possible. (Ville) - Init crtc_state while declaring it in check_group_state(). (Ville) - Join obj->base.id, obj->name arg lines in debug prints to reduce LOC. (Ville) - Add/rework intel_dp_tunnel_atomic_alloc_bw() to prepare for moving the BW allocation from encoder hooks up to intel_atomic_commit_tail() later in the patchset. - Disable BW alloc mode during system suspend. - Allocate the required BW for all tunnels during system resume. - Add intel_dp_tunnel_atomic_clear_stream_bw() instead of the open-coded sequence in a follow-up patch. - Add function documentation to all exported functions. - Add CONFIG_USB4 dependency to CONFIG_DRM_I915_DP_TUNNEL. v3: - Rebase on intel_dp_get_active_pipes() change in previous patch. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Uma Shankar <uma.shankar@intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240226185246.1276018-4-imre.deak@intel.com
133 lines
3.8 KiB
C
133 lines
3.8 KiB
C
/* SPDX-License-Identifier: MIT */
|
|
/*
|
|
* Copyright © 2023 Intel Corporation
|
|
*/
|
|
|
|
#ifndef __INTEL_DP_TUNNEL_H__
|
|
#define __INTEL_DP_TUNNEL_H__
|
|
|
|
#include <linux/errno.h>
|
|
#include <linux/types.h>
|
|
|
|
struct drm_i915_private;
|
|
struct drm_connector_state;
|
|
struct drm_modeset_acquire_ctx;
|
|
|
|
struct intel_atomic_state;
|
|
struct intel_connector;
|
|
struct intel_crtc;
|
|
struct intel_crtc_state;
|
|
struct intel_dp;
|
|
struct intel_encoder;
|
|
struct intel_link_bw_limits;
|
|
|
|
#if defined(CONFIG_DRM_I915_DP_TUNNEL) && defined(I915)
|
|
|
|
int intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx);
|
|
void intel_dp_tunnel_disconnect(struct intel_dp *intel_dp);
|
|
void intel_dp_tunnel_destroy(struct intel_dp *intel_dp);
|
|
void intel_dp_tunnel_resume(struct intel_dp *intel_dp,
|
|
const struct intel_crtc_state *crtc_state,
|
|
bool dpcd_updated);
|
|
void intel_dp_tunnel_suspend(struct intel_dp *intel_dp);
|
|
|
|
bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp *intel_dp);
|
|
|
|
void
|
|
intel_dp_tunnel_atomic_cleanup_inherited_state(struct intel_atomic_state *state);
|
|
|
|
int intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state *state,
|
|
struct intel_dp *intel_dp,
|
|
const struct intel_connector *connector,
|
|
struct intel_crtc_state *crtc_state);
|
|
void intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
|
|
struct intel_crtc_state *crtc_state);
|
|
|
|
int intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state *state,
|
|
struct intel_crtc *crtc);
|
|
int intel_dp_tunnel_atomic_check_link(struct intel_atomic_state *state,
|
|
struct intel_link_bw_limits *limits);
|
|
int intel_dp_tunnel_atomic_check_state(struct intel_atomic_state *state,
|
|
struct intel_dp *intel_dp,
|
|
struct intel_connector *connector);
|
|
|
|
void intel_dp_tunnel_atomic_alloc_bw(struct intel_atomic_state *state);
|
|
|
|
int intel_dp_tunnel_mgr_init(struct drm_i915_private *i915);
|
|
void intel_dp_tunnel_mgr_cleanup(struct drm_i915_private *i915);
|
|
|
|
#else
|
|
|
|
static inline int
|
|
intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline void intel_dp_tunnel_disconnect(struct intel_dp *intel_dp) {}
|
|
static inline void intel_dp_tunnel_destroy(struct intel_dp *intel_dp) {}
|
|
static inline void intel_dp_tunnel_resume(struct intel_dp *intel_dp,
|
|
const struct intel_crtc_state *crtc_state,
|
|
bool dpcd_updated) {}
|
|
static inline void intel_dp_tunnel_suspend(struct intel_dp *intel_dp) {}
|
|
|
|
static inline bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp *intel_dp)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline void
|
|
intel_dp_tunnel_atomic_cleanup_inherited_state(struct intel_atomic_state *state) {}
|
|
|
|
static inline int
|
|
intel_dp_tunnel_atomic_compute_stream_bw(struct intel_atomic_state *state,
|
|
struct intel_dp *intel_dp,
|
|
const struct intel_connector *connector,
|
|
struct intel_crtc_state *crtc_state)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline void
|
|
intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
|
|
struct intel_crtc_state *crtc_state) {}
|
|
|
|
static inline int
|
|
intel_dp_tunnel_atomic_add_state_for_crtc(struct intel_atomic_state *state,
|
|
struct intel_crtc *crtc)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int
|
|
intel_dp_tunnel_atomic_check_link(struct intel_atomic_state *state,
|
|
struct intel_link_bw_limits *limits)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int
|
|
intel_dp_tunnel_atomic_check_state(struct intel_atomic_state *state,
|
|
struct intel_dp *intel_dp,
|
|
struct intel_connector *connector)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int
|
|
intel_dp_tunnel_atomic_alloc_bw(struct intel_atomic_state *state)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int
|
|
intel_dp_tunnel_mgr_init(struct drm_i915_private *i915)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline void intel_dp_tunnel_mgr_cleanup(struct drm_i915_private *i915) {}
|
|
|
|
#endif /* CONFIG_DRM_I915_DP_TUNNEL */
|
|
|
|
#endif /* __INTEL_DP_TUNNEL_H__ */
|