VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/DevHDACommon.h@ 88158

Last change on this file since 88158 was 88137, checked in by vboxsync, 4 years ago

DevHDA: Made the DMA timer scheduling heuristics more flexible and ditched the alternative approaches. Changed the DMA engine to load the whole BDL and not reload BDLEs as we work thru them. Ditched the HDABDLE structure and some other DMA related stuff (FIFO buffer is on the todo list). bugref:9890

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette