1e8d548d5SKuninori Morimoto /* 2e8d548d5SKuninori Morimoto * Renesas USB driver 3e8d548d5SKuninori Morimoto * 4e8d548d5SKuninori Morimoto * Copyright (C) 2011 Renesas Solutions Corp. 5e8d548d5SKuninori Morimoto * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 6e8d548d5SKuninori Morimoto * 7e8d548d5SKuninori Morimoto * This program is distributed in the hope that it will be useful, 8e8d548d5SKuninori Morimoto * but WITHOUT ANY WARRANTY; without even the implied warranty of 9e8d548d5SKuninori Morimoto * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10e8d548d5SKuninori Morimoto * GNU General Public License for more details. 11e8d548d5SKuninori Morimoto * 12e8d548d5SKuninori Morimoto * You should have received a copy of the GNU General Public License 13e8d548d5SKuninori Morimoto * along with this program; if not, write to the Free Software 14e8d548d5SKuninori Morimoto * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 15e8d548d5SKuninori Morimoto * 16e8d548d5SKuninori Morimoto */ 17e8d548d5SKuninori Morimoto #include <linux/delay.h> 18e8d548d5SKuninori Morimoto #include <linux/io.h> 19e8d548d5SKuninori Morimoto #include "./common.h" 20e8d548d5SKuninori Morimoto #include "./pipe.h" 21e8d548d5SKuninori Morimoto 22d3af90a5SKuninori Morimoto #define usbhsf_get_cfifo(p) (&((p)->fifo_info.cfifo)) 23*e73a9891SKuninori Morimoto #define usbhsf_get_d0fifo(p) (&((p)->fifo_info.d0fifo)) 24*e73a9891SKuninori Morimoto #define usbhsf_get_d1fifo(p) (&((p)->fifo_info.d1fifo)) 25d3af90a5SKuninori Morimoto 26d77e3f4eSKuninori Morimoto #define usbhsf_fifo_is_busy(f) ((f)->pipe) /* see usbhs_pipe_select_fifo */ 27d77e3f4eSKuninori Morimoto 28e8d548d5SKuninori Morimoto /* 294bd04811SKuninori Morimoto * packet info function 304bd04811SKuninori Morimoto */ 3197664a20SKuninori Morimoto static int usbhsf_null_handle(struct usbhs_pkt *pkt, int *is_done) 32dad67397SKuninori Morimoto { 33dad67397SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pkt->pipe); 34dad67397SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 35dad67397SKuninori Morimoto 36dad67397SKuninori Morimoto dev_err(dev, "null handler\n"); 37dad67397SKuninori Morimoto 38dad67397SKuninori Morimoto return -EINVAL; 39dad67397SKuninori Morimoto } 40dad67397SKuninori Morimoto 41dad67397SKuninori Morimoto static struct usbhs_pkt_handle usbhsf_null_handler = { 42dad67397SKuninori Morimoto .prepare = usbhsf_null_handle, 43dad67397SKuninori Morimoto .try_run = usbhsf_null_handle, 44dad67397SKuninori Morimoto }; 45dad67397SKuninori Morimoto 466acb95d4SKuninori Morimoto void usbhs_pkt_init(struct usbhs_pkt *pkt) 474bd04811SKuninori Morimoto { 48*e73a9891SKuninori Morimoto pkt->dma = DMA_ADDR_INVALID; 496acb95d4SKuninori Morimoto INIT_LIST_HEAD(&pkt->node); 506acb95d4SKuninori Morimoto } 516acb95d4SKuninori Morimoto 52659d4954SKuninori Morimoto void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, 53dad67397SKuninori Morimoto struct usbhs_pkt_handle *handler, 54659d4954SKuninori Morimoto void *buf, int len, int zero) 556acb95d4SKuninori Morimoto { 56dad67397SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 57dad67397SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 5897664a20SKuninori Morimoto unsigned long flags; 5997664a20SKuninori Morimoto 6097664a20SKuninori Morimoto /******************** spin lock ********************/ 6197664a20SKuninori Morimoto usbhs_lock(priv, flags); 62dad67397SKuninori Morimoto 63dad67397SKuninori Morimoto if (!handler) { 64dad67397SKuninori Morimoto dev_err(dev, "no handler function\n"); 65dad67397SKuninori Morimoto handler = &usbhsf_null_handler; 66dad67397SKuninori Morimoto } 67dad67397SKuninori Morimoto 686acb95d4SKuninori Morimoto list_del_init(&pkt->node); 696acb95d4SKuninori Morimoto list_add_tail(&pkt->node, &pipe->list); 706acb95d4SKuninori Morimoto 716acb95d4SKuninori Morimoto pkt->pipe = pipe; 72659d4954SKuninori Morimoto pkt->buf = buf; 73dad67397SKuninori Morimoto pkt->handler = handler; 74659d4954SKuninori Morimoto pkt->length = len; 75659d4954SKuninori Morimoto pkt->zero = zero; 76659d4954SKuninori Morimoto pkt->actual = 0; 7797664a20SKuninori Morimoto 7897664a20SKuninori Morimoto usbhs_unlock(priv, flags); 7997664a20SKuninori Morimoto /******************** spin unlock ******************/ 800432eed0SKuninori Morimoto 810432eed0SKuninori Morimoto usbhs_pkt_start(pipe); 826acb95d4SKuninori Morimoto } 836acb95d4SKuninori Morimoto 8497664a20SKuninori Morimoto static void __usbhsf_pkt_del(struct usbhs_pkt *pkt) 856acb95d4SKuninori Morimoto { 866acb95d4SKuninori Morimoto list_del_init(&pkt->node); 876acb95d4SKuninori Morimoto } 886acb95d4SKuninori Morimoto 8997664a20SKuninori Morimoto static struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe) 906acb95d4SKuninori Morimoto { 916acb95d4SKuninori Morimoto if (list_empty(&pipe->list)) 926acb95d4SKuninori Morimoto return NULL; 936acb95d4SKuninori Morimoto 946acb95d4SKuninori Morimoto return list_entry(pipe->list.next, struct usbhs_pkt, node); 956acb95d4SKuninori Morimoto } 966acb95d4SKuninori Morimoto 9797664a20SKuninori Morimoto struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) 9897664a20SKuninori Morimoto { 9997664a20SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 10097664a20SKuninori Morimoto unsigned long flags; 10197664a20SKuninori Morimoto 10297664a20SKuninori Morimoto /******************** spin lock ********************/ 10397664a20SKuninori Morimoto usbhs_lock(priv, flags); 10497664a20SKuninori Morimoto 10597664a20SKuninori Morimoto if (!pkt) 10697664a20SKuninori Morimoto pkt = __usbhsf_pkt_get(pipe); 10797664a20SKuninori Morimoto 10897664a20SKuninori Morimoto if (pkt) 10997664a20SKuninori Morimoto __usbhsf_pkt_del(pkt); 11097664a20SKuninori Morimoto 11197664a20SKuninori Morimoto usbhs_unlock(priv, flags); 11297664a20SKuninori Morimoto /******************** spin unlock ******************/ 11397664a20SKuninori Morimoto 11497664a20SKuninori Morimoto return pkt; 11597664a20SKuninori Morimoto } 11697664a20SKuninori Morimoto 11797664a20SKuninori Morimoto int __usbhs_pkt_handler(struct usbhs_pipe *pipe, int type) 11897664a20SKuninori Morimoto { 11997664a20SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 12097664a20SKuninori Morimoto struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv); 12197664a20SKuninori Morimoto struct usbhs_pkt *pkt; 12297664a20SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 12397664a20SKuninori Morimoto int (*func)(struct usbhs_pkt *pkt, int *is_done); 12497664a20SKuninori Morimoto unsigned long flags; 12597664a20SKuninori Morimoto int ret = 0; 12697664a20SKuninori Morimoto int is_done = 0; 12797664a20SKuninori Morimoto 12897664a20SKuninori Morimoto /******************** spin lock ********************/ 12997664a20SKuninori Morimoto usbhs_lock(priv, flags); 13097664a20SKuninori Morimoto 13197664a20SKuninori Morimoto pkt = __usbhsf_pkt_get(pipe); 13297664a20SKuninori Morimoto if (!pkt) 13397664a20SKuninori Morimoto goto __usbhs_pkt_handler_end; 13497664a20SKuninori Morimoto 13597664a20SKuninori Morimoto switch (type) { 13697664a20SKuninori Morimoto case USBHSF_PKT_PREPARE: 13797664a20SKuninori Morimoto func = pkt->handler->prepare; 13897664a20SKuninori Morimoto break; 13997664a20SKuninori Morimoto case USBHSF_PKT_TRY_RUN: 14097664a20SKuninori Morimoto func = pkt->handler->try_run; 14197664a20SKuninori Morimoto break; 142*e73a9891SKuninori Morimoto case USBHSF_PKT_DMA_DONE: 143*e73a9891SKuninori Morimoto func = pkt->handler->dma_done; 144*e73a9891SKuninori Morimoto break; 14597664a20SKuninori Morimoto default: 14697664a20SKuninori Morimoto dev_err(dev, "unknown pkt hander\n"); 14797664a20SKuninori Morimoto goto __usbhs_pkt_handler_end; 14897664a20SKuninori Morimoto } 14997664a20SKuninori Morimoto 15097664a20SKuninori Morimoto ret = func(pkt, &is_done); 15197664a20SKuninori Morimoto 15297664a20SKuninori Morimoto if (is_done) 15397664a20SKuninori Morimoto __usbhsf_pkt_del(pkt); 15497664a20SKuninori Morimoto 15597664a20SKuninori Morimoto __usbhs_pkt_handler_end: 15697664a20SKuninori Morimoto usbhs_unlock(priv, flags); 15797664a20SKuninori Morimoto /******************** spin unlock ******************/ 15897664a20SKuninori Morimoto 1590432eed0SKuninori Morimoto if (is_done) { 16097664a20SKuninori Morimoto info->done(pkt); 1610432eed0SKuninori Morimoto usbhs_pkt_start(pipe); 1620432eed0SKuninori Morimoto } 16397664a20SKuninori Morimoto 16497664a20SKuninori Morimoto return ret; 16597664a20SKuninori Morimoto } 16697664a20SKuninori Morimoto 1674bd04811SKuninori Morimoto /* 168659d4954SKuninori Morimoto * irq enable/disable function 169659d4954SKuninori Morimoto */ 170659d4954SKuninori Morimoto #define usbhsf_irq_empty_ctrl(p, e) usbhsf_irq_callback_ctrl(p, bempsts, e) 171659d4954SKuninori Morimoto #define usbhsf_irq_ready_ctrl(p, e) usbhsf_irq_callback_ctrl(p, brdysts, e) 172659d4954SKuninori Morimoto #define usbhsf_irq_callback_ctrl(pipe, status, enable) \ 173659d4954SKuninori Morimoto ({ \ 174659d4954SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); \ 175659d4954SKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); \ 176659d4954SKuninori Morimoto u16 status = (1 << usbhs_pipe_number(pipe)); \ 177659d4954SKuninori Morimoto if (!mod) \ 178659d4954SKuninori Morimoto return; \ 179659d4954SKuninori Morimoto if (enable) \ 180659d4954SKuninori Morimoto mod->irq_##status |= status; \ 181659d4954SKuninori Morimoto else \ 182659d4954SKuninori Morimoto mod->irq_##status &= ~status; \ 183659d4954SKuninori Morimoto usbhs_irq_callback_update(priv, mod); \ 184659d4954SKuninori Morimoto }) 185659d4954SKuninori Morimoto 186659d4954SKuninori Morimoto static void usbhsf_tx_irq_ctrl(struct usbhs_pipe *pipe, int enable) 187659d4954SKuninori Morimoto { 188659d4954SKuninori Morimoto /* 189659d4954SKuninori Morimoto * And DCP pipe can NOT use "ready interrupt" for "send" 190659d4954SKuninori Morimoto * it should use "empty" interrupt. 191659d4954SKuninori Morimoto * see 192659d4954SKuninori Morimoto * "Operation" - "Interrupt Function" - "BRDY Interrupt" 193659d4954SKuninori Morimoto * 194659d4954SKuninori Morimoto * on the other hand, normal pipe can use "ready interrupt" for "send" 195659d4954SKuninori Morimoto * even though it is single/double buffer 196659d4954SKuninori Morimoto */ 197659d4954SKuninori Morimoto if (usbhs_pipe_is_dcp(pipe)) 198659d4954SKuninori Morimoto usbhsf_irq_empty_ctrl(pipe, enable); 199659d4954SKuninori Morimoto else 200659d4954SKuninori Morimoto usbhsf_irq_ready_ctrl(pipe, enable); 201659d4954SKuninori Morimoto } 202659d4954SKuninori Morimoto 203659d4954SKuninori Morimoto static void usbhsf_rx_irq_ctrl(struct usbhs_pipe *pipe, int enable) 204659d4954SKuninori Morimoto { 205659d4954SKuninori Morimoto usbhsf_irq_ready_ctrl(pipe, enable); 206659d4954SKuninori Morimoto } 207659d4954SKuninori Morimoto 208659d4954SKuninori Morimoto /* 209e8d548d5SKuninori Morimoto * FIFO ctrl 210e8d548d5SKuninori Morimoto */ 211d3af90a5SKuninori Morimoto static void usbhsf_send_terminator(struct usbhs_pipe *pipe, 212d3af90a5SKuninori Morimoto struct usbhs_fifo *fifo) 213e8d548d5SKuninori Morimoto { 214e8d548d5SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 215e8d548d5SKuninori Morimoto 216d3af90a5SKuninori Morimoto usbhs_bset(priv, fifo->ctr, BVAL, BVAL); 217e8d548d5SKuninori Morimoto } 218e8d548d5SKuninori Morimoto 219d3af90a5SKuninori Morimoto static int usbhsf_fifo_barrier(struct usbhs_priv *priv, 220d3af90a5SKuninori Morimoto struct usbhs_fifo *fifo) 221e8d548d5SKuninori Morimoto { 222e8d548d5SKuninori Morimoto int timeout = 1024; 223e8d548d5SKuninori Morimoto 224e8d548d5SKuninori Morimoto do { 225e8d548d5SKuninori Morimoto /* The FIFO port is accessible */ 226d3af90a5SKuninori Morimoto if (usbhs_read(priv, fifo->ctr) & FRDY) 227e8d548d5SKuninori Morimoto return 0; 228e8d548d5SKuninori Morimoto 229e8d548d5SKuninori Morimoto udelay(10); 230e8d548d5SKuninori Morimoto } while (timeout--); 231e8d548d5SKuninori Morimoto 232e8d548d5SKuninori Morimoto return -EBUSY; 233e8d548d5SKuninori Morimoto } 234e8d548d5SKuninori Morimoto 235d3af90a5SKuninori Morimoto static void usbhsf_fifo_clear(struct usbhs_pipe *pipe, 236d3af90a5SKuninori Morimoto struct usbhs_fifo *fifo) 237e8d548d5SKuninori Morimoto { 238e8d548d5SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 239e8d548d5SKuninori Morimoto 240e8d548d5SKuninori Morimoto if (!usbhs_pipe_is_dcp(pipe)) 241d3af90a5SKuninori Morimoto usbhsf_fifo_barrier(priv, fifo); 242e8d548d5SKuninori Morimoto 243d3af90a5SKuninori Morimoto usbhs_write(priv, fifo->ctr, BCLR); 244e8d548d5SKuninori Morimoto } 245e8d548d5SKuninori Morimoto 246d3af90a5SKuninori Morimoto static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv, 247d3af90a5SKuninori Morimoto struct usbhs_fifo *fifo) 248e8d548d5SKuninori Morimoto { 249d3af90a5SKuninori Morimoto return usbhs_read(priv, fifo->ctr) & DTLN_MASK; 250e8d548d5SKuninori Morimoto } 251e8d548d5SKuninori Morimoto 252d77e3f4eSKuninori Morimoto static void usbhsf_fifo_unselect(struct usbhs_pipe *pipe, 253d77e3f4eSKuninori Morimoto struct usbhs_fifo *fifo) 254d77e3f4eSKuninori Morimoto { 255d77e3f4eSKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 256d77e3f4eSKuninori Morimoto 257d77e3f4eSKuninori Morimoto usbhs_pipe_select_fifo(pipe, NULL); 258d77e3f4eSKuninori Morimoto usbhs_write(priv, fifo->sel, 0); 259d77e3f4eSKuninori Morimoto } 260d77e3f4eSKuninori Morimoto 261d3af90a5SKuninori Morimoto static int usbhsf_fifo_select(struct usbhs_pipe *pipe, 262d3af90a5SKuninori Morimoto struct usbhs_fifo *fifo, 263d3af90a5SKuninori Morimoto int write) 264e8d548d5SKuninori Morimoto { 265e8d548d5SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 266e8d548d5SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 267e8d548d5SKuninori Morimoto int timeout = 1024; 268e8d548d5SKuninori Morimoto u16 mask = ((1 << 5) | 0xF); /* mask of ISEL | CURPIPE */ 269e8d548d5SKuninori Morimoto u16 base = usbhs_pipe_number(pipe); /* CURPIPE */ 270e8d548d5SKuninori Morimoto 271d77e3f4eSKuninori Morimoto if (usbhs_pipe_is_busy(pipe) || 272d77e3f4eSKuninori Morimoto usbhsf_fifo_is_busy(fifo)) 273d77e3f4eSKuninori Morimoto return -EBUSY; 274d77e3f4eSKuninori Morimoto 275e8d548d5SKuninori Morimoto if (usbhs_pipe_is_dcp(pipe)) 276e8d548d5SKuninori Morimoto base |= (1 == write) << 5; /* ISEL */ 277e8d548d5SKuninori Morimoto 278e8d548d5SKuninori Morimoto /* "base" will be used below */ 279d3af90a5SKuninori Morimoto usbhs_write(priv, fifo->sel, base | MBW_32); 280e8d548d5SKuninori Morimoto 281e8d548d5SKuninori Morimoto /* check ISEL and CURPIPE value */ 282e8d548d5SKuninori Morimoto while (timeout--) { 283d77e3f4eSKuninori Morimoto if (base == (mask & usbhs_read(priv, fifo->sel))) { 284d77e3f4eSKuninori Morimoto usbhs_pipe_select_fifo(pipe, fifo); 285e8d548d5SKuninori Morimoto return 0; 286d77e3f4eSKuninori Morimoto } 287e8d548d5SKuninori Morimoto udelay(10); 288e8d548d5SKuninori Morimoto } 289e8d548d5SKuninori Morimoto 290e8d548d5SKuninori Morimoto dev_err(dev, "fifo select error\n"); 291e8d548d5SKuninori Morimoto 292e8d548d5SKuninori Morimoto return -EIO; 293e8d548d5SKuninori Morimoto } 294e8d548d5SKuninori Morimoto 295e8d548d5SKuninori Morimoto /* 296e8d548d5SKuninori Morimoto * PIO fifo functions 297e8d548d5SKuninori Morimoto */ 2980cb7e61dSKuninori Morimoto static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done) 299e8d548d5SKuninori Morimoto { 3004bd04811SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 301e8d548d5SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 302659d4954SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 303d3af90a5SKuninori Morimoto struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */ 304d3af90a5SKuninori Morimoto void __iomem *addr = priv->base + fifo->port; 305659d4954SKuninori Morimoto u8 *buf; 306e8d548d5SKuninori Morimoto int maxp = usbhs_pipe_get_maxpacket(pipe); 307e8d548d5SKuninori Morimoto int total_len; 3084bd04811SKuninori Morimoto int i, ret, len; 30997664a20SKuninori Morimoto int is_short; 310e8d548d5SKuninori Morimoto 311d3af90a5SKuninori Morimoto ret = usbhsf_fifo_select(pipe, fifo, 1); 312e8d548d5SKuninori Morimoto if (ret < 0) 313d77e3f4eSKuninori Morimoto return 0; 314e8d548d5SKuninori Morimoto 315dad67397SKuninori Morimoto ret = usbhs_pipe_is_accessible(pipe); 316e8d548d5SKuninori Morimoto if (ret < 0) 317659d4954SKuninori Morimoto goto usbhs_fifo_write_busy; 318e8d548d5SKuninori Morimoto 319d3af90a5SKuninori Morimoto ret = usbhsf_fifo_barrier(priv, fifo); 320e8d548d5SKuninori Morimoto if (ret < 0) 321659d4954SKuninori Morimoto goto usbhs_fifo_write_busy; 322e8d548d5SKuninori Morimoto 323659d4954SKuninori Morimoto buf = pkt->buf + pkt->actual; 324659d4954SKuninori Morimoto len = pkt->length - pkt->actual; 325659d4954SKuninori Morimoto len = min(len, maxp); 326e8d548d5SKuninori Morimoto total_len = len; 327659d4954SKuninori Morimoto is_short = total_len < maxp; 328e8d548d5SKuninori Morimoto 329e8d548d5SKuninori Morimoto /* 330e8d548d5SKuninori Morimoto * FIXME 331e8d548d5SKuninori Morimoto * 332e8d548d5SKuninori Morimoto * 32-bit access only 333e8d548d5SKuninori Morimoto */ 334659d4954SKuninori Morimoto if (len >= 4 && !((unsigned long)buf & 0x03)) { 335e8d548d5SKuninori Morimoto iowrite32_rep(addr, buf, len / 4); 336e8d548d5SKuninori Morimoto len %= 4; 337e8d548d5SKuninori Morimoto buf += total_len - len; 338e8d548d5SKuninori Morimoto } 339e8d548d5SKuninori Morimoto 340e8d548d5SKuninori Morimoto /* the rest operation */ 341e8d548d5SKuninori Morimoto for (i = 0; i < len; i++) 342e8d548d5SKuninori Morimoto iowrite8(buf[i], addr + (0x03 - (i & 0x03))); 343e8d548d5SKuninori Morimoto 344659d4954SKuninori Morimoto /* 345659d4954SKuninori Morimoto * variable update 346659d4954SKuninori Morimoto */ 347659d4954SKuninori Morimoto pkt->actual += total_len; 348659d4954SKuninori Morimoto 349659d4954SKuninori Morimoto if (pkt->actual < pkt->length) 35097664a20SKuninori Morimoto *is_done = 0; /* there are remainder data */ 351659d4954SKuninori Morimoto else if (is_short) 35297664a20SKuninori Morimoto *is_done = 1; /* short packet */ 353659d4954SKuninori Morimoto else 35497664a20SKuninori Morimoto *is_done = !pkt->zero; /* send zero packet ? */ 355659d4954SKuninori Morimoto 356659d4954SKuninori Morimoto /* 357659d4954SKuninori Morimoto * pipe/irq handling 358659d4954SKuninori Morimoto */ 359659d4954SKuninori Morimoto if (is_short) 360d3af90a5SKuninori Morimoto usbhsf_send_terminator(pipe, fifo); 361e8d548d5SKuninori Morimoto 36297664a20SKuninori Morimoto usbhsf_tx_irq_ctrl(pipe, !*is_done); 3634bd04811SKuninori Morimoto usbhs_pipe_enable(pipe); 3644bd04811SKuninori Morimoto 365659d4954SKuninori Morimoto dev_dbg(dev, " send %d (%d/ %d/ %d/ %d)\n", 366659d4954SKuninori Morimoto usbhs_pipe_number(pipe), 36797664a20SKuninori Morimoto pkt->length, pkt->actual, *is_done, pkt->zero); 368659d4954SKuninori Morimoto 369659d4954SKuninori Morimoto /* 370659d4954SKuninori Morimoto * Transmission end 371659d4954SKuninori Morimoto */ 37297664a20SKuninori Morimoto if (*is_done) { 373659d4954SKuninori Morimoto if (usbhs_pipe_is_dcp(pipe)) 374659d4954SKuninori Morimoto usbhs_dcp_control_transfer_done(pipe); 3754bd04811SKuninori Morimoto } 3764bd04811SKuninori Morimoto 377d77e3f4eSKuninori Morimoto usbhsf_fifo_unselect(pipe, fifo); 378d77e3f4eSKuninori Morimoto 3794bd04811SKuninori Morimoto return 0; 380659d4954SKuninori Morimoto 381659d4954SKuninori Morimoto usbhs_fifo_write_busy: 382d77e3f4eSKuninori Morimoto usbhsf_fifo_unselect(pipe, fifo); 383d77e3f4eSKuninori Morimoto 384659d4954SKuninori Morimoto /* 385659d4954SKuninori Morimoto * pipe is busy. 386659d4954SKuninori Morimoto * retry in interrupt 387659d4954SKuninori Morimoto */ 388659d4954SKuninori Morimoto usbhsf_tx_irq_ctrl(pipe, 1); 389659d4954SKuninori Morimoto 390659d4954SKuninori Morimoto return ret; 391e8d548d5SKuninori Morimoto } 392e8d548d5SKuninori Morimoto 3930cb7e61dSKuninori Morimoto struct usbhs_pkt_handle usbhs_fifo_pio_push_handler = { 3940cb7e61dSKuninori Morimoto .prepare = usbhsf_pio_try_push, 3950cb7e61dSKuninori Morimoto .try_run = usbhsf_pio_try_push, 396dad67397SKuninori Morimoto }; 397dad67397SKuninori Morimoto 39897664a20SKuninori Morimoto static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) 399e8d548d5SKuninori Morimoto { 400dad67397SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 401d77e3f4eSKuninori Morimoto 402d77e3f4eSKuninori Morimoto if (usbhs_pipe_is_busy(pipe)) 403d77e3f4eSKuninori Morimoto return 0; 404e8d548d5SKuninori Morimoto 405e8d548d5SKuninori Morimoto /* 406d77e3f4eSKuninori Morimoto * pipe enable to prepare packet receive 407e8d548d5SKuninori Morimoto */ 408e8d548d5SKuninori Morimoto 409e8d548d5SKuninori Morimoto usbhs_pipe_enable(pipe); 410659d4954SKuninori Morimoto usbhsf_rx_irq_ctrl(pipe, 1); 411e8d548d5SKuninori Morimoto 412d3af90a5SKuninori Morimoto return 0; 413e8d548d5SKuninori Morimoto } 414e8d548d5SKuninori Morimoto 4150cb7e61dSKuninori Morimoto static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done) 416e8d548d5SKuninori Morimoto { 4174bd04811SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 418e8d548d5SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 419659d4954SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 420d3af90a5SKuninori Morimoto struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */ 421d3af90a5SKuninori Morimoto void __iomem *addr = priv->base + fifo->port; 422659d4954SKuninori Morimoto u8 *buf; 423659d4954SKuninori Morimoto u32 data = 0; 424659d4954SKuninori Morimoto int maxp = usbhs_pipe_get_maxpacket(pipe); 4254bd04811SKuninori Morimoto int rcv_len, len; 426e8d548d5SKuninori Morimoto int i, ret; 4274bd04811SKuninori Morimoto int total_len = 0; 428e8d548d5SKuninori Morimoto 429d3af90a5SKuninori Morimoto ret = usbhsf_fifo_select(pipe, fifo, 0); 430e8d548d5SKuninori Morimoto if (ret < 0) 431d77e3f4eSKuninori Morimoto return 0; 432e8d548d5SKuninori Morimoto 433d3af90a5SKuninori Morimoto ret = usbhsf_fifo_barrier(priv, fifo); 434e8d548d5SKuninori Morimoto if (ret < 0) 435d77e3f4eSKuninori Morimoto goto usbhs_fifo_read_busy; 436e8d548d5SKuninori Morimoto 437d3af90a5SKuninori Morimoto rcv_len = usbhsf_fifo_rcv_len(priv, fifo); 438e8d548d5SKuninori Morimoto 439659d4954SKuninori Morimoto buf = pkt->buf + pkt->actual; 440659d4954SKuninori Morimoto len = pkt->length - pkt->actual; 441659d4954SKuninori Morimoto len = min(len, rcv_len); 442659d4954SKuninori Morimoto total_len = len; 443659d4954SKuninori Morimoto 444e8d548d5SKuninori Morimoto /* 445e8d548d5SKuninori Morimoto * Buffer clear if Zero-Length packet 446e8d548d5SKuninori Morimoto * 447e8d548d5SKuninori Morimoto * see 448e8d548d5SKuninori Morimoto * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function" 449e8d548d5SKuninori Morimoto */ 450e8d548d5SKuninori Morimoto if (0 == rcv_len) { 451d3af90a5SKuninori Morimoto usbhsf_fifo_clear(pipe, fifo); 4524bd04811SKuninori Morimoto goto usbhs_fifo_read_end; 453e8d548d5SKuninori Morimoto } 454e8d548d5SKuninori Morimoto 455e8d548d5SKuninori Morimoto /* 456e8d548d5SKuninori Morimoto * FIXME 457e8d548d5SKuninori Morimoto * 458e8d548d5SKuninori Morimoto * 32-bit access only 459e8d548d5SKuninori Morimoto */ 460659d4954SKuninori Morimoto if (len >= 4 && !((unsigned long)buf & 0x03)) { 461e8d548d5SKuninori Morimoto ioread32_rep(addr, buf, len / 4); 462e8d548d5SKuninori Morimoto len %= 4; 463659d4954SKuninori Morimoto buf += total_len - len; 464e8d548d5SKuninori Morimoto } 465e8d548d5SKuninori Morimoto 466e8d548d5SKuninori Morimoto /* the rest operation */ 467e8d548d5SKuninori Morimoto for (i = 0; i < len; i++) { 468e8d548d5SKuninori Morimoto if (!(i & 0x03)) 469e8d548d5SKuninori Morimoto data = ioread32(addr); 470e8d548d5SKuninori Morimoto 471e8d548d5SKuninori Morimoto buf[i] = (data >> ((i & 0x03) * 8)) & 0xff; 472e8d548d5SKuninori Morimoto } 473e8d548d5SKuninori Morimoto 474659d4954SKuninori Morimoto pkt->actual += total_len; 475659d4954SKuninori Morimoto 4764bd04811SKuninori Morimoto usbhs_fifo_read_end: 477659d4954SKuninori Morimoto if ((pkt->actual == pkt->length) || /* receive all data */ 47897664a20SKuninori Morimoto (total_len < maxp)) { /* short packet */ 47997664a20SKuninori Morimoto *is_done = 1; 48097664a20SKuninori Morimoto usbhsf_rx_irq_ctrl(pipe, 0); 48197664a20SKuninori Morimoto usbhs_pipe_disable(pipe); 48297664a20SKuninori Morimoto } 483659d4954SKuninori Morimoto 484659d4954SKuninori Morimoto dev_dbg(dev, " recv %d (%d/ %d/ %d/ %d)\n", 485659d4954SKuninori Morimoto usbhs_pipe_number(pipe), 48697664a20SKuninori Morimoto pkt->length, pkt->actual, *is_done, pkt->zero); 4874bd04811SKuninori Morimoto 488d77e3f4eSKuninori Morimoto usbhs_fifo_read_busy: 489d77e3f4eSKuninori Morimoto usbhsf_fifo_unselect(pipe, fifo); 490d77e3f4eSKuninori Morimoto 491d77e3f4eSKuninori Morimoto return ret; 492e8d548d5SKuninori Morimoto } 493dad67397SKuninori Morimoto 4940cb7e61dSKuninori Morimoto struct usbhs_pkt_handle usbhs_fifo_pio_pop_handler = { 495dad67397SKuninori Morimoto .prepare = usbhsf_prepare_pop, 4960cb7e61dSKuninori Morimoto .try_run = usbhsf_pio_try_pop, 497dad67397SKuninori Morimoto }; 498dad67397SKuninori Morimoto 499dad67397SKuninori Morimoto /* 500dad67397SKuninori Morimoto * handler function 501dad67397SKuninori Morimoto */ 50297664a20SKuninori Morimoto static int usbhsf_ctrl_stage_end(struct usbhs_pkt *pkt, int *is_done) 503dad67397SKuninori Morimoto { 50497664a20SKuninori Morimoto usbhs_dcp_control_transfer_done(pkt->pipe); 505dad67397SKuninori Morimoto 50697664a20SKuninori Morimoto *is_done = 1; 507dad67397SKuninori Morimoto 508dad67397SKuninori Morimoto return 0; 509dad67397SKuninori Morimoto } 510dad67397SKuninori Morimoto 511dad67397SKuninori Morimoto struct usbhs_pkt_handle usbhs_ctrl_stage_end_handler = { 512dad67397SKuninori Morimoto .prepare = usbhsf_ctrl_stage_end, 513dad67397SKuninori Morimoto .try_run = usbhsf_ctrl_stage_end, 514dad67397SKuninori Morimoto }; 515dad67397SKuninori Morimoto 516dad67397SKuninori Morimoto /* 517*e73a9891SKuninori Morimoto * DMA fifo functions 518*e73a9891SKuninori Morimoto */ 519*e73a9891SKuninori Morimoto static struct dma_chan *usbhsf_dma_chan_get(struct usbhs_fifo *fifo, 520*e73a9891SKuninori Morimoto struct usbhs_pkt *pkt) 521*e73a9891SKuninori Morimoto { 522*e73a9891SKuninori Morimoto if (&usbhs_fifo_dma_push_handler == pkt->handler) 523*e73a9891SKuninori Morimoto return fifo->tx_chan; 524*e73a9891SKuninori Morimoto 525*e73a9891SKuninori Morimoto if (&usbhs_fifo_dma_pop_handler == pkt->handler) 526*e73a9891SKuninori Morimoto return fifo->rx_chan; 527*e73a9891SKuninori Morimoto 528*e73a9891SKuninori Morimoto return NULL; 529*e73a9891SKuninori Morimoto } 530*e73a9891SKuninori Morimoto 531*e73a9891SKuninori Morimoto static struct usbhs_fifo *usbhsf_get_dma_fifo(struct usbhs_priv *priv, 532*e73a9891SKuninori Morimoto struct usbhs_pkt *pkt) 533*e73a9891SKuninori Morimoto { 534*e73a9891SKuninori Morimoto struct usbhs_fifo *fifo; 535*e73a9891SKuninori Morimoto 536*e73a9891SKuninori Morimoto /* DMA :: D0FIFO */ 537*e73a9891SKuninori Morimoto fifo = usbhsf_get_d0fifo(priv); 538*e73a9891SKuninori Morimoto if (usbhsf_dma_chan_get(fifo, pkt) && 539*e73a9891SKuninori Morimoto !usbhsf_fifo_is_busy(fifo)) 540*e73a9891SKuninori Morimoto return fifo; 541*e73a9891SKuninori Morimoto 542*e73a9891SKuninori Morimoto /* DMA :: D1FIFO */ 543*e73a9891SKuninori Morimoto fifo = usbhsf_get_d1fifo(priv); 544*e73a9891SKuninori Morimoto if (usbhsf_dma_chan_get(fifo, pkt) && 545*e73a9891SKuninori Morimoto !usbhsf_fifo_is_busy(fifo)) 546*e73a9891SKuninori Morimoto return fifo; 547*e73a9891SKuninori Morimoto 548*e73a9891SKuninori Morimoto return NULL; 549*e73a9891SKuninori Morimoto } 550*e73a9891SKuninori Morimoto 551*e73a9891SKuninori Morimoto #define usbhsf_dma_start(p, f) __usbhsf_dma_ctrl(p, f, DREQE) 552*e73a9891SKuninori Morimoto #define usbhsf_dma_stop(p, f) __usbhsf_dma_ctrl(p, f, 0) 553*e73a9891SKuninori Morimoto static void __usbhsf_dma_ctrl(struct usbhs_pipe *pipe, 554*e73a9891SKuninori Morimoto struct usbhs_fifo *fifo, 555*e73a9891SKuninori Morimoto u16 dreqe) 556*e73a9891SKuninori Morimoto { 557*e73a9891SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 558*e73a9891SKuninori Morimoto 559*e73a9891SKuninori Morimoto usbhs_bset(priv, fifo->sel, DREQE, dreqe); 560*e73a9891SKuninori Morimoto } 561*e73a9891SKuninori Morimoto 562*e73a9891SKuninori Morimoto #define usbhsf_dma_map(p) __usbhsf_dma_map_ctrl(p, 1) 563*e73a9891SKuninori Morimoto #define usbhsf_dma_unmap(p) __usbhsf_dma_map_ctrl(p, 0) 564*e73a9891SKuninori Morimoto static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map) 565*e73a9891SKuninori Morimoto { 566*e73a9891SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 567*e73a9891SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 568*e73a9891SKuninori Morimoto struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv); 569*e73a9891SKuninori Morimoto 570*e73a9891SKuninori Morimoto return info->dma_map_ctrl(pkt, map); 571*e73a9891SKuninori Morimoto } 572*e73a9891SKuninori Morimoto 573*e73a9891SKuninori Morimoto static void usbhsf_dma_complete(void *arg); 574*e73a9891SKuninori Morimoto static void usbhsf_dma_prepare_tasklet(unsigned long data) 575*e73a9891SKuninori Morimoto { 576*e73a9891SKuninori Morimoto struct usbhs_pkt *pkt = (struct usbhs_pkt *)data; 577*e73a9891SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 578*e73a9891SKuninori Morimoto struct usbhs_fifo *fifo = usbhs_pipe_to_fifo(pipe); 579*e73a9891SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 580*e73a9891SKuninori Morimoto struct scatterlist sg; 581*e73a9891SKuninori Morimoto struct dma_async_tx_descriptor *desc; 582*e73a9891SKuninori Morimoto struct dma_chan *chan = usbhsf_dma_chan_get(fifo, pkt); 583*e73a9891SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 584*e73a9891SKuninori Morimoto enum dma_data_direction dir; 585*e73a9891SKuninori Morimoto dma_cookie_t cookie; 586*e73a9891SKuninori Morimoto 587*e73a9891SKuninori Morimoto dir = usbhs_pipe_is_dir_in(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; 588*e73a9891SKuninori Morimoto 589*e73a9891SKuninori Morimoto sg_init_table(&sg, 1); 590*e73a9891SKuninori Morimoto sg_set_page(&sg, virt_to_page(pkt->dma), 591*e73a9891SKuninori Morimoto pkt->length, offset_in_page(pkt->dma)); 592*e73a9891SKuninori Morimoto sg_dma_address(&sg) = pkt->dma + pkt->actual; 593*e73a9891SKuninori Morimoto sg_dma_len(&sg) = pkt->trans; 594*e73a9891SKuninori Morimoto 595*e73a9891SKuninori Morimoto desc = chan->device->device_prep_slave_sg(chan, &sg, 1, dir, 596*e73a9891SKuninori Morimoto DMA_PREP_INTERRUPT | 597*e73a9891SKuninori Morimoto DMA_CTRL_ACK); 598*e73a9891SKuninori Morimoto if (!desc) 599*e73a9891SKuninori Morimoto return; 600*e73a9891SKuninori Morimoto 601*e73a9891SKuninori Morimoto desc->callback = usbhsf_dma_complete; 602*e73a9891SKuninori Morimoto desc->callback_param = pipe; 603*e73a9891SKuninori Morimoto 604*e73a9891SKuninori Morimoto cookie = desc->tx_submit(desc); 605*e73a9891SKuninori Morimoto if (cookie < 0) { 606*e73a9891SKuninori Morimoto dev_err(dev, "Failed to submit dma descriptor\n"); 607*e73a9891SKuninori Morimoto return; 608*e73a9891SKuninori Morimoto } 609*e73a9891SKuninori Morimoto 610*e73a9891SKuninori Morimoto dev_dbg(dev, " %s %d (%d/ %d)\n", 611*e73a9891SKuninori Morimoto fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); 612*e73a9891SKuninori Morimoto 613*e73a9891SKuninori Morimoto usbhsf_dma_start(pipe, fifo); 614*e73a9891SKuninori Morimoto dma_async_issue_pending(chan); 615*e73a9891SKuninori Morimoto } 616*e73a9891SKuninori Morimoto 617*e73a9891SKuninori Morimoto static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done) 618*e73a9891SKuninori Morimoto { 619*e73a9891SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 620*e73a9891SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 621*e73a9891SKuninori Morimoto struct usbhs_fifo *fifo; 622*e73a9891SKuninori Morimoto int len = pkt->length - pkt->actual; 623*e73a9891SKuninori Morimoto int ret; 624*e73a9891SKuninori Morimoto 625*e73a9891SKuninori Morimoto if (usbhs_pipe_is_busy(pipe)) 626*e73a9891SKuninori Morimoto return 0; 627*e73a9891SKuninori Morimoto 628*e73a9891SKuninori Morimoto /* use PIO if packet is less than pio_dma_border or pipe is DCP */ 629*e73a9891SKuninori Morimoto if ((len < usbhs_get_dparam(priv, pio_dma_border)) || 630*e73a9891SKuninori Morimoto usbhs_pipe_is_dcp(pipe)) 631*e73a9891SKuninori Morimoto goto usbhsf_pio_prepare_push; 632*e73a9891SKuninori Morimoto 633*e73a9891SKuninori Morimoto if (len % 4) /* 32bit alignment */ 634*e73a9891SKuninori Morimoto goto usbhsf_pio_prepare_push; 635*e73a9891SKuninori Morimoto 636*e73a9891SKuninori Morimoto /* get enable DMA fifo */ 637*e73a9891SKuninori Morimoto fifo = usbhsf_get_dma_fifo(priv, pkt); 638*e73a9891SKuninori Morimoto if (!fifo) 639*e73a9891SKuninori Morimoto goto usbhsf_pio_prepare_push; 640*e73a9891SKuninori Morimoto 641*e73a9891SKuninori Morimoto if (usbhsf_dma_map(pkt) < 0) 642*e73a9891SKuninori Morimoto goto usbhsf_pio_prepare_push; 643*e73a9891SKuninori Morimoto 644*e73a9891SKuninori Morimoto ret = usbhsf_fifo_select(pipe, fifo, 0); 645*e73a9891SKuninori Morimoto if (ret < 0) 646*e73a9891SKuninori Morimoto goto usbhsf_pio_prepare_push_unmap; 647*e73a9891SKuninori Morimoto 648*e73a9891SKuninori Morimoto pkt->trans = len; 649*e73a9891SKuninori Morimoto 650*e73a9891SKuninori Morimoto tasklet_init(&fifo->tasklet, 651*e73a9891SKuninori Morimoto usbhsf_dma_prepare_tasklet, 652*e73a9891SKuninori Morimoto (unsigned long)pkt); 653*e73a9891SKuninori Morimoto 654*e73a9891SKuninori Morimoto tasklet_schedule(&fifo->tasklet); 655*e73a9891SKuninori Morimoto 656*e73a9891SKuninori Morimoto return 0; 657*e73a9891SKuninori Morimoto 658*e73a9891SKuninori Morimoto usbhsf_pio_prepare_push_unmap: 659*e73a9891SKuninori Morimoto usbhsf_dma_unmap(pkt); 660*e73a9891SKuninori Morimoto usbhsf_pio_prepare_push: 661*e73a9891SKuninori Morimoto /* 662*e73a9891SKuninori Morimoto * change handler to PIO 663*e73a9891SKuninori Morimoto */ 664*e73a9891SKuninori Morimoto pkt->handler = &usbhs_fifo_pio_push_handler; 665*e73a9891SKuninori Morimoto 666*e73a9891SKuninori Morimoto return pkt->handler->prepare(pkt, is_done); 667*e73a9891SKuninori Morimoto } 668*e73a9891SKuninori Morimoto 669*e73a9891SKuninori Morimoto static int usbhsf_dma_push_done(struct usbhs_pkt *pkt, int *is_done) 670*e73a9891SKuninori Morimoto { 671*e73a9891SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 672*e73a9891SKuninori Morimoto 673*e73a9891SKuninori Morimoto pkt->actual = pkt->trans; 674*e73a9891SKuninori Morimoto 675*e73a9891SKuninori Morimoto *is_done = !pkt->zero; /* send zero packet ? */ 676*e73a9891SKuninori Morimoto 677*e73a9891SKuninori Morimoto usbhsf_dma_stop(pipe, pipe->fifo); 678*e73a9891SKuninori Morimoto usbhsf_dma_unmap(pkt); 679*e73a9891SKuninori Morimoto usbhsf_fifo_unselect(pipe, pipe->fifo); 680*e73a9891SKuninori Morimoto 681*e73a9891SKuninori Morimoto return 0; 682*e73a9891SKuninori Morimoto } 683*e73a9891SKuninori Morimoto 684*e73a9891SKuninori Morimoto struct usbhs_pkt_handle usbhs_fifo_dma_push_handler = { 685*e73a9891SKuninori Morimoto .prepare = usbhsf_dma_prepare_push, 686*e73a9891SKuninori Morimoto .dma_done = usbhsf_dma_push_done, 687*e73a9891SKuninori Morimoto }; 688*e73a9891SKuninori Morimoto 689*e73a9891SKuninori Morimoto static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done) 690*e73a9891SKuninori Morimoto { 691*e73a9891SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 692*e73a9891SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 693*e73a9891SKuninori Morimoto struct usbhs_fifo *fifo; 694*e73a9891SKuninori Morimoto int len, ret; 695*e73a9891SKuninori Morimoto 696*e73a9891SKuninori Morimoto if (usbhs_pipe_is_busy(pipe)) 697*e73a9891SKuninori Morimoto return 0; 698*e73a9891SKuninori Morimoto 699*e73a9891SKuninori Morimoto if (usbhs_pipe_is_dcp(pipe)) 700*e73a9891SKuninori Morimoto goto usbhsf_pio_prepare_pop; 701*e73a9891SKuninori Morimoto 702*e73a9891SKuninori Morimoto /* get enable DMA fifo */ 703*e73a9891SKuninori Morimoto fifo = usbhsf_get_dma_fifo(priv, pkt); 704*e73a9891SKuninori Morimoto if (!fifo) 705*e73a9891SKuninori Morimoto goto usbhsf_pio_prepare_pop; 706*e73a9891SKuninori Morimoto 707*e73a9891SKuninori Morimoto ret = usbhsf_fifo_select(pipe, fifo, 0); 708*e73a9891SKuninori Morimoto if (ret < 0) 709*e73a9891SKuninori Morimoto goto usbhsf_pio_prepare_pop; 710*e73a9891SKuninori Morimoto 711*e73a9891SKuninori Morimoto /* use PIO if packet is less than pio_dma_border */ 712*e73a9891SKuninori Morimoto len = usbhsf_fifo_rcv_len(priv, fifo); 713*e73a9891SKuninori Morimoto len = min(pkt->length - pkt->actual, len); 714*e73a9891SKuninori Morimoto if (len % 4) /* 32bit alignment */ 715*e73a9891SKuninori Morimoto goto usbhsf_pio_prepare_pop_unselect; 716*e73a9891SKuninori Morimoto 717*e73a9891SKuninori Morimoto if (len < usbhs_get_dparam(priv, pio_dma_border)) 718*e73a9891SKuninori Morimoto goto usbhsf_pio_prepare_pop_unselect; 719*e73a9891SKuninori Morimoto 720*e73a9891SKuninori Morimoto ret = usbhsf_fifo_barrier(priv, fifo); 721*e73a9891SKuninori Morimoto if (ret < 0) 722*e73a9891SKuninori Morimoto goto usbhsf_pio_prepare_pop_unselect; 723*e73a9891SKuninori Morimoto 724*e73a9891SKuninori Morimoto if (usbhsf_dma_map(pkt) < 0) 725*e73a9891SKuninori Morimoto goto usbhsf_pio_prepare_pop_unselect; 726*e73a9891SKuninori Morimoto 727*e73a9891SKuninori Morimoto /* DMA */ 728*e73a9891SKuninori Morimoto 729*e73a9891SKuninori Morimoto /* 730*e73a9891SKuninori Morimoto * usbhs_fifo_dma_pop_handler :: prepare 731*e73a9891SKuninori Morimoto * enabled irq to come here. 732*e73a9891SKuninori Morimoto * but it is no longer needed for DMA. disable it. 733*e73a9891SKuninori Morimoto */ 734*e73a9891SKuninori Morimoto usbhsf_rx_irq_ctrl(pipe, 0); 735*e73a9891SKuninori Morimoto 736*e73a9891SKuninori Morimoto pkt->trans = len; 737*e73a9891SKuninori Morimoto 738*e73a9891SKuninori Morimoto tasklet_init(&fifo->tasklet, 739*e73a9891SKuninori Morimoto usbhsf_dma_prepare_tasklet, 740*e73a9891SKuninori Morimoto (unsigned long)pkt); 741*e73a9891SKuninori Morimoto 742*e73a9891SKuninori Morimoto tasklet_schedule(&fifo->tasklet); 743*e73a9891SKuninori Morimoto 744*e73a9891SKuninori Morimoto return 0; 745*e73a9891SKuninori Morimoto 746*e73a9891SKuninori Morimoto usbhsf_pio_prepare_pop_unselect: 747*e73a9891SKuninori Morimoto usbhsf_fifo_unselect(pipe, fifo); 748*e73a9891SKuninori Morimoto usbhsf_pio_prepare_pop: 749*e73a9891SKuninori Morimoto 750*e73a9891SKuninori Morimoto /* 751*e73a9891SKuninori Morimoto * change handler to PIO 752*e73a9891SKuninori Morimoto */ 753*e73a9891SKuninori Morimoto pkt->handler = &usbhs_fifo_pio_pop_handler; 754*e73a9891SKuninori Morimoto 755*e73a9891SKuninori Morimoto return pkt->handler->try_run(pkt, is_done); 756*e73a9891SKuninori Morimoto } 757*e73a9891SKuninori Morimoto 758*e73a9891SKuninori Morimoto static int usbhsf_dma_pop_done(struct usbhs_pkt *pkt, int *is_done) 759*e73a9891SKuninori Morimoto { 760*e73a9891SKuninori Morimoto struct usbhs_pipe *pipe = pkt->pipe; 761*e73a9891SKuninori Morimoto int maxp = usbhs_pipe_get_maxpacket(pipe); 762*e73a9891SKuninori Morimoto 763*e73a9891SKuninori Morimoto usbhsf_dma_stop(pipe, pipe->fifo); 764*e73a9891SKuninori Morimoto usbhsf_dma_unmap(pkt); 765*e73a9891SKuninori Morimoto usbhsf_fifo_unselect(pipe, pipe->fifo); 766*e73a9891SKuninori Morimoto 767*e73a9891SKuninori Morimoto pkt->actual += pkt->trans; 768*e73a9891SKuninori Morimoto 769*e73a9891SKuninori Morimoto if ((pkt->actual == pkt->length) || /* receive all data */ 770*e73a9891SKuninori Morimoto (pkt->trans < maxp)) { /* short packet */ 771*e73a9891SKuninori Morimoto *is_done = 1; 772*e73a9891SKuninori Morimoto } else { 773*e73a9891SKuninori Morimoto /* re-enable */ 774*e73a9891SKuninori Morimoto usbhsf_prepare_pop(pkt, is_done); 775*e73a9891SKuninori Morimoto } 776*e73a9891SKuninori Morimoto 777*e73a9891SKuninori Morimoto return 0; 778*e73a9891SKuninori Morimoto } 779*e73a9891SKuninori Morimoto 780*e73a9891SKuninori Morimoto struct usbhs_pkt_handle usbhs_fifo_dma_pop_handler = { 781*e73a9891SKuninori Morimoto .prepare = usbhsf_prepare_pop, 782*e73a9891SKuninori Morimoto .try_run = usbhsf_dma_try_pop, 783*e73a9891SKuninori Morimoto .dma_done = usbhsf_dma_pop_done 784*e73a9891SKuninori Morimoto }; 785*e73a9891SKuninori Morimoto 786*e73a9891SKuninori Morimoto /* 787*e73a9891SKuninori Morimoto * DMA setting 788*e73a9891SKuninori Morimoto */ 789*e73a9891SKuninori Morimoto static bool usbhsf_dma_filter(struct dma_chan *chan, void *param) 790*e73a9891SKuninori Morimoto { 791*e73a9891SKuninori Morimoto struct sh_dmae_slave *slave = param; 792*e73a9891SKuninori Morimoto 793*e73a9891SKuninori Morimoto /* 794*e73a9891SKuninori Morimoto * FIXME 795*e73a9891SKuninori Morimoto * 796*e73a9891SKuninori Morimoto * usbhs doesn't recognize id = 0 as valid DMA 797*e73a9891SKuninori Morimoto */ 798*e73a9891SKuninori Morimoto if (0 == slave->slave_id) 799*e73a9891SKuninori Morimoto return false; 800*e73a9891SKuninori Morimoto 801*e73a9891SKuninori Morimoto chan->private = slave; 802*e73a9891SKuninori Morimoto 803*e73a9891SKuninori Morimoto return true; 804*e73a9891SKuninori Morimoto } 805*e73a9891SKuninori Morimoto 806*e73a9891SKuninori Morimoto static void usbhsf_dma_quit(struct usbhs_priv *priv, struct usbhs_fifo *fifo) 807*e73a9891SKuninori Morimoto { 808*e73a9891SKuninori Morimoto if (fifo->tx_chan) 809*e73a9891SKuninori Morimoto dma_release_channel(fifo->tx_chan); 810*e73a9891SKuninori Morimoto if (fifo->rx_chan) 811*e73a9891SKuninori Morimoto dma_release_channel(fifo->rx_chan); 812*e73a9891SKuninori Morimoto 813*e73a9891SKuninori Morimoto fifo->tx_chan = NULL; 814*e73a9891SKuninori Morimoto fifo->rx_chan = NULL; 815*e73a9891SKuninori Morimoto } 816*e73a9891SKuninori Morimoto 817*e73a9891SKuninori Morimoto static void usbhsf_dma_init(struct usbhs_priv *priv, 818*e73a9891SKuninori Morimoto struct usbhs_fifo *fifo) 819*e73a9891SKuninori Morimoto { 820*e73a9891SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 821*e73a9891SKuninori Morimoto dma_cap_mask_t mask; 822*e73a9891SKuninori Morimoto 823*e73a9891SKuninori Morimoto dma_cap_zero(mask); 824*e73a9891SKuninori Morimoto dma_cap_set(DMA_SLAVE, mask); 825*e73a9891SKuninori Morimoto fifo->tx_chan = dma_request_channel(mask, usbhsf_dma_filter, 826*e73a9891SKuninori Morimoto &fifo->tx_slave); 827*e73a9891SKuninori Morimoto 828*e73a9891SKuninori Morimoto dma_cap_zero(mask); 829*e73a9891SKuninori Morimoto dma_cap_set(DMA_SLAVE, mask); 830*e73a9891SKuninori Morimoto fifo->rx_chan = dma_request_channel(mask, usbhsf_dma_filter, 831*e73a9891SKuninori Morimoto &fifo->rx_slave); 832*e73a9891SKuninori Morimoto 833*e73a9891SKuninori Morimoto if (fifo->tx_chan || fifo->rx_chan) 834*e73a9891SKuninori Morimoto dev_info(dev, "enable DMAEngine (%s%s%s)\n", 835*e73a9891SKuninori Morimoto fifo->name, 836*e73a9891SKuninori Morimoto fifo->tx_chan ? "[TX]" : " ", 837*e73a9891SKuninori Morimoto fifo->rx_chan ? "[RX]" : " "); 838*e73a9891SKuninori Morimoto } 839*e73a9891SKuninori Morimoto 840*e73a9891SKuninori Morimoto /* 841dad67397SKuninori Morimoto * irq functions 842dad67397SKuninori Morimoto */ 843dad67397SKuninori Morimoto static int usbhsf_irq_empty(struct usbhs_priv *priv, 844dad67397SKuninori Morimoto struct usbhs_irq_state *irq_state) 845dad67397SKuninori Morimoto { 846dad67397SKuninori Morimoto struct usbhs_pipe *pipe; 847dad67397SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 848dad67397SKuninori Morimoto int i, ret; 849dad67397SKuninori Morimoto 850dad67397SKuninori Morimoto if (!irq_state->bempsts) { 851dad67397SKuninori Morimoto dev_err(dev, "debug %s !!\n", __func__); 852dad67397SKuninori Morimoto return -EIO; 853dad67397SKuninori Morimoto } 854dad67397SKuninori Morimoto 855dad67397SKuninori Morimoto dev_dbg(dev, "irq empty [0x%04x]\n", irq_state->bempsts); 856dad67397SKuninori Morimoto 857dad67397SKuninori Morimoto /* 858dad67397SKuninori Morimoto * search interrupted "pipe" 859dad67397SKuninori Morimoto * not "uep". 860dad67397SKuninori Morimoto */ 861dad67397SKuninori Morimoto usbhs_for_each_pipe_with_dcp(pipe, priv, i) { 862dad67397SKuninori Morimoto if (!(irq_state->bempsts & (1 << i))) 863dad67397SKuninori Morimoto continue; 864dad67397SKuninori Morimoto 86597664a20SKuninori Morimoto ret = usbhs_pkt_run(pipe); 866dad67397SKuninori Morimoto if (ret < 0) 867dad67397SKuninori Morimoto dev_err(dev, "irq_empty run_error %d : %d\n", i, ret); 868dad67397SKuninori Morimoto } 869dad67397SKuninori Morimoto 870dad67397SKuninori Morimoto return 0; 871dad67397SKuninori Morimoto } 872dad67397SKuninori Morimoto 873dad67397SKuninori Morimoto static int usbhsf_irq_ready(struct usbhs_priv *priv, 874dad67397SKuninori Morimoto struct usbhs_irq_state *irq_state) 875dad67397SKuninori Morimoto { 876dad67397SKuninori Morimoto struct usbhs_pipe *pipe; 877dad67397SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 878dad67397SKuninori Morimoto int i, ret; 879dad67397SKuninori Morimoto 880dad67397SKuninori Morimoto if (!irq_state->brdysts) { 881dad67397SKuninori Morimoto dev_err(dev, "debug %s !!\n", __func__); 882dad67397SKuninori Morimoto return -EIO; 883dad67397SKuninori Morimoto } 884dad67397SKuninori Morimoto 885dad67397SKuninori Morimoto dev_dbg(dev, "irq ready [0x%04x]\n", irq_state->brdysts); 886dad67397SKuninori Morimoto 887dad67397SKuninori Morimoto /* 888dad67397SKuninori Morimoto * search interrupted "pipe" 889dad67397SKuninori Morimoto * not "uep". 890dad67397SKuninori Morimoto */ 891dad67397SKuninori Morimoto usbhs_for_each_pipe_with_dcp(pipe, priv, i) { 892dad67397SKuninori Morimoto if (!(irq_state->brdysts & (1 << i))) 893dad67397SKuninori Morimoto continue; 894dad67397SKuninori Morimoto 89597664a20SKuninori Morimoto ret = usbhs_pkt_run(pipe); 896dad67397SKuninori Morimoto if (ret < 0) 897dad67397SKuninori Morimoto dev_err(dev, "irq_ready run_error %d : %d\n", i, ret); 898dad67397SKuninori Morimoto } 899dad67397SKuninori Morimoto 900dad67397SKuninori Morimoto return 0; 901dad67397SKuninori Morimoto } 902dad67397SKuninori Morimoto 903*e73a9891SKuninori Morimoto static void usbhsf_dma_complete(void *arg) 904*e73a9891SKuninori Morimoto { 905*e73a9891SKuninori Morimoto struct usbhs_pipe *pipe = arg; 906*e73a9891SKuninori Morimoto struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 907*e73a9891SKuninori Morimoto struct device *dev = usbhs_priv_to_dev(priv); 908*e73a9891SKuninori Morimoto int ret; 909*e73a9891SKuninori Morimoto 910*e73a9891SKuninori Morimoto ret = usbhs_pkt_dmadone(pipe); 911*e73a9891SKuninori Morimoto if (ret < 0) 912*e73a9891SKuninori Morimoto dev_err(dev, "dma_complete run_error %d : %d\n", 913*e73a9891SKuninori Morimoto usbhs_pipe_number(pipe), ret); 914*e73a9891SKuninori Morimoto } 915*e73a9891SKuninori Morimoto 916dad67397SKuninori Morimoto /* 917dad67397SKuninori Morimoto * fifo init 918dad67397SKuninori Morimoto */ 919dad67397SKuninori Morimoto void usbhs_fifo_init(struct usbhs_priv *priv) 920dad67397SKuninori Morimoto { 921dad67397SKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 922d77e3f4eSKuninori Morimoto struct usbhs_fifo *cfifo = usbhsf_get_cfifo(priv); 923*e73a9891SKuninori Morimoto struct usbhs_fifo *d0fifo = usbhsf_get_d0fifo(priv); 924*e73a9891SKuninori Morimoto struct usbhs_fifo *d1fifo = usbhsf_get_d1fifo(priv); 925dad67397SKuninori Morimoto 926dad67397SKuninori Morimoto mod->irq_empty = usbhsf_irq_empty; 927dad67397SKuninori Morimoto mod->irq_ready = usbhsf_irq_ready; 928dad67397SKuninori Morimoto mod->irq_bempsts = 0; 929dad67397SKuninori Morimoto mod->irq_brdysts = 0; 930d77e3f4eSKuninori Morimoto 931d77e3f4eSKuninori Morimoto cfifo->pipe = NULL; 932*e73a9891SKuninori Morimoto cfifo->tx_chan = NULL; 933*e73a9891SKuninori Morimoto cfifo->rx_chan = NULL; 934*e73a9891SKuninori Morimoto 935*e73a9891SKuninori Morimoto d0fifo->pipe = NULL; 936*e73a9891SKuninori Morimoto d0fifo->tx_chan = NULL; 937*e73a9891SKuninori Morimoto d0fifo->rx_chan = NULL; 938*e73a9891SKuninori Morimoto 939*e73a9891SKuninori Morimoto d1fifo->pipe = NULL; 940*e73a9891SKuninori Morimoto d1fifo->tx_chan = NULL; 941*e73a9891SKuninori Morimoto d1fifo->rx_chan = NULL; 942*e73a9891SKuninori Morimoto 943*e73a9891SKuninori Morimoto usbhsf_dma_init(priv, usbhsf_get_d0fifo(priv)); 944*e73a9891SKuninori Morimoto usbhsf_dma_init(priv, usbhsf_get_d1fifo(priv)); 945dad67397SKuninori Morimoto } 946dad67397SKuninori Morimoto 947dad67397SKuninori Morimoto void usbhs_fifo_quit(struct usbhs_priv *priv) 948dad67397SKuninori Morimoto { 949dad67397SKuninori Morimoto struct usbhs_mod *mod = usbhs_mod_get_current(priv); 950dad67397SKuninori Morimoto 951dad67397SKuninori Morimoto mod->irq_empty = NULL; 952dad67397SKuninori Morimoto mod->irq_ready = NULL; 953dad67397SKuninori Morimoto mod->irq_bempsts = 0; 954dad67397SKuninori Morimoto mod->irq_brdysts = 0; 955*e73a9891SKuninori Morimoto 956*e73a9891SKuninori Morimoto usbhsf_dma_quit(priv, usbhsf_get_d0fifo(priv)); 957*e73a9891SKuninori Morimoto usbhsf_dma_quit(priv, usbhsf_get_d1fifo(priv)); 958dad67397SKuninori Morimoto } 959d3af90a5SKuninori Morimoto 960d3af90a5SKuninori Morimoto int usbhs_fifo_probe(struct usbhs_priv *priv) 961d3af90a5SKuninori Morimoto { 962d3af90a5SKuninori Morimoto struct usbhs_fifo *fifo; 963d3af90a5SKuninori Morimoto 964d3af90a5SKuninori Morimoto /* CFIFO */ 965d3af90a5SKuninori Morimoto fifo = usbhsf_get_cfifo(priv); 966*e73a9891SKuninori Morimoto fifo->name = "CFIFO"; 967d3af90a5SKuninori Morimoto fifo->port = CFIFO; 968d3af90a5SKuninori Morimoto fifo->sel = CFIFOSEL; 969d3af90a5SKuninori Morimoto fifo->ctr = CFIFOCTR; 970d3af90a5SKuninori Morimoto 971*e73a9891SKuninori Morimoto /* D0FIFO */ 972*e73a9891SKuninori Morimoto fifo = usbhsf_get_d0fifo(priv); 973*e73a9891SKuninori Morimoto fifo->name = "D0FIFO"; 974*e73a9891SKuninori Morimoto fifo->port = D0FIFO; 975*e73a9891SKuninori Morimoto fifo->sel = D0FIFOSEL; 976*e73a9891SKuninori Morimoto fifo->ctr = D0FIFOCTR; 977*e73a9891SKuninori Morimoto fifo->tx_slave.slave_id = usbhs_get_dparam(priv, d0_tx_id); 978*e73a9891SKuninori Morimoto fifo->rx_slave.slave_id = usbhs_get_dparam(priv, d0_rx_id); 979*e73a9891SKuninori Morimoto 980*e73a9891SKuninori Morimoto /* D1FIFO */ 981*e73a9891SKuninori Morimoto fifo = usbhsf_get_d1fifo(priv); 982*e73a9891SKuninori Morimoto fifo->name = "D1FIFO"; 983*e73a9891SKuninori Morimoto fifo->port = D1FIFO; 984*e73a9891SKuninori Morimoto fifo->sel = D1FIFOSEL; 985*e73a9891SKuninori Morimoto fifo->ctr = D1FIFOCTR; 986*e73a9891SKuninori Morimoto fifo->tx_slave.slave_id = usbhs_get_dparam(priv, d1_tx_id); 987*e73a9891SKuninori Morimoto fifo->rx_slave.slave_id = usbhs_get_dparam(priv, d1_rx_id); 988*e73a9891SKuninori Morimoto 989d3af90a5SKuninori Morimoto return 0; 990d3af90a5SKuninori Morimoto } 991d3af90a5SKuninori Morimoto 992d3af90a5SKuninori Morimoto void usbhs_fifo_remove(struct usbhs_priv *priv) 993d3af90a5SKuninori Morimoto { 994d3af90a5SKuninori Morimoto } 995