Skip to content

Commit 637cee5

Browse files
Gabriel-Fernandzbebarino
authored andcommitted
clk: stm32: Introduce STM32MP13 RCC drivers (Reset Clock Controller)
This driver manages Reset and Clock of STM32MP13 soc. It uses a clk-stm32-core module to manage stm32 gate, mux and divider for STM32MP13 and for new future soc. All gates, muxes, dividers are identify by an index and information are stored in array (register address, shift, with, flags...) This is useful when we have two clocks with the same gate or when one mux manages two output clocks. Signed-off-by: Gabriel Fernandez <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 722dc8a commit 637cee5

File tree

9 files changed

+2590
-0
lines changed

9 files changed

+2590
-0
lines changed

drivers/clk/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,11 @@ config COMMON_CLK_VC5
368368
This driver supports the IDT VersaClock 5 and VersaClock 6
369369
programmable clock generators.
370370

371+
config COMMON_CLK_STM32MP135
372+
def_bool COMMON_CLK && MACH_STM32MP13
373+
help
374+
Support for stm32mp135 SoC family clocks
375+
371376
config COMMON_CLK_STM32MP157
372377
def_bool COMMON_CLK && MACH_STM32MP157
373378
help

drivers/clk/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ obj-y += socfpga/
115115
obj-$(CONFIG_PLAT_SPEAR) += spear/
116116
obj-y += sprd/
117117
obj-$(CONFIG_ARCH_STI) += st/
118+
obj-$(CONFIG_ARCH_STM32) += stm32/
118119
obj-$(CONFIG_SOC_STARFIVE) += starfive/
119120
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
120121
obj-y += sunxi-ng/

drivers/clk/stm32/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
obj-$(CONFIG_COMMON_CLK_STM32MP135) += clk-stm32mp13.o clk-stm32-core.o reset-stm32.o

drivers/clk/stm32/clk-stm32-core.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (C) STMicroelectronics 2022 - All Rights Reserved
4+
* Author: Gabriel Fernandez <[email protected]> for STMicroelectronics.
5+
*/
6+
7+
#include <linux/clk.h>
8+
#include <linux/delay.h>
9+
#include <linux/device.h>
10+
#include <linux/err.h>
11+
#include <linux/io.h>
12+
#include <linux/of.h>
13+
#include <linux/of_address.h>
14+
#include <linux/slab.h>
15+
#include <linux/spinlock.h>
16+
17+
#include "clk-stm32-core.h"
18+
#include "reset-stm32.h"
19+
20+
static DEFINE_SPINLOCK(rlock);
21+
22+
static int stm32_rcc_clock_init(struct device *dev,
23+
const struct of_device_id *match,
24+
void __iomem *base)
25+
{
26+
const struct stm32_rcc_match_data *data = match->data;
27+
struct clk_hw_onecell_data *clk_data = data->hw_clks;
28+
struct device_node *np = dev_of_node(dev);
29+
struct clk_hw **hws;
30+
int n, max_binding;
31+
32+
max_binding = data->maxbinding;
33+
34+
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, max_binding), GFP_KERNEL);
35+
if (!clk_data)
36+
return -ENOMEM;
37+
38+
clk_data->num = max_binding;
39+
40+
hws = clk_data->hws;
41+
42+
for (n = 0; n < max_binding; n++)
43+
hws[n] = ERR_PTR(-ENOENT);
44+
45+
for (n = 0; n < data->num_clocks; n++) {
46+
const struct clock_config *cfg_clock = &data->tab_clocks[n];
47+
struct clk_hw *hw = ERR_PTR(-ENOENT);
48+
49+
if (cfg_clock->func)
50+
hw = (*cfg_clock->func)(dev, data, base, &rlock,
51+
cfg_clock);
52+
53+
if (IS_ERR(hw)) {
54+
dev_err(dev, "Can't register clk %d: %ld\n", n,
55+
PTR_ERR(hw));
56+
return PTR_ERR(hw);
57+
}
58+
59+
if (cfg_clock->id != NO_ID)
60+
hws[cfg_clock->id] = hw;
61+
}
62+
63+
return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
64+
}
65+
66+
int stm32_rcc_init(struct device *dev, const struct of_device_id *match_data,
67+
void __iomem *base)
68+
{
69+
const struct of_device_id *match;
70+
int err;
71+
72+
match = of_match_node(match_data, dev_of_node(dev));
73+
if (!match) {
74+
dev_err(dev, "match data not found\n");
75+
return -ENODEV;
76+
}
77+
78+
/* RCC Reset Configuration */
79+
err = stm32_rcc_reset_init(dev, match, base);
80+
if (err) {
81+
pr_err("stm32 reset failed to initialize\n");
82+
return err;
83+
}
84+
85+
/* RCC Clock Configuration */
86+
err = stm32_rcc_clock_init(dev, match, base);
87+
if (err) {
88+
pr_err("stm32 clock failed to initialize\n");
89+
return err;
90+
}
91+
92+
return 0;
93+
}

