blob: c0b343edb62796ac2080b0499873707a4f992338 [file] [log] [blame]
/****************************************************************************
* arch/arm/src/lc823450/lc823450_clockconfig.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#include "arm_internal.h"
#include "lc823450_clockconfig.h"
#include "lc823450_syscontrol.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_MAX_CPU_CLOCK_150
# define SYSCLK 150 /* MHz */
#else
# define SYSCLK 160 /* MHz */
#endif
#ifdef CONFIG_AHB_CLOCK_IS_CPU_CLOCK
# define HCLKDIV 0 /* AHB = system / (HCLKIDV + 1) */
#else
# define HCLKDIV 3 /* AHB = system / (HCLKIDV + 1) */
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
unsigned int XT1OSC_CLK;
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: lc823450_get_systemfreq
****************************************************************************/
uint32_t lc823450_get_systemfreq(void)
{
return SYSCLK * 1000000;
}
/****************************************************************************
* Name: lc823450_get_apb
****************************************************************************/
#ifndef CONFIG_DVFS
uint32_t lc823450_get_apb(void)
{
return SYSCLK * 1000000;
}
#endif
/****************************************************************************
* Name: lc823450_get_ahb
****************************************************************************/
uint32_t lc823450_get_ahb(void)
{
return (SYSCLK * 1000000) / (HCLKDIV + 1);
}
/****************************************************************************
* Name: lc823450_clockconfig
****************************************************************************/
void lc823450_clockconfig()
{
uint32_t val;
val = getreg32(BMODE_DT) & BMODE_DT_XTALINFO_MASK;
if (val == BMODE_DT_XTALINFO_20)
{
XT1OSC_CLK = (20 * 1000 * 1000);
}
else
{
XT1OSC_CLK = (24 * 1000 * 1000);
}
/* XT1 enable */
modifyreg32(OSCCNT, 0, OSCCNT_XT1EN);
/* Clear MAINDIV */
modifyreg32(OSCCNT, OSCCNT_MAINDIV_MASK, 0);
/* Select system clock source from MAIN(XT1) */
val = getreg32(OSCCNT);
val &= ~OSCCNT_SCKSEL_MASK;
val |= OSCCNT_SCKSEL_MAIN;
putreg32(val, OSCCNT);
#ifdef CONFIG_LC823450_IPL2
/* Set the common PLL values
* XTAL / XT1OSC_CLK = 1MHz
*/
putreg32((XT1OSC_CLK / 1000000) - 1, PLL1MDIV);
/* 1MHz * SYSCLK = system clock */
putreg32(SYSCLK * 2 - 1, PLL1NDIV);
#else
if (SYSCLK == 150 && XT1OSC_CLK == 24000000)
{
putreg32(0x01, PLL1MDIV);
putreg32(0x18, PLL1NDIV);
}
else if (SYSCLK == 160 && XT1OSC_CLK == 24000000)
{
putreg32(0x02, PLL1MDIV);
putreg32(0x27, PLL1NDIV);
}
else if (SYSCLK == 160 && XT1OSC_CLK == 20000000)
{
putreg32(0x00, PLL1MDIV);
putreg32(0x0f, PLL1NDIV);
}
else
{
DEBUGPANIC();
}
#endif
/* enable PLL */
val = getreg32(PLL1CNT);
val |= PLL1CNT_STYB;
val |= PLL1CNT_RSTB;
putreg32(val, PLL1CNT);
/* wait for lock */
up_udelay(10000);
#if 0
/* To check basic clock by PHI pin.
* Don't forget to change GPIO09 pinmux.
*/
val = getreg32(FCLKCNT);
val |= (1 << 26);
putreg32(val, FCLKCNT);
#endif
/* S-Flash fclock = sysclk / 4 */
val = getreg32(FCLKCNT);
val |= FCLKCNT_SFDIV4;
putreg32(val, FCLKCNT);
/* set AHB with HCLKDIV */
modifyreg32(PERICLKDIV,
PERICLKDIV_HCLKDIV_MASK,
HCLKDIV);
/* EXT4 = sysclk / 3 (53.3MHz=18.8n) */
val = getreg32(PERICLKDIV);
val |= (3 - 1) << 16;
putreg32(val, PERICLKDIV);
/* MAIN clock source = PLL */
val = getreg32(OSCCNT);
val |= OSCCNT_MCSEL;
putreg32(val, OSCCNT);
/* Set ROM wait cycle (DSP=1wait, CPU=1wait) */
modifyreg32(MEMEN4, 0, MEMEN4_DWAIT | MEMEN4_HWAIT);
/* Select system clock source from MAIN(PLL) */
val = getreg32(OSCCNT);
val &= ~OSCCNT_SCKSEL_MASK;
val |= OSCCNT_SCKSEL_MAIN;
putreg32(val, OSCCNT);
}