xref: /linux/drivers/clk/sophgo/clk-cv18xx-pll.h (revision daa121128a2d2ac6006159e2c47676e4fcd21eab)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com>
4  */
5 
6 #ifndef _CLK_SOPHGO_CV1800_PLL_H_
7 #define _CLK_SOPHGO_CV1800_PLL_H_
8 
9 #include "clk-cv18xx-common.h"
10 
11 struct cv1800_clk_pll_limit {
12 	struct {
13 		u8 min;
14 		u8 max;
15 	} pre_div, div, post_div, ictrl, mode;
16 };
17 
18 #define _CV1800_PLL_LIMIT(_min, _max)	\
19 	{				\
20 		.min = _min,		\
21 		.max = _max,		\
22 	}				\
23 
24 #define for_each_pll_limit_range(_var, _restrict) \
25 	for (_var = (_restrict)->min; _var <= (_restrict)->max; _var++)
26 
27 struct cv1800_clk_pll_synthesizer {
28 	struct cv1800_clk_regbit	en;
29 	struct cv1800_clk_regbit	clk_half;
30 	u32				ctrl;
31 	u32				set;
32 };
33 
34 #define _PLL_PRE_DIV_SEL_FIELD		GENMASK(6, 0)
35 #define _PLL_POST_DIV_SEL_FIELD		GENMASK(14, 8)
36 #define _PLL_SEL_MODE_FIELD		GENMASK(16, 15)
37 #define _PLL_DIV_SEL_FIELD		GENMASK(23, 17)
38 #define _PLL_ICTRL_FIELD		GENMASK(26, 24)
39 
40 #define _PLL_ALL_FIELD_MASK \
41 	(_PLL_PRE_DIV_SEL_FIELD | \
42 	 _PLL_POST_DIV_SEL_FIELD | \
43 	 _PLL_SEL_MODE_FIELD | \
44 	 _PLL_DIV_SEL_FIELD | \
45 	 _PLL_ICTRL_FIELD)
46 
47 #define PLL_COPY_REG(_dest, _src) \
48 	(((_dest) & (~_PLL_ALL_FIELD_MASK)) | ((_src) & _PLL_ALL_FIELD_MASK))
49 
50 #define PLL_GET_PRE_DIV_SEL(_reg) \
51 	FIELD_GET(_PLL_PRE_DIV_SEL_FIELD, (_reg))
52 #define PLL_GET_POST_DIV_SEL(_reg) \
53 	FIELD_GET(_PLL_POST_DIV_SEL_FIELD, (_reg))
54 #define PLL_GET_SEL_MODE(_reg) \
55 	FIELD_GET(_PLL_SEL_MODE_FIELD, (_reg))
56 #define PLL_GET_DIV_SEL(_reg) \
57 	FIELD_GET(_PLL_DIV_SEL_FIELD, (_reg))
58 #define PLL_GET_ICTRL(_reg) \
59 	FIELD_GET(_PLL_ICTRL_FIELD, (_reg))
60 
61 #define PLL_SET_PRE_DIV_SEL(_reg, _val) \
62 	_CV1800_SET_FIELD((_reg), (_val), _PLL_PRE_DIV_SEL_FIELD)
63 #define PLL_SET_POST_DIV_SEL(_reg, _val) \
64 	_CV1800_SET_FIELD((_reg), (_val), _PLL_POST_DIV_SEL_FIELD)
65 #define PLL_SET_SEL_MODE(_reg, _val) \
66 	_CV1800_SET_FIELD((_reg), (_val), _PLL_SEL_MODE_FIELD)
67 #define PLL_SET_DIV_SEL(_reg, _val) \
68 	_CV1800_SET_FIELD((_reg), (_val), _PLL_DIV_SEL_FIELD)
69 #define PLL_SET_ICTRL(_reg, _val) \
70 	_CV1800_SET_FIELD((_reg), (_val), _PLL_ICTRL_FIELD)
71 
72 struct cv1800_clk_pll {
73 	struct cv1800_clk_common		common;
74 	u32					pll_reg;
75 	struct cv1800_clk_regbit		pll_pwd;
76 	struct cv1800_clk_regbit		pll_status;
77 	const struct cv1800_clk_pll_limit	*pll_limit;
78 	struct cv1800_clk_pll_synthesizer	*pll_syn;
79 };
80 
81 #define CV1800_INTEGRAL_PLL(_name, _parent, _pll_reg,			\
82 			     _pll_pwd_reg, _pll_pwd_shift,		\
83 			     _pll_status_reg, _pll_status_shift,	\
84 			     _pll_limit, _flags)			\
85 	struct cv1800_clk_pll _name = {					\
86 		.common		= CV1800_CLK_COMMON(#_name, _parent,	\
87 						    &cv1800_clk_ipll_ops,\
88 						    _flags),		\
89 		.pll_reg	= _pll_reg,				\
90 		.pll_pwd	= CV1800_CLK_BIT(_pll_pwd_reg,		\
91 					       _pll_pwd_shift),		\
92 		.pll_status	= CV1800_CLK_BIT(_pll_status_reg,	\
93 					       _pll_status_shift),	\
94 		.pll_limit	= _pll_limit,				\
95 		.pll_syn	= NULL,					\
96 	}
97 
98 #define CV1800_FACTIONAL_PLL(_name, _parent, _pll_reg,			\
99 			     _pll_pwd_reg, _pll_pwd_shift,		\
100 			     _pll_status_reg, _pll_status_shift,	\
101 			     _pll_limit, _pll_syn, _flags)		\
102 	struct cv1800_clk_pll _name = {					\
103 		.common		= CV1800_CLK_COMMON(#_name, _parent,	\
104 						    &cv1800_clk_fpll_ops,\
105 						    _flags),		\
106 		.pll_reg	= _pll_reg,				\
107 		.pll_pwd	= CV1800_CLK_BIT(_pll_pwd_reg,		\
108 					       _pll_pwd_shift),		\
109 		.pll_status	= CV1800_CLK_BIT(_pll_status_reg,	\
110 					       _pll_status_shift),	\
111 		.pll_limit	= _pll_limit,				\
112 		.pll_syn	= _pll_syn,				\
113 	}
114 
115 extern const struct clk_ops cv1800_clk_ipll_ops;
116 extern const struct clk_ops cv1800_clk_fpll_ops;
117 
118 #endif // _CLK_SOPHGO_CV1800_PLL_H_
119