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: Register value of PLLX_SW1_CTRL (PLLx_SWCR1).
20 * @swcr3: Register value of the PLLx_SW3_CTRL's lowest 31 bits of
21 * PLLx_SW3_CTRL (PLLx_SWCR3). This highest bit is for enabling
22 * the PLL and not contained in this field.
23 */
24 struct ccu_pll_rate_tbl {
25 unsigned long rate;
26 u32 swcr1;
27 u32 swcr3;
28 };
29
30 struct ccu_pll_config {
31 const struct ccu_pll_rate_tbl *rate_tbl;
32 u32 tbl_num;
33 u32 reg_lock;
34 u32 mask_lock;
35 };
36
37 #define CCU_PLL_RATE(_rate, _swcr1, _swcr3) \
38 { \
39 .rate = _rate, \
40 .swcr1 = _swcr1, \
41 .swcr3 = _swcr3, \
42 }
43
44 struct ccu_pll {
45 struct ccu_common common;
46 struct ccu_pll_config config;
47 };
48
49 #define CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock) \
50 { \
51 .rate_tbl = _table, \
52 .tbl_num = ARRAY_SIZE(_table), \
53 .reg_lock = (_reg_lock), \
54 .mask_lock = (_mask_lock), \
55 }
56
57 #define CCU_PLL_HWINIT(_name, _flags) \
58 (&(struct clk_init_data) { \
59 .name = #_name, \
60 .ops = &spacemit_ccu_pll_ops, \
61 .parent_data = &(struct clk_parent_data) { .index = 0 }, \
62 .num_parents = 1, \
63 .flags = _flags, \
64 })
65
66 #define CCU_PLL_DEFINE(_name, _table, _reg_swcr1, _reg_swcr3, _reg_lock, \
67 _mask_lock, _flags) \
68 static struct ccu_pll _name = { \
69 .config = CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock), \
70 .common = { \
71 .reg_swcr1 = _reg_swcr1, \
72 .reg_swcr3 = _reg_swcr3, \
73 .hw.init = CCU_PLL_HWINIT(_name, _flags) \
74 } \
75 }
76
hw_to_ccu_pll(struct clk_hw * hw)77 static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw)
78 {
79 struct ccu_common *common = hw_to_ccu_common(hw);
80
81 return container_of(common, struct ccu_pll, common);
82 }
83
84 extern const struct clk_ops spacemit_ccu_pll_ops;
85
86 #endif
87