X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fusb%2Fhost%2Fehci-fsl.c;h=f54b4089662d8cf472ff39f7f3d230987d630228;hb=39fd6342a431abc0de786936eab87e731ba29cb7;hp=c674929725230a9bb94b9bbe07a802ea56b7611b;hpb=6a6bf27f26999ee716972536bfce30cb35c8b032;p=u-boot diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index c674929725..f54b408966 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2009 Freescale Semiconductor, Inc. + * (C) Copyright 2009, 2011 Freescale Semiconductor, Inc. * * (C) Copyright 2008, Excito Elektronik i Sk=E5ne AB * @@ -26,9 +26,21 @@ #include #include #include +#include #include "ehci.h" -#include "ehci-core.h" + +/* Check USB PHY clock valid */ +static int usb_phy_clk_valid(struct usb_ehci *ehci) +{ + if (!((in_be32(&ehci->control) & PHY_CLK_VALID) || + in_be32(&ehci->prictrl))) { + printf("USB PHY clock invalid!\n"); + return 0; + } else { + return 1; + } +} /* * Create the appropriate control structures to manage @@ -36,14 +48,21 @@ * * Excerpts from linux ehci fsl driver. */ -int ehci_hcd_init(void) +int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { struct usb_ehci *ehci; + const char *phy_type = NULL; + size_t len; +#ifdef CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY + char usb_phy[5]; - ehci = (struct usb_ehci *)CONFIG_SYS_MPC8xxx_USB_ADDR; - hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); - hcor = (struct ehci_hcor *)((uint32_t) hccr + - HC_LENGTH(ehci_readl(&hccr->cr_capbase))); + usb_phy[0] = '\0'; +#endif + + ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB_ADDR; + *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); + *hcor = (struct ehci_hcor *)((uint32_t) *hccr + + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); /* Set to Host mode */ setbits_le32(&ehci->usbmode, CM_HOST); @@ -52,13 +71,38 @@ int ehci_hcd_init(void) out_be32(&ehci->snoop2, 0x80000000 | SNOOP_SIZE_2GB); /* Init phy */ - if (!strcmp(getenv("usb_phy_type"), "utmi")) - out_le32(&(hcor->or_portsc[0]), PORT_PTS_UTMI); + if (hwconfig_sub("usb1", "phy_type")) + phy_type = hwconfig_subarg("usb1", "phy_type", &len); else - out_le32(&(hcor->or_portsc[0]), PORT_PTS_ULPI); + phy_type = getenv("usb_phy_type"); + + if (!phy_type) { +#ifdef CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY + /* if none specified assume internal UTMI */ + strcpy(usb_phy, "utmi"); + phy_type = usb_phy; +#else + printf("WARNING: USB phy type not defined !!\n"); + return -1; +#endif + } - /* Enable interface. */ - setbits_be32(&ehci->control, USB_EN); + if (!strcmp(phy_type, "utmi")) { +#if defined(CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY) + setbits_be32(&ehci->control, PHY_CLK_SEL_UTMI); + setbits_be32(&ehci->control, UTMI_PHY_EN); + udelay(1000); /* delay required for PHY Clk to appear */ +#endif + out_le32(&(*hcor)->or_portsc[0], PORT_PTS_UTMI); + setbits_be32(&ehci->control, USB_EN); + } else { + setbits_be32(&ehci->control, PHY_CLK_SEL_ULPI); + clrsetbits_be32(&ehci->control, UTMI_PHY_EN, USB_EN); + udelay(1000); /* delay required for PHY Clk to appear */ + if (!usb_phy_clk_valid(ehci)) + return -EINVAL; + out_le32(&(*hcor)->or_portsc[0], PORT_PTS_ULPI); + } out_be32(&ehci->prictrl, 0x0000000c); out_be32(&ehci->age_cnt_limit, 0x00000040); @@ -73,7 +117,7 @@ int ehci_hcd_init(void) * Destroy the appropriate control structures corresponding * the the EHCI host controller. */ -int ehci_hcd_stop(void) +int ehci_hcd_stop(int index) { return 0; }