Commit c82d84d1 authored by Aric Cyr's avatar Aric Cyr Committed by Alex Deucher
Browse files

drm/amd/display: Create a temporary scratch dc_link



Create a temporary scratch dc_link for programming purposes
and fix a copy of pipe_ctx on the stack to a pointer reference.

Reviewed-by: default avatarJosip Pavic <josip.pavic@amd.com>
Signed-off-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Signed-off-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent d5a7fdc8
Loading
Loading
Loading
Loading
+165 −164
Original line number Diff line number Diff line
@@ -1419,6 +1419,170 @@ struct dc_scratch_space {
	struct dc_stream_state stream_state;
};

/*
 * A link contains one or more sinks and their connected status.
 * The currently active signal type (HDMI, DP-SST, DP-MST) is also reported.
 */
 struct dc_link {
	struct dc_sink *remote_sinks[MAX_SINKS_PER_LINK];
	unsigned int sink_count;
	struct dc_sink *local_sink;
	unsigned int link_index;
	enum dc_connection_type type;
	enum signal_type connector_signal;
	enum dc_irq_source irq_source_hpd;
	enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse  */

	bool is_hpd_filter_disabled;
	bool dp_ss_off;

	/**
	 * @link_state_valid:
	 *
	 * If there is no link and local sink, this variable should be set to
	 * false. Otherwise, it should be set to true; usually, the function
	 * core_link_enable_stream sets this field to true.
	 */
	bool link_state_valid;
	bool aux_access_disabled;
	bool sync_lt_in_progress;
	bool skip_stream_reenable;
	bool is_internal_display;
	/** @todo Rename. Flag an endpoint as having a programmable mapping to a DIG encoder. */
	bool is_dig_mapping_flexible;
	bool hpd_status; /* HPD status of link without physical HPD pin. */
	bool is_hpd_pending; /* Indicates a new received hpd */

	/* USB4 DPIA links skip verifying link cap, instead performing the fallback method
	 * for every link training. This is incompatible with DP LL compliance automation,
	 * which expects the same link settings to be used every retry on a link loss.
	 * This flag is used to skip the fallback when link loss occurs during automation.
	 */
	bool skip_fallback_on_link_loss;

	bool edp_sink_present;

	struct dp_trace dp_trace;

	/* caps is the same as reported_link_cap. link_traing use
	 * reported_link_cap. Will clean up.  TODO
	 */
	struct dc_link_settings reported_link_cap;
	struct dc_link_settings verified_link_cap;
	struct dc_link_settings cur_link_settings;
	struct dc_lane_settings cur_lane_setting[LANE_COUNT_DP_MAX];
	struct dc_link_settings preferred_link_setting;
	/* preferred_training_settings are override values that
	 * come from DM. DM is responsible for the memory
	 * management of the override pointers.
	 */
	struct dc_link_training_overrides preferred_training_settings;
	struct dp_audio_test_data audio_test_data;

	uint8_t ddc_hw_inst;

	uint8_t hpd_src;

	uint8_t link_enc_hw_inst;
	/* DIG link encoder ID. Used as index in link encoder resource pool.
	 * For links with fixed mapping to DIG, this is not changed after dc_link
	 * object creation.
	 */
	enum engine_id eng_id;
	enum engine_id dpia_preferred_eng_id;

	bool test_pattern_enabled;
	/* Pending/Current test pattern are only used to perform and track
	 * FIXED_VS retimer test pattern/lane adjustment override state.
	 * Pending allows link HWSS to differentiate PHY vs non-PHY pattern,
	 * to perform specific lane adjust overrides before setting certain
	 * PHY test patterns. In cases when lane adjust and set test pattern
	 * calls are not performed atomically (i.e. performing link training),
	 * pending_test_pattern will be invalid or contain a non-PHY test pattern
	 * and current_test_pattern will contain required context for any future
	 * set pattern/set lane adjust to transition between override state(s).
	 * */
	enum dp_test_pattern current_test_pattern;
	enum dp_test_pattern pending_test_pattern;

	union compliance_test_state compliance_test_state;

	void *priv;

	struct ddc_service *ddc;

	enum dp_panel_mode panel_mode;
	bool aux_mode;

	/* Private to DC core */

	const struct dc *dc;

	struct dc_context *ctx;

	struct panel_cntl *panel_cntl;
	struct link_encoder *link_enc;
	struct graphics_object_id link_id;
	/* Endpoint type distinguishes display endpoints which do not have entries
	 * in the BIOS connector table from those that do. Helps when tracking link
	 * encoder to display endpoint assignments.
	 */
	enum display_endpoint_type ep_type;
	union ddi_channel_mapping ddi_channel_mapping;
	struct connector_device_tag_info device_tag;
	struct dpcd_caps dpcd_caps;
	uint32_t dongle_max_pix_clk;
	unsigned short chip_caps;
	unsigned int dpcd_sink_count;
	struct hdcp_caps hdcp_caps;
	enum edp_revision edp_revision;
	union dpcd_sink_ext_caps dpcd_sink_ext_caps;

	struct psr_settings psr_settings;
	struct replay_settings replay_settings;

	/* Drive settings read from integrated info table */
	struct dc_lane_settings bios_forced_drive_settings;

	/* Vendor specific LTTPR workaround variables */
	uint8_t vendor_specific_lttpr_link_rate_wa;
	bool apply_vendor_specific_lttpr_link_rate_wa;

	/* MST record stream using this link */
	struct link_flags {
		bool dp_keep_receiver_powered;
		bool dp_skip_DID2;
		bool dp_skip_reset_segment;
		bool dp_skip_fs_144hz;
		bool dp_mot_reset_segment;
		/* Some USB4 docks do not handle turning off MST DSC once it has been enabled. */
		bool dpia_mst_dsc_always_on;
		/* Forced DPIA into TBT3 compatibility mode. */
		bool dpia_forced_tbt3_mode;
		bool dongle_mode_timing_override;
		bool blank_stream_on_ocs_change;
		bool read_dpcd204h_on_irq_hpd;
		bool force_dp_ffe_preset;
	} wa_flags;
	union dc_dp_ffe_preset forced_dp_ffe_preset;
	struct link_mst_stream_allocation_table mst_stream_alloc_table;

	struct dc_link_status link_status;
	struct dprx_states dprx_states;

	struct gpio *hpd_gpio;
	enum dc_link_fec_state fec_state;
	bool link_powered_externally;	// Used to bypass hardware sequencing delays when panel is powered down forcibly

	struct dc_panel_config panel_config;
	struct phy_state phy_state;
	uint32_t phy_transition_bitmask;
	// BW ALLOCATON USB4 ONLY
	struct dc_dpia_bw_alloc dpia_bw_alloc_config;
	bool skip_implict_edp_power_control;
	enum backlight_control_type backlight_control_type;
};

