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

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

 




> -----Original Message-----
> From: Mehresh Ramneek-B31383
> Sent: Tuesday, March 06, 2012 5:50 PM
> To: linux-usb@xxxxxxxxxxxxxxx
> Cc: Chen Peter-B29397; Li Yang-R58472; Mehresh Ramneek-B31383
> Subject: [PATCH][v7]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@xxxxxxxxxxxxx>
> ---
> v6 is tested and acked by Peter Chen
> 
> Changes for v7:
> 	- moved usb_get_ver_info() from include/linux/fsl_devices.h
> 	  to drivers/usb/host/fsl-mph-dr-of.c
> 	- made usb_get_ver_info() non-static and non-inline funcion
> 
>  drivers/usb/gadget/fsl_udc_core.c |   37
> ++++++++++++++++++++++++++++++++-----
>  drivers/usb/gadget/fsl_usb2_udc.h |   11 +++++++++++
>  drivers/usb/host/ehci-fsl.c       |   35 ++++++++++++++++++++++++++++---
> ----
>  drivers/usb/host/ehci-fsl.h       |   13 ++++++++++++-
>  drivers/usb/host/fsl-mph-dr-of.c  |   36
> ++++++++++++++++++++++++++++++++++++
>  include/linux/fsl_devices.h       |   10 +++++++++-
>  6 files changed, 128 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/usb/gadget/fsl_udc_core.c
> b/drivers/usb/gadget/fsl_udc_core.c
> index b30e21f..ff2a99e 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>
> @@ -59,9 +59,8 @@ static const char driver_name[] = "fsl-usb2-udc";
>  static const char driver_desc[] = DRIVER_DESC;
> 
>  static struct usb_dr_device *dr_regs;
> -#ifndef CONFIG_ARCH_MXC
> +
>  static struct usb_sys_interface *usb_sys_regs;
> -#endif
> 
>  /* it is initialized in probe()  */
>  static struct fsl_udc *udc_controller = NULL;
> @@ -245,23 +244,51 @@ 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
>  	unsigned int ctrl;
> -#endif
>  	unsigned long timeout;
> +	int contr_ver = usb_get_ver_info();
> +
>  #define FSL_UDC_RESET_TIMEOUT 1000
> 
> +	if (udc->pdata->have_sysif_regs) {
> +		if (contr_ver < 0) {
> +			pr_warn("fsl-usb2-udc: 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:
> +		if (udc->pdata->have_sysif_regs) {
> +			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);
> +			}
> +		}
>  		portctrl |= PORTSCX_PTS_ULPI;
>  		break;
>  	case FSL_USB2_PHY_UTMI_WIDE:
>  		portctrl |= PORTSCX_PTW_16BIT;
>  		/* fall through */
>  	case FSL_USB2_PHY_UTMI:
> +		if (udc->pdata->have_sysif_regs) {
> +			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*/
> +			}
> +		}
>  		portctrl |= PORTSCX_PTS_UTMI;
>  		break;
>  	case FSL_USB2_PHY_SERIAL:
> diff --git a/drivers/usb/gadget/fsl_usb2_udc.h
> b/drivers/usb/gadget/fsl_usb2_udc.h
> index e651469..1212646 100644
> --- a/drivers/usb/gadget/fsl_usb2_udc.h
> +++ b/drivers/usb/gadget/fsl_usb2_udc.h
> @@ -1,4 +1,12 @@
>  /*
> + * 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 +356,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 cf56667..6c2c2ce 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,19 +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;
> -	struct usb_hcd *hcd = ehci_to_hcd(ehci);
> +	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:
> @@ -233,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*/
> +		}
>  		/* enable UTMI PHY */
>  		setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN);
>  		portsc |= PORT_PTS_UTMI;
> @@ -271,7 +292,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;
> @@ -285,9 +306,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 863fb0c..8840368 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
> @@ -50,4 +50,15 @@
>  #define CTRL_UTMI_PHY_EN	(1<<9)
>  #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/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-
> dr-of.c
> index ab333ac..89e83e8 100644
> --- a/drivers/usb/host/fsl-mph-dr-of.c
> +++ b/drivers/usb/host/fsl-mph-dr-of.c

It's a good file to add this.  But I'm still concerned that the file is in the host/ directory but used by both host and gadget.  It is out of the scope of this patch.  We can do the move later.
 
> @@ -193,6 +193,42 @@ static int __devexit
> fsl_usb2_mph_dr_of_remove(struct platform_device *ofdev)
>  	return 0;
>  }
> 
> +#ifdef CONFIG_USB_FSL_MPH_DR_OF

No #ifdef here, this file won't be compiled without this config.

> +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 */
> +			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 */
> +			ver = 0;
> +	}
> +
> +	return ver;
> +}
> +#endif /* CONFIG_USB_FSL_MPH_DR_OF */
> +

As you are adding the version judgment in this file, I think the better way is to add a version field in the struct fsl_usb2_platform_data and initialize it on probe.

- Leo


--
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