Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72246da4 authored by Felipe Balbi's avatar Felipe Balbi Committed by Greg Kroah-Hartman
Browse files

usb: Introduce DesignWare USB3 DRD Driver

The DesignWare USB3 is a highly
configurable IP Core which can be
instantiated as Dual-Role Device (DRD),
Peripheral Only and Host Only (XHCI)
configurations.

Several other parameters can be configured
like amount of FIFO space, amount of TX and
RX endpoints, amount of Host Interrupters,
etc.

The current driver has been validated with
a virtual model of version 1.73a of that core
and with an FPGA burned with version 1.83a
of the DRD core. We have support for PCIe
bus, which is used on FPGA prototyping, and
for the OMAP5, more adaptation (or glue)
layers can be easily added and the driver
is half prepared to handle any possible
configuration the HW engineer has chosen
considering we have the information on
one of the GHWPARAMS registers to do
runtime checking of certain features.

More runtime checks can, and should, be added
in order to make this driver even more flexible
with regards to number of endpoints, FIFO sizes,
transfer types, etc.

While this supports only the device side, for
now, we will add support for Host side (xHCI -
see the updated series Sebastian has sent [1])
and OTG after we have it all stabilized.

[1] http://marc.info/?l=linux-usb&m=131341992020339&w=2



Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 500fdf8b
Loading
Loading
Loading
Loading
+53 −0
Original line number Original line Diff line number Diff line

 TODO
~~~~~~
Please pick something while reading :)

- Implement streaming support for BULK endpoints
  Tatyana's patch "usb: Add streams support to the gadget framework"
  introduces streaming support for the gadget driver.
  Every usb_request has new field called stream_id which holds its id.
  Every usb_ep has a field num_supported_strms which describes the max
  number of streams supported (for this ep).
  UAS is AFAIK the only gadget with streaming support.

- Convert interrupt handler to per-ep-thread-irq

  As it turns out some DWC3-commands ~1ms to complete. Currently we spin
  until the command completes which is bad.

  Implementation idea:
  - dwc core implements a demultiplexing irq chip for interrupts per
    endpoint. The interrupt numbers are allocated during probe and belong
    to the device. If MSI provides per-endpoint interrupt this dummy
    interrupt chip can be replaced with "real" interrupts.
  - interrupts are requested / allocated on usb_ep_enable() and removed on
    usb_ep_disable(). Worst case are 32 interrupts, the lower limit is two
    for ep0/1.
  - dwc3_send_gadget_ep_cmd() will sleep in wait_for_completion_timeout()
    until the command completes.
  - the interrupt handler is split into the following pieces:
    - primary handler of the device
      goes through every event and calls generic_handle_irq() for event
      it. On return from generic_handle_irq() in acknowledges the event
      counter so interrupt goes away (eventually).

    - threaded handler of the device
      none

    - primary handler of the EP-interrupt
      reads the event and tries to process it. Everything that requries
      sleeping is handed over to the Thread. The event is saved in an
      per-endpoint data-structure.
      We probably have to pay attention not to process events once we
      handed something to thread so we don't process event X prio Y
      where X > Y.

    - threaded handler of the EP-interrupt
      handles the remaining EP work which might sleep such as waiting
      for command completion.

  Latency:
   There should be no increase in latency since the interrupt-thread has a
   high priority and will be run before an average task in user land
   (except the user changed priorities).
+2 −0
Original line number Original line Diff line number Diff line
@@ -111,6 +111,8 @@ config USB


source "drivers/usb/core/Kconfig"
source "drivers/usb/core/Kconfig"


source "drivers/usb/dwc3/Kconfig"

source "drivers/usb/mon/Kconfig"
source "drivers/usb/mon/Kconfig"


source "drivers/usb/wusbcore/Kconfig"
source "drivers/usb/wusbcore/Kconfig"
+2 −0
Original line number Original line Diff line number Diff line
@@ -6,6 +6,8 @@


obj-$(CONFIG_USB)		+= core/
obj-$(CONFIG_USB)		+= core/


obj-$(CONFIG_USB_DWC3)		+= dwc3/

obj-$(CONFIG_USB_MON)		+= mon/
obj-$(CONFIG_USB_MON)		+= mon/


obj-$(CONFIG_PCI)		+= host/
obj-$(CONFIG_PCI)		+= host/
+25 −0
Original line number Original line Diff line number Diff line
config USB_DWC3
	tristate "DesignWare USB3 DRD Core Support"
	depends on (USB || USB_GADGET)
	select USB_OTG_UTILS
	help
	  Say Y or M here if your system has a Dual Role SuperSpeed
	  USB controller based on the DesignWare USB3 IP Core.

	  If you choose to build this driver is a dynamically linked
	  module, the module will be called dwc3.ko.

if USB_DWC3

config USB_DWC3_DEBUG
	bool "Enable Debugging Messages"
	help
	  Say Y here to enable debugging messages on DWC3 Driver.

config USB_DWC3_VERBOSE
	bool "Enable Verbose Debugging Messages"
	depends on USB_DWC3_DEBUG
	help
	  Say Y here to enable verbose debugging messages on DWC3 Driver.

endif
+36 −0
Original line number Original line Diff line number Diff line
ccflags-$(CONFIG_USB_DWC3_DEBUG)	:= -DDEBUG
ccflags-$(CONFIG_USB_DWC3_VERBOSE)	+= -DVERBOSE_DEBUG

obj-$(CONFIG_USB_DWC3)			+= dwc3.o

dwc3-y					:= core.o

ifneq ($(CONFIG_USB_GADGET_DWC3),)
	dwc3-y				+= gadget.o ep0.o
endif

ifneq ($(CONFIG_DEBUG_FS),)
	dwc3-y				+= debugfs.o
endif

##
# Platform-specific glue layers go here
#
# NOTICE: Make sure your glue layer doesn't depend on anything
# which is arch-specific and that it compiles on all situations.
#
# We want to keep this requirement in order to be able to compile
# the entire driver (with all its glue layers) on several architectures
# and make sure it compiles fine. This will also help with allmodconfig
# and allyesconfig builds.
#
# The only exception is the PCI glue layer, but that's only because
# PCI doesn't provide nops if CONFIG_PCI isn't enabled.
##

obj-$(CONFIG_USB_DWC3)		+= dwc3-omap.o

ifneq ($(CONFIG_PCI),)
	obj-$(CONFIG_USB_DWC3)		+= dwc3-pci.o
endif
Loading