socsvn commit: r305326 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve
iateaca at FreeBSD.org
iateaca at FreeBSD.org
Sat Jun 18 12:20:06 UTC 2016
Author: iateaca
Date: Sat Jun 18 12:20:05 2016
New Revision: 305326
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=305326
Log:
design the hda_bdle_desc, hda_stream_desc data structures
implement the reset stream procedure
M bhyve/pci_hda.c
Modified:
soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c
Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c
==============================================================================
--- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sat Jun 18 09:48:20 2016 (r305325)
+++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sat Jun 18 12:20:05 2016 (r305326)
@@ -10,12 +10,18 @@
#define INTEL_VENDORID 0x8086
#define HDA_INTEL_82801G 0x27d8
+#define HDA_IOSS_NO 0x08
#define HDA_OSS_NO 0x04
#define HDA_ISS_NO 0x04
#define HDA_CODEC_MAX 0x0f
#define HDA_LAST_OFFSET (0x80 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20))
#define HDA_CORB_ENTRY_LEN 0x04
#define HDA_RIRB_ENTRY_LEN 0x08
+#define HDA_STREAM_TAGS_CNT 0x10
+#define HDA_STREAM_REGS_BASE 0x80
+#define HDA_STREAM_REGS_LEN 0x20
+
+#define HDA_BDL_MAX_LEN 0x0100
/*
* HDA data structures
@@ -25,6 +31,19 @@
typedef void (*hda_set_reg_handler)(struct hda_softc *sc, uint32_t offset, uint32_t old);
+struct hda_bdle {
+ uint32_t addrl;
+ uint32_t addrh;
+ uint32_t len;
+ uint32_t ioc;
+} __packed;
+
+struct hda_bdle_desc {
+ void *addr;
+ uint32_t len;
+ uint8_t ioc;
+};
+
struct hda_codec_cmd_ctl {
char *name;
void *dma_vaddr;
@@ -34,6 +53,14 @@
uint8_t run;
};
+struct hda_stream_desc {
+ uint8_t run;
+ uint8_t dir;
+
+ struct hda_bdle_desc bdl[HDA_BDL_MAX_LEN];
+ uint32_t bdl_cnt;
+};
+
struct hda_softc {
struct pci_devinst *pci_dev;
uint32_t regs[HDA_LAST_OFFSET];
@@ -43,6 +70,9 @@
struct hda_codec_inst *codecs[HDA_CODEC_MAX];
uint8_t codecs_no;
+
+ struct hda_stream_desc streams[HDA_IOSS_NO];
+ uint8_t stream_map[HDA_STREAM_TAGS_CNT];
};
/*
@@ -67,6 +97,8 @@
hda_reset(struct hda_softc *sc);
static void
hda_reset_regs(struct hda_softc *sc);
+static void
+hda_reset_stream(struct hda_softc *sc, uint8_t stream_ind);
static uint32_t
hda_read(struct hda_softc *sc, uint32_t offset);
static int
@@ -90,6 +122,8 @@
static inline uint8_t
hda_get_stream_by_offsets(uint32_t offset, uint8_t reg_offset);
+static inline uint32_t
+hda_get_offset_stream(uint8_t stream_ind);
static void
hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old);
@@ -355,6 +389,25 @@
return;
}
+static void
+hda_reset_stream(struct hda_softc *sc, uint8_t stream_ind)
+{
+ struct hda_stream_desc *st = &sc->streams[stream_ind];
+ uint32_t off = hda_get_offset_stream(stream_ind);
+
+ DPRINTF("Reset the HDA stream: 0x%x\n", stream_ind);
+
+ /* Reset the Stream Descriptor registers */
+ memset(sc->regs + HDA_STREAM_REGS_BASE + off, 0, HDA_STREAM_REGS_LEN);
+
+ /* Reset the Stream Descriptor */
+ memset(st, 0, sizeof(*st));
+
+ hda_set_field_by_offset(sc, off + HDAC_SDCTL0, HDAC_SDCTL_SRST, HDAC_SDCTL_SRST);
+
+ return;
+}
+
static uint32_t
hda_read(struct hda_softc *sc, uint32_t offset)
{
@@ -521,7 +574,17 @@
static inline uint8_t
hda_get_stream_by_offsets(uint32_t offset, uint8_t reg_offset)
{
- return (offset - reg_offset - 0x80) / 0x20;
+ uint8_t stream_ind = (offset - reg_offset) >> 5;
+
+ assert(stream_ind < HDA_IOSS_NO);
+
+ return stream_ind;
+}
+
+static inline uint32_t
+hda_get_offset_stream(uint8_t stream_ind)
+{
+ return stream_ind << 5;
}
static void
@@ -583,10 +646,15 @@
static void
hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
{
- uint8_t stream_ind = hda_get_stream_by_offsets(offset, 0x00);
+ uint8_t stream_ind = hda_get_stream_by_offsets(offset, HDAC_SDCTL0);
+ uint32_t value = hda_get_reg_by_offset(sc, offset);
DPRINTF("stream_ind: 0x%x old: 0x%x\n", stream_ind, old);
+ if (value & HDAC_SDCTL_SRST) {
+ hda_reset_stream(sc, stream_ind);
+ }
+
return;
}
More information about the svn-soc-all
mailing list