Hi all,

I would like to submit you a patch to add a preliminary support to EHCI USB 
Freescale controller integrated on MPC5121.
There is still much job to do..for now, this patch add support for USB0 on UTMI 
phy. 
I've personally tested this feature with mass storage and it does work.

Could be a base for future development..I'm available to possible improvement 
of source code with your suggestions.

Summary:
- introduced ehci_hcd_init and ehci_hcd_stop functions for MPC5121 integrated 
EHCI USB controller
- introduced enable of EHCI USB controller in include/mpc5121ads.h
- introduced many defines and struct ehci fields to be able to provvide OTG 
feature

Regards,
Francesco Rendine.

Signed-off-by: Francesco Rendine <francesco.rend...@valueteam.com> 

diff --git a/board/freescale/mpc5121ads/mpc5121ads.c 
b/board/freescale/mpc5121ads/mpc5121ads.c
index ec74fd3..0ae4d04 100644
--- a/board/freescale/mpc5121ads/mpc5121ads.c
+++ b/board/freescale/mpc5121ads/mpc5121ads.c
@@ -54,7 +54,8 @@ extern void ide_set_reset(int idereset);
 #define SCCR2_CLOCKS_EN        (CLOCK_SCCR2_DIU_EN |           \
                         CLOCK_SCCR2_I2C_EN |           \
                         CLOCK_SCCR2_MEM_EN |           \
-                        CLOCK_SCCR2_SPDIF_EN)
+                        CLOCK_SCCR2_SPDIF_EN |         \
+                        CLOCK_SCCR2_USB1_EN)
 
 #define CSAW_START(start)      ((start) & 0xFFFF0000)
 #define CSAW_STOP(start, size) (((start) + (size) - 1) >> 16)
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index bf148c4..24d63ae 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -1,4 +1,7 @@
 /*
+ * (C) Copyright 2009, Value Team S.p.A. 
+ * Francesco Rendine, <francesco.rend...@valueteam.com> 
+ *
  * (C) Copyright 2009 Freescale Semiconductor, Inc.
  *
  * (C) Copyright 2008, Excito Elektronik i Sk=E5ne AB
@@ -30,6 +33,7 @@
 #include "ehci.h"
 #include "ehci-core.h"
 
+#ifndef  CONFIG_MPC512X
 /*
  * Create the appropriate control structures to manage
  * a new EHCI host controller.
@@ -38,34 +42,93 @@
  */
 int ehci_hcd_init(void)
 {
-       struct usb_ehci *ehci;
+        struct usb_ehci *ehci;
 
-       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)));
+        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((void *)ehci->usbmode, CM_HOST);
+        /* Set to Host mode */
+        setbits_le32((void *)ehci->usbmode, CM_HOST);
 
-       out_be32((void *)ehci->snoop1, SNOOP_SIZE_2GB);
-       out_be32((void *)ehci->snoop2, 0x80000000 | SNOOP_SIZE_2GB);
+        out_be32((void *)ehci->snoop1, SNOOP_SIZE_2GB);
+        out_be32((void *)ehci->snoop2, 0x80000000 | SNOOP_SIZE_2GB);
 
-       /* Init phy */
-       if (!strcmp(getenv("usb_phy_type"), "utmi"))
-               out_le32(&(hcor->or_portsc[0]), PORT_PTS_UTMI);
-       else
-               out_le32(&(hcor->or_portsc[0]), PORT_PTS_ULPI);
+        /* Init phy */
+        if (!strcmp(getenv("usb_phy_type"), "utmi"))
+                out_le32(&(hcor->or_portsc[0]), PORT_PTS_UTMI);
+        else
+                out_le32(&(hcor->or_portsc[0]), PORT_PTS_ULPI);
 
-       /* Enable interface. */
-       setbits_be32((void *)ehci->control, USB_EN);
+        /* Enable interface. */
+        setbits_be32((void *)ehci->control, USB_EN);
 
-       out_be32((void *)ehci->prictrl, 0x0000000c);
-       out_be32((void *)ehci->age_cnt_limit, 0x00000040);
-       out_be32((void *)ehci->sictrl, 0x00000001);
+        out_be32((void *)ehci->prictrl, 0x0000000c);
+        out_be32((void *)ehci->age_cnt_limit, 0x00000040);
+        out_be32((void *)ehci->sictrl, 0x00000001);
 
