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 Add logic for management of device addresses. This logic does not
currently hook into into anything. It will someday be a part of the currently hook into into anything. It will someday be a part of the
NuttX USB hub implementation (2013-8-18). 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 default n
---help--- ---help---
Build support for the SAMA5 USB high speed Enhanced Host Controller 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 endmenu # USB High Speed Host driver option
endif # SAMA5_UHPHS endif # SAMA5_UHPHS

View File

@ -69,11 +69,11 @@
/* Host Controller Capability Registers */ /* 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 */ /* 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 * Public Types

View File

@ -179,9 +179,11 @@
#define PMC_CKGR_UCKR_UPLLEN (1 << 16) /* Bit 16: UTMI PLL Enable */ #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_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_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_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_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 */ /* PMC Clock Generator Main Oscillator Register */
@ -251,6 +253,7 @@
# define PMC_USB_USBS_UPLL PMC_USB_USBS # 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_SHIFT (8) /* Bits 8-11: Divider for USB Clock */
#define PMC_USB_USBDIV_MASK (15 << PMC_USB_USBDIV_SHIFT) #define PMC_USB_USBDIV_MASK (15 << PMC_USB_USBDIV_SHIFT)
# define PMC_USB_USBDIV(a) ((a) << PMC_USB_USBDIV_SHIFT)
/* Soft Modem Clock Register */ /* Soft Modem Clock Register */

View File

@ -352,7 +352,15 @@ static inline void sam_usbclockconfig(void)
#endif #endif
#ifdef CONFIG_SAMA5_EHCI #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 * 1) Enable UHP peripheral clock, bit (1 << AT91C_ID_UHPHS) in
* PMC_PCER register. * PMC_PCER register.
@ -371,19 +379,42 @@ static inline void sam_usbclockconfig(void)
* driver is initialized. * driver is initialized.
*/ */
# warning Missing logic /* 2) Write CKGR_PLLCOUNT field in PMC_UCKR register. */
#endif
#if 0 // #ifdef CONFIG_USBDEV regval = PMC_CKGR_UCKR_UPLLCOUNT(BOARD_CKGR_UCKR_UPLLCOUNT);
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);
putreg32(regval, SAM_PMC_CKGR_UCKR); 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); 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 #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 /* 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 * 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; 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 #ifdef CONFIG_SAMA5_EHCI
struct usbhost_driver_s; struct usbhost_connection_s;
FAR struct usbhost_driver_s *sam_ehci_initialize(int controller); FAR struct usbhost_connection_s *sam_ehci_initialize(int controller);
#endif #endif
/*********************************************************************************** /***********************************************************************************

View File

@ -100,6 +100,7 @@
#define BOARD_PMC_MCKR_PLLADIV PMC_MCKR_PLLADIV2 #define BOARD_PMC_MCKR_PLLADIV PMC_MCKR_PLLADIV2
#define BOARD_PMC_MCKR_MDIV PMC_MCKR_MDIV_PCKDIV3 #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: /* 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 * 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. * frame rate. I cannot explain the factor of 2 difference.
*/ */
#define BOARD_OHCI_INPUT PMC_USB_USBS_PLLA # define BOARD_OHCI_INPUT PMC_USB_USBS_PLLA
#define BOARD_OHCI_DIVIDER (7) # define BOARD_OHCI_DIVIDER (7)
#endif
/* Resulting frequencies */ /* Resulting frequencies */

View File

@ -98,7 +98,7 @@
#define BOARD_PMC_MCKR_PRES PMC_MCKR_PRES_DIV1 #define BOARD_PMC_MCKR_PRES PMC_MCKR_PRES_DIV1
#define BOARD_PMC_MCKR_PLLADIV PMC_MCKR_PLLADIV2 #define BOARD_PMC_MCKR_PLLADIV PMC_MCKR_PLLADIV2
#define BOARD_PMC_MCKR_MDIV PMC_MCKR_MDIV_PCKDIV3 #define BOARD_PMC_MCKR_MDIV PMC_MCKR_MDIV_PCKDIV3
786
/* Resulting frequencies */ /* Resulting frequencies */
#define BOARD_MAINOSC_FREQUENCY (12000000) /* MAINOSC: 12MHz crystal on-board */ #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_PCK_FREQUENCY (396000000) /* CPU: PLLACK / 2 / 1 */
#define BOARD_MCK_FREQUENCY (132000000) /* MCK: PLLACK / 2 / 1 / 3 */ #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 /* HSMCI clocking
* *
* Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK) * Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK)