Subversion Repositories Kolibri OS

Rev

Rev 5271 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5271 Rev 6104
Line 21... Line 21...
21
 *
21
 *
22
 */
22
 */
23
#include 
23
#include 
24
#include 
24
#include 
25
#include "radeon.h"
25
#include "radeon.h"
-
 
26
#include "radeon_audio.h"
26
#include "sid.h"
27
#include "sid.h"
Line -... Line 28...
-
 
28
 
-
 
29
#define DCE8_DCCG_AUDIO_DTO1_PHASE	0x05b8
-
 
30
#define DCE8_DCCG_AUDIO_DTO1_MODULE	0x05bc
27
 
31
 
28
static u32 dce6_endpoint_rreg(struct radeon_device *rdev,
32
u32 dce6_endpoint_rreg(struct radeon_device *rdev,
29
			      u32 block_offset, u32 reg)
33
			      u32 block_offset, u32 reg)
30
{
34
{
31
	unsigned long flags;
35
	unsigned long flags;
Line 37... Line 41...
37
	spin_unlock_irqrestore(&rdev->end_idx_lock, flags);
41
	spin_unlock_irqrestore(&rdev->end_idx_lock, flags);
Line 38... Line 42...
38
 
42
 
39
	return r;
43
	return r;
Line 40... Line 44...
40
}
44
}
41
 
45
 
42
static void dce6_endpoint_wreg(struct radeon_device *rdev,
46
void dce6_endpoint_wreg(struct radeon_device *rdev,
43
			       u32 block_offset, u32 reg, u32 v)
47
			       u32 block_offset, u32 reg, u32 v)
Line 44... Line 48...
44
{
48
{
Line 52... Line 56...
52
		       AZ_ENDPOINT_REG_WRITE_EN | AZ_ENDPOINT_REG_INDEX(reg));
56
		       AZ_ENDPOINT_REG_WRITE_EN | AZ_ENDPOINT_REG_INDEX(reg));
53
	WREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset, v);
57
	WREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset, v);
54
	spin_unlock_irqrestore(&rdev->end_idx_lock, flags);
58
	spin_unlock_irqrestore(&rdev->end_idx_lock, flags);
55
}
59
}
Line 56... Line -...
56
 
-
 
57
#define RREG32_ENDPOINT(block, reg) dce6_endpoint_rreg(rdev, (block), (reg))
-
 
58
#define WREG32_ENDPOINT(block, reg, v) dce6_endpoint_wreg(rdev, (block), (reg), (v))
-
 
59
 
-
 
60
 
60
 
61
static void dce6_afmt_get_connected_pins(struct radeon_device *rdev)
61
static void dce6_afmt_get_connected_pins(struct radeon_device *rdev)
62
{
62
{
63
	int i;
63
	int i;
Line 74... Line 74...
74
	}
74
	}
75
}
75
}
Line 76... Line 76...
76
 
76
 
77
struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev)
77
struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev)
-
 
78
{
-
 
79
	struct drm_encoder *encoder;
-
 
80
	struct radeon_encoder *radeon_encoder;
-
 
81
	struct radeon_encoder_atom_dig *dig;
78
{
82
	struct r600_audio_pin *pin = NULL;
Line 79... Line 83...
79
	int i;
83
	int i, pin_count;
Line 80... Line 84...
80
 
84
 
81
	dce6_afmt_get_connected_pins(rdev);
85
	dce6_afmt_get_connected_pins(rdev);
82
 
86
 
-
 
87
	for (i = 0; i < rdev->audio.num_pins; i++) {
-
 
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);
83
	for (i = 0; i < rdev->audio.num_pins; i++) {
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;
84
		if (rdev->audio.pin[i].connected)
103
		}
85
			return &rdev->audio.pin[i];
104
	}
86
	}
105
	if (!pin)
Line 87... Line 106...
87
	DRM_ERROR("No connected audio pins found!\n");
106
		DRM_ERROR("No connected audio pins found!\n");
88
	return NULL;
107
	return pin;
89
}
108
}
90
 
109
 
91
void dce6_afmt_select_pin(struct drm_encoder *encoder)
110
void dce6_afmt_select_pin(struct drm_encoder *encoder)
92
{
-
 
Line 93... Line 111...
93
	struct radeon_device *rdev = encoder->dev->dev_private;
111
{
94
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
112
	struct radeon_device *rdev = encoder->dev->dev_private;
Line 95... Line -...
95
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-
 
96
	u32 offset;
-
 
97
 
113
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
98
	if (!dig || !dig->afmt || !dig->afmt->pin)
114
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
99
		return;
115
 
Line 100... Line 116...
100
 
116
	if (!dig || !dig->afmt || !dig->pin)
-
 
117
		return;
101
	offset = dig->afmt->offset;
118
 
102
 
119
	WREG32(AFMT_AUDIO_SRC_CONTROL +  dig->afmt->offset,
103
	WREG32(AFMT_AUDIO_SRC_CONTROL + offset,
120
	       AFMT_AUDIO_SRC_SELECT(dig->pin->id));
104
	       AFMT_AUDIO_SRC_SELECT(dig->afmt->pin->id));
121
}
105
}
122
 
106
 
-
 
107
void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
-
 
108
				    struct drm_display_mode *mode)
123
void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
109
{
-
 
110
	struct radeon_device *rdev = encoder->dev->dev_private;
-
 
111
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-
 
112
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-
 
113
	struct drm_connector *connector;
-
 
114
	struct radeon_connector *radeon_connector = NULL;
-
 
115
	u32 tmp = 0, offset;
-
 
116
 
-
 
117
	if (!dig || !dig->afmt || !dig->afmt->pin)
-
 
118
		return;
-
 
119
 
-
 
120
	offset = dig->afmt->pin->offset;
-
 
Line 121... Line 124...
121
 
124
				    struct drm_connector *connector,
122
	list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
-
 
123
		if (connector->encoder == encoder) {
125
				    struct drm_display_mode *mode)
124
			radeon_connector = to_radeon_connector(connector);
-
 
Line 125... Line 126...
125
			break;
126
{
126
		}
127
	struct radeon_device *rdev = encoder->dev->dev_private;
127
	}
128
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
128
 
129
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
Line 142... Line 143...
142
			tmp = VIDEO_LIPSYNC(connector->video_latency[0]) |
143
			tmp = VIDEO_LIPSYNC(connector->video_latency[0]) |
143
				AUDIO_LIPSYNC(connector->audio_latency[0]);
144
				AUDIO_LIPSYNC(connector->audio_latency[0]);
144
		else
145
		else
145
			tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0);
146
			tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0);
146
	}
147
	}
-
 
148
	WREG32_ENDPOINT(dig->pin->offset,
147
	WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp);
149
			AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp);
148
}
150
}
Line 149... Line 151...
149
 
151
 
-
 
152
void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
150
void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
153
					     u8 *sadb, int sad_count)
151
{
154
{
152
	struct radeon_device *rdev = encoder->dev->dev_private;
155
	struct radeon_device *rdev = encoder->dev->dev_private;
153
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
156
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
154
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-
 
155
	struct drm_connector *connector;
-
 
156
	struct radeon_connector *radeon_connector = NULL;
157
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
157
	u32 offset, tmp;
-
 
158
	u8 *sadb = NULL;
-
 
Line 159... Line 158...
159
	int sad_count;
158
	u32 tmp;
160
 
159
 
Line 161... Line -...
161
	if (!dig || !dig->afmt || !dig->afmt->pin)
-
 
162
		return;
-
 
163
 
-
 
164
	offset = dig->afmt->pin->offset;
-
 
165
 
-
 
166
	list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
-
 
167
		if (connector->encoder == encoder) {
-
 
168
			radeon_connector = to_radeon_connector(connector);
-
 
169
			break;
-
 
170
		}
-
 
171
	}
-
 
172
 
-
 
173
	if (!radeon_connector) {
-
 
174
		DRM_ERROR("Couldn't find encoder's connector\n");
-
 
175
		return;
-
 
176
	}
-
 
177
 
-
 
178
	sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb);
-
 
179
	if (sad_count < 0) {
-
 
180
		DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
-
 
181
		sad_count = 0;
160
	if (!dig || !dig->afmt || !dig->pin)
-
 
161
		return;
182
	}
162
 
183
 
163
	/* program the speaker allocation */
184
	/* program the speaker allocation */
