Commit 58c559e6509f276d0afb4621b2122e994e70160c
Committed by
Greg Kroah-Hartman
1 parent
67c88382e0
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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>
Showing 6 changed files with 123 additions and 14 deletions Side-by-side Diff
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> |
6 | 6 | |
... | ... | @@ -58,9 +58,8 @@ |
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; |
67 | 66 | |
68 | 67 | |
... | ... | @@ -244,10 +243,9 @@ |
244 | 243 | { |
245 | 244 | unsigned int tmp, portctrl, ep_num; |
246 | 245 | unsigned int max_no_of_ep; |
247 | -#ifndef CONFIG_ARCH_MXC | |
248 | 246 | unsigned int ctrl; |
249 | -#endif | |
250 | 247 | unsigned long timeout; |
248 | + | |
251 | 249 | #define FSL_UDC_RESET_TIMEOUT 1000 |
252 | 250 | |
253 | 251 | /* Config PHY interface */ |
254 | 252 | |
... | ... | @@ -255,12 +253,32 @@ |
255 | 253 | portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH); |
256 | 254 | switch (udc->phy_mode) { |
257 | 255 | case FSL_USB2_PHY_ULPI: |
256 | + if (udc->pdata->have_sysif_regs) { | |
257 | + if (udc->pdata->controller_ver) { | |
258 | + /* controller version 1.6 or above */ | |
259 | + ctrl = __raw_readl(&usb_sys_regs->control); | |
260 | + ctrl &= ~USB_CTRL_UTMI_PHY_EN; | |
261 | + ctrl |= USB_CTRL_USB_EN; | |
262 | + __raw_writel(ctrl, &usb_sys_regs->control); | |
263 | + } | |
264 | + } | |
258 | 265 | portctrl |= PORTSCX_PTS_ULPI; |
259 | 266 | break; |
260 | 267 | case FSL_USB2_PHY_UTMI_WIDE: |
261 | 268 | portctrl |= PORTSCX_PTW_16BIT; |
262 | 269 | /* fall through */ |
263 | 270 | case FSL_USB2_PHY_UTMI: |
271 | + if (udc->pdata->have_sysif_regs) { | |
272 | + if (udc->pdata->controller_ver) { | |
273 | + /* controller version 1.6 or above */ | |
274 | + ctrl = __raw_readl(&usb_sys_regs->control); | |
275 | + ctrl |= (USB_CTRL_UTMI_PHY_EN | | |
276 | + USB_CTRL_USB_EN); | |
277 | + __raw_writel(ctrl, &usb_sys_regs->control); | |
278 | + mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI | |
279 | + PHY CLK to become stable - 10ms*/ | |
280 | + } | |
281 | + } | |
264 | 282 | portctrl |= PORTSCX_PTS_UTMI; |
265 | 283 | break; |
266 | 284 | case FSL_USB2_PHY_SERIAL: |
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 |
... | ... | @@ -348,6 +356,9 @@ |
348 | 356 | /* control Register Bit Masks */ |
349 | 357 | #define USB_CTRL_IOENB 0x00000004 |
350 | 358 | #define USB_CTRL_ULPI_INT0EN 0x00000001 |
359 | +#define USB_CTRL_UTMI_PHY_EN 0x00000200 | |
360 | +#define USB_CTRL_USB_EN 0x00000004 | |
361 | +#define USB_CTRL_ULPI_PHY_CLK_SEL 0x00000400 | |
351 | 362 | |
352 | 363 | /* Endpoint Queue Head data struct |
353 | 364 | * Rem: all the variables of qh are LittleEndian Mode |
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 |
7 | 7 | |
8 | 8 | |
9 | 9 | |
10 | 10 | |
... | ... | @@ -211,19 +211,32 @@ |
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; | |
221 | 223 | |
224 | + if (pdata->controller_ver < 0) { | |
225 | + dev_warn(hcd->self.controller, "Could not get controller version\n"); | |
226 | + return; | |
227 | + } | |
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: |
... | ... | @@ -233,6 +246,14 @@ |
233 | 246 | portsc |= PORT_PTS_PTW; |
234 | 247 | /* fall through */ |
235 | 248 | case FSL_USB2_PHY_UTMI: |
249 | + if (pdata->controller_ver) { | |
250 | + /* controller version 1.6 or above */ | |
251 | + temp = in_be32(non_ehci + FSL_SOC_USB_CTRL); | |
252 | + out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | | |
253 | + UTMI_PHY_EN | USB_CTRL_USB_EN); | |
254 | + mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI PHY CLK to | |
255 | + become stable - 10ms*/ | |
256 | + } | |
236 | 257 | /* enable UTMI PHY */ |
237 | 258 | setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN); |
238 | 259 | portsc |= PORT_PTS_UTMI; |
... | ... | @@ -271,7 +292,7 @@ |
271 | 292 | |
272 | 293 | if ((pdata->operating_mode == FSL_USB2_DR_HOST) || |
273 | 294 | (pdata->operating_mode == FSL_USB2_DR_OTG)) |
274 | - ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0); | |
295 | + ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0); | |
275 | 296 | |
276 | 297 | if (pdata->operating_mode == FSL_USB2_MPH_HOST) { |
277 | 298 | unsigned int chip, rev, svr; |
278 | 299 | |
... | ... | @@ -285,9 +306,9 @@ |
285 | 306 | ehci->has_fsl_port_bug = 1; |
286 | 307 | |
287 | 308 | if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) |
288 | - ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0); | |
309 | + ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0); | |
289 | 310 | if (pdata->port_enables & FSL_USB2_PORT1_ENABLED) |
290 | - ehci_fsl_setup_phy(ehci, pdata->phy_mode, 1); | |
311 | + ehci_fsl_setup_phy(hcd, pdata->phy_mode, 1); | |
291 | 312 | } |
292 | 313 | |
293 | 314 | if (pdata->have_sysif_regs) { |
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,5 +50,16 @@ |
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 */ |
drivers/usb/host/fsl-mph-dr-of.c
... | ... | @@ -119,6 +119,39 @@ |
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; |
... | ... | @@ -166,6 +199,14 @@ |
166 | 199 | |
167 | 200 | prop = of_get_property(np, "phy_type", NULL); |
168 | 201 | pdata->phy_mode = determine_usb_phy(prop); |
202 | + pdata->controller_ver = usb_get_ver_info(np); | |
203 | + | |
204 | + if (pdata->have_sysif_regs) { | |
205 | + if (pdata->controller_ver < 0) { | |
206 | + dev_warn(&ofdev->dev, "Could not get controller version\n"); | |
207 | + return -ENODEV; | |
208 | + } | |
209 | + } | |
169 | 210 | |
170 | 211 | for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) { |
171 | 212 | if (!dev_data->drivers[i]) |
include/linux/fsl_devices.h
... | ... | @@ -6,7 +6,7 @@ |
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 |
... | ... | @@ -17,6 +17,12 @@ |
17 | 17 | #ifndef _FSL_DEVICE_H_ |
18 | 18 | #define _FSL_DEVICE_H_ |
19 | 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 | |
25 | + | |
20 | 26 | #include <linux/types.h> |
21 | 27 | |
22 | 28 | /* |
... | ... | @@ -63,6 +69,7 @@ |
63 | 69 | |
64 | 70 | struct fsl_usb2_platform_data { |
65 | 71 | /* board specific information */ |
72 | + int controller_ver; | |
66 | 73 | enum fsl_usb2_operating_modes operating_mode; |
67 | 74 | enum fsl_usb2_phy_modes phy_mode; |
68 | 75 | unsigned int port_enables; |