diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2013-08-15 05:16:30 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-08-30 16:30:46 -0400 |
commit | 6159b65a5f4e04773e62e57a785df2452ddde1bc (patch) | |
tree | 755b656f86659e6f113e57ddd2739093d69171ed /drivers/gpu/drm/radeon/dce6_afmt.c | |
parent | b530602fd4625f763344e455902981b22f85f609 (diff) |
drm/radeon: set speakers allocation earlier
Do it before enabling audio channels (in AFMT_AUDIO_PACKET_CONTROL2
register).
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/dce6_afmt.c')
-rw-r--r-- | drivers/gpu/drm/radeon/dce6_afmt.c | 69 |
1 files changed, 48 insertions, 21 deletions
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 0d9a6a21088c..8953255e894b 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c | |||
@@ -94,17 +94,62 @@ void dce6_afmt_select_pin(struct drm_encoder *encoder) | |||
94 | WREG32(AFMT_AUDIO_SRC_CONTROL + offset, AFMT_AUDIO_SRC_SELECT(id)); | 94 | WREG32(AFMT_AUDIO_SRC_CONTROL + offset, AFMT_AUDIO_SRC_SELECT(id)); |
95 | } | 95 | } |
96 | 96 | ||
97 | void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) | 97 | void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) |
98 | { | 98 | { |
99 | struct radeon_device *rdev = encoder->dev->dev_private; | 99 | struct radeon_device *rdev = encoder->dev->dev_private; |
100 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 100 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
101 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 101 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
102 | struct drm_connector *connector; | ||
103 | struct radeon_connector *radeon_connector = NULL; | ||
102 | u32 offset, tmp; | 104 | u32 offset, tmp; |
105 | u8 *sadb; | ||
106 | int sad_count; | ||
107 | |||
108 | if (!dig->afmt->pin) | ||
109 | return; | ||
110 | |||
111 | offset = dig->afmt->pin->offset; | ||
112 | |||
113 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | ||
114 | if (connector->encoder == encoder) | ||
115 | radeon_connector = to_radeon_connector(connector); | ||
116 | } | ||
117 | |||
118 | if (!radeon_connector) { | ||
119 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
120 | return; | ||
121 | } | ||
122 | |||
123 | sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); | ||
124 | if (sad_count < 0) { | ||
125 | DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | /* program the speaker allocation */ | ||
130 | tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); | ||
131 | tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); | ||
132 | /* set HDMI mode */ | ||
133 | tmp |= HDMI_CONNECTION; | ||
134 | if (sad_count) | ||
135 | tmp |= SPEAKER_ALLOCATION(sadb[0]); | ||
136 | else | ||
137 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ | ||
138 | WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); | ||
139 | |||
140 | kfree(sadb); | ||
141 | } | ||
142 | |||
143 | void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) | ||
144 | { | ||
145 | struct radeon_device *rdev = encoder->dev->dev_private; | ||
146 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
147 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
148 | u32 offset; | ||
103 | struct drm_connector *connector; | 149 | struct drm_connector *connector; |
104 | struct radeon_connector *radeon_connector = NULL; | 150 | struct radeon_connector *radeon_connector = NULL; |
105 | struct cea_sad *sads; | 151 | struct cea_sad *sads; |
106 | int i, sad_count, sadb_count; | 152 | int i, sad_count; |
107 | u8 *sadb; | ||
108 | 153 | ||
109 | static const u16 eld_reg_to_type[][2] = { | 154 | static const u16 eld_reg_to_type[][2] = { |
110 | { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, | 155 | { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, |
@@ -143,23 +188,6 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) | |||
143 | } | 188 | } |
144 | BUG_ON(!sads); | 189 | BUG_ON(!sads); |
145 | 190 | ||
146 | sadb_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); | ||
147 | if (sadb_count < 0) { | ||
148 | DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sadb_count); | ||
149 | return; | ||
150 | } | ||
151 | |||
152 | /* program the speaker allocation */ | ||
153 | tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); | ||
154 | tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); | ||
155 | /* set HDMI mode */ | ||
156 | tmp |= HDMI_CONNECTION; | ||
157 | if (sadb_count) | ||
158 | tmp |= SPEAKER_ALLOCATION(sadb[0]); | ||
159 | else | ||
160 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ | ||
161 | WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); | ||
162 | |||
163 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { | 191 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { |
164 | u32 value = 0; | 192 | u32 value = 0; |
165 | int j; | 193 | int j; |
@@ -180,7 +208,6 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) | |||
180 | } | 208 | } |
181 | 209 | ||
182 | kfree(sads); | 210 | kfree(sads); |
183 | kfree(sadb); | ||
184 | } | 211 | } |
185 | 212 | ||
186 | static int dce6_audio_chipset_supported(struct radeon_device *rdev) | 213 | static int dce6_audio_chipset_supported(struct radeon_device *rdev) |