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 15 size_t rockchip_scmi_clock_count(unsigned int agent_id __unused) 16 { 17 return 0; 18 } 19 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 26 size_t plat_scmi_clock_count(unsigned int agent_id) 27 { 28 return rockchip_scmi_clock_count(agent_id); 29 } 30 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 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 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 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 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 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 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