Merge tag 'gcc-plugins-v5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / clk / meson / clk-regmap.h
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 *
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 extern const struct clk_ops clk_regmap_gate_ro_ops;
55
56 /**
57  * struct clk_regmap_div_data - regmap backed adjustable divider specific data
58  *
59  * @offset:     offset of the register controlling the divider
60  * @shift:      shift to the divider bit field
61  * @width:      width of the divider bit field
62  * @table:      array of value/divider pairs, last entry should have div = 0
63  *
64  * Flags:
65  * Same as clk_divider except CLK_DIVIDER_HIWORD_MASK which is ignored
66  */
67 struct clk_regmap_div_data {
68         unsigned int    offset;
69         u8              shift;
70         u8              width;
71         u8              flags;
72         const struct clk_div_table      *table;
73 };
74
75 static inline struct clk_regmap_div_data *
76 clk_get_regmap_div_data(struct clk_regmap *clk)
77 {
78         return (struct clk_regmap_div_data *)clk->data;
79 }
80
81 extern const struct clk_ops clk_regmap_divider_ops;
82 extern const struct clk_ops clk_regmap_divider_ro_ops;
83
84 /**
85  * struct clk_regmap_mux_data - regmap backed multiplexer clock specific data
86  *
87  * @hw:         handle between common and hardware-specific interfaces
88  * @offset:     offset of theregister controlling multiplexer
89  * @table:      array of parent indexed register values
90  * @shift:      shift to multiplexer bit field
91  * @mask:       mask of mutliplexer bit field
92  * @flags:      hardware-specific flags
93  *
94  * Flags:
95  * Same as clk_divider except CLK_MUX_HIWORD_MASK which is ignored
96  */
97 struct clk_regmap_mux_data {
98         unsigned int    offset;
99         u32             *table;
100         u32             mask;
101         u8              shift;
102         u8              flags;
103 };
104
105 static inline struct clk_regmap_mux_data *
106 clk_get_regmap_mux_data(struct clk_regmap *clk)
107 {
108         return (struct clk_regmap_mux_data *)clk->data;
109 }
110
111 extern const struct clk_ops clk_regmap_mux_ops;
112 extern const struct clk_ops clk_regmap_mux_ro_ops;
113
114 #define __MESON_PCLK(_name, _reg, _bit, _ops, _pname)                   \
115 struct clk_regmap _name = {                                             \
116         .data = &(struct clk_regmap_gate_data){                         \
117                 .offset = (_reg),                                       \
118                 .bit_idx = (_bit),                                      \
119         },                                                              \
120         .hw.init = &(struct clk_init_data) {                            \
121                 .name = #_name,                                         \
122                 .ops = _ops,                                            \
123                 .parent_hws = (const struct clk_hw *[]) { _pname },     \
124                 .num_parents = 1,                                       \
125                 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),     \
126         },                                                              \
127 }
128
129 #define MESON_PCLK(_name, _reg, _bit, _pname)   \
130         __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pname)
131
132 #define MESON_PCLK_RO(_name, _reg, _bit, _pname)        \
133         __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pname)
134 #endif /* __CLK_REGMAP_H */