/* ---------------------------------------------------------------------------- | |
* SAM Software Package License | |
* ---------------------------------------------------------------------------- | |
* Copyright (c) 2015, Atmel Corporation | |
* | |
* All rights reserved. | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions are met: | |
* | |
* - Redistributions of source code must retain the above copyright notice, | |
* this list of conditions and the disclaimer below. | |
* | |
* Atmel's name may not be used to endorse or promote products derived from | |
* this software without specific prior written permission. | |
* | |
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR | |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | |
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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. | |
* ---------------------------------------------------------------------------- | |
*/ | |
#ifndef _PMC_H_ | |
#define _PMC_H_ | |
/*---------------------------------------------------------------------------- | |
* Headers | |
*----------------------------------------------------------------------------*/ | |
#include "board.h" | |
#include <stdint.h> | |
/*---------------------------------------------------------------------------- | |
* Types | |
*----------------------------------------------------------------------------*/ | |
struct pck_mck_cfg { | |
/** PLL A, SLCK, MAIN, UPLL */ | |
uint32_t pck_input; | |
/** RC12M (false) or EXT12M (true) */ | |
bool ext12m; | |
/** RC32K (false) or EXT32K (true) */ | |
bool ext32k; | |
/** PLLA MUL value in PMC PLL register */ | |
uint32_t plla_mul; | |
/** PLLA DIV value in PMC PLL register */ | |
uint32_t plla_div; | |
/** PLLA DIV value by 2 */ | |
bool plla_div2; | |
/** Master/Processor Clock Prescaler */ | |
uint32_t pck_pres; | |
/** Master Clock Division after Prescaler divider */ | |
uint32_t mck_div; | |
/** true if the AHB 32-bit Matrix frequency is equal to the AHB 64-bit Matrix frequency divided by 2 */ | |
bool h32mxdiv2; | |
}; | |
/** | |
* \brief System clock identifiers, used for pmc_{enable,disable}_system_clock | |
*/ | |
enum _pmc_system_clock { | |
PMC_SYSTEM_CLOCK_PCK, | |
PMC_SYSTEM_CLOCK_DDR, | |
PMC_SYSTEM_CLOCK_LCD, | |
PMC_SYSTEM_CLOCK_SMD, | |
PMC_SYSTEM_CLOCK_UHP, | |
PMC_SYSTEM_CLOCK_UDP, | |
PMC_SYSTEM_CLOCK_PCK0, | |
PMC_SYSTEM_CLOCK_PCK1, | |
PMC_SYSTEM_CLOCK_PCK2, | |
PMC_SYSTEM_CLOCK_ISC, | |
}; | |
#ifdef CONFIG_HAVE_PMC_AUDIO_CLOCK | |
/** | |
* \brief Configuration data for Audio clock | |
* | |
* AUDIOPLLCK = BOARD_EXT_OSC * (nd + 1 + (fracr / 2^22)) / (qdpmc + 1) | |
* AUDIOPINCLK = BOARD_EXT_OSC * (nc + 1 + (fracr / 2^22)) / (div * qdaudio) | |
*/ | |
struct _pmc_audio_cfg { | |
uint32_t nd; | |
uint32_t fracr; | |
uint32_t qdpmc; | |
uint32_t div; | |
uint32_t qdaudio; | |
}; | |
#endif /* CONFIG_HAVE_PMC_AUDIO_CLOCK */ | |
/*---------------------------------------------------------------------------- | |
* Exported functions | |
*----------------------------------------------------------------------------*/ | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
/** | |
* \brief Configure PCK and MCK with custom setting | |
*/ | |
extern void pmc_set_custom_pck_mck(struct pck_mck_cfg *cfg); | |
/** | |
* \brief Get the configured frequency of the master clock | |
* \return master clock frequency in Hz | |
*/ | |
extern uint32_t pmc_get_master_clock(void); | |
/** | |
* \brief Get the configured frequency of the slow clock | |
* \return slow clock frequency in Hz | |
*/ | |
extern uint32_t pmc_get_slow_clock(void); | |
/** | |
* \brief Get the configured frequency of the main clock | |
* \return main clock frequency in Hz | |
*/ | |
extern uint32_t pmc_get_main_clock(void); | |
/** | |
* \brief Get the configured frequency of the PLLA clock | |
* \return PLLA clock frequency in Hz | |
*/ | |
extern uint32_t pmc_get_plla_clock(void); | |
/** | |
* \brief Get the configured frequency of the processor clock | |
* \return processor clock frequency in Hz | |
*/ | |
extern uint32_t pmc_get_processor_clock(void); | |
/** | |
* \brief Select external 32K crystal. | |
*/ | |
extern void pmc_select_external_crystal(void); | |
/** | |
* \brief Select internal 32K crystal. | |
*/ | |
extern void pmc_select_internal_crystal(void); | |
/** | |
* \brief Select external 12M OSC. | |
*/ | |
extern void pmc_select_external_osc(void); | |
/** | |
* \brief Disable external 12M OSC. | |
*/ | |
extern void pmc_disable_external_osc(void); | |
/** | |
* \brief Select internal 12M OSC. | |
*/ | |
extern void pmc_select_internal_osc(void); | |
/** | |
* \brief Disable internal 12M OSC. | |
*/ | |
extern void pmc_disable_internal_osc(void); | |
/** | |
* \brief Switch PMC from MCK to PLL clock. | |
*/ | |
extern void pmc_switch_mck_to_pll(void); | |
/** | |
* \brief Switch PMC from MCK to UPLL clock. | |
*/ | |
extern void pmc_switch_mck_to_upll(void); | |
/** | |
* \brief Switch PMC from MCK to main clock. | |
*/ | |
extern void pmc_switch_mck_to_main(void); | |
/** | |
* \brief Switch PMC from MCK to slow clock. | |
*/ | |
extern void pmc_switch_mck_to_slck(void); | |
/** | |
* \brief Configure PLL Register. | |
* \param pll pll value. | |
* \param cpcr cpcr value. | |
*/ | |
extern void pmc_set_plla(uint32_t pll, uint32_t cpcr); | |
/** | |
* \brief Configure MCK Prescaler. | |
* \param prescaler prescaler value. | |
*/ | |
extern void pmc_set_mck_prescaler(uint32_t prescaler); | |
/** | |
* \brief Configure MCK Divider. | |
* \param divider divider value. | |
*/ | |
extern void pmc_set_mck_divider(uint32_t divider); | |
/** | |
* \brief Configure MCK H32MXDIV. | |
* \param divider divider value. | |
*/ | |
extern void pmc_set_mck_h32mxdiv(uint32_t divider); | |
/** | |
* \brief Configure MCK PLLA divider. | |
* \param divider PLL divider value. | |
*/ | |
extern void pmc_set_mck_plla_div(uint32_t divider); | |
/** | |
* \brief Disable PLLA Register. | |
*/ | |
extern void pmc_disable_plla(void); | |
/** | |
* \brief Enables a system clock | |
* \param clock system clock to enable | |
*/ | |
extern void pmc_enable_system_clock(enum _pmc_system_clock clock); | |
/** | |
* \brief Disables a system clock | |
* \param clock system clock to disable | |
*/ | |
extern void pmc_disable_system_clock(enum _pmc_system_clock clock); | |
#ifdef CONFIG_HAVE_PMC_FAST_STARTUP | |
/** | |
* \brief Set up fast startup mode | |
* \param source and low power mode | |
*/ | |
extern void pmc_set_fast_startup_mode(uint32_t startup_mode); | |
/** | |
* \brief Set up fast startup polarity | |
* \param level | |
*/ | |
extern void pmc_set_fast_startup_polarity(uint32_t high_level, | |
uint32_t low_level); | |
#endif /* CONFIG_HAVE_PMC_FAST_STARTUP */ | |
/** | |
* \brief Enables the clock of a peripheral. The peripheral ID is used | |
* to identify which peripheral is targeted. | |
* | |
* \param id Peripheral ID (ID_xxx). | |
*/ | |
extern void pmc_enable_peripheral(uint32_t id); | |
/** | |
* \brief Disables the clock of a peripheral. The peripheral ID is used | |
* to identify which peripheral is targeted. | |
* | |
* \param id Peripheral ID (ID_xxx). | |
*/ | |
extern void pmc_disable_peripheral(uint32_t id); | |
/** | |
* \brief Get Peripheral Status for the given peripheral ID. | |
* | |
* \param id Peripheral ID (ID_xxx). | |
*/ | |
extern uint32_t pmc_is_peripheral_enabled(uint32_t id); | |
/** | |
* \brief Get current frequency clock for the given peripheral ID. | |
* | |
* \param id Peripheral ID (ID_xxx). | |
*/ | |
extern uint32_t pmc_get_peripheral_clock(uint32_t id); | |
/** | |
* \brief Disable clocks for all peripherals | |
*/ | |
extern void pmc_disable_all_peripherals(void); | |
/** | |
* \brief Configure programmable clock 0 (PCK0) with the given master clock | |
* source and clock prescaler | |
* \param clock_source clock source selection (one of the PMC_PCK_CSS_xxx_CLK | |
* constants) | |
* \param prescaler prescaler | |
*/ | |
extern void pmc_configure_pck0(uint32_t clock_source, uint32_t prescaler); | |
/** | |
* \brief Enable programmable clock 0 (PCK0) | |
*/ | |
extern void pmc_enable_pck0(void); | |
/** | |
* \brief Disable programmable clock 0 (PCK0) | |
*/ | |
extern void pmc_disable_pck0(void); | |
/** | |
* \brief Get the frequency of the programmable clock 0 (PCK0) | |
* \return PCK0 frequency in Hz | |
*/ | |
extern uint32_t pmc_get_pck0_clock(void); | |
/** | |
* \brief Configure programmable clock 1 (PCK1) with the given master clock | |
* source and clock prescaler | |
* \param clock_source Clock source selection (one of the PMC_PCK_CSS_xxx_CLK | |
* constants) | |
* \param prescaler Prescaler value | |
*/ | |
extern void pmc_configure_pck1(uint32_t clock_source, uint32_t prescaler); | |
/** | |
* \brief Enable programmable clock 1 (PCK1) | |
*/ | |
extern void pmc_enable_pck1(void); | |
/** | |
* \brief Disable programmable clock 1 (PCK1) | |
*/ | |
extern void pmc_disable_pck1(void); | |
/** | |
* \brief Get the frequency of the programmable clock 1 (PCK1) | |
* \return PCK1 Frequency in Hz | |
*/ | |
extern uint32_t pmc_get_pck1_clock(void); | |
/** | |
* \brief Configure programmable clock 2 (PCK2) with the given master clock | |
* source and clock prescaler | |
* \param clock_source Clock source selection (one of the PMC_PCK_CSS_xxx_CLK | |
* constants) | |
* \param prescaler Prescaler value | |
*/ | |
extern void pmc_configure_pck2(uint32_t clock_source, uint32_t prescaler); | |
/** | |
* \brief Enable programmable clock 2 (PCK2) | |
*/ | |
extern void pmc_enable_pck2(void); | |
/** | |
* \brief Disable programmable clock 2 (PCK2) | |
*/ | |
extern void pmc_disable_pck2(void); | |
/** | |
* \brief Get the frequency of the programmable clock 2 (PCK2) | |
* \return PCK2 Frequency in Hz | |
*/ | |
extern uint32_t pmc_get_pck2_clock(void); | |
/** | |
* \brief Enable the UPLL clock | |
*/ | |
extern void pmc_enable_upll_clock(void); | |
/** | |
* \brief Disable the UPLL clock | |
*/ | |
extern void pmc_disable_upll_clock(void); | |
/** | |
* \brief Get the frequency of the UPLL clock | |
* \return UPLL clock frequency in Hz | |
*/ | |
extern uint32_t pmc_get_upll_clock(void); | |
/** | |
* \brief Enable the UPLL clock bias | |
*/ | |
extern void pmc_enable_upll_bias(void); | |
/** | |
* \brief Disable the UPLL clock bias | |
*/ | |
extern void pmc_disable_upll_bias(void); | |
#ifdef CONFIG_HAVE_PMC_GENERATED_CLOCKS | |
/** | |
* \brief Configure the generated clock (GCK) for the given peripheral with the | |
* given master clock source and clock prescaler | |
* \param id Peripheral ID (ID_xxx) | |
* \param clock_source Clock source selection (one of the | |
* PMC_PCR_GCKCSS_xxx_CLK constants) | |
* \param div Generated Clock Division Ratio (selected clock is divided by | |
* div + 1) | |
*/ | |
extern void pmc_configure_gck(uint32_t id, uint32_t clock_source, uint32_t div); | |
/** | |
* \brief Enable generated clock for the given peripheral | |
* \param id Peripheral ID (ID_xxx) | |
*/ | |
extern void pmc_enable_gck(uint32_t id); | |
/** | |
* \brief Disable generated clock for the given peripheral | |
* \param id Peripheral ID (ID_xxx) | |
*/ | |
extern void pmc_disable_gck(uint32_t id); | |
/** | |
* \brief Get the frequency of the generated clock (GCK) for the given | |
* peripheral | |
* \param id Peripheral ID (ID_xxx) | |
* \return GCK Frequency in Hz | |
*/ | |
extern uint32_t pmc_get_gck_clock(uint32_t id); | |
#endif /* CONFIG_HAVE_PMC_GENERATED_CLOCKS */ | |
#ifdef CONFIG_HAVE_PMC_AUDIO_CLOCK | |
/** | |
* \brief Configure the audio clock | |
*/ | |
extern void pmc_configure_audio(struct _pmc_audio_cfg *cfg); | |
/** | |
* \brief Enable audio clocks | |
* \param pmc_clock if true AUDIOPLLCK is sent to the PMC | |
* \param pad_clock if true the external audio pin is driven by AUDIOPINCLK, if | |
* false the audio pin is driven low | |
*/ | |
extern void pmc_enable_audio(bool pmc_clock, bool pad_clock); | |
/** | |
* \brief Disable audio clocks | |
*/ | |
extern void pmc_disable_audio(void); | |
/** | |
* \brief Get the frequency of the audio PMC clock | |
* \return Audio PMC Frequency in Hz | |
*/ | |
extern uint32_t pmc_get_audio_pmc_clock(void); | |
/** | |
* \brief Get the frequency of the audio pad clock | |
* \return Audio pad Frequency in Hz | |
*/ | |
extern uint32_t pmc_get_audio_pad_clock(void); | |
#endif /* CONFIG_HAVE_PMC_AUDIO_CLOCK */ | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif /* #ifndef _PMC_H_ */ |