nuttx/arch/arm/src/lpc54xx/lpc54_clockconfig.c
Gregory Nutt 037c9ea0a4 arch/arm: Rename all up_*.h files to arm_*.h
Summary

The naming standard at https://cwiki.apache.org/confluence/display/NUTTX/Naming+FAQ requires that all MCU-private files begin with the name of the architecture, not up_.

This PR addresses only these name changes for the up_*.h files.  There are only three, but almost 1680 files that include them:

    up_arch.h
    up_internal.h
    up_vfork.h

The only change to the files is from including up_arch.h to arm_arch.h (for example).

The entire job required to be compatible with that Naming Convention will also require changing the naming of the up_() functions that are used only within arch/arm and board/arm.

Impact

There should be not impact of this change (other that one step toward more consistent naming).

Testing

stm32f4discovery:netnsh
2020-05-01 03:43:44 +01:00

359 lines
10 KiB
C

/****************************************************************************
* arch/arm/src/lpc54628/lpc54_clockconfig.c
*
* Copyright (C) 2017-2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Parts of this file were adapted from sample code provided for the LPC54xx
* family from NXP which has a compatible BSD license.
*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright (c) 2016 - 2017 , NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#include "arm_arch.h"
#include "arm_internal.h"
#include "hardware/lpc54_syscon.h"
#include "lpc54_power.h"
#include "lpc54_clockconfig.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: lpc54_setvoltage
*
* Description:
* Set voltage for PLL frequency.
*
****************************************************************************/
static void lpc54_setvoltage(uint32_t freq)
{
if (freq == 12000000)
{
putreg32(0x21e, 0x40020040);
putreg32(4, LPC54_SYSCON_PDRUNCFGSET0);
}
else if (freq == 48000000)
{
putreg32(0x31e, 0x40020040);
putreg32(4, LPC54_SYSCON_PDRUNCFGSET0);
}
else
{
putreg32(15, 0x40020000);
putreg32(12, 0x40020004);
putreg32(11, 0x40020008);
putreg32(15, 0x4002000c);
putreg32(11, 0x40020010);
putreg32(11, 0x40020014);
}
}
/****************************************************************************
* Name: lpc54_power_pll
*
* Description:
* Provide VD3 power to the PLL
*
****************************************************************************/
static void lpc54_power_pll(void)
{
putreg32(0x4000000, 0x40000630);
while ((getreg32(0x40020054) & (1 << 26)) != 0)
{
}
}
/****************************************************************************
* Name: lpc54_set_flash_waitstates
*
* Description:
* Set the FLASH wait states for the passed frequency
*
****************************************************************************/
static void lpc54_set_flash_waitstates(uint32_t freq)
{
uint32_t regval;
regval = getreg32(LPC54_SYSCON_FLASHCFG);
regval &= ~SYSCON_FLASHCFG_FLASHTIM_MASK;
if (freq <= 12000000)
{
regval |= SYSCON_FLASHCFG_FLASHTIM(1);
}
else if (freq <= 24000000)
{
regval |= SYSCON_FLASHCFG_FLASHTIM(2);
}
else if (freq <= 36000000)
{
regval |= SYSCON_FLASHCFG_FLASHTIM(3);
}
else if (freq <= 60000000)
{
regval |= SYSCON_FLASHCFG_FLASHTIM(4);
}
else if (freq <= 96000000)
{
regval |= SYSCON_FLASHCFG_FLASHTIM(5);
}
else if (freq <= 120000000)
{
regval |= SYSCON_FLASHCFG_FLASHTIM(6);
}
else if (freq <= 144000000)
{
regval |= SYSCON_FLASHCFG_FLASHTIM(7);
}
else if (freq <= 168000000)
{
regval |= SYSCON_FLASHCFG_FLASHTIM(8);
}
else
{
regval |= SYSCON_FLASHCFG_FLASHTIM(9);
}
putreg32(regval, LPC54_SYSCON_FLASHCFG);
}
/****************************************************************************
* Name: lpc54_configure_pll
*
* Description:
* Configure the PLL.
*
*****************************************************************************/
static void lpc54_configure_pll(FAR const struct pll_setup_s *pllsetup)
{
uint32_t regval;
regval = getreg32(LPC54_SYSCON_SYSPLLCLKSEL);
if ((regval & SYSCON_SYSPLLCLKSEL_MASK) != 0)
{
uint32_t temp;
temp = getreg32(LPC54_SYSCON_PDRUNCFGCLR0);
temp |= SYSCON_PDRUNCFG0_VD2ANA;
putreg32(temp, LPC54_SYSCON_PDRUNCFGCLR0);
temp = getreg32(LPC54_SYSCON_PDRUNCFGCLR1);
temp |= SYSCON_PDRUNCFG1_SYSOSC;
putreg32(temp, LPC54_SYSCON_PDRUNCFGCLR1);
}
/* Enable power VD3 for PLLs */
lpc54_power_pll();
/* Power off PLL during setup changes */
lpc54_syspll_powerdown();
/* Write PLL setup data */
putreg32(pllsetup->pllctrl, LPC54_SYSCON_SYSPLLCTRL);
putreg32(pllsetup->pllndec, LPC54_SYSCON_SYSPLLNDEC);
putreg32(pllsetup->pllndec | SYSCON_SYSPLLNDEC_NREQ,
LPC54_SYSCON_SYSPLLNDEC);
putreg32(pllsetup->pllpdec, LPC54_SYSCON_SYSPLLPDEC);
putreg32(pllsetup->pllpdec | SYSCON_SYSPLLPDEC_PREQ,
LPC54_SYSCON_SYSPLLPDEC);
putreg32(pllsetup->pllmdec, LPC54_SYSCON_SYSPLLMDEC);
putreg32(pllsetup->pllmdec | SYSCON_SYSPLLMDEC_MREQ,
LPC54_SYSCON_SYSPLLMDEC);
/* Flags for lock or power on */
if ((pllsetup->pllflags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0)
{
/* If turning the PLL back on, perform the following sequence to
* accelerate PLL lock.
*/
volatile uint32_t delay;
uint32_t maxcco = (1 << 18) | 0x5dd2; /* CCO = 1.6Ghz + MDEC enabled */
uint32_t ssctrl = getreg32(LPC54_SYSCON_SYSPLLMDEC) & ~SYSCON_SYSPLLMDEC_MREQ;
/* Initialize and power up PLL */
putreg32(maxcco, LPC54_SYSCON_SYSPLLMDEC);
lpc54_syspll_powerup();
/* Set MREQ to activate */
putreg32(maxcco | SYSCON_SYSPLLMDEC_MREQ, LPC54_SYSCON_SYSPLLMDEC);
/* Delay for 72 uSec @ 12Mhz */
for (delay = 0; delay < 172; delay++)
{
}
/* Clear MREQ to prepare for restoring MREQ */
putreg32(ssctrl, LPC54_SYSCON_SYSPLLMDEC);
/* set original value back and activate */
putreg32(ssctrl | SYSCON_SYSPLLMDEC_MREQ, LPC54_SYSCON_SYSPLLMDEC);
/* Enable PLL */
lpc54_syspll_powerup();
}
/* Wait for the lock? */
if ((pllsetup->pllflags & PLL_SETUPFLAG_WAITLOCK) != 0)
{
while ((getreg32(LPC54_SYSCON_SYSPLLSTAT) & SYSCON_SYSPLLSTAT_LOCK) == 0)
{
}
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: lpc54_clockconfig
*
* Description:
* Called to initialize the LPC54628. This does whatever setup is needed
* to put the MCU in a usable state. This includes the initialization of
* clocking using the settings in board.h. This function also performs
* other low-level chip as necessary.
*
*****************************************************************************/
void lpc54_clockconfig(FAR const struct pll_setup_s *pllsetup)
{
uint32_t regval;
/* Set up the clock sources */
/* Power up the FRO 12MHz clock source */
lpc54_fro_powerup();
/* Switch to FRO 12MHz first to ensure we can change voltage without
* accidentally being below the voltage for current speed.
*/
putreg32(SYSCON_MAINCLKSELA_FRO12, LPC54_SYSCON_MAINCLKSELA);
putreg32(SYSCON_MAINCLKSELB_MAINCLKSELA, LPC54_SYSCON_MAINCLKSELB);
/* Set the voltage for the find PLL output frequency. This assumes
* that the PLL output frequency is >=12MHz.
*/
lpc54_setvoltage(pllsetup->pllfout);
/* Set up the FLASH wait states for the core
*
* REVISIT: Should this be the PLL output frequency (Main clock) or
* the AHB clock?
*/
lpc54_set_flash_waitstates(pllsetup->pllfout);
/* Set up the PLL clock source as specified by PLL configuration. */
putreg32(0, LPC54_SYSCON_MAINCLKSELB);
putreg32(pllsetup->pllclksel, LPC54_SYSCON_SYSPLLCLKSEL);
/* Check if the selected PLL clock source is clk_in, the external clock
* that comes from a crystal oscillator.
*/
if (pllsetup->pllclksel == SYSCON_SYSPLLCLKSEL_CLKIN)
{
/* If so, provide power for the external clock.
*
* VD2ANA - Analog supply for System Oscillator
* SYSOSC - System oscillator power.
*
* REVISIT: This was not necessary for the LPC54628 but kxjiang
* <kxjiangs@gmail.com> reports this to be necessary for the
* LPC54608 when the CLKIN source is selected. This has not been
* re-verified on the LPC54628.
*
* REVISIT: Note that these power supplies are not disabled if a
* different clock source is selected. Should they be?
*/
putreg32(SYSCON_PDRUNCFG0_VD2ANA, LPC54_SYSCON_PDRUNCFGCLR0);
putreg32(SYSCON_PDRUNCFG1_SYSOSC, LPC54_SYSCON_PDRUNCFGCLR1);
}
/* Configure the PLL */
lpc54_configure_pll(pllsetup);
/* Set up the AHB/CPU clock divider */
putreg32(pllsetup->ahbdiv, LPC54_SYSCON_AHBCLKDIV);
/* Switch System clock to SYS PLL */
putreg32(SYSCON_MAINCLKSELA_FRO12, LPC54_SYSCON_MAINCLKSELA);
putreg32(SYSCON_MAINCLKSELB_PLLCLK, LPC54_SYSCON_MAINCLKSELB);
regval = getreg32(LPC54_SYSCON_MAINCLKSELA);
regval = (regval & ~SYSCON_MAINCLKSELA_MASK);
putreg32(regval, LPC54_SYSCON_MAINCLKSELA);
}