
Problem:
I have got the MX25PDK board to detect the USB hub but its power is cut at usb_hub_power_on(hub) because (I guess) the control register is not set properly.
Method:
a) Enable USB options in mx25pdk.h b) Enable signal muxing of USBH2_PWR and USBH2_OC.
Experiment:
When booting Linux it is shown: "io mem 0x53ff4400" so my guess was that address should be used for both mxc_set_usbcontrol() and ehci_hcd_init()? And actually, changing the define helped me:
wPortStatus: 0x508 wPortChange: 0x0 <- With writel(v, IMX_USB_BASE + 0x600); wPortChange: 0x301 wPortChange: 0x1 <- With writel(v, IMX_USB_BASE + 0x400);
The change did not make very much sense, and actually wPortChange: 0x301 wPortChange: 0x1 is given also when skipping mxc_set_usbcontrol() completely :)
1) So, what is the proper control address for using the MX25PDK's standard USB host port (not OTG)?
Indeed, without a proper mxc_set_usbcontrol() the root hub gets "local power source is lost (inactive)". Actually the USB host port, J18, supplies the required 5V (4.89V to be exact) to my plugged stick until usb_hub_power_on(hub) has run. This line makes the USB host controller set the USBH2_PWR (pin D9) to zero, that makes the regulator stop feeding the port.
2) Do I need to set the mux's SW_PAD_CTL for the D9 pins? 3) Are there any pins I have forgot to mux?
If I comment out usb_hub_power_on(hub): | ... | local power source is lost (inactive) | no over-current condition exists | usb_control_msg: request: 0x0, requesttype: 0xA3, value 0x0 index 0x1 length 0x4 | req=0 (0x0), type=163 (0xa3), value=0, index=1 | wPortStatus: 400 wPortChange: 0 | Port 1 Status 400 Change 0 | 1 USB Device(s) found | scan end | scanning bus for storage devices... 0 Storage Device(s) found
The 5V is kept but I will not get the wPortChange=0x1 so usb_new_device() will be skipped. Off course, the usb_hub_power_on(hub) should be kept. But without the 5V, usb_new_device() will not find any device :)
See bellow for details!
Hugo Holgersson
Debug log:
MX25PDK U-Boot > usb start (Re)start USB... USB: Register 10011 NbrPorts 1 USB EHCI 1.00 scanning bus for devices... New Device 0 usb_control_msg: request: 0x6, requesttype: 0x80, value 0x100 index 0x0 length 0x40 req=6 (0x6), type=128 (0x80), value=256, index=0 USB_DT_DEVICE request set address 1 usb_control_msg: request: 0x5, requesttype: 0x0, value 0x1 index 0x0 length 0x0 req=5 (0x5), type=0 (0x0), value=1, index=0 USB_REQ_SET_ADDRESS Len is 0 usb_control_msg: request: 0x6, requesttype: 0x80, value 0x100 index 0x0 length 0x12 req=6 (0x6), type=128 (0x80), value=256, index=0 USB_DT_DEVICE request usb_control_msg: request: 0x6, requesttype: 0x80, value 0x200 index 0x0 length 0x9 req=6 (0x6), type=128 (0x80), value=512, index=0 USB_DT_CONFIG config usb_control_msg: request: 0x6, requesttype: 0x80, value 0x200 index 0x0 length 0x19 req=6 (0x6), type=128 (0x80), value=512, index=0 USB_DT_CONFIG config get_conf_no 0 Result 25, wLength 25 if 0, ep 0 ##EP epmaxpacketin[1] = 8 set configuration 1 usb_control_msg: request: 0x9, requesttype: 0x0, value 0x1 index 0x0 length 0x0 req=9 (0x9), type=0 (0x0), value=1, index=0 USB_REQ_SET_CONFIGURATION Len is 0 new device strings: Mfr=1, Product=2, SerialNumber=0 usb_control_msg: request: 0x6, requesttype: 0x80, value 0x300 index 0x0 length 0xFF req=6 (0x6), type=128 (0x80), value=768, index=0 USB_DT_STRING config USB device number 1 default language ID 0x1 usb_control_msg: request: 0x6, requesttype: 0x80, value 0x301 index 0x1 length 0xFF req=6 (0x6), type=128 (0x80), value=769, index=1 USB_DT_STRING config usb_control_msg: request: 0x6, requesttype: 0x80, value 0x302 index 0x1 length 0xFF req=6 (0x6), type=128 (0x80), value=770, index=1 USB_DT_STRING config Manufacturer u-boot Product EHCI Host Controller SerialNumber USB hub found usb_control_msg: request: 0x6, requesttype: 0xA0, value 0x2900 index 0x0 length 0x4 req=6 (0x6), type=160 (0xa0), value=10496, index=0 USB_DT_HUB config usb_control_msg: request: 0x6, requesttype: 0xA0, value 0x2900 index 0x0 length 0x8 req=6 (0x6), type=160 (0xa0), value=10496, index=0 USB_DT_HUB config 1 ports detected individual port power switching standalone hub global over-current protection power on to power good time: 510ms hub controller current requirement: 0mA port 1 is removable usb_control_msg: request: 0x0, requesttype: 0xA0, value 0x0 index 0x0 length 0x4 req=0 (0x0), type=160 (0xa0), value=0, index=0 get_hub_status returned status 1, change 8101 local power source is lost (inactive) no over-current condition exists enabling power on all ports usb_control_msg: request: 0x3, requesttype: 0x23, value 0x8 index 0x1 length 0x0 req=3 (0x3), type=35 (0x23), value=8, index=1 Len is 0 port 1 returns 0 usb_control_msg: request: 0x0, requesttype: 0xA3, value 0x0 index 0x1 length 0x4 req=0 (0x0), type=163 (0xa3), value=0, index=1 Port 1 Status 301 Change 1 port 1 connection change usb_control_msg: request: 0x0, requesttype: 0xA3, value 0x0 index 0x1 length 0x4 req=0 (0x0), type=163 (0xa3), value=0, index=1 portstatus 301, change 1, 1.5 Mb/s usb_control_msg: request: 0x1, requesttype: 0x23, value 0x10 index 0x1 length 0x0 req=1 (0x1), type=35 (0x23), value=16, index=1 Len is 0 hub_port_reset: resetting port 0... usb_control_msg: request: 0x3, requesttype: 0x23, value 0x4 index 0x1 length 0x0 req=3 (0x3), type=35 (0x23), value=4, index=1 Len is 0 usb_control_msg: request: 0x0, requesttype: 0xA3, value 0x0 index 0x1 length 0x4 req=0 (0x0), type=163 (0xa3), value=0, index=1 portstatus 303, change 10, 1.5 Mb/s STAT_C_CONNECTION = 0 STAT_CONNECTION = 1 USB_PORT_STAT_ENABLE 1 usb_control_msg: request: 0x1, requesttype: 0x23, value 0x14 index 0x1 length 0x0 req=1 (0x1), type=35 (0x23), value=20, index=1 Len is 0 New Device 1 usb_control_msg: request: 0x6, requesttype: 0x80, value 0x100 index 0x0 length 0x40 dev=83fe13f0, pipe=84000083, buffer=83d9a55c, length=64, req=83feb7b4 req=6 (0x6), type=128 (0x80), value=256 (0x100), index=0 EHCI timed out on TD - token=0x80008c80 TOKEN=0x80248 usb_new_device: usb_get_descriptor() failed hub: disabling port 1 usb_control_msg: request: 0x1, requesttype: 0x23, value 0x1 index 0x1 length 0x0 req=1 (0x1), type=35 (0x23), value=1, index=1 Len is 0 2 USB Device(s) found scan end scanning bus for storage devices... 0 Storage Device(s) found MX25PDK U-Boot > MX25PDK U-Boot > usb tree
Device Tree: 1 Hub (480 Mb/s, 0mA) | u-boot EHCI Host Controller | +-0 See Interface (1.5 Mb/s, 0mA)
Code changes:
diff --git a/board/freescale/mx25pdk/lowlevel_init.S b/board/freescale/mx25pdk/lowlevel_init.S index 6e6810f..1997115 100644 --- a/board/freescale/mx25pdk/lowlevel_init.S +++ b/board/freescale/mx25pdk/lowlevel_init.S @@ -15,7 +15,41 @@ * GNU General Public License for more details. */
+#include <asm/macro.h> +#include <asm/arch/macro.h> +#include <asm/arch/imx-regs.h> +#include <generated/asm-offsets.h> + +/* + * clocks + */ +.macro init_clocks + + /* disable clock output */ + write32 IMX_CCM_BASE + CCM_MCR, 0x00000000 + write32 IMX_CCM_BASE + CCM_CCTL, 0x50030000 + + /* first enable CLKO debug output + * 0x40000000 enables the debug CLKO signal + * 0x05000000 sets CLKO divider to 6 + * 0x00600000 makes CLKO parent clk the USB clk + */ + write32 0x53f80064, 0x45600000 + write32 0x53f80008, 0x20034000 + + /* + * enable all implemented clocks in all three + * clock control registers + */ + write32 IMX_CCM_BASE + CCM_CGCR0, 0x1fffffff + write32 IMX_CCM_BASE + CCM_CGCR1, 0xffffffff + write32 IMX_CCM_BASE + CCM_CGCR2, 0xfffff + + /* Devide NAND clock by 32 */ + write32 IMX_CCM_BASE + CCM_PCDR2, 0x0101011F +.endm + .globl lowlevel_init lowlevel_init: - + init_clocks mov pc, lr diff --git a/board/freescale/mx25pdk/mx25pdk.c b/board/freescale/mx25pdk/mx25pdk.c index 4a8352f..9212607 100644 --- a/board/freescale/mx25pdk/mx25pdk.c +++ b/board/freescale/mx25pdk/mx25pdk.c @@ -19,10 +19,12 @@
#include <common.h> #include <asm/io.h> +#include <asm/gpio.h> #include <asm/arch/imx-regs.h> #include <asm/arch/imx25-pinmux.h> #include <asm/arch/sys_proto.h>
+ DECLARE_GLOBAL_DATA_PTR;
int dram_init(void) @@ -42,6 +44,25 @@ int board_early_init_f(void)
int board_init(void) { + struct iomuxc_mux_ctl *muxctl; + struct iomuxc_pad_ctl *padctl; + u32 gpio_mux_mode5 = MX25_PIN_MUX_MODE(5); + u32 gpio_mux_mode6 = MX25_PIN_MUX_MODE(6); + + muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE; + + /* USBH2_PWR */ + writel(gpio_mux_mode6, &muxctl->pad_d9); + //writel(gpio_mux_mode5, &muxctl->pad_d9); + //gpio_direction_output(MXC_GPIO_PORT_TO_NUM(4, 11), 1); /* Try keep power on. */ + + /* USBH2_OC */ + writel(gpio_mux_mode6, &muxctl->pad_d8); + + /* USB_BT_CS low selects USB Host */ + writel(gpio_mux_mode5, &muxctl->pad_a21); /* GPIO2[7] */ + gpio_direction_output(MXC_GPIO_PORT_TO_NUM(2, 7), 0); /* Chip select 0*/ + /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
diff --git a/config.mk b/config.mk index 3fa9eef..b83179c 100644 --- a/config.mk +++ b/config.mk @@ -163,8 +163,8 @@ else ARFLAGS = crv endif RELFLAGS= $(PLATFORM_RELFLAGS) -DBGFLAGS= -g # -DDEBUG -OPTFLAGS= -Os #-fomit-frame-pointer +DBGFLAGS= -g -DDEBUG +OPTFLAGS= -fno-schedule-insns -fno-schedule-insns2 #-fomit-frame-pointer
OBJCFLAGS += --gap-fill=0xff
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index a0cfbb7..54b90c8 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -102,7 +102,8 @@ static int mxc_set_usbcontrol(int port, unsigned int flags) } #endif
- writel(v, IMX_USB_BASE + USBCTRL_OTGBASE_OFFSET); + writel(v, (IMX_USB_BASE + + (0x200 * CONFIG_MXC_USB_PORT))); return 0; }
diff --git a/include/configs/mx25pdk.h b/include/configs/mx25pdk.h index 8414376..b26e2bc 100644 --- a/include/configs/mx25pdk.h +++ b/include/configs/mx25pdk.h @@ -17,6 +17,7 @@
/* High Level Configuration Options */
+#define CONFIG_MX25 #define CONFIG_MX25_CLK32 32768 /* OSC32K frequency */ #define CONFIG_SYS_HZ 1000 #define CONFIG_SYS_TEXT_BASE 0x81200000 @@ -83,6 +84,28 @@ /* U-Boot commands */ #include <config_cmd_default.h> #define CONFIG_CMD_CACHE +#define CONFIG_CMD_PING +#define CONFIG_CMD_USB + +/* + * USB + */ +#ifdef CONFIG_CMD_USB +#define CONFIG_USB_EHCI /* Enable EHCI USB support */ +#define CONFIG_USB_EHCI_MXC +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET +#define CONFIG_MXC_USB_FLAGS 0 +#define CONFIG_MXC_USB_PORT 2 +#define CONFIG_EHCI_IS_TDI +#define CONFIG_USB_STORAGE +#define CONFIG_DOS_PARTITION +#define CONFIG_SUPPORT_VFAT +#endif /* CONFIG_CMD_USB */ + +/* + * GPIO + */ +#define CONFIG_MXC_GPIO
/* Ethernet */ #define CONFIG_FEC_MXC

Hi Hugo,
2011/11/4 Hugo Holgersson hugoh@student.chalmers.se:
- Do I need to set the mux's SW_PAD_CTL for the D9 pins?
- Are there any pins I have forgot to mux?
I looked at the IOMUX configuration for USBH2 on the Freescale Linux BSP and the code is below:
int gpio_usbh2_active(void) { if (mxc_request_iomux(MX25_PIN_D9, MUX_CONFIG_ALT6) || /* PWR */ mxc_request_iomux(MX25_PIN_D8, MUX_CONFIG_ALT6) || /* OC */ mxc_request_iomux(MX25_PIN_A21, MUX_CONFIG_ALT5)) { /* BT_USB_CS */ return -EINVAL; }
/* * This pin controls the mux that switches between * the J18 connector and the on-board bluetooth module. * dir: 0 = out * pin: 0 = J18, 1 = BT */ gpio_request(IOMUX_TO_GPIO(MX25_PIN_A21), "a21"); gpio_direction_output(IOMUX_TO_GPIO(MX25_PIN_A21), 0); gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_A21), 0);
return 0; }
,so please make sure you control MX25_PIN_A21 correctly for USB operation.
Regards,
Fabio Estevam

2011/11/4 Fabio Estevam festevam@gmail.com:
Hi Hugo,
2011/11/4 Hugo Holgersson hugoh@student.chalmers.se:
- Do I need to set the mux's SW_PAD_CTL for the D9 pins?
- Are there any pins I have forgot to mux?
I looked at the IOMUX configuration for USBH2 on the Freescale Linux BSP and the code is below:
Ops, I see that you have already taken care of this pin.

2011/11/4 Hugo Holgersson hugoh@student.chalmers.se:
int board_init(void) {
- struct iomuxc_mux_ctl *muxctl;
- struct iomuxc_pad_ctl *padctl;
- u32 gpio_mux_mode5 = MX25_PIN_MUX_MODE(5);
- u32 gpio_mux_mode6 = MX25_PIN_MUX_MODE(6);
- muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE;
- /* USBH2_PWR */
- writel(gpio_mux_mode6, &muxctl->pad_d9);
- //writel(gpio_mux_mode5, &muxctl->pad_d9);
- //gpio_direction_output(MXC_GPIO_PORT_TO_NUM(4, 11), 1); /* Try keep power on. */
- /* USBH2_OC */
- writel(gpio_mux_mode6, &muxctl->pad_d8);
- /* USB_BT_CS low selects USB Host */
- writel(gpio_mux_mode5, &muxctl->pad_a21); /* GPIO2[7] */
- gpio_direction_output(MXC_GPIO_PORT_TO_NUM(2, 7), 0); /* Chip select 0*/
Can you try to place the USBH2 IOMUX inside board_early_init_f instead?
Regards,
Fabio Estevam

2011/11/4 Hugo Holgersson hugoh@student.chalmers.se:
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index a0cfbb7..54b90c8 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -102,7 +102,8 @@ static int mxc_set_usbcontrol(int port, unsigned int flags) } #endif
- writel(v, IMX_USB_BASE + USBCTRL_OTGBASE_OFFSET);
- writel(v, (IMX_USB_BASE +
- (0x200 * CONFIG_MXC_USB_PORT)));
return 0; }
I am looking at the usb/host/ehci-mxc.c file and I see that the write to the portsc USB register is currently only done for MX31:
#ifdef CONFIG_MX31 setbits_le32(&ehci->control, USB_EN);
__raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc); #endif
I think you need to allow the portsc register write on MX25 too (and maybe for all i.MX devices).
In Linux we have: .portsc = MXC_EHCI_MODE_SERIAL for MX25PDK
,where #define MXC_EHCI_MODE_SERIAL (3 << 30)
Regards,
Fabio Estevam
participants (2)
-
Fabio Estevam
-
Hugo Holgersson