1 | /* $Id: DevHDACommon.h 71754 2018-04-09 01:27:04Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | * DevHDACommon.h - Shared HDA device defines / functions.
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*
|
---|
7 | * Copyright (C) 2016-2018 Oracle Corporation
|
---|
8 | *
|
---|
9 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
10 | * available from http://www.virtualbox.org. This file is free software;
|
---|
11 | * you can redistribute it and/or modify it under the terms of the GNU
|
---|
12 | * General Public License (GPL) as published by the Free Software
|
---|
13 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
14 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
15 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
16 | */
|
---|
17 |
|
---|
18 | #ifndef DEV_HDA_COMMON_H
|
---|
19 | #define DEV_HDA_COMMON_H
|
---|
20 |
|
---|
21 | #include "AudioMixer.h"
|
---|
22 | #include <VBox/log.h> /* LOG_ENABLED */
|
---|
23 |
|
---|
24 | /** See 302349 p 6.2. */
|
---|
25 | typedef struct HDAREGDESC
|
---|
26 | {
|
---|
27 | /** Register offset in the register space. */
|
---|
28 | uint32_t offset;
|
---|
29 | /** Size in bytes. Registers of size > 4 are in fact tables. */
|
---|
30 | uint32_t size;
|
---|
31 | /** Readable bits. */
|
---|
32 | uint32_t readable;
|
---|
33 | /** Writable bits. */
|
---|
34 | uint32_t writable;
|
---|
35 | /** Register descriptor (RD) flags of type HDA_RD_FLAG_.
|
---|
36 | * These are used to specify the handling (read/write)
|
---|
37 | * policy of the register. */
|
---|
38 | uint32_t fFlags;
|
---|
39 | /** Read callback. */
|
---|
40 | int (*pfnRead)(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
|
---|
41 | /** Write callback. */
|
---|
42 | int (*pfnWrite)(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
|
---|
43 | /** Index into the register storage array. */
|
---|
44 | uint32_t mem_idx;
|
---|
45 | /** Abbreviated name. */
|
---|
46 | const char *abbrev;
|
---|
47 | /** Descripton. */
|
---|
48 | const char *desc;
|
---|
49 | } HDAREGDESC, *PHDAREGDESC;
|
---|
50 |
|
---|
51 | /**
|
---|
52 | * HDA register aliases (HDA spec 3.3.45).
|
---|
53 | * @remarks Sorted by offReg.
|
---|
54 | */
|
---|
55 | typedef struct HDAREGALIAS
|
---|
56 | {
|
---|
57 | /** The alias register offset. */
|
---|
58 | uint32_t offReg;
|
---|
59 | /** The register index. */
|
---|
60 | int idxAlias;
|
---|
61 | } HDAREGALIAS, *PHDAREGALIAS;
|
---|
62 |
|
---|
63 | /**
|
---|
64 | * At the moment we support 4 input + 4 output streams max, which is 8 in total.
|
---|
65 | * Bidirectional streams are currently *not* supported.
|
---|
66 | *
|
---|
67 | * Note: When changing any of those values, be prepared for some saved state
|
---|
68 | * fixups / trouble!
|
---|
69 | */
|
---|
70 | #define HDA_MAX_SDI 4
|
---|
71 | #define HDA_MAX_SDO 4
|
---|
72 | #define HDA_MAX_STREAMS (HDA_MAX_SDI + HDA_MAX_SDO)
|
---|
73 | AssertCompile(HDA_MAX_SDI <= HDA_MAX_SDO);
|
---|
74 |
|
---|
75 | /** Number of general registers. */
|
---|
76 | #define HDA_NUM_GENERAL_REGS 34
|
---|
77 | /** Number of total registers in the HDA's register map. */
|
---|
78 | #define HDA_NUM_REGS (HDA_NUM_GENERAL_REGS + (HDA_MAX_STREAMS * 10 /* Each stream descriptor has 10 registers */))
|
---|
79 | /** Total number of stream tags (channels). Index 0 is reserved / invalid. */
|
---|
80 | #define HDA_MAX_TAGS 16
|
---|
81 |
|
---|
82 | /**
|
---|
83 | * ICH6 datasheet defines limits for FIFOS registers (18.2.39).
|
---|
84 | * Formula: size - 1
|
---|
85 | * Other values not listed are not supported.
|
---|
86 | */
|
---|
87 | /** Maximum FIFO size (in bytes). */
|
---|
88 | #define HDA_FIFO_MAX 256
|
---|
89 |
|
---|
90 | /** Default timer frequency (in Hz).
|
---|
91 | *
|
---|
92 | * Lowering this value can ask for trouble, as backends then can run
|
---|
93 | * into data underruns. */
|
---|
94 | #define HDA_TIMER_HZ_DEFAULT 100
|
---|
95 |
|
---|
96 | /** Default position adjustment (in audio samples).
|
---|
97 | *
|
---|
98 | * For snd_hda_intel (Linux guests), the first BDL entry always is being used as
|
---|
99 | * so-called BDL adjustment, which can vary, and is being used for chipsets which
|
---|
100 | * misbehave and/or are incorrectly implemented.
|
---|
101 | *
|
---|
102 | * The BDL adjustment entry *always* has the IOC (Interrupt on Completion) bit set.
|
---|
103 | *
|
---|
104 | * For Intel Baytrail / Braswell implementations the BDL default adjustment is 32 frames, whereas
|
---|
105 | * for ICH / PCH it's only one (1) frame.
|
---|
106 | *
|
---|
107 | * See default_bdl_pos_adj() and snd_hdac_stream_setup_periods() for more information.
|
---|
108 | *
|
---|
109 | * By default we apply some simple heuristics in hdaStreamInit().
|
---|
110 | */
|
---|
111 | #define HDA_POS_ADJUST_DEFAULT 0
|
---|
112 |
|
---|
113 | /** HDA's (fixed) audio frame size in bytes.
|
---|
114 | * We only support 16-bit stereo frames at the moment. */
|
---|
115 | #define HDA_FRAME_SIZE 4
|
---|
116 |
|
---|
117 | /** Offset of the SD0 register map. */
|
---|
118 | #define HDA_REG_DESC_SD0_BASE 0x80
|
---|
119 |
|
---|
120 | /** Turn a short global register name into an memory index and a stringized name. */
|
---|
121 | #define HDA_REG_IDX(abbrev) HDA_MEM_IND_NAME(abbrev), #abbrev
|
---|
122 |
|
---|
123 | /** Turns a short stream register name into an memory index and a stringized name. */
|
---|
124 | #define HDA_REG_IDX_STRM(reg, suff) HDA_MEM_IND_NAME(reg ## suff), #reg #suff
|
---|
125 |
|
---|
126 | /** Same as above for a register *not* stored in memory. */
|
---|
127 | #define HDA_REG_IDX_NOMEM(abbrev) 0, #abbrev
|
---|
128 |
|
---|
129 | extern const HDAREGDESC g_aHdaRegMap[HDA_NUM_REGS];
|
---|
130 |
|
---|
131 | /**
|
---|
132 | * NB: Register values stored in memory (au32Regs[]) are indexed through
|
---|
133 | * the HDA_RMX_xxx macros (also HDA_MEM_IND_NAME()). On the other hand, the
|
---|
134 | * register descriptors in g_aHdaRegMap[] are indexed through the
|
---|
135 | * HDA_REG_xxx macros (also HDA_REG_IND_NAME()).
|
---|
136 | *
|
---|
137 | * The au32Regs[] layout is kept unchanged for saved state
|
---|
138 | * compatibility.
|
---|
139 | */
|
---|
140 |
|
---|
141 | /* Registers */
|
---|
142 | #define HDA_REG_IND_NAME(x) HDA_REG_##x
|
---|
143 | #define HDA_MEM_IND_NAME(x) HDA_RMX_##x
|
---|
144 | #define HDA_REG_IND(pThis, x) ((pThis)->au32Regs[g_aHdaRegMap[x].mem_idx])
|
---|
145 | #define HDA_REG(pThis, x) (HDA_REG_IND((pThis), HDA_REG_IND_NAME(x)))
|
---|
146 |
|
---|
147 |
|
---|
148 | #define HDA_REG_GCAP 0 /* Range 0x00 - 0x01 */
|
---|
149 | #define HDA_RMX_GCAP 0
|
---|
150 | /**
|
---|
151 | * GCAP HDASpec 3.3.2 This macro encodes the following information about HDA in a compact manner:
|
---|
152 | *
|
---|
153 | * oss (15:12) - Number of output streams supported.
|
---|
154 | * iss (11:8) - Number of input streams supported.
|
---|
155 | * bss (7:3) - Number of bidirectional streams supported.
|
---|
156 | * bds (2:1) - Number of serial data out (SDO) signals supported.
|
---|
157 | * b64sup (0) - 64 bit addressing supported.
|
---|
158 | */
|
---|
159 | #define HDA_MAKE_GCAP(oss, iss, bss, bds, b64sup) \
|
---|
160 | ( (((oss) & 0xF) << 12) \
|
---|
161 | | (((iss) & 0xF) << 8) \
|
---|
162 | | (((bss) & 0x1F) << 3) \
|
---|
163 | | (((bds) & 0x3) << 2) \
|
---|
164 | | ((b64sup) & 1))
|
---|
165 |
|
---|
166 | #define HDA_REG_VMIN 1 /* 0x02 */
|
---|
167 | #define HDA_RMX_VMIN 1
|
---|
168 |
|
---|
169 | #define HDA_REG_VMAJ 2 /* 0x03 */
|
---|
170 | #define HDA_RMX_VMAJ 2
|
---|
171 |
|
---|
172 | #define HDA_REG_OUTPAY 3 /* 0x04-0x05 */
|
---|
173 | #define HDA_RMX_OUTPAY 3
|
---|
174 |
|
---|
175 | #define HDA_REG_INPAY 4 /* 0x06-0x07 */
|
---|
176 | #define HDA_RMX_INPAY 4
|
---|
177 |
|
---|
178 | #define HDA_REG_GCTL 5 /* 0x08-0x0B */
|
---|
179 | #define HDA_RMX_GCTL 5
|
---|
180 | #define HDA_GCTL_UNSOL RT_BIT(8) /* Accept Unsolicited Response Enable */
|
---|
181 | #define HDA_GCTL_FCNTRL RT_BIT(1) /* Flush Control */
|
---|
182 | #define HDA_GCTL_CRST RT_BIT(0) /* Controller Reset */
|
---|
183 |
|
---|
184 | #define HDA_REG_WAKEEN 6 /* 0x0C */
|
---|
185 | #define HDA_RMX_WAKEEN 6
|
---|
186 |
|
---|
187 | #define HDA_REG_STATESTS 7 /* 0x0E */
|
---|
188 | #define HDA_RMX_STATESTS 7
|
---|
189 | #define HDA_STATESTS_SCSF_MASK 0x7 /* State Change Status Flags (6.2.8). */
|
---|
190 |
|
---|
191 | #define HDA_REG_GSTS 8 /* 0x10-0x11*/
|
---|
192 | #define HDA_RMX_GSTS 8
|
---|
193 | #define HDA_GSTS_FSTS RT_BIT(1) /* Flush Status */
|
---|
194 |
|
---|
195 | #define HDA_REG_OUTSTRMPAY 9 /* 0x18 */
|
---|
196 | #define HDA_RMX_OUTSTRMPAY 112
|
---|
197 |
|
---|
198 | #define HDA_REG_INSTRMPAY 10 /* 0x1a */
|
---|
199 | #define HDA_RMX_INSTRMPAY 113
|
---|
200 |
|
---|
201 | #define HDA_REG_INTCTL 11 /* 0x20 */
|
---|
202 | #define HDA_RMX_INTCTL 9
|
---|
203 | #define HDA_INTCTL_GIE RT_BIT(31) /* Global Interrupt Enable */
|
---|
204 | #define HDA_INTCTL_CIE RT_BIT(30) /* Controller Interrupt Enable */
|
---|
205 | /** Bits 0-29 correspond to streams 0-29. */
|
---|
206 | #define HDA_STRMINT_MASK 0xFF /* Streams 0-7 implemented. Applies to INTCTL and INTSTS. */
|
---|
207 |
|
---|
208 | #define HDA_REG_INTSTS 12 /* 0x24 */
|
---|
209 | #define HDA_RMX_INTSTS 10
|
---|
210 | #define HDA_INTSTS_GIS RT_BIT(31) /* Global Interrupt Status */
|
---|
211 | #define HDA_INTSTS_CIS RT_BIT(30) /* Controller Interrupt Status */
|
---|
212 |
|
---|
213 | #define HDA_REG_WALCLK 13 /* 0x30 */
|
---|
214 | /**NB: HDA_RMX_WALCLK is not defined because the register is not stored in memory. */
|
---|
215 |
|
---|
216 | /**
|
---|
217 | * Note: The HDA specification defines a SSYNC register at offset 0x38. The
|
---|
218 | * ICH6/ICH9 datahseet defines SSYNC at offset 0x34. The Linux HDA driver matches
|
---|
219 | * the datasheet.
|
---|
220 | */
|
---|
221 | #define HDA_REG_SSYNC 14 /* 0x34 */
|
---|
222 | #define HDA_RMX_SSYNC 12
|
---|
223 |
|
---|
224 | #define HDA_REG_CORBLBASE 15 /* 0x40 */
|
---|
225 | #define HDA_RMX_CORBLBASE 13
|
---|
226 |
|
---|
227 | #define HDA_REG_CORBUBASE 16 /* 0x44 */
|
---|
228 | #define HDA_RMX_CORBUBASE 14
|
---|
229 |
|
---|
230 | #define HDA_REG_CORBWP 17 /* 0x48 */
|
---|
231 | #define HDA_RMX_CORBWP 15
|
---|
232 |
|
---|
233 | #define HDA_REG_CORBRP 18 /* 0x4A */
|
---|
234 | #define HDA_RMX_CORBRP 16
|
---|
235 | #define HDA_CORBRP_RST RT_BIT(15) /* CORB Read Pointer Reset */
|
---|
236 |
|
---|
237 | #define HDA_REG_CORBCTL 19 /* 0x4C */
|
---|
238 | #define HDA_RMX_CORBCTL 17
|
---|
239 | #define HDA_CORBCTL_DMA RT_BIT(1) /* Enable CORB DMA Engine */
|
---|
240 | #define HDA_CORBCTL_CMEIE RT_BIT(0) /* CORB Memory Error Interrupt Enable */
|
---|
241 |
|
---|
242 | #define HDA_REG_CORBSTS 20 /* 0x4D */
|
---|
243 | #define HDA_RMX_CORBSTS 18
|
---|
244 |
|
---|
245 | #define HDA_REG_CORBSIZE 21 /* 0x4E */
|
---|
246 | #define HDA_RMX_CORBSIZE 19
|
---|
247 | #define HDA_CORBSIZE_SZ_CAP 0xF0
|
---|
248 | #define HDA_CORBSIZE_SZ 0x3
|
---|
249 |
|
---|
250 | /** Number of CORB buffer entries. */
|
---|
251 | #define HDA_CORB_SIZE 256
|
---|
252 | /** CORB element size (in bytes). */
|
---|
253 | #define HDA_CORB_ELEMENT_SIZE 4
|
---|
254 | /** Number of RIRB buffer entries. */
|
---|
255 | #define HDA_RIRB_SIZE 256
|
---|
256 | /** RIRB element size (in bytes). */
|
---|
257 | #define HDA_RIRB_ELEMENT_SIZE 8
|
---|
258 |
|
---|
259 | #define HDA_REG_RIRBLBASE 22 /* 0x50 */
|
---|
260 | #define HDA_RMX_RIRBLBASE 20
|
---|
261 |
|
---|
262 | #define HDA_REG_RIRBUBASE 23 /* 0x54 */
|
---|
263 | #define HDA_RMX_RIRBUBASE 21
|
---|
264 |
|
---|
265 | #define HDA_REG_RIRBWP 24 /* 0x58 */
|
---|
266 | #define HDA_RMX_RIRBWP 22
|
---|
267 | #define HDA_RIRBWP_RST RT_BIT(15) /* RIRB Write Pointer Reset */
|
---|
268 |
|
---|
269 | #define HDA_REG_RINTCNT 25 /* 0x5A */
|
---|
270 | #define HDA_RMX_RINTCNT 23
|
---|
271 |
|
---|
272 | /** Maximum number of Response Interrupts. */
|
---|
273 | #define HDA_MAX_RINTCNT 256
|
---|
274 |
|
---|
275 | #define HDA_REG_RIRBCTL 26 /* 0x5C */
|
---|
276 | #define HDA_RMX_RIRBCTL 24
|
---|
277 | #define HDA_RIRBCTL_ROIC RT_BIT(2) /* Response Overrun Interrupt Control */
|
---|
278 | #define HDA_RIRBCTL_RDMAEN RT_BIT(1) /* RIRB DMA Enable */
|
---|
279 | #define HDA_RIRBCTL_RINTCTL RT_BIT(0) /* Response Interrupt Control */
|
---|
280 |
|
---|
281 | #define HDA_REG_RIRBSTS 27 /* 0x5D */
|
---|
282 | #define HDA_RMX_RIRBSTS 25
|
---|
283 | #define HDA_RIRBSTS_RIRBOIS RT_BIT(2) /* Response Overrun Interrupt Status */
|
---|
284 | #define HDA_RIRBSTS_RINTFL RT_BIT(0) /* Response Interrupt Flag */
|
---|
285 |
|
---|
286 | #define HDA_REG_RIRBSIZE 28 /* 0x5E */
|
---|
287 | #define HDA_RMX_RIRBSIZE 26
|
---|
288 |
|
---|
289 | #define HDA_REG_IC 29 /* 0x60 */
|
---|
290 | #define HDA_RMX_IC 27
|
---|
291 |
|
---|
292 | #define HDA_REG_IR 30 /* 0x64 */
|
---|
293 | #define HDA_RMX_IR 28
|
---|
294 |
|
---|
295 | #define HDA_REG_IRS 31 /* 0x68 */
|
---|
296 | #define HDA_RMX_IRS 29
|
---|
297 | #define HDA_IRS_IRV RT_BIT(1) /* Immediate Result Valid */
|
---|
298 | #define HDA_IRS_ICB RT_BIT(0) /* Immediate Command Busy */
|
---|
299 |
|
---|
300 | #define HDA_REG_DPLBASE 32 /* 0x70 */
|
---|
301 | #define HDA_RMX_DPLBASE 30
|
---|
302 |
|
---|
303 | #define HDA_REG_DPUBASE 33 /* 0x74 */
|
---|
304 | #define HDA_RMX_DPUBASE 31
|
---|
305 |
|
---|
306 | #define DPBASE_ADDR_MASK (~(uint64_t)0x7f)
|
---|
307 |
|
---|
308 | #define HDA_STREAM_REG_DEF(name, num) (HDA_REG_SD##num##name)
|
---|
309 | #define HDA_STREAM_RMX_DEF(name, num) (HDA_RMX_SD##num##name)
|
---|
310 | /** Note: sdnum here _MUST_ be stream reg number [0,7]. */
|
---|
311 | #define HDA_STREAM_REG(pThis, name, sdnum) (HDA_REG_IND((pThis), HDA_REG_SD0##name + (sdnum) * 10))
|
---|
312 |
|
---|
313 | #define HDA_SD_NUM_FROM_REG(pThis, func, reg) ((reg - HDA_STREAM_REG_DEF(func, 0)) / 10)
|
---|
314 |
|
---|
315 | /** @todo Condense marcos! */
|
---|
316 |
|
---|
317 | #define HDA_REG_SD0CTL HDA_NUM_GENERAL_REGS /* 0x80; other streams offset by 0x20 */
|
---|
318 | #define HDA_RMX_SD0CTL 32
|
---|
319 | #define HDA_RMX_SD1CTL (HDA_STREAM_RMX_DEF(CTL, 0) + 10)
|
---|
320 | #define HDA_RMX_SD2CTL (HDA_STREAM_RMX_DEF(CTL, 0) + 20)
|
---|
321 | #define HDA_RMX_SD3CTL (HDA_STREAM_RMX_DEF(CTL, 0) + 30)
|
---|
322 | #define HDA_RMX_SD4CTL (HDA_STREAM_RMX_DEF(CTL, 0) + 40)
|
---|
323 | #define HDA_RMX_SD5CTL (HDA_STREAM_RMX_DEF(CTL, 0) + 50)
|
---|
324 | #define HDA_RMX_SD6CTL (HDA_STREAM_RMX_DEF(CTL, 0) + 60)
|
---|
325 | #define HDA_RMX_SD7CTL (HDA_STREAM_RMX_DEF(CTL, 0) + 70)
|
---|
326 |
|
---|
327 | #define HDA_SDCTL_NUM_MASK 0xF
|
---|
328 | #define HDA_SDCTL_NUM_SHIFT 20
|
---|
329 | #define HDA_SDCTL_DIR RT_BIT(19) /* Direction (Bidirectional streams only!) */
|
---|
330 | #define HDA_SDCTL_TP RT_BIT(18) /* Traffic Priority (PCI Express) */
|
---|
331 | #define HDA_SDCTL_STRIPE_MASK 0x3
|
---|
332 | #define HDA_SDCTL_STRIPE_SHIFT 16
|
---|
333 | #define HDA_SDCTL_DEIE RT_BIT(4) /* Descriptor Error Interrupt Enable */
|
---|
334 | #define HDA_SDCTL_FEIE RT_BIT(3) /* FIFO Error Interrupt Enable */
|
---|
335 | #define HDA_SDCTL_IOCE RT_BIT(2) /* Interrupt On Completion Enable */
|
---|
336 | #define HDA_SDCTL_RUN RT_BIT(1) /* Stream Run */
|
---|
337 | #define HDA_SDCTL_SRST RT_BIT(0) /* Stream Reset */
|
---|
338 |
|
---|
339 | #define HDA_REG_SD0STS 35 /* 0x83; other streams offset by 0x20 */
|
---|
340 | #define HDA_RMX_SD0STS 33
|
---|
341 | #define HDA_RMX_SD1STS (HDA_STREAM_RMX_DEF(STS, 0) + 10)
|
---|
342 | #define HDA_RMX_SD2STS (HDA_STREAM_RMX_DEF(STS, 0) + 20)
|
---|
343 | #define HDA_RMX_SD3STS (HDA_STREAM_RMX_DEF(STS, 0) + 30)
|
---|
344 | #define HDA_RMX_SD4STS (HDA_STREAM_RMX_DEF(STS, 0) + 40)
|
---|
345 | #define HDA_RMX_SD5STS (HDA_STREAM_RMX_DEF(STS, 0) + 50)
|
---|
346 | #define HDA_RMX_SD6STS (HDA_STREAM_RMX_DEF(STS, 0) + 60)
|
---|
347 | #define HDA_RMX_SD7STS (HDA_STREAM_RMX_DEF(STS, 0) + 70)
|
---|
348 |
|
---|
349 | #define HDA_SDSTS_FIFORDY RT_BIT(5) /* FIFO Ready */
|
---|
350 | #define HDA_SDSTS_DESE RT_BIT(4) /* Descriptor Error */
|
---|
351 | #define HDA_SDSTS_FIFOE RT_BIT(3) /* FIFO Error */
|
---|
352 | #define HDA_SDSTS_BCIS RT_BIT(2) /* Buffer Completion Interrupt Status */
|
---|
353 |
|
---|
354 | #define HDA_REG_SD0LPIB 36 /* 0x84; other streams offset by 0x20 */
|
---|
355 | #define HDA_REG_SD1LPIB (HDA_STREAM_REG_DEF(LPIB, 0) + 10) /* 0xA4 */
|
---|
356 | #define HDA_REG_SD2LPIB (HDA_STREAM_REG_DEF(LPIB, 0) + 20) /* 0xC4 */
|
---|
357 | #define HDA_REG_SD3LPIB (HDA_STREAM_REG_DEF(LPIB, 0) + 30) /* 0xE4 */
|
---|
358 | #define HDA_REG_SD4LPIB (HDA_STREAM_REG_DEF(LPIB, 0) + 40) /* 0x104 */
|
---|
359 | #define HDA_REG_SD5LPIB (HDA_STREAM_REG_DEF(LPIB, 0) + 50) /* 0x124 */
|
---|
360 | #define HDA_REG_SD6LPIB (HDA_STREAM_REG_DEF(LPIB, 0) + 60) /* 0x144 */
|
---|
361 | #define HDA_REG_SD7LPIB (HDA_STREAM_REG_DEF(LPIB, 0) + 70) /* 0x164 */
|
---|
362 | #define HDA_RMX_SD0LPIB 34
|
---|
363 | #define HDA_RMX_SD1LPIB (HDA_STREAM_RMX_DEF(LPIB, 0) + 10)
|
---|
364 | #define HDA_RMX_SD2LPIB (HDA_STREAM_RMX_DEF(LPIB, 0) + 20)
|
---|
365 | #define HDA_RMX_SD3LPIB (HDA_STREAM_RMX_DEF(LPIB, 0) + 30)
|
---|
366 | #define HDA_RMX_SD4LPIB (HDA_STREAM_RMX_DEF(LPIB, 0) + 40)
|
---|
367 | #define HDA_RMX_SD5LPIB (HDA_STREAM_RMX_DEF(LPIB, 0) + 50)
|
---|
368 | #define HDA_RMX_SD6LPIB (HDA_STREAM_RMX_DEF(LPIB, 0) + 60)
|
---|
369 | #define HDA_RMX_SD7LPIB (HDA_STREAM_RMX_DEF(LPIB, 0) + 70)
|
---|
370 |
|
---|
371 | #define HDA_REG_SD0CBL 37 /* 0x88; other streams offset by 0x20 */
|
---|
372 | #define HDA_RMX_SD0CBL 35
|
---|
373 | #define HDA_RMX_SD1CBL (HDA_STREAM_RMX_DEF(CBL, 0) + 10)
|
---|
374 | #define HDA_RMX_SD2CBL (HDA_STREAM_RMX_DEF(CBL, 0) + 20)
|
---|
375 | #define HDA_RMX_SD3CBL (HDA_STREAM_RMX_DEF(CBL, 0) + 30)
|
---|
376 | #define HDA_RMX_SD4CBL (HDA_STREAM_RMX_DEF(CBL, 0) + 40)
|
---|
377 | #define HDA_RMX_SD5CBL (HDA_STREAM_RMX_DEF(CBL, 0) + 50)
|
---|
378 | #define HDA_RMX_SD6CBL (HDA_STREAM_RMX_DEF(CBL, 0) + 60)
|
---|
379 | #define HDA_RMX_SD7CBL (HDA_STREAM_RMX_DEF(CBL, 0) + 70)
|
---|
380 |
|
---|
381 | #define HDA_REG_SD0LVI 38 /* 0x8C; other streams offset by 0x20 */
|
---|
382 | #define HDA_RMX_SD0LVI 36
|
---|
383 | #define HDA_RMX_SD1LVI (HDA_STREAM_RMX_DEF(LVI, 0) + 10)
|
---|
384 | #define HDA_RMX_SD2LVI (HDA_STREAM_RMX_DEF(LVI, 0) + 20)
|
---|
385 | #define HDA_RMX_SD3LVI (HDA_STREAM_RMX_DEF(LVI, 0) + 30)
|
---|
386 | #define HDA_RMX_SD4LVI (HDA_STREAM_RMX_DEF(LVI, 0) + 40)
|
---|
387 | #define HDA_RMX_SD5LVI (HDA_STREAM_RMX_DEF(LVI, 0) + 50)
|
---|
388 | #define HDA_RMX_SD6LVI (HDA_STREAM_RMX_DEF(LVI, 0) + 60)
|
---|
389 | #define HDA_RMX_SD7LVI (HDA_STREAM_RMX_DEF(LVI, 0) + 70)
|
---|
390 |
|
---|
391 | #define HDA_REG_SD0FIFOW 39 /* 0x8E; other streams offset by 0x20 */
|
---|
392 | #define HDA_RMX_SD0FIFOW 37
|
---|
393 | #define HDA_RMX_SD1FIFOW (HDA_STREAM_RMX_DEF(FIFOW, 0) + 10)
|
---|
394 | #define HDA_RMX_SD2FIFOW (HDA_STREAM_RMX_DEF(FIFOW, 0) + 20)
|
---|
395 | #define HDA_RMX_SD3FIFOW (HDA_STREAM_RMX_DEF(FIFOW, 0) + 30)
|
---|
396 | #define HDA_RMX_SD4FIFOW (HDA_STREAM_RMX_DEF(FIFOW, 0) + 40)
|
---|
397 | #define HDA_RMX_SD5FIFOW (HDA_STREAM_RMX_DEF(FIFOW, 0) + 50)
|
---|
398 | #define HDA_RMX_SD6FIFOW (HDA_STREAM_RMX_DEF(FIFOW, 0) + 60)
|
---|
399 | #define HDA_RMX_SD7FIFOW (HDA_STREAM_RMX_DEF(FIFOW, 0) + 70)
|
---|
400 |
|
---|
401 | /*
|
---|
402 | * ICH6 datasheet defined limits for FIFOW values (18.2.38).
|
---|
403 | */
|
---|
404 | #define HDA_SDFIFOW_8B 0x2
|
---|
405 | #define HDA_SDFIFOW_16B 0x3
|
---|
406 | #define HDA_SDFIFOW_32B 0x4
|
---|
407 |
|
---|
408 | #define HDA_REG_SD0FIFOS 40 /* 0x90; other streams offset by 0x20 */
|
---|
409 | #define HDA_RMX_SD0FIFOS 38
|
---|
410 | #define HDA_RMX_SD1FIFOS (HDA_STREAM_RMX_DEF(FIFOS, 0) + 10)
|
---|
411 | #define HDA_RMX_SD2FIFOS (HDA_STREAM_RMX_DEF(FIFOS, 0) + 20)
|
---|
412 | #define HDA_RMX_SD3FIFOS (HDA_STREAM_RMX_DEF(FIFOS, 0) + 30)
|
---|
413 | #define HDA_RMX_SD4FIFOS (HDA_STREAM_RMX_DEF(FIFOS, 0) + 40)
|
---|
414 | #define HDA_RMX_SD5FIFOS (HDA_STREAM_RMX_DEF(FIFOS, 0) + 50)
|
---|
415 | #define HDA_RMX_SD6FIFOS (HDA_STREAM_RMX_DEF(FIFOS, 0) + 60)
|
---|
416 | #define HDA_RMX_SD7FIFOS (HDA_STREAM_RMX_DEF(FIFOS, 0) + 70)
|
---|
417 |
|
---|
418 | #define HDA_SDIFIFO_120B 0x77 /* 8-, 16-, 20-, 24-, 32-bit Input Streams */
|
---|
419 | #define HDA_SDIFIFO_160B 0x9F /* 20-, 24-bit Input Streams Streams */
|
---|
420 |
|
---|
421 | #define HDA_SDOFIFO_16B 0x0F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */
|
---|
422 | #define HDA_SDOFIFO_32B 0x1F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */
|
---|
423 | #define HDA_SDOFIFO_64B 0x3F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */
|
---|
424 | #define HDA_SDOFIFO_128B 0x7F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */
|
---|
425 | #define HDA_SDOFIFO_192B 0xBF /* 8-, 16-, 20-, 24-, 32-bit Output Streams */
|
---|
426 | #define HDA_SDOFIFO_256B 0xFF /* 20-, 24-bit Output Streams */
|
---|
427 |
|
---|
428 | #define HDA_REG_SD0FMT 41 /* 0x92; other streams offset by 0x20 */
|
---|
429 | #define HDA_RMX_SD0FMT 39
|
---|
430 | #define HDA_RMX_SD1FMT (HDA_STREAM_RMX_DEF(FMT, 0) + 10)
|
---|
431 | #define HDA_RMX_SD2FMT (HDA_STREAM_RMX_DEF(FMT, 0) + 20)
|
---|
432 | #define HDA_RMX_SD3FMT (HDA_STREAM_RMX_DEF(FMT, 0) + 30)
|
---|
433 | #define HDA_RMX_SD4FMT (HDA_STREAM_RMX_DEF(FMT, 0) + 40)
|
---|
434 | #define HDA_RMX_SD5FMT (HDA_STREAM_RMX_DEF(FMT, 0) + 50)
|
---|
435 | #define HDA_RMX_SD6FMT (HDA_STREAM_RMX_DEF(FMT, 0) + 60)
|
---|
436 | #define HDA_RMX_SD7FMT (HDA_STREAM_RMX_DEF(FMT, 0) + 70)
|
---|
437 |
|
---|
438 | #define HDA_REG_SD0BDPL 42 /* 0x98; other streams offset by 0x20 */
|
---|
439 | #define HDA_RMX_SD0BDPL 40
|
---|
440 | #define HDA_RMX_SD1BDPL (HDA_STREAM_RMX_DEF(BDPL, 0) + 10)
|
---|
441 | #define HDA_RMX_SD2BDPL (HDA_STREAM_RMX_DEF(BDPL, 0) + 20)
|
---|
442 | #define HDA_RMX_SD3BDPL (HDA_STREAM_RMX_DEF(BDPL, 0) + 30)
|
---|
443 | #define HDA_RMX_SD4BDPL (HDA_STREAM_RMX_DEF(BDPL, 0) + 40)
|
---|
444 | #define HDA_RMX_SD5BDPL (HDA_STREAM_RMX_DEF(BDPL, 0) + 50)
|
---|
445 | #define HDA_RMX_SD6BDPL (HDA_STREAM_RMX_DEF(BDPL, 0) + 60)
|
---|
446 | #define HDA_RMX_SD7BDPL (HDA_STREAM_RMX_DEF(BDPL, 0) + 70)
|
---|
447 |
|
---|
448 | #define HDA_REG_SD0BDPU 43 /* 0x9C; other streams offset by 0x20 */
|
---|
449 | #define HDA_RMX_SD0BDPU 41
|
---|
450 | #define HDA_RMX_SD1BDPU (HDA_STREAM_RMX_DEF(BDPU, 0) + 10)
|
---|
451 | #define HDA_RMX_SD2BDPU (HDA_STREAM_RMX_DEF(BDPU, 0) + 20)
|
---|
452 | #define HDA_RMX_SD3BDPU (HDA_STREAM_RMX_DEF(BDPU, 0) + 30)
|
---|
453 | #define HDA_RMX_SD4BDPU (HDA_STREAM_RMX_DEF(BDPU, 0) + 40)
|
---|
454 | #define HDA_RMX_SD5BDPU (HDA_STREAM_RMX_DEF(BDPU, 0) + 50)
|
---|
455 | #define HDA_RMX_SD6BDPU (HDA_STREAM_RMX_DEF(BDPU, 0) + 60)
|
---|
456 | #define HDA_RMX_SD7BDPU (HDA_STREAM_RMX_DEF(BDPU, 0) + 70)
|
---|
457 |
|
---|
458 | #define HDA_CODEC_CAD_SHIFT 28
|
---|
459 | /** Encodes the (required) LUN into a codec command. */
|
---|
460 | #define HDA_CODEC_CMD(cmd, lun) ((cmd) | (lun << HDA_CODEC_CAD_SHIFT))
|
---|
461 |
|
---|
462 | #define HDA_SDFMT_NON_PCM_SHIFT 15
|
---|
463 | #define HDA_SDFMT_NON_PCM_MASK 0x1
|
---|
464 | #define HDA_SDFMT_BASE_RATE_SHIFT 14
|
---|
465 | #define HDA_SDFMT_BASE_RATE_MASK 0x1
|
---|
466 | #define HDA_SDFMT_MULT_SHIFT 11
|
---|
467 | #define HDA_SDFMT_MULT_MASK 0x7
|
---|
468 | #define HDA_SDFMT_DIV_SHIFT 8
|
---|
469 | #define HDA_SDFMT_DIV_MASK 0x7
|
---|
470 | #define HDA_SDFMT_BITS_SHIFT 4
|
---|
471 | #define HDA_SDFMT_BITS_MASK 0x7
|
---|
472 | #define HDA_SDFMT_CHANNELS_MASK 0xF
|
---|
473 |
|
---|
474 | #define HDA_SDFMT_TYPE RT_BIT(15)
|
---|
475 | #define HDA_SDFMT_TYPE_PCM (0)
|
---|
476 | #define HDA_SDFMT_TYPE_NON_PCM (1)
|
---|
477 |
|
---|
478 | #define HDA_SDFMT_BASE RT_BIT(14)
|
---|
479 | #define HDA_SDFMT_BASE_48KHZ (0)
|
---|
480 | #define HDA_SDFMT_BASE_44KHZ (1)
|
---|
481 |
|
---|
482 | #define HDA_SDFMT_MULT_1X (0)
|
---|
483 | #define HDA_SDFMT_MULT_2X (1)
|
---|
484 | #define HDA_SDFMT_MULT_3X (2)
|
---|
485 | #define HDA_SDFMT_MULT_4X (3)
|
---|
486 |
|
---|
487 | #define HDA_SDFMT_DIV_1X (0)
|
---|
488 | #define HDA_SDFMT_DIV_2X (1)
|
---|
489 | #define HDA_SDFMT_DIV_3X (2)
|
---|
490 | #define HDA_SDFMT_DIV_4X (3)
|
---|
491 | #define HDA_SDFMT_DIV_5X (4)
|
---|
492 | #define HDA_SDFMT_DIV_6X (5)
|
---|
493 | #define HDA_SDFMT_DIV_7X (6)
|
---|
494 | #define HDA_SDFMT_DIV_8X (7)
|
---|
495 |
|
---|
496 | #define HDA_SDFMT_8_BIT (0)
|
---|
497 | #define HDA_SDFMT_16_BIT (1)
|
---|
498 | #define HDA_SDFMT_20_BIT (2)
|
---|
499 | #define HDA_SDFMT_24_BIT (3)
|
---|
500 | #define HDA_SDFMT_32_BIT (4)
|
---|
501 |
|
---|
502 | #define HDA_SDFMT_CHAN_MONO (0)
|
---|
503 | #define HDA_SDFMT_CHAN_STEREO (1)
|
---|
504 |
|
---|
505 | /** Emits a SDnFMT register format.
|
---|
506 | * Also being used in the codec's converter format. */
|
---|
507 | #define HDA_SDFMT_MAKE(_afNonPCM, _aBaseRate, _aMult, _aDiv, _aBits, _aChan) \
|
---|
508 | ( (((_afNonPCM) & HDA_SDFMT_NON_PCM_MASK) << HDA_SDFMT_NON_PCM_SHIFT) \
|
---|
509 | | (((_aBaseRate) & HDA_SDFMT_BASE_RATE_MASK) << HDA_SDFMT_BASE_RATE_SHIFT) \
|
---|
510 | | (((_aMult) & HDA_SDFMT_MULT_MASK) << HDA_SDFMT_MULT_SHIFT) \
|
---|
511 | | (((_aDiv) & HDA_SDFMT_DIV_MASK) << HDA_SDFMT_DIV_SHIFT) \
|
---|
512 | | (((_aBits) & HDA_SDFMT_BITS_MASK) << HDA_SDFMT_BITS_SHIFT) \
|
---|
513 | | ( (_aChan) & HDA_SDFMT_CHANNELS_MASK))
|
---|
514 |
|
---|
515 | /** Interrupt on completion (IOC) flag. */
|
---|
516 | #define HDA_BDLE_FLAG_IOC RT_BIT(0)
|
---|
517 |
|
---|
518 |
|
---|
519 |
|
---|
520 | /** The HDA controller. */
|
---|
521 | typedef struct HDASTATE *PHDASTATE;
|
---|
522 | /** The HDA stream. */
|
---|
523 | typedef struct HDASTREAM *PHDASTREAM;
|
---|
524 |
|
---|
525 | typedef struct HDAMIXERSINK *PHDAMIXERSINK;
|
---|
526 |
|
---|
527 |
|
---|
528 | /**
|
---|
529 | * Internal state of a Buffer Descriptor List Entry (BDLE),
|
---|
530 | * needed to keep track of the data needed for the actual device
|
---|
531 | * emulation.
|
---|
532 | */
|
---|
533 | typedef struct HDABDLESTATE
|
---|
534 | {
|
---|
535 | /** Own index within the BDL (Buffer Descriptor List). */
|
---|
536 | uint32_t u32BDLIndex;
|
---|
537 | /** Number of bytes below the stream's FIFO watermark (SDFIFOW).
|
---|
538 | * Used to check if we need fill up the FIFO again. */
|
---|
539 | uint32_t cbBelowFIFOW;
|
---|
540 | /** Current offset in DMA buffer (in bytes).*/
|
---|
541 | uint32_t u32BufOff;
|
---|
542 | uint32_t Padding;
|
---|
543 | } HDABDLESTATE, *PHDABDLESTATE;
|
---|
544 |
|
---|
545 | /**
|
---|
546 | * BDL description structure.
|
---|
547 | * Do not touch this, as this must match to the HDA specs.
|
---|
548 | */
|
---|
549 | typedef struct HDABDLEDESC
|
---|
550 | {
|
---|
551 | /** Starting address of the actual buffer. Must be 128-bit aligned. */
|
---|
552 | uint64_t u64BufAdr;
|
---|
553 | /** Size of the actual buffer (in bytes). */
|
---|
554 | uint32_t u32BufSize;
|
---|
555 | /** Bit 0: Interrupt on completion; the controller will generate
|
---|
556 | * an interrupt when the last byte of the buffer has been
|
---|
557 | * fetched by the DMA engine.
|
---|
558 | *
|
---|
559 | * Rest is reserved for further use and must be 0. */
|
---|
560 | uint32_t fFlags;
|
---|
561 | } HDABDLEDESC, *PHDABDLEDESC;
|
---|
562 | AssertCompileSize(HDABDLEDESC, 16); /* Always 16 byte. Also must be aligned on 128-byte boundary. */
|
---|
563 |
|
---|
564 | /**
|
---|
565 | * Buffer Descriptor List Entry (BDLE) (3.6.3).
|
---|
566 | */
|
---|
567 | typedef struct HDABDLE
|
---|
568 | {
|
---|
569 | /** The actual BDL description. */
|
---|
570 | HDABDLEDESC Desc;
|
---|
571 | /** Internal state of this BDLE.
|
---|
572 | * Not part of the actual BDLE registers. */
|
---|
573 | HDABDLESTATE State;
|
---|
574 | } HDABDLE;
|
---|
575 | AssertCompileSizeAlignment(HDABDLE, 8);
|
---|
576 | /** Pointer to a buffer descriptor list entry (BDLE). */
|
---|
577 | typedef HDABDLE *PHDABDLE;
|
---|
578 |
|
---|
579 | /** @name Object lookup functions.
|
---|
580 | * @{
|
---|
581 | */
|
---|
582 | #ifdef IN_RING3
|
---|
583 | PHDAMIXERSINK hdaR3GetDefaultSink(PHDASTATE pThis, uint8_t uSD);
|
---|
584 | #endif
|
---|
585 | PDMAUDIODIR hdaGetDirFromSD(uint8_t uSD);
|
---|
586 | PHDASTREAM hdaGetStreamFromSD(PHDASTATE pThis, uint8_t uSD);
|
---|
587 | #ifdef IN_RING3
|
---|
588 | PHDASTREAM hdaR3GetStreamFromSink(PHDASTATE pThis, PHDAMIXERSINK pSink);
|
---|
589 | #endif
|
---|
590 | /** @} */
|
---|
591 |
|
---|
592 | /** @name Interrupt functions.
|
---|
593 | * @{
|
---|
594 | */
|
---|
595 | #ifdef LOG_ENABLED
|
---|
596 | int hdaProcessInterrupt(PHDASTATE pThis, const char *pszSource);
|
---|
597 | #else
|
---|
598 | int hdaProcessInterrupt(PHDASTATE pThis);
|
---|
599 | #endif
|
---|
600 | /** @} */
|
---|
601 |
|
---|
602 | /** @name Wall clock (WALCLK) functions.
|
---|
603 | * @{
|
---|
604 | */
|
---|
605 | uint64_t hdaWalClkGetCurrent(PHDASTATE pThis);
|
---|
606 | #ifdef IN_RING3
|
---|
607 | bool hdaR3WalClkSet(PHDASTATE pThis, uint64_t u64WalClk, bool fForce);
|
---|
608 | #endif
|
---|
609 | /** @} */
|
---|
610 |
|
---|
611 | /** @name DMA utility functions.
|
---|
612 | * @{
|
---|
613 | */
|
---|
614 | #ifdef IN_RING3
|
---|
615 | int hdaR3DMARead(PHDASTATE pThis, PHDASTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
|
---|
616 | int hdaR3DMAWrite(PHDASTATE pThis, PHDASTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten);
|
---|
617 | #endif
|
---|
618 | /** @} */
|
---|
619 |
|
---|
620 | /** @name Register functions.
|
---|
621 | * @{
|
---|
622 | */
|
---|
623 | uint32_t hdaGetINTSTS(PHDASTATE pThis);
|
---|
624 | #ifdef IN_RING3
|
---|
625 | int hdaR3SDFMTToPCMProps(uint32_t u32SDFMT, PPDMAUDIOPCMPROPS pProps);
|
---|
626 | #endif /* IN_RING3 */
|
---|
627 | /** @} */
|
---|
628 |
|
---|
629 | /** @name BDLE (Buffer Descriptor List Entry) functions.
|
---|
630 | * @{
|
---|
631 | */
|
---|
632 | #ifdef IN_RING3
|
---|
633 | # ifdef LOG_ENABLED
|
---|
634 | void hdaR3BDLEDumpAll(PHDASTATE pThis, uint64_t u64BDLBase, uint16_t cBDLE);
|
---|
635 | # endif
|
---|
636 | int hdaR3BDLEFetch(PHDASTATE pThis, PHDABDLE pBDLE, uint64_t u64BaseDMA, uint16_t u16Entry);
|
---|
637 | bool hdaR3BDLEIsComplete(PHDABDLE pBDLE);
|
---|
638 | bool hdaR3BDLENeedsInterrupt(PHDABDLE pBDLE);
|
---|
639 | #endif /* IN_RING3 */
|
---|
640 | /** @} */
|
---|
641 |
|
---|
642 | /** @name Device timer functions.
|
---|
643 | * @{
|
---|
644 | */
|
---|
645 | #ifdef IN_RING3
|
---|
646 | bool hdaR3TimerSet(PHDASTATE pThis, PHDASTREAM pStream, uint64_t u64Expire, bool fForce);
|
---|
647 | #endif /* IN_RING3 */
|
---|
648 | /** @} */
|
---|
649 |
|
---|
650 | #endif /* !DEV_HDA_H_COMMON */
|
---|
651 |
|
---|