diff options
Diffstat (limited to 'drivers/usb/musb/musb_cppi41.c')
| -rw-r--r-- | drivers/usb/musb/musb_cppi41.c | 164 |
1 files changed, 140 insertions, 24 deletions
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index ff9d6de2b746..a12bd30401e0 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c | |||
| @@ -38,6 +38,7 @@ struct cppi41_dma_channel { | |||
| 38 | u32 prog_len; | 38 | u32 prog_len; |
| 39 | u32 transferred; | 39 | u32 transferred; |
| 40 | u32 packet_sz; | 40 | u32 packet_sz; |
| 41 | struct list_head tx_check; | ||
| 41 | }; | 42 | }; |
| 42 | 43 | ||
| 43 | #define MUSB_DMA_NUM_CHANNELS 15 | 44 | #define MUSB_DMA_NUM_CHANNELS 15 |
| @@ -47,6 +48,8 @@ struct cppi41_dma_controller { | |||
| 47 | struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS]; | 48 | struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS]; |
| 48 | struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS]; | 49 | struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS]; |
| 49 | struct musb *musb; | 50 | struct musb *musb; |
| 51 | struct hrtimer early_tx; | ||
| 52 | struct list_head early_tx_list; | ||
| 50 | u32 rx_mode; | 53 | u32 rx_mode; |
| 51 | u32 tx_mode; | 54 | u32 tx_mode; |
| 52 | u32 auto_req; | 55 | u32 auto_req; |
| @@ -96,31 +99,27 @@ static void update_rx_toggle(struct cppi41_dma_channel *cppi41_channel) | |||
| 96 | cppi41_channel->usb_toggle = toggle; | 99 | cppi41_channel->usb_toggle = toggle; |
| 97 | } | 100 | } |
| 98 | 101 | ||
| 99 | static void cppi41_dma_callback(void *private_data) | 102 | static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep) |
| 100 | { | 103 | { |
| 101 | struct dma_channel *channel = private_data; | 104 | u8 epnum = hw_ep->epnum; |
| 102 | struct cppi41_dma_channel *cppi41_channel = channel->private_data; | 105 | struct musb *musb = hw_ep->musb; |
| 103 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | 106 | void __iomem *epio = musb->endpoints[epnum].regs; |
| 104 | struct musb *musb = hw_ep->musb; | 107 | u16 csr; |
| 105 | unsigned long flags; | ||
| 106 | struct dma_tx_state txstate; | ||
| 107 | u32 transferred; | ||
| 108 | 108 | ||
| 109 | spin_lock_irqsave(&musb->lock, flags); | 109 | csr = musb_readw(epio, MUSB_TXCSR); |
| 110 | if (csr & MUSB_TXCSR_TXPKTRDY) | ||
| 111 | return false; | ||
| 112 | return true; | ||
| 113 | } | ||
| 110 | 114 | ||
| 111 | dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie, | 115 | static void cppi41_dma_callback(void *private_data); |
| 112 | &txstate); | ||
| 113 | transferred = cppi41_channel->prog_len - txstate.residue; | ||
| 114 | cppi41_channel->transferred += transferred; | ||
| 115 | 116 | ||
| 116 | dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n", | 117 | static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) |
| 117 | hw_ep->epnum, cppi41_channel->transferred, | 118 | { |
| 118 | cppi41_channel->total_len); | 119 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; |
| 120 | struct musb *musb = hw_ep->musb; | ||
| 119 | 121 | ||
| 120 | update_rx_toggle(cppi41_channel); | 122 | if (!cppi41_channel->prog_len) { |
| 121 | |||
| 122 | if (cppi41_channel->transferred == cppi41_channel->total_len || | ||
| 123 | transferred < cppi41_channel->packet_sz) { | ||
| 124 | 123 | ||
| 125 | /* done, complete */ | 124 | /* done, complete */ |
| 126 | cppi41_channel->channel.actual_len = | 125 | cppi41_channel->channel.actual_len = |
| @@ -150,13 +149,11 @@ static void cppi41_dma_callback(void *private_data) | |||
| 150 | remain_bytes, | 149 | remain_bytes, |
| 151 | direction, | 150 | direction, |
| 152 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 151 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 153 | if (WARN_ON(!dma_desc)) { | 152 | if (WARN_ON(!dma_desc)) |
| 154 | spin_unlock_irqrestore(&musb->lock, flags); | ||
| 155 | return; | 153 | return; |
| 156 | } | ||
| 157 | 154 | ||
| 158 | dma_desc->callback = cppi41_dma_callback; | 155 | dma_desc->callback = cppi41_dma_callback; |
| 159 | dma_desc->callback_param = channel; | 156 | dma_desc->callback_param = &cppi41_channel->channel; |
| 160 | cppi41_channel->cookie = dma_desc->tx_submit(dma_desc); | 157 | cppi41_channel->cookie = dma_desc->tx_submit(dma_desc); |
| 161 | dma_async_issue_pending(dc); | 158 | dma_async_issue_pending(dc); |
| 162 | 159 | ||
| @@ -166,6 +163,117 @@ static void cppi41_dma_callback(void *private_data) | |||
| 166 | musb_writew(epio, MUSB_RXCSR, csr); | 163 | musb_writew(epio, MUSB_RXCSR, csr); |
| 167 | } | 164 | } |
| 168 | } | 165 | } |
| 166 | } | ||
| 167 | |||
| 168 | static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer) | ||
| 169 | { | ||
| 170 | struct cppi41_dma_controller *controller; | ||
| 171 | struct cppi41_dma_channel *cppi41_channel, *n; | ||
| 172 | struct musb *musb; | ||
| 173 | unsigned long flags; | ||
| 174 | enum hrtimer_restart ret = HRTIMER_NORESTART; | ||
| 175 | |||
| 176 | controller = container_of(timer, struct cppi41_dma_controller, | ||
| 177 | early_tx); | ||
| 178 | musb = controller->musb; | ||
| 179 | |||
| 180 | spin_lock_irqsave(&musb->lock, flags); | ||
| 181 | list_for_each_entry_safe(cppi41_channel, n, &controller->early_tx_list, | ||
| 182 | tx_check) { | ||
| 183 | bool empty; | ||
| 184 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | ||
| 185 | |||
| 186 | empty = musb_is_tx_fifo_empty(hw_ep); | ||
| 187 | if (empty) { | ||
| 188 | list_del_init(&cppi41_channel->tx_check); | ||
| 189 | cppi41_trans_done(cppi41_channel); | ||
| 190 | } | ||
| 191 | } | ||
| 192 | |||
| 193 | if (!list_empty(&controller->early_tx_list)) { | ||
| 194 | ret = HRTIMER_RESTART; | ||
| 195 | hrtimer_forward_now(&controller->early_tx, | ||
| 196 | ktime_set(0, 150 * NSEC_PER_USEC)); | ||
| 197 | } | ||
| 198 | |||
| 199 | spin_unlock_irqrestore(&musb->lock, flags); | ||
| 200 | return ret; | ||
| 201 | } | ||
| 202 | |||
| 203 | static void cppi41_dma_callback(void *private_data) | ||
| 204 | { | ||
| 205 | struct dma_channel *channel = private_data; | ||
| 206 | struct cppi41_dma_channel *cppi41_channel = channel->private_data; | ||
| 207 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | ||
| 208 | struct musb *musb = hw_ep->musb; | ||
| 209 | unsigned long flags; | ||
| 210 | struct dma_tx_state txstate; | ||
| 211 | u32 transferred; | ||
| 212 | bool empty; | ||
| 213 | |||
| 214 | spin_lock_irqsave(&musb->lock, flags); | ||
| 215 | |||
| 216 | dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie, | ||
| 217 | &txstate); | ||
| 218 | transferred = cppi41_channel->prog_len - txstate.residue; | ||
| 219 | cppi41_channel->transferred += transferred; | ||
| 220 | |||
| 221 | dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n", | ||
| 222 | hw_ep->epnum, cppi41_channel->transferred, | ||
| 223 | cppi41_channel->total_len); | ||
| 224 | |||
| 225 | update_rx_toggle(cppi41_channel); | ||
| 226 | |||
| 227 | if (cppi41_channel->transferred == cppi41_channel->total_len || | ||
| 228 | transferred < cppi41_channel->packet_sz) | ||
| 229 | cppi41_channel->prog_len = 0; | ||
| 230 | |||
| 231 | empty = musb_is_tx_fifo_empty(hw_ep); | ||
| 232 | if (empty) { | ||
| 233 | cppi41_trans_done(cppi41_channel); | ||
| 234 | } else { | ||
| 235 | struct cppi41_dma_controller *controller; | ||
| 236 | /* | ||
| 237 | * On AM335x it has been observed that the TX interrupt fires | ||
| 238 | * too early that means the TXFIFO is not yet empty but the DMA | ||
| 239 | * engine says that it is done with the transfer. We don't | ||
| 240 | * receive a FIFO empty interrupt so the only thing we can do is | ||
| 241 | * to poll for the bit. On HS it usually takes 2us, on FS around | ||
| 242 | * 110us - 150us depending on the transfer size. | ||
| 243 | * We spin on HS (no longer than than 25us and setup a timer on | ||
| 244 | * FS to check for the bit and complete the transfer. | ||
| 245 | */ | ||
| 246 | controller = cppi41_channel->controller; | ||
| 247 | |||
| 248 | if (musb->g.speed == USB_SPEED_HIGH) { | ||
| 249 | unsigned wait = 25; | ||
| 250 | |||
| 251 | do { | ||
| 252 | empty = musb_is_tx_fifo_empty(hw_ep); | ||
| 253 | if (empty) | ||
| 254 | break; | ||
| 255 | wait--; | ||
| 256 | if (!wait) | ||
| 257 | break; | ||
| 258 | udelay(1); | ||
| 259 | } while (1); | ||
| 260 | |||
| 261 | empty = musb_is_tx_fifo_empty(hw_ep); | ||
| 262 | if (empty) { | ||
| 263 | cppi41_trans_done(cppi41_channel); | ||
| 264 | goto out; | ||
| 265 | } | ||
| 266 | } | ||
| 267 | list_add_tail(&cppi41_channel->tx_check, | ||
| 268 | &controller->early_tx_list); | ||
| 269 | if (!hrtimer_active(&controller->early_tx)) { | ||
| 270 | hrtimer_start_range_ns(&controller->early_tx, | ||
| 271 | ktime_set(0, 140 * NSEC_PER_USEC), | ||
| 272 | 40 * NSEC_PER_USEC, | ||
| 273 | HRTIMER_MODE_REL); | ||
| 274 | } | ||
| 275 | } | ||
| 276 | out: | ||
| 169 | spin_unlock_irqrestore(&musb->lock, flags); | 277 | spin_unlock_irqrestore(&musb->lock, flags); |
| 170 | } | 278 | } |
| 171 | 279 | ||
| @@ -364,6 +472,8 @@ static int cppi41_is_compatible(struct dma_channel *channel, u16 maxpacket, | |||
| 364 | WARN_ON(1); | 472 | WARN_ON(1); |
| 365 | return 1; | 473 | return 1; |
| 366 | } | 474 | } |
| 475 | if (cppi41_channel->hw_ep->ep_in.type != USB_ENDPOINT_XFER_BULK) | ||
| 476 | return 0; | ||
| 367 | if (cppi41_channel->is_tx) | 477 | if (cppi41_channel->is_tx) |
| 368 | return 1; | 478 | return 1; |
| 369 | /* AM335x Advisory 1.0.13. No workaround for device RX mode */ | 479 | /* AM335x Advisory 1.0.13. No workaround for device RX mode */ |
| @@ -388,6 +498,7 @@ static int cppi41_dma_channel_abort(struct dma_channel *channel) | |||
| 388 | if (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE) | 498 | if (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE) |
| 389 | return 0; | 499 | return 0; |
| 390 | 500 | ||
| 501 | list_del_init(&cppi41_channel->tx_check); | ||
| 391 | if (is_tx) { | 502 | if (is_tx) { |
| 392 | csr = musb_readw(epio, MUSB_TXCSR); | 503 | csr = musb_readw(epio, MUSB_TXCSR); |
| 393 | csr &= ~MUSB_TXCSR_DMAENAB; | 504 | csr &= ~MUSB_TXCSR_DMAENAB; |
| @@ -495,6 +606,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) | |||
| 495 | cppi41_channel->controller = controller; | 606 | cppi41_channel->controller = controller; |
| 496 | cppi41_channel->port_num = port; | 607 | cppi41_channel->port_num = port; |
| 497 | cppi41_channel->is_tx = is_tx; | 608 | cppi41_channel->is_tx = is_tx; |
| 609 | INIT_LIST_HEAD(&cppi41_channel->tx_check); | ||
| 498 | 610 | ||
| 499 | musb_dma = &cppi41_channel->channel; | 611 | musb_dma = &cppi41_channel->channel; |
| 500 | musb_dma->private_data = cppi41_channel; | 612 | musb_dma->private_data = cppi41_channel; |
| @@ -520,6 +632,7 @@ void dma_controller_destroy(struct dma_controller *c) | |||
| 520 | struct cppi41_dma_controller *controller = container_of(c, | 632 | struct cppi41_dma_controller *controller = container_of(c, |
| 521 | struct cppi41_dma_controller, controller); | 633 | struct cppi41_dma_controller, controller); |
| 522 | 634 | ||
| 635 | hrtimer_cancel(&controller->early_tx); | ||
| 523 | cppi41_dma_controller_stop(controller); | 636 | cppi41_dma_controller_stop(controller); |
| 524 | kfree(controller); | 637 | kfree(controller); |
| 525 | } | 638 | } |
| @@ -539,6 +652,9 @@ struct dma_controller *dma_controller_create(struct musb *musb, | |||
| 539 | if (!controller) | 652 | if (!controller) |
| 540 | goto kzalloc_fail; | 653 | goto kzalloc_fail; |
| 541 | 654 | ||
| 655 | hrtimer_init(&controller->early_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
| 656 | controller->early_tx.function = cppi41_recheck_tx_req; | ||
| 657 | INIT_LIST_HEAD(&controller->early_tx_list); | ||
| 542 | controller->musb = musb; | 658 | controller->musb = musb; |
| 543 | 659 | ||
| 544 | controller->controller.channel_alloc = cppi41_dma_channel_allocate; | 660 | controller->controller.channel_alloc = cppi41_dma_channel_allocate; |
