Merge branch 'linux-linaro-lsk-v4.4-android' of git://git.linaro.org/kernel/linux...
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc3 / core.h
index 36f1cb74588c5b7bff230e3ed91e42f73c3b47e8..5a517f3946591b98b98e0dbe3a719ef8e03c4798 100644 (file)
 #define DWC3_MSG_MAX   500
 
 /* Global constants */
+#define DWC3_ZLP_BUF_SIZE      1024    /* size of a superspeed bulk */
 #define DWC3_EP0_BOUNCE_SIZE   512
 #define DWC3_ENDPOINTS_NUM     32
 #define DWC3_XHCI_RESOURCES_NUM        2
 
 #define DWC3_SCRATCHBUF_SIZE   4096    /* each buffer is assumed to be 4KiB */
-#define DWC3_EVENT_SIZE                4       /* bytes */
-#define DWC3_EVENT_MAX_NUM     64      /* 2 events/endpoint */
-#define DWC3_EVENT_BUFFERS_SIZE        (DWC3_EVENT_SIZE * DWC3_EVENT_MAX_NUM)
+#define DWC3_EVENT_BUFFERS_SIZE        4096
 #define DWC3_EVENT_TYPE_MASK   0xfe
 
 #define DWC3_EVENT_TYPE_DEV    0
@@ -85,6 +84,7 @@
 #define DWC3_GCTL              0xc110
 #define DWC3_GEVTEN            0xc114
 #define DWC3_GSTS              0xc118
+#define DWC3_GUCTL1            0xc11c
 #define DWC3_GSNPSID           0xc120
 #define DWC3_GGPIO             0xc124
 #define DWC3_GUID              0xc128
 #define DWC3_DGCMDPAR          0xc710
 #define DWC3_DGCMD             0xc714
 #define DWC3_DALEPENA          0xc720
-#define DWC3_DEPCMDPAR2(n)     (0xc800 + (n * 0x10))
-#define DWC3_DEPCMDPAR1(n)     (0xc804 + (n * 0x10))
-#define DWC3_DEPCMDPAR0(n)     (0xc808 + (n * 0x10))
-#define DWC3_DEPCMD(n)         (0xc80c + (n * 0x10))
+
+#define DWC3_DEP_BASE(n)       (0xc800 + (n * 0x10))
+#define DWC3_DEPCMDPAR2                0x00
+#define DWC3_DEPCMDPAR1                0x04
+#define DWC3_DEPCMDPAR0                0x08
+#define DWC3_DEPCMD            0x0c
 
 /* OTG Registers */
 #define DWC3_OCFG              0xcc00
 
 /* Bit fields */
 
+/* Global Debug Queue/FIFO Space Available Register */
+#define DWC3_GDBGFIFOSPACE_NUM(n)      ((n) & 0x1f)
+#define DWC3_GDBGFIFOSPACE_TYPE(n)     (((n) << 5) & 0x1e0)
+#define DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(n) (((n) >> 16) & 0xffff)
+
+#define DWC3_TXFIFOQ           1
+#define DWC3_RXFIFOQ           3
+#define DWC3_TXREQQ            5
+#define DWC3_RXREQQ            7
+#define DWC3_RXINFOQ           9
+#define DWC3_DESCFETCHQ                13
+#define DWC3_EVENTQ            15
+
+/* Global RX Threshold Configuration Register */
+#define DWC3_GRXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0x1f) << 19)
+#define DWC3_GRXTHRCFG_RXPKTCNT(n) (((n) & 0xf) << 24)
+#define DWC3_GRXTHRCFG_PKTCNTSEL (1 << 29)
+
 /* Global Configuration Register */
 #define DWC3_GCTL_PWRDNSCALE(n)        ((n) << 19)
 #define DWC3_GCTL_U2RSTECN     (1 << 16)
 
 /* Global USB2 PHY Configuration Register */
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST    (1 << 31)
+#define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS     (1 << 30)
 #define DWC3_GUSB2PHYCFG_SUSPHY                (1 << 6)
 #define DWC3_GUSB2PHYCFG_ULPI_UTMI     (1 << 4)
 #define DWC3_GUSB2PHYCFG_ENBLSLPM      (1 << 8)
