blob: d6d4b37518fcd74116bf2cc57fa8867b3f0ed354 [file] [log] [blame]
/*
* Copyright (c) 2024, Rockchip, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <drivers/scmi-msg.h>
#include <drivers/scmi.h>
#include "scmi_clock.h"
#pragma weak rockchip_scmi_clock_count
#pragma weak rockchip_scmi_get_clock
size_t rockchip_scmi_clock_count(unsigned int agent_id __unused)
{
return 0;
}
rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id __unused,
uint32_t scmi_id __unused)
{
return NULL;
}
size_t plat_scmi_clock_count(unsigned int agent_id)
{
return rockchip_scmi_clock_count(agent_id);
}
const char *plat_scmi_clock_get_name(unsigned int agent_id,
unsigned int scmi_id)
{
rk_scmi_clock_t *clock;
clock = rockchip_scmi_get_clock(agent_id, scmi_id);
if (clock == NULL)
return NULL;
return clock->name;
}
int32_t plat_scmi_clock_rates_array(unsigned int agent_id,
unsigned int scmi_id,
unsigned long *rates,
size_t *nb_elts,
uint32_t start_idx)
{
uint32_t i;
unsigned long *rate_table;
rk_scmi_clock_t *clock;
clock = rockchip_scmi_get_clock(agent_id, scmi_id);
if (clock == NULL)
return SCMI_NOT_FOUND;
rate_table = clock->rate_table;
if (rate_table == NULL)
return SCMI_NOT_SUPPORTED;
if (rates == 0) {
*nb_elts = clock->rate_cnt;
goto out;
}
if (start_idx + *nb_elts > clock->rate_cnt)
return SCMI_OUT_OF_RANGE;
for (i = 0; i < *nb_elts; i++)
rates[i] = rate_table[start_idx + i];
out:
return SCMI_SUCCESS;
}
int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id __unused,
unsigned int scmi_id __unused,
unsigned long *steps __unused)
{
return SCMI_NOT_SUPPORTED;
}
unsigned long plat_scmi_clock_get_rate(unsigned int agent_id,
unsigned int scmi_id)
{
rk_scmi_clock_t *clock;
unsigned long rate = 0;
clock = rockchip_scmi_get_clock(agent_id, scmi_id);
if (clock == NULL)
return 0;
if (clock->clk_ops && clock->clk_ops->get_rate)
rate = clock->clk_ops->get_rate(clock);
/* return cur_rate if no get_rate ops or get_rate return 0 */
if (rate == 0)
rate = clock->cur_rate;
return rate;
}
int32_t plat_scmi_clock_set_rate(unsigned int agent_id,
unsigned int scmi_id,
unsigned long rate)
{
rk_scmi_clock_t *clock;
int32_t status = 0;
clock = rockchip_scmi_get_clock(agent_id, scmi_id);
if (clock == NULL)
return SCMI_NOT_FOUND;
if (clock->clk_ops && clock->clk_ops->set_rate) {
status = clock->clk_ops->set_rate(clock, rate);
if (status == SCMI_SUCCESS)
clock->cur_rate = rate;
} else {
status = SCMI_NOT_SUPPORTED;
}
return status;
}
int32_t plat_scmi_clock_get_state(unsigned int agent_id,
unsigned int scmi_id)
{
rk_scmi_clock_t *clock;
clock = rockchip_scmi_get_clock(agent_id, scmi_id);
if (clock == NULL)
return 0;
return clock->enable;
}
int32_t plat_scmi_clock_set_state(unsigned int agent_id,
unsigned int scmi_id,
bool enable_not_disable)
{
rk_scmi_clock_t *clock;
int32_t status = 0;
clock = rockchip_scmi_get_clock(agent_id, scmi_id);
if (clock == NULL)
return SCMI_NOT_FOUND;
if (clock->clk_ops && clock->clk_ops->set_status) {
status = clock->clk_ops->set_status(clock, enable_not_disable);
if (status == SCMI_SUCCESS)
clock->enable = enable_not_disable;
} else {
status = SCMI_NOT_SUPPORTED;
}
return status;
}