linux/drivers/gpu/drm/i915/display/intel_dp_mst.c

/*
 * Copyright © 2008 Intel Corporation
 *             2014 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS 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.
 *
 */

#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_fixed.h>
#include <drm/drm_probe_helper.h>

#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_audio.h"
#include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_ddi.h"
#include "intel_de.h"
#include "intel_display_driver.h"
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_dp_hdcp.h"
#include "intel_dp_mst.h"
#include "intel_dp_tunnel.h"
#include "intel_dp_link_training.h"
#include "intel_dpio_phy.h"
#include "intel_hdcp.h"
#include "intel_hotplug.h"
#include "intel_link_bw.h"
#include "intel_psr.h"
#include "intel_vdsc.h"
#include "skl_scaler.h"

static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state,
				    bool dsc)
{}

static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state,
				    const struct intel_connector *connector,
				    bool ssc, int dsc_slice_count, int bpp_x16)
{}

static void intel_dp_mst_compute_m_n(const struct intel_crtc_state *crtc_state,
				     const struct intel_connector *connector,
				     int overhead,
				     int bpp_x16,
				     struct intel_link_m_n *m_n)
{}

static int intel_dp_mst_calc_pbn(int pixel_clock, int bpp_x16, int bw_overhead)
{}

static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connector,
					    const struct intel_crtc_state *crtc_state)
{}

static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
						struct intel_crtc_state *crtc_state,
						int max_bpp,
						int min_bpp,
						struct link_config_limits *limits,
						struct drm_connector_state *conn_state,
						int step,
						bool dsc)
{}

static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
					    struct intel_crtc_state *crtc_state,
					    struct drm_connector_state *conn_state,
					    struct link_config_limits *limits)
{}

static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder,
						struct intel_crtc_state *crtc_state,
						struct drm_connector_state *conn_state,
						struct link_config_limits *limits)
{}
static int intel_dp_mst_update_slots(struct intel_encoder *encoder,
				     struct intel_crtc_state *crtc_state,
				     struct drm_connector_state *conn_state)
{}

static int mode_hblank_period_ns(const struct drm_display_mode *mode)
{}

static bool
hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector,
				 const struct intel_crtc_state *crtc_state,
				 const struct link_config_limits *limits)
{}

static bool
adjust_limits_for_dsc_hblank_expansion_quirk(const struct intel_connector *connector,
					     const struct intel_crtc_state *crtc_state,
					     struct link_config_limits *limits,
					     bool dsc)
{}

static bool
intel_dp_mst_compute_config_limits(struct intel_dp *intel_dp,
				   const struct intel_connector *connector,
				   struct intel_crtc_state *crtc_state,
				   bool dsc,
				   struct link_config_limits *limits)
{}

static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
				       struct intel_crtc_state *pipe_config,
				       struct drm_connector_state *conn_state)
{}

/*
 * Iterate over all connectors and return a mask of
 * all CPU transcoders streaming over the same DP link.
 */
static unsigned int
intel_dp_mst_transcoder_mask(struct intel_atomic_state *state,
			     struct intel_dp *mst_port)
{}

static u8 get_pipes_downstream_of_mst_port(struct intel_atomic_state *state,
					   struct drm_dp_mst_topology_mgr *mst_mgr,
					   struct drm_dp_mst_port *parent_port)
{}

static int intel_dp_mst_check_fec_change(struct intel_atomic_state *state,
					 struct drm_dp_mst_topology_mgr *mst_mgr,
					 struct intel_link_bw_limits *limits)
{}

static int intel_dp_mst_check_bw(struct intel_atomic_state *state,
				 struct drm_dp_mst_topology_mgr *mst_mgr,
				 struct drm_dp_mst_topology_state *mst_state,
				 struct intel_link_bw_limits *limits)
{}

/**
 * intel_dp_mst_atomic_check_link - check all modeset MST link configuration
 * @state: intel atomic state
 * @limits: link BW limits
 *
 * Check the link configuration for all modeset MST outputs. If the
 * configuration is invalid @limits will be updated if possible to
 * reduce the total BW, after which the configuration for all CRTCs in
 * @state must be recomputed with the updated @limits.
 *
 * Returns:
 *   - 0 if the confugration is valid
 *   - %-EAGAIN, if the configuration is invalid and @limits got updated
 *     with fallback values with which the configuration of all CRTCs in
 *     @state must be recomputed
 *   - Other negative error, if the configuration is invalid without a
 *     fallback possibility, or the check failed for another reason
 */
