summaryrefslogtreecommitdiff
path: root/drivers/usb/da8xx_usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/da8xx_usb.c')
-rw-r--r--drivers/usb/da8xx_usb.c213
1 files changed, 213 insertions, 0 deletions
diff --git a/drivers/usb/da8xx_usb.c b/drivers/usb/da8xx_usb.c
new file mode 100644
index 0000000000..5dd5f12393
--- /dev/null
+++ b/drivers/usb/da8xx_usb.c
@@ -0,0 +1,213 @@
+/*
+ * TI's DA8xx platform specific usb wrapper functions.
+ *
+ * Copyright (c) 2004 Texas Instruments
+ *
+ * This package is free software; you can redistribute it and/or
+ * modify it under the terms of the license found in the file
+ * named COPYING that should have accompanied this file.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
+ *
+ * Copyright (c) 2003 Wolfgang Denk, wd@denx.de
+ *
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_USB_DA8XX
+
+#include "da8xx_usb.h"
+
+/* extern functions */
+extern void lpsc_on(unsigned int id);
+
+/* Timeout for DA8xx usb module */
+#define DA8XX_USB_TIMEOUT 0x3FFFF
+
+
+/* This function writes to a 32-bit register of platform usb wrapper */
+inline void pusb_writel( u32 offset , u32 value )
+{
+ *(volatile u32*)(DA8XX_USB0_BASE+offset) = value;
+}
+
+/* This function reads a 32-bit register of platform usb wrapper */
+inline u32 pusb_readl(u32 offset)
+{
+ return(*(volatile u32*)(DA8XX_USB0_BASE+offset));
+}
+
+/* This function writes to a 16-bit register of platform musb core */
+inline void musb_writew(u32 offset, u16 value)
+{
+ *(volatile u16*)(MENTOR_USB0_BASE+offset) = value;
+}
+
+/* This function writes to a 8-bit register of platform musb core */
+inline void musb_writeb(u32 offset, u8 value)
+{
+ *(volatile u8*)(MENTOR_USB0_BASE+offset) = value;
+}
+
+/* This function reads a 16-bit register of platform usb wrapper */
+inline u16 musb_readw(u32 offset)
+{
+ return(*(volatile u16*)(MENTOR_USB0_BASE + offset));
+}
+
+/* This function reads a 8-bit register of platform usb wrapper */
+inline u8 musb_readb(u32 offset)
+{
+ return(*(volatile u8*)(MENTOR_USB0_BASE+offset));
+}
+
+/*
+ * This function enables VBUS by driving the GPIO Bank4 Pin 15 high.
+ */
+static void enable_vbus(void)
+{
+ u32 value;
+
+ /* configure GPIO bank4 pin 15 in output direction */
+ value = *(volatile u32 *)GPIO_BANK4_REG_DIR_ADDR;
+ value &= ~0x8000;
+ *(volatile u32 *)GPIO_BANK4_REG_DIR_ADDR = value;
+
+ /* set GPIO bank4 pin 15 high to drive VBUS */
+ value = *(volatile u32 *)GPIO_BANK4_REG_SET_ADDR;
+ value |= 0x8000;
+ *(volatile u32 *)GPIO_BANK4_REG_SET_ADDR = value;
+}
+
+/*
+ * Enable the usb0 phy. This initialization procedure is explained in
+ * the DA8xx USB user guide document.
+ */
+static u8 phy_on( void )
+{
+ u32 timeout;
+ u8 result = 1;
+
+ /* write access keys */
+ *(volatile u32 *)(KICK0) = 0x83e70b13;
+ *(volatile u32 *)(KICK1) = 0x95a4f1e0;
+
+
+#ifdef CONFIG_USE_PINMUX
+
+ /* set PINMUX[7:4] = 1 */
+ *(volatile u32 *)(PINMUX9) |= ( 1 << 4 );
+ *(volatile u32 *)(PINMUX9) &= 0xFFFFFF7F;
+
+#endif
+
+ /* reset the usb controller */
+ pusb_writel( DA8XX_USB_CTRL_REG , 0x1 );
+ udelay( 5000 );
+
+ /* enable and then disable the usb phy reset */
+ *(volatile u32*)CFGCHIP2 |= 0x00008000;
+ udelay( 5000 );
+ *(volatile u32*)CFGCHIP2 &= 0xFFFF7FFF;
+ udelay( 5000 );
+
+ /* configure phy (refer to da8xx usb user guide use case section) */
+ *(volatile u32*)CFGCHIP2 &= 0xFFFF9FFF;
+ *(volatile u32*)CFGCHIP2 &= 0xFFFFFBFF;
+ *(volatile u32*)CFGCHIP2 &= 0xFFFFFDFF;
+ *(volatile u32*)CFGCHIP2 |= 0x00000100;
+ *(volatile u32*)CFGCHIP2 |= 0x00000020;
+ *(volatile u32*)CFGCHIP2 |= 0x00000010;
+ *(volatile u32*)CFGCHIP2 |= 0x00000002;
+ *(volatile u32*)CFGCHIP2 &= 0xFFFFE7FF;
+ *(volatile u32*)CFGCHIP2 |= 0x00000800;
+
+ *(volatile u32*)CFGCHIP2 &= 0xFFFF9FFF;
+ *(volatile u32*)CFGCHIP2 |= 0x00002000;
+ *(volatile u32*)CFGCHIP2 |= 0x00000040;
+
+ /* wait until the usb phy pll locks */
+ timeout = DA8XX_USB_TIMEOUT;
+ do {
+ timeout--;
+ if (timeout == 0)
+ break;
+ }
+ while(((*(volatile u32*)CFGCHIP2) & 0x00020000) == 0);
+
+ /* disable register access by writing invalid keys */
+ *(volatile u32 *)(0x01C14038) = 0x0;
+ *(volatile u32 *)(0x01C1403C) = 0x0;
+
+ if (timeout == 0)
+ result = 0;
+
+ return(result);
+}
+
+/*
+ * Disable the usb phy
+ */
+static void phy_off(void)
+{
+ /* write access keys */
+ *(volatile u32 *)(KICK0) = 0;
+ *(volatile u32 *)(KICK1) = 0;
+
+ /* powerdown the on-chip PHY and its oscillator */
+ *(volatile u32*)(CFGCHIP2) = 0x8600;
+}
+
+
+/*
+ * This function performs DA8xx platform specific initialization for usb0.
+ */
+int musb_platform_init(void)
+{
+ u32 revision;
+
+ /* enable psc for usb2.0 */
+ lpsc_on(33);
+
+ /* enable usb vbus */
+ enable_vbus();
+
+ /* start the on-chip usb phy and its pll */
+ if (phy_on() == 0)
+ return(-1);
+
+ /* reset the controller */
+ pusb_writel(DA8XX_USB_CTRL_REG, 0x1);
+ udelay(5000);
+
+ /* Returns zero if e.g. not clocked */
+ revision = pusb_readl(DA8XX_USB_VERSION_REG);
+ if (revision == 0)
+ return(-1);
+
+ /* Disable all interrupts */
+ pusb_writel(DA8XX_USB_INT_MASK_SET_REG, 0x01FF1F1F);
+ return(0);
+}
+
+
+/*
+ * This function performs DA8xx platform specific deinitialization for usb0.
+ */
+void musb_platform_deinit(void)
+{
+ /* Turn of the phy */
+ phy_off();
+
+ /* flush any interrupts */
+ pusb_writel(DA8XX_USB_INT_MASK_CLR_REG, DA8XX_USB_USBINT_MASK|DA8XX_USB_TXINT_MASK|DA8XX_USB_RXINT_MASK);
+ pusb_writel(DA8XX_USB_EOI_REG, 0);
+}
+
+#endif /* CONFIG_USB_DA8XX */
+