Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fsl/usb: Add controller version based ULPI and UTMI phy support

Add support for ULPI and UTMI PHYs based on usb controller
version info read from device-tree

Example of USB Controller versioning info:
Version 1.2 and below : MPC8536, MPC8315, etc
Version 1.6 : P1020, P1010, P2020, P5020, etc
Version 2.2 : PSC9131, PSC9132, P3060, etc

No changes for non-DT users

Signed-off-by: Ramneek Mehresh <ramneek.mehresh@freescale.com>
Acked-by: Li Yang <leoli@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Ramneek Mehresh and committed by
Greg Kroah-Hartman
58c559e6 67c88382

+123 -14
+23 -5
drivers/usb/gadget/fsl_udc_core.c
··· 1 1 /* 2 - * Copyright (C) 2004-2007,2011 Freescale Semiconductor, Inc. 2 + * Copyright (C) 2004-2007,2011-2012 Freescale Semiconductor, Inc. 3 3 * All rights reserved. 4 4 * 5 5 * Author: Li Yang <leoli@freescale.com> ··· 58 58 static const char driver_desc[] = DRIVER_DESC; 59 59 60 60 static struct usb_dr_device *dr_regs; 61 - #ifndef CONFIG_ARCH_MXC 61 + 62 62 static struct usb_sys_interface *usb_sys_regs; 63 - #endif 64 63 65 64 /* it is initialized in probe() */ 66 65 static struct fsl_udc *udc_controller = NULL; ··· 243 244 { 244 245 unsigned int tmp, portctrl, ep_num; 245 246 unsigned int max_no_of_ep; 246 - #ifndef CONFIG_ARCH_MXC 247 247 unsigned int ctrl; 248 - #endif 249 248 unsigned long timeout; 249 + 250 250 #define FSL_UDC_RESET_TIMEOUT 1000 251 251 252 252 /* Config PHY interface */ ··· 253 255 portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH); 254 256 switch (udc->phy_mode) { 255 257 case FSL_USB2_PHY_ULPI: 258 + if (udc->pdata->have_sysif_regs) { 259 + if (udc->pdata->controller_ver) { 260 + /* controller version 1.6 or above */ 261 + ctrl = __raw_readl(&usb_sys_regs->control); 262 + ctrl &= ~USB_CTRL_UTMI_PHY_EN; 263 + ctrl |= USB_CTRL_USB_EN; 264 + __raw_writel(ctrl, &usb_sys_regs->control); 265 + } 266 + } 256 267 portctrl |= PORTSCX_PTS_ULPI; 257 268 break; 258 269 case FSL_USB2_PHY_UTMI_WIDE: 259 270 portctrl |= PORTSCX_PTW_16BIT; 260 271 /* fall through */ 261 272 case FSL_USB2_PHY_UTMI: 273 + if (udc->pdata->have_sysif_regs) { 274 + if (udc->pdata->controller_ver) { 275 + /* controller version 1.6 or above */ 276 + ctrl = __raw_readl(&usb_sys_regs->control); 277 + ctrl |= (USB_CTRL_UTMI_PHY_EN | 278 + USB_CTRL_USB_EN); 279 + __raw_writel(ctrl, &usb_sys_regs->control); 280 + mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI 281 + PHY CLK to become stable - 10ms*/ 282 + } 283 + } 262 284 portctrl |= PORTSCX_PTS_UTMI; 263 285 break; 264 286 case FSL_USB2_PHY_SERIAL:
+11
drivers/usb/gadget/fsl_usb2_udc.h
··· 1 1 /* 2 + * Copyright (C) 2004,2012 Freescale Semiconductor, Inc 3 + * All rights reserved. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License as published by the 7 + * Free Software Foundation; either version 2 of the License, or (at your 8 + * option) any later version. 9 + * 2 10 * Freescale USB device/endpoint management registers 3 11 */ 4 12 #ifndef __FSL_USB2_UDC_H ··· 356 348 /* control Register Bit Masks */ 357 349 #define USB_CTRL_IOENB 0x00000004 358 350 #define USB_CTRL_ULPI_INT0EN 0x00000001 351 + #define USB_CTRL_UTMI_PHY_EN 0x00000200 352 + #define USB_CTRL_USB_EN 0x00000004 353 + #define USB_CTRL_ULPI_PHY_CLK_SEL 0x00000400 359 354 360 355 /* Endpoint Queue Head data struct 361 356 * Rem: all the variables of qh are LittleEndian Mode
+28 -7
drivers/usb/host/ehci-fsl.c
··· 1 1 /* 2 2 * Copyright 2005-2009 MontaVista Software, Inc. 3 - * Copyright 2008 Freescale Semiconductor, Inc. 3 + * Copyright 2008,2012 Freescale Semiconductor, Inc. 4 4 * 5 5 * This program is free software; you can redistribute it and/or modify it 6 6 * under the terms of the GNU General Public License as published by the ··· 211 211 usb_put_hcd(hcd); 212 212 } 213 213 214 - static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, 214 + static void ehci_fsl_setup_phy(struct usb_hcd *hcd, 215 215 enum fsl_usb2_phy_modes phy_mode, 216 216 unsigned int port_offset) 217 217 { 218 - u32 portsc; 219 - struct usb_hcd *hcd = ehci_to_hcd(ehci); 218 + u32 portsc, temp; 219 + struct ehci_hcd *ehci = hcd_to_ehci(hcd); 220 220 void __iomem *non_ehci = hcd->regs; 221 + struct device *dev = hcd->self.controller; 222 + struct fsl_usb2_platform_data *pdata = dev->platform_data; 223 + 224 + if (pdata->controller_ver < 0) { 225 + dev_warn(hcd->self.controller, "Could not get controller version\n"); 226 + return; 227 + } 221 228 222 229 portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); 223 230 portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); 224 231 225 232 switch (phy_mode) { 226 233 case FSL_USB2_PHY_ULPI: 234 + if (pdata->controller_ver) { 235 + /* controller version 1.6 or above */ 236 + temp = in_be32(non_ehci + FSL_SOC_USB_CTRL); 237 + out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 238 + USB_CTRL_USB_EN | ULPI_PHY_CLK_SEL); 239 + } 227 240 portsc |= PORT_PTS_ULPI; 228 241 break; 229 242 case FSL_USB2_PHY_SERIAL: ··· 246 233 portsc |= PORT_PTS_PTW; 247 234 /* fall through */ 248 235 case FSL_USB2_PHY_UTMI: 236 + if (pdata->controller_ver) { 237 + /* controller version 1.6 or above */ 238 + temp = in_be32(non_ehci + FSL_SOC_USB_CTRL); 239 + out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 240 + UTMI_PHY_EN | USB_CTRL_USB_EN); 241 + mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI PHY CLK to 242 + become stable - 10ms*/ 243 + } 249 244 /* enable UTMI PHY */ 250 245 setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN); 251 246 portsc |= PORT_PTS_UTMI; ··· 292 271 293 272 if ((pdata->operating_mode == FSL_USB2_DR_HOST) || 294 273 (pdata->operating_mode == FSL_USB2_DR_OTG)) 295 - ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0); 274 + ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0); 296 275 297 276 if (pdata->operating_mode == FSL_USB2_MPH_HOST) { 298 277 unsigned int chip, rev, svr; ··· 306 285 ehci->has_fsl_port_bug = 1; 307 286 308 287 if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) 309 - ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0); 288 + ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0); 310 289 if (pdata->port_enables & FSL_USB2_PORT1_ENABLED) 311 - ehci_fsl_setup_phy(ehci, pdata->phy_mode, 1); 290 + ehci_fsl_setup_phy(hcd, pdata->phy_mode, 1); 312 291 } 313 292 314 293 if (pdata->have_sysif_regs) {
+12 -1
drivers/usb/host/ehci-fsl.h
··· 1 - /* Copyright (C) 2005-2010 Freescale Semiconductor, Inc. 1 + /* Copyright (C) 2005-2010,2012 Freescale Semiconductor, Inc. 2 2 * Copyright (c) 2005 MontaVista Software 3 3 * 4 4 * This program is free software; you can redistribute it and/or modify it ··· 50 50 #define CTRL_UTMI_PHY_EN (1<<9) 51 51 #define CTRL_PHY_CLK_VALID (1 << 17) 52 52 #define SNOOP_SIZE_2GB 0x1e 53 + 54 + /* control Register Bit Masks */ 55 + #define ULPI_INT_EN (1<<0) 56 + #define WU_INT_EN (1<<1) 57 + #define USB_CTRL_USB_EN (1<<2) 58 + #define LINE_STATE_FILTER__EN (1<<3) 59 + #define KEEP_OTG_ON (1<<4) 60 + #define OTG_PORT (1<<5) 61 + #define PLL_RESET (1<<8) 62 + #define UTMI_PHY_EN (1<<9) 63 + #define ULPI_PHY_CLK_SEL (1<<10) 53 64 #endif /* _EHCI_FSL_H */
+41
drivers/usb/host/fsl-mph-dr-of.c
··· 119 119 120 120 static const struct of_device_id fsl_usb2_mph_dr_of_match[]; 121 121 122 + static int usb_get_ver_info(struct device_node *np) 123 + { 124 + int ver = -1; 125 + 126 + /* 127 + * returns 1 for usb controller version 1.6 128 + * returns 2 for usb controller version 2.2 129 + * returns 0 otherwise 130 + */ 131 + if (of_device_is_compatible(np, "fsl-usb2-dr")) { 132 + if (of_device_is_compatible(np, "fsl-usb2-dr-v1.6")) 133 + ver = FSL_USB_VER_1_6; 134 + else if (of_device_is_compatible(np, "fsl-usb2-dr-v2.2")) 135 + ver = FSL_USB_VER_2_2; 136 + else /* for previous controller versions */ 137 + ver = FSL_USB_VER_OLD; 138 + 139 + if (ver > -1) 140 + return ver; 141 + } 142 + 143 + if (of_device_is_compatible(np, "fsl-usb2-mph")) { 144 + if (of_device_is_compatible(np, "fsl-usb2-mph-v1.6")) 145 + ver = FSL_USB_VER_1_6; 146 + else if (of_device_is_compatible(np, "fsl-usb2-mph-v2.2")) 147 + ver = FSL_USB_VER_2_2; 148 + else /* for previous controller versions */ 149 + ver = FSL_USB_VER_OLD; 150 + } 151 + 152 + return ver; 153 + } 154 + 122 155 static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) 123 156 { 124 157 struct device_node *np = ofdev->dev.of_node; ··· 199 166 200 167 prop = of_get_property(np, "phy_type", NULL); 201 168 pdata->phy_mode = determine_usb_phy(prop); 169 + pdata->controller_ver = usb_get_ver_info(np); 170 + 171 + if (pdata->have_sysif_regs) { 172 + if (pdata->controller_ver < 0) { 173 + dev_warn(&ofdev->dev, "Could not get controller version\n"); 174 + return -ENODEV; 175 + } 176 + } 202 177 203 178 for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) { 204 179 if (!dev_data->drivers[i])
+8 -1
include/linux/fsl_devices.h
··· 6 6 * 7 7 * Maintainer: Kumar Gala <galak@kernel.crashing.org> 8 8 * 9 - * Copyright 2004 Freescale Semiconductor, Inc 9 + * Copyright 2004,2012 Freescale Semiconductor, Inc 10 10 * 11 11 * This program is free software; you can redistribute it and/or modify it 12 12 * under the terms of the GNU General Public License as published by the ··· 16 16 17 17 #ifndef _FSL_DEVICE_H_ 18 18 #define _FSL_DEVICE_H_ 19 + 20 + #define FSL_UTMI_PHY_DLY 10 /*As per P1010RM, delay for UTMI 21 + PHY CLK to become stable - 10ms*/ 22 + #define FSL_USB_VER_OLD 0 23 + #define FSL_USB_VER_1_6 1 24 + #define FSL_USB_VER_2_2 2 19 25 20 26 #include <linux/types.h> 21 27 ··· 69 63 70 64 struct fsl_usb2_platform_data { 71 65 /* board specific information */ 66 + int controller_ver; 72 67 enum fsl_usb2_operating_modes operating_mode; 73 68 enum fsl_usb2_phy_modes phy_mode; 74 69 unsigned int port_enables;