1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | // |
3 | // Spreadtrum divider clock driver |
4 | // |
5 | // Copyright (C) 2017 Spreadtrum, Inc. |
6 | // Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> |
7 | |
8 | #ifndef _SPRD_DIV_H_ |
9 | #define _SPRD_DIV_H_ |
10 | |
11 | #include "common.h" |
12 | |
13 | /** |
14 | * struct sprd_div_internal - Internal divider description |
15 | * @shift: Bit offset of the divider in its register |
16 | * @width: Width of the divider field in its register |
17 | * |
18 | * That structure represents a single divider, and is meant to be |
19 | * embedded in other structures representing the various clock |
20 | * classes. |
21 | */ |
22 | struct sprd_div_internal { |
23 | s32 offset; |
24 | u8 shift; |
25 | u8 width; |
26 | }; |
27 | |
28 | #define _SPRD_DIV_CLK(_offset, _shift, _width) \ |
29 | { \ |
30 | .offset = _offset, \ |
31 | .shift = _shift, \ |
32 | .width = _width, \ |
33 | } |
34 | |
35 | struct sprd_div { |
36 | struct sprd_div_internal div; |
37 | struct sprd_clk_common common; |
38 | }; |
39 | |
40 | #define SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _offset, \ |
41 | _shift, _width, _flags, _fn) \ |
42 | struct sprd_div _struct = { \ |
43 | .div = _SPRD_DIV_CLK(_offset, _shift, _width), \ |
44 | .common = { \ |
45 | .regmap = NULL, \ |
46 | .reg = _reg, \ |
47 | .hw.init = _fn(_name, _parent, \ |
48 | &sprd_div_ops, _flags), \ |
49 | } \ |
50 | } |
51 | |
52 | #define SPRD_DIV_CLK(_struct, _name, _parent, _reg, \ |
53 | _shift, _width, _flags) \ |
54 | SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, 0x0, \ |
55 | _shift, _width, _flags, CLK_HW_INIT) |
56 | |
57 | #define SPRD_DIV_CLK_FW_NAME(_struct, _name, _parent, _reg, \ |
58 | _shift, _width, _flags) \ |
59 | SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, 0x0, \ |
60 | _shift, _width, _flags, CLK_HW_INIT_FW_NAME) |
61 | |
62 | #define SPRD_DIV_CLK_HW(_struct, _name, _parent, _reg, \ |
63 | _shift, _width, _flags) \ |
64 | SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, 0x0, \ |
65 | _shift, _width, _flags, CLK_HW_INIT_HW) |
66 | |
67 | static inline struct sprd_div *hw_to_sprd_div(const struct clk_hw *hw) |
68 | { |
69 | struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); |
70 | |
71 | return container_of(common, struct sprd_div, common); |
72 | } |
73 | |
74 | unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common, |
75 | const struct sprd_div_internal *div, |
76 | unsigned long parent_rate); |
77 | |
78 | int sprd_div_helper_set_rate(const struct sprd_clk_common *common, |
79 | const struct sprd_div_internal *div, |
80 | unsigned long rate, |
81 | unsigned long parent_rate); |
82 | |
83 | extern const struct clk_ops sprd_div_ops; |
84 | |
85 | #endif /* _SPRD_DIV_H_ */ |
86 | |