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@freescale.com> Acked-by: Li Yang <leoli@freescale.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
67c88382e0
commit
58c559e650
|
@ -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@freescale.com>
|
||||
|
@ -58,9 +58,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;
|
||||
|
@ -244,10 +243,9 @@ 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;
|
||||
|
||||
#define FSL_UDC_RESET_TIMEOUT 1000
|
||||
|
||||
/* Config PHY interface */
|
||||
|
@ -255,12 +253,32 @@ static int dr_controller_setup(struct fsl_udc *udc)
|
|||
portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH);
|
||||
switch (udc->phy_mode) {
|
||||
case FSL_USB2_PHY_ULPI:
|
||||
if (udc->pdata->have_sysif_regs) {
|
||||
if (udc->pdata->controller_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 (udc->pdata->controller_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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
struct device *dev = hcd->self.controller;
|
||||
struct fsl_usb2_platform_data *pdata = dev->platform_data;
|
||||
|
||||
if (pdata->controller_ver < 0) {
|
||||
dev_warn(hcd->self.controller, "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 (pdata->controller_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 (pdata->controller_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 void 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 void 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) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -119,6 +119,39 @@ error:
|
|||
|
||||
static const struct of_device_id fsl_usb2_mph_dr_of_match[];
|
||||
|
||||
static int usb_get_ver_info(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
|
||||
*/
|
||||
if (of_device_is_compatible(np, "fsl-usb2-dr")) {
|
||||
if (of_device_is_compatible(np, "fsl-usb2-dr-v1.6"))
|
||||
ver = FSL_USB_VER_1_6;
|
||||
else if (of_device_is_compatible(np, "fsl-usb2-dr-v2.2"))
|
||||
ver = FSL_USB_VER_2_2;
|
||||
else /* for previous controller versions */
|
||||
ver = FSL_USB_VER_OLD;
|
||||
|
||||
if (ver > -1)
|
||||
return ver;
|
||||
}
|
||||
|
||||
if (of_device_is_compatible(np, "fsl-usb2-mph")) {
|
||||
if (of_device_is_compatible(np, "fsl-usb2-mph-v1.6"))
|
||||
ver = FSL_USB_VER_1_6;
|
||||
else if (of_device_is_compatible(np, "fsl-usb2-mph-v2.2"))
|
||||
ver = FSL_USB_VER_2_2;
|
||||
else /* for previous controller versions */
|
||||
ver = FSL_USB_VER_OLD;
|
||||
}
|
||||
|
||||
return ver;
|
||||
}
|
||||
|
||||
static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
|
||||
{
|
||||
struct device_node *np = ofdev->dev.of_node;
|
||||
|
@ -166,6 +199,14 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
|
|||
|
||||
prop = of_get_property(np, "phy_type", NULL);
|
||||
pdata->phy_mode = determine_usb_phy(prop);
|
||||
pdata->controller_ver = usb_get_ver_info(np);
|
||||
|
||||
if (pdata->have_sysif_regs) {
|
||||
if (pdata->controller_ver < 0) {
|
||||
dev_warn(&ofdev->dev, "Could not get controller version\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) {
|
||||
if (!dev_data->drivers[i])
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
|
||||
*
|
||||
* 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,6 +17,12 @@
|
|||
#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*/
|
||||
#define FSL_USB_VER_OLD 0
|
||||
#define FSL_USB_VER_1_6 1
|
||||
#define FSL_USB_VER_2_2 2
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
|
@ -63,6 +69,7 @@ struct platform_device;
|
|||
|
||||
struct fsl_usb2_platform_data {
|
||||
/* board specific information */
|
||||
int controller_ver;
|
||||
enum fsl_usb2_operating_modes operating_mode;
|
||||
enum fsl_usb2_phy_modes phy_mode;
|
||||
unsigned int port_enables;
|
||||
|
|
Loading…
Reference in New Issue