File Index
Files and directories
Sign in
FILE

exynos-acpm-dvfs.c

File preview with syntax highlighting.

linux-6.19.14/drivers/firmware/samsung/exynos-acpm-dvfs.c C
 1// SPDX-License-Identifier: GPL-2.0-only
 2/*
 3 * Copyright 2020 Samsung Electronics Co., Ltd.
 4 * Copyright 2020 Google LLC.
 5 * Copyright 2025 Linaro Ltd.
 6 */
 7
 8#include <linux/bitfield.h>
 9#include <linux/firmware/samsung/exynos-acpm-protocol.h>
10#include <linux/ktime.h>
11#include <linux/types.h>
12#include <linux/units.h>
13
14#include "exynos-acpm.h"
15#include "exynos-acpm-dvfs.h"
16
17#define ACPM_DVFS_ID			GENMASK(11, 0)
18#define ACPM_DVFS_REQ_TYPE		GENMASK(15, 0)
19
20#define ACPM_DVFS_FREQ_REQ		0
21#define ACPM_DVFS_FREQ_GET		1
22
23static void acpm_dvfs_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen,
24			       unsigned int acpm_chan_id, bool response)
25{
26	xfer->acpm_chan_id = acpm_chan_id;
27	xfer->txd = cmd;
28	xfer->txlen = cmdlen;
29
30	if (response) {
31		xfer->rxd = cmd;
32		xfer->rxlen = cmdlen;
33	}
34}
35
36static void acpm_dvfs_init_set_rate_cmd(u32 cmd[4], unsigned int clk_id,
37					unsigned long rate)
38{
39	cmd[0] = FIELD_PREP(ACPM_DVFS_ID, clk_id);
40	cmd[1] = rate / HZ_PER_KHZ;
41	cmd[2] = FIELD_PREP(ACPM_DVFS_REQ_TYPE, ACPM_DVFS_FREQ_REQ);
42	cmd[3] = ktime_to_ms(ktime_get());
43}
44
45int acpm_dvfs_set_rate(const struct acpm_handle *handle,
46		       unsigned int acpm_chan_id, unsigned int clk_id,
47		       unsigned long rate)
48{
49	struct acpm_xfer xfer = {0};
50	u32 cmd[4];
51
52	acpm_dvfs_init_set_rate_cmd(cmd, clk_id, rate);
53	acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, false);
54
55	return acpm_do_xfer(handle, &xfer);
56}
57
58static void acpm_dvfs_init_get_rate_cmd(u32 cmd[4], unsigned int clk_id)
59{
60	cmd[0] = FIELD_PREP(ACPM_DVFS_ID, clk_id);
61	cmd[2] = FIELD_PREP(ACPM_DVFS_REQ_TYPE, ACPM_DVFS_FREQ_GET);
62	cmd[3] = ktime_to_ms(ktime_get());
63}
64
65unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle,
66				 unsigned int acpm_chan_id, unsigned int clk_id)
67{
68	struct acpm_xfer xfer;
69	unsigned int cmd[4] = {0};
70	int ret;
71
72	acpm_dvfs_init_get_rate_cmd(cmd, clk_id);
73	acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, true);
74
75	ret = acpm_do_xfer(handle, &xfer);
76	if (ret)
77		return 0;
78
79	return xfer.rxd[1] * HZ_PER_KHZ;
80}
~/ Read-only file preview.