xref: /linux/drivers/clk/spacemit/ccu_pll.h (revision 1fd1dc41724319406b0aff221a352a400b0ddfc5)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (c) 2024 SpacemiT Technology Co. Ltd
4  * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org>
5  */
6 
7 #ifndef _CCU_PLL_H_
8 #define _CCU_PLL_H_
9 
10 #include <linux/clk-provider.h>
11 
12 #include "ccu_common.h"
13 
14 /**
15  * struct ccu_pll_rate_tbl - Structure mapping between PLL rate and register
16  * configuration.
17  *
18  * @rate:	PLL rate
19  * @swcr1:	Value of register PLLx_SW1_CTRL.
20  * @swcr2:	Value of register PLLAx_SW2_CTRL.
21  * @swcr3:	value of register PLLx_SW3_CTRL.
22  *
23  * See below tables for the register used in PPL/PPLA clocks
24  *
25  * Regular PLL type
26  *  | Enable | swcr3 | PLLx_SW3_CTRL - BIT[31]    |
27  *  -----------------------------------------------
28  *  | Config | swcr1 | PLLx_SW1_CTRL - BIT[31:0]  |
29  *  |        | swcr2 | Not used                   |
30  *  |        | swcr3 | PLLx_SW3_CTRL - BIT[30:0]  |
31  *
32  * Special PLL type A
33  *  | Enable | swcr2 | PLLAx_SW2_CTRL - BIT[16]   |
34  *  -----------------------------------------------
35  *  | Config | swcr1 | PLLAx_SW1_CTRL - BIT[31:0] |
36  *  |        | swcr2 | PLLAx_SW2_CTRL - BIT[15:8] |
37  *  |        | swcr3 | PLLAx_SW3_CTRL - BIT[31:0] |
38  *
39  */
40 struct ccu_pll_rate_tbl {
41 	unsigned long rate;
42 	u32 swcr1;
43 	u32 swcr2;
44 	u32 swcr3;
45 };
46 
47 struct ccu_pll_config {
48 	const struct ccu_pll_rate_tbl *rate_tbl;
49 	u32 tbl_num;
50 	u32 reg_lock;
51 	u32 mask_lock;
52 };
53 
54 #define CCU_PLL_RATE(_rate, _swcr1, _swcr3) \
55 	{									\
56 		.rate	= _rate,						\
57 		.swcr1	= _swcr1,						\
58 		.swcr3	= _swcr3,						\
59 	}
60 
61 #define CCU_PLLA_RATE(_rate, _swcr1, _swcr2, _swcr3) \
62 	{									\
63 		.rate	= _rate,						\
64 		.swcr1	= _swcr1,						\
65 		.swcr2	= _swcr2,						\
66 		.swcr3	= _swcr3,						\
67 	}
68 
69 struct ccu_pll {
70 	struct ccu_common	common;
71 	struct ccu_pll_config	config;
72 };
73 
74 #define CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock) \
75 	{									\
76 		.rate_tbl	= _table,					\
77 		.tbl_num	= ARRAY_SIZE(_table),				\
78 		.reg_lock	= (_reg_lock),					\
79 		.mask_lock	= (_mask_lock),					\
80 	}
81 
82 #define CCU_PLL_COMMON_HWINIT(_name, _ops, _flags)				\
83 	(&(struct clk_init_data) {						\
84 		.name		= #_name,					\
85 		.ops		= _ops,						\
86 		.parent_data	= &(struct clk_parent_data) { .index = 0 },	\
87 		.num_parents	= 1,						\
88 		.flags		= _flags,					\
89 	})
90 
91 #define CCU_PLL_X_DEFINE(_name, _table, _reg_swcr1, _reg_swcr2, _reg_swcr3,	\
92 		       _reg_lock, _mask_lock, _ops, _flags)			\
93 static struct ccu_pll _name = {							\
94 	.config	= CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock),		\
95 	.common = {								\
96 		.reg_swcr1	= _reg_swcr1,					\
97 		.reg_swcr2	= _reg_swcr2,					\
98 		.reg_swcr3	= _reg_swcr3,					\
99 		.hw.init	= CCU_PLL_COMMON_HWINIT(_name, _ops, _flags)	\
100 	}									\
101 }
102 
103 #define CCU_PLL_DEFINE(_name, _table, _reg_swcr1, _reg_swcr3, _reg_lock,	\
104 		       _mask_lock, _flags)					\
105 	CCU_PLL_X_DEFINE(_name, _table, _reg_swcr1, 0, _reg_swcr3,		\
106 		       _reg_lock, _mask_lock, &spacemit_ccu_pll_ops, _flags)
107 
108 #define CCU_PLLA_DEFINE(_name, _table, _reg_swcr1, _reg_swcr2, _reg_swcr3,	\
109 		       _reg_lock, _mask_lock, _flags)				\
110 	CCU_PLL_X_DEFINE(_name, _table, _reg_swcr1, _reg_swcr2, _reg_swcr3,	\
111 		       _reg_lock, _mask_lock, &spacemit_ccu_plla_ops, _flags)
112 
113 static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw)
114 {
115 	struct ccu_common *common = hw_to_ccu_common(hw);
116 
117 	return container_of(common, struct ccu_pll, common);
118 }
119 
120 extern const struct clk_ops spacemit_ccu_pll_ops;
121 extern const struct clk_ops spacemit_ccu_plla_ops;
122 
123 #endif
124