Beginning of support for SAMA5 EHCI. Not much there yet
This commit is contained in:
parent
e3a76b2e64
commit
320a2e2a0a
@ -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).
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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
1626
arch/arm/src/sama5/sam_ehci.c
Executable file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||||
|
@ -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
|
||||||
|
|
||||||
/***********************************************************************************
|
/***********************************************************************************
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user