blob: d6d4b37518fcd74116bf2cc57fa8867b3f0ed354 [file] [log] [blame]
XiaoDong Huang51c6bf82023-06-25 17:38:13 +08001/*
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
15size_t rockchip_scmi_clock_count(unsigned int agent_id __unused)
16{
17 return 0;
18}
19
20rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id __unused,
21 uint32_t scmi_id __unused)
22{
23 return NULL;
24}
25
26size_t plat_scmi_clock_count(unsigned int agent_id)
27{
28 return rockchip_scmi_clock_count(agent_id);
29}
30
31const 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
43int32_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
72out:
73 return SCMI_SUCCESS;
74}
75
76int32_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
83unsigned 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
103int32_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
125int32_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
137int32_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}