diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clk/Kconfig | 10 | ||||
-rw-r--r-- | drivers/clk/clk-stm32mp1.c | 101 |
2 files changed, 110 insertions, 1 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index e80918be8e9c..e367a033e121 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -335,6 +335,16 @@ config COMMON_CLK_STM32MP157 help Support for stm32mp157 SoC family clocks +config COMMON_CLK_STM32MP157_SCMI + bool "stm32mp157 Clock driver with Trusted Firmware" + depends on COMMON_CLK_STM32MP157 + select COMMON_CLK_SCMI + select ARM_SCMI_PROTOCOL + default y + help + Support for stm32mp157 SoC family clocks with Trusted Firmware using + SCMI protocol. + config COMMON_CLK_STM32F def_bool COMMON_CLK && (MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746) help diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index 6d3a36f81b2d..6adc625e79cb 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c @@ -2056,11 +2056,61 @@ static const struct clock_config stm32mp1_clock_cfg[] = { _DIV(RCC_DBGCFGR, 0, 3, 0, ck_trace_div_table)), }; +static const u32 stm32mp1_clock_secured[] = { + CK_HSE, + CK_HSI, + CK_CSI, + CK_LSI, + CK_LSE, + PLL1, + PLL2, + PLL1_P, + PLL2_P, + PLL2_Q, + PLL2_R, + CK_MPU, + CK_AXI, + SPI6, + I2C4, + I2C6, + USART1, + RTCAPB, + TZC1, + TZC2, + TZPC, + IWDG1, + BSEC, + STGEN, + GPIOZ, + CRYP1, + HASH1, + RNG1, + BKPSRAM, + RNG1_K, + STGEN_K, + SPI6_K, + I2C4_K, + I2C6_K, + USART1_K, + RTC, +}; + +static bool stm32_check_security(const struct clock_config *cfg) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(stm32mp1_clock_secured); i++) + if (cfg->id == stm32mp1_clock_secured[i]) + return true; + return false; +} + struct stm32_rcc_match_data { const struct clock_config *cfg; unsigned int num; unsigned int maxbinding; u32 clear_offset; + bool (*check_security)(const struct clock_config *cfg); }; static struct stm32_rcc_match_data stm32mp1_data = { @@ -2070,11 +2120,23 @@ static struct stm32_rcc_match_data stm32mp1_data = { .clear_offset = RCC_CLR, }; +static struct stm32_rcc_match_data stm32mp1_data_secure = { + .cfg = stm32mp1_clock_cfg, + .num = ARRAY_SIZE(stm32mp1_clock_cfg), + .maxbinding = STM32MP1_LAST_CLK, + .clear_offset = RCC_CLR, + .check_security = &stm32_check_security +}; + static const struct of_device_id stm32mp1_match_data[] = { { .compatible = "st,stm32mp1-rcc", .data = &stm32mp1_data, }, + { + .compatible = "st,stm32mp1-rcc-secure", + .data = &stm32mp1_data_secure, + }, { } }; MODULE_DEVICE_TABLE(of, stm32mp1_match_data); @@ -2234,6 +2296,9 @@ static int stm32_rcc_clock_init(struct device *dev, void __iomem *base, hws[n] = ERR_PTR(-ENOENT); for (n = 0; n < data->num; n++) { + if (data->check_security && data->check_security(&data->cfg[n])) + continue; + err = stm32_register_hw_clk(dev, clk_data, base, &rlock, &data->cfg[n]); if (err) { @@ -2301,11 +2366,45 @@ out: return ret; } +static int get_clock_deps(struct device *dev) +{ + static const char * const clock_deps_name[] = { + "hsi", "hse", "csi", "lsi", "lse", + }; + size_t deps_size = sizeof(struct clk *) * ARRAY_SIZE(clock_deps_name); + struct clk **clk_deps; + int i; + + clk_deps = devm_kzalloc(dev, deps_size, GFP_KERNEL); + if (!clk_deps) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(clock_deps_name); i++) { + struct clk *clk = of_clk_get_by_name(dev_of_node(dev), + clock_deps_name[i]); + + if (IS_ERR(clk)) { + if (PTR_ERR(clk) != -EINVAL && PTR_ERR(clk) != -ENOENT) + return PTR_ERR(clk); + } else { + /* Device gets a reference count on the clock */ + clk_deps[i] = devm_clk_get(dev, __clk_get_name(clk)); + clk_put(clk); + } + } + + return 0; +} + static int stm32mp1_rcc_clocks_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + int ret = get_clock_deps(dev); + + if (!ret) + ret = stm32mp1_rcc_init(dev); - return stm32mp1_rcc_init(dev); + return ret; } static int stm32mp1_rcc_clocks_remove(struct platform_device *pdev) |