vf6xx: calculate core clocks
Extend the clock controller module with a function to calculate core clocks from the current registers settings. On Vybrid, we assume that the core clocks are setup by the main operating system running on the Cortex-A5. Nevertheless we need to know their actual values in order to calculate other clocks or baud rates. Verified on a Colibri VF61, which calculates following values: ccm_core_clk: 500210526 ccm_platform_bus_clk: 166736842 ccm_ipg_bus_clk: 83368421
This commit is contained in:
parent
511f16e8c7
commit
c9857ad52a
224
include/libopencm3/vf6xx/anadig.h
Normal file
224
include/libopencm3/vf6xx/anadig.h
Normal file
@ -0,0 +1,224 @@
|
||||
/** @defgroup anadig_defines ANADIG Defines
|
||||
*
|
||||
* @brief <b>Defined Constants and Types for the VF6xx Analog components
|
||||
* control digital interface</b>
|
||||
*
|
||||
* @ingroup VF6xx_defines
|
||||
*
|
||||
* @version 1.0.0
|
||||
*
|
||||
* @author @htmlonly © @endhtmlonly 2014
|
||||
* Stefan Agner <stefan@agner.ch>
|
||||
*
|
||||
* @date 01 July 2014
|
||||
*
|
||||
* LGPL License Terms @ref lgpl_license
|
||||
* */
|
||||
/*
|
||||
* This file is part of the libopencm3 project.
|
||||
*
|
||||
* Copyright (C) 2014 Stefan Agner <stefan@agner.ch>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENCM3_ANADIG_H
|
||||
#define LIBOPENCM3_ANADIG_H
|
||||
|
||||
#include <libopencm3/cm3/common.h>
|
||||
#include <libopencm3/vf6xx/memorymap.h>
|
||||
|
||||
/* --- ANADIG registers ---------------------------------------------------- */
|
||||
|
||||
#define ANADIG_PLL3_CTRL MMIO32(ANADIG_BASE + 0x010)
|
||||
#define ANADIG_PLL7_CTRL MMIO32(ANADIG_BASE + 0x020)
|
||||
#define ANADIG_PLL2_CTRL MMIO32(ANADIG_BASE + 0x030)
|
||||
#define ANADIG_PLL2_SS MMIO32(ANADIG_BASE + 0x040)
|
||||
#define ANADIG_PLL2_NUM MMIO32(ANADIG_BASE + 0x050)
|
||||
#define ANADIG_PLL2_DENOM MMIO32(ANADIG_BASE + 0x060)
|
||||
#define ANADIG_PLL4_CTRL MMIO32(ANADIG_BASE + 0x070)
|
||||
#define ANADIG_PLL4_NUM MMIO32(ANADIG_BASE + 0x080)
|
||||
#define ANADIG_PLL4_DENOM MMIO32(ANADIG_BASE + 0x090)
|
||||
#define ANADIG_PLL6_CTRL MMIO32(ANADIG_BASE + 0x0A0)
|
||||
#define ANADIG_PLL6_NUM MMIO32(ANADIG_BASE + 0x0B0)
|
||||
#define ANADIG_PLL6_DENOM MMIO32(ANADIG_BASE + 0x0C0)
|
||||
#define ANADIG_PLL5_CTRL MMIO32(ANADIG_BASE + 0x0E0)
|
||||
#define ANADIG_PLL3_PFD MMIO32(ANADIG_BASE + 0x0F0)
|
||||
#define ANADIG_PLL2_PFD MMIO32(ANADIG_BASE + 0x100)
|
||||
#define ANADIG_REG_1P1 MMIO32(ANADIG_BASE + 0x110)
|
||||
#define ANADIG_REG_3P0 MMIO32(ANADIG_BASE + 0x120)
|
||||
#define ANADIG_REG_2P5 MMIO32(ANADIG_BASE + 0x130)
|
||||
#define ANADIG_ANA_MISC0 MMIO32(ANADIG_BASE + 0x150)
|
||||
#define ANADIG_ANA_MISC1 MMIO32(ANADIG_BASE + 0x160)
|
||||
#define ANADIG_ANADIG_DIGPROG MMIO32(ANADIG_BASE + 0x260)
|
||||
#define ANADIG_PLL1_CTRL MMIO32(ANADIG_BASE + 0x270)
|
||||
#define ANADIG_PLL1_SS MMIO32(ANADIG_BASE + 0x280)
|
||||
#define ANADIG_PLL1_NUM MMIO32(ANADIG_BASE + 0x290)
|
||||
#define ANADIG_PLL1_DENOM MMIO32(ANADIG_BASE + 0x2A0)
|
||||
#define ANADIG_PLL1_PFD MMIO32(ANADIG_BASE + 0x2B0)
|
||||
#define ANADIG_PLL_LOCK MMIO32(ANADIG_BASE + 0x2C0)
|
||||
|
||||
/* --- ANADIG values -....-------------------------------------------------- */
|
||||
|
||||
/* ANADIG_PLL3_CTRL: PLL3 Control Register (480MHz PLL of USB0) */
|
||||
#define ANADIG_PLL3_CTRL_LOCK (1 << 31)
|
||||
#define ANADIG_PLL3_CTRL_BYPASS (1 << 16)
|
||||
#define ANADIG_PLL3_CTRL_BYPASS_CLK_SRC (1 << 14)
|
||||
#define ANADIG_PLL3_CTRL_ENABLE (1 << 13)
|
||||
#define ANADIG_PLL3_CTRL_POWER (1 << 12)
|
||||
#define ANADIG_PLL3_CTRL_EN_USB_CLKS (1 << 6)
|
||||
#define ANADIG_PLL3_CTRL_DIV_SELECT (1 << 1)
|
||||
|
||||
/* ANADIG_PLL7_CTRL: PLL7 Control Register (480MHz PLL of USB1) */
|
||||
#define ANADIG_PLL7_CTRL_LOCK (1 << 31)
|
||||
#define ANADIG_PLL7_CTRL_BYPASS (1 << 16)
|
||||
#define ANADIG_PLL7_CTRL_BYPASS_CLK_SRC (1 << 14)
|
||||
#define ANADIG_PLL7_CTRL_ENABLE (1 << 13)
|
||||
#define ANADIG_PLL7_CTRL_POWER (1 << 12)
|
||||
#define ANADIG_PLL7_CTRL_EN_USB_CLKS (1 << 6)
|
||||
#define ANADIG_PLL7_CTRL_DIV_SELECT (1 << 1)
|
||||
|
||||
/* ANADIG_PLL2_CTRL: PLL2 Control Register (528MHz PLL) */
|
||||
#define ANADIG_PLL2_CTRL_LOCK (1 << 31)
|
||||
#define ANADIG_PLL2_CTRL_PFD_OFFSET_EN (1 << 18)
|
||||
#define ANADIG_PLL2_CTRL_DITHER_ENABLE (1 << 17)
|
||||
#define ANADIG_PLL2_CTRL_BYPASS (1 << 16)
|
||||
#define ANADIG_PLL2_CTRL_BYPASS_CLK_SRC (1 << 14)
|
||||
#define ANADIG_PLL2_CTRL_ENABLE (1 << 13)
|
||||
#define ANADIG_PLL2_CTRL_POWERDOWN (1 << 12)
|
||||
#define ANADIG_PLL2_CTRL_DIV_SELECT (1 << 1)
|
||||
|
||||
/* ANADIG_PLL2_SS: PLL2 Spread Spectrum definition register */
|
||||
#define ANADIG_PLL2_SS_STOP_MASK (0xffff << 16)
|
||||
#define ANADIG_PLL2_SS_ENABLE (1 << 15)
|
||||
#define ANADIG_PLL2_SS_STEP_MASK 0x8fff
|
||||
|
||||
/* ANADIG_PLL2_NUM: PLL2 Numerator definition register */
|
||||
#define ANADIG_PLL2_NUM_MFN_MASK 0x3fffffff
|
||||
|
||||
/* ANADIG_PLL2_DENOM: PLL2 Denominator definition register */
|
||||
#define ANADIG_PLL2_DENOM_MFN_MASK 0x3fffffff
|
||||
|
||||
/* ANADIG_PLL4_CTRL: PLL4 Control Register (audio PLL) */
|
||||
#define ANADIG_PLL4_CTRL_LOCK (1 << 31)
|
||||
#define ANADIG_PLL4_CTRL_PFD_OFFSET_EN (1 << 18)
|
||||
#define ANADIG_PLL4_CTRL_DITHER_ENABLE (1 << 17)
|
||||
#define ANADIG_PLL4_CTRL_BYPASS (1 << 16)
|
||||
#define ANADIG_PLL4_CTRL_BYPASS_CLK_SRC (1 << 14)
|
||||
#define ANADIG_PLL4_CTRL_ENABLE (1 << 13)
|
||||
#define ANADIG_PLL4_CTRL_POWERDOWN (1 << 12)
|
||||
#define ANADIG_PLL4_CTRL_DIV_SELECT_MASK (0x7f)
|
||||
|
||||
/* ANADIG_PLL4_NUM: PLL4 Numerator definition register */
|
||||
#define ANADIG_PLL4_NUM_MFN_MASK 0x3fffffff
|
||||
|
||||
/* ANADIG_PLL4_DENOM: PLL4 Denominator definition register */
|
||||
#define ANADIG_PLL4_DENOM_MFN_MASK 0x3fffffff
|
||||
|
||||
/* ANADIG_PLL6_CTRL: PLL6 Control Register (video PLL) */
|
||||
#define ANADIG_PLL6_CTRL_LOCK (1 << 31)
|
||||
#define ANADIG_PLL6_CTRL_PFD_OFFSET_EN (1 << 18)
|
||||
#define ANADIG_PLL6_CTRL_DITHER_ENABLE (1 << 17)
|
||||
#define ANADIG_PLL6_CTRL_BYPASS (1 << 16)
|
||||
#define ANADIG_PLL6_CTRL_BYPASS_CLK_SRC (1 << 14)
|
||||
#define ANADIG_PLL6_CTRL_ENABLE (1 << 13)
|
||||
#define ANADIG_PLL6_CTRL_POWERDOWN (1 << 12)
|
||||
#define ANADIG_PLL6_CTRL_DIV_SELECT_MASK (0x7f)
|
||||
|
||||
/* ANADIG_PLL6_NUM: PLL6 Numerator definition register */
|
||||
#define ANADIG_PLL6_NUM_MFN_MASK 0x3fffffff
|
||||
|
||||
/* ANADIG_PLL6_DENOM: PLL6 Denominator definition register */
|
||||
#define ANADIG_PLL6_DENOM_MFN_MASK 0x3fffffff
|
||||
|
||||
/* ANADIG_PLL5_CTRL: PLL5 Control Register (video PLL) */
|
||||
#define ANADIG_PLL5_CTRL_LOCK (1 << 31)
|
||||
#define ANADIG_PLL5_CTRL_PFD_OFFSET_EN (1 << 18)
|
||||
#define ANADIG_PLL5_CTRL_DITHER_ENABLE (1 << 17)
|
||||
#define ANADIG_PLL5_CTRL_BYPASS (1 << 16)
|
||||
#define ANADIG_PLL5_CTRL_BYPASS_CLK_SRC (1 << 14)
|
||||
#define ANADIG_PLL5_CTRL_ENABLE (1 << 13)
|
||||
#define ANADIG_PLL5_CTRL_POWERDOWN (1 << 12)
|
||||
#define ANADIG_PLL5_CTRL_DIV_SELECT_MASK (0x3)
|
||||
|
||||
/* ANADIG_PLL_PFD: PLL1/PLL2/PLL3 PFD Clocks */
|
||||
#define ANADIG_PLL_PFD4_CLKGATE (1 << 31)
|
||||
#define ANADIG_PLL_PFD4_STABLE (1 << 30)
|
||||
#define ANADIG_PLL_PFD4_FRAC_SHIFT 24
|
||||
#define ANADIG_PLL_PFD4_FRAC_MASK (0x3f << 24)
|
||||
#define ANADIG_PLL_PFD3_CLKGATE (1 << 23)
|
||||
#define ANADIG_PLL_PFD3_STABLE (1 << 22)
|
||||
#define ANADIG_PLL_PFD3_FRAC_SHIFT 16
|
||||
#define ANADIG_PLL_PFD3_FRAC_MASK (0x3f << 16)
|
||||
#define ANADIG_PLL_PFD2_CLKGATE (1 << 15)
|
||||
#define ANADIG_PLL_PFD2_STABLE (1 << 14)
|
||||
#define ANADIG_PLL_PFD2_FRAC_SHIFT 8
|
||||
#define ANADIG_PLL_PFD2_FRAC_MASK (0x3f << 8)
|
||||
#define ANADIG_PLL_PFD1_CLKGATE (1 << 7)
|
||||
#define ANADIG_PLL_PFD1_STABLE (1 << 6)
|
||||
#define ANADIG_PLL_PFD1_FRAC_SHIFT 0
|
||||
#define ANADIG_PLL_PFD1_FRAC_MASK (0x3f << 0)
|
||||
|
||||
/* AANADIG_ANA_MISC0: miscellaneous analog blocks */
|
||||
#define ANADIG_ANA_MISC0_OSC_XTALOK_EN (1 << 17)
|
||||
#define ANADIG_ANA_MISC0_OSC_XTALOK (1 << 16)
|
||||
#define ANADIG_ANA_MISC0_CLK_24M_IRC_XTAL_SEL (1 << 13)
|
||||
#define ANADIG_ANA_MISC0_STOP_MODE_CONFIG (1 << 12)
|
||||
#define ANADIG_ANA_MISC0_REFTOP_VBGUP (1 << 7)
|
||||
#define ANADIG_ANA_MISC0_REFTOP_SELBIASOFF (1 << 3)
|
||||
#define ANADIG_ANA_MISC0_REFTOP_LOWPOWER (1 << 2)
|
||||
#define ANADIG_ANA_MISC0_REFTOP_PWDVBGUP (1 << 1)
|
||||
#define ANADIG_ANA_MISC0_REFTOP_PWD (1 << 0)
|
||||
|
||||
/* AANADIG_ANA_MISC0: miscellaneous analog blocks */
|
||||
#define ANADIG_ANA_MISC1_IRQ_ANA_BO (1 << 30)
|
||||
#define ANADIG_ANA_MISC1_IRQ_TEMPSENSE (1 << 29)
|
||||
#define ANADIG_ANA_MISC1_LVDSCLK1_IBEN (1 << 12)
|
||||
#define ANADIG_ANA_MISC1_LVDSCLK1_OBEN (1 << 10)
|
||||
|
||||
/* AANADIG_ANA_DIGPROG: Digital Program register */
|
||||
#define ANADIG_ANADIG_DIGPROG_MAJOR_MASK (0xffff << 8)
|
||||
#define ANADIG_ANADIG_DIGPROG_MINOR_MASK (0xff << 0)
|
||||
|
||||
/* ANADIG_PLL1_CTRL: PLL1 Control Register (video PLL) */
|
||||
#define ANADIG_PLL1_CTRL_LOCK (1 << 31)
|
||||
#define ANADIG_PLL1_CTRL_PFD_OFFSET_EN (1 << 18)
|
||||
#define ANADIG_PLL1_CTRL_DITHER_ENABLE (1 << 17)
|
||||
#define ANADIG_PLL1_CTRL_BYPASS (1 << 16)
|
||||
#define ANADIG_PLL1_CTRL_BYPASS_CLK_SRC (1 << 14)
|
||||
#define ANADIG_PLL1_CTRL_ENABLE (1 << 13)
|
||||
#define ANADIG_PLL1_CTRL_POWERDOWN (1 << 12)
|
||||
#define ANADIG_PLL1_CTRL_DIV_SELECT (1 << 1)
|
||||
|
||||
/* ANADIG_PLL1_SS: PLL1 Spread Spectrum definition register */
|
||||
#define ANADIG_PLL1_SS_STOP_MASK (0xffff << 16)
|
||||
#define ANADIG_PLL1_SS_ENABLE (1 << 15)
|
||||
#define ANADIG_PLL1_SS_STEP_MASK 0x8fff
|
||||
|
||||
/* ANADIG_PLL1_NUM: PLL1 Numerator definition register */
|
||||
#define ANADIG_PLL1_NUM_MFN_MASK 0x3fffffff
|
||||
|
||||
/* ANADIG_PLL1_DENOM: PLL1 Denominator definition register */
|
||||
#define ANADIG_PLL1_DENOM_MFN_MASK 0x3fffffff
|
||||
|
||||
/* ANADIG_PLL_LOCK: PLL Lock Register */
|
||||
#define ANADIG_PLL_LOCK_PLL1 (1 << 6)
|
||||
#define ANADIG_PLL_LOCK_PLL2 (1 << 5)
|
||||
#define ANADIG_PLL_LOCK_PLL4 (1 << 4)
|
||||
#define ANADIG_PLL_LOCK_PLL6 (1 << 3)
|
||||
#define ANADIG_PLL_LOCK_PLL5 (1 << 2)
|
||||
#define ANADIG_PLL_LOCK_PLL3 (1 << 1)
|
||||
#define ANADIG_PLL_LOCK_PLL7 (1 << 0)
|
||||
|
||||
#endif
|
@ -81,19 +81,17 @@
|
||||
|
||||
#define CCM_CCSR_DAP_EN (1 << 24)
|
||||
|
||||
/* PLL1/PLL2 PFD SEL definition */
|
||||
#define CCM_CCSR_PLL2_PFD_CLK_SEL_SHIFT 19
|
||||
#define CCM_CCSR_PLL2_PFD_CLK_SEL_MAIN 0x0
|
||||
#define CCM_CCSR_PLL2_PFD_CLK_SEL_PFD1 0x1
|
||||
#define CCM_CCSR_PLL2_PFD_CLK_SEL_PFD2 0x2
|
||||
#define CCM_CCSR_PLL2_PFD_CLK_SEL_PFD3 0x3
|
||||
#define CCM_CCSR_PLL2_PFD_CLK_SEL_PFD4 0x4
|
||||
|
||||
#define CCM_CCSR_PLL2_PFD_CLK_SEL_MASK (0x7 << 19)
|
||||
#define CCM_CCSR_PLL1_PFD_CLK_SEL_SHIFT 16
|
||||
#define CCM_CCSR_PLL1_PFD_CLK_SEL_MAIN 0x0
|
||||
#define CCM_CCSR_PLL1_PFD_CLK_SEL_PFD1 0x1
|
||||
#define CCM_CCSR_PLL1_PFD_CLK_SEL_PFD2 0x2
|
||||
#define CCM_CCSR_PLL1_PFD_CLK_SEL_PFD3 0x3
|
||||
#define CCM_CCSR_PLL1_PFD_CLK_SEL_PFD4 0x4
|
||||
#define CCM_CCSR_PLL1_PFD_CLK_SEL_MASK (0x7 << 16)
|
||||
|
||||
#define CCM_CCSR_PLL_PFD_CLK_SEL_MAIN 0x0
|
||||
#define CCM_CCSR_PLL_PFD_CLK_SEL_PFD1 0x1
|
||||
#define CCM_CCSR_PLL_PFD_CLK_SEL_PFD2 0x2
|
||||
#define CCM_CCSR_PLL_PFD_CLK_SEL_PFD3 0x3
|
||||
#define CCM_CCSR_PLL_PFD_CLK_SEL_PFD4 0x4
|
||||
|
||||
#define CCM_CCSR_PLL2_PFDN4_EN (1 << 15)
|
||||
#define CCM_CCSR_PLL2_PFDN3_EN (1 << 14)
|
||||
@ -110,6 +108,7 @@
|
||||
#define CCM_CCSR_SLOW_CLK_SEL (1 << 5)
|
||||
|
||||
#define CCM_CCSR_SYS_CLK_SEL_SHIFT 0
|
||||
#define CCM_CCSR_SYS_CLK_SEL_MASK 0x7
|
||||
#define CCM_CCSR_SYS_CLK_SEL_FAST 0x0
|
||||
#define CCM_CCSR_SYS_CLK_SEL_SLOW 0x1
|
||||
#define CCM_CCSR_SYS_CLK_SEL_PLL2_PFD 0x2
|
||||
@ -117,7 +116,28 @@
|
||||
#define CCM_CCSR_SYS_CLK_SEL_PLL1_PFD 0x4
|
||||
#define CCM_CCSR_SYS_CLK_SEL_PLL3 0x5
|
||||
|
||||
/* CACRR: ARM Clock Root Register */
|
||||
#define CCM_CACRR_FLEX_CLK_DIV_SHIFT 22
|
||||
#define CCM_CACRR_FLEX_CLK_DIV_MASK (0x7 << 22)
|
||||
#define CCM_CACRR_PLL6_CLK_DIV (1 << 21)
|
||||
#define CCM_CACRR_PLL3_CLK_DIV (1 << 20)
|
||||
#define CCM_CACRR_PLL1_PFD_CLK_DIV_SHIFT 16
|
||||
#define CCM_CACRR_PLL1_PFD_CLK_DIV_MASK (0x3 << 16)
|
||||
#define CCM_CACRR_IPG_CLK_DIV_SHIFT 11
|
||||
#define CCM_CACRR_IPG_CLK_DIV_MASK (0x3 << 11)
|
||||
#define CCM_CACRR_PLL4_CLK_DIV_SHIFT 6
|
||||
#define CCM_CACRR_PLL4_CLK_DIV_MASK (0x7 << 6)
|
||||
#define CCM_CACRR_BUS_CLK_DIV_SHIFT 3
|
||||
#define CCM_CACRR_BUS_CLK_DIV_MASK (0x7 << 3)
|
||||
#define CCM_CACRR_ARM_CLK_DIV_SHIFT 0
|
||||
#define CCM_CACRR_ARM_CLK_DIV_MASK (0x7 << 0)
|
||||
|
||||
/* --- Variable definitions ------------------------------------------------ */
|
||||
|
||||
extern uint32_t ccm_core_clk;
|
||||
extern uint32_t ccm_platform_bus_clk;
|
||||
extern uint32_t ccm_ipg_bus_clk;
|
||||
|
||||
enum ccm_clock_gate {
|
||||
/* AIPS0 */
|
||||
CG0_FLEXCAN0 = 0,
|
||||
@ -323,6 +343,8 @@ enum ccm_clock_gate {
|
||||
BEGIN_DECLS
|
||||
|
||||
void ccm_clock_gate_enable(enum ccm_clock_gate gr);
|
||||
void ccm_clock_gate_disable(enum ccm_clock_gate gr);
|
||||
void ccm_calculate_clocks(void);
|
||||
|
||||
END_DECLS
|
||||
|
||||
|
@ -44,6 +44,8 @@
|
||||
#define SPI0_BASE (PERIPH_BASE_AIPS0 + 0x2C000)
|
||||
#define SPI1_BASE (PERIPH_BASE_AIPS0 + 0x2D000)
|
||||
|
||||
#define ANADIG_BASE (PERIPH_BASE_AIPS0 + 0x50000)
|
||||
|
||||
#define CCM_BASE (PERIPH_BASE_AIPS0 + 0x6B000)
|
||||
|
||||
/* AIPS1 */
|
||||
|
135
lib/vf6xx/ccm.c
135
lib/vf6xx/ccm.c
@ -37,8 +37,25 @@
|
||||
|
||||
#include <libopencm3/vf6xx/memorymap.h>
|
||||
#include <libopencm3/vf6xx/ccm.h>
|
||||
#include <libopencm3/vf6xx/anadig.h>
|
||||
|
||||
/**@{*/
|
||||
static const uint32_t pll1_main_clk = 528000000;
|
||||
static const uint32_t pll2_main_clk = 528000000;
|
||||
static const uint32_t pll3_main_clk = 480000000;
|
||||
|
||||
/* ARM Cortex-A5 clock, core clock */
|
||||
uint32_t ccm_core_clk = 0;
|
||||
|
||||
/* Platform bus clock and Cortex-M4 core clock */
|
||||
uint32_t ccm_platform_bus_clk = 0;
|
||||
|
||||
/* IPS bus clock */
|
||||
uint32_t ccm_ipg_bus_clk = 0;
|
||||
|
||||
|
||||
uint32_t ccm_get_pll_pfd(uint32_t pfd_sel, uint32_t pll_pfd, uint32_t pll_clk);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @brief Enable clock of given device
|
||||
@ -66,4 +83,122 @@ void ccm_clock_gate_disable(enum ccm_clock_gate gr)
|
||||
uint32_t gr_mask = 0x3 << ((gr % 16) * 2);
|
||||
CCM_CCGR(offset * 4) &= ~gr_mask;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @brief Calculate PFD clock
|
||||
|
||||
This function calculates the PFD clock for PLL1/2 or 3. All those PLLs
|
||||
have the same PFD clock muxing/calculating logic, hence we can use one
|
||||
function for all of them
|
||||
|
||||
@param[in] pfd_sel uint32_t. The PFD selection (muxing) value
|
||||
@param[in] pll_pfd uint32_t. The ANADIG PFD register containing the fractions
|
||||
for all possible PFDs
|
||||
@param[in] pll_clk uint32_t. PLLs main clock (which the PFDs are derived from)
|
||||
*/
|
||||
|
||||
uint32_t ccm_get_pll_pfd(uint32_t pfd_sel, uint32_t pll_pfd, uint32_t pll_clk)
|
||||
{
|
||||
uint64_t pll_pfd_clk;
|
||||
uint32_t pll_pfd_frac = pll_pfd;
|
||||
|
||||
switch(pfd_sel)
|
||||
{
|
||||
case CCM_CCSR_PLL_PFD_CLK_SEL_MAIN:
|
||||
return pll_clk;
|
||||
case CCM_CCSR_PLL_PFD_CLK_SEL_PFD1:
|
||||
pll_pfd_frac &= ANADIG_PLL_PFD1_FRAC_MASK;
|
||||
pll_pfd_frac >>= ANADIG_PLL_PFD1_FRAC_SHIFT;
|
||||
break;
|
||||
case CCM_CCSR_PLL_PFD_CLK_SEL_PFD2:
|
||||
pll_pfd_frac &= ANADIG_PLL_PFD2_FRAC_MASK;
|
||||
pll_pfd_frac >>= ANADIG_PLL_PFD2_FRAC_SHIFT;
|
||||
break;
|
||||
case CCM_CCSR_PLL_PFD_CLK_SEL_PFD3:
|
||||
pll_pfd_frac &= ANADIG_PLL_PFD3_FRAC_MASK;
|
||||
pll_pfd_frac >>= ANADIG_PLL_PFD3_FRAC_SHIFT;
|
||||
break;
|
||||
case CCM_CCSR_PLL_PFD_CLK_SEL_PFD4:
|
||||
pll_pfd_frac &= ANADIG_PLL_PFD4_FRAC_MASK;
|
||||
pll_pfd_frac >>= ANADIG_PLL_PFD4_FRAC_SHIFT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Calculate using to PLL PFD fraction */
|
||||
pll_pfd_clk = pll_clk;
|
||||
pll_pfd_clk *= 18;
|
||||
pll_pfd_clk /= pll_pfd_frac;
|
||||
|
||||
return (uint32_t)pll_pfd_clk;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @brief Calculate clocks
|
||||
|
||||
This function calculates the root clocks from the registers. On Vybrid, we
|
||||
assume that the clocks/device is setup by the main operating system running
|
||||
on the Cortex-A5 (for instance Linux). However, in order to calculate clocks
|
||||
for peripherals its important to know the current value of those clocks.
|
||||
|
||||
This are mainly the @ref ccm_core_clk which the Cortex-A5 is running with
|
||||
and lots of other clocks derive from.
|
||||
The @ref ccm_platform_bus_clk is the clock which the Cortex-M4 is running
|
||||
with.
|
||||
And the @ref ccm_ipg_bus_clk is the clock most peripherals run with.
|
||||
|
||||
*/
|
||||
|
||||
void ccm_calculate_clocks()
|
||||
{
|
||||
uint32_t ccsr = CCM_CCSR;
|
||||
uint32_t cacrr = CCM_CACRR;
|
||||
uint32_t arm_clk_div = (cacrr & CCM_CACRR_ARM_CLK_DIV_MASK) + 1;
|
||||
uint32_t bus_clk_div = cacrr & CCM_CACRR_BUS_CLK_DIV_MASK;
|
||||
uint32_t ipg_clk_div = cacrr & CCM_CACRR_IPG_CLK_DIV_MASK;
|
||||
uint32_t pll_pfd_sel;
|
||||
|
||||
bus_clk_div >>= CCM_CACRR_BUS_CLK_DIV_SHIFT;
|
||||
bus_clk_div += 1;
|
||||
|
||||
ipg_clk_div >>= CCM_CACRR_IPG_CLK_DIV_SHIFT;
|
||||
ipg_clk_div += 1;
|
||||
|
||||
/* Get Cortex-A5 core clock from system clock selection */
|
||||
switch(ccsr & CCM_CCSR_SYS_CLK_SEL_MASK)
|
||||
{
|
||||
case CCM_CCSR_SYS_CLK_SEL_FAST:
|
||||
ccm_core_clk = 24000000;
|
||||
break;
|
||||
case CCM_CCSR_SYS_CLK_SEL_SLOW:
|
||||
ccm_core_clk = 32000;
|
||||
break;
|
||||
case CCM_CCSR_SYS_CLK_SEL_PLL2_PFD:
|
||||
pll_pfd_sel = ccsr & CCM_CCSR_PLL2_PFD_CLK_SEL_MASK;
|
||||
pll_pfd_sel >>= CCM_CCSR_PLL2_PFD_CLK_SEL_SHIFT;
|
||||
|
||||
ccm_core_clk = ccm_get_pll_pfd(pll_pfd_sel, ANADIG_PLL2_PFD,
|
||||
pll2_main_clk);
|
||||
break;
|
||||
case CCM_CCSR_SYS_CLK_SEL_PLL2:
|
||||
ccm_core_clk = pll2_main_clk;
|
||||
break;
|
||||
case CCM_CCSR_SYS_CLK_SEL_PLL1_PFD:
|
||||
pll_pfd_sel = ccsr & CCM_CCSR_PLL1_PFD_CLK_SEL_MASK;
|
||||
pll_pfd_sel >>= CCM_CCSR_PLL1_PFD_CLK_SEL_SHIFT;
|
||||
|
||||
ccm_core_clk = ccm_get_pll_pfd(pll_pfd_sel, ANADIG_PLL1_PFD,
|
||||
pll1_main_clk);
|
||||
break;
|
||||
case CCM_CCSR_SYS_CLK_SEL_PLL3:
|
||||
ccm_core_clk = pll3_main_clk;
|
||||
break;
|
||||
}
|
||||
|
||||
ccm_core_clk /= arm_clk_div;
|
||||
ccm_platform_bus_clk = ccm_core_clk / bus_clk_div;
|
||||
ccm_ipg_bus_clk = ccm_platform_bus_clk / ipg_clk_div;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user