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