On Thu, Feb 16, 2012 at 11:30:31AM +0530, Ramneek Mehresh wrote: > 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 v4: > - removed drivers/usb/host/fsl directory > - moved usb_get_ver_info() from fsl_usb.h file to > include/linux/fsl_devices.h > - replaced printk() with dev_warn() > > Top commit > commit 5407a3c3d942e75d4d123d213fd692bce5acc961 > Author: Felipe Balbi <balbi@xxxxxx> > Date: Wed Feb 15 09:34:26 2012 +0200 > > Hi Peter, could you please help me test this patch in IMX platform It causes compile error at i.mx platform due to struct usb_sys_interface *usb_sys_regs is only defined at PowerPC platform. Below is the error message: /home/b29397/work/code/git/linus/linux-2.6/drivers/usb/gadget/fsl_udc_core.c: In function 'dr_controller_setup': /home/b29397/work/code/git/linus/linux-2.6/drivers/usb/gadget/fsl_udc_core.c:269: error: 'ctrl' undeclared (first use in this function) /home/b29397/work/code/git/linus/linux-2.6/drivers/usb/gadget/fsl_udc_core.c:269: error: (Each undeclared identifier is reported only once /home/b29397/work/code/git/linus/linux-2.6/drivers/usb/gadget/fsl_udc_core.c:269: error: for each function it appears in.) /home/b29397/work/code/git/linus/linux-2.6/drivers/usb/gadget/fsl_udc_core.c:269: error: 'usb_sys_regs' undeclared (first use in this function) make[4]: *** [drivers/usb/gadget/fsl_udc_core.o] Error 1 make[3]: *** [drivers/usb/gadget] Error 2 > > drivers/usb/gadget/fsl_udc_core.c | 24 +++++++++++++++++++++- > 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 | 39 ++++++++++++++++++++++++++++++++++++- > 5 files changed, 115 insertions(+), 9 deletions(-) > > diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c > index b04712f..aa3ab17 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,45 @@ static int dr_controller_setup(struct fsl_udc *udc) > { > unsigned int tmp, portctrl, ep_num; > unsigned int max_no_of_ep; > + int contr_ver = usb_get_ver_info(); > #ifndef CONFIG_ARCH_MXC > 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: > + 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 (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 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..c54bf5b 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,37 @@ int fsl_deep_sleep(void); > static inline int fsl_deep_sleep(void) { return 0; } > #endif > > +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 /* _FSL_DEVICE_H_ */ > -- > 1.7.1 > > -- Best Regards, Peter Chen -- 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