Date: Sun, 29 May 2016 17:08:36 GMT From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r304163 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve Message-ID: <201605291708.u4TH8aP7017771@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605291708.u4TH8aP7017771>