firmware: arm_scmi: Add support for plh vendor protocol
PLH vendor protocol snapshot from msm-5.10 branch commit 975d6a6235dd ("Add support for plh vendor protocol"). Change-Id: Idb412d3bc5b0596a669bb9ec54daa978e7c11903 Signed-off-by: simran jaiswal <quic_simranja@quicinc.com>
This commit is contained in:
parent
4817d1d1de
commit
d2d3445771
@ -169,6 +169,17 @@ config QTI_SCMI_C1DCVS_PROTOCOL
|
||||
This driver defines the comands or message ID's used for this
|
||||
communication and also exposes the ops used by clients.
|
||||
|
||||
config QTI_SCMI_PLH_PROTOCOL
|
||||
tristate "Qualcomm Technologies, Inc. SCMI PLH vendor Protocol"
|
||||
depends on ARM_SCMI_PROTOCOL && QCOM_CPUCP
|
||||
help
|
||||
System Control and Management Interface (SCMI) plh vendor protocol
|
||||
this protocol provides interface to communicate with micro controller
|
||||
which is executing the plh algorithm.
|
||||
|
||||
This driver defines the comands or message ID's used for this
|
||||
communication and also exposes the ops used by clients.
|
||||
|
||||
endif #ARM_SCMI_PROTOCOL
|
||||
|
||||
config ARM_SCMI_POWER_DOMAIN
|
||||
|
@ -16,6 +16,7 @@ obj-$(CONFIG_ARM_SCMI_POWER_CONTROL) += scmi_power_control.o
|
||||
obj-$(CONFIG_QTI_SCMI_PMU_PROTOCOL) += pmu_vendor.o
|
||||
obj-$(CONFIG_QTI_SCMI_C1DCVS_PROTOCOL) += c1dcvs_vendor.o
|
||||
obj-$(CONFIG_QTI_SCMI_VENDOR_PROTOCOL) += qcom_scmi_vendor.o
|
||||
obj-$(CONFIG_QTI_SCMI_PLH_PROTOCOL) += plh_vendor.o
|
||||
|
||||
ifeq ($(CONFIG_THUMB2_KERNEL)$(CONFIG_CC_IS_CLANG),yy)
|
||||
# The use of R7 in the SMCCC conflicts with the compiler's use of R7 as a frame
|
||||
|
175
drivers/firmware/arm_scmi/plh_vendor.c
Normal file
175
drivers/firmware/arm_scmi/plh_vendor.c
Normal file
@ -0,0 +1,175 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/scmi_plh.h>
|
||||
#include "common.h"
|
||||
|
||||
#define SCMI_VENDOR_MSG_MAX_TX_SIZE (100) /* in bytes */
|
||||
#define SCMI_VENDOR_MSG_START (3) /* MSG 3-15 can be used for spl purpose */
|
||||
#define SCMI_VENDOR_MSG_SPLH_START (16) /* Each PLH module to use MAX 16 MSG */
|
||||
#define SCMI_VENDOR_MSG_SPLH_END (31)
|
||||
#define SCMI_VENDOR_MSG_LPLH_START (32) /* Each PLH module to use MAX 16 MSG */
|
||||
#define SCMI_VENDOR_MSG_LPLH_END (47)
|
||||
|
||||
enum scmi_plh_protocol_cmd {
|
||||
PERF_LOCK_SCROLL_INIT_IPC_FREQ_TBL_MSG_ID = SCMI_VENDOR_MSG_SPLH_START,
|
||||
PERF_LOCK_SCROLL_START_MSG_ID,
|
||||
PERF_LOCK_SCROLL_STOP_MSG_ID,
|
||||
PERF_LOCK_SCROLL_SET_SAMPLE_MS,
|
||||
PERF_LOCK_SCROLL_SET_LOG_LEVEL,
|
||||
PERF_LOCK_SCROLL_MAX_MSG_ID = SCMI_VENDOR_MSG_SPLH_END,
|
||||
PERF_LOCK_LAUNCH_INIT_IPC_FREQ_TBL_MSG_ID = SCMI_VENDOR_MSG_LPLH_START,
|
||||
PERF_LOCK_LAUNCH_START_MSG_ID,
|
||||
PERF_LOCK_LAUNCH_STOP_MSG_ID,
|
||||
PERF_LOCK_LAUNCH_SET_SAMPLE_MS,
|
||||
PERF_LOCK_LAUNCH_SET_LOG_LEVEL,
|
||||
PERF_LOCK_LAUNCH_MAX_MSG_ID = SCMI_VENDOR_MSG_LPLH_END,
|
||||
};
|
||||
|
||||
|
||||
static int scmi_plh_init_ipc_freq_tbl(const struct scmi_protocol_handle *ph,
|
||||
u16 *p_init_args, u16 init_len, enum plh_features feature)
|
||||
{
|
||||
uint32_t *msg, msg_size, msg_val, align_init_len = init_len;
|
||||
struct scmi_xfer *t;
|
||||
int ret, i = 0;
|
||||
|
||||
if (init_len % 2)
|
||||
align_init_len += 1; /* align in multiple of u32 */
|
||||
|
||||
msg_size = align_init_len * sizeof(*p_init_args);
|
||||
|
||||
if (msg_size > SCMI_VENDOR_MSG_MAX_TX_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (feature == PERF_LOCK_SCROLL)
|
||||
ret = ph->xops->xfer_get_init(ph, PERF_LOCK_SCROLL_INIT_IPC_FREQ_TBL_MSG_ID,
|
||||
(msg_size), sizeof(uint32_t), &t);
|
||||
else if (feature == PERF_LOCK_LAUNCH)
|
||||
ret = ph->xops->xfer_get_init(ph, PERF_LOCK_LAUNCH_INIT_IPC_FREQ_TBL_MSG_ID,
|
||||
(msg_size), sizeof(uint32_t), &t);
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
msg = t->tx.buf;
|
||||
|
||||
for (i = 0; i < init_len/2 ; i++) {
|
||||
msg_val = *p_init_args++;
|
||||
msg_val |= ((*p_init_args++) << 16);
|
||||
*msg++ = cpu_to_le32(msg_val);
|
||||
}
|
||||
|
||||
if (init_len % 2)
|
||||
*msg = cpu_to_le32(*p_init_args);
|
||||
|
||||
ret = ph->xops->do_xfer(ph, t);
|
||||
ph->xops->xfer_put(ph, t);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scmi_plh_set_u16_val(const struct scmi_protocol_handle *ph,
|
||||
u16 val, u32 msg_id)
|
||||
{
|
||||
int ret = 0;
|
||||
struct scmi_xfer *t;
|
||||
uint32_t *msg;
|
||||
|
||||
ret = ph->xops->xfer_get_init(ph, msg_id,
|
||||
sizeof(*msg), sizeof(uint32_t), &t);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
msg = t->tx.buf;
|
||||
*msg = cpu_to_le32(val);
|
||||
ret = ph->xops->do_xfer(ph, t);
|
||||
ph->xops->xfer_put(ph, t);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scmi_plh_start_cmd(const struct scmi_protocol_handle *ph,
|
||||
u16 value, enum plh_features feature)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (feature == PERF_LOCK_SCROLL)
|
||||
ret = scmi_plh_set_u16_val(ph, value, PERF_LOCK_SCROLL_START_MSG_ID);
|
||||
else if (feature == PERF_LOCK_LAUNCH)
|
||||
ret = scmi_plh_set_u16_val(ph, value, PERF_LOCK_LAUNCH_START_MSG_ID);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scmi_plh_stop_cmd(const struct scmi_protocol_handle *ph, enum plh_features feature)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (feature == PERF_LOCK_SCROLL)
|
||||
ret = scmi_plh_set_u16_val(ph, 0, PERF_LOCK_SCROLL_STOP_MSG_ID);
|
||||
else if (feature == PERF_LOCK_LAUNCH)
|
||||
ret = scmi_plh_set_u16_val(ph, 0, PERF_LOCK_LAUNCH_STOP_MSG_ID);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scmi_plh_set_sample_ms(const struct scmi_protocol_handle *ph,
|
||||
u16 sample_ms, enum plh_features feature)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (feature == PERF_LOCK_SCROLL)
|
||||
ret = scmi_plh_set_u16_val(ph, sample_ms, PERF_LOCK_SCROLL_SET_SAMPLE_MS);
|
||||
else if (feature == PERF_LOCK_LAUNCH)
|
||||
ret = scmi_plh_set_u16_val(ph, sample_ms, PERF_LOCK_LAUNCH_SET_SAMPLE_MS);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scmi_plh_set_log_level(const struct scmi_protocol_handle *ph,
|
||||
u16 log_level, enum plh_features feature)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (feature == PERF_LOCK_SCROLL)
|
||||
ret = scmi_plh_set_u16_val(ph, log_level, PERF_LOCK_SCROLL_SET_LOG_LEVEL);
|
||||
else if (feature == PERF_LOCK_LAUNCH)
|
||||
ret = scmi_plh_set_u16_val(ph, log_level, PERF_LOCK_LAUNCH_SET_LOG_LEVEL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct scmi_plh_vendor_ops plh_proto_ops = {
|
||||
.init_plh_ipc_freq_tbl = scmi_plh_init_ipc_freq_tbl,
|
||||
.start_plh = scmi_plh_start_cmd,
|
||||
.stop_plh = scmi_plh_stop_cmd,
|
||||
.set_plh_sample_ms = scmi_plh_set_sample_ms,
|
||||
.set_plh_log_level = scmi_plh_set_log_level,
|
||||
};
|
||||
|
||||
static int scmi_plh_vendor_protocol_init(const struct scmi_protocol_handle *ph)
|
||||
{
|
||||
u32 version;
|
||||
|
||||
ph->xops->version_get(ph, &version);
|
||||
|
||||
dev_dbg(ph->dev, "PLH version %d.%d\n",
|
||||
PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct scmi_protocol scmi_plh_vendor = {
|
||||
.id = SCMI_PROTOCOL_PLH,
|
||||
.owner = THIS_MODULE,
|
||||
.instance_init = &scmi_plh_vendor_protocol_init,
|
||||
.ops = &plh_proto_ops,
|
||||
};
|
||||
module_scmi_protocol(scmi_plh_vendor);
|
||||
|
||||
MODULE_DESCRIPTION("SCMI plh vendor Protocol");
|
||||
MODULE_LICENSE("GPL");
|
@ -1018,6 +1018,19 @@ config MSM_PERFORMANCE
|
||||
fmin and fmax. The user space can request the cpu freq change by
|
||||
writing cpu#:freq values
|
||||
|
||||
config QTI_PLH_SCMI_CLIENT
|
||||
tristate "Qualcomm Technologies Inc. SCMI client driver for PLH"
|
||||
depends on MSM_PERFORMANCE && QTI_SCMI_PLH_PROTOCOL
|
||||
default n
|
||||
help
|
||||
SCMI client driver registers itself with SCMI framework for PLH
|
||||
vendor protocol, and also registers with the plh interface driver
|
||||
msm_performance.
|
||||
|
||||
This driver deliver the PLH vendor protocol handle to interface
|
||||
driver, and interface driver will use this handle to communicate
|
||||
with CPUCP PLH.
|
||||
|
||||
config QCOM_PANEL_EVENT_NOTIFIER
|
||||
tristate "panel event notifier"
|
||||
depends on DRM
|
||||
|
@ -84,6 +84,7 @@ obj-$(CONFIG_QCOM_CPUCP) += qcom_cpucp.o
|
||||
obj-$(CONFIG_QTI_CPUCP_LOG) += cpucp_log.o
|
||||
obj-$(CONFIG_QTI_SYS_PM_VX) += sys_pm_vx.o
|
||||
obj-$(CONFIG_MSM_PERFORMANCE) += msm_performance.o
|
||||
obj-$(CONFIG_QTI_PLH_SCMI_CLIENT) += plh_scmi.o
|
||||
obj-$(CONFIG_QCOM_WCD_USBSS_I2C) += wcd_usbss_i2c.o
|
||||
obj-$(CONFIG_QCOM_SYSMON_SUBSYSTEM_STATS) += sysmon_subsystem_stats.o
|
||||
obj-$(CONFIG_QCOM_CDSP_RM) += cdsprm.o
|
||||
|
58
drivers/soc/qcom/plh_scmi.c
Normal file
58
drivers/soc/qcom/plh_scmi.c
Normal file
@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/scmi_plh.h>
|
||||
#include <linux/scmi_protocol.h>
|
||||
|
||||
static struct scmi_device *scmi_dev;
|
||||
static int scmi_plh_inited;
|
||||
|
||||
struct scmi_device *get_plh_scmi_device(void)
|
||||
{
|
||||
if (!scmi_plh_inited)
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
|
||||
if (!scmi_dev || !scmi_dev->handle)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
return scmi_dev;
|
||||
}
|
||||
EXPORT_SYMBOL(get_plh_scmi_device);
|
||||
|
||||
static int scmi_plh_probe(struct scmi_device *sdev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
scmi_dev = sdev;
|
||||
if (!sdev)
|
||||
ret = -ENODEV;
|
||||
|
||||
scmi_plh_inited = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct scmi_device_id scmi_id_table[] = {
|
||||
{ .protocol_id = SCMI_PROTOCOL_PLH, .name = "scmi_protocol_plh" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(scmi, scmi_id_table);
|
||||
|
||||
static struct scmi_driver scmi_plh_drv = {
|
||||
.name = "scmi-plh-driver",
|
||||
.probe = scmi_plh_probe,
|
||||
.id_table = scmi_id_table,
|
||||
};
|
||||
module_scmi_driver(scmi_plh_drv);
|
||||
|
||||
MODULE_SOFTDEP("pre: plh_vendor");
|
||||
MODULE_DESCRIPTION("ARM SCMI PLH driver");
|
||||
MODULE_LICENSE("GPL");
|
47
include/linux/scmi_plh.h
Normal file
47
include/linux/scmi_plh.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* SCMI Vendor Protocols header
|
||||
*
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SCMI_PLH_VENDOR_H
|
||||
#define _SCMI_PLH_VENDOR_H
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define SCMI_PROTOCOL_PLH 0x81
|
||||
|
||||
enum plh_features {
|
||||
PERF_LOCK_SCROLL,
|
||||
PERF_LOCK_LAUNCH,
|
||||
};
|
||||
|
||||
struct scmi_protocol_handle;
|
||||
extern struct scmi_device *get_plh_scmi_device(void);
|
||||
|
||||
/**
|
||||
* struct scmi_plh_vendor_ops - represents the various operations provided
|
||||
* by SCMI PLH Protocol
|
||||
*
|
||||
* @init_plh_ipc_freq_tbl: initialize plh ipc freq voting table in cpucp
|
||||
* @start_plh: starts plh in cpucp
|
||||
* @stop_plh: stops plh in cpucp
|
||||
* @set_plh_sample_ms: configure the sampling duration of plh in cpucp
|
||||
* @set_plh_log_level: configure the supported log_level of plh in cpucp
|
||||
*/
|
||||
struct scmi_plh_vendor_ops {
|
||||
int (*init_plh_ipc_freq_tbl)(const struct scmi_protocol_handle *ph,
|
||||
u16 *p_init_args, u16 init_len, enum plh_features feature);
|
||||
int (*start_plh)(const struct scmi_protocol_handle *ph, u16 fps, enum plh_features feature);
|
||||
int (*stop_plh)(const struct scmi_protocol_handle *ph, enum plh_features feature);
|
||||
int (*set_plh_sample_ms)(const struct scmi_protocol_handle *ph,
|
||||
u16 sample_ms, enum plh_features feature);
|
||||
int (*set_plh_log_level)(const struct scmi_protocol_handle *ph,
|
||||
u16 log_level, enum plh_features feature);
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user