summaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/davinci.c
blob: 359c635bf6aff8ddf77edfb29166e2f58a789efc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * TI's Davinci platform specific USB wrapper functions.
 *
 * Copyright (c) 2008 Texas Instruments
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 *
 * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
 */

#include <common.h>
#include <asm/io.h>
#include "davinci.h"
#include <asm/arch/hardware.h>

#if !defined(CONFIG_DV_USBPHY_CTL)
#define CONFIG_DV_USBPHY_CTL (USBPHY_SESNDEN | USBPHY_VBDTCTEN)
#endif

/* MUSB platform configuration */
struct musb_config musb_cfg = {
	.regs		= (struct musb_regs *)MENTOR_USB0_BASE,
	.timeout	= DAVINCI_USB_TIMEOUT,
	.musb_speed	= 0,
};

/* MUSB module register overlay */
struct davinci_usb_regs *dregs;

/*
 * Enable the USB phy
 */
static u8 phy_on(void)
{
	u32 timeout;
#ifdef DAVINCI_DM365EVM
	u32 val;
#endif
	/* Wait until the USB phy is turned on */
#ifdef DAVINCI_DM365EVM
	writel(USBPHY_PHY24MHZ | USBPHY_SESNDEN |
			USBPHY_VBDTCTEN, USBPHY_CTL_PADDR);
#else
	writel(CONFIG_DV_USBPHY_CTL, USBPHY_CTL_PADDR);
#endif
	timeout = musb_cfg.timeout;

#ifdef DAVINCI_DM365EVM
	/* Set the ownership of GIO33 to USB */
	val = readl(PINMUX4);
	val &= ~(PINMUX4_USBDRVBUS_BITCLEAR);
	val |= PINMUX4_USBDRVBUS_BITSET;
	writel(val, PINMUX4);
#endif
	while (timeout--)
		if (readl(USBPHY_CTL_PADDR) & USBPHY_PHYCLKGD)
			return 1;

	/* USB phy was not turned on */
	return 0;
}

/*
 * Disable the USB phy
 */
static void phy_off(void)
{
	/* powerdown the on-chip PHY and its oscillator */
	writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN, USBPHY_CTL_PADDR);
}

void __enable_vbus(void)
{
	/*
	 *  nothing to do, vbus is handled through the cpu.
	 *  Define this function in board code, if it is
	 *  different on your board.
	 */
}
void  enable_vbus(void)
	__attribute__((weak, alias("__enable_vbus")));

/*
 * This function performs Davinci platform specific initialization for usb0.
 */
int musb_platform_init(void)
{
	u32  revision;

	/* enable USB VBUS */
	enable_vbus();

	/* start the on-chip USB phy and its pll */
	if (!phy_on())
		return -1;

	/* reset the controller */
	dregs = (struct davinci_usb_regs *)DAVINCI_USB0_BASE;
	writel(1, &dregs->ctrlr);
	udelay(5000);

	/* Returns zero if e.g. not clocked */
	revision = readl(&dregs->version);
	if (!revision)
		return -1;

	/* Disable all interrupts */
	writel(DAVINCI_USB_USBINT_MASK | DAVINCI_USB_RXINT_MASK |
			DAVINCI_USB_TXINT_MASK , &dregs->intmsksetr);
	return 0;
}

/*
 * This function performs Davinci platform specific deinitialization for usb0.
 */
void musb_platform_deinit(void)
{
	/* Turn of the phy */
	phy_off();

	/* flush any interrupts */
	writel(DAVINCI_USB_USBINT_MASK | DAVINCI_USB_TXINT_MASK |
			DAVINCI_USB_RXINT_MASK , &dregs->intclrr);
}
OpenPOWER on IntegriCloud