OSDN Git Service

drm/amd/display: add automated audio test support
authorabdoulaye berthe <abdoulaye.berthe@amd.com>
Fri, 26 Jul 2019 15:25:43 +0000 (11:25 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 19 Nov 2019 15:12:51 +0000 (10:12 -0500)
Signed-off-by: abdoulaye berthe <abdoulaye.berthe@amd.com>
Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dc_dp_types.h
drivers/gpu/drm/amd/display/dc/dc_link.h

index b814b74..b72db01 100644 (file)
@@ -2546,6 +2546,92 @@ static void dp_test_send_link_test_pattern(struct dc_link *link)
                        0);
 }
 
+static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video)
+{
+       union audio_test_mode            dpcd_test_mode = {0};
+       struct audio_test_pattern_type   dpcd_pattern_type = {0};
+       union audio_test_pattern_period  dpcd_pattern_period[AUDIO_CHANNELS_COUNT] = {0};
+       enum dp_test_pattern test_pattern = DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
+
+       struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
+       struct pipe_ctx *pipe_ctx = &pipes[0];
+       unsigned int channel_count;
+       unsigned int channel = 0;
+       unsigned int modes = 0;
+       unsigned int sampling_rate_in_hz = 0;
+
+       // get audio test mode and test pattern parameters
+       core_link_read_dpcd(
+               link,
+               DP_TEST_AUDIO_MODE,
+               &dpcd_test_mode.raw,
+               sizeof(dpcd_test_mode));
+
+       core_link_read_dpcd(
+               link,
+               DP_TEST_AUDIO_PATTERN_TYPE,
+               &dpcd_pattern_type.value,
+               sizeof(dpcd_pattern_type));
+
+       channel_count = dpcd_test_mode.bits.channel_count + 1;
+
+       // read pattern periods for requested channels when sawTooth pattern is requested
+       if (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH ||
+                       dpcd_pattern_type.value == AUDIO_TEST_PATTERN_OPERATOR_DEFINED) {
+
+               test_pattern = (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH) ?
+                               DP_TEST_PATTERN_AUDIO_SAWTOOTH : DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
+               // read period for each channel
+               for (channel = 0; channel < channel_count; channel++) {
+                       core_link_read_dpcd(
+                                                       link,
+                                                       DP_TEST_AUDIO_PERIOD_CH1 + channel,
+                                                       &dpcd_pattern_period[channel].raw,
+                                                       sizeof(dpcd_pattern_period[channel]));
+               }
+       }
+
+       // translate sampling rate
+       switch (dpcd_test_mode.bits.sampling_rate) {
+       case AUDIO_SAMPLING_RATE_32KHZ:
+               sampling_rate_in_hz = 32000;
+               break;
+       case AUDIO_SAMPLING_RATE_44_1KHZ:
+               sampling_rate_in_hz = 44100;
+               break;
+       case AUDIO_SAMPLING_RATE_48KHZ:
+               sampling_rate_in_hz = 48000;
+               break;
+       case AUDIO_SAMPLING_RATE_88_2KHZ:
+               sampling_rate_in_hz = 88200;
+               break;
+       case AUDIO_SAMPLING_RATE_96KHZ:
+               sampling_rate_in_hz = 96000;
+               break;
+       case AUDIO_SAMPLING_RATE_176_4KHZ:
+               sampling_rate_in_hz = 176400;
+               break;
+       case AUDIO_SAMPLING_RATE_192KHZ:
+               sampling_rate_in_hz = 192000;
+               break;
+       default:
+               sampling_rate_in_hz = 0;
+               break;
+       }
+
+       link->audio_test_data.flags.test_requested = 1;
+       link->audio_test_data.flags.disable_video = disable_video;
+       link->audio_test_data.sampling_rate = sampling_rate_in_hz;
+       link->audio_test_data.channel_count = channel_count;
+       link->audio_test_data.pattern_type = test_pattern;
+
+       if (test_pattern == DP_TEST_PATTERN_AUDIO_SAWTOOTH) {
+               for (modes = 0; modes < pipe_ctx->stream->audio_info.mode_count; modes++) {
+                       link->audio_test_data.pattern_period[modes] = dpcd_pattern_period[modes].bits.pattern_period;
+               }
+       }
+}
+
 static void handle_automated_test(struct dc_link *link)
 {
        union test_request test_request;
@@ -2575,6 +2661,12 @@ static void handle_automated_test(struct dc_link *link)
                dp_test_send_link_test_pattern(link);
                test_response.bits.ACK = 1;
        }
+
+       if (test_request.bits.AUDIO_TEST_PATTERN) {
+               dp_test_get_audio_test_data(link, test_request.bits.TEST_AUDIO_DISABLED_VIDEO);
+               test_response.bits.ACK = 1;
+       }
+
        if (test_request.bits.PHY_TEST_PATTERN) {
                dp_test_send_phy_test_pattern(link);
                test_response.bits.ACK = 1;
index 4d3378d..1b68d7c 100644 (file)
@@ -469,13 +469,13 @@ union training_aux_rd_interval {
 /* Automated test structures */
 union test_request {
        struct {
-       uint8_t LINK_TRAINING         :1;
-       uint8_t LINK_TEST_PATTRN      :1;
-       uint8_t EDID_READ             :1;
-       uint8_t PHY_TEST_PATTERN      :1;
-       uint8_t AUDIO_TEST_PATTERN    :1;
-       uint8_t RESERVED              :1;
-       uint8_t TEST_STEREO_3D        :1;
+       uint8_t LINK_TRAINING                :1;
+       uint8_t LINK_TEST_PATTRN             :1;
+       uint8_t EDID_READ                    :1;
+       uint8_t PHY_TEST_PATTERN             :1;
+       uint8_t RESERVED                     :1;
+       uint8_t AUDIO_TEST_PATTERN           :1;
+       uint8_t TEST_AUDIO_DISABLED_VIDEO    :1;
        } bits;
        uint8_t raw;
 };
@@ -534,6 +534,40 @@ union test_misc {
        unsigned char raw;
 };
 
+union audio_test_mode {
+       struct {
+               unsigned char sampling_rate   :4;
+               unsigned char channel_count   :4;
+       } bits;
+       unsigned char raw;
+};
+
+union audio_test_pattern_period {
+       struct {
+               unsigned char pattern_period   :4;
+               unsigned char reserved         :4;
+       } bits;
+       unsigned char raw;
+};
+
+struct audio_test_pattern_type {
+       unsigned char value;
+};
+
+struct dp_audio_test_data_flags {
+       uint8_t test_requested  :1;
+       uint8_t disable_video   :1;
+};
+
+struct dp_audio_test_data {
+
+       struct dp_audio_test_data_flags flags;
+       uint8_t sampling_rate;
+       uint8_t channel_count;
+       uint8_t pattern_type;
+       uint8_t pattern_period[8];
+};
+
 /* FEC capability DPCD register field bits-*/
 union dpcd_fec_capability {
        struct {
index 8971ce3..314d204 100644 (file)
@@ -94,6 +94,7 @@ struct dc_link {
        struct dc_lane_settings cur_lane_setting;
        struct dc_link_settings preferred_link_setting;
        struct dc_link_training_overrides preferred_training_settings;
+       struct dp_audio_test_data audio_test_data;
 
        uint8_t ddc_hw_inst;