linux/drivers/usb/gadget/mv_u3d.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms and conditions of the GNU General Public License,
   6 * version 2, as published by the Free Software Foundation.
   7 */
   8
   9#ifndef __MV_U3D_H
  10#define __MV_U3D_H
  11
  12#define MV_U3D_EP_CONTEXT_ALIGNMENT     32
  13#define MV_U3D_TRB_ALIGNMENT    16
  14#define MV_U3D_DMA_BOUNDARY     4096
  15#define MV_U3D_EP0_MAX_PKT_SIZE 512
  16
  17/* ep0 transfer state */
  18#define MV_U3D_WAIT_FOR_SETUP           0
  19#define MV_U3D_DATA_STATE_XMIT          1
  20#define MV_U3D_DATA_STATE_NEED_ZLP      2
  21#define MV_U3D_WAIT_FOR_OUT_STATUS      3
  22#define MV_U3D_DATA_STATE_RECV          4
  23#define MV_U3D_STATUS_STAGE             5
  24
  25#define MV_U3D_EP_MAX_LENGTH_TRANSFER   0x10000
  26
  27/* USB3 Interrupt Status */
  28#define MV_U3D_USBINT_SETUP             0x00000001
  29#define MV_U3D_USBINT_RX_COMPLETE       0x00000002
  30#define MV_U3D_USBINT_TX_COMPLETE       0x00000004
  31#define MV_U3D_USBINT_UNDER_RUN 0x00000008
  32#define MV_U3D_USBINT_RXDESC_ERR        0x00000010
  33#define MV_U3D_USBINT_TXDESC_ERR        0x00000020
  34#define MV_U3D_USBINT_RX_TRB_COMPLETE   0x00000040
  35#define MV_U3D_USBINT_TX_TRB_COMPLETE   0x00000080
  36#define MV_U3D_USBINT_VBUS_VALID        0x00010000
  37#define MV_U3D_USBINT_STORAGE_CMD_FULL  0x00020000
  38#define MV_U3D_USBINT_LINK_CHG          0x01000000
  39
  40/* USB3 Interrupt Enable */
  41#define MV_U3D_INTR_ENABLE_SETUP                0x00000001
  42#define MV_U3D_INTR_ENABLE_RX_COMPLETE          0x00000002
  43#define MV_U3D_INTR_ENABLE_TX_COMPLETE          0x00000004
  44#define MV_U3D_INTR_ENABLE_UNDER_RUN            0x00000008
  45#define MV_U3D_INTR_ENABLE_RXDESC_ERR           0x00000010
  46#define MV_U3D_INTR_ENABLE_TXDESC_ERR           0x00000020
  47#define MV_U3D_INTR_ENABLE_RX_TRB_COMPLETE      0x00000040
  48#define MV_U3D_INTR_ENABLE_TX_TRB_COMPLETE      0x00000080
  49#define MV_U3D_INTR_ENABLE_RX_BUFFER_ERR        0x00000100
  50#define MV_U3D_INTR_ENABLE_VBUS_VALID           0x00010000
  51#define MV_U3D_INTR_ENABLE_STORAGE_CMD_FULL     0x00020000
  52#define MV_U3D_INTR_ENABLE_LINK_CHG             0x01000000
  53#define MV_U3D_INTR_ENABLE_PRIME_STATUS 0x02000000
  54
  55/* USB3 Link Change */
  56#define MV_U3D_LINK_CHANGE_LINK_UP              0x00000001
  57#define MV_U3D_LINK_CHANGE_SUSPEND              0x00000002
  58#define MV_U3D_LINK_CHANGE_RESUME               0x00000004
  59#define MV_U3D_LINK_CHANGE_WRESET               0x00000008
  60#define MV_U3D_LINK_CHANGE_HRESET               0x00000010
  61#define MV_U3D_LINK_CHANGE_VBUS_INVALID 0x00000020
  62#define MV_U3D_LINK_CHANGE_INACT                0x00000040
  63#define MV_U3D_LINK_CHANGE_DISABLE_AFTER_U0     0x00000080
  64#define MV_U3D_LINK_CHANGE_U1                   0x00000100
  65#define MV_U3D_LINK_CHANGE_U2                   0x00000200
  66#define MV_U3D_LINK_CHANGE_U3                   0x00000400
  67
  68/* bridge setting */
  69#define MV_U3D_BRIDGE_SETTING_VBUS_VALID        (1 << 16)
  70
  71/* Command Register Bit Masks */
  72#define MV_U3D_CMD_RUN_STOP             0x00000001
  73#define MV_U3D_CMD_CTRL_RESET           0x00000002
  74
  75/* ep control register */
  76#define MV_U3D_EPXCR_EP_TYPE_CONTROL            0
  77#define MV_U3D_EPXCR_EP_TYPE_ISOC               1
  78#define MV_U3D_EPXCR_EP_TYPE_BULK               2
  79#define MV_U3D_EPXCR_EP_TYPE_INT                3
  80#define MV_U3D_EPXCR_EP_ENABLE_SHIFT            4
  81#define MV_U3D_EPXCR_MAX_BURST_SIZE_SHIFT       12
  82#define MV_U3D_EPXCR_MAX_PACKET_SIZE_SHIFT      16
  83#define MV_U3D_USB_BULK_BURST_OUT               6
  84#define MV_U3D_USB_BULK_BURST_IN                14
  85
  86#define MV_U3D_EPXCR_EP_FLUSH           (1 << 7)
  87#define MV_U3D_EPXCR_EP_HALT            (1 << 1)
  88#define MV_U3D_EPXCR_EP_INIT            (1)
  89
  90/* TX/RX Status Register */
  91#define MV_U3D_XFERSTATUS_COMPLETE_SHIFT        24
  92#define MV_U3D_COMPLETE_INVALID 0
  93#define MV_U3D_COMPLETE_SUCCESS 1
  94#define MV_U3D_COMPLETE_BUFF_ERR        2
  95#define MV_U3D_COMPLETE_SHORT_PACKET    3
  96#define MV_U3D_COMPLETE_TRB_ERR 5
  97#define MV_U3D_XFERSTATUS_TRB_LENGTH_MASK       (0xFFFFFF)
  98
  99#define MV_U3D_USB_LINK_BYPASS_VBUS     0x8
 100
 101#define MV_U3D_LTSSM_PHY_INIT_DONE              0x80000000
 102#define MV_U3D_LTSSM_NEVER_GO_COMPLIANCE        0x40000000
 103
 104#define MV_U3D_USB3_OP_REGS_OFFSET      0x100
 105#define MV_U3D_USB3_PHY_OFFSET          0xB800
 106
 107#define DCS_ENABLE      0x1
 108
 109/* timeout */
 110#define MV_U3D_RESET_TIMEOUT            10000
 111#define MV_U3D_FLUSH_TIMEOUT            100000
 112#define MV_U3D_OWN_TIMEOUT              10000
 113#define LOOPS_USEC_SHIFT        4
 114#define LOOPS_USEC              (1 << LOOPS_USEC_SHIFT)
 115#define LOOPS(timeout)          ((timeout) >> LOOPS_USEC_SHIFT)
 116
 117/* ep direction */
 118#define MV_U3D_EP_DIR_IN                1
 119#define MV_U3D_EP_DIR_OUT               0
 120#define mv_u3d_ep_dir(ep)       (((ep)->ep_num == 0) ? \
 121                                ((ep)->u3d->ep0_dir) : ((ep)->direction))
 122
 123/* usb capability registers */
 124struct mv_u3d_cap_regs {
 125        u32     rsvd[5];
 126        u32     dboff;  /* doorbell register offset */
 127        u32     rtsoff; /* runtime register offset */
 128        u32     vuoff;  /* vendor unique register offset */
 129};
 130
 131/* operation registers */
 132struct mv_u3d_op_regs {
 133        u32     usbcmd;         /* Command register */
 134        u32     rsvd1[11];
 135        u32     dcbaapl;        /* Device Context Base Address low register */
 136        u32     dcbaaph;        /* Device Context Base Address high register */
 137        u32     rsvd2[243];
 138        u32     portsc;         /* port status and control register*/
 139        u32     portlinkinfo;   /* port link info register*/
 140        u32     rsvd3[9917];
 141        u32     doorbell;       /* doorbell register */
 142};
 143
 144/* control enpoint enable registers */
 145struct epxcr {
 146        u32     epxoutcr0;      /* ep out control 0 register */
 147        u32     epxoutcr1;      /* ep out control 1 register */
 148        u32     epxincr0;       /* ep in control 0 register */
 149        u32     epxincr1;       /* ep in control 1 register */
 150};
 151
 152/* transfer status registers */
 153struct xferstatus {
 154        u32     curdeqlo;       /* current TRB pointer low */
 155        u32     curdeqhi;       /* current TRB pointer high */
 156        u32     statuslo;       /* transfer status low */
 157        u32     statushi;       /* transfer status high */
 158};
 159
 160/* vendor unique control registers */
 161struct mv_u3d_vuc_regs {
 162        u32     ctrlepenable;   /* control endpoint enable register */
 163        u32     setuplock;      /* setup lock register */
 164        u32     endcomplete;    /* endpoint transfer complete register */
 165        u32     intrcause;      /* interrupt cause register */
 166        u32     intrenable;     /* interrupt enable register */
 167        u32     trbcomplete;    /* TRB complete register */
 168        u32     linkchange;     /* link change register */
 169        u32     rsvd1[5];
 170        u32     trbunderrun;    /* TRB underrun register */
 171        u32     rsvd2[43];
 172        u32     bridgesetting;  /* bridge setting register */
 173        u32     rsvd3[7];
 174        struct xferstatus       txst[16];       /* TX status register */
 175        struct xferstatus       rxst[16];       /* RX status register */
 176        u32     ltssm;          /* LTSSM control register */
 177        u32     pipe;           /* PIPE control register */
 178        u32     linkcr0;        /* link control 0 register */
 179        u32     linkcr1;        /* link control 1 register */
 180        u32     rsvd6[60];
 181        u32     mib0;           /* MIB0 counter register */
 182        u32     usblink;        /* usb link control register */
 183        u32     ltssmstate;     /* LTSSM state register */
 184        u32     linkerrorcause; /* link error cause register */
 185        u32     rsvd7[60];
 186        u32     devaddrtiebrkr; /* device address and tie breaker */
 187        u32     itpinfo0;       /* ITP info 0 register */
 188        u32     itpinfo1;       /* ITP info 1 register */
 189        u32     rsvd8[61];
 190        struct epxcr    epcr[16];       /* ep control register */
 191        u32     rsvd9[64];
 192        u32     phyaddr;        /* PHY address register */
 193        u32     phydata;        /* PHY data register */
 194};
 195
 196/* Endpoint context structure */
 197struct mv_u3d_ep_context {
 198        u32     rsvd0;
 199        u32     rsvd1;
 200        u32     trb_addr_lo;            /* TRB address low 32 bit */
 201        u32     trb_addr_hi;            /* TRB address high 32 bit */
 202        u32     rsvd2;
 203        u32     rsvd3;
 204        struct usb_ctrlrequest setup_buffer;    /* setup data buffer */
 205};
 206
 207/* TRB control data structure */
 208struct mv_u3d_trb_ctrl {
 209        u32     own:1;          /* owner of TRB */
 210        u32     rsvd1:3;
 211        u32     chain:1;        /* associate this TRB with the
 212                                next TRB on the Ring */
 213        u32     ioc:1;          /* interrupt on complete */
 214        u32     rsvd2:4;
 215        u32     type:6;         /* TRB type */
 216#define TYPE_NORMAL     1
 217#define TYPE_DATA       3
 218#define TYPE_LINK       6
 219        u32     dir:1;          /* Working at data stage of control endpoint
 220                                operation. 0 is OUT and 1 is IN. */
 221        u32     rsvd3:15;
 222};
 223
 224/* TRB data structure
 225 * For multiple TRB, all the TRBs' physical address should be continuous.
 226 */
 227struct mv_u3d_trb_hw {
 228        u32     buf_addr_lo;    /* data buffer address low 32 bit */
 229        u32     buf_addr_hi;    /* data buffer address high 32 bit */
 230        u32     trb_len;        /* transfer length */
 231        struct mv_u3d_trb_ctrl  ctrl;   /* TRB control data */
 232};
 233
 234/* TRB structure */
 235struct mv_u3d_trb {
 236        struct mv_u3d_trb_hw *trb_hw;   /* point to the trb_hw structure */
 237        dma_addr_t trb_dma;             /* dma address for this trb_hw */
 238        struct list_head trb_list;      /* trb list */
 239};
 240
 241/* device data structure */
 242struct mv_u3d {
 243        struct usb_gadget               gadget;
 244        struct usb_gadget_driver        *driver;
 245        spinlock_t                      lock;   /* device lock */
 246        struct completion               *done;
 247        struct device                   *dev;
 248        int                             irq;
 249
 250        /* usb controller registers */
 251        struct mv_u3d_cap_regs __iomem  *cap_regs;
 252        struct mv_u3d_op_regs __iomem   *op_regs;
 253        struct mv_u3d_vuc_regs __iomem  *vuc_regs;
 254        void __iomem                    *phy_regs;
 255
 256        unsigned int                    max_eps;
 257        struct mv_u3d_ep_context        *ep_context;
 258        size_t                          ep_context_size;
 259        dma_addr_t                      ep_context_dma;
 260
 261        struct dma_pool                 *trb_pool; /* for TRB data structure */
 262        struct mv_u3d_ep                *eps;
 263
 264        struct mv_u3d_req               *status_req; /* ep0 status request */
 265        struct usb_ctrlrequest          local_setup_buff; /* store setup data*/
 266
 267        unsigned int            resume_state;   /* USB state to resume */
 268        unsigned int            usb_state;      /* USB current state */
 269        unsigned int            ep0_state;      /* Endpoint zero state */
 270        unsigned int            ep0_dir;
 271
 272        unsigned int            dev_addr;       /* device address */
 273
 274        unsigned int            errors;
 275
 276        unsigned                softconnect:1;
 277        unsigned                vbus_active:1;  /* vbus is active or not */
 278        unsigned                remote_wakeup:1; /* support remote wakeup */
 279        unsigned                clock_gating:1; /* clock gating or not */
 280        unsigned                active:1;       /* udc is active or not */
 281        unsigned                vbus_valid_detect:1; /* udc vbus detection */
 282
 283        struct mv_usb_addon_irq *vbus;
 284        unsigned int            power;
 285
 286        struct clk              *clk;
 287};
 288
 289/* endpoint data structure */
 290struct mv_u3d_ep {
 291        struct usb_ep           ep;
 292        struct mv_u3d           *u3d;
 293        struct list_head        queue;  /* ep request queued hardware */
 294        struct list_head        req_list; /* list of ep request */
 295        struct mv_u3d_ep_context        *ep_context; /* ep context */
 296        u32                     direction;
 297        char                    name[14];
 298        u32                     processing; /* there is ep request
 299                                                queued on haredware */
 300        spinlock_t              req_lock; /* ep lock */
 301        unsigned                wedge:1;
 302        unsigned                enabled:1;
 303        unsigned                ep_type:2;
 304        unsigned                ep_num:8;
 305};
 306
 307/* request data structure */
 308struct mv_u3d_req {
 309        struct usb_request      req;
 310        struct mv_u3d_ep        *ep;
 311        struct list_head        queue;  /* ep requst queued on hardware */
 312        struct list_head        list;   /* ep request list */
 313        struct list_head        trb_list; /* trb list of a request */
 314
 315        struct mv_u3d_trb       *trb_head; /* point to first trb of a request */
 316        unsigned                trb_count; /* TRB number in the chain */
 317        unsigned                chain;     /* TRB chain or not */
 318};
 319
 320#endif
 321