1 /* 2 * da8xx.c - TI's DA8xx platform specific usb wrapper functions. 3 * 4 * Author: Ajay Kumar Gupta <ajay.gupta@ti.com> 5 * 6 * Based on drivers/usb/musb/davinci.c 7 * 8 * Copyright (C) 2009 Texas Instruments Incorporated 9 * 10 * SPDX-License-Identifier: GPL-2.0+ 11 */ 12 #include <common.h> 13 14 #include "musb_core.h" 15 #include <asm/arch/da8xx-usb.h> 16 17 /* MUSB platform configuration */ 18 struct musb_config musb_cfg = { 19 .regs = (struct musb_regs *)DA8XX_USB_OTG_CORE_BASE, 20 .timeout = DA8XX_USB_OTG_TIMEOUT, 21 .musb_speed = 0, 22 }; 23 24 /* 25 * This function enables VBUS by driving the GPIO Bank4 Pin 15 high. 26 */ 27 static void enable_vbus(void) 28 { 29 u32 value; 30 31 /* configure GPIO bank4 pin 15 in output direction */ 32 value = readl(&davinci_gpio_bank45->dir); 33 writel((value & (~DA8XX_USB_VBUS_GPIO)), &davinci_gpio_bank45->dir); 34 35 /* set GPIO bank4 pin 15 high to drive VBUS */ 36 value = readl(&davinci_gpio_bank45->set_data); 37 writel((value | DA8XX_USB_VBUS_GPIO), &davinci_gpio_bank45->set_data); 38 } 39 40 /* 41 * Enable the usb0 phy. This initialization procedure is explained in 42 * the DA8xx USB user guide document. 43 */ 44 static u8 phy_on(void) 45 { 46 u32 timeout; 47 u32 cfgchip2; 48 49 cfgchip2 = readl(&davinci_syscfg_regs->cfgchip2); 50 51 cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN | 52 CFGCHIP2_OTGMODE | CFGCHIP2_REFFREQ); 53 cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN | CFGCHIP2_PHY_PLLON | 54 CFGCHIP2_REFFREQ_24MHZ; 55 56 writel(cfgchip2, &davinci_syscfg_regs->cfgchip2); 57 58 /* wait until the usb phy pll locks */ 59 timeout = musb_cfg.timeout; 60 while (timeout--) 61 if (readl(&davinci_syscfg_regs->cfgchip2) & CFGCHIP2_PHYCLKGD) 62 return 1; 63 64 /* USB phy was not turned on */ 65 return 0; 66 } 67 68 /* 69 * Disable the usb phy 70 */ 71 static void phy_off(void) 72 { 73 u32 cfgchip2; 74 75 /* 76 * Power down the on-chip PHY. 77 */ 78 cfgchip2 = readl(&davinci_syscfg_regs->cfgchip2); 79 cfgchip2 &= ~CFGCHIP2_PHY_PLLON; 80 cfgchip2 |= CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN; 81 writel(cfgchip2, &davinci_syscfg_regs->cfgchip2); 82 } 83 84 /* 85 * This function performs DA8xx platform specific initialization for usb0. 86 */ 87 int musb_platform_init(void) 88 { 89 u32 revision; 90 91 /* enable psc for usb2.0 */ 92 lpsc_on(33); 93 94 /* enable usb vbus */ 95 enable_vbus(); 96 97 /* reset the controller */ 98 writel(0x1, &da8xx_usb_regs->control); 99 udelay(5000); 100 101 /* start the on-chip usb phy and its pll */ 102 if (phy_on() == 0) 103 return -1; 104 105 /* Returns zero if e.g. not clocked */ 106 revision = readl(&da8xx_usb_regs->revision); 107 if (revision == 0) 108 return -1; 109 110 /* Disable all interrupts */ 111 writel((DA8XX_USB_USBINT_MASK | DA8XX_USB_TXINT_MASK | 112 DA8XX_USB_RXINT_MASK), &da8xx_usb_regs->intmsk_set); 113 return 0; 114 } 115 116 /* 117 * This function performs DA8xx platform specific deinitialization for usb0. 118 */ 119 void musb_platform_deinit(void) 120 { 121 /* Turn of the phy */ 122 phy_off(); 123 124 /* flush any interrupts */ 125 writel((DA8XX_USB_USBINT_MASK | DA8XX_USB_TXINT_MASK | 126 DA8XX_USB_RXINT_MASK), &da8xx_usb_regs->intmsk_clr); 127 writel(0, &da8xx_usb_regs->eoi); 128 } 129