"Das U-Boot" Source Tree

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>

+51 -5
+12 -2
drivers/soc/qcom/rpmh-rsc.c
··· 282 282 const struct tcs_request *msg) 283 283 { 284 284 u32 msgid; 285 - u32 cmd_msgid = CMD_MSGID_LEN | CMD_MSGID_WRITE; 285 + u32 cmd_msgid = CMD_MSGID_LEN; 286 286 u32 cmd_enable = 0; 287 287 u32 cmd_complete = 0; 288 288 struct tcs_cmd *cmd; 289 289 int i, j; 290 + 291 + if (!msg->is_read) 292 + cmd_msgid |= CMD_MSGID_WRITE; 290 293 291 294 if (msg->wait_for_compl) 292 295 cmd_msgid |= CMD_MSGID_RESP_REQ; ··· 302 305 303 306 write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_MSGID], tcs_id, j, msgid); 304 307 write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], tcs_id, j, cmd->addr); 305 - write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data); 308 + if (!msg->is_read) 309 + write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data); 306 310 debug("tcs(%d): [%s] cmd_id: %d: msgid: %#x addr: %#x data: %#x complete: %#x\n", 307 311 tcs_id, msg->state == RPMH_ACTIVE_ONLY_STATE ? "active" : "?", j, msgid, 308 312 cmd->addr, cmd->data, cmd_complete); ··· 416 420 if (val & CMD_STATUS_COMPL) 417 421 break; 418 422 udelay(1); 423 + } 424 + 425 + /* U-Boot: read the response now we know it's available */ 426 + if (msg->is_read) { 427 + msg->cmds[0].data = read_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_RESP_DATA], tcs_id, 0); 428 + log_debug("data response: %#x\n", msg->cmds[0].data); 419 429 } 420 430 421 431 __tcs_set_trigger(drv, tcs_id, false);
+35 -2
drivers/soc/qcom/rpmh.c
··· 68 68 } 69 69 70 70 static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state, 71 - const struct tcs_cmd *cmd, u32 n) 71 + const struct tcs_cmd *cmd, u32 n, bool is_read) 72 72 { 73 73 if (!cmd || !n || n > MAX_RPMH_PAYLOAD) 74 74 return -EINVAL; ··· 78 78 req->msg.state = state; 79 79 req->msg.cmds = req->cmd; 80 80 req->msg.num_cmds = n; 81 + req->msg.is_read = is_read; 81 82 82 83 debug("rpmh_msg: %d, %d cmds [first %#x/%#x]\n", state, n, cmd->addr, cmd->data); 83 84 ··· 85 86 } 86 87 87 88 /** 89 + * rpmh_read: Read a resource value 90 + * 91 + * @dev: The device making the request 92 + * @cmd: The payload having address of resource to read 93 + * 94 + * Reads the value for the resource address given in tcs_cmd->addr 95 + * and returns the tcs_cmd->data filled with same. 96 + * 97 + * May sleep. Do not call from atomic contexts. 98 + * 99 + * Return: 0 on success, negative errno on failure 100 + */ 101 + int rpmh_read(const struct udevice *dev, enum rpmh_state state, struct tcs_cmd *cmd) 102 + { 103 + DEFINE_RPMH_MSG_ONSTACK(dev, state, rpm_msg); 104 + int ret; 105 + 106 + ret = __fill_rpmh_msg(&rpm_msg, state, cmd, 1, true); 107 + if (ret) 108 + return ret; 109 + 110 + ret = __rpmh_write(dev, state, &rpm_msg); 111 + if (ret) 112 + return ret; 113 + 114 + /* Read back the response into the cmd data structure */ 115 + cmd->data = rpm_msg.cmd[0].data; 116 + 117 + return (ret > 0) ? 0 : ret; 118 + } 119 + 120 + /** 88 121 * rpmh_write: Write a set of RPMH commands and block until response 89 122 * 90 123 * @dev: The device making the request ··· 100 133 DEFINE_RPMH_MSG_ONSTACK(dev, state, rpm_msg); 101 134 int ret; 102 135 103 - ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n); 136 + ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n, false); 104 137 if (ret) 105 138 return ret; 106 139
+3 -1
include/soc/qcom/rpmh.h
··· 13 13 #if IS_ENABLED(CONFIG_QCOM_RPMH) 14 14 int rpmh_write(const struct udevice *dev, enum rpmh_state state, 15 15 const struct tcs_cmd *cmd, u32 n); 16 - 16 + int rpmh_read(const struct udevice *dev, enum rpmh_state state, struct tcs_cmd *cmd); 17 17 #else 18 18 19 19 static inline int rpmh_write(const struct device *dev, enum rpmh_state state, 20 20 const struct tcs_cmd *cmd, u32 n) 21 + { return -ENODEV; } 22 + static inline int rpmh_read(const struct udevice *dev, struct tcs_cmd *cmd) 21 23 { return -ENODEV; } 22 24 23 25 #endif /* CONFIG_QCOM_RPMH */
+1
include/soc/qcom/tcs.h
··· 55 55 */ 56 56 struct tcs_request { 57 57 enum rpmh_state state; 58 + bool is_read; 58 59 u32 wait_for_compl; 59 60 u32 num_cmds; 60 61 struct tcs_cmd *cmds;