xref: /linux/drivers/clk/meson/clk-regmap.h (revision 2d945dde7fa3f17f46349360a9f97614de9f47da)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (c) 2018 BayLibre, SAS.
4  * Author: Jerome Brunet <jbrunet@baylibre.com>
5  */
6 
7 #ifndef __CLK_REGMAP_H
8 #define __CLK_REGMAP_H
9 
10 #include <linux/device.h>
11 #include <linux/clk-provider.h>
12 #include <linux/regmap.h>
13 
14 /**
15  * struct clk_regmap - regmap backed clock
16  *
17  * @hw:		handle between common and hardware-specific interfaces
18  * @map:	pointer to the regmap structure controlling the clock
19  * @data:	data specific to the clock type
20  *
21  * Clock which is controlled by regmap backed registers. The actual type of
22  * of the clock is controlled by the clock_ops and data.
23  */
24 struct clk_regmap {
25 	struct clk_hw	hw;
26 	struct regmap	*map;
27 	void		*data;
28 };
29 
to_clk_regmap(struct clk_hw * hw)30 static inline struct clk_regmap *to_clk_regmap(struct clk_hw *hw)
31 {
32 	return container_of(hw, struct clk_regmap, hw);
33 }
34 
35 /* clk_regmap init op to get and cache regmap from the controllers */
36 int clk_regmap_init(struct clk_hw *hw);
37 
38 /**
39  * struct clk_regmap_gate_data - regmap backed gate specific data
40  *
41  * @offset:	offset of the register controlling gate
42  * @bit_idx:	single bit controlling gate
43  * @flags:	hardware-specific flags
44  *
45  * Flags:
46  * Same as clk_gate except CLK_GATE_HIWORD_MASK which is ignored
47  */
48 struct clk_regmap_gate_data {
49 	unsigned int	offset;
50 	u8		bit_idx;
51 	u8		flags;
52 };
53 
54 static inline struct clk_regmap_gate_data *
clk_get_regmap_gate_data(struct clk_regmap * clk)55 clk_get_regmap_gate_data(struct clk_regmap *clk)
56 {
57 	return (struct clk_regmap_gate_data *)clk->data;
58 }
59 
60 extern const struct clk_ops clk_regmap_gate_ops;
61 extern const struct clk_ops clk_regmap_gate_ro_ops;
62 
63 /**
64  * struct clk_regmap_div_data - regmap backed adjustable divider specific data
65  *
66  * @offset:	offset of the register controlling the divider
67  * @shift:	shift to the divider bit field
68  * @width:	width of the divider bit field
69  * @table:	array of value/divider pairs, last entry should have div = 0
70  *
71  * Flags:
72  * Same as clk_divider except CLK_DIVIDER_HIWORD_MASK which is ignored
73  */
74 struct clk_regmap_div_data {
75 	unsigned int	offset;
76 	u8		shift;
77 	u8		width;
78 	u8		flags;
79 	const struct clk_div_table	*table;
80 };
81 
82 static inline struct clk_regmap_div_data *
clk_get_regmap_div_data(struct clk_regmap * clk)83 clk_get_regmap_div_data(struct clk_regmap *clk)
84 {
85 	return (struct clk_regmap_div_data *)clk->data;
86 }
87 
88 extern const struct clk_ops clk_regmap_divider_ops;
89 extern const struct clk_ops clk_regmap_divider_ro_ops;
90 
91 /**
92  * struct clk_regmap_mux_data - regmap backed multiplexer clock specific data
93  *
94  * @hw:		handle between common and hardware-specific interfaces
95  * @offset:	offset of theregister controlling multiplexer
96  * @table:	array of parent indexed register values
97  * @shift:	shift to multiplexer bit field
98  * @mask:	mask of mutliplexer bit field
99  * @flags:	hardware-specific flags
100  *
101  * Flags:
102  * Same as clk_divider except CLK_MUX_HIWORD_MASK which is ignored
103  */
104 struct clk_regmap_mux_data {
105 	unsigned int	offset;
106 	u32		*table;
107 	u32		mask;
108 	u8		shift;
109 	u8		flags;
110 };
111 
112 static inline struct clk_regmap_mux_data *
clk_get_regmap_mux_data(struct clk_regmap * clk)113 clk_get_regmap_mux_data(struct clk_regmap *clk)
114 {
115 	return (struct clk_regmap_mux_data *)clk->data;
116 }
117 
118 extern const struct clk_ops clk_regmap_mux_ops;
119 extern const struct clk_ops clk_regmap_mux_ro_ops;
120 
121 #define __MESON_PCLK(_name, _reg, _bit, _ops, _pname)			\
122 struct clk_regmap _name = {						\
123 	.data = &(struct clk_regmap_gate_data){				\
124 		.offset = (_reg),					\
125 		.bit_idx = (_bit),					\
126 	},								\
127 	.hw.init = &(struct clk_init_data) {				\
128 		.name = #_name,						\
129 		.ops = _ops,						\
130 		.parent_hws = (const struct clk_hw *[]) { _pname },	\
131 		.num_parents = 1,					\
132 		.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),	\
133 	},								\
134 }
135 
136 #define MESON_PCLK(_name, _reg, _bit, _pname)	\
137 	__MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pname)
138 
139 #define MESON_PCLK_RO(_name, _reg, _bit, _pname)	\
140 	__MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pname)
141 #endif /* __CLK_REGMAP_H */
142