feat(nxp-clk): add PERIPH PLL enablement

Peripheral PLL is one of the platform's PLLs, providing a clock for
peripherals such as UART, QSPI, uSDHC, SPI and CAN. Its source can be
either the FIRC or FXOSC oscillators. It has eight outputs (PHIs) and
their frequencies can be controlled programmatically using output
dividers. An additional output clocks the PERIPH DFS using the VCO
frequency of the PERIPH PLL.

Change-Id: I637294b2da94f35e95dc1750dad36c129a276bb9
Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
This commit is contained in:
Ghennadi Procopciuc 2024-08-06 11:48:11 +03:00
parent 553b70c3ef
commit 8653352ad7
6 changed files with 79 additions and 7 deletions

View file

@ -9,6 +9,7 @@
#define FXOSC_BASE_ADDR (0x40050000UL)
#define ARMPLL_BASE_ADDR (0x40038000UL)
#define PERIPHPLL_BASE_ADDR (0x4003C000UL)
#define ARM_DFS_BASE_ADDR (0x40054000UL)
#define CGM0_BASE_ADDR (0x40030000UL)
#define CGM1_BASE_ADDR (0x40034000UL)

View file

@ -22,6 +22,7 @@
struct s32cc_clk_drv {
uintptr_t fxosc_base;
uintptr_t armpll_base;
uintptr_t periphpll_base;
uintptr_t armdfs_base;
uintptr_t cgm0_base;
uintptr_t cgm1_base;
@ -42,6 +43,7 @@ static struct s32cc_clk_drv *get_drv(void)
static struct s32cc_clk_drv driver = {
.fxosc_base = FXOSC_BASE_ADDR,
.armpll_base = ARMPLL_BASE_ADDR,
.periphpll_base = PERIPHPLL_BASE_ADDR,
.armdfs_base = ARM_DFS_BASE_ADDR,
.cgm0_base = CGM0_BASE_ADDR,
.cgm1_base = CGM1_BASE_ADDR,
@ -91,6 +93,9 @@ static int get_base_addr(enum s32cc_clk_source id, const struct s32cc_clk_drv *d
case S32CC_ARM_PLL:
*base = drv->armpll_base;
break;
case S32CC_PERIPH_PLL:
*base = drv->periphpll_base;
break;
case S32CC_ARM_DFS:
*base = drv->armdfs_base;
break;

View file

@ -107,7 +107,24 @@ static struct s32cc_clk a53_core_div10_clk =
S32CC_FREQ_MODULE_CLK(a53_core_div10, S32CC_A53_MIN_FREQ / 10,
S32CC_A53_MAX_FREQ / 10);
static struct s32cc_clk *s32cc_hw_clk_list[13] = {
/* PERIPH PLL */
static struct s32cc_clkmux periph_pll_mux =
S32CC_CLKMUX_INIT(S32CC_PERIPH_PLL, 0, 2,
S32CC_CLK_FIRC,
S32CC_CLK_FXOSC, 0, 0, 0);
static struct s32cc_clk periph_pll_mux_clk =
S32CC_MODULE_CLK(periph_pll_mux);
static struct s32cc_pll periphpll =
S32CC_PLL_INIT(periph_pll_mux_clk, S32CC_PERIPH_PLL, 2);
static struct s32cc_clk periph_pll_vco_clk =
S32CC_FREQ_MODULE_CLK(periphpll, 1300 * MHZ, 2 * GHZ);
static struct s32cc_pll_out_div periph_pll_phi3_div =
S32CC_PLL_OUT_DIV_INIT(periphpll, 3);
static struct s32cc_clk periph_pll_phi3_clk =
S32CC_FREQ_MODULE_CLK(periph_pll_phi3_div, 0, 133333333);
static struct s32cc_clk *s32cc_hw_clk_list[22] = {
/* Oscillators */
[S32CC_CLK_ID(S32CC_CLK_FIRC)] = &firc_clk,
[S32CC_CLK_ID(S32CC_CLK_SIRC)] = &sirc_clk,
@ -116,6 +133,8 @@ static struct s32cc_clk *s32cc_hw_clk_list[13] = {
[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_PHI0)] = &arm_pll_phi0_clk,
/* ARM DFS */
[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_DFS1)] = &arm_dfs1_clk,
/* PERIPH PLL */
[S32CC_CLK_ID(S32CC_CLK_PERIPH_PLL_PHI3)] = &periph_pll_phi3_clk,
};
static struct s32cc_clk_array s32cc_hw_clocks = {
@ -124,10 +143,13 @@ static struct s32cc_clk_array s32cc_hw_clocks = {
.n_clks = ARRAY_SIZE(s32cc_hw_clk_list),
};
static struct s32cc_clk *s32cc_arch_clk_list[13] = {
static struct s32cc_clk *s32cc_arch_clk_list[15] = {
/* ARM PLL */
[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_MUX)] = &arm_pll_mux_clk,
[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_VCO)] = &arm_pll_vco_clk,
/* PERIPH PLL */
[S32CC_CLK_ID(S32CC_CLK_PERIPH_PLL_MUX)] = &periph_pll_mux_clk,
[S32CC_CLK_ID(S32CC_CLK_PERIPH_PLL_VCO)] = &periph_pll_vco_clk,
/* MC_CGM0 */
[S32CC_CLK_ID(S32CC_CLK_MC_CGM0_MUX0)] = &cgm0_mux0_clk,
/* XBAR */

View file

@ -8,11 +8,13 @@
#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_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 (125U * MHZ)
static int enable_fxosc_clk(void)
{
@ -63,6 +65,38 @@ static int enable_arm_pll(void)
return ret;
}
static int enable_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;
}
ret = clk_enable(S32CC_CLK_PERIPH_PLL_VCO);
if (ret != 0) {
return ret;
}
ret = clk_enable(S32CC_CLK_PERIPH_PLL_PHI3);
if (ret != 0) {
return ret;
}
return ret;
}
static int enable_a53_clk(void)
{
int ret;
@ -128,6 +162,11 @@ int s32cc_init_early_clks(void)
return ret;
}
ret = enable_periph_pll();
if (ret != 0) {
return ret;
}
ret = enable_a53_clk();
if (ret != 0) {
return ret;

View file

@ -87,4 +87,8 @@
#define S32CC_CLK_XBAR_DIV4 S32CC_ARCH_CLK(11)
#define S32CC_CLK_XBAR_DIV6 S32CC_ARCH_CLK(12)
/* Periph PLL */
#define S32CC_CLK_PERIPH_PLL_MUX S32CC_ARCH_CLK(13)
#define S32CC_CLK_PERIPH_PLL_VCO S32CC_ARCH_CLK(14)
#endif /* S32CC_CLK_IDS_H */

View file

@ -30,6 +30,7 @@ enum s32cc_clk_source {
S32CC_SIRC,
S32CC_ARM_PLL,
S32CC_ARM_DFS,
S32CC_PERIPH_PLL,
S32CC_CGM0,
S32CC_CGM1,
};