| .. | .. |
|---|
| 50 | 50 | #include <linux/module.h> |
|---|
| 51 | 51 | #include <linux/usb/hcd.h> |
|---|
| 52 | 52 | #include <linux/prefetch.h> |
|---|
| 53 | +#include <linux/dma-mapping.h> |
|---|
| 53 | 54 | #include <linux/platform_device.h> |
|---|
| 54 | 55 | |
|---|
| 55 | 56 | #include <asm/octeon/octeon.h> |
|---|
| .. | .. |
|---|
| 377 | 378 | struct cvmx_usb_tx_fifo nonperiodic; |
|---|
| 378 | 379 | }; |
|---|
| 379 | 380 | |
|---|
| 380 | | -/* This macro spins on a register waiting for it to reach a condition. */ |
|---|
| 381 | | -#define CVMX_WAIT_FOR_FIELD32(address, _union, cond, timeout_usec) \ |
|---|
| 382 | | - ({int result; \ |
|---|
| 383 | | - do { \ |
|---|
| 384 | | - u64 done = cvmx_get_cycle() + (u64)timeout_usec * \ |
|---|
| 385 | | - octeon_get_clock_rate() / 1000000; \ |
|---|
| 386 | | - union _union c; \ |
|---|
| 387 | | - \ |
|---|
| 388 | | - while (1) { \ |
|---|
| 389 | | - c.u32 = cvmx_usb_read_csr32(usb, address); \ |
|---|
| 390 | | - \ |
|---|
| 391 | | - if (cond) { \ |
|---|
| 392 | | - result = 0; \ |
|---|
| 393 | | - break; \ |
|---|
| 394 | | - } else if (cvmx_get_cycle() > done) { \ |
|---|
| 395 | | - result = -1; \ |
|---|
| 396 | | - break; \ |
|---|
| 397 | | - } else \ |
|---|
| 398 | | - __delay(100); \ |
|---|
| 399 | | - } \ |
|---|
| 400 | | - } while (0); \ |
|---|
| 401 | | - result; }) |
|---|
| 402 | | - |
|---|
| 403 | 381 | /* |
|---|
| 404 | 382 | * This macro logically sets a single field in a CSR. It does the sequence |
|---|
| 405 | 383 | * read, modify, and write |
|---|
| .. | .. |
|---|
| 428 | 406 | */ |
|---|
| 429 | 407 | struct octeon_temp_buffer { |
|---|
| 430 | 408 | void *orig_buffer; |
|---|
| 431 | | - u8 data[0]; |
|---|
| 409 | + u8 data[]; |
|---|
| 432 | 410 | }; |
|---|
| 433 | 411 | |
|---|
| 434 | 412 | static inline struct usb_hcd *octeon_to_hcd(struct octeon_hcd *p) |
|---|
| .. | .. |
|---|
| 543 | 521 | */ |
|---|
| 544 | 522 | static inline u32 cvmx_usb_read_csr32(struct octeon_hcd *usb, u64 address) |
|---|
| 545 | 523 | { |
|---|
| 546 | | - u32 result = cvmx_read64_uint32(address ^ 4); |
|---|
| 547 | | - return result; |
|---|
| 524 | + return cvmx_read64_uint32(address ^ 4); |
|---|
| 548 | 525 | } |
|---|
| 549 | 526 | |
|---|
| 550 | 527 | /** |
|---|
| .. | .. |
|---|
| 593 | 570 | return 0; /* Data0 */ |
|---|
| 594 | 571 | } |
|---|
| 595 | 572 | |
|---|
| 573 | +/* Loops through register until txfflsh or rxfflsh become zero.*/ |
|---|
| 574 | +static int cvmx_wait_tx_rx(struct octeon_hcd *usb, int fflsh_type) |
|---|
| 575 | +{ |
|---|
| 576 | + int result; |
|---|
| 577 | + u64 address = CVMX_USBCX_GRSTCTL(usb->index); |
|---|
| 578 | + u64 done = cvmx_get_cycle() + 100 * |
|---|
| 579 | + (u64)octeon_get_clock_rate / 1000000; |
|---|
| 580 | + union cvmx_usbcx_grstctl c; |
|---|
| 581 | + |
|---|
| 582 | + while (1) { |
|---|
| 583 | + c.u32 = cvmx_usb_read_csr32(usb, address); |
|---|
| 584 | + if (fflsh_type == 0 && c.s.txfflsh == 0) { |
|---|
| 585 | + result = 0; |
|---|
| 586 | + break; |
|---|
| 587 | + } else if (fflsh_type == 1 && c.s.rxfflsh == 0) { |
|---|
| 588 | + result = 0; |
|---|
| 589 | + break; |
|---|
| 590 | + } else if (cvmx_get_cycle() > done) { |
|---|
| 591 | + result = -1; |
|---|
| 592 | + break; |
|---|
| 593 | + } |
|---|
| 594 | + |
|---|
| 595 | + __delay(100); |
|---|
| 596 | + } |
|---|
| 597 | + return result; |
|---|
| 598 | +} |
|---|
| 599 | + |
|---|
| 596 | 600 | static void cvmx_fifo_setup(struct octeon_hcd *usb) |
|---|
| 597 | 601 | { |
|---|
| 598 | 602 | union cvmx_usbcx_ghwcfg3 usbcx_ghwcfg3; |
|---|
| .. | .. |
|---|
| 634 | 638 | cvmx_usbcx_grstctl, txfnum, 0x10); |
|---|
| 635 | 639 | USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), |
|---|
| 636 | 640 | cvmx_usbcx_grstctl, txfflsh, 1); |
|---|
| 637 | | - CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), |
|---|
| 638 | | - cvmx_usbcx_grstctl, c.s.txfflsh == 0, 100); |
|---|
| 641 | + cvmx_wait_tx_rx(usb, 0); |
|---|
| 639 | 642 | USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), |
|---|
| 640 | 643 | cvmx_usbcx_grstctl, rxfflsh, 1); |
|---|
| 641 | | - CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), |
|---|
| 642 | | - cvmx_usbcx_grstctl, c.s.rxfflsh == 0, 100); |
|---|
| 644 | + cvmx_wait_tx_rx(usb, 1); |
|---|
| 643 | 645 | } |
|---|
| 644 | 646 | |
|---|
| 645 | 647 | /** |
|---|
| .. | .. |
|---|
| 1231 | 1233 | cvmx_write64_uint32(csr_address, *ptr++); |
|---|
| 1232 | 1234 | cvmx_write64_uint32(csr_address, *ptr++); |
|---|
| 1233 | 1235 | cvmx_write64_uint32(csr_address, *ptr++); |
|---|
| 1234 | | - cvmx_read64_uint64( |
|---|
| 1235 | | - CVMX_USBNX_DMA0_INB_CHN0(usb->index)); |
|---|
| 1236 | + cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index)); |
|---|
| 1236 | 1237 | words -= 3; |
|---|
| 1237 | 1238 | } |
|---|
| 1238 | 1239 | cvmx_write64_uint32(csr_address, *ptr++); |
|---|
| .. | .. |
|---|
| 1834 | 1835 | * |
|---|
| 1835 | 1836 | * Returns: Pipe or NULL if none are ready |
|---|
| 1836 | 1837 | */ |
|---|
| 1837 | | -static struct cvmx_usb_pipe *cvmx_usb_find_ready_pipe( |
|---|
| 1838 | | - struct octeon_hcd *usb, |
|---|
| 1838 | +static struct cvmx_usb_pipe *cvmx_usb_find_ready_pipe(struct octeon_hcd *usb, |
|---|
| 1839 | 1839 | enum cvmx_usb_transfer xfer_type) |
|---|
| 1840 | 1840 | { |
|---|
| 1841 | 1841 | struct list_head *list = usb->active_pipes + xfer_type; |
|---|
| .. | .. |
|---|
| 2382 | 2382 | */ |
|---|
| 2383 | 2383 | static int cvmx_usb_get_frame_number(struct octeon_hcd *usb) |
|---|
| 2384 | 2384 | { |
|---|
| 2385 | | - int frame_number; |
|---|
| 2386 | 2385 | union cvmx_usbcx_hfnum usbc_hfnum; |
|---|
| 2387 | 2386 | |
|---|
| 2388 | 2387 | usbc_hfnum.u32 = cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index)); |
|---|
| 2389 | | - frame_number = usbc_hfnum.s.frnum; |
|---|
| 2390 | 2388 | |
|---|
| 2391 | | - return frame_number; |
|---|
| 2389 | + return usbc_hfnum.s.frnum; |
|---|
| 2392 | 2390 | } |
|---|
| 2393 | 2391 | |
|---|
| 2394 | 2392 | static void cvmx_usb_transfer_control(struct octeon_hcd *usb, |
|---|
| .. | .. |
|---|
| 2768 | 2766 | (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT)) |
|---|
| 2769 | 2767 | pipe->flags |= CVMX_USB_PIPE_FLAGS_NEED_PING; |
|---|
| 2770 | 2768 | |
|---|
| 2771 | | - if (unlikely(WARN_ON_ONCE(bytes_this_transfer < 0))) { |
|---|
| 2769 | + if (WARN_ON_ONCE(bytes_this_transfer < 0)) { |
|---|
| 2772 | 2770 | /* |
|---|
| 2773 | 2771 | * In some rare cases the DMA engine seems to get stuck and |
|---|
| 2774 | 2772 | * keeps substracting same byte count over and over again. In |
|---|
| .. | .. |
|---|
| 3512 | 3510 | .product_desc = "Octeon Host Controller", |
|---|
| 3513 | 3511 | .hcd_priv_size = sizeof(struct octeon_hcd), |
|---|
| 3514 | 3512 | .irq = octeon_usb_irq, |
|---|
| 3515 | | - .flags = HCD_MEMORY | HCD_USB2, |
|---|
| 3513 | + .flags = HCD_MEMORY | HCD_DMA | HCD_USB2, |
|---|
| 3516 | 3514 | .start = octeon_usb_start, |
|---|
| 3517 | 3515 | .stop = octeon_usb_stop, |
|---|
| 3518 | 3516 | .urb_enqueue = octeon_usb_urb_enqueue, |
|---|
| .. | .. |
|---|
| 3604 | 3602 | * Set the DMA mask to 64bits so we get buffers already translated for |
|---|
| 3605 | 3603 | * DMA. |
|---|
| 3606 | 3604 | */ |
|---|
| 3607 | | - dev->coherent_dma_mask = ~0; |
|---|
| 3608 | | - dev->dma_mask = &dev->coherent_dma_mask; |
|---|
| 3605 | + i = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64)); |
|---|
| 3606 | + if (i) |
|---|
| 3607 | + return i; |
|---|
| 3609 | 3608 | |
|---|
| 3610 | 3609 | /* |
|---|
| 3611 | 3610 | * Only cn52XX and cn56XX have DWC_OTG USB hardware and the |
|---|