Skip to content

Commit 21e7433

Browse files
Gabriel-Fernandzbebarino
authored andcommitted
clk: stm32mp1: new compatible for secure RCC support
Platform STM32MP1 can be used in configuration where some clock resources cannot be accessed by Linux kernel when executing in non-secure state of the CPU(s). In such configuration, the RCC clock driver must not register clocks it cannot access. They are expected to be registered from another clock driver such as the SCMI clock driver. This change uses specific compatible string "st,stm32mp1-rcc-secure" to specify RCC clock driver configuration where RCC is secure. Signed-off-by: Etienne Carriere <[email protected]> Signed-off-by: Gabriel Fernandez <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 94b7888 commit 21e7433

File tree

2 files changed

+110
-1
lines changed

2 files changed

+110
-1
lines changed

drivers/clk/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,16 @@ config COMMON_CLK_STM32MP157
335335
help
336336
Support for stm32mp157 SoC family clocks
337337

338+
config COMMON_CLK_STM32MP157_SCMI
339+
bool "stm32mp157 Clock driver with Trusted Firmware"
340+
depends on COMMON_CLK_STM32MP157
341+
select COMMON_CLK_SCMI
342+
select ARM_SCMI_PROTOCOL
343+
default y
344+
help
345+
Support for stm32mp157 SoC family clocks with Trusted Firmware using
346+
SCMI protocol.
347+
338348
config COMMON_CLK_STM32F
339349
def_bool COMMON_CLK && (MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746)
340350
help

drivers/clk/clk-stm32mp1.c

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2056,11 +2056,61 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
20562056
_DIV(RCC_DBGCFGR, 0, 3, 0, ck_trace_div_table)),
20572057
};
20582058

2059+
static const u32 stm32mp1_clock_secured[] = {
2060+
CK_HSE,
2061+
CK_HSI,
2062+
CK_CSI,
2063+
CK_LSI,
2064+
CK_LSE,
2065+
PLL1,
2066+
PLL2,
2067+
PLL1_P,
2068+
PLL2_P,
2069+
PLL2_Q,
2070+
PLL2_R,
2071+
CK_MPU,
2072+
CK_AXI,
2073+
SPI6,
2074+
I2C4,
2075+
I2C6,
2076+
USART1,
2077+
RTCAPB,
2078+
TZC1,
2079+
TZC2,
2080+
TZPC,
2081+
IWDG1,
2082+
BSEC,
2083+
STGEN,
2084+
GPIOZ,
2085+
CRYP1,
2086+
HASH1,
2087+
RNG1,
2088+
BKPSRAM,
2089+
RNG1_K,
2090+
STGEN_K,
2091+
SPI6_K,
2092+
I2C4_K,
2093+
I2C6_K,
2094+
USART1_K,
2095+
RTC,
2096+
};
2097+
2098+
static bool stm32_check_security(const struct clock_config *cfg)
2099+
{
2100+
int i;
2101+
2102+
for (i = 0; i < ARRAY_SIZE(stm32mp1_clock_secured); i++)
2103+
if (cfg->id == stm32mp1_clock_secured[i])
2104+
return true;
2105+
return false;
2106+
}
2107+
20592108
struct stm32_rcc_match_data {
20602109
const struct clock_config *cfg;
20612110
unsigned int num;
20622111
unsigned int maxbinding;
20632112
u32 clear_offset;
2113+
bool (*check_security)(const struct clock_config *cfg);
20642114
};
20652115

20662116
static struct stm32_rcc_match_data stm32mp1_data = {
@@ -2070,11 +2120,23 @@ static struct stm32_rcc_match_data stm32mp1_data = {
20702120
.clear_offset = RCC_CLR,
20712121
};
20722122

2123+
static struct stm32_rcc_match_data stm32mp1_data_secure = {
2124+
.cfg = stm32mp1_clock_cfg,
2125+
.num = ARRAY_SIZE(stm32mp1_clock_cfg),
2126+
.maxbinding = STM32MP1_LAST_CLK,
2127+
.clear_offset = RCC_CLR,
2128+
.check_security = &stm32_check_security
2129+
};
2130+
20732131
static const struct of_device_id stm32mp1_match_data[] = {
20742132
{
20752133
.compatible = "st,stm32mp1-rcc",
20762134
.data = &stm32mp1_data,
20772135
},
2136+
{
2137+
.compatible = "st,stm32mp1-rcc-secure",
2138+
.data = &stm32mp1_data_secure,
2139+
},
20782140
{ }
20792141
};
20802142
MODULE_DEVICE_TABLE(of, stm32mp1_match_data);
@@ -2234,6 +2296,9 @@ static int stm32_rcc_clock_init(struct device *dev, void __iomem *base,
22342296
hws[n] = ERR_PTR(-ENOENT);
22352297

22362298
for (n = 0; n < data->num; n++) {
2299+
if (data->check_security && data->check_security(&data->cfg[n]))
2300+
continue;
2301+
22372302
err = stm32_register_hw_clk(dev, clk_data, base, &rlock,
22382303
&data->cfg[n]);
22392304
if (err) {
@@ -2301,11 +2366,45 @@ static int stm32mp1_rcc_init(struct device *dev)
23012366
return ret;
23022367
}
23032368

2369+
static int get_clock_deps(struct device *dev)
2370+
{
2371+
static const char * const clock_deps_name[] = {
2372+
"hsi", "hse", "csi", "lsi", "lse",
2373+
};
2374+
size_t deps_size = sizeof(struct clk *) * ARRAY_SIZE(clock_deps_name);
2375+
struct clk **clk_deps;
2376+
int i;
2377+
2378+
clk_deps = devm_kzalloc(dev, deps_size, GFP_KERNEL);
2379+
if (!clk_deps)
2380+
return -ENOMEM;
2381+
2382+
for (i = 0; i < ARRAY_SIZE(clock_deps_name); i++) {
2383+
struct clk *clk = of_clk_get_by_name(dev_of_node(dev),
2384+
clock_deps_name[i]);
2385+
2386+
if (IS_ERR(clk)) {
2387+
if (PTR_ERR(clk) != -EINVAL && PTR_ERR(clk) != -ENOENT)
2388+
return PTR_ERR(clk);
2389+
} else {
2390+
/* Device gets a reference count on the clock */
2391+
clk_deps[i] = devm_clk_get(dev, __clk_get_name(clk));
2392+
clk_put(clk);
2393+
}
2394+
}
2395+
2396+
return 0;
2397+
}
2398+
23042399
static int stm32mp1_rcc_clocks_probe(struct platform_device *pdev)
23052400
{
23062401
struct device *dev = &pdev->dev;
2402+
int ret = get_clock_deps(dev);
2403+
2404+
if (!ret)
2405+
ret = stm32mp1_rcc_init(dev);
23072406

2308-
return stm32mp1_rcc_init(dev);
2407+
return ret;
23092408
}
23102409

23112410
static int stm32mp1_rcc_clocks_remove(struct platform_device *pdev)

0 commit comments

Comments
 (0)