164
	tmp = RREG32_ENDPOINT(dig->pin->offset,
185
	tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
165
			      AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
186
	tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK);
166
	tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK);
187
	/* set HDMI mode */
167
	/* set HDMI mode */
188
	tmp |= HDMI_CONNECTION;
168
	tmp |= HDMI_CONNECTION;
189
	if (sad_count)
169
	if (sad_count)
-
 
170
		tmp |= SPEAKER_ALLOCATION(sadb[0]);
190
		tmp |= SPEAKER_ALLOCATION(sadb[0]);
171
	else
191
	else
-
 
192
		tmp |= SPEAKER_ALLOCATION(5); /* stereo */
-
 
193
	WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
172
		tmp |= SPEAKER_ALLOCATION(5); /* stereo */
Line 194... Line 173...
194
 
173
	WREG32_ENDPOINT(dig->pin->offset,
-
 
174
			AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
195
	kfree(sadb);
175
}
196
}
176
 
197
 
177
void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,
198
void dce6_afmt_write_sad_regs(struct drm_encoder *encoder)
178
					   u8 *sadb, int sad_count)
199
{
179
{
-
 
180
	struct radeon_device *rdev = encoder->dev->dev_private;
200
	struct radeon_device *rdev = encoder->dev->dev_private;
181
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
201
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-
 
202
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-
 
203
	u32 offset;
182
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
Line -... Line 183...
-
 
183
	u32 tmp;
-
 
184
 
-
 
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
	struct drm_connector *connector;
204
{
205
	struct radeon_connector *radeon_connector = NULL;
205
	int i;
206
	struct cea_sad *sads;
206
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
207
	int i, sad_count;
207
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
208
 
208
	struct radeon_device *rdev = encoder->dev->dev_private;
Line 219... Line 219...
219
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR10, HDMI_AUDIO_CODING_TYPE_DTS_HD },
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 },
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 },
221
		{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO },
222
	};
222
	};
Line 223... Line 223...
223
 
223
 
224
	if (!dig || !dig->afmt || !dig->afmt->pin)
224
	if (!dig || !dig->afmt || !dig->pin)
Line 225... Line -...
225
		return;
-
 
226
 
-
 
227
	offset = dig->afmt->pin->offset;
-
 
228
 
-
 
229
	list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
-
 
230
		if (connector->encoder == encoder) {
-
 
231
			radeon_connector = to_radeon_connector(connector);
-
 
232
			break;
-
 
233
		}
-
 
234
	}
-
 
235
 
-
 
236
	if (!radeon_connector) {
-
 
237
		DRM_ERROR("Couldn't find encoder's connector\n");
-
 
238
		return;
-
 
239
	}
-
 
240
 
-
 
241
	sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads);
-
 
242
	if (sad_count <= 0) {
-
 
243
		DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
-
 
244
		return;
-
 
245
	}
-
 
246
	BUG_ON(!sads);
225
		return;
247
 
226
 
248
	for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) {
227
	for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) {
249
		u32 value = 0;
228
		u32 value = 0;
250
		u8 stereo_freqs = 0;
229
		u8 stereo_freqs = 0;
Line 269... Line 248...
269
			}
248
			}
270
		}
249
		}
Line 271... Line 250...
271
 
250
 
Line 272... Line 251...
272
		value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs);
251
		value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs);
273
 
-
 
274
		WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value);
-
 
275
	}
-
 
276
 
252
 
277
	kfree(sads);
-
 
278
}
-
 
279
 
-
 
280
static int dce6_audio_chipset_supported(struct radeon_device *rdev)
-
 
281
{
253
		WREG32_ENDPOINT(dig->pin->offset, eld_reg_to_type[i][0], value);
Line 282... Line 254...
282
	return !ASIC_IS_NODCE(rdev);
254
	}
283
}
255
}
284
 
256
 
Line 291... Line 263...
291
 
263
 
292
	WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
264
	WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
293
			enable_mask ? AUDIO_ENABLED : 0);
265
			enable_mask ? AUDIO_ENABLED : 0);
Line 294... Line 266...
294
}
266
}
295
 
-
 
296
static const u32 pin_offsets[7] =
-
 
297
{
-
 
298
	(0x5e00 - 0x5e00),
-
 
299
	(0x5e18 - 0x5e00),
-
 
300
	(0x5e30 - 0x5e00),
-
 
301
	(0x5e48 - 0x5e00),
-
 
302
	(0x5e60 - 0x5e00),
-
 
303
	(0x5e78 - 0x5e00),
-
 
304
	(0x5e90 - 0x5e00),
-
 
305
};
267
 
306
 
268
void dce6_hdmi_audio_set_dto(struct radeon_device *rdev,
307
int dce6_audio_init(struct radeon_device *rdev)
-
 
308
{
-
 
309
	int i;
269
			     struct radeon_crtc *crtc, unsigned int clock)
310
 
270
{
Line -... Line 271...
-
 
271
	/* Two dtos; generally use dto0 for HDMI */
311
	if (!radeon_audio || !dce6_audio_chipset_supported(rdev))
272
	u32 value = 0;
Line 312... Line -...
312
		return 0;
-
 
313
 
-
 
314
	rdev->audio.enabled = true;
-
 
315
 
-
 
316
	if (ASIC_IS_DCE81(rdev)) /* KV: 4 streams, 7 endpoints */
-
 
317
		rdev->audio.num_pins = 7;
-
 
318
	else if (ASIC_IS_DCE83(rdev)) /* KB: 2 streams, 3 endpoints */
-
 
319
		rdev->audio.num_pins = 3;
-
 
320
	else if (ASIC_IS_DCE8(rdev)) /* BN/HW: 6 streams, 7 endpoints */
-
 
321
		rdev->audio.num_pins = 7;
-
 
322
	else if (ASIC_IS_DCE61(rdev)) /* TN: 4 streams, 6 endpoints */
273
 
323
		rdev->audio.num_pins = 6;
-
 
Line 324... Line 274...
324
	else if (ASIC_IS_DCE64(rdev)) /* OL: 2 streams, 2 endpoints */
274
	if (crtc)
325
		rdev->audio.num_pins = 2;
-
 
326
	else /* SI: 6 streams, 6 endpoints */
-
 
327
		rdev->audio.num_pins = 6;
-
 
328
 
-
 
329
	for (i = 0; i < rdev->audio.num_pins; i++) {
-
 
330
		rdev->audio.pin[i].channels = -1;
-
 
331
		rdev->audio.pin[i].rate = -1;
-
 
332
		rdev->audio.pin[i].bits_per_sample = -1;
-
 
333
		rdev->audio.pin[i].status_bits = 0;
275
		value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
334
		rdev->audio.pin[i].category_code = 0;
276
 
335
		rdev->audio.pin[i].connected = false;
277
	WREG32(DCCG_AUDIO_DTO_SOURCE, value);
336
		rdev->audio.pin[i].offset = pin_offsets[i];
-
 
337
		rdev->audio.pin[i].id = i;
278
 
-
 
279
	/* Express [24MHz / target pixel clock] as an exact rational
338
		/* disable audio.  it will be set up later */
280
	 * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
Line 339... Line 281...
339
		dce6_audio_enable(rdev, &rdev->audio.pin[i], false);
281
	 * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
-
 
282
	 */
340
	}
283
	WREG32(DCCG_AUDIO_DTO0_PHASE, 24000);
-
 
284
	WREG32(DCCG_AUDIO_DTO0_MODULE, clock);
341
 
285
}
-
 
286
 
Line 342... Line -...
342
	return 0;
-
 
343
}
287
void dce6_dp_audio_set_dto(struct radeon_device *rdev,
-
 
288
			   struct radeon_crtc *crtc, unsigned int clock)
Line 344... Line -...
344
 
-
 
345
void dce6_audio_fini(struct radeon_device *rdev)
289
{
Line -... Line 290...
-
 
290
	/* Two dtos; generally use dto1 for DP */
-
 
291
	u32 value = 0;
-
 
292
	value |= DCCG_AUDIO_DTO_SEL;
-
 
293
 
346
{
294
	if (crtc)
-
 
295
		value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
-
 
296
 
-
 
297
	WREG32(DCCG_AUDIO_DTO_SOURCE, value);
-
 
298
 
-
 
299
	/* Express [24MHz / target pixel clock] as an exact rational
-
 
300
	 * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
347
	int i;
301
	 * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator