Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / usb / gadget / udc / mv_u3d.h
diff --git a/kernel/drivers/usb/gadget/udc/mv_u3d.h b/kernel/drivers/usb/gadget/udc/mv_u3d.h
new file mode 100644 (file)
index 0000000..e32a787
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#ifndef __MV_U3D_H
+#define __MV_U3D_H
+
+#define MV_U3D_EP_CONTEXT_ALIGNMENT    32
+#define MV_U3D_TRB_ALIGNMENT   16
+#define MV_U3D_DMA_BOUNDARY    4096
+#define MV_U3D_EP0_MAX_PKT_SIZE        512
+
+/* ep0 transfer state */
+#define MV_U3D_WAIT_FOR_SETUP          0
+#define MV_U3D_DATA_STATE_XMIT         1
+#define MV_U3D_DATA_STATE_NEED_ZLP     2
+#define MV_U3D_WAIT_FOR_OUT_STATUS     3
+#define MV_U3D_DATA_STATE_RECV         4
+#define MV_U3D_STATUS_STAGE            5
+
+#define MV_U3D_EP_MAX_LENGTH_TRANSFER  0x10000
+
+/* USB3 Interrupt Status */
+#define MV_U3D_USBINT_SETUP            0x00000001
+#define MV_U3D_USBINT_RX_COMPLETE      0x00000002
+#define MV_U3D_USBINT_TX_COMPLETE      0x00000004
+#define MV_U3D_USBINT_UNDER_RUN        0x00000008
+#define MV_U3D_USBINT_RXDESC_ERR       0x00000010
+#define MV_U3D_USBINT_TXDESC_ERR       0x00000020
+#define MV_U3D_USBINT_RX_TRB_COMPLETE  0x00000040
+#define MV_U3D_USBINT_TX_TRB_COMPLETE  0x00000080
+#define MV_U3D_USBINT_VBUS_VALID       0x00010000
+#define MV_U3D_USBINT_STORAGE_CMD_FULL 0x00020000
+#define MV_U3D_USBINT_LINK_CHG         0x01000000
+
+/* USB3 Interrupt Enable */
+#define MV_U3D_INTR_ENABLE_SETUP               0x00000001
+#define MV_U3D_INTR_ENABLE_RX_COMPLETE         0x00000002
+#define MV_U3D_INTR_ENABLE_TX_COMPLETE         0x00000004
+#define MV_U3D_INTR_ENABLE_UNDER_RUN           0x00000008
+#define MV_U3D_INTR_ENABLE_RXDESC_ERR          0x00000010
+#define MV_U3D_INTR_ENABLE_TXDESC_ERR          0x00000020
+#define MV_U3D_INTR_ENABLE_RX_TRB_COMPLETE     0x00000040
+#define MV_U3D_INTR_ENABLE_TX_TRB_COMPLETE     0x00000080
+#define MV_U3D_INTR_ENABLE_RX_BUFFER_ERR       0x00000100
+#define MV_U3D_INTR_ENABLE_VBUS_VALID          0x00010000
+#define MV_U3D_INTR_ENABLE_STORAGE_CMD_FULL    0x00020000
+#define MV_U3D_INTR_ENABLE_LINK_CHG            0x01000000
+#define MV_U3D_INTR_ENABLE_PRIME_STATUS        0x02000000
+
+/* USB3 Link Change */
+#define MV_U3D_LINK_CHANGE_LINK_UP             0x00000001
+#define MV_U3D_LINK_CHANGE_SUSPEND             0x00000002
+#define MV_U3D_LINK_CHANGE_RESUME              0x00000004
+#define MV_U3D_LINK_CHANGE_WRESET              0x00000008
+#define MV_U3D_LINK_CHANGE_HRESET              0x00000010
+#define MV_U3D_LINK_CHANGE_VBUS_INVALID        0x00000020
+#define MV_U3D_LINK_CHANGE_INACT               0x00000040
+#define MV_U3D_LINK_CHANGE_DISABLE_AFTER_U0    0x00000080
+#define MV_U3D_LINK_CHANGE_U1                  0x00000100
+#define MV_U3D_LINK_CHANGE_U2                  0x00000200
+#define MV_U3D_LINK_CHANGE_U3                  0x00000400
+
+/* bridge setting */
+#define MV_U3D_BRIDGE_SETTING_VBUS_VALID       (1 << 16)
+
+/* Command Register Bit Masks */
+#define MV_U3D_CMD_RUN_STOP            0x00000001
+#define MV_U3D_CMD_CTRL_RESET          0x00000002
+
+/* ep control register */
+#define MV_U3D_EPXCR_EP_TYPE_CONTROL           0
+#define MV_U3D_EPXCR_EP_TYPE_ISOC              1
+#define MV_U3D_EPXCR_EP_TYPE_BULK              2
+#define MV_U3D_EPXCR_EP_TYPE_INT               3
+#define MV_U3D_EPXCR_EP_ENABLE_SHIFT           4
+#define MV_U3D_EPXCR_MAX_BURST_SIZE_SHIFT      12
+#define MV_U3D_EPXCR_MAX_PACKET_SIZE_SHIFT     16
+#define MV_U3D_USB_BULK_BURST_OUT              6
+#define MV_U3D_USB_BULK_BURST_IN               14
+
+#define MV_U3D_EPXCR_EP_FLUSH          (1 << 7)
+#define MV_U3D_EPXCR_EP_HALT           (1 << 1)
+#define MV_U3D_EPXCR_EP_INIT           (1)
+
+/* TX/RX Status Register */
+#define MV_U3D_XFERSTATUS_COMPLETE_SHIFT       24
+#define MV_U3D_COMPLETE_INVALID        0
+#define MV_U3D_COMPLETE_SUCCESS        1
+#define MV_U3D_COMPLETE_BUFF_ERR       2
+#define MV_U3D_COMPLETE_SHORT_PACKET   3
+#define MV_U3D_COMPLETE_TRB_ERR        5
+#define MV_U3D_XFERSTATUS_TRB_LENGTH_MASK      (0xFFFFFF)
+
+#define MV_U3D_USB_LINK_BYPASS_VBUS    0x8
+
+#define MV_U3D_LTSSM_PHY_INIT_DONE             0x80000000
+#define MV_U3D_LTSSM_NEVER_GO_COMPLIANCE       0x40000000
+
+#define MV_U3D_USB3_OP_REGS_OFFSET     0x100
+#define MV_U3D_USB3_PHY_OFFSET         0xB800
+
+#define DCS_ENABLE     0x1
+
+/* timeout */
+#define MV_U3D_RESET_TIMEOUT           10000
+#define MV_U3D_FLUSH_TIMEOUT           100000
+#define MV_U3D_OWN_TIMEOUT             10000
+#define LOOPS_USEC_SHIFT       4
+#define LOOPS_USEC             (1 << LOOPS_USEC_SHIFT)
+#define LOOPS(timeout)         ((timeout) >> LOOPS_USEC_SHIFT)
+
+/* ep direction */
+#define MV_U3D_EP_DIR_IN               1
+#define MV_U3D_EP_DIR_OUT              0
+#define mv_u3d_ep_dir(ep)      (((ep)->ep_num == 0) ? \
+                               ((ep)->u3d->ep0_dir) : ((ep)->direction))
+
+/* usb capability registers */
+struct mv_u3d_cap_regs {
+       u32     rsvd[5];
+       u32     dboff;  /* doorbell register offset */
+       u32     rtsoff; /* runtime register offset */
+       u32     vuoff;  /* vendor unique register offset */
+};
+
+/* operation registers */
+struct mv_u3d_op_regs {
+       u32     usbcmd;         /* Command register */
+       u32     rsvd1[11];
+       u32     dcbaapl;        /* Device Context Base Address low register */
+       u32     dcbaaph;        /* Device Context Base Address high register */
+       u32     rsvd2[243];
+       u32     portsc;         /* port status and control register*/
+       u32     portlinkinfo;   /* port link info register*/
+       u32     rsvd3[9917];
+       u32     doorbell;       /* doorbell register */
+};
+
+/* control enpoint enable registers */
+struct epxcr {
+       u32     epxoutcr0;      /* ep out control 0 register */
+       u32     epxoutcr1;      /* ep out control 1 register */
+       u32     epxincr0;       /* ep in control 0 register */
+       u32     epxincr1;       /* ep in control 1 register */
+};
+
+/* transfer status registers */
+struct xferstatus {
+       u32     curdeqlo;       /* current TRB pointer low */
+       u32     curdeqhi;       /* current TRB pointer high */
+       u32     statuslo;       /* transfer status low */
+       u32     statushi;       /* transfer status high */
+};
+
+/* vendor unique control registers */
+struct mv_u3d_vuc_regs {
+       u32     ctrlepenable;   /* control endpoint enable register */
+       u32     setuplock;      /* setup lock register */
+       u32     endcomplete;    /* endpoint transfer complete register */
+       u32     intrcause;      /* interrupt cause register */
+       u32     intrenable;     /* interrupt enable register */
+       u32     trbcomplete;    /* TRB complete register */
+       u32     linkchange;     /* link change register */
+       u32     rsvd1[5];
+       u32     trbunderrun;    /* TRB underrun register */
+       u32     rsvd2[43];
+       u32     bridgesetting;  /* bridge setting register */
+       u32     rsvd3[7];
+       struct xferstatus       txst[16];       /* TX status register */
+       struct xferstatus       rxst[16];       /* RX status register */
+       u32     ltssm;          /* LTSSM control register */
+       u32     pipe;           /* PIPE control register */
+       u32     linkcr0;        /* link control 0 register */
+       u32     linkcr1;        /* link control 1 register */
+       u32     rsvd6[60];
+       u32     mib0;           /* MIB0 counter register */
+       u32     usblink;        /* usb link control register */
+       u32     ltssmstate;     /* LTSSM state register */
+       u32     linkerrorcause; /* link error cause register */
+       u32     rsvd7[60];
+       u32     devaddrtiebrkr; /* device address and tie breaker */
+       u32     itpinfo0;       /* ITP info 0 register */
+       u32     itpinfo1;       /* ITP info 1 register */
+       u32     rsvd8[61];
+       struct epxcr    epcr[16];       /* ep control register */
+       u32     rsvd9[64];
+       u32     phyaddr;        /* PHY address register */
+       u32     phydata;        /* PHY data register */
+};
+
+/* Endpoint context structure */
+struct mv_u3d_ep_context {
+       u32     rsvd0;
+       u32     rsvd1;
+       u32     trb_addr_lo;            /* TRB address low 32 bit */
+       u32     trb_addr_hi;            /* TRB address high 32 bit */
+       u32     rsvd2;
+       u32     rsvd3;
+       struct usb_ctrlrequest setup_buffer;    /* setup data buffer */
+};
+
+/* TRB control data structure */
+struct mv_u3d_trb_ctrl {
+       u32     own:1;          /* owner of TRB */
+       u32     rsvd1:3;
+       u32     chain:1;        /* associate this TRB with the
+                               next TRB on the Ring */
+       u32     ioc:1;          /* interrupt on complete */
+       u32     rsvd2:4;
+       u32     type:6;         /* TRB type */
+#define TYPE_NORMAL    1
+#define TYPE_DATA      3
+#define TYPE_LINK      6
+       u32     dir:1;          /* Working at data stage of control endpoint
+                               operation. 0 is OUT and 1 is IN. */
+       u32     rsvd3:15;
+};
+
+/* TRB data structure
+ * For multiple TRB, all the TRBs' physical address should be continuous.
+ */
+struct mv_u3d_trb_hw {
+       u32     buf_addr_lo;    /* data buffer address low 32 bit */
+       u32     buf_addr_hi;    /* data buffer address high 32 bit */
+       u32     trb_len;        /* transfer length */
+       struct mv_u3d_trb_ctrl  ctrl;   /* TRB control data */
+};
+
+/* TRB structure */
+struct mv_u3d_trb {
+       struct mv_u3d_trb_hw *trb_hw;   /* point to the trb_hw structure */
+       dma_addr_t trb_dma;             /* dma address for this trb_hw */
+       struct list_head trb_list;      /* trb list */
+};
+
+/* device data structure */
+struct mv_u3d {
+       struct usb_gadget               gadget;
+       struct usb_gadget_driver        *driver;
+       spinlock_t                      lock;   /* device lock */
+       struct completion               *done;
+       struct device                   *dev;
+       int                             irq;
+
+       /* usb controller registers */
+       struct mv_u3d_cap_regs __iomem  *cap_regs;
+       struct mv_u3d_op_regs __iomem   *op_regs;
+       struct mv_u3d_vuc_regs __iomem  *vuc_regs;
+       void __iomem                    *phy_regs;
+
+       unsigned int                    max_eps;
+       struct mv_u3d_ep_context        *ep_context;
+       size_t                          ep_context_size;
+       dma_addr_t                      ep_context_dma;
+
+       struct dma_pool                 *trb_pool; /* for TRB data structure */
+       struct mv_u3d_ep                *eps;
+
+       struct mv_u3d_req               *status_req; /* ep0 status request */
+       struct usb_ctrlrequest          local_setup_buff; /* store setup data*/
+
+       unsigned int            resume_state;   /* USB state to resume */
+       unsigned int            usb_state;      /* USB current state */
+       unsigned int            ep0_state;      /* Endpoint zero state */
+       unsigned int            ep0_dir;
+
+       unsigned int            dev_addr;       /* device address */
+
+       unsigned int            errors;
+
+       unsigned                softconnect:1;
+       unsigned                vbus_active:1;  /* vbus is active or not */
+       unsigned                remote_wakeup:1; /* support remote wakeup */
+       unsigned                clock_gating:1; /* clock gating or not */
+       unsigned                active:1;       /* udc is active or not */
+       unsigned                vbus_valid_detect:1; /* udc vbus detection */
+
+       struct mv_usb_addon_irq *vbus;
+       unsigned int            power;
+
+       struct clk              *clk;
+};
+
+/* endpoint data structure */
+struct mv_u3d_ep {
+       struct usb_ep           ep;
+       struct mv_u3d           *u3d;
+       struct list_head        queue;  /* ep request queued hardware */
+       struct list_head        req_list; /* list of ep request */
+       struct mv_u3d_ep_context        *ep_context; /* ep context */
+       u32                     direction;
+       char                    name[14];
+       u32                     processing; /* there is ep request
+                                               queued on haredware */
+       spinlock_t              req_lock; /* ep lock */
+       unsigned                wedge:1;
+       unsigned                enabled:1;
+       unsigned                ep_type:2;
+       unsigned                ep_num:8;
+};
+
+/* request data structure */
+struct mv_u3d_req {
+       struct usb_request      req;
+       struct mv_u3d_ep        *ep;
+       struct list_head        queue;  /* ep requst queued on hardware */
+       struct list_head        list;   /* ep request list */
+       struct list_head        trb_list; /* trb list of a request */
+
+       struct mv_u3d_trb       *trb_head; /* point to first trb of a request */
+       unsigned                trb_count; /* TRB number in the chain */
+       unsigned                chain;     /* TRB chain or not */
+};
+
+#endif