xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/radeon/radeon_audio.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2014 Advanced Micro Devices, Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a
5*4882a593Smuzhiyun  * copy of this software and associated documentation files (the "Software"),
6*4882a593Smuzhiyun  * to deal in the Software without restriction, including without limitation
7*4882a593Smuzhiyun  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*4882a593Smuzhiyun  * and/or sell copies of the Software, and to permit persons to whom the
9*4882a593Smuzhiyun  * Software is furnished to do so, subject to the following conditions:
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * The above copyright notice and this permission notice shall be included in
12*4882a593Smuzhiyun  * all copies or substantial portions of the Software.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*4882a593Smuzhiyun  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17*4882a593Smuzhiyun  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*4882a593Smuzhiyun  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*4882a593Smuzhiyun  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*4882a593Smuzhiyun  * OTHER DEALINGS IN THE SOFTWARE.
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  * Authors: Slava Grigorev <slava.grigorev@amd.com>
23*4882a593Smuzhiyun  */
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #include <linux/gcd.h>
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #include <drm/drm_crtc.h>
28*4882a593Smuzhiyun #include "radeon.h"
29*4882a593Smuzhiyun #include "atom.h"
30*4882a593Smuzhiyun #include "radeon_audio.h"
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun void r600_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin,
33*4882a593Smuzhiyun 		u8 enable_mask);
34*4882a593Smuzhiyun void dce4_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin,
35*4882a593Smuzhiyun 		u8 enable_mask);
36*4882a593Smuzhiyun void dce6_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin,
37*4882a593Smuzhiyun 		u8 enable_mask);
38*4882a593Smuzhiyun u32 dce6_endpoint_rreg(struct radeon_device *rdev, u32 offset, u32 reg);
39*4882a593Smuzhiyun void dce6_endpoint_wreg(struct radeon_device *rdev,
40*4882a593Smuzhiyun 		u32 offset, u32 reg, u32 v);
41*4882a593Smuzhiyun void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder,
42*4882a593Smuzhiyun 		struct cea_sad *sads, int sad_count);
43*4882a593Smuzhiyun void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder,
44*4882a593Smuzhiyun 		struct cea_sad *sads, int sad_count);
45*4882a593Smuzhiyun void dce6_afmt_write_sad_regs(struct drm_encoder *encoder,
46*4882a593Smuzhiyun 		struct cea_sad *sads, int sad_count);
47*4882a593Smuzhiyun void dce3_2_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
48*4882a593Smuzhiyun 		u8 *sadb, int sad_count);
49*4882a593Smuzhiyun void dce3_2_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,
50*4882a593Smuzhiyun 		u8 *sadb, int sad_count);
51*4882a593Smuzhiyun void dce4_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
52*4882a593Smuzhiyun 		u8 *sadb, int sad_count);
53*4882a593Smuzhiyun void dce4_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,
54*4882a593Smuzhiyun 		u8 *sadb, int sad_count);
55*4882a593Smuzhiyun void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
56*4882a593Smuzhiyun 		u8 *sadb, int sad_count);
57*4882a593Smuzhiyun void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,
58*4882a593Smuzhiyun 		u8 *sadb, int sad_count);
59*4882a593Smuzhiyun void dce4_afmt_write_latency_fields(struct drm_encoder *encoder,
60*4882a593Smuzhiyun 		struct drm_connector *connector, struct drm_display_mode *mode);
61*4882a593Smuzhiyun void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
62*4882a593Smuzhiyun 		struct drm_connector *connector, struct drm_display_mode *mode);
63*4882a593Smuzhiyun struct r600_audio_pin* r600_audio_get_pin(struct radeon_device *rdev);
64*4882a593Smuzhiyun struct r600_audio_pin* dce6_audio_get_pin(struct radeon_device *rdev);
65*4882a593Smuzhiyun void dce6_afmt_select_pin(struct drm_encoder *encoder);
66*4882a593Smuzhiyun void r600_hdmi_audio_set_dto(struct radeon_device *rdev,
67*4882a593Smuzhiyun 	struct radeon_crtc *crtc, unsigned int clock);
68*4882a593Smuzhiyun void dce3_2_audio_set_dto(struct radeon_device *rdev,
69*4882a593Smuzhiyun 	struct radeon_crtc *crtc, unsigned int clock);
70*4882a593Smuzhiyun void dce4_hdmi_audio_set_dto(struct radeon_device *rdev,
71*4882a593Smuzhiyun 	struct radeon_crtc *crtc, unsigned int clock);
72*4882a593Smuzhiyun void dce4_dp_audio_set_dto(struct radeon_device *rdev,
73*4882a593Smuzhiyun 	struct radeon_crtc *crtc, unsigned int clock);
74*4882a593Smuzhiyun void dce6_hdmi_audio_set_dto(struct radeon_device *rdev,
75*4882a593Smuzhiyun 	struct radeon_crtc *crtc, unsigned int clock);
76*4882a593Smuzhiyun void dce6_dp_audio_set_dto(struct radeon_device *rdev,
77*4882a593Smuzhiyun 	struct radeon_crtc *crtc, unsigned int clock);
78*4882a593Smuzhiyun void r600_set_avi_packet(struct radeon_device *rdev, u32 offset,
79*4882a593Smuzhiyun 	unsigned char *buffer, size_t size);
80*4882a593Smuzhiyun void evergreen_set_avi_packet(struct radeon_device *rdev, u32 offset,
81*4882a593Smuzhiyun 	unsigned char *buffer, size_t size);
82*4882a593Smuzhiyun void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset,
83*4882a593Smuzhiyun 	const struct radeon_hdmi_acr *acr);
84*4882a593Smuzhiyun void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset,
85*4882a593Smuzhiyun 	const struct radeon_hdmi_acr *acr);
86*4882a593Smuzhiyun void evergreen_hdmi_update_acr(struct drm_encoder *encoder, long offset,
87*4882a593Smuzhiyun 	const struct radeon_hdmi_acr *acr);
88*4882a593Smuzhiyun void r600_set_vbi_packet(struct drm_encoder *encoder, u32 offset);
89*4882a593Smuzhiyun void dce4_set_vbi_packet(struct drm_encoder *encoder, u32 offset);
90*4882a593Smuzhiyun void dce4_hdmi_set_color_depth(struct drm_encoder *encoder,
91*4882a593Smuzhiyun 	u32 offset, int bpc);
92*4882a593Smuzhiyun void r600_set_audio_packet(struct drm_encoder *encoder, u32 offset);
93*4882a593Smuzhiyun void dce3_2_set_audio_packet(struct drm_encoder *encoder, u32 offset);
94*4882a593Smuzhiyun void dce4_set_audio_packet(struct drm_encoder *encoder, u32 offset);
95*4882a593Smuzhiyun void r600_set_mute(struct drm_encoder *encoder, u32 offset, bool mute);
96*4882a593Smuzhiyun void dce3_2_set_mute(struct drm_encoder *encoder, u32 offset, bool mute);
97*4882a593Smuzhiyun void dce4_set_mute(struct drm_encoder *encoder, u32 offset, bool mute);
98*4882a593Smuzhiyun static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder,
99*4882a593Smuzhiyun 	struct drm_display_mode *mode);
100*4882a593Smuzhiyun static void radeon_audio_dp_mode_set(struct drm_encoder *encoder,
101*4882a593Smuzhiyun 	struct drm_display_mode *mode);
102*4882a593Smuzhiyun void r600_hdmi_enable(struct drm_encoder *encoder, bool enable);
103*4882a593Smuzhiyun void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable);
104*4882a593Smuzhiyun void evergreen_dp_enable(struct drm_encoder *encoder, bool enable);
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun static const u32 pin_offsets[7] =
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun 	(0x5e00 - 0x5e00),
109*4882a593Smuzhiyun 	(0x5e18 - 0x5e00),
110*4882a593Smuzhiyun 	(0x5e30 - 0x5e00),
111*4882a593Smuzhiyun 	(0x5e48 - 0x5e00),
112*4882a593Smuzhiyun 	(0x5e60 - 0x5e00),
113*4882a593Smuzhiyun 	(0x5e78 - 0x5e00),
114*4882a593Smuzhiyun 	(0x5e90 - 0x5e00),
115*4882a593Smuzhiyun };
116*4882a593Smuzhiyun 
radeon_audio_rreg(struct radeon_device * rdev,u32 offset,u32 reg)117*4882a593Smuzhiyun static u32 radeon_audio_rreg(struct radeon_device *rdev, u32 offset, u32 reg)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun 	return RREG32(reg);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun 
radeon_audio_wreg(struct radeon_device * rdev,u32 offset,u32 reg,u32 v)122*4882a593Smuzhiyun static void radeon_audio_wreg(struct radeon_device *rdev, u32 offset,
123*4882a593Smuzhiyun 		u32 reg, u32 v)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun 	WREG32(reg, v);
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun static struct radeon_audio_basic_funcs r600_funcs = {
129*4882a593Smuzhiyun 	.endpoint_rreg = radeon_audio_rreg,
130*4882a593Smuzhiyun 	.endpoint_wreg = radeon_audio_wreg,
131*4882a593Smuzhiyun 	.enable = r600_audio_enable,
132*4882a593Smuzhiyun };
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun static struct radeon_audio_basic_funcs dce32_funcs = {
135*4882a593Smuzhiyun 	.endpoint_rreg = radeon_audio_rreg,
136*4882a593Smuzhiyun 	.endpoint_wreg = radeon_audio_wreg,
137*4882a593Smuzhiyun 	.enable = r600_audio_enable,
138*4882a593Smuzhiyun };
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun static struct radeon_audio_basic_funcs dce4_funcs = {
141*4882a593Smuzhiyun 	.endpoint_rreg = radeon_audio_rreg,
142*4882a593Smuzhiyun 	.endpoint_wreg = radeon_audio_wreg,
143*4882a593Smuzhiyun 	.enable = dce4_audio_enable,
144*4882a593Smuzhiyun };
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun static struct radeon_audio_basic_funcs dce6_funcs = {
147*4882a593Smuzhiyun 	.endpoint_rreg = dce6_endpoint_rreg,
148*4882a593Smuzhiyun 	.endpoint_wreg = dce6_endpoint_wreg,
149*4882a593Smuzhiyun 	.enable = dce6_audio_enable,
150*4882a593Smuzhiyun };
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun static struct radeon_audio_funcs r600_hdmi_funcs = {
153*4882a593Smuzhiyun 	.get_pin = r600_audio_get_pin,
154*4882a593Smuzhiyun 	.set_dto = r600_hdmi_audio_set_dto,
155*4882a593Smuzhiyun 	.update_acr = r600_hdmi_update_acr,
156*4882a593Smuzhiyun 	.set_vbi_packet = r600_set_vbi_packet,
157*4882a593Smuzhiyun 	.set_avi_packet = r600_set_avi_packet,
158*4882a593Smuzhiyun 	.set_audio_packet = r600_set_audio_packet,
159*4882a593Smuzhiyun 	.set_mute = r600_set_mute,
160*4882a593Smuzhiyun 	.mode_set = radeon_audio_hdmi_mode_set,
161*4882a593Smuzhiyun 	.dpms = r600_hdmi_enable,
162*4882a593Smuzhiyun };
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun static struct radeon_audio_funcs dce32_hdmi_funcs = {
165*4882a593Smuzhiyun 	.get_pin = r600_audio_get_pin,
166*4882a593Smuzhiyun 	.write_sad_regs = dce3_2_afmt_write_sad_regs,
167*4882a593Smuzhiyun 	.write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation,
168*4882a593Smuzhiyun 	.set_dto = dce3_2_audio_set_dto,
169*4882a593Smuzhiyun 	.update_acr = dce3_2_hdmi_update_acr,
170*4882a593Smuzhiyun 	.set_vbi_packet = r600_set_vbi_packet,
171*4882a593Smuzhiyun 	.set_avi_packet = r600_set_avi_packet,
172*4882a593Smuzhiyun 	.set_audio_packet = dce3_2_set_audio_packet,
173*4882a593Smuzhiyun 	.set_mute = dce3_2_set_mute,
174*4882a593Smuzhiyun 	.mode_set = radeon_audio_hdmi_mode_set,
175*4882a593Smuzhiyun 	.dpms = r600_hdmi_enable,
176*4882a593Smuzhiyun };
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun static struct radeon_audio_funcs dce32_dp_funcs = {
179*4882a593Smuzhiyun 	.get_pin = r600_audio_get_pin,
180*4882a593Smuzhiyun 	.write_sad_regs = dce3_2_afmt_write_sad_regs,
181*4882a593Smuzhiyun 	.write_speaker_allocation = dce3_2_afmt_dp_write_speaker_allocation,
182*4882a593Smuzhiyun 	.set_dto = dce3_2_audio_set_dto,
183*4882a593Smuzhiyun 	.set_avi_packet = r600_set_avi_packet,
184*4882a593Smuzhiyun 	.set_audio_packet = dce3_2_set_audio_packet,
185*4882a593Smuzhiyun };
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun static struct radeon_audio_funcs dce4_hdmi_funcs = {
188*4882a593Smuzhiyun 	.get_pin = r600_audio_get_pin,
189*4882a593Smuzhiyun 	.write_sad_regs = evergreen_hdmi_write_sad_regs,
190*4882a593Smuzhiyun 	.write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation,
191*4882a593Smuzhiyun 	.write_latency_fields = dce4_afmt_write_latency_fields,
192*4882a593Smuzhiyun 	.set_dto = dce4_hdmi_audio_set_dto,
193*4882a593Smuzhiyun 	.update_acr = evergreen_hdmi_update_acr,
194*4882a593Smuzhiyun 	.set_vbi_packet = dce4_set_vbi_packet,
195*4882a593Smuzhiyun 	.set_color_depth = dce4_hdmi_set_color_depth,
196*4882a593Smuzhiyun 	.set_avi_packet = evergreen_set_avi_packet,
197*4882a593Smuzhiyun 	.set_audio_packet = dce4_set_audio_packet,
198*4882a593Smuzhiyun 	.set_mute = dce4_set_mute,
199*4882a593Smuzhiyun 	.mode_set = radeon_audio_hdmi_mode_set,
200*4882a593Smuzhiyun 	.dpms = evergreen_hdmi_enable,
201*4882a593Smuzhiyun };
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun static struct radeon_audio_funcs dce4_dp_funcs = {
204*4882a593Smuzhiyun 	.get_pin = r600_audio_get_pin,
205*4882a593Smuzhiyun 	.write_sad_regs = evergreen_hdmi_write_sad_regs,
206*4882a593Smuzhiyun 	.write_speaker_allocation = dce4_afmt_dp_write_speaker_allocation,
207*4882a593Smuzhiyun 	.write_latency_fields = dce4_afmt_write_latency_fields,
208*4882a593Smuzhiyun 	.set_dto = dce4_dp_audio_set_dto,
209*4882a593Smuzhiyun 	.set_avi_packet = evergreen_set_avi_packet,
210*4882a593Smuzhiyun 	.set_audio_packet = dce4_set_audio_packet,
211*4882a593Smuzhiyun 	.mode_set = radeon_audio_dp_mode_set,
212*4882a593Smuzhiyun 	.dpms = evergreen_dp_enable,
213*4882a593Smuzhiyun };
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun static struct radeon_audio_funcs dce6_hdmi_funcs = {
216*4882a593Smuzhiyun 	.select_pin = dce6_afmt_select_pin,
217*4882a593Smuzhiyun 	.get_pin = dce6_audio_get_pin,
218*4882a593Smuzhiyun 	.write_sad_regs = dce6_afmt_write_sad_regs,
219*4882a593Smuzhiyun 	.write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation,
220*4882a593Smuzhiyun 	.write_latency_fields = dce6_afmt_write_latency_fields,
221*4882a593Smuzhiyun 	.set_dto = dce6_hdmi_audio_set_dto,
222*4882a593Smuzhiyun 	.update_acr = evergreen_hdmi_update_acr,
223*4882a593Smuzhiyun 	.set_vbi_packet = dce4_set_vbi_packet,
224*4882a593Smuzhiyun 	.set_color_depth = dce4_hdmi_set_color_depth,
225*4882a593Smuzhiyun 	.set_avi_packet = evergreen_set_avi_packet,
226*4882a593Smuzhiyun 	.set_audio_packet = dce4_set_audio_packet,
227*4882a593Smuzhiyun 	.set_mute = dce4_set_mute,
228*4882a593Smuzhiyun 	.mode_set = radeon_audio_hdmi_mode_set,
229*4882a593Smuzhiyun 	.dpms = evergreen_hdmi_enable,
230*4882a593Smuzhiyun };
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun static struct radeon_audio_funcs dce6_dp_funcs = {
233*4882a593Smuzhiyun 	.select_pin = dce6_afmt_select_pin,
234*4882a593Smuzhiyun 	.get_pin = dce6_audio_get_pin,
235*4882a593Smuzhiyun 	.write_sad_regs = dce6_afmt_write_sad_regs,
236*4882a593Smuzhiyun 	.write_speaker_allocation = dce6_afmt_dp_write_speaker_allocation,
237*4882a593Smuzhiyun 	.write_latency_fields = dce6_afmt_write_latency_fields,
238*4882a593Smuzhiyun 	.set_dto = dce6_dp_audio_set_dto,
239*4882a593Smuzhiyun 	.set_avi_packet = evergreen_set_avi_packet,
240*4882a593Smuzhiyun 	.set_audio_packet = dce4_set_audio_packet,
241*4882a593Smuzhiyun 	.mode_set = radeon_audio_dp_mode_set,
242*4882a593Smuzhiyun 	.dpms = evergreen_dp_enable,
243*4882a593Smuzhiyun };
244*4882a593Smuzhiyun 
radeon_audio_enable(struct radeon_device * rdev,struct r600_audio_pin * pin,u8 enable_mask)245*4882a593Smuzhiyun static void radeon_audio_enable(struct radeon_device *rdev,
246*4882a593Smuzhiyun 				struct r600_audio_pin *pin, u8 enable_mask)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun 	struct drm_encoder *encoder;
249*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder;
250*4882a593Smuzhiyun 	struct radeon_encoder_atom_dig *dig;
251*4882a593Smuzhiyun 	int pin_count = 0;
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	if (!pin)
254*4882a593Smuzhiyun 		return;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	if (rdev->mode_info.mode_config_initialized) {
257*4882a593Smuzhiyun 		list_for_each_entry(encoder, &rdev->ddev->mode_config.encoder_list, head) {
258*4882a593Smuzhiyun 			if (radeon_encoder_is_digital(encoder)) {
259*4882a593Smuzhiyun 				radeon_encoder = to_radeon_encoder(encoder);
260*4882a593Smuzhiyun 				dig = radeon_encoder->enc_priv;
261*4882a593Smuzhiyun 				if (dig->pin == pin)
262*4882a593Smuzhiyun 					pin_count++;
263*4882a593Smuzhiyun 			}
264*4882a593Smuzhiyun 		}
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 		if ((pin_count > 1) && (enable_mask == 0))
267*4882a593Smuzhiyun 			return;
268*4882a593Smuzhiyun 	}
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	if (rdev->audio.funcs->enable)
271*4882a593Smuzhiyun 		rdev->audio.funcs->enable(rdev, pin, enable_mask);
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun 
radeon_audio_interface_init(struct radeon_device * rdev)274*4882a593Smuzhiyun static void radeon_audio_interface_init(struct radeon_device *rdev)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun 	if (ASIC_IS_DCE6(rdev)) {
277*4882a593Smuzhiyun 		rdev->audio.funcs = &dce6_funcs;
278*4882a593Smuzhiyun 		rdev->audio.hdmi_funcs = &dce6_hdmi_funcs;
279*4882a593Smuzhiyun 		rdev->audio.dp_funcs = &dce6_dp_funcs;
280*4882a593Smuzhiyun 	} else if (ASIC_IS_DCE4(rdev)) {
281*4882a593Smuzhiyun 		rdev->audio.funcs = &dce4_funcs;
282*4882a593Smuzhiyun 		rdev->audio.hdmi_funcs = &dce4_hdmi_funcs;
283*4882a593Smuzhiyun 		rdev->audio.dp_funcs = &dce4_dp_funcs;
284*4882a593Smuzhiyun 	} else if (ASIC_IS_DCE32(rdev)) {
285*4882a593Smuzhiyun 		rdev->audio.funcs = &dce32_funcs;
286*4882a593Smuzhiyun 		rdev->audio.hdmi_funcs = &dce32_hdmi_funcs;
287*4882a593Smuzhiyun 		rdev->audio.dp_funcs = &dce32_dp_funcs;
288*4882a593Smuzhiyun 	} else {
289*4882a593Smuzhiyun 		rdev->audio.funcs = &r600_funcs;
290*4882a593Smuzhiyun 		rdev->audio.hdmi_funcs = &r600_hdmi_funcs;
291*4882a593Smuzhiyun 		rdev->audio.dp_funcs = NULL;
292*4882a593Smuzhiyun 	}
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun 
radeon_audio_chipset_supported(struct radeon_device * rdev)295*4882a593Smuzhiyun static int radeon_audio_chipset_supported(struct radeon_device *rdev)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun 	return ASIC_IS_DCE2(rdev) && !ASIC_IS_NODCE(rdev);
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun 
radeon_audio_init(struct radeon_device * rdev)300*4882a593Smuzhiyun int radeon_audio_init(struct radeon_device *rdev)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun 	int i;
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	if (!radeon_audio || !radeon_audio_chipset_supported(rdev))
305*4882a593Smuzhiyun 		return 0;
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	rdev->audio.enabled = true;
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	if (ASIC_IS_DCE83(rdev))		/* KB: 2 streams, 3 endpoints */
310*4882a593Smuzhiyun 		rdev->audio.num_pins = 3;
311*4882a593Smuzhiyun 	else if (ASIC_IS_DCE81(rdev))	/* KV: 4 streams, 7 endpoints */
312*4882a593Smuzhiyun 		rdev->audio.num_pins = 7;
313*4882a593Smuzhiyun 	else if (ASIC_IS_DCE8(rdev))	/* BN/HW: 6 streams, 7 endpoints */
314*4882a593Smuzhiyun 		rdev->audio.num_pins = 7;
315*4882a593Smuzhiyun 	else if (ASIC_IS_DCE64(rdev))	/* OL: 2 streams, 2 endpoints */
316*4882a593Smuzhiyun 		rdev->audio.num_pins = 2;
317*4882a593Smuzhiyun 	else if (ASIC_IS_DCE61(rdev))	/* TN: 4 streams, 6 endpoints */
318*4882a593Smuzhiyun 		rdev->audio.num_pins = 6;
319*4882a593Smuzhiyun 	else if (ASIC_IS_DCE6(rdev))	/* SI: 6 streams, 6 endpoints */
320*4882a593Smuzhiyun 		rdev->audio.num_pins = 6;
321*4882a593Smuzhiyun 	else
322*4882a593Smuzhiyun 		rdev->audio.num_pins = 1;
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	for (i = 0; i < rdev->audio.num_pins; i++) {
325*4882a593Smuzhiyun 		rdev->audio.pin[i].channels = -1;
326*4882a593Smuzhiyun 		rdev->audio.pin[i].rate = -1;
327*4882a593Smuzhiyun 		rdev->audio.pin[i].bits_per_sample = -1;
328*4882a593Smuzhiyun 		rdev->audio.pin[i].status_bits = 0;
329*4882a593Smuzhiyun 		rdev->audio.pin[i].category_code = 0;
330*4882a593Smuzhiyun 		rdev->audio.pin[i].connected = false;
331*4882a593Smuzhiyun 		rdev->audio.pin[i].offset = pin_offsets[i];
332*4882a593Smuzhiyun 		rdev->audio.pin[i].id = i;
333*4882a593Smuzhiyun 	}
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	radeon_audio_interface_init(rdev);
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	/* disable audio.  it will be set up later */
338*4882a593Smuzhiyun 	for (i = 0; i < rdev->audio.num_pins; i++)
339*4882a593Smuzhiyun 		radeon_audio_enable(rdev, &rdev->audio.pin[i], 0);
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	return 0;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun 
radeon_audio_endpoint_rreg(struct radeon_device * rdev,u32 offset,u32 reg)344*4882a593Smuzhiyun u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, u32 offset, u32 reg)
345*4882a593Smuzhiyun {
346*4882a593Smuzhiyun 	if (rdev->audio.funcs->endpoint_rreg)
347*4882a593Smuzhiyun 		return rdev->audio.funcs->endpoint_rreg(rdev, offset, reg);
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun 	return 0;
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun 
radeon_audio_endpoint_wreg(struct radeon_device * rdev,u32 offset,u32 reg,u32 v)352*4882a593Smuzhiyun void radeon_audio_endpoint_wreg(struct radeon_device *rdev, u32 offset,
353*4882a593Smuzhiyun 	u32 reg, u32 v)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun 	if (rdev->audio.funcs->endpoint_wreg)
356*4882a593Smuzhiyun 		rdev->audio.funcs->endpoint_wreg(rdev, offset, reg, v);
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun 
radeon_audio_write_sad_regs(struct drm_encoder * encoder)359*4882a593Smuzhiyun static void radeon_audio_write_sad_regs(struct drm_encoder *encoder)
360*4882a593Smuzhiyun {
361*4882a593Smuzhiyun 	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
362*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
363*4882a593Smuzhiyun 	struct cea_sad *sads;
364*4882a593Smuzhiyun 	int sad_count;
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun 	if (!connector)
367*4882a593Smuzhiyun 		return;
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads);
370*4882a593Smuzhiyun 	if (sad_count < 0)
371*4882a593Smuzhiyun 		DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
372*4882a593Smuzhiyun 	if (sad_count <= 0)
373*4882a593Smuzhiyun 		return;
374*4882a593Smuzhiyun 	BUG_ON(!sads);
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	if (radeon_encoder->audio && radeon_encoder->audio->write_sad_regs)
377*4882a593Smuzhiyun 		radeon_encoder->audio->write_sad_regs(encoder, sads, sad_count);
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	kfree(sads);
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun 
radeon_audio_write_speaker_allocation(struct drm_encoder * encoder)382*4882a593Smuzhiyun static void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder)
383*4882a593Smuzhiyun {
384*4882a593Smuzhiyun 	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
385*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
386*4882a593Smuzhiyun 	u8 *sadb = NULL;
387*4882a593Smuzhiyun 	int sad_count;
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	if (!connector)
390*4882a593Smuzhiyun 		return;
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun 	sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector),
393*4882a593Smuzhiyun 						   &sadb);
394*4882a593Smuzhiyun 	if (sad_count < 0) {
395*4882a593Smuzhiyun 		DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n",
396*4882a593Smuzhiyun 			  sad_count);
397*4882a593Smuzhiyun 		sad_count = 0;
398*4882a593Smuzhiyun 	}
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	if (radeon_encoder->audio && radeon_encoder->audio->write_speaker_allocation)
401*4882a593Smuzhiyun 		radeon_encoder->audio->write_speaker_allocation(encoder, sadb, sad_count);
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	kfree(sadb);
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun 
radeon_audio_write_latency_fields(struct drm_encoder * encoder,struct drm_display_mode * mode)406*4882a593Smuzhiyun static void radeon_audio_write_latency_fields(struct drm_encoder *encoder,
407*4882a593Smuzhiyun 					      struct drm_display_mode *mode)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun 	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
410*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	if (!connector)
413*4882a593Smuzhiyun 		return;
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun 	if (radeon_encoder->audio && radeon_encoder->audio->write_latency_fields)
416*4882a593Smuzhiyun 		radeon_encoder->audio->write_latency_fields(encoder, connector, mode);
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun 
radeon_audio_get_pin(struct drm_encoder * encoder)419*4882a593Smuzhiyun struct r600_audio_pin* radeon_audio_get_pin(struct drm_encoder *encoder)
420*4882a593Smuzhiyun {
421*4882a593Smuzhiyun 	struct radeon_device *rdev = encoder->dev->dev_private;
422*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	if (radeon_encoder->audio && radeon_encoder->audio->get_pin)
425*4882a593Smuzhiyun 		return radeon_encoder->audio->get_pin(rdev);
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 	return NULL;
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun 
radeon_audio_select_pin(struct drm_encoder * encoder)430*4882a593Smuzhiyun static void radeon_audio_select_pin(struct drm_encoder *encoder)
431*4882a593Smuzhiyun {
432*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 	if (radeon_encoder->audio && radeon_encoder->audio->select_pin)
435*4882a593Smuzhiyun 		radeon_encoder->audio->select_pin(encoder);
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun 
radeon_audio_detect(struct drm_connector * connector,struct drm_encoder * encoder,enum drm_connector_status status)438*4882a593Smuzhiyun void radeon_audio_detect(struct drm_connector *connector,
439*4882a593Smuzhiyun 			 struct drm_encoder *encoder,
440*4882a593Smuzhiyun 			 enum drm_connector_status status)
441*4882a593Smuzhiyun {
442*4882a593Smuzhiyun 	struct drm_device *dev = connector->dev;
443*4882a593Smuzhiyun 	struct radeon_device *rdev = dev->dev_private;
444*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
445*4882a593Smuzhiyun 	struct radeon_encoder_atom_dig *dig;
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	if (!radeon_audio_chipset_supported(rdev))
448*4882a593Smuzhiyun 		return;
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 	if (!radeon_encoder_is_digital(encoder))
451*4882a593Smuzhiyun 		return;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 	dig = radeon_encoder->enc_priv;
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	if (status == connector_status_connected) {
456*4882a593Smuzhiyun 		if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
457*4882a593Smuzhiyun 			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 			if (radeon_dp_getsinktype(radeon_connector) ==
460*4882a593Smuzhiyun 			    CONNECTOR_OBJECT_ID_DISPLAYPORT)
461*4882a593Smuzhiyun 				radeon_encoder->audio = rdev->audio.dp_funcs;
462*4882a593Smuzhiyun 			else
463*4882a593Smuzhiyun 				radeon_encoder->audio = rdev->audio.hdmi_funcs;
464*4882a593Smuzhiyun 		} else {
465*4882a593Smuzhiyun 			radeon_encoder->audio = rdev->audio.hdmi_funcs;
466*4882a593Smuzhiyun 		}
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 		if (drm_detect_monitor_audio(radeon_connector_edid(connector))) {
469*4882a593Smuzhiyun 			if (!dig->pin)
470*4882a593Smuzhiyun 				dig->pin = radeon_audio_get_pin(encoder);
471*4882a593Smuzhiyun 			radeon_audio_enable(rdev, dig->pin, 0xf);
472*4882a593Smuzhiyun 		} else {
473*4882a593Smuzhiyun 			radeon_audio_enable(rdev, dig->pin, 0);
474*4882a593Smuzhiyun 			dig->pin = NULL;
475*4882a593Smuzhiyun 		}
476*4882a593Smuzhiyun 	} else {
477*4882a593Smuzhiyun 		radeon_audio_enable(rdev, dig->pin, 0);
478*4882a593Smuzhiyun 		dig->pin = NULL;
479*4882a593Smuzhiyun 	}
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun 
radeon_audio_fini(struct radeon_device * rdev)482*4882a593Smuzhiyun void radeon_audio_fini(struct radeon_device *rdev)
483*4882a593Smuzhiyun {
484*4882a593Smuzhiyun 	int i;
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 	if (!rdev->audio.enabled)
487*4882a593Smuzhiyun 		return;
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun 	for (i = 0; i < rdev->audio.num_pins; i++)
490*4882a593Smuzhiyun 		radeon_audio_enable(rdev, &rdev->audio.pin[i], 0);
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	rdev->audio.enabled = false;
493*4882a593Smuzhiyun }
494*4882a593Smuzhiyun 
radeon_audio_set_dto(struct drm_encoder * encoder,unsigned int clock)495*4882a593Smuzhiyun static void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock)
496*4882a593Smuzhiyun {
497*4882a593Smuzhiyun 	struct radeon_device *rdev = encoder->dev->dev_private;
498*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
499*4882a593Smuzhiyun 	struct radeon_crtc *crtc = to_radeon_crtc(encoder->crtc);
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	if (radeon_encoder->audio && radeon_encoder->audio->set_dto)
502*4882a593Smuzhiyun 		radeon_encoder->audio->set_dto(rdev, crtc, clock);
503*4882a593Smuzhiyun }
504*4882a593Smuzhiyun 
radeon_audio_set_avi_packet(struct drm_encoder * encoder,struct drm_display_mode * mode)505*4882a593Smuzhiyun static int radeon_audio_set_avi_packet(struct drm_encoder *encoder,
506*4882a593Smuzhiyun 				       struct drm_display_mode *mode)
507*4882a593Smuzhiyun {
508*4882a593Smuzhiyun 	struct radeon_device *rdev = encoder->dev->dev_private;
509*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
510*4882a593Smuzhiyun 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
511*4882a593Smuzhiyun 	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
512*4882a593Smuzhiyun 	u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
513*4882a593Smuzhiyun 	struct hdmi_avi_infoframe frame;
514*4882a593Smuzhiyun 	int err;
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 	if (!connector)
517*4882a593Smuzhiyun 		return -EINVAL;
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 	err = drm_hdmi_avi_infoframe_from_display_mode(&frame, connector, mode);
520*4882a593Smuzhiyun 	if (err < 0) {
521*4882a593Smuzhiyun 		DRM_ERROR("failed to setup AVI infoframe: %d\n", err);
522*4882a593Smuzhiyun 		return err;
523*4882a593Smuzhiyun 	}
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 	if (radeon_encoder->output_csc != RADEON_OUTPUT_CSC_BYPASS) {
526*4882a593Smuzhiyun 		drm_hdmi_avi_infoframe_quant_range(&frame, connector, mode,
527*4882a593Smuzhiyun 						   radeon_encoder->output_csc == RADEON_OUTPUT_CSC_TVRGB ?
528*4882a593Smuzhiyun 						   HDMI_QUANTIZATION_RANGE_LIMITED :
529*4882a593Smuzhiyun 						   HDMI_QUANTIZATION_RANGE_FULL);
530*4882a593Smuzhiyun 	}
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
533*4882a593Smuzhiyun 	if (err < 0) {
534*4882a593Smuzhiyun 		DRM_ERROR("failed to pack AVI infoframe: %d\n", err);
535*4882a593Smuzhiyun 		return err;
536*4882a593Smuzhiyun 	}
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 	if (dig && dig->afmt && radeon_encoder->audio &&
539*4882a593Smuzhiyun 	    radeon_encoder->audio->set_avi_packet)
540*4882a593Smuzhiyun 		radeon_encoder->audio->set_avi_packet(rdev, dig->afmt->offset,
541*4882a593Smuzhiyun 			buffer, sizeof(buffer));
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun 	return 0;
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun /*
547*4882a593Smuzhiyun  * calculate CTS and N values if they are not found in the table
548*4882a593Smuzhiyun  */
radeon_audio_calc_cts(unsigned int clock,int * CTS,int * N,int freq)549*4882a593Smuzhiyun static void radeon_audio_calc_cts(unsigned int clock, int *CTS, int *N, int freq)
550*4882a593Smuzhiyun {
551*4882a593Smuzhiyun 	int n, cts;
552*4882a593Smuzhiyun 	unsigned long div, mul;
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun 	/* Safe, but overly large values */
555*4882a593Smuzhiyun 	n = 128 * freq;
556*4882a593Smuzhiyun 	cts = clock * 1000;
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun 	/* Smallest valid fraction */
559*4882a593Smuzhiyun 	div = gcd(n, cts);
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	n /= div;
562*4882a593Smuzhiyun 	cts /= div;
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	/*
565*4882a593Smuzhiyun 	 * The optimal N is 128*freq/1000. Calculate the closest larger
566*4882a593Smuzhiyun 	 * value that doesn't truncate any bits.
567*4882a593Smuzhiyun 	 */
568*4882a593Smuzhiyun 	mul = ((128*freq/1000) + (n-1))/n;
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 	n *= mul;
571*4882a593Smuzhiyun 	cts *= mul;
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun 	/* Check that we are in spec (not always possible) */
574*4882a593Smuzhiyun 	if (n < (128*freq/1500))
575*4882a593Smuzhiyun 		pr_warn("Calculated ACR N value is too small. You may experience audio problems.\n");
576*4882a593Smuzhiyun 	if (n > (128*freq/300))
577*4882a593Smuzhiyun 		pr_warn("Calculated ACR N value is too large. You may experience audio problems.\n");
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	*N = n;
580*4882a593Smuzhiyun 	*CTS = cts;
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun 	DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n",
583*4882a593Smuzhiyun 		*N, *CTS, freq);
584*4882a593Smuzhiyun }
585*4882a593Smuzhiyun 
radeon_audio_acr(unsigned int clock)586*4882a593Smuzhiyun static const struct radeon_hdmi_acr* radeon_audio_acr(unsigned int clock)
587*4882a593Smuzhiyun {
588*4882a593Smuzhiyun 	static struct radeon_hdmi_acr res;
589*4882a593Smuzhiyun 	u8 i;
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 	static const struct radeon_hdmi_acr hdmi_predefined_acr[] = {
592*4882a593Smuzhiyun 		/*       32kHz    44.1kHz   48kHz    */
593*4882a593Smuzhiyun 		/* Clock      N     CTS      N     CTS      N     CTS */
594*4882a593Smuzhiyun 		{  25175,  4096,  25175, 28224, 125875,  6144,  25175 }, /*  25,20/1.001 MHz */
595*4882a593Smuzhiyun 		{  25200,  4096,  25200,  6272,  28000,  6144,  25200 }, /*  25.20       MHz */
596*4882a593Smuzhiyun 		{  27000,  4096,  27000,  6272,  30000,  6144,  27000 }, /*  27.00       MHz */
597*4882a593Smuzhiyun 		{  27027,  4096,  27027,  6272,  30030,  6144,  27027 }, /*  27.00*1.001 MHz */
598*4882a593Smuzhiyun 		{  54000,  4096,  54000,  6272,  60000,  6144,  54000 }, /*  54.00       MHz */
599*4882a593Smuzhiyun 		{  54054,  4096,  54054,  6272,  60060,  6144,  54054 }, /*  54.00*1.001 MHz */
600*4882a593Smuzhiyun 		{  74176,  4096,  74176,  5733,  75335,  6144,  74176 }, /*  74.25/1.001 MHz */
601*4882a593Smuzhiyun 		{  74250,  4096,  74250,  6272,  82500,  6144,  74250 }, /*  74.25       MHz */
602*4882a593Smuzhiyun 		{ 148352,  4096, 148352,  5733, 150670,  6144, 148352 }, /* 148.50/1.001 MHz */
603*4882a593Smuzhiyun 		{ 148500,  4096, 148500,  6272, 165000,  6144, 148500 }, /* 148.50       MHz */
604*4882a593Smuzhiyun 	};
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 	/* Precalculated values for common clocks */
607*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(hdmi_predefined_acr); i++)
608*4882a593Smuzhiyun 		if (hdmi_predefined_acr[i].clock == clock)
609*4882a593Smuzhiyun 			return &hdmi_predefined_acr[i];
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun 	/* And odd clocks get manually calculated */
612*4882a593Smuzhiyun 	radeon_audio_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000);
613*4882a593Smuzhiyun 	radeon_audio_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100);
614*4882a593Smuzhiyun 	radeon_audio_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000);
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun 	return &res;
617*4882a593Smuzhiyun }
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun /*
620*4882a593Smuzhiyun  * update the N and CTS parameters for a given pixel clock rate
621*4882a593Smuzhiyun  */
radeon_audio_update_acr(struct drm_encoder * encoder,unsigned int clock)622*4882a593Smuzhiyun static void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock)
623*4882a593Smuzhiyun {
624*4882a593Smuzhiyun 	const struct radeon_hdmi_acr *acr = radeon_audio_acr(clock);
625*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
626*4882a593Smuzhiyun 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 	if (!dig || !dig->afmt)
629*4882a593Smuzhiyun 		return;
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun 	if (radeon_encoder->audio && radeon_encoder->audio->update_acr)
632*4882a593Smuzhiyun 		radeon_encoder->audio->update_acr(encoder, dig->afmt->offset, acr);
633*4882a593Smuzhiyun }
634*4882a593Smuzhiyun 
radeon_audio_set_vbi_packet(struct drm_encoder * encoder)635*4882a593Smuzhiyun static void radeon_audio_set_vbi_packet(struct drm_encoder *encoder)
636*4882a593Smuzhiyun {
637*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
638*4882a593Smuzhiyun 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun 	if (!dig || !dig->afmt)
641*4882a593Smuzhiyun 		return;
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun 	if (radeon_encoder->audio && radeon_encoder->audio->set_vbi_packet)
644*4882a593Smuzhiyun 		radeon_encoder->audio->set_vbi_packet(encoder, dig->afmt->offset);
645*4882a593Smuzhiyun }
646*4882a593Smuzhiyun 
radeon_hdmi_set_color_depth(struct drm_encoder * encoder)647*4882a593Smuzhiyun static void radeon_hdmi_set_color_depth(struct drm_encoder *encoder)
648*4882a593Smuzhiyun {
649*4882a593Smuzhiyun 	int bpc = 8;
650*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
651*4882a593Smuzhiyun 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 	if (!dig || !dig->afmt)
654*4882a593Smuzhiyun 		return;
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun 	if (encoder->crtc) {
657*4882a593Smuzhiyun 		struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
658*4882a593Smuzhiyun 		bpc = radeon_crtc->bpc;
659*4882a593Smuzhiyun 	}
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun 	if (radeon_encoder->audio && radeon_encoder->audio->set_color_depth)
662*4882a593Smuzhiyun 		radeon_encoder->audio->set_color_depth(encoder, dig->afmt->offset, bpc);
663*4882a593Smuzhiyun }
664*4882a593Smuzhiyun 
radeon_audio_set_audio_packet(struct drm_encoder * encoder)665*4882a593Smuzhiyun static void radeon_audio_set_audio_packet(struct drm_encoder *encoder)
666*4882a593Smuzhiyun {
667*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
668*4882a593Smuzhiyun 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	if (!dig || !dig->afmt)
671*4882a593Smuzhiyun 		return;
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun 	if (radeon_encoder->audio && radeon_encoder->audio->set_audio_packet)
674*4882a593Smuzhiyun 		radeon_encoder->audio->set_audio_packet(encoder, dig->afmt->offset);
675*4882a593Smuzhiyun }
676*4882a593Smuzhiyun 
radeon_audio_set_mute(struct drm_encoder * encoder,bool mute)677*4882a593Smuzhiyun static void radeon_audio_set_mute(struct drm_encoder *encoder, bool mute)
678*4882a593Smuzhiyun {
679*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
680*4882a593Smuzhiyun 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun 	if (!dig || !dig->afmt)
683*4882a593Smuzhiyun 		return;
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun 	if (radeon_encoder->audio && radeon_encoder->audio->set_mute)
686*4882a593Smuzhiyun 		radeon_encoder->audio->set_mute(encoder, dig->afmt->offset, mute);
687*4882a593Smuzhiyun }
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun /*
690*4882a593Smuzhiyun  * update the info frames with the data from the current display mode
691*4882a593Smuzhiyun  */
radeon_audio_hdmi_mode_set(struct drm_encoder * encoder,struct drm_display_mode * mode)692*4882a593Smuzhiyun static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder,
693*4882a593Smuzhiyun 				       struct drm_display_mode *mode)
694*4882a593Smuzhiyun {
695*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
696*4882a593Smuzhiyun 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
697*4882a593Smuzhiyun 	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
698*4882a593Smuzhiyun 
699*4882a593Smuzhiyun 	if (!dig || !dig->afmt)
700*4882a593Smuzhiyun 		return;
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun 	if (!connector)
703*4882a593Smuzhiyun 		return;
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun 	if (drm_detect_monitor_audio(radeon_connector_edid(connector))) {
706*4882a593Smuzhiyun 		radeon_audio_set_mute(encoder, true);
707*4882a593Smuzhiyun 
708*4882a593Smuzhiyun 		radeon_audio_write_speaker_allocation(encoder);
709*4882a593Smuzhiyun 		radeon_audio_write_sad_regs(encoder);
710*4882a593Smuzhiyun 		radeon_audio_write_latency_fields(encoder, mode);
711*4882a593Smuzhiyun 		radeon_audio_set_dto(encoder, mode->clock);
712*4882a593Smuzhiyun 		radeon_audio_set_vbi_packet(encoder);
713*4882a593Smuzhiyun 		radeon_hdmi_set_color_depth(encoder);
714*4882a593Smuzhiyun 		radeon_audio_update_acr(encoder, mode->clock);
715*4882a593Smuzhiyun 		radeon_audio_set_audio_packet(encoder);
716*4882a593Smuzhiyun 		radeon_audio_select_pin(encoder);
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun 		if (radeon_audio_set_avi_packet(encoder, mode) < 0)
719*4882a593Smuzhiyun 			return;
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 		radeon_audio_set_mute(encoder, false);
722*4882a593Smuzhiyun 	} else {
723*4882a593Smuzhiyun 		radeon_hdmi_set_color_depth(encoder);
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun 		if (radeon_audio_set_avi_packet(encoder, mode) < 0)
726*4882a593Smuzhiyun 			return;
727*4882a593Smuzhiyun 	}
728*4882a593Smuzhiyun }
729*4882a593Smuzhiyun 
radeon_audio_dp_mode_set(struct drm_encoder * encoder,struct drm_display_mode * mode)730*4882a593Smuzhiyun static void radeon_audio_dp_mode_set(struct drm_encoder *encoder,
731*4882a593Smuzhiyun 				     struct drm_display_mode *mode)
732*4882a593Smuzhiyun {
733*4882a593Smuzhiyun 	struct drm_device *dev = encoder->dev;
734*4882a593Smuzhiyun 	struct radeon_device *rdev = dev->dev_private;
735*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
736*4882a593Smuzhiyun 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
737*4882a593Smuzhiyun 	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
738*4882a593Smuzhiyun 
739*4882a593Smuzhiyun 	if (!dig || !dig->afmt)
740*4882a593Smuzhiyun 		return;
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 	if (!connector)
743*4882a593Smuzhiyun 		return;
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	if (drm_detect_monitor_audio(radeon_connector_edid(connector))) {
746*4882a593Smuzhiyun 		radeon_audio_write_speaker_allocation(encoder);
747*4882a593Smuzhiyun 		radeon_audio_write_sad_regs(encoder);
748*4882a593Smuzhiyun 		radeon_audio_write_latency_fields(encoder, mode);
749*4882a593Smuzhiyun 		radeon_audio_set_dto(encoder, rdev->clock.vco_freq * 10);
750*4882a593Smuzhiyun 		radeon_audio_set_audio_packet(encoder);
751*4882a593Smuzhiyun 		radeon_audio_select_pin(encoder);
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun 		if (radeon_audio_set_avi_packet(encoder, mode) < 0)
754*4882a593Smuzhiyun 			return;
755*4882a593Smuzhiyun 	}
756*4882a593Smuzhiyun }
757*4882a593Smuzhiyun 
radeon_audio_mode_set(struct drm_encoder * encoder,struct drm_display_mode * mode)758*4882a593Smuzhiyun void radeon_audio_mode_set(struct drm_encoder *encoder,
759*4882a593Smuzhiyun 			   struct drm_display_mode *mode)
760*4882a593Smuzhiyun {
761*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
762*4882a593Smuzhiyun 
763*4882a593Smuzhiyun 	if (radeon_encoder->audio && radeon_encoder->audio->mode_set)
764*4882a593Smuzhiyun 		radeon_encoder->audio->mode_set(encoder, mode);
765*4882a593Smuzhiyun }
766*4882a593Smuzhiyun 
radeon_audio_dpms(struct drm_encoder * encoder,int mode)767*4882a593Smuzhiyun void radeon_audio_dpms(struct drm_encoder *encoder, int mode)
768*4882a593Smuzhiyun {
769*4882a593Smuzhiyun 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
770*4882a593Smuzhiyun 
771*4882a593Smuzhiyun 	if (radeon_encoder->audio && radeon_encoder->audio->dpms)
772*4882a593Smuzhiyun 		radeon_encoder->audio->dpms(encoder, mode == DRM_MODE_DPMS_ON);
773*4882a593Smuzhiyun }
774*4882a593Smuzhiyun 
radeon_audio_decode_dfs_div(unsigned int div)775*4882a593Smuzhiyun unsigned int radeon_audio_decode_dfs_div(unsigned int div)
776*4882a593Smuzhiyun {
777*4882a593Smuzhiyun 	if (div >= 8 && div < 64)
778*4882a593Smuzhiyun 		return (div - 8) * 25 + 200;
779*4882a593Smuzhiyun 	else if (div >= 64 && div < 96)
780*4882a593Smuzhiyun 		return (div - 64) * 50 + 1600;
781*4882a593Smuzhiyun 	else if (div >= 96 && div < 128)
782*4882a593Smuzhiyun 		return (div - 96) * 100 + 3200;
783*4882a593Smuzhiyun 	else
784*4882a593Smuzhiyun 		return 0;
785*4882a593Smuzhiyun }
786