1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2016 Alex Teaca <iateaca@FreeBSD.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 */
29
30 #include <sys/param.h>
31 #include <time.h>
32
33 #include "pci_hda.h"
34 #include "bhyverun.h"
35 #include "config.h"
36 #include "pci_emul.h"
37 #include "hdac_reg.h"
38
39 /*
40 * HDA defines
41 */
42 #define PCIR_HDCTL 0x40
43 #define INTEL_VENDORID 0x8086
44 #define HDA_INTEL_82801G 0x27d8
45
46 #define HDA_IOSS_NO 0x08
47 #define HDA_OSS_NO 0x04
48 #define HDA_ISS_NO 0x04
49 #define HDA_CODEC_MAX 0x0f
50 #define HDA_LAST_OFFSET \
51 (0x2084 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20))
52 #define HDA_CORB_ENTRY_LEN 0x04
53 #define HDA_RIRB_ENTRY_LEN 0x08
54 #define HDA_BDL_ENTRY_LEN 0x10
55 #define HDA_DMA_PIB_ENTRY_LEN 0x08
56 #define HDA_STREAM_TAGS_CNT 0x10
57 #define HDA_STREAM_REGS_BASE 0x80
58 #define HDA_STREAM_REGS_LEN 0x20
59
60 #define HDA_DMA_ACCESS_LEN (sizeof(uint32_t))
61 #define HDA_BDL_MAX_LEN 0x0100
62
63 #define HDAC_SDSTS_FIFORDY (1 << 5)
64
65 #define HDA_RIRBSTS_IRQ_MASK (HDAC_RIRBSTS_RINTFL | HDAC_RIRBSTS_RIRBOIS)
66 #define HDA_STATESTS_IRQ_MASK ((1 << HDA_CODEC_MAX) - 1)
67 #define HDA_SDSTS_IRQ_MASK \
68 (HDAC_SDSTS_DESE | HDAC_SDSTS_FIFOE | HDAC_SDSTS_BCIS)
69
70 /*
71 * HDA data structures
72 */
73
74 struct hda_softc;
75
76 typedef void (*hda_set_reg_handler)(struct hda_softc *sc, uint32_t offset,
77 uint32_t old);
78
79 struct hda_bdle {
80 uint32_t addrl;
81 uint32_t addrh;
82 uint32_t len;
83 uint32_t ioc;
84 } __packed;
85
86 struct hda_bdle_desc {
87 void *addr;
88 uint8_t ioc;
89 uint32_t len;
90 };
91
92 struct hda_codec_cmd_ctl {
93 const char *name;
94 void *dma_vaddr;
95 uint8_t run;
96 uint16_t rp;
97 uint16_t size;
98 uint16_t wp;
99 };
100
101 struct hda_stream_desc {
102 uint8_t dir;
103 uint8_t run;
104 uint8_t stream;
105
106 /* bp is the no. of bytes transferred in the current bdle */
107 uint32_t bp;
108 /* be is the no. of bdles transferred in the bdl */
109 uint32_t be;
110
111 uint32_t bdl_cnt;
112 struct hda_bdle_desc bdl[HDA_BDL_MAX_LEN];
113 };
114
115 struct hda_softc {
116 struct pci_devinst *pci_dev;
117 uint32_t regs[HDA_LAST_OFFSET];
118
119 uint8_t lintr;
120 uint8_t rirb_cnt;
121 uint64_t wall_clock_start;
122
123 struct hda_codec_cmd_ctl corb;
124 struct hda_codec_cmd_ctl rirb;
125
126 uint8_t codecs_no;
127 struct hda_codec_inst *codecs[HDA_CODEC_MAX];
128
129 /* Base Address of the DMA Position Buffer */
130 void *dma_pib_vaddr;
131
132 struct hda_stream_desc streams[HDA_IOSS_NO];
133 /* 2 tables for output and input */
134 uint8_t stream_map[2][HDA_STREAM_TAGS_CNT];
135 };
136
137 /*
138 * HDA module function declarations
139 */
140 static inline void hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset,
141 uint32_t value);
142 static inline uint32_t hda_get_reg_by_offset(struct hda_softc *sc,
143 uint32_t offset);
144 static inline void hda_set_field_by_offset(struct hda_softc *sc,
145 uint32_t offset, uint32_t mask, uint32_t value);
146
147 static struct hda_softc *hda_init(nvlist_t *nvl);
148 static void hda_update_intr(struct hda_softc *sc);
149 static void hda_response_interrupt(struct hda_softc *sc);
150 static int hda_codec_constructor(struct hda_softc *sc,
151 struct hda_codec_class *codec, const char *play, const char *rec);
152 static struct hda_codec_class *hda_find_codec_class(const char *name);
153
154 static int hda_send_command(struct hda_softc *sc, uint32_t verb);
155 static int hda_notify_codecs(struct hda_softc *sc, uint8_t run,
156 uint8_t stream, uint8_t dir);
157 static void hda_reset(struct hda_softc *sc);
158 static void hda_reset_regs(struct hda_softc *sc);
159 static void hda_stream_reset(struct hda_softc *sc, uint8_t stream_ind);
160 static int hda_stream_start(struct hda_softc *sc, uint8_t stream_ind);
161 static int hda_stream_stop(struct hda_softc *sc, uint8_t stream_ind);
162 static uint32_t hda_read(struct hda_softc *sc, uint32_t offset);
163 static int hda_write(struct hda_softc *sc, uint32_t offset, uint8_t size,
164 uint32_t value);
165
166 static inline void hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p);
167 static int hda_corb_start(struct hda_softc *sc);
168 static int hda_corb_run(struct hda_softc *sc);
169 static int hda_rirb_start(struct hda_softc *sc);
170
171 static void *hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr,
172 size_t len);
173 static void hda_dma_st_dword(void *dma_vaddr, uint32_t data);
174 static uint32_t hda_dma_ld_dword(void *dma_vaddr);
175
176 static inline uint8_t hda_get_stream_by_offsets(uint32_t offset,
177 uint8_t reg_offset);
178 static inline uint32_t hda_get_offset_stream(uint8_t stream_ind);
179
180 static void hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old);
181 static void hda_set_statests(struct hda_softc *sc, uint32_t offset,
182 uint32_t old);
183 static void hda_set_corbwp(struct hda_softc *sc, uint32_t offset, uint32_t old);
184 static void hda_set_corbctl(struct hda_softc *sc, uint32_t offset,
185 uint32_t old);
186 static void hda_set_rirbctl(struct hda_softc *sc, uint32_t offset,
187 uint32_t old);
188 static void hda_set_rirbsts(struct hda_softc *sc, uint32_t offset,
189 uint32_t old);
190 static void hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset,
191 uint32_t old);
192 static void hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old);
193 static void hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old);
194 static void hda_set_sdsts(struct hda_softc *sc, uint32_t offset, uint32_t old);
195
196 static int hda_signal_state_change(struct hda_codec_inst *hci);
197 static int hda_response(struct hda_codec_inst *hci, uint32_t response,
198 uint8_t unsol);
199 static int hda_transfer(struct hda_codec_inst *hci, uint8_t stream,
200 uint8_t dir, uint8_t *buf, size_t count);
201
202 static void hda_set_pib(struct hda_softc *sc, uint8_t stream_ind, uint32_t pib);
203 static uint64_t hda_get_clock_ns(void);
204
205 /*
206 * PCI HDA function declarations
207 */
208 static int pci_hda_init(struct pci_devinst *pi, nvlist_t *nvl);
209 static void pci_hda_write(struct pci_devinst *pi, int baridx, uint64_t offset,
210 int size, uint64_t value);
211 static uint64_t pci_hda_read(struct pci_devinst *pi, int baridx,
212 uint64_t offset, int size);
213 /*
214 * HDA global data
215 */
216
217 static const hda_set_reg_handler hda_set_reg_table[] = {
218 [HDAC_GCTL] = hda_set_gctl,
219 [HDAC_STATESTS] = hda_set_statests,
220 [HDAC_CORBWP] = hda_set_corbwp,
221 [HDAC_CORBCTL] = hda_set_corbctl,
222 [HDAC_RIRBCTL] = hda_set_rirbctl,
223 [HDAC_RIRBSTS] = hda_set_rirbsts,
224 [HDAC_DPIBLBASE] = hda_set_dpiblbase,
225
226 #define HDAC_ISTREAM(n, iss, oss) \
227 [_HDAC_ISDCTL(n, iss, oss)] = hda_set_sdctl, \
228 [_HDAC_ISDCTL(n, iss, oss) + 2] = hda_set_sdctl2, \
229 [_HDAC_ISDSTS(n, iss, oss)] = hda_set_sdsts, \
230
231 #define HDAC_OSTREAM(n, iss, oss) \
232 [_HDAC_OSDCTL(n, iss, oss)] = hda_set_sdctl, \
233 [_HDAC_OSDCTL(n, iss, oss) + 2] = hda_set_sdctl2, \
234 [_HDAC_OSDSTS(n, iss, oss)] = hda_set_sdsts, \
235
236 HDAC_ISTREAM(0, HDA_ISS_NO, HDA_OSS_NO)
237 HDAC_ISTREAM(1, HDA_ISS_NO, HDA_OSS_NO)
238 HDAC_ISTREAM(2, HDA_ISS_NO, HDA_OSS_NO)
239 HDAC_ISTREAM(3, HDA_ISS_NO, HDA_OSS_NO)
240
241 HDAC_OSTREAM(0, HDA_ISS_NO, HDA_OSS_NO)
242 HDAC_OSTREAM(1, HDA_ISS_NO, HDA_OSS_NO)
243 HDAC_OSTREAM(2, HDA_ISS_NO, HDA_OSS_NO)
244 HDAC_OSTREAM(3, HDA_ISS_NO, HDA_OSS_NO)
245 };
246
247 static const uint16_t hda_corb_sizes[] = {
248 [HDAC_CORBSIZE_CORBSIZE_2] = 2,
249 [HDAC_CORBSIZE_CORBSIZE_16] = 16,
250 [HDAC_CORBSIZE_CORBSIZE_256] = 256,
251 [HDAC_CORBSIZE_CORBSIZE_MASK] = 0,
252 };
253
254 static const uint16_t hda_rirb_sizes[] = {
255 [HDAC_RIRBSIZE_RIRBSIZE_2] = 2,
256 [HDAC_RIRBSIZE_RIRBSIZE_16] = 16,
257 [HDAC_RIRBSIZE_RIRBSIZE_256] = 256,
258 [HDAC_RIRBSIZE_RIRBSIZE_MASK] = 0,
259 };
260
261 static const struct hda_ops hops = {
262 .signal = hda_signal_state_change,
263 .response = hda_response,
264 .transfer = hda_transfer,
265 };
266
267 static const struct pci_devemu pci_de_hda = {
268 .pe_emu = "hda",
269 .pe_init = pci_hda_init,
270 .pe_barwrite = pci_hda_write,
271 .pe_barread = pci_hda_read
272 };
273 PCI_EMUL_SET(pci_de_hda);
274
275 SET_DECLARE(hda_codec_class_set, struct hda_codec_class);
276
277 #if DEBUG_HDA == 1
278 FILE *dbg;
279 #endif
280
281 /*
282 * HDA module function definitions
283 */
284
285 static inline void
hda_set_reg_by_offset(struct hda_softc * sc,uint32_t offset,uint32_t value)286 hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset, uint32_t value)
287 {
288 assert(offset < HDA_LAST_OFFSET);
289 sc->regs[offset] = value;
290 }
291
292 static inline uint32_t
hda_get_reg_by_offset(struct hda_softc * sc,uint32_t offset)293 hda_get_reg_by_offset(struct hda_softc *sc, uint32_t offset)
294 {
295 assert(offset < HDA_LAST_OFFSET);
296 return sc->regs[offset];
297 }
298
299 static inline void
hda_set_field_by_offset(struct hda_softc * sc,uint32_t offset,uint32_t mask,uint32_t value)300 hda_set_field_by_offset(struct hda_softc *sc, uint32_t offset,
301 uint32_t mask, uint32_t value)
302 {
303 uint32_t reg_value = 0;
304
305 reg_value = hda_get_reg_by_offset(sc, offset);
306
307 reg_value &= ~mask;
308 reg_value |= (value & mask);
309
310 hda_set_reg_by_offset(sc, offset, reg_value);
311 }
312
313 static struct hda_softc *
hda_init(nvlist_t * nvl)314 hda_init(nvlist_t *nvl)
315 {
316 struct hda_softc *sc = NULL;
317 struct hda_codec_class *codec = NULL;
318 const char *value;
319 char *play;
320 char *rec;
321 int err;
322
323 #if DEBUG_HDA == 1
324 dbg = fopen(DEBUG_HDA_FILE, "w+");
325 #endif
326
327 sc = calloc(1, sizeof(*sc));
328 if (!sc)
329 return (NULL);
330
331 hda_reset_regs(sc);
332
333 /*
334 * TODO search all configured codecs
335 * For now we play with one single codec
336 */
337 codec = hda_find_codec_class("hda_codec");
338 if (codec) {
339 value = get_config_value_node(nvl, "play");
340 if (value == NULL)
341 play = NULL;
342 else
343 play = strdup(value);
344 value = get_config_value_node(nvl, "rec");
345 if (value == NULL)
346 rec = NULL;
347 else
348 rec = strdup(value);
349 DPRINTF("play: %s rec: %s", play, rec);
350 if (play != NULL || rec != NULL) {
351 err = hda_codec_constructor(sc, codec, play, rec);
352 assert(!err);
353 }
354 free(play);
355 free(rec);
356 }
357
358 return (sc);
359 }
360
361 static void
hda_update_intr(struct hda_softc * sc)362 hda_update_intr(struct hda_softc *sc)
363 {
364 struct pci_devinst *pi = sc->pci_dev;
365 uint32_t intctl = hda_get_reg_by_offset(sc, HDAC_INTCTL);
366 uint32_t intsts = 0;
367 uint32_t sdsts = 0;
368 uint32_t rirbsts = 0;
369 uint32_t wakeen = 0;
370 uint32_t statests = 0;
371 uint32_t off = 0;
372 int i;
373
374 /* update the CIS bits */
375 rirbsts = hda_get_reg_by_offset(sc, HDAC_RIRBSTS);
376 if (rirbsts & (HDAC_RIRBSTS_RINTFL | HDAC_RIRBSTS_RIRBOIS))
377 intsts |= HDAC_INTSTS_CIS;
378
379 wakeen = hda_get_reg_by_offset(sc, HDAC_WAKEEN);
380 statests = hda_get_reg_by_offset(sc, HDAC_STATESTS);
381 if (statests & wakeen)
382 intsts |= HDAC_INTSTS_CIS;
383
384 /* update the SIS bits */
385 for (i = 0; i < HDA_IOSS_NO; i++) {
386 off = hda_get_offset_stream(i);
387 sdsts = hda_get_reg_by_offset(sc, off + HDAC_SDSTS);
388 if (sdsts & HDAC_SDSTS_BCIS)
389 intsts |= (1 << i);
390 }
391
392 /* update the GIS bit */
393 if (intsts)
394 intsts |= HDAC_INTSTS_GIS;
395
396 hda_set_reg_by_offset(sc, HDAC_INTSTS, intsts);
397
398 if ((intctl & HDAC_INTCTL_GIE) && ((intsts & \
399 ~HDAC_INTSTS_GIS) & intctl)) {
400 if (!sc->lintr) {
401 pci_lintr_assert(pi);
402 sc->lintr = 1;
403 }
404 } else {
405 if (sc->lintr) {
406 pci_lintr_deassert(pi);
407 sc->lintr = 0;
408 }
409 }
410 }
411
412 static void
hda_response_interrupt(struct hda_softc * sc)413 hda_response_interrupt(struct hda_softc *sc)
414 {
415 uint8_t rirbctl = hda_get_reg_by_offset(sc, HDAC_RIRBCTL);
416
417 if ((rirbctl & HDAC_RIRBCTL_RINTCTL) && sc->rirb_cnt) {
418 sc->rirb_cnt = 0;
419 hda_set_field_by_offset(sc, HDAC_RIRBSTS, HDAC_RIRBSTS_RINTFL,
420 HDAC_RIRBSTS_RINTFL);
421 hda_update_intr(sc);
422 }
423 }
424
425 static int
hda_codec_constructor(struct hda_softc * sc,struct hda_codec_class * codec,const char * play,const char * rec)426 hda_codec_constructor(struct hda_softc *sc, struct hda_codec_class *codec,
427 const char *play, const char *rec)
428 {
429 struct hda_codec_inst *hci = NULL;
430
431 if (sc->codecs_no >= HDA_CODEC_MAX)
432 return (-1);
433
434 hci = calloc(1, sizeof(struct hda_codec_inst));
435 if (!hci)
436 return (-1);
437
438 hci->hda = sc;
439 hci->hops = &hops;
440 hci->cad = sc->codecs_no;
441 hci->codec = codec;
442
443 sc->codecs[sc->codecs_no++] = hci;
444
445 if (!codec->init) {
446 DPRINTF("This codec does not implement the init function");
447 return (-1);
448 }
449
450 return (codec->init(hci, play, rec));
451 }
452
453 static struct hda_codec_class *
hda_find_codec_class(const char * name)454 hda_find_codec_class(const char *name)
455 {
456 struct hda_codec_class **pdpp = NULL, *pdp = NULL;
457
458 SET_FOREACH(pdpp, hda_codec_class_set) {
459 pdp = *pdpp;
460 if (!strcmp(pdp->name, name)) {
461 return (pdp);
462 }
463 }
464
465 return (NULL);
466 }
467
468 static int
hda_send_command(struct hda_softc * sc,uint32_t verb)469 hda_send_command(struct hda_softc *sc, uint32_t verb)
470 {
471 struct hda_codec_inst *hci = NULL;
472 struct hda_codec_class *codec = NULL;
473 uint8_t cad = (verb >> HDA_CMD_CAD_SHIFT) & 0x0f;
474
475 if (cad >= sc->codecs_no)
476 return (-1);
477
478 DPRINTF("cad: 0x%x verb: 0x%x", cad, verb);
479
480 hci = sc->codecs[cad];
481 assert(hci);
482
483 codec = hci->codec;
484 assert(codec);
485
486 if (!codec->command) {
487 DPRINTF("This codec does not implement the command function");
488 return (-1);
489 }
490
491 return (codec->command(hci, verb));
492 }
493
494 static int
hda_notify_codecs(struct hda_softc * sc,uint8_t run,uint8_t stream,uint8_t dir)495 hda_notify_codecs(struct hda_softc *sc, uint8_t run, uint8_t stream,
496 uint8_t dir)
497 {
498 struct hda_codec_inst *hci = NULL;
499 struct hda_codec_class *codec = NULL;
500 int err;
501 int i;
502
503 /* Notify each codec */
504 for (i = 0; i < sc->codecs_no; i++) {
505 hci = sc->codecs[i];
506 assert(hci);
507
508 codec = hci->codec;
509 assert(codec);
510
511 if (codec->notify) {
512 err = codec->notify(hci, run, stream, dir);
513 if (!err)
514 break;
515 }
516 }
517
518 return (i == sc->codecs_no ? (-1) : 0);
519 }
520
521 static void
hda_reset(struct hda_softc * sc)522 hda_reset(struct hda_softc *sc)
523 {
524 int i;
525 struct hda_codec_inst *hci = NULL;
526 struct hda_codec_class *codec = NULL;
527
528 hda_reset_regs(sc);
529
530 /* Reset each codec */
531 for (i = 0; i < sc->codecs_no; i++) {
532 hci = sc->codecs[i];
533 assert(hci);
534
535 codec = hci->codec;
536 assert(codec);
537
538 if (codec->reset)
539 codec->reset(hci);
540 }
541
542 sc->wall_clock_start = hda_get_clock_ns();
543 }
544
545 static void
hda_reset_regs(struct hda_softc * sc)546 hda_reset_regs(struct hda_softc *sc)
547 {
548 uint32_t off = 0;
549 uint8_t i;
550
551 DPRINTF("Reset the HDA controller registers ...");
552
553 memset(sc->regs, 0, sizeof(sc->regs));
554
555 hda_set_reg_by_offset(sc, HDAC_GCAP,
556 HDAC_GCAP_64OK |
557 (HDA_ISS_NO << HDAC_GCAP_ISS_SHIFT) |
558 (HDA_OSS_NO << HDAC_GCAP_OSS_SHIFT));
559 hda_set_reg_by_offset(sc, HDAC_VMAJ, 0x01);
560 hda_set_reg_by_offset(sc, HDAC_OUTPAY, 0x3c);
561 hda_set_reg_by_offset(sc, HDAC_INPAY, 0x1d);
562 hda_set_reg_by_offset(sc, HDAC_CORBSIZE,
563 HDAC_CORBSIZE_CORBSZCAP_256 | HDAC_CORBSIZE_CORBSIZE_256);
564 hda_set_reg_by_offset(sc, HDAC_RIRBSIZE,
565 HDAC_RIRBSIZE_RIRBSZCAP_256 | HDAC_RIRBSIZE_RIRBSIZE_256);
566
567 for (i = 0; i < HDA_IOSS_NO; i++) {
568 off = hda_get_offset_stream(i);
569 hda_set_reg_by_offset(sc, off + HDAC_SDFIFOS, HDA_FIFO_SIZE);
570 }
571 }
572
573 static void
hda_stream_reset(struct hda_softc * sc,uint8_t stream_ind)574 hda_stream_reset(struct hda_softc *sc, uint8_t stream_ind)
575 {
576 struct hda_stream_desc *st = &sc->streams[stream_ind];
577 uint32_t off = hda_get_offset_stream(stream_ind);
578
579 DPRINTF("Reset the HDA stream: 0x%x", stream_ind);
580
581 /* Reset the Stream Descriptor registers */
582 memset(sc->regs + HDA_STREAM_REGS_BASE + off, 0, HDA_STREAM_REGS_LEN);
583
584 /* Reset the Stream Descriptor */
585 memset(st, 0, sizeof(*st));
586
587 hda_set_field_by_offset(sc, off + HDAC_SDSTS,
588 HDAC_SDSTS_FIFORDY, HDAC_SDSTS_FIFORDY);
589 hda_set_field_by_offset(sc, off + HDAC_SDCTL0,
590 HDAC_SDCTL_SRST, HDAC_SDCTL_SRST);
591 }
592
593 static int
hda_stream_start(struct hda_softc * sc,uint8_t stream_ind)594 hda_stream_start(struct hda_softc *sc, uint8_t stream_ind)
595 {
596 struct hda_stream_desc *st = &sc->streams[stream_ind];
597 struct hda_bdle_desc *bdle_desc = NULL;
598 struct hda_bdle *bdle = NULL;
599 uint32_t lvi = 0;
600 uint32_t bdl_cnt = 0;
601 uint64_t bdpl = 0;
602 uint64_t bdpu = 0;
603 uint64_t bdl_paddr = 0;
604 void *bdl_vaddr = NULL;
605 uint32_t bdle_sz = 0;
606 uint64_t bdle_addrl = 0;
607 uint64_t bdle_addrh = 0;
608 uint64_t bdle_paddr = 0;
609 void *bdle_vaddr = NULL;
610 uint32_t off = hda_get_offset_stream(stream_ind);
611 uint32_t sdctl = 0;
612 uint8_t strm = 0;
613 uint8_t dir = 0;
614
615 assert(!st->run);
616
617 lvi = hda_get_reg_by_offset(sc, off + HDAC_SDLVI);
618 bdpl = hda_get_reg_by_offset(sc, off + HDAC_SDBDPL);
619 bdpu = hda_get_reg_by_offset(sc, off + HDAC_SDBDPU);
620
621 bdl_cnt = lvi + 1;
622 assert(bdl_cnt <= HDA_BDL_MAX_LEN);
623
624 bdl_paddr = bdpl | (bdpu << 32);
625 bdl_vaddr = hda_dma_get_vaddr(sc, bdl_paddr,
626 HDA_BDL_ENTRY_LEN * bdl_cnt);
627 if (!bdl_vaddr) {
628 DPRINTF("Fail to get the guest virtual address");
629 return (-1);
630 }
631
632 DPRINTF("stream: 0x%x bdl_cnt: 0x%x bdl_paddr: 0x%lx",
633 stream_ind, bdl_cnt, bdl_paddr);
634
635 st->bdl_cnt = bdl_cnt;
636
637 bdle = (struct hda_bdle *)bdl_vaddr;
638 for (size_t i = 0; i < bdl_cnt; i++, bdle++) {
639 bdle_sz = bdle->len;
640 assert(!(bdle_sz % HDA_DMA_ACCESS_LEN));
641
642 bdle_addrl = bdle->addrl;
643 bdle_addrh = bdle->addrh;
644
645 bdle_paddr = bdle_addrl | (bdle_addrh << 32);
646 bdle_vaddr = hda_dma_get_vaddr(sc, bdle_paddr, bdle_sz);
647 if (!bdle_vaddr) {
648 DPRINTF("Fail to get the guest virtual address");
649 return (-1);
650 }
651
652 bdle_desc = &st->bdl[i];
653 bdle_desc->addr = bdle_vaddr;
654 bdle_desc->len = bdle_sz;
655 bdle_desc->ioc = bdle->ioc;
656
657 DPRINTF("bdle: 0x%zx bdle_sz: 0x%x", i, bdle_sz);
658 }
659
660 sdctl = hda_get_reg_by_offset(sc, off + HDAC_SDCTL0);
661 strm = (sdctl >> 20) & 0x0f;
662 dir = stream_ind >= HDA_ISS_NO;
663
664 DPRINTF("strm: 0x%x, dir: 0x%x", strm, dir);
665
666 sc->stream_map[dir][strm] = stream_ind;
667 st->stream = strm;
668 st->dir = dir;
669 st->bp = 0;
670 st->be = 0;
671
672 hda_set_pib(sc, stream_ind, 0);
673
674 st->run = 1;
675
676 hda_notify_codecs(sc, 1, strm, dir);
677
678 return (0);
679 }
680
681 static int
hda_stream_stop(struct hda_softc * sc,uint8_t stream_ind)682 hda_stream_stop(struct hda_softc *sc, uint8_t stream_ind)
683 {
684 struct hda_stream_desc *st = &sc->streams[stream_ind];
685 uint8_t strm = st->stream;
686 uint8_t dir = st->dir;
687
688 DPRINTF("stream: 0x%x, strm: 0x%x, dir: 0x%x", stream_ind, strm, dir);
689
690 st->run = 0;
691
692 hda_notify_codecs(sc, 0, strm, dir);
693
694 return (0);
695 }
696
697 static uint32_t
hda_read(struct hda_softc * sc,uint32_t offset)698 hda_read(struct hda_softc *sc, uint32_t offset)
699 {
700 if (offset == HDAC_WALCLK)
701 return (24 * (hda_get_clock_ns() - \
702 sc->wall_clock_start) / 1000);
703
704 return (hda_get_reg_by_offset(sc, offset));
705 }
706
707 static int
hda_write(struct hda_softc * sc,uint32_t offset,uint8_t size,uint32_t value)708 hda_write(struct hda_softc *sc, uint32_t offset, uint8_t size, uint32_t value)
709 {
710 uint32_t old = hda_get_reg_by_offset(sc, offset);
711 uint32_t masks[] = {0x00000000, 0x000000ff, 0x0000ffff,
712 0x00ffffff, 0xffffffff};
713 hda_set_reg_handler set_reg_handler = NULL;
714
715 if (offset < nitems(hda_set_reg_table))
716 set_reg_handler = hda_set_reg_table[offset];
717
718 hda_set_field_by_offset(sc, offset, masks[size], value);
719
720 if (set_reg_handler)
721 set_reg_handler(sc, offset, old);
722
723 return (0);
724 }
725
726 #if DEBUG_HDA == 1
727 static inline void
hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl * p)728 hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p)
729 {
730 DPRINTF("%s size: %d", p->name, p->size);
731 DPRINTF("%s dma_vaddr: %p", p->name, p->dma_vaddr);
732 DPRINTF("%s wp: 0x%x", p->name, p->wp);
733 DPRINTF("%s rp: 0x%x", p->name, p->rp);
734 }
735 #else
736 static inline void
hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl * p __unused)737 hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p __unused) {}
738 #endif
739
740 static int
hda_corb_start(struct hda_softc * sc)741 hda_corb_start(struct hda_softc *sc)
742 {
743 struct hda_codec_cmd_ctl *corb = &sc->corb;
744 uint8_t corbsize = 0;
745 uint64_t corblbase = 0;
746 uint64_t corbubase = 0;
747 uint64_t corbpaddr = 0;
748
749 corb->name = "CORB";
750
751 corbsize = hda_get_reg_by_offset(sc, HDAC_CORBSIZE) & \
752 HDAC_CORBSIZE_CORBSIZE_MASK;
753 corb->size = hda_corb_sizes[corbsize];
754
755 if (!corb->size) {
756 DPRINTF("Invalid corb size");
757 return (-1);
758 }
759
760 corblbase = hda_get_reg_by_offset(sc, HDAC_CORBLBASE);
761 corbubase = hda_get_reg_by_offset(sc, HDAC_CORBUBASE);
762
763 corbpaddr = corblbase | (corbubase << 32);
764 DPRINTF("CORB dma_paddr: %p", (void *)corbpaddr);
765
766 corb->dma_vaddr = hda_dma_get_vaddr(sc, corbpaddr,
767 HDA_CORB_ENTRY_LEN * corb->size);
768 if (!corb->dma_vaddr) {
769 DPRINTF("Fail to get the guest virtual address");
770 return (-1);
771 }
772
773 corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP);
774 corb->rp = hda_get_reg_by_offset(sc, HDAC_CORBRP);
775
776 corb->run = 1;
777
778 hda_print_cmd_ctl_data(corb);
779
780 return (0);
781 }
782
783 static int
hda_corb_run(struct hda_softc * sc)784 hda_corb_run(struct hda_softc *sc)
785 {
786 struct hda_codec_cmd_ctl *corb = &sc->corb;
787 uint32_t verb = 0;
788 int err;
789
790 corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP);
791 if (corb->wp >= corb->size) {
792 DPRINTF("Invalid HDAC_CORBWP %u >= size %u", corb->wp,
793 corb->size);
794 return (-1);
795 }
796
797 while (corb->rp != corb->wp && corb->run) {
798 corb->rp++;
799 corb->rp %= corb->size;
800
801 verb = hda_dma_ld_dword((uint8_t *)corb->dma_vaddr +
802 HDA_CORB_ENTRY_LEN * corb->rp);
803
804 err = hda_send_command(sc, verb);
805 assert(!err);
806 }
807
808 hda_set_reg_by_offset(sc, HDAC_CORBRP, corb->rp);
809
810 if (corb->run)
811 hda_response_interrupt(sc);
812
813 return (0);
814 }
815
816 static int
hda_rirb_start(struct hda_softc * sc)817 hda_rirb_start(struct hda_softc *sc)
818 {
819 struct hda_codec_cmd_ctl *rirb = &sc->rirb;
820 uint8_t rirbsize = 0;
821 uint64_t rirblbase = 0;
822 uint64_t rirbubase = 0;
823 uint64_t rirbpaddr = 0;
824
825 rirb->name = "RIRB";
826
827 rirbsize = hda_get_reg_by_offset(sc, HDAC_RIRBSIZE) & \
828 HDAC_RIRBSIZE_RIRBSIZE_MASK;
829 rirb->size = hda_rirb_sizes[rirbsize];
830
831 if (!rirb->size) {
832 DPRINTF("Invalid rirb size");
833 return (-1);
834 }
835
836 rirblbase = hda_get_reg_by_offset(sc, HDAC_RIRBLBASE);
837 rirbubase = hda_get_reg_by_offset(sc, HDAC_RIRBUBASE);
838
839 rirbpaddr = rirblbase | (rirbubase << 32);
840 DPRINTF("RIRB dma_paddr: %p", (void *)rirbpaddr);
841
842 rirb->dma_vaddr = hda_dma_get_vaddr(sc, rirbpaddr,
843 HDA_RIRB_ENTRY_LEN * rirb->size);
844 if (!rirb->dma_vaddr) {
845 DPRINTF("Fail to get the guest virtual address");
846 return (-1);
847 }
848
849 rirb->wp = hda_get_reg_by_offset(sc, HDAC_RIRBWP);
850 rirb->rp = 0x0000;
851
852 rirb->run = 1;
853
854 hda_print_cmd_ctl_data(rirb);
855
856 return (0);
857 }
858
859 static void *
hda_dma_get_vaddr(struct hda_softc * sc,uint64_t dma_paddr,size_t len)860 hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr, size_t len)
861 {
862 struct pci_devinst *pi = sc->pci_dev;
863
864 assert(pi);
865
866 return (paddr_guest2host(pi->pi_vmctx, (uintptr_t)dma_paddr, len));
867 }
868
869 static void
hda_dma_st_dword(void * dma_vaddr,uint32_t data)870 hda_dma_st_dword(void *dma_vaddr, uint32_t data)
871 {
872 *(uint32_t*)dma_vaddr = data;
873 }
874
875 static uint32_t
hda_dma_ld_dword(void * dma_vaddr)876 hda_dma_ld_dword(void *dma_vaddr)
877 {
878 return (*(uint32_t*)dma_vaddr);
879 }
880
881 static inline uint8_t
hda_get_stream_by_offsets(uint32_t offset,uint8_t reg_offset)882 hda_get_stream_by_offsets(uint32_t offset, uint8_t reg_offset)
883 {
884 uint8_t stream_ind = (offset - reg_offset) >> 5;
885
886 assert(stream_ind < HDA_IOSS_NO);
887
888 return (stream_ind);
889 }
890
891 static inline uint32_t
hda_get_offset_stream(uint8_t stream_ind)892 hda_get_offset_stream(uint8_t stream_ind)
893 {
894 return (stream_ind << 5);
895 }
896
897 static void
hda_set_gctl(struct hda_softc * sc,uint32_t offset,uint32_t old __unused)898 hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old __unused)
899 {
900 uint32_t value = hda_get_reg_by_offset(sc, offset);
901
902 if (!(value & HDAC_GCTL_CRST)) {
903 hda_reset(sc);
904 }
905 }
906
907 static void
hda_set_statests(struct hda_softc * sc,uint32_t offset,uint32_t old)908 hda_set_statests(struct hda_softc *sc, uint32_t offset, uint32_t old)
909 {
910 uint32_t value = hda_get_reg_by_offset(sc, offset);
911
912 hda_set_reg_by_offset(sc, offset, old);
913
914 /* clear the corresponding bits written by the software (guest) */
915 hda_set_field_by_offset(sc, offset, value & HDA_STATESTS_IRQ_MASK, 0);
916
917 hda_update_intr(sc);
918 }
919
920 static void
hda_set_corbwp(struct hda_softc * sc,uint32_t offset __unused,uint32_t old __unused)921 hda_set_corbwp(struct hda_softc *sc, uint32_t offset __unused,
922 uint32_t old __unused)
923 {
924 hda_corb_run(sc);
925 }
926
927 static void
hda_set_corbctl(struct hda_softc * sc,uint32_t offset,uint32_t old)928 hda_set_corbctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
929 {
930 uint32_t value = hda_get_reg_by_offset(sc, offset);
931 int err;
932 struct hda_codec_cmd_ctl *corb = NULL;
933
934 if (value & HDAC_CORBCTL_CORBRUN) {
935 if (!(old & HDAC_CORBCTL_CORBRUN)) {
936 err = hda_corb_start(sc);
937 assert(!err);
938 }
939 } else {
940 corb = &sc->corb;
941 memset(corb, 0, sizeof(*corb));
942 }
943
944 hda_corb_run(sc);
945 }
946
947 static void
hda_set_rirbctl(struct hda_softc * sc,uint32_t offset,uint32_t old __unused)948 hda_set_rirbctl(struct hda_softc *sc, uint32_t offset, uint32_t old __unused)
949 {
950 uint32_t value = hda_get_reg_by_offset(sc, offset);
951 int err;
952 struct hda_codec_cmd_ctl *rirb = NULL;
953
954 if (value & HDAC_RIRBCTL_RIRBDMAEN) {
955 err = hda_rirb_start(sc);
956 assert(!err);
957 } else {
958 rirb = &sc->rirb;
959 memset(rirb, 0, sizeof(*rirb));
960 }
961 }
962
963 static void
hda_set_rirbsts(struct hda_softc * sc,uint32_t offset,uint32_t old)964 hda_set_rirbsts(struct hda_softc *sc, uint32_t offset, uint32_t old)
965 {
966 uint32_t value = hda_get_reg_by_offset(sc, offset);
967
968 hda_set_reg_by_offset(sc, offset, old);
969
970 /* clear the corresponding bits written by the software (guest) */
971 hda_set_field_by_offset(sc, offset, value & HDA_RIRBSTS_IRQ_MASK, 0);
972
973 hda_update_intr(sc);
974 }
975
976 static void
hda_set_dpiblbase(struct hda_softc * sc,uint32_t offset,uint32_t old)977 hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset, uint32_t old)
978 {
979 uint32_t value = hda_get_reg_by_offset(sc, offset);
980 uint64_t dpiblbase = 0;
981 uint64_t dpibubase = 0;
982 uint64_t dpibpaddr = 0;
983
984 if ((value & HDAC_DPLBASE_DPLBASE_DMAPBE) != (old & \
985 HDAC_DPLBASE_DPLBASE_DMAPBE)) {
986 if (value & HDAC_DPLBASE_DPLBASE_DMAPBE) {
987 dpiblbase = value & HDAC_DPLBASE_DPLBASE_MASK;
988 dpibubase = hda_get_reg_by_offset(sc, HDAC_DPIBUBASE);
989
990 dpibpaddr = dpiblbase | (dpibubase << 32);
991 DPRINTF("DMA Position In Buffer dma_paddr: %p",
992 (void *)dpibpaddr);
993
994 sc->dma_pib_vaddr = hda_dma_get_vaddr(sc, dpibpaddr,
995 HDA_DMA_PIB_ENTRY_LEN * HDA_IOSS_NO);
996 if (!sc->dma_pib_vaddr) {
997 DPRINTF("Fail to get the guest \
998 virtual address");
999 assert(0);
1000 }
1001 } else {
1002 DPRINTF("DMA Position In Buffer Reset");
1003 sc->dma_pib_vaddr = NULL;
1004 }
1005 }
1006 }
1007
1008 static void
hda_set_sdctl(struct hda_softc * sc,uint32_t offset,uint32_t old)1009 hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
1010 {
1011 uint8_t stream_ind = hda_get_stream_by_offsets(offset, HDAC_SDCTL0);
1012 uint32_t value = hda_get_reg_by_offset(sc, offset);
1013 int err;
1014
1015 DPRINTF("stream_ind: 0x%x old: 0x%x value: 0x%x",
1016 stream_ind, old, value);
1017
1018 if (value & HDAC_SDCTL_SRST) {
1019 hda_stream_reset(sc, stream_ind);
1020 }
1021
1022 if ((value & HDAC_SDCTL_RUN) != (old & HDAC_SDCTL_RUN)) {
1023 if (value & HDAC_SDCTL_RUN) {
1024 err = hda_stream_start(sc, stream_ind);
1025 assert(!err);
1026 } else {
1027 err = hda_stream_stop(sc, stream_ind);
1028 assert(!err);
1029 }
1030 }
1031 }
1032
1033 static void
hda_set_sdctl2(struct hda_softc * sc,uint32_t offset,uint32_t old __unused)1034 hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old __unused)
1035 {
1036 uint32_t value = hda_get_reg_by_offset(sc, offset);
1037
1038 hda_set_field_by_offset(sc, offset - 2, 0x00ff0000, value << 16);
1039 }
1040
1041 static void
hda_set_sdsts(struct hda_softc * sc,uint32_t offset,uint32_t old)1042 hda_set_sdsts(struct hda_softc *sc, uint32_t offset, uint32_t old)
1043 {
1044 uint32_t value = hda_get_reg_by_offset(sc, offset);
1045
1046 hda_set_reg_by_offset(sc, offset, old);
1047
1048 /* clear the corresponding bits written by the software (guest) */
1049 hda_set_field_by_offset(sc, offset, value & HDA_SDSTS_IRQ_MASK, 0);
1050
1051 hda_update_intr(sc);
1052 }
1053
1054 static int
hda_signal_state_change(struct hda_codec_inst * hci)1055 hda_signal_state_change(struct hda_codec_inst *hci)
1056 {
1057 struct hda_softc *sc = NULL;
1058 uint32_t sdiwake = 0;
1059
1060 assert(hci);
1061 assert(hci->hda);
1062
1063 DPRINTF("cad: 0x%x", hci->cad);
1064
1065 sc = hci->hda;
1066 sdiwake = 1 << hci->cad;
1067
1068 hda_set_field_by_offset(sc, HDAC_STATESTS, sdiwake, sdiwake);
1069 hda_update_intr(sc);
1070
1071 return (0);
1072 }
1073
1074 static int
hda_response(struct hda_codec_inst * hci,uint32_t response,uint8_t unsol)1075 hda_response(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol)
1076 {
1077 struct hda_softc *sc = NULL;
1078 struct hda_codec_cmd_ctl *rirb = NULL;
1079 uint32_t response_ex = 0;
1080 uint8_t rintcnt = 0;
1081
1082 assert(hci);
1083 assert(hci->cad <= HDA_CODEC_MAX);
1084
1085 response_ex = hci->cad | unsol;
1086
1087 sc = hci->hda;
1088 assert(sc);
1089
1090 rirb = &sc->rirb;
1091
1092 if (rirb->run) {
1093 rirb->wp++;
1094 rirb->wp %= rirb->size;
1095
1096 hda_dma_st_dword((uint8_t *)rirb->dma_vaddr +
1097 HDA_RIRB_ENTRY_LEN * rirb->wp, response);
1098 hda_dma_st_dword((uint8_t *)rirb->dma_vaddr +
1099 HDA_RIRB_ENTRY_LEN * rirb->wp + 0x04, response_ex);
1100
1101 hda_set_reg_by_offset(sc, HDAC_RIRBWP, rirb->wp);
1102
1103 sc->rirb_cnt++;
1104 }
1105
1106 rintcnt = hda_get_reg_by_offset(sc, HDAC_RINTCNT);
1107 if (sc->rirb_cnt == rintcnt)
1108 hda_response_interrupt(sc);
1109
1110 return (0);
1111 }
1112
1113 static int
hda_transfer(struct hda_codec_inst * hci,uint8_t stream,uint8_t dir,uint8_t * buf,size_t count)1114 hda_transfer(struct hda_codec_inst *hci, uint8_t stream, uint8_t dir,
1115 uint8_t *buf, size_t count)
1116 {
1117 struct hda_softc *sc = NULL;
1118 struct hda_stream_desc *st = NULL;
1119 struct hda_bdle_desc *bdl = NULL;
1120 struct hda_bdle_desc *bdle_desc = NULL;
1121 uint8_t stream_ind = 0;
1122 uint32_t lpib = 0;
1123 uint32_t off = 0;
1124 size_t left = 0;
1125 uint8_t irq = 0;
1126
1127 assert(hci);
1128 assert(hci->hda);
1129 assert(buf);
1130 assert(!(count % HDA_DMA_ACCESS_LEN));
1131
1132 if (!stream) {
1133 DPRINTF("Invalid stream");
1134 return (-1);
1135 }
1136
1137 sc = hci->hda;
1138
1139 assert(stream < HDA_STREAM_TAGS_CNT);
1140 stream_ind = sc->stream_map[dir][stream];
1141
1142 if (!dir)
1143 assert(stream_ind < HDA_ISS_NO);
1144 else
1145 assert(stream_ind >= HDA_ISS_NO && stream_ind < HDA_IOSS_NO);
1146
1147 st = &sc->streams[stream_ind];
1148 if (!st->run) {
1149 DPRINTF("Stream 0x%x stopped", stream);
1150 return (-1);
1151 }
1152
1153 assert(st->stream == stream);
1154
1155 off = hda_get_offset_stream(stream_ind);
1156
1157 lpib = hda_get_reg_by_offset(sc, off + HDAC_SDLPIB);
1158
1159 bdl = st->bdl;
1160
1161 assert(st->be < st->bdl_cnt);
1162 assert(st->bp < bdl[st->be].len);
1163
1164 left = count;
1165 while (left) {
1166 bdle_desc = &bdl[st->be];
1167
1168 if (dir)
1169 *(uint32_t *)buf = hda_dma_ld_dword(
1170 (uint8_t *)bdle_desc->addr + st->bp);
1171 else
1172 hda_dma_st_dword((uint8_t *)bdle_desc->addr +
1173 st->bp, *(uint32_t *)buf);
1174
1175 buf += HDA_DMA_ACCESS_LEN;
1176 st->bp += HDA_DMA_ACCESS_LEN;
1177 lpib += HDA_DMA_ACCESS_LEN;
1178 left -= HDA_DMA_ACCESS_LEN;
1179
1180 if (st->bp == bdle_desc->len) {
1181 st->bp = 0;
1182 if (bdle_desc->ioc)
1183 irq = 1;
1184 st->be++;
1185 if (st->be == st->bdl_cnt) {
1186 st->be = 0;
1187 lpib = 0;
1188 }
1189 bdle_desc = &bdl[st->be];
1190 }
1191 }
1192
1193 hda_set_pib(sc, stream_ind, lpib);
1194
1195 if (irq) {
1196 hda_set_field_by_offset(sc, off + HDAC_SDSTS,
1197 HDAC_SDSTS_BCIS, HDAC_SDSTS_BCIS);
1198 hda_update_intr(sc);
1199 }
1200
1201 return (0);
1202 }
1203
1204 static void
hda_set_pib(struct hda_softc * sc,uint8_t stream_ind,uint32_t pib)1205 hda_set_pib(struct hda_softc *sc, uint8_t stream_ind, uint32_t pib)
1206 {
1207 uint32_t off = hda_get_offset_stream(stream_ind);
1208
1209 hda_set_reg_by_offset(sc, off + HDAC_SDLPIB, pib);
1210 /* LPIB Alias */
1211 hda_set_reg_by_offset(sc, 0x2000 + off + HDAC_SDLPIB, pib);
1212 if (sc->dma_pib_vaddr)
1213 *(uint32_t *)((uint8_t *)sc->dma_pib_vaddr + stream_ind *
1214 HDA_DMA_PIB_ENTRY_LEN) = pib;
1215 }
1216
hda_get_clock_ns(void)1217 static uint64_t hda_get_clock_ns(void)
1218 {
1219 struct timespec ts;
1220 int err;
1221
1222 err = clock_gettime(CLOCK_MONOTONIC, &ts);
1223 assert(!err);
1224
1225 return (ts.tv_sec * 1000000000LL + ts.tv_nsec);
1226 }
1227
1228 /*
1229 * PCI HDA function definitions
1230 */
1231 static int
pci_hda_init(struct pci_devinst * pi,nvlist_t * nvl)1232 pci_hda_init(struct pci_devinst *pi, nvlist_t *nvl)
1233 {
1234 struct hda_softc *sc = NULL;
1235
1236 assert(pi != NULL);
1237
1238 pci_set_cfgdata16(pi, PCIR_VENDOR, INTEL_VENDORID);
1239 pci_set_cfgdata16(pi, PCIR_DEVICE, HDA_INTEL_82801G);
1240
1241 pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_MULTIMEDIA_HDA);
1242 pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_MULTIMEDIA);
1243
1244 /* select the Intel HDA mode */
1245 pci_set_cfgdata8(pi, PCIR_HDCTL, 0x01);
1246
1247 /* allocate one BAR register for the Memory address offsets */
1248 pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, HDA_LAST_OFFSET);
1249
1250 /* allocate an IRQ pin for our slot */
1251 pci_lintr_request(pi);
1252
1253 sc = hda_init(nvl);
1254 if (!sc)
1255 return (-1);
1256
1257 sc->pci_dev = pi;
1258 pi->pi_arg = sc;
1259
1260 return (0);
1261 }
1262
1263 static void
pci_hda_write(struct pci_devinst * pi,int baridx,uint64_t offset,int size,uint64_t value)1264 pci_hda_write(struct pci_devinst *pi, int baridx, uint64_t offset, int size,
1265 uint64_t value)
1266 {
1267 struct hda_softc *sc = pi->pi_arg;
1268 int err;
1269
1270 assert(sc);
1271 assert(baridx == 0);
1272 assert(size <= 4);
1273
1274 DPRINTF("offset: 0x%lx value: 0x%lx", offset, value);
1275
1276 err = hda_write(sc, offset, size, value);
1277 assert(!err);
1278 }
1279
1280 static uint64_t
pci_hda_read(struct pci_devinst * pi,int baridx,uint64_t offset,int size)1281 pci_hda_read(struct pci_devinst *pi, int baridx, uint64_t offset, int size)
1282 {
1283 struct hda_softc *sc = pi->pi_arg;
1284 uint64_t value = 0;
1285
1286 assert(sc);
1287 assert(baridx == 0);
1288 assert(size <= 4);
1289
1290 value = hda_read(sc, offset);
1291
1292 DPRINTF("offset: 0x%lx value: 0x%lx", offset, value);
1293
1294 return (value);
1295 }
1296