From: Marek Vasut <marek.va...@gmail.com> This commit adds USB support for EfikaMX and EfikaSB.
Signed-off-by: Marek Vasut <marek.va...@gmail.com> Signed-off-by: Jana Rapava <ferma...@gmail.com> --- Changes for v2: - changed to proper patch Changes for v3: - merged other USB patches from u-boot-pxa/efikasb - offset-based access changed to struct-based access - use {clrset,clr,set}bits_le32() calls - CodingStyle and naming cleanup board/efikamx/Makefile | 3 + board/efikamx/efikamx-usb.c | 349 +++++++++++++++++++++++++++++++++++++++++++ board/efikamx/efikamx.c | 10 ++ drivers/usb/host/ehci-hcd.c | 19 +++ drivers/usb/host/ehci-mxc.c | 9 +- include/configs/efikamx.h | 35 ++++- include/usb/ehci-fsl.h | 112 ++++++++++++++- 7 files changed, 524 insertions(+), 13 deletions(-) create mode 100644 board/efikamx/efikamx-usb.c diff --git a/board/efikamx/Makefile b/board/efikamx/Makefile index ee4a16e..860e4d2 100644 --- a/board/efikamx/Makefile +++ b/board/efikamx/Makefile @@ -28,6 +28,9 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).o COBJS := efikamx.o +ifdef CONFIG_CMD_USB +COBJS += efikamx-usb.o +endif SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/efikamx/efikamx-usb.c b/board/efikamx/efikamx-usb.c new file mode 100644 index 0000000..19227d4 --- /dev/null +++ b/board/efikamx/efikamx-usb.c @@ -0,0 +1,349 @@ +#include <common.h> +#include <usb.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/mx5x_pins.h> +#include <asm/arch/iomux.h> +#include <asm/gpio.h> +#include <usb/ehci-fsl.h> +#include <errno.h> + +#include "../../drivers/usb/host/ehci.h" +#include "../../drivers/usb/host/ehci-core.h" + +/* + * Configure the USB H1 and USB H2 IOMUX + */ +#define USB_PAD_CONFIG (PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST | \ + PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | \ + PAD_CTL_HYS_ENABLE | PAD_CTL_PUE_PULL) +void setup_iomux_usb(void) +{ + /* + * Configure USBH1 pads + */ + mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_STP, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_USBH1_CLK, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_CLK, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_USBH1_DIR, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_DIR, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_USBH1_NXT, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_NXT, USB_PAD_CONFIG); + + mxc_request_iomux(MX51_PIN_USBH1_DATA0, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_DATA0, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_USBH1_DATA1, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_DATA1, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_USBH1_DATA2, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_DATA2, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_USBH1_DATA3, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_DATA3, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_USBH1_DATA4, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_DATA4, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_USBH1_DATA5, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_DATA5, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_USBH1_DATA6, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_DATA6, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_USBH1_DATA7, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_DATA7, USB_PAD_CONFIG); + + /* + * Configure USBH1 control pads + */ + + /* USB PHY reset */ + mxc_request_iomux(MX51_PIN_EIM_D27, IOMUX_CONFIG_ALT1); + mxc_iomux_set_pad(MX51_PIN_EIM_D27, PAD_CTL_PKE_ENABLE | + PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH); + + /* USB HUB reset */ + mxc_request_iomux(MX51_PIN_GPIO1_5, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_GPIO1_5, PAD_CTL_PKE_ENABLE | + PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH); + + +#ifdef CONFIG_MACH_EFIKASB + /* + * Configure USBH2 pads (used on EfikaSB) + */ + /* USBH2_DATA */ + mxc_request_iomux(MX51_PIN_EIM_D16, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_EIM_D16, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_EIM_D17, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_EIM_D17, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_EIM_D18, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_EIM_D18, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_EIM_D19, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_EIM_D19, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_EIM_D20, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_EIM_D20, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_EIM_D21, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_EIM_D21, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_EIM_D22, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_EIM_D22, USB_PAD_CONFIG); + mxc_request_iomux(MX51_PIN_EIM_D23, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_EIM_D23, USB_PAD_CONFIG); + + /* USBH2_CLK */ + mxc_request_iomux(MX51_PIN_EIM_A24, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_EIM_A24, USB_PAD_CONFIG); + /* USBH2_DIR */ + mxc_request_iomux(MX51_PIN_EIM_A25, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_EIM_A25, USB_PAD_CONFIG); + /* USBH2_STP */ + mxc_request_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_EIM_A26, USB_PAD_CONFIG); + /* USBH2_NXT */ + mxc_request_iomux(MX51_PIN_EIM_A27, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_EIM_A27, USB_PAD_CONFIG); +#endif + + /* WIFI EN (act low) */ + mxc_request_iomux(MX51_PIN_EIM_A22, IOMUX_CONFIG_GPIO); + mxc_iomux_set_pad(MX51_PIN_EIM_A22, 0); + /* WIFI RESET */ + mxc_request_iomux(MX51_PIN_EIM_A16, IOMUX_CONFIG_GPIO); + mxc_iomux_set_pad(MX51_PIN_EIM_A16, 0); + /* BT EN (act low) */ + mxc_request_iomux(MX51_PIN_EIM_A17, IOMUX_CONFIG_GPIO); + mxc_iomux_set_pad(MX51_PIN_EIM_A17, 0); +} + +/* + * Enable devices connected to USB BUSes + */ +void efika_usb_enable_devices(void) +{ + /* Enable Bluetooth */ + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_A17), 0); + udelay(10000); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_A17), 1); + + /* Enable WiFi */ + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_A22), 1); + udelay(10000); + + /* Reset the WiFi chip */ + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_A16), 0); + udelay(10000); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_A16), 1); +} + +/* + * Reset USB HUB (or HUBs on EfikaSB) + */ +void efika_usb_hub_reset(void) +{ + /* HUB reset */ + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_GPIO1_5), 1); + udelay(1000); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_5), 0); + udelay(1000); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_5), 1); +} + +/* + * Reset USB PHY (or PHYs on EfikaSB) + */ +void efika_usb_phy_reset(void) +{ + /* SMSC 3317 PHY reset */ + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_D27), 0); + udelay(1000); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_D27), 1); +} + +/* + * Configure control registers of the USB controller + */ +void control_regs_setup(struct usb_control_regs *control) +{ + clrsetbits_le32(&control->usbctrl, + (MXX1_OTG_WUE | MXX1_OTG_PM | MX51_H1_ULPI_IE | MX51_H1_WUE), + MX51_H1_PM); + + clrsetbits_le32(&control->phyctrl0, + MX51_OTG_OVERCURD, + MX51_EHCI_POWERPINSE); + + clrsetbits_le32(&control->phyctrl1, + MX51_SYSCLOCK_MASK, + MX51_SYSCLOCK_24_MHZ); + + setbits_le32(&control->usbctrl1, MX51_H1_EXTCLKE); + + clrsetbits_le32(&control->uh2ctrl, + (MX51_H2_ULPI_IE | MX51_H2_WUE), + MX51_H2_PM); + + udelay(10000); +} + +#define ULPI_ADDR_SHIFT 16 +#define ulpi_write_mask(value) ((value) & 0xff) +#define ulpi_read_mask(value) (((value) >> 8) & 0xff) + + +void ulpi_write(u32 reg, u32 value, struct usb_ehci *ehci) +{ + if (!(readl(&ehci->ulpi_viewpoint) & ULPI_SS)) { + writel(ULPI_WU, &ehci->ulpi_viewpoint); + while (readl(&ehci->ulpi_viewpoint) & ULPI_WU) + ; + } + writel(ULPI_RWRUN | ULPI_RWCTRL | reg << ULPI_ADDR_SHIFT | ulpi_write_mask(value), + &ehci->ulpi_viewpoint); + + while (readl(&ehci->ulpi_viewpoint) & ULPI_RWRUN) + ; +} + +u32 ulpi_read(u32 reg, struct usb_ehci *ehci) +{ + u32 tmp; + if (!(readl(&ehci->ulpi_viewpoint) & ULPI_SS)) { + writel(ULPI_WU, &ehci->ulpi_viewpoint); + while (readl(&ehci->ulpi_viewpoint) & ULPI_WU) + ; + } + writel(ULPI_RWRUN | reg << ULPI_ADDR_SHIFT, &ehci->ulpi_viewpoint); + do { + tmp = readl(&ehci->ulpi_viewpoint); + } while (tmp & ULPI_RWRUN); + return ulpi_read_mask(tmp); +} + +void ehciX_init(u32 base, struct ulpi_regs *ulpi, struct usb_ehci *ehci) +{ + u32 tmp = 0; + int reg, i; + + /* get ID from ULPI immediate registers*/ + for (reg = ULPI_ID_REGS_COUNT - 1; reg >= 0; reg--) + tmp |= ulpi_read(reg, ehci) << (reg * 8); + /* split into vendor and product ID */ + debug("Found ULPI TX, ID %04x:%04x\n", tmp >> 16, tmp & 0xffff); + + /* ULPI check integrity */ + for (i = 0; i < 2; i++) { + ulpi_write(&ulpi->scratch_write, 0x55 << i, ehci); + tmp = ulpi_read(&ulpi->scratch_write, ehci); + + if (tmp != (0x55 << i)) { + printf("ULPI integrity check failed\n"); + return; + } + } + + /* ULPI set flags */ + ulpi_write(&ulpi->otg_ctrl_write, + ULPI_OTG_EXT_VBUS_IND | ULPI_OTG_DM_PULLDOWN | ULPI_OTG_DP_PULLDOWN, ehci); + ulpi_write(&ulpi->function_ctrl_write, + ULPI_FC_XCVR_SELECT | ULPI_FC_OPMODE_NORMAL | ULPI_FC_SUSPENDM_PWRED, ehci); + ulpi_write(&ulpi->iface_ctrl_write, 0, ehci); + ulpi_write(&ulpi->otg_ctrl_set, + ULPI_OTG_DRV_VBUS | ULPI_OTG_DRV_VBUS_EXT, ehci); + + /* + * NOTE: This violates USB specification, but otherwise, USB on Efika + * doesn't work. + */ + ulpi_write(&ulpi->otg_ctrl_set, ULPI_OTG_CHRG_VBUS, ehci); +} + +void ehci0_init(struct usb_ehci *ehci) +{ + setbits_le32(&ehci->portsc, MX51_16BIT_UTMI); +} + +void ehci1_init(struct usb_ehci *ehci, struct ulpi_regs *ulpi) +{ + mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_USBH1_STP, PAD_CTL_DRV_HIGH | + PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_USBH1_STP), 0); + udelay(1000); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_USBH1_STP), 1); + udelay(1000); + + mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_STP, USB_PAD_CONFIG); + udelay(10000); + + clrbits_le32(&ehci->usbcmd, MX51_ITC_IMMEDIATE_MASK); + udelay(10000); + + writel(MX51_ULPI_MODE_MASK, &ehci->portsc); + udelay(10000); + + ehciX_init(OTG_BASE_ADDR + MX51_UH1_ID, ulpi, ehci); +} + + +void ehci2_init(struct usb_ehci *ehci, struct ulpi_regs *ulpi) +{ + mxc_request_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT1); + mxc_iomux_set_pad(MX51_PIN_EIM_A26, PAD_CTL_DRV_HIGH | + PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_A26), 0); + udelay(1000); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_A26), 1); + udelay(1000); + + mxc_request_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT2); + mxc_iomux_set_pad(MX51_PIN_EIM_A26, USB_PAD_CONFIG); + + setbits_le32(&ehci->portsc, MX51_ULPI_MODE_MASK); + udelay(10000); + + ehciX_init(OTG_BASE_ADDR + MX51_UH2_ID, ulpi, ehci); +} + +int ehci_hcd_init(void) +{ + struct usb_ehci *ehci; + struct usb_control_regs *control; + struct ulpi_regs *ulpi; + + /* Init iMX51 EHCI */ + efika_usb_phy_reset(); + efika_usb_hub_reset(); + efika_usb_enable_devices(); + + control = (struct usb_control_regs *)(OTG_BASE_ADDR + + MX51_CTRL_REGS); + control_regs_setup(control); + + ulpi = (struct ulpi_regs *)(0); + /* Init EHCI core */ + ehci = (struct usb_ehci *)(OTG_BASE_ADDR + + (MX51_REGISTER_LAYOUT_LENGTH * CONFIG_MXC_USB_PORT)); + hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); + hcor = (struct ehci_hcor *)((uint32_t) hccr + + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); + setbits_le32(&ehci->usbmode, CM_HOST); + setbits_le32(&ehci->control, USB_EN); + + switch (CONFIG_MXC_USB_PORT) { + case 0: + ehci0_init(ehci); + case 1: + ehci1_init(ehci, ulpi); +#ifdef MACH_EFIKASB + case 2: + ehci2_init(ehci, ulpi); +#endif + }; + + /* EfikaMX USB has issues ... */ + udelay(10000); + + + return 0; +} + +int ehci_hcd_stop(void) +{ + return 0; +} diff --git a/board/efikamx/efikamx.c b/board/efikamx/efikamx.c index 5be1f6c..0f84ae0 100644 --- a/board/efikamx/efikamx.c +++ b/board/efikamx/efikamx.c @@ -489,6 +489,15 @@ static inline void setup_iomux_ata(void) { } #endif /* + * EHCI USB + */ +#ifdef CONFIG_CMD_USB +extern void setup_iomux_usb(void); +#else +static inline void setup_iomux_usb(void) { } +#endif + +/* * LED configuration */ void setup_iomux_led(void) @@ -621,6 +630,7 @@ int board_late_init(void) setup_iomux_led(); setup_iomux_ata(); + setup_iomux_usb(); efikamx_toggle_led(EFIKAMX_LED_BLUE); diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 2197119..52b98c2 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -26,6 +26,7 @@ #include <asm/io.h> #include <malloc.h> #include <watchdog.h> +#include <usb/ehci-fsl.h> #include "ehci.h" @@ -709,8 +710,26 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, * usb 2.0 specification say 50 ms resets on * root */ + /* wait_ms(50); */ + +#if 1 + struct usb_ehci *ehci = (struct usb_ehci *)(OTG_BASE_ADDR + + (MX51_REGISTER_LAYOUT_LENGTH)); + extern u32 ulpi_read(u32 reg, struct usb_ehci *ehci); + extern void ulpi_write(u32 reg, u32 value, struct usb_ehci *ehci); + #define XXBASE 0x73f80200 + /* OTG |= 1 << 4 */ + u32 tmp = ulpi_read(0x0a, ehci); + tmp |= (1 << 4); + ulpi_write(0x0a, tmp, ehci); + wait_ms(50); + + /* terminate the reset */ + reg = ehci_readl(status_reg); + reg |= EHCI_PS_PE; +#endif ehci_writel(status_reg, reg & ~EHCI_PS_PR); /* * A host controller must terminate the reset diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index a0cfbb7..de7ed00 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -37,9 +37,6 @@ #endif #ifdef CONFIG_MX31 -#define MX31_OTG_SIC_SHIFT 29 -#define MX31_OTG_SIC_MASK (0x3 << MX31_OTG_SIC_SHIFT) -#define MX31_OTG_PM_BIT (1 << 24) #define MX31_H2_SIC_SHIFT 21 #define MX31_H2_SIC_MASK (0x3 << MX31_H2_SIC_SHIFT) @@ -66,11 +63,11 @@ static int mxc_set_usbcontrol(int port, unsigned int flags) switch (port) { case 0: /* OTG port */ - v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); + v &= ~(MXX1_OTG_SIC_MASK | MXX1_OTG_PM_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) - << MX31_OTG_SIC_SHIFT; + << MXX1_OTG_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) - v |= MX31_OTG_PM_BIT; + v |= MXX1_OTG_PM_BIT; break; case 1: /* H1 port */ diff --git a/include/configs/efikamx.h b/include/configs/efikamx.h index b90e342..9cbb024 100644 --- a/include/configs/efikamx.h +++ b/include/configs/efikamx.h @@ -40,6 +40,10 @@ #define CONFIG_SYS_TEXT_BASE 0x97800000 +#define CONFIG_L2_OFF +#define CONFIG_SYS_ICACHE_OFF +#define CONFIG_SYS_DCACHE_OFF + /* * Bootloader Components Configuration */ @@ -49,6 +53,8 @@ #define CONFIG_CMD_FAT #define CONFIG_CMD_EXT2 #define CONFIG_CMD_IDE +#define CONFIG_CMD_NET +#define CONFIG_CMD_DATE #undef CONFIG_CMD_IMLS /* @@ -168,17 +174,34 @@ #endif /* + * USB + */ +#define CONFIG_CMD_USB +#ifdef CONFIG_CMD_USB +#define CONFIG_USB_EHCI /* Enable EHCI USB support */ +#define CONFIG_MXC_USB_PORT 1 +#define CONFIG_EHCI_IS_TDI +#define CONFIG_USB_STORAGE +#define CONFIG_USB_HOST_ETHER +#define CONFIG_USB_KEYBOARD +/* USB NET */ +#ifdef CONFIG_CMD_NET +#define CONFIG_USB_ETHER_ASIX +#define CONFIG_NET_MULTI +#define CONFIG_CMD_PING +#define CONFIG_CMD_DHCP +#endif +#endif /* CONFIG_CMD_USB */ + +/* * Filesystems */ #ifdef CONFIG_CMD_FAT #define CONFIG_DOS_PARTITION +#ifdef CONFIG_CMD_NET +#define CONFIG_CMD_NFS +#endif #endif - -#undef CONFIG_CMD_PING -#undef CONFIG_CMD_DHCP -#undef CONFIG_CMD_NET -#undef CONFIG_CMD_NFS -#define CONFIG_CMD_DATE /* * Miscellaneous configurable options diff --git a/include/usb/ehci-fsl.h b/include/usb/ehci-fsl.h index 67600ed..9360ba5 100644 --- a/include/usb/ehci-fsl.h +++ b/include/usb/ehci-fsl.h @@ -169,6 +169,78 @@ #define CONFIG_SYS_FSL_USB_ADDR CONFIG_SYS_MPC512x_USB_ADDR #endif + +#ifdef CONFIG_MX51 || CONFIG_MX31 +/* USB_CTRL register bits of interest*/ +#define MXX1_OTG_SIC_SHIFT 29 +#define MXX1_OTG_SIC_MASK (0x3 << MX31_OTG_SIC_SHIFT) +#define MXX1_OTG_WUE (1 << 27) +#define MXX1_OTG_PM (1 << 24) +#endif + +#ifdef CONFIG_MX51 +#define MX51_REGISTER_LAYOUT_LENGTH 0x200 + +/* Register offsets for MX51 */ +#define MX51_OTG_ID 0x000 +#define MX51_UH1_ID 0x200 +#define MX51_UH2_ID 0x400 +#define MX51_CTRL_REGS 0x800 + +/* USB_CTRL register bits of interest*/ +#define MX51_OTG_PM (1 << 24) +#define MX51_H1_ULPI_IE (1 << 12) +#define MX51_H1_WUE (1 << 11) +#define MX51_H1_PM (1 << 8) + +/* PHY_CTRL_0 register bits of interest */ +#define MX51_OTG_OVERCURD (1 << 8) +#define MX51_EHCI_POWERPINSE (1 << 5) + +/* PHY_CTRL_1 register bits of interest */ +#define MX51_SYSCLOCK_24_MHZ (1 << 0) +#define MX51_SYSCLOCK_MASK (~(0xffffffff << 2)) + +/* USB_CTRL_1 register bits of interest */ +#define MX51_H1_EXTCLKE (1 << 25) + +/* USB Host 2 CTRL register bits of interest */ +#define MX51_H2_ULPI_IE (1 << 8) +#define MX51_H2_WUE (1 << 7) +#define MX51_H2_PM (1 << 4) + +/* PORTSCx bits of interest */ +#define MX51_ULPI_MODE_MASK (2 << 30) +#define MX51_16BIT_UTMI (1 << 28) + +/* USBCMD bits of interest */ +#define MX51_ITC_IMMEDIATE_MASK (0xff << 16) +#endif + +/* +* ULPI +*/ +#define ULPI_ID_REGS_COUNT 4 + +/* ULPI viewport control bits */ +#define ULPI_WU (1 << 31) +#define ULPI_SS (1 << 27) +#define ULPI_RWRUN (1 << 30) +#define ULPI_RWCTRL (1 << 29) + +/* ULPI OTG Control bits of interest */ +#define ULPI_OTG_EXT_VBUS_IND (1 << 7) +#define ULPI_OTG_DM_PULLDOWN (1 << 2) +#define ULPI_OTG_DP_PULLDOWN (1 << 1) +#define ULPI_OTG_DRV_VBUS (1 << 5) +#define ULPI_OTG_DRV_VBUS_EXT (1 << 6) +#define ULPI_OTG_CHRG_VBUS (1 << 4) + +/* ULPI Function Control bits of interest */ +#define ULPI_FC_XCVR_SELECT (1 << 0) +#define ULPI_FC_OPMODE_NORMAL (0 << 3) +#define ULPI_FC_SUSPENDM_PWRED (1 << 6) + /* * USB Registers */ @@ -210,7 +282,7 @@ struct usb_ehci { u32 txfilltuning; /* 0x164 - Host TT Transmit pre-buffer packet tuning */ u8 res7[0x8]; - u32 ulpi_viewpoint; /* 0x170 - ULPI Reister Access */ + u32 ulpi_viewpoint; /* 0x170 - ULPI Register Access */ u8 res8[0xc]; u32 config_flag; /* 0x180 - Configured Flag Register */ u32 portsc; /* 0x184 - Port status/control */ @@ -242,4 +314,42 @@ struct usb_ehci { u8 res13[0xafc]; }; +struct usb_control_regs { + u32 usbctrl; /* 0x800 - USB Control */ + u32 otgmirror; /* 0x804 - OTG Port Mirror */ + u32 phyctrl0; /* 0x808 - UTMI PHY Control Register 0 */ + u32 phyctrl1; /* 0x80C - UTMI PHY Control Register 1 */ + u32 usbctrl1; /* 0x810 - USB Control Register 1 */ + u32 uh2ctrl; /* 0x814 - USB Host2 Control */ + u32 uh3ctrl; /* 0x818 - USB Host3 Control */ +}; + +struct ulpi_regs { + u8 vendor_id_low; /* 0x00 - Vendor ID lower byte */ + u8 vendor_id_high; /* 0x01 - Vendor ID upper byte */ + u8 product_id_low; /* 0x02 - Product ID lower byte */ + u8 product_id_high; /* 0x03 - Product ID higher byte */ + u8 function_ctrl_write; /* Function Control; 0x04 - 0x06 Read, 0x04 Write */ + u8 function_ctrl_set; /* 0x05 Set */ + u8 function_ctrl_clear; /* 0x06 Clear */ + u8 iface_ctrl_write; /* Interface Control; 0x07 - 0x09 Read, 0x07 Write */ + u8 iface_ctrl_set; /* 0x08 Set */ + u8 iface_ctrl_clear; /* 0x09 Clear */ + u8 otg_ctrl_write; /* OTG Control; 0x0A - 0x0C Read, 0x0A Write */ + u8 otg_ctrl_set; /* 0x0B Set */ + u8 otg_ctrl_clear; /* 0x0C Clear */ + u8 usb_ie_rising_write; /* USB Interrupt Enable Rising; 0x0D - 0x0F Read, 0x0D Write */ + u8 usb_ie_rising_set; /* 0x0E Set */ + u8 usb_ie_rising_clear; /* 0x0F Clear */ + u8 usb_ie_falling_write; /* USB Interrupt Enable Falling; 0x10 - 0x12 Read, 0x10 Write */ + u8 usb_ie_falling_set; /* 0x11 Set */ + u8 usb_ie_falling_clear; /* 0x12 Clear */ + u8 usb_int_status; /* 0x13 - USB Interrupt Status */ + u8 usb_int_latch; /* 0x14 - USB Interrupt Latch */ + u8 debug; /* 0x15 - Debug */ + u8 scratch_write; /* Scratch Register; 0x16 - 0x18 Read, 0x16 Write */ + u8 scratch_set; /* 0x17 Set */ + u8 scratch_clear; /* 0x18 */ +}; + #endif /* _EHCI_FSL_H */ -- 1.7.6.3 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot