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