[PATCH][v5]fsl/usb:Add controller version based ULPI and UTMI phy support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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, etc
Version 2.2 : PSC9131, PSC9132, P3060, etc

No changes for non-DT users

Signed-off-by: Ramneek Mehresh <ramneek.mehresh@xxxxxxxxxxxxx>
---
Changes for v5:
	- used CONFIG_USB_FSL_MPH_DR_OF macro in gadget driver
	  to exclude the code for nonDT users

 drivers/usb/gadget/fsl_udc_core.c |   32 ++++++++++++++++++++++++++--
 drivers/usb/gadget/fsl_usb2_udc.h |   13 +++++++++++
 drivers/usb/host/ehci-fsl.c       |   35 ++++++++++++++++++++++++++-----
 drivers/usb/host/ehci-fsl.h       |   13 ++++++++++-
 include/linux/fsl_devices.h       |   41 ++++++++++++++++++++++++++++++++++++-
 5 files changed, 123 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index b04712f..18a2312 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2007,2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2004-2007,2011-2012 Freescale Semiconductor, Inc.
  * All rights reserved.
  *
  * Author: Li Yang <leoli@xxxxxxxxxxxxx>
@@ -245,23 +245,49 @@ static int dr_controller_setup(struct fsl_udc *udc)
 {
 	unsigned int tmp, portctrl, ep_num;
 	unsigned int max_no_of_ep;
-#ifndef CONFIG_ARCH_MXC
+	int contr_ver = usb_get_ver_info();
+#ifdef CONFIG_USB_FSL_MPH_DR_OF
 	unsigned int ctrl;
 #endif
 	unsigned long timeout;
 #define FSL_UDC_RESET_TIMEOUT 1000
 
+	if (contr_ver < 0) {
+		dev_warn(&(udc->gadget.dev), "fsl_usb: Could not get"
+			" controller version\n");
+		return -ENODEV;
+	}
+
 	/* Config PHY interface */
 	portctrl = fsl_readl(&dr_regs->portsc1);
 	portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH);
 	switch (udc->phy_mode) {
 	case FSL_USB2_PHY_ULPI:
+#ifdef CONFIG_USB_FSL_MPH_DR_OF
+		if (contr_ver) {
+			/* controller version 1.6 or above */
+			ctrl = __raw_readl(&usb_sys_regs->control);
+			ctrl &= ~USB_CTRL_UTMI_PHY_EN;
+			ctrl |= USB_CTRL_USB_EN;
+			__raw_writel(ctrl, &usb_sys_regs->control);
+		}
+#endif
 		portctrl |= PORTSCX_PTS_ULPI;
 		break;
 	case FSL_USB2_PHY_UTMI_WIDE:
 		portctrl |= PORTSCX_PTW_16BIT;
 		/* fall through */
 	case FSL_USB2_PHY_UTMI:
+#ifdef CONFIG_USB_FSL_MPH_DR_OF
+		if (contr_ver) {
+			/* controller version 1.6 or above */
+			ctrl = __raw_readl(&usb_sys_regs->control);
+			ctrl |= (USB_CTRL_UTMI_PHY_EN | USB_CTRL_USB_EN);
+			__raw_writel(ctrl, &usb_sys_regs->control);
+			mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI PHY CLK to
+						become stable - 10ms*/
+		}
+#endif
 		portctrl |= PORTSCX_PTS_UTMI;
 		break;
 	case FSL_USB2_PHY_SERIAL:
@@ -321,7 +347,7 @@ static int dr_controller_setup(struct fsl_udc *udc)
 		fsl_writel(tmp, &dr_regs->endptctrl[ep_num]);
 	}
 	/* Config control enable i/o output, cpu endian register */
-#ifndef CONFIG_ARCH_MXC
+#ifdef CONFIG_USB_FSL_MPH_DR_OF
 	if (udc->pdata->have_sysif_regs) {
 		ctrl = __raw_readl(&usb_sys_regs->control);
 		ctrl |= USB_CTRL_IOENB;
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h
index f781f5d..b4e5fd7 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -1,4 +1,14 @@
 /*
+ * Copyright (C) 2004,2012 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/*
  * Freescale USB device/endpoint management registers
  */
 #ifndef __FSL_USB2_UDC_H
@@ -348,6 +358,9 @@ struct usb_sys_interface {
 /* control Register Bit Masks */
 #define  USB_CTRL_IOENB                       0x00000004
 #define  USB_CTRL_ULPI_INT0EN                 0x00000001
+#define  USB_CTRL_UTMI_PHY_EN		      0x00000200
+#define  USB_CTRL_USB_EN		      0x00000004
+#define  USB_CTRL_ULPI_PHY_CLK_SEL	      0x00000400
 
 /* Endpoint Queue Head data struct
  * 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 10e008a..129d3bb 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -1,6 +1,6 @@
 /*
  * Copyright 2005-2009 MontaVista Software, Inc.
- * Copyright 2008      Freescale Semiconductor, Inc.
+ * Copyright 2008,2012      Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -211,17 +211,32 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
 	usb_put_hcd(hcd);
 }
 
-static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
+static void ehci_fsl_setup_phy(struct usb_hcd *hcd,
 			       enum fsl_usb2_phy_modes phy_mode,
 			       unsigned int port_offset)
 {
-	u32 portsc;
+	u32 portsc, temp;
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	void __iomem *non_ehci = hcd->regs;
+	int contr_ver = usb_get_ver_info();
+
+	if (contr_ver < 0) {
+		dev_warn(hcd->self.controller, "fsl_usb: Could not get"
+			" controller version\n");
+		return;
+	}
 
 	portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
 	portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
 
 	switch (phy_mode) {
 	case FSL_USB2_PHY_ULPI:
+		if (contr_ver) {
+			/* controller version 1.6 or above */
+			temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
+			out_be32(non_ehci + FSL_SOC_USB_CTRL, temp |
+				USB_CTRL_USB_EN | ULPI_PHY_CLK_SEL);
+		}
 		portsc |= PORT_PTS_ULPI;
 		break;
 	case FSL_USB2_PHY_SERIAL:
@@ -231,6 +246,14 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
 		portsc |= PORT_PTS_PTW;
 		/* fall through */
 	case FSL_USB2_PHY_UTMI:
+		if (contr_ver) {
+			/* controller version 1.6 or above */
+			temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
+			out_be32(non_ehci + FSL_SOC_USB_CTRL, temp |
+				UTMI_PHY_EN | USB_CTRL_USB_EN);
+			mdelay(FSL_UTMI_PHY_DLY);  /* Delay for UTMI PHY CLK to
+						become stable - 10ms*/
+		}
 		portsc |= PORT_PTS_UTMI;
 		break;
 	case FSL_USB2_PHY_NONE:
@@ -270,7 +293,7 @@ static int ehci_fsl_usb_setup(struct ehci_hcd *ehci)
 
 	if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
 			(pdata->operating_mode == FSL_USB2_DR_OTG))
