1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved.
4  */
5 
6 #ifndef _CCU_SDM_H
7 #define _CCU_SDM_H
8 
9 #include <linux/clk-provider.h>
10 
11 #include "ccu_common.h"
12 
13 struct ccu_sdm_setting {
14 	unsigned long	rate;
15 
16 	/*
17 	 * XXX We don't know what the step and bottom register fields
18 	 * mean. Just copy the whole register value from the vendor
19 	 * kernel for now.
20 	 */
21 	u32		pattern;
22 
23 	/*
24 	 * M and N factors here should be the values used in
25 	 * calculation, not the raw values written to registers
26 	 */
27 	u32		m;
28 	u32		n;
29 };
30 
31 struct ccu_sdm_internal {
32 	struct ccu_sdm_setting	*table;
33 	u32		table_size;
34 	/* early SoCs don't have the SDM enable bit in the PLL register */
35 	u32		enable;
36 	/* second enable bit in tuning register */
37 	u32		tuning_enable;
38 	u16		tuning_reg;
39 };
40 
41 #define _SUNXI_CCU_SDM(_table, _enable,			\
42 		       _reg, _reg_enable)		\
43 	{						\
44 		.table		= _table,		\
45 		.table_size	= ARRAY_SIZE(_table),	\
46 		.enable		= _enable,		\
47 		.tuning_enable	= _reg_enable,		\
48 		.tuning_reg	= _reg,			\
49 	}
50 
51 bool ccu_sdm_helper_is_enabled(struct ccu_common *common,
52 			       struct ccu_sdm_internal *sdm);
53 void ccu_sdm_helper_enable(struct ccu_common *common,
54 			   struct ccu_sdm_internal *sdm,
55 			   unsigned long rate);
56 void ccu_sdm_helper_disable(struct ccu_common *common,
57 			    struct ccu_sdm_internal *sdm);
58 
59 bool ccu_sdm_helper_has_rate(struct ccu_common *common,
60 			     struct ccu_sdm_internal *sdm,
61 			     unsigned long rate);
62 
63 unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common,
64 				       struct ccu_sdm_internal *sdm,
65 				       u32 m, u32 n);
66 
67 int ccu_sdm_helper_get_factors(struct ccu_common *common,
68 			       struct ccu_sdm_internal *sdm,
69 			       unsigned long rate,
70 			       unsigned long *m, unsigned long *n);
71 
72 #endif
73