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/clk-provider.h>
11 #include <linux/regmap.h>
12 
13 /**
14  * struct clk_regmap - regmap backed clock
15  *
16  * @hw:		handle between common and hardware-specific interfaces
17  * @map:	pointer to the regmap structure controlling the clock
18  * @data:	data specific to the clock type
19  *
20  * Clock which is controlled by regmap backed registers. The actual type of
21  * of the clock is controlled by the clock_ops and data.
22  */
23 struct clk_regmap {
24 	struct clk_hw	hw;
25 	struct regmap	*map;
26 	void		*data;
27 };
28 
29 #define to_clk_regmap(_hw) container_of(_hw, struct clk_regmap, hw)
30 
31 /**
32  * struct clk_regmap_gate_data - regmap backed gate specific data
33  *
34  * @offset:	offset of the register controlling gate
35  * @bit_idx:	single bit controlling gate
36  * @flags:	hardware-specific flags
37  *
38  * Flags:
39  * Same as clk_gate except CLK_GATE_HIWORD_MASK which is ignored
40  */
41 struct clk_regmap_gate_data {
42 	unsigned int	offset;
43 	u8		bit_idx;
44 	u8		flags;
45 };
46 
47 static inline struct clk_regmap_gate_data *
clk_get_regmap_gate_data(struct clk_regmap * clk)48 clk_get_regmap_gate_data(struct clk_regmap *clk)
49 {
50 	return (struct clk_regmap_gate_data *)clk->data;
51 }
52 
53 extern const struct clk_ops clk_regmap_gate_ops;
54 
55 /**
56  * struct clk_regmap_div_data - regmap backed adjustable divider specific data
57  *
58  * @offset:	offset of the register controlling the divider
59  * @shift:	shift to the divider bit field
60  * @width:	width of the divider bit field
61  * @table:	array of value/divider pairs, last entry should have div = 0
62  *
63  * Flags:
64  * Same as clk_divider except CLK_DIVIDER_HIWORD_MASK which is ignored
65  */
66 struct clk_regmap_div_data {
67 	unsigned int	offset;
68 	u8		shift;
69 	u8		width;
70 	u8		flags;
71 	const struct clk_div_table	*table;
72 };
73 
74 static inline struct clk_regmap_div_data *
clk_get_regmap_div_data(struct clk_regmap * clk)75 clk_get_regmap_div_data(struct clk_regmap *clk)
76 {
77 	return (struct clk_regmap_div_data *)clk->data;
78 }
79 
80 extern const struct clk_ops clk_regmap_divider_ops;
81 extern const struct clk_ops clk_regmap_divider_ro_ops;
82 
83 /**
84  * struct clk_regmap_mux_data - regmap backed multiplexer clock specific data
85  *
86  * @hw:		handle between common and hardware-specific interfaces
87  * @offset:	offset of theregister controlling multiplexer
88  * @table:	array of parent indexed register values
89  * @shift:	shift to multiplexer bit field
90  * @mask:	mask of mutliplexer bit field
91  * @flags:	hardware-specific flags
92  *
93  * Flags:
94  * Same as clk_divider except CLK_MUX_HIWORD_MASK which is ignored
95  */
96 struct clk_regmap_mux_data {
97 	unsigned int	offset;
98 	u32		*table;
99 	u32		mask;
100 	u8		shift;
101 	u8		flags;
102 };
103 
104 static inline struct clk_regmap_mux_data *
clk_get_regmap_mux_data(struct clk_regmap * clk)105 clk_get_regmap_mux_data(struct clk_regmap *clk)
106 {
107 	return (struct clk_regmap_mux_data *)clk->data;
108 }
109 
110 extern const struct clk_ops clk_regmap_mux_ops;
111 extern const struct clk_ops clk_regmap_mux_ro_ops;
112 
113 #endif /* __CLK_REGMAP_H */
114