USB hangs on AU1100
Hello,
I'm just using USB host support on a AU1100 developing board (DB1100 configuration) and i notice that CPU locks in function au1xxx_start_hc():
/* wait for reset complete (read register twice; see au1500 errata) */
while (au_readl(USB_HOST_CONFIG),
!(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD))
udelay(1000);while waiting for USB controller to reset. I checked it out and I discovered that register USB_HOST_CONFIG is fixed at value 0xe! So the controller never reset...
Linux is 2.6.12-rc3 from CVS.
Someone knows whats wrong?
Thanks in advance,
Rodolfo Giometti
Signature · 4 lines
GNU/Linux Solutions e-mail: [email protected] Linux Device Driver [email protected] Embedded Systems home page: giometti.enneenne.com UNIX programming phone: +39 349 2432127
Quoted 11 lines · Rodolfo Giometti
Hello,
I'm just using USB host support on a AU1100 developing board (DB1100 configuration) and i notice that CPU locks in function
au1xxx_start_hc():/* wait for reset complete (read register twice; see au1500 errata) */ while (au_readl(USB_HOST_CONFIG), !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD)) udelay(1000);
Quoted 7 lines
while waiting for USB controller to reset. I checked it out and I discovered that register
USB_HOST_CONFIGis fixed at value0xe! So the controller never reset...Linux is 2.6.12-rc3 from CVS.
Someone knows whats wrong?
It sounds like this is a custom Au1100 based board? What boot code are you running? I'm guessing the SOC isn't setup correctly or you have a HW problem.
Pete
Quoted 16 lines · Pete Popov
Quoted 15 lines · Rodolfo Giometti
Hello,
I'm just using USB host support on a AU1100 developing board (DB1100 configuration) and i notice that CPU locks in function
au1xxx_start_hc():/* wait for reset complete (read register twice; see au1500 errata) */ while (au_readl(USB_HOST_CONFIG), !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD)) udelay(1000);while waiting for USB controller to reset. I checked it out and I discovered that register
USB_HOST_CONFIGis fixed at value0xe! So the controller never reset...
Quoted 7 lines
Quoted 3 lines
Linux is 2.6.12-rc3 from CVS.
Someone knows whats wrong?
It sounds like this is a custom Au1100 based board? What boot code are you running? I'm guessing the SOC isn't setup correctly or you have a HW problem.
I wonder if the code works reliable. At least, a comma operator isn't a sequence point, which means the compiler is free to change the execution order.
Thiemo
Quoted 17 lines · Thiemo Seufer
Quoted 17 lines
Quoted 16 lines
I'm just using USB host support on a AU1100 developing board (DB1100 configuration) and i notice that CPU locks in function
au1xxx_start_hc():/* wait for reset complete (read register twice; see au1500 errata) */ while (au_readl(USB_HOST_CONFIG), !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD)) udelay(1000);while waiting for USB controller to reset. I checked it out and I discovered that register
USB_HOST_CONFIGis fixed at value0xe! So the controller never reset...Linux is 2.6.12-rc3 from CVS.
Someone knows whats wrong?
Quoted 7 lines
Quoted 3 lines
It sounds like this is a custom Au1100 based board? What boot code are you running? I'm guessing the SOC isn't setup correctly or you have a HW problem.
I wonder if the code works reliable. At least, a comma operator isn't a sequence point, which means the compiler is free to change the execution order.
Good point -- even though the code is valid C, it's complete rubbish.
I'd suggest rewriting it to get something readable first.
Maciej
Quoted 24 lines · Maciej W. Rozycki
Quoted 13 lines · Thiemo Seufer
Quoted 13 lines
Quoted 13 lines
I'm just using USB host support on a AU1100 developing board (DB1100 configuration) and i notice that CPU locks in function
au1xxx_start_hc():/* wait for reset complete (read register twice; see au1500 errata) */ while (au_readl(USB_HOST_CONFIG), !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD)) udelay(1000);while waiting for USB controller to reset. I checked it out and I discovered that register
USB_HOST_CONFIGis fixed at value0xe! So the controller never reset...Quoted 5 lines
Quoted 5 lines
Quoted 3 lines
Linux is 2.6.12-rc3 from CVS.
Someone knows whats wrong?
It sounds like this is a custom Au1100 based board? What
oot code are
Quoted 3 lines
Quoted 2 lines
you running? I'm guessing the SOC isn't setup correctly or you have a HW problem.
Quoted 6 lines
Quoted 3 lines
I wonder if the code works reliable. At least, a comma operator isn't a sequence point, which means the compiler is free to change the execution order.
Good point -- even though the code is valid C, it's complete rubbish.
I'd suggest rewriting it to get something readable first.
Interesting. I hadn't looked at this chunk of code before.
Pete
Hi,
[del]
Quoted 3 lines
I wonder if the code works reliable. At least, a comma operator isn't a sequence point, which means the compiler is free to change the execution order.
Not accordingly to the C standard, which notes strict left-to-right execution without reordering for the comma operator.
HTH,
Uli
Signature · 3 lines
Dipl. Inf. Ulrich Teichert|e-mail: [email protected] Stormweg 24 |listening to: Suicide Drive (The Deep Eynde) 24539 Neumuenster, Germany|Public Pervert (Interpol) Cauchemar (Opération S)
Quoted 9 lines · Ulrich Teichert
Hi,
[del]
Quoted 3 lines
I wonder if the code works reliable. At least, a comma operator isn't a sequence point, which means the compiler is free to change the execution order.
Not accordingly to the C standard, which notes strict left-to-right execution without reordering for the comma operator.
You are right, apparently I remembered incorrectly.
Thiemo
Quoted 1 line · Pete Popov
It sounds like this is a custom Au1100 based board? What boot code are
Yes, but is very close to the DB1100.
Quoted 2 lines
you running? I'm guessing the SOC isn't setup correctly or you have a HW problem.
I selected the code for the DB1100... I'm very puzzled about this problem!
However let me suggest you this little patch in order to advice the user about this problem and to avoid system locks.
Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: [email protected] Linux Device Driver [email protected] Embedded Systems home page: giometti.enneenne.com UNIX programming phone: +39 349 2432127
Index: ohci-au1xxx.c
===================================================================
RCS file: /home/cvs/linux/drivers/usb/host/ohci-au1xxx.c,v retrieving revision 1.5
ohci-au1xxx.c +18 -3
@@ -38,8 +38,10 @@/*-------------------------------------------------------------------------*/ -static void au1xxx_start_hc (struct platform_device *dev) +static int au1xxx_start_hc (struct platform_device *dev) { +int count =3000 ; + printk(KERN_DEBUG __FILE__ ": starting Au1xxx OHCI USB Controller\n");
@@ -51,11 +53,19 @@/* wait for reset complete (read register twice; see au1500 errata) */ while (au_readl (USB_HOST_CONFIG ), - !(au_readl (USB_HOST_CONFIG ) &USBH_ENABLE_RD )) + !(au_readl (USB_HOST_CONFIG ) &USBH_ENABLE_RD )) {udelay (1000 ); +if (--count ==0 ) { + printk(KERN_ERR __FILE__ + ": unable to reset USB host\n"); +return -EBUSY ; + } + } printk(KERN_DEBUG __FILE__ ": Clock to USB host has been enabled \n"); + +return 0 ; }static void au1xxx_stop_hc (struct platform_device *dev)
@@ -113,7 +123,11 @@ goto err2; } -au1xxx_start_hc (dev); + retval =au1xxx_start_hc (dev); +if (retval <0 ) { +pr_debug ("au1xxx start failed" ); + goto err3; + }ohci_hcd_init (hcd_to_ohci (hcd)); retval =usb_add_hcd (hcd, dev->resource[1 ].start,SA_INTERRUPT );
@@ -121,6 +135,7 @@return retval;au1xxx_stop_hc (dev); + err3:iounmap (hcd->regs); err2:release_mem_region (hcd->rsrc_start, hcd->rsrc_len);
Quoted 3 lines · Pete Popov
It sounds like this is a custom Au1100 based board? What boot code are you running? I'm guessing the SOC isn't setup correctly or you have a HW problem.
Yes, you was right, I missing to setup USB clock... I just added this code to the board init function (board_setup() function) and now USB works:
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_AU1X00_USB_DEVICE)
/* zero and disable FREQ2 */
sys_freqctrl = au_readl(SYS_FREQCTRL0);
sys_freqctrl &= ~0xFFF00000;
au_writel(sys_freqctrl, SYS_FREQCTRL0);
/* zero and disable USBH/USBD/IrDA clock */
sys_clksrc = au_readl(SYS_CLKSRC);
sys_clksrc &= ~0x0000001F;
au_writel(sys_clksrc, SYS_CLKSRC);
sys_freqctrl = au_readl(SYS_FREQCTRL0);
sys_freqctrl &= ~0xFFF00000;
sys_clksrc = au_readl(SYS_CLKSRC);
sys_clksrc &= ~0x0000001F;
/* FREQ2 = aux/2 = 48 MHz */
sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
au_writel(sys_freqctrl, SYS_FREQCTRL0);
/* Route 48MHz FREQ2 into USBH/USBD/IrDA */
sys_clksrc |= ((4<<2) | (0<<1) | 0 );
au_writel(sys_clksrc, SYS_CLKSRC);
/* setup the static bus controller */
au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */
au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
/* Get USB Functionality pin state (device vs host drive pins) */
pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
#ifndef CONFIG_AU1X00_USB_DEVICE
/* 2nd USB port is USB host */
pin_func |= 0x8000;
#endif
au_writel(pin_func, SYS_PINFUNC);
#endif /* defined (CONFIG_USB_OHCI_HCD) || defined (CONFIG_AU1X00_USB_DEVICE) */But don't you think is better to put this code into USB driver (file ohci-au1xxx.c) during probing stage? In this manner each platforms may don't worry about clock initialization...
Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: [email protected] Linux Device Driver [email protected] Embedded Systems home page: giometti.enneenne.com UNIX programming phone: +39 349 2432127
Quoted 1 line · Rodolfo Giometti
Yes, you was right, I missing to setup USB clock...
The other thing you have to always remember when comparing operation to "... a board just like the Db1xxx ... " is that yamon does lots and lots of set up for the board that Linux assumes will be done. We've discussed this in the past, I just wanted to mention it again so it isn't forgotten. ;-)
Thanks.
-- Dan
Quoted 48 lines · Rodolfo Giometti
Quoted 3 lines · Pete Popov
It sounds like this is a custom Au1100 based board? What boot code are you running? I'm guessing the SOC isn't setup correctly or you have a HW problem.
Yes, you was right, I missing to setup USB clock... I just added this code to the board init function (
board_setup()function) and now USB works:#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_AU1X00_USB_DEVICE) /* zero and disable FREQ2 */ sys_freqctrl = au_readl(SYS_FREQCTRL0); sys_freqctrl &= ~0xFFF00000; au_writel(sys_freqctrl, SYS_FREQCTRL0); /* zero and disable USBH/USBD/IrDA clock */ sys_clksrc = au_readl(SYS_CLKSRC); sys_clksrc &= ~0x0000001F; au_writel(sys_clksrc, SYS_CLKSRC); sys_freqctrl = au_readl(SYS_FREQCTRL0); sys_freqctrl &= ~0xFFF00000; sys_clksrc = au_readl(SYS_CLKSRC); sys_clksrc &= ~0x0000001F; /* FREQ2 = aux/2 = 48 MHz */ sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); au_writel(sys_freqctrl, SYS_FREQCTRL0); /* Route 48MHz FREQ2 into USBH/USBD/IrDA */ sys_clksrc |= ((4<<2) | (0<<1) | 0 ); au_writel(sys_clksrc, SYS_CLKSRC); /* setup the static bus controller */ au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ /* Get USB Functionality pin state (device vs host drive pins) */ pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); #ifndef CONFIG_AU1X00_USB_DEVICE /* 2nd USB port is USB host */ pin_func |= 0x8000; #endif au_writel(pin_func, SYS_PINFUNC); #endif /* defined (CONFIG_USB_OHCI_HCD) || defined (CONFIG_AU1X00_USB_DEVICE) */
Quoted 3 lines
But don't you think is better to put this code into USB driver (file
ohci-au1xxx.c) during probing stage? In this manner each platforms may don't worry about clock initialization...
Seems too board specific since the clocks can be routed differently on each board.
Pete