1 /******************************************************************
2 * Copyright 2005 Mentor Graphics Corporation
3 * Copyright (C) 2005-2006 by Texas Instruments
5 * This file is part of the Inventra Controller Driver for Linux.
7 * The Inventra Controller Driver for Linux is free software; you
8 * can redistribute it and/or modify it under the terms of the GNU
9 * General Public License version 2 as published by the Free Software
12 * The Inventra Controller Driver for Linux is distributed in
13 * the hope that it will be useful, but WITHOUT ANY WARRANTY;
14 * without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 * License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with The Inventra Controller Driver for Linux ; if not,
20 * write to the Free Software Foundation, Inc., 59 Temple Place,
21 * Suite 330, Boston, MA 02111-1307 USA
23 * ANY DOWNLOAD, USE, REPRODUCTION, MODIFICATION OR DISTRIBUTION
24 * OF THIS DRIVER INDICATES YOUR COMPLETE AND UNCONDITIONAL ACCEPTANCE
25 * OF THOSE TERMS.THIS DRIVER IS PROVIDED "AS IS" AND MENTOR GRAPHICS
26 * MAKES NO WARRANTIES, EXPRESS OR IMPLIED, RELATED TO THIS DRIVER.
27 * MENTOR GRAPHICS SPECIFICALLY DISCLAIMS ALL IMPLIED WARRANTIES
28 * OF MERCHANTABILITY; FITNESS FOR A PARTICULAR PURPOSE AND
29 * NON-INFRINGEMENT. MENTOR GRAPHICS DOES NOT PROVIDE SUPPORT
30 * SERVICES OR UPDATES FOR THIS DRIVER, EVEN IF YOU ARE A MENTOR
31 * GRAPHICS SUPPORT CUSTOMER.
32 ******************************************************************/
35 * Inventra Controller Driver (ICD) for Linux.
37 * The code managing debug files (currently in procfs).
40 #include <linux/kernel.h>
41 #include <linux/proc_fs.h>
42 #include <linux/seq_file.h>
43 #include <asm/uaccess.h> /* FIXME remove procfs writes */
44 #include <asm/arch/hardware.h>
51 const char *otg_state_string(struct musb *musb)
53 switch (musb->xceiv.state) {
54 case OTG_STATE_A_IDLE: return "a_idle";
55 case OTG_STATE_A_WAIT_VRISE: return "a_wait_vrise";
56 case OTG_STATE_A_WAIT_BCON: return "a_wait_bcon";
57 case OTG_STATE_A_HOST: return "a_host";
58 case OTG_STATE_A_SUSPEND: return "a_suspend";
59 case OTG_STATE_A_PERIPHERAL: return "a_peripheral";
60 case OTG_STATE_A_WAIT_VFALL: return "a_wait_vfall";
61 case OTG_STATE_A_VBUS_ERR: return "a_vbus_err";
62 case OTG_STATE_B_IDLE: return "b_idle";
63 case OTG_STATE_B_SRP_INIT: return "b_srp_init";
64 case OTG_STATE_B_PERIPHERAL: return "b_peripheral";
65 case OTG_STATE_B_WAIT_ACON: return "b_wait_acon";
66 case OTG_STATE_B_HOST: return "b_host";
67 default: return "UNDEFINED";
71 #ifdef CONFIG_USB_MUSB_HDRC_HCD
73 static int dump_qh(struct musb_qh *qh, char *buf, unsigned max)
77 struct usb_host_endpoint *hep = qh->hep;
80 count = snprintf(buf, max, " qh %p dev%d ep%d%s max%d\n",
81 qh, qh->dev->devnum, qh->epnum,
82 ({ char *s; switch (qh->type) {
83 case USB_ENDPOINT_XFER_BULK:
85 case USB_ENDPOINT_XFER_INT:
87 case USB_ENDPOINT_XFER_CONTROL:
98 list_for_each_entry(urb, &hep->urb_list, urb_list) {
99 tmp = snprintf(buf, max, "\t%s urb %p %d/%d\n",
100 usb_pipein(urb->pipe) ? "in" : "out",
101 urb, urb->actual_length,
102 urb->transfer_buffer_length);
105 tmp = min(tmp, (int)max);
114 dump_queue(struct list_head *q, char *buf, unsigned max)
119 list_for_each_entry(qh, q, ring) {
122 tmp = dump_qh(qh, buf, max);
125 tmp = min(tmp, (int)max);
135 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
136 static int dump_ep(struct musb_ep *ep, char *buffer, unsigned max)
140 void __iomem *regs = ep->hw_ep->regs;
144 if (ep->hw_ep->tx_double_buffered)
147 if (ep->hw_ep->rx_double_buffered)
152 struct usb_request *req;
154 code = snprintf(buf, max,
155 "\n%s (hw%d): %s%s, csr %04x maxp %04x\n",
156 ep->name, ep->current_epnum,
157 mode, ep->dma ? " dma" : "",
159 (ep->is_in || !ep->current_epnum)
162 musb_readw(regs, ep->is_in
168 code = min(code, (int) max);
172 if (is_cppi_enabled() && ep->current_epnum) {
173 unsigned cppi = ep->current_epnum - 1;
174 void __iomem *base = ep->musb->ctrl_base;
175 unsigned off1 = cppi << 2;
176 void __iomem *ram = base;
180 ram += DAVINCI_TXCPPI_STATERAM_OFFSET(cppi);
183 ram += DAVINCI_RXCPPI_STATERAM_OFFSET(cppi);
184 snprintf(tmp, sizeof tmp, "%d left, ",
186 DAVINCI_RXCPPI_BUFCNT0_REG + off1));
189 code = snprintf(buf, max, "%cX DMA%d: %s"
190 "%08x %08x, %08x %08x; "
191 "%08x %08x %08x .. %08x\n",
192 ep->is_in ? 'T' : 'R',
193 ep->current_epnum - 1, tmp,
194 musb_readl(ram, 0 * 4),
195 musb_readl(ram, 1 * 4),
196 musb_readl(ram, 2 * 4),
197 musb_readl(ram, 3 * 4),
198 musb_readl(ram, 4 * 4),
199 musb_readl(ram, 5 * 4),
200 musb_readl(ram, 6 * 4),
201 musb_readl(ram, 7 * 4));
204 code = min(code, (int) max);
209 if (list_empty(&ep->req_list)) {
210 code = snprintf(buf, max, "\t(queue empty)\n");
213 code = min(code, (int) max);
218 list_for_each_entry (req, &ep->req_list, list) {
219 code = snprintf(buf, max, "\treq %p, %s%s%d/%d\n",
221 req->zero ? "zero, " : "",
222 req->short_not_ok ? "!short, " : "",
223 req->actual, req->length);
226 code = min(code, (int) max);
236 dump_end_info(struct musb *musb, u8 bEnd, char *aBuffer, unsigned max)
240 struct musb_hw_ep *hw_ep = &musb->endpoints[bEnd];
243 MGC_SelectEnd(musb->mregs, bEnd);
244 #ifdef CONFIG_USB_MUSB_HDRC_HCD
245 if (is_host_active(musb)) {
246 int dump_rx, dump_tx;
247 void __iomem *regs = hw_ep->regs;
249 /* TEMPORARY (!) until we have a real periodic
253 /* control is shared, uses RX queue
254 * but (mostly) shadowed tx registers
256 dump_tx = !list_empty(&musb->control);
258 } else if (hw_ep == musb->bulk_ep) {
259 dump_tx = !list_empty(&musb->out_bulk);
260 dump_rx = !list_empty(&musb->in_bulk);
261 } else if (musb->periodic[bEnd]) {
262 struct usb_host_endpoint *hep;
264 hep = musb->periodic[bEnd]->hep;
265 dump_rx = hep->desc.bEndpointAddress
266 & USB_ENDPOINT_DIR_MASK;
274 code = snprintf(buf, max,
275 "\nRX%d: %s rxcsr %04x interval %02x "
276 "max %04x type %02x; "
277 "dev %d hub %d port %d"
280 hw_ep->rx_double_buffered
282 musb_readw(regs, MGC_O_HDRC_RXCSR),
283 musb_readb(regs, MGC_O_HDRC_RXINTERVAL),
284 musb_readw(regs, MGC_O_HDRC_RXMAXP),
285 musb_readb(regs, MGC_O_HDRC_RXTYPE),
286 /* FIXME: assumes multipoint */
287 musb_readb(musb->mregs,
288 MGC_BUSCTL_OFFSET(bEnd,
289 MGC_O_HDRC_RXFUNCADDR)),
290 musb_readb(musb->mregs,
291 MGC_BUSCTL_OFFSET(bEnd,
292 MGC_O_HDRC_RXHUBADDR)),
293 musb_readb(musb->mregs,
294 MGC_BUSCTL_OFFSET(bEnd,
295 MGC_O_HDRC_RXHUBPORT))
299 code = min(code, (int) max);
303 if (is_cppi_enabled()
305 && hw_ep->rx_channel) {
306 unsigned cppi = bEnd - 1;
307 unsigned off1 = cppi << 2;
312 base = musb->ctrl_base;
313 ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
315 snprintf(tmp, sizeof tmp, "%d left, ",
317 DAVINCI_RXCPPI_BUFCNT0_REG
320 code = snprintf(buf, max,
322 "%08x %08x, %08x %08x; "
323 "%08x %08x %08x .. %08x\n",
325 musb_readl(ram, 0 * 4),
326 musb_readl(ram, 1 * 4),
327 musb_readl(ram, 2 * 4),
328 musb_readl(ram, 3 * 4),
329 musb_readl(ram, 4 * 4),
330 musb_readl(ram, 5 * 4),
331 musb_readl(ram, 6 * 4),
332 musb_readl(ram, 7 * 4));
335 code = min(code, (int) max);
340 if (hw_ep == musb->bulk_ep
343 code = dump_queue(&musb->in_bulk,
347 code = min(code, (int) max);
350 } else if (musb->periodic[bEnd]) {
351 code = dump_qh(musb->periodic[bEnd],
355 code = min(code, (int) max);
362 code = snprintf(buf, max,
363 "\nTX%d: %s txcsr %04x interval %02x "
364 "max %04x type %02x; "
365 "dev %d hub %d port %d"
368 hw_ep->tx_double_buffered
370 musb_readw(regs, MGC_O_HDRC_TXCSR),
371 musb_readb(regs, MGC_O_HDRC_TXINTERVAL),
372 musb_readw(regs, MGC_O_HDRC_TXMAXP),
373 musb_readb(regs, MGC_O_HDRC_TXTYPE),
374 /* FIXME: assumes multipoint */
375 musb_readb(musb->mregs,
376 MGC_BUSCTL_OFFSET(bEnd,
377 MGC_O_HDRC_TXFUNCADDR)),
378 musb_readb(musb->mregs,
379 MGC_BUSCTL_OFFSET(bEnd,
380 MGC_O_HDRC_TXHUBADDR)),
381 musb_readb(musb->mregs,
382 MGC_BUSCTL_OFFSET(bEnd,
383 MGC_O_HDRC_TXHUBPORT))
387 code = min(code, (int) max);
391 if (is_cppi_enabled()
393 && hw_ep->tx_channel) {
394 unsigned cppi = bEnd - 1;
398 base = musb->ctrl_base;
399 ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
401 code = snprintf(buf, max,
403 "%08x %08x, %08x %08x; "
404 "%08x %08x %08x .. %08x\n",
406 musb_readl(ram, 0 * 4),
407 musb_readl(ram, 1 * 4),
408 musb_readl(ram, 2 * 4),
409 musb_readl(ram, 3 * 4),
410 musb_readl(ram, 4 * 4),
411 musb_readl(ram, 5 * 4),
412 musb_readl(ram, 6 * 4),
413 musb_readl(ram, 7 * 4));
416 code = min(code, (int) max);
421 if (hw_ep == musb->control_ep
424 code = dump_queue(&musb->control,
428 code = min(code, (int) max);
431 } else if (hw_ep == musb->bulk_ep
434 code = dump_queue(&musb->out_bulk,
438 code = min(code, (int) max);
441 } else if (musb->periodic[bEnd]) {
442 code = dump_qh(musb->periodic[bEnd],
446 code = min(code, (int) max);
453 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
454 if (is_peripheral_active(musb)) {
457 if (hw_ep->ep_in.desc || !bEnd) {
458 code = dump_ep(&hw_ep->ep_in, buf, max);
461 code = min(code, (int) max);
465 if (hw_ep->ep_out.desc) {
466 code = dump_ep(&hw_ep->ep_out, buf, max);
469 code = min(code, (int) max);
477 return buf - aBuffer;
480 /** Dump the current status and compile options.
481 * @param musb the device driver instance
482 * @param buffer where to dump the status; it must be big enough hold the
483 * result otherwise "BAD THINGS HAPPENS(TM)".
485 static int dump_header_stats(struct musb *musb, char *buffer)
488 const void __iomem *mbase = musb->mregs;
491 count = sprintf(buffer, "Status: %sHDRC, Mode=%s "
492 "(Power=%02x, DevCtl=%02x)\n",
493 (musb->bIsMultipoint ? "M" : ""), MUSB_MODE(musb),
494 musb_readb(mbase, MGC_O_HDRC_POWER),
495 musb_readb(mbase, MGC_O_HDRC_DEVCTL));
500 code = sprintf(buffer, "OTG state: %s; %sactive\n",
501 otg_state_string(musb),
502 musb->is_active ? "" : "in");
508 code = sprintf(buffer,
510 #ifdef CONFIG_USB_INVENTRA_FIFO
512 #elif defined(CONFIG_USB_TI_CPPI_DMA)
514 #elif defined(CONFIG_USB_INVENTRA_DMA)
516 #elif defined(CONFIG_USB_TUSB_OMAP_DMA)
522 #ifdef CONFIG_USB_MUSB_OTG
523 "otg (peripheral+host)"
524 #elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
526 #elif defined(CONFIG_USB_MUSB_HDRC_HCD)
529 ", debug=%d [eps=%d]\n",
537 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
538 code = sprintf(buffer, "Peripheral address: %02x\n",
539 musb_readb(musb, MGC_O_HDRC_FADDR));
546 #ifdef CONFIG_USB_MUSB_HDRC_HCD
547 code = sprintf(buffer, "Root port status: %08x\n",
555 #ifdef CONFIG_ARCH_DAVINCI
556 code = sprintf(buffer,
557 "DaVinci: ctrl=%02x stat=%1x phy=%03x\n"
558 "\trndis=%05x auto=%04x intsrc=%08x intmsk=%08x"
560 musb_readl(musb->ctrl_base, DAVINCI_USB_CTRL_REG),
561 musb_readl(musb->ctrl_base, DAVINCI_USB_STAT_REG),
562 __raw_readl(IO_ADDRESS(USBPHY_CTL_PADDR)),
563 musb_readl(musb->ctrl_base, DAVINCI_RNDIS_REG),
564 musb_readl(musb->ctrl_base, DAVINCI_AUTOREQ_REG),
565 musb_readl(musb->ctrl_base,
566 DAVINCI_USB_INT_SOURCE_REG),
567 musb_readl(musb->ctrl_base,
568 DAVINCI_USB_INT_MASK_REG));
575 #ifdef CONFIG_USB_TUSB6010
576 code = sprintf(buffer,
577 "TUSB6010: devconf %08x, phy enable %08x drive %08x"
578 "\n\totg %03x timer %08x"
579 "\n\tprcm conf %08x mgmt %08x; int src %08x mask %08x"
581 musb_readl(musb->ctrl_base, TUSB_DEV_CONF),
582 musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE),
583 musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL),
584 musb_readl(musb->ctrl_base, TUSB_DEV_OTG_STAT),
585 musb_readl(musb->ctrl_base, TUSB_DEV_OTG_TIMER),
586 musb_readl(musb->ctrl_base, TUSB_PRCM_CONF),
587 musb_readl(musb->ctrl_base, TUSB_PRCM_MNGMT),
588 musb_readl(musb->ctrl_base, TUSB_INT_SRC),
589 musb_readl(musb->ctrl_base, TUSB_INT_MASK));
596 if (is_cppi_enabled() && musb->pDmaController) {
597 code = sprintf(buffer,
598 "CPPI: txcr=%d txsrc=%01x txena=%01x; "
599 "rxcr=%d rxsrc=%01x rxena=%01x "
601 musb_readl(musb->ctrl_base,
602 DAVINCI_TXCPPI_CTRL_REG),
603 musb_readl(musb->ctrl_base,
604 DAVINCI_TXCPPI_RAW_REG),
605 musb_readl(musb->ctrl_base,
606 DAVINCI_TXCPPI_INTENAB_REG),
607 musb_readl(musb->ctrl_base,
608 DAVINCI_RXCPPI_CTRL_REG),
609 musb_readl(musb->ctrl_base,
610 DAVINCI_RXCPPI_RAW_REG),
611 musb_readl(musb->ctrl_base,
612 DAVINCI_RXCPPI_INTENAB_REG));
619 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
620 if (is_peripheral_enabled(musb)) {
621 code = sprintf(buffer, "Gadget driver: %s\n",
623 ? musb->pGadgetDriver->driver.name
643 * F force session (OTG-unfriendly)
644 * E rElinquish bus (OTG)
645 * H request host mode
646 * h cancel host request
647 * T start sending TEST_PACKET
648 * D<num> set/query the debug level
650 static int musb_proc_write(struct file *file, const char __user *buffer,
651 unsigned long count, void *data)
655 struct musb *musb = (struct musb *)data;
656 void __iomem *mbase = musb->mregs;
658 /* MOD_INC_USE_COUNT; */
660 if (unlikely(copy_from_user(&cmd, buffer, 1)))
666 bReg = musb_readb(mbase, MGC_O_HDRC_POWER)
667 | MGC_M_POWER_SOFTCONN;
668 musb_writeb(mbase, MGC_O_HDRC_POWER, bReg);
674 bReg = musb_readb(mbase, MGC_O_HDRC_POWER)
675 & ~MGC_M_POWER_SOFTCONN;
676 musb_writeb(mbase, MGC_O_HDRC_POWER, bReg);
682 bReg = musb_readb(mbase, MGC_O_HDRC_POWER)
683 | MGC_M_POWER_HSENAB;
684 musb_writeb(mbase, MGC_O_HDRC_POWER, bReg);
690 bReg = musb_readb(mbase, MGC_O_HDRC_POWER)
691 & ~MGC_M_POWER_HSENAB;
692 musb_writeb(mbase, MGC_O_HDRC_POWER, bReg);
697 bReg = musb_readb(mbase, MGC_O_HDRC_DEVCTL);
698 bReg |= MGC_M_DEVCTL_SESSION;
699 musb_writeb(mbase, MGC_O_HDRC_DEVCTL, bReg);
704 bReg = musb_readb(mbase, MGC_O_HDRC_DEVCTL);
705 bReg |= MGC_M_DEVCTL_HR;
706 musb_writeb(mbase, MGC_O_HDRC_DEVCTL, bReg);
707 //MUSB_HST_MODE( ((struct musb*)data) );
708 //WARN("Host Mode\n");
714 bReg = musb_readb(mbase, MGC_O_HDRC_DEVCTL);
715 bReg &= ~MGC_M_DEVCTL_HR;
716 musb_writeb(mbase, MGC_O_HDRC_DEVCTL, bReg);
722 musb_load_testpacket(musb);
723 musb_writeb(mbase, MGC_O_HDRC_TESTMODE,
729 /* set/read debug level */
732 char digits[8], *p = digits;
733 int i = 0, level = 0, sign = 1;
734 int len = min(count - 1, (unsigned long)8);
736 if (copy_from_user(&digits, &buffer[1], len))
747 while (i++ < len && *p > '0' && *p < '9') {
748 level = level * 10 + (*p - '0');
753 DBG(1, "debug level %d\n", level);
761 INFO("?: you are seeing it\n");
762 INFO("C/c: soft connect enable/disable\n");
763 INFO("I/i: hispeed enable/disable\n");
764 INFO("F: force session start\n");
765 INFO("H: host mode\n");
766 INFO("T: start sending TEST_PACKET\n");
767 INFO("D: set/read dbug level\n");
772 ERR("Command %c not implemented\n", cmd);
776 musb_platform_try_idle(musb, 0);
781 static int musb_proc_read(char *page, char **start,
782 off_t off, int count, int *eof, void *data)
787 struct musb *musb = data;
791 count -= 1; /* for NUL at end */
795 spin_lock_irqsave(&musb->Lock, flags);
797 code = dump_header_stats(musb, buffer);
803 /* generate the report for the end points */
804 // REVISIT ... not unless something's connected!
805 for (bEnd = 0; count >= 0 && bEnd < musb->nr_endpoints;
807 code = dump_end_info(musb, bEnd, buffer, count);
814 musb_platform_try_idle(musb, 0);
816 spin_unlock_irqrestore(&musb->Lock, flags);
819 return buffer - page;
822 void __devexit musb_debug_delete(char *name, struct musb *musb)
824 if (musb->pProcEntry)
825 remove_proc_entry(name, NULL);
828 struct proc_dir_entry *__init
829 musb_debug_create(char *name, struct musb *data)
831 struct proc_dir_entry *pde;
833 /* FIXME convert everything to seq_file; then later, debugfs */
838 data->pProcEntry = pde = create_proc_entry(name,
839 S_IFREG | S_IRUGO | S_IWUSR, NULL);
842 // pde->owner = THIS_MODULE;
844 pde->read_proc = musb_proc_read;
845 pde->write_proc = musb_proc_write;
849 pr_debug("Registered /proc/%s\n", name);
851 pr_debug("Cannot create a valid proc file entry");