diff --git a/arch/arm64/configs/vendor/pineapple_GKI.config b/arch/arm64/configs/vendor/pineapple_GKI.config index c6864d7dfa80..7f6e8066626a 100644 --- a/arch/arm64/configs/vendor/pineapple_GKI.config +++ b/arch/arm64/configs/vendor/pineapple_GKI.config @@ -211,7 +211,7 @@ CONFIG_QTI_BATTERY_CHARGER=m CONFIG_QTI_BATTERY_GLINK_DEBUG=m CONFIG_QTI_BCL_PMIC5=m CONFIG_QTI_BCL_SOC_DRIVER=m -CONFIG_QTI_C1DCVS_SCMI_CLIENT=m +CONFIG_QTI_C1DCVS_SCMI_V2=m CONFIG_QTI_CHARGER_ULOG_GLINK=m CONFIG_QTI_CPUCP_LOG=m CONFIG_QTI_CPUFREQ_CDEV=m @@ -225,16 +225,16 @@ CONFIG_QTI_DEVFREQ_CDEV=m CONFIG_QTI_GLINK_ADC=m CONFIG_QTI_HW_KEY_MANAGER=m CONFIG_QTI_IOMMU_SUPPORT=m +CONFIG_QTI_MPAM=m CONFIG_QTI_PMIC_EUSB2_REPEATER=m CONFIG_QTI_PMIC_GLINK=m # CONFIG_QTI_PMIC_GLINK_CLIENT_DEBUG is not set CONFIG_QTI_PMIC_GLINK_DEBUG=m CONFIG_QTI_PMIC_PON_LOG=m -CONFIG_QTI_PMU_SCMI_CLIENT=m +CONFIG_QTI_QCOM_SCMI_CLIENT=m CONFIG_QTI_QMI_COOLING_DEVICE=m CONFIG_QTI_QMI_SENSOR_V2=m -CONFIG_QTI_SCMI_C1DCVS_PROTOCOL=m -CONFIG_QTI_SCMI_PMU_PROTOCOL=m +CONFIG_QTI_SCMI_VENDOR_PROTOCOL=m CONFIG_QTI_SYS_PM_VX=m CONFIG_QTI_THERMAL_LIMITS_DCVS=m CONFIG_QTI_USERSPACE_CDEV=m diff --git a/drivers/soc/qcom/dcvs/Kconfig b/drivers/soc/qcom/dcvs/Kconfig index 59b2e05f2262..55aa639b0abc 100644 --- a/drivers/soc/qcom/dcvs/Kconfig +++ b/drivers/soc/qcom/dcvs/Kconfig @@ -96,3 +96,15 @@ config QTI_C1DCVS_SCMI_V2 This driver is used to expose sysfs interface to communicate with cpucp for C1 DCVS based on SCMI consolidation. + +config QTI_MPAM + tristate "Qualcomm Technologies Inc. MPAM Interface Driver" + depends on QTI_SCMI_VENDOR_PROTOCOL + default n + help + Driver to expose MPAM sysfs nodes to user space. + + This driver gathers MPAM configuration parameters from sysfs + userspace and relays them to CPUCP via SCMI communication. + It is intended to be used by clients familiar with modifying + the ARM MPAM configuration settings. diff --git a/drivers/soc/qcom/dcvs/Makefile b/drivers/soc/qcom/dcvs/Makefile index 1bae8ef509b8..0bd51b754dd4 100644 --- a/drivers/soc/qcom/dcvs/Makefile +++ b/drivers/soc/qcom/dcvs/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_QTI_PMU_SCMI_CLIENT) += pmu_scmi.o obj-$(CONFIG_QTI_C1DCVS_SCMI_CLIENT) += c1dcvs_scmi.o obj-$(CONFIG_QTI_QCOM_SCMI_CLIENT) += qcom_scmi_client.o obj-$(CONFIG_QTI_C1DCVS_SCMI_V2) += c1dcvs_scmi_v2.o +obj-$(CONFIG_QTI_MPAM) += mpam.o diff --git a/drivers/soc/qcom/dcvs/mpam.c b/drivers/soc/qcom/dcvs/mpam.c new file mode 100644 index 000000000000..7e29d41a90b6 --- /dev/null +++ b/drivers/soc/qcom/dcvs/mpam.c @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MPAM_ALGO_STR 0x4D50414D4558544E /* "MPAMEXTN" */ + +enum mpam_profiling_param_ids { + PARAM_CACHE_PORTION = 1, +}; + +struct mpam_cache_portion { + uint32_t part_id; + uint32_t cache_portion; +}; + +static struct mpam_cache_portion cur_cache_portion; +static struct kobject mpam_kobj; +static struct scmi_protocol_handle *ph; +static const struct qcom_scmi_vendor_ops *ops; +static struct scmi_device *sdev; + + +static int qcom_mpam_set_cache_portion(struct mpam_cache_portion *msg) +{ + int ret = 0; + + ret = ops->set_param(ph, msg, MPAM_ALGO_STR, PARAM_CACHE_PORTION, + sizeof(*msg)); + + if (!ret) + memcpy(&cur_cache_portion, msg, sizeof(*msg)); + + return ret; +} + +struct qcom_mpam_attr { + struct attribute attr; + ssize_t (*show)(struct kobject *kobj, struct attribute *attr, + char *buf); + ssize_t (*store)(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t count); +}; + +#define to_mpam_attr(_attr) \ + container_of(_attr, struct qcom_mpam_attr, attr) +#define MPAM_ATTR_RW(_name) \ +static struct qcom_mpam_attr _name = \ +__ATTR(_name, 0644, show_##_name, store_##_name) \ + + +static ssize_t store_set_cache_portion(struct kobject *kobj, + struct attribute *attr, const char *buf, + size_t count) +{ + int i, ret = -EINVAL; + unsigned int val[2]; + char *str, *s = kstrdup(buf, GFP_KERNEL); + struct mpam_cache_portion msg; + + for (i = 0; i < 2; i++) { + str = strsep(&s, " "); + if (!str) + goto out; + ret = kstrtouint(str, 10, &val[i]); + if (ret < 0) { + pr_err("Invalid value :%d\n", ret); + goto out; + } + } + + msg.part_id = val[0]; + msg.cache_portion = val[1]; + + ret = qcom_mpam_set_cache_portion(&msg); + +out: + kfree(s); + return ((ret < 0) ? ret : count); +} + +static ssize_t show_set_cache_portion(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%u\t%u\n", cur_cache_portion.part_id, + cur_cache_portion.cache_portion); +} + +MPAM_ATTR_RW(set_cache_portion); + +static struct attribute *mpam_settings_attrs[] = { + &set_cache_portion.attr, + NULL, +}; +ATTRIBUTE_GROUPS(mpam_settings); + +static ssize_t attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct qcom_mpam_attr *mpam_attr = to_mpam_attr(attr); + ssize_t ret = -EIO; + + if (mpam_attr->show) + ret = mpam_attr->show(kobj, attr, buf); + + return ret; +} + +static ssize_t attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t count) +{ + struct qcom_mpam_attr *mpam_attr = to_mpam_attr(attr); + ssize_t ret = -EIO; + + if (mpam_attr->store) + ret = mpam_attr->store(kobj, attr, buf, count); + + return ret; +} + +static const struct sysfs_ops mpam_sysfs_ops = { + .show = attr_show, + .store = attr_store, +}; +static struct kobj_type mpam_settings_ktype = { + .sysfs_ops = &mpam_sysfs_ops, + .default_groups = mpam_settings_groups, +}; + +static int mpam_dev_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int ret = 0; + + sdev = get_qcom_scmi_device(); + if (IS_ERR(sdev)) { + ret = PTR_ERR(sdev); + if (ret != -EPROBE_DEFER) + dev_err(dev, "Error getting scmi_dev ret=%d\n", ret); + return ret; + } + ops = sdev->handle->devm_protocol_get(sdev, QCOM_SCMI_VENDOR_PROTOCOL, &ph); + if (IS_ERR(ops)) { + ret = PTR_ERR(ops); + dev_err(dev, "Error getting vendor protocol ops: %d\n", ret); + return ret; + } + + ret = kobject_init_and_add(&mpam_kobj, &mpam_settings_ktype, + &cpu_subsys.dev_root->kobj, "mpam"); + if (ret < 0) { + dev_err(dev, "failed to init mpam kobj: %d\n", ret); + kobject_put(&mpam_kobj); + } + + return ret; +} + +static const struct of_device_id qcom_mpam_table[] = { + { .compatible = "qcom,mpam" }, + {}, +}; + +static struct platform_driver qcom_mpam_driver = { + .driver = { + .name = "qcom-mpam", + .of_match_table = qcom_mpam_table, + }, + .probe = mpam_dev_probe, +}; + +module_platform_driver(qcom_mpam_driver); +MODULE_SOFTDEP("pre: qcom_scmi_client"); +MODULE_DESCRIPTION("QCOM MPAM driver"); +MODULE_LICENSE("GPL"); diff --git a/modules.list.msm.pineapple b/modules.list.msm.pineapple index 72ec07d192dd..7ec56da7f354 100644 --- a/modules.list.msm.pineapple +++ b/modules.list.msm.pineapple @@ -1,6 +1,8 @@ qcom_wdt_core.ko gh_virt_wdt.ko qcom_cpu_vendor_hooks.ko +qcom_scmi_vendor.ko +qcom_scmi_client.ko cmd-db.ko qcom_rpmh.ko qcom-pdc.ko diff --git a/pineapple.bzl b/pineapple.bzl index f35941299da4..95eafdb0c048 100644 --- a/pineapple.bzl +++ b/pineapple.bzl @@ -31,8 +31,7 @@ def define_pineapple(): "drivers/dma/qcom/bam_dma.ko", "drivers/dma/qcom/msm_gpi.ko", "drivers/edac/qcom_edac.ko", - "drivers/firmware/arm_scmi/c1dcvs_vendor.ko", - "drivers/firmware/arm_scmi/pmu_vendor.ko", + "drivers/firmware/arm_scmi/qcom_scmi_vendor.ko", "drivers/firmware/qcom-scm.ko", "drivers/gpu/drm/display/drm_display_helper.ko", "drivers/gpu/drm/display/drm_dp_aux_bus.ko", @@ -128,6 +127,7 @@ def define_pineapple(): "drivers/soc/qcom/adsp_sleepmon.ko", "drivers/soc/qcom/altmode-glink.ko", "drivers/soc/qcom/boot_stats.ko", + "drivers/soc/qcom/dcvs/c1dcvs_scmi_v2.ko", "drivers/soc/qcom/cdsprm.ko", "drivers/soc/qcom/charger-ulog-glink.ko", "drivers/soc/qcom/cmd-db.ko", @@ -137,12 +137,12 @@ def define_pineapple(): "drivers/soc/qcom/crypto-qti.ko", "drivers/soc/qcom/dcc_v2.ko", "drivers/soc/qcom/dcvs/bwmon.ko", - "drivers/soc/qcom/dcvs/c1dcvs_scmi.ko", "drivers/soc/qcom/dcvs/dcvs_fp.ko", "drivers/soc/qcom/dcvs/memlat.ko", - "drivers/soc/qcom/dcvs/pmu_scmi.ko", + "drivers/soc/qcom/dcvs/mpam.ko", "drivers/soc/qcom/dcvs/qcom-dcvs.ko", "drivers/soc/qcom/dcvs/qcom-pmu-lib.ko", + "drivers/soc/qcom/dcvs/qcom_scmi_client.ko", "drivers/soc/qcom/debug_symbol.ko", "drivers/soc/qcom/dmesg_dumper.ko", "drivers/soc/qcom/eud.ko",