aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/modules
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/modules')
-rw-r--r--drivers/gpu/drm/amd/display/modules/freesync/freesync.c5
-rw-r--r--drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c2
-rw-r--r--drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c4
-rw-r--r--drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h11
-rw-r--r--drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h3
-rw-r--r--drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c29
-rw-r--r--drivers/gpu/drm/amd/display/modules/power/power_helpers.c84
-rw-r--r--drivers/gpu/drm/amd/display/modules/power/power_helpers.h6
-rw-r--r--drivers/gpu/drm/amd/display/modules/vmid/vmid.c2
9 files changed, 142 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index 03fa63d56fa6..0686223034de 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -1374,6 +1374,11 @@ unsigned long long mod_freesync_calc_field_rate_from_timing(
return field_rate_in_uhz;
}
+bool mod_freesync_get_freesync_enabled(struct mod_vrr_params *pVrr)
+{
+ return (pVrr->state != VRR_STATE_UNSUPPORTED) && (pVrr->state != VRR_STATE_DISABLED);
+}
+
bool mod_freesync_is_valid_range(uint32_t min_refresh_cap_in_uhz,
uint32_t max_refresh_cap_in_uhz,
uint32_t nominal_field_rate_in_uhz)
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c
index 1f4095b26409..c5f6c11de7e5 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c
@@ -524,7 +524,7 @@ enum mod_hdcp_status mod_hdcp_hdcp2_dp_transition(struct mod_hdcp *hdcp,
set_watchdog_in_ms(hdcp, 3000, output);
set_state_id(hdcp, output, D2_A6_WAIT_FOR_RX_ID_LIST);
} else {
- callback_in_ms(0, output);
+ callback_in_ms(1, output);
set_state_id(hdcp, output, D2_SEND_CONTENT_STREAM_TYPE);
}
break;
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
index be61975f1470..ee67a35c2a8e 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
@@ -202,6 +202,10 @@ static enum mod_hdcp_status add_display_to_topology_v3(
dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;
dtm_cmd->dtm_in_message.topology_update_v3.phy_id = link->phy_idx;
dtm_cmd->dtm_in_message.topology_update_v3.link_hdcp_cap = link->hdcp_supported_informational;
+ dtm_cmd->dtm_in_message.topology_update_v3.dio_output_type = link->dp.usb4_enabled ?
+ TA_DTM_DIO_OUTPUT_TYPE__DPIA :
+ TA_DTM_DIO_OUTPUT_TYPE__DIRECT;
+ dtm_cmd->dtm_in_message.topology_update_v3.dio_output_id = link->dio_output_id;
psp_dtm_invoke(psp, dtm_cmd->cmd_id);
mutex_unlock(&psp->dtm_context.mutex);
diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h
index 2937b4b61461..5b71bc96b98c 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h
@@ -94,6 +94,15 @@ enum ta_dtm_encoder_type {
TA_DTM_ENCODER_TYPE__DIG = 0x10
};
+/* @enum ta_dtm_dio_output_type
+ * This enum defines software value for dio_output_type
+ */
+typedef enum {
+ TA_DTM_DIO_OUTPUT_TYPE__INVALID,
+ TA_DTM_DIO_OUTPUT_TYPE__DIRECT,
+ TA_DTM_DIO_OUTPUT_TYPE__DPIA
+} ta_dtm_dio_output_type;
+
struct ta_dtm_topology_update_input_v3 {
/* display handle is unique across the driver and is used to identify a display */
/* for all security interfaces which reference displays such as HDCP */
@@ -111,6 +120,8 @@ struct ta_dtm_topology_update_input_v3 {
enum ta_dtm_encoder_type encoder_type;
uint32_t phy_id;
uint32_t link_hdcp_cap;
+ ta_dtm_dio_output_type dio_output_type;
+ uint32_t dio_output_id;
};
struct ta_dtm_topology_assr_enable {
diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
index cf6bc9446244..afe1f6cce528 100644
--- a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
+++ b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
@@ -194,4 +194,7 @@ unsigned int mod_freesync_calc_v_total_from_refresh(
const struct dc_stream_state *stream,
unsigned int refresh_in_uhz);
+// Returns true when FreeSync is supported and enabled (even if it is inactive)
+bool mod_freesync_get_freesync_enabled(struct mod_vrr_params *pVrr);
+
#endif
diff --git a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
index 79bc207415bc..27ceba9d6d65 100644
--- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
+++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
@@ -145,8 +145,10 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
stereo3dSupport = true;
}
- /*VSC packet set to 2 when DP revision >= 1.2*/
- if (stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED)
+ /* VSC packet set to 4 for PSR-SU, or 2 for PSR1 */
+ if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1)
+ vsc_packet_revision = vsc_packet_rev4;
+ else if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_1)
vsc_packet_revision = vsc_packet_rev2;
/* Update to revision 5 for extended colorimetry support */
@@ -159,6 +161,29 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
if (vsc_packet_revision == vsc_packet_undefined)
return;
+ if (vsc_packet_revision == vsc_packet_rev4) {
+ /* Secondary-data Packet ID = 0*/
+ info_packet->hb0 = 0x00;
+ /* 07h - Packet Type Value indicating Video
+ * Stream Configuration packet
+ */
+ info_packet->hb1 = 0x07;
+ /* 04h = VSC SDP supporting 3D stereo + PSR/PSR2 + Y-coordinate
+ * (applies to eDP v1.4 or higher).
+ */
+ info_packet->hb2 = 0x04;
+ /* 0Eh = VSC SDP supporting 3D stereo + PSR2
+ * (HB2 = 04h), with Y-coordinate of first scan
+ * line of the SU region
+ */
+ info_packet->hb3 = 0x0E;
+
+ for (i = 0; i < 28; i++)
+ info_packet->sb[i] = 0;
+
+ info_packet->valid = true;
+ }
+
if (vsc_packet_revision == vsc_packet_rev2) {
/* Secondary-data Packet ID = 0*/
info_packet->hb0 = 0x00;
diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
index 97928d4c3b9a..bc239d38c3c7 100644
--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
+++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
@@ -822,3 +822,87 @@ bool is_psr_su_specific_panel(struct dc_link *link)
return false;
}
+
+/**
+ * mod_power_calc_psr_configs() - calculate/update generic psr configuration fields.
+ * @psr_config: [output], psr configuration structure to be updated
+ * @link: [input] dc link pointer
+ * @stream: [input] dc stream state pointer
+ *
+ * calculate and update the psr configuration fields that are not DM specific, i.e. such
+ * fields which are based on DPCD caps or timing information. To setup PSR in DMUB FW,
+ * this helper is assumed to be called before the call of the DC helper dc_link_setup_psr().
+ *
+ * PSR config fields to be updated within the helper:
+ * - psr_rfb_setup_time
+ * - psr_sdp_transmit_line_num_deadline
+ * - line_time_in_us
+ * - su_y_granularity
+ * - su_granularity_required
+ * - psr_frame_capture_indication_req
+ * - psr_exit_link_training_required
+ *
+ * PSR config fields that are DM specific and NOT updated within the helper:
+ * - allow_smu_optimizations
+ * - allow_multi_disp_optimizations
+ */
+void mod_power_calc_psr_configs(struct psr_config *psr_config,
+ struct dc_link *link,
+ const struct dc_stream_state *stream)
+{
+ unsigned int num_vblank_lines = 0;
+ unsigned int vblank_time_in_us = 0;
+ unsigned int sdp_tx_deadline_in_us = 0;
+ unsigned int line_time_in_us = 0;
+ struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
+ const int psr_setup_time_step_in_us = 55; /* refer to eDP spec DPCD 0x071h */
+
+ /* timing parameters */
+ num_vblank_lines = stream->timing.v_total -
+ stream->timing.v_addressable -
+ stream->timing.v_border_top -
+ stream->timing.v_border_bottom;
+
+ vblank_time_in_us = (stream->timing.h_total * num_vblank_lines * 1000) / (stream->timing.pix_clk_100hz / 10);
+
+ line_time_in_us = ((stream->timing.h_total * 1000) / (stream->timing.pix_clk_100hz / 10)) + 1;
+
+ /**
+ * psr configuration fields
+ *
+ * as per eDP 1.5 pg. 377 of 459, DPCD 0x071h bits [3:1], psr setup time bits interpreted as below
+ * 000b <--> 330 us (default)
+ * 001b <--> 275 us
+ * 010b <--> 220 us
+ * 011b <--> 165 us
+ * 100b <--> 110 us
+ * 101b <--> 055 us
+ * 110b <--> 000 us
+ */
+ psr_config->psr_rfb_setup_time =
+ (6 - dpcd_caps->psr_info.psr_dpcd_caps.bits.PSR_SETUP_TIME) * psr_setup_time_step_in_us;
+
+ if (psr_config->psr_rfb_setup_time > vblank_time_in_us) {
+ link->psr_settings.psr_frame_capture_indication_req = true;
+ link->psr_settings.psr_sdp_transmit_line_num_deadline = num_vblank_lines;
+ } else {
+ sdp_tx_deadline_in_us = vblank_time_in_us - psr_config->psr_rfb_setup_time;
+
+ /* Set the last possible line SDP may be transmitted without violating the RFB setup time */
+ link->psr_settings.psr_frame_capture_indication_req = false;
+ link->psr_settings.psr_sdp_transmit_line_num_deadline = sdp_tx_deadline_in_us / line_time_in_us;
+ }
+
+ psr_config->psr_sdp_transmit_line_num_deadline = link->psr_settings.psr_sdp_transmit_line_num_deadline;
+ psr_config->line_time_in_us = line_time_in_us;
+ psr_config->su_y_granularity = dpcd_caps->psr_info.psr2_su_y_granularity_cap;
+ psr_config->su_granularity_required = dpcd_caps->psr_info.psr_dpcd_caps.bits.SU_GRANULARITY_REQUIRED;
+ psr_config->psr_frame_capture_indication_req = link->psr_settings.psr_frame_capture_indication_req;
+ psr_config->psr_exit_link_training_required =
+ !link->dpcd_caps.psr_info.psr_dpcd_caps.bits.LINK_TRAINING_ON_EXIT_NOT_REQUIRED;
+}
+
+bool mod_power_only_edp(const struct dc_state *context, const struct dc_stream_state *stream)
+{
+ return context && context->stream_count == 1 && dc_is_embedded_signal(stream->signal);
+}
diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h
index 1a634d8c78c5..316452e9dbc9 100644
--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.h
+++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.h
@@ -27,6 +27,7 @@
#include "dc/inc/hw/dmcu.h"
#include "dc/inc/hw/abm.h"
+#include "dc/inc/core_types.h"
struct resource_pool;
@@ -53,4 +54,9 @@ bool dmub_init_abm_config(struct resource_pool *res_pool,
unsigned int inst);
bool is_psr_su_specific_panel(struct dc_link *link);
+void mod_power_calc_psr_configs(struct psr_config *psr_config,
+ struct dc_link *link,
+ const struct dc_stream_state *stream);
+bool mod_power_only_edp(const struct dc_state *context,
+ const struct dc_stream_state *stream);
#endif /* MODULES_POWER_POWER_HELPERS_H_ */
diff --git a/drivers/gpu/drm/amd/display/modules/vmid/vmid.c b/drivers/gpu/drm/amd/display/modules/vmid/vmid.c
index 61ee4be35d27..2c40212d86da 100644
--- a/drivers/gpu/drm/amd/display/modules/vmid/vmid.c
+++ b/drivers/gpu/drm/amd/display/modules/vmid/vmid.c
@@ -66,7 +66,7 @@ static void evict_vmids(struct core_vmid *core_vmid)
}
}
-// Return value of -1 indicates vmid table unitialized or ptb dne in the table
+// Return value of -1 indicates vmid table uninitialized or ptb dne in the table
static int get_existing_vmid_for_ptb(struct core_vmid *core_vmid, uint64_t ptb)
{
int i;