blob: 96f14a9afdf20e3736d0826a4a23649105c06558 [file] [log] [blame]
Caleb Connolly90ff5812024-07-15 12:08:02 +02001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
4 */
5
Caleb Connolly77e9be42024-07-15 12:08:11 +02006#include <dm/device.h>
7#include <dm/device_compat.h>
Caleb Connolly90ff5812024-07-15 12:08:02 +02008#include <linux/bug.h>
Caleb Connolly90ff5812024-07-15 12:08:02 +02009#include <linux/kernel.h>
10#include <linux/list.h>
Caleb Connolly90ff5812024-07-15 12:08:02 +020011#include <linux/types.h>
Caleb Connolly90ff5812024-07-15 12:08:02 +020012
13#include <soc/qcom/rpmh.h>
14
15#include "rpmh-internal.h"
16
17#define RPMH_TIMEOUT_MS msecs_to_jiffies(10000)
18
Caleb Connolly14794852024-07-15 12:08:13 +020019#define DEFINE_RPMH_MSG_ONSTACK(device, s, name) \
Caleb Connolly90ff5812024-07-15 12:08:02 +020020 struct rpmh_request name = { \
21 .msg = { \
22 .state = s, \
23 .cmds = name.cmd, \
24 .num_cmds = 0, \
Caleb Connolly90ff5812024-07-15 12:08:02 +020025 }, \
26 .cmd = { { 0 } }, \
Caleb Connolly90ff5812024-07-15 12:08:02 +020027 .dev = device, \
Caleb Connolly14794852024-07-15 12:08:13 +020028 .needs_free = false, \
Caleb Connolly90ff5812024-07-15 12:08:02 +020029 }
30
31#define ctrlr_to_drv(ctrlr) container_of(ctrlr, struct rsc_drv, client)
32
Caleb Connolly14794852024-07-15 12:08:13 +020033static struct rpmh_ctrlr *get_rpmh_ctrlr(const struct udevice *dev)
Caleb Connolly90ff5812024-07-15 12:08:02 +020034{
Caleb Connolly14794852024-07-15 12:08:13 +020035 struct rsc_drv *drv = (struct rsc_drv *)dev_get_priv(dev->parent);
36
37 if (!drv) {
38 log_err("BUG: no RPMh driver for %s (parent %s)\n", dev->name, dev->parent->name);
39 BUG();
40 }
Caleb Connolly90ff5812024-07-15 12:08:02 +020041
42 return &drv->client;
43}
44
Caleb Connolly90ff5812024-07-15 12:08:02 +020045/**
46 * __rpmh_write: Cache and send the RPMH request
47 *
48 * @dev: The device making the request
49 * @state: Active/Sleep request type
50 * @rpm_msg: The data that needs to be sent (cmds).
51 *
52 * Cache the RPMH request and send if the state is ACTIVE_ONLY.
53 * SLEEP/WAKE_ONLY requests are not sent to the controller at
54 * this time. Use rpmh_flush() to send them to the controller.
55 */
Caleb Connolly14794852024-07-15 12:08:13 +020056static int __rpmh_write(const struct udevice *dev, enum rpmh_state state,
Caleb Connolly90ff5812024-07-15 12:08:02 +020057 struct rpmh_request *rpm_msg)
58{
59 struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
Caleb Connolly90ff5812024-07-15 12:08:02 +020060
Caleb Connolly14794852024-07-15 12:08:13 +020061 if (state != RPMH_ACTIVE_ONLY_STATE) {
62 log_err("only ACTIVE_ONLY state supported\n");
63 return -EINVAL;
Caleb Connolly90ff5812024-07-15 12:08:02 +020064 }
65
Caleb Connolly14794852024-07-15 12:08:13 +020066 return rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msg->msg);
Caleb Connolly90ff5812024-07-15 12:08:02 +020067}
68
69static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state,
Caleb Connolly14794852024-07-15 12:08:13 +020070 const struct tcs_cmd *cmd, u32 n)
Caleb Connolly90ff5812024-07-15 12:08:02 +020071{
72 if (!cmd || !n || n > MAX_RPMH_PAYLOAD)
73 return -EINVAL;
74
75 memcpy(req->cmd, cmd, n * sizeof(*cmd));
76
77 req->msg.state = state;
78 req->msg.cmds = req->cmd;
79 req->msg.num_cmds = n;
80
Caleb Connolly14794852024-07-15 12:08:13 +020081 debug("rpmh_msg: %d, %d cmds [first %#x/%#x]\n", state, n, cmd->addr, cmd->data);
82
Caleb Connolly90ff5812024-07-15 12:08:02 +020083 return 0;
84}
Caleb Connolly90ff5812024-07-15 12:08:02 +020085
86/**
87 * rpmh_write: Write a set of RPMH commands and block until response
88 *
89 * @dev: The device making the request
90 * @state: Active/sleep set
91 * @cmd: The payload data
92 * @n: The number of elements in @cmd
93 *
94 * May sleep. Do not call from atomic contexts.
95 */
Caleb Connolly14794852024-07-15 12:08:13 +020096int rpmh_write(const struct udevice *dev, enum rpmh_state state,
Caleb Connolly90ff5812024-07-15 12:08:02 +020097 const struct tcs_cmd *cmd, u32 n)
98{
Caleb Connolly14794852024-07-15 12:08:13 +020099 DEFINE_RPMH_MSG_ONSTACK(dev, state, rpm_msg);
Caleb Connolly90ff5812024-07-15 12:08:02 +0200100 int ret;
101
102 ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n);
103 if (ret)
104 return ret;
105
106 ret = __rpmh_write(dev, state, &rpm_msg);
Caleb Connolly90ff5812024-07-15 12:08:02 +0200107
Caleb Connolly14794852024-07-15 12:08:13 +0200108 return ret;
Caleb Connolly90ff5812024-07-15 12:08:02 +0200109}
110EXPORT_SYMBOL_GPL(rpmh_write);