sandbox: add SCMI power domain protocol support for testing
SCMI power domain management protocol is supported on sandbox for test purpose. Add fake agent interfaces and associated power domain devices. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
c1d2ed0c63
commit
8e545b3781
|
@ -733,6 +733,11 @@
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pwrdom_scmi: protocol@11 {
|
||||
reg = <0x11>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
|
||||
clk_scmi: protocol@14 {
|
||||
reg = <0x14>;
|
||||
#clock-cells = <1>;
|
||||
|
@ -1647,6 +1652,7 @@
|
|||
|
||||
sandbox_scmi {
|
||||
compatible = "sandbox,scmi-devices";
|
||||
power-domains = <&pwrdom_scmi 2>;
|
||||
clocks = <&clk_scmi 2>, <&clk_scmi 0>;
|
||||
resets = <&reset_scmi 3>;
|
||||
regul0-supply = <®ul0_scmi>;
|
||||
|
|
|
@ -6,10 +6,22 @@
|
|||
#ifndef __SANDBOX_SCMI_TEST_H
|
||||
#define __SANDBOX_SCMI_TEST_H
|
||||
|
||||
#include <power-domain.h>
|
||||
|
||||
struct udevice;
|
||||
struct sandbox_scmi_agent;
|
||||
struct sandbox_scmi_service;
|
||||
|
||||
/**
|
||||
* struct sandbox_scmi_pwd
|
||||
* @id: Identifier of the power domain used in the SCMI protocol
|
||||
* @pstate:: Power state of the domain
|
||||
*/
|
||||
struct sandbox_scmi_pwd {
|
||||
uint id;
|
||||
u32 pstate;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sandbox_scmi_clk - Simulated clock exposed by SCMI
|
||||
* @id: Identifier of the clock used in the SCMI protocol
|
||||
|
@ -45,6 +57,8 @@ struct sandbox_scmi_voltd {
|
|||
|
||||
/**
|
||||
* struct sandbox_scmi_agent - Simulated SCMI service seen by SCMI agent
|
||||
* @pwdom_version: Implemented power domain protocol version
|
||||
* @pwdom_count: Simulated power domains array size
|
||||
* @clk: Simulated clocks
|
||||
* @clk_count: Simulated clocks array size
|
||||
* @reset: Simulated reset domains
|
||||
|
@ -53,6 +67,9 @@ struct sandbox_scmi_voltd {
|
|||
* @voltd_count: Simulated voltage domains array size
|
||||
*/
|
||||
struct sandbox_scmi_agent {
|
||||
int pwdom_version;
|
||||
struct sandbox_scmi_pwd *pwdom;
|
||||
size_t pwdom_count;
|
||||
struct sandbox_scmi_clk *clk;
|
||||
size_t clk_count;
|
||||
struct sandbox_scmi_reset *reset;
|
||||
|
@ -71,6 +88,8 @@ struct sandbox_scmi_service {
|
|||
|
||||
/**
|
||||
* struct sandbox_scmi_devices - Reference to devices probed through SCMI
|
||||
* @pwdom: Array of power domains
|
||||
* @pwdom_count: Number of power domains probed
|
||||
* @clk: Array the clock devices
|
||||
* @clk_count: Number of clock devices probed
|
||||
* @reset: Array the reset controller devices
|
||||
|
@ -79,6 +98,8 @@ struct sandbox_scmi_service {
|
|||
* @regul_count: Number of regulator devices probed
|
||||
*/
|
||||
struct sandbox_scmi_devices {
|
||||
struct power_domain *pwdom;
|
||||
size_t pwdom_count;
|
||||
struct clk *clk;
|
||||
size_t clk_count;
|
||||
struct reset_ctl *reset;
|
||||
|
|
|
@ -240,6 +240,7 @@ CONFIG_PINCTRL_SANDBOX=y
|
|||
CONFIG_PINCTRL_SINGLE=y
|
||||
CONFIG_POWER_DOMAIN=y
|
||||
CONFIG_SANDBOX_POWER_DOMAIN=y
|
||||
CONFIG_SCMI_POWER_DOMAIN=y
|
||||
CONFIG_DM_PMIC=y
|
||||
CONFIG_PMIC_ACT8846=y
|
||||
CONFIG_DM_PMIC_PFUZE100=y
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#define SANDBOX_SCMI_AGENT_NAME "OSPM"
|
||||
#define SANDBOX_SCMI_PLATFORM_NAME "platform"
|
||||
|
||||
#define SANDBOX_SCMI_PWD_PROTOCOL_VERSION SCMI_PWD_PROTOCOL_VERSION
|
||||
|
||||
/**
|
||||
* struct sandbox_channel - Description of sandbox transport
|
||||
* @channel_id: Channel identifier
|
||||
|
@ -64,6 +66,7 @@ struct scmi_channel {
|
|||
};
|
||||
|
||||
static u8 protocols[] = {
|
||||
SCMI_PROTOCOL_ID_POWER_DOMAIN,
|
||||
SCMI_PROTOCOL_ID_CLOCK,
|
||||
SCMI_PROTOCOL_ID_RESET_DOMAIN,
|
||||
SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN,
|
||||
|
@ -71,6 +74,12 @@ static u8 protocols[] = {
|
|||
|
||||
#define NUM_PROTOCOLS ARRAY_SIZE(protocols)
|
||||
|
||||
static struct sandbox_scmi_pwd scmi_pwdom[] = {
|
||||
{ .id = 0 },
|
||||
{ .id = 1 },
|
||||
{ .id = 2 },
|
||||
};
|
||||
|
||||
static struct sandbox_scmi_clk scmi_clk[] = {
|
||||
{ .rate = 333 },
|
||||
{ .rate = 200 },
|
||||
|
@ -458,6 +467,238 @@ static int sandbox_scmi_base_reset_agent_configuration(struct udevice *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Power Domain Management Protocol */
|
||||
|
||||
/**
|
||||
* sandbox_scmi_pwd_protocol_version - implement SCMI_PROTOCOL_VERSION
|
||||
* @dev: SCMI device
|
||||
* @msg: SCMI message
|
||||
*
|
||||
* Implement SCMI_PROTOCOL_VERSION command.
|
||||
*
|
||||
* Return: 0 on success, error code on failure
|
||||
*/
|
||||
static int sandbox_scmi_pwd_protocol_version(struct udevice *dev,
|
||||
struct scmi_msg *msg)
|
||||
{
|
||||
struct scmi_protocol_version_out *out = NULL;
|
||||
|
||||
if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
|
||||
return -EINVAL;
|
||||
|
||||
out = (struct scmi_protocol_version_out *)msg->out_msg;
|
||||
out->version = SANDBOX_SCMI_PWD_PROTOCOL_VERSION;
|
||||
out->status = SCMI_SUCCESS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sandbox_scmi_pwd_protocol_attribs - implement SCMI_PWD_PROTOCOL_ATTRS
|
||||
* @dev: SCMI device
|
||||
* @msg: SCMI message
|
||||
*
|
||||
* Implement SCMI_PWD_PROTOCOL_ATTRS command.
|
||||
*
|
||||
* Return: 0 on success, error code on failure
|
||||
*/
|
||||
static int sandbox_scmi_pwd_protocol_attribs(struct udevice *dev,
|
||||
struct scmi_msg *msg)
|
||||
{
|
||||
struct scmi_pwd_protocol_attrs_out *out;
|
||||
|
||||
if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
|
||||
return -EINVAL;
|
||||
|
||||
out = (struct scmi_pwd_protocol_attrs_out *)msg->out_msg;
|
||||
|
||||
out->attributes = ARRAY_SIZE(scmi_pwdom);
|
||||
out->stats_addr_low = 0;
|
||||
out->stats_addr_high = 0;
|
||||
out->stats_len = 0;
|
||||
out->status = SCMI_SUCCESS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sandbox_scmi_pwd_protocol_msg_attribs - implement
|
||||
SCMI_PWD_PROTOCOL_MESSAGE_ATTRS
|
||||
* @dev: SCMI device
|
||||
* @msg: SCMI message
|
||||
*
|
||||
* Implement SCMI_PWD_PROTOCOL_MESSAGE_ATTRS command.
|
||||
*
|
||||
* Return: 0 on success, error code on failure
|
||||
*/
|
||||
static int sandbox_scmi_pwd_protocol_msg_attribs(struct udevice *dev,
|
||||
struct scmi_msg *msg)
|
||||
{
|
||||
u32 message_id;
|
||||
struct scmi_pwd_protocol_msg_attrs_out *out;
|
||||
|
||||
if (!msg->in_msg || msg->in_msg_sz < sizeof(message_id) ||
|
||||
!msg->out_msg || msg->out_msg_sz < sizeof(*out))
|
||||
return -EINVAL;
|
||||
|
||||
message_id = *(u32 *)msg->in_msg;
|
||||
|
||||
out = (struct scmi_pwd_protocol_msg_attrs_out *)msg->out_msg;
|
||||
if (message_id <= SCMI_PWD_STATE_GET ||
|
||||
message_id == SCMI_PWD_NAME_GET) {
|
||||
out->attributes = 0;
|
||||
out->status = SCMI_SUCCESS;
|
||||
} else {
|
||||
out->status = SCMI_NOT_FOUND;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sandbox_scmi_pwd_attribs - implement SCMI_PWD_ATTRS
|
||||
* @dev: SCMI device
|
||||
* @msg: SCMI message
|
||||
*
|
||||
* Implement SCMI_PWD_ATTRS command.
|
||||
*
|
||||
* Return: 0 on success, error code on failure
|
||||
*/
|
||||
static int sandbox_scmi_pwd_attribs(struct udevice *dev, struct scmi_msg *msg)
|
||||
{
|
||||
u32 domain_id;
|
||||
struct scmi_pwd_attrs_out *out;
|
||||
|
||||
if (!msg->in_msg || msg->in_msg_sz < sizeof(domain_id) ||
|
||||
!msg->out_msg || msg->out_msg_sz < sizeof(*out))
|
||||
return -EINVAL;
|
||||
|
||||
domain_id = *(u32 *)msg->in_msg;
|
||||
out = (struct scmi_pwd_attrs_out *)msg->out_msg;
|
||||
|
||||
if (domain_id > ARRAY_SIZE(scmi_pwdom)) {
|
||||
out->status = SCMI_NOT_FOUND;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
out->attributes =
|
||||
SCMI_PWD_ATTR_PSTATE_SYNC | SCMI_PWD_ATTR_EXTENDED_NAME;
|
||||
/* just 15-char + NULL */
|
||||
snprintf(out->name, SCMI_PWD_NAME_LENGTH_MAX, "power-domain--%d",
|
||||
domain_id);
|
||||
out->status = SCMI_SUCCESS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sandbox_scmi_pwd_state_set - implement SCMI_PWD_STATE_SET
|
||||
* @dev: SCMI device
|
||||
* @msg: SCMI message
|
||||
*
|
||||
* Implement SCMI_PWD_STATE_SET command.
|
||||
*
|
||||
* Return: 0 on success, error code on failure
|
||||
*/
|
||||
static int sandbox_scmi_pwd_state_set(struct udevice *dev, struct scmi_msg *msg)
|
||||
{
|
||||
struct scmi_pwd_state_set_in *in;
|
||||
s32 *status;
|
||||
|
||||
if (!msg->in_msg || msg->in_msg_sz < sizeof(in) ||
|
||||
!msg->out_msg || msg->out_msg_sz < sizeof(*status))
|
||||
return -EINVAL;
|
||||
|
||||
in = (struct scmi_pwd_state_set_in *)msg->in_msg;
|
||||
status = (s32 *)msg->out_msg;
|
||||
|
||||
if (in->domain_id > ARRAY_SIZE(scmi_pwdom)) {
|
||||
*status = SCMI_NOT_FOUND;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((in->flags & SCMI_PWD_SET_FLAGS_ASYNC) ||
|
||||
(in->pstate != SCMI_PWD_PSTATE_TYPE_LOST && in->pstate)) {
|
||||
*status = SCMI_INVALID_PARAMETERS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
scmi_pwdom[in->domain_id].pstate = in->pstate;
|
||||
*status = SCMI_SUCCESS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sandbox_scmi_pwd_state_get - implement SCMI_PWD_STATE_GET
|
||||
* @dev: SCMI device
|
||||
* @msg: SCMI message
|
||||
*
|
||||
* Implement SCMI_PWD_STATE_GET command.
|
||||
*
|
||||
* Return: 0 on success, error code on failure
|
||||
*/
|
||||
static int sandbox_scmi_pwd_state_get(struct udevice *dev, struct scmi_msg *msg)
|
||||
{
|
||||
u32 domain_id;
|
||||
struct scmi_pwd_state_get_out *out;
|
||||
|
||||
if (!msg->in_msg || msg->in_msg_sz < sizeof(domain_id) ||
|
||||
!msg->out_msg || msg->out_msg_sz < sizeof(*out))
|
||||
return -EINVAL;
|
||||
|
||||
domain_id = *(u32 *)msg->in_msg;
|
||||
out = (struct scmi_pwd_state_get_out *)msg->out_msg;
|
||||
|
||||
if (domain_id > ARRAY_SIZE(scmi_pwdom)) {
|
||||
out->status = SCMI_NOT_FOUND;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
out->pstate = scmi_pwdom[domain_id].pstate;
|
||||
out->status = SCMI_SUCCESS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sandbox_scmi_pwd_name_get - implement SCMI_PWD_NAME_GET
|
||||
* @dev: SCMI device
|
||||
* @msg: SCMI message
|
||||
*
|
||||
* Implement SCMI_PWD_NAME_GET command.
|
||||
*
|
||||
* Return: 0 on success, error code on failure
|
||||
*/
|
||||
static int sandbox_scmi_pwd_name_get(struct udevice *dev, struct scmi_msg *msg)
|
||||
{
|
||||
u32 domain_id;
|
||||
struct scmi_pwd_name_get_out *out;
|
||||
|
||||
if (!msg->in_msg || msg->in_msg_sz < sizeof(domain_id) ||
|
||||
!msg->out_msg || msg->out_msg_sz < sizeof(*out))
|
||||
return -EINVAL;
|
||||
|
||||
domain_id = *(u32 *)msg->in_msg;
|
||||
out = (struct scmi_pwd_name_get_out *)msg->out_msg;
|
||||
|
||||
if (domain_id > ARRAY_SIZE(scmi_pwdom)) {
|
||||
out->status = SCMI_NOT_FOUND;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf(out->extended_name, SCMI_PWD_EXTENDED_NAME_MAX,
|
||||
"power-domain--%d-extended", domain_id);
|
||||
out->status = SCMI_SUCCESS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Clock Protocol */
|
||||
|
||||
static int sandbox_scmi_clock_protocol_attribs(struct udevice *dev,
|
||||
|
@ -918,6 +1159,26 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev,
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case SCMI_PROTOCOL_ID_POWER_DOMAIN:
|
||||
switch (msg->message_id) {
|
||||
case SCMI_PROTOCOL_VERSION:
|
||||
return sandbox_scmi_pwd_protocol_version(dev, msg);
|
||||
case SCMI_PROTOCOL_ATTRIBUTES:
|
||||
return sandbox_scmi_pwd_protocol_attribs(dev, msg);
|
||||
case SCMI_PROTOCOL_MESSAGE_ATTRIBUTES:
|
||||
return sandbox_scmi_pwd_protocol_msg_attribs(dev, msg);
|
||||
case SCMI_PWD_ATTRIBUTES:
|
||||
return sandbox_scmi_pwd_attribs(dev, msg);
|
||||
case SCMI_PWD_STATE_SET:
|
||||
return sandbox_scmi_pwd_state_set(dev, msg);
|
||||
case SCMI_PWD_STATE_GET:
|
||||
return sandbox_scmi_pwd_state_get(dev, msg);
|
||||
case SCMI_PWD_NAME_GET:
|
||||
return sandbox_scmi_pwd_name_get(dev, msg);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SCMI_PROTOCOL_ID_CLOCK:
|
||||
switch (msg->message_id) {
|
||||
case SCMI_PROTOCOL_ATTRIBUTES:
|
||||
|
@ -960,7 +1221,6 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev,
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case SCMI_PROTOCOL_ID_POWER_DOMAIN:
|
||||
case SCMI_PROTOCOL_ID_SYSTEM:
|
||||
case SCMI_PROTOCOL_ID_PERF:
|
||||
case SCMI_PROTOCOL_ID_SENSOR:
|
||||
|
@ -993,6 +1253,9 @@ static int sandbox_scmi_test_probe(struct udevice *dev)
|
|||
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
|
||||
|
||||
*agent = (struct sandbox_scmi_agent){
|
||||
.pwdom_version = SANDBOX_SCMI_PWD_PROTOCOL_VERSION,
|
||||
.pwdom = scmi_pwdom,
|
||||
.pwdom_count = ARRAY_SIZE(scmi_pwdom),
|
||||
.clk = scmi_clk,
|
||||
.clk_count = ARRAY_SIZE(scmi_clk),
|
||||
.reset = scmi_reset,
|
||||
|
|
|
@ -29,12 +29,14 @@
|
|||
|
||||
/*
|
||||
* struct sandbox_scmi_device_priv - Storage for device handles used by test
|
||||
* @pwdom: Power domain device
|
||||
* @clk: Array of clock instances used by tests
|
||||
* @reset_clt: Array of the reset controller instances used by tests
|
||||
* @regulators: Array of regulator device references used by the tests
|
||||
* @devices: Resources exposed by sandbox_scmi_devices_ctx()
|
||||
*/
|
||||
struct sandbox_scmi_device_priv {
|
||||
struct power_domain pwdom;
|
||||
struct clk clk[SCMI_TEST_DEVICES_CLK_COUNT];
|
||||
struct reset_ctl reset_ctl[SCMI_TEST_DEVICES_RD_COUNT];
|
||||
struct udevice *regulators[SCMI_TEST_DEVICES_VOLTD_COUNT];
|
||||
|
@ -77,6 +79,8 @@ static int sandbox_scmi_devices_probe(struct udevice *dev)
|
|||
size_t n;
|
||||
|
||||
priv->devices = (struct sandbox_scmi_devices){
|
||||
.pwdom = &priv->pwdom,
|
||||
.pwdom_count = 1,
|
||||
.clk = priv->clk,
|
||||
.clk_count = SCMI_TEST_DEVICES_CLK_COUNT,
|
||||
.reset = priv->reset_ctl,
|
||||
|
@ -85,6 +89,12 @@ static int sandbox_scmi_devices_probe(struct udevice *dev)
|
|||
.regul_count = SCMI_TEST_DEVICES_VOLTD_COUNT,
|
||||
};
|
||||
|
||||
ret = power_domain_get_by_index(dev, priv->devices.pwdom, 0);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: Failed on power domain\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (n = 0; n < SCMI_TEST_DEVICES_CLK_COUNT; n++) {
|
||||
ret = clk_get_by_index(dev, n, priv->devices.clk + n);
|
||||
if (ret) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user