1 /* 2 * Implementation of whatever is hardware specific in AM335x MCU 3 */ 4 5 #include <string.h> /* memset */ 6 7 #include <usbd/hcd_common.h> 8 #include <usbd/hcd_platforms.h> 9 #include <usbd/hcd_interface.h> 10 #include <usbd/usbd_common.h> 11 12 #include "musb_core.h" 13 14 /* TODO: BeagleBone white uses USB0 for PC connection as peripheral, 15 * so this is disabled by default */ 16 /* Should USB0 ever be used on BBB/BBW, one can change it to '#define': */ 17 #undef AM335X_USE_USB0 18 19 20 /*===========================================================================* 21 * AM335x base register defines * 22 *===========================================================================*/ 23 /* Memory placement defines */ 24 #define AM335X_USBSS_BASE_ADDR 0x47400000u 25 #define AM335X_USB0_BASE_OFFSET 0x1000u 26 #define AM335X_MUSB_CORE0_BASE_OFFSET 0x1400u 27 #define AM335X_USB1_BASE_OFFSET 0x1800u 28 #define AM335X_MUSB_CORE1_BASE_OFFSET 0x1C00u 29 #define AM335X_USBSS_TOTAL_REG_LEN 0x5000u 30 31 32 /*===========================================================================* 33 * AM335x USB specific register defines * 34 *===========================================================================*/ 35 /* SS registers base address */ 36 37 #define AM335X_REG_REVREG 0x000u 38 #define AM335X_REG_SYSCONFIG 0x010u 39 #define AM335X_REG_IRQSTATRAW 0x024u 40 #define AM335X_REG_IRQSTAT 0x028u 41 #define AM335X_REG_IRQENABLER 0x02Cu 42 #define AM335X_REG_IRQCLEARR 0x030u 43 #define AM335X_REG_IRQDMATHOLDTX00 0x100u 44 #define AM335X_REG_IRQDMATHOLDTX01 0x104u 45 #define AM335X_REG_IRQDMATHOLDTX02 0x108u 46 #define AM335X_REG_IRQDMATHOLDTX03 0x10Cu 47 #define AM335X_REG_IRQDMATHOLDRX00 0x110u 48 #define AM335X_REG_IRQDMATHOLDRX01 0x114u 49 #define AM335X_REG_IRQDMATHOLDRX02 0x118u 50 #define AM335X_REG_IRQDMATHOLDRX03 0x11Cu 51 #define AM335X_REG_IRQDMATHOLDTX10 0x120u 52 #define AM335X_REG_IRQDMATHOLDTX11 0x124u 53 #define AM335X_REG_IRQDMATHOLDTX12 0x128u 54 #define AM335X_REG_IRQDMATHOLDTX13 0x12Cu 55 #define AM335X_REG_IRQDMATHOLDRX10 0x130u 56 #define AM335X_REG_IRQDMATHOLDRX11 0x134u 57 #define AM335X_REG_IRQDMATHOLDRX12 0x138u 58 #define AM335X_REG_IRQDMATHOLDRX13 0x13Cu 59 #define AM335X_REG_IRQDMAENABLE0 0x140u 60 #define AM335X_REG_IRQDMAENABLE1 0x144u 61 #define AM335X_REG_IRQFRAMETHOLDTX00 0x200u 62 #define AM335X_REG_IRQFRAMETHOLDTX01 0x204u 63 #define AM335X_REG_IRQFRAMETHOLDTX02 0x208u 64 #define AM335X_REG_IRQFRAMETHOLDTX03 0x20Cu 65 #define AM335X_REG_IRQFRAMETHOLDRX00 0x210u 66 #define AM335X_REG_IRQFRAMETHOLDRX01 0x214u 67 #define AM335X_REG_IRQFRAMETHOLDRX02 0x218u 68 #define AM335X_REG_IRQFRAMETHOLDRX03 0x21Cu 69 #define AM335X_REG_IRQFRAMETHOLDTX10 0x220u 70 #define AM335X_REG_IRQFRAMETHOLDTX11 0x224u 71 #define AM335X_REG_IRQFRAMETHOLDTX12 0x228u 72 #define AM335X_REG_IRQFRAMETHOLDTX13 0x22Cu 73 #define AM335X_REG_IRQFRAMETHOLDRX10 0x230u 74 #define AM335X_REG_IRQFRAMETHOLDRX11 0x234u 75 #define AM335X_REG_IRQFRAMETHOLDRX12 0x238u 76 #define AM335X_REG_IRQFRAMETHOLDRX13 0x23Cu 77 #define AM335X_REG_IRQFRAMEENABLE0 0x240u 78 #define AM335X_REG_IRQFRAMEENABLE1 0x244u 79 80 #define AM335X_REG_USBXREV 0x00u 81 #define AM335X_REG_USBXCTRL 0x14u 82 #define AM335X_REG_USBXSTAT 0x18u 83 #define AM335X_REG_USBXIRQMSTAT 0x20u 84 #define AM335X_REG_USBXIRQSTATRAW0 0x28u 85 #define AM335X_REG_USBXIRQSTATRAW1 0x2Cu 86 #define AM335X_REG_USBXIRQSTAT0 0x30u 87 #define AM335X_REG_USBXIRQSTAT1 0x34u 88 #define AM335X_REG_USBXIRQENABLESET0 0x38u 89 #define AM335X_REG_USBXIRQENABLESET1 0x3Cu 90 #define AM335X_REG_USBXIRQENABLECLR0 0x40u 91 #define AM335X_REG_USBXIRQENABLECLR1 0x44u 92 #define AM335X_REG_USBXTXMODE 0x70u 93 #define AM335X_REG_USBXRXMODE 0x74u 94 #define AM335X_REG_USBXGENRNDISEP1 0x80u 95 #define AM335X_REG_USBXGENRNDISEP2 0x84u 96 #define AM335X_REG_USBXGENRNDISEP3 0x88u 97 #define AM335X_REG_USBXGENRNDISEP4 0x8Cu 98 #define AM335X_REG_USBXGENRNDISEP5 0x90u 99 #define AM335X_REG_USBXGENRNDISEP6 0x94u 100 #define AM335X_REG_USBXGENRNDISEP7 0x98u 101 #define AM335X_REG_USBXGENRNDISEP8 0x9Cu 102 #define AM335X_REG_USBXGENRNDISEP9 0xA0u 103 #define AM335X_REG_USBXGENRNDISEP10 0xA4u 104 #define AM335X_REG_USBXGENRNDISEP11 0xA8u 105 #define AM335X_REG_USBXGENRNDISEP12 0xACu 106 #define AM335X_REG_USBXGENRNDISEP13 0xB0u 107 #define AM335X_REG_USBXGENRNDISEP14 0xB4u 108 #define AM335X_REG_USBXGENRNDISEP15 0xB8u 109 #define AM335X_REG_USBXAUTOREQ 0xD0u 110 #define AM335X_REG_USBXSRPFIXTIME 0xD4u 111 #define AM335X_REG_USBX_TDOWN 0xD8u 112 #define AM335X_REG_USBXUTMI 0xE0u 113 #define AM335X_REG_USBXMGCUTMILB 0xE4u 114 #define AM335X_REG_USBXMODE 0xE8u 115 116 /* Values to be set */ 117 #define AM335X_VAL_USBXCTRL_SOFT_RESET HCD_BIT(0) 118 #define AM335X_VAL_USBXCTRL_UINT HCD_BIT(3) 119 120 #define AM335X_VAL_USBXMODE_IDDIG_MUX HCD_BIT(7) 121 #define AM335X_VAL_USBXMODE_IDDIG HCD_BIT(8) 122 123 #define AM335X_VAL_USBXIRQENABLEXXX0_EP0 HCD_BIT(0) 124 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP1 HCD_BIT(1) 125 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP2 HCD_BIT(2) 126 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP3 HCD_BIT(3) 127 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP4 HCD_BIT(4) 128 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP5 HCD_BIT(5) 129 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP6 HCD_BIT(6) 130 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP7 HCD_BIT(7) 131 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP8 HCD_BIT(8) 132 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP9 HCD_BIT(9) 133 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP10 HCD_BIT(10) 134 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP11 HCD_BIT(11) 135 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP12 HCD_BIT(12) 136 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP13 HCD_BIT(13) 137 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP14 HCD_BIT(14) 138 #define AM335X_VAL_USBXIRQENABLEXXX0_TX_EP15 HCD_BIT(15) 139 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP1 HCD_BIT(17) 140 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP2 HCD_BIT(18) 141 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP3 HCD_BIT(19) 142 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP4 HCD_BIT(20) 143 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP5 HCD_BIT(21) 144 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP6 HCD_BIT(22) 145 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP7 HCD_BIT(23) 146 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP8 HCD_BIT(24) 147 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP9 HCD_BIT(25) 148 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP10 HCD_BIT(26) 149 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP11 HCD_BIT(27) 150 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP12 HCD_BIT(28) 151 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP13 HCD_BIT(29) 152 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP14 HCD_BIT(30) 153 #define AM335X_VAL_USBXIRQENABLEXXX0_RX_EP15 HCD_BIT(31) 154 155 #define AM335X_VAL_USBXIRQENABLEXXX1_SUSPEND HCD_BIT(0) 156 #define AM335X_VAL_USBXIRQENABLEXXX1_RESUME HCD_BIT(1) 157 #define AM335X_VAL_USBXIRQENABLEXXX1_RESET_BABBLE HCD_BIT(2) 158 #define AM335X_VAL_USBXIRQENABLEXXX1_SOF HCD_BIT(3) 159 #define AM335X_VAL_USBXIRQENABLEXXX1_CONNECTED HCD_BIT(4) 160 #define AM335X_VAL_USBXIRQENABLEXXX1_DISCONNECTED HCD_BIT(5) 161 #define AM335X_VAL_USBXIRQENABLEXXX1_SRP HCD_BIT(6) 162 #define AM335X_VAL_USBXIRQENABLEXXX1_VBUS HCD_BIT(7) 163 #define AM335X_VAL_USBXIRQENABLEXXX1_DRVVBUS HCD_BIT(8) 164 #define AM335X_VAL_USBXIRQENABLEXXX1_GENERIC HCD_BIT(9) 165 166 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_1 HCD_BIT(17) 167 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_2 HCD_BIT(18) 168 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_3 HCD_BIT(19) 169 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_4 HCD_BIT(20) 170 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_5 HCD_BIT(21) 171 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_6 HCD_BIT(22) 172 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_7 HCD_BIT(23) 173 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_8 HCD_BIT(24) 174 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_9 HCD_BIT(25) 175 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_10 HCD_BIT(26) 176 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_11 HCD_BIT(27) 177 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_12 HCD_BIT(28) 178 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_13 HCD_BIT(29) 179 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_14 HCD_BIT(30) 180 #define AM335X_VAL_USBXIRQENABLEXXX1_TX_FIFO_15 HCD_BIT(31) 181 182 #define AM335X_VAL_USBXIRQSTAT1_SUSPEND HCD_BIT(0) 183 #define AM335X_VAL_USBXIRQSTAT1_RESUME HCD_BIT(1) 184 #define AM335X_VAL_USBXIRQSTAT1_RESET_BABBLE HCD_BIT(2) 185 #define AM335X_VAL_USBXIRQSTAT1_SOF HCD_BIT(3) 186 #define AM335X_VAL_USBXIRQSTAT1_CONNECTED HCD_BIT(4) 187 #define AM335X_VAL_USBXIRQSTAT1_DISCONNECTED HCD_BIT(5) 188 #define AM335X_VAL_USBXIRQSTAT1_SRP HCD_BIT(6) 189 #define AM335X_VAL_USBXIRQSTAT1_VBUS HCD_BIT(7) 190 #define AM335X_VAL_USBXIRQSTAT1_DRVVBUS HCD_BIT(8) 191 #define AM335X_VAL_USBXIRQSTAT1_GENERIC HCD_BIT(9) 192 193 /* Helpers for interrupt clearing */ 194 #define CLEAR_IRQ0(irq0_bit) HCD_WR4(r, AM335X_REG_USBXIRQSTAT0, (irq0_bit)) 195 #define CLEAR_IRQ1(irq1_bit) HCD_WR4(r, AM335X_REG_USBXIRQSTAT1, (irq1_bit)) 196 197 198 /*===========================================================================* 199 * AM335x clocking register defines * 200 *===========================================================================*/ 201 /* Clock module registers offsets */ 202 #define AM335X_REG_CM_PER_USB0_CLKCTRL_OFFSET 0x1Cu 203 204 /* Possible values to be set */ 205 #define AM335X_VAL_CM_PER_USB0_CLKCTRL_MODULEMODE_ENABLE 0x2u 206 #define AM335X_CLKCONF_FULL_VAL 0xFFFFFFFFu 207 208 209 /*===========================================================================* 210 * AM335x USB configuration structures * 211 *===========================================================================*/ 212 #define AM335X_USBSS_IRQ 17 213 #define AM335X_USB0_IRQ 18 214 #define AM335X_USB1_IRQ 19 215 216 /* Hardware configuration values specific to AM335X USBSS (USB Subsystem) */ 217 typedef struct am335x_ss_config { 218 219 void * regs; /* Points to beginning of memory mapped register space */ 220 } 221 am335x_ss_config; 222 223 /* Hardware configuration values specific to AM335X USB(0,1) OTG */ 224 typedef struct am335x_usbX_config { 225 226 void * regs; /* Points to beginning of memory mapped register space */ 227 } 228 am335x_usbX_config; 229 230 /* Private data for AM335X's IRQ thread */ 231 typedef struct am335x_irq_private { 232 233 int usb_num; /* Number of currently handled controller (0, 1) */ 234 } 235 am335x_irq_private; 236 237 /* Single MUSB peripheral information */ 238 typedef struct am335x_controller { 239 240 am335x_irq_private priv; 241 am335x_usbX_config usb; 242 musb_core_config core; 243 hcd_driver_state driver; 244 } 245 am335x_controller; 246 247 #define AM335X_NUM_USB_CONTROLLERS 2 248 #define AM335X_USB0 0 249 #define AM335X_USB1 1 250 251 /* Configuration values specific to AM335X... */ 252 typedef struct am335x_config { 253 254 am335x_ss_config ss; 255 am335x_controller ctrl[AM335X_NUM_USB_CONTROLLERS]; 256 } 257 am335x_config; 258 259 /* ...and their current holder */ 260 static am335x_config am335x; 261 262 263 /*===========================================================================* 264 * Local declarations * 265 *===========================================================================*/ 266 /* Basic functionality */ 267 static int musb_am335x_internal_init(void); 268 static void musb_am335x_internal_deinit(void); 269 270 /* Interrupt related */ 271 static void musb_am335x_irq_init(void *); 272 static void musb_am335x_usbss_isr(void *); 273 static void musb_am335x_usbx_isr(void *); 274 static hcd_reg1 musb_am335x_irqstat0_to_ep(int); 275 276 /* Configuration helpers */ 277 static void musb_am335x_usb_reset(int); 278 static void musb_am335x_otg_enable(int); 279 280 281 /*===========================================================================* 282 * musb_am335x_init * 283 *===========================================================================*/ 284 int 285 musb_am335x_init(void) 286 { 287 am335x_controller * ctrl; 288 289 DEBUG_DUMP; 290 291 /* Initial cleanup */ 292 memset(&am335x, 0, sizeof(am335x)); 293 294 /* These registers are specific to AM335X so they are mapped here */ 295 /* -------------------------------------------------------------- */ 296 /* USBSS -------------------------------------------------------- */ 297 /* -------------------------------------------------------------- */ 298 299 /* Map memory for USBSS */ 300 am335x.ss.regs = hcd_os_regs_init(AM335X_USBSS_BASE_ADDR, 301 AM335X_USBSS_TOTAL_REG_LEN); 302 303 if (NULL == am335x.ss.regs) 304 return EXIT_FAILURE; 305 306 /* Attach IRQ to number */ 307 if (EXIT_SUCCESS != hcd_os_interrupt_attach(AM335X_USBSS_IRQ, 308 musb_am335x_irq_init, 309 musb_am335x_usbss_isr, 310 NULL)) 311 return EXIT_FAILURE; 312 313 #ifdef AM335X_USE_USB0 314 /* -------------------------------------------------------------- */ 315 /* USB0 --------------------------------------------------------- */ 316 /* -------------------------------------------------------------- */ 317 { 318 ctrl = &(am335x.ctrl[AM335X_USB0]); 319 320 /* IRQ thread private data */ 321 ctrl->priv.usb_num = AM335X_USB0; 322 323 /* MUSB core addresses for later registering */ 324 ctrl->core.regs = (void*)((hcd_addr)am335x.ss.regs + 325 AM335X_MUSB_CORE0_BASE_OFFSET); 326 327 /* Map AM335X USB0 specific addresses */ 328 ctrl->usb.regs = (void*)((hcd_addr)am335x.ss.regs + 329 AM335X_USB0_BASE_OFFSET); 330 331 /* Attach IRQ to number */ 332 if (EXIT_SUCCESS != hcd_os_interrupt_attach(AM335X_USB0_IRQ, 333 musb_am335x_irq_init, 334 musb_am335x_usbx_isr, 335 &(ctrl->priv))) 336 return EXIT_FAILURE; 337 338 /* Initialize HCD driver */ 339 ctrl->driver.private_data = &(ctrl->core); 340 ctrl->driver.setup_device = musb_setup_device; 341 ctrl->driver.reset_device = musb_reset_device; 342 ctrl->driver.setup_stage = musb_setup_stage; 343 ctrl->driver.rx_stage = musb_rx_stage; 344 ctrl->driver.tx_stage = musb_tx_stage; 345 ctrl->driver.in_data_stage = musb_in_data_stage; 346 ctrl->driver.out_data_stage = musb_out_data_stage; 347 ctrl->driver.in_status_stage = musb_in_status_stage; 348 ctrl->driver.out_status_stage = musb_out_status_stage; 349 ctrl->driver.read_data = musb_read_data; 350 ctrl->driver.check_error = musb_check_error; 351 ctrl->driver.port_device = NULL; 352 } 353 #endif 354 355 /* -------------------------------------------------------------- */ 356 /* USB1 --------------------------------------------------------- */ 357 /* -------------------------------------------------------------- */ 358 { 359 ctrl = &(am335x.ctrl[AM335X_USB1]); 360 361 /* IRQ thread private data */ 362 ctrl->priv.usb_num = AM335X_USB1; 363 364 /* MUSB core addresses for later registering */ 365 ctrl->core.regs = (void*)((hcd_addr)am335x.ss.regs + 366 AM335X_MUSB_CORE1_BASE_OFFSET); 367 368 /* Map AM335X USB0 specific addresses */ 369 ctrl->usb.regs = (void*)((hcd_addr)am335x.ss.regs + 370 AM335X_USB1_BASE_OFFSET); 371 372 /* Attach IRQ to number */ 373 if (EXIT_SUCCESS != hcd_os_interrupt_attach(AM335X_USB1_IRQ, 374 musb_am335x_irq_init, 375 musb_am335x_usbx_isr, 376 &(ctrl->priv))) 377 return EXIT_FAILURE; 378 379 /* Initialize HCD driver */ 380 ctrl->driver.private_data = &(ctrl->core); 381 ctrl->driver.setup_device = musb_setup_device; 382 ctrl->driver.reset_device = musb_reset_device; 383 ctrl->driver.setup_stage = musb_setup_stage; 384 ctrl->driver.rx_stage = musb_rx_stage; 385 ctrl->driver.tx_stage = musb_tx_stage; 386 ctrl->driver.in_data_stage = musb_in_data_stage; 387 ctrl->driver.out_data_stage = musb_out_data_stage; 388 ctrl->driver.in_status_stage = musb_in_status_stage; 389 ctrl->driver.out_status_stage = musb_out_status_stage; 390 ctrl->driver.read_data = musb_read_data; 391 ctrl->driver.check_error = musb_check_error; 392 ctrl->driver.port_device = NULL; 393 } 394 395 return musb_am335x_internal_init(); 396 } 397 398 399 /*===========================================================================* 400 * musb_am335x_deinit * 401 *===========================================================================*/ 402 void 403 musb_am335x_deinit(void) 404 { 405 DEBUG_DUMP; 406 407 musb_am335x_internal_deinit(); 408 409 /* Release IRQ resources */ 410 /* TODO: DDEKit has no checks on NULL IRQ and may crash on detach 411 * if interrupts were not attached properly */ 412 hcd_os_interrupt_detach(AM335X_USB1_IRQ); 413 #ifdef AM335X_USE_USB0 414 hcd_os_interrupt_detach(AM335X_USB0_IRQ); 415 #endif 416 hcd_os_interrupt_detach(AM335X_USBSS_IRQ); 417 418 /* Release maps if anything was assigned */ 419 if (NULL != am335x.ss.regs) 420 if (EXIT_SUCCESS != hcd_os_regs_deinit((hcd_addr)am335x.ss.regs, 421 AM335X_USBSS_TOTAL_REG_LEN)) 422 USB_MSG("Failed to release USBSS mapping"); 423 } 424 425 426 /*===========================================================================* 427 * musb_am335x_internal_init * 428 *===========================================================================*/ 429 static int 430 musb_am335x_internal_init(void) 431 { 432 DEBUG_DUMP; 433 434 /* Configure clocking */ 435 if (hcd_os_clkconf(AM335X_REG_CM_PER_USB0_CLKCTRL_OFFSET, 436 AM335X_VAL_CM_PER_USB0_CLKCTRL_MODULEMODE_ENABLE, 437 AM335X_CLKCONF_FULL_VAL)) 438 return EXIT_FAILURE; 439 440 /* Read and dump revision register */ 441 USB_MSG("MUSB revision (REVREG): 0x%08X", 442 (unsigned int)HCD_RD4(am335x.ss.regs, AM335X_REG_REVREG)); 443 444 /* Allow OS to handle previously configured USBSS interrupts */ 445 hcd_os_interrupt_enable(AM335X_USBSS_IRQ); 446 447 #ifdef AM335X_USE_USB0 448 /* Reset controllers so we get default register values */ 449 musb_am335x_usb_reset(AM335X_USB0); 450 /* Allow OS to handle previously configured USB0 interrupts */ 451 hcd_os_interrupt_enable(AM335X_USB0_IRQ); 452 /* Enable whatever necessary for OTG part of controller */ 453 musb_am335x_otg_enable(AM335X_USB0); 454 /* Start actual MUSB core */ 455 musb_core_start(&(am335x.ctrl[AM335X_USB0].core)); 456 #endif 457 458 /* Reset controllers so we get default register values */ 459 musb_am335x_usb_reset(AM335X_USB1); 460 /* Allow OS to handle previously configured USB1 interrupts */ 461 hcd_os_interrupt_enable(AM335X_USB1_IRQ); 462 /* Enable whatever necessary for OTG part of controller */ 463 musb_am335x_otg_enable(AM335X_USB1); 464 /* Start actual MUSB core */ 465 musb_core_start(&(am335x.ctrl[AM335X_USB1].core)); 466 467 return EXIT_SUCCESS; 468 } 469 470 471 /*===========================================================================* 472 * musb_am335x_internal_deinit * 473 *===========================================================================*/ 474 static void 475 musb_am335x_internal_deinit(void) 476 { 477 DEBUG_DUMP; 478 479 /* Disable all interrupts */ 480 hcd_os_interrupt_disable(AM335X_USBSS_IRQ); 481 #ifdef AM335X_USE_USB0 482 hcd_os_interrupt_disable(AM335X_USB0_IRQ); 483 #endif 484 hcd_os_interrupt_disable(AM335X_USB1_IRQ); 485 486 /* Stop core */ 487 #ifdef AM335X_USE_USB0 488 musb_core_stop(&(am335x.ctrl[AM335X_USB0].core)); 489 #endif 490 musb_core_stop(&(am335x.ctrl[AM335X_USB1].core)); 491 492 /* Every clkconf call should have corresponding release */ 493 hcd_os_clkconf_release(); 494 } 495 496 497 /*===========================================================================* 498 * musb_am335x_irq_init * 499 *===========================================================================*/ 500 static void 501 musb_am335x_irq_init(void * UNUSED(unused)) 502 { 503 DEBUG_DUMP; 504 505 /* TODO: This function does nothing and is not needed by MUSB but 506 * is still required by DDEKit for initialization, as NULL pointer 507 * cannot be passed to ddekit_interrupt_attach */ 508 return; 509 } 510 511 512 /*===========================================================================* 513 * musb_am335x_usbss_isr * 514 *===========================================================================*/ 515 static void 516 musb_am335x_usbss_isr(void * UNUSED(data)) 517 { 518 void * r; 519 hcd_reg4 irqstat; 520 521 DEBUG_DUMP; 522 523 r = am335x.ss.regs; 524 525 irqstat = HCD_RD4(r, AM335X_REG_IRQSTAT); 526 527 USB_DBG("AM335X_REG_IRQSTAT = %X", (unsigned int)irqstat); 528 529 /* Write to clear interrupt */ 530 HCD_WR4(r, AM335X_REG_IRQSTAT, irqstat); 531 } 532 533 534 /*===========================================================================* 535 * musb_am335x_usbx_isr * 536 *===========================================================================*/ 537 static void 538 musb_am335x_usbx_isr(void * data) 539 { 540 void * r; 541 hcd_driver_state * driver; 542 hcd_reg4 irqstat0; 543 hcd_reg4 irqstat1; 544 int usb_num; 545 546 DEBUG_DUMP; 547 548 /* Prepare locals based on USB controller number for this interrupt */ 549 usb_num = ((am335x_irq_private*)data)->usb_num; 550 r = am335x.ctrl[usb_num].usb.regs; 551 driver = &(am335x.ctrl[usb_num].driver); 552 553 /* Read, handle and clean interrupts */ 554 irqstat0 = HCD_RD4(r, AM335X_REG_USBXIRQSTAT0); 555 irqstat1 = HCD_RD4(r, AM335X_REG_USBXIRQSTAT1); 556 557 /* Interrupts, seem to appear one at a time 558 * Check which bit is set to resolve event */ 559 if (irqstat1 & AM335X_VAL_USBXIRQSTAT1_DRVVBUS) { 560 USB_DBG("DRVVBUS level changed"); 561 CLEAR_IRQ1(AM335X_VAL_USBXIRQSTAT1_DRVVBUS); 562 return; 563 } 564 565 if (irqstat1 & AM335X_VAL_USBXIRQENABLEXXX1_CONNECTED) { 566 USB_DBG("Device connected"); 567 CLEAR_IRQ1(AM335X_VAL_USBXIRQENABLEXXX1_CONNECTED); 568 hcd_update_port(driver, HCD_EVENT_CONNECTED); 569 hcd_handle_event(driver->port_device, HCD_EVENT_CONNECTED, 570 HCD_UNUSED_VAL); 571 return; 572 } 573 574 if (irqstat1 & AM335X_VAL_USBXIRQENABLEXXX1_DISCONNECTED) { 575 USB_DBG("Device disconnected"); 576 CLEAR_IRQ1(AM335X_VAL_USBXIRQENABLEXXX1_DISCONNECTED); 577 hcd_handle_event(driver->port_device, HCD_EVENT_DISCONNECTED, 578 HCD_UNUSED_VAL); 579 hcd_update_port(driver, HCD_EVENT_DISCONNECTED); 580 return; 581 } 582 583 if (0 != irqstat0) { 584 USB_DBG("EP interrupt"); 585 CLEAR_IRQ0(irqstat0); 586 hcd_handle_event(driver->port_device, HCD_EVENT_ENDPOINT, 587 musb_am335x_irqstat0_to_ep(irqstat0)); 588 return; 589 } 590 591 if (irqstat1 & AM335X_VAL_USBXIRQENABLEXXX1_SUSPEND) { 592 USB_DBG("Unhandled SUSPEND IRQ"); 593 CLEAR_IRQ1(AM335X_VAL_USBXIRQENABLEXXX1_SUSPEND); 594 return; 595 } 596 597 if (irqstat1 & AM335X_VAL_USBXIRQENABLEXXX1_RESUME) { 598 USB_DBG("Unhandled RESUME IRQ"); 599 CLEAR_IRQ1(AM335X_VAL_USBXIRQENABLEXXX1_RESUME); 600 return; 601 } 602 603 if (irqstat1 & AM335X_VAL_USBXIRQENABLEXXX1_RESET_BABBLE) { 604 USB_DBG("Unhandled RESET/BABBLE IRQ"); 605 CLEAR_IRQ1(AM335X_VAL_USBXIRQENABLEXXX1_RESET_BABBLE); 606 return; 607 } 608 609 if (irqstat1 & AM335X_VAL_USBXIRQENABLEXXX1_SOF) { 610 USB_DBG("Unhandled SOF IRQ"); 611 CLEAR_IRQ1(AM335X_VAL_USBXIRQENABLEXXX1_SOF); 612 return; 613 } 614 615 if (irqstat1 & AM335X_VAL_USBXIRQENABLEXXX1_SRP) { 616 USB_DBG("Unhandled SRP IRQ"); 617 CLEAR_IRQ1(AM335X_VAL_USBXIRQENABLEXXX1_SRP); 618 return; 619 } 620 621 if (irqstat1 & AM335X_VAL_USBXIRQENABLEXXX1_VBUS) { 622 USB_DBG("Unhandled VBUS IRQ"); 623 CLEAR_IRQ1(AM335X_VAL_USBXIRQENABLEXXX1_VBUS); 624 return; 625 } 626 627 if (irqstat1 & AM335X_VAL_USBXIRQENABLEXXX1_GENERIC) { 628 USB_DBG("Unhandled GENERIC IRQ"); 629 CLEAR_IRQ1(AM335X_VAL_USBXIRQENABLEXXX1_GENERIC); 630 return; 631 } 632 633 /* When controller is correctly configured this should never happen: */ 634 USB_MSG("Illegal value of IRQxSTAT: 0=%X 1=%X", 635 (unsigned int)irqstat0, (unsigned int)irqstat1); 636 USB_ASSERT(0, "IRQxSTAT error"); 637 } 638 639 640 /*===========================================================================* 641 * musb_am335x_irqstat0_to_ep * 642 *===========================================================================*/ 643 static hcd_reg1 644 musb_am335x_irqstat0_to_ep(int irqstat0) 645 { 646 hcd_reg1 ep; 647 648 DEBUG_DUMP; 649 650 ep = 0; 651 652 while (0 == (irqstat0 & 0x01)) { 653 irqstat0 >>= 1; 654 ep++; 655 /* Must be within two consecutive EP sets */ 656 USB_ASSERT(ep < (2 * HCD_TOTAL_EP), 657 "Invalid IRQSTAT0 supplied (1)"); 658 } 659 660 /* Convert RX interrupt to EP number */ 661 if (ep >= HCD_TOTAL_EP) { 662 ep -= HCD_TOTAL_EP; 663 /* Must not be control EP */ 664 USB_ASSERT(ep != HCD_DEFAULT_EP, 665 "Invalid IRQSTAT0 supplied (2)"); 666 } 667 668 return ep; 669 } 670 671 672 /*===========================================================================* 673 * musb_am335x_usb_reset * 674 *===========================================================================*/ 675 static void 676 musb_am335x_usb_reset(int usb_num) 677 { 678 void * r; 679 hcd_reg4 ctrl; 680 681 DEBUG_DUMP; 682 683 r = am335x.ctrl[usb_num].usb.regs; 684 685 /* Set SOFT_RESET bit and wait until it is off */ 686 ctrl = HCD_RD4(r, AM335X_REG_USBXCTRL); 687 HCD_SET(ctrl, AM335X_VAL_USBXCTRL_SOFT_RESET); 688 HCD_WR4(r, AM335X_REG_USBXCTRL, ctrl); 689 while (HCD_RD4(r, AM335X_REG_USBXCTRL) & 690 AM335X_VAL_USBXCTRL_SOFT_RESET); 691 } 692 693 694 /*===========================================================================* 695 * musb_am335x_otg_enable * 696 *===========================================================================*/ 697 static void 698 musb_am335x_otg_enable(int usb_num) 699 { 700 void * r; 701 hcd_reg4 intreg; 702 hcd_reg4 mode; 703 704 DEBUG_DUMP; 705 706 r = am335x.ctrl[usb_num].usb.regs; 707 708 /* Force host operation */ 709 mode = HCD_RD4(r, AM335X_REG_USBXMODE); 710 HCD_SET(mode, AM335X_VAL_USBXMODE_IDDIG_MUX); 711 HCD_CLR(mode, AM335X_VAL_USBXMODE_IDDIG); 712 HCD_WR4(r, AM335X_REG_USBXMODE, mode); 713 714 /* Set all important interrupts to be handled */ 715 intreg = HCD_RD4(r, AM335X_REG_USBXIRQENABLESET1); 716 HCD_SET(intreg, AM335X_VAL_USBXIRQENABLEXXX1_SUSPEND | 717 AM335X_VAL_USBXIRQENABLEXXX1_RESUME | 718 AM335X_VAL_USBXIRQENABLEXXX1_RESET_BABBLE | 719 /* AM335X_VAL_USBXIRQENABLEXXX1_SOF | */ 720 AM335X_VAL_USBXIRQENABLEXXX1_CONNECTED | 721 AM335X_VAL_USBXIRQENABLEXXX1_DISCONNECTED | 722 AM335X_VAL_USBXIRQENABLEXXX1_SRP | 723 AM335X_VAL_USBXIRQENABLEXXX1_VBUS | 724 AM335X_VAL_USBXIRQENABLEXXX1_DRVVBUS | 725 AM335X_VAL_USBXIRQENABLEXXX1_GENERIC); 726 727 HCD_WR4(r, AM335X_REG_USBXIRQENABLESET1, intreg); 728 729 /* Set all EP interrupts as enabled */ 730 intreg = AM335X_VAL_USBXIRQENABLEXXX0_EP0 | 731 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP1 | 732 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP2 | 733 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP3 | 734 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP4 | 735 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP5 | 736 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP6 | 737 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP7 | 738 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP8 | 739 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP9 | 740 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP10 | 741 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP11 | 742 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP12 | 743 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP13 | 744 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP14 | 745 AM335X_VAL_USBXIRQENABLEXXX0_TX_EP15 | 746 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP1 | 747 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP2 | 748 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP3 | 749 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP4 | 750 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP5 | 751 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP6 | 752 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP7 | 753 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP8 | 754 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP9 | 755 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP10 | 756 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP11 | 757 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP12 | 758 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP13 | 759 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP14 | 760 AM335X_VAL_USBXIRQENABLEXXX0_RX_EP15 ; 761 762 HCD_WR4(r, AM335X_REG_USBXIRQENABLESET0, intreg); 763 } 764