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
81