GNU Linux-libre 4.19.314-gnu1
[releases.git] / drivers / clk / sunxi-ng / ccu_sdm.h
1 /*
2  * Copyright (c) 2017 Chen-Yu Tsai. 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_SDM_H
15 #define _CCU_SDM_H
16
17 #include <linux/clk-provider.h>
18
19 #include "ccu_common.h"
20
21 struct ccu_sdm_setting {
22         unsigned long   rate;
23
24         /*
25          * XXX We don't know what the step and bottom register fields
26          * mean. Just copy the whole register value from the vendor
27          * kernel for now.
28          */
29         u32             pattern;
30
31         /*
32          * M and N factors here should be the values used in
33          * calculation, not the raw values written to registers
34          */
35         u32             m;
36         u32             n;
37 };
38
39 struct ccu_sdm_internal {
40         struct ccu_sdm_setting  *table;
41         u32             table_size;
42         /* early SoCs don't have the SDM enable bit in the PLL register */
43         u32             enable;
44         /* second enable bit in tuning register */
45         u32             tuning_enable;
46         u16             tuning_reg;
47 };
48
49 #define _SUNXI_CCU_SDM(_table, _enable,                 \
50                        _reg, _reg_enable)               \
51         {                                               \
52                 .table          = _table,               \
53                 .table_size     = ARRAY_SIZE(_table),   \
54                 .enable         = _enable,              \
55                 .tuning_enable  = _reg_enable,          \
56                 .tuning_reg     = _reg,                 \
57         }
58
59 bool ccu_sdm_helper_is_enabled(struct ccu_common *common,
60                                struct ccu_sdm_internal *sdm);
61 void ccu_sdm_helper_enable(struct ccu_common *common,
62                            struct ccu_sdm_internal *sdm,
63                            unsigned long rate);
64 void ccu_sdm_helper_disable(struct ccu_common *common,
65                             struct ccu_sdm_internal *sdm);
66
67 bool ccu_sdm_helper_has_rate(struct ccu_common *common,
68                              struct ccu_sdm_internal *sdm,
69                              unsigned long rate);
70
71 unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common,
72                                        struct ccu_sdm_internal *sdm,
73                                        u32 m, u32 n);
74
75 int ccu_sdm_helper_get_factors(struct ccu_common *common,
76                                struct ccu_sdm_internal *sdm,
77                                unsigned long rate,
78                                unsigned long *m, unsigned long *n);
79
80 #endif