Lines Matching +full:gemini +full:- +full:pci
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
6 * Copyright (c) 2008-2012 Alexander Motin <mav@FreeBSD.org>
40 #include <dev/pci/pcireg.h>
41 #include <dev/pci/pcivar.h>
47 #include <dev/sound/pci/hda/hdac_private.h>
48 #include <dev/sound/pci/hda/hdac_reg.h>
49 #include <dev/sound/pci/hda/hda_reg.h>
50 #include <dev/sound/pci/hda/hdac.h>
54 #define hdac_lock(sc) snd_mtxlock((sc)->lock)
55 #define hdac_unlock(sc) snd_mtxunlock((sc)->lock)
56 #define hdac_lockassert(sc) snd_mtxassert((sc)->lock)
80 { HDA_INTEL_CMLKLP, "Intel Comet Lake-LP", 0, 0 },
81 { HDA_INTEL_CMLKH, "Intel Comet Lake-H", 0, 0 },
88 { HDA_INTEL_BXTNT, "Intel Broxton-T", 0, 0 },
98 { HDA_INTEL_LPTLP1, "Intel Lynx Point-LP", 0, 0 },
99 { HDA_INTEL_LPTLP2, "Intel Lynx Point-LP", 0, 0 },
100 { HDA_INTEL_SRPTLP, "Intel Sunrise Point-LP", 0, 0 },
101 { HDA_INTEL_KBLKLP, "Intel Kaby Lake-LP", 0, 0 },
104 { HDA_INTEL_KBLKH, "Intel Kaby Lake-H", 0, 0 },
106 { HDA_INTEL_CMLKS, "Intel Comet Lake-S", 0, 0 },
110 { HDA_INTEL_TGLKH, "Intel Tiger Lake-H", 0, 0 },
111 { HDA_INTEL_GMLK, "Intel Gemini Lake", 0, 0 },
113 { HDA_INTEL_ALLKM, "Intel Alder Lake-M", 0, 0 },
114 { HDA_INTEL_ALLKN, "Intel Alder Lake-N", 0, 0 },
115 { HDA_INTEL_ALLKP1, "Intel Alder Lake-P", 0, 0 },
116 { HDA_INTEL_ALLKP2, "Intel Alder Lake-P", 0, 0 },
117 { HDA_INTEL_ALLKPS, "Intel Alder Lake-PS", 0, 0 },
118 { HDA_INTEL_RPTLK1, "Intel Raptor Lake-P", 0, 0 },
119 { HDA_INTEL_RPTLK2, "Intel Raptor Lake-P", 0, 0 },
120 { HDA_INTEL_RPTLK3, "Intel Raptor Lake-S", 0, 0 },
121 { HDA_INTEL_MTL, "Intel Meteor Lake-P", 0, 0 },
122 { HDA_INTEL_ARLS, "Intel Arrow Lake-S", 0, 0 },
124 { HDA_INTEL_LNLP, "Intel Lunar Lake-P", 0, 0 },
137 { HDA_INTEL_BXTNP, "Intel Broxton-P", 0, 0 },
203 { HDA_AMD_HUDSON2, "AMD Hudson-2", 0, 0 },
273 if (resource_string_value(device_get_name(sc->dev), in hdac_config_fetch()
274 device_get_unit(sc->dev), "config", &res) != 0) in hdac_config_fetch()
279 device_printf(sc->dev, "Config options:"); in hdac_config_fetch()
295 len = j - i; in hdac_config_fetch()
302 hdac_quirks_tab[k].key, len - inv) != 0) in hdac_config_fetch()
304 if (len - inv != strlen(hdac_quirks_tab[k].key)) in hdac_config_fetch()
336 * a reset or a wake-up event. in hdac_one_intr()
352 rirbsts = HDAC_READ_1(&sc->mem, HDAC_RIRBSTS); in hdac_one_intr()
354 HDAC_WRITE_1(&sc->mem, in hdac_one_intr()
357 rirbsts = HDAC_READ_1(&sc->mem, HDAC_RIRBSTS); in hdac_one_intr()
359 if (sc->unsolq_rp != sc->unsolq_wp) in hdac_one_intr()
360 taskqueue_enqueue(taskqueue_thread, &sc->unsolq_task); in hdac_one_intr()
364 for (i = 0; i < sc->num_ss; i++) { in hdac_one_intr()
367 HDAC_WRITE_1(&sc->mem, (i << 5) + HDAC_SDSTS, in hdac_one_intr()
369 if ((dev = sc->streams[i].dev) != NULL) { in hdac_one_intr()
371 sc->streams[i].dir, sc->streams[i].stream); in hdac_one_intr()
393 * from zero to one. GIS is formed by OR-ing multiple hardware in hdac_intr_handler()
397 * re-examine GIS then we can leave it set and never get an interrupt in hdac_intr_handler()
401 intsts = HDAC_READ_4(&sc->mem, HDAC_INTSTS); in hdac_intr_handler()
404 intsts = HDAC_READ_4(&sc->mem, HDAC_INTSTS); in hdac_intr_handler()
418 if (sc->polling == 0) { in hdac_poll_callback()
422 callout_reset(&sc->poll_callout, sc->poll_ival, hdac_poll_callback, sc); in hdac_poll_callback()
442 for (i = 0; i < sc->num_iss; i++) in hdac_reset()
443 HDAC_WRITE_4(&sc->mem, HDAC_ISDCTL(sc, i), 0x0); in hdac_reset()
444 for (i = 0; i < sc->num_oss; i++) in hdac_reset()
445 HDAC_WRITE_4(&sc->mem, HDAC_OSDCTL(sc, i), 0x0); in hdac_reset()
446 for (i = 0; i < sc->num_bss; i++) in hdac_reset()
447 HDAC_WRITE_4(&sc->mem, HDAC_BSDCTL(sc, i), 0x0); in hdac_reset()
452 HDAC_WRITE_1(&sc->mem, HDAC_CORBCTL, 0x0); in hdac_reset()
453 HDAC_WRITE_1(&sc->mem, HDAC_RIRBCTL, 0x0); in hdac_reset()
458 HDAC_WRITE_4(&sc->mem, HDAC_DPIBLBASE, 0x0); in hdac_reset()
459 HDAC_WRITE_4(&sc->mem, HDAC_DPIBUBASE, 0x0); in hdac_reset()
465 gctl = HDAC_READ_4(&sc->mem, HDAC_GCTL); in hdac_reset()
466 HDAC_WRITE_4(&sc->mem, HDAC_GCTL, gctl & ~HDAC_GCTL_CRST); in hdac_reset()
469 gctl = HDAC_READ_4(&sc->mem, HDAC_GCTL); in hdac_reset()
473 } while (--count); in hdac_reset()
475 device_printf(sc->dev, "Unable to put hdac in reset\n"); in hdac_reset()
479 /* If wakeup is not requested - leave the controller in reset state. */ in hdac_reset()
484 gctl = HDAC_READ_4(&sc->mem, HDAC_GCTL); in hdac_reset()
485 HDAC_WRITE_4(&sc->mem, HDAC_GCTL, gctl | HDAC_GCTL_CRST); in hdac_reset()
488 gctl = HDAC_READ_4(&sc->mem, HDAC_GCTL); in hdac_reset()
492 } while (--count); in hdac_reset()
494 device_printf(sc->dev, "Device stuck in reset\n"); in hdac_reset()
523 gcap = HDAC_READ_2(&sc->mem, HDAC_GCAP); in hdac_get_capabilities()
524 sc->num_iss = HDAC_GCAP_ISS(gcap); in hdac_get_capabilities()
525 sc->num_oss = HDAC_GCAP_OSS(gcap); in hdac_get_capabilities()
526 sc->num_bss = HDAC_GCAP_BSS(gcap); in hdac_get_capabilities()
527 sc->num_ss = sc->num_iss + sc->num_oss + sc->num_bss; in hdac_get_capabilities()
528 sc->num_sdo = HDAC_GCAP_NSDO(gcap); in hdac_get_capabilities()
529 sc->support_64bit = (gcap & HDAC_GCAP_64OK) != 0; in hdac_get_capabilities()
530 if (sc->quirks_on & HDAC_QUIRK_64BIT) in hdac_get_capabilities()
531 sc->support_64bit = 1; in hdac_get_capabilities()
532 else if (sc->quirks_off & HDAC_QUIRK_64BIT) in hdac_get_capabilities()
533 sc->support_64bit = 0; in hdac_get_capabilities()
535 corbsize = HDAC_READ_1(&sc->mem, HDAC_CORBSIZE); in hdac_get_capabilities()
538 sc->corb_size = 256; in hdac_get_capabilities()
541 sc->corb_size = 16; in hdac_get_capabilities()
544 sc->corb_size = 2; in hdac_get_capabilities()
546 device_printf(sc->dev, "%s: Invalid corb size (%x)\n", in hdac_get_capabilities()
551 rirbsize = HDAC_READ_1(&sc->mem, HDAC_RIRBSIZE); in hdac_get_capabilities()
554 sc->rirb_size = 256; in hdac_get_capabilities()
557 sc->rirb_size = 16; in hdac_get_capabilities()
560 sc->rirb_size = 2; in hdac_get_capabilities()
562 device_printf(sc->dev, "%s: Invalid rirb size (%x)\n", in hdac_get_capabilities()
568 device_printf(sc->dev, "Caps: OSS %d, ISS %d, BSS %d, " in hdac_get_capabilities()
570 sc->num_oss, sc->num_iss, sc->num_bss, 1 << sc->num_sdo, in hdac_get_capabilities()
571 sc->support_64bit ? ", 64bit" : "", in hdac_get_capabilities()
572 sc->corb_size, sc->rirb_size); in hdac_get_capabilities()
592 dma->dma_paddr = segs[0].ds_addr; in hdac_dma_cb()
615 bus_get_dma_tag(sc->dev), /* parent */ in hdac_dma_alloc()
618 (sc->support_64bit) ? BUS_SPACE_MAXADDR : in hdac_dma_alloc()
629 &dma->dma_tag); /* dmat */ in hdac_dma_alloc()
631 device_printf(sc->dev, "%s: bus_dma_tag_create failed (%d)\n", in hdac_dma_alloc()
639 result = bus_dmamem_alloc(dma->dma_tag, (void **)&dma->dma_vaddr, in hdac_dma_alloc()
641 ((sc->flags & HDAC_F_DMA_NOCACHE) ? BUS_DMA_NOCACHE : in hdac_dma_alloc()
643 &dma->dma_map); in hdac_dma_alloc()
645 device_printf(sc->dev, "%s: bus_dmamem_alloc failed (%d)\n", in hdac_dma_alloc()
650 dma->dma_size = roundsz; in hdac_dma_alloc()
655 result = bus_dmamap_load(dma->dma_tag, dma->dma_map, in hdac_dma_alloc()
656 (void *)dma->dma_vaddr, roundsz, hdac_dma_cb, (void *)dma, 0); in hdac_dma_alloc()
657 if (result != 0 || dma->dma_paddr == 0) { in hdac_dma_alloc()
660 device_printf(sc->dev, "%s: bus_dmamem_load failed (%d)\n", in hdac_dma_alloc()
666 device_printf(sc->dev, "%s: size=%ju -> roundsz=%ju\n", in hdac_dma_alloc()
687 if (dma->dma_paddr != 0) { in hdac_dma_free()
689 bus_dmamap_sync(dma->dma_tag, dma->dma_map, in hdac_dma_free()
691 bus_dmamap_unload(dma->dma_tag, dma->dma_map); in hdac_dma_free()
692 dma->dma_paddr = 0; in hdac_dma_free()
694 if (dma->dma_vaddr != NULL) { in hdac_dma_free()
695 bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map); in hdac_dma_free()
696 dma->dma_vaddr = NULL; in hdac_dma_free()
698 if (dma->dma_tag != NULL) { in hdac_dma_free()
699 bus_dma_tag_destroy(dma->dma_tag); in hdac_dma_free()
700 dma->dma_tag = NULL; in hdac_dma_free()
702 dma->dma_size = 0; in hdac_dma_free()
716 mem = &sc->mem; in hdac_mem_alloc()
717 mem->mem_rid = PCIR_BAR(0); in hdac_mem_alloc()
718 mem->mem_res = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, in hdac_mem_alloc()
719 &mem->mem_rid, RF_ACTIVE); in hdac_mem_alloc()
720 if (mem->mem_res == NULL) { in hdac_mem_alloc()
721 device_printf(sc->dev, in hdac_mem_alloc()
725 mem->mem_tag = rman_get_bustag(mem->mem_res); in hdac_mem_alloc()
726 mem->mem_handle = rman_get_bushandle(mem->mem_res); in hdac_mem_alloc()
741 mem = &sc->mem; in hdac_mem_free()
742 if (mem->mem_res != NULL) in hdac_mem_free()
743 bus_release_resource(sc->dev, SYS_RES_MEMORY, mem->mem_rid, in hdac_mem_free()
744 mem->mem_res); in hdac_mem_free()
745 mem->mem_res = NULL; in hdac_mem_free()
759 irq = &sc->irq; in hdac_irq_alloc()
760 irq->irq_rid = 0x0; in hdac_irq_alloc()
762 if ((sc->quirks_off & HDAC_QUIRK_MSI) == 0 && in hdac_irq_alloc()
763 (result = pci_msi_count(sc->dev)) == 1 && in hdac_irq_alloc()
764 pci_alloc_msi(sc->dev, &result) == 0) in hdac_irq_alloc()
765 irq->irq_rid = 0x1; in hdac_irq_alloc()
767 irq->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, in hdac_irq_alloc()
768 &irq->irq_rid, RF_SHAREABLE | RF_ACTIVE); in hdac_irq_alloc()
769 if (irq->irq_res == NULL) { in hdac_irq_alloc()
770 device_printf(sc->dev, "%s: Unable to allocate irq\n", in hdac_irq_alloc()
774 result = bus_setup_intr(sc->dev, irq->irq_res, INTR_MPSAFE | INTR_TYPE_AV, in hdac_irq_alloc()
775 NULL, hdac_intr_handler, sc, &irq->irq_handle); in hdac_irq_alloc()
777 device_printf(sc->dev, in hdac_irq_alloc()
801 irq = &sc->irq; in hdac_irq_free()
802 if (irq->irq_res != NULL && irq->irq_handle != NULL) in hdac_irq_free()
803 bus_teardown_intr(sc->dev, irq->irq_res, irq->irq_handle); in hdac_irq_free()
804 if (irq->irq_res != NULL) in hdac_irq_free()
805 bus_release_resource(sc->dev, SYS_RES_IRQ, irq->irq_rid, in hdac_irq_free()
806 irq->irq_res); in hdac_irq_free()
807 if (irq->irq_rid == 0x1) in hdac_irq_free()
808 pci_release_msi(sc->dev); in hdac_irq_free()
809 irq->irq_handle = NULL; in hdac_irq_free()
810 irq->irq_res = NULL; in hdac_irq_free()
811 irq->irq_rid = 0x0; in hdac_irq_free()
827 switch (sc->corb_size) { in hdac_corb_init()
838 panic("%s: Invalid CORB size (%x)\n", __func__, sc->corb_size); in hdac_corb_init()
840 HDAC_WRITE_1(&sc->mem, HDAC_CORBSIZE, corbsize); in hdac_corb_init()
843 corbpaddr = (uint64_t)sc->corb_dma.dma_paddr; in hdac_corb_init()
844 HDAC_WRITE_4(&sc->mem, HDAC_CORBLBASE, (uint32_t)corbpaddr); in hdac_corb_init()
845 HDAC_WRITE_4(&sc->mem, HDAC_CORBUBASE, (uint32_t)(corbpaddr >> 32)); in hdac_corb_init()
848 sc->corb_wp = 0; in hdac_corb_init()
849 HDAC_WRITE_2(&sc->mem, HDAC_CORBWP, sc->corb_wp); in hdac_corb_init()
850 HDAC_WRITE_2(&sc->mem, HDAC_CORBRP, HDAC_CORBRP_CORBRPRST); in hdac_corb_init()
857 HDAC_WRITE_2(&sc->mem, HDAC_CORBRP, 0x0); in hdac_corb_init()
861 HDAC_WRITE_1(&sc->mem, HDAC_CORBCTL, HDAC_CORBCTL_CMEIE); in hdac_corb_init()
878 switch (sc->rirb_size) { in hdac_rirb_init()
889 panic("%s: Invalid RIRB size (%x)\n", __func__, sc->rirb_size); in hdac_rirb_init()
891 HDAC_WRITE_1(&sc->mem, HDAC_RIRBSIZE, rirbsize); in hdac_rirb_init()
894 rirbpaddr = (uint64_t)sc->rirb_dma.dma_paddr; in hdac_rirb_init()
895 HDAC_WRITE_4(&sc->mem, HDAC_RIRBLBASE, (uint32_t)rirbpaddr); in hdac_rirb_init()
896 HDAC_WRITE_4(&sc->mem, HDAC_RIRBUBASE, (uint32_t)(rirbpaddr >> 32)); in hdac_rirb_init()
899 sc->rirb_rp = 0; in hdac_rirb_init()
900 HDAC_WRITE_2(&sc->mem, HDAC_RIRBWP, HDAC_RIRBWP_RIRBWPRST); in hdac_rirb_init()
903 HDAC_WRITE_2(&sc->mem, HDAC_RINTCNT, sc->rirb_size / 2); in hdac_rirb_init()
907 HDAC_WRITE_1(&sc->mem, HDAC_RIRBCTL, in hdac_rirb_init()
910 HDAC_WRITE_1(&sc->mem, HDAC_RIRBCTL, HDAC_RIRBCTL_RINTCTL); in hdac_rirb_init()
917 * read-only from now on. in hdac_rirb_init()
919 bus_dmamap_sync(sc->rirb_dma.dma_tag, sc->rirb_dma.dma_map, in hdac_rirb_init()
933 corbctl = HDAC_READ_1(&sc->mem, HDAC_CORBCTL); in hdac_corb_start()
935 HDAC_WRITE_1(&sc->mem, HDAC_CORBCTL, corbctl); in hdac_corb_start()
948 rirbctl = HDAC_READ_1(&sc->mem, HDAC_RIRBCTL); in hdac_rirb_start()
950 HDAC_WRITE_1(&sc->mem, HDAC_RIRBCTL, rirbctl); in hdac_rirb_start()
962 rirb_base = (struct hdac_rirb *)sc->rirb_dma.dma_vaddr; in hdac_rirb_flush()
963 rirbwp = HDAC_READ_1(&sc->mem, HDAC_RIRBWP); in hdac_rirb_flush()
964 bus_dmamap_sync(sc->rirb_dma.dma_tag, sc->rirb_dma.dma_map, in hdac_rirb_flush()
968 while (sc->rirb_rp != rirbwp) { in hdac_rirb_flush()
969 sc->rirb_rp++; in hdac_rirb_flush()
970 sc->rirb_rp %= sc->rirb_size; in hdac_rirb_flush()
971 rirb = &rirb_base[sc->rirb_rp]; in hdac_rirb_flush()
972 resp = le32toh(rirb->response); in hdac_rirb_flush()
973 resp_ex = le32toh(rirb->response_ex); in hdac_rirb_flush()
976 sc->unsolq[sc->unsolq_wp++] = resp; in hdac_rirb_flush()
977 sc->unsolq_wp %= HDAC_UNSOLQ_MAX; in hdac_rirb_flush()
978 sc->unsolq[sc->unsolq_wp++] = cad; in hdac_rirb_flush()
979 sc->unsolq_wp %= HDAC_UNSOLQ_MAX; in hdac_rirb_flush()
980 } else if (sc->codecs[cad].pending <= 0) { in hdac_rirb_flush()
981 device_printf(sc->dev, "Unexpected unsolicited " in hdac_rirb_flush()
984 sc->codecs[cad].response = resp; in hdac_rirb_flush()
985 sc->codecs[cad].pending--; in hdac_rirb_flush()
990 bus_dmamap_sync(sc->rirb_dma.dma_tag, sc->rirb_dma.dma_map, in hdac_rirb_flush()
1003 if (sc->unsolq_st == HDAC_UNSOLQ_READY) { in hdac_unsolq_flush()
1004 sc->unsolq_st = HDAC_UNSOLQ_BUSY; in hdac_unsolq_flush()
1005 while (sc->unsolq_rp != sc->unsolq_wp) { in hdac_unsolq_flush()
1006 resp = sc->unsolq[sc->unsolq_rp++]; in hdac_unsolq_flush()
1007 sc->unsolq_rp %= HDAC_UNSOLQ_MAX; in hdac_unsolq_flush()
1008 cad = sc->unsolq[sc->unsolq_rp++]; in hdac_unsolq_flush()
1009 sc->unsolq_rp %= HDAC_UNSOLQ_MAX; in hdac_unsolq_flush()
1010 if ((child = sc->codecs[cad].dev) != NULL && in hdac_unsolq_flush()
1015 sc->unsolq_st = HDAC_UNSOLQ_READY; in hdac_unsolq_flush()
1035 sc->codecs[cad].response = HDA_INVALID; in hdac_send_command()
1037 sc->codecs[cad].pending++; in hdac_send_command()
1038 sc->corb_wp++; in hdac_send_command()
1039 sc->corb_wp %= sc->corb_size; in hdac_send_command()
1040 corb = (uint32_t *)sc->corb_dma.dma_vaddr; in hdac_send_command()
1041 bus_dmamap_sync(sc->corb_dma.dma_tag, in hdac_send_command()
1042 sc->corb_dma.dma_map, BUS_DMASYNC_PREWRITE); in hdac_send_command()
1043 corb[sc->corb_wp] = htole32(verb); in hdac_send_command()
1044 bus_dmamap_sync(sc->corb_dma.dma_tag, in hdac_send_command()
1045 sc->corb_dma.dma_map, BUS_DMASYNC_POSTWRITE); in hdac_send_command()
1046 HDAC_WRITE_2(&sc->mem, HDAC_CORBWP, sc->corb_wp); in hdac_send_command()
1052 } while (sc->codecs[cad].pending != 0 && --timeout); in hdac_send_command()
1054 if (sc->codecs[cad].pending != 0) { in hdac_send_command()
1055 device_printf(sc->dev, "Command 0x%08x timeout on address %d\n", in hdac_send_command()
1057 sc->codecs[cad].pending = 0; in hdac_send_command()
1060 if (sc->unsolq_rp != sc->unsolq_wp) in hdac_send_command()
1061 taskqueue_enqueue(taskqueue_thread, &sc->unsolq_task); in hdac_send_command()
1062 return (sc->codecs[cad].response); in hdac_send_command()
1140 int i, devid = -1; in hdac_attach()
1148 device_printf(dev, "PCI card vendor: 0x%04x, device: 0x%04x\n", in hdac_attach()
1172 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "HDA driver mutex"); in hdac_attach()
1173 sc->dev = dev; in hdac_attach()
1174 TASK_INIT(&sc->unsolq_task, 0, hdac_unsolq_task, sc); in hdac_attach()
1175 callout_init(&sc->poll_callout, 1); in hdac_attach()
1177 sc->codecs[i].dev = NULL; in hdac_attach()
1179 sc->quirks_on = hdac_devices[devid].quirks_on; in hdac_attach()
1180 sc->quirks_off = hdac_devices[devid].quirks_off; in hdac_attach()
1182 sc->quirks_on = 0; in hdac_attach()
1183 sc->quirks_off = 0; in hdac_attach()
1188 sc->quirks_off |= HDAC_QUIRK_MSI; in hdac_attach()
1190 sc->quirks_on |= HDAC_QUIRK_MSI; in hdac_attach()
1191 sc->quirks_off |= ~HDAC_QUIRK_MSI; in hdac_attach()
1194 hdac_config_fetch(sc, &sc->quirks_on, &sc->quirks_off); in hdac_attach()
1196 device_printf(sc->dev, in hdac_attach()
1198 sc->quirks_on, sc->quirks_off); in hdac_attach()
1200 sc->poll_ival = hz; in hdac_attach()
1203 sc->polling = 1; in hdac_attach()
1205 sc->polling = 0; in hdac_attach()
1211 /* TCSEL -> TC0 */ in hdac_attach()
1215 device_printf(dev, "TCSEL: 0x%02d -> 0x%02d\n", v, in hdac_attach()
1221 sc->flags |= HDAC_F_DMA_NOCACHE; in hdac_attach()
1226 sc->flags &= ~HDAC_F_DMA_NOCACHE; in hdac_attach()
1236 * http://msdn2.microsoft.com/en-us/library/ms790324.aspx in hdac_attach()
1241 sc->flags &= ~HDAC_F_DMA_NOCACHE; in hdac_attach()
1260 sc->flags |= HDAC_F_DMA_NOCACHE; in hdac_attach()
1271 (sc->flags & HDAC_F_DMA_NOCACHE) ? in hdac_attach()
1287 result = hdac_dma_alloc(sc, &sc->corb_dma, in hdac_attach()
1288 sc->corb_size * sizeof(uint32_t)); in hdac_attach()
1291 result = hdac_dma_alloc(sc, &sc->rirb_dma, in hdac_attach()
1292 sc->rirb_size * sizeof(struct hdac_rirb)); in hdac_attach()
1295 sc->streams = malloc(sizeof(struct hdac_stream) * sc->num_ss, in hdac_attach()
1297 for (i = 0; i < sc->num_ss; i++) { in hdac_attach()
1298 result = hdac_dma_alloc(sc, &sc->streams[i].bdl, in hdac_attach()
1303 if (sc->quirks_on & HDAC_QUIRK_DMAPOS) { in hdac_attach()
1304 if (hdac_dma_alloc(sc, &sc->pos_dma, (sc->num_ss) * 8) != 0) { in hdac_attach()
1308 "(non-fatal)\n"); in hdac_attach()
1311 uint64_t addr = sc->pos_dma.dma_paddr; in hdac_attach()
1313 HDAC_WRITE_4(&sc->mem, HDAC_DPIBUBASE, addr >> 32); in hdac_attach()
1314 HDAC_WRITE_4(&sc->mem, HDAC_DPIBLBASE, in hdac_attach()
1321 bus_get_dma_tag(sc->dev), /* parent */ in hdac_attach()
1324 (sc->support_64bit) ? BUS_SPACE_MAXADDR : in hdac_attach()
1335 &sc->chan_dmat); /* dmat */ in hdac_attach()
1357 sc->intrhook.ich_func = hdac_attach2; in hdac_attach()
1358 sc->intrhook.ich_arg = (void *)sc; in hdac_attach()
1359 if (cold == 0 || config_intrhook_establish(&sc->intrhook) != 0) { in hdac_attach()
1360 sc->intrhook.ich_func = NULL; in hdac_attach()
1368 if (sc->streams != NULL) in hdac_attach()
1369 for (i = 0; i < sc->num_ss; i++) in hdac_attach()
1370 hdac_dma_free(sc, &sc->streams[i].bdl); in hdac_attach()
1371 free(sc->streams, M_HDAC); in hdac_attach()
1372 hdac_dma_free(sc, &sc->rirb_dma); in hdac_attach()
1373 hdac_dma_free(sc, &sc->corb_dma); in hdac_attach()
1375 snd_mtxfree(sc->lock); in hdac_attach()
1388 dev = oidp->oid_arg1; in sysctl_hdac_pindump()
1394 if (err != 0 || req->newptr == NULL || val == 0) in sysctl_hdac_pindump()
1462 if (sc->polling == 0) in hdac_poll_reinit()
1464 if (sc->unsol_registered > 0) in hdac_poll_reinit()
1466 for (i = 0; i < sc->num_ss; i++) { in hdac_poll_reinit()
1467 s = &sc->streams[i]; in hdac_poll_reinit()
1468 if (s->running == 0) in hdac_poll_reinit()
1470 pollticks = ((uint64_t)hz * s->blksz) / in hdac_poll_reinit()
1471 (hdac_mdata_rate(s->format) / 8); in hdac_poll_reinit()
1480 sc->poll_ival = min; in hdac_poll_reinit()
1482 callout_stop(&sc->poll_callout); in hdac_poll_reinit()
1484 callout_reset(&sc->poll_callout, 1, hdac_poll_callback, sc); in hdac_poll_reinit()
1495 dev = oidp->oid_arg1; in sysctl_hdac_polling()
1500 val = sc->polling; in sysctl_hdac_polling()
1504 if (err != 0 || req->newptr == NULL) in sysctl_hdac_polling()
1510 if (val != sc->polling) { in sysctl_hdac_polling()
1512 callout_stop(&sc->poll_callout); in sysctl_hdac_polling()
1514 callout_drain(&sc->poll_callout); in sysctl_hdac_polling()
1516 sc->polling = 0; in sysctl_hdac_polling()
1517 ctl = HDAC_READ_4(&sc->mem, HDAC_INTCTL); in sysctl_hdac_polling()
1519 HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, ctl); in sysctl_hdac_polling()
1521 ctl = HDAC_READ_4(&sc->mem, HDAC_INTCTL); in sysctl_hdac_polling()
1523 HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, ctl); in sysctl_hdac_polling()
1524 sc->polling = 1; in sysctl_hdac_polling()
1547 if (sc->intrhook.ich_func != NULL) { in hdac_attach2()
1548 config_intrhook_disestablish(&sc->intrhook); in hdac_attach2()
1549 sc->intrhook.ich_func = NULL; in hdac_attach2()
1553 device_printf(sc->dev, "Starting CORB Engine...\n"); in hdac_attach2()
1557 device_printf(sc->dev, "Starting RIRB Engine...\n"); in hdac_attach2()
1569 HDAC_WRITE_2(&sc->mem, HDAC_WAKEEN, 0); in hdac_attach2()
1572 * Read and clear post-reset SDI wake status. in hdac_attach2()
1575 statests = HDAC_READ_2(&sc->mem, HDAC_STATESTS); in hdac_attach2()
1576 HDAC_WRITE_2(&sc->mem, HDAC_STATESTS, statests); in hdac_attach2()
1579 device_printf(sc->dev, in hdac_attach2()
1582 HDAC_WRITE_4(&sc->mem, HDAC_GCTL, HDAC_READ_4(&sc->mem, HDAC_GCTL) | in hdac_attach2()
1584 if (sc->polling == 0) { in hdac_attach2()
1585 HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, in hdac_attach2()
1591 device_printf(sc->dev, "Scanning HDA codecs ...\n"); in hdac_attach2()
1597 device_printf(sc->dev, in hdac_attach2()
1608 device_printf(sc->dev, in hdac_attach2()
1612 sc->codecs[i].vendor_id = in hdac_attach2()
1614 sc->codecs[i].device_id = in hdac_attach2()
1616 sc->codecs[i].revision_id = in hdac_attach2()
1618 sc->codecs[i].stepping_id = in hdac_attach2()
1620 child = device_add_child(sc->dev, "hdacc", DEVICE_UNIT_ANY); in hdac_attach2()
1622 device_printf(sc->dev, in hdac_attach2()
1627 sc->codecs[i].dev = child; in hdac_attach2()
1630 bus_attach_children(sc->dev); in hdac_attach2()
1632 SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev), in hdac_attach2()
1633 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO, in hdac_attach2()
1634 "pindump", CTLTYPE_INT | CTLFLAG_RW, sc->dev, in hdac_attach2()
1635 sizeof(sc->dev), sysctl_hdac_pindump, "I", "Dump pin states/data"); in hdac_attach2()
1636 SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev), in hdac_attach2()
1637 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO, in hdac_attach2()
1638 "polling", CTLTYPE_INT | CTLFLAG_RW, sc->dev, in hdac_attach2()
1639 sizeof(sc->dev), sysctl_hdac_polling, "I", "Enable polling mode"); in hdac_attach2()
1655 callout_drain(&sc->poll_callout); in hdac_shutdown()
1656 taskqueue_drain(taskqueue_thread, &sc->unsolq_task); in hdac_shutdown()
1690 callout_stop(&sc->poll_callout); in hdac_suspend()
1693 callout_drain(&sc->poll_callout); in hdac_suspend()
1694 taskqueue_drain(taskqueue_thread, &sc->unsolq_task); in hdac_suspend()
1745 HDAC_WRITE_2(&sc->mem, HDAC_WAKEEN, 0); in hdac_resume()
1746 HDAC_WRITE_2(&sc->mem, HDAC_STATESTS, HDAC_STATESTS_SDIWAKE_MASK); in hdac_resume()
1751 HDAC_WRITE_4(&sc->mem, HDAC_GCTL, HDAC_READ_4(&sc->mem, HDAC_GCTL) | in hdac_resume()
1753 HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, HDAC_INTCTL_CIE | HDAC_INTCTL_GIE); in hdac_resume()
1781 callout_stop(&sc->poll_callout); in hdac_detach()
1784 callout_drain(&sc->poll_callout); in hdac_detach()
1785 taskqueue_drain(taskqueue_thread, &sc->unsolq_task); in hdac_detach()
1788 for (i = 0; i < sc->num_ss; i++) in hdac_detach()
1789 hdac_dma_free(sc, &sc->streams[i].bdl); in hdac_detach()
1790 free(sc->streams, M_HDAC); in hdac_detach()
1791 hdac_dma_free(sc, &sc->pos_dma); in hdac_detach()
1792 hdac_dma_free(sc, &sc->rirb_dma); in hdac_detach()
1793 hdac_dma_free(sc, &sc->corb_dma); in hdac_detach()
1794 if (sc->chan_dmat != NULL) { in hdac_detach()
1795 bus_dma_tag_destroy(sc->chan_dmat); in hdac_detach()
1796 sc->chan_dmat = NULL; in hdac_detach()
1799 snd_mtxfree(sc->lock); in hdac_detach()
1808 return (sc->chan_dmat); in hdac_get_dma_tag()
1839 sc->codecs[cad].vendor_id, sc->codecs[cad].device_id, in hdac_child_pnpinfo_method()
1840 sc->codecs[cad].revision_id, sc->codecs[cad].stepping_id); in hdac_child_pnpinfo_method()
1855 *result = sc->codecs[cad].vendor_id; in hdac_read_ivar()
1858 *result = sc->codecs[cad].device_id; in hdac_read_ivar()
1861 *result = sc->codecs[cad].revision_id; in hdac_read_ivar()
1864 *result = sc->codecs[cad].stepping_id; in hdac_read_ivar()
1873 *result = (sc->flags & HDAC_F_DMA_NOCACHE) != 0; in hdac_read_ivar()
1876 *result = (1 << (1 << sc->num_sdo)) - 1; in hdac_read_ivar()
1889 return (sc->lock); in hdac_get_mtx()
1905 ss = -1; in hdac_find_stream()
1908 for (i = 0; i < sc->num_iss; i++) { in hdac_find_stream()
1909 if (sc->streams[i].stream == stream) { in hdac_find_stream()
1915 for (i = 0; i < sc->num_oss; i++) { in hdac_find_stream()
1916 if (sc->streams[i + sc->num_iss].stream == stream) { in hdac_find_stream()
1917 ss = i + sc->num_iss; in hdac_find_stream()
1923 if (ss == -1) { in hdac_find_stream()
1924 for (i = 0; i < sc->num_bss; i++) { in hdac_find_stream()
1925 if (sc->streams[i + sc->num_iss + sc->num_oss].stream in hdac_find_stream()
1927 ss = i + sc->num_iss + sc->num_oss; in hdac_find_stream()
1953 bw *= 1 << (sc->num_sdo - stripe); in hdac_stream_alloc()
1954 prevbw = sc->sdo_bw_used; in hdac_stream_alloc()
1955 maxbw = 48000 * 960 * (1 << sc->num_sdo); in hdac_stream_alloc()
1957 prevbw = sc->codecs[cad].sdi_bw_used; in hdac_stream_alloc()
1963 bw + prevbw > maxbw ? " -- OVERFLOW!" : ""); in hdac_stream_alloc()
1968 sc->sdo_bw_used += bw; in hdac_stream_alloc()
1970 sc->codecs[cad].sdi_bw_used += bw; in hdac_stream_alloc()
1973 if (ss >= sc->num_iss + sc->num_oss) in hdac_stream_alloc()
1974 stream = 15 - (ss - sc->num_iss - sc->num_oss); in hdac_stream_alloc()
1975 else if (ss >= sc->num_iss) in hdac_stream_alloc()
1976 stream = ss - sc->num_iss + 1; in hdac_stream_alloc()
1980 sc->streams[ss].dev = child; in hdac_stream_alloc()
1981 sc->streams[ss].dir = dir; in hdac_stream_alloc()
1982 sc->streams[ss].stream = stream; in hdac_stream_alloc()
1983 sc->streams[ss].bw = bw; in hdac_stream_alloc()
1984 sc->streams[ss].format = format; in hdac_stream_alloc()
1985 sc->streams[ss].stripe = stripe; in hdac_stream_alloc()
1987 if (sc->pos_dma.dma_vaddr != NULL) in hdac_stream_alloc()
1988 *dmapos = (uint32_t *)(sc->pos_dma.dma_vaddr + ss * 8); in hdac_stream_alloc()
2006 sc->sdo_bw_used -= sc->streams[ss].bw; in hdac_stream_free()
2008 sc->codecs[cad].sdi_bw_used -= sc->streams[ss].bw; in hdac_stream_free()
2009 sc->streams[ss].stream = 0; in hdac_stream_free()
2010 sc->streams[ss].dev = NULL; in hdac_stream_free()
2028 bdle = (struct hdac_bdle *)sc->streams[ss].bdl.dma_vaddr; in hdac_stream_start()
2030 bdle->addrl = htole32((uint32_t)addr); in hdac_stream_start()
2031 bdle->addrh = htole32((uint32_t)(addr >> 32)); in hdac_stream_start()
2032 bdle->len = htole32(blksz); in hdac_stream_start()
2033 bdle->ioc = htole32(1); in hdac_stream_start()
2037 bus_dmamap_sync(sc->streams[ss].bdl.dma_tag, in hdac_stream_start()
2038 sc->streams[ss].bdl.dma_map, BUS_DMASYNC_PREWRITE); in hdac_stream_start()
2041 HDAC_WRITE_4(&sc->mem, off + HDAC_SDCBL, blksz * blkcnt); in hdac_stream_start()
2042 HDAC_WRITE_2(&sc->mem, off + HDAC_SDLVI, blkcnt - 1); in hdac_stream_start()
2043 addr = sc->streams[ss].bdl.dma_paddr; in hdac_stream_start()
2044 HDAC_WRITE_4(&sc->mem, off + HDAC_SDBDPL, (uint32_t)addr); in hdac_stream_start()
2045 HDAC_WRITE_4(&sc->mem, off + HDAC_SDBDPU, (uint32_t)(addr >> 32)); in hdac_stream_start()
2047 ctl = HDAC_READ_1(&sc->mem, off + HDAC_SDCTL2); in hdac_stream_start()
2055 ctl |= sc->streams[ss].stripe << HDAC_SDCTL2_STRIPE_SHIFT; in hdac_stream_start()
2056 HDAC_WRITE_1(&sc->mem, off + HDAC_SDCTL2, ctl); in hdac_stream_start()
2058 HDAC_WRITE_2(&sc->mem, off + HDAC_SDFMT, sc->streams[ss].format); in hdac_stream_start()
2060 ctl = HDAC_READ_4(&sc->mem, HDAC_INTCTL); in hdac_stream_start()
2062 HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, ctl); in hdac_stream_start()
2064 HDAC_WRITE_1(&sc->mem, off + HDAC_SDSTS, in hdac_stream_start()
2066 ctl = HDAC_READ_1(&sc->mem, off + HDAC_SDCTL0); in hdac_stream_start()
2069 HDAC_WRITE_1(&sc->mem, off + HDAC_SDCTL0, ctl); in hdac_stream_start()
2071 sc->streams[ss].blksz = blksz; in hdac_stream_start()
2072 sc->streams[ss].running = 1; in hdac_stream_start()
2088 bus_dmamap_sync(sc->streams[ss].bdl.dma_tag, in hdac_stream_stop()
2089 sc->streams[ss].bdl.dma_map, BUS_DMASYNC_POSTWRITE); in hdac_stream_stop()
2092 ctl = HDAC_READ_1(&sc->mem, off + HDAC_SDCTL0); in hdac_stream_stop()
2095 HDAC_WRITE_1(&sc->mem, off + HDAC_SDCTL0, ctl); in hdac_stream_stop()
2097 ctl = HDAC_READ_4(&sc->mem, HDAC_INTCTL); in hdac_stream_stop()
2099 HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, ctl); in hdac_stream_stop()
2101 sc->streams[ss].running = 0; in hdac_stream_stop()
2119 ctl = HDAC_READ_1(&sc->mem, off + HDAC_SDCTL0); in hdac_stream_reset()
2121 HDAC_WRITE_1(&sc->mem, off + HDAC_SDCTL0, ctl); in hdac_stream_reset()
2123 ctl = HDAC_READ_1(&sc->mem, off + HDAC_SDCTL0); in hdac_stream_reset()
2127 } while (--to); in hdac_stream_reset()
2131 HDAC_WRITE_1(&sc->mem, off + HDAC_SDCTL0, ctl); in hdac_stream_reset()
2134 ctl = HDAC_READ_1(&sc->mem, off + HDAC_SDCTL0); in hdac_stream_reset()
2138 } while (--to); in hdac_stream_reset()
2154 return (HDAC_READ_4(&sc->mem, off + HDAC_SDLPIB)); in hdac_stream_getptr()
2162 sc->unsol_registered++; in hdac_unsol_alloc()
2172 sc->unsol_registered--; in hdac_unsol_free()
2209 DRIVER_MODULE(snd_hda, pci, hdac_driver, NULL, NULL);