Loading drivers/soc/qcom/cdsprm.c +103 −14 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ /* Loading @@ -13,6 +13,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/completion.h> #include <linux/string.h> #include <linux/err.h> Loading Loading @@ -231,6 +232,7 @@ struct cdsprm { bool b_rpmsg_register; bool b_qosinitdone; bool b_applyingNpuLimit; bool b_silver_en; int latency_request; int b_cdsprm_devinit; int b_hvxrm_devinit; Loading @@ -245,6 +247,9 @@ struct cdsprm { int (*set_l3_freq_cached)(unsigned int freq_khz); int (*set_corner_limit)(enum cdsprm_npu_corner); int (*set_corner_limit_cached)(enum cdsprm_npu_corner); u32 *coreno; u32 corecount; struct dev_pm_qos_request *dev_pm_qos_req; }; static struct cdsprm gcdsprm; Loading Loading @@ -594,8 +599,84 @@ void cdsprm_unregister_cdspl3gov(void) } EXPORT_SYMBOL(cdsprm_unregister_cdspl3gov); static void qos_cores_init(struct device *dev) { int i, err = 0; u32 *cpucores = NULL; of_find_property(dev->of_node, "qcom,qos-cores", &gcdsprm.corecount); if (gcdsprm.corecount) { gcdsprm.corecount /= sizeof(u32); cpucores = kcalloc(gcdsprm.corecount, sizeof(u32), GFP_KERNEL); if (cpucores == NULL) { dev_err(dev, "kcalloc failed for cpucores\n"); gcdsprm.b_silver_en = false; } for (i = 0; i < gcdsprm.corecount; i++) { err = of_property_read_u32_index(dev->of_node, "qcom,qos-cores", i, &cpucores[i]); if (err) { dev_err(dev, "%s: failed to read QOS coree for core:%d\n", __func__, i); gcdsprm.b_silver_en = false; } } gcdsprm.coreno = cpucores; gcdsprm.dev_pm_qos_req = kcalloc(gcdsprm.corecount, sizeof(struct dev_pm_qos_request), GFP_KERNEL); if (gcdsprm.dev_pm_qos_req == NULL) { dev_err(dev, "kcalloc failed for dev_pm_qos_req\n"); gcdsprm.b_silver_en = false; } } } static void set_qos_latency(int latency) { int err = 0; u32 ii = 0; int cpu; if (gcdsprm.b_silver_en) { for (ii = 0; ii < gcdsprm.corecount; ii++) { cpu = gcdsprm.coreno[ii]; if (!gcdsprm.qos_request) { err = dev_pm_qos_add_request( get_cpu_device(cpu), &gcdsprm.dev_pm_qos_req[ii], DEV_PM_QOS_RESUME_LATENCY, latency); } else { err = dev_pm_qos_update_request( &gcdsprm.dev_pm_qos_req[ii], latency); } if (err < 0) { pr_err("%s: %s: PM voting cpu:%d fail,err %d,QoS update %d\n", current->comm, __func__, cpu, err, gcdsprm.qos_request); break; } } if (err >= 0) gcdsprm.qos_request = true; } else { if (!gcdsprm.qos_request) { pm_qos_add_request(&gcdsprm.pm_qos_req, PM_QOS_CPU_DMA_LATENCY, latency); Loading @@ -605,6 +686,7 @@ static void set_qos_latency(int latency) latency); } } } static void process_rm_request(struct sysmon_msg *msg) { Loading Loading @@ -646,9 +728,9 @@ static void process_rm_request(struct sysmon_msg *msg) } else if ((rm_msg->b_qos_flag == SYSMON_CDSP_QOS_FLAG_DISABLE) && (gcdsprm.latency_request != QOS_LATENCY_DISABLE_VALUE)) { set_qos_latency(QOS_LATENCY_DISABLE_VALUE); gcdsprm.latency_request = QOS_LATENCY_DISABLE_VALUE; PM_QOS_RESUME_LATENCY_DEFAULT_VALUE)) { set_qos_latency(PM_QOS_RESUME_LATENCY_DEFAULT_VALUE); gcdsprm.latency_request = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; pr_debug("Set qos latency to %d\n", gcdsprm.latency_request); } Loading Loading @@ -689,8 +771,8 @@ static void process_delayed_rm_request(struct work_struct *work) curr_timestamp = __arch_counter_get_cntvct(); } set_qos_latency(QOS_LATENCY_DISABLE_VALUE); gcdsprm.latency_request = QOS_LATENCY_DISABLE_VALUE; set_qos_latency(PM_QOS_RESUME_LATENCY_DEFAULT_VALUE); gcdsprm.latency_request = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; pr_debug("Set qos latency to %d\n", gcdsprm.latency_request); gcdsprm.dt_state = CDSP_DELAY_THREAD_EXITING; Loading Loading @@ -1142,10 +1224,17 @@ static int cdsp_rm_driver_probe(struct platform_device *pdev) { int n, m, i, ret; u32 p; struct device *dev = &pdev->dev; struct thermal_cooling_device *tcdev = 0; unsigned int cooling_cells = 0; gcdsprm.b_silver_en = of_property_read_bool(dev->of_node, "qcom,qos-cores"); if (gcdsprm.b_silver_en) qos_cores_init(dev); if (of_property_read_u32(dev->of_node, "qcom,qos-latency-us", &gcdsprm.qos_latency_us)) { return -EINVAL; Loading Loading @@ -1505,8 +1594,8 @@ static void __exit cdsprm_exit(void) pr_info("Exit module called\n"); if (gcdsprm.qos_request) { set_qos_latency(QOS_LATENCY_DISABLE_VALUE); gcdsprm.latency_request = QOS_LATENCY_DISABLE_VALUE; set_qos_latency(PM_QOS_RESUME_LATENCY_DEFAULT_VALUE); gcdsprm.latency_request = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; } if (gcdsprm.hvx_tcdev) Loading Loading
drivers/soc/qcom/cdsprm.c +103 −14 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ /* Loading @@ -13,6 +13,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/completion.h> #include <linux/string.h> #include <linux/err.h> Loading Loading @@ -231,6 +232,7 @@ struct cdsprm { bool b_rpmsg_register; bool b_qosinitdone; bool b_applyingNpuLimit; bool b_silver_en; int latency_request; int b_cdsprm_devinit; int b_hvxrm_devinit; Loading @@ -245,6 +247,9 @@ struct cdsprm { int (*set_l3_freq_cached)(unsigned int freq_khz); int (*set_corner_limit)(enum cdsprm_npu_corner); int (*set_corner_limit_cached)(enum cdsprm_npu_corner); u32 *coreno; u32 corecount; struct dev_pm_qos_request *dev_pm_qos_req; }; static struct cdsprm gcdsprm; Loading Loading @@ -594,8 +599,84 @@ void cdsprm_unregister_cdspl3gov(void) } EXPORT_SYMBOL(cdsprm_unregister_cdspl3gov); static void qos_cores_init(struct device *dev) { int i, err = 0; u32 *cpucores = NULL; of_find_property(dev->of_node, "qcom,qos-cores", &gcdsprm.corecount); if (gcdsprm.corecount) { gcdsprm.corecount /= sizeof(u32); cpucores = kcalloc(gcdsprm.corecount, sizeof(u32), GFP_KERNEL); if (cpucores == NULL) { dev_err(dev, "kcalloc failed for cpucores\n"); gcdsprm.b_silver_en = false; } for (i = 0; i < gcdsprm.corecount; i++) { err = of_property_read_u32_index(dev->of_node, "qcom,qos-cores", i, &cpucores[i]); if (err) { dev_err(dev, "%s: failed to read QOS coree for core:%d\n", __func__, i); gcdsprm.b_silver_en = false; } } gcdsprm.coreno = cpucores; gcdsprm.dev_pm_qos_req = kcalloc(gcdsprm.corecount, sizeof(struct dev_pm_qos_request), GFP_KERNEL); if (gcdsprm.dev_pm_qos_req == NULL) { dev_err(dev, "kcalloc failed for dev_pm_qos_req\n"); gcdsprm.b_silver_en = false; } } } static void set_qos_latency(int latency) { int err = 0; u32 ii = 0; int cpu; if (gcdsprm.b_silver_en) { for (ii = 0; ii < gcdsprm.corecount; ii++) { cpu = gcdsprm.coreno[ii]; if (!gcdsprm.qos_request) { err = dev_pm_qos_add_request( get_cpu_device(cpu), &gcdsprm.dev_pm_qos_req[ii], DEV_PM_QOS_RESUME_LATENCY, latency); } else { err = dev_pm_qos_update_request( &gcdsprm.dev_pm_qos_req[ii], latency); } if (err < 0) { pr_err("%s: %s: PM voting cpu:%d fail,err %d,QoS update %d\n", current->comm, __func__, cpu, err, gcdsprm.qos_request); break; } } if (err >= 0) gcdsprm.qos_request = true; } else { if (!gcdsprm.qos_request) { pm_qos_add_request(&gcdsprm.pm_qos_req, PM_QOS_CPU_DMA_LATENCY, latency); Loading @@ -605,6 +686,7 @@ static void set_qos_latency(int latency) latency); } } } static void process_rm_request(struct sysmon_msg *msg) { Loading Loading @@ -646,9 +728,9 @@ static void process_rm_request(struct sysmon_msg *msg) } else if ((rm_msg->b_qos_flag == SYSMON_CDSP_QOS_FLAG_DISABLE) && (gcdsprm.latency_request != QOS_LATENCY_DISABLE_VALUE)) { set_qos_latency(QOS_LATENCY_DISABLE_VALUE); gcdsprm.latency_request = QOS_LATENCY_DISABLE_VALUE; PM_QOS_RESUME_LATENCY_DEFAULT_VALUE)) { set_qos_latency(PM_QOS_RESUME_LATENCY_DEFAULT_VALUE); gcdsprm.latency_request = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; pr_debug("Set qos latency to %d\n", gcdsprm.latency_request); } Loading Loading @@ -689,8 +771,8 @@ static void process_delayed_rm_request(struct work_struct *work) curr_timestamp = __arch_counter_get_cntvct(); } set_qos_latency(QOS_LATENCY_DISABLE_VALUE); gcdsprm.latency_request = QOS_LATENCY_DISABLE_VALUE; set_qos_latency(PM_QOS_RESUME_LATENCY_DEFAULT_VALUE); gcdsprm.latency_request = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; pr_debug("Set qos latency to %d\n", gcdsprm.latency_request); gcdsprm.dt_state = CDSP_DELAY_THREAD_EXITING; Loading Loading @@ -1142,10 +1224,17 @@ static int cdsp_rm_driver_probe(struct platform_device *pdev) { int n, m, i, ret; u32 p; struct device *dev = &pdev->dev; struct thermal_cooling_device *tcdev = 0; unsigned int cooling_cells = 0; gcdsprm.b_silver_en = of_property_read_bool(dev->of_node, "qcom,qos-cores"); if (gcdsprm.b_silver_en) qos_cores_init(dev); if (of_property_read_u32(dev->of_node, "qcom,qos-latency-us", &gcdsprm.qos_latency_us)) { return -EINVAL; Loading Loading @@ -1505,8 +1594,8 @@ static void __exit cdsprm_exit(void) pr_info("Exit module called\n"); if (gcdsprm.qos_request) { set_qos_latency(QOS_LATENCY_DISABLE_VALUE); gcdsprm.latency_request = QOS_LATENCY_DISABLE_VALUE; set_qos_latency(PM_QOS_RESUME_LATENCY_DEFAULT_VALUE); gcdsprm.latency_request = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; } if (gcdsprm.hvx_tcdev) Loading