+#define DWC3_GUSB2PHYCFG_PHYIF(n)      (n << 3)
+#define DWC3_GUSB2PHYCFG_PHYIF_MASK    DWC3_GUSB2PHYCFG_PHYIF(1)
+#define DWC3_GUSB2PHYCFG_USBTRDTIM(n)  (n << 10)
+#define DWC3_GUSB2PHYCFG_USBTRDTIM_MASK        DWC3_GUSB2PHYCFG_USBTRDTIM(0xf)
+#define USBTRDTIM_UTMI_8_BIT           9
+#define USBTRDTIM_UTMI_16_BIT          5
+#define UTMI_PHYIF_16_BIT              1
+#define UTMI_PHYIF_8_BIT               0
 
 /* Global USB2 PHY Vendor Control Register */
 #define DWC3_GUSB2PHYACC_NEWREGREQ     (1 << 25)
 /* Global USB3 PIPE Control Register */
 #define DWC3_GUSB3PIPECTL_PHYSOFTRST   (1 << 31)
 #define DWC3_GUSB3PIPECTL_U2SSINP3OK   (1 << 29)
+#define DWC3_GUSB3PIPECTL_DISRXDETINP3 (1 << 28)
 #define DWC3_GUSB3PIPECTL_REQP1P2P3    (1 << 24)
 #define DWC3_GUSB3PIPECTL_DEP1P2P3(n)  ((n) << 19)
 #define DWC3_GUSB3PIPECTL_DEP1P2P3_MASK        DWC3_GUSB3PIPECTL_DEP1P2P3(7)
 #define DWC3_GEVNTSIZ_INTMASK          (1 << 31)
 #define DWC3_GEVNTSIZ_SIZE(n)          ((n) & 0xffff)
 
+/* Global HWPARAMS0 Register */
+#define DWC3_GHWPARAMS0_USB3_MODE(n)   ((n) & 0x3)
+#define DWC3_GHWPARAMS0_MBUS_TYPE(n)   (((n) >> 3) & 0x7)
+#define DWC3_GHWPARAMS0_SBUS_TYPE(n)   (((n) >> 6) & 0x3)
+#define DWC3_GHWPARAMS0_MDWIDTH(n)     (((n) >> 8) & 0xff)
+#define DWC3_GHWPARAMS0_SDWIDTH(n)     (((n) >> 16) & 0xff)
+#define DWC3_GHWPARAMS0_AWIDTH(n)      (((n) >> 24) & 0xff)
+
 /* Global HWPARAMS1 Register */
 #define DWC3_GHWPARAMS1_EN_PWROPT(n)   (((n) & (3 << 24)) >> 24)
 #define DWC3_GHWPARAMS1_EN_PWROPT_NO   0
 /* Global HWPARAMS6 Register */
 #define DWC3_GHWPARAMS6_EN_FPGA                        (1 << 7)
 
+/* Global HWPARAMS7 Register */
+#define DWC3_GHWPARAMS7_RAM1_DEPTH(n)  ((n) & 0xffff)
+#define DWC3_GHWPARAMS7_RAM2_DEPTH(n)  (((n) >> 16) & 0xffff)
+
 /* Global Frame Length Adjustment Register */
 #define DWC3_GFLADJ_30MHZ_SDBND_SEL            (1 << 7)
 #define DWC3_GFLADJ_30MHZ_MASK                 0x3f
 #define DWC3_DCFG_LOWSPEED     (2 << 0)
 #define DWC3_DCFG_FULLSPEED1   (3 << 0)
 
