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 | |
| 28 | /****************************************************************************** |
| 29 | * STRUCTURES |
| 30 | *****************************************************************************/ |
| 31 | /* DMA layout of transfer descriptors */ |
| 32 | struct ci13xxx_td { |
| 33 | /* 0 */ |
| 34 | u32 next; |
| 35 | #define TD_TERMINATE BIT(0) |
Pavankumar Kondeti | 0e6ca19 | 2011-02-18 17:43:16 +0530 | [diff] [blame] | 36 | #define TD_ADDR_MASK (0xFFFFFFEUL << 5) |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 37 | /* 1 */ |
| 38 | u32 token; |
| 39 | #define TD_STATUS (0x00FFUL << 0) |
| 40 | #define TD_STATUS_TR_ERR BIT(3) |
| 41 | #define TD_STATUS_DT_ERR BIT(5) |
| 42 | #define TD_STATUS_HALTED BIT(6) |
| 43 | #define TD_STATUS_ACTIVE BIT(7) |
| 44 | #define TD_MULTO (0x0003UL << 10) |
| 45 | #define TD_IOC BIT(15) |
| 46 | #define TD_TOTAL_BYTES (0x7FFFUL << 16) |
| 47 | /* 2 */ |
| 48 | u32 page[5]; |
| 49 | #define TD_CURR_OFFSET (0x0FFFUL << 0) |
| 50 | #define TD_FRAME_NUM (0x07FFUL << 0) |
| 51 | #define TD_RESERVED_MASK (0x0FFFUL << 0) |
| 52 | } __attribute__ ((packed)); |
| 53 | |
| 54 | /* DMA layout of queue heads */ |
| 55 | struct ci13xxx_qh { |
| 56 | /* 0 */ |
| 57 | u32 cap; |
| 58 | #define QH_IOS BIT(15) |
| 59 | #define QH_MAX_PKT (0x07FFUL << 16) |
| 60 | #define QH_ZLT BIT(29) |
| 61 | #define QH_MULT (0x0003UL << 30) |
| 62 | /* 1 */ |
| 63 | u32 curr; |
| 64 | /* 2 - 8 */ |
| 65 | struct ci13xxx_td td; |
| 66 | /* 9 */ |
| 67 | u32 RESERVED; |
| 68 | struct usb_ctrlrequest setup; |
| 69 | } __attribute__ ((packed)); |
| 70 | |
| 71 | /* Extension of usb_request */ |
| 72 | struct ci13xxx_req { |
| 73 | struct usb_request req; |
| 74 | unsigned map; |
| 75 | struct list_head queue; |
| 76 | struct ci13xxx_td *ptr; |
| 77 | dma_addr_t dma; |
Pavankumar Kondeti | 0e6ca19 | 2011-02-18 17:43:16 +0530 | [diff] [blame] | 78 | struct ci13xxx_td *zptr; |
| 79 | dma_addr_t zdma; |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 80 | }; |
| 81 | |
| 82 | /* Extension of usb_ep */ |
| 83 | struct ci13xxx_ep { |
| 84 | struct usb_ep ep; |
| 85 | const struct usb_endpoint_descriptor *desc; |
| 86 | u8 dir; |
| 87 | u8 num; |
| 88 | u8 type; |
| 89 | char name[16]; |
| 90 | struct { |
| 91 | struct list_head queue; |
| 92 | struct ci13xxx_qh *ptr; |
| 93 | dma_addr_t dma; |
Pavankumar Kondeti | ca9cfea | 2011-01-11 09:19:22 +0530 | [diff] [blame] | 94 | } qh; |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 95 | int wedge; |
| 96 | |
| 97 | /* global resources */ |
| 98 | spinlock_t *lock; |
| 99 | struct device *device; |
| 100 | struct dma_pool *td_pool; |
| 101 | }; |
| 102 | |
Pavankumar Kondeti | f01ef57 | 2010-12-07 17:54:02 +0530 | [diff] [blame] | 103 | struct ci13xxx; |
| 104 | struct ci13xxx_udc_driver { |
| 105 | const char *name; |
| 106 | unsigned long flags; |
| 107 | #define CI13XXX_REGS_SHARED BIT(0) |
| 108 | #define CI13XXX_REQUIRE_TRANSCEIVER BIT(1) |
| 109 | #define CI13XXX_PULLUP_ON_VBUS BIT(2) |
| 110 | #define CI13XXX_DISABLE_STREAMING BIT(3) |
| 111 | |
| 112 | #define CI13XXX_CONTROLLER_RESET_EVENT 0 |
| 113 | #define CI13XXX_CONTROLLER_STOPPED_EVENT 1 |
| 114 | void (*notify_event) (struct ci13xxx *udc, unsigned event); |
| 115 | }; |
| 116 | |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 117 | /* CI13XXX UDC descriptor & global resources */ |
| 118 | struct ci13xxx { |
| 119 | spinlock_t *lock; /* ctrl register bank access */ |
Pavankumar Kondeti | f01ef57 | 2010-12-07 17:54:02 +0530 | [diff] [blame] | 120 | void __iomem *regs; /* registers address space */ |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 121 | |
| 122 | struct dma_pool *qh_pool; /* DMA pool for queue heads */ |
| 123 | struct dma_pool *td_pool; /* DMA pool for transfer descs */ |
Pavankumar Kondeti | ca9cfea | 2011-01-11 09:19:22 +0530 | [diff] [blame] | 124 | struct usb_request *status; /* ep0 status request */ |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 125 | |
| 126 | struct usb_gadget gadget; /* USB slave device */ |
| 127 | struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ |
Pavankumar Kondeti | ca9cfea | 2011-01-11 09:19:22 +0530 | [diff] [blame] | 128 | u32 ep0_dir; /* ep0 direction */ |
| 129 | #define ep0out ci13xxx_ep[0] |
| 130 | #define ep0in ci13xxx_ep[16] |
Pavankumar Kondeti | e2b61c1 | 2011-02-18 17:43:17 +0530 | [diff] [blame] | 131 | u8 remote_wakeup; /* Is remote wakeup feature |
| 132 | enabled by the host? */ |
| 133 | u8 suspended; /* suspended by the host */ |
Pavankumar Kondeti | 541cace | 2011-02-18 17:43:18 +0530 | [diff] [blame] | 134 | u8 test_mode; /* the selected test mode */ |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 135 | |
| 136 | struct usb_gadget_driver *driver; /* 3rd party gadget driver */ |
Pavankumar Kondeti | f01ef57 | 2010-12-07 17:54:02 +0530 | [diff] [blame] | 137 | struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ |
| 138 | int vbus_active; /* is VBUS active */ |
| 139 | struct otg_transceiver *transceiver; /* Transceiver struct */ |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 140 | }; |
| 141 | |
| 142 | /****************************************************************************** |
| 143 | * REGISTERS |
| 144 | *****************************************************************************/ |
| 145 | /* register size */ |
| 146 | #define REG_BITS (32) |
| 147 | |
| 148 | /* HCCPARAMS */ |
| 149 | #define HCCPARAMS_LEN BIT(17) |
| 150 | |
| 151 | /* DCCPARAMS */ |
| 152 | #define DCCPARAMS_DEN (0x1F << 0) |
| 153 | #define DCCPARAMS_DC BIT(7) |
| 154 | |
| 155 | /* TESTMODE */ |
| 156 | #define TESTMODE_FORCE BIT(0) |
| 157 | |
| 158 | /* USBCMD */ |
| 159 | #define USBCMD_RS BIT(0) |
| 160 | #define USBCMD_RST BIT(1) |
| 161 | #define USBCMD_SUTW BIT(13) |
Pavankumar Kondeti | 0e6ca19 | 2011-02-18 17:43:16 +0530 | [diff] [blame] | 162 | #define USBCMD_ATDTW BIT(14) |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 163 | |
| 164 | /* USBSTS & USBINTR */ |
| 165 | #define USBi_UI BIT(0) |
| 166 | #define USBi_UEI BIT(1) |
| 167 | #define USBi_PCI BIT(2) |
| 168 | #define USBi_URI BIT(6) |
| 169 | #define USBi_SLI BIT(8) |
| 170 | |
| 171 | /* DEVICEADDR */ |
| 172 | #define DEVICEADDR_USBADRA BIT(24) |
| 173 | #define DEVICEADDR_USBADR (0x7FUL << 25) |
| 174 | |
| 175 | /* PORTSC */ |
Pavankumar Kondeti | e2b61c1 | 2011-02-18 17:43:17 +0530 | [diff] [blame] | 176 | #define PORTSC_FPR BIT(6) |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 177 | #define PORTSC_SUSP BIT(7) |
| 178 | #define PORTSC_HSP BIT(9) |
| 179 | #define PORTSC_PTC (0x0FUL << 16) |
| 180 | |
| 181 | /* DEVLC */ |
| 182 | #define DEVLC_PSPD (0x03UL << 25) |
| 183 | #define DEVLC_PSPD_HS (0x02UL << 25) |
| 184 | |
| 185 | /* USBMODE */ |
| 186 | #define USBMODE_CM (0x03UL << 0) |
| 187 | #define USBMODE_CM_IDLE (0x00UL << 0) |
| 188 | #define USBMODE_CM_DEVICE (0x02UL << 0) |
| 189 | #define USBMODE_CM_HOST (0x03UL << 0) |
| 190 | #define USBMODE_SLOM BIT(3) |
Pavankumar Kondeti | f01ef57 | 2010-12-07 17:54:02 +0530 | [diff] [blame] | 191 | #define USBMODE_SDIS BIT(4) |
David Lopo | aa69a80 | 2008-11-17 14:14:51 -0800 | [diff] [blame] | 192 | |
| 193 | /* ENDPTCTRL */ |
| 194 | #define ENDPTCTRL_RXS BIT(0) |
| 195 | #define ENDPTCTRL_RXT (0x03UL << 2) |
| 196 | #define ENDPTCTRL_RXR BIT(6) /* reserved for port 0 */ |
| 197 | #define ENDPTCTRL_RXE BIT(7) |
| 198 | #define ENDPTCTRL_TXS BIT(16) |
| 199 | #define ENDPTCTRL_TXT (0x03UL << 18) |
| 200 | #define ENDPTCTRL_TXR BIT(22) /* reserved for port 0 */ |
| 201 | #define ENDPTCTRL_TXE BIT(23) |
| 202 | |
| 203 | /****************************************************************************** |
| 204 | * LOGGING |
| 205 | *****************************************************************************/ |
| 206 | #define ci13xxx_printk(level, format, args...) \ |
| 207 | do { \ |
| 208 | if (_udc == NULL) \ |
| 209 | printk(level "[%s] " format "\n", __func__, ## args); \ |
| 210 | else \ |
| 211 | dev_printk(level, _udc->gadget.dev.parent, \ |
| 212 | "[%s] " format "\n", __func__, ## args); \ |
| 213 | } while (0) |
| 214 | |
| 215 | #define err(format, args...) ci13xxx_printk(KERN_ERR, format, ## args) |
| 216 | #define warn(format, args...) ci13xxx_printk(KERN_WARNING, format, ## args) |
| 217 | #define info(format, args...) ci13xxx_printk(KERN_INFO, format, ## args) |
| 218 | |
| 219 | #ifdef TRACE |
| 220 | #define trace(format, args...) ci13xxx_printk(KERN_DEBUG, format, ## args) |
| 221 | #define dbg_trace(format, args...) dev_dbg(dev, format, ##args) |
| 222 | #else |
| 223 | #define trace(format, args...) do {} while (0) |
| 224 | #define dbg_trace(format, args...) do {} while (0) |
| 225 | #endif |
| 226 | |
| 227 | #endif /* _CI13XXX_h_ */ |