Subversion Repositories Kolibri OS

Rev

Rev 5271 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5078 serge 1
/*
2
 * Copyright 2013 Advanced Micro Devices, Inc.
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
 * OTHER DEALINGS IN THE SOFTWARE.
21
 *
22
 */
23
#include 
24
#include 
25
#include "radeon.h"
6104 serge 26
#include "radeon_audio.h"
5078 serge 27
#include "sid.h"
28
 
6104 serge 29
#define DCE8_DCCG_AUDIO_DTO1_PHASE	0x05b8
30
#define DCE8_DCCG_AUDIO_DTO1_MODULE	0x05bc
31
 
32
u32 dce6_endpoint_rreg(struct radeon_device *rdev,
5078 serge 33
			      u32 block_offset, u32 reg)
34
{
35
	unsigned long flags;
36
	u32 r;
37
 
38
	spin_lock_irqsave(&rdev->end_idx_lock, flags);
39
	WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
40
	r = RREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset);
41
	spin_unlock_irqrestore(&rdev->end_idx_lock, flags);
42
 
43
	return r;
44
}
45
 
6104 serge 46
void dce6_endpoint_wreg(struct radeon_device *rdev,
5078 serge 47
			       u32 block_offset, u32 reg, u32 v)
48
{
49
	unsigned long flags;
50
 
51
	spin_lock_irqsave(&rdev->end_idx_lock, flags);
52
	if (ASIC_IS_DCE8(rdev))
53
		WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
54
	else
55
		WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset,
56
		       AZ_ENDPOINT_REG_WRITE_EN | AZ_ENDPOINT_REG_INDEX(reg));
57
	WREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset, v);
58
	spin_unlock_irqrestore(&rdev->end_idx_lock, flags);
59
}
60
 
61
static void dce6_afmt_get_connected_pins(struct radeon_device *rdev)
62
{
63
	int i;
64
	u32 offset, tmp;
65
 
66
	for (i = 0; i < rdev->audio.num_pins; i++) {
67
		offset = rdev->audio.pin[i].offset;
68
		tmp = RREG32_ENDPOINT(offset,
69
				      AZ_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT);
70
		if (((tmp & PORT_CONNECTIVITY_MASK) >> PORT_CONNECTIVITY_SHIFT) == 1)
71
			rdev->audio.pin[i].connected = false;
72
		else
73
			rdev->audio.pin[i].connected = true;
74
	}
75
}
76
 
77
struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev)
78
{
6104 serge 79
	struct drm_encoder *encoder;
80
	struct radeon_encoder *radeon_encoder;
81
	struct radeon_encoder_atom_dig *dig;
82
	struct r600_audio_pin *pin = NULL;
83
	int i, pin_count;
5078 serge 84
 
85
	dce6_afmt_get_connected_pins(rdev);
86
 
87
	for (i = 0; i < rdev->audio.num_pins; i++) {
6104 serge 88
		if (rdev->audio.pin[i].connected) {
89
			pin = &rdev->audio.pin[i];
90
			pin_count = 0;
91
 
92
			list_for_each_entry(encoder, &rdev->ddev->mode_config.encoder_list, head) {
93
				if (radeon_encoder_is_digital(encoder)) {
94
					radeon_encoder = to_radeon_encoder(encoder);
95
					dig = radeon_encoder->enc_priv;
96
					if (dig->pin == pin)
97
						pin_count++;
98
				}
99
			}
100
 
101
			if (pin_count == 0)
102
				return pin;
103
		}
5078 serge 104
	}
6104 serge 105
	if (!pin)
106
		DRM_ERROR("No connected audio pins found!\n");
107
	return pin;
5078 serge 108
}
109
 
