mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-18 10:34:19 +00:00

The uSDHC module clock must be enabled to use the SD/eMMC storage from where the BL2 is expected to load images for the next boot stages. Change-Id: Ib1cc7d5dda7a4283a29716f5b3d776048bd5b7ba Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
281 lines
4.4 KiB
C
281 lines
4.4 KiB
C
/*
|
|
* Copyright 2024-2025 NXP
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
#include <drivers/clk.h>
|
|
#include <platform_def.h>
|
|
#include <s32cc-clk-drv.h>
|
|
#include <s32cc-clk-ids.h>
|
|
#include <s32cc-clk-utils.h>
|
|
|
|
#define S32CC_FXOSC_FREQ (40U * MHZ)
|
|
#define S32CC_ARM_PLL_VCO_FREQ (2U * GHZ)
|
|
#define S32CC_ARM_PLL_PHI0_FREQ (1U * GHZ)
|
|
#define S32CC_A53_FREQ (1U * GHZ)
|
|
#define S32CC_XBAR_2X_FREQ (800U * MHZ)
|
|
#define S32CC_PERIPH_PLL_VCO_FREQ (2U * GHZ)
|
|
#define S32CC_PERIPH_PLL_PHI3_FREQ UART_CLOCK_HZ
|
|
#define S32CC_DDR_PLL_VCO_FREQ (1600U * MHZ)
|
|
#define S32CC_DDR_PLL_PHI0_FREQ (800U * MHZ)
|
|
#define S32CC_PERIPH_DFS_PHI3_FREQ (800U * MHZ)
|
|
#define S32CC_USDHC_FREQ (400U * MHZ)
|
|
|
|
static int setup_fxosc(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int setup_arm_pll(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = clk_set_parent(S32CC_CLK_ARM_PLL_MUX, S32CC_CLK_FXOSC);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_set_rate(S32CC_CLK_ARM_PLL_VCO, S32CC_ARM_PLL_VCO_FREQ, NULL);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_set_rate(S32CC_CLK_ARM_PLL_PHI0, S32CC_ARM_PLL_PHI0_FREQ, NULL);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int setup_periph_pll(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = clk_set_parent(S32CC_CLK_PERIPH_PLL_MUX, S32CC_CLK_FXOSC);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_VCO, S32CC_PERIPH_PLL_VCO_FREQ, NULL);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_PHI3, S32CC_PERIPH_PLL_PHI3_FREQ, NULL);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int enable_a53_clk(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = clk_set_parent(S32CC_CLK_MC_CGM1_MUX0, S32CC_CLK_ARM_PLL_PHI0);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_set_rate(S32CC_CLK_A53_CORE, S32CC_A53_FREQ, NULL);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_enable(S32CC_CLK_A53_CORE);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int enable_xbar_clk(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX0, S32CC_CLK_ARM_PLL_DFS1);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_set_rate(S32CC_CLK_XBAR_2X, S32CC_XBAR_2X_FREQ, NULL);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_enable(S32CC_CLK_ARM_PLL_DFS1);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_enable(S32CC_CLK_XBAR_2X);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int enable_uart_clk(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX8, S32CC_CLK_PERIPH_PLL_PHI3);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_enable(S32CC_CLK_LINFLEX_BAUD);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int setup_ddr_pll(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = clk_set_parent(S32CC_CLK_DDR_PLL_MUX, S32CC_CLK_FXOSC);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_set_rate(S32CC_CLK_DDR_PLL_VCO, S32CC_DDR_PLL_VCO_FREQ, NULL);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_set_rate(S32CC_CLK_DDR_PLL_PHI0, S32CC_DDR_PLL_PHI0_FREQ, NULL);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int enable_ddr_clk(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = clk_set_parent(S32CC_CLK_MC_CGM5_MUX0, S32CC_CLK_DDR_PLL_PHI0);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_enable(S32CC_CLK_DDR);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int enable_usdhc_clk(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX14,
|
|
S32CC_CLK_PERIPH_PLL_DFS3);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_DFS3,
|
|
S32CC_PERIPH_DFS_PHI3_FREQ, NULL);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_set_rate(S32CC_CLK_USDHC, S32CC_USDHC_FREQ, NULL);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = clk_enable(S32CC_CLK_USDHC);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int s32cc_init_core_clocks(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = s32cc_clk_register_drv(false);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = setup_fxosc();
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = setup_arm_pll();
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = enable_a53_clk();
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = enable_xbar_clk();
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int s32cc_init_early_clks(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = s32cc_clk_register_drv(true);
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = setup_periph_pll();
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = enable_uart_clk();
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = setup_ddr_pll();
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = enable_ddr_clk();
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
ret = enable_usdhc_clk();
|
|
if (ret != 0) {
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|