-       in_le32((void *)ehci->usbmode);
+        in_le32((void *)ehci->usbmode);
 
+        return 0;
+}
+
+/*
+ * Destroy the appropriate control structures corresponding
+ * the the EHCI host controller.
+ */
+int ehci_hcd_stop(void)
+{
+        return 0;
+}
+#else
+/*
+ * Initialize SOC FSL EHCI Controller 
+ * 
+ * This code is derived from EHCI FSL USB Linux driver for MPC5121
+ *
+ */
+int ehci_hcd_init(void)
+{
+       struct usb_ehci *ehci;
+       u32 temp; 
+
+        /* Hook the memory mapped registers for EHCI-Controller */
+        ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB_ADDR;
+        hccr = (struct ehci_hccr *)(&ehci->caplength);
+       hcor = (struct ehci_hcor *)((uint32_t) hccr +
+                      HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+       /* Confgure interface for UTMI_WIDE */
+        temp = in_be32(&ehci->isiphyctrl);
+        out_be32(&ehci->isiphyctrl, temp | PHYCTRL_PHYE | PHYCTRL_PXE);
+
+        temp = in_be32(&ehci->usbgenctrl);
+        out_be32(&ehci->usbgenctrl, temp | GC_PPP | GC_PFP );
+
+        /* Workaround: disable ULPI phy */
+        temp = 0x60000000 | 0x0C << 16 | 0x20 ;
+        temp = cpu_to_hc32(temp);
+        out_be32(&ehci->ulpi_viewpoint, temp);
+
+       /* Configure interrupt */
+       temp = ehci_readl(&hcor->or_usbintr);
+       temp |= (INTR_UE | INTR_UEE | INTR_PCE | INTR_SEE | INTR_AAE);
+       ehci_writel(&hcor->or_usbintr, temp);
+ 
+       /* Init phy USB0 to UTMI+ */
+       temp = ehci_readl(&hcor->or_portsc[0]);
+       temp &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
+       temp |= (PORT_PTS_UTMI | PORT_PTS_PTW);
+       ehci_writel(&hcor->or_portsc[0], temp);
+ 
+       /* Set to Host mode */
+#ifdef CONFIG_EHCI_DESC_BIG_ENDIAN 
+       setbits_be32(&ehci->usbmode, CM_HOST | ES_BE);
+#else
+       setbits_be32(&ehci->usbmode, CM_HOST);
+#endif
+       
        return 0;
 }
 
@@ -75,5 +138,16 @@ int ehci_hcd_init(void)
  */
 int ehci_hcd_stop(void)
 {
+       u32 temp;
+
+       /* Disable phy USB0 */
+       temp = ehci_readl(&hcor->or_portsc[0]);
+       temp &= ~(PORT_PTS_MSK | PORT_PTS_PTW | PORT_PP | PORT_PR);
+       ehci_writel(&hcor->or_portsc[0], temp);
+
+       /* Unhook struct */
+       hccr = hcor = NULL;
+
        return 0;
 }
+#endif
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index b3c1d5d..6fae8ba 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -71,6 +71,11 @@ struct ehci_hcor {
 #define        STD_ASS         (1 << 15)
 #define STS_HALT       (1 << 12)
        uint32_t or_usbintr;
+#define INTR_UE         (1 << 0)                /* USB interrupt enable */
+#define INTR_UEE        (1 << 1)                /* USB error interrupt enable 
*/
+#define INTR_PCE        (1 << 2)                /* Port change detect enable */
+#define INTR_SEE        (1 << 4)                /* system error enable */
+#define INTR_AAE        (1 << 5)                /* Interrupt on async adavance 
enable */
        uint32_t or_frindex;
        uint32_t or_ctrldssegment;
        uint32_t or_periodiclistbase;
diff --git a/include/asm-ppc/immap_512x.h b/include/asm-ppc/immap_512x.h
index 3648a05..1bb414f 100644
--- a/include/asm-ppc/immap_512x.h
+++ b/include/asm-ppc/immap_512x.h
@@ -1228,4 +1228,8 @@ static inline u32 get_pata_base (void)
 }
 #endif /* __ASSEMBLY__ */
 
+#define CONFIG_SYS_MPC512x_USB_OFFSET   0x4000
+#define CONFIG_SYS_MPC512x_USB_ADDR \
+                        (CONFIG_SYS_IMMR + CONFIG_SYS_MPC512x_USB_OFFSET)
+
 #endif /* __IMMAP_512x__ */
diff --git a/include/configs/mpc5121ads.h b/include/configs/mpc5121ads.h
index 45a004e..60b85a4 100644
--- a/include/configs/mpc5121ads.h
+++ b/include/configs/mpc5121ads.h
@@ -342,6 +342,21 @@
 #define CONFIG_RTC_M41T62                      /* use M41T62 rtc via i2 */
 #define CONFIG_SYS_I2C_RTC_ADDR                0x68    /* at address 0x68      
        */
 
+/* USB  Support */
+#define CONFIG_USB
+
+#ifdef CONFIG_USB
+    #define CONFIG_USB_EHCI
+#endif
+
+#ifdef CONFIG_USB_EHCI
+    #define CONFIG_USB_EHCI_FSL
+    #define CONFIG_EHCI_MMIO_BIG_ENDIAN
+    #define CONFIG_EHCI_DESC_BIG_ENDIAN
+    #define CONFIG_SYS_USB_EHCI_REGS_BASE   0x80004000
+    #define CONFIG_EHCI_IS_TDI
+#endif
+
 /*
  * Environment
  */
@@ -387,6 +402,16 @@
 #define CONFIG_ISO_PARTITION
 #endif /* defined(CONFIG_CMD_IDE) */
 
+#if defined(CONFIG_USB)
+#define CONFIG_CMD_USB
+#define CONFIG_CMD_FAT
+#define CONFIG_SUPPORT_VFAT
+#define CONFIG_USB_STORAGE
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MAC_PARTITION
+#define CONFIG_ISO_PARTITION
+#endif
+
 /*
  * Watchdog timeout = CONFIG_SYS_WATCHDOG_VALUE * 65536 / IPS clock.
  * For example, when IPS is set to 66MHz and CONFIG_SYS_WATCHDOG_VALUE is set
@@ -484,6 +509,7 @@
        "rootpath=/opt/eldk/ppc_6xx\n"                                  \
        "netdev=eth0\0"                                                 \
        "consdev=ttyPSC0\0"                                             \
+       "usb_phy_type=utmi\0"                                           \
        "nfsargs=setenv bootargs root=/dev/nfs rw "                     \
                "nfsroot=${serverip}:${rootpath}\0"                     \
        "ramargs=setenv bootargs root=/dev/ram rw\0"                    \
diff --git a/include/usb/ehci-fsl.h b/include/usb/ehci-fsl.h
index 1140561..cf03638 100644
--- a/include/usb/ehci-fsl.h
+++ b/include/usb/ehci-fsl.h
@@ -35,12 +35,16 @@
 #define PORT_PTS_ULPI          (2 << 30)
 #define PORT_PTS_SERIAL                (3 << 30)
 #define PORT_PTS_PTW           (1 << 28)
+#define PORT_PTS_PHCD           (1 << 23)
+#define PORT_PP                 (1 << 12)       
+#define PORT_PR                 (1 << 8)
 
 /* USBMODE Register bits */
 #define CM_IDLE                        (0 << 0)
 #define CM_RESERVED            (1 << 0)
 #define CM_DEVICE              (2 << 0)
 #define CM_HOST                        (3 << 0)
+#define ES_BE                   (1 << 2)        /* Big Endian Select, default 
is LE */
 #define USBMODE_RESERVED_2     (0 << 2)
 #define SLOM                   (1 << 3)
 #define SDIS                   (1 << 4)
@@ -70,7 +74,74 @@
 #define PHY_CLK_VALID          (1 << 17)
 
 #define FSL_SOC_USB_PORTSC2    0x188
+
+/* OTG Status Control Register bits */
+#define FSL_SOC_USB_OTGSC       0x1a4   
+#define CTRL_VBUS_DISCHARGE     (0x1<<0)
+#define CTRL_VBUS_CHARGE        (0x1<<1)
+#define CTRL_OTG_TERMINATION    (0x1<<3)
+#define CTRL_DATA_PULSING       (0x1<<4)
+#define CTRL_ID_PULL_EN         (0x1<<5)
+#define HA_DATA_PULSE           (0x1<<6)
+#define HA_BA                   (0x1<<7)
+#define STS_USB_ID              (0x1<<8)
+#define STS_A_VBUS_VALID        (0x1<<9)
+#define STS_A_SESSION_VALID     (0x1<<10)
+#define STS_B_SESSION_VALID     (0x1<<11)
+#define STS_B_SESSION_END       (0x1<<12)
+#define STS_1MS_TOGGLE          (0x1<<13)
+#define STS_DATA_PULSING        (0x1<<14)
+#define INTSTS_USB_ID           (0x1<<16)
+#define INTSTS_A_VBUS_VALID     (0x1<<17)
+#define INTSTS_A_SESSION_VALID  (0x1<<18)
+#define INTSTS_B_SESSION_VALID  (0x1<<19)
+#define INTSTS_B_SESSION_END    (0x1<<20)
+#define INTSTS_1MS              (0x1<<21)
+#define INTSTS_DATA_PULSING     (0x1<<22)
+#define INTR_USB_ID_EN          (0x1<<24)
+#define INTR_A_VBUS_VALID_EN    (0x1<<25)
+#define INTR_A_SESSION_VALID_EN (0x1<<26)
+#define INTR_B_SESSION_VALID_EN (0x1<<27)
+#define INTR_B_SESSION_END_EN   (0x1<<28)
+#define INTR_1MS_TIMER_EN       (0x1<<29)
+#define INTR_DATA_PULSING_EN    (0x1<<30)
+#define INTSTS_MASK             (0x00ff0000)
+
+#define  INTERRUPT_ENABLE_BITS_MASK  \
+        (INTR_USB_ID_EN            | \
+        INTR_1MS_TIMER_EN          | \
+        INTR_A_VBUS_VALID_EN       | \
+        INTR_A_SESSION_VALID_EN    | \
+        INTR_B_SESSION_VALID_EN    | \
+        INTR_B_SESSION_END_EN      | \
+        INTR_DATA_PULSING_EN)
+
+#define  INTERRUPT_STATUS_BITS_MASK  \
+        (INTSTS_USB_ID          |    \
+        INTR_1MS_TIMER_EN       |    \
+        INTSTS_A_VBUS_VALID     |    \
+        INTSTS_A_SESSION_VALID  |    \
+        INTSTS_B_SESSION_VALID  |    \
+        INTSTS_B_SESSION_END    |    \
+        INTSTS_DATA_PULSING)
+
 #define FSL_SOC_USB_USBMODE    0x1a8
+
+#define USBGENCTRL              0x200           /* NOTE: big endian */
+#define GC_WU_INT_CLR           (1 << 5)        /* Wakeup int clear */
+#define GC_ULPI_SEL             (1 << 4)        /* ULPI i/f select (usb0 
only)*/
+#define GC_PPP                  (1 << 3)        /* Port Power Polarity */
+#define GC_PFP                  (1 << 2)        /* Power Fault Polarity */
+#define GC_WU_ULPI_EN           (1 << 1)        /* Wakeup on ULPI event */
+#define GC_WU_IE                (1 << 1)        /* Wakeup interrupt enable */
+
+#define ISIPHYCTRL              0x204           /* NOTE: big endian */
+#define PHYCTRL_PHYE            (1 << 4)        /* On-chip UTMI PHY enable */
+#define PHYCTRL_BSENH           (1 << 3)        /* Bit Stuff Enable High */
+#define PHYCTRL_BSEN            (1 << 2)        /* Bit Stuff Enable */
+#define PHYCTRL_LSFE            (1 << 1)        /* Line State Filter Enable */
+#define PHYCTRL_PXE             (1 << 0)        /* PHY oscillator enable */
+
 #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 */
