1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
6 * Serge Semin <Sergey.Semin@baikalelectronics.ru>
7 * Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
9 * Baikal-T1 CCU PLL clocks driver
12 #define pr_fmt(fmt) "bt1-ccu-pll: " fmt
14 #include <linux/kernel.h>
15 #include <linux/platform_device.h>
16 #include <linux/printk.h>
17 #include <linux/slab.h>
18 #include <linux/clk-provider.h>
19 #include <linux/mfd/syscon.h>
21 #include <linux/of_address.h>
22 #include <linux/ioport.h>
23 #include <linux/regmap.h>
25 #include <dt-bindings/clock/bt1-ccu.h>
29 #define CCU_CPU_PLL_BASE 0x000
30 #define CCU_SATA_PLL_BASE 0x008
31 #define CCU_DDR_PLL_BASE 0x010
32 #define CCU_PCIE_PLL_BASE 0x018
33 #define CCU_ETH_PLL_BASE 0x020
35 #define CCU_PLL_INFO(_id, _name, _pname, _base, _flags, _features) \
39 .parent_name = _pname, \
42 .features = _features, \
45 #define CCU_PLL_NUM ARRAY_SIZE(pll_info)
50 const char *parent_name
;
53 unsigned long features
;
57 * Alas we have to mark all PLLs as critical. CPU and DDR PLLs are sources of
58 * CPU cores and DDR controller reference clocks, due to which they obviously
59 * shouldn't be ever gated. SATA and PCIe PLLs are the parents of APB-bus and
60 * DDR controller AXI-bus clocks. If they are gated the system will be
61 * unusable. Moreover disabling SATA and Ethernet PLLs causes automatic reset
62 * of the corresponding subsystems. So until we aren't ready to re-initialize
63 * all the devices consuming those PLLs, they will be marked as critical too.
65 static const struct ccu_pll_info pll_info
[] = {
66 CCU_PLL_INFO(CCU_CPU_PLL
, "cpu_pll", "ref_clk", CCU_CPU_PLL_BASE
,
67 CLK_IS_CRITICAL
, CCU_PLL_BASIC
),
68 CCU_PLL_INFO(CCU_SATA_PLL
, "sata_pll", "ref_clk", CCU_SATA_PLL_BASE
,
69 CLK_IS_CRITICAL
| CLK_SET_RATE_GATE
, 0),
70 CCU_PLL_INFO(CCU_DDR_PLL
, "ddr_pll", "ref_clk", CCU_DDR_PLL_BASE
,
71 CLK_IS_CRITICAL
| CLK_SET_RATE_GATE
, 0),
72 CCU_PLL_INFO(CCU_PCIE_PLL
, "pcie_pll", "ref_clk", CCU_PCIE_PLL_BASE
,
73 CLK_IS_CRITICAL
, CCU_PLL_BASIC
),
74 CCU_PLL_INFO(CCU_ETH_PLL
, "eth_pll", "ref_clk", CCU_ETH_PLL_BASE
,
75 CLK_IS_CRITICAL
| CLK_SET_RATE_GATE
, 0)
79 struct device_node
*np
;
80 struct regmap
*sys_regs
;
81 struct ccu_pll
*plls
[CCU_PLL_NUM
];
84 static struct ccu_pll_data
*pll_data
;
86 static struct ccu_pll
*ccu_pll_find_desc(struct ccu_pll_data
*data
,
91 for (idx
= 0; idx
< CCU_PLL_NUM
; ++idx
) {
92 if (pll_info
[idx
].id
== clk_id
)
93 return data
->plls
[idx
];
96 return ERR_PTR(-EINVAL
);
99 static struct ccu_pll_data
*ccu_pll_create_data(struct device_node
*np
)
101 struct ccu_pll_data
*data
;
103 data
= kzalloc(sizeof(*data
), GFP_KERNEL
);
105 return ERR_PTR(-ENOMEM
);
112 static void ccu_pll_free_data(struct ccu_pll_data
*data
)
117 static int ccu_pll_find_sys_regs(struct ccu_pll_data
*data
)
119 data
->sys_regs
= syscon_node_to_regmap(data
->np
->parent
);
120 if (IS_ERR(data
->sys_regs
)) {
121 pr_err("Failed to find syscon regs for '%s'\n",
122 of_node_full_name(data
->np
));
123 return PTR_ERR(data
->sys_regs
);
129 static struct clk_hw
*ccu_pll_of_clk_hw_get(struct of_phandle_args
*clkspec
,
132 struct ccu_pll_data
*data
= priv
;
136 clk_id
= clkspec
->args
[0];
137 pll
= ccu_pll_find_desc(data
, clk_id
);
139 if (pll
!= ERR_PTR(-EPROBE_DEFER
))
140 pr_info("Invalid PLL clock ID %d specified\n", clk_id
);
142 return ERR_CAST(pll
);
145 return ccu_pll_get_clk_hw(pll
);
148 static int ccu_pll_clk_register(struct ccu_pll_data
*data
, bool defer
)
152 for (idx
= 0; idx
< CCU_PLL_NUM
; ++idx
) {
153 const struct ccu_pll_info
*info
= &pll_info
[idx
];
154 struct ccu_pll_init_data init
= {0};
156 /* Defer non-basic PLLs allocation for the probe stage */
157 if (!!(info
->features
& CCU_PLL_BASIC
) ^ defer
) {
158 if (!data
->plls
[idx
])
159 data
->plls
[idx
] = ERR_PTR(-EPROBE_DEFER
);
165 init
.name
= info
->name
;
166 init
.parent_name
= info
->parent_name
;
167 init
.base
= info
->base
;
168 init
.sys_regs
= data
->sys_regs
;
170 init
.flags
= info
->flags
;
171 init
.features
= info
->features
;
173 data
->plls
[idx
] = ccu_pll_hw_register(&init
);
174 if (IS_ERR(data
->plls
[idx
])) {
175 ret
= PTR_ERR(data
->plls
[idx
]);
176 pr_err("Couldn't register PLL hw '%s'\n",
178 goto err_hw_unregister
;
185 for (--idx
; idx
>= 0; --idx
) {
186 if (!!(pll_info
[idx
].features
& CCU_PLL_BASIC
) ^ defer
)
189 ccu_pll_hw_unregister(data
->plls
[idx
]);
195 static void ccu_pll_clk_unregister(struct ccu_pll_data
*data
, bool defer
)
199 /* Uninstall only the clocks registered on the specfied stage */
200 for (idx
= 0; idx
< CCU_PLL_NUM
; ++idx
) {
201 if (!!(pll_info
[idx
].features
& CCU_PLL_BASIC
) ^ defer
)
204 ccu_pll_hw_unregister(data
->plls
[idx
]);
208 static int ccu_pll_of_register(struct ccu_pll_data
*data
)
212 ret
= of_clk_add_hw_provider(data
->np
, ccu_pll_of_clk_hw_get
, data
);
214 pr_err("Couldn't register PLL provider of '%s'\n",
215 of_node_full_name(data
->np
));
221 static int ccu_pll_probe(struct platform_device
*pdev
)
223 struct ccu_pll_data
*data
= pll_data
;
228 return ccu_pll_clk_register(data
, false);
231 static const struct of_device_id ccu_pll_of_match
[] = {
232 { .compatible
= "baikal,bt1-ccu-pll" },
236 static struct platform_driver ccu_pll_driver
= {
237 .probe
= ccu_pll_probe
,
239 .name
= "clk-ccu-pll",
240 .of_match_table
= ccu_pll_of_match
,
241 .suppress_bind_attrs
= true,
244 builtin_platform_driver(ccu_pll_driver
);
246 static __init
void ccu_pll_init(struct device_node
*np
)
248 struct ccu_pll_data
*data
;
251 data
= ccu_pll_create_data(np
);
255 ret
= ccu_pll_find_sys_regs(data
);
259 ret
= ccu_pll_clk_register(data
, true);
263 ret
= ccu_pll_of_register(data
);
265 goto err_clk_unregister
;
272 ccu_pll_clk_unregister(data
, true);
275 ccu_pll_free_data(data
);
277 CLK_OF_DECLARE_DRIVER(ccu_pll
, "baikal,bt1-ccu-pll", ccu_pll_init
);