drivers/clk/stm32/clk-stm32-core.h

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Copyright (C) STMicroelectronics 2022 - All Rights Reserved
4+
* Author: Gabriel Fernandez <[email protected]> for STMicroelectronics.
5+
*/
6+
7+
#include <linux/clk-provider.h>
8+
9+
struct stm32_rcc_match_data;
10+
11+
struct stm32_mux_cfg {
12+
u16 offset;
13+
u8 shift;
14+
u8 width;
15+
u8 flags;
16+
u32 *table;
17+
u8 ready;
18+
};
19+
20+
struct stm32_gate_cfg {
21+
u16 offset;
22+
u8 bit_idx;
23+
u8 set_clr;
24+
};
25+
26+
struct stm32_div_cfg {
27+
u16 offset;
28+
u8 shift;
29+
u8 width;
30+
u8 flags;
31+
u8 ready;
32+
const struct clk_div_table *table;
33+
};
34+
35+
struct stm32_composite_cfg {
36+
int mux;
37+
int gate;
38+
int div;
39+
};
40+
41+
#define NO_ID 0xFFFFFFFF
42+
43+
#define NO_STM32_MUX 0xFFFF
44+
#define NO_STM32_DIV 0xFFFF
45+
#define NO_STM32_GATE 0xFFFF
46+
47+
struct clock_config {
48+
unsigned long id;
49+
void *clock_cfg;
50+
51+
struct clk_hw *(*func)(struct device *dev,
52+
const struct stm32_rcc_match_data *data,
53+
void __iomem *base,
54+
spinlock_t *lock,
55+
const struct clock_config *cfg);
56+
};
57+
58+
struct clk_stm32_clock_data {
59+
u16 *gate_cpt;
60+
const struct stm32_gate_cfg *gates;
61+
const struct stm32_mux_cfg *muxes;
62+
const struct stm32_div_cfg *dividers;
63+
};
64+
65+
struct stm32_rcc_match_data {
66+
struct clk_hw_onecell_data *hw_clks;
67+
unsigned int num_clocks;
68+
const struct clock_config *tab_clocks;
69+
unsigned int maxbinding;
70+
struct clk_stm32_clock_data *clock_data;
71+
u32 clear_offset;
72+
};
73+
74+
int stm32_rcc_reset_init(struct device *dev, const struct of_device_id *match,
75+
void __iomem *base);
76+
77+
int stm32_rcc_init(struct device *dev, const struct of_device_id *match_data,
78+
void __iomem *base);
79+
80+
/* MUX define */
81+
#define MUX_NO_RDY 0xFF
82+
83+
/* DIV define */
84+
#define DIV_NO_RDY 0xFF
85+
86+
/* Clock registering */
87+
#define STM32_CLOCK_CFG(_binding, _clk, _struct, _register)\
88+
{\
89+
.id = (_binding),\
90+
.clock_cfg = (_struct) {_clk},\
91+
.func = (_register),\
92+
}

0 commit comments

Comments
 (0)