feat(stm32mp1): preserve the PLL4 settings for USB boot

The PLL4 can be used by ROM code as the source clock of USB PHYC and,
in this case, the PLL4 configuration must be preserved
with pll4_preserve to avoid USB disturbance.

This patch also adds an error when the clock tree PLL4 configuration
is not the PLL4 configuration used by ROM code; this error allows to
detect a invalid clock tree.

This commit corrects the coverity issue 343023.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Change-Id: I4bae9312a2db8dd342a38e649513d689b13976bb
This commit is contained in:
Patrick Delaunay 2020-09-04 17:39:12 +02:00 committed by Patrick Delaunay
parent 1777ac11a5
commit bf1af154db
1 changed files with 33 additions and 0 deletions

View File

@ -1744,6 +1744,8 @@ int stm32mp1_clk_init(void)
bool pll4_bootrom = false;
const fdt32_t *pkcs_cell;
void *fdt;
int stgen_p = stm32mp1_clk_get_parent(STGEN_K);
int usbphy_p = stm32mp1_clk_get_parent(USBPHY_K);
if (fdt_get_address(&fdt) == 0) {
return -FDT_ERR_NOTFOUND;
@ -1843,6 +1845,13 @@ int stm32mp1_clk_init(void)
pllcfg[_PLL4],
plloff[_PLL4]);
}
/* Don't initialize PLL4, when used by BOOTROM */
if ((stm32mp_get_boot_itf_selected() ==
BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB) &&
((stgen_p == (int)_PLL4_R) || (usbphy_p == (int)_PLL4_R))) {
pll4_bootrom = true;
pll4_preserve = true;
}
for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
if (((i == _PLL3) && pll3_preserve) ||
@ -1994,6 +2003,11 @@ int stm32mp1_clk_init(void)
if (pkcs_cell != NULL) {
bool ckper_disabled = false;
uint32_t j;
uint32_t usbreg_bootrom = 0U;
if (pll4_bootrom) {
usbreg_bootrom = mmio_read_32(rcc_base + RCC_USBCKSELR);
}
for (j = 0; j < ((uint32_t)len / sizeof(uint32_t)); j++) {
uint32_t pkcs = fdt32_to_cpu(pkcs_cell[j]);
@ -2014,6 +2028,25 @@ int stm32mp1_clk_init(void)
if (ckper_disabled) {
stm32mp1_pkcs_config(CLK_CKPER_DISABLED);
}
if (pll4_bootrom) {
uint32_t usbreg_value, usbreg_mask;
const struct stm32mp1_clk_sel *sel;
sel = clk_sel_ref(_USBPHY_SEL);
usbreg_mask = (uint32_t)sel->msk << sel->src;
sel = clk_sel_ref(_USBO_SEL);
usbreg_mask |= (uint32_t)sel->msk << sel->src;
usbreg_value = mmio_read_32(rcc_base + RCC_USBCKSELR) &
usbreg_mask;
usbreg_bootrom &= usbreg_mask;
if (usbreg_bootrom != usbreg_value) {
VERBOSE("forbidden new USB clk path\n");
VERBOSE("vs bootrom on USB boot\n");
return -FDT_ERR_BADVALUE;
}
}
}
/* Switch OFF HSI if not found in device-tree */