1 /*
2  * TI's Davinci platform specific USB wrapper functions.
3  *
4  * Copyright (c) 2008 Texas Instruments
5  *
6  * SPDX-License-Identifier:	GPL-2.0+
7  *
8  * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
9  */
10 
11 #include <common.h>
12 #include <asm/io.h>
13 #include "davinci.h"
14 #include <asm/arch/hardware.h>
15 
16 #if !defined(CONFIG_DV_USBPHY_CTL)
17 #define CONFIG_DV_USBPHY_CTL (USBPHY_SESNDEN | USBPHY_VBDTCTEN)
18 #endif
19 
20 /* MUSB platform configuration */
21 struct musb_config musb_cfg = {
22 	.regs		= (struct musb_regs *)MENTOR_USB0_BASE,
23 	.timeout	= DAVINCI_USB_TIMEOUT,
24 	.musb_speed	= 0,
25 };
26 
27 /* MUSB module register overlay */
28 struct davinci_usb_regs *dregs;
29 
30 /*
31  * Enable the USB phy
32  */
phy_on(void)33 static u8 phy_on(void)
34 {
35 	u32 timeout;
36 #ifdef DAVINCI_DM365EVM
37 	u32 val;
38 #endif
39 	/* Wait until the USB phy is turned on */
40 #ifdef DAVINCI_DM365EVM
41 	writel(USBPHY_PHY24MHZ | USBPHY_SESNDEN |
42 			USBPHY_VBDTCTEN, USBPHY_CTL_PADDR);
43 #else
44 	writel(CONFIG_DV_USBPHY_CTL, USBPHY_CTL_PADDR);
45 #endif
46 	timeout = musb_cfg.timeout;
47 
48 #ifdef DAVINCI_DM365EVM
49 	/* Set the ownership of GIO33 to USB */
50 	val = readl(PINMUX4);
51 	val &= ~(PINMUX4_USBDRVBUS_BITCLEAR);
52 	val |= PINMUX4_USBDRVBUS_BITSET;
53 	writel(val, PINMUX4);
54 #endif
55 	while (timeout--)
56 		if (readl(USBPHY_CTL_PADDR) & USBPHY_PHYCLKGD)
57 			return 1;
58 
59 	/* USB phy was not turned on */
60 	return 0;
61 }
62 
63 /*
64  * Disable the USB phy
65  */
phy_off(void)66 static void phy_off(void)
67 {
68 	/* powerdown the on-chip PHY and its oscillator */
69 	writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN, USBPHY_CTL_PADDR);
70 }
71 
__enable_vbus(void)72 void __enable_vbus(void)
73 {
74 	/*
75 	 *  nothing to do, vbus is handled through the cpu.
76 	 *  Define this function in board code, if it is
77 	 *  different on your board.
78 	 */
79 }
80 void  enable_vbus(void)
81 	__attribute__((weak, alias("__enable_vbus")));
82 
83 /*
84  * This function performs Davinci platform specific initialization for usb0.
85  */
musb_platform_init(void)86 int musb_platform_init(void)
87 {
88 	u32  revision;
89 
90 	/* enable USB VBUS */
91 	enable_vbus();
92 
93 	/* start the on-chip USB phy and its pll */
94 	if (!phy_on())
95 		return -1;
96 
97 	/* reset the controller */
98 	dregs = (struct davinci_usb_regs *)DAVINCI_USB0_BASE;
99 	writel(1, &dregs->ctrlr);
100 	udelay(5000);
101 
102 	/* Returns zero if e.g. not clocked */
103 	revision = readl(&dregs->version);
104 	if (!revision)
105 		return -1;
106 
107 	/* Disable all interrupts */
108 	writel(DAVINCI_USB_USBINT_MASK | DAVINCI_USB_RXINT_MASK |
109 			DAVINCI_USB_TXINT_MASK , &dregs->intmsksetr);
110 	return 0;
111 }
112 
113 /*
114  * This function performs Davinci platform specific deinitialization for usb0.
115  */
musb_platform_deinit(void)116 void musb_platform_deinit(void)
117 {
118 	/* Turn of the phy */
119 	phy_off();
120 
121 	/* flush any interrupts */
122 	writel(DAVINCI_USB_USBINT_MASK | DAVINCI_USB_TXINT_MASK |
123 			DAVINCI_USB_RXINT_MASK , &dregs->intclrr);
124 }
125