aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2013-04-19 13:01:26 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-04-23 18:03:59 -0400
commit46892caabe756228666d8d83aea5724d9557601a (patch)
tree79d6b10a5852ed64da812019df0a302374edbf9e
parentfe214163cc6e6b33253b7ac14bc3dd616e76b513 (diff)
drm/radeon/evergreen: set SAD registers
This allows audio (alsa) driver to read them and have a clue about audio capabilities of connected receiver. This has been verified to be compatible with fglrx behaviour for Onkyo TX-SR605 and Denon 1912. Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/evergreen_hdmi.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c
index e32fd2cbc368..b4ab8ceb1654 100644
--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c
+++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c
@@ -54,6 +54,68 @@ static void evergreen_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t cloc
54 WREG32(HDMI_ACR_48_1 + offset, acr.n_48khz); 54 WREG32(HDMI_ACR_48_1 + offset, acr.n_48khz);
55} 55}
56 56
57static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder)
58{
59 struct radeon_device *rdev = encoder->dev->dev_private;
60 struct drm_connector *connector;
61 struct radeon_connector *radeon_connector = NULL;
62 struct cea_sad *sads;
63 int i, sad_count;
64
65 static const u16 eld_reg_to_type[][2] = {
66 { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM },
67 { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 },
68 { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR2, HDMI_AUDIO_CODING_TYPE_MPEG1 },
69 { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR3, HDMI_AUDIO_CODING_TYPE_MP3 },
70 { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR4, HDMI_AUDIO_CODING_TYPE_MPEG2 },
71 { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR5, HDMI_AUDIO_CODING_TYPE_AAC_LC },
72 { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR6, HDMI_AUDIO_CODING_TYPE_DTS },
73 { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR7, HDMI_AUDIO_CODING_TYPE_ATRAC },
74 { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR9, HDMI_AUDIO_CODING_TYPE_EAC3 },
75 { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR10, HDMI_AUDIO_CODING_TYPE_DTS_HD },
76 { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR11, HDMI_AUDIO_CODING_TYPE_MLP },
77 { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO },
78 };
79
80 list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
81 if (connector->encoder == encoder)
82 radeon_connector = to_radeon_connector(connector);
83 }
84
85 if (!radeon_connector) {
86 DRM_ERROR("Couldn't find encoder's connector\n");
87 return;
88 }
89
90 sad_count = drm_edid_to_sad(radeon_connector->edid, &sads);
91 if (sad_count < 0) {
92 DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
93 return;
94 }
95 BUG_ON(!sads);
96
97 for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) {
98 u32 value = 0;
99 int j;
100
101 for (j = 0; j < sad_count; j++) {
102 struct cea_sad *sad = &sads[j];
103
104 if (sad->format == eld_reg_to_type[i][1]) {
105 value = MAX_CHANNELS(sad->channels) |
106 DESCRIPTOR_BYTE_2(sad->byte2) |
107 SUPPORTED_FREQUENCIES(sad->freq);
108 if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM)
109 value |= SUPPORTED_FREQUENCIES_STEREO(sad->freq);
110 break;
111 }
112 }
113 WREG32(eld_reg_to_type[i][0], value);
114 }
115
116 kfree(sads);
117}
118
57/* 119/*
58 * build a HDMI Video Info Frame 120 * build a HDMI Video Info Frame
59 */ 121 */
@@ -187,6 +249,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
187 AFMT_AUDIO_CHANNEL_ENABLE(0xff)); 249 AFMT_AUDIO_CHANNEL_ENABLE(0xff));
188 250
189 /* fglrx sets 0x40 in 0x5f80 here */ 251 /* fglrx sets 0x40 in 0x5f80 here */
252 evergreen_hdmi_write_sad_regs(encoder);
190 253
191 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); 254 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
192 if (err < 0) { 255 if (err < 0) {