Lines Matching +full:offset +full:- +full:x

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
66 #define HDA_STATESTS_IRQ_MASK ((1 << HDA_CODEC_MAX) - 1)
76 typedef void (*hda_set_reg_handler)(struct hda_softc *sc, uint32_t offset,
140 static inline void hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset,
143 uint32_t offset);
145 uint32_t offset, uint32_t mask, uint32_t value);
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,
176 static inline uint8_t hda_get_stream_by_offsets(uint32_t offset,
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,
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,
186 static void hda_set_rirbctl(struct hda_softc *sc, uint32_t offset,
188 static void hda_set_rirbsts(struct hda_softc *sc, uint32_t offset,
190 static void hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset,
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);
209 static void pci_hda_write(struct pci_devinst *pi, int baridx, uint64_t offset,
212 uint64_t offset, int size);
286 hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset, uint32_t value) in hda_set_reg_by_offset() argument
288 assert(offset < HDA_LAST_OFFSET); in hda_set_reg_by_offset()
289 sc->regs[offset] = value; in hda_set_reg_by_offset()
293 hda_get_reg_by_offset(struct hda_softc *sc, uint32_t offset) in hda_get_reg_by_offset() argument
295 assert(offset < HDA_LAST_OFFSET); in hda_get_reg_by_offset()
296 return sc->regs[offset]; in hda_get_reg_by_offset()
300 hda_set_field_by_offset(struct hda_softc *sc, uint32_t offset, in hda_set_field_by_offset() argument
305 reg_value = hda_get_reg_by_offset(sc, offset); in hda_set_field_by_offset()
310 hda_set_reg_by_offset(sc, offset, reg_value); in hda_set_field_by_offset()
364 struct pci_devinst *pi = sc->pci_dev; in hda_update_intr()
400 if (!sc->lintr) { in hda_update_intr()
402 sc->lintr = 1; in hda_update_intr()
405 if (sc->lintr) { in hda_update_intr()
407 sc->lintr = 0; in hda_update_intr()
417 if ((rirbctl & HDAC_RIRBCTL_RINTCTL) && sc->rirb_cnt) { in hda_response_interrupt()
418 sc->rirb_cnt = 0; in hda_response_interrupt()
431 if (sc->codecs_no >= HDA_CODEC_MAX) in hda_codec_constructor()
432 return (-1); in hda_codec_constructor()
436 return (-1); in hda_codec_constructor()
438 hci->hda = sc; in hda_codec_constructor()
439 hci->hops = &hops; in hda_codec_constructor()
440 hci->cad = sc->codecs_no; in hda_codec_constructor()
441 hci->codec = codec; in hda_codec_constructor()
443 sc->codecs[sc->codecs_no++] = hci; in hda_codec_constructor()
445 if (!codec->init) { in hda_codec_constructor()
447 return (-1); in hda_codec_constructor()
450 return (codec->init(hci, play, rec)); in hda_codec_constructor()
460 if (!strcmp(pdp->name, name)) { in hda_find_codec_class()
475 if (cad >= sc->codecs_no) in hda_send_command()
476 return (-1); in hda_send_command()
478 DPRINTF("cad: 0x%x verb: 0x%x", cad, verb); in hda_send_command()
480 hci = sc->codecs[cad]; in hda_send_command()
483 codec = hci->codec; in hda_send_command()
486 if (!codec->command) { in hda_send_command()
488 return (-1); in hda_send_command()
491 return (codec->command(hci, verb)); in hda_send_command()
504 for (i = 0; i < sc->codecs_no; i++) { in hda_notify_codecs()
505 hci = sc->codecs[i]; in hda_notify_codecs()
508 codec = hci->codec; in hda_notify_codecs()
511 if (codec->notify) { in hda_notify_codecs()
512 err = codec->notify(hci, run, stream, dir); in hda_notify_codecs()
518 return (i == sc->codecs_no ? (-1) : 0); in hda_notify_codecs()
531 for (i = 0; i < sc->codecs_no; i++) { in hda_reset()
532 hci = sc->codecs[i]; in hda_reset()
535 codec = hci->codec; in hda_reset()
538 if (codec->reset) in hda_reset()
539 codec->reset(hci); in hda_reset()
542 sc->wall_clock_start = hda_get_clock_ns(); in hda_reset()
553 memset(sc->regs, 0, sizeof(sc->regs)); in hda_reset_regs()
576 struct hda_stream_desc *st = &sc->streams[stream_ind]; in hda_stream_reset()
579 DPRINTF("Reset the HDA stream: 0x%x", stream_ind); in hda_stream_reset()
582 memset(sc->regs + HDA_STREAM_REGS_BASE + off, 0, HDA_STREAM_REGS_LEN); in hda_stream_reset()
596 struct hda_stream_desc *st = &sc->streams[stream_ind]; in hda_stream_start()
615 assert(!st->run); in hda_stream_start()
629 return (-1); in hda_stream_start()
632 DPRINTF("stream: 0x%x bdl_cnt: 0x%x bdl_paddr: 0x%lx", in hda_stream_start()
635 st->bdl_cnt = bdl_cnt; in hda_stream_start()
639 bdle_sz = bdle->len; in hda_stream_start()
642 bdle_addrl = bdle->addrl; in hda_stream_start()
643 bdle_addrh = bdle->addrh; in hda_stream_start()
649 return (-1); in hda_stream_start()
652 bdle_desc = &st->bdl[i]; in hda_stream_start()
653 bdle_desc->addr = bdle_vaddr; in hda_stream_start()
654 bdle_desc->len = bdle_sz; in hda_stream_start()
655 bdle_desc->ioc = bdle->ioc; in hda_stream_start()
657 DPRINTF("bdle: 0x%zx bdle_sz: 0x%x", i, bdle_sz); in hda_stream_start()
664 DPRINTF("strm: 0x%x, dir: 0x%x", strm, dir); in hda_stream_start()
666 sc->stream_map[dir][strm] = stream_ind; in hda_stream_start()
667 st->stream = strm; in hda_stream_start()
668 st->dir = dir; in hda_stream_start()
669 st->bp = 0; in hda_stream_start()
670 st->be = 0; in hda_stream_start()
674 st->run = 1; in hda_stream_start()
684 struct hda_stream_desc *st = &sc->streams[stream_ind]; in hda_stream_stop()
685 uint8_t strm = st->stream; in hda_stream_stop()
686 uint8_t dir = st->dir; in hda_stream_stop()
688 DPRINTF("stream: 0x%x, strm: 0x%x, dir: 0x%x", stream_ind, strm, dir); in hda_stream_stop()
690 st->run = 0; in hda_stream_stop()
698 hda_read(struct hda_softc *sc, uint32_t offset) in hda_read() argument
700 if (offset == HDAC_WALCLK) in hda_read()
701 return (24 * (hda_get_clock_ns() - \ in hda_read()
702 sc->wall_clock_start) / 1000); in hda_read()
704 return (hda_get_reg_by_offset(sc, offset)); in hda_read()
708 hda_write(struct hda_softc *sc, uint32_t offset, uint8_t size, uint32_t value) in hda_write() argument
710 uint32_t old = hda_get_reg_by_offset(sc, offset); in hda_write()
715 if (offset < nitems(hda_set_reg_table)) in hda_write()
716 set_reg_handler = hda_set_reg_table[offset]; in hda_write()
718 hda_set_field_by_offset(sc, offset, masks[size], value); in hda_write()
721 set_reg_handler(sc, offset, old); in hda_write()
730 DPRINTF("%s size: %d", p->name, p->size); in hda_print_cmd_ctl_data()
731 DPRINTF("%s dma_vaddr: %p", p->name, p->dma_vaddr); in hda_print_cmd_ctl_data()
732 DPRINTF("%s wp: 0x%x", p->name, p->wp); in hda_print_cmd_ctl_data()
733 DPRINTF("%s rp: 0x%x", p->name, p->rp); in hda_print_cmd_ctl_data()
743 struct hda_codec_cmd_ctl *corb = &sc->corb; in hda_corb_start()
749 corb->name = "CORB"; in hda_corb_start()
753 corb->size = hda_corb_sizes[corbsize]; in hda_corb_start()
755 if (!corb->size) { in hda_corb_start()
757 return (-1); in hda_corb_start()
766 corb->dma_vaddr = hda_dma_get_vaddr(sc, corbpaddr, in hda_corb_start()
767 HDA_CORB_ENTRY_LEN * corb->size); in hda_corb_start()
768 if (!corb->dma_vaddr) { in hda_corb_start()
770 return (-1); in hda_corb_start()
773 corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP); in hda_corb_start()
774 corb->rp = hda_get_reg_by_offset(sc, HDAC_CORBRP); in hda_corb_start()
776 corb->run = 1; in hda_corb_start()
786 struct hda_codec_cmd_ctl *corb = &sc->corb; in hda_corb_run()
790 corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP); in hda_corb_run()
791 if (corb->wp >= corb->size) { in hda_corb_run()
792 DPRINTF("Invalid HDAC_CORBWP %u >= size %u", corb->wp, in hda_corb_run()
793 corb->size); in hda_corb_run()
794 return (-1); in hda_corb_run()
797 while (corb->rp != corb->wp && corb->run) { in hda_corb_run()
798 corb->rp++; in hda_corb_run()
799 corb->rp %= corb->size; in hda_corb_run()
801 verb = hda_dma_ld_dword((uint8_t *)corb->dma_vaddr + in hda_corb_run()
802 HDA_CORB_ENTRY_LEN * corb->rp); in hda_corb_run()
808 hda_set_reg_by_offset(sc, HDAC_CORBRP, corb->rp); in hda_corb_run()
810 if (corb->run) in hda_corb_run()
819 struct hda_codec_cmd_ctl *rirb = &sc->rirb; in hda_rirb_start()
825 rirb->name = "RIRB"; in hda_rirb_start()
829 rirb->size = hda_rirb_sizes[rirbsize]; in hda_rirb_start()
831 if (!rirb->size) { in hda_rirb_start()
833 return (-1); in hda_rirb_start()
842 rirb->dma_vaddr = hda_dma_get_vaddr(sc, rirbpaddr, in hda_rirb_start()
843 HDA_RIRB_ENTRY_LEN * rirb->size); in hda_rirb_start()
844 if (!rirb->dma_vaddr) { in hda_rirb_start()
846 return (-1); in hda_rirb_start()
849 rirb->wp = hda_get_reg_by_offset(sc, HDAC_RIRBWP); in hda_rirb_start()
850 rirb->rp = 0x0000; in hda_rirb_start()
852 rirb->run = 1; in hda_rirb_start()
862 struct pci_devinst *pi = sc->pci_dev; in hda_dma_get_vaddr()
866 return (paddr_guest2host(pi->pi_vmctx, (uintptr_t)dma_paddr, len)); in hda_dma_get_vaddr()
882 hda_get_stream_by_offsets(uint32_t offset, uint8_t reg_offset) in hda_get_stream_by_offsets() argument
884 uint8_t stream_ind = (offset - reg_offset) >> 5; in hda_get_stream_by_offsets()
898 hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old __unused) in hda_set_gctl() argument
900 uint32_t value = hda_get_reg_by_offset(sc, offset); in hda_set_gctl()
908 hda_set_statests(struct hda_softc *sc, uint32_t offset, uint32_t old) in hda_set_statests() argument
910 uint32_t value = hda_get_reg_by_offset(sc, offset); in hda_set_statests()
912 hda_set_reg_by_offset(sc, offset, old); in hda_set_statests()
915 hda_set_field_by_offset(sc, offset, value & HDA_STATESTS_IRQ_MASK, 0); in hda_set_statests()
921 hda_set_corbwp(struct hda_softc *sc, uint32_t offset __unused, in hda_set_corbwp()
928 hda_set_corbctl(struct hda_softc *sc, uint32_t offset, uint32_t old) in hda_set_corbctl() argument
930 uint32_t value = hda_get_reg_by_offset(sc, offset); in hda_set_corbctl()
940 corb = &sc->corb; in hda_set_corbctl()
948 hda_set_rirbctl(struct hda_softc *sc, uint32_t offset, uint32_t old __unused) in hda_set_rirbctl() argument
950 uint32_t value = hda_get_reg_by_offset(sc, offset); in hda_set_rirbctl()
958 rirb = &sc->rirb; in hda_set_rirbctl()
964 hda_set_rirbsts(struct hda_softc *sc, uint32_t offset, uint32_t old) in hda_set_rirbsts() argument
966 uint32_t value = hda_get_reg_by_offset(sc, offset); in hda_set_rirbsts()
968 hda_set_reg_by_offset(sc, offset, old); in hda_set_rirbsts()
971 hda_set_field_by_offset(sc, offset, value & HDA_RIRBSTS_IRQ_MASK, 0); in hda_set_rirbsts()
977 hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset, uint32_t old) in hda_set_dpiblbase() argument
979 uint32_t value = hda_get_reg_by_offset(sc, offset); in hda_set_dpiblbase()
994 sc->dma_pib_vaddr = hda_dma_get_vaddr(sc, dpibpaddr, in hda_set_dpiblbase()
996 if (!sc->dma_pib_vaddr) { in hda_set_dpiblbase()
1003 sc->dma_pib_vaddr = NULL; in hda_set_dpiblbase()
1009 hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old) in hda_set_sdctl() argument
1011 uint8_t stream_ind = hda_get_stream_by_offsets(offset, HDAC_SDCTL0); in hda_set_sdctl()
1012 uint32_t value = hda_get_reg_by_offset(sc, offset); in hda_set_sdctl()
1015 DPRINTF("stream_ind: 0x%x old: 0x%x value: 0x%x", in hda_set_sdctl()
1034 hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old __unused) in hda_set_sdctl2() argument
1036 uint32_t value = hda_get_reg_by_offset(sc, offset); in hda_set_sdctl2()
1038 hda_set_field_by_offset(sc, offset - 2, 0x00ff0000, value << 16); in hda_set_sdctl2()
1042 hda_set_sdsts(struct hda_softc *sc, uint32_t offset, uint32_t old) in hda_set_sdsts() argument
1044 uint32_t value = hda_get_reg_by_offset(sc, offset); in hda_set_sdsts()
1046 hda_set_reg_by_offset(sc, offset, old); in hda_set_sdsts()
1049 hda_set_field_by_offset(sc, offset, value & HDA_SDSTS_IRQ_MASK, 0); in hda_set_sdsts()
1061 assert(hci->hda); in hda_signal_state_change()
1063 DPRINTF("cad: 0x%x", hci->cad); in hda_signal_state_change()
1065 sc = hci->hda; in hda_signal_state_change()
1066 sdiwake = 1 << hci->cad; in hda_signal_state_change()
1083 assert(hci->cad <= HDA_CODEC_MAX); in hda_response()
1085 response_ex = hci->cad | unsol; in hda_response()
1087 sc = hci->hda; in hda_response()
1090 rirb = &sc->rirb; in hda_response()
1092 if (rirb->run) { in hda_response()
1093 rirb->wp++; in hda_response()
1094 rirb->wp %= rirb->size; in hda_response()
1096 hda_dma_st_dword((uint8_t *)rirb->dma_vaddr + in hda_response()
1097 HDA_RIRB_ENTRY_LEN * rirb->wp, response); in hda_response()
1098 hda_dma_st_dword((uint8_t *)rirb->dma_vaddr + in hda_response()
1099 HDA_RIRB_ENTRY_LEN * rirb->wp + 0x04, response_ex); in hda_response()
1101 hda_set_reg_by_offset(sc, HDAC_RIRBWP, rirb->wp); in hda_response()
1103 sc->rirb_cnt++; in hda_response()
1107 if (sc->rirb_cnt == rintcnt) in hda_response()
1128 assert(hci->hda); in hda_transfer()
1134 return (-1); in hda_transfer()
1137 sc = hci->hda; in hda_transfer()
1140 stream_ind = sc->stream_map[dir][stream]; in hda_transfer()
1147 st = &sc->streams[stream_ind]; in hda_transfer()
1148 if (!st->run) { in hda_transfer()
1149 DPRINTF("Stream 0x%x stopped", stream); in hda_transfer()
1150 return (-1); in hda_transfer()
1153 assert(st->stream == stream); in hda_transfer()
1159 bdl = st->bdl; in hda_transfer()
1161 assert(st->be < st->bdl_cnt); in hda_transfer()
1162 assert(st->bp < bdl[st->be].len); in hda_transfer()
1166 bdle_desc = &bdl[st->be]; in hda_transfer()
1170 (uint8_t *)bdle_desc->addr + st->bp); in hda_transfer()
1172 hda_dma_st_dword((uint8_t *)bdle_desc->addr + in hda_transfer()
1173 st->bp, *(uint32_t *)buf); in hda_transfer()
1176 st->bp += HDA_DMA_ACCESS_LEN; in hda_transfer()
1178 left -= HDA_DMA_ACCESS_LEN; in hda_transfer()
1180 if (st->bp == bdle_desc->len) { in hda_transfer()
1181 st->bp = 0; in hda_transfer()
1182 if (bdle_desc->ioc) in hda_transfer()
1184 st->be++; in hda_transfer()
1185 if (st->be == st->bdl_cnt) { in hda_transfer()
1186 st->be = 0; in hda_transfer()
1189 bdle_desc = &bdl[st->be]; in hda_transfer()
1212 if (sc->dma_pib_vaddr) in hda_set_pib()
1213 *(uint32_t *)((uint8_t *)sc->dma_pib_vaddr + stream_ind * in hda_set_pib()
1255 return (-1); in pci_hda_init()
1257 sc->pci_dev = pi; in pci_hda_init()
1258 pi->pi_arg = sc; in pci_hda_init()
1264 pci_hda_write(struct pci_devinst *pi, int baridx, uint64_t offset, int size, in pci_hda_write() argument
1267 struct hda_softc *sc = pi->pi_arg; in pci_hda_write()
1274 DPRINTF("offset: 0x%lx value: 0x%lx", offset, value); in pci_hda_write()
1276 err = hda_write(sc, offset, size, value); in pci_hda_write()
1281 pci_hda_read(struct pci_devinst *pi, int baridx, uint64_t offset, int size) in pci_hda_read() argument
1283 struct hda_softc *sc = pi->pi_arg; in pci_hda_read()
1290 value = hda_read(sc, offset); in pci_hda_read()
1292 DPRINTF("offset: 0x%lx value: 0x%lx", offset, value); in pci_hda_read()