altos/lpc: Get the IRC turned off after boot time
authorKeith Packard <keithp@keithp.com>
Mon, 17 Jun 2013 21:00:11 +0000 (14:00 -0700)
committerKeith Packard <keithp@keithp.com>
Mon, 17 Jun 2013 21:00:11 +0000 (14:00 -0700)
This involved carefully moving the USB away from the IRC before
turning it off.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/lpc/ao_timer_lpc.c
src/lpc/ao_usb_lpc.c

index 62235d1e463026088ac11e4dd0b059752702acff..c0de90a3ab483343b7c3748ef40fc97b6a403ec9 100644 (file)
@@ -106,12 +106,18 @@ ao_clock_init(void)
        
        /* Switch to the IRC clock */
        lpc_scb.mainclksel = LPC_SCB_MAINCLKSEL_SEL_IRC << LPC_SCB_MAINCLKSEL_SEL;
        
        /* Switch to the IRC clock */
        lpc_scb.mainclksel = LPC_SCB_MAINCLKSEL_SEL_IRC << LPC_SCB_MAINCLKSEL_SEL;
-       lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA);
        lpc_scb.mainclkuen = (0 << LPC_SCB_MAINCLKUEN_ENA);
        lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA);
        while (!(lpc_scb.mainclkuen & (1 << LPC_SCB_MAINCLKUEN_ENA)))
                ;
        
        lpc_scb.mainclkuen = (0 << LPC_SCB_MAINCLKUEN_ENA);
        lpc_scb.mainclkuen = (1 << LPC_SCB_MAINCLKUEN_ENA);
        while (!(lpc_scb.mainclkuen & (1 << LPC_SCB_MAINCLKUEN_ENA)))
                ;
        
+       /* Switch USB to the main clock */
+       lpc_scb.usbclksel = (LPC_SCB_USBCLKSEL_SEL_MAIN_CLOCK << LPC_SCB_USBCLKSEL_SEL);
+       lpc_scb.usbclkuen = (0 << LPC_SCB_USBCLKUEN_ENA);
+       lpc_scb.usbclkuen = (1 << LPC_SCB_USBCLKUEN_ENA);
+       while (!(lpc_scb.usbclkuen & (1 << LPC_SCB_USBCLKUEN_ENA)))
+               ;
+       
        /* Find a PLL post divider ratio that gets the FCCO in range */
        for (p = 0; p < 4; p++)
                if (AO_LPC_CLKOUT << (1 + p) >= AO_LPC_FCCO_MIN)
        /* Find a PLL post divider ratio that gets the FCCO in range */
        for (p = 0; p < 4; p++)
                if (AO_LPC_CLKOUT << (1 + p) >= AO_LPC_FCCO_MIN)
@@ -178,7 +184,13 @@ ao_clock_init(void)
        lpc_scb.usbclkdiv = 0;
        lpc_scb.clkoutdiv = 0;
 
        lpc_scb.usbclkdiv = 0;
        lpc_scb.clkoutdiv = 0;
 
-#if 0
+       /* Switch USB PLL source to system osc so we can power down the IRC */
+       lpc_scb.usbpllclksel = (LPC_SCB_USBPLLCLKSEL_SEL_SYSOSC << LPC_SCB_USBPLLCLKSEL_SEL);
+       lpc_scb.usbpllclkuen = (0 << LPC_SCB_USBPLLCLKUEN_ENA);
+       lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA);
+       while (!(lpc_scb.usbpllclkuen & (1 << LPC_SCB_USBPLLCLKUEN_ENA)))
+               ;
+       
        /* Power down everything we don't need */
        lpc_scb.pdruncfg = ((1 << LPC_SCB_PDRUNCFG_IRCOUT_PD) |
                            (1 << LPC_SCB_PDRUNCFG_IRC_PD) |
        /* Power down everything we don't need */
        lpc_scb.pdruncfg = ((1 << LPC_SCB_PDRUNCFG_IRCOUT_PD) |
                            (1 << LPC_SCB_PDRUNCFG_IRC_PD) |
@@ -189,5 +201,4 @@ ao_clock_init(void)
                            (1 << LPC_SCB_PDRUNCFG_USBPAD_PD) |
                            (1 << 11) |
                            (7 << 13));
                            (1 << LPC_SCB_PDRUNCFG_USBPAD_PD) |
                            (1 << 11) |
                            (7 << 13));
-#endif
 }
 }
index aac0df04a8956f5b485dfcc9940ac4814fe571ef..e574f1e23f6eb3b6d80afc5b05cca9fe9a6888b2 100644 (file)
@@ -834,8 +834,9 @@ ao_usb_disable(void)
        /* Turn off USB clock */
        lpc_scb.usbclkdiv = 0;
 
        /* Turn off USB clock */
        lpc_scb.usbclkdiv = 0;
 
-       /* Disable USB PHY */
-       lpc_scb.pdruncfg |= (1 << LPC_SCB_PDRUNCFG_USBPAD_PD);
+       /* Disable USB PHY and PLL */
+       lpc_scb.pdruncfg |= ((1 << LPC_SCB_PDRUNCFG_USBPAD_PD) |
+                            (1 << LPC_SCB_PDRUNCFG_USBPLL_PD));
 
        /* Disable USB registers and RAM */
        lpc_scb.sysahbclkctrl &= ~((1 << LPC_SCB_SYSAHBCLKCTRL_USB) |
 
        /* Disable USB registers and RAM */
        lpc_scb.sysahbclkctrl &= ~((1 << LPC_SCB_SYSAHBCLKCTRL_USB) |
@@ -877,7 +878,6 @@ ao_usb_enable(void)
        lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_USBPLL_PD);
 
        lpc_scb.usbpllclksel = (LPC_SCB_SYSPLLCLKSEL_SEL_SYSOSC << LPC_SCB_SYSPLLCLKSEL_SEL);
        lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_USBPLL_PD);
 
        lpc_scb.usbpllclksel = (LPC_SCB_SYSPLLCLKSEL_SEL_SYSOSC << LPC_SCB_SYSPLLCLKSEL_SEL);
-       lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA);
        lpc_scb.usbpllclkuen = (0 << LPC_SCB_USBPLLCLKUEN_ENA);
        lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA);
        while (!(lpc_scb.usbpllclkuen & (1 << LPC_SCB_USBPLLCLKUEN_ENA)))
        lpc_scb.usbpllclkuen = (0 << LPC_SCB_USBPLLCLKUEN_ENA);
        lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA);
        while (!(lpc_scb.usbpllclkuen & (1 << LPC_SCB_USBPLLCLKUEN_ENA)))
@@ -887,6 +887,10 @@ ao_usb_enable(void)
                ;
 
        lpc_scb.usbclksel = 0;
                ;
 
        lpc_scb.usbclksel = 0;
+       lpc_scb.usbclkuen = (0 << LPC_SCB_USBCLKUEN_ENA);
+       lpc_scb.usbclkuen = (1 << LPC_SCB_USBCLKUEN_ENA);
+       while (!(lpc_scb.usbclkuen & (1 << LPC_SCB_USBCLKUEN_ENA)))
+               ;
 
        /* Turn on USB clock, use 48MHz clock unchanged */
        lpc_scb.usbclkdiv = 1;
 
        /* Turn on USB clock, use 48MHz clock unchanged */
        lpc_scb.usbclkdiv = 1;