diff --git a/arch/arm/src/samv7/sam_clockconfig.c b/arch/arm/src/samv7/sam_clockconfig.c index 9d68d4d278c..6ce1bde3040 100644 --- a/arch/arm/src/samv7/sam_clockconfig.c +++ b/arch/arm/src/samv7/sam_clockconfig.c @@ -224,30 +224,26 @@ static inline void sam_pmcsetup(void) putreg32(BOARD_CKGR_PLLAR, SAM_PMC_CKGR_PLLAR); sam_pmcwait(PMC_INT_LOCKA); -#ifdef CONFIG_USBDEV +#ifdef CONFIG_SAMV7_USBDEVHS /* UTMI configuration: Enable port0, select 12/16 MHz MAINOSC crystal source */ -#if 0 /* REVISIT: Does this apply only to OHCI? */ - putreg32(UTMI_OHCIICR_RES0, SAM_UTMI_OHCIICR); -#endif - #if BOARD_MAINOSC_FREQUENCY == 12000000 putreg32(UTMI_CKTRIM_FREQ_XTAL12, SAM_UTMI_CKTRIM); -#elif BOARD_MAINOSC_FREQUENCY == 12000000 +#elif BOARD_MAINOSC_FREQUENCY == 16000000 putreg32(UTMI_CKTRIM_FREQ_XTAL16, SAM_UTMI_CKTRIM); #else # error ERROR: Unrecognized MAINSOSC frequency #endif +#ifdef CONFIG_SAMV7_USBDEVHS_LOWPOWER /* Enable UTMI Clocking. The USBHS can work in two modes: * * - Normal mode where High speed, Full speed and Low speed are available. * - Low-power mode where only Full speed and Low speed are available. * - * Only the normal mode is supported by this logic. + * Only the Low-power mode is mode is supported by this logic. */ -#ifdef CONFIG_SAMV7_USBDEVHS_LOWPOWER /* UTMI Low-power mode, Full/Low Speed mode * * Enable the 48MHz FS Clock. @@ -255,15 +251,6 @@ static inline void sam_pmcsetup(void) putreg32(PMC_USBCLK, SAM_PMC_SCER); -#else - /* UTMI normal mode, High/Full/Low Speed - * - * Disable the 48MHz USB FS Clock. It is not used in this configuration - */ - - putreg32(PMC_USBCLK, SAM_PMC_SCDR); -#endif - /* Select the UTMI PLL as the USB PLL clock input (480MHz) with divider * to get to 48MHz. UPLL output frequency is determined only by the * 12/16MHz crystal selection above. @@ -271,7 +258,6 @@ static inline void sam_pmcsetup(void) regval = PMC_USB_USBS_UPLL; -#ifdef CONFIG_SAMV7_USBDEVHS_LOWPOWER if ((getreg32(SAM_PMC_MCKR) & PMC_MCKR_PLLADIV2) != 0) { /* Divider = 480 Mhz / 2 / 48 Mhz = 5 */ @@ -284,7 +270,6 @@ static inline void sam_pmcsetup(void) regval |= PMC_USB_USBDIV(9); } -#endif putreg32(regval, SAM_PMC_USB); @@ -296,7 +281,9 @@ static inline void sam_pmcsetup(void) /* Wait for LOCKU */ sam_pmcwait(PMC_INT_LOCKU); -#endif + +#endif /* CONFIG_SAMV7_USBDEVHS_LOWPOWER */ +#endif /* CONFIG_SAMV7_USBDEVHS */ /* Switch to the fast clock and wait for MCKRDY */ @@ -405,3 +392,50 @@ void sam_clockconfig(void) sam_enabledefaultmaster(); } + +/**************************************************************************** + * Name: sam_usbclock + * + * Description: + * Enable USBHS clocking. + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_USBDEVHS) && !defined(CONFIG_SAMV7_USBDEVHS_LOWPOWER) +void sam_usbclock(void) +{ + uint32_t regval; + + /* Enable UTMI Clocking. The USBHS can work in two modes: + * + * - Normal mode where High speed, Full speed and Low speed are available. + * - Low-power mode where only Full speed and Low speed are available. + * + * Only the normal mode is supported by this logic. + */ + + /* UTMI normal mode, High/Full/Low Speed + * + * Disable the 48MHz USB FS Clock. It is not used in this configuration + */ + + putreg32(PMC_USBCLK, SAM_PMC_SCDR); + + /* Select the UTMI PLL as the USB PLL clock input (480MHz) with a divider + * of 1. UPLL output frequency is determined only by the 12/16MHz crystal + * selection set in sam_clockconfig(). + */ + + putreg32(PMC_USB_USBS_UPLL, SAM_PMC_USB); + + /* Enable the UTMI PLL with the maximum start-up time */ + + regval = PMC_CKGR_UCKR_UPLLEN | PMC_CKGR_UCKR_UPLLCOUNT_MAX; + putreg32(regval, SAM_PMC_CKGR_UCKR); + + /* Wait for LOCKU */ + + sam_pmcwait(PMC_INT_LOCKU); +} + +#endif /* CONFIG_SAMV7_USBDEVHS && !CONFIG_SAMV7_USBDEVHS_LOWPOWER */ diff --git a/arch/arm/src/samv7/sam_clockconfig.h b/arch/arm/src/samv7/sam_clockconfig.h index 9f264bc84af..f62d7329041 100644 --- a/arch/arm/src/samv7/sam_clockconfig.h +++ b/arch/arm/src/samv7/sam_clockconfig.h @@ -85,6 +85,20 @@ extern "C" void sam_clockconfig(void); +/**************************************************************************** + * Name: sam_usbclock + * + * Description: + * Enable USBHS clocking. + * + ****************************************************************************/ + +#if defined(CONFIG_SAMV7_USBDEVHS) && !defined(CONFIG_SAMV7_USBDEVHS_LOWPOWER) +void sam_usbclock(void); +#else +# define sam_usbclock() +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/arch/arm/src/samv7/sam_usbdevhs.c b/arch/arm/src/samv7/sam_usbdevhs.c index e6c20e11ea5..8e0a81e4312 100644 --- a/arch/arm/src/samv7/sam_usbdevhs.c +++ b/arch/arm/src/samv7/sam_usbdevhs.c @@ -74,6 +74,7 @@ #include "sam_periphclks.h" #include "chip/sam_usbhs.h" +#include "sam_clockconfig.h" #include "sam_usbdev.h" #if defined(CONFIG_USBDEV) && defined(CONFIG_SAMV7_USBDEVHS) @@ -2832,14 +2833,14 @@ static int sam_usbhs_interrupt(int irq, void *context) sam_putreg(USBHS_DEVINT_SUSPD | USBHS_DEVINT_WAKEUP, SAM_USBHS_DEVICR); + /* Inform board logic that USB is suspended */ + + sam_suspend(priv); + /* Re-freeze the clock */ regval |= USBHS_CTRL_FRZCLK; sam_putreg(regval, SAM_USBHS_CTRL); - - /* Inform board logic that USB is suspended */ - - sam_suspend(priv); } /* SOF interrupt */ @@ -4325,6 +4326,10 @@ static void sam_hw_setup(struct sam_usbdev_s *priv) regval &= ~USBHS_CTRL_USBE; sam_putreg(regval, SAM_USBHS_CTRL); + /* Configure USBHS pins. Nothing needs to be done: HDM and HDP are the + * primary pin functions and there are not alternatives. + */ + /* Enable clocking to the USBHS peripheral. * * The clock for the USBHS bus interface is generated by the Power @@ -4346,7 +4351,7 @@ static void sam_hw_setup(struct sam_usbdev_s *priv) * 3. Enable the UPLL 480 MHz. * 4. Wait for the UPLL 480 MHz to be considered as locked by the PMC. * - * Steps 1,3, and 4 were performed in sam_clockconfig.c. + * Steps 3 and 4 are performed in sam_usbclock.c. */ /* Enable the USBHS peripheral clock (PMC_PCER) */ @@ -4366,6 +4371,10 @@ static void sam_hw_setup(struct sam_usbdev_s *priv) regval &= ~USBHS_CTRL_FRZCLK; sam_putreg(regval, SAM_USBHS_CTRL); + /* Enable the UPLL */ + + sam_usbclock(); + /* Select High Speed or force Full Speed */ regval = sam_getreg(SAM_USBHS_DEVCTRL);