xref: /rk3399_ARM-atf/drivers/clk/clk.c (revision 19f9e2e657918d023c9836f8330a967e97a45d7e)
1847c6bc8SGabriel Fernandez /*
2847c6bc8SGabriel Fernandez  * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
3847c6bc8SGabriel Fernandez  * Author(s): Ludovic Barre, <ludovic.barre@st.com> for STMicroelectronics.
4847c6bc8SGabriel Fernandez  *
5847c6bc8SGabriel Fernandez  * SPDX-License-Identifier: BSD-3-Clause
6847c6bc8SGabriel Fernandez  */
7847c6bc8SGabriel Fernandez 
8847c6bc8SGabriel Fernandez #include <assert.h>
9847c6bc8SGabriel Fernandez #include <errno.h>
10847c6bc8SGabriel Fernandez #include <stdbool.h>
11847c6bc8SGabriel Fernandez 
12847c6bc8SGabriel Fernandez #include <drivers/clk.h>
13847c6bc8SGabriel Fernandez 
14847c6bc8SGabriel Fernandez static const struct clk_ops *ops;
15847c6bc8SGabriel Fernandez 
16847c6bc8SGabriel Fernandez int clk_enable(unsigned long id)
17847c6bc8SGabriel Fernandez {
18847c6bc8SGabriel Fernandez 	assert((ops != NULL) && (ops->enable != NULL));
19847c6bc8SGabriel Fernandez 
20847c6bc8SGabriel Fernandez 	return ops->enable(id);
21847c6bc8SGabriel Fernandez }
22847c6bc8SGabriel Fernandez 
23847c6bc8SGabriel Fernandez void clk_disable(unsigned long id)
24847c6bc8SGabriel Fernandez {
25847c6bc8SGabriel Fernandez 	assert((ops != NULL) && (ops->disable != NULL));
26847c6bc8SGabriel Fernandez 
27847c6bc8SGabriel Fernandez 	ops->disable(id);
28847c6bc8SGabriel Fernandez }
29847c6bc8SGabriel Fernandez 
30847c6bc8SGabriel Fernandez unsigned long clk_get_rate(unsigned long id)
31847c6bc8SGabriel Fernandez {
32847c6bc8SGabriel Fernandez 	assert((ops != NULL) && (ops->get_rate != NULL));
33847c6bc8SGabriel Fernandez 
34847c6bc8SGabriel Fernandez 	return ops->get_rate(id);
35847c6bc8SGabriel Fernandez }
36847c6bc8SGabriel Fernandez 
37*19f9e2e6SGhennadi Procopciuc int clk_set_rate(unsigned long id, unsigned long rate, unsigned long *orate)
38*19f9e2e6SGhennadi Procopciuc {
39*19f9e2e6SGhennadi Procopciuc 	unsigned long lrate;
40*19f9e2e6SGhennadi Procopciuc 
41*19f9e2e6SGhennadi Procopciuc 	assert((ops != NULL) && (ops->set_rate != NULL));
42*19f9e2e6SGhennadi Procopciuc 
43*19f9e2e6SGhennadi Procopciuc 	if (orate != NULL) {
44*19f9e2e6SGhennadi Procopciuc 		return ops->set_rate(id, rate, orate);
45*19f9e2e6SGhennadi Procopciuc 	}
46*19f9e2e6SGhennadi Procopciuc 
47*19f9e2e6SGhennadi Procopciuc 	/* In case the caller is not interested in the output rate */
48*19f9e2e6SGhennadi Procopciuc 	return ops->set_rate(id, rate, &lrate);
49*19f9e2e6SGhennadi Procopciuc }
50*19f9e2e6SGhennadi Procopciuc 
51847c6bc8SGabriel Fernandez int clk_get_parent(unsigned long id)
52847c6bc8SGabriel Fernandez {
53847c6bc8SGabriel Fernandez 	assert((ops != NULL) && (ops->get_parent != NULL));
54847c6bc8SGabriel Fernandez 
55847c6bc8SGabriel Fernandez 	return ops->get_parent(id);
56847c6bc8SGabriel Fernandez }
57847c6bc8SGabriel Fernandez 
58a2c6016fSGhennadi Procopciuc int clk_set_parent(unsigned long id, unsigned long parent_id)
59a2c6016fSGhennadi Procopciuc {
60a2c6016fSGhennadi Procopciuc 	assert((ops != NULL) && (ops->set_parent != NULL));
61a2c6016fSGhennadi Procopciuc 
62a2c6016fSGhennadi Procopciuc 	return ops->set_parent(id, parent_id);
63a2c6016fSGhennadi Procopciuc }
64a2c6016fSGhennadi Procopciuc 
65847c6bc8SGabriel Fernandez bool clk_is_enabled(unsigned long id)
66847c6bc8SGabriel Fernandez {
67847c6bc8SGabriel Fernandez 	assert((ops != NULL) && (ops->is_enabled != NULL));
68847c6bc8SGabriel Fernandez 
69847c6bc8SGabriel Fernandez 	return ops->is_enabled(id);
70847c6bc8SGabriel Fernandez }
71847c6bc8SGabriel Fernandez 
72847c6bc8SGabriel Fernandez /*
73847c6bc8SGabriel Fernandez  * Initialize the clk. The fields in the provided clk
74847c6bc8SGabriel Fernandez  * ops pointer must be valid.
75847c6bc8SGabriel Fernandez  */
76847c6bc8SGabriel Fernandez void clk_register(const struct clk_ops *ops_ptr)
77847c6bc8SGabriel Fernandez {
78847c6bc8SGabriel Fernandez 	assert((ops_ptr != NULL) &&
79847c6bc8SGabriel Fernandez 	       (ops_ptr->enable != NULL) &&
80847c6bc8SGabriel Fernandez 	       (ops_ptr->disable != NULL) &&
81847c6bc8SGabriel Fernandez 	       (ops_ptr->get_rate != NULL) &&
82847c6bc8SGabriel Fernandez 	       (ops_ptr->get_parent != NULL) &&
83847c6bc8SGabriel Fernandez 	       (ops_ptr->is_enabled != NULL));
84847c6bc8SGabriel Fernandez 
85847c6bc8SGabriel Fernandez 	ops = ops_ptr;
86847c6bc8SGabriel Fernandez }
87