diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 564bd87989df867ec7afadc54f0565b59da63ab9..577f965c633c242e1ec403d45c45c026a09f2146 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -1735,6 +1735,8 @@ int stm32mp1_clk_init(void) bool pll4_bootrom = false; const fdt32_t *pkcs_cell; void *fdt; + int stgen_p = stm32mp1_clk_get_parent((int)STGEN_K); + int usbphy_p = stm32mp1_clk_get_parent((int)USBPHY_K); if (fdt_get_address(&fdt) == 0) { return false; @@ -1834,6 +1836,12 @@ int stm32mp1_clk_init(void) pllcfg[_PLL4], plloff[_PLL4]); } + /* Don't initialize PLL4, when used by BOOTROM */ + if ((get_boot_device() == BOOT_DEVICE_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) || @@ -1985,6 +1993,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]); @@ -2005,6 +2018,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 */