Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 213609
b: refs/heads/master
c: 230f7ed
h: refs/heads/master
i:
  213607: 8f73d7d
v: v3
  • Loading branch information
Anatolij Gustschin authored and Greg Kroah-Hartman committed Oct 22, 2010
1 parent f02fb25 commit 6b029d4
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 33 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 126512e3f274802ca65ebeca8660237f0361ad48
refs/heads/master: 230f7ede6c2f0e403f29e03e0251a470aa9350dd
22 changes: 22 additions & 0 deletions trunk/Documentation/powerpc/dts-bindings/fsl/usb.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and additions :
Required properties :
- compatible : Should be "fsl-usb2-mph" for multi port host USB
controllers, or "fsl-usb2-dr" for dual role USB controllers
or "fsl,mpc5121-usb2-dr" for dual role USB controllers of MPC5121
- phy_type : For multi port host USB controllers, should be one of
"ulpi", or "serial". For dual role USB controllers, should be
one of "ulpi", "utmi", "utmi_wide", or "serial".
Expand All @@ -33,6 +34,12 @@ Recommended properties :
- interrupt-parent : the phandle for the interrupt controller that
services interrupts for this device.

Optional properties :
- fsl,invert-drvvbus : boolean; for MPC5121 USB0 only. Indicates the
port power polarity of internal PHY signal DRVVBUS is inverted.
- fsl,invert-pwr-fault : boolean; for MPC5121 USB0 only. Indicates
the PWR_FAULT signal polarity is inverted.

Example multi port host USB controller device node :
usb@22000 {
compatible = "fsl-usb2-mph";
Expand All @@ -57,3 +64,18 @@ Example dual role USB controller device node :
dr_mode = "otg";
phy = "ulpi";
};

Example dual role USB controller device node for MPC5121ADS:

usb@4000 {
compatible = "fsl,mpc5121-usb2-dr";
reg = <0x4000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
interrupt-parent = < &ipic >;
interrupts = <44 0x8>;
dr_mode = "otg";
phy_type = "utmi_wide";
fsl,invert-drvvbus;
fsl,invert-pwr-fault;
};
1 change: 1 addition & 0 deletions trunk/drivers/usb/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ config USB_ARCH_HAS_OHCI
config USB_ARCH_HAS_EHCI
boolean
default y if PPC_83xx
default y if PPC_MPC512x
default y if SOC_AU1200
default y if ARCH_IXP4XX
default y if ARCH_W90X900
Expand Down
6 changes: 4 additions & 2 deletions trunk/drivers/usb/host/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,14 @@ config USB_EHCI_TT_NEWSCHED

config USB_EHCI_BIG_ENDIAN_MMIO
bool
depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX)
depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || \
XPS_USB_HCD_XILINX || PPC_MPC512x)
default y

config USB_EHCI_BIG_ENDIAN_DESC
bool
depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX)
depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
PPC_MPC512x)
default y

config XPS_USB_HCD_XILINX
Expand Down
99 changes: 71 additions & 28 deletions trunk/drivers/usb/host/ehci-fsl.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,33 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
goto err3;
}

/* Enable USB controller */
temp = in_be32(hcd->regs + 0x500);
out_be32(hcd->regs + 0x500, temp | 0x4);
pdata->regs = hcd->regs;

/* Set to Host mode */
temp = in_le32(hcd->regs + 0x1a8);
out_le32(hcd->regs + 0x1a8, temp | 0x3);
/*
* do platform specific init: check the clock, grab/config pins, etc.
*/
if (pdata->init && pdata->init(pdev)) {
retval = -ENODEV;
goto err3;
}

/*
* Check if it is MPC5121 SoC, otherwise set pdata->have_sysif_regs
* flag for 83xx or 8536 system interface registers.
*/
if (pdata->big_endian_mmio)
temp = in_be32(hcd->regs + FSL_SOC_USB_ID);
else
temp = in_le32(hcd->regs + FSL_SOC_USB_ID);

if ((temp & ID_MSK) != (~((temp & NID_MSK) >> 8) & ID_MSK))
pdata->have_sysif_regs = 1;

/* Enable USB controller, 83xx or 8536 */
if (pdata->have_sysif_regs)
setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4);

/* Don't need to set host mode here. It will be done by tdi_reset() */

retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
if (retval != 0)
Expand All @@ -137,6 +157,8 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
usb_put_hcd(hcd);
err1:
dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
if (pdata->exit)
pdata->exit(pdev);
return retval;
}

Expand All @@ -154,17 +176,30 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
struct platform_device *pdev)
{
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;

usb_remove_hcd(hcd);

/*
* do platform specific un-initialization:
* release iomux pins, disable clock, etc.
*/
if (pdata->exit)
pdata->exit(pdev);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
}

static void mpc83xx_setup_phy(struct ehci_hcd *ehci,
enum fsl_usb2_phy_modes phy_mode,
unsigned int port_offset)
static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
enum fsl_usb2_phy_modes phy_mode,
unsigned int port_offset)
{
u32 portsc = 0;
u32 portsc;

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:
portsc |= PORT_PTS_ULPI;
Expand All @@ -184,20 +219,21 @@ static void mpc83xx_setup_phy(struct ehci_hcd *ehci,
ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]);
}

static void mpc83xx_usb_setup(struct usb_hcd *hcd)
static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct usb_hcd *hcd = ehci_to_hcd(ehci);
struct fsl_usb2_platform_data *pdata;
void __iomem *non_ehci = hcd->regs;
u32 temp;

pdata =
(struct fsl_usb2_platform_data *)hcd->self.controller->
platform_data;
pdata = hcd->self.controller->platform_data;

/* Enable PHY interface in the control reg. */
temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 0x00000004);
out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
if (pdata->have_sysif_regs) {
temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 0x00000004);
out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
}

#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
/*
Expand All @@ -214,7 +250,7 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)

if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
(pdata->operating_mode == FSL_USB2_DR_OTG))
mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);

if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
unsigned int chip, rev, svr;
Expand All @@ -228,25 +264,27 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
ehci->has_fsl_port_bug = 1;

if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
mpc83xx_setup_phy(ehci, pdata->phy_mode, 1);
ehci_fsl_setup_phy(ehci, pdata->phy_mode, 1);
}

if (pdata->have_sysif_regs) {
#ifdef CONFIG_PPC_85xx
out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008);
out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080);
out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008);
out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080);
#else
out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c);
out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040);
out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c);
out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040);
#endif
out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
}
}

/* called after powerup, by probe or system-pm "wakeup" */
static int ehci_fsl_reinit(struct ehci_hcd *ehci)
{
mpc83xx_usb_setup(ehci_to_hcd(ehci));
ehci_fsl_usb_setup(ehci);
ehci_port_power(ehci, 0);

return 0;
Expand All @@ -257,6 +295,11 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
int retval;
struct fsl_usb2_platform_data *pdata;

pdata = hcd->self.controller->platform_data;
ehci->big_endian_desc = pdata->big_endian_desc;
ehci->big_endian_mmio = pdata->big_endian_mmio;

/* EHCI registers start at offset 0x100 */
ehci->caps = hcd->regs + 0x100;
Expand Down Expand Up @@ -370,7 +413,7 @@ static const struct hc_driver ehci_fsl_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
.flags = HCD_USB2,
.flags = HCD_USB2 | HCD_MEMORY,

/*
* basic lifecycle operations
Expand Down
13 changes: 12 additions & 1 deletion trunk/drivers/usb/host/ehci-fsl.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2005 freescale semiconductor
/* Copyright (C) 2005-2010 Freescale Semiconductor, Inc.
* Copyright (c) 2005 MontaVista Software
*
* This program is free software; you can redistribute it and/or modify it
Expand All @@ -19,6 +19,9 @@
#define _EHCI_FSL_H

/* offsets for the non-ehci registers in the FSL SOC USB controller */
#define FSL_SOC_USB_ID 0x0
#define ID_MSK 0x3f
#define NID_MSK 0x3f00
#define FSL_SOC_USB_ULPIVP 0x170
#define FSL_SOC_USB_PORTSC1 0x184
#define PORT_PTS_MSK (3<<30)
Expand All @@ -27,6 +30,14 @@
#define PORT_PTS_SERIAL (3<<30)
#define PORT_PTS_PTW (1<<28)
#define FSL_SOC_USB_PORTSC2 0x188

#define FSL_SOC_USB_USBGENCTRL 0x200
#define USBGENCTRL_PPP (1 << 3)
#define USBGENCTRL_PFP (1 << 2)
#define FSL_SOC_USB_ISIPHYCTRL 0x204
#define ISIPHYCTRL_PXE (1)
#define ISIPHYCTRL_PHYE (1 << 4)

#define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */
#define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */
#define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/usb/host/ehci-mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static inline void ehci_qtd_init(struct ehci_hcd *ehci, struct ehci_qtd *qtd,
{
memset (qtd, 0, sizeof *qtd);
qtd->qtd_dma = dma;
qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
qtd->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT);
qtd->hw_next = EHCI_LIST_END(ehci);
qtd->hw_alt_next = EHCI_LIST_END(ehci);
INIT_LIST_HEAD (&qtd->qtd_list);
Expand Down
Loading

0 comments on commit 6b029d4

Please sign in to comment.