SAMA5: Add support for sharing ports when both OHCI and EHCI are enabled
This commit is contained in:
parent
e59924a9e6
commit
189174e26b
@ -370,7 +370,7 @@ config SAMA5_OHCI_REGDEBUG
|
||||
default n
|
||||
depends on DEBUG
|
||||
|
||||
endif # OHCI
|
||||
endif # SAMA5_OHCI
|
||||
|
||||
config SAMA5_EHCI
|
||||
bool "High speed EHCI support"
|
||||
@ -408,7 +408,75 @@ config SAMA5_EHCI_REGDEBUG
|
||||
default n
|
||||
depends on DEBUG
|
||||
|
||||
endif # EHCI
|
||||
endif # SAMA5_EHCI
|
||||
|
||||
if SAMA5_OHCI && SAMA5_EHCI
|
||||
|
||||
config SAMA5_OHCI_RHPORT1
|
||||
bool "Use Port A for OHCI"
|
||||
default n
|
||||
depends on !SAMA5_UDPHS
|
||||
|
||||
config SAMA5_OHCI_RHPORT2
|
||||
bool "Use Port B for OHCI"
|
||||
default n
|
||||
|
||||
config SAMA5_OHCI_RHPORT3
|
||||
bool "Use Port C for OHCI"
|
||||
default y
|
||||
|
||||
config SAMA5_EHCI_RHPORT1
|
||||
bool
|
||||
default y if !SAMA5_OHCI_RHPORT1
|
||||
default n if SAMA5_OHCI_RHPORT1
|
||||
depends on !SAMA5_UDPHS
|
||||
|
||||
config SAMA5_EHCI_RHPORT2
|
||||
bool
|
||||
default y if !SAMA5_OHCI_RHPORT2
|
||||
default n if SAMA5_OHCI_RHPORT2
|
||||
|
||||
config SAMA5_EHCI_RHPORT3
|
||||
bool
|
||||
default y if !SAMA5_OHCI_RHPORT3
|
||||
default n if SAMA5_OHCI_RHPORT3
|
||||
|
||||
endif # SAMA5_OHCI && SAMA5_EHCI
|
||||
|
||||
if SAMA5_OHCI && !SAMA5_EHCI
|
||||
|
||||
config SAMA5_OHCI_RHPORT1
|
||||
bool
|
||||
default y
|
||||
depends on !SAMA5_UDPHS
|
||||
|
||||
config SAMA5_OHCI_RHPORT2
|
||||
bool
|
||||
default y
|
||||
|
||||
config SAMA5_OHCI_RHPORT3
|
||||
bool
|
||||
default y
|
||||
|
||||
endif # SAMA5_OHCI && !SAMA5_EHCI
|
||||
|
||||
if !SAMA5_OHCI && SAMA5_EHCI
|
||||
|
||||
config SAMA5_EHCI_RHPORT1
|
||||
bool
|
||||
default y
|
||||
depends on !SAMA5_UDPHS
|
||||
|
||||
config SAMA5_EHCI_RHPORT2
|
||||
bool
|
||||
default y
|
||||
|
||||
config SAMA5_EHCI_RHPORT3
|
||||
bool
|
||||
default y
|
||||
|
||||
endif # !SAMA5_OHCI && SAMA5_EHCI
|
||||
|
||||
endmenu # USB High Speed Host driver option
|
||||
endif # SAMA5_UHPHS
|
||||
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "sam_periphclks.h"
|
||||
#include "sam_memories.h"
|
||||
#include "sam_usbhost.h"
|
||||
#include "chip/sam_sfr.h"
|
||||
#include "chip/sam_ehci.h"
|
||||
|
||||
#ifdef CONFIG_SAMA5_EHCI
|
||||
@ -110,6 +111,18 @@
|
||||
#undef CONFIG_USBHOST_ISOC_DISABLE
|
||||
#define CONFIG_USBHOST_ISOC_DISABLE 1
|
||||
|
||||
/* If UDPHS is enabled, then don't use port A */
|
||||
|
||||
#ifdef CONFIG_SAMA5_UDPHS
|
||||
# undef CONFIG_SAMA5_EHCI_RHPORT1
|
||||
#endif
|
||||
|
||||
/* For now, suppress use of PORTA in any event. I use that for SAM-BA and
|
||||
* would prefer that the board not try to drive VBUS on that port!
|
||||
*/
|
||||
|
||||
#undef CONFIG_SAMA5_EHCI_RHPORT1
|
||||
|
||||
/* Driver-private Definitions **************************************************/
|
||||
|
||||
/* This is the set of interrupts handled by this driver */
|
||||
@ -874,7 +887,7 @@ static int sam_qh_foreach(struct sam_qh_s *qh, uint32_t **bp, foreach_qh_t handl
|
||||
* the end of the asynchronous queue?
|
||||
*/
|
||||
|
||||
else if (sam_virtramaddr(physaddr & QH_HLP_MASK) == &g_asynchead)
|
||||
else if (sam_virtramaddr(physaddr & QH_HLP_MASK) == (uintptr_t)&g_asynchead)
|
||||
{
|
||||
/* That will also terminate the loop */
|
||||
|
||||
@ -1973,16 +1986,16 @@ static int sam_qtd_ioccheck(struct sam_qtd_s *qtd, uint32_t **bp, void *arg)
|
||||
(uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s));
|
||||
sam_qtd_print(qtd);
|
||||
|
||||
/* Remove the qTD from the list */
|
||||
/* Remove the qTD from the list
|
||||
*
|
||||
* NOTE that we don't check if the qTD is active nor do we check if there
|
||||
* are any errors reported in the qTD. If the transfer halted due to
|
||||
* an error, then qTDs in the list after the error qTD will still appear
|
||||
* to be active.
|
||||
*/
|
||||
|
||||
**bp = qtd->hw.nqp;
|
||||
|
||||
/* NOTE that we don't check if the qTD is active nor do we check if there
|
||||
* are any errors reported in the qTD. If the transfer halted due to
|
||||
* an error, then I am not sure if we can believe this information anyway.
|
||||
* The only sure place to check for errors in in the QH overlay.
|
||||
*/
|
||||
|
||||
/* Release this QH by returning it to the free list */
|
||||
|
||||
sam_qtd_free(qtd);
|
||||
@ -2064,6 +2077,7 @@ static int sam_qh_ioccheck(struct sam_qh_s *qh, uint32_t **bp, void *arg)
|
||||
*/
|
||||
|
||||
**bp = qh->hw.hlp;
|
||||
cp15_coherent_dcache((uintptr_t)*bp, (uintptr_t)*bp + sizeof(uint32_t));
|
||||
|
||||
/* Check for errors, update the data toggle */
|
||||
|
||||
@ -3377,9 +3391,30 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller)
|
||||
regval = sam_getreg((volatile uint32_t *)SAM_PMC_SCER);
|
||||
regval |= PMC_UHP;
|
||||
sam_putreg(regval, (volatile uint32_t *)SAM_PMC_SCER);
|
||||
|
||||
/* "One transceiver is shared with the USB High Speed Device (port A). The
|
||||
* selection between Host Port A and USB Device is controlled by the UDPHS
|
||||
* enable bit (EN_UDPHS) located in the UDPHS_CTRL control register."
|
||||
*
|
||||
* Make all three ports usable for EHCI unless the high speed device is
|
||||
* enabled; then let the device manage port zero. Zero is the reset
|
||||
* value for all ports; one makes the corresponding port available to OHCI.
|
||||
*/
|
||||
|
||||
regval = getreg32(SAM_SFR_OHCIICR);
|
||||
#ifdef CONFIG_SAMA5_EHCI_RHPORT1
|
||||
regval &= ~SFR_OHCIICR_RES1;
|
||||
#endif
|
||||
#ifdef CONFIG_SAMA5_EHCI_RHPORT2
|
||||
regval &= ~SFR_OHCIICR_RES1;
|
||||
#endif
|
||||
#ifdef CONFIG_SAMA5_EHCI_RHPORT3
|
||||
regval &= ~SFR_OHCIICR_RES2;
|
||||
#endif
|
||||
putreg32(regval, SAM_SFR_OHCIICR);
|
||||
irqrestore(flags);
|
||||
|
||||
/* Note that no pin pinconfiguration is required. All USB HS pins have
|
||||
/* Note that no pin configuration is required. All USB HS pins have
|
||||
* dedicated function
|
||||
*/
|
||||
|
||||
@ -3631,7 +3666,15 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller)
|
||||
* mode.
|
||||
*/
|
||||
|
||||
sam_usbhost_vbusdrive(SAM_EHCI_IFACE, true);
|
||||
#ifndef CONFIG_SAMA5_EHCI_RHPORT1
|
||||
sam_usbhost_vbusdrive(SAM_RHPORT1, true);
|
||||
#endif
|
||||
#ifndef CONFIG_SAMA5_EHCI_RHPORT2
|
||||
sam_usbhost_vbusdrive(SAM_RHPORT2, true);
|
||||
#endif
|
||||
#ifndef CONFIG_SAMA5_EHCI_RHPORT3
|
||||
sam_usbhost_vbusdrive(SAM_RHPORT3, true);
|
||||
#endif
|
||||
up_mdelay(50);
|
||||
|
||||
/* If there is a USB device in the slot at power up, then we will not
|
||||
|
@ -117,6 +117,18 @@
|
||||
|
||||
#define SAM_BUFALLOC (CONFIG_SAMA5_OHCI_TDBUFFERS * CONFIG_SAMA5_OHCI_TDBUFSIZE)
|
||||
|
||||
/* If UDPHS is enabled, then don't use port A */
|
||||
|
||||
#ifdef CONFIG_SAMA5_UDPHS
|
||||
# undef CONFIG_SAMA5_OHCI_RHPORT1
|
||||
#endif
|
||||
|
||||
/* For now, suppress use of PORTA in any event. I use that for SAM-BA and
|
||||
* would prefer that the board not try to drive VBUS on that port!
|
||||
*/
|
||||
|
||||
#undef CONFIG_SAMA5_OHCI_RHPORT1
|
||||
|
||||
/* Debug */
|
||||
|
||||
#ifndef CONFIG_DEBUG
|
||||
@ -3013,20 +3025,30 @@ FAR struct usbhost_connection_s *sam_ohci_initialize(int controller)
|
||||
regval = getreg32(SAM_PMC_SCER);
|
||||
regval |= PMC_UHP;
|
||||
putreg32(regval, SAM_PMC_SCER);
|
||||
irqrestore(flags);
|
||||
|
||||
/* Make all three ports usable. Zero is the reset value and holds the
|
||||
* ports in reset.
|
||||
* REVISIT: This will have to change in future. Should be a configuration
|
||||
* setting
|
||||
/* "One transceiver is shared with the USB High Speed Device (port A). The
|
||||
* selection between Host Port A and USB Device is controlled by the UDPHS
|
||||
* enable bit (EN_UDPHS) located in the UDPHS_CTRL control register."
|
||||
*
|
||||
* Make all three ports usable for OHCI unless the high speed device is
|
||||
* enabled; then let the device manage port zero. Zero is the reset
|
||||
* value for all ports; one makes the corresponding port available to OHCI.
|
||||
*/
|
||||
|
||||
regval = getreg32(SAM_SFR_OHCIICR);
|
||||
regval |= (SFR_OHCIICR_RES0 | SFR_OHCIICR_RES1 | SFR_OHCIICR_RES2);
|
||||
#ifdef CONFIG_SAMA5_OHCI_RHPORT1
|
||||
regval |= SFR_OHCIICR_RES1;
|
||||
#endif
|
||||
#ifdef CONFIG_SAMA5_OHCI_RHPORT2
|
||||
regval |= SFR_OHCIICR_RES1;
|
||||
#endif
|
||||
#ifdef CONFIG_SAMA5_OHCI_RHPORT3
|
||||
regval |= SFR_OHCIICR_RES2;
|
||||
#endif
|
||||
putreg32(regval, SAM_SFR_OHCIICR);
|
||||
irqrestore(flags);
|
||||
|
||||
/* Note that no pin pinconfiguration is required. All USB HS pins have
|
||||
/* Note that no pin configuration is required. All USB HS pins have
|
||||
* dedicated function
|
||||
*/
|
||||
|
||||
@ -3140,7 +3162,15 @@ FAR struct usbhost_connection_s *sam_ohci_initialize(int controller)
|
||||
* mode.
|
||||
*/
|
||||
|
||||
sam_usbhost_vbusdrive(SAM_OHCI_IFACE, true);
|
||||
#ifndef CONFIG_SAMA5_OHCI_RHPORT1
|
||||
sam_usbhost_vbusdrive(SAM_RHPORT1, true);
|
||||
#endif
|
||||
#ifndef CONFIG_SAMA5_OHCI_RHPORT2
|
||||
sam_usbhost_vbusdrive(SAM_RHPORT2, true);
|
||||
#endif
|
||||
#ifndef CONFIG_SAMA5_OHCI_RHPORT3
|
||||
sam_usbhost_vbusdrive(SAM_RHPORT3, true);
|
||||
#endif
|
||||
up_mdelay(50);
|
||||
|
||||
/* If there is a USB device in the slot at power up, then we will not
|
||||
|
@ -54,6 +54,14 @@
|
||||
#define SAM_EHCI_IFACE 0
|
||||
#define SAM_OHCI_IFACE 1
|
||||
|
||||
/* This is the interface argument for call outs to board-specific functions which
|
||||
* need to know which root hub port is being used.
|
||||
*/
|
||||
|
||||
#define SAM_RHPORT1 0
|
||||
#define SAM_RHPORT2 1
|
||||
#define SAM_RHPORT3 2
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
************************************************************************************/
|
||||
@ -149,9 +157,8 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller);
|
||||
* each platform that implements the OHCI or EHCI host interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* iface - Selects USB host interface:
|
||||
* 0 = EHCI
|
||||
* 1 = OHCI
|
||||
* rhport - Selects root hub port to be powered host interface. See SAM_RHPORT_*
|
||||
* definitions above.
|
||||
* enable - true: enable VBUS power; false: disable VBUS power
|
||||
*
|
||||
* Returned Value:
|
||||
@ -159,7 +166,7 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller);
|
||||
*
|
||||
***********************************************************************************/
|
||||
|
||||
void sam_usbhost_vbusdrive(int iface, bool enable);
|
||||
void sam_usbhost_vbusdrive(int rhport, bool enable);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
Loading…
Reference in New Issue
Block a user