Beginning of support for SAMA5 EHCI. Not much there yet

This commit is contained in:
Gregory Nutt 2013-08-20 15:46:36 -06:00
parent e3a76b2e64
commit 320a2e2a0a
10 changed files with 1746 additions and 20 deletions

View File

@ -5421,3 +5421,7 @@
Add logic for management of device addresses. This logic does not
currently hook into into anything. It will someday be a part of the
NuttX USB hub implementation (2013-8-18).
* nuttx/arch/arm/src/sama5/sam_ehci.c and other files: Create a skeleton
environment for development of an EHCI driver. Not much in place yet
(2013-8-20).

View File

@ -377,8 +377,38 @@ config SAMA5_EHCI
default n
---help---
Build support for the SAMA5 USB high speed Enhanced Host Controller
Interface (OHCI).
Interface (EHCI).
if SAMA5_EHCI
config SAMA5_EHCI_NQHS
int "Number of Queue Head (QH) structures"
default 4
---help---
Configurable number of Queue Head (QH) structures. The default is
one per Root hub port plus one for EP0.
config SAMA5_EHCI_NQTDS
int "Number of Queue Element Transfer Descriptor (qTDs)"
default 4
---help---
Configurable number of Queue Element Transfer Descriptor (qTDs).
The default is one per root hub plus three from EP0.
config SAMA5_EHCI_BUFSIZE
int "Size of one request/descriptor buffer"
default 128
---help---
The size of one request/descriptor buffer in bytes. The TD buffe
size must be an even number of 32-bit words and must be large enough
to hangle the largest transfer via a SETUP request.
config SAMA5_EHCI_REGDEBUG
bool "Enable low-level EHCI register debug"
default n
depends on DEBUG
endif # EHCI
endmenu # USB High Speed Host driver option
endif # SAMA5_UHPHS

View File

@ -69,11 +69,11 @@
/* Host Controller Capability Registers */
#define HCCR ((struct ehci_hccr_s *)SAM_UHPEHCI_VSECTION
#define HCCR ((struct ehci_hccr_s *)SAM_UHPEHCI_VSECTION)
/* Host Controller Operational Registers */
#define HCOR ((volatile struct ehci_hcor_s *)(SAM_UHPEHCI_VSECTION + 0x10)
#define HCOR ((volatile struct ehci_hcor_s *)(SAM_UHPEHCI_VSECTION + 0x10))
/****************************************************************************
* Public Types

View File

@ -179,9 +179,11 @@
#define PMC_CKGR_UCKR_UPLLEN (1 << 16) /* Bit 16: UTMI PLL Enable */
#define PMC_CKGR_UCKR_UPLLCOUNT_SHIFT (20) /* Bits 20-23: UTMI PLL Start-up Time */
#define PMC_CKGR_UCKR_UPLLCOUNT_MASK (15 << PMC_CKGR_UCKR_UPLLCOUNT_SHIFT)
# define PMC_CKGR_UCKR_UPLLCOUNT(n) ((n) << PMC_CKGR_UCKR_UPLLCOUNT_SHIFT)
#define PMC_CKGR_UCKR_BIASEN (1 << 24) /* Bit 24: UTMI BIAS Enable */
#define PMC_CKGR_UCKR_BIASCOUNT_SHIFT (28) /* Bits 28-31: UTMI BIAS Start-up Time */
#define PMC_CKGR_UCKR_BIASCOUNT_MASK (15 << PMC_CKGR_UCKR_BIASCOUNT_SHIFT) */
#define PMC_CKGR_UCKR_BIASCOUNT_MASK (15 << PMC_CKGR_UCKR_BIASCOUNT_SHIFT)
# define PMC_CKGR_UCKR_BIASCOUNT(n) ((n) << PMC_CKGR_UCKR_BIASCOUNT_SHIFT)
/* PMC Clock Generator Main Oscillator Register */
@ -251,6 +253,7 @@
# define PMC_USB_USBS_UPLL PMC_USB_USBS
#define PMC_USB_USBDIV_SHIFT (8) /* Bits 8-11: Divider for USB Clock */
#define PMC_USB_USBDIV_MASK (15 << PMC_USB_USBDIV_SHIFT)
# define PMC_USB_USBDIV(a) ((a) << PMC_USB_USBDIV_SHIFT)
/* Soft Modem Clock Register */

View File

@ -352,7 +352,15 @@ static inline void sam_usbclockconfig(void)
#endif
#ifdef CONFIG_SAMA5_EHCI
/* For High-speed operations, the user has to perform the following:
uint32_t regval;
/* The USB Host High Speed requires a 480 MHz clock (UPLLCK) for the
* embedded High-speed transceivers. UPLLCK is the output of the 480 MHz
* UTMI PLL (UPLL). The source clock of the UTMI PLL is the Main OSC output:
* Either the 12MHz internal oscillator on a 12MHz crystal. The Main OSC
* must be 12MHz because the UPLL has a built-in 40x multiplier.
*
* For High-speed operations, the user has to perform the following:
*
* 1) Enable UHP peripheral clock, bit (1 << AT91C_ID_UHPHS) in
* PMC_PCER register.
@ -371,19 +379,42 @@ static inline void sam_usbclockconfig(void)
* driver is initialized.
*/
# warning Missing logic
#endif
/* 2) Write CKGR_PLLCOUNT field in PMC_UCKR register. */
#if 0 // #ifdef CONFIG_USBDEV
uint32_t regval;
/* Setup UTMI for USB and wait for LOCKU */
regval = getreg32(SAM_PMC_CKGR_UCKR);
regval |= (BOARD_CKGR_UCKR_UPLLCOUNT | PMC_CKGR_UCKR_UPLLEN);
regval = PMC_CKGR_UCKR_UPLLCOUNT(BOARD_CKGR_UCKR_UPLLCOUNT);
putreg32(regval, SAM_PMC_CKGR_UCKR);
/* 3) Enable UPLL, bit AT91C_CKGR_UPLLEN in PMC_UCKR register. */
regval |= PMC_CKGR_UCKR_UPLLEN;
putreg32(regval, SAM_PMC_CKGR_UCKR);
/* 4) Wait until UTMI_PLL is locked. LOCKU bit in PMC_SR register */
sam_pmcwait(PMC_INT_LOCKU);
/* 5) Enable BIAS, bit AT91C_CKGR_BIASEN in PMC_UCKR register. */
regval |= PMC_CKGR_UCKR_BIASCOUNT(BOARD_CKGR_UCKR_BIASCOUNT);
putreg32(regval, SAM_PMC_CKGR_UCKR);
regval |= PMC_CKGR_UCKR_BIASEN;
putreg32(regval, SAM_PMC_CKGR_UCKR);
/* 6) Select UPLLCK as Input clock of OHCI part, USBS bit in PMC_USB
* register.
*/
regval = PMC_USB_USBS_UPLL;
putreg32(regval, SAM_PMC_USB);
/* 7) Program the OHCI clocks (UHP48M and UHP12M) with USBDIV field in
* PMC_USB register. USBDIV must be 9 (division by 10) if UPLLCK is
* selected.
*/
regval |= PMC_USB_USBDIV(9);
putreg32(regval, SAM_PMC_USB);
#endif
}

1626
arch/arm/src/sama5/sam_ehci.c Executable file

File diff suppressed because it is too large Load Diff

View File

@ -192,7 +192,7 @@ struct sam_rhport_s
{
/* Common device fields. This must be the first thing defined in the
* structure so that it is possible to simply cast from struct usbhost_s
* to structsam_usbhost_s.
* to struct sam_rhport_s.
*/
struct usbhost_driver_s drvr;

View File

@ -137,8 +137,8 @@ FAR struct usbhost_connection_s *sam_ohci_initialize(int controller);
*******************************************************************************/
#ifdef CONFIG_SAMA5_EHCI
struct usbhost_driver_s;
FAR struct usbhost_driver_s *sam_ehci_initialize(int controller);
struct usbhost_connection_s;
FAR struct usbhost_connection_s *sam_ehci_initialize(int controller);
#endif
/***********************************************************************************

View File

@ -100,6 +100,7 @@
#define BOARD_PMC_MCKR_PLLADIV PMC_MCKR_PLLADIV2
#define BOARD_PMC_MCKR_MDIV PMC_MCKR_MDIV_PCKDIV3
#ifdef CONFIG_SAMA5_OHCI
/* For OHCI Full-speed operations, the user has to perform the following:
*
* 1) Enable UHP peripheral clock, bit (1 << AT91C_ID_UHPHS) in PMC_PCER
@ -131,8 +132,9 @@
* frame rate. I cannot explain the factor of 2 difference.
*/
#define BOARD_OHCI_INPUT PMC_USB_USBS_PLLA
#define BOARD_OHCI_DIVIDER (7)
# define BOARD_OHCI_INPUT PMC_USB_USBS_PLLA
# define BOARD_OHCI_DIVIDER (7)
#endif
/* Resulting frequencies */

View File

@ -98,7 +98,7 @@
#define BOARD_PMC_MCKR_PRES PMC_MCKR_PRES_DIV1
#define BOARD_PMC_MCKR_PLLADIV PMC_MCKR_PLLADIV2
#define BOARD_PMC_MCKR_MDIV PMC_MCKR_MDIV_PCKDIV3
786
/* Resulting frequencies */
#define BOARD_MAINOSC_FREQUENCY (12000000) /* MAINOSC: 12MHz crystal on-board */
@ -106,6 +106,36 @@
#define BOARD_PCK_FREQUENCY (396000000) /* CPU: PLLACK / 2 / 1 */
#define BOARD_MCK_FREQUENCY (132000000) /* MCK: PLLACK / 2 / 1 / 3 */
#ifdef CONFIG_SAMA5_EHCI
/* The USB Host High Speed requires a 480 MHz clock (UPLLCK) for the embedded
* High-speed transceivers. UPLLCK is the output of the 480 MHz UTMI PLL
* (UPLL). The source clock of the UTMI PLL is the Main OSC output: Either
* the 12MHz internal RC oscillator on a an external 12MHz crystal. The
* Main OSC must be 12MHz because the UPLL has a built-in 40x multiplier.
*
* For High-speed operations, the user has to perform the following:
*
* 1) Enable UHP peripheral clock, bit (1 << AT91C_ID_UHPHS) in
* PMC_PCER register.
* 2) Write CKGR_PLLCOUNT field in PMC_UCKR register.
* 3) Enable UPLL, bit AT91C_CKGR_UPLLEN in PMC_UCKR register.
* 4) Wait until UTMI_PLL is locked. LOCKU bit in PMC_SR register
* 5) Enable BIAS, bit AT91C_CKGR_BIASEN in PMC_UCKR register.
* 6) Select UPLLCK as Input clock of OHCI part, USBS bit in PMC_USB
* register.
* 7) Program the OHCI clocks (UHP48M and UHP12M) with USBDIV field in
* PMC_USB register. USBDIV must be 9 (division by 10) if UPLLCK is
* selected.
* 8) Enable OHCI clocks, UHP bit in PMC_SCER register.
*
* Steps 2 through 7 performed here. 1 and 8 are performed in the EHCI
* driver is initialized.
*/
# define BOARD_CKGR_UCKR_UPLLCOUNT (15) /* Maximum value */
# define BOARD_CKGR_UCKR_BIASCOUNT (15) /* Maximum value */
#endif
/* HSMCI clocking
*
* Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK)