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/host/ehci-fsl.c | |
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/host/ehci-fsl.c')
-rw-r--r-- | drivers/usb/host/ehci-fsl.c | 35 |
1 files changed, 28 insertions, 7 deletions
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) { |