Created
July 12, 2013 11:55
-
-
Save pamaury/5983912 to your computer and use it in GitHub Desktop.
Original code from TheSeven
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 63276ed0a61f6d7a362f70a3760b9fd332950472 | |
Author: Amaury Pouly <[email protected]> | |
Date: Thu Mar 28 19:07:25 2013 +0100 | |
Add synopsysotg driver from TheSeven | |
Change-Id: Ib2a3f343d7769929ad3301e3e77e564bc8a47770 | |
diff --git a/firmware/SOURCES b/firmware/SOURCES | |
index 8ba45af..903bec6 100644 | |
--- a/firmware/SOURCES | |
+++ b/firmware/SOURCES | |
@@ -703,6 +703,7 @@ target/arm/usb-drv-arc.c | |
target/arm/as3525/usb-drv-as3525.c | |
#elif CONFIG_USBOTG == USBOTG_S3C6400X | |
target/arm/usb-s3c6400x.c | |
+target/arm/synopsisotg.h | |
#elif CONFIG_USBOTG == USBOTG_ISP1583 | |
drivers/isp1583.c | |
#elif CONFIG_USBOTG == USBOTG_RK27XX | |
diff --git a/firmware/target/arm/synopsysotg.c b/firmware/target/arm/synopsysotg.c | |
new file mode 100644 | |
index 0000000..6fc620d | |
--- /dev/null | |
+++ b/firmware/target/arm/synopsysotg.c | |
@@ -0,0 +1,437 @@ | |
+#include "global.h" | |
+#include "core/synopsysotg/synopsysotg.h" | |
+#include "protocol/usb/usb.h" | |
+#include "sys/time.h" | |
+#include "sys/util.h" | |
+ | |
+#ifndef SYNOPSYSOTG_AHB_BURST_LEN | |
+#define SYNOPSYSOTG_AHB_BURST_LEN 5 | |
+#endif | |
+#ifndef SYNOPSYSOTG_AHB_THRESHOLD | |
+#define SYNOPSYSOTG_AHB_THRESHOLD 8 | |
+#endif | |
+#ifndef SYNOPSYSOTG_TURNAROUND | |
+#define SYNOPSYSOTG_TURNAROUND 3 | |
+#endif | |
+ | |
+static void synopsysotg_flush_in_endpoint(const struct usb_instance* instance, int ep) | |
+{ | |
+ const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config; | |
+ if (data->core->inep_regs[ep].diepctl.b.epena) | |
+ { | |
+ // Urgh, someone was still babbling on our IN pipe, and now we have some | |
+ // old crap in the FIFO. Disable the endpoint, to make sure nobody will | |
+ // fetch any more old crap while we're trying to get rid of it. | |
+ synopsysotg_target_disable_irq(instance); | |
+ data->core->inep_regs[ep].diepctl.b.snak = 1; | |
+ while (!(data->core->inep_regs[ep].diepint.b.inepnakeff)); | |
+ data->core->inep_regs[ep].diepctl.b.epdis = 1; | |
+ while (!(data->core->inep_regs[ep].diepint.b.epdisabled)); | |
+ synopsysotg_target_enable_irq(instance); | |
+ // Wait for any DMA activity to stop, to make sure nobody will touch the FIFO. | |
+ while (!data->core->gregs.grstctl.b.ahbidle); | |
+ // Flush it all the way down! | |
+ union synopsysotg_grstctl grstctl = { .b = { .txfnum = ep, .txfflsh = 1 } }; | |
+ data->core->gregs.grstctl = grstctl; | |
+ while (data->core->gregs.grstctl.b.txfflsh); | |
+ } | |
+ // Reset the transfer size register. Not strictly neccessary, but can't hurt. | |
+ data->core->inep_regs[ep].dieptsiz.d32 = 0; | |
+} | |
+ | |
+static void synopsysotg_flush_ints(const struct usb_instance* instance) | |
+{ | |
+ const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config; | |
+ int i; | |
+ for (i = 0; i < 16; i++) | |
+ { | |
+ data->core->outep_regs[i].doepint = data->core->outep_regs[i].doepint; | |
+ data->core->inep_regs[i].diepint = data->core->inep_regs[i].diepint; | |
+ } | |
+ data->core->gregs.gintsts = data->core->gregs.gintsts; | |
+} | |
+ | |
+void synopsysotg_start_rx(const struct usb_instance* instance, union usb_endpoint_number ep, void* buf, int size) | |
+{ | |
+ const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config; | |
+ struct synopsysotg_state* state = (struct synopsysotg_state*)instance->driver_state; | |
+ | |
+ // Find the appropriate set of endpoint registers | |
+ volatile struct synopsysotg_outepregs* regs = &data->core->outep_regs[ep.number]; | |
+ | |
+ // Calculate number of packets (if size == 0 an empty packet will be sent) | |
+ int maxpacket = regs->doepctl.b.mps; | |
+ int packets = (size + maxpacket - 1) / maxpacket; | |
+ if (!packets) packets = 1; | |
+ | |
+ // Set up data desination | |
+ if (data->use_dma) regs->doepdma = buf; | |
+ else state->endpoints[ep.number].rxaddr = (uint32_t*)buf; | |
+ union synopsysotg_depxfrsiz deptsiz = { .b = { .pktcnt = packets, .xfersize = size } }; | |
+ regs->doeptsiz = deptsiz; | |
+ | |
+ // Flush CPU cache if necessary | |
+ if (data->use_dma) invalidate_dcache(buf, size); | |
+ | |
+ // Enable the endpoint | |
+ union synopsysotg_depctl depctl = regs->doepctl; | |
+ depctl.b.epena = 1; | |
+ depctl.b.cnak = 1; | |
+ regs->doepctl = depctl; | |
+} | |
+ | |
+void synopsysotg_start_tx(const struct usb_instance* instance, union usb_endpoint_number ep, const void* buf, int size) | |
+{ | |
+ const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config; | |
+ struct synopsysotg_state* state = (struct synopsysotg_state*)instance->driver_state; | |
+ | |
+ // Find the appropriate set of endpoint registers | |
+ volatile struct synopsysotg_inepregs* regs = &data->core->inep_regs[ep.number]; | |
+ | |
+ // Calculate number of packets (if size == 0 an empty packet will be sent) | |
+ int maxpacket = regs->diepctl.b.mps; | |
+ int packets = (size + maxpacket - 1) / maxpacket; | |
+ if (!packets) packets = 1; | |
+ | |
+ // Set up data desination | |
+ if (data->use_dma) regs->diepdma = buf; | |
+ else state->endpoints[ep.number].txaddr = (uint32_t*)buf; | |
+ union synopsysotg_depxfrsiz deptsiz = { .b = { .pktcnt = packets, .xfersize = size } }; | |
+ regs->dieptsiz = deptsiz; | |
+ | |
+ // Flush CPU cache if necessary | |
+ if (data->use_dma) clean_dcache(buf, size); | |
+ | |
+ // Enable the endpoint | |
+ union synopsysotg_depctl depctl = regs->diepctl; | |
+ depctl.b.epena = 1; | |
+ depctl.b.cnak = 1; | |
+ regs->diepctl = depctl; | |
+ | |
+ // Start pushing data into the FIFO (must be done after enabling the endpoint) | |
+ if (!data->use_dma) data->core->dregs.diepempmsk.ep.in |= (1 << ep.number); | |
+} | |
+ | |
+void synopsysotg_set_stall(const struct usb_instance* instance, union usb_endpoint_number ep, int stall) | |
+{ | |
+ const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config; | |
+ if (ep.direction == USB_ENDPOINT_DIRECTION_IN) | |
+ data->core->inep_regs[ep.number].diepctl.b.stall = !!stall; | |
+ else data->core->outep_regs[ep.number].doepctl.b.stall = !!stall; | |
+} | |
+ | |
+void synopsysotg_set_address(const struct usb_instance* instance, uint8_t address) | |
+{ | |
+ const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config; | |
+ data->core->dregs.dcfg.b.devaddr = address; | |
+} | |
+ | |
+void synopsysotg_unconfigure_ep(const struct usb_instance* instance, union usb_endpoint_number ep) | |
+{ | |
+ const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config; | |
+ union synopsysotg_depctl depctl = { .b = { .epdis = 1 } }; | |
+ if (ep.direction == USB_ENDPOINT_DIRECTION_IN) | |
+ { | |
+ synopsysotg_flush_in_endpoint(instance, ep.number); | |
+ data->core->inep_regs[ep.number].diepctl = depctl; | |
+ // Mask interrupts for this endpoint | |
+ data->core->dregs.daintmsk.ep.in &= ~(1 << ep.number); | |
+ } | |
+ else | |
+ { | |
+ // We can't really do much about in-flight OUT requests except for ignoring them. | |
+ data->core->outep_regs[ep.number].doeptsiz.d32 = 0; | |
+ data->core->outep_regs[ep.number].doepctl = depctl; | |
+ // Mask interrupts for this endpoint | |
+ data->core->dregs.daintmsk.ep.out &= ~(1 << ep.number); | |
+ } | |
+} | |
+ | |
+void synopsysotg_configure_ep(const struct usb_instance* instance, union usb_endpoint_number ep, | |
+ enum usb_endpoint_type type, int maxpacket) | |
+{ | |
+ const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config; | |
+ | |
+ // Reset the endpoint, just in case someone left it in a dirty state. | |
+ synopsysotg_unconfigure_ep(instance, ep); | |
+ | |
+ // Write the new configuration and unmask interrupts for the endpoint. | |
+ // Reset data toggle to DATA0, as required by the USB specification. | |
+ union synopsysotg_depctl depctl = { .b = { .usbactep = 1, .eptype = type, .mps = maxpacket, .txfnum = ep.number, .setd0pid = 1 } }; | |
+ if (ep.direction == USB_ENDPOINT_DIRECTION_IN) | |
+ { | |
+ data->core->inep_regs[ep.number].diepctl = depctl; | |
+ data->core->dregs.daintmsk.ep.in |= (1 << ep.number); | |
+ } | |
+ else | |
+ { | |
+ data->core->outep_regs[ep.number].doepctl = depctl; | |
+ data->core->dregs.daintmsk.ep.out |= (1 << ep.number); | |
+ } | |
+} | |
+ | |
+void synopsysotg_ep0_start_rx(const struct usb_instance* instance, int non_setup) | |
+{ | |
+ const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config; | |
+ struct synopsysotg_state* state = (struct synopsysotg_state*)instance->driver_state; | |
+ | |
+ // If we don't expect a non-SETUP packet, we can stall the OUT pipe, | |
+ // SETUP packets will ignore that. | |
+ if (!non_setup) data->core->outep_regs[0].doepctl.b.stall = 1; | |
+ | |
+ // Set up data desination | |
+ if (data->use_dma) data->core->outep_regs[0].doepdma = instance->buffer; | |
+ else state->endpoints[0].rxaddr = (uint32_t*)instance->buffer; | |
+ union synopsysotg_dep0xfrsiz deptsiz = { .b = { .supcnt = 3, .pktcnt = !!non_setup, .xfersize = 64 } }; | |
+ data->core->outep_regs[0].doeptsiz.d32 = deptsiz.d32; | |
+ | |
+ // Flush CPU cache if necessary | |
+ if (data->use_dma) invalidate_dcache(instance->buffer, sizeof(instance->buffer)); | |
+ | |
+ // Enable the endpoint | |
+ union synopsysotg_depctl depctl = data->core->outep_regs[0].doepctl; | |
+ depctl.b.epena = 1; | |
+ depctl.b.cnak = 1; | |
+ data->core->outep_regs[0].doepctl = depctl; | |
+} | |
+ | |
+void synopsysotg_ep0_start_tx(const struct usb_instance* instance, const void* buf, int len) | |
+{ | |
+ const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config; | |
+ struct synopsysotg_state* state = (struct synopsysotg_state*)instance->driver_state; | |
+ | |
+ if (len) | |
+ { | |
+ // Set up data source | |
+ if (data->use_dma) data->core->inep_regs[0].diepdma = buf; | |
+ else state->endpoints[0].txaddr = buf; | |
+ union synopsysotg_dep0xfrsiz deptsiz = { .b = { .pktcnt = (len + 63) >> 6, .xfersize = len } }; | |
+ data->core->inep_regs[0].dieptsiz.d32 = deptsiz.d32; | |
+ } | |
+ else | |
+ { | |
+ // Set up the IN pipe for a zero-length packet | |
+ union synopsysotg_dep0xfrsiz deptsiz = { .b = { .pktcnt = 1 } }; | |
+ data->core->inep_regs[0].dieptsiz.d32 = deptsiz.d32; | |
+ } | |
+ | |
+ // Flush CPU cache if necessary | |
+ if (data->use_dma) clean_dcache(buf, len); | |
+ | |
+ // Enable the endpoint | |
+ union synopsysotg_depctl depctl = data->core->inep_regs[0].diepctl; | |
+ depctl.b.epena = 1; | |
+ depctl.b.cnak = 1; | |
+ data->core->inep_regs[0].diepctl = depctl; | |
+ | |
+ // Start pushing data into the FIFO (must be done after enabling the endpoint) | |
+ if (len && !data->use_dma) data->core->dregs.diepempmsk.ep.in |= 1; | |
+} | |
+ | |
+static void synopsysotg_ep0_init(const struct usb_instance* instance) | |
+{ | |
+ const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config; | |
+ | |
+ // Make sure both EP0 pipes are active. | |
+ // (The hardware should take care of that, but who knows...) | |
+ union synopsysotg_depctl depctl = { .b = { .usbactep = 1 } }; | |
+ data->core->outep_regs[0].doepctl = depctl; | |
+ data->core->inep_regs[0].diepctl = depctl; | |
+ | |
+ // Prime EP0 for the first setup packet. | |
+ usb_ep0_expect_setup(instance); | |
+} | |
+ | |
+void synopsysotg_irq(const struct usb_instance* instance) | |
+{ | |
+ const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config; | |
+ struct synopsysotg_state* state = (struct synopsysotg_state*)instance->driver_state; | |
+ | |
+ union synopsysotg_gintsts gintsts = data->core->gregs.gintsts; | |
+ | |
+ if (gintsts.b.usbreset) | |
+ { | |
+ data->core->dregs.dcfg.b.devaddr = 0; | |
+ synopsysotg_ep0_init(instance); | |
+ usb_handle_bus_reset(instance, data->core->dregs.dsts.b.enumspd == 0); | |
+ } | |
+ | |
+ if (gintsts.b.rxstsqlvl) | |
+ { | |
+ // Device to memory part of the "software DMA" implementation, used to receive data if use_dma == 0. | |
+ // Handle one packet at a time, the IRQ will re-trigger if there's something left. | |
+ union synopsysotg_grxfsts rxsts = data->core->gregs.grxstsp; | |
+ int ep = rxsts.b.chnum; | |
+ int words = (rxsts.b.bcnt + 3) >> 2; | |
+ while (words--) *state->endpoints[ep].rxaddr++ = data->core->dfifo[0][0]; | |
+ } | |
+ | |
+ if (gintsts.b.inepintr) | |
+ { | |
+ union synopsysotg_daint daint = data->core->dregs.daint; | |
+ int ep; | |
+ for (ep = 0; ep < 16; ep++) | |
+ if (daint.ep.in & (1 << ep)) | |
+ { | |
+ union synopsysotg_diepintn epints = data->core->inep_regs[ep].diepint; | |
+ if (epints.b.emptyintr) | |
+ { | |
+ // Memory to device part of the "software DMA" implementation, used to transmit data if use_dma == 0. | |
+ union synopsysotg_depxfrsiz deptsiz = data->core->inep_regs[ep].dieptsiz; | |
+ if (!deptsiz.b.pktcnt) data->core->dregs.diepempmsk.ep.in &= ~(1 << ep); | |
+ else | |
+ { | |
+ // Push data into the TX FIFO until we don't have anything left or the FIFO would overflow. | |
+ int left = (deptsiz.b.xfersize + 3) >> 2; | |
+ while (left) | |
+ { | |
+ int words = data->core->inep_regs[ep].dtxfsts.b.txfspcavail; | |
+ if (words > left) words = left; | |
+ if (!words) break; | |
+ left -= words; | |
+ while (words--) data->core->dfifo[ep][0] = *state->endpoints[ep].txaddr++; | |
+ } | |
+ } | |
+ } | |
+ union usb_endpoint_number epnum = { .direction = USB_ENDPOINT_DIRECTION_IN, .number = ep }; | |
+ int bytesleft = data->core->inep_regs[ep].dieptsiz.b.xfersize; | |
+ if (epints.b.timeout) usb_handle_timeout(instance, epnum, bytesleft); | |
+ if (epints.b.xfercompl) usb_handle_xfer_complete(instance, epnum, bytesleft); | |
+ data->core->inep_regs[ep].diepint = epints; | |
+ } | |
+ } | |
+ | |
+ if (gintsts.b.outepintr) | |
+ { | |
+ union synopsysotg_daint daint = data->core->dregs.daint; | |
+ int ep; | |
+ for (ep = 0; ep < 16; ep++) | |
+ if (daint.ep.out & (1 << ep)) | |
+ { | |
+ union synopsysotg_doepintn epints = data->core->outep_regs[ep].doepint; | |
+ union usb_endpoint_number epnum = { .direction = USB_ENDPOINT_DIRECTION_OUT, .number = ep }; | |
+ if (epints.b.setup) | |
+ { | |
+ if (data->use_dma) invalidate_dcache(instance->buffer, sizeof(instance->buffer)); | |
+ union synopsysotg_dep0xfrsiz deptsiz = { .d32 = data->core->outep_regs[0].doeptsiz.d32 }; | |
+ int back2back = 3 - deptsiz.b.supcnt; | |
+ synopsysotg_flush_in_endpoint(instance, ep); | |
+ usb_handle_setup_received(instance, epnum, back2back); | |
+ } | |
+ else if (epints.b.xfercompl) | |
+ { | |
+ int bytesleft = data->core->inep_regs[ep].dieptsiz.b.xfersize; | |
+ usb_handle_xfer_complete(instance, epnum, bytesleft); | |
+ } | |
+ data->core->outep_regs[ep].doepint = epints; | |
+ } | |
+ } | |
+ | |
+ data->core->gregs.gintsts = gintsts; | |
+} | |
+ | |
+void synopsysotg_init(const struct usb_instance* instance) | |
+{ | |
+ int i; | |
+ | |
+ const struct synopsysotg_config* data = (const struct synopsysotg_config*)instance->driver_config; | |
+ | |
+ // Disable IRQ during setup | |
+ synopsysotg_target_disable_irq(instance); | |
+ | |
+ // Enable OTG clocks | |
+ synopsysotg_target_enable_clocks(instance); | |
+ | |
+ // Enable PHY clocks | |
+ union synopsysotg_pcgcctl pcgcctl = { .b = {} }; | |
+ data->core->pcgcctl = pcgcctl; | |
+ | |
+ // Configure PHY type (must be done before reset) | |
+ union synopsysotg_gccfg gccfg = { .b = { .disablevbussensing = 1, .pwdn = 0 } }; | |
+ data->core->gregs.gccfg = gccfg; | |
+ union synopsysotg_gusbcfg gusbcfg = { .b = { .force_dev = 1, .usbtrdtim = SYNOPSYSOTG_TURNAROUND } }; | |
+ if (data->phy_16bit) gusbcfg.b.phyif = 1; | |
+ else if (data->phy_ulpi) gusbcfg.b.ulpi_utmi_sel = 1; | |
+ else gusbcfg.b.physel = 1; | |
+ data->core->gregs.gusbcfg = gusbcfg; | |
+ | |
+ // Reset the whole USB core | |
+ union synopsysotg_grstctl grstctl = { .b = { .csftrst = 1 } }; | |
+ udelay(100); | |
+ while (!data->core->gregs.grstctl.b.ahbidle); | |
+ data->core->gregs.grstctl = grstctl; | |
+ while (data->core->gregs.grstctl.b.csftrst); | |
+ while (!data->core->gregs.grstctl.b.ahbidle); | |
+ | |
+ // Soft disconnect | |
+ union synopsysotg_dctl dctl = { .b = { .sftdiscon = 1 } }; | |
+ data->core->dregs.dctl = dctl; | |
+ | |
+ // Configure the core | |
+ union synopsysotg_gahbcfg gahbcfg = { .b = { .dmaenable = data->use_dma, .hburstlen = SYNOPSYSOTG_AHB_BURST_LEN, .glblintrmsk = 1 } }; | |
+ if (data->disable_double_buffering) | |
+ { | |
+ gahbcfg.b.nptxfemplvl_txfemplvl = 1; | |
+ gahbcfg.b.ptxfemplvl = 1; | |
+ } | |
+ data->core->gregs.gahbcfg = gahbcfg; | |
+ data->core->gregs.gusbcfg = gusbcfg; | |
+ gccfg.b.pwdn = 1; | |
+ data->core->gregs.gccfg = gccfg; | |
+ union synopsysotg_dcfg dcfg = { .b = { .nzstsouthshk = 1 } }; | |
+ data->core->dregs.dcfg = dcfg; | |
+ | |
+ // Configure the FIFOs | |
+ if (data->use_dma) | |
+ { | |
+ union synopsysotg_dthrctl dthrctl = { .b = { .arb_park_en = 1, .rx_thr_en = 1, .iso_thr_en = 0, .non_iso_thr_en = 0, | |
+ .rx_thr_len = SYNOPSYSOTG_AHB_THRESHOLD } }; | |
+ data->core->dregs.dthrctl = dthrctl; | |
+ } | |
+ int addr = data->fifosize; | |
+ for (i = 0; i < 16; i++) | |
+ { | |
+ int size = data->txfifosize[i]; | |
+ addr -= size; | |
+ if (size) | |
+ { | |
+ union synopsysotg_txfsiz fsiz = { .b = { .startaddr = addr, .depth = size } }; | |
+ if (!i) data->core->gregs.dieptxf0_hnptxfsiz = fsiz; | |
+ else data->core->gregs.dieptxf[i - 1] = fsiz; | |
+ } | |
+ } | |
+ union synopsysotg_rxfsiz fsiz = { .b = { .depth = addr } }; | |
+ data->core->gregs.grxfsiz = fsiz; | |
+ | |
+ // Set up interrupts | |
+ union synopsysotg_doepintn doepmsk = { .b = { .xfercompl = 1, .setup = 1 } }; | |
+ data->core->dregs.doepmsk = doepmsk; | |
+ union synopsysotg_diepintn diepmsk = { .b = { .xfercompl = 1, .timeout = 1 } }; | |
+ data->core->dregs.diepmsk = diepmsk; | |
+ data->core->dregs.diepempmsk.d32 = 0; | |
+ union synopsysotg_daint daintmsk = { .ep = { .in = 0b0000000000000001, .out = 0b0000000000000001 } }; | |
+ data->core->dregs.daintmsk = daintmsk; | |
+ union synopsysotg_gintmsk gintmsk = { .b = { .usbreset = 1, .outepintr = 1, .inepintr = 1 } }; | |
+ if (!data->use_dma) gintmsk.b.rxstsqlvl = 1; | |
+ data->core->gregs.gintmsk = gintmsk; | |
+ synopsysotg_flush_ints(instance); | |
+ synopsysotg_target_clear_irq(instance); | |
+ synopsysotg_target_enable_irq(instance); | |
+ | |
+ // Soft reconnect | |
+ dctl.b.sftdiscon = 0; | |
+ data->core->dregs.dctl = dctl; | |
+} | |
+ | |
+const struct usb_driver synopsysotg_driver = | |
+{ | |
+ .init = synopsysotg_init, | |
+ .ep0_start_rx = synopsysotg_ep0_start_rx, | |
+ .ep0_start_tx = synopsysotg_ep0_start_tx, | |
+ .start_rx = synopsysotg_start_rx, | |
+ .start_tx = synopsysotg_start_tx, | |
+ .set_stall = synopsysotg_set_stall, | |
+ .set_address = synopsysotg_set_address, | |
+ .configure_ep = synopsysotg_configure_ep, | |
+ .unconfigure_ep = synopsysotg_unconfigure_ep, | |
+}; | |
diff --git a/firmware/target/arm/synopsysotg.h b/firmware/target/arm/synopsysotg.h | |
new file mode 100644 | |
index 0000000..a335115 | |
--- /dev/null | |
+++ b/firmware/target/arm/synopsysotg.h | |
@@ -0,0 +1,39 @@ | |
+#ifndef __CORE_SYNOPSYSOTG_SYNOPSYSOTG_H__ | |
+#define __CORE_SYNOPSYSOTG_SYNOPSYSOTG_H__ | |
+ | |
+#include "global.h" | |
+#include "protocol/usb/usb.h" | |
+#include "core/synopsysotg/regs.h" | |
+ | |
+struct __attribute__((packed,aligned(4))) synopsysotg_config | |
+{ | |
+ volatile struct synopsysotg_core_regs* core; | |
+ uint32_t phy_16bit : 1; | |
+ uint32_t phy_ulpi : 1; | |
+ uint32_t use_dma : 1; | |
+ uint32_t disable_double_buffering : 1; | |
+ uint32_t reserved0 : 4; | |
+ uint8_t reserved1; | |
+ uint16_t fifosize; | |
+ uint16_t txfifosize[16]; | |
+}; | |
+ | |
+struct __attribute__((packed,aligned(4))) synopsysotg_state | |
+{ | |
+ int dummy[0]; | |
+ struct | |
+ { | |
+ uint32_t* rxaddr; | |
+ const uint32_t* txaddr; | |
+ } endpoints[]; | |
+}; | |
+ | |
+extern const struct usb_driver synopsysotg_driver; | |
+ | |
+extern void synopsysotg_irq(const struct usb_instance* instance); | |
+extern void synopsysotg_target_enable_clocks(const struct usb_instance* instance); | |
+extern void synopsysotg_target_enable_irq(const struct usb_instance* instance); | |
+extern void synopsysotg_target_disable_irq(const struct usb_instance* instance); | |
+extern void synopsysotg_target_clear_irq(const struct usb_instance* instance); | |
+ | |
+#endif | |
diff --git a/firmware/target/arm/synopsysotg_regs.h b/firmware/target/arm/synopsysotg_regs.h | |
new file mode 100644 | |
index 0000000..476bae3 | |
--- /dev/null | |
+++ b/firmware/target/arm/synopsysotg_regs.h | |
@@ -0,0 +1,838 @@ | |
+#ifndef __CORESYNOPSYSOTG_REGS_H__ | |
+#define __CORESYNOPSYSOTG_REGS_H__ | |
+ | |
+#include "global.h" | |
+ | |
+ | |
+union synopsysotg_gotgctl | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t sesreqscs :1; | |
+ uint32_t sesreq :1; | |
+ uint32_t reserved2_7 :6; | |
+ uint32_t hstnegscs :1; | |
+ uint32_t hnpreq :1; | |
+ uint32_t hstsethnpen :1; | |
+ uint32_t devhnpen :1; | |
+ uint32_t reserved12_15 :4; | |
+ uint32_t conidsts :1; | |
+ uint32_t reserved17 :1; | |
+ uint32_t asesvld :1; | |
+ uint32_t bsesvld :1; | |
+ uint32_t currmod :1; | |
+ uint32_t reserved21_31 :11; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_gotgint | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t reserved0_1 :2; | |
+ uint32_t sesenddet :1; | |
+ uint32_t reserved3_7 :5; | |
+ uint32_t sesreqsucstschng :1; | |
+ uint32_t hstnegsucstschng :1; | |
+ uint32_t reserver10_16 :7; | |
+ uint32_t hstnegdet :1; | |
+ uint32_t adevtoutchng :1; | |
+ uint32_t debdone :1; | |
+ uint32_t reserved31_20 :12; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_gahbcfg | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t glblintrmsk :1; | |
+ uint32_t hburstlen :4; | |
+ uint32_t dmaenable :1; | |
+ uint32_t reserved :1; | |
+ uint32_t nptxfemplvl_txfemplvl :1; | |
+ uint32_t ptxfemplvl :1; | |
+ uint32_t reserved9_31 :23; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_gusbcfg | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t toutcal :3; | |
+ uint32_t phyif :1; | |
+ uint32_t ulpi_utmi_sel :1; | |
+ uint32_t fsintf :1; | |
+ uint32_t physel :1; | |
+ uint32_t ddrsel :1; | |
+ uint32_t srpcap :1; | |
+ uint32_t hnpcap :1; | |
+ uint32_t usbtrdtim :4; | |
+ uint32_t nptxfrwnden :1; | |
+ uint32_t phylpwrclksel :1; | |
+ uint32_t otgutmifssel :1; | |
+ uint32_t ulpi_fsls :1; | |
+ uint32_t ulpi_auto_res :1; | |
+ uint32_t ulpi_clk_sus_m :1; | |
+ uint32_t ulpi_ext_vbus_drv :1; | |
+ uint32_t ulpi_int_vbus_indicator :1; | |
+ uint32_t term_sel_dl_pulse :1; | |
+ uint32_t reserved :6; | |
+ uint32_t force_host :1; | |
+ uint32_t force_dev :1; | |
+ uint32_t corrupt_tx :1; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_grstctl | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t csftrst :1; | |
+ uint32_t hsftrst :1; | |
+ uint32_t hstfrm :1; | |
+ uint32_t intknqflsh :1; | |
+ uint32_t rxfflsh :1; | |
+ uint32_t txfflsh :1; | |
+ uint32_t txfnum :5; | |
+ uint32_t reserved11_29 :19; | |
+ uint32_t dmareq :1; | |
+ uint32_t ahbidle :1; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_gintmsk | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t reserved0 :1; | |
+ uint32_t modemismatch :1; | |
+ uint32_t otgintr :1; | |
+ uint32_t sofintr :1; | |
+ uint32_t rxstsqlvl :1; | |
+ uint32_t nptxfempty :1; | |
+ uint32_t ginnakeff :1; | |
+ uint32_t goutnakeff :1; | |
+ uint32_t reserved8 :1; | |
+ uint32_t i2cintr :1; | |
+ uint32_t erlysuspend :1; | |
+ uint32_t usbsuspend :1; | |
+ uint32_t usbreset :1; | |
+ uint32_t enumdone :1; | |
+ uint32_t isooutdrop :1; | |
+ uint32_t eopframe :1; | |
+ uint32_t reserved16 :1; | |
+ uint32_t epmismatch :1; | |
+ uint32_t inepintr :1; | |
+ uint32_t outepintr :1; | |
+ uint32_t incomplisoin :1; | |
+ uint32_t incomplisoout :1; | |
+ uint32_t reserved22_23 :2; | |
+ uint32_t portintr :1; | |
+ uint32_t hcintr :1; | |
+ uint32_t ptxfempty :1; | |
+ uint32_t reserved27 :1; | |
+ uint32_t conidstschng :1; | |
+ uint32_t disconnect :1; | |
+ uint32_t sessreqintr :1; | |
+ uint32_t wkupintr :1; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_gintsts | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t curmode :1; | |
+ uint32_t modemismatch :1; | |
+ uint32_t otgintr :1; | |
+ uint32_t sofintr :1; | |
+ uint32_t rxstsqlvl :1; | |
+ uint32_t nptxfempty :1; | |
+ uint32_t ginnakeff :1; | |
+ uint32_t goutnakeff :1; | |
+ uint32_t reserved8 :1; | |
+ uint32_t i2cintr :1; | |
+ uint32_t erlysuspend :1; | |
+ uint32_t usbsuspend :1; | |
+ uint32_t usbreset :1; | |
+ uint32_t enumdone :1; | |
+ uint32_t isooutdrop :1; | |
+ uint32_t eopframe :1; | |
+ uint32_t intimerrx :1; | |
+ uint32_t epmismatch :1; | |
+ uint32_t inepintr :1; | |
+ uint32_t outepintr :1; | |
+ uint32_t incomplisoin :1; | |
+ uint32_t incomplisoout :1; | |
+ uint32_t reserved22_23 :2; | |
+ uint32_t portintr :1; | |
+ uint32_t hcintr :1; | |
+ uint32_t ptxfempty :1; | |
+ uint32_t reserved27 :1; | |
+ uint32_t conidstschng :1; | |
+ uint32_t disconnect :1; | |
+ uint32_t sessreqintr :1; | |
+ uint32_t wkupintr :1; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_drxsts | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t epnum :4; | |
+ uint32_t bcnt :11; | |
+ uint32_t dpid :2; | |
+ uint32_t pktsts :4; | |
+ uint32_t fn :4; | |
+ uint32_t reserved :7; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_grxfsts | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t chnum :4; | |
+ uint32_t bcnt :11; | |
+ uint32_t dpid :2; | |
+ uint32_t pktsts :4; | |
+ uint32_t reserved :11; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_txfsiz | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t startaddr :16; | |
+ uint32_t depth :16; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_rxfsiz | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t depth :16; | |
+ uint32_t reserved :16; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_hnptxsts | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t nptxfspcavail :16; | |
+ uint32_t nptxqspcavail :8; | |
+ uint32_t nptxqtop_terminate :1; | |
+ uint32_t nptxqtop_timer :2; | |
+ uint32_t nptxqtop :2; | |
+ uint32_t chnum :2; | |
+ uint32_t reserved :1; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_dtxfstsn | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t txfspcavail :16; | |
+ uint32_t reserved :16; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_gi2cctl | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t rwdata :8; | |
+ uint32_t regaddr :8; | |
+ uint32_t addr :7; | |
+ uint32_t i2cen :1; | |
+ uint32_t ack :1; | |
+ uint32_t i2csuspctl :1; | |
+ uint32_t i2cdevaddr :2; | |
+ uint32_t dat_se0 :1; | |
+ uint32_t reserved :1; | |
+ uint32_t rw :1; | |
+ uint32_t bsydne :1; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_gccfg | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t reserved_in :16; | |
+ uint32_t pwdn :1; | |
+ uint32_t i2cifen :1; | |
+ uint32_t vbussensinga :1; | |
+ uint32_t vbussensingb :1; | |
+ uint32_t sofouten :1; | |
+ uint32_t disablevbussensing :1; | |
+ uint32_t reserved_out :10; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_ghwcfg1 | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t ep0 :2; | |
+ uint32_t ep1 :2; | |
+ uint32_t ep2 :2; | |
+ uint32_t ep3 :2; | |
+ uint32_t ep4 :2; | |
+ uint32_t ep5 :2; | |
+ uint32_t ep6 :2; | |
+ uint32_t ep7 :2; | |
+ uint32_t ep8 :2; | |
+ uint32_t ep9 :2; | |
+ uint32_t ep10 :2; | |
+ uint32_t ep11 :2; | |
+ uint32_t ep12 :2; | |
+ uint32_t ep13 :2; | |
+ uint32_t ep14 :2; | |
+ uint32_t ep15 :2; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_ghwcfg2 | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t otgmode :3; | |
+ uint32_t otgarch :2; | |
+ uint32_t singpnt :1; | |
+ uint32_t hsphytype :2; | |
+ uint32_t fsphytype :2; | |
+ uint32_t numdeveps :4; | |
+ uint32_t numhstchnl :4; | |
+ uint32_t periosupport :1; | |
+ uint32_t dynfifosizing :1; | |
+ uint32_t reserved_20_21 :2; | |
+ uint32_t nptxqdepth :2; | |
+ uint32_t ptxqdepth :2; | |
+ uint32_t tknqdepth :5; | |
+ uint32_t reserved_31_31 :1; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_ghwcfg3 | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t xfersizewidth :4; | |
+ uint32_t pktsizewidth :3; | |
+ uint32_t otgen :1; | |
+ uint32_t i2c_selection :1; | |
+ uint32_t vendor_control_interface_support :1; | |
+ uint32_t optfeature :1; | |
+ uint32_t rsttype :1; | |
+ uint32_t ahbphysync :1; | |
+ uint32_t reserved_13_15 :3; | |
+ uint32_t dfifodepth :16; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_ghwcfg4 | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t numdevperioeps :4; | |
+ uint32_t enablepwropt :1; | |
+ uint32_t ahbfreq :1; | |
+ uint32_t reserved_6_13 :8; | |
+ uint32_t phydatawidth :2; | |
+ uint32_t numctleps :4; | |
+ uint32_t iddgfltr :1; | |
+ uint32_t vbusvalidfltr :1; | |
+ uint32_t avalidfltr :1; | |
+ uint32_t bvalidfltr :1; | |
+ uint32_t sessendfltr :1; | |
+ uint32_t endedtrfifo :1; | |
+ uint32_t numdevmodinend :4; | |
+ uint32_t reserved_30_31 :2; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_dcfg | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t devspd :2; | |
+ uint32_t nzstsouthshk :1; | |
+ uint32_t reserved3 :1; | |
+ uint32_t devaddr :7; | |
+ uint32_t perfrint :2; | |
+ uint32_t reserved13_17 :5; | |
+ uint32_t epmscnt :4; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_dctl | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t rmtwkupsig :1; | |
+ uint32_t sftdiscon :1; | |
+ uint32_t gnpinnaksts :1; | |
+ uint32_t goutnaksts :1; | |
+ uint32_t tstctl :3; | |
+ uint32_t sgnpinnak :1; | |
+ uint32_t cgnpinnak :1; | |
+ uint32_t sgoutnak :1; | |
+ uint32_t cgoutnak :1; | |
+ uint32_t reserved :21; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_dsts | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t suspsts :1; | |
+ uint32_t enumspd :2; | |
+ uint32_t errticerr :1; | |
+ uint32_t reserved4_7 :4; | |
+ uint32_t soffn :14; | |
+ uint32_t reserved22_31 :10; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_diepintn | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t xfercompl :1; | |
+ uint32_t epdisabled :1; | |
+ uint32_t ahberr :1; | |
+ uint32_t timeout :1; | |
+ uint32_t intktxfemp :1; | |
+ uint32_t intknepmis :1; | |
+ uint32_t inepnakeff :1; | |
+ uint32_t emptyintr :1; | |
+ uint32_t txfifoundrn :1; | |
+ uint32_t reserved08_31 :23; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_doepintn | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t xfercompl :1; | |
+ uint32_t epdisabled :1; | |
+ uint32_t ahberr :1; | |
+ uint32_t setup :1; | |
+ uint32_t reserved04_31 :28; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_daint | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t in :16; | |
+ uint32_t out :16; | |
+ } ep; | |
+}; | |
+ | |
+union synopsysotg_dthrctl | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t non_iso_thr_en :1; | |
+ uint32_t iso_thr_en :1; | |
+ uint32_t tx_thr_len :9; | |
+ uint32_t reserved11_15 :5; | |
+ uint32_t rx_thr_en :1; | |
+ uint32_t rx_thr_len :9; | |
+ uint32_t reserved26 :1; | |
+ uint32_t arb_park_en :1; | |
+ uint32_t reserved28_31 :4; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_depctl | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t mps :11; | |
+ uint32_t reserved :4; | |
+ uint32_t usbactep :1; | |
+ uint32_t dpid :1; | |
+ uint32_t naksts :1; | |
+ uint32_t eptype :2; | |
+ uint32_t snp :1; | |
+ uint32_t stall :1; | |
+ uint32_t txfnum :4; | |
+ uint32_t cnak :1; | |
+ uint32_t snak :1; | |
+ uint32_t setd0pid :1; | |
+ uint32_t setd1pid :1; | |
+ uint32_t epdis :1; | |
+ uint32_t epena :1; | |
+ } b; | |
+}; | |
+union synopsysotg_depxfrsiz | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t xfersize :19; | |
+ uint32_t pktcnt :10; | |
+ uint32_t mc :2; | |
+ uint32_t reserved :1; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_dep0xfrsiz | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t xfersize :7; | |
+ uint32_t reserved7_18 :12; | |
+ uint32_t pktcnt :2; | |
+ uint32_t reserved21_28 :8; | |
+ uint32_t supcnt :2; | |
+ uint32_t reserved31; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_hcfg | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t fslspclksel :2; | |
+ uint32_t fslssupp :1; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_hfrmintrvl | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t frint :16; | |
+ uint32_t reserved :16; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_hfnum | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t frnum :16; | |
+ uint32_t frrem :16; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_hptxsts | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t ptxfspcavail :16; | |
+ uint32_t ptxqspcavail :8; | |
+ uint32_t ptxqtop_terminate :1; | |
+ uint32_t ptxqtop_timer :2; | |
+ uint32_t ptxqtop :2; | |
+ uint32_t chnum :2; | |
+ uint32_t ptxqtop_odd :1; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_hprt0 | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t prtconnsts :1; | |
+ uint32_t prtconndet :1; | |
+ uint32_t prtena :1; | |
+ uint32_t prtenchng :1; | |
+ uint32_t prtovrcurract :1; | |
+ uint32_t prtovrcurrchng :1; | |
+ uint32_t prtres :1; | |
+ uint32_t prtsusp :1; | |
+ uint32_t prtrst :1; | |
+ uint32_t reserved9 :1; | |
+ uint32_t prtlnsts :2; | |
+ uint32_t prtpwr :1; | |
+ uint32_t prttstctl :4; | |
+ uint32_t prtspd :2; | |
+ uint32_t reserved19_31 :13; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_haint | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t chint :16; | |
+ uint32_t reserved :16; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_haintmsk | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t chint :16; | |
+ uint32_t reserved :16; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_hcchar | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t mps :11; | |
+ uint32_t epnum :4; | |
+ uint32_t epdir :1; | |
+ uint32_t reserved :1; | |
+ uint32_t lspddev :1; | |
+ uint32_t eptype :2; | |
+ uint32_t multicnt :2; | |
+ uint32_t devaddr :7; | |
+ uint32_t oddfrm :1; | |
+ uint32_t chdis :1; | |
+ uint32_t chen :1; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_hcsplt | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t prtaddr :7; | |
+ uint32_t hubaddr :7; | |
+ uint32_t xactpos :2; | |
+ uint32_t compsplt :1; | |
+ uint32_t reserved :14; | |
+ uint32_t spltena :1; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_hcintn | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t xfercompl :1; | |
+ uint32_t chhltd :1; | |
+ uint32_t ahberr :1; | |
+ uint32_t stall :1; | |
+ uint32_t nak :1; | |
+ uint32_t ack :1; | |
+ uint32_t nyet :1; | |
+ uint32_t xacterr :1; | |
+ uint32_t bblerr :1; | |
+ uint32_t frmovrun :1; | |
+ uint32_t datatglerr :1; | |
+ uint32_t reserved :21; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_hctsizn | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t xfersize :19; | |
+ uint32_t pktcnt :10; | |
+ uint32_t pid :2; | |
+ uint32_t dopng :1; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_hcgintmsk | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t xfercompl :1; | |
+ uint32_t chhltd :1; | |
+ uint32_t ahberr :1; | |
+ uint32_t stall :1; | |
+ uint32_t nak :1; | |
+ uint32_t ack :1; | |
+ uint32_t nyet :1; | |
+ uint32_t xacterr :1; | |
+ uint32_t bblerr :1; | |
+ uint32_t frmovrun :1; | |
+ uint32_t datatglerr :1; | |
+ uint32_t reserved :21; | |
+ } b; | |
+}; | |
+ | |
+union synopsysotg_pcgcctl | |
+{ | |
+ uint32_t d32; | |
+ struct | |
+ { | |
+ uint32_t stoppclk :1; | |
+ uint32_t gatehclk :1; | |
+ uint32_t reserved :30; | |
+ } b; | |
+}; | |
+ | |
+struct synopsysotg_gregs | |
+{ | |
+ volatile union synopsysotg_gotgctl gotgctl; | |
+ volatile union synopsysotg_gotgint gotgint; | |
+ volatile union synopsysotg_gahbcfg gahbcfg; | |
+ volatile union synopsysotg_gusbcfg gusbcfg; | |
+ volatile union synopsysotg_grstctl grstctl; | |
+ volatile union synopsysotg_gintsts gintsts; | |
+ volatile union synopsysotg_gintmsk gintmsk; | |
+ volatile union synopsysotg_grxfsts grxstsr; | |
+ volatile union synopsysotg_grxfsts grxstsp; | |
+ volatile union synopsysotg_rxfsiz grxfsiz; | |
+ volatile union synopsysotg_txfsiz dieptxf0_hnptxfsiz; | |
+ volatile union synopsysotg_hnptxsts hnptxsts; | |
+ volatile union synopsysotg_gi2cctl gi2cctl; | |
+ volatile uint32_t reserved34; | |
+ volatile union synopsysotg_gccfg gccfg; | |
+ volatile uint32_t cid; | |
+ volatile uint32_t gsnpsid; | |
+ volatile union synopsysotg_ghwcfg1 ghwcfg1; | |
+ volatile union synopsysotg_ghwcfg2 ghwcfg2; | |
+ volatile union synopsysotg_ghwcfg3 ghwcfg3; | |
+ volatile union synopsysotg_ghwcfg4 ghwcfg4; | |
+ volatile uint32_t glpmcfg; | |
+ volatile uint32_t reserved58[42]; | |
+ volatile union synopsysotg_txfsiz hptxfsiz; | |
+ volatile union synopsysotg_txfsiz dieptxf[15]; | |
+}; | |
+ | |
+struct synopsysotg_dregs | |
+{ | |
+ volatile union synopsysotg_dcfg dcfg; | |
+ volatile union synopsysotg_dctl dctl; | |
+ volatile union synopsysotg_dsts dsts; | |
+ volatile uint32_t reserved0c; | |
+ volatile union synopsysotg_diepintn diepmsk; | |
+ volatile union synopsysotg_doepintn doepmsk; | |
+ volatile union synopsysotg_daint daint; | |
+ volatile union synopsysotg_daint daintmsk; | |
+ volatile uint32_t reserved20; | |
+ volatile uint32_t reserved9; | |
+ volatile uint32_t dvbusdis; | |
+ volatile uint32_t dvbuspulse; | |
+ volatile union synopsysotg_dthrctl dthrctl; | |
+ volatile union synopsysotg_daint diepempmsk; | |
+ volatile union synopsysotg_daint deachint; | |
+ volatile union synopsysotg_daint deachmsk; | |
+ volatile union synopsysotg_diepintn dinep1msk; | |
+ volatile uint32_t reserved44[15]; | |
+ volatile union synopsysotg_doepintn doutep1msk; | |
+}; | |
+ | |
+struct synopsysotg_inepregs | |
+{ | |
+ volatile union synopsysotg_depctl diepctl; | |
+ volatile uint32_t reserved04; | |
+ volatile union synopsysotg_diepintn diepint; | |
+ volatile uint32_t reserved0c; | |
+ volatile union synopsysotg_depxfrsiz dieptsiz; | |
+ volatile const void* diepdma; | |
+ volatile union synopsysotg_dtxfstsn dtxfsts; | |
+ volatile uint32_t reserved18; | |
+}; | |
+ | |
+struct synopsysotg_outepregs | |
+{ | |
+ volatile union synopsysotg_depctl doepctl; | |
+ volatile uint32_t doutepfrm; | |
+ volatile union synopsysotg_doepintn doepint; | |
+ volatile uint32_t reserved0c; | |
+ volatile union synopsysotg_depxfrsiz doeptsiz; | |
+ volatile void* doepdma; | |
+ volatile uint32_t reserved18[2]; | |
+}; | |
+ | |
+struct synopsysotg_hregs | |
+{ | |
+ volatile union synopsysotg_hcfg hcfg; | |
+ volatile uint32_t hfir; | |
+ volatile union synopsysotg_hfnum hfnum; | |
+ volatile uint32_t reserved40c; | |
+ volatile union synopsysotg_hptxsts hptxsts; | |
+ volatile union synopsysotg_haint haint; | |
+ volatile union synopsysotg_haintmsk haintmsk; | |
+}; | |
+ | |
+struct synopsysotg_hc_regs | |
+{ | |
+ volatile union synopsysotg_hcchar hcchar; | |
+ volatile union synopsysotg_hcsplt hcsplt; | |
+ volatile union synopsysotg_hcintn hcint; | |
+ volatile union synopsysotg_hcintn hcgintmsk; | |
+ volatile union synopsysotg_hctsizn hctsiz; | |
+ volatile void* hcdma; | |
+ volatile uint32_t reserved[2]; | |
+}; | |
+ | |
+struct synopsysotg_core_regs | |
+{ | |
+ volatile struct synopsysotg_gregs gregs; | |
+ volatile uint32_t reserved140[176]; | |
+ volatile struct synopsysotg_hregs hregs; | |
+ volatile uint32_t reserved41c[9]; | |
+ volatile union synopsysotg_hprt0 hprt0; | |
+ volatile uint32_t reserved444[47]; | |
+ volatile struct synopsysotg_hc_regs hc_regs[16]; | |
+ volatile uint32_t reserved700[64]; | |
+ volatile struct synopsysotg_dregs dregs; | |
+ volatile uint32_t reserved884[31]; | |
+ volatile struct synopsysotg_inepregs inep_regs[16]; | |
+ volatile struct synopsysotg_outepregs outep_regs[16]; | |
+ volatile uint32_t reservedd00[64]; | |
+ volatile union synopsysotg_pcgcctl pcgcctl; | |
+ volatile uint32_t reservede04[127]; | |
+ volatile uint32_t dfifo[16][1024]; | |
+ volatile uint32_t reserved11000[15360]; | |
+ volatile uint32_t rawfifo[32768]; | |
+}; | |
+ | |
+ | |
+#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment