2 * MUSB OTG driver debug support
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 * Inventra Controller Driver (ICD) for Linux.
38 * The code managing debug files (currently in procfs).
41 #include <linux/kernel.h>
42 #include <linux/proc_fs.h>
43 #include <linux/seq_file.h>
44 #include <asm/uaccess.h> /* FIXME remove procfs writes */
45 #include <asm/arch/hardware.h>
52 const char *otg_state_string(struct musb *musb)
54 switch (musb->xceiv.state) {
55 case OTG_STATE_A_IDLE: return "a_idle";
56 case OTG_STATE_A_WAIT_VRISE: return "a_wait_vrise";
57 case OTG_STATE_A_WAIT_BCON: return "a_wait_bcon";
58 case OTG_STATE_A_HOST: return "a_host";
59 case OTG_STATE_A_SUSPEND: return "a_suspend";
60 case OTG_STATE_A_PERIPHERAL: return "a_peripheral";
61 case OTG_STATE_A_WAIT_VFALL: return "a_wait_vfall";
62 case OTG_STATE_A_VBUS_ERR: return "a_vbus_err";
63 case OTG_STATE_B_IDLE: return "b_idle";
64 case OTG_STATE_B_SRP_INIT: return "b_srp_init";
65 case OTG_STATE_B_PERIPHERAL: return "b_peripheral";
66 case OTG_STATE_B_WAIT_ACON: return "b_wait_acon";
67 case OTG_STATE_B_HOST: return "b_host";
68 default: return "UNDEFINED";
72 #ifdef CONFIG_USB_MUSB_HDRC_HCD
74 static int dump_qh(struct musb_qh *qh, char *buf, unsigned max)
78 struct usb_host_endpoint *hep = qh->hep;
81 count = snprintf(buf, max, " qh %p dev%d ep%d%s max%d\n",
82 qh, qh->dev->devnum, qh->epnum,
83 ({ char *s; switch (qh->type) {
84 case USB_ENDPOINT_XFER_BULK:
86 case USB_ENDPOINT_XFER_INT:
88 case USB_ENDPOINT_XFER_CONTROL:
99 list_for_each_entry(urb, &hep->urb_list, urb_list) {
100 tmp = snprintf(buf, max, "\t%s urb %p %d/%d\n",
101 usb_pipein(urb->pipe) ? "in" : "out",
102 urb, urb->actual_length,
103 urb->transfer_buffer_length);
106 tmp = min(tmp, (int)max);
115 dump_queue(struct list_head *q, char *buf, unsigned max)
120 list_for_each_entry(qh, q, ring) {
123 tmp = dump_qh(qh, buf, max);
126 tmp = min(tmp, (int)max);
136 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
137 static int dump_ep(struct musb_ep *ep, char *buffer, unsigned max)
141 void __iomem *regs = ep->hw_ep->regs;
145 if (ep->hw_ep->tx_double_buffered)
148 if (ep->hw_ep->rx_double_buffered)
153 struct usb_request *req;
155 code = snprintf(buf, max,
156 "\n%s (hw%d): %s%s, csr %04x maxp %04x\n",
157 ep->name, ep->current_epnum,
158 mode, ep->dma ? " dma" : "",
160 (ep->is_in || !ep->current_epnum)
163 musb_readw(regs, ep->is_in
169 code = min(code, (int) max);
173 if (is_cppi_enabled() && ep->current_epnum) {
174 unsigned cppi = ep->current_epnum - 1;
175 void __iomem *base = ep->musb->ctrl_base;
176 unsigned off1 = cppi << 2;
177 void __iomem *ram = base;
181 ram += DAVINCI_TXCPPI_STATERAM_OFFSET(cppi);
184 ram += DAVINCI_RXCPPI_STATERAM_OFFSET(cppi);
185 snprintf(tmp, sizeof tmp, "%d left, ",
187 DAVINCI_RXCPPI_BUFCNT0_REG + off1));
190 code = snprintf(buf, max, "%cX DMA%d: %s"
191 "%08x %08x, %08x %08x; "
192 "%08x %08x %08x .. %08x\n",
193 ep->is_in ? 'T' : 'R',
194 ep->current_epnum - 1, tmp,
195 musb_readl(ram, 0 * 4),
196 musb_readl(ram, 1 * 4),
197 musb_readl(ram, 2 * 4),
198 musb_readl(ram, 3 * 4),
199 musb_readl(ram, 4 * 4),
200 musb_readl(ram, 5 * 4),
201 musb_readl(ram, 6 * 4),
202 musb_readl(ram, 7 * 4));
205 code = min(code, (int) max);
210 if (list_empty(&ep->req_list)) {
211 code = snprintf(buf, max, "\t(queue empty)\n");
214 code = min(code, (int) max);
219 list_for_each_entry (req, &ep->req_list, list) {
220 code = snprintf(buf, max, "\treq %p, %s%s%d/%d\n",
222 req->zero ? "zero, " : "",
223 req->short_not_ok ? "!short, " : "",
224 req->actual, req->length);
227 code = min(code, (int) max);
237 dump_end_info(struct musb *musb, u8 epnum, char *aBuffer, unsigned max)
241 struct musb_hw_ep *hw_ep = &musb->endpoints[epnum];
244 musb_ep_select(musb->mregs, epnum);
245 #ifdef CONFIG_USB_MUSB_HDRC_HCD
246 if (is_host_active(musb)) {
247 int dump_rx, dump_tx;
248 void __iomem *regs = hw_ep->regs;
250 /* TEMPORARY (!) until we have a real periodic
254 /* control is shared, uses RX queue
255 * but (mostly) shadowed tx registers
257 dump_tx = !list_empty(&musb->control);
259 } else if (hw_ep == musb->bulk_ep) {
260 dump_tx = !list_empty(&musb->out_bulk);
261 dump_rx = !list_empty(&musb->in_bulk);
262 } else if (musb->periodic[epnum]) {
263 struct usb_host_endpoint *hep;
265 hep = musb->periodic[epnum]->hep;
266 dump_rx = hep->desc.bEndpointAddress
267 & USB_ENDPOINT_DIR_MASK;
275 code = snprintf(buf, max,
276 "\nRX%d: %s rxcsr %04x interval %02x "
277 "max %04x type %02x; "
278 "dev %d hub %d port %d"
281 hw_ep->rx_double_buffered
283 musb_readw(regs, MUSB_RXCSR),
284 musb_readb(regs, MUSB_RXINTERVAL),
285 musb_readw(regs, MUSB_RXMAXP),
286 musb_readb(regs, MUSB_RXTYPE),
287 /* FIXME: assumes multipoint */
288 musb_readb(musb->mregs,
289 MUSB_BUSCTL_OFFSET(epnum,
291 musb_readb(musb->mregs,
292 MUSB_BUSCTL_OFFSET(epnum,
294 musb_readb(musb->mregs,
295 MUSB_BUSCTL_OFFSET(epnum,
300 code = min(code, (int) max);
304 if (is_cppi_enabled()
306 && hw_ep->rx_channel) {
307 unsigned cppi = epnum - 1;
308 unsigned off1 = cppi << 2;
313 base = musb->ctrl_base;
314 ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
316 snprintf(tmp, sizeof tmp, "%d left, ",
318 DAVINCI_RXCPPI_BUFCNT0_REG
321 code = snprintf(buf, max,
323 "%08x %08x, %08x %08x; "
324 "%08x %08x %08x .. %08x\n",
326 musb_readl(ram, 0 * 4),
327 musb_readl(ram, 1 * 4),
328 musb_readl(ram, 2 * 4),
329 musb_readl(ram, 3 * 4),
330 musb_readl(ram, 4 * 4),
331 musb_readl(ram, 5 * 4),
332 musb_readl(ram, 6 * 4),
333 musb_readl(ram, 7 * 4));
336 code = min(code, (int) max);
341 if (hw_ep == musb->bulk_ep
344 code = dump_queue(&musb->in_bulk,
348 code = min(code, (int) max);
351 } else if (musb->periodic[epnum]) {
352 code = dump_qh(musb->periodic[epnum],
356 code = min(code, (int) max);
363 code = snprintf(buf, max,
364 "\nTX%d: %s txcsr %04x interval %02x "
365 "max %04x type %02x; "
366 "dev %d hub %d port %d"
369 hw_ep->tx_double_buffered
371 musb_readw(regs, MUSB_TXCSR),
372 musb_readb(regs, MUSB_TXINTERVAL),
373 musb_readw(regs, MUSB_TXMAXP),
374 musb_readb(regs, MUSB_TXTYPE),
375 /* FIXME: assumes multipoint */
376 musb_readb(musb->mregs,
377 MUSB_BUSCTL_OFFSET(epnum,
379 musb_readb(musb->mregs,
380 MUSB_BUSCTL_OFFSET(epnum,
382 musb_readb(musb->mregs,
383 MUSB_BUSCTL_OFFSET(epnum,
388 code = min(code, (int) max);
392 if (is_cppi_enabled()
394 && hw_ep->tx_channel) {
395 unsigned cppi = epnum - 1;
399 base = musb->ctrl_base;
400 ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
402 code = snprintf(buf, max,
404 "%08x %08x, %08x %08x; "
405 "%08x %08x %08x .. %08x\n",
407 musb_readl(ram, 0 * 4),
408 musb_readl(ram, 1 * 4),
409 musb_readl(ram, 2 * 4),
410 musb_readl(ram, 3 * 4),
411 musb_readl(ram, 4 * 4),
412 musb_readl(ram, 5 * 4),
413 musb_readl(ram, 6 * 4),
414 musb_readl(ram, 7 * 4));
417 code = min(code, (int) max);
422 if (hw_ep == musb->control_ep
425 code = dump_queue(&musb->control,
429 code = min(code, (int) max);
432 } else if (hw_ep == musb->bulk_ep
435 code = dump_queue(&musb->out_bulk,
439 code = min(code, (int) max);
442 } else if (musb->periodic[epnum]) {
443 code = dump_qh(musb->periodic[epnum],
447 code = min(code, (int) max);
454 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
455 if (is_peripheral_active(musb)) {
458 if (hw_ep->ep_in.desc || !epnum) {
459 code = dump_ep(&hw_ep->ep_in, buf, max);
462 code = min(code, (int) max);
466 if (hw_ep->ep_out.desc) {
467 code = dump_ep(&hw_ep->ep_out, buf, max);
470 code = min(code, (int) max);
478 return buf - aBuffer;
481 /** Dump the current status and compile options.
482 * @param musb the device driver instance
483 * @param buffer where to dump the status; it must be big enough hold the
484 * result otherwise "BAD THINGS HAPPENS(TM)".
486 static int dump_header_stats(struct musb *musb, char *buffer)
489 const void __iomem *mbase = musb->mregs;
492 count = sprintf(buffer, "Status: %sHDRC, Mode=%s "
493 "(Power=%02x, DevCtl=%02x)\n",
494 (musb->is_multipoint ? "M" : ""), MUSB_MODE(musb),
495 musb_readb(mbase, MUSB_POWER),
496 musb_readb(mbase, MUSB_DEVCTL));
501 code = sprintf(buffer, "OTG state: %s; %sactive\n",
502 otg_state_string(musb),
503 musb->is_active ? "" : "in");
509 code = sprintf(buffer,
511 #ifdef CONFIG_USB_INVENTRA_FIFO
513 #elif defined(CONFIG_USB_TI_CPPI_DMA)
515 #elif defined(CONFIG_USB_INVENTRA_DMA)
517 #elif defined(CONFIG_USB_TUSB_OMAP_DMA)
523 #ifdef CONFIG_USB_MUSB_OTG
524 "otg (peripheral+host)"
525 #elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
527 #elif defined(CONFIG_USB_MUSB_HDRC_HCD)
530 ", debug=%d [eps=%d]\n",
538 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
539 code = sprintf(buffer, "Peripheral address: %02x\n",
540 musb_readb(musb, MUSB_FADDR));
547 #ifdef CONFIG_USB_MUSB_HDRC_HCD
548 code = sprintf(buffer, "Root port status: %08x\n",
556 #ifdef CONFIG_ARCH_DAVINCI
557 code = sprintf(buffer,
558 "DaVinci: ctrl=%02x stat=%1x phy=%03x\n"
559 "\trndis=%05x auto=%04x intsrc=%08x intmsk=%08x"
561 musb_readl(musb->ctrl_base, DAVINCI_USB_CTRL_REG),
562 musb_readl(musb->ctrl_base, DAVINCI_USB_STAT_REG),
563 __raw_readl(IO_ADDRESS(USBPHY_CTL_PADDR)),
564 musb_readl(musb->ctrl_base, DAVINCI_RNDIS_REG),
565 musb_readl(musb->ctrl_base, DAVINCI_AUTOREQ_REG),
566 musb_readl(musb->ctrl_base,
567 DAVINCI_USB_INT_SOURCE_REG),
568 musb_readl(musb->ctrl_base,
569 DAVINCI_USB_INT_MASK_REG));
576 #ifdef CONFIG_USB_TUSB6010
577 code = sprintf(buffer,
578 "TUSB6010: devconf %08x, phy enable %08x drive %08x"
579 "\n\totg %03x timer %08x"
580 "\n\tprcm conf %08x mgmt %08x; int src %08x mask %08x"
582 musb_readl(musb->ctrl_base, TUSB_DEV_CONF),
583 musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE),
584 musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL),
585 musb_readl(musb->ctrl_base, TUSB_DEV_OTG_STAT),
586 musb_readl(musb->ctrl_base, TUSB_DEV_OTG_TIMER),
587 musb_readl(musb->ctrl_base, TUSB_PRCM_CONF),
588 musb_readl(musb->ctrl_base, TUSB_PRCM_MNGMT),
589 musb_readl(musb->ctrl_base, TUSB_INT_SRC),
590 musb_readl(musb->ctrl_base, TUSB_INT_MASK));
597 if (is_cppi_enabled() && musb->dma_controller) {
598 code = sprintf(buffer,
599 "CPPI: txcr=%d txsrc=%01x txena=%01x; "
600 "rxcr=%d rxsrc=%01x rxena=%01x "
602 musb_readl(musb->ctrl_base,
603 DAVINCI_TXCPPI_CTRL_REG),
604 musb_readl(musb->ctrl_base,
605 DAVINCI_TXCPPI_RAW_REG),
606 musb_readl(musb->ctrl_base,
607 DAVINCI_TXCPPI_INTENAB_REG),
608 musb_readl(musb->ctrl_base,
609 DAVINCI_RXCPPI_CTRL_REG),
610 musb_readl(musb->ctrl_base,
611 DAVINCI_RXCPPI_RAW_REG),
612 musb_readl(musb->ctrl_base,
613 DAVINCI_RXCPPI_INTENAB_REG));
620 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
621 if (is_peripheral_enabled(musb)) {
622 code = sprintf(buffer, "Gadget driver: %s\n",
624 ? musb->gadget_driver->driver.name
644 * F force session (OTG-unfriendly)
645 * E rElinquish bus (OTG)
646 * H request host mode
647 * h cancel host request
648 * T start sending TEST_PACKET
649 * D<num> set/query the debug level
651 static int musb_proc_write(struct file *file, const char __user *buffer,
652 unsigned long count, void *data)
656 struct musb *musb = (struct musb *)data;
657 void __iomem *mbase = musb->mregs;
659 /* MOD_INC_USE_COUNT; */
661 if (unlikely(copy_from_user(&cmd, buffer, 1)))
667 bReg = musb_readb(mbase, MUSB_POWER)
668 | MUSB_POWER_SOFTCONN;
669 musb_writeb(mbase, MUSB_POWER, bReg);
675 bReg = musb_readb(mbase, MUSB_POWER)
676 & ~MUSB_POWER_SOFTCONN;
677 musb_writeb(mbase, MUSB_POWER, bReg);
683 bReg = musb_readb(mbase, MUSB_POWER)
685 musb_writeb(mbase, MUSB_POWER, bReg);
691 bReg = musb_readb(mbase, MUSB_POWER)
692 & ~MUSB_POWER_HSENAB;
693 musb_writeb(mbase, MUSB_POWER, bReg);
698 bReg = musb_readb(mbase, MUSB_DEVCTL);
699 bReg |= MUSB_DEVCTL_SESSION;
700 musb_writeb(mbase, MUSB_DEVCTL, bReg);
705 bReg = musb_readb(mbase, MUSB_DEVCTL);
706 bReg |= MUSB_DEVCTL_HR;
707 musb_writeb(mbase, MUSB_DEVCTL, bReg);
708 //MUSB_HST_MODE( ((struct musb*)data) );
709 //WARN("Host Mode\n");
715 bReg = musb_readb(mbase, MUSB_DEVCTL);
716 bReg &= ~MUSB_DEVCTL_HR;
717 musb_writeb(mbase, MUSB_DEVCTL, bReg);
723 musb_load_testpacket(musb);
724 musb_writeb(mbase, MUSB_TESTMODE,
730 /* set/read debug level */
733 char digits[8], *p = digits;
734 int i = 0, level = 0, sign = 1;
735 int len = min(count - 1, (unsigned long)8);
737 if (copy_from_user(&digits, &buffer[1], len))
748 while (i++ < len && *p > '0' && *p < '9') {
749 level = level * 10 + (*p - '0');
754 DBG(1, "debug level %d\n", level);
762 INFO("?: you are seeing it\n");
763 INFO("C/c: soft connect enable/disable\n");
764 INFO("I/i: hispeed enable/disable\n");
765 INFO("F: force session start\n");
766 INFO("H: host mode\n");
767 INFO("T: start sending TEST_PACKET\n");
768 INFO("D: set/read dbug level\n");
773 ERR("Command %c not implemented\n", cmd);
777 musb_platform_try_idle(musb, 0);
782 static int musb_proc_read(char *page, char **start,
783 off_t off, int count, int *eof, void *data)
788 struct musb *musb = data;
792 count -= 1; /* for NUL at end */
796 spin_lock_irqsave(&musb->lock, flags);
798 code = dump_header_stats(musb, buffer);
804 /* generate the report for the end points */
805 // REVISIT ... not unless something's connected!
806 for (epnum = 0; count >= 0 && epnum < musb->nr_endpoints;
808 code = dump_end_info(musb, epnum, buffer, count);
815 musb_platform_try_idle(musb, 0);
817 spin_unlock_irqrestore(&musb->lock, flags);
820 return buffer - page;
823 void __devexit musb_debug_delete(char *name, struct musb *musb)
825 if (musb->proc_entry)
826 remove_proc_entry(name, NULL);
829 struct proc_dir_entry *__init
830 musb_debug_create(char *name, struct musb *data)
832 struct proc_dir_entry *pde;
834 /* FIXME convert everything to seq_file; then later, debugfs */
839 data->proc_entry = pde = create_proc_entry(name,
840 S_IFREG | S_IRUGO | S_IWUSR, NULL);
843 // pde->owner = THIS_MODULE;
845 pde->read_proc = musb_proc_read;
846 pde->write_proc = musb_proc_write;
850 pr_debug("Registered /proc/%s\n", name);
852 pr_debug("Cannot create a valid proc file entry");