diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2013-04-19 13:01:26 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-04-23 18:03:59 -0400 |
commit | 46892caabe756228666d8d83aea5724d9557601a (patch) | |
tree | 79d6b10a5852ed64da812019df0a302374edbf9e | |
parent | fe214163cc6e6b33253b7ac14bc3dd616e76b513 (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.c | 63 |
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 | ||
57 | static 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) { |