• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <drivers/scmi-msg.h>
8 #include <drivers/scmi.h>
9 
10 #include "scmi_clock.h"
11 
12 #pragma weak rockchip_scmi_clock_count
13 #pragma weak rockchip_scmi_get_clock
14 
rockchip_scmi_clock_count(unsigned int agent_id __unused)15 size_t rockchip_scmi_clock_count(unsigned int agent_id __unused)
16 {
17 	return 0;
18 }
19 
rockchip_scmi_get_clock(uint32_t agent_id __unused,uint32_t scmi_id __unused)20 rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id __unused,
21 					 uint32_t scmi_id __unused)
22 {
23 	return NULL;
24 }
25 
plat_scmi_clock_count(unsigned int agent_id)26 size_t plat_scmi_clock_count(unsigned int agent_id)
27 {
28 	return rockchip_scmi_clock_count(agent_id);
29 }
30 
plat_scmi_clock_get_name(unsigned int agent_id,unsigned int scmi_id)31 const char *plat_scmi_clock_get_name(unsigned int agent_id,
32 				     unsigned int scmi_id)
33 {
34 	rk_scmi_clock_t *clock;
35 
36 	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
37 	if (clock == NULL)
38 		return NULL;
39 
40 	return clock->name;
41 }
42 
plat_scmi_clock_rates_array(unsigned int agent_id,unsigned int scmi_id,unsigned long * rates,size_t * nb_elts,uint32_t start_idx)43 int32_t plat_scmi_clock_rates_array(unsigned int agent_id,
44 				    unsigned int scmi_id,
45 				    unsigned long *rates,
46 				    size_t *nb_elts,
47 				    uint32_t start_idx)
48 {
49 	uint32_t i;
50 	unsigned long *rate_table;
51 	rk_scmi_clock_t *clock;
52 
53 	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
54 	if (clock == NULL)
55 		return SCMI_NOT_FOUND;
56 
57 	rate_table = clock->rate_table;
58 	if (rate_table == NULL)
59 		return SCMI_NOT_SUPPORTED;
60 
61 	if (rates == 0) {
62 		*nb_elts = clock->rate_cnt;
63 		goto out;
64 	}
65 
66 	if (start_idx + *nb_elts > clock->rate_cnt)
67 		return SCMI_OUT_OF_RANGE;
68 
69 	for (i = 0; i < *nb_elts; i++)
70 		rates[i] = rate_table[start_idx + i];
71 
72 out:
73 	return SCMI_SUCCESS;
74 }
75 
plat_scmi_clock_rates_by_step(unsigned int agent_id __unused,unsigned int scmi_id __unused,unsigned long * steps __unused)76 int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id __unused,
77 				      unsigned int scmi_id __unused,
78 				      unsigned long *steps __unused)
79 {
80 	return SCMI_NOT_SUPPORTED;
81 }
82 
plat_scmi_clock_get_rate(unsigned int agent_id,unsigned int scmi_id)83 unsigned long plat_scmi_clock_get_rate(unsigned int agent_id,
84 				       unsigned int scmi_id)
85 {
86 	rk_scmi_clock_t *clock;
87 	unsigned long rate = 0;
88 
89 	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
90 	if (clock == NULL)
91 		return 0;
92 
93 	if (clock->clk_ops && clock->clk_ops->get_rate)
94 		rate = clock->clk_ops->get_rate(clock);
95 
96 	/* return cur_rate if no get_rate ops or get_rate return 0 */
97 	if (rate == 0)
98 		rate = clock->cur_rate;
99 
100 	return rate;
101 }
102 
plat_scmi_clock_set_rate(unsigned int agent_id,unsigned int scmi_id,unsigned long rate)103 int32_t plat_scmi_clock_set_rate(unsigned int agent_id,
104 				 unsigned int scmi_id,
105 				 unsigned long rate)
106 {
107 	rk_scmi_clock_t *clock;
108 	int32_t status = 0;
109 
110 	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
111 	if (clock == NULL)
112 		return SCMI_NOT_FOUND;
113 
114 	if (clock->clk_ops && clock->clk_ops->set_rate) {
115 		status = clock->clk_ops->set_rate(clock, rate);
116 		if (status == SCMI_SUCCESS)
117 			clock->cur_rate = rate;
118 	} else {
119 		status = SCMI_NOT_SUPPORTED;
120 	}
121 
122 	return status;
123 }
124 
plat_scmi_clock_get_state(unsigned int agent_id,unsigned int scmi_id)125 int32_t plat_scmi_clock_get_state(unsigned int agent_id,
126 				  unsigned int scmi_id)
127 {
128 	rk_scmi_clock_t *clock;
129 
130 	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
131 	if (clock == NULL)
132 		return 0;
133 
134 	return clock->enable;
135 }
136 
plat_scmi_clock_set_state(unsigned int agent_id,unsigned int scmi_id,bool enable_not_disable)137 int32_t plat_scmi_clock_set_state(unsigned int agent_id,
138 				  unsigned int scmi_id,
139 				  bool enable_not_disable)
140 {
141 	rk_scmi_clock_t *clock;
142 	int32_t status = 0;
143 
144 	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
145 	if (clock == NULL)
146 		return SCMI_NOT_FOUND;
147 
148 	if (clock->clk_ops && clock->clk_ops->set_status) {
149 		status = clock->clk_ops->set_status(clock, enable_not_disable);
150 		if (status == SCMI_SUCCESS)
151 			clock->enable = enable_not_disable;
152 	} else {
153 		status = SCMI_NOT_SUPPORTED;
154 	}
155 
156 	return status;
157 }
158