1 /* 2 * am35x.c - TI's AM35x platform specific usb wrapper functions. 3 * 4 * Author: Ajay Kumar Gupta <ajay.gupta@ti.com> 5 * 6 * Based on drivers/usb/musb/da8xx.c 7 * 8 * Copyright (c) 2010 Texas Instruments Incorporated 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 */ 24 #include <common.h> 25 26 #include "am35x.h" 27 28 /* MUSB platform configuration */ 29 struct musb_config musb_cfg = { 30 .regs = (struct musb_regs *)AM35X_USB_OTG_CORE_BASE, 31 .timeout = AM35X_USB_OTG_TIMEOUT, 32 .musb_speed = 0, 33 }; 34 35 /* 36 * Enable the USB phy 37 */ 38 static u8 phy_on(void) 39 { 40 u32 devconf2; 41 u32 timeout; 42 43 devconf2 = readl(&am35x_scm_general_regs->devconf2); 44 45 devconf2 &= ~(DEVCONF2_RESET | DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN | 46 DEVCONF2_OTGMODE | DEVCONF2_REFFREQ | 47 DEVCONF2_PHY_GPIOMODE); 48 devconf2 |= DEVCONF2_SESENDEN | DEVCONF2_VBDTCTEN | DEVCONF2_PHY_PLLON | 49 DEVCONF2_REFFREQ_13MHZ | DEVCONF2_DATPOL; 50 51 writel(devconf2, &am35x_scm_general_regs->devconf2); 52 53 /* wait until the USB phy is turned on */ 54 timeout = musb_cfg.timeout; 55 while (timeout--) 56 if (readl(&am35x_scm_general_regs->devconf2) & DEVCONF2_PHYCKGD) 57 return 1; 58 59 /* USB phy was not turned on */ 60 return 0; 61 } 62 63 /* 64 * Disable the USB phy 65 */ 66 static void phy_off(void) 67 { 68 u32 devconf2; 69 70 /* 71 * Power down the on-chip PHY. 72 */ 73 devconf2 = readl(&am35x_scm_general_regs->devconf2); 74 75 devconf2 &= ~DEVCONF2_PHY_PLLON; 76 devconf2 |= DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN; 77 writel(devconf2, &am35x_scm_general_regs->devconf2); 78 } 79 80 /* 81 * This function performs platform specific initialization for usb0. 82 */ 83 int musb_platform_init(void) 84 { 85 u32 revision; 86 u32 sw_reset; 87 88 /* global usb reset */ 89 sw_reset = readl(&am35x_scm_general_regs->ip_sw_reset); 90 sw_reset |= (1 << 0); 91 writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset); 92 sw_reset &= ~(1 << 0); 93 writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset); 94 95 /* reset the controller */ 96 writel(0x1, &am35x_usb_regs->control); 97 udelay(5000); 98 99 /* start the on-chip usb phy and its pll */ 100 if (phy_on() == 0) 101 return -1; 102 103 /* Returns zero if e.g. not clocked */ 104 revision = readl(&am35x_usb_regs->revision); 105 if (revision == 0) 106 return -1; 107 108 return 0; 109 } 110 111 /* 112 * This function performs platform specific deinitialization for usb0. 113 */ 114 void musb_platform_deinit(void) 115 { 116 /* Turn off the phy */ 117 phy_off(); 118 } 119 120 /* 121 * This function reads data from endpoint fifo for AM35x 122 * which supports only 32bit read operation. 123 * 124 * ep - endpoint number 125 * length - number of bytes to read from FIFO 126 * fifo_data - pointer to data buffer into which data is read 127 */ 128 __attribute__((weak)) 129 void read_fifo(u8 ep, u32 length, void *fifo_data) 130 { 131 u8 *data = (u8 *)fifo_data; 132 u32 val; 133 int i; 134 135 /* select the endpoint index */ 136 writeb(ep, &musbr->index); 137 138 if (length > 4) { 139 for (i = 0; i < (length >> 2); i++) { 140 val = readl(&musbr->fifox[ep]); 141 memcpy(data, &val, 4); 142 data += 4; 143 } 144 length %= 4; 145 } 146 if (length > 0) { 147 val = readl(&musbr->fifox[ep]); 148 memcpy(data, &val, length); 149 } 150 } 151