110
void dce6_afmt_select_pin(struct drm_encoder *encoder)
111
{
112
	struct radeon_device *rdev = encoder->dev->dev_private;
113
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
114
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
115
 
6104 serge 116
	if (!dig || !dig->afmt || !dig->pin)
5078 serge 117
		return;
118
 
6104 serge 119
	WREG32(AFMT_AUDIO_SRC_CONTROL +  dig->afmt->offset,
120
	       AFMT_AUDIO_SRC_SELECT(dig->pin->id));
5078 serge 121
}
122
 
123
void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
6104 serge 124
				    struct drm_connector *connector,
5078 serge 125
				    struct drm_display_mode *mode)
126
{
127
	struct radeon_device *rdev = encoder->dev->dev_private;
128
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
129
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
6104 serge 130
	u32 tmp = 0;
5078 serge 131
 
6104 serge 132
	if (!dig || !dig->afmt || !dig->pin)
5078 serge 133
		return;
134
 
135
	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
136
		if (connector->latency_present[1])
137
			tmp = VIDEO_LIPSYNC(connector->video_latency[1]) |
138
				AUDIO_LIPSYNC(connector->audio_latency[1]);
139
		else
140
			tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0);
141
	} else {
142
		if (connector->latency_present[0])
143
			tmp = VIDEO_LIPSYNC(connector->video_latency[0]) |
144
				AUDIO_LIPSYNC(connector->audio_latency[0]);
145
		else
146
			tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0);
147
	}
6104 serge 148
	WREG32_ENDPOINT(dig->pin->offset,
149
			AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp);
5078 serge 150
}
151
 
6104 serge 152
void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
153
					     u8 *sadb, int sad_count)
5078 serge 154
{
155
	struct radeon_device *rdev = encoder->dev->dev_private;
156
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
157
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
6104 serge 158
	u32 tmp;
5078 serge 159
 
6104 serge 160
	if (!dig || !dig->afmt || !dig->pin)
5078 serge 161
		return;
162
 
163
	/* program the speaker allocation */
6104 serge 164
	tmp = RREG32_ENDPOINT(dig->pin->offset,
165
			      AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
5078 serge 166
	tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK);
167
	/* set HDMI mode */
168
	tmp |= HDMI_CONNECTION;
169
	if (sad_count)
170
		tmp |= SPEAKER_ALLOCATION(sadb[0]);
171
	else
172
		tmp |= SPEAKER_ALLOCATION(5); /* stereo */
6104 serge 173
	WREG32_ENDPOINT(dig->pin->offset,
174
			AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
5078 serge 175
}
176
 
6104 serge 177
void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,
178
					   u8 *sadb, int sad_count)
5078 serge 179
{
180
	struct radeon_device *rdev = encoder->dev->dev_private;
181
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
182
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
6104 serge 183
	u32 tmp;
5078 serge 184
 
6104 serge 185
	if (!dig || !dig->afmt || !dig->pin)
186
		return;
187
 
188
	/* program the speaker allocation */
189
	tmp = RREG32_ENDPOINT(dig->pin->offset,
190
			      AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
191
	tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK);
192
	/* set DP mode */
193
	tmp |= DP_CONNECTION;
194
	if (sad_count)
195
		tmp |= SPEAKER_ALLOCATION(sadb[0]);
196
	else
197
		tmp |= SPEAKER_ALLOCATION(5); /* stereo */
198
	WREG32_ENDPOINT(dig->pin->offset,
199
			AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
200
}
201
 
202
void dce6_afmt_write_sad_regs(struct drm_encoder *encoder,
203
			      struct cea_sad *sads, int sad_count)
204
{
205
	int i;
206
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
207
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
208
	struct radeon_device *rdev = encoder->dev->dev_private;
5078 serge 209
	static const u16 eld_reg_to_type[][2] = {
210
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM },
211
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 },
212
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR2, HDMI_AUDIO_CODING_TYPE_MPEG1 },
213
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR3, HDMI_AUDIO_CODING_TYPE_MP3 },
214
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR4, HDMI_AUDIO_CODING_TYPE_MPEG2 },
215
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR5, HDMI_AUDIO_CODING_TYPE_AAC_LC },
216
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR6, HDMI_AUDIO_CODING_TYPE_DTS },
217
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR7, HDMI_AUDIO_CODING_TYPE_ATRAC },
218
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR9, HDMI_AUDIO_CODING_TYPE_EAC3 },
219
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR10, HDMI_AUDIO_CODING_TYPE_DTS_HD },
220
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR11, HDMI_AUDIO_CODING_TYPE_MLP },
221
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO },
222
	};
