xref: /linux/sound/x86/intel_hdmi_lpe_audio.h (revision 03c3437755881a9f6f1b5f8c05e62edf7898a87f)
1287599cfSJerome Anand /*
2287599cfSJerome Anand  *   intel_hdmi_lpe_audio.h - Intel HDMI LPE audio driver
3287599cfSJerome Anand  *
4287599cfSJerome Anand  *  Copyright (C) 2016 Intel Corp
5287599cfSJerome Anand  *  Authors:	Sailaja Bandarupalli <sailaja.bandarupalli@intel.com>
6287599cfSJerome Anand  *		Ramesh Babu K V <ramesh.babu@intel.com>
7287599cfSJerome Anand  *		Vaibhav Agarwal <vaibhav.agarwal@intel.com>
8287599cfSJerome Anand  *		Jerome Anand <jerome.anand@intel.com>
9287599cfSJerome Anand  *		Aravind Siddappaji <aravindx.siddappaji@intel.com>
10287599cfSJerome Anand  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11287599cfSJerome Anand  *
12287599cfSJerome Anand  *  This program is free software; you can redistribute it and/or modify
13287599cfSJerome Anand  *  it under the terms of the GNU General Public License as published by
14287599cfSJerome Anand  *  the Free Software Foundation; version 2 of the License.
15287599cfSJerome Anand  *
16287599cfSJerome Anand  *  This program is distributed in the hope that it will be useful, but
17287599cfSJerome Anand  *  WITHOUT ANY WARRANTY; without even the implied warranty of
18287599cfSJerome Anand  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19287599cfSJerome Anand  *  General Public License for more details.
20287599cfSJerome Anand  *
21287599cfSJerome Anand  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22287599cfSJerome Anand  */
23287599cfSJerome Anand #ifndef __INTEL_HDMI_LPE_AUDIO_H
24287599cfSJerome Anand #define __INTEL_HDMI_LPE_AUDIO_H
25287599cfSJerome Anand 
26287599cfSJerome Anand #define HAD_MAX_DEVICES		1
27287599cfSJerome Anand #define HAD_MIN_CHANNEL		2
28287599cfSJerome Anand #define HAD_MAX_CHANNEL		8
29287599cfSJerome Anand #define HAD_NUM_OF_RING_BUFS	4
30287599cfSJerome Anand 
31287599cfSJerome Anand /* Assume 192KHz, 8channel, 25msec period */
32287599cfSJerome Anand #define HAD_MAX_BUFFER		(600*1024)
33287599cfSJerome Anand #define HAD_MIN_BUFFER		(32*1024)
34287599cfSJerome Anand #define HAD_MAX_PERIODS		4
35287599cfSJerome Anand #define HAD_MIN_PERIODS		4
36287599cfSJerome Anand #define HAD_MAX_PERIOD_BYTES	(HAD_MAX_BUFFER/HAD_MIN_PERIODS)
37287599cfSJerome Anand #define HAD_MIN_PERIOD_BYTES	256
38287599cfSJerome Anand #define HAD_FIFO_SIZE		0 /* fifo not being used */
39287599cfSJerome Anand #define MAX_SPEAKERS		8
40287599cfSJerome Anand 
41287599cfSJerome Anand #define AUD_SAMPLE_RATE_32	32000
42287599cfSJerome Anand #define AUD_SAMPLE_RATE_44_1	44100
43287599cfSJerome Anand #define AUD_SAMPLE_RATE_48	48000
44287599cfSJerome Anand #define AUD_SAMPLE_RATE_88_2	88200
45287599cfSJerome Anand #define AUD_SAMPLE_RATE_96	96000
46287599cfSJerome Anand #define AUD_SAMPLE_RATE_176_4	176400
47287599cfSJerome Anand #define AUD_SAMPLE_RATE_192	192000
48287599cfSJerome Anand 
49287599cfSJerome Anand #define HAD_MIN_RATE		AUD_SAMPLE_RATE_32
50287599cfSJerome Anand #define HAD_MAX_RATE		AUD_SAMPLE_RATE_192
51287599cfSJerome Anand 
52287599cfSJerome Anand #define DIS_SAMPLE_RATE_25_2	25200
53287599cfSJerome Anand #define DIS_SAMPLE_RATE_27	27000
54287599cfSJerome Anand #define DIS_SAMPLE_RATE_54	54000
55287599cfSJerome Anand #define DIS_SAMPLE_RATE_74_25	74250
56287599cfSJerome Anand #define DIS_SAMPLE_RATE_148_5	148500
57287599cfSJerome Anand #define HAD_REG_WIDTH		0x08
58287599cfSJerome Anand #define HAD_MAX_HW_BUFS		0x04
59287599cfSJerome Anand #define HAD_MAX_DIP_WORDS		16
60287599cfSJerome Anand #define INTEL_HAD		"IntelHdmiLpeAudio"
61287599cfSJerome Anand 
62964ca808SPierre-Louis Bossart /* DP Link Rates */
63964ca808SPierre-Louis Bossart #define DP_2_7_GHZ			270000
64964ca808SPierre-Louis Bossart #define DP_1_62_GHZ			162000
65964ca808SPierre-Louis Bossart 
66964ca808SPierre-Louis Bossart /* Maud Values */
67964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_32_DP_2_7_MAUD_VAL		1988
68964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_44_1_DP_2_7_MAUD_VAL		2740
69964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_48_DP_2_7_MAUD_VAL		2982
70964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_88_2_DP_2_7_MAUD_VAL		5480
71964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_96_DP_2_7_MAUD_VAL		5965
72964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_176_4_DP_2_7_MAUD_VAL		10961
73964ca808SPierre-Louis Bossart #define HAD_MAX_RATE_DP_2_7_MAUD_VAL			11930
74964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_32_DP_1_62_MAUD_VAL		3314
75964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_44_1_DP_1_62_MAUD_VAL		4567
76964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_48_DP_1_62_MAUD_VAL		4971
77964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_88_2_DP_1_62_MAUD_VAL		9134
78964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_96_DP_1_62_MAUD_VAL		9942
79964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_176_4_DP_1_62_MAUD_VAL		18268
80964ca808SPierre-Louis Bossart #define HAD_MAX_RATE_DP_1_62_MAUD_VAL			19884
81964ca808SPierre-Louis Bossart 
82964ca808SPierre-Louis Bossart /* Naud Value */
83964ca808SPierre-Louis Bossart #define DP_NAUD_VAL					32768
84964ca808SPierre-Louis Bossart 
85287599cfSJerome Anand enum had_drv_status {
86287599cfSJerome Anand 	HAD_DRV_CONNECTED,
87287599cfSJerome Anand 	HAD_DRV_RUNNING,
88287599cfSJerome Anand 	HAD_DRV_DISCONNECTED,
89287599cfSJerome Anand 	HAD_DRV_SUSPENDED,
90287599cfSJerome Anand 	HAD_DRV_ERR,
91287599cfSJerome Anand };
92287599cfSJerome Anand 
93287599cfSJerome Anand /* enum intel_had_aud_buf_type - HDMI controller ring buffer types */
94287599cfSJerome Anand enum intel_had_aud_buf_type {
95287599cfSJerome Anand 	HAD_BUF_TYPE_A = 0,
96287599cfSJerome Anand 	HAD_BUF_TYPE_B = 1,
97287599cfSJerome Anand 	HAD_BUF_TYPE_C = 2,
98287599cfSJerome Anand 	HAD_BUF_TYPE_D = 3,
99287599cfSJerome Anand };
100287599cfSJerome Anand 
101287599cfSJerome Anand /* HDMI Controller register offsets - audio domain common */
102287599cfSJerome Anand /* Base address for below regs = 0x65000 */
103287599cfSJerome Anand enum hdmi_ctrl_reg_offset_common {
104287599cfSJerome Anand 	AUDIO_HDMI_CONFIG_A = 0x000,
105287599cfSJerome Anand 	AUDIO_HDMI_CONFIG_B = 0x800,
106287599cfSJerome Anand 	AUDIO_HDMI_CONFIG_C = 0x900,
107287599cfSJerome Anand };
108287599cfSJerome Anand /* HDMI controller register offsets */
1094151ee84STakashi Iwai enum hdmi_ctrl_reg_offset {
110287599cfSJerome Anand 	AUD_CONFIG		= 0x0,
111287599cfSJerome Anand 	AUD_CH_STATUS_0		= 0x08,
112287599cfSJerome Anand 	AUD_CH_STATUS_1		= 0x0C,
113287599cfSJerome Anand 	AUD_HDMI_CTS		= 0x10,
114287599cfSJerome Anand 	AUD_N_ENABLE		= 0x14,
115287599cfSJerome Anand 	AUD_SAMPLE_RATE		= 0x18,
116287599cfSJerome Anand 	AUD_BUF_CONFIG		= 0x20,
117287599cfSJerome Anand 	AUD_BUF_CH_SWAP		= 0x24,
118287599cfSJerome Anand 	AUD_BUF_A_ADDR		= 0x40,
119287599cfSJerome Anand 	AUD_BUF_A_LENGTH	= 0x44,
120287599cfSJerome Anand 	AUD_BUF_B_ADDR		= 0x48,
121287599cfSJerome Anand 	AUD_BUF_B_LENGTH	= 0x4c,
122287599cfSJerome Anand 	AUD_BUF_C_ADDR		= 0x50,
123287599cfSJerome Anand 	AUD_BUF_C_LENGTH	= 0x54,
124287599cfSJerome Anand 	AUD_BUF_D_ADDR		= 0x58,
125287599cfSJerome Anand 	AUD_BUF_D_LENGTH	= 0x5c,
126287599cfSJerome Anand 	AUD_CNTL_ST		= 0x60,
1274151ee84STakashi Iwai 	AUD_HDMI_STATUS		= 0x64, /* v2 */
1284151ee84STakashi Iwai 	AUD_HDMIW_INFOFR	= 0x68, /* v2 */
129287599cfSJerome Anand };
130287599cfSJerome Anand 
131287599cfSJerome Anand /*
132287599cfSJerome Anand  *	CEA speaker placement:
133287599cfSJerome Anand  *
134287599cfSJerome Anand  *	FL  FLC   FC   FRC   FR
135287599cfSJerome Anand  *
136287599cfSJerome Anand  *						LFE
137287599cfSJerome Anand  *
138287599cfSJerome Anand  *	RL  RLC   RC   RRC   RR
139287599cfSJerome Anand  *
140287599cfSJerome Anand  *	The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M
141287599cfSJerome Anand  *	corresponds to CEA RL/RR; The SMPTE channel _assignment_ C/LFE is
142287599cfSJerome Anand  *	swapped to CEA LFE/FC.
143287599cfSJerome Anand  */
144287599cfSJerome Anand enum cea_speaker_placement {
145287599cfSJerome Anand 	FL  = (1 <<  0),        /* Front Left           */
146287599cfSJerome Anand 	FC  = (1 <<  1),        /* Front Center         */
147287599cfSJerome Anand 	FR  = (1 <<  2),        /* Front Right          */
148287599cfSJerome Anand 	FLC = (1 <<  3),        /* Front Left Center    */
149287599cfSJerome Anand 	FRC = (1 <<  4),        /* Front Right Center   */
150287599cfSJerome Anand 	RL  = (1 <<  5),        /* Rear Left            */
151287599cfSJerome Anand 	RC  = (1 <<  6),        /* Rear Center          */
152287599cfSJerome Anand 	RR  = (1 <<  7),        /* Rear Right           */
153287599cfSJerome Anand 	RLC = (1 <<  8),        /* Rear Left Center     */
154287599cfSJerome Anand 	RRC = (1 <<  9),        /* Rear Right Center    */
155287599cfSJerome Anand 	LFE = (1 << 10),        /* Low Frequency Effect */
156287599cfSJerome Anand };
157287599cfSJerome Anand 
158287599cfSJerome Anand struct cea_channel_speaker_allocation {
159287599cfSJerome Anand 	int ca_index;
160287599cfSJerome Anand 	int speakers[8];
161287599cfSJerome Anand 
162287599cfSJerome Anand 	/* derived values, just for convenience */
163287599cfSJerome Anand 	int channels;
164287599cfSJerome Anand 	int spk_mask;
165287599cfSJerome Anand };
166287599cfSJerome Anand 
167287599cfSJerome Anand struct channel_map_table {
168287599cfSJerome Anand 	unsigned char map;              /* ALSA API channel map position */
169287599cfSJerome Anand 	unsigned char cea_slot;         /* CEA slot value */
170287599cfSJerome Anand 	int spk_mask;                   /* speaker position bit mask */
171287599cfSJerome Anand };
172287599cfSJerome Anand 
1737ceba75fSTakashi Iwai /* Audio configuration */
174287599cfSJerome Anand union aud_cfg {
175287599cfSJerome Anand 	struct {
176287599cfSJerome Anand 		u32 aud_en:1;
177287599cfSJerome Anand 		u32 layout:1;
178287599cfSJerome Anand 		u32 fmt:2;
179287599cfSJerome Anand 		u32 num_ch:3;
180287599cfSJerome Anand 		u32 set:1;
181287599cfSJerome Anand 		u32 flat:1;
182287599cfSJerome Anand 		u32 val_bit:1;
183287599cfSJerome Anand 		u32 user_bit:1;
184287599cfSJerome Anand 		u32 underrun:1;
185287599cfSJerome Anand 		u32 packet_mode:1;
186287599cfSJerome Anand 		u32 left_align:1;
187287599cfSJerome Anand 		u32 bogus_sample:1;
188287599cfSJerome Anand 		u32 dp_modei:1;
189287599cfSJerome Anand 		u32 rsvd:16;
1907ceba75fSTakashi Iwai 	} regx;
1917ceba75fSTakashi Iwai 	u32 regval;
192287599cfSJerome Anand };
193287599cfSJerome Anand 
194*03c34377STakashi Iwai #define AUD_CONFIG_BLOCK_BIT			(1 << 7)
195*03c34377STakashi Iwai #define AUD_CONFIG_VALID_BIT			(1 << 9)
196*03c34377STakashi Iwai #define AUD_CONFIG_DP_MODE			(1 << 15)
197*03c34377STakashi Iwai 
1987ceba75fSTakashi Iwai /* Audio Channel Status 0 Attributes */
199287599cfSJerome Anand union aud_ch_status_0 {
200287599cfSJerome Anand 	struct {
201287599cfSJerome Anand 		u32 ch_status:1;
202287599cfSJerome Anand 		u32 lpcm_id:1;
203287599cfSJerome Anand 		u32 cp_info:1;
204287599cfSJerome Anand 		u32 format:3;
205287599cfSJerome Anand 		u32 mode:2;
206287599cfSJerome Anand 		u32 ctg_code:8;
207287599cfSJerome Anand 		u32 src_num:4;
208287599cfSJerome Anand 		u32 ch_num:4;
209287599cfSJerome Anand 		u32 samp_freq:4;
210287599cfSJerome Anand 		u32 clk_acc:2;
211287599cfSJerome Anand 		u32 rsvd:2;
2127ceba75fSTakashi Iwai 	} regx;
2137ceba75fSTakashi Iwai 	u32 regval;
214287599cfSJerome Anand };
215287599cfSJerome Anand 
2167ceba75fSTakashi Iwai /* Audio Channel Status 1 Attributes */
217287599cfSJerome Anand union aud_ch_status_1 {
218287599cfSJerome Anand 	struct {
219287599cfSJerome Anand 		u32 max_wrd_len:1;
220287599cfSJerome Anand 		u32 wrd_len:3;
221287599cfSJerome Anand 		u32 rsvd:28;
2227ceba75fSTakashi Iwai 	} regx;
2237ceba75fSTakashi Iwai 	u32 regval;
224287599cfSJerome Anand };
225287599cfSJerome Anand 
2267ceba75fSTakashi Iwai /* CTS register */
227287599cfSJerome Anand union aud_hdmi_cts {
228287599cfSJerome Anand 	struct {
229287599cfSJerome Anand 		u32 cts_val:24;
230287599cfSJerome Anand 		u32 en_cts_prog:1;
231287599cfSJerome Anand 		u32 rsvd:7;
2327ceba75fSTakashi Iwai 	} regx;
2337ceba75fSTakashi Iwai 	u32 regval;
234287599cfSJerome Anand };
235287599cfSJerome Anand 
2367ceba75fSTakashi Iwai /* N register */
237287599cfSJerome Anand union aud_hdmi_n_enable {
238287599cfSJerome Anand 	struct {
239287599cfSJerome Anand 		u32 n_val:24;
240287599cfSJerome Anand 		u32 en_n_prog:1;
241287599cfSJerome Anand 		u32 rsvd:7;
2427ceba75fSTakashi Iwai 	} regx;
2437ceba75fSTakashi Iwai 	u32 regval;
244287599cfSJerome Anand };
245287599cfSJerome Anand 
2467ceba75fSTakashi Iwai /* Audio Buffer configurations */
247287599cfSJerome Anand union aud_buf_config {
248287599cfSJerome Anand 	struct {
249287599cfSJerome Anand 		u32 audio_fifo_watermark:8;
250287599cfSJerome Anand 		u32 dma_fifo_watermark:3;
251287599cfSJerome Anand 		u32 rsvd0:5;
252287599cfSJerome Anand 		u32 aud_delay:8;
253287599cfSJerome Anand 		u32 rsvd1:8;
2547ceba75fSTakashi Iwai 	} regx;
2557ceba75fSTakashi Iwai 	u32 regval;
256287599cfSJerome Anand };
257287599cfSJerome Anand 
2587ceba75fSTakashi Iwai /* Audio Sample Swapping offset */
259287599cfSJerome Anand union aud_buf_ch_swap {
260287599cfSJerome Anand 	struct {
261287599cfSJerome Anand 		u32 first_0:3;
262287599cfSJerome Anand 		u32 second_0:3;
263287599cfSJerome Anand 		u32 first_1:3;
264287599cfSJerome Anand 		u32 second_1:3;
265287599cfSJerome Anand 		u32 first_2:3;
266287599cfSJerome Anand 		u32 second_2:3;
267287599cfSJerome Anand 		u32 first_3:3;
268287599cfSJerome Anand 		u32 second_3:3;
269287599cfSJerome Anand 		u32 rsvd:8;
2707ceba75fSTakashi Iwai 	} regx;
2717ceba75fSTakashi Iwai 	u32 regval;
272287599cfSJerome Anand };
273287599cfSJerome Anand 
2747ceba75fSTakashi Iwai /* Address for Audio Buffer */
275287599cfSJerome Anand union aud_buf_addr {
276287599cfSJerome Anand 	struct {
277287599cfSJerome Anand 		u32 valid:1;
278287599cfSJerome Anand 		u32 intr_en:1;
279287599cfSJerome Anand 		u32 rsvd:4;
280287599cfSJerome Anand 		u32 addr:26;
2817ceba75fSTakashi Iwai 	} regx;
2827ceba75fSTakashi Iwai 	u32 regval;
283287599cfSJerome Anand };
284287599cfSJerome Anand 
2857ceba75fSTakashi Iwai /* Length of Audio Buffer */
286287599cfSJerome Anand union aud_buf_len {
287287599cfSJerome Anand 	struct {
288287599cfSJerome Anand 		u32 buf_len:20;
289287599cfSJerome Anand 		u32 rsvd:12;
2907ceba75fSTakashi Iwai 	} regx;
2917ceba75fSTakashi Iwai 	u32 regval;
292287599cfSJerome Anand };
293287599cfSJerome Anand 
2947ceba75fSTakashi Iwai /* Audio Control State Register offset */
295287599cfSJerome Anand union aud_ctrl_st {
296287599cfSJerome Anand 	struct {
297287599cfSJerome Anand 		u32 ram_addr:4;
298287599cfSJerome Anand 		u32 eld_ack:1;
299287599cfSJerome Anand 		u32 eld_addr:4;
300287599cfSJerome Anand 		u32 eld_buf_size:5;
301287599cfSJerome Anand 		u32 eld_valid:1;
302287599cfSJerome Anand 		u32 cp_ready:1;
303287599cfSJerome Anand 		u32 dip_freq:2;
304287599cfSJerome Anand 		u32 dip_idx:3;
305287599cfSJerome Anand 		u32 dip_en_sta:4;
306287599cfSJerome Anand 		u32 rsvd:7;
3077ceba75fSTakashi Iwai 	} regx;
3087ceba75fSTakashi Iwai 	u32 regval;
309287599cfSJerome Anand };
310287599cfSJerome Anand 
3117ceba75fSTakashi Iwai /* Audio HDMI Widget Data Island Packet offset */
312287599cfSJerome Anand union aud_info_frame1 {
313287599cfSJerome Anand 	struct {
314287599cfSJerome Anand 		u32 pkt_type:8;
315287599cfSJerome Anand 		u32 ver_num:8;
316287599cfSJerome Anand 		u32 len:5;
317287599cfSJerome Anand 		u32 rsvd:11;
3187ceba75fSTakashi Iwai 	} regx;
3197ceba75fSTakashi Iwai 	u32 regval;
320287599cfSJerome Anand };
321287599cfSJerome Anand 
3227ceba75fSTakashi Iwai /* DIP frame 2 */
323287599cfSJerome Anand union aud_info_frame2 {
324287599cfSJerome Anand 	struct {
325287599cfSJerome Anand 		u32 chksum:8;
326287599cfSJerome Anand 		u32 chnl_cnt:3;
327287599cfSJerome Anand 		u32 rsvd0:1;
328287599cfSJerome Anand 		u32 coding_type:4;
329287599cfSJerome Anand 		u32 smpl_size:2;
330287599cfSJerome Anand 		u32 smpl_freq:3;
331287599cfSJerome Anand 		u32 rsvd1:3;
332287599cfSJerome Anand 		u32 format:8;
3337ceba75fSTakashi Iwai 	} regx;
3347ceba75fSTakashi Iwai 	u32 regval;
335287599cfSJerome Anand };
336287599cfSJerome Anand 
3377ceba75fSTakashi Iwai /* DIP frame 3 */
338287599cfSJerome Anand union aud_info_frame3 {
339287599cfSJerome Anand 	struct {
340287599cfSJerome Anand 		u32 chnl_alloc:8;
341287599cfSJerome Anand 		u32 rsvd0:3;
342287599cfSJerome Anand 		u32 lsv:4;
343287599cfSJerome Anand 		u32 dm_inh:1;
344287599cfSJerome Anand 		u32 rsvd1:16;
3457ceba75fSTakashi Iwai 	} regx;
3467ceba75fSTakashi Iwai 	u32 regval;
347287599cfSJerome Anand };
348287599cfSJerome Anand 
349*03c34377STakashi Iwai /* AUD_HDMI_STATUS bits */
350*03c34377STakashi Iwai #define HDMI_AUDIO_UNDERRUN		(1U << 31)
351*03c34377STakashi Iwai #define HDMI_AUDIO_BUFFER_DONE		(1U << 29)
352287599cfSJerome Anand 
353*03c34377STakashi Iwai /* AUD_HDMI_STATUS register mask */
354*03c34377STakashi Iwai #define AUD_CONFIG_MASK_UNDERRUN	0xC0000000
355*03c34377STakashi Iwai #define AUD_CONFIG_MASK_SRDBG		0x00000002
356*03c34377STakashi Iwai #define AUD_CONFIG_MASK_FUNCRST		0x00000001
357287599cfSJerome Anand 
358287599cfSJerome Anand #endif
359