socsvn commit: r304163 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve

iateaca at FreeBSD.org iateaca at FreeBSD.org
Sun May 29 17:08:37 UTC 2016


Author: iateaca
Date: Sun May 29 17:08:35 2016
New Revision: 304163
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=304163

Log:
  implement the send_command in controller and .command handler in codec
  implement the .response handler in controller (RIRB); used by to codec to send responses
  
  M    bhyve/hda_codec.c
  M    bhyve/pci_hda.c
  M    bhyve/pci_hda.h

Modified:
  soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c
  soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c
  soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h

Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c
==============================================================================
--- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c	Sun May 29 16:39:28 2016	(r304162)
+++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c	Sun May 29 17:08:35 2016	(r304163)
@@ -1,10 +1,25 @@
 
 #include "pci_hda.h"
 
+/*
+ * HDA Codec defines
+ */
+#define HDA_CODEC_RESPONSE_EX_UNSOL		0x10
+#define HDA_CODEC_RESPONSE_EX_SOL		0x00
+
+/*
+ * HDA Codec module function declarations
+ */
 static int
 hda_codec_init(struct hda_codec_inst *hci, const char *opts);
 static int
 hda_codec_reset(struct hda_codec_inst *hci);
+static int
+hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data);
+
+/*
+ * HDA Codec module function definitions
+ */
 
 static int
 hda_codec_init(struct hda_codec_inst *hci, const char *opts)
@@ -26,15 +41,48 @@
 
 	DPRINTF("cad: 0x%x\n", hci->cad);
 
-	hops->signal(hci);
+	if (!hops->signal) {
+		DPRINTF("The controller ops does not implement the signal function\n");
+		return -1;
+	}
 
-	return 0;
+	return hops->signal(hci);
+}
+
+static int
+hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data)
+{
+	struct hda_ops *hops = NULL;
+	uint8_t cad = 0, nid = 0;
+	uint16_t verb = 0, payload = 0;
+
+	// TODO find if the cmd is 12bit or 4bit
+	cad = (cmd_data >> HDA_CMD_CAD_SHIFT) & 0x0f;			// 4 bits
+	nid = (cmd_data >> HDA_CMD_NID_SHIFT) & 0xff;			// 8 bits
+	verb = (cmd_data >> HDA_CMD_VERB_12BIT_SHIFT) & 0x0fff;		// 12 bits
+	payload = cmd_data & 0xff;					// 8 bits
+
+	assert(cad == hci->cad);
+	assert(hci);
+
+	hops = hci->hops;
+	assert(hops);
+
+	DPRINTF("cad: 0x%x nid: 0x%x verb: 0x%x payload: 0x%x\n", cad, nid, verb, payload);
+
+	if (!hops->response) {
+		DPRINTF("The controller ops does not implement the response function\n");
+		return -1;
+	}
+
+	return hops->response(hci, 0, HDA_CODEC_RESPONSE_EX_SOL);
 }
 
 struct hda_codec_class hda_codec  = {
-	.name	= "hda_codec",
-	.init	= hda_codec_init,
-	.reset	= hda_codec_reset,
+	.name		= "hda_codec",
+	.init		= hda_codec_init,
+	.reset		= hda_codec_reset,
+	.command	= hda_codec_command,
 };
 
 HDA_EMUL_SET(hda_codec);

Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c
==============================================================================
--- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c	Sun May 29 16:39:28 2016	(r304162)
+++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c	Sun May 29 17:08:35 2016	(r304163)
@@ -61,6 +61,8 @@
 static struct hda_codec_class *
 hda_find_codec_class(const char *name);
 
+static int
+hda_send_command(struct hda_softc *sc, uint32_t verb);
 static void
 hda_reset(struct hda_softc *sc);
 static void
@@ -102,6 +104,8 @@
 
 static int
 hda_signal_state_change(struct hda_codec_inst *hci);
+static int
+hda_response(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol);
 
 /*
  * PCI HDA function declarations
@@ -159,6 +163,7 @@
 
 static struct hda_ops hops = {
 	.signal		= hda_signal_state_change,
+	.response	= hda_response,
 };
 
 struct pci_devemu pci_de_hda = {
@@ -246,7 +251,6 @@
 hda_codec_constructor(struct hda_softc *sc, struct hda_codec_class *codec)
 {
 	struct hda_codec_inst *hci = NULL;
-	int err;
 
 	if (sc->codecs_no >= HDA_CODEC_MAX)
 		return -1;
@@ -262,10 +266,12 @@
 
 	sc->codecs[sc->codecs_no++] = hci;
 
-	err = codec->init(hci, NULL);
-	assert(!err);
+	if (!codec->init) {
+		DPRINTF("This codec does not implement the init function\n");
+		return -1;
+	}
 
-	return 0;
+	return codec->init(hci, NULL);
 }
 
 static struct hda_codec_class *
@@ -283,6 +289,30 @@
 	return NULL;
 }
 
+static int
+hda_send_command(struct hda_softc *sc, uint32_t verb)
+{
+	struct hda_codec_inst *hci = NULL;
+	struct hda_codec_class *codec = NULL;
+	uint8_t cad = (verb >> HDA_CMD_CAD_SHIFT) & 0x0f;
+
+	hci = sc->codecs[cad];
+	if (!hci)
+		return -1;
+
+	DPRINTF("cad: 0x%x verb: 0x%x\n", cad, verb);
+
+	codec = hci->codec;
+	assert(codec);
+
+	if (!codec->command) {
+		DPRINTF("This codec does not implement the command function\n");
+		return -1;
+	}
+
+	return codec->command(hci, verb);
+}
+
 static void
 hda_reset(struct hda_softc *sc)
 {
@@ -300,7 +330,8 @@
 		codec = hci->codec;
 		assert(codec);
 
-		codec->reset(hci);
+		if (codec->reset)
+			codec->reset(hci);
 	}
 
 	return;
@@ -493,6 +524,7 @@
 	struct hda_codec_cmd_ctl *corb = &sc->corb;
 	uint32_t value = sc->regs[offset];
 	uint32_t verb = 0;
+	int err;
 
 	corb->wp = value;
 
@@ -503,10 +535,8 @@
 		corb->rp++;
 		verb = hda_dma_ld_dword(corb->dma_vaddr + HDA_CORB_ENTRY_LEN * corb->rp);
 
-		/*
-		 * TODO get cad from verb and send command to codec[cad]
-		 */
-		DPRINTF("VERB: 0x%x\n", verb);
+		err = hda_send_command(sc, verb);
+		assert(!err);
 	}
 
 	hda_set_reg_by_offset(sc, HDAC_CORBRP, corb->rp);
@@ -579,6 +609,36 @@
 	return 0;
 }
 
+static int
+hda_response(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol)
+{
+	struct hda_softc *sc = NULL;
+	struct hda_codec_cmd_ctl *rirb = NULL;
+	uint32_t response_ex = 0;
+
+	assert(hci);
+	assert(hci->cad <= HDA_CODEC_MAX);
+
+	response_ex = hci->cad | unsol;
+
+	sc = hci->hda;
+	assert(sc);
+
+	rirb = &sc->rirb;
+
+	if (rirb->run) {
+		rirb->wp++;
+		rirb->wp %= rirb->size;
+
+		hda_dma_st_dword(rirb->dma_vaddr + HDA_RIRB_ENTRY_LEN * rirb->wp, response);
+		hda_dma_st_dword(rirb->dma_vaddr + HDA_RIRB_ENTRY_LEN * rirb->wp + 0x04, response_ex);
+
+		hda_set_reg_by_offset(sc, HDAC_RIRBWP, rirb->wp);
+	}
+
+	return 0;
+}
+
 /*
  * PCI HDA function definitions
  */

Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h
==============================================================================
--- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h	Sun May 29 16:39:28 2016	(r304162)
+++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h	Sun May 29 17:08:35 2016	(r304163)
@@ -12,6 +12,8 @@
 #include <sys/queue.h>
 #include <sys/kernel.h>
 
+#include "hda_reg.h"
+
 /*
  * HDA Debug Log
  */
@@ -40,10 +42,12 @@
 	char *name;
 	int (*init)(struct hda_codec_inst *hci, const char *opts);
 	int (*reset)(struct hda_codec_inst *hci);
+	int (*command)(struct hda_codec_inst *hci, uint32_t cmd_data);
 };
 
 struct hda_ops {
 	int (*signal)(struct hda_codec_inst *hci);
+	int (*response)(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol);
 };
 
 #define HDA_EMUL_SET(x)		DATA_SET(hda_codec_class_set, x);


More information about the svn-soc-all mailing list