+#define DWC3_DCFG_NUMP_SHIFT   17
+#define DWC3_DCFG_NUMP(n)      (((n) >> DWC3_DCFG_NUMP_SHIFT) & 0x1f)
+#define DWC3_DCFG_NUMP_MASK    (0x1f << DWC3_DCFG_NUMP_SHIFT)
 #define DWC3_DCFG_LPM_CAP      (1 << 22)
 
 /* Device Control Register */
 #define DWC3_DEPCMD_GET_RSC_IDX(x)     (((x) >> DWC3_DEPCMD_PARAM_SHIFT) & 0x7f)
 #define DWC3_DEPCMD_STATUS(x)          (((x) >> 12) & 0x0F)
 #define DWC3_DEPCMD_HIPRI_FORCERM      (1 << 11)
+#define DWC3_DEPCMD_CLEARPENDIN                (1 << 11)
 #define DWC3_DEPCMD_CMDACT             (1 << 10)
 #define DWC3_DEPCMD_CMDIOC             (1 << 8)
 
@@ -434,18 +480,19 @@ struct dwc3_event_buffer {
 #define DWC3_EP_DIRECTION_TX   true
 #define DWC3_EP_DIRECTION_RX   false
 
-#define DWC3_TRB_NUM           32
-#define DWC3_TRB_MASK          (DWC3_TRB_NUM - 1)
+#define DWC3_TRB_NUM           256
 
 /**
  * struct dwc3_ep - device side endpoint representation
  * @endpoint: usb endpoint
- * @request_list: list of requests for this endpoint
- * @req_queued: list of requests on this ep which have TRBs setup
+ * @pending_list: list of pending requests for this endpoint
+ * @started_list: list of started requests on this endpoint
+ * @lock: spinlock for endpoint request queue traversal
+ * @regs: pointer to first endpoint register
  * @trb_pool: array of transaction buffers
  * @trb_pool_dma: dma address of @trb_pool
- * @free_slot: next slot which is going to be used
- * @busy_slot: first slot which is owned by HW
+ * @trb_enqueue: enqueue 'pointer' into TRB array
+ * @trb_dequeue: dequeue 'pointer' into TRB array
  * @desc: usb_endpoint_descriptor pointer
  * @dwc: pointer to DWC controller
  * @saved_state: ep state saved during hibernation
@@ -454,19 +501,22 @@ struct dwc3_event_buffer {
  * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK
  * @resource_index: Resource transfer index
  * @interval: the interval on which the ISOC transfer is started
+ * @allocated_requests: number of requests allocated
+ * @queued_requests: number of requests queued for transfer
  * @name: a human readable name e.g. ep1out-bulk
  * @direction: true for TX, false for RX
  * @stream_capable: true when streams are enabled
  */
 struct dwc3_ep {
        struct usb_ep           endpoint;
-       struct list_head        request_list;
-       struct list_head        req_queued;
+       struct list_head        pending_list;
+       struct list_head        started_list;
+
+       spinlock_t              lock;
+       void __iomem            *regs;
 
        struct dwc3_trb         *trb_pool;
        dma_addr_t              trb_pool_dma;
-       u32                     free_slot;
-       u32                     busy_slot;
        const struct usb_ss_ep_comp_descriptor *comp_desc;
        struct dwc3             *dwc;
 
@@ -482,9 +532,23 @@ struct dwc3_ep {
        /* This last one is specific to EP0 */
 #define DWC3_EP0_DIR_IN                (1 << 31)
 
+       /*
+        * IMPORTANT: we *know* we have 256 TRBs in our @trb_pool, so we will
+        * use a u8 type here. If anybody decides to increase number of TRBs to
+        * anything larger than 256 - I can't see why people would want to do
+        * this though - then this type needs to be changed.
+        *
+        * By using u8 types we ensure that our % operator when incrementing
+        * enqueue and dequeue get optimized away by the compiler.
+        */
+       u8                      trb_enqueue;
+       u8                      trb_dequeue;
+
        u8                      number;
        u8                      type;
        u8                      resource_index;
+       u32                     allocated_requests;
+       u32                     queued_requests;
        u32                     interval;
 
        char                    name[20];
@@ -553,6 +617,7 @@ enum dwc3_link_state {
 #define DWC3_TRB_CTRL_IOC              (1 << 11)
 #define DWC3_TRB_CTRL_SID_SOFN(n)      (((n) & 0xffff) << 14)
 
+#define DWC3_TRBCTL_TYPE(n)            ((n) & (0x3f << 4))
 #define DWC3_TRBCTL_NORMAL             DWC3_TRB_CTRL_TRBCTL(1)
 #define DWC3_TRBCTL_CONTROL_SETUP      DWC3_TRB_CTRL_TRBCTL(2)
 #define DWC3_TRBCTL_CONTROL_STATUS2    DWC3_TRB_CTRL_TRBCTL(3)
@@ -619,19 +684,32 @@ struct dwc3_hwparams {
 /* HWPARAMS7 */
 #define DWC3_RAM1_DEPTH(n)     ((n) & 0xffff)
 
+/**
+ * struct dwc3_request - representation of a transfer request
+ * @request: struct usb_request to be transferred
+ * @list: a list_head used for request queueing
+ * @dep: struct dwc3_ep owning this request
+ * @first_trb_index: index to first trb used by this request
+ * @epnum: endpoint number to which this request refers
+ * @trb: pointer to struct dwc3_trb
+ * @trb_dma: DMA address of @trb
+ * @direction: IN or OUT direction flag
+ * @mapped: true when request has been dma-mapped
+ * @queued: true when request has been queued to HW
+ */
 struct dwc3_request {
        struct usb_request      request;
        struct list_head        list;
        struct dwc3_ep          *dep;
-       u32                     start_slot;
 
+       u8                      first_trb_index;
        u8                      epnum;
        struct dwc3_trb         *trb;
        dma_addr_t              trb_dma;
 
        unsigned                direction:1;
        unsigned                mapped:1;
-       unsigned                queued:1;
+       unsigned                started:1;
 };
 
 /*
@@ -647,6 +725,7 @@ struct dwc3_scratchpad_array {
  * @ctrl_req: usb control request which is used for ep0
  * @ep0_trb: trb which is used for the ctrl_req
  * @ep0_bounce: bounce buffer for ep0
+ * @zlp_buf: used when request->zero is set
  * @setup_buf: used while precessing STD USB requests
  * @ctrl_req_addr: dma address of ctrl_req
  * @ep0_trb: dma address of ep0_trb
@@ -661,12 +740,16 @@ struct dwc3_scratchpad_array {
  * @gadget_driver: pointer to the gadget driver
  * @regs: base address for our registers
  * @regs_size: address space size
+ * @fladj: frame length adjustment
+ * @irq_gadget: peripheral controller's IRQ number
  * @nr_scratch: number of scratch buffers
- * @num_event_buffers: calculated number of event buffers
  * @u1u2: only used on revisions <1.83a for workaround
  * @maximum_speed: maximum speed requested (mainly for testing purposes)
  * @revision: revision register contents
  * @dr_mode: requested mode of operation
+ * @hsphy_mode: UTMI phy mode, one of following:
+ *             - USBPHY_INTERFACE_MODE_UTMI
+ *             - USBPHY_INTERFACE_MODE_UTMIW
  * @usb2_phy: pointer to USB2 PHY
  * @usb3_phy: pointer to USB3 PHY
  * @usb2_generic_phy: pointer to USB2 PHY
@@ -694,6 +777,7 @@ struct dwc3_scratchpad_array {
  * @lpm_nyet_threshold: LPM NYET response threshold
  * @hird_threshold: HIRD threshold
  * @hsphy_interface: "utmi" or "ulpi"
+ * @connected: true when we're connected to a host, false otherwise
  * @delayed_status: true when gadget driver asks for delayed status
  * @ep0_bounced: true when we used bounce buffer
  * @ep0_expect_in: true when we expect a DATA IN transfer
@@ -704,9 +788,8 @@ struct dwc3_scratchpad_array {
  *     0       - utmi_sleep_n
  *     1       - utmi_l1_suspend_n
  * @is_fpga: true when we are using the FPGA board
- * @needs_fifo_resize: not all users might want fifo resizing, flag it
+ * @pending_events: true when we have pending IRQs to be handled
  * @pullups_connected: true when Run/Stop bit is set
- * @resize_fifos: tells us it's ok to reconfigure our TxFIFO sizes.
  * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround
  * @start_config_issued: true when StartConfig command has been issued
  * @three_stage_setup: set if we perform a three phase setup
@@ -719,10 +802,19 @@ struct dwc3_scratchpad_array {
  * @del_phy_power_chg_quirk: set if we enable delay phy power change quirk
  * @lfps_filter_quirk: set if we enable LFPS filter quirk
  * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk
+ * @dis_u3_autosuspend_quirk: set if the we disable usb3 autosuspend
  * @dis_u3_susphy_quirk: set if we disable usb3 suspend phy
  * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy
  * @dis_enblslpm_quirk: set if we clear enblslpm in GUSB2PHYCFG,
  *                      disabling the suspend signal to the PHY.
+ * @dis_u2_freeclk_exists_quirk : set if we clear u2_freeclk_exists
+ *                     in GUSB2PHYCFG, specify that USB2 PHY doesn't
+ *                     provide a free-running PHY clock.
+ * @dis_del_phy_power_chg_quirk: set if we disable delay phy power
+ *                     change quirk.
+ * @xhci_slow_suspend_quirk: set if need an extraordinary delay to wait
+ *                     for xHC enter the Halted state after the Run/Stop
+ *                     (R/S) bit is cleared to '0'.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  *     0       - -6dB de-emphasis
@@ -734,6 +826,7 @@ struct dwc3 {
        struct usb_ctrlrequest  *ctrl_req;
        struct dwc3_trb         *ep0_trb;
        void                    *ep0_bounce;
+       void                    *zlp_buf;
        void                    *scratchbuf;
        u8                      *setup_buf;
        dma_addr_t              ctrl_req_addr;
@@ -750,7 +843,7 @@ struct dwc3 {
        struct platform_device  *xhci;
        struct resource         xhci_resources[DWC3_XHCI_RESOURCES_NUM];
 
-       struct dwc3_event_buffer **ev_buffs;
+       struct dwc3_event_buffer *ev_buf;
        struct dwc3_ep          *eps[DWC3_ENDPOINTS_NUM];
 
        struct usb_gadget       gadget;
@@ -768,13 +861,11 @@ struct dwc3 {
        size_t                  regs_size;
 
        enum usb_dr_mode        dr_mode;
+       enum usb_phy_interface  hsphy_mode;
 
-       /* used for suspend/resume */
-       u32                     dcfg;
-       u32                     gctl;
-
+       u32                     fladj;
+       u32                     irq_gadget;
        u32                     nr_scratch;
-       u32                     num_event_buffers;
        u32                     u1u2;
        u32                     maximum_speed;
 
@@ -812,7 +903,7 @@ struct dwc3 {
  * just so dwc31 revisions are always larger than dwc3.
  */
 #define DWC3_REVISION_IS_DWC31         0x80000000
-#define DWC3_USB31_REVISION_110A       (0x3131302a | DWC3_REVISION_IS_USB31)
+#define DWC3_USB31_REVISION_110A       (0x3131302a | DWC3_REVISION_IS_DWC31)
 
        enum dwc3_ep0_next      ep0_next_event;
        enum dwc3_ep0_state     ep0state;
@@ -842,6 +933,7 @@ struct dwc3 {
 
        const char              *hsphy_interface;
 
+       unsigned                connected:1;
        unsigned                delayed_status:1;
        unsigned                ep0_bounced:1;
        unsigned                ep0_expect_in:1;
@@ -849,11 +941,9 @@ struct dwc3 {
        unsigned                has_lpm_erratum:1;
        unsigned                is_utmi_l1_suspend:1;
        unsigned                is_fpga:1;
-       unsigned                needs_fifo_resize:1;
+       unsigned                pending_events:1;
        unsigned                pullups_connected:1;
-       unsigned                resize_fifos:1;
        unsigned                setup_packet_pending:1;
-       unsigned                start_config_issued:1;
        unsigned                three_stage_setup:1;
        unsigned                usb3_lpm_capable:1;
 
@@ -865,9 +955,14 @@ struct dwc3 {
        unsigned                del_phy_power_chg_quirk:1;
        unsigned                lfps_filter_quirk:1;
        unsigned                rx_detect_poll_quirk:1;
+       unsigned                dis_u3_autosuspend_quirk:1;
        unsigned                dis_u3_susphy_quirk:1;
        unsigned                dis_u2_susphy_quirk:1;
        unsigned                dis_enblslpm_quirk:1;
+       unsigned                dis_rxdet_inp3_quirk:1;
+       unsigned                dis_u2_freeclk_exists_quirk:1;
+       unsigned                dis_del_phy_power_chg_quirk:1;
+       unsigned                xhci_slow_suspend_quirk:1;
 
        unsigned                tx_de_emphasis_quirk:1;
        unsigned                tx_de_emphasis:2;
@@ -933,6 +1028,10 @@ struct dwc3_event_depevt {
 #define DEPEVT_STATUS_CONTROL_DATA     1
 #define DEPEVT_STATUS_CONTROL_STATUS   2
 
+/* In response to Start Transfer */
+#define DEPEVT_TRANSFER_NO_RESOURCE    1
+#define DEPEVT_TRANSFER_BUS_EXPIRY     2
+
        u32     parameters:16;
 } __packed;
 
@@ -1020,7 +1119,13 @@ struct dwc3_gadget_ep_cmd_params {
 
 /* prototypes */
 void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
-int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);
+u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type);
+
+/* check whether we are on the DWC_usb31 core */
+static inline bool dwc3_is_usb31(struct dwc3 *dwc)
+{
+       return !!(dwc->revision & DWC3_REVISION_IS_DWC31);
+}
 
 #if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
 int dwc3_host_init(struct dwc3 *dwc);
@@ -1038,8 +1143,8 @@ void dwc3_gadget_exit(struct dwc3 *dwc);
 int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode);
 int dwc3_gadget_get_link_state(struct dwc3 *dwc);
 int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state);
-int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
-               unsigned cmd, struct dwc3_gadget_ep_cmd_params *params);
+int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
+               struct dwc3_gadget_ep_cmd_params *params);
 int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param);
 #else
 static inline int dwc3_gadget_init(struct dwc3 *dwc)
@@ -1054,8 +1159,8 @@ static inline int dwc3_gadget_set_link_state(struct dwc3 *dwc,
                enum dwc3_link_state state)
 { return 0; }
 
-static inline int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
-               unsigned cmd, struct dwc3_gadget_ep_cmd_params *params)
+static inline int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
+               struct dwc3_gadget_ep_cmd_params *params)
 { return 0; }
 static inline int dwc3_send_gadget_generic_command(struct dwc3 *dwc,
                int cmd, u32 param)
@@ -1066,6 +1171,7 @@ static inline int dwc3_send_gadget_generic_command(struct dwc3 *dwc,
 #if !IS_ENABLED(CONFIG_USB_DWC3_HOST)
 int dwc3_gadget_suspend(struct dwc3 *dwc);
 int dwc3_gadget_resume(struct dwc3 *dwc);
+void dwc3_gadget_process_pending_events(struct dwc3 *dwc);
 #else
 static inline int dwc3_gadget_suspend(struct dwc3 *dwc)
 {
@@ -1076,6 +1182,10 @@ static inline int dwc3_gadget_resume(struct dwc3 *dwc)
 {
        return 0;
 }
+
+static inline void dwc3_gadget_process_pending_events(struct dwc3 *dwc)
+{
+}
 #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */
 
 #if IS_ENABLED(CONFIG_USB_DWC3_ULPI)