struct dc {
	struct dc_debug_options debug;
	struct dc_versions versions;
@@ -1486,6 +1650,7 @@ struct dc {
		struct dc_scratch_space current_state;
		struct dc_scratch_space new_state;
		struct dc_stream_state temp_stream; // Used so we don't need to allocate stream on the stack
		struct dc_link temp_link;
		bool pipes_to_unlock_first[MAX_PIPES]; /* Any of the pipes indicated here should be unlocked first */
	} scratch;

@@ -1652,170 +1817,6 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
		const enum dc_link_encoding_format link_encoding);

/* Link Interfaces */
/*
 * A link contains one or more sinks and their connected status.
 * The currently active signal type (HDMI, DP-SST, DP-MST) is also reported.
 */
struct dc_link {
	struct dc_sink *remote_sinks[MAX_SINKS_PER_LINK];
	unsigned int sink_count;
	struct dc_sink *local_sink;
	unsigned int link_index;
	enum dc_connection_type type;
	enum signal_type connector_signal;
	enum dc_irq_source irq_source_hpd;
	enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse  */

	bool is_hpd_filter_disabled;
	bool dp_ss_off;

	/**
	 * @link_state_valid:
	 *
	 * If there is no link and local sink, this variable should be set to
	 * false. Otherwise, it should be set to true; usually, the function
	 * core_link_enable_stream sets this field to true.
	 */
	bool link_state_valid;
	bool aux_access_disabled;
	bool sync_lt_in_progress;
	bool skip_stream_reenable;
	bool is_internal_display;
	/** @todo Rename. Flag an endpoint as having a programmable mapping to a DIG encoder. */
	bool is_dig_mapping_flexible;
	bool hpd_status; /* HPD status of link without physical HPD pin. */
	bool is_hpd_pending; /* Indicates a new received hpd */

	/* USB4 DPIA links skip verifying link cap, instead performing the fallback method
	 * for every link training. This is incompatible with DP LL compliance automation,
	 * which expects the same link settings to be used every retry on a link loss.
	 * This flag is used to skip the fallback when link loss occurs during automation.
	 */
	bool skip_fallback_on_link_loss;

	bool edp_sink_present;

	struct dp_trace dp_trace;

	/* caps is the same as reported_link_cap. link_traing use
	 * reported_link_cap. Will clean up.  TODO
	 */
	struct dc_link_settings reported_link_cap;
	struct dc_link_settings verified_link_cap;
	struct dc_link_settings cur_link_settings;
	struct dc_lane_settings cur_lane_setting[LANE_COUNT_DP_MAX];
	struct dc_link_settings preferred_link_setting;
	/* preferred_training_settings are override values that
	 * come from DM. DM is responsible for the memory
	 * management of the override pointers.
	 */
	struct dc_link_training_overrides preferred_training_settings;
	struct dp_audio_test_data audio_test_data;

	uint8_t ddc_hw_inst;

	uint8_t hpd_src;

	uint8_t link_enc_hw_inst;
	/* DIG link encoder ID. Used as index in link encoder resource pool.
	 * For links with fixed mapping to DIG, this is not changed after dc_link
	 * object creation.
	 */
	enum engine_id eng_id;
	enum engine_id dpia_preferred_eng_id;

	bool test_pattern_enabled;
	/* Pending/Current test pattern are only used to perform and track
	 * FIXED_VS retimer test pattern/lane adjustment override state.
	 * Pending allows link HWSS to differentiate PHY vs non-PHY pattern,
	 * to perform specific lane adjust overrides before setting certain
	 * PHY test patterns. In cases when lane adjust and set test pattern
	 * calls are not performed atomically (i.e. performing link training),
	 * pending_test_pattern will be invalid or contain a non-PHY test pattern
	 * and current_test_pattern will contain required context for any future
	 * set pattern/set lane adjust to transition between override state(s).
	 * */
	enum dp_test_pattern current_test_pattern;
	enum dp_test_pattern pending_test_pattern;

	union compliance_test_state compliance_test_state;

	void *priv;

	struct ddc_service *ddc;

	enum dp_panel_mode panel_mode;
	bool aux_mode;

	/* Private to DC core */

	const struct dc *dc;

	struct dc_context *ctx;

	struct panel_cntl *panel_cntl;
	struct link_encoder *link_enc;
	struct graphics_object_id link_id;
	/* Endpoint type distinguishes display endpoints which do not have entries
	 * in the BIOS connector table from those that do. Helps when tracking link
	 * encoder to display endpoint assignments.
	 */
	enum display_endpoint_type ep_type;
	union ddi_channel_mapping ddi_channel_mapping;
	struct connector_device_tag_info device_tag;
	struct dpcd_caps dpcd_caps;
	uint32_t dongle_max_pix_clk;
	unsigned short chip_caps;
	unsigned int dpcd_sink_count;
	struct hdcp_caps hdcp_caps;
	enum edp_revision edp_revision;
	union dpcd_sink_ext_caps dpcd_sink_ext_caps;

	struct psr_settings psr_settings;
	struct replay_settings replay_settings;

	/* Drive settings read from integrated info table */
	struct dc_lane_settings bios_forced_drive_settings;

	/* Vendor specific LTTPR workaround variables */
	uint8_t vendor_specific_lttpr_link_rate_wa;
	bool apply_vendor_specific_lttpr_link_rate_wa;

	/* MST record stream using this link */
	struct link_flags {
		bool dp_keep_receiver_powered;
		bool dp_skip_DID2;
		bool dp_skip_reset_segment;
		bool dp_skip_fs_144hz;
		bool dp_mot_reset_segment;
		/* Some USB4 docks do not handle turning off MST DSC once it has been enabled. */
		bool dpia_mst_dsc_always_on;
		/* Forced DPIA into TBT3 compatibility mode. */
		bool dpia_forced_tbt3_mode;
		bool dongle_mode_timing_override;
		bool blank_stream_on_ocs_change;
		bool read_dpcd204h_on_irq_hpd;
		bool force_dp_ffe_preset;
	} wa_flags;
	union dc_dp_ffe_preset forced_dp_ffe_preset;
	struct link_mst_stream_allocation_table mst_stream_alloc_table;

	struct dc_link_status link_status;
	struct dprx_states dprx_states;

	struct gpio *hpd_gpio;
	enum dc_link_fec_state fec_state;
	bool link_powered_externally;	// Used to bypass hardware sequencing delays when panel is powered down forcibly

	struct dc_panel_config panel_config;
	struct phy_state phy_state;
	uint32_t phy_transition_bitmask;
	// BW ALLOCATON USB4 ONLY
	struct dc_dpia_bw_alloc dpia_bw_alloc_config;
	bool skip_implict_edp_power_control;
	enum backlight_control_type backlight_control_type;
};

/* Return an enumerated dc_link.
 * dc_link order is constant and determined at
 * boot time.  They cannot be created or destroyed.
+1 −1
Original line number Diff line number Diff line
@@ -507,7 +507,7 @@ struct resource_context {
	unsigned int hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS];
	int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS];
	bool is_mpc_3dlut_acquired[MAX_PIPES];
	/* solely used for build scalar data in dml2 */
	/* used to build scalar data in dml2 and for edp backlight programming */
	struct pipe_ctx temp_pipe;
};

+4 −4
Original line number Diff line number Diff line
@@ -524,7 +524,7 @@ bool edp_set_backlight_level(const struct dc_link *link,
	struct dc  *dc = link->ctx->dc;
	uint32_t backlight_pwm_u16_16 = backlight_level_params->backlight_pwm_u16_16;
	uint32_t frame_ramp = backlight_level_params->frame_ramp;
	DC_LOGGER_INIT(link->ctx->logger);

	DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
			backlight_pwm_u16_16, backlight_pwm_u16_16);

@@ -1130,11 +1130,11 @@ static struct abm *get_abm_from_stream_res(const struct dc_link *link)
	struct abm *abm = NULL;

	for (i = 0; i < MAX_PIPES; i++) {
		struct pipe_ctx pipe_ctx = dc->current_state->res_ctx.pipe_ctx[i];
		struct dc_stream_state *stream = pipe_ctx.stream;
		struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
		struct dc_stream_state *stream = pipe_ctx->stream;

		if (stream && stream->link == link) {
			abm = pipe_ctx.stream_res.abm;
			abm = pipe_ctx->stream_res.abm;
			break;
		}
	}