-		ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
+		ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0);
 
 	if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
 		unsigned int chip, rev, svr;
@@ -284,9 +307,9 @@ static int ehci_fsl_usb_setup(struct ehci_hcd *ehci)
 			ehci->has_fsl_port_bug = 1;
 
 		if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
-			ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
+			ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0);
 		if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
-			ehci_fsl_setup_phy(ehci, pdata->phy_mode, 1);
+			ehci_fsl_setup_phy(hcd, pdata->phy_mode, 1);
 	}
 
 	if (pdata->have_sysif_regs) {
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
index 6d5a94e..60f00db 100644
--- a/drivers/usb/host/ehci-fsl.h
+++ b/drivers/usb/host/ehci-fsl.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2010 Freescale Semiconductor, Inc.
+/* Copyright (C) 2005-2010,2012 Freescale Semiconductor, Inc.
  * Copyright (c) 2005 MontaVista Software
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -49,4 +49,15 @@
 #define FSL_SOC_USB_CTRL	0x500	/* NOTE: big-endian */
 #define CTRL_PHY_CLK_VALID	(1 << 17)
 #define SNOOP_SIZE_2GB		0x1e
+
+/* control Register Bit Masks */
+#define ULPI_INT_EN             (1<<0)
+#define WU_INT_EN               (1<<1)
+#define USB_CTRL_USB_EN         (1<<2)
+#define LINE_STATE_FILTER__EN   (1<<3)
+#define KEEP_OTG_ON             (1<<4)
+#define OTG_PORT                (1<<5)
+#define PLL_RESET               (1<<8)
+#define UTMI_PHY_EN             (1<<9)
+#define ULPI_PHY_CLK_SEL        (1<<10)
 #endif				/* _EHCI_FSL_H */
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index fffdf00..b86986d 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -6,7 +6,7 @@
  *
  * Maintainer: Kumar Gala <galak@xxxxxxxxxxxxxxxxxxx>
  *
- * Copyright 2004 Freescale Semiconductor, Inc
+ * Copyright 2004,2012 Freescale Semiconductor, Inc
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -17,7 +17,11 @@
 #ifndef _FSL_DEVICE_H_
 #define _FSL_DEVICE_H_
 
+#define FSL_UTMI_PHY_DLY	10	/*As per P1010RM, delay for UTMI
+					  PHY CLK to become stable - 10ms*/
+
 #include <linux/types.h>
+#include <linux/of.h>
 
 /*
  * Some conventions on how we handle peripherals on Freescale chips
@@ -135,4 +139,39 @@ int fsl_deep_sleep(void);
 static inline int fsl_deep_sleep(void) { return 0; }
 #endif
 
+#ifdef CONFIG_USB_FSL_MPH_DR_OF
+static inline int usb_get_ver_info(void)
+{
+	struct device_node *np;
+	int ver = -1;
+
+	/*
+	 * returns 1 for usb controller version 1.6
+	 * returns 2 for usb controller version 2.2
+	 * returns 0 otherwise
+	 */
+	for_each_compatible_node(np, NULL, "fsl-usb2-dr") {
+		if (of_device_is_compatible(np, "fsl-usb2-dr-v1.6"))
+			ver = 1;
+		else if (of_device_is_compatible(np, "fsl-usb2-dr-v2.2"))
+			ver = 2;
+		else /* for previous controller versions/non-dt users */
+			ver = 0;
+	}
+
+	if (ver > -1)
+		return ver;
+
+	for_each_compatible_node(np, NULL, "fsl-usb2-mph") {
+		if (of_device_is_compatible(np, "fsl-usb2-mph-v1.6"))
+			ver = 1;
+		else if (of_device_is_compatible(np, "fsl-usb2-mph-v2.2"))
+			ver = 2;
+		else /* for previous controller versions/non-dt users */
+			ver = 0;
+	}
+
+	return ver;
+}
+#endif /* CONFIG_USB_FSL_MPH_DR_OF */
 #endif /* _FSL_DEVICE_H_ */
-- 
1.7.1



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux