mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-19 02:54:24 +00:00
feat(nxp-clk): add ARM PLL ODIV enablement
Enable the PLL dividers using their memory-mapped interface. Otherwise, the clock will not be propagated to downstream clock modules. Change-Id: I39115cb2cb754cee87d7b6b4aa7502c3f1ef37ce Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
This commit is contained in:
parent
b5101c452e
commit
84e82085a1
2 changed files with 87 additions and 3 deletions
|
@ -233,6 +233,11 @@ static void disable_odiv(uintptr_t pll_addr, uint32_t div_index)
|
|||
mmio_clrbits_32(PLLDIG_PLLODIV(pll_addr, div_index), PLLDIG_PLLODIV_DE);
|
||||
}
|
||||
|
||||
static void enable_odiv(uintptr_t pll_addr, uint32_t div_index)
|
||||
{
|
||||
mmio_setbits_32(PLLDIG_PLLODIV(pll_addr, div_index), PLLDIG_PLLODIV_DE);
|
||||
}
|
||||
|
||||
static void disable_odivs(uintptr_t pll_addr, uint32_t ndivs)
|
||||
{
|
||||
uint32_t i;
|
||||
|
@ -341,6 +346,80 @@ static int enable_pll(const struct s32cc_clk_obj *module,
|
|||
return program_pll(pll, pll_addr, drv, sclk_id, sclk_freq);
|
||||
}
|
||||
|
||||
static inline struct s32cc_pll *get_div_pll(const struct s32cc_pll_out_div *pdiv)
|
||||
{
|
||||
const struct s32cc_clk_obj *parent;
|
||||
|
||||
parent = pdiv->parent;
|
||||
if (parent == NULL) {
|
||||
ERROR("Failed to identify PLL divider's parent\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (parent->type != s32cc_pll_t) {
|
||||
ERROR("The parent of the divider is not a PLL instance\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return s32cc_obj2pll(parent);
|
||||
}
|
||||
|
||||
static void config_pll_out_div(uintptr_t pll_addr, uint32_t div_index, uint32_t dc)
|
||||
{
|
||||
uint32_t pllodiv;
|
||||
uint32_t pdiv;
|
||||
|
||||
pllodiv = mmio_read_32(PLLDIG_PLLODIV(pll_addr, div_index));
|
||||
pdiv = PLLDIG_PLLODIV_DIV(pllodiv);
|
||||
|
||||
if (((pdiv + 1U) == dc) && ((pllodiv & PLLDIG_PLLODIV_DE) != 0U)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((pllodiv & PLLDIG_PLLODIV_DE) != 0U) {
|
||||
disable_odiv(pll_addr, div_index);
|
||||
}
|
||||
|
||||
pllodiv = PLLDIG_PLLODIV_DIV_SET(dc - 1U);
|
||||
mmio_write_32(PLLDIG_PLLODIV(pll_addr, div_index), pllodiv);
|
||||
|
||||
enable_odiv(pll_addr, div_index);
|
||||
}
|
||||
|
||||
static int enable_pll_div(const struct s32cc_clk_obj *module,
|
||||
const struct s32cc_clk_drv *drv,
|
||||
unsigned int *depth)
|
||||
{
|
||||
const struct s32cc_pll_out_div *pdiv = s32cc_obj2plldiv(module);
|
||||
uintptr_t pll_addr = 0x0ULL;
|
||||
const struct s32cc_pll *pll;
|
||||
uint32_t dc;
|
||||
int ret;
|
||||
|
||||
ret = update_stack_depth(depth);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
pll = get_div_pll(pdiv);
|
||||
if (pll == NULL) {
|
||||
ERROR("The parent of the PLL DIV is invalid\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = get_base_addr(pll->instance, drv, &pll_addr);
|
||||
if (ret != 0) {
|
||||
ERROR("Failed to detect PLL instance\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dc = (uint32_t)(pll->vco_freq / pdiv->freq);
|
||||
|
||||
config_pll_out_div(pll_addr, pdiv->index, dc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth)
|
||||
{
|
||||
const struct s32cc_clk_drv *drv = get_drv();
|
||||
|
@ -365,15 +444,15 @@ static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth
|
|||
case s32cc_pll_t:
|
||||
ret = enable_pll(module, drv, depth);
|
||||
break;
|
||||
case s32cc_pll_out_div_t:
|
||||
ret = enable_pll_div(module, drv, depth);
|
||||
break;
|
||||
case s32cc_clkmux_t:
|
||||
ret = -ENOTSUP;
|
||||
break;
|
||||
case s32cc_shared_clkmux_t:
|
||||
ret = -ENOTSUP;
|
||||
break;
|
||||
case s32cc_pll_out_div_t:
|
||||
ret = -ENOTSUP;
|
||||
break;
|
||||
case s32cc_fixed_div_t:
|
||||
ret = -ENOTSUP;
|
||||
break;
|
||||
|
|
|
@ -59,5 +59,10 @@ int s32cc_init_early_clks(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_enable(S32CC_CLK_ARM_PLL_PHI0);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue