diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 3eaae98b1320..07967497fb34 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3421,6 +3421,20 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, fill_stream_properties_from_drm_display_mode(stream, &mode, &aconnector->base, con_state, old_stream); +#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT + /* stream->timing.flags.DSC = 0; */ + /* */ + /* if (aconnector->dc_link && */ + /* aconnector->dc_link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT #<{(|&& */ + /* aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.is_dsc_supported|)}>#) */ + /* if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc, */ + /* &aconnector->dc_link->dpcd_caps.dsc_caps, */ + /* dc_link_bandwidth_kbps(aconnector->dc_link, dc_link_get_link_cap(aconnector->dc_link)), */ + /* &stream->timing, */ + /* &stream->timing.dsc_cfg)) */ + /* stream->timing.flags.DSC = 1; */ +#endif + update_stream_scaling_settings(&mode, dm_state, stream); fill_audio_info( diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 017f88c9f2e4..056be4c34a98 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -2382,10 +2382,6 @@ static bool retrieve_link_cap(struct dc_link *link) uint32_t read_dpcd_retry_cnt = 3; int i; struct dp_sink_hw_fw_revision dp_hw_fw_revision; -#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT - uint8_t dsc_data[16]; /* DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT + 1 == 16 */ - struct dsc_dec_dpcd_caps *dsc_dec_caps; -#endif memset(dpcd_data, '\0', sizeof(dpcd_data)); memset(&down_strm_port_count, @@ -2558,93 +2554,26 @@ static bool retrieve_link_cap(struct dc_link *link) sizeof(dp_hw_fw_revision.ieee_fw_rev)); #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT - dsc_dec_caps = &link->dpcd_caps.dsc_sink_caps; - memset(dsc_dec_caps, '\0', sizeof(*dsc_dec_caps)); - memset(&link->dpcd_caps.dsc_sink_caps, '\0', - sizeof(link->dpcd_caps.dsc_sink_caps)); + memset(&link->dpcd_caps.dsc_caps, '\0', + sizeof(link->dpcd_caps.dsc_caps)); memset(&link->dpcd_caps.fec_cap, '\0', sizeof(link->dpcd_caps.fec_cap)); /* Read DSC and FEC sink capabilities if DP revision is 1.4 and up */ if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14) { - status = core_link_read_dpcd( - link, - DP_DSC_SUPPORT, - dsc_data, - sizeof(dsc_data)); - if (status == DC_OK) { - DC_LOG_DSC("DSC DPCD capability read at link %d:", - link->link_index); - DC_LOG_DSC("\t%02x %02x %02x %02x", - dsc_data[0], dsc_data[1], - dsc_data[2], dsc_data[3]); - DC_LOG_DSC("\t%02x %02x %02x %02x", - dsc_data[4], dsc_data[5], - dsc_data[6], dsc_data[7]); - DC_LOG_DSC("\t%02x %02x %02x %02x", - dsc_data[8], dsc_data[9], - dsc_data[10], dsc_data[11]); - DC_LOG_DSC("\t%02x %02x %02x %02x", - dsc_data[12], dsc_data[13], - dsc_data[14], dsc_data[15]); - } else { - dm_error("%s: Read DSC dpcd data failed.\n", __func__); - return false; - } - - if (dc_dsc_parse_dsc_dpcd(dsc_data, NULL, - dsc_dec_caps)) { - DC_LOG_DSC("DSC DPCD capabilities parsed at link %d:", - link->link_index); - DC_LOG_DSC("\tis_dsc_supported:\t%d", - dsc_dec_caps->is_dsc_supported); - DC_LOG_DSC("\tdsc_version:\t%d", dsc_dec_caps->dsc_version); - DC_LOG_DSC("\trc_buffer_size:\t%d", - dsc_dec_caps->rc_buffer_size); - DC_LOG_DSC("\tslice_caps1:\t0x%x20", - dsc_dec_caps->slice_caps1.raw); - DC_LOG_DSC("\tslice_caps2:\t0x%x20", - dsc_dec_caps->slice_caps2.raw); - DC_LOG_DSC("\tlb_bit_depth:\t%d", - dsc_dec_caps->lb_bit_depth); - DC_LOG_DSC("\tis_block_pred_supported:\t%d", - dsc_dec_caps->is_block_pred_supported); - DC_LOG_DSC("\tedp_max_bits_per_pixel:\t%d", - dsc_dec_caps->edp_max_bits_per_pixel); - DC_LOG_DSC("\tcolor_formats:\t%d", - dsc_dec_caps->color_formats.raw); - DC_LOG_DSC("\tcolor_depth:\t%d", - dsc_dec_caps->color_depth.raw); - DC_LOG_DSC("\tthroughput_mode_0_mps:\t%d", - dsc_dec_caps->throughput_mode_0_mps); - DC_LOG_DSC("\tthroughput_mode_1_mps:\t%d", - dsc_dec_caps->throughput_mode_1_mps); - DC_LOG_DSC("\tmax_slice_width:\t%d", - dsc_dec_caps->max_slice_width); - DC_LOG_DSC("\tbpp_increment_div:\t%d", - dsc_dec_caps->bpp_increment_div); - DC_LOG_DSC("\tbranch_overall_throughput_0_mps:\t%d", - dsc_dec_caps->branch_overall_throughput_0_mps); - DC_LOG_DSC("\tbranch_overall_throughput_1_mps:\t%d", - dsc_dec_caps->branch_overall_throughput_1_mps); - DC_LOG_DSC("\tbranch_max_line_width:\t%d", - dsc_dec_caps->branch_max_line_width); - } else { - /* Some sinks return bogus DSC DPCD data - * when they don't support DSC. - */ - dm_error("%s: DSC DPCD data doesn't make sense. " - "DSC will be disabled.\n", __func__); - memset(&link->dpcd_caps.dsc_sink_caps, '\0', - sizeof(link->dpcd_caps.dsc_sink_caps)); - } - status = core_link_read_dpcd( link, DP_FEC_CAPABILITY, &link->dpcd_caps.fec_cap.raw, sizeof(link->dpcd_caps.fec_cap.raw)); - if (status != DC_OK) - dm_error("%s: Read FEC dpcd register failed.\n", - __func__); + status = core_link_read_dpcd( + link, + DP_DSC_SUPPORT, + link->dpcd_caps.dsc_caps.dsc_basic_caps.raw, + sizeof(link->dpcd_caps.dsc_caps.dsc_basic_caps.raw)); + status = core_link_read_dpcd( + link, + DP_DSC_BRANCH_OVERALL_THROUGHPUT_0, + link->dpcd_caps.dsc_caps.dsc_ext_caps.raw, + sizeof(link->dpcd_caps.dsc_caps.dsc_ext_caps.raw)); } #endif diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 80c118f0d6da..252eba2ee116 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -910,8 +910,8 @@ struct dpcd_caps { bool dpcd_display_control_capable; bool ext_receiver_cap_field_present; #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT - union fec_capability fec_cap; - struct dsc_dec_dpcd_caps dsc_sink_caps; + union dpcd_fec_capability fec_cap; + struct dpcd_dsc_capabilities dsc_caps; #endif }; @@ -933,6 +933,14 @@ struct dc_container_id { }; +#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT +struct dc_sink_dsc_caps { + // 'true' if these are virtual DPCD's DSC caps (immediately upstream of sink in MST topology), + // 'false' if they are sink's DSC caps + bool is_virtual_dpcd_dsc; + struct dsc_dec_dpcd_caps dsc_dec_caps; +}; +#endif /* * The sink structure contains EDID and other display device properties @@ -948,12 +956,7 @@ struct dc_sink { bool converter_disable_audio; #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT - struct dc_sink_dsc_caps { - // 'true' if these are virtual DPCD's DSC caps (immediately upstream of sink in MST topology), - // 'false' if they are sink's DSC caps - bool is_virtual_dpcd_dsc; - struct dsc_dec_dpcd_caps dsc_dec_caps; - } sink_dsc_caps; + struct dc_sink_dsc_caps sink_dsc_caps; #endif /* private to DC core */ diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h index 6892bf80c9e0..dfcec4d3e9c0 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h @@ -514,7 +514,7 @@ union test_misc { #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT /* FEC capability DPCD register field bits-*/ -union fec_capability { +union dpcd_fec_capability { struct { uint8_t FEC_CAPABLE:1; uint8_t UNCORRECTED_BLOCK_ERROR_COUNT_CAPABLE:1; @@ -524,6 +524,119 @@ union fec_capability { } bits; uint8_t raw; }; + +/* DSC capability DPCD register field bits-*/ +struct dpcd_dsc_support { + uint8_t DSC_SUPPORT :1; + uint8_t DSC_PASSTHROUGH_SUPPORT :1; + uint8_t RESERVED :6; +}; + +struct dpcd_dsc_algorithm_revision { + uint8_t DSC_VERSION_MAJOR :4; + uint8_t DSC_VERSION_MINOR :4; +}; + +struct dpcd_dsc_rc_buffer_block_size { + uint8_t RC_BLOCK_BUFFER_SIZE :2; + uint8_t RESERVED :6; +}; + +struct dpcd_dsc_slice_capability1 { + uint8_t ONE_SLICE_PER_DP_DSC_SINK_DEVICE :1; + uint8_t TWO_SLICES_PER_DP_DSC_SINK_DEVICE :1; + uint8_t RESERVED :1; + uint8_t FOUR_SLICES_PER_DP_DSC_SINK_DEVICE :1; + uint8_t SIX_SLICES_PER_DP_DSC_SINK_DEVICE :1; + uint8_t EIGHT_SLICES_PER_DP_DSC_SINK_DEVICE :1; + uint8_t TEN_SLICES_PER_DP_DSC_SINK_DEVICE :1; + uint8_t TWELVE_SLICES_PER_DP_DSC_SINK_DEVICE :1; +}; + +struct dpcd_dsc_line_buffer_bit_depth { + uint8_t LINE_BUFFER_BIT_DEPTH :4; + uint8_t RESERVED :4; +}; + +struct dpcd_dsc_block_prediction_support { + uint8_t BLOCK_PREDICTION_SUPPORT:1; + uint8_t RESERVED :7; +}; + +struct dpcd_maximum_bits_per_pixel_supported_by_the_decompressor { + uint8_t MAXIMUM_BITS_PER_PIXEL_SUPPORTED_BY_THE_DECOMPRESSOR_LOW :7; + uint8_t MAXIMUM_BITS_PER_PIXEL_SUPPORTED_BY_THE_DECOMPRESSOR_HIGH :7; + uint8_t RESERVED :2; +}; + +struct dpcd_dsc_decoder_color_format_capabilities { + uint8_t RGB_SUPPORT :1; + uint8_t Y_CB_CR_444_SUPPORT :1; + uint8_t Y_CB_CR_SIMPLE_422_SUPPORT :1; + uint8_t Y_CB_CR_NATIVE_422_SUPPORT :1; + uint8_t Y_CB_CR_NATIVE_420_SUPPORT :1; + uint8_t RESERVED :3; +}; + +struct dpcd_dsc_decoder_color_depth_capabilities { + uint8_t RESERVED0 :1; + uint8_t EIGHT_BITS_PER_COLOR_SUPPORT :1; + uint8_t TEN_BITS_PER_COLOR_SUPPORT :1; + uint8_t TWELVE_BITS_PER_COLOR_SUPPORT :1; + uint8_t RESERVED1 :4; +}; + +struct dpcd_peak_dsc_throughput_dsc_sink { + uint8_t THROUGHPUT_MODE_0:4; + uint8_t THROUGHPUT_MODE_1:4; +}; + +struct dpcd_dsc_slice_capabilities_2 { + uint8_t SIXTEEN_SLICES_PER_DSC_SINK_DEVICE :1; + uint8_t TWENTY_SLICES_PER_DSC_SINK_DEVICE :1; + uint8_t TWENTYFOUR_SLICES_PER_DSC_SINK_DEVICE :1; + uint8_t RESERVED :5; +}; + +struct dpcd_bits_per_pixel_increment{ + uint8_t INCREMENT_OF_BITS_PER_PIXEL_SUPPORTED :3; + uint8_t RESERVED :5; +}; +union dpcd_dsc_basic_capabilities { + struct { + struct dpcd_dsc_support dsc_support; + struct dpcd_dsc_algorithm_revision dsc_algorithm_revision; + struct dpcd_dsc_rc_buffer_block_size dsc_rc_buffer_block_size; + uint8_t dsc_rc_buffer_size; + struct dpcd_dsc_slice_capability1 dsc_slice_capabilities_1; + struct dpcd_dsc_line_buffer_bit_depth dsc_line_buffer_bit_depth; + struct dpcd_dsc_block_prediction_support dsc_block_prediction_support; + struct dpcd_maximum_bits_per_pixel_supported_by_the_decompressor maximum_bits_per_pixel_supported_by_the_decompressor; + struct dpcd_dsc_decoder_color_format_capabilities dsc_decoder_color_format_capabilities; + struct dpcd_dsc_decoder_color_depth_capabilities dsc_decoder_color_depth_capabilities; + struct dpcd_peak_dsc_throughput_dsc_sink peak_dsc_throughput_dsc_sink; + uint8_t dsc_maximum_slice_width; + struct dpcd_dsc_slice_capabilities_2 dsc_slice_capabilities_2; + uint8_t reserved; + struct dpcd_bits_per_pixel_increment bits_per_pixel_increment; + } fields; + uint8_t raw[16]; +}; + +union dpcd_dsc_ext_capabilities { + struct { + uint8_t BRANCH_OVERALL_THROUGHPUT_0; + uint8_t BRANCH_OVERALL_THROUGHPUT_1; + uint8_t BRANCH_MAX_LINE_WIDTH; + } fields; + uint8_t raw[3]; +}; + +struct dpcd_dsc_capabilities { + union dpcd_dsc_basic_capabilities dsc_basic_caps; + union dpcd_dsc_ext_capabilities dsc_ext_caps; +}; + #endif /* CONFIG_DRM_AMD_DC_DSC_SUPPORT */ #endif /* DC_DP_TYPES_H */ diff --git a/drivers/gpu/drm/amd/display/dc/dc_dsc.h b/drivers/gpu/drm/amd/display/dc/dc_dsc.h index 6de3bc9162ea..6e42209f0e20 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dsc.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dsc.h @@ -25,6 +25,12 @@ * Author: AMD */ +/* put it here temporarily until linux has the new addresses official defined */ +/* DP Extended DSC Capabilities */ +#define DP_DSC_BRANCH_OVERALL_THROUGHPUT_0 0x0a0 /* DP 1.4a SCR */ +#define DP_DSC_BRANCH_OVERALL_THROUGHPUT_1 0x0a1 +#define DP_DSC_BRANCH_MAX_LINE_WIDTH 0x0a2 + struct dc_dsc_bw_range { uint32_t min_kbps; /* Bandwidth if min_target_bpp_x16 is used */ uint32_t min_target_bpp_x16; diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c index 252c3d0a2555..96b18bb3b1cc 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c @@ -725,9 +725,12 @@ done: bool dc_dsc_parse_dsc_dpcd(const uint8_t *dpcd_dsc_basic_data, const uint8_t *dpcd_dsc_ext_data, struct dsc_dec_dpcd_caps *dsc_sink_caps) { + if (!dpcd_dsc_basic_data) + return false; + dsc_sink_caps->is_dsc_supported = (dpcd_dsc_basic_data[DP_DSC_SUPPORT - DP_DSC_SUPPORT] & DP_DSC_DECOMPRESSION_IS_SUPPORTED) != 0; if (!dsc_sink_caps->is_dsc_supported) - return true; + return false; dsc_sink_caps->dsc_version = dpcd_dsc_basic_data[DP_DSC_REV - DP_DSC_SUPPORT]; diff --git a/drivers/gpu/drm/amd/display/include/dpcd_structs.h b/drivers/gpu/drm/amd/display/include/dpcd_structs.h deleted file mode 100644 index ca9c5e0c062f..000000000000 --- a/drivers/gpu/drm/amd/display/include/dpcd_structs.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * dpcd_structs.h - * - * Created on: Oct 31, 2018 - * Author: jlei - */ - -#ifndef DAL_INCLUDE_DPCD_STRUCTS_H_ -#define DAL_INCLUDE_DPCD_STRUCTS_H_ - -struct dpcd_receive_port0_cap01 { - union { - struct { - // Byte 0 - unsigned char reserved0 :1; // Bit0 - unsigned char local_edid_present :1; - unsigned char associated_to_preceding_port :1; - unsigned char hblank_expansion_capable :1; - unsigned char buffer_size_unit :1; // Bit4 - unsigned char buffer_size_per_port :1; - unsigned char reserved1 :2; - - // Byte 1 - unsigned char buffer_size :8; - } fields; - unsigned char raw[2]; - }; -}; - -#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT - -struct dpcd_dsc_basic_capabilities { - union { - struct { - // Byte 0 - struct { - unsigned char dsc_support :1; // Bit0 - unsigned char dsc_passthrough_support :1; // Bit1 - unsigned char reserved :6; - } dsc_support; - - // Byte 1 - struct { - unsigned char dsc_version_major :4; - unsigned char dsc_version_minor :4; - } dsc_algorithm_revision; - - // Byte 2 - struct { - unsigned char rc_block_buffer_size :2; - unsigned char reserved :6; - } dsc_rc_buffer_block_size; - - // Byte 3 - unsigned char dsc_rc_buffer_size; - - // Byte 4 - struct { - unsigned char one_slice_per_dp_dsc_sink_device :1; // Bit0 - unsigned char two_slices_per_dp_dsc_sink_device :1; - unsigned char reserved :1; - unsigned char four_slices_per_dp_dsc_sink_device :1; - unsigned char six_slices_per_dp_dsc_sink_device :1; // Bit 4 - unsigned char eight_slices_per_dp_dsc_sink_device :1; - unsigned char ten_slices_per_dp_dsc_sink_device :1; - unsigned char twelve_slices_per_dp_dsc_sink_device :1; - } dsc_slice_capabilities_1; - - // Byte 5 - struct { - unsigned char line_buffer_bit_depth :4; - unsigned char reserved :4; - } dsc_line_buffer_bit_depth; - - // Byte 6 - struct { - unsigned char block_prediction_support :1; - unsigned char reserved :7; - } dsc_block_prediction_support; - - // Byte 7,8 - struct { - unsigned char maximum_bits_per_pixel_supported_by_the_decompressor_low :7; - unsigned char maximum_bits_per_pixel_supported_by_the_decompressor_high :7; - } maximum_bits_per_pixel_supported_by_the_decompressor; - - // Byte 9 - struct { - unsigned char rgb_support :1; // Bit0 - unsigned char y_cb_cr_444_support :1; - unsigned char y_cb_cr_simple_422_support :1; - unsigned char y_cb_cr_native_422_support :1; - unsigned char y_cb_cr_native_420_support :1; // Bit 4 - unsigned char reserved :3; - } dsc_decoder_color_format_capabilities; - - // Byte 10 - struct { - unsigned char reserved0 :1; // Bit0 - unsigned char eight_bits_per_color_support :1; - unsigned char ten_bits_per_color_support :1; - unsigned char twelve_bits_per_color_support :1; - unsigned char reserved1 :4; // Bit 4 - } dsc_decoder_color_depth_capabilities; - - // Byte 11 - struct { - unsigned char throughput_mode_0 :4; - unsigned char throughput_mode_1 :4; - } peak_dsc_throughput_dsc_sink; - - // Byte 12 - unsigned char dsc_maximum_slice_width; - - // Byte 13 - struct { - unsigned char sixteen_slices_per_dsc_sink_device :1; - unsigned char twenty_slices_per_dsc_sink_device :1; - unsigned char twentyfour_slices_per_dsc_sink_device :1; - unsigned char reserved :5; - } dsc_slice_capabilities_2; - - // Byte 14 - unsigned char reserved; - - // Byte 15 - struct { - unsigned char increment_of_bits_per_pixel_supported :3; - unsigned char reserved :5; - } bits_per_pixel_increment; - } fields; - unsigned char raw[16]; - }; -}; - -struct dpcd_dsc_ext_capabilities { - union { - struct { - unsigned char branch_overall_throughput_0; // Byte 0 - unsigned char branch_overall_throughput_1; // Byte 1 - unsigned char branch_max_line_width; // Byte 2 - } fields; - unsigned char raw[3]; - }; -}; - -struct dpcd_dsc_capabilities { - struct dpcd_dsc_basic_capabilities dsc_basic_caps; - struct dpcd_dsc_ext_capabilities dsc_ext_caps; -}; - -struct dpcd_fec_capability { - union { - struct { - // Byte 0 - unsigned char fec_capable :1; // Bit0 - unsigned char uncorrected_block_error_count_capable :1; - unsigned char corrected_block_error_count_capable :1; - unsigned char bit_error_count_capable :1; - unsigned char reserved :4; // Bit4 - } fields; - unsigned char raw[1]; - }; -}; - -#endif - -#endif /* DAL_INCLUDE_DPCD_STRUCTS_H_ */