aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Grzeschik <m.grzeschik@pengutronix.de>2013-06-13 10:59:56 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-06-17 16:47:09 -0400
commit40dcd0e8067b35e247f74409d79443634daf35ac (patch)
tree91b9e6678ad1b2bd72e45d3e35a9266aaefa016f /drivers
parent1c9af65357a309b60d78a442bd61d27cad458d00 (diff)
usb: chipidea: add PTW, PTS and STS handling
This patch makes it possible to configure the PTW, PTS and STS bits inside the portsc register for host and device mode before the driver starts and the phy can be addressed as hardware implementation is designed. Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/chipidea/bits.h16
-rw-r--r--drivers/usb/chipidea/core.c48
2 files changed, 63 insertions, 1 deletions
diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
index 050de8562a04..aefa0261220c 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -48,10 +48,24 @@
48#define PORTSC_SUSP BIT(7) 48#define PORTSC_SUSP BIT(7)
49#define PORTSC_HSP BIT(9) 49#define PORTSC_HSP BIT(9)
50#define PORTSC_PTC (0x0FUL << 16) 50#define PORTSC_PTC (0x0FUL << 16)
51/* PTS and PTW for non lpm version only */
52#define PORTSC_PTS(d) \
53 ((((d) & 0x3) << 30) | (((d) & 0x4) ? BIT(25) : 0))
54#define PORTSC_PTW BIT(28)
55#define PORTSC_STS BIT(29)
51 56
52/* DEVLC */ 57/* DEVLC */
53#define DEVLC_PSPD (0x03UL << 25) 58#define DEVLC_PSPD (0x03UL << 25)
54#define DEVLC_PSPD_HS (0x02UL << 25) 59#define DEVLC_PSPD_HS (0x02UL << 25)
60#define DEVLC_PTW BIT(27)
61#define DEVLC_STS BIT(28)
62#define DEVLC_PTS(d) (((d) & 0x7) << 29)
63
64/* Encoding for DEVLC_PTS and PORTSC_PTS */
65#define PTS_UTMI 0
66#define PTS_ULPI 2
67#define PTS_SERIAL 3
68#define PTS_HSIC 4
55 69
56/* OTGSC */ 70/* OTGSC */
57#define OTGSC_IDPU BIT(5) 71#define OTGSC_IDPU BIT(5)
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index a40e944401d2..a25f6b68550f 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -63,6 +63,8 @@
63#include <linux/usb/gadget.h> 63#include <linux/usb/gadget.h>
64#include <linux/usb/otg.h> 64#include <linux/usb/otg.h>
65#include <linux/usb/chipidea.h> 65#include <linux/usb/chipidea.h>
66#include <linux/usb/of.h>
67#include <linux/phy.h>
66 68
67#include "ci.h" 69#include "ci.h"
68#include "udc.h" 70#include "udc.h"
@@ -207,6 +209,45 @@ static int hw_device_init(struct ci13xxx *ci, void __iomem *base)
207 return 0; 209 return 0;
208} 210}
209 211
212static void hw_phymode_configure(struct ci13xxx *ci)
213{
214 u32 portsc, lpm, sts;
215
216 switch (ci->platdata->phy_mode) {
217 case USBPHY_INTERFACE_MODE_UTMI:
218 portsc = PORTSC_PTS(PTS_UTMI);
219 lpm = DEVLC_PTS(PTS_UTMI);
220 break;
221 case USBPHY_INTERFACE_MODE_UTMIW:
222 portsc = PORTSC_PTS(PTS_UTMI) | PORTSC_PTW;
223 lpm = DEVLC_PTS(PTS_UTMI) | DEVLC_PTW;
224 break;
225 case USBPHY_INTERFACE_MODE_ULPI:
226 portsc = PORTSC_PTS(PTS_ULPI);
227 lpm = DEVLC_PTS(PTS_ULPI);
228 break;
229 case USBPHY_INTERFACE_MODE_SERIAL:
230 portsc = PORTSC_PTS(PTS_SERIAL);
231 lpm = DEVLC_PTS(PTS_SERIAL);
232 sts = 1;
233 break;
234 case USBPHY_INTERFACE_MODE_HSIC:
235 portsc = PORTSC_PTS(PTS_HSIC);
236 lpm = DEVLC_PTS(PTS_HSIC);
237 break;
238 default:
239 return;
240 }
241
242 if (ci->hw_bank.lpm) {
243 hw_write(ci, OP_DEVLC, DEVLC_PTS(7) | DEVLC_PTW, lpm);
244 hw_write(ci, OP_DEVLC, DEVLC_STS, sts);
245 } else {
246 hw_write(ci, OP_PORTSC, PORTSC_PTS(7) | PORTSC_PTW, portsc);
247 hw_write(ci, OP_PORTSC, PORTSC_STS, sts);
248 }
249}
250
210/** 251/**
211 * hw_device_reset: resets chip (execute without interruption) 252 * hw_device_reset: resets chip (execute without interruption)
212 * @ci: the controller 253 * @ci: the controller
@@ -223,6 +264,7 @@ int hw_device_reset(struct ci13xxx *ci, u32 mode)
223 while (hw_read(ci, OP_USBCMD, USBCMD_RST)) 264 while (hw_read(ci, OP_USBCMD, USBCMD_RST))
224 udelay(10); /* not RTOS friendly */ 265 udelay(10); /* not RTOS friendly */
225 266
267 hw_phymode_configure(ci);
226 268
227 if (ci->platdata->notify_event) 269 if (ci->platdata->notify_event)
228 ci->platdata->notify_event(ci, 270 ci->platdata->notify_event(ci,
@@ -369,6 +411,9 @@ static int ci_hdrc_probe(struct platform_device *pdev)
369 return -ENODEV; 411 return -ENODEV;
370 } 412 }
371 413
414 if (!dev->of_node && dev->parent)
415 dev->of_node = dev->parent->of_node;
416
372 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 417 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
373 base = devm_ioremap_resource(dev, res); 418 base = devm_ioremap_resource(dev, res);
374 if (IS_ERR(base)) 419 if (IS_ERR(base))
@@ -408,6 +453,9 @@ static int ci_hdrc_probe(struct platform_device *pdev)
408 return -ENODEV; 453 return -ENODEV;
409 } 454 }
410 455
456 if (!ci->platdata->phy_mode)
457 ci->platdata->phy_mode = of_usb_get_phy_mode(dev->of_node);
458
411 /* initialize role(s) before the interrupt is requested */ 459 /* initialize role(s) before the interrupt is requested */
412 ret = ci_hdrc_host_init(ci); 460 ret = ci_hdrc_host_init(ci);
413 if (ret) 461 if (ret)