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/config.h>
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:
97 list_for_each_entry(urb, &hep->urb_list, urb_list) {
98 tmp = snprintf(buf, max, "\t%s urb %p %d/%d\n",
99 usb_pipein(urb->pipe) ? "in" : "out",
100 urb, urb->actual_length,
101 urb->transfer_buffer_length);
104 tmp = min(tmp, (int)max);
113 dump_queue(struct list_head *q, char *buf, unsigned max)
118 list_for_each_entry(qh, q, ring) {
121 tmp = dump_qh(qh, buf, max);
124 tmp = min(tmp, (int)max);
134 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
135 static int dump_ep(struct musb_ep *ep, char *buffer, unsigned max)
139 void __iomem *regs = ep->hw_ep->regs;
142 struct usb_request *req;
144 code = snprintf(buf, max,
145 "\n%s (hw%d): %scsr %04x maxp %04x\n",
146 ep->name, ep->bEndNumber,
147 ep->dma ? "dma, " : "",
149 (ep->is_in || !ep->bEndNumber)
152 musb_readw(regs, ep->is_in
158 code = min(code, (int) max);
162 #ifdef CONFIG_USB_TI_CPPI_DMA
163 if (ep->bEndNumber) {
164 unsigned cppi = ep->bEndNumber - 1;
165 void __iomem *base = ep->pThis->ctrl_base;
166 unsigned off1 = cppi << 2;
167 void __iomem *ram = base;
171 ram += DAVINCI_TXCPPI_STATERAM_OFFSET(cppi);
174 ram += DAVINCI_RXCPPI_STATERAM_OFFSET(cppi);
175 snprintf(tmp, sizeof tmp, "%d left, ",
177 DAVINCI_RXCPPI_BUFCNT0_REG + off1));
180 code = snprintf(buf, max, "%cX DMA%d: %s"
181 "%08x %08x, %08x %08x; "
182 "%08x %08x %08x .. %08x\n",
183 ep->is_in ? 'T' : 'R',
184 ep->bEndNumber - 1, tmp,
185 musb_readl(ram, 0 * 4),
186 musb_readl(ram, 1 * 4),
187 musb_readl(ram, 2 * 4),
188 musb_readl(ram, 3 * 4),
189 musb_readl(ram, 4 * 4),
190 musb_readl(ram, 5 * 4),
191 musb_readl(ram, 6 * 4),
192 musb_readl(ram, 7 * 4));
195 code = min(code, (int) max);
201 if (list_empty(&ep->req_list)) {
202 code = snprintf(buf, max, "\t(queue empty)\n");
205 code = min(code, (int) max);
210 list_for_each_entry (req, &ep->req_list, list) {
211 code = snprintf(buf, max, "\treq %p, %s%s%d/%d\n",
213 req->zero ? "zero, " : "",
214 req->short_not_ok ? "!short, " : "",
215 req->actual, req->length);
218 code = min(code, (int) max);
223 return (buf > buffer) ? (buf - buffer) : code;
228 dump_end_info(struct musb *pThis, u8 bEnd, char *aBuffer, unsigned max)
232 struct musb_hw_ep *pEnd = &pThis->aLocalEnd[bEnd];
235 MGC_SelectEnd(pThis->pRegs, bEnd);
236 #ifdef CONFIG_USB_MUSB_HDRC_HCD
237 if (is_host_active(pThis)) {
238 int dump_rx, dump_tx;
239 void __iomem *regs = pEnd->regs;
241 /* TEMPORARY (!) until we have a real periodic
245 /* control is shared, uses RX queue
246 * but (mostly) shadowed tx registers
248 dump_tx = !list_empty(&pThis->control);
250 } else if (pEnd == pThis->bulk_ep) {
251 dump_tx = !list_empty(&pThis->out_bulk);
252 dump_rx = !list_empty(&pThis->in_bulk);
253 } else if (pThis->periodic[bEnd]) {
254 struct usb_host_endpoint *hep;
256 hep = pThis->periodic[bEnd]->hep;
257 dump_rx = hep->desc.bEndpointAddress
258 & USB_ENDPOINT_DIR_MASK;
265 /* FIXME for rx and tx dump hardware fifo and
266 * double-buffer flags ... and make register and stat
267 * dumps (mostly) usable on the peripheral side too
270 code = snprintf(buf, max,
271 "\nRX%d: rxcsr %04x interval %02x "
272 "max %04x type %02x; "
273 "dev %d hub %d port %d"
276 musb_readw(regs, MGC_O_HDRC_RXCSR),
277 musb_readb(regs, MGC_O_HDRC_RXINTERVAL),
278 musb_readw(regs, MGC_O_HDRC_RXMAXP),
279 musb_readb(regs, MGC_O_HDRC_RXTYPE),
280 /* FIXME: assumes multipoint */
281 musb_readb(pThis->pRegs,
282 MGC_BUSCTL_OFFSET(bEnd,
283 MGC_O_HDRC_RXFUNCADDR)),
284 musb_readb(pThis->pRegs,
285 MGC_BUSCTL_OFFSET(bEnd,
286 MGC_O_HDRC_RXHUBADDR)),
287 musb_readb(pThis->pRegs,
288 MGC_BUSCTL_OFFSET(bEnd,
289 MGC_O_HDRC_RXHUBPORT))
293 code = min(code, (int) max);
297 #ifdef CONFIG_USB_TI_CPPI_DMA
298 if (bEnd && pEnd->rx_channel) {
299 unsigned cppi = bEnd - 1;
300 unsigned off1 = cppi << 2;
305 base = pThis->ctrl_base;
306 ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
308 snprintf(tmp, sizeof tmp, "%d left, ",
310 DAVINCI_RXCPPI_BUFCNT0_REG
313 code = snprintf(buf, max,
315 "%08x %08x, %08x %08x; "
316 "%08x %08x %08x .. %08x\n",
318 musb_readl(ram, 0 * 4),
319 musb_readl(ram, 1 * 4),
320 musb_readl(ram, 2 * 4),
321 musb_readl(ram, 3 * 4),
322 musb_readl(ram, 4 * 4),
323 musb_readl(ram, 5 * 4),
324 musb_readl(ram, 6 * 4),
325 musb_readl(ram, 7 * 4));
328 code = min(code, (int) max);
333 if (pEnd == pThis->bulk_ep
336 code = dump_queue(&pThis->in_bulk,
340 code = min(code, (int) max);
343 } else if (pThis->periodic[bEnd]) {
344 code = dump_qh(pThis->periodic[bEnd],
348 code = min(code, (int) max);
355 code = snprintf(buf, max,
356 "\nTX%d: txcsr %04x interval %02x "
357 "max %04x type %02x; "
358 "dev %d hub %d port %d"
361 musb_readw(regs, MGC_O_HDRC_TXCSR),
362 musb_readb(regs, MGC_O_HDRC_TXINTERVAL),
363 musb_readw(regs, MGC_O_HDRC_TXMAXP),
364 musb_readb(regs, MGC_O_HDRC_TXTYPE),
365 /* FIXME: assumes multipoint */
366 musb_readb(pThis->pRegs,
367 MGC_BUSCTL_OFFSET(bEnd,
368 MGC_O_HDRC_TXFUNCADDR)),
369 musb_readb(pThis->pRegs,
370 MGC_BUSCTL_OFFSET(bEnd,
371 MGC_O_HDRC_TXHUBADDR)),
372 musb_readb(pThis->pRegs,
373 MGC_BUSCTL_OFFSET(bEnd,
374 MGC_O_HDRC_TXHUBPORT))
378 code = min(code, (int) max);
381 #ifdef CONFIG_USB_TI_CPPI_DMA
382 if (bEnd && pEnd->tx_channel) {
383 unsigned cppi = bEnd - 1;
387 base = pThis->ctrl_base;
388 ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
390 code = snprintf(buf, max,
392 "%08x %08x, %08x %08x; "
393 "%08x %08x %08x .. %08x\n",
395 musb_readl(ram, 0 * 4),
396 musb_readl(ram, 1 * 4),
397 musb_readl(ram, 2 * 4),
398 musb_readl(ram, 3 * 4),
399 musb_readl(ram, 4 * 4),
400 musb_readl(ram, 5 * 4),
401 musb_readl(ram, 6 * 4),
402 musb_readl(ram, 7 * 4));
405 code = min(code, (int) max);
410 if (pEnd == pThis->control_ep
413 code = dump_queue(&pThis->control,
417 code = min(code, (int) max);
420 } else if (pEnd == pThis->bulk_ep
423 code = dump_queue(&pThis->out_bulk,
427 code = min(code, (int) max);
430 } else if (pThis->periodic[bEnd]) {
431 code = dump_qh(pThis->periodic[bEnd],
435 code = min(code, (int) max);
442 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
443 if (is_peripheral_active(pThis)) {
446 if (pEnd->ep_in.desc || !bEnd) {
447 code = dump_ep(&pEnd->ep_in, buf, max);
450 code = min(code, (int) max);
454 if (pEnd->ep_out.desc) {
455 code = dump_ep(&pEnd->ep_out, buf, max);
458 code = min(code, (int) max);
466 return buf - aBuffer;
469 /** Dump the current status and compile options.
470 * @param pThis the device driver instance
471 * @param buffer where to dump the status; it must be big enough hold the
472 * result otherwise "BAD THINGS HAPPENS(TM)".
474 static int dump_header_stats(struct musb *pThis, char *buffer)
477 const void __iomem *pBase = pThis->pRegs;
480 count = sprintf(buffer, "Status: %sHDRC, Mode=%s "
481 "(Power=%02x, DevCtl=%02x)\n",
482 (pThis->bIsMultipoint ? "M" : ""), MUSB_MODE(pThis),
483 musb_readb(pBase, MGC_O_HDRC_POWER),
484 musb_readb(pBase, MGC_O_HDRC_DEVCTL));
489 code = sprintf(buffer, "OTG state: %s; %sactive\n",
490 otg_state_string(pThis),
491 pThis->is_active ? "" : "in");
497 code = sprintf(buffer,
499 #ifdef CONFIG_USB_INVENTRA_FIFO
501 #elif defined(CONFIG_USB_TI_CPPI_DMA)
503 #elif defined(CONFIG_USB_INVENTRA_DMA)
505 #elif defined(CONFIG_USB_TUSB_OMAP_DMA)
511 #ifdef CONFIG_USB_MUSB_OTG
512 "otg (peripheral+host)"
513 #elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
515 #elif defined(CONFIG_USB_MUSB_HDRC_HCD)
518 ", debug=%d [eps=%d]\n",
526 #ifdef CONFIG_ARCH_DAVINCI
527 code = sprintf(buffer,
528 "DaVinci: ctrl=%02x stat=%1x phy=%03x\n"
529 "\trndis=%05x auto=%04x intsrc=%08x intmsk=%08x"
531 musb_readl(pThis->ctrl_base, DAVINCI_USB_CTRL_REG),
532 musb_readl(pThis->ctrl_base, DAVINCI_USB_STAT_REG),
533 __raw_readl(IO_ADDRESS(USBPHY_CTL_PADDR)),
534 musb_readl(pThis->ctrl_base, DAVINCI_RNDIS_REG),
535 musb_readl(pThis->ctrl_base, DAVINCI_AUTOREQ_REG),
536 musb_readl(pThis->ctrl_base,
537 DAVINCI_USB_INT_SOURCE_REG),
538 musb_readl(pThis->ctrl_base,
539 DAVINCI_USB_INT_MASK_REG));
546 #ifdef CONFIG_USB_TUSB6010
547 code = sprintf(buffer,
548 "TUSB6010: devconf %08x, phy enable %08x drive %08x"
549 "\n\totg %03x timer %08x"
550 "\n\tprcm conf %08x mgmt %08x; intmask %08x"
552 musb_readl(pThis->ctrl_base, TUSB_DEV_CONF),
553 musb_readl(pThis->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE),
554 musb_readl(pThis->ctrl_base, TUSB_PHY_OTG_CTRL),
555 musb_readl(pThis->ctrl_base, TUSB_DEV_OTG_STAT),
556 musb_readl(pThis->ctrl_base, TUSB_DEV_OTG_TIMER),
557 musb_readl(pThis->ctrl_base, TUSB_PRCM_CONF),
558 musb_readl(pThis->ctrl_base, TUSB_PRCM_MNGMT),
559 musb_readl(pThis->ctrl_base, TUSB_INT_MASK));
566 #ifdef CONFIG_USB_TI_CPPI_DMA
567 if (pThis->pDmaController) {
568 code = sprintf(buffer,
569 "CPPI: txcr=%d txsrc=%01x txena=%01x; "
570 "rxcr=%d rxsrc=%01x rxena=%01x "
572 musb_readl(pThis->ctrl_base,
573 DAVINCI_TXCPPI_CTRL_REG),
574 musb_readl(pThis->ctrl_base,
575 DAVINCI_TXCPPI_RAW_REG),
576 musb_readl(pThis->ctrl_base,
577 DAVINCI_TXCPPI_INTENAB_REG),
578 musb_readl(pThis->ctrl_base,
579 DAVINCI_RXCPPI_CTRL_REG),
580 musb_readl(pThis->ctrl_base,
581 DAVINCI_RXCPPI_RAW_REG),
582 musb_readl(pThis->ctrl_base,
583 DAVINCI_RXCPPI_INTENAB_REG));
591 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
592 if (is_peripheral_enabled(pThis)) {
593 code = sprintf(buffer, "Gadget driver: %s\n",
595 ? pThis->pGadgetDriver->driver.name
614 * F force session (OTG-unfriendly)
615 * E rElinquish bus (OTG)
616 * H request host mode
617 * h cancel host request
618 * D<num> set/query the debug level
620 static int musb_proc_write(struct file *file, const char __user *buffer,
621 unsigned long count, void *data)
625 struct musb *musb = (struct musb *)data;
626 void __iomem *pBase = musb->pRegs;
628 /* MOD_INC_USE_COUNT; */
630 copy_from_user(&cmd, buffer, 1);
634 bReg = musb_readb(pBase, MGC_O_HDRC_POWER)
635 | MGC_M_POWER_SOFTCONN;
636 musb_writeb(pBase, MGC_O_HDRC_POWER, bReg);
642 bReg = musb_readb(pBase, MGC_O_HDRC_POWER)
643 & ~MGC_M_POWER_SOFTCONN;
644 musb_writeb(pBase, MGC_O_HDRC_POWER, bReg);
650 bReg = musb_readb(pBase, MGC_O_HDRC_POWER)
651 | MGC_M_POWER_HSENAB;
652 musb_writeb(pBase, MGC_O_HDRC_POWER, bReg);
658 bReg = musb_readb(pBase, MGC_O_HDRC_POWER)
659 & ~MGC_M_POWER_HSENAB;
660 musb_writeb(pBase, MGC_O_HDRC_POWER, bReg);
665 bReg = musb_readb(pBase, MGC_O_HDRC_DEVCTL);
666 bReg |= MGC_M_DEVCTL_SESSION;
667 musb_writeb(pBase, MGC_O_HDRC_DEVCTL, bReg);
672 bReg = musb_readb(pBase, MGC_O_HDRC_DEVCTL);
673 bReg |= MGC_M_DEVCTL_HR;
674 musb_writeb(pBase, MGC_O_HDRC_DEVCTL, bReg);
675 //MUSB_HST_MODE( ((struct musb*)data) );
676 //WARN("Host Mode\n");
682 bReg = musb_readb(pBase, MGC_O_HDRC_DEVCTL);
683 bReg &= ~MGC_M_DEVCTL_HR;
684 musb_writeb(pBase, MGC_O_HDRC_DEVCTL, bReg);
689 /* set/read debug level */
692 char digits[8], *p = digits;
693 int i = 0, level = 0, sign = 1;
694 int len = min(count - 1, (unsigned long)8);
696 copy_from_user(&digits, &buffer[1], len);
706 while (i++ < len && *p > '0' && *p < '9') {
707 level = level * 10 + (*p - '0');
712 DBG(1, "debug level %d\n", level);
720 INFO("?: you are seeing it\n");
721 INFO("C/c: soft connect enable/disable\n");
722 INFO("I/i: hispeed enable/disable\n");
723 INFO("F: force session start\n");
724 INFO("H: host mode\n");
725 INFO("D: set/read dbug level\n");
730 ERR("Command %c not implemented\n", cmd);
734 musb_platform_try_idle(musb);
739 static int musb_proc_read(char *page, char **start,
740 off_t off, int count, int *eof, void *data)
745 struct musb *pThis = data;
749 count -= 1; /* for NUL at end */
753 spin_lock_irqsave(&pThis->Lock, flags);
755 code = dump_header_stats(pThis, buffer);
761 /* generate the report for the end points */
762 // REVISIT ... not unless something's connected!
763 for (bEnd = 0; count >= 0 && bEnd < pThis->bEndCount;
765 code = dump_end_info(pThis, bEnd, buffer, count);
772 musb_platform_try_idle(pThis);
774 spin_unlock_irqrestore(&pThis->Lock, flags);
777 return (buffer - page) - off;
780 void __devexit musb_debug_delete(char *name, struct musb *musb)
782 if (musb->pProcEntry)
783 remove_proc_entry(name, NULL);
786 struct proc_dir_entry *__devinit
787 musb_debug_create(char *name, struct musb *data)
789 struct proc_dir_entry *pde;
791 /* FIXME convert everything to seq_file; then later, debugfs */
796 data->pProcEntry = pde = create_proc_entry(name,
797 S_IFREG | S_IRUGO | S_IWUSR, NULL);
800 // pde->owner = THIS_MODULE;
802 pde->read_proc = musb_proc_read;
803 pde->write_proc = musb_proc_write;
807 pr_debug("Registered /proc/%s\n", name);
809 pr_debug("Cannot create a valid proc file entry");