blob: c623b0c7a23c3f7229445aa0b40051245f95b028 [file] [log] [blame]
Maxime Ripard6174a1e2016-06-29 21:05:31 +02001/*
2 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#ifndef _CCU_NM_H_
15#define _CCU_NM_H_
16
17#include <linux/clk-provider.h>
18
19#include "ccu_common.h"
20#include "ccu_div.h"
21#include "ccu_frac.h"
22#include "ccu_mult.h"
Chen-Yu Tsai392ba5f2017-10-12 16:37:00 +080023#include "ccu_sdm.h"
Maxime Ripard6174a1e2016-06-29 21:05:31 +020024
25/*
26 * struct ccu_nm - Definition of an N-M clock
27 *
28 * Clocks based on the formula parent * N / M
29 */
30struct ccu_nm {
31 u32 enable;
32 u32 lock;
33
Maxime Riparda501a142016-09-30 10:05:32 +020034 struct ccu_mult_internal n;
35 struct ccu_div_internal m;
36 struct ccu_frac_internal frac;
Chen-Yu Tsai392ba5f2017-10-12 16:37:00 +080037 struct ccu_sdm_internal sdm;
Maxime Ripard6174a1e2016-06-29 21:05:31 +020038
39 struct ccu_common common;
40};
41
Chen-Yu Tsai392ba5f2017-10-12 16:37:00 +080042#define SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(_struct, _name, _parent, _reg, \
43 _nshift, _nwidth, \
44 _mshift, _mwidth, \
45 _sdm_table, _sdm_en, \
46 _sdm_reg, _sdm_reg_en, \
47 _gate, _lock, _flags) \
48 struct ccu_nm _struct = { \
49 .enable = _gate, \
50 .lock = _lock, \
51 .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \
52 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
53 .sdm = _SUNXI_CCU_SDM(_sdm_table, _sdm_en, \
54 _sdm_reg, _sdm_reg_en),\
55 .common = { \
56 .reg = _reg, \
57 .features = CCU_FEATURE_SIGMA_DELTA_MOD, \
58 .hw.init = CLK_HW_INIT(_name, \
59 _parent, \
60 &ccu_nm_ops, \
61 _flags), \
62 }, \
63 }
64
Maxime Ripard6174a1e2016-06-29 21:05:31 +020065#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(_struct, _name, _parent, _reg, \
66 _nshift, _nwidth, \
67 _mshift, _mwidth, \
68 _frac_en, _frac_sel, \
69 _frac_rate_0, _frac_rate_1, \
70 _gate, _lock, _flags) \
71 struct ccu_nm _struct = { \
72 .enable = _gate, \
73 .lock = _lock, \
74 .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \
75 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
76 .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \
77 _frac_rate_0, \
78 _frac_rate_1), \
79 .common = { \
80 .reg = _reg, \
81 .features = CCU_FEATURE_FRACTIONAL, \
82 .hw.init = CLK_HW_INIT(_name, \
83 _parent, \
84 &ccu_nm_ops, \
85 _flags), \
86 }, \
87 }
88
89#define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \
90 _nshift, _nwidth, \
91 _mshift, _mwidth, \
92 _gate, _lock, _flags) \
93 struct ccu_nm _struct = { \
94 .enable = _gate, \
95 .lock = _lock, \
96 .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \
97 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
98 .common = { \
99 .reg = _reg, \
100 .hw.init = CLK_HW_INIT(_name, \
101 _parent, \
102 &ccu_nm_ops, \
103 _flags), \
104 }, \
105 }
106
107static inline struct ccu_nm *hw_to_ccu_nm(struct clk_hw *hw)
108{
109 struct ccu_common *common = hw_to_ccu_common(hw);
110
111 return container_of(common, struct ccu_nm, common);
112}
113
114extern const struct clk_ops ccu_nm_ops;
115
116#endif /* _CCU_NM_H_ */