223
 
6104 serge 224
	if (!dig || !dig->afmt || !dig->pin)
5078 serge 225
		return;
226
 
227
	for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) {
228
		u32 value = 0;
229
		u8 stereo_freqs = 0;
230
		int max_channels = -1;
231
		int j;
232
 
233
		for (j = 0; j < sad_count; j++) {
234
			struct cea_sad *sad = &sads[j];
235
 
236
			if (sad->format == eld_reg_to_type[i][1]) {
237
				if (sad->channels > max_channels) {
238
					value = MAX_CHANNELS(sad->channels) |
239
						DESCRIPTOR_BYTE_2(sad->byte2) |
240
						SUPPORTED_FREQUENCIES(sad->freq);
241
					max_channels = sad->channels;
242
				}
243
 
244
				if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM)
245
					stereo_freqs |= sad->freq;
246
				else
247
					break;
248
			}
249
		}
250
 
251
		value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs);
252
 
6104 serge 253
		WREG32_ENDPOINT(dig->pin->offset, eld_reg_to_type[i][0], value);
5078 serge 254
	}
255
}
256
 
257
void dce6_audio_enable(struct radeon_device *rdev,
258
		       struct r600_audio_pin *pin,
5271 serge 259
		       u8 enable_mask)
5078 serge 260
{
261
	if (!pin)
262
		return;
263
 
5271 serge 264
	WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
265
			enable_mask ? AUDIO_ENABLED : 0);
5078 serge 266
}
267
 
6104 serge 268
void dce6_hdmi_audio_set_dto(struct radeon_device *rdev,
269
			     struct radeon_crtc *crtc, unsigned int clock)
5078 serge 270
{
6104 serge 271
	/* Two dtos; generally use dto0 for HDMI */
272
	u32 value = 0;
5078 serge 273
 
6104 serge 274
	if (crtc)
275
		value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
5078 serge 276
 
6104 serge 277
	WREG32(DCCG_AUDIO_DTO_SOURCE, value);
5078 serge 278
 
6104 serge 279
	/* Express [24MHz / target pixel clock] as an exact rational
280
	 * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
281
	 * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
282
	 */
283
	WREG32(DCCG_AUDIO_DTO0_PHASE, 24000);
284
	WREG32(DCCG_AUDIO_DTO0_MODULE, clock);
5078 serge 285
}
286
 
6104 serge 287
void dce6_dp_audio_set_dto(struct radeon_device *rdev,
288
			   struct radeon_crtc *crtc, unsigned int clock)
5078 serge 289
{
6104 serge 290
	/* Two dtos; generally use dto1 for DP */
291
	u32 value = 0;
292
	value |= DCCG_AUDIO_DTO_SEL;
5078 serge 293
 
6104 serge 294
	if (crtc)
295
		value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
5078 serge 296
 
6104 serge 297
	WREG32(DCCG_AUDIO_DTO_SOURCE, value);
5078 serge 298
 
6104 serge 299
	/* Express [24MHz / target pixel clock] as an exact rational
300
	 * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
301
	 * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
302
	 */
303
	if (ASIC_IS_DCE8(rdev)) {
304
		WREG32(DCE8_DCCG_AUDIO_DTO1_PHASE, 24000);
305
		WREG32(DCE8_DCCG_AUDIO_DTO1_MODULE, clock);
306
	} else {
307
		WREG32(DCCG_AUDIO_DTO1_PHASE, 24000);
308
		WREG32(DCCG_AUDIO_DTO1_MODULE, clock);
309
	}
5078 serge 310
}