int intel_dp_mst_atomic_check_link(struct intel_atomic_state *state,
				   struct intel_link_bw_limits *limits)
{}

static int intel_dp_mst_compute_config_late(struct intel_encoder *encoder,
					    struct intel_crtc_state *crtc_state,
					    struct drm_connector_state *conn_state)
{}

/*
 * If one of the connectors in a MST stream needs a modeset, mark all CRTCs
 * that shares the same MST stream as mode changed,
 * intel_modeset_pipe_config()+intel_crtc_check_fastset() will take care to do
 * a fastset when possible.
 *
 * On TGL+ this is required since each stream go through a master transcoder,
 * so if the master transcoder needs modeset, all other streams in the
 * topology need a modeset. All platforms need to add the atomic state
 * for all streams in the topology, since a modeset on one may require
 * changing the MST link BW usage of the others, which in turn needs a
 * recomputation of the corresponding CRTC states.
 */
static int
intel_dp_mst_atomic_topology_check(struct intel_connector *connector,
				   struct intel_atomic_state *state)
{}

static int
intel_dp_mst_atomic_check(struct drm_connector *connector,
			  struct drm_atomic_state *_state)
{}

static void clear_act_sent(struct intel_encoder *encoder,
			   const struct intel_crtc_state *crtc_state)
{}

static void wait_for_act_sent(struct intel_encoder *encoder,
			      const struct intel_crtc_state *crtc_state)
{}

static void intel_mst_disable_dp(struct intel_atomic_state *state,
				 struct intel_encoder *encoder,
				 const struct intel_crtc_state *old_crtc_state,
				 const struct drm_connector_state *old_conn_state)
{}

static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
				      struct intel_encoder *encoder,
				      const struct intel_crtc_state *old_crtc_state,
				      const struct drm_connector_state *old_conn_state)
{}

static void intel_mst_post_pll_disable_dp(struct intel_atomic_state *state,
					  struct intel_encoder *encoder,
					  const struct intel_crtc_state *old_crtc_state,
					  const struct drm_connector_state *old_conn_state)
{}

static void intel_mst_pre_pll_enable_dp(struct intel_atomic_state *state,
					struct intel_encoder *encoder,
					const struct intel_crtc_state *pipe_config,
					const struct drm_connector_state *conn_state)
{}

static bool intel_mst_probed_link_params_valid(struct intel_dp *intel_dp,
					       int link_rate, int lane_count)
{}

static void intel_mst_set_probed_link_params(struct intel_dp *intel_dp,
					     int link_rate, int lane_count)
{}

static void intel_mst_reprobe_topology(struct intel_dp *intel_dp,
				       const struct intel_crtc_state *crtc_state)
{}

static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
				    struct intel_encoder *encoder,
				    const struct intel_crtc_state *pipe_config,
				    const struct drm_connector_state *conn_state)
{}

static void enable_bs_jitter_was(const struct intel_crtc_state *crtc_state)
{}

static void intel_mst_enable_dp(struct intel_atomic_state *state,
				struct intel_encoder *encoder,
				const struct intel_crtc_state *pipe_config,
				const struct drm_connector_state *conn_state)
{}

static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
				      enum pipe *pipe)
{}

static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
					struct intel_crtc_state *pipe_config)
{}

static bool intel_dp_mst_initial_fastset_check(struct intel_encoder *encoder,
					       struct intel_crtc_state *crtc_state)
{}

static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
{}

static int
intel_dp_mst_connector_late_register(struct drm_connector *connector)
{}

static void
intel_dp_mst_connector_early_unregister(struct drm_connector *connector)
{}

static const struct drm_connector_funcs intel_dp_mst_connector_funcs =;

static int intel_dp_mst_get_modes(struct drm_connector *connector)
{}

static int
intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
			    struct drm_display_mode *mode,
			    struct drm_modeset_acquire_ctx *ctx,
			    enum drm_mode_status *status)
{}

static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *connector,
							 struct drm_atomic_state *state)
{}

static int
intel_dp_mst_detect(struct drm_connector *connector,
		    struct drm_modeset_acquire_ctx *ctx, bool force)
{}

static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs =;

static void intel_dp_mst_encoder_destroy(struct drm_encoder *encoder)
{}

static const struct drm_encoder_funcs intel_dp_mst_enc_funcs =;

static bool intel_dp_mst_get_hw_state(struct intel_connector *connector)
{}

static int intel_dp_mst_add_properties(struct intel_dp *intel_dp,
				       struct drm_connector *connector,
				       const char *pathprop)
{}

static void
intel_dp_mst_read_decompression_port_dsc_caps(struct intel_dp *intel_dp,
					      struct intel_connector *connector)
{}

static bool detect_dsc_hblank_expansion_quirk(const struct intel_connector *connector)
{}

static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
							struct drm_dp_mst_port *port,
							const char *pathprop)
{}

static void
intel_dp_mst_poll_hpd_irq(struct drm_dp_mst_topology_mgr *mgr)
{}

static const struct drm_dp_mst_topology_cbs mst_cbs =;

static struct intel_dp_mst_encoder *
intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe pipe)
{}

static bool
intel_dp_create_fake_mst_encoders(struct intel_digital_port *dig_port)
{}

int
intel_dp_mst_encoder_active_links(struct intel_digital_port *dig_port)
{}

int
intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
{}

bool intel_dp_mst_source_support(struct intel_dp *intel_dp)
{}

void
intel_dp_mst_encoder_cleanup(struct intel_digital_port *dig_port)
{}

bool intel_dp_mst_is_master_trans(const struct intel_crtc_state *crtc_state)
{}

bool intel_dp_mst_is_slave_trans(const struct intel_crtc_state *crtc_state)
{}

/**
 * intel_dp_mst_add_topology_state_for_connector - add MST topology state for a connector
 * @state: atomic state
 * @connector: connector to add the state for
 * @crtc: the CRTC @connector is attached to
 *
 * Add the MST topology state for @connector to @state.
 *
 * Returns 0 on success, negative error code on failure.
 */
static int
intel_dp_mst_add_topology_state_for_connector(struct intel_atomic_state *state,
					      struct intel_connector *connector,
					      struct intel_crtc *crtc)
{}

/**
 * intel_dp_mst_add_topology_state_for_crtc - add MST topology state for a CRTC
 * @state: atomic state
 * @crtc: CRTC to add the state for
 *
 * Add the MST topology state for @crtc to @state.
 *
 * Returns 0 on success, negative error code on failure.
 */
int intel_dp_mst_add_topology_state_for_crtc(struct intel_atomic_state *state,
					     struct intel_crtc *crtc)
{}

static struct intel_connector *
get_connector_in_state_for_crtc(struct intel_atomic_state *state,
				const struct intel_crtc *crtc)
{}

/**
 * intel_dp_mst_crtc_needs_modeset - check if changes in topology need to modeset the given CRTC
 * @state: atomic state
 * @crtc: CRTC for which to check the modeset requirement
 *
 * Check if any change in a MST topology requires a forced modeset on @crtc in
 * this topology. One such change is enabling/disabling the DSC decompression
 * state in the first branch device's UFP DPCD as required by one CRTC, while
 * the other @crtc in the same topology is still active, requiring a full modeset
 * on @crtc.
 */
bool intel_dp_mst_crtc_needs_modeset(struct intel_atomic_state *state,
				     struct intel_crtc *crtc)
{}

/**
 * intel_dp_mst_prepare_probe - Prepare an MST link for topology probing
 * @intel_dp: DP port object
 *
 * Prepare an MST link for topology probing, programming the target
 * link parameters to DPCD. This step is a requirement of the enumaration
 * of path resources during probing.
 */
void intel_dp_mst_prepare_probe(struct intel_dp *intel_dp)
{}

/*
 * intel_dp_mst_verify_dpcd_state - verify the MST SW enabled state wrt. the DPCD
 * @intel_dp: DP port object
 *
 * Verify if @intel_dp's MST enabled SW state matches the corresponding DPCD
 * state. A long HPD pulse - not long enough to be detected as a disconnected
 * state - could've reset the DPCD state, which requires tearing
 * down/recreating the MST topology.
 *
 * Returns %true if the SW MST enabled and DPCD states match, %false
 * otherwise.
 */
bool intel_dp_mst_verify_dpcd_state(struct intel_dp *intel_dp)
{}