@@ -86,43 +157,59 @@
 #define MPC83XX_SCCR_USB_DRCM_10       0x00200000
 
 #if defined(CONFIG_MPC83XX)
-#define CONFIG_SYS_MPC8xxx_USB_ADDR CONFIG_SYS_MPC83xx_USB_ADDR
+#define CONFIG_SYS_FSL_USB_ADDR CONFIG_SYS_MPC83xx_USB_ADDR
 #elif defined(CONFIG_MPC85xx)
-#define CONFIG_SYS_MPC8xxx_USB_ADDR CONFIG_SYS_MPC85xx_USB_ADDR
+#define CONFIG_SYS_FSL_USB_ADDR CONFIG_SYS_MPC85xx_USB_ADDR
+#elif defined(CONFIG_MPC512X)
+#define CONFIG_SYS_FSL_USB_ADDR CONFIG_SYS_MPC512x_USB_ADDR
 #endif
 
+
 /*
  * USB Registers
  */
 struct usb_ehci {
-       u8      res1[0x100];
+       u32     id;             /* 0x000 - Identification register */
+       u32     hwgeneral;      /* 0x004 - General hardware parameters */
+       u32     hwhost;         /* 0x008 - Host hardware parameters */  
+       u32     hwdevice;       /* 0x00C - Device hardware parameters  */
+       u32     hwtxbuf;        /* 0x010 - TX buffer hardware parameters */
+       u32     hwrxbuf;        /* 0x014 - RX buffer hardware parameters */
+       u8      res1[0x68];
+       u32     gptimer0_ld;    /* 0x080 - General Purpose Timer 0 load value */
+       u32     gptimer0_ctrl;  /* 0x084 - General Purpose Timer 0 control */
+       u32     gptimer1_ld;    /* 0x088 - General Purpose Timer 1 load value */
+        u32     gptimer1_ctrl;  /* 0x08C - General Purpose Timer 1 control */
+       u32     sbuscfg;        /* 0x090 - System Bus Interface Control */
+       u8      res2[0x6C];
        u16     caplength;      /* 0x100 - Capability Register Length */
        u16     hciversion;     /* 0x102 - Host Interface Version */
        u32     hcsparams;      /* 0x104 - Host Structural Parameters */
        u32     hccparams;      /* 0x108 - Host Capability Parameters */
-       u8      res2[0x14];
+       u8      res3[0x14];
        u32     dciversion;     /* 0x120 - Device Interface Version */
        u32     dciparams;      /* 0x124 - Device Controller Params */
-       u8      res3[0x18];
+       u8      res4[0x18];
        u32     usbcmd;         /* 0x140 - USB Command */
        u32     usbsts;         /* 0x144 - USB Status */
        u32     usbintr;        /* 0x148 - USB Interrupt Enable */
        u32     frindex;        /* 0x14C - USB Frame Index */
-       u8      res4[0x4];
+       u8      res5[0x4];
        u32     perlistbase;    /* 0x154 - Periodic List Base
                                         - USB Device Address */
        u32     ep_list_addr;   /* 0x158 - Next Asynchronous List
                                         - End Point Address */
-       u8      res5[0x4];
+       u8      res6[0x4];
        u32     burstsize;      /* 0x160 - Programmable Burst Size */
        u32     txfilltuning;   /* 0x164 - Host TT Transmit
                                           pre-buffer packet tuning */
-       u8      res6[0x8];
+       u8      res7[0x8];
        u32     ulpi_viewpoint; /* 0x170 - ULPI Reister Access */
-       u8      res7[0xc];
+       u8      res8[0xc];
        u32     config_flag;    /* 0x180 - Configured Flag Register */
        u32     portsc;         /* 0x184 - Port status/control */
-       u8      res8[0x20];
+       u8      res9[0x1C];
+       u32     otgsc;          /* 0x1a4 - Oo-The-Go status and control */
        u32     usbmode;        /* 0x1a8 - USB Device Mode */
        u32     epsetupstat;    /* 0x1ac - End Point Setup Status */
        u32     epprime;        /* 0x1b0 - End Point Init Status */
@@ -135,15 +222,18 @@ struct usb_ehci {
        u32     epctrl3;        /* 0x1cc - End Point Control 3 */
        u32     epctrl4;        /* 0x1d0 - End Point Control 4 */
        u32     epctrl5;        /* 0x1d4 - End Point Control 5 */
-       u8      res9[0x228];
+       u8      res10[0x28];
+       u32     usbgenctrl;     /* 0x200 - USB General Control */
+       u32     isiphyctrl;     /* 0x204 - On-Chip PHY Control */
+       u8      res11[0x1F8];
        u32     snoop1;         /* 0x400 - Snoop 1 */
        u32     snoop2;         /* 0x404 - Snoop 2 */
        u32     age_cnt_limit;  /* 0x408 - Age Count Threshold */
        u32     prictrl;        /* 0x40c - Priority Control */
        u32     sictrl;         /* 0x410 - System Interface Control */
-       u8      res10[0xEC];
+       u8      res12[0xEC];
        u32     control;        /* 0x500 - Control */
-       u8      res11[0xafc];
+       u8      res13[0xafc];
 };
 
 #endif /* _EHCI_FSL_H */

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to