David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 1 | /* |
| 2 | * ci13xxx_udc.h - structures, registers, and macros MIPS USB IP core |
| 3 | * |
| 4 | * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved. |
| 5 | * |
| 6 | * Author: David Lopo |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License version 2 as |
| 10 | * published by the Free Software Foundation. |
| 11 | * |
| 12 | * Description: MIPS USB IP core family device controller |
| 13 | * Structures, registers and logging macros |
| 14 | */ |
| 15 | |
| 16 | #ifndef _CI13XXX_h_ |
| 17 | #define _CI13XXX_h_ |
| 18 | |
| 19 | /****************************************************************************** |
| 20 | * DEFINE |
| 21 | *****************************************************************************/ |
Artem Leonenko | 0a313c4 | 2010-12-14 23:47:06 -0800 | [diff] [blame] | 22 | #define CI13XXX_PAGE_SIZE 4096ul /* page size for TD's */ |
Pavankumar Kondeti | ca9cfea | 2011-01-11 09:19:22 +0530 | [diff] [blame] | 23 | #define ENDPT_MAX (32) |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 24 | #define CTRL_PAYLOAD_MAX (64) |
| 25 | #define RX (0) /* similar to USB_DIR_OUT but can be used as an index */ |
| 26 | #define TX (1) /* similar to USB_DIR_IN but can be used as an index */ |
| 27 | |
Ofir Cohen | a1c2a87 | 2011-12-14 10:26:34 +0200 | [diff] [blame] | 28 | /* UDC private data: |
| 29 | * 16MSb - Vendor ID | 16 LSb Vendor private data |
| 30 | */ |
| 31 | #define CI13XX_REQ_VENDOR_ID(id) (id & 0xFFFF0000UL) |
| 32 | |
Ido Shayevitz | d1cb16c | 2012-03-28 18:57:47 +0200 | [diff] [blame] | 33 | #define MSM_ETD_TYPE BIT(1) |
| 34 | #define MSM_EP_PIPE_ID_RESET_VAL 0x1F001F |
Ofir Cohen | a1c2a87 | 2011-12-14 10:26:34 +0200 | [diff] [blame] | 35 | |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 36 | /****************************************************************************** |
| 37 | * STRUCTURES |
| 38 | *****************************************************************************/ |
| 39 | /* DMA layout of transfer descriptors */ |
| 40 | struct ci13xxx_td { |
| 41 | /* 0 */ |
| 42 | u32 next; |
| 43 | #define TD_TERMINATE BIT(0) |
Pavankumar Kondeti | 0e6ca19 | 2011-02-18 17:43:16 +0530 | [diff] [blame] | 44 | #define TD_ADDR_MASK (0xFFFFFFEUL << 5) |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 45 | /* 1 */ |
| 46 | u32 token; |
| 47 | #define TD_STATUS (0x00FFUL << 0) |
| 48 | #define TD_STATUS_TR_ERR BIT(3) |
| 49 | #define TD_STATUS_DT_ERR BIT(5) |
| 50 | #define TD_STATUS_HALTED BIT(6) |
| 51 | #define TD_STATUS_ACTIVE BIT(7) |
| 52 | #define TD_MULTO (0x0003UL << 10) |
| 53 | #define TD_IOC BIT(15) |
| 54 | #define TD_TOTAL_BYTES (0x7FFFUL << 16) |
| 55 | /* 2 */ |
| 56 | u32 page[5]; |
| 57 | #define TD_CURR_OFFSET (0x0FFFUL << 0) |
| 58 | #define TD_FRAME_NUM (0x07FFUL << 0) |
| 59 | #define TD_RESERVED_MASK (0x0FFFUL << 0) |
Michael Grzeschik | 6e02248 | 2013-04-04 13:13:46 +0300 | [diff] [blame] | 60 | } __attribute__ ((packed, aligned(4))); |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 61 | |
| 62 | /* DMA layout of queue heads */ |
| 63 | struct ci13xxx_qh { |
| 64 | /* 0 */ |
| 65 | u32 cap; |
| 66 | #define QH_IOS BIT(15) |
| 67 | #define QH_MAX_PKT (0x07FFUL << 16) |
| 68 | #define QH_ZLT BIT(29) |
| 69 | #define QH_MULT (0x0003UL << 30) |
Vijayavardhan Vennapusa | 153be58 | 2012-10-05 15:36:59 +0530 | [diff] [blame] | 70 | #define QH_MULT_SHIFT 11 |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 71 | /* 1 */ |
| 72 | u32 curr; |
| 73 | /* 2 - 8 */ |
| 74 | struct ci13xxx_td td; |
| 75 | /* 9 */ |
| 76 | u32 RESERVED; |
| 77 | struct usb_ctrlrequest setup; |
Michael Grzeschik | 6e02248 | 2013-04-04 13:13:46 +0300 | [diff] [blame] | 78 | } __attribute__ ((packed, aligned(4))); |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 79 | |
Pavankumar Kondeti | cbd44db | 2013-02-06 20:52:46 +0530 | [diff] [blame] | 80 | /* cache of larger request's original attributes */ |
| 81 | struct ci13xxx_multi_req { |
| 82 | unsigned len; |
| 83 | unsigned actual; |
| 84 | void *buf; |
| 85 | }; |
| 86 | |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 87 | /* Extension of usb_request */ |
| 88 | struct ci13xxx_req { |
| 89 | struct usb_request req; |
| 90 | unsigned map; |
| 91 | struct list_head queue; |
Pavankumar Kondeti | e0bf826 | 2013-02-07 20:48:34 +0530 | [diff] [blame] | 92 | struct ci13xxx_td *ptr; |
| 93 | dma_addr_t dma; |
| 94 | struct ci13xxx_td *zptr; |
| 95 | dma_addr_t zdma; |
Pavankumar Kondeti | cbd44db | 2013-02-06 20:52:46 +0530 | [diff] [blame] | 96 | struct ci13xxx_multi_req multi; |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 97 | }; |
| 98 | |
| 99 | /* Extension of usb_ep */ |
| 100 | struct ci13xxx_ep { |
| 101 | struct usb_ep ep; |
| 102 | const struct usb_endpoint_descriptor *desc; |
| 103 | u8 dir; |
| 104 | u8 num; |
| 105 | u8 type; |
| 106 | char name[16]; |
| 107 | struct { |
| 108 | struct list_head queue; |
| 109 | struct ci13xxx_qh *ptr; |
| 110 | dma_addr_t dma; |
Pavankumar Kondeti | ca9cfea | 2011-01-11 09:19:22 +0530 | [diff] [blame] | 111 | } qh; |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 112 | int wedge; |
| 113 | |
| 114 | /* global resources */ |
| 115 | spinlock_t *lock; |
| 116 | struct device *device; |
| 117 | struct dma_pool *td_pool; |
Pavankumar Kondeti | 011217a | 2013-04-09 15:13:28 +0530 | [diff] [blame] | 118 | struct ci13xxx_td *last_zptr; |
| 119 | dma_addr_t last_zdma; |
Anji jonnala | 6fb918c | 2011-10-21 17:54:21 +0530 | [diff] [blame] | 120 | unsigned long dTD_update_fail_count; |
Vijayavardhan Vennapusa | 9e4a505 | 2012-10-03 13:14:06 +0530 | [diff] [blame] | 121 | unsigned long prime_fail_count; |
| 122 | int prime_timer_count; |
| 123 | struct timer_list prime_timer; |
Pavankumar Kondeti | cbd44db | 2013-02-06 20:52:46 +0530 | [diff] [blame] | 124 | |
| 125 | bool multi_req; |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 126 | }; |
| 127 | |
Pavankumar Kondeti | f01ef57 | 2010-12-07 17:54:02 +0530 | [diff] [blame] | 128 | struct ci13xxx; |
| 129 | struct ci13xxx_udc_driver { |
| 130 | const char *name; |
| 131 | unsigned long flags; |
Amit Blay | 1037ba7 | 2013-06-11 19:50:59 +0300 | [diff] [blame] | 132 | unsigned int nz_itc; |
Pavankumar Kondeti | f01ef57 | 2010-12-07 17:54:02 +0530 | [diff] [blame] | 133 | #define CI13XXX_REGS_SHARED BIT(0) |
| 134 | #define CI13XXX_REQUIRE_TRANSCEIVER BIT(1) |
| 135 | #define CI13XXX_PULLUP_ON_VBUS BIT(2) |
| 136 | #define CI13XXX_DISABLE_STREAMING BIT(3) |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 137 | #define CI13XXX_ZERO_ITC BIT(4) |
Vijayavardhan Vennapusa | d450cb0 | 2012-02-25 14:35:26 +0530 | [diff] [blame] | 138 | #define CI13XXX_IS_OTG BIT(5) |
Pavankumar Kondeti | f01ef57 | 2010-12-07 17:54:02 +0530 | [diff] [blame] | 139 | |
Amit Blay | 725cdeb | 2012-04-30 14:20:56 +0300 | [diff] [blame] | 140 | #define CI13XXX_CONTROLLER_RESET_EVENT 0 |
| 141 | #define CI13XXX_CONTROLLER_CONNECT_EVENT 1 |
| 142 | #define CI13XXX_CONTROLLER_SUSPEND_EVENT 2 |
Stephen Boyd | 4251740 | 2013-01-14 16:41:42 -0800 | [diff] [blame] | 143 | #define CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT 3 |
| 144 | #define CI13XXX_CONTROLLER_RESUME_EVENT 4 |
| 145 | #define CI13XXX_CONTROLLER_DISCONNECT_EVENT 5 |
| 146 | #define CI13XXX_CONTROLLER_UDC_STARTED_EVENT 6 |
Ido Shayevitz | ab60163 | 2012-09-16 15:11:26 +0300 | [diff] [blame] | 147 | |
Pavankumar Kondeti | f01ef57 | 2010-12-07 17:54:02 +0530 | [diff] [blame] | 148 | void (*notify_event) (struct ci13xxx *udc, unsigned event); |
| 149 | }; |
| 150 | |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 151 | /* CI13XXX UDC descriptor & global resources */ |
| 152 | struct ci13xxx { |
| 153 | spinlock_t *lock; /* ctrl register bank access */ |
Pavankumar Kondeti | f01ef57 | 2010-12-07 17:54:02 +0530 | [diff] [blame] | 154 | void __iomem *regs; /* registers address space */ |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 155 | |
| 156 | struct dma_pool *qh_pool; /* DMA pool for queue heads */ |
| 157 | struct dma_pool *td_pool; /* DMA pool for transfer descs */ |
Pavankumar Kondeti | ca9cfea | 2011-01-11 09:19:22 +0530 | [diff] [blame] | 158 | struct usb_request *status; /* ep0 status request */ |
Pavankumar Kondeti | 011217a | 2013-04-09 15:13:28 +0530 | [diff] [blame] | 159 | void *status_buf;/* GET_STATUS buffer */ |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 160 | |
| 161 | struct usb_gadget gadget; /* USB slave device */ |
| 162 | struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ |
Pavankumar Kondeti | ca9cfea | 2011-01-11 09:19:22 +0530 | [diff] [blame] | 163 | u32 ep0_dir; /* ep0 direction */ |
| 164 | #define ep0out ci13xxx_ep[0] |
Marc Kleine-Budde | dd39c35 | 2011-10-10 18:38:10 +0200 | [diff] [blame] | 165 | #define ep0in ci13xxx_ep[hw_ep_max / 2] |
Pavankumar Kondeti | e2b61c1 | 2011-02-18 17:43:17 +0530 | [diff] [blame] | 166 | u8 remote_wakeup; /* Is remote wakeup feature |
| 167 | enabled by the host? */ |
| 168 | u8 suspended; /* suspended by the host */ |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 169 | u8 configured; /* is device configured */ |
Pavankumar Kondeti | 541cace | 2011-02-18 17:43:18 +0530 | [diff] [blame] | 170 | u8 test_mode; /* the selected test mode */ |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 171 | |
Amit Blay | fd075dd | 2012-06-26 13:12:50 +0300 | [diff] [blame] | 172 | struct delayed_work rw_work; /* remote wakeup delayed work */ |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 173 | struct usb_gadget_driver *driver; /* 3rd party gadget driver */ |
Pavankumar Kondeti | f01ef57 | 2010-12-07 17:54:02 +0530 | [diff] [blame] | 174 | struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ |
| 175 | int vbus_active; /* is VBUS active */ |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 176 | int softconnect; /* is pull-up enable allowed */ |
Anji jonnala | 6fb918c | 2011-10-21 17:54:21 +0530 | [diff] [blame] | 177 | unsigned long dTD_update_fail_count; |
Heikki Krogerus | 8675381 | 2012-02-13 13:24:02 +0200 | [diff] [blame] | 178 | struct usb_phy *transceiver; /* Transceiver struct */ |
Pavankumar Kondeti | 2a630fb | 2013-01-28 12:31:15 +0530 | [diff] [blame] | 179 | bool skip_flush; /* skip flushing remaining EP |
| 180 | upon flush timeout for the |
| 181 | first EP. */ |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 182 | }; |
| 183 | |
| 184 | /****************************************************************************** |
| 185 | * REGISTERS |
| 186 | *****************************************************************************/ |
| 187 | /* register size */ |
| 188 | #define REG_BITS (32) |
| 189 | |
| 190 | /* HCCPARAMS */ |
| 191 | #define HCCPARAMS_LEN BIT(17) |
| 192 | |
| 193 | /* DCCPARAMS */ |
| 194 | #define DCCPARAMS_DEN (0x1F << 0) |
| 195 | #define DCCPARAMS_DC BIT(7) |
| 196 | |
| 197 | /* TESTMODE */ |
| 198 | #define TESTMODE_FORCE BIT(0) |
| 199 | |
| 200 | /* USBCMD */ |
| 201 | #define USBCMD_RS BIT(0) |
| 202 | #define USBCMD_RST BIT(1) |
| 203 | #define USBCMD_SUTW BIT(13) |
Pavankumar Kondeti | 0e6ca19 | 2011-02-18 17:43:16 +0530 | [diff] [blame] | 204 | #define USBCMD_ATDTW BIT(14) |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 205 | |
| 206 | /* USBSTS & USBINTR */ |
| 207 | #define USBi_UI BIT(0) |
| 208 | #define USBi_UEI BIT(1) |
| 209 | #define USBi_PCI BIT(2) |
| 210 | #define USBi_URI BIT(6) |
| 211 | #define USBi_SLI BIT(8) |
| 212 | |
| 213 | /* DEVICEADDR */ |
| 214 | #define DEVICEADDR_USBADRA BIT(24) |
| 215 | #define DEVICEADDR_USBADR (0x7FUL << 25) |
| 216 | |
| 217 | /* PORTSC */ |
Pavankumar Kondeti | e2b61c1 | 2011-02-18 17:43:17 +0530 | [diff] [blame] | 218 | #define PORTSC_FPR BIT(6) |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 219 | #define PORTSC_SUSP BIT(7) |
| 220 | #define PORTSC_HSP BIT(9) |
| 221 | #define PORTSC_PTC (0x0FUL << 16) |
| 222 | |
| 223 | /* DEVLC */ |
| 224 | #define DEVLC_PSPD (0x03UL << 25) |
| 225 | #define DEVLC_PSPD_HS (0x02UL << 25) |
| 226 | |
| 227 | /* USBMODE */ |
| 228 | #define USBMODE_CM (0x03UL << 0) |
| 229 | #define USBMODE_CM_IDLE (0x00UL << 0) |
| 230 | #define USBMODE_CM_DEVICE (0x02UL << 0) |
| 231 | #define USBMODE_CM_HOST (0x03UL << 0) |
| 232 | #define USBMODE_SLOM BIT(3) |
Pavankumar Kondeti | f01ef57 | 2010-12-07 17:54:02 +0530 | [diff] [blame] | 233 | #define USBMODE_SDIS BIT(4) |
Bryan Huntsman | 3f2bc4d | 2011-08-16 17:27:22 -0700 | [diff] [blame] | 234 | #define USBCMD_ITC(n) (n << 16) /* n = 0, 1, 2, 4, 8, 16, 32, 64 */ |
| 235 | #define USBCMD_ITC_MASK (0xFF << 16) |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 236 | |
| 237 | /* ENDPTCTRL */ |
| 238 | #define ENDPTCTRL_RXS BIT(0) |
| 239 | #define ENDPTCTRL_RXT (0x03UL << 2) |
| 240 | #define ENDPTCTRL_RXR BIT(6) /* reserved for port 0 */ |
| 241 | #define ENDPTCTRL_RXE BIT(7) |
| 242 | #define ENDPTCTRL_TXS BIT(16) |
| 243 | #define ENDPTCTRL_TXT (0x03UL << 18) |
| 244 | #define ENDPTCTRL_TXR BIT(22) /* reserved for port 0 */ |
| 245 | #define ENDPTCTRL_TXE BIT(23) |
| 246 | |
| 247 | /****************************************************************************** |
| 248 | * LOGGING |
| 249 | *****************************************************************************/ |
| 250 | #define ci13xxx_printk(level, format, args...) \ |
| 251 | do { \ |
| 252 | if (_udc == NULL) \ |
| 253 | printk(level "[%s] " format "\n", __func__, ## args); \ |
| 254 | else \ |
| 255 | dev_printk(level, _udc->gadget.dev.parent, \ |
| 256 | "[%s] " format "\n", __func__, ## args); \ |
| 257 | } while (0) |
| 258 | |
Ofir Cohen | 06789f1 | 2012-01-16 09:43:13 +0200 | [diff] [blame] | 259 | #ifndef err |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 260 | #define err(format, args...) ci13xxx_printk(KERN_ERR, format, ## args) |
Ofir Cohen | 06789f1 | 2012-01-16 09:43:13 +0200 | [diff] [blame] | 261 | #endif |
| 262 | |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 263 | #define warn(format, args...) ci13xxx_printk(KERN_WARNING, format, ## args) |
| 264 | #define info(format, args...) ci13xxx_printk(KERN_INFO, format, ## args) |
| 265 | |
| 266 | #ifdef TRACE |
| 267 | #define trace(format, args...) ci13xxx_printk(KERN_DEBUG, format, ## args) |
| 268 | #define dbg_trace(format, args...) dev_dbg(dev, format, ##args) |
| 269 | #else |
| 270 | #define trace(format, args...) do {} while (0) |
| 271 | #define dbg_trace(format, args...) do {} while (0) |
| 272 | #endif |
| 273 | |
| 274 | #endif /* _CI13XXX_h_ */ |