Commit 5ca38a18 authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher
Browse files

drm/amd/display: move public dc link function implementation to dc_link_exports



[why]
Link is a subcomponent in dc. DM should be aware of dc link structure
as one of the abstracted objects maintained by dc. However it should
have no idea of the existence of a link component in dc dedicated to
maintain the states of dc link structure. As such we are moving link interfaces
out of dc_link.h and directly added to dc.h. We are grandually fading out
the explicit inclusion of dc_link header and eventually delete it.

On dc side, since link is a subcomponent behind dc interfaces, it is not
a good idea to implement dc interfaces in each individual subcomponent
of link which is already a subcomponent of dc. So we are decoupling it
by implementing a dc_link_exports in dc. This file will be a thin
translation layer that breaks the dependency so link is able to make
interface changes without breaking DM.

Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarQingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9b0f51e8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LI
include $(AMD_DC)

DISPLAY_CORE = dc.o dc_stat.o dc_resource.o dc_hw_sequencer.o dc_sink.o \
dc_surface.o dc_debug.o dc_stream.o dc_link_enc_cfg.o
dc_surface.o dc_debug.o dc_stream.o dc_link_enc_cfg.o dc_link_exports.o

DISPLAY_CORE += dc_vm_helper.o

+103 −0
Original line number Diff line number Diff line
/*
 * Copyright 2023 Advanced Micro Devices, 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 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: AMD
 *
 */

/* FILE POLICY AND INTENDED USAGE:
 * This file provides single entrance to link functionality declared in dc
 * public headers. The file is intended to be used as a thin translation layer
 * that directly calls link internal functions without adding new functional
 * behavior.
 *
 * When exporting a new link related dc function, add function declaration in
 * dc.h with detail interface documentation, then add function implementation
 * in this file which calls link functions.
 */
#include "link.h"

bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
{
	return link_detect(link, reason);
}

bool dc_link_detect_connection_type(struct dc_link *link,
		enum dc_connection_type *type)
{
	return link_detect_connection_type(link, type);
}

const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
{
	return link_get_status(link);
}
#ifdef CONFIG_DRM_AMD_DC_HDCP

/* return true if the connected receiver supports the hdcp version */
bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal)
{
	return link_is_hdcp14(link, signal);
}

bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal)
{
	return link_is_hdcp22(link, signal);
}
#endif

void dc_link_clear_dprx_states(struct dc_link *link)
{
	link_clear_dprx_states(link);
}

bool dc_link_reset_cur_dp_mst_topology(struct dc_link *link)
{
	return link_reset_cur_dp_mst_topology(link);
}

uint32_t dc_link_bandwidth_kbps(
	const struct dc_link *link,
	const struct dc_link_settings *link_settings)
{
	return dp_link_bandwidth_kbps(link, link_settings);
}

uint32_t dc_bandwidth_in_kbps_from_timing(
	const struct dc_crtc_timing *timing)
{
	return link_timing_bandwidth_kbps(timing);
}

void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map)
{
	link_get_cur_res_map(dc, map);
}

void dc_restore_link_res_map(const struct dc *dc, uint32_t *map)
{
	link_restore_res_map(dc, map);
}

bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx)
{
	return link_update_dsc_config(pipe_ctx);
}
+113 −95
Original line number Diff line number Diff line
@@ -52,7 +52,6 @@ struct dmub_notification;
#define MAX_SURFACES 3
#define MAX_PLANES 6
#define MAX_STREAMS 6
#define MAX_SINKS_PER_LINK 4
#define MIN_VIEWPORT_SIZE 12
#define MAX_NUM_EDP 2

@@ -1372,109 +1371,128 @@ struct dc_state *dc_copy_state(struct dc_state *src_ctx);
void dc_retain_state(struct dc_state *context);
void dc_release_state(struct dc_state *context);

struct dc_plane_state *dc_get_surface_for_mpcc(struct dc *dc,
		struct dc_stream_state *stream,
		int mpcc_inst);


uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane);

/* Link Interfaces */
/* TODO: remove this after resolving external dependencies */
#include "dc_link.h"

struct dpcd_caps {
	union dpcd_rev dpcd_rev;
	union max_lane_count max_ln_count;
	union max_down_spread max_down_spread;
	union dprx_feature dprx_feature;

	/* valid only for eDP v1.4 or higher*/
	uint8_t edp_supported_link_rates_count;
	enum dc_link_rate edp_supported_link_rates[8];

