diff options
author | Ramneek Mehresh <ramneek.mehresh@freescale.com> | 2012-03-20 01:05:50 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-04-18 16:46:42 -0400 |
commit | 58c559e6509f276d0afb4621b2122e994e70160c (patch) | |
tree | a283772f0748cb6dd63d236851ecd20b3f89b780 /drivers/usb | |
parent | 67c88382e0bf92d7e09536ac47674c9fc9398b98 (diff) |
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>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/fsl_udc_core.c | 28 | ||||
-rw-r--r-- | drivers/usb/gadget/fsl_usb2_udc.h | 11 | ||||
-rw-r--r-- | drivers/usb/host/ehci-fsl.c | 35 | ||||
-rw-r--r-- | drivers/usb/host/ehci-fsl.h | 13 | ||||
-rw-r--r-- | drivers/usb/host/fsl-mph-dr-of.c | 41 |
5 files changed, 115 insertions, 13 deletions
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 5f94e79cd6b9..6087fa698a38 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2004-2007,2011 Freescale Semiconductor, Inc. | 2 | * Copyright (C) 2004-2007,2011-2012 Freescale Semiconductor, Inc. |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * Author: Li Yang <leoli@freescale.com> | 5 | * Author: Li Yang <leoli@freescale.com> |
@@ -58,9 +58,8 @@ static const char driver_name[] = "fsl-usb2-udc"; | |||
58 | static const char driver_desc[] = DRIVER_DESC; | 58 | static const char driver_desc[] = DRIVER_DESC; |
59 | 59 | ||
60 | static struct usb_dr_device *dr_regs; | 60 | static struct usb_dr_device *dr_regs; |
61 | #ifndef CONFIG_ARCH_MXC | 61 | |
62 | static struct usb_sys_interface *usb_sys_regs; | 62 | static struct usb_sys_interface *usb_sys_regs; |
63 | #endif | ||
64 | 63 | ||
65 | /* it is initialized in probe() */ | 64 | /* it is initialized in probe() */ |
66 | static struct fsl_udc *udc_controller = NULL; | 65 | static struct fsl_udc *udc_controller = NULL; |
@@ -244,10 +243,9 @@ static int dr_controller_setup(struct fsl_udc *udc) | |||
244 | { | 243 | { |
245 | unsigned int tmp, portctrl, ep_num; | 244 | unsigned int tmp, portctrl, ep_num; |
246 | unsigned int max_no_of_ep; | 245 | unsigned int max_no_of_ep; |
247 | #ifndef CONFIG_ARCH_MXC | ||
248 | unsigned int ctrl; | 246 | unsigned int ctrl; |
249 | #endif | ||
250 | unsigned long timeout; | 247 | unsigned long timeout; |
248 | |||
251 | #define FSL_UDC_RESET_TIMEOUT 1000 | 249 | #define FSL_UDC_RESET_TIMEOUT 1000 |
252 | 250 | ||
253 | /* Config PHY interface */ | 251 | /* Config PHY interface */ |
@@ -255,12 +253,32 @@ static int dr_controller_setup(struct fsl_udc *udc) | |||
255 | portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH); | 253 | portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH); |
256 | switch (udc->phy_mode) { | 254 | switch (udc->phy_mode) { |
257 | case FSL_USB2_PHY_ULPI: | 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 | portctrl |= PORTSCX_PTS_ULPI; | 265 | portctrl |= PORTSCX_PTS_ULPI; |
259 | break; | 266 | break; |
260 | case FSL_USB2_PHY_UTMI_WIDE: | 267 | case FSL_USB2_PHY_UTMI_WIDE: |
261 | portctrl |= PORTSCX_PTW_16BIT; | 268 | portctrl |= PORTSCX_PTW_16BIT; |
262 | /* fall through */ | 269 | /* fall through */ |
263 | case FSL_USB2_PHY_UTMI: | 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 | portctrl |= PORTSCX_PTS_UTMI; | 282 | portctrl |= PORTSCX_PTS_UTMI; |
265 | break; | 283 | break; |
266 | case FSL_USB2_PHY_SERIAL: | 284 | case FSL_USB2_PHY_SERIAL: |
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index e651469fd39b..1212646841a3 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h | |||
@@ -1,4 +1,12 @@ | |||
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 | * Freescale USB device/endpoint management registers | 10 | * Freescale USB device/endpoint management registers |
3 | */ | 11 | */ |
4 | #ifndef __FSL_USB2_UDC_H | 12 | #ifndef __FSL_USB2_UDC_H |
@@ -348,6 +356,9 @@ struct usb_sys_interface { | |||
348 | /* control Register Bit Masks */ | 356 | /* control Register Bit Masks */ |
349 | #define USB_CTRL_IOENB 0x00000004 | 357 | #define USB_CTRL_IOENB 0x00000004 |
350 | #define USB_CTRL_ULPI_INT0EN 0x00000001 | 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 | /* Endpoint Queue Head data struct | 363 | /* Endpoint Queue Head data struct |
353 | * Rem: all the variables of qh are LittleEndian Mode | 364 | * Rem: all the variables of qh are LittleEndian Mode |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 3e7345172e03..653e577ab3ee 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2005-2009 MontaVista Software, Inc. | 2 | * Copyright 2005-2009 MontaVista Software, Inc. |
3 | * Copyright 2008 Freescale Semiconductor, Inc. | 3 | * Copyright 2008,2012 Freescale Semiconductor, Inc. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 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 | 6 | * under the terms of the GNU General Public License as published by the |
@@ -211,19 +211,32 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd, | |||
211 | usb_put_hcd(hcd); | 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 | enum fsl_usb2_phy_modes phy_mode, | 215 | enum fsl_usb2_phy_modes phy_mode, |
216 | unsigned int port_offset) | 216 | unsigned int port_offset) |
217 | { | 217 | { |
218 | u32 portsc; | 218 | u32 portsc, temp; |
219 | struct usb_hcd *hcd = ehci_to_hcd(ehci); | 219 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
220 | void __iomem *non_ehci = hcd->regs; | 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 | portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); | 229 | portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); |
223 | portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); | 230 | portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); |
224 | 231 | ||
225 | switch (phy_mode) { | 232 | switch (phy_mode) { |
226 | case FSL_USB2_PHY_ULPI: | 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 | portsc |= PORT_PTS_ULPI; | 240 | portsc |= PORT_PTS_ULPI; |
228 | break; | 241 | break; |
229 | case FSL_USB2_PHY_SERIAL: | 242 | case FSL_USB2_PHY_SERIAL: |
@@ -233,6 +246,14 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, | |||
233 | portsc |= PORT_PTS_PTW; | 246 | portsc |= PORT_PTS_PTW; |
234 | /* fall through */ | 247 | /* fall through */ |
235 | case FSL_USB2_PHY_UTMI: | 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 | /* enable UTMI PHY */ | 257 | /* enable UTMI PHY */ |
237 | setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN); | 258 | setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN); |
238 | portsc |= PORT_PTS_UTMI; | 259 | portsc |= PORT_PTS_UTMI; |
@@ -271,7 +292,7 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci) | |||
271 | 292 | ||
272 | if ((pdata->operating_mode == FSL_USB2_DR_HOST) || | 293 | if ((pdata->operating_mode == FSL_USB2_DR_HOST) || |
273 | (pdata->operating_mode == FSL_USB2_DR_OTG)) | 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 | if (pdata->operating_mode == FSL_USB2_MPH_HOST) { | 297 | if (pdata->operating_mode == FSL_USB2_MPH_HOST) { |
277 | unsigned int chip, rev, svr; | 298 | unsigned int chip, rev, svr; |
@@ -285,9 +306,9 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci) | |||
285 | ehci->has_fsl_port_bug = 1; | 306 | ehci->has_fsl_port_bug = 1; |
286 | 307 | ||
287 | if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) | 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 | if (pdata->port_enables & FSL_USB2_PORT1_ENABLED) | 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 | if (pdata->have_sysif_regs) { | 314 | if (pdata->have_sysif_regs) { |
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h index 863fb0c080d7..88403684d10b 100644 --- a/drivers/usb/host/ehci-fsl.h +++ b/drivers/usb/host/ehci-fsl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (C) 2005-2010 Freescale Semiconductor, Inc. | 1 | /* Copyright (C) 2005-2010,2012 Freescale Semiconductor, Inc. |
2 | * Copyright (c) 2005 MontaVista Software | 2 | * Copyright (c) 2005 MontaVista Software |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
@@ -50,4 +50,15 @@ | |||
50 | #define CTRL_UTMI_PHY_EN (1<<9) | 50 | #define CTRL_UTMI_PHY_EN (1<<9) |
51 | #define CTRL_PHY_CLK_VALID (1 << 17) | 51 | #define CTRL_PHY_CLK_VALID (1 << 17) |
52 | #define SNOOP_SIZE_2GB 0x1e | 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 | #endif /* _EHCI_FSL_H */ | 64 | #endif /* _EHCI_FSL_H */ |
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index ab333ac6071d..22ff6b3a676f 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c | |||
@@ -119,6 +119,39 @@ error: | |||
119 | 119 | ||
120 | static const struct of_device_id fsl_usb2_mph_dr_of_match[]; | 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 | static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) | 155 | static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) |
123 | { | 156 | { |
124 | struct device_node *np = ofdev->dev.of_node; | 157 | struct device_node *np = ofdev->dev.of_node; |
@@ -166,6 +199,14 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) | |||
166 | 199 | ||
167 | prop = of_get_property(np, "phy_type", NULL); | 200 | prop = of_get_property(np, "phy_type", NULL); |
168 | pdata->phy_mode = determine_usb_phy(prop); | 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 | for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) { | 211 | for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) { |
171 | if (!dev_data->drivers[i]) | 212 | if (!dev_data->drivers[i]) |