net2280.h revision b6c63937001889af6fe431aaba97e59d04e028e7
1/* 2 * NetChip 2280 high/full speed USB device controller. 3 * Unlike many such controllers, this one talks PCI. 4 */ 5 6/* 7 * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com) 8 * Copyright (C) 2003 David Brownell 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 */ 24 25#include <linux/usb/net2280.h> 26 27/*-------------------------------------------------------------------------*/ 28 29#ifdef __KERNEL__ 30 31/* indexed registers [11.10] are accessed indirectly 32 * caller must own the device lock. 33 */ 34 35static inline u32 36get_idx_reg (struct net2280_regs __iomem *regs, u32 index) 37{ 38 writel (index, ®s->idxaddr); 39 /* NOTE: synchs device/cpu memory views */ 40 return readl (®s->idxdata); 41} 42 43static inline void 44set_idx_reg (struct net2280_regs __iomem *regs, u32 index, u32 value) 45{ 46 writel (index, ®s->idxaddr); 47 writel (value, ®s->idxdata); 48 /* posted, may not be visible yet */ 49} 50 51#endif /* __KERNEL__ */ 52 53 54#define REG_DIAG 0x0 55#define RETRY_COUNTER 16 56#define FORCE_PCI_SERR 11 57#define FORCE_PCI_INTERRUPT 10 58#define FORCE_USB_INTERRUPT 9 59#define FORCE_CPU_INTERRUPT 8 60#define ILLEGAL_BYTE_ENABLES 5 61#define FAST_TIMES 4 62#define FORCE_RECEIVE_ERROR 2 63#define FORCE_TRANSMIT_CRC_ERROR 0 64#define REG_FRAME 0x02 /* from last sof */ 65#define REG_CHIPREV 0x03 /* in bcd */ 66#define REG_HS_NAK_RATE 0x0a /* NAK per N uframes */ 67 68#define CHIPREV_1 0x0100 69#define CHIPREV_1A 0x0110 70 71#ifdef __KERNEL__ 72 73/* ep a-f highspeed and fullspeed maxpacket, addresses 74 * computed from ep->num 75 */ 76#define REG_EP_MAXPKT(dev,num) (((num) + 1) * 0x10 + \ 77 (((dev)->gadget.speed == USB_SPEED_HIGH) ? 0 : 1)) 78 79/*-------------------------------------------------------------------------*/ 80 81/* [8.3] for scatter/gather i/o 82 * use struct net2280_dma_regs bitfields 83 */ 84struct net2280_dma { 85 __le32 dmacount; 86 __le32 dmaaddr; /* the buffer */ 87 __le32 dmadesc; /* next dma descriptor */ 88 __le32 _reserved; 89} __attribute__ ((aligned (16))); 90 91/*-------------------------------------------------------------------------*/ 92 93/* DRIVER DATA STRUCTURES and UTILITIES */ 94 95struct net2280_ep { 96 struct usb_ep ep; 97 struct net2280_ep_regs __iomem *regs; 98 struct net2280_dma_regs __iomem *dma; 99 struct net2280_dma *dummy; 100 dma_addr_t td_dma; /* of dummy */ 101 struct net2280 *dev; 102 unsigned long irqs; 103 104 /* analogous to a host-side qh */ 105 struct list_head queue; 106 const struct usb_endpoint_descriptor *desc; 107 unsigned num : 8, 108 fifo_size : 12, 109 in_fifo_validate : 1, 110 out_overflow : 1, 111 stopped : 1, 112 is_in : 1, 113 is_iso : 1, 114 responded : 1; 115}; 116 117static inline void allow_status (struct net2280_ep *ep) 118{ 119 /* ep0 only */ 120 writel ( (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) 121 | (1 << CLEAR_NAK_OUT_PACKETS) 122 | (1 << CLEAR_NAK_OUT_PACKETS_MODE) 123 , &ep->regs->ep_rsp); 124 ep->stopped = 1; 125} 126 127/* count (<= 4) bytes in the next fifo write will be valid */ 128static inline void set_fifo_bytecount (struct net2280_ep *ep, unsigned count) 129{ 130 writeb (count, 2 + (u8 __iomem *) &ep->regs->ep_cfg); 131} 132 133struct net2280_request { 134 struct usb_request req; 135 struct net2280_dma *td; 136 dma_addr_t td_dma; 137 struct list_head queue; 138 unsigned mapped : 1, 139 valid : 1; 140}; 141 142struct net2280 { 143 /* each pci device provides one gadget, several endpoints */ 144 struct usb_gadget gadget; 145 spinlock_t lock; 146 struct net2280_ep ep [7]; 147 struct usb_gadget_driver *driver; 148 unsigned enabled : 1, 149 protocol_stall : 1, 150 softconnect : 1, 151 got_irq : 1, 152 region : 1; 153 u16 chiprev; 154 155 /* pci state used to access those endpoints */ 156 struct pci_dev *pdev; 157 struct net2280_regs __iomem *regs; 158 struct net2280_usb_regs __iomem *usb; 159 struct net2280_pci_regs __iomem *pci; 160 struct net2280_dma_regs __iomem *dma; 161 struct net2280_dep_regs __iomem *dep; 162 struct net2280_ep_regs __iomem *epregs; 163 164 struct pci_pool *requests; 165 // statistics... 166}; 167 168static inline void set_halt (struct net2280_ep *ep) 169{ 170 /* ep0 and bulk/intr endpoints */ 171 writel ( (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE) 172 /* set NAK_OUT for erratum 0114 */ 173 | ((ep->dev->chiprev == CHIPREV_1) << SET_NAK_OUT_PACKETS) 174 | (1 << SET_ENDPOINT_HALT) 175 , &ep->regs->ep_rsp); 176} 177 178static inline void clear_halt (struct net2280_ep *ep) 179{ 180 /* ep0 and bulk/intr endpoints */ 181 writel ( (1 << CLEAR_ENDPOINT_HALT) 182 | (1 << CLEAR_ENDPOINT_TOGGLE) 183 /* unless the gadget driver left a short packet in the 184 * fifo, this reverses the erratum 0114 workaround. 185 */ 186 | ((ep->dev->chiprev == CHIPREV_1) << CLEAR_NAK_OUT_PACKETS) 187 , &ep->regs->ep_rsp); 188} 189 190#ifdef USE_RDK_LEDS 191 192static inline void net2280_led_init (struct net2280 *dev) 193{ 194 /* LED3 (green) is on during USB activity. note erratum 0113. */ 195 writel ((1 << GPIO3_LED_SELECT) 196 | (1 << GPIO3_OUTPUT_ENABLE) 197 | (1 << GPIO2_OUTPUT_ENABLE) 198 | (1 << GPIO1_OUTPUT_ENABLE) 199 | (1 << GPIO0_OUTPUT_ENABLE) 200 , &dev->regs->gpioctl); 201} 202 203/* indicate speed with bi-color LED 0/1 */ 204static inline 205void net2280_led_speed (struct net2280 *dev, enum usb_device_speed speed) 206{ 207 u32 val = readl (&dev->regs->gpioctl); 208 switch (speed) { 209 case USB_SPEED_HIGH: /* green */ 210 val &= ~(1 << GPIO0_DATA); 211 val |= (1 << GPIO1_DATA); 212 break; 213 case USB_SPEED_FULL: /* red */ 214 val &= ~(1 << GPIO1_DATA); 215 val |= (1 << GPIO0_DATA); 216 break; 217 default: /* (off/black) */ 218 val &= ~((1 << GPIO1_DATA) | (1 << GPIO0_DATA)); 219 break; 220 } 221 writel (val, &dev->regs->gpioctl); 222} 223 224/* indicate power with LED 2 */ 225static inline void net2280_led_active (struct net2280 *dev, int is_active) 226{ 227 u32 val = readl (&dev->regs->gpioctl); 228 229 // FIXME this LED never seems to turn on. 230 if (is_active) 231 val |= GPIO2_DATA; 232 else 233 val &= ~GPIO2_DATA; 234 writel (val, &dev->regs->gpioctl); 235} 236static inline void net2280_led_shutdown (struct net2280 *dev) 237{ 238 /* turn off all four GPIO*_DATA bits */ 239 writel (readl (&dev->regs->gpioctl) & ~0x0f, 240 &dev->regs->gpioctl); 241} 242 243#else 244 245#define net2280_led_init(dev) do { } while (0) 246#define net2280_led_speed(dev, speed) do { } while (0) 247#define net2280_led_shutdown(dev) do { } while (0) 248 249#endif 250 251/*-------------------------------------------------------------------------*/ 252 253#define xprintk(dev,level,fmt,args...) \ 254 printk(level "%s %s: " fmt , driver_name , \ 255 pci_name(dev->pdev) , ## args) 256 257#ifdef DEBUG 258#undef DEBUG 259#define DEBUG(dev,fmt,args...) \ 260 xprintk(dev , KERN_DEBUG , fmt , ## args) 261#else 262#define DEBUG(dev,fmt,args...) \ 263 do { } while (0) 264#endif /* DEBUG */ 265 266#ifdef VERBOSE 267#define VDEBUG DEBUG 268#else 269#define VDEBUG(dev,fmt,args...) \ 270 do { } while (0) 271#endif /* VERBOSE */ 272 273#define ERROR(dev,fmt,args...) \ 274 xprintk(dev , KERN_ERR , fmt , ## args) 275#define WARNING(dev,fmt,args...) \ 276 xprintk(dev , KERN_WARNING , fmt , ## args) 277#define INFO(dev,fmt,args...) \ 278 xprintk(dev , KERN_INFO , fmt , ## args) 279 280/*-------------------------------------------------------------------------*/ 281 282static inline void start_out_naking (struct net2280_ep *ep) 283{ 284 /* NOTE: hardware races lurk here, and PING protocol issues */ 285 writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); 286 /* synch with device */ 287 readl (&ep->regs->ep_rsp); 288} 289 290#ifdef DEBUG 291static inline void assert_out_naking (struct net2280_ep *ep, const char *where) 292{ 293 u32 tmp = readl (&ep->regs->ep_stat); 294 295 if ((tmp & (1 << NAK_OUT_PACKETS)) == 0) { 296 DEBUG (ep->dev, "%s %s %08x !NAK\n", 297 ep->ep.name, where, tmp); 298 writel ((1 << SET_NAK_OUT_PACKETS), 299 &ep->regs->ep_rsp); 300 } 301} 302#define ASSERT_OUT_NAKING(ep) assert_out_naking(ep,__func__) 303#else 304#define ASSERT_OUT_NAKING(ep) do {} while (0) 305#endif 306 307static inline void stop_out_naking (struct net2280_ep *ep) 308{ 309 u32 tmp; 310 311 tmp = readl (&ep->regs->ep_stat); 312 if ((tmp & (1 << NAK_OUT_PACKETS)) != 0) 313 writel ((1 << CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp); 314} 315 316#endif /* __KERNEL__ */ 317