soc/qcom: rpmh: add RPMh read

Implement support for RPMh reads, these allow reading out the
current votes for RPMh controlled resources such as regulators and
interconnects.

Link: https://patch.msgid.link/20260108-rpmh-regulator-fixes-v1-4-d1b5b300b665@linaro.org
Signed-off-by: Casey Connolly <casey.connolly@linaro.org>
This commit is contained in:
Casey Connolly
2026-01-08 21:28:46 +01:00
parent 5942ad0ddb
commit dc1cd6ed4b
4 changed files with 51 additions and 5 deletions

View File

@@ -282,12 +282,15 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
const struct tcs_request *msg)
{
u32 msgid;
u32 cmd_msgid = CMD_MSGID_LEN | CMD_MSGID_WRITE;
u32 cmd_msgid = CMD_MSGID_LEN;
u32 cmd_enable = 0;
u32 cmd_complete = 0;
struct tcs_cmd *cmd;
int i, j;
if (!msg->is_read)
cmd_msgid |= CMD_MSGID_WRITE;
if (msg->wait_for_compl)
cmd_msgid |= CMD_MSGID_RESP_REQ;
@@ -302,7 +305,8 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_MSGID], tcs_id, j, msgid);
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], tcs_id, j, cmd->addr);
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data);
if (!msg->is_read)
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data);
debug("tcs(%d): [%s] cmd_id: %d: msgid: %#x addr: %#x data: %#x complete: %#x\n",
tcs_id, msg->state == RPMH_ACTIVE_ONLY_STATE ? "active" : "?", j, msgid,
cmd->addr, cmd->data, cmd_complete);
@@ -418,6 +422,12 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg)
udelay(1);
}
/* U-Boot: read the response now we know it's available */
if (msg->is_read) {
msg->cmds[0].data = read_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_RESP_DATA], tcs_id, 0);
log_debug("data response: %#x\n", msg->cmds[0].data);
}
__tcs_set_trigger(drv, tcs_id, false);
/* Reclaim the TCS */

View File

@@ -68,7 +68,7 @@ static int __rpmh_write(const struct udevice *dev, enum rpmh_state state,
}
static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state,
const struct tcs_cmd *cmd, u32 n)
const struct tcs_cmd *cmd, u32 n, bool is_read)
{
if (!cmd || !n || n > MAX_RPMH_PAYLOAD)
return -EINVAL;
@@ -78,12 +78,45 @@ static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state,
req->msg.state = state;
req->msg.cmds = req->cmd;
req->msg.num_cmds = n;
req->msg.is_read = is_read;
debug("rpmh_msg: %d, %d cmds [first %#x/%#x]\n", state, n, cmd->addr, cmd->data);
return 0;
}
/**
* rpmh_read: Read a resource value
*
* @dev: The device making the request
* @cmd: The payload having address of resource to read
*
* Reads the value for the resource address given in tcs_cmd->addr
* and returns the tcs_cmd->data filled with same.
*
* May sleep. Do not call from atomic contexts.
*
* Return: 0 on success, negative errno on failure
*/
int rpmh_read(const struct udevice *dev, enum rpmh_state state, struct tcs_cmd *cmd)
{
DEFINE_RPMH_MSG_ONSTACK(dev, state, rpm_msg);
int ret;
ret = __fill_rpmh_msg(&rpm_msg, state, cmd, 1, true);
if (ret)
return ret;
ret = __rpmh_write(dev, state, &rpm_msg);
if (ret)
return ret;
/* Read back the response into the cmd data structure */
cmd->data = rpm_msg.cmd[0].data;
return (ret > 0) ? 0 : ret;
}
/**
* rpmh_write: Write a set of RPMH commands and block until response
*
@@ -100,7 +133,7 @@ int rpmh_write(const struct udevice *dev, enum rpmh_state state,
DEFINE_RPMH_MSG_ONSTACK(dev, state, rpm_msg);
int ret;
ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n);
ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n, false);
if (ret)
return ret;

View File

@@ -13,12 +13,14 @@
#if IS_ENABLED(CONFIG_QCOM_RPMH)
int rpmh_write(const struct udevice *dev, enum rpmh_state state,
const struct tcs_cmd *cmd, u32 n);
int rpmh_read(const struct udevice *dev, enum rpmh_state state, struct tcs_cmd *cmd);
#else
static inline int rpmh_write(const struct device *dev, enum rpmh_state state,
const struct tcs_cmd *cmd, u32 n)
{ return -ENODEV; }
static inline int rpmh_read(const struct udevice *dev, struct tcs_cmd *cmd)
{ return -ENODEV; }
#endif /* CONFIG_QCOM_RPMH */

View File

@@ -55,6 +55,7 @@ struct tcs_cmd {
*/
struct tcs_request {
enum rpmh_state state;
bool is_read;
u32 wait_for_compl;
u32 num_cmds;
struct tcs_cmd *cmds;