diff options
| author | Yuri Tikhonov <yur@emcraft.com> | 2008-09-04 11:19:05 +0200 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2008-09-06 01:24:55 +0200 | 
| commit | e90fb6afab2c0c074dfb67bacb4de179eb188a24 (patch) | |
| tree | d0cb5743f747384543690ca93f2bbd2aeba99756 | |
| parent | 5875d358f025c1b042d8a0f08384b756de7256c9 (diff) | |
| download | olio-uboot-2014.01-e90fb6afab2c0c074dfb67bacb4de179eb188a24.tar.xz olio-uboot-2014.01-e90fb6afab2c0c074dfb67bacb4de179eb188a24.zip | |
USB EHCI: reset root hub
Some of multi-function USB controllers (e.g. ISP1562) allow root hub
resetting only via EHCI registers. So, this patch adds the
corresponding kind of reset to OHCI's hc_reset() if the newly
introduced CONFIG_PCI_EHCI_DEVNO option is set (e.g. for Socrates
board).
Signed-off-by: Yuri Tikhonov <yur@emcraft.com>
Acked-by: Markus Klotzbuecher <mk@denx.de>
| -rw-r--r-- | drivers/usb/usb_ohci.c | 35 | ||||
| -rw-r--r-- | drivers/usb/usb_ohci.h | 3 | ||||
| -rw-r--r-- | include/configs/socrates.h | 1 | 
3 files changed, 39 insertions, 0 deletions
| diff --git a/drivers/usb/usb_ohci.c b/drivers/usb/usb_ohci.c index 0bfa4d782..fd5567f71 100644 --- a/drivers/usb/usb_ohci.c +++ b/drivers/usb/usb_ohci.c @@ -109,6 +109,14 @@ static struct pci_device_id ohci_pci_ids[] = {  };  #endif +#ifdef CONFIG_PCI_EHCI_DEVNO +static struct pci_device_id ehci_pci_ids[] = { +	{0x1131, 0x1562},	/* Philips 1562 PCI EHCI module ids */ +	/* Please add supported PCI EHCI controller ids here */ +	{0, 0} +}; +#endif +  #ifdef DEBUG  #define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)  #else @@ -1572,11 +1580,38 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,  static int hc_reset (ohci_t *ohci)  { +#ifdef CONFIG_PCI_EHCI_DEVNO +	pci_dev_t pdev; +#endif  	int timeout = 30;  	int smm_timeout = 50; /* 0,5 sec */  	dbg("%s\n", __FUNCTION__); +#ifdef CONFIG_PCI_EHCI_DEVNO +	/* +	 *  Some multi-function controllers (e.g. ISP1562) allow root hub +	 * resetting via EHCI registers only. +	 */ +	pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVNO); +	if (pdev != -1) { +		u32 base; +		int timeout = 1000; + +		pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &base); +		writel (readl(base + EHCI_USBCMD_OFF) | EHCI_USBCMD_HCRESET, +			base + EHCI_USBCMD_OFF); + +		while (readl(base + EHCI_USBCMD_OFF) & EHCI_USBCMD_HCRESET) { +			if (timeout-- <= 0) { +				printf("USB RootHub reset timed out!"); +				break; +			} +			udelay(1); +		} +	} else +		printf("No EHCI func at %d index!\n", CONFIG_PCI_EHCI_DEVNO); +#endif  	if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */  		writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */  		info("USB HC TakeOver from SMM"); diff --git a/drivers/usb/usb_ohci.h b/drivers/usb/usb_ohci.h index 380cb4c92..7a04bf5e8 100644 --- a/drivers/usb/usb_ohci.h +++ b/drivers/usb/usb_ohci.h @@ -195,6 +195,9 @@ struct ohci_regs {  	} roothub;  } __attribute((aligned(32))); +/* Some EHCI controls */ +#define EHCI_USBCMD_OFF		0x20 +#define EHCI_USBCMD_HCRESET	(1 << 1)  /* OHCI CONTROL AND STATUS REGISTER MASKS */ diff --git a/include/configs/socrates.h b/include/configs/socrates.h index 15abec199..5cc4213de 100644 --- a/include/configs/socrates.h +++ b/include/configs/socrates.h @@ -410,6 +410,7 @@  #define CONFIG_USB_OHCI_NEW		1  #define CONFIG_PCI_OHCI			1  #define CONFIG_PCI_OHCI_DEVNO		3 /* Number in PCI list */ +#define CONFIG_PCI_EHCI_DEVNO		(CONFIG_PCI_OHCI_DEVNO / 2)  #define CFG_USB_OHCI_MAX_ROOT_PORTS	15  #define CFG_USB_OHCI_SLOT_NAME		"ohci_pci"  #define CFG_OHCI_SWAP_REG_ACCESS	1 |