	/* dongle type (DP converter, CV smart dongle) */
	enum display_dongle_type dongle_type;
	bool is_dongle_type_one;
	/* branch device or sink device */
	bool is_branch_dev;
	/* Dongle's downstream count. */
	union sink_count sink_count;
	bool is_mst_capable;
	/* If dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER,
	indicates 'Frame Sequential-to-lllFrame Pack' conversion capability.*/
	struct dc_dongle_caps dongle_caps;

	uint32_t sink_dev_id;
	int8_t sink_dev_id_str[6];
	int8_t sink_hw_revision;
	int8_t sink_fw_revision[2];

	uint32_t branch_dev_id;
	int8_t branch_dev_name[6];
	int8_t branch_hw_revision;
	int8_t branch_fw_revision[2];

	bool allow_invalid_MSA_timing_param;
	bool panel_mode_edp;
	bool dpcd_display_control_capable;
	bool ext_receiver_cap_field_present;
	bool set_power_state_capable_edp;
	bool dynamic_backlight_capable_edp;
	union dpcd_fec_capability fec_cap;
	struct dpcd_dsc_capabilities dsc_caps;
	struct dc_lttpr_caps lttpr_caps;
	struct adaptive_sync_caps adaptive_sync_caps;
	struct dpcd_usb4_dp_tunneling_info usb4_dp_tun_info;

	union dp_128b_132b_supported_link_rates dp_128b_132b_supported_link_rates;
	union dp_main_line_channel_coding_cap channel_coding_cap;
	union dp_sink_video_fallback_formats fallback_formats;
	union dp_fec_capability1 fec_cap1;
	union dp_cable_id cable_id;
	uint8_t edp_rev;
	union edp_alpm_caps alpm_caps;
	struct edp_psr_info psr_info;
};

union dpcd_sink_ext_caps {
	struct {
		/* 0 - Sink supports backlight adjust via PWM during SDR/HDR mode
		 * 1 - Sink supports backlight adjust via AUX during SDR/HDR mode.
/* The function initiates detection handshake over the given link. It first
 * determines if there are display connections over the link. If so it initiates
 * detection protocols supported by the connected receiver device. The function
 * contains protocol specific handshake sequences which are sometimes mandatory
 * to establish a proper connection between TX and RX. So it is always
 * recommended to call this function as the first link operation upon HPD event
 * or power up event. Upon completion, the function will update link structure
 * in place based on latest RX capabilities. The function may also cause dpms
 * to be reset to off for all currently enabled streams to the link. It is DM's
 * responsibility to serialize detection and DPMS updates.
 *
 * @reason - Indicate which event triggers this detection. dc may customize
 * detection flow depending on the triggering events.
 * return false - if detection is not fully completed. This could happen when
 * there is an unrecoverable error during detection or detection is partially
 * completed (detection has been delegated to dm mst manager ie.
 * link->connection_type == dc_connection_mst_branch when returning false).
 * return true - detection is completed, link has been fully updated with latest
 * detection result.
 */
		uint8_t sdr_aux_backlight_control : 1;
		uint8_t hdr_aux_backlight_control : 1;
		uint8_t reserved_1 : 2;
		uint8_t oled : 1;
		uint8_t reserved : 3;
	} bits;
	uint8_t raw;
};
bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason);

#if defined(CONFIG_DRM_AMD_DC_HDCP)
union hdcp_rx_caps {
	struct {
		uint8_t version;
		uint8_t reserved;
		struct {
			uint8_t repeater	: 1;
			uint8_t hdcp_capable	: 1;
			uint8_t reserved	: 6;
		} byte0;
	} fields;
	uint8_t raw[3];
};
/* determine if there is a sink connected to the link
 *
 * @type - dc_connection_single if connected, dc_connection_none otherwise.
 * return - false if an unexpected error occurs, true otherwise.
 *
 * NOTE: This function doesn't detect downstream sink connections i.e
 * dc_connection_mst_branch, dc_connection_sst_branch. In this case, it will
 * return dc_connection_single if the branch device is connected despite of
 * downstream sink's connection status.
 */
bool dc_link_detect_connection_type(struct dc_link *link,
		enum dc_connection_type *type);

union hdcp_bcaps {
	struct {
		uint8_t HDCP_CAPABLE:1;
		uint8_t REPEATER:1;
		uint8_t RESERVED:6;
	} bits;
	uint8_t raw;
};
/* Getter for cached link status from given link */
const struct dc_link_status *dc_link_get_status(const struct dc_link *link);

struct hdcp_caps {
	union hdcp_rx_caps rx_caps;
	union hdcp_bcaps bcaps;
};
#ifdef CONFIG_DRM_AMD_DC_HDCP
/* return true if the connected receiver supports the hdcp version */
bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal);
bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal);
#endif

#include "dc_link.h"
/* The function clears recorded DP RX states in the link. DM should call this
 * function when it is resuming from S3 power state to previously connected links.
 *
 * TODO - in the future we should consider to expand link resume interface to
 * support clearing previous rx states. So we don't have to rely on dm to call
 * this interface explicitly.
 */
void dc_link_clear_dprx_states(struct dc_link *link);

uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane);
/* Destruct the mst topology of the link and reset the allocated payload table
 *
 * NOTE: this should only be called if DM chooses not to call dc_link_detect but
 * still wants to reset MST topology on an unplug event */
bool dc_link_reset_cur_dp_mst_topology(struct dc_link *link);

/* The function calculates effective DP link bandwidth when a given link is
 * using the given link settings.
 *
 * return - total effective link bandwidth in kbps.
 */
uint32_t dc_link_bandwidth_kbps(
	const struct dc_link *link,
	const struct dc_link_settings *link_setting);

/* The function returns minimum bandwidth required to drive a given timing
 * return - minimum required timing bandwidth in kbps.
 */
uint32_t dc_bandwidth_in_kbps_from_timing(
	const struct dc_crtc_timing *timing);

/* The function takes a snapshot of current link resource allocation state
 * @dc: pointer to dc of the dm calling this
 * @map: a dc link resource snapshot defined internally to dc.
 *
 * DM needs to capture a snapshot of current link resource allocation mapping
 * and store it in its persistent storage.
 *
 * Some of the link resource is using first come first serve policy.
 * The allocation mapping depends on original hotplug order. This information
 * is lost after driver is loaded next time. The snapshot is used in order to
 * restore link resource to its previous state so user will get consistent
 * link capability allocation across reboot.
 *
 */
void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map);

/* This function restores link resource allocation state from a snapshot
 * @dc: pointer to dc of the dm calling this
 * @map: a dc link resource snapshot defined internally to dc.
 *
 * DM needs to call this function after initial link detection on boot and
 * before first commit streams to restore link resource allocation state
 * from previous boot session.
 *
 * Some of the link resource is using first come first serve policy.
 * The allocation mapping depends on original hotplug order. This information
 * is lost after driver is loaded next time. The snapshot is used in order to
 * restore link resource to its previous state so user will get consistent
 * link capability allocation across reboot.
 *
 */
void dc_restore_link_res_map(const struct dc *dc, uint32_t *map);

/* TODO: this is not meant to be exposed to DM. Should switch to stream update
 * interface i.e stream_update->dsc_config
 */
bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx);
/* Sink Interfaces - A sink corresponds to a display output device */

struct dc_container_id {
+3 −0
Original line number Diff line number Diff line
@@ -178,6 +178,9 @@ enum display_dongle_type {
	DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE,
};

#define DC_MAX_EDID_BUFFER_SIZE 2048
#define DC_EDID_BLOCK_SIZE 128

struct ddc_service {
	struct ddc *ddc_pin;
	struct ddc_flags flags;
+136 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#define DC_DP_TYPES_H

#include "os_types.h"
#include "dc_ddc_types.h"

enum dc_lane_count {
	LANE_COUNT_UNKNOWN = 0,
@@ -1125,4 +1126,139 @@ struct edp_psr_info {
	uint8_t force_psrsu_cap;
};

struct dprx_states {
	bool cable_id_written;
};

enum dpcd_downstream_port_max_bpc {
	DOWN_STREAM_MAX_8BPC = 0,
	DOWN_STREAM_MAX_10BPC,
	DOWN_STREAM_MAX_12BPC,
	DOWN_STREAM_MAX_16BPC
};

enum link_training_offset {
	DPRX                = 0,
	LTTPR_PHY_REPEATER1 = 1,
	LTTPR_PHY_REPEATER2 = 2,
	LTTPR_PHY_REPEATER3 = 3,
	LTTPR_PHY_REPEATER4 = 4,
	LTTPR_PHY_REPEATER5 = 5,
	LTTPR_PHY_REPEATER6 = 6,
	LTTPR_PHY_REPEATER7 = 7,
	LTTPR_PHY_REPEATER8 = 8
};

#define MAX_REPEATER_CNT 8

struct dc_lttpr_caps {
	union dpcd_rev revision;
	uint8_t mode;
	uint8_t max_lane_count;
	uint8_t max_link_rate;
	uint8_t phy_repeater_cnt;
	uint8_t max_ext_timeout;
	union dp_main_link_channel_coding_lttpr_cap main_link_channel_coding;
	union dp_128b_132b_supported_lttpr_link_rates supported_128b_132b_rates;
	uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1];
};

struct dc_dongle_dfp_cap_ext {
	bool supported;
	uint16_t max_pixel_rate_in_mps;
	uint16_t max_video_h_active_width;
	uint16_t max_video_v_active_height;
	struct dp_encoding_format_caps encoding_format_caps;
	struct dp_color_depth_caps rgb_color_depth_caps;
	struct dp_color_depth_caps ycbcr444_color_depth_caps;
	struct dp_color_depth_caps ycbcr422_color_depth_caps;
	struct dp_color_depth_caps ycbcr420_color_depth_caps;
};

struct dc_dongle_caps {
	/* dongle type (DP converter, CV smart dongle) */
	enum display_dongle_type dongle_type;
	bool extendedCapValid;
	/* If dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER,
	indicates 'Frame Sequential-to-lllFrame Pack' conversion capability.*/
	bool is_dp_hdmi_s3d_converter;
	bool is_dp_hdmi_ycbcr422_pass_through;
	bool is_dp_hdmi_ycbcr420_pass_through;
	bool is_dp_hdmi_ycbcr422_converter;
	bool is_dp_hdmi_ycbcr420_converter;
	uint32_t dp_hdmi_max_bpc;
	uint32_t dp_hdmi_max_pixel_clk_in_khz;
	uint32_t dp_hdmi_frl_max_link_bw_in_kbps;
	struct dc_dongle_dfp_cap_ext dfp_cap_ext;
};

struct dpcd_caps {
	union dpcd_rev dpcd_rev;
	union max_lane_count max_ln_count;
	union max_down_spread max_down_spread;
	union dprx_feature dprx_feature;

	/* valid only for eDP v1.4 or higher*/
	uint8_t edp_supported_link_rates_count;
	enum dc_link_rate edp_supported_link_rates[8];

	/* dongle type (DP converter, CV smart dongle) */
	enum display_dongle_type dongle_type;
	bool is_dongle_type_one;
	/* branch device or sink device */
	bool is_branch_dev;
	/* Dongle's downstream count. */
	union sink_count sink_count;
	bool is_mst_capable;
	/* If dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER,
	indicates 'Frame Sequential-to-lllFrame Pack' conversion capability.*/
	struct dc_dongle_caps dongle_caps;

	uint32_t sink_dev_id;
	int8_t sink_dev_id_str[6];
	int8_t sink_hw_revision;
	int8_t sink_fw_revision[2];

	uint32_t branch_dev_id;
	int8_t branch_dev_name[6];
	int8_t branch_hw_revision;
	int8_t branch_fw_revision[2];

	bool allow_invalid_MSA_timing_param;
	bool panel_mode_edp;
	bool dpcd_display_control_capable;
	bool ext_receiver_cap_field_present;
	bool set_power_state_capable_edp;
	bool dynamic_backlight_capable_edp;
	union dpcd_fec_capability fec_cap;
	struct dpcd_dsc_capabilities dsc_caps;
	struct dc_lttpr_caps lttpr_caps;
	struct adaptive_sync_caps adaptive_sync_caps;
	struct dpcd_usb4_dp_tunneling_info usb4_dp_tun_info;

	union dp_128b_132b_supported_link_rates dp_128b_132b_supported_link_rates;
	union dp_main_line_channel_coding_cap channel_coding_cap;
	union dp_sink_video_fallback_formats fallback_formats;
	union dp_fec_capability1 fec_cap1;
	union dp_cable_id cable_id;
	uint8_t edp_rev;
	union edp_alpm_caps alpm_caps;
	struct edp_psr_info psr_info;
};

union dpcd_sink_ext_caps {
	struct {
		/* 0 - Sink supports backlight adjust via PWM during SDR/HDR mode
		 * 1 - Sink supports backlight adjust via AUX during SDR/HDR mode.
		 */
		uint8_t sdr_aux_backlight_control : 1;
		uint8_t hdr_aux_backlight_control : 1;
		uint8_t reserved_1 : 2;
		uint8_t oled : 1;
		uint8_t reserved_2 : 1;
		uint8_t miniled : 1;
		uint8_t reserved : 1;
	} bits;
	uint8_t raw;
};
#endif /* DC_DP_TYPES_H */
Loading