aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap_phy_internal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/omap_phy_internal.c')
-rw-r--r--arch/arm/mach-omap2/omap_phy_internal.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c
index ebe33df708bd..e2e605fe9138 100644
--- a/arch/arm/mach-omap2/omap_phy_internal.c
+++ b/arch/arm/mach-omap2/omap_phy_internal.c
@@ -29,6 +29,7 @@
29#include <linux/usb.h> 29#include <linux/usb.h>
30 30
31#include <plat/usb.h> 31#include <plat/usb.h>
32#include "control.h"
32 33
33/* OMAP control module register for UTMI PHY */ 34/* OMAP control module register for UTMI PHY */
34#define CONTROL_DEV_CONF 0x300 35#define CONTROL_DEV_CONF 0x300
@@ -162,3 +163,95 @@ int omap4430_phy_exit(struct device *dev)
162 163
163 return 0; 164 return 0;
164} 165}
166
167void am35x_musb_reset(void)
168{
169 u32 regval;
170
171 /* Reset the musb interface */
172 regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
173
174 regval |= AM35XX_USBOTGSS_SW_RST;
175 omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
176
177 regval &= ~AM35XX_USBOTGSS_SW_RST;
178 omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
179
180 regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
181}
182
183void am35x_musb_phy_power(u8 on)
184{
185 unsigned long timeout = jiffies + msecs_to_jiffies(100);
186 u32 devconf2;
187
188 if (on) {
189 /*
190 * Start the on-chip PHY and its PLL.
191 */
192 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
193
194 devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN);
195 devconf2 |= CONF2_PHY_PLLON;
196
197 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
198
199 pr_info(KERN_INFO "Waiting for PHY clock good...\n");
200 while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2)
201 & CONF2_PHYCLKGD)) {
202 cpu_relax();
203
204 if (time_after(jiffies, timeout)) {
205 pr_err(KERN_ERR "musb PHY clock good timed out\n");
206 break;
207 }
208 }
209 } else {
210 /*
211 * Power down the on-chip PHY.
212 */
213 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
214
215 devconf2 &= ~CONF2_PHY_PLLON;
216 devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN;
217 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
218 }
219}
220
221void am35x_musb_clear_irq(void)
222{
223 u32 regval;
224
225 regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
226 regval |= AM35XX_USBOTGSS_INT_CLR;
227 omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
228 regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
229}
230
231void am35x_musb_set_mode(u8 musb_mode)
232{
233 u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
234
235 devconf2 &= ~CONF2_OTGMODE;
236 switch (musb_mode) {
237#ifdef CONFIG_USB_MUSB_HDRC_HCD
238 case MUSB_HOST: /* Force VBUS valid, ID = 0 */
239 devconf2 |= CONF2_FORCE_HOST;
240 break;
241#endif
242#ifdef CONFIG_USB_GADGET_MUSB_HDRC
243 case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */
244 devconf2 |= CONF2_FORCE_DEVICE;
245 break;
246#endif
247#ifdef CONFIG_USB_MUSB_OTG
248 case MUSB_OTG: /* Don't override the VBUS/ID comparators */
249 devconf2 |= CONF2_NO_OVERRIDE;
250 break;
251#endif
252 default:
253 pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode);
